aboutsummaryrefslogtreecommitdiffstats
path: root/src/backend/targets
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/targets')
-rw-r--r--src/backend/targets/C/ast_to_c.c231
-rw-r--r--src/backend/targets/C/ast_to_c.h19
-rw-r--r--src/backend/targets/print/print.c3
3 files changed, 201 insertions, 52 deletions
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");
}