Add a third of the load command
authorLukáš Jiřiště <gymnazium.jiriste@gmail.com>
Thu, 14 Aug 2025 07:11:07 +0000 (09:11 +0200)
committerLukáš Jiřiště <gymnazium.jiriste@gmail.com>
Thu, 14 Aug 2025 07:11:07 +0000 (09:11 +0200)
The load command encompasses the language spec, its parsing and building
the circuit representation (and it also should create the graphics for
the loaded part).
In this commit only a part of the parsing is done (and the
prerequisites such as input handling).
This now correctly(?) parses the input file into a catalog of parts with
their dependencies.
I am sorry for the big (and yet incomplete) commit.

Makefile
TODO
grammar [new file with mode: 0644]
inc/FET_sim.h
parsing_table [new file with mode: 0644]
src/c_load.c [new file with mode: 0644]
src/main.c

index 9915d68eed0f3680946a5ff097e5c27504c6c62f..d6dd7117c69678c72bd2cebe85bc31f821c60698 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -38,6 +38,7 @@ SOURCES :=    main.c                  \
                        c_draw.c                \
                        c_next.c                \
                        c_help.c                \
+                       c_load.c                \
 
 SOURCES := $(addprefix $(SRCDIR)/, $(SOURCES))
 
diff --git a/TODO b/TODO
index 5dae8bf1ccf230f88b475fcfc8679012e959e7d4..67bf114db8b51aed6b758d6f54ea88c20a72e1d9 100644 (file)
--- a/TODO
+++ b/TODO
@@ -1,9 +1,12 @@
 TODO
+fix file not loading when load command repeated with empty command
+       - caused by saving file descriptor for file that is closed on load
 make build_graph not output
 rewrite command parsing (what I've created is just ugly)
 come up with better file structure
 create language to write circuits in (circuit language?) (something like MHRD language?)
 implement circuit builder that converts circuit language to FET_sim representation in order to simulate
+Group nodes and mosfets in a "graph" structure
 add even more simulation commands(eg. delete node/fet)
 test the project
 improve simulator io (maybe add graphics?)
diff --git a/grammar b/grammar
new file mode 100644 (file)
index 0000000..f6da7d5
--- /dev/null
+++ b/grammar
@@ -0,0 +1,43 @@
+PartSpecList -> PartSpecification
+PartSpecList -> PartSpecList PartSpecification
+PartSpecification -> DefinedPartName IO UsedParts Connections
+DefinedPartName -> PartName SEMICOLON
+IO -> IO_HEAD IOList SEMICOLON
+UsedParts -> USED_PARTS_HEAD UsedPartsList SEMICOLON
+Connections -> CONNECTIONS_HEAD ConnectionList SEMICOLON
+IOList -> IOSpec
+IOList -> IOList COMMA IOSpec
+UsedPartsList -> PartReference
+UsedPartsList -> UsedPartsList COMMA PartReference
+ConnectionList -> Connection
+ConnectionList -> ConnectionList COMMA Connection
+IOSpec -> PinName
+IOSpec -> BusName LEFT_BRACKET Size RIGHT_BRACKET
+PartReference -> SpecificName HYPHEN PartName
+Connection -> BusSpec EQUAL BusSpec
+Connection -> PinSpec HYPHEN PinSpec
+Connection -> BusSpec NARROWS PinSpec
+Connection -> PinSpec WIDENS BusSpec
+Connection -> STATE HYPHEN PinSpec
+Connection -> PinSpec HYPHEN STATE
+Connection -> STATE EQUAL BusSpec
+Connection -> STATE WIDENS BusSpec
+Connection -> BusSpec EQUAL STATE
+Connection -> BusSpec NARROWS STATE
+PinName -> Name
+BusName -> Name
+Size -> NUMBER
+SpecificName -> Name
+PartName -> Name
+BusSpec -> PartBusSpec
+BusSpec -> PartName DOT PartBusSpec
+PartBusSpec -> BusName
+PartBusSpec -> BusName SubBusAccess
+PinSpec -> PartPinSpec
+PinSpec -> PartName DOT PartPinSpec
+PartPinSpec -> PinName
+PartPinSpec -> BusName PinBusAccess
+Name -> STRING
+SubBusAccess -> LEFT_BRACKET Index SEMICOLON Index RIGHT_BRACKET
+PinBusAccess -> LEFT_BRACKET Index RIGHT_BRACKET
+Index -> NUMBER
index 12eb9829d4d303b675d0c9855eb4956bc05760a7..973582dd6a74c3ca76139ac63c0c315f1c2b71a4 100644 (file)
@@ -17,6 +17,7 @@ typedef enum e_state
        floating,
        zkrat,
        unknown,
+       state_count
 }      t_state;
 
 typedef enum e_terminal
