diff options
Diffstat (limited to 'src/backend')
-rw-r--r-- | src/backend/backend.c | 116 | ||||
-rw-r--r-- | src/backend/backend.h | 13 | ||||
-rw-r--r-- | src/backend/targets/C/ast_to_c.c | 288 | ||||
-rw-r--r-- | src/backend/targets/C/ast_to_c.h | 36 |
4 files changed, 413 insertions, 40 deletions
diff --git a/src/backend/backend.c b/src/backend/backend.c index 122e84c..6646e6c 100644 --- a/src/backend/backend.c +++ b/src/backend/backend.c @@ -6,6 +6,7 @@ struct State_And_Transitions** extract_transition_table(struct AST_States *states,struct AST_Transitions *transitions) { struct State_And_Transitions **ret; + struct AST_State *hold_state; struct Queue *qs; size_t i; @@ -18,7 +19,13 @@ struct State_And_Transitions** extract_transition_table(struct AST_States *state /*traverse transitions and push them into the queue of their coresponding state*/ for(i=0;i<transitions->size;++i) - Queue_Push(qs+transitions->transitions[i]->from->number,transitions->transitions[i]); + { + hold_state=extract_state(transitions->transitions[i]->from,states); + + assert(hold_state!=NULL); + + Queue_Push(qs+hold_state->number,transitions->transitions[i]); + } /*condense the queues into the arrays*/ for(i=0;i<states->number_of_states;++i) @@ -34,4 +41,111 @@ struct State_And_Transitions** extract_transition_table(struct AST_States *state return ret; } +_Bool expression_is_binary(struct AST* expression) +{ + return (expression->type==AST_TYPE_OP_OR || expression->type==AST_TYPE_OP_AND); +} +_Bool expression_is_unary(struct AST* expression) +{ + return (expression->type==AST_TYPE_OP_NOT); +} +_Bool state_is_in_states(struct AST_State *state,struct AST_States *states) +{ + return state==Map_Check(states->states_map,state->name->data,state->name->size); +} + +struct AST_State* extract_state(struct AST *expression,struct AST_States *states) +{ + struct AST_State *hold_state; + + assert(expression->type==AST_TYPE_OP_NOT || expression->type==AST_TYPE_OP_AND || expression->type==AST_TYPE_OP_OR + || expression->type==AST_TYPE_STATE ); + + if(expression->type==AST_TYPE_STATE) + { + if(state_is_in_states((struct AST_State*)expression,states)) + return (struct AST_State*)expression; + else + return NULL; + }else if(expression_is_binary(expression)) + { + hold_state=extract_state(((struct AST_Binary_Expression*)expression)->left,states); + if(hold_state) + return hold_state; + else + return extract_state(((struct AST_Binary_Expression*)expression)->right,states); + }else + { + return extract_state(((struct AST_Unary_Expression*)expression)->operand,states); + } +} + +_Bool check_expression(struct AST *state,struct AST_Translation_Unit *unit) +{ + +} +_Bool check_transition(struct AST *state,struct AST_Translation_Unit *unit) +{ + +} +void anotate_unchecked_states(struct AST_Translation_Unit *unit,struct Translation_Data *translation_data) +{ + size_t i; + for(i=0;i<unit->number_of_machines;++i) + { + anotate_machine(unit->machines[i],unit); + } + if(has_new_errors( + +} +void anotate_machine(struct AST_Machine *machine,struct AST_Translation_Unit *unit,struct Translation_Data *translation_data) +{ + size_t i; + for(i=0;i<machine->transitions->size;++i) + { + machine->transitions->transitions[i]->from=anotate_expression(machine->transitions->transitions[i]->from,machine,unit); + } + if(has_new_errors(translation_data)) + { + push_error_with_token("in machine",translation_data,machine->id); + delete_ast_machine(machine); + } +} +struct AST* anotate_expression(struct AST *expression,struct AST_Translation_Unit *unit,struct AST_Machine *current_machine,struct Translation_Data *translation_data); +{ + struct AST_Machine *hold_machine; + struct AST *hold_left; + struct AST *hold_right; + + if(expression_is_binary(expression)) + { + left=((struct AST_Binary_Expression*)expression)->left; + right=((struct AST_Binary_Expression*)expression)->right; + + if(expression->type==AST_TYPE_OP_SELECTOR) + { + hold_machine=Map_Check(unit->machines_map,((struct AST_Unchecked_State*)hold_left)->name->data,((struct AST_Unchecked_State*)hold_left)->name->size); + if(hold_machine==NULL) + { + push_error_with_token("machine id is undefined",((struct AST_Unchecked_State*)hold_left)->name,translation_data); + delete_ast(expression); + return NULL; + }else + { + return ast_check_state(hold_right,hold_machine->states,translation_data); + } + }else + { + AS_BIN_EXPR_PTR(expression)->right=anotate_expression(AS_BIN_EXPR_PTR(expression)->right,machine,unit); + AS_BIN_EXPR_PTR(expression)->left=anotate_expression(AS_BIN_EXPR_PTR(expression)->left,machine,unit); + return expression; + } + }else if(expression_is_unary(expression)) + { + AS_UN_EXPR_PTR(expression)->operand=anotate_expression(AS_UN_EXPR_PTR(expression)->operand,machine,unit); + }else if(expression->type==AST_TYPE_UNFINISHED_STATE) + { + return ast_check_state(AS_UNCK_EXPR_PTR(expression),machine->states,translation_data); + } +} #endif diff --git a/src/backend/backend.h b/src/backend/backend.h index 1857cd0..8b865fd 100644 --- a/src/backend/backend.h +++ b/src/backend/backend.h @@ -2,6 +2,7 @@ #define BACKEND_H BACKEND_H #include <parser.h> #include <ast_to_c.h> +#include <map.h> /* * describes a given state and the transitions coming out of it @@ -15,4 +16,16 @@ struct State_And_Transitions }; /*returns an array of state_and_transition structs*/ struct State_And_Transitions** extract_transition_table(struct AST_States *states,struct AST_Transitions *transitions); +/*extracts a state from the expression that belongs in the states structure*/ +struct AST_State* extract_state(struct AST *expression,struct AST_States *states); + +void anotate_unchecked_states(struct AST_Translation_Unit *unit,struct Translation_Data *translation_data); +void anotate_machine(struct AST_Machine *machine,struct AST_Translation_Unit *unit,struct Translation_Data *translation_data); +struct AST* anotate_expression(struct AST *expression,struct AST_Translation_Unit *unit,struct AST_Machine *current_machine,struct Translation_Data *translation_data); + +_Bool expression_is_binary(struct AST* expression); +_Bool expression_is_unary(struct AST* expression); +_Bool state_is_in_states(struct AST_State *state,struct AST_States *states); +_Bool check_expression(struct AST *state,struct AST_Translation_Unit *unit); +_Bool check_transition(struct AST *state,struct AST_Translation_Unit *unit); #endif diff --git a/src/backend/targets/C/ast_to_c.c b/src/backend/targets/C/ast_to_c.c index 346801c..79d6017 100644 --- a/src/backend/targets/C/ast_to_c.c +++ b/src/backend/targets/C/ast_to_c.c @@ -3,10 +3,118 @@ #include <ast_to_c.h> #include <print.h> -void ast_to_c(FILE *out,struct AST *tree) +void ast_to_c(char *output_name,struct AST *tree) { - assert(tree->type==AST_TYPE_MACHINE); - ast_machine_to_c(out,(struct AST_Machine*)tree); + size_t output_name_length; + char *hold_name; + FILE *hold_out; + + if(output_name!=NULL) + { + output_name_length=strnlen(output_name,1000); + + hold_name=calloc(output_name_length+100,1); + memcpy(hold_name,output_name,output_name_length); + + memcpy(hold_name+output_name_length,".h",sizeof(".h")); + hold_out=fopen(hold_name,"w"); + ast_translation_unit_to_c_print_header_part(hold_out,output_name,(struct AST_Translation_Unit*)tree); + fclose(hold_out); + + memcpy(hold_name+output_name_length,".c",sizeof(".c")); + hold_out=fopen(hold_name,"w"); + ast_translation_unit_to_c_print_body_part(hold_out,output_name,(struct AST_Translation_Unit*)tree); + fclose(hold_out); + + memcpy(hold_name+output_name_length,"_external.h",sizeof("_external.h")); + hold_out=fopen(hold_name,"w"); + ast_translation_unit_to_c_print_external_commands(hold_out,output_name,(struct AST_Translation_Unit*)tree); + fclose(hold_out); + + free(hold_name); + + }else + { + ast_translation_unit_to_c_print_external_commands(stdout,NULL,(struct AST_Translation_Unit*)tree); + ast_translation_unit_to_c_print_header_part(stdout,NULL,(struct AST_Translation_Unit*)tree); + ast_translation_unit_to_c_print_body_part(stdout,NULL,(struct AST_Translation_Unit*)tree); + } + +} +void ast_translation_unit_to_c_print_base_name(FILE *out, char *base_name) +{ + size_t i; + for(i=0;i<1000 && base_name[i]!='\0';++i) + fprintf(out,"%c",toupper(base_name[i])); +} +void ast_translation_unit_to_c_print_header_string(FILE *out,char *base_name,char *file_suffix) +{ + fprintf(out,"#ifndef "); + ast_translation_unit_to_c_print_base_name(out,base_name); + fprintf(out,"%s\n#define ",file_suffix); + ast_translation_unit_to_c_print_base_name(out,base_name); + fprintf(out,"%s ",file_suffix); + ast_translation_unit_to_c_print_base_name(out,base_name); + fprintf(out,"%s\n",file_suffix); +} +void ast_translation_unit_to_c_print_footer_string(FILE *out,char *base_name,char *file_suffix) +{ + fprintf(out,"\n#endif //#ifndef "); + ast_translation_unit_to_c_print_base_name(out,base_name); + fprintf(out,"%s",file_suffix); +} +void ast_translation_unit_to_c_print_header_part(FILE *out,char *base_name,struct AST_Translation_Unit *translation_unit) +{ + size_t i; + if(base_name) + { + ast_translation_unit_to_c_print_header_string(out,base_name,"_H"); + fprintf(out,"#include<stdlib.h>\n\n"); + } + + ast_to_c_print_internal_stuff_for_header(out,translation_unit); + + for(i=0;i<translation_unit->number_of_machines;++i) + ast_machine_to_c_make_header_part(out,translation_unit->machines[i]); + + ast_machines_to_c_array(out,translation_unit); + + if(base_name) + ast_translation_unit_to_c_print_footer_string(out,base_name,"_H"); +} +void ast_translation_unit_to_c_print_body_part(FILE *out,char *base_name,struct AST_Translation_Unit *translation_unit) +{ + size_t i; + + if(base_name) + { + ast_translation_unit_to_c_print_header_string(out,base_name,"_C"); + fprintf(out,"#include \"%s.h\"\n",base_name); + fprintf(out,"#include \"%s_external.h\"\n\n",base_name); + } + + for(i=0;i<translation_unit->number_of_machines;++i) + ast_machine_to_c_make_body_part(out,translation_unit->machines[i]); + + ast_to_c_print_internal_stuff_for_body(out); + + if(base_name) + ast_translation_unit_to_c_print_footer_string(out,base_name,"_C"); +} +void ast_translation_unit_to_c_print_external_commands(FILE *out,char *base_name,struct AST_Translation_Unit *translation_unit) +{ + if(base_name) + { + ast_translation_unit_to_c_print_header_string(out,base_name,"_EXTERNAL_H"); + fprintf(out,"#include \"%s.h\"\n\n",base_name); + } + + Map_Map_Extended(translation_unit->used_commands_map,(void (*)(void*,void*))ast_command_to_c_extern_declaration,out); + + if(base_name) + { + ast_translation_unit_to_c_print_footer_string(out,base_name,"_EXTERNAL_H"); + } } void ast_machine_to_c(FILE *out,struct AST_Machine *machine) { @@ -17,7 +125,6 @@ void ast_machine_to_c(FILE *out,struct AST_Machine *machine) ast_machine_to_c_make_header_part(out,machine); ast_machine_to_c_make_body_part(out,machine); - } void ast_machine_to_c_make_body_part(FILE *out,struct AST_Machine *machine) { @@ -36,8 +143,6 @@ void ast_machine_to_c_make_body_part(FILE *out,struct AST_Machine *machine) } void ast_machine_to_c_make_header_part(FILE *out,struct AST_Machine *machine) { - fprintf(out,"typedef struct machine_buffer_t \n{" - "\n\tsize_t size;\n\tunsigned char buffer[];\n} machine_buffer_t;\n\n"); ast_events_to_c(out,machine); ast_states_to_c(out,machine); } @@ -48,15 +153,13 @@ void ast_events_to_c(FILE *out,struct AST_Machine *machine) assert(out!=NULL && machine!=NULL && machine->type==AST_TYPE_MACHINE); fprintf(out,"enum "); - ast_event_name_to_c(out,machine); + ast_machine_enum_tag(out,machine); fprintf(out,"\n{\n"); for(i=0;i<machine->events->number_of_events;++i) { fprintf(out,"\t"); - ast_token_to_c(out,machine->id); - fprintf(out,"_EVENT_"); - ast_token_to_c(out,machine->events->events[i]->name); + ast_event_to_c_enum(out,machine,machine->events->events[i]); fprintf(out,",\n"); } fprintf(out,"};\n"); @@ -75,19 +178,31 @@ void ast_states_to_c(FILE *out,struct AST_Machine *machine) void ast_transitions_of_state_to_c(FILE *out,struct AST_Machine *machine,struct State_And_Transitions *vector) { size_t i; - ast_state_to_c_signature(out,machine,vector->state); - fprintf(out,"\n{\n\n\tswitch(event)\n\t{\n"); - for(i=0;i<vector->number_of_transitions;++i) + //fprintf(out,"\tmachine_buffer_t *hold_buffer;\n\thold_buffer=input;\n\n"); + + if(vector->number_of_transitions>0) { - fprintf(out,"\t\tcase "); - ast_token_to_c(out,vector->transitions[i]->event->name); - fprintf(out,":\n"); - ast_pipeline_to_c(out,3,vector->transitions[i]->pipeline); - fprintf(out,"\n\t\t\tbreak;\n"); + fprintf(out,"\tswitch(event)\n\t{\n"); + for(i=0;i<vector->number_of_transitions;++i) + { + fprintf(out,"\t\tcase "); + ast_event_to_c_enum(out,machine,vector->transitions[i]->event); + + fprintf(out,":\n"); + ast_pipeline_to_c(out,3,vector->transitions[i]->pipeline); + fprintf(out,"\t\t\tmachine_states["); + ast_token_to_c(out,machine->id); + fprintf(out,"]="); + ast_state_to_c_function_name(out,machine,vector->transitions[i]->to); + fprintf(out,";\n\t\t\tbreak;\n"); + } + fprintf(out,"\t}\n"); } + fprintf(out,"\tdelete_machine_buffer(input);\n"); } -void ast_event_name_to_c(FILE *out,struct AST_Machine *machine) +/*prints the enum tag for the given machine*/ +void ast_machine_enum_tag(FILE *out,struct AST_Machine *machine) { fprintf(out,"MACHINE_"); ast_token_to_c(out,machine->id); @@ -95,13 +210,9 @@ void ast_event_name_to_c(FILE *out,struct AST_Machine *machine) } void ast_state_to_c_signature(FILE *out,struct AST_Machine *machine,struct AST_State *state) { - fprintf(out,"void machine_"); - ast_token_to_c(out,machine->id); - fprintf(out,"_state_"); - ast_token_to_c(out,state->name); - fprintf(out,"(enum "); - ast_event_name_to_c(out,machine); - fprintf(out," event)\n"); + fprintf(out,"void "); + ast_state_to_c_function_name(out,machine,state); + fprintf(out,"(int event,machine_buffer_t *input)"); } void ast_token_to_c(FILE *out,struct token *token) { @@ -116,18 +227,16 @@ void ast_pipeline_to_c(FILE *out,size_t indentation,struct AST_Pipeline *pipelin { size_t i; - ast_to_c_print_tabs(out,indentation); - fprintf(out,"machine_buffer_t *hold_buffer;\n"); + if(pipeline==NULL) return; for(i=0;i<pipeline->size;++i) { ast_to_c_print_tabs(out,indentation); - fprintf(out,"hold_buffer="); - ast_command_to_c(out,pipeline->pipeline[i],"hold_buffer"); + fprintf(out,"input="); + ast_command_to_c(out,pipeline->pipeline[i],"input"); fprintf(out,";\n"); } - ast_to_c_print_tabs(out,indentation); - fprintf(out,"delete_machine_buffer(hold_buffer);\n"); + //ast_to_c_print_tabs(out,indentation); } void ast_command_to_c(FILE *out,struct AST_Command *command,char *hold_buffer) { @@ -140,11 +249,11 @@ void ast_command_to_c(FILE *out,struct AST_Command *command,char *hold_buffer) fprintf(out,",%s)",hold_buffer); } -void ast_command_to_c_signature(FILE *out,struct AST_Command *command) +void ast_command_to_c_extern_declaration(struct AST_Command *command,FILE *out) { - fprintf(out,"machine_buffer_t* "); + fprintf(out,"extern machine_buffer_t* "); ast_token_to_c(out,command->function_name); - fprintf(out,"machine_buffer_t *arguments,machine_buffer_t *input)"); + fprintf(out,"(machine_buffer_t *arguments,machine_buffer_t *input);\n"); } void ast_to_c_print_tabs(FILE *out,size_t number_of_tabs) { @@ -152,4 +261,113 @@ void ast_to_c_print_tabs(FILE *out,size_t number_of_tabs) for(i=0;i<number_of_tabs;++i) fprintf(out,"\t"); } +void ast_machines_to_c_array(FILE *out,struct AST_Translation_Unit *translation_unit) +{ + size_t i; + + fprintf(out,"void (*machine_states[])(int,machine_buffer_t*)={"); + for(i=0;i<translation_unit->number_of_machines;++i) + { + ast_state_to_c_function_name(out,translation_unit->machines[i],translation_unit->machines[i]->starting_state); + fprintf(out,","); + } + fprintf(out,"};\n"); +} +void ast_machines_to_c_enum(FILE *out,struct AST_Translation_Unit *translation_unit) +{ + size_t i; + fprintf(out,"enum MACHINES_ENUM\n{\n"); + for(i=0;i<translation_unit->number_of_machines;++i) + { + fprintf(out,"\t"); + ast_token_to_c(out,translation_unit->machines[i]->id); + fprintf(out,",\n"); + } + + fprintf(out,"\tMACHINES_ENUM_END\n};\n"); +} +void ast_state_to_c_function_name(FILE *out,struct AST_Machine *machine,struct AST_State *state) +{ + fprintf(out,"machine_"); + ast_token_to_c(out,machine->id); + fprintf(out,"_state_"); + ast_token_to_c(out,state->name); +} +void ast_event_to_c_enum(FILE *out,struct AST_Machine *machine,struct AST_Event *event) +{ + ast_token_to_c(out,machine->id); + fprintf(out,"_EVENT_"); + ast_token_to_c(out,event->name); +} +void ast_to_c_print_internal_stuff_for_header(FILE *out,struct AST_Translation_Unit *translation_unit) +{ + fprintf(out,"\n\n"); + ast_machines_to_c_enum(out,translation_unit); + fprintf(out,"\n\n"); + + + ast_to_c_print_comment(out,"\tthis is the structure that facilitates data exchange"); + fprintf(out,"typedef struct machine_buffer_t \n{" + "\n\tsize_t size;\n\tunsigned char buffer[];\n} machine_buffer_t;\n\n"); + + + ast_to_c_print_comment(out, "\tuse this function to pass an event to a machine\n" + "\tthe input buffer is passed to the first executed function if any\n" + "\tany remaining buffer after the pipeline has finished is passed\n" + "\tto the delete_machine_buffer function\n" + "\tinput can be NULL" + + ); + fprintf(out,"void push_event_to_machine(enum MACHINES_ENUM machine,int event,machine_buffer_t *input);\n\n"); + + + + + ast_to_c_print_comment(out, "\tthis function creates a buffer structure in the heap\n" + "\tit COPIES the contents of content \n" + "\tsize is in bytes" + ); + + fprintf(out,"machine_buffer_t* get_machine_buffer(void *content,size_t size);\n\n"); + ast_to_c_print_comment(out,"\tfrees the buffer from the heap"); + fprintf(out,"void delete_machine_buffer(machine_buffer_t *buffer);\n\n"); +} +void ast_to_c_print_internal_stuff_for_body(FILE *out) +{ + + fprintf(out, "void push_event_to_machine(enum MACHINES_ENUM machine,int event,machine_buffer_t *input)\n" + "{\n" + "\tif(machine<MACHINES_ENUM_END)" + "\n\t{" + "\n\t\tmachine_states[machine](event,input);" + "\n\t}" + "\n}\n" + ); + + fprintf(out, "machine_buffer_t* get_machine_buffer(void *content,size_t size)\n" + "{\n" + "\tmachine_buffer_t *ret;\n" + "\tsize_t i;\n" + "\t\n" + "\tret=malloc(sizeof(machine_buffer_t)+size);\n" + "\tret->size=size;\n" + "\tfor(i=0;i<size;++i)\n" + "\t\tret->buffer[i]=((unsigned char*)content)[i];\n" + "\treturn ret;\n" + "}\n"); + + fprintf(out, "\nvoid delete_machine_buffer(machine_buffer_t *buffer)\n" + "{\n" + "\tif(buffer)\n" + "\t{\n" + "\t\tfree(buffer);\n" + "\t}\n}" + ); +} +void ast_to_c_print_comment(FILE *out,char *comment) +{ + fprintf(out,"/*\n"); + fprintf(out,"%s\n",comment); + fprintf(out,"*/\n"); +} #endif diff --git a/src/backend/targets/C/ast_to_c.h b/src/backend/targets/C/ast_to_c.h index 8c86687..6e4006f 100644 --- a/src/backend/targets/C/ast_to_c.h +++ b/src/backend/targets/C/ast_to_c.h @@ -4,25 +4,53 @@ #include <parser.h> #include <backend.h> #include <ctype.h> +#include <stdio.h> +#include <string.h> struct State_And_Transitions; -void ast_to_c(FILE *out,struct AST *tree); +void ast_to_c(char *output_name,struct AST *tree); + +void ast_translation_unit_to_c_print_header_part(FILE *out,char *base_name,struct AST_Translation_Unit *translation_unit); +void ast_translation_unit_to_c_print_body_part(FILE *out,char *base_name,struct AST_Translation_Unit *translation_unit); +void ast_translation_unit_to_c_print_external_commands(FILE *out,char *base_name,struct AST_Translation_Unit *translation_unit); + +void ast_translation_unit_to_c_print_base_name(FILE *out, char *base_name); +void ast_translation_unit_to_c_print_header_string(FILE *out,char *base_name,char *file_suffix); +void ast_translation_unit_to_c_print_footer_string(FILE *out,char *base_name,char *file_suffix); + +void ast_translation_unit_to_c(FILE *out,struct AST_Translation_Unit *translation_unit); void ast_machine_to_c(FILE *out,struct AST_Machine *machine); void ast_machine_to_c_make_header_part(FILE *out,struct AST_Machine *machine); void ast_machine_to_c_make_body_part(FILE *out,struct AST_Machine *machine); + void ast_events_to_c(FILE *out,struct AST_Machine *machine); void ast_states_to_c(FILE *out,struct AST_Machine *machine); -void ast_pipeline_to_c(FILE *out,size_t indentation,struct AST_Pipeline *pipeline); void ast_command_to_c(FILE *out,struct AST_Command *command,char *hold_buffer); -void ast_command_to_c_signature(FILE *out,struct AST_Command *command); + +/*note the ordering*/ +void ast_command_to_c_extern_declaration(struct AST_Command *command,FILE *out); + +void ast_pipeline_to_c(FILE *out,size_t indentation,struct AST_Pipeline *pipeline); void ast_transitions_of_state_to_c(FILE *out,struct AST_Machine *machine,struct State_And_Transitions *vector); void ast_token_to_c(FILE *out,struct token *token); -void ast_event_name_to_c(FILE *out,struct AST_Machine *machine); +void ast_machine_enum_tag(FILE *out,struct AST_Machine *machine); void ast_state_to_c_signature(FILE *out,struct AST_Machine *machine,struct AST_State *state); +void ast_state_to_c_function_name(FILE *out,struct AST_Machine *machine,struct AST_State *state); +void ast_machines_to_c_array(FILE *out,struct AST_Translation_Unit *translation_unit); +void ast_machines_to_c_enum(FILE *out,struct AST_Translation_Unit *translation_unit); +void ast_event_to_c_enum(FILE *out,struct AST_Machine *machine,struct AST_Event *event); + + +void ast_to_c_print_internal_stuff_for_header(FILE *out,struct AST_Translation_Unit *translation_unit); +void ast_to_c_print_internal_stuff_for_body(FILE *out); +void ast_to_c_print_comment(FILE *out,char *comment); + + + /* :X */ void ast_to_c_print_tabs(FILE *out,size_t number_of_tabs); |