From: Lukáš Jiřiště Date: Thu, 14 Aug 2025 07:11:07 +0000 (+0200) Subject: Add a third of the load command X-Git-Url: https://git.ljiriste.work/?a=commitdiff_plain;h=b38a5516874e2d02943f90ad1a12530e0761dc88;p=FET_sim.git Add a third of the load command 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. --- diff --git a/Makefile b/Makefile index 9915d68..d6dd711 100644 --- 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 5dae8bf..67bf114 100644 --- 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 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 diff --git a/inc/FET_sim.h b/inc/FET_sim.h index 12eb982..973582d 100644 --- a/inc/FET_sim.h +++ b/inc/FET_sim.h @@ -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 index 0000000..b5b806c --- /dev/null +++ b/parsing_table @@ -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 index 0000000..e3c2e26 --- /dev/null +++ b/src/c_load.c @@ -0,0 +1,427 @@ +#include "FET_sim.h" +#include "libft.h" +#include +#include + +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); +} diff --git a/src/main.c b/src/main.c index 384797d..fa2949a 100644 --- a/src/main.c +++ b/src/main.c @@ -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)