@@ -100,6 +101,7 @@ typedef enum e_command
        bind,
        help,
        connect,
+       load,
        refresh_schema,
        switch_to_schema,
        exitsim,
@@ -112,10 +114,12 @@ typedef enum e_arg_type
        state,
        type,
        command,
+       file_descriptor,
 }      t_arg_type;
 
 typedef union u_arg_val
 {
+       int                     fd;
        size_t          num;
        t_terminal      terminal;
        t_state         state;
@@ -189,9 +193,13 @@ int                        c_addnode(WINDOW *command_win, t_input input, t_vec *nodes);
 int                    c_bind(WINDOW *command_win, t_input input, t_vec *nodes, t_vec *mosfets);
 int                    c_connect(WINDOW *command_win, t_input input, t_vec *nodes, t_vec *mosfets);
 int                    c_draw(WINDOW *command_win, t_input input, t_vec *nodes, t_vec *mosfets);
+int                    c_load(WINDOW *command_win, t_input input, t_vec *nodes, t_vec *mosfets);
 int                    c_help(WINDOW *command_win, t_input input);
 int                    c_next(t_input input, t_vec *nodes, t_vec *mosfets);
 int                    c_setnode(WINDOW *command_win, t_input input, t_vec *nodes);
 int                    refresh_schema_win(WINDOW *schematics_win, t_vec *nodes, t_vec *mosfets);
 int                    schema_mode(WINDOW *schematics_win, t_vec *nodes, t_vec *mosfets);
+
+int    str_is_num(const char *str);
+
 #endif //FET_SIM_H
diff --git a/parsing_table b/parsing_table
new file mode 100644 (file)
index 0000000..b5b806c
--- /dev/null
@@ -0,0 +1,114 @@
+State;STRING;DOT;NUMBER;STATE;WIDENS;NARROWS;EQUAL;HYPHEN;RIGHT_BRACKET;LEFT_BRACKET;COMMA;CONNECTIONS_HEAD;USED_PARTS_HEAD;IO_HEAD;SEMICOLON;$;PartSpecList;PartSpecification;DefinedPartName;IO;UsedParts;Connections;PartName;IOList;UsedPartsList;ConnectionList;IOSpec;PartReference;Connection;PinName;BusName;Size;SpecificName;BusSpec;PinSpec;Name;PartBusSpec;SubBusAccess;PartPinSpec;PinBusAccess;Index
+0;s1;;;;;;;;;;;;;;;;2;112;4;;;;109;;;;;;;;;;;;;111;;;;;
+1;;;;;;;;;;;;;;;r39;;;;;;;;;;;;;;;;;;;;;;;;;;
+2;s1;;;;;;;;;;;;;;;acc;;3;4;;;;109;;;;;;;;;;;;;111;;;;;
+3;r1;;;;;;;;;;;;;;;r1;;;;;;;;;;;;;;;;;;;;;;;;;
+4;;;;;;;;;;;;;;s5;;;;;;19;;;;;;;;;;;;;;;;;;;;;
+5;s6;;;;;;;;;;;;;;;;;;;;;;;7;;;18;;;10;11;;;;;16;;;;;
+6;;;;;;;;;;r39;r39;;;;r39;;;;;;;;;;;;;;;;;;;;;;;;;;
+7;;;;;;;;;;;s8;;;;s17;;;;;;;;;;;;;;;;;;;;;;;;;;
+8;s6;;;;;;;;;;;;;;;;;;;;;;;;;;9;;;10;11;;;;;16;;;;;
+9;;;;;;;;;;;r8;;;;r8;;;;;;;;;;;;;;;;;;;;;;;;;;
+10;;;;;;;;;;;r13;;;;r13;;;;;;;;;;;;;;;;;;;;;;;;;;
+11;;;;;;;;;;s12;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+12;;;s13;;;;;;;;;;;;;;;;;;;;;;;;;;;;;14;;;;;;;;;
+13;;;;;;;;;r28;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+14;;;;;;;;;s15;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+15;;;;;;;;;;;r14;;;;r14;;;;;;;;;;;;;;;;;;;;;;;;;;
+16;;;;;;;;;;r27;r26;;;;r26;;;;;;;;;;;;;;;;;;;;;;;;;;
+17;;;;;;;;;;;;;r4;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+18;;;;;;;;;;;r7;;;;r7;;;;;;;;;;;;;;;;;;;;;;;;;;
+19;;;;;;;;;;;;;s20;;;;;;;;33;;;;;;;;;;;;;;;;;;;;
+20;s21;;;;;;;;;;;;;;;;;;;;;;;;22;;;32;;;;;25;;;30;;;;;
+21;;;;;;;;r39;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+22;;;;;;;;;;;s23;;;;s31;;;;;;;;;;;;;;;;;;;;;;;;;;
+23;s21;;;;;;;;;;;;;;;;;;;;;;;;;;;24;;;;;25;;;30;;;;;
+24;;;;;;;;;;;r10;;;;r10;;;;;;;;;;;;;;;;;;;;;;;;;;
+25;;;;;;;;s26;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+26;s27;;;;;;;;;;;;;;;;;;;;;;28;;;;;;;;;;;;;29;;;;;
+27;;;;;;;;;;;r39;;;;r39;;;;;;;;;;;;;;;;;;;;;;;;;;
+28;;;;;;;;;;;r15;;;;r15;;;;;;;;;;;;;;;;;;;;;;;;;;
+29;;;;;;;;;;;r30;;;;r30;;;;;;;;;;;;;;;;;;;;;;;;;;
+30;;;;;;;;r29;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+31;;;;;;;;;;;;r5;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+32;;;;;;;;;;;r9;;;;r9;;;;;;;;;;;;;;;;;;;;;;;;;;
+33;;;;;;;;;;;;s34;;;;;;;;;;108;;;;;;;;;;;;;;;;;;;
+34;s35;;;s36;;;;;;;;;;;;;;;;;;;70;;;87;;;107;73;74;;;90;97;103;104;;105;;
+35;;r39;;;r39;r39;r39;r39;;r39;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+36;;;;;s37;;s55;s57;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+37;s38;;;;;;;;;;;;;;;;;;;;;;39;;;;;;;;41;;;52;;53;54;;;;
+38;;r39;;;;;;;;r39;r39;;;;r39;;;;;;;;;;;;;;;;;;;;;;;;;;
+39;;s40;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+40;s6;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;41;;;;;50;51;;;;
+41;;;;;;;;;;s42;r33;;;;r33;;;;;;;;;;;;;;;;;;;;;;;49;;;
+42;;;s43;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;44
+43;;;;;;;;;;;;;;;r42;;;;;;;;;;;;;;;;;;;;;;;;;;
+44;;;;;;;;;;;;;;;s45;;;;;;;;;;;;;;;;;;;;;;;;;;
+45;;;s46;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;47
+46;;;;;;;;;r42;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+47;;;;;;;;;s48;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+48;;;;;;;;;;;r40;;;;r40;;;;;;;;;;;;;;;;;;;;;;;;;;
+49;;;;;;;;;;;r34;;;;r34;;;;;;;;;;;;;;;;;;;;;;;;;;
+50;;;;;;;;;;r27;r27;;;;r27;;;;;;;;;;;;;;;;;;;;;;;;;;
+51;;;;;;;;;;;r32;;;;r32;;;;;;;;;;;;;;;;;;;;;;;;;;
+52;;;;;;;;;;;r23;;;;r23;;;;;;;;;;;;;;;;;;;;;;;;;;
+53;;r30;;;;;;;;r27;r27;;;;r27;;;;;;;;;;;;;;;;;;;;;;;;;;
+54;;;;;;;;;;;r31;;;;r31;;;;;;;;;;;;;;;;;;;;;;;;;;
+55;s38;;;;;;;;;;;;;;;;;;;;;;39;;;;;;;;41;;;56;;53;54;;;;
+56;;;;;;;;;;;r22;;;;r22;;;;;;;;;;;;;;;;;;;;;;;;;;
+57;s38;;;;;;;;;;;;;;;;;;;;;;58;;;;;;;60;61;;;;67;68;;;69;;
+58;;s59;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+59;s6;;;;;;;;;;;;;;;;;;;;;;;;;;;;;60;61;;;;;16;;;66;;
+60;;;;;;;;;;;r37;;;;r37;;;;;;;;;;;;;;;;;;;;;;;;;;
+61;;;;;;;;;;s62;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;65;
+62;;;s46;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;63
+63;;;;;;;;;s64;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+64;;;;;;;;;;;r41;;;;r41;;;;;;;;;;;;;;;;;;;;;;;;;;
+65;;;;;;;;;;;r38;;;;r38;;;;;;;;;;;;;;;;;;;;;;;;;;
+66;;;;;;;;;;;r36;;;;r36;;;;;;;;;;;;;;;;;;;;;;;;;;
+67;;;;;;;;;;;r20;;;;r20;;;;;;;;;;;;;;;;;;;;;;;;;;
+68;;r30;;;;;;;;r27;r26;;;;r26;;;;;;;;;;;;;;;;;;;;;;;;;;
+69;;;;;;;;;;;r35;;;;r35;;;;;;;;;;;;;;;;;;;;;;;;;;
+70;;s71;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+71;s72;;;;;;;;;;;;;;;;;;;;;;;;;;;;;73;74;;;;;84;85;;86;;
+72;;;;;r39;r39;r39;r39;;r39;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+73;;;;;r37;;;r37;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+74;;;;;;r33;r33;;;s75;;;;;;;;;;;;;;;;;;;;;;;;;;;;82;;83;
+75;;;s76;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;77
+76;;;;;;;;;r42;;;;;;r42;;;;;;;;;;;;;;;;;;;;;;;;;;
+77;;;;;;;;;s78;;;;;;s79;;;;;;;;;;;;;;;;;;;;;;;;;;
+78;;;;;r41;;;r41;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+79;;;s46;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;80
+80;;;;;;;;;s81;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+81;;;;;;r40;r40;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+82;;;;;;r34;r34;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+83;;;;;r38;;;r38;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+84;;;;;r26;r27;r27;r26;;r27;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+85;;;;;;r32;r32;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+86;;;;;r36;;;r36;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+87;;;;;;;;;;;s88;;;;s106;;;;;;;;;;;;;;;;;;;;;;;;;;
+88;s35;;;s36;;;;;;;;;;;;;;;;;;;70;;;;;;89;73;74;;;90;97;103;104;;105;;
+89;;;;;;;;;;;r12;;;;r12;;;;;;;;;;;;;;;;;;;;;;;;;;
+90;;;;;;s91;s94;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+91;s38;;;s92;;;;;;;;;;;;;;;;;;;58;;;;;;;60;61;;;;93;68;;;69;;
+92;;;;;;;;;;;r25;;;;r25;;;;;;;;;;;;;;;;;;;;;;;;;;
+93;;;;;;;;;;;r18;;;;r18;;;;;;;;;;;;;;;;;;;;;;;;;;
+94;s38;;;s95;;;;;;;;;;;;;;;;;;;39;;;;;;;;41;;;96;;53;54;;;;
+95;;;;;;;;;;;r24;;;;r24;;;;;;;;;;;;;;;;;;;;;;;;;;
+96;;;;;;;;;;;r16;;;;r16;;;;;;;;;;;;;;;;;;;;;;;;;;
+97;;;;;s98;;;s100;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+98;s38;;;;;;;;;;;;;;;;;;;;;;39;;;;;;;;41;;;99;;53;54;;;;
+99;;;;;;;;;;;r19;;;;r19;;;;;;;;;;;;;;;;;;;;;;;;;;
+100;s38;;;s101;;;;;;;;;;;;;;;;;;;58;;;;;;;60;61;;;;102;68;;;69;;
+101;;;;;;;;;;;r21;;;;r21;;;;;;;;;;;;;;;;;;;;;;;;;;
+102;;;;;;;;;;;r17;;;;r17;;;;;;;;;;;;;;;;;;;;;;;;;;
+103;;r30;;;r26;r27;r27;r26;;r27;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+104;;;;;;r31;r31;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+105;;;;;r35;;;r35;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+106;r6;;;;;;;;;;;;;;;r6;;;;;;;;;;;;;;;;;;;;;;;;;
+107;;;;;;;;;;;r11;;;;r11;;;;;;;;;;;;;;;;;;;;;;;;;;
+108;r2;;;;;;;;;;;;;;;r2;;;;;;;;;;;;;;;;;;;;;;;;;
+109;;;;;;;;;;;;;;;s110;;;;;;;;;;;;;;;;;;;;;;;;;;
+110;;;;;;;;;;;;;;r3;;;;;;;;;;;;;;;;;;;;;;;;;;;
+111;;;;;;;;;;;;;;;r30;;;;;;;;;;;;;;;;;;;;;;;;;;
+112;r0;;;;;;;;;;;;;;;r0;;;;;;;;;;;;;;;;;;;;;;;;;
diff --git a/src/c_load.c b/src/c_load.c
new file mode 100644 (file)
index 0000000..e3c2e26
--- /dev/null
@@ -0,0 +1,427 @@
+#include "FET_sim.h"
+#include "libft.h"
+#include <stdlib.h>
+#include <unistd.h>
+
+typedef enum e_token_type
+{
+       dot,
+       comma,
+       semicolon,
+       left_bracket,
+       right_bracket,
+       equal_sign,
+       hyphen,
+       narrow_sign,
+       widen_sign,
+       io_head,
+       part_head,
+       connections_head,
+       delimiter_count,
+       number = delimiter_count,
+       node_state,
+       string,
+       types_count
+} t_token_type;
+
+static const t_token g_defined_tokens[] = {
+       {.type = "DOT", .str = "."},
+       {.type = "COMMA", .str = ","},
+       {.type = "SEMICOLON", .str = ";"},
+       {.type = "LEFT_BRACKET", .str = "["},
+       {.type = "RIGHT_BRACKET", .str = "]"},
+       {.type = "EQUAL", .str = "="},
+       {.type = "HYPHEN", .str = "-"},
+       {.type = "NARROWS", .str = ">"},
+       {.type = "WIDENS", .str = "<"},
+       {.type = "IO_HEAD", .str = "Connectors:"},
+       {.type = "USED_PARTS_HEAD", .str = "Parts:"},
+       {.type = "CONNECTIONS_HEAD", .str = "Connections:"},
+       {.type = "NUMBER", .str = NULL},
+       {.type = "STATE", .str = NULL},
+       {.type = "STRING", .str = NULL},
+};
+
+static const t_token   empty_token = {.type = NULL, .str = NULL};
+
+static const char *const g_node_state_strings[] = {
+       "off",
+       "on",
+       "pull_down",
+       "pull_up",
+       "floating",
+       "zkrat",
+       "unknown",
+};
+
+// This would also work but I think it's less readable
+// if (!ft_isspace(str[i++]))
+//     str[j++] = str[i - 1];
+void   remove_whitespace(char *str)
+{
+       size_t  i;
+       size_t  j;
+
+       i = 0;
+       j = 0;
+       while (str[i])
+       {
+               if (ft_isspace(str[i]))
+                       ++i;
+               else
+                       str[j++] = str[i++];
+       }
+       str[j] = str[i];
+       return ;
+}
+
+t_token token_dup(t_token token)
+{
+       t_token duplicate;
+
+       duplicate.type = ft_strdup(token.type);
+       if (!duplicate.type)
+               return (empty_token);
+       if (token.str)
+       {
+               duplicate.str = ft_strdup(token.str);
+               if (!duplicate.str)
+               {
+                       free(duplicate.type);
+                       return (empty_token);
+               }
+       }
+       else
+               duplicate.str = NULL;
+       return (duplicate);
+}
+
+t_token        find_delimiter(const char *str, size_t *i)
+{
+       t_token_type    type;
+
+       while (str[*i])
+       {
+               type = 0;
+               while (type < delimiter_count)
+               {
+                       if (!ft_strncmp(g_defined_tokens[type].str, str + *i, ft_strlen(g_defined_tokens[type].str)))
+                               return (token_dup(g_defined_tokens[type]));
+                       ++type;
+               }
+               ++*i;
+       }
+       return (empty_token);
+}
+
+char   *string_to_type(const char *str)
+{
+       t_state state;
+
+       if (!str)
+               return (NULL);
+       if (str_is_num(str))
+               return (ft_strdup(g_defined_tokens[number].type));
+       state = 0;
+       while (state < state_count)
+       {
+               if (!ft_strcmp(str, g_node_state_strings[state]))
+                       return (ft_strdup(g_defined_tokens[state].type));
+               ++state;
+       }
+       return (ft_strdup(g_defined_tokens[string].type));
+}
+
+t_token identify_token(char *str)
+{
+       t_token token;
+
+       token.type = string_to_type(str);
+       token.str = str;
+       return (token);
+}
+
+void   free_token(t_token *token)
+{
+       if (!token)
+               return ;
+       free(token->str);
+       free(token->type);
+       return ;
+}
+
+void   free_token_void(void *token)
+{
+       free_token(token);
+       return ;
+}
+
+int    tokenize(t_vec *tokens, int fd)
+{
+       char                    *line;
+       char                    *tmp;
+       t_token                 delimiter_token;
+       t_token                 info_token;
+       size_t                  i;
+       size_t                  j;
+
+       ft_vec_init(tokens, sizeof(t_token));
+       line = get_next_line(fd);
+       while (line)
+       {
+               remove_whitespace(line);
+               i = 0;
+               while (1)
+               {
+                       j = i;
+                       delimiter_token = find_delimiter(line, &i);
+                       if (!delimiter_token.type)
+                               break;
+                       info_token = identify_token(ft_strndup(line + j, i - j));
+                       if (info_token.type && info_token.str)
+                       {
+                               if (info_token.str[0] != '\0')
+                               {
+                                       if (ft_vec_append(tokens, &info_token) != success)
+                                       {
+                                               free(line);
+                                               ft_vec_free(tokens, free_token_void);
+                                               return (1);
+                                       }
+                               }
+                               else
+                                       free_token(&info_token);
+                       }
+                       else
+                       {
+                               free(line);
+                               ft_vec_free(tokens, free_token_void);
+                               return (1);
+                       }
+                       if (ft_vec_append(tokens, &delimiter_token))
+                       {
+                               free(line);
+                               ft_vec_free(tokens, free_token_void);
+                               return (1);
+                       }
+                       i += ft_strlen(delimiter_token.str);
+               }
+               tmp = line;
+               line = ft_strdup(line + j);
+               free(tmp);
+               tmp = get_next_line(fd);
+               if (!tmp)
+                       break;
+               ft_strcat_alloc(&line, tmp);
+               free(tmp);
+       }
+       return (0);
+}
+
+typedef struct s_part
+{
+       char    *name;
+       t_vec   nodes;
+       t_vec   mosfets;
+       t_dict  used_parts;
+       t_dict  io_to_node;
+}      t_part;
+
+int    cmp_parts_void(const void *a_v, const void *b_v)
+{
+       const t_part    *a;
+       const t_part    *b;
+
+       a = a_v;
+       b = b_v;
+       return (ft_strcmp(a->name, b->name));
+}
+
+union u_part_spec
+{
+       char                    *name;
+       const t_part    *part;
+};
+
+typedef struct s_part_spec
+{
+       int                                     is_string_tag;
+       union u_part_spec       spec;
+}                                              t_part_spec;
+
+const char     *get_name_from_spec(t_part_spec spec)
+{
+       if (spec.is_string_tag)
+               return (spec.spec.name);
+       return (spec.spec.part->name);
+}
+
+const t_part   *get_part_from_spec(t_part_spec spec)
+{
+       if (spec.is_string_tag)
+               return (NULL);
+       return (spec.spec.part);
+}
+
+int    cmp_strings_void(const void *a_v, const void *b_v)
+{
+       char *const     *a;
+       char *const *b;
+
+       a = a_v;
+       b = b_v;
+       return (ft_strcmp(*a, *b));
+}
+
+int    init_new_part(t_part *part)
+{
+       t_ft_stat       res;
+
+       part->name = NULL;
+       res = ft_vec_init(&part->nodes, sizeof(t_node));
+       res = res || ft_vec_init(&part->mosfets, sizeof(t_mosfet));
+       res = res || ft_dict_init(&part->io_to_node, sizeof(char *), sizeof(t_node *), cmp_strings_void);
+       res = res || ft_dict_init(&part->used_parts, sizeof(char *), sizeof(t_part_spec), cmp_strings_void);
+       return (res != success);
+}
+
+void   free_string_void(void *string_v)
+{
+       char    **string;
+
+       string = string_v;
+       free(*string);
+       return ;
+}
+
+void   free_part(t_part *part)
+{
+       if (!part)
+               return ;
+       free(part->name);
+       ft_vec_free(&part->nodes, free_node);
+       ft_vec_free(&part->mosfets, NULL);
+       ft_dict_free(&part->used_parts, free_string_void, NULL);
+       ft_dict_free(&part->io_to_node, free_string_void, NULL);
+       return ;
+}
+
+void   free_part_void(void *part)
+{
+       free_part(part);
+       return ;
+}
+
+int    write_used_part(t_part *part, const t_parse_tree_node *part_reference)
+{
+       char            *specific_name;
+       t_part_spec     part_spec;
+
+       specific_name = ft_strdup(ft_cget_child_deep(part_reference, 3, 0, 0, 0)->token.str);
+       part_spec.is_string_tag = 1;
+       part_spec.spec.name = ft_strdup(ft_cget_child_deep(part_reference, 3, 2, 0, 0)->token.str);
+       if (specific_name && part_spec.spec.name
+               && ft_dict_insert(&part->used_parts, &specific_name, &part_spec) == success)
+               return (0);
+       free(specific_name);
+       free(part_spec.spec.name);
+       return (1);
+}
+
+int    extract_used_names(t_rbtree *part_catalog, t_parse_tree_node *part_spec_list)
+{
+       int                                             res;
+       t_part                                  new_part;
+       const t_parse_tree_node *part_specification;
+       const t_parse_tree_node *used_parts;
+
+       if (init_new_part(&new_part))
+               return (1);
+       part_specification = ft_cget_node_child(part_spec_list, part_spec_list->children.size - 1);
+       new_part.name = ft_strdup(ft_cget_child_deep(part_specification, 4, 0, 0, 0, 0)->token.str);
+       if (!new_part.name)
+               return (1);
+       used_parts = ft_cget_child_deep(part_specification, 2, 2, 1);
+       while (used_parts->children.size == 3)
+       {
+               res = write_used_part(&new_part, ft_cget_node_child(used_parts, 2));
+               if (res != success)
+                       break ;
+               used_parts = ft_cget_node_child(used_parts, 0);
+       }
+       res = res || write_used_part(&new_part, ft_cget_node_child(used_parts, 0));
+       res = res || ft_rbtree_insert(part_catalog, &new_part) != success;
+       if (res)
+       {
+               free_part(&new_part);
+               return (1);
+       }
+       if (part_spec_list->children.size == 2)
+               return (extract_used_names(part_catalog, ft_get_node_child(part_spec_list, 0)));
+       return (0);
+}
+
+int    construct_new_graph(t_parse_tree_node *parse_tree, __attribute__((unused)) t_vec *nodes, __attribute__((unused)) t_vec *mosfets)
+{
+       t_rbtree        part_catalog;
+
+       ft_rbtree_init(&part_catalog, sizeof(t_part), cmp_parts_void);
+       extract_used_names(&part_catalog, parse_tree);
+       //fill_used_parts(&part_catalog);
+       //build_graphs(&part_catalog, parse_tree);
+       //transfer_main(&part_catalog, nodes, mosfets);
+       ft_rbtree_free(&part_catalog, free_part_void);
+       return (0);
+}
+
+int    rewrite_graph(t_parse_tree_node *parse_tree, t_vec *nodes, t_vec *mosfets)
+{
+       t_vec   new_nodes;
+       t_vec   new_mosfets;
+
+       ft_vec_init(&new_nodes, sizeof(t_node));
+       ft_vec_init(&new_mosfets, sizeof(t_mosfet));
+       if (construct_new_graph(parse_tree, &new_nodes, &new_mosfets))
+               return (1);
+       ft_vec_free(nodes, free_node);
+       ft_vec_free(mosfets, NULL);
+       *nodes = new_nodes;
+       *mosfets = new_mosfets;
+       return (0);
+}
+
+int    c_load(WINDOW *command_win, t_input input, t_vec *nodes, t_vec *mosfets)
+{
+       t_vec                           tokens;
+       t_parsing_table         parsing_table;
+       t_parse_tree_node       *parse_tree;
+       
+       if (tokenize(&tokens, input.argv[0].val.fd))
+       {
+               wprintw(command_win, "Could not tokenize file\n");
+               close(input.argv[0].val.fd);
+               return (1);
+       }
+       close(input.argv[0].val.fd);
+       ft_parsing_table_init(&parsing_table);
+       if (ft_parsing_table_load_name(&parsing_table, "parsing_table", "grammar") != success)
+       {
+               wprintw(command_win, "CRITICAL ERROR: Could not load parsing info\n");
+               return (0);
+       }
+       parse_tree = ft_parse(&tokens, &parsing_table);
+       ft_parsing_table_free(&parsing_table);
+       ft_vec_free(&tokens, NULL);
+       if (parse_tree == NULL)
+       {
+               wprintw(command_win, "Could not parse file\n");
+               return (1);
+       }
+       if (rewrite_graph(parse_tree, nodes, mosfets))
+       {
+               wprintw(command_win, "Could not execute file\n");
+               return (1);
+       }
+       //rebuild_schema(nodes, mosfets);
+       return (1);
+}
index 384797d71614e0215da9ec42b44b1239cd2e27fb..fa2949aa7e9e49d918b39f4cd2421f743d59419d 100644 (file)
@@ -61,6 +61,8 @@ int   parse_command(const char *str, t_command *cmd)
                *cmd = help;
        else if (!ft_strcmp(str, "c") || !ft_strcmp(str, "con") || !ft_strcmp(str, "connect"))
                *cmd = connect;
+       else if (!ft_strcmp(str, "l") || !ft_strcmp(str, "load"))
+               *cmd = load;
        else if (!ft_strcmp(str, "e") || !ft_strcmp(str, "exit"))
                *cmd = exitsim;
        else if (!ft_strcmp(str, "schema"))
@@ -124,6 +126,8 @@ int has_correct_argc(t_input input)
        argc = input.argc;
        if ((c == next || c == draw || c == help) && argc > 1)
                return (0);
+       if (c == load && argc != 1)
+               return (0);
        if (c == setnode && argc != 2)
                return (0);
        if (c == bind && argc != 3)
@@ -139,7 +143,7 @@ int has_correct_argc(t_input input)
        return (1);
 }
 
-static int     str_is_num(const char *str)
+int    str_is_num(const char *str)
 {
        size_t  i;
 
@@ -193,6 +197,12 @@ int        parse_arg(t_input *input, const char *str, size_t i)
                        res = parse_terminal(str, &input->argv[i].val.terminal);
                        input->argv[i].type = terminal;
                }
+               else if (c == load)
+               {
+                       input->argv[i].type = file_descriptor;
+                       input->argv[i].val.fd = open(str, O_RDONLY);
+                       res = (input->argv[i].val.fd >= 0);
+               }
        }
        return (res);
 }
@@ -249,6 +259,11 @@ int        process_input(t_windows *windows, t_vec *nodes, t_vec *mosfets)
                res = c_bind(windows->command_win, input, nodes, mosfets);
        else if (input.command == connect)
                res = c_connect(windows->command_win, input, nodes, mosfets);
+       else if (input.command == load)
+       {
+               res = c_load(windows->command_win, input, nodes, mosfets);
+               refresh_schema_win(windows->schematics_win, nodes, mosfets);
+       }
        else if (input.command == help)
                res = c_help(windows->command_win, input);
        else if(input.command == refresh_schema)