{.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},
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)
{
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)
{
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));
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)
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);
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);
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;
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);