diff options
author | Galin Simeonov <gts@volconst.com> | 2021-06-04 22:49:33 +0300 |
---|---|---|
committer | Galin Simeonov <gts@volconst.com> | 2021-07-15 18:07:29 +0300 |
commit | c875f8795586056a676e8a643a44211041ce44d2 (patch) | |
tree | 88bfd4b4923ed30de31b130672dda65e4b18a607 /src/backend | |
parent | a26684a417729699e95b335a3d00798237ffba9b (diff) | |
download | MEGATRON-c875f8795586056a676e8a643a44211041ce44d2.tar.gz |
various stuffs
Diffstat (limited to 'src/backend')
-rw-r--r-- | src/backend/backend.c | 10 | ||||
-rw-r--r-- | src/backend/targets/C/ast_to_c.c | 231 | ||||
-rw-r--r-- | src/backend/targets/C/ast_to_c.h | 19 | ||||
-rw-r--r-- | src/backend/targets/print/print.c | 3 |
4 files changed, 207 insertions, 56 deletions
diff --git a/src/backend/backend.c b/src/backend/backend.c index ff9d0bf..b6b78bd 100644 --- a/src/backend/backend.c +++ b/src/backend/backend.c @@ -99,11 +99,12 @@ void anotate_machine(struct AST_Machine *machine,struct AST_Translation_Unit *un for(i=0;i<machine->transitions->size;++i) { machine->transitions->transitions[i]->statement=anotate_statement(machine->transitions->transitions[i]->statement,unit,machine,translation_data); + if(machine->transitions->transitions[i]->granted) + machine->transitions->transitions[i]->granted=anotate_expression(machine->transitions->transitions[i]->granted,unit,machine,translation_data); } if(has_new_errors(translation_data)) { push_error_with_token("in machine",machine->id,translation_data); - delete_ast_machine(machine); } } struct AST* anotate_statement(struct AST *statement,struct AST_Translation_Unit *unit,struct AST_Machine *current_machine,struct Translation_Data *translation_data) @@ -134,7 +135,10 @@ struct AST* anotate_expression(struct AST *expression,struct AST_Translation_Uni 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 if(hold_machine==current_machine) + { + push_error_with_token("using a state from the current machine is disallowed",((struct AST_Unchecked_State*)hold_left)->name,translation_data); return NULL; }else { @@ -142,12 +146,10 @@ struct AST* anotate_expression(struct AST *expression,struct AST_Translation_Uni if(hold_left) { ((struct AST_State*)hold_left)->parent=hold_machine; - delete_ast(hold_right); return hold_left; }else { push_error_with_token("state id from foreign machine is undefined",((struct AST_Unchecked_State*)hold_right)->name,translation_data); - delete_ast(hold_right); return NULL; } } diff --git a/src/backend/targets/C/ast_to_c.c b/src/backend/targets/C/ast_to_c.c index 9c8b38d..76ebbfd 100644 --- a/src/backend/targets/C/ast_to_c.c +++ b/src/backend/targets/C/ast_to_c.c @@ -3,7 +3,7 @@ #include <ast_to_c.h> #include <print.h> -void ast_to_c(char *output_name,struct AST_Translation_Unit *tree) +void ast_to_c(char *output_name,struct AST_Translation_Unit *tree,struct Options *options) { size_t output_name_length; char *hold_name; @@ -18,26 +18,26 @@ void ast_to_c(char *output_name,struct AST_Translation_Unit *tree) 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); + ast_translation_unit_to_c_print_header_part(hold_out,output_name,(struct AST_Translation_Unit*)tree,options); 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); + ast_translation_unit_to_c_print_body_part(hold_out,output_name,(struct AST_Translation_Unit*)tree,options); 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); + ast_translation_unit_to_c_print_external_part(hold_out,output_name,(struct AST_Translation_Unit*)tree,options); 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); + ast_translation_unit_to_c_print_external_part(stdout,NULL,(struct AST_Translation_Unit*)tree,options); + ast_translation_unit_to_c_print_header_part(stdout,NULL,(struct AST_Translation_Unit*)tree,options); + ast_translation_unit_to_c_print_body_part(stdout,NULL,(struct AST_Translation_Unit*)tree,options); } } @@ -63,7 +63,7 @@ void ast_translation_unit_to_c_print_footer_string(FILE *out,char *base_name,cha 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) +void ast_translation_unit_to_c_print_header_part(FILE *out,char *base_name,struct AST_Translation_Unit *translation_unit,struct Options *options) { size_t i; if(base_name) @@ -72,17 +72,16 @@ void ast_translation_unit_to_c_print_header_part(FILE *out,char *base_name,struc fprintf(out,"#include<stdlib.h>\n\n"); } - ast_to_c_print_internal_stuff_for_header(out,translation_unit); + ast_to_c_print_internal_stuff_for_header(out,translation_unit,options); 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) +void ast_translation_unit_to_c_print_body_part(FILE *out,char *base_name,struct AST_Translation_Unit *translation_unit,struct Options *options) { size_t i; @@ -93,15 +92,16 @@ void ast_translation_unit_to_c_print_body_part(FILE *out,char *base_name,struct fprintf(out,"#include \"%s_external.h\"\n\n",base_name); } + ast_machines_to_c_array(out,translation_unit); + ast_to_c_print_internal_stuff_for_body(out,options); 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) +void ast_translation_unit_to_c_print_external_part(FILE *out,char *base_name,struct AST_Translation_Unit *translation_unit,struct Options *options) { if(base_name) { @@ -109,6 +109,22 @@ void ast_translation_unit_to_c_print_external_commands(FILE *out,char *base_name fprintf(out,"#include \"%s.h\"\n\n",base_name); } + if(options->providing_own_queue_implementation) + { + fprintf(out, "extern void machine_push_to_global_event_queue(machine_buffer_t *input,int event,enum MACHINES_ENUM target_machine);\n"); + fprintf(out, "extern void machine_pop_from_global_event_queue();\n"); + fprintf(out, "extern struct machine_queue_t machine_queue_global;\n"); + } + if(options->providing_own_buffer_implementation) + { + fprintf(out, "extern machine_buffer_t* get_machine_buffer(void *content,size_t size);\n"); + fprintf(out, "\nextern void delete_machine_buffer(machine_buffer_t *buffer);\n"); + } + if(options->has_mutex) + { + fprintf(out, "extern void machine_mutex_lock(machine_buffer_t *input,int event, enum MACHINES_ENUM target_machine); \n"); + fprintf(out, "extern void machine_mutex_unlock(int event, enum MACHINES_ENUM target_machine); \n"); + } Map_Map_Extended(translation_unit->used_commands_map,(void (*)(void*,void*))ast_command_to_c_extern_declaration,out); if(base_name) @@ -178,10 +194,12 @@ 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; + short indentation=3; //fprintf(out,"\tmachine_buffer_t *hold_buffer;\n\thold_buffer=input;\n\n"); if(vector->number_of_transitions>0) { + fprintf(out,"\n\tmachine_states_lock=1;\n"); fprintf(out,"\tswitch(event)\n\t{\n"); for(i=0;i<vector->number_of_transitions;++i) { @@ -189,17 +207,33 @@ void ast_transitions_of_state_to_c(FILE *out,struct AST_Machine *machine,struct ast_event_to_c_enum(out,machine,vector->transitions[i]->event); fprintf(out,":\n"); + if(vector->transitions[i]->granted) + { + fprintf(out,"\t\t\tif("); + ast_expression_to_c(out,vector->transitions[i]->granted); + fprintf(out,")\n\t\t\t{\n"); + indentation++; + } + //ast_pipeline_to_c(out,3,vector->transitions[i]->pipeline); - ast_statement_to_c(out,3,vector->transitions[i]->statement); - fprintf(out,"\t\t\tmachine_states["); + ast_statement_to_c(out,indentation,vector->transitions[i]->statement); + ast_to_c_print_tabs(out,indentation); + fprintf(out,"machine_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,";\n"); + ast_to_c_print_tabs(out,indentation); + fprintf(out,"break;\n"); + if(vector->transitions[i]->granted) + { + fprintf(out,"\t\t\t}\n"); + } } fprintf(out,"\t}\n"); } fprintf(out,"\tdelete_machine_buffer(input);\n"); + fprintf(out,"\n\tmachine_states_lock=0;"); } /*prints the enum tag for the given machine*/ @@ -246,7 +280,13 @@ void ast_command_to_c(FILE *out,struct AST_Command *command,char *hold_buffer) if(command->argument==NULL) fprintf(out,"NULL"); else + { + fprintf(out,"get_machine_buffer(\""); + ast_token_to_c(out,command->argument); + fprintf(out,"\",sizeof(\""); ast_token_to_c(out,command->argument); + fprintf(out,"\"))"); + } fprintf(out,",%s)",hold_buffer); } @@ -273,6 +313,8 @@ void ast_machines_to_c_array(FILE *out,struct AST_Translation_Unit *translation_ fprintf(out,","); } fprintf(out,"};\n"); + + fprintf(out,"_Bool machine_states_lock=0;\n"); } void ast_machines_to_c_enum(FILE *out,struct AST_Translation_Unit *translation_unit) { @@ -300,16 +342,21 @@ void ast_event_to_c_enum(FILE *out,struct AST_Machine *machine,struct AST_Event 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) +void ast_to_c_print_internal_stuff_for_header(FILE *out,struct AST_Translation_Unit *translation_unit,struct Options *options) { 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"); + if(options->providing_own_buffer_implementation) + { + fprintf(out,"typedef struct machine_buffer_t machine_buffer_t\t\n"); + }else + { + ast_print_machine_buffer_declarations(out); + } + if(!options->providing_own_queue_implementation) + ast_to_c_print_event_queue_declaration(out); ast_to_c_print_comment(out, "\tuse this function to pass an event to a machine\n" @@ -319,7 +366,7 @@ void ast_to_c_print_internal_stuff_for_header(FILE *out,struct AST_Translation_U "\tinput can be NULL" ); - fprintf(out,"void push_event_to_machine(enum MACHINES_ENUM machine,int event,machine_buffer_t *input);\n\n"); + fprintf(out,"extern void push_event_to_machine(enum MACHINES_ENUM machine,int event,machine_buffer_t *input);\n\n"); @@ -329,41 +376,40 @@ void ast_to_c_print_internal_stuff_for_header(FILE *out,struct AST_Translation_U "\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) +void ast_to_c_print_internal_stuff_for_body(FILE *out,struct Options *options) { + if(!options->providing_own_queue_implementation) + ast_to_c_print_event_queue_definition(out); + if(!options->providing_own_buffer_implementation) + ast_print_machine_buffer_definitions(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);" + ); + if(options->has_mutex) + fprintf(out,"\t\tmachine_mutex_lock(input,event,machine);\n"); + fprintf(out, + "\n\t\tif(machine_states_lock)" + "\n\t\t{" + "\n\t\t\tmachine_push_to_global_event_queue(input,event,machine);" + "\n\t\t}else" + "\n\t\t{" + "\n\t\t\tmachine_states[machine](event,input);" + "\n\t\t\twhile(machine_queue_global.size>0)machine_pop_from_global_event_queue();" + "\n\t\t}" "\n\t}" + ); + if(options->has_mutex) + fprintf(out,"\t\tmachine_mutex_unlock(event,machine);\n"); + fprintf(out, "\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) { @@ -444,4 +490,97 @@ void ast_expression_state_to_c(FILE *out,struct AST_State *state) ast_state_to_c_function_name(out,state->parent,state); } +void ast_to_c_print_event_queue_declaration(FILE *out) +{ + ast_to_c_print_comment(out, "\tthis queue is used when an event is received for a machine that is\n" + "\tcurrently in transit\n" + "\tdoes not guarantee any thread safety,\n" + "\tbut preserves intuitive order of execution\n" + "\tdo not use these manually" + ); + fprintf(out, "struct machine_queue_node_t\n" + "{\n" + "\tstruct machine_queue_node_t *prev;\n" + "\tmachine_buffer_t *input;\n" + "\tint event;\n" + "\tenum MACHINES_ENUM target_machine;\n" + "};\n" + ); + fprintf(out, "struct machine_queue_t\n" + "{\n" + "\tstruct machine_queue_node_t *first,*last;\n" + "\tsize_t size;\n" + "};\n" + ); + fprintf(out, "extern void machine_push_to_global_event_queue(machine_buffer_t *input,int event,enum MACHINES_ENUM target_machine);\n"); + fprintf(out, "extern void machine_pop_from_global_event_queue();\n"); +} +void ast_to_c_print_event_queue_definition(FILE *out) +{ + fprintf(out, "struct machine_queue_t machine_queue_global = { .first=NULL,.last=NULL,.size=0};\n"); + fprintf(out, "void machine_push_to_global_event_queue(machine_buffer_t *input,int event,enum MACHINES_ENUM target_machine)\n" + "{\n" + "\tif(machine_queue_global.size==0)\n" + "\t{\n" + "\t\tmachine_queue_global.first=machine_queue_global.last=malloc(sizeof(struct machine_queue_node_t));\n" + "\t\tmachine_queue_global.last->input=input;\n" + "\t\tmachine_queue_global.last->event=event;\n" + "\t\tmachine_queue_global.last->target_machine=target_machine;\n" + "\t\tmachine_queue_global.size=1;\n" + "\t}else\n" + "\t{\n" + "\t\tmachine_queue_global.last=machine_queue_global.last->prev=malloc(sizeof(struct machine_queue_node_t));\n" + "\t\tmachine_queue_global.last->input=input;\n" + "\t\tmachine_queue_global.last->event=event;\n" + "\t\tmachine_queue_global.last->target_machine=target_machine;\n" + "\t\t++machine_queue_global.size;\n" + "\t}\n" + "}\n" + + ); + + fprintf(out, "void machine_pop_from_global_event_queue()\n" + "{\n" + "\tstruct machine_queue_node_t *hold_node;\n" + "\thold_node=machine_queue_global.first;\n" + "\tmachine_queue_global.first=machine_queue_global.first->prev;\n" + "\tif(--machine_queue_global.size==0)\n" + "\t\tmachine_queue_global.last=NULL;\n" + "\tmachine_states[hold_node->target_machine](hold_node->event,hold_node->input);\n" + "\tfree(hold_node);\n" + "}\n" + ); +} +void ast_print_machine_buffer_declarations(FILE *out) +{ + 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"); + + fprintf(out,"extern 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,"extern void delete_machine_buffer(machine_buffer_t *buffer);\n\n"); +} +void ast_print_machine_buffer_definitions(FILE *out) +{ + 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}\n" + ); +} #endif diff --git a/src/backend/targets/C/ast_to_c.h b/src/backend/targets/C/ast_to_c.h index 299d6db..76b556c 100644 --- a/src/backend/targets/C/ast_to_c.h +++ b/src/backend/targets/C/ast_to_c.h @@ -3,21 +3,23 @@ #include <stdio.h> #include <parser.h> #include <backend.h> +#include <program.h> #include <ctype.h> #include <stdio.h> #include <string.h> struct State_And_Transitions; -void ast_to_c(char *output_name,struct AST_Translation_Unit *tree); +void ast_to_c(char *output_name,struct AST_Translation_Unit *tree,struct Options *options); -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_header_part(FILE *out,char *base_name,struct AST_Translation_Unit *translation_unit,struct Options *options); +void ast_translation_unit_to_c_print_body_part(FILE *out,char *base_name,struct AST_Translation_Unit *translation_unit,struct Options *options); +void ast_translation_unit_to_c_print_external_part(FILE *out,char *base_name,struct AST_Translation_Unit *translation_unit,struct Options *options); 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_print_external_commands(FILE *out,char *base_name,struct AST_Translation_Unit *translation_unit); 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); @@ -49,11 +51,16 @@ void ast_if_to_c(FILE *out,size_t indentation,struct AST_If_Statement *statement void ast_expression_to_c(FILE *out,struct AST *expression); void ast_expression_state_to_c(FILE *out,struct AST_State *state); -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_internal_stuff_for_header(FILE *out,struct AST_Translation_Unit *translation_unit,struct Options *options); +void ast_to_c_print_internal_stuff_for_body(FILE *out,struct Options *options); void ast_to_c_print_comment(FILE *out,char *comment); +void ast_to_c_print_event_queue_declaration(FILE *out); +void ast_to_c_print_event_queue_definition(FILE *out); + +void ast_print_machine_buffer_declarations(FILE *out); +void ast_print_machine_buffer_definitions(FILE *out); /* :X */ void ast_to_c_print_tabs(FILE *out,size_t number_of_tabs); diff --git a/src/backend/targets/print/print.c b/src/backend/targets/print/print.c index 3c33438..cfe22e9 100644 --- a/src/backend/targets/print/print.c +++ b/src/backend/targets/print/print.c @@ -87,6 +87,9 @@ void print_keyword_enum(enum Keyword code) case KW_ELSE: printf("KW_ELSE"); break; + case KW_GRANTED: + printf("KW_GRANTED"); + break; default: printf("LEXERROR"); } |