#ifndef AST_TO_C_C #define AST_TO_C_C AST_TO_C_C #include #include void ast_to_c(FILE *out,struct AST *tree) { assert(tree->type==AST_TYPE_MACHINE); ast_machine_to_c(out,(struct AST_Machine*)tree); } void ast_machine_to_c(FILE *out,struct AST_Machine *machine) { assert(out!=NULL && machine!=NULL && machine->type==AST_TYPE_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) { size_t i; struct State_And_Transitions **table; table=extract_transition_table(machine->states,machine->transitions); for(i=0;istates->number_of_states;++i) { ast_state_to_c_signature(out,machine,machine->states->states[i]); fprintf(out,"\n{\n"); ast_transitions_of_state_to_c(out,machine,table[i]); fprintf(out,"\n}\n"); } } 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); } void ast_events_to_c(FILE *out,struct AST_Machine *machine) { size_t i; assert(out!=NULL && machine!=NULL && machine->type==AST_TYPE_MACHINE); fprintf(out,"enum "); ast_event_name_to_c(out,machine); fprintf(out,"\n{\n"); for(i=0;ievents->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); fprintf(out,",\n"); } fprintf(out,"};\n"); } void ast_states_to_c(FILE *out,struct AST_Machine *machine) { size_t i; assert(out!=NULL && machine!=NULL && machine->type==AST_TYPE_MACHINE); for(i=0;istates->number_of_states;++i) { fprintf(out,"extern "); ast_state_to_c_signature(out,machine,machine->states->states[i]); fprintf(out,";\n"); } } 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;inumber_of_transitions;++i) { 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"); } } void ast_event_name_to_c(FILE *out,struct AST_Machine *machine) { fprintf(out,"MACHINE_"); ast_token_to_c(out,machine->id); fprintf(out,"_EVENTS_ENUM"); } 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"); } void ast_token_to_c(FILE *out,struct token *token) { size_t i; assert(out!=NULL && token!=NULL); for(i=0;isize;++i) fprintf(out,"%c",token->data[i]); } void ast_pipeline_to_c(FILE *out,size_t indentation,struct AST_Pipeline *pipeline) { size_t i; ast_to_c_print_tabs(out,indentation); fprintf(out,"machine_buffer_t *hold_buffer;\n"); for(i=0;isize;++i) { ast_to_c_print_tabs(out,indentation); fprintf(out,"hold_buffer="); ast_command_to_c(out,pipeline->pipeline[i],"hold_buffer"); fprintf(out,";\n"); } ast_to_c_print_tabs(out,indentation); fprintf(out,"delete_machine_buffer(hold_buffer);\n"); } void ast_command_to_c(FILE *out,struct AST_Command *command,char *hold_buffer) { ast_token_to_c(out,command->function_name); fprintf(out,"("); if(command->argument==NULL) fprintf(out,"NULL"); else ast_token_to_c(out,command->argument); fprintf(out,",%s)",hold_buffer); } void ast_command_to_c_signature(FILE *out,struct AST_Command *command) { fprintf(out,"machine_buffer_t* "); ast_token_to_c(out,command->function_name); fprintf(out,"machine_buffer_t *arguments,machine_buffer_t *input)"); } void ast_to_c_print_tabs(FILE *out,size_t number_of_tabs) { size_t i; for(i=0;i