From 00914102e7fd82c7fd2730954c5403303cbff91b Mon Sep 17 00:00:00 2001 From: =?utf8?q?Luk=C3=A1=C5=A1=20Ji=C5=99i=C5=A1t=C4=9B?= Date: Sun, 17 Aug 2025 14:03:28 +0200 Subject: [PATCH] Implement IO nodes Now the IO nodes get transformed from the parse tree into members of their part. --- Libft | 2 +- grammar | 2 +- parsing_table | 8 +-- src/c_load.c | 151 ++++++++++++++++++++++++++++++++++++++++++-------- 4 files changed, 135 insertions(+), 28 deletions(-) diff --git a/Libft b/Libft index addf28c..afad394 160000 --- a/Libft +++ b/Libft @@ -1 +1 @@ -Subproject commit addf28c14063c052d44dce1b6bd0ddc532497163 +Subproject commit afad394321e07d175dfb1bd25e339a462cae69bf diff --git a/grammar b/grammar index f6da7d5..e1c9771 100644 --- a/grammar +++ b/grammar @@ -38,6 +38,6 @@ PinSpec -> PartName DOT PartPinSpec PartPinSpec -> PinName PartPinSpec -> BusName PinBusAccess Name -> STRING -SubBusAccess -> LEFT_BRACKET Index SEMICOLON Index RIGHT_BRACKET +SubBusAccess -> LEFT_BRACKET Index COMMA Index RIGHT_BRACKET PinBusAccess -> LEFT_BRACKET Index RIGHT_BRACKET Index -> NUMBER diff --git a/parsing_table b/parsing_table index b5b806c..726b2d4 100644 --- a/parsing_table +++ b/parsing_table @@ -42,8 +42,8 @@ State;STRING;DOT;NUMBER;STATE;WIDENS;NARROWS;EQUAL;HYPHEN;RIGHT_BRACKET;LEFT_BRA 40;s6;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;41;;;;;50;51;;;; 41;;;;;;;;;;s42;r33;;;;r33;;;;;;;;;;;;;;;;;;;;;;;49;;; 42;;;s43;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;44 -43;;;;;;;;;;;;;;;r42;;;;;;;;;;;;;;;;;;;;;;;;;; -44;;;;;;;;;;;;;;;s45;;;;;;;;;;;;;;;;;;;;;;;;;; +43;;;;;;;;;;;r42;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +44;;;;;;;;;;;s45;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 45;;;s46;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;47 46;;;;;;;;;r42;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 47;;;;;;;;;s48;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; @@ -75,8 +75,8 @@ State;STRING;DOT;NUMBER;STATE;WIDENS;NARROWS;EQUAL;HYPHEN;RIGHT_BRACKET;LEFT_BRA 73;;;;;r37;;;r37;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 74;;;;;;r33;r33;;;s75;;;;;;;;;;;;;;;;;;;;;;;;;;;;82;;83; 75;;;s76;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;77 -76;;;;;;;;;r42;;;;;;r42;;;;;;;;;;;;;;;;;;;;;;;;;; -77;;;;;;;;;s78;;;;;;s79;;;;;;;;;;;;;;;;;;;;;;;;;; +76;;;;;;;;;r42;;r42;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +77;;;;;;;;;s78;;s79;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 78;;;;;r41;;;r41;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 79;;;s46;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;80 80;;;;;;;;;s81;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; diff --git a/src/c_load.c b/src/c_load.c index 3d19937..d120967 100644 --- a/src/c_load.c +++ b/src/c_load.c @@ -34,9 +34,9 @@ static const t_token g_defined_tokens[] = { {.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 = "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}, @@ -220,12 +220,14 @@ int tokenize(t_vec *tokens, int fd) typedef struct s_part { - char *name; - t_vec nodes; - t_vec mosfets; - t_dict used_parts; - t_dict io_to_node; -} t_part; + int is_graph_built; + char *name; + const t_parse_tree_node *parsed_node; + 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) { @@ -336,13 +338,10 @@ t_ft_stat insert_into_catalog(t_catalog *part_catalog, t_part *part) return (ft_rbtree_insert(part_catalog, part) != success); } -// This works because part name is the first member of a part and there can -// be no padding before the first member of a struct -// -// Thinking about it this is an easy way to use rbtrees as dicts... t_part *access_catalog(t_catalog *part_catalog, const char *part_name) { - return (ft_rbtree_search(part_catalog, &part_name)); + const t_part part = {.name = (char *)part_name}; + return (ft_rbtree_search(part_catalog, (t_part *)&part)); } void free_catalog(t_catalog *part_catalog) @@ -356,16 +355,16 @@ int extract_used_names(t_catalog *part_catalog, t_parse_tree_node *part_spec_lis { 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); + new_part.parsed_node = ft_cget_node_child(part_spec_list, part_spec_list->children.size - 1); + new_part.name = ft_strdup(ft_cget_child_deep(new_part.parsed_node, 4, 0, 0, 0, 0)->token.str); + new_part.is_graph_built = 0; if (!new_part.name) return (1); - used_parts = ft_cget_child_deep(part_specification, 2, 2, 1); + used_parts = ft_cget_child_deep(new_part.parsed_node, 2, 2, 1); while (used_parts->children.size == 3) { res = write_used_part(&new_part, ft_cget_node_child(used_parts, 2)); @@ -415,7 +414,7 @@ static const char g_p_name[] = "p"; static const char g_n_name[] = "n"; // IO needs to hold node id instead of pointer -#define G_SIZE_OF_IO_NODE (sizeof(t_rbtree_node) + sizeof(char *) + sizeof(t_node *)) +#define G_SIZE_OF_IO_NODE (sizeof(t_rbtree_node) + sizeof(char *) + sizeof(t_id)) #define G_COMPLETE_SIZE_OF_FET_PART (sizeof(t_part) + 3 * (sizeof(t_node)) + sizeof(t_id) + sizeof(t_mosfet) + 3 * G_SIZE_OF_IO_NODE) void init_fet_nodes(t_part *fet, t_node *nodes, t_id *mosfet) @@ -463,7 +462,7 @@ void init_fet_single_io(t_part *fet, t_rbtree_node *io_node, t_node *node, t_ter io_node->is_black = 1; io_node->left = NULL; io_node->right = NULL; - ft_memcpy((char *)&io_node->data + sizeof(char *), &node, sizeof(t_node *)); + ft_memcpy((char *)&io_node->data + sizeof(char *), &node->id, sizeof(t_id)); if (terminal == source) { bind_fet_node(&fet->nodes, mosfet, node, source); @@ -499,7 +498,7 @@ void init_fet_io(t_part *fet, t_rbtree_node *io_node_source) const int gate_drain_cmp = cmp_strings_void(&g_gate_str, &g_drain_str); const int drain_source_cmp = cmp_strings_void(&g_drain_str, &g_source_str); - ft_dict_init(&fet->io_to_node, sizeof(char *), sizeof(t_node *), cmp_strings_void); + ft_dict_init(&fet->io_to_node, sizeof(char *), sizeof(t_id), cmp_strings_void); init_fet_single_io(fet, io_node_source, ft_vec_access(&fet->nodes, 0), source); init_fet_single_io(fet, io_node_gate, ft_vec_access(&fet->nodes, 1), gate); init_fet_single_io(fet, io_node_drain, ft_vec_access(&fet->nodes, 2), drain); @@ -592,6 +591,114 @@ int rebind_names_to_parts(t_catalog *parts_catalog) return (0); } +int add_pin(t_part *part, const char *name) +{ + t_node *node; + char *name_copy; + + node = add_node(&part->nodes, floating); + if (!node) + return (1); + name_copy = ft_strdup(name); + if (!name_copy) + return (1); + if (ft_dict_insert(&part->io_to_node, &name_copy, &node->id) != success) + { + free(name_copy); + return (1); + } + return (0); +} + +// For simplicity the index is written in reverse order +void fill_index(char *buffer, size_t index) +{ + while (index > 0) + { + *buffer = '0' + index % 10; + index /= 10; + ++buffer; + } + *buffer = '\0'; +} + +static const char g_bus_index_separator[] = "-"; + +int add_bus(t_part *part, const t_parse_tree_node *bus_spec) +{ + const char *const bus_name = ft_cget_child_deep(bus_spec, 3, 0, 0, 0)->token.str; + const char *const bus_size_str = ft_cget_child_deep(bus_spec, 2, 2, 0)->token.str; + size_t bus_size; + char *buffer; + size_t buffer_size; + size_t base_size; + + bus_size = (size_t)ft_atoi(bus_size_str); + buffer = ft_itoa((int)bus_size); + if (!buffer || ft_strcmp(buffer, bus_size_str)) + { + free(buffer); + return (1); + } + free(buffer); + base_size = ft_strlen(bus_name) + ft_strlen(g_bus_index_separator); + buffer_size = base_size + ft_strlen(bus_size_str) + 1; + buffer = malloc(buffer_size); + if (!buffer) + return (1); + while (bus_size > 0) + { + --bus_size; + ft_strlcpy(buffer, bus_name, buffer_size); + ft_strlcat(buffer, g_bus_index_separator, buffer_size); + fill_index(buffer + base_size, bus_size); + if (add_pin(part, buffer)) + { + free(buffer); + return (1); + } + } + return (0); +} + +int add_io(t_part *part, const t_parse_tree_node *io_spec) +{ + if (io_spec->children.size == 1) + return (add_pin(part, ft_cget_child_deep(io_spec, 3, 0, 0, 0)->token.str)); + return (add_bus(part, io_spec)); +} + +int prepare_io(t_part *part) +{ + const t_parse_tree_node *io_list; + + io_list = ft_cget_child_deep(part->parsed_node, 2, 1, 1); + while (io_list->children.size == 3) + { + if (add_io(part, ft_cget_node_child(io_list, 2))) + return (1); + io_list = ft_cget_node_child(io_list, 0); + } + return (add_io(part, ft_cget_node_child(io_list, 0))); +} + +int build_part_graph(t_part *part) +{ + if (prepare_io(part)) + return (1); + return (0); +} + +int build_main_graph(t_catalog *part_catalog) +{ + t_part *main_part; + + main_part = access_catalog(part_catalog, "main"); + if (!main_part) + return (1); + return (build_part_graph(main_part)); +} + int construct_new_graph(t_parse_tree_node *parse_tree, __attribute__((unused)) t_vec *nodes, __attribute__((unused)) t_vec *mosfets) { t_catalog part_catalog; @@ -599,7 +706,7 @@ int construct_new_graph(t_parse_tree_node *parse_tree, __attribute__((unused)) t init_catalog(&part_catalog); extract_used_names(&part_catalog, parse_tree); rebind_names_to_parts(&part_catalog); - //build_graphs(&part_catalog, parse_tree); + build_main_graph(&part_catalog); //transfer_main(&part_catalog, nodes, mosfets); free_catalog(&part_catalog); return (0); -- 2.30.2