diff options
Diffstat (limited to 'src/backend/targets/C/ast_to_c.c')
-rw-r--r-- | src/backend/targets/C/ast_to_c.c | 288 |
1 files changed, 253 insertions, 35 deletions
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 |