4545// for module
4646STRING_CACHE* modules_inputs_sc;
4747STRING_CACHE* modules_outputs_sc;
48+ STRING_CACHE* modules_inouts_sc;
4849STRING_CACHE* module_instances_sc;
4950
5051// for function
5152STRING_CACHE* functions_inputs_sc;
5253STRING_CACHE* functions_outputs_sc;
54+ STRING_CACHE* functions_inouts_sc;
5355
5456STRING_CACHE* tasks_inputs_sc;
5557STRING_CACHE* tasks_outputs_sc;
58+ STRING_CACHE* tasks_inouts_sc;
5659
5760STRING_CACHE* module_names_to_idx;
5861STRING_CACHE* instantiated_modules;
@@ -124,10 +127,13 @@ ast_t* init_parser() {
124127 /* create string caches to hookup PORTS with INPUT and OUTPUTs. This is made per module and will be cleaned and remade at next_module */
125128 modules_inputs_sc = sc_new_string_cache ();
126129 modules_outputs_sc = sc_new_string_cache ();
130+ modules_inouts_sc = sc_new_string_cache ();
127131 functions_inputs_sc = sc_new_string_cache ();
128132 functions_outputs_sc = sc_new_string_cache ();
133+ functions_inouts_sc = sc_new_string_cache ();
129134 tasks_inputs_sc = sc_new_string_cache ();
130135 tasks_outputs_sc = sc_new_string_cache ();
136+ tasks_inouts_sc = sc_new_string_cache ();
131137 instantiated_modules = sc_new_string_cache ();
132138 module_instances_sc = sc_new_string_cache ();
133139 /* record of each of the individual modules */
@@ -158,10 +164,13 @@ ast_t* init_parser() {
158164void cleanup_parser () {
159165 modules_inputs_sc = sc_free_string_cache (modules_inputs_sc);
160166 modules_outputs_sc = sc_free_string_cache (modules_outputs_sc);
167+ modules_inouts_sc = sc_free_string_cache (modules_inouts_sc);
161168 functions_inputs_sc = sc_free_string_cache (functions_inputs_sc);
162169 functions_outputs_sc = sc_free_string_cache (functions_outputs_sc);
170+ functions_inouts_sc = sc_free_string_cache (functions_inouts_sc);
163171 tasks_inputs_sc = sc_free_string_cache (tasks_inputs_sc);
164172 tasks_outputs_sc = sc_free_string_cache (tasks_outputs_sc);
173+ tasks_inouts_sc = sc_free_string_cache (tasks_inouts_sc);
165174 instantiated_modules = sc_free_string_cache (instantiated_modules);
166175 module_instances_sc = sc_free_string_cache (module_instances_sc);
167176}
@@ -357,53 +366,58 @@ ast_node_t* resolve_ports(ids top_type, ast_node_t* symbol_list) {
357366 }
358367 } else {
359368 long sc_spot = -1 ;
360-
369+ STRING_CACHE* sc = NULL ;
370+
361371 if (top_type == MODULE) {
372+
362373 /* find the related INPUT or OUTPUT definition and store that instead */
363374 if ((sc_spot = sc_lookup_string (modules_inputs_sc, symbol_list->children [i]->children [0 ]->types .identifier )) != -1 ) {
364- oassert (((ast_node_t *)modules_inputs_sc->data [sc_spot])->type == VAR_DECLARE);
365- free_whole_tree (symbol_list->children [i]);
366- symbol_list->children [i] = (ast_node_t *)modules_inputs_sc->data [sc_spot];
367- oassert (symbol_list->children [i]->types .variable .is_input );
375+ sc = modules_inputs_sc;
376+ oassert (((ast_node_t *)sc->data [sc_spot])->types .variable .is_input );
368377 } else if ((sc_spot = sc_lookup_string (modules_outputs_sc, symbol_list->children [i]->children [0 ]->types .identifier )) != -1 ) {
369- oassert (((ast_node_t *)modules_outputs_sc->data [sc_spot])->type == VAR_DECLARE);
370- free_whole_tree (symbol_list->children [i]);
371- symbol_list->children [i] = (ast_node_t *)modules_outputs_sc->data [sc_spot];
372- oassert (symbol_list->children [i]->types .variable .is_output );
378+ sc = modules_outputs_sc;
379+ oassert (((ast_node_t *)sc->data [sc_spot])->types .variable .is_output );
380+ } else if ((sc_spot = sc_lookup_string (modules_inouts_sc, symbol_list->children [i]->children [0 ]->types .identifier )) != -1 ) {
381+ sc = modules_inouts_sc;
382+ oassert (((ast_node_t *)sc->data [sc_spot])->types .variable .is_inout );
373383 } else {
374384 error_message (AST, symbol_list->children [i]->line_number , current_parse_file, " No matching declaration for port %s\n " , symbol_list->children [i]->children [0 ]->types .identifier );
375385 }
376386 } else if (top_type == FUNCTION) {
377387 /* find the related INPUT or OUTPUT definition and store that instead */
378388 if ((sc_spot = sc_lookup_string (functions_inputs_sc, symbol_list->children [i]->children [0 ]->types .identifier )) != -1 ) {
379- oassert (((ast_node_t *)functions_inputs_sc->data [sc_spot])->type == VAR_DECLARE);
380- free_whole_tree (symbol_list->children [i]);
381- symbol_list->children [i] = (ast_node_t *)functions_inputs_sc->data [sc_spot];
382- oassert (symbol_list->children [i]->types .variable .is_input );
389+ sc = functions_inputs_sc;
390+ oassert (((ast_node_t *)sc->data [sc_spot])->types .variable .is_input );
383391 } else if ((sc_spot = sc_lookup_string (functions_outputs_sc, symbol_list->children [i]->children [0 ]->types .identifier )) != -1 ) {
384- oassert (((ast_node_t *)functions_outputs_sc->data [sc_spot])->type == VAR_DECLARE);
385- free_whole_tree (symbol_list->children [i]);
386- symbol_list->children [i] = (ast_node_t *)functions_outputs_sc->data [sc_spot];
387- oassert (symbol_list->children [i]->types .variable .is_output );
392+ sc = functions_outputs_sc;
393+ oassert (((ast_node_t *)sc->data [sc_spot])->types .variable .is_output );
394+ } else if ((sc_spot = sc_lookup_string (functions_inouts_sc, symbol_list->children [i]->children [0 ]->types .identifier )) != -1 ) {
395+ sc = functions_inouts_sc;
396+ oassert (((ast_node_t *)sc->data [sc_spot])->types .variable .is_inout );
388397 } else {
389398 error_message (AST, symbol_list->children [i]->line_number , current_parse_file, " No matching declaration for port %s\n " , symbol_list->children [i]->children [0 ]->types .identifier );
390399 }
391400 } else if (top_type == TASK) {
392401 /* find the related INPUT or OUTPUT definition and store that instead */
393402 if ((sc_spot = sc_lookup_string (tasks_inputs_sc, symbol_list->children [i]->children [0 ]->types .identifier )) != -1 ) {
394- oassert (((ast_node_t *)tasks_inputs_sc->data [sc_spot])->type == VAR_DECLARE);
395- free_whole_tree (symbol_list->children [i]);
396- symbol_list->children [i] = (ast_node_t *)tasks_inputs_sc->data [sc_spot];
397- oassert (symbol_list->children [i]->types .variable .is_input );
403+ sc = tasks_inputs_sc;
404+ oassert (((ast_node_t *)sc->data [sc_spot])->types .variable .is_input );
398405 } else if ((sc_spot = sc_lookup_string (tasks_outputs_sc, symbol_list->children [i]->children [0 ]->types .identifier )) != -1 ) {
399- oassert (((ast_node_t *)tasks_outputs_sc->data [sc_spot])->type == VAR_DECLARE);
400- free_whole_tree (symbol_list->children [i]);
401- symbol_list->children [i] = (ast_node_t *)tasks_outputs_sc->data [sc_spot];
402- oassert (symbol_list->children [i]->types .variable .is_output );
406+ sc = tasks_outputs_sc;
407+ oassert (((ast_node_t *)sc->data [sc_spot])->types .variable .is_output );
408+ } else if ((sc_spot = sc_lookup_string (tasks_inouts_sc, symbol_list->children [i]->children [0 ]->types .identifier )) != -1 ) {
409+ sc = tasks_inouts_sc;
410+ oassert (((ast_node_t *)sc->data [sc_spot])->types .variable .is_inout );
403411 } else {
404412 error_message (AST, symbol_list->children [i]->line_number , current_parse_file, " No matching declaration for port %s\n " , symbol_list->children [i]->children [0 ]->types .identifier );
405413 }
406414 }
415+
416+ if ( sc ) {
417+ oassert (((ast_node_t *)sc->data [sc_spot])->type == VAR_DECLARE);
418+ free_whole_tree (symbol_list->children [i]);
419+ symbol_list->children [i] = (ast_node_t *)sc->data [sc_spot];
420+ }
407421 }
408422 symbol_list->children [i]->types .variable .is_port = true ;
409423 }
@@ -420,6 +434,7 @@ ast_node_t* markAndProcessPortWith(ids top_type, ids port_id, ids net_id, ast_no
420434 const char * top_type_name = NULL ;
421435 STRING_CACHE* this_inputs_sc = NULL ;
422436 STRING_CACHE* this_outputs_sc = NULL ;
437+ STRING_CACHE* this_inouts_sc = NULL ;
423438
424439 if (top_type == MODULE) {
425440 top_type_name = " Module" ;
@@ -431,20 +446,20 @@ ast_node_t* markAndProcessPortWith(ids top_type, ids port_id, ids net_id, ast_no
431446
432447 ids temp_net_id = NO_ID;
433448
434- if (port->types .variable .is_port ) {
435- oassert (false && " Port was already marked" );
436- }
449+ oassert (!port->types .variable .is_port && " Port was already marked" );
437450
438451 if (top_type == MODULE) {
439452 this_inputs_sc = modules_inputs_sc;
440453 this_outputs_sc = modules_outputs_sc;
441-
454+ this_inouts_sc = modules_inouts_sc;
442455 } else if (top_type == FUNCTION) {
443456 this_inputs_sc = functions_inputs_sc;
444457 this_outputs_sc = functions_outputs_sc;
458+ this_inouts_sc = functions_inouts_sc;
445459 } else if (top_type == TASK) {
446460 this_inputs_sc = tasks_inputs_sc;
447461 this_outputs_sc = tasks_outputs_sc;
462+ this_inouts_sc = tasks_inouts_sc;
448463 }
449464
450465 /* look for processed inputs with this name */
@@ -460,6 +475,13 @@ ast_node_t* markAndProcessPortWith(ids top_type, ids port_id, ids net_id, ast_no
460475 error_message (AST, port->line_number , current_parse_file, " %s already has output with this name %s\n " ,
461476 top_type_name, ((ast_node_t *)this_outputs_sc->data [sc_spot])->children [0 ]->types .identifier );
462477 }
478+
479+ /* look for processed inouts with this name */
480+ sc_spot = sc_lookup_string (this_inouts_sc, port->children [0 ]->types .identifier );
481+ if (sc_spot > -1 && ((ast_node_t *)this_inouts_sc->data [sc_spot])->types .variable .is_port ) {
482+ error_message (PARSE_ERROR, port->line_number , current_parse_file, " %s already has inout with this name %s\n " ,
483+ top_type_name, ((ast_node_t *)this_inouts_sc->data [sc_spot])->children [0 ]->types .identifier );
484+ }
463485
464486 switch (net_id) {
465487 case REG:
@@ -565,9 +587,15 @@ ast_node_t* markAndProcessPortWith(ids top_type, ids port_id, ids net_id, ast_no
565587
566588 case INOUT:
567589 port->types .variable .is_inout = true ;
568- port->types .variable .is_input = false ;
569- port->types .variable .is_output = false ;
570- error_message (AST, port->line_number , current_parse_file, " Odin does not handle inouts (%s)\n " , port->children [0 ]->types .identifier );
590+ port->types .variable .is_input = true ;
591+ port->types .variable .is_output = true ;
592+
593+ /* add this output to the modules string cache */
594+ sc_spot = sc_add_string (this_inouts_sc, port->children [0 ]->types .identifier );
595+
596+ /* store the data which is an idx here */
597+ this_inouts_sc->data [sc_spot] = (void *)port;
598+
571599 break ;
572600
573601 default :
@@ -582,10 +610,10 @@ ast_node_t* markAndProcessPortWith(ids top_type, ids port_id, ids net_id, ast_no
582610 } else if (port->types .variable .is_inout
583611 && !(port->types .variable .is_input )
584612 && !(port->types .variable .is_output )) {
585- error_message (AST, port->line_number , current_parse_file, " Odin does not handle inouts (%s)\n " , port->children [0 ]->types .identifier );
586613 port = markAndProcessPortWith (top_type, INOUT, net_id, port, is_signed);
587614 } else {
588615 // shouldn't ever get here...
616+ oassert ( false && " This is just my own debugging thing and if this gets merged I have a bad memory and noone reviewed it" ); // TODO Check if this is valid
589617 oassert (port->types .variable .is_input
590618 || port->types .variable .is_output
591619 || port->types .variable .is_inout );
@@ -1776,9 +1804,11 @@ void next_task() {
17761804 /* old ones are done so clean */
17771805 sc_free_string_cache (tasks_inputs_sc);
17781806 sc_free_string_cache (tasks_outputs_sc);
1807+ sc_free_string_cache (tasks_inouts_sc);
17791808 /* make for next task */
17801809 tasks_inputs_sc = sc_new_string_cache ();
17811810 tasks_outputs_sc = sc_new_string_cache ();
1811+ tasks_inouts_sc = sc_new_string_cache ();
17821812}
17831813/* ---------------------------------------------------------------------------------------------
17841814 * (function: next_function)
@@ -1793,9 +1823,11 @@ void next_function() {
17931823 /* old ones are done so clean */
17941824 sc_free_string_cache (functions_inputs_sc);
17951825 sc_free_string_cache (functions_outputs_sc);
1826+ sc_free_string_cache (functions_inouts_sc);
17961827 /* make for next function */
17971828 functions_inputs_sc = sc_new_string_cache ();
17981829 functions_outputs_sc = sc_new_string_cache ();
1830+ functions_inouts_sc = sc_new_string_cache ();
17991831}
18001832/* ---------------------------------------------------------------------------------------------
18011833 * (function: next_module)
@@ -1813,10 +1845,12 @@ void next_module() {
18131845 /* old ones are done so clean */
18141846 sc_free_string_cache (modules_inputs_sc);
18151847 sc_free_string_cache (modules_outputs_sc);
1848+ sc_free_string_cache (modules_inouts_sc);
18161849 sc_free_string_cache (module_instances_sc);
18171850 /* make for next module */
18181851 modules_inputs_sc = sc_new_string_cache ();
18191852 modules_outputs_sc = sc_new_string_cache ();
1853+ modules_inouts_sc = sc_new_string_cache ();
18201854 module_instances_sc = sc_new_string_cache ();
18211855}
18221856
0 commit comments