aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGalin Simeonov <gts@volconst.com>2021-07-14 00:23:47 +0300
committerGalin Simeonov <gts@volconst.com>2021-07-15 18:07:29 +0300
commit3877ff9860d2cbeda7127d932e45573ff0d9600b (patch)
tree26d827da8cf07003530a812a22c143baa6f3e757
parentc875f8795586056a676e8a643a44211041ce44d2 (diff)
downloadMEGATRON-3877ff9860d2cbeda7127d932e45573ff0d9600b.tar.gz
added context support
-rw-r--r--src/backend/targets/C/ast_to_c.c298
-rw-r--r--src/backend/targets/C/ast_to_c.h33
-rw-r--r--src/program/program.c16
-rw-r--r--src/program/program.h1
4 files changed, 239 insertions, 109 deletions
diff --git a/src/backend/targets/C/ast_to_c.c b/src/backend/targets/C/ast_to_c.c
index 76ebbfd..9b8f95c 100644
--- a/src/backend/targets/C/ast_to_c.c
+++ b/src/backend/targets/C/ast_to_c.c
@@ -75,7 +75,7 @@ void ast_translation_unit_to_c_print_header_part(FILE *out,char *base_name,struc
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_machine_to_c_make_header_part(out,translation_unit->machines[i],options);
if(base_name)
@@ -92,10 +92,9 @@ 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);
+ ast_to_c_print_internal_stuff_for_body(out,translation_unit,options);
for(i=0;i<translation_unit->number_of_machines;++i)
- ast_machine_to_c_make_body_part(out,translation_unit->machines[i]);
+ ast_machine_to_c_make_body_part(out,translation_unit->machines[i],options);
if(base_name)
@@ -111,9 +110,16 @@ void ast_translation_unit_to_c_print_external_part(FILE *out,char *base_name,str
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->has_context)
+ {
+ fprintf(out, "extern void machine_push_to_event_queue(machine_conotext_t *context, machine_buffer_t *input,int event,enum MACHINES_ENUM target_machine);\n");
+ fprintf(out, "extern void machine_pop_from__event_queue(machine_context_t *context);\n");
+ }else
+ {
+ 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)
{
@@ -132,17 +138,17 @@ void ast_translation_unit_to_c_print_external_part(FILE *out,char *base_name,str
ast_translation_unit_to_c_print_footer_string(out,base_name,"_EXTERNAL_H");
}
}
-void ast_machine_to_c(FILE *out,struct AST_Machine *machine)
+void ast_machine_to_c(FILE *out,struct AST_Machine *machine,struct Options *options)
{
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);
+ ast_machine_to_c_make_header_part(out,machine,options);
+ ast_machine_to_c_make_body_part(out,machine,options);
}
-void ast_machine_to_c_make_body_part(FILE *out,struct AST_Machine *machine)
+void ast_machine_to_c_make_body_part(FILE *out,struct AST_Machine *machine,struct Options *options)
{
size_t i;
struct State_And_Transitions **table;
@@ -151,18 +157,18 @@ void ast_machine_to_c_make_body_part(FILE *out,struct AST_Machine *machine)
for(i=0;i<machine->states->number_of_states;++i)
{
- ast_state_to_c_signature(out,machine,machine->states->states[i]);
+ ast_state_to_c_signature(out,machine,machine->states->states[i],options);
fprintf(out,"\n{\n");
- ast_transitions_of_state_to_c(out,machine,table[i]);
+ ast_transitions_of_state_to_c(out,machine,table[i],options);
fprintf(out,"\n}\n");
}
}
-void ast_machine_to_c_make_header_part(FILE *out,struct AST_Machine *machine)
+void ast_machine_to_c_make_header_part(FILE *out,struct AST_Machine *machine,struct Options *options)
{
- ast_events_to_c(out,machine);
- ast_states_to_c(out,machine);
+ ast_events_to_c(out,machine,options);
+ ast_states_to_c(out,machine,options);
}
-void ast_events_to_c(FILE *out,struct AST_Machine *machine)
+void ast_events_to_c(FILE *out,struct AST_Machine *machine,struct Options *options)
{
size_t i;
@@ -180,26 +186,30 @@ void ast_events_to_c(FILE *out,struct AST_Machine *machine)
}
fprintf(out,"};\n");
}
-void ast_states_to_c(FILE *out,struct AST_Machine *machine)
+void ast_states_to_c(FILE *out,struct AST_Machine *machine,struct Options *options)
{
size_t i;
assert(out!=NULL && machine!=NULL && machine->type==AST_TYPE_MACHINE);
for(i=0;i<machine->states->number_of_states;++i)
{
fprintf(out,"extern ");
- ast_state_to_c_signature(out,machine,machine->states->states[i]);
+ ast_state_to_c_signature(out,machine,machine->states->states[i],options);
fprintf(out,";\n");
}
}
-void ast_transitions_of_state_to_c(FILE *out,struct AST_Machine *machine,struct State_And_Transitions *vector)
+void ast_transitions_of_state_to_c(FILE *out,struct AST_Machine *machine,struct State_And_Transitions *vector,struct Options *options)
{
size_t i;
short indentation=3;
+ const char *context_arrow="";
+ if(options->has_context)
+ context_arrow="context->";
+
//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,"\n\t%smachine_states_lock=1;\n",context_arrow);
fprintf(out,"\tswitch(event)\n\t{\n");
for(i=0;i<vector->number_of_transitions;++i)
{
@@ -210,15 +220,15 @@ void ast_transitions_of_state_to_c(FILE *out,struct AST_Machine *machine,struct
if(vector->transitions[i]->granted)
{
fprintf(out,"\t\t\tif(");
- ast_expression_to_c(out,vector->transitions[i]->granted);
+ ast_expression_to_c(out,vector->transitions[i]->granted,options);
fprintf(out,")\n\t\t\t{\n");
indentation++;
}
//ast_pipeline_to_c(out,3,vector->transitions[i]->pipeline);
- ast_statement_to_c(out,indentation,vector->transitions[i]->statement);
+ ast_statement_to_c(out,indentation,vector->transitions[i]->statement,options);
ast_to_c_print_tabs(out,indentation);
- fprintf(out,"machine_states[");
+ fprintf(out,"%smachine_states[",context_arrow);
ast_token_to_c(out,machine->id);
fprintf(out,"]=");
ast_state_to_c_function_name(out,machine,vector->transitions[i]->to);
@@ -233,7 +243,7 @@ void ast_transitions_of_state_to_c(FILE *out,struct AST_Machine *machine,struct
fprintf(out,"\t}\n");
}
fprintf(out,"\tdelete_machine_buffer(input);\n");
- fprintf(out,"\n\tmachine_states_lock=0;");
+ fprintf(out,"\n\t%smachine_states_lock=0;\n",context_arrow);
}
/*prints the enum tag for the given machine*/
@@ -243,11 +253,11 @@ void ast_machine_enum_tag(FILE *out,struct AST_Machine *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)
+void ast_state_to_c_signature(FILE *out,struct AST_Machine *machine,struct AST_State *state,struct Options *options)
{
fprintf(out,"void ");
ast_state_to_c_function_name(out,machine,state);
- fprintf(out,"(int event,machine_buffer_t *input)");
+ fprintf(out,"(%sint event,machine_buffer_t *input)",(options->has_context?"machine_context_t *context,":""));
}
void ast_token_to_c(FILE *out,struct token *token)
{
@@ -302,19 +312,29 @@ 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)
+void ast_machines_to_c_array(FILE *out,struct AST_Translation_Unit *translation_unit,struct Options *options,short indent)
{
size_t i;
- fprintf(out,"void (*machine_states[])(int,machine_buffer_t*)={");
- for(i=0;i<translation_unit->number_of_machines;++i)
+ ast_to_c_print_tabs(out,indent);
+ fprintf(out,"void (*machine_states[%zu])(%sint,machine_buffer_t*)",translation_unit->number_of_machines,(options->has_context?"machine_context_t *context,":""));
+ if(options->has_context==0)
{
- ast_state_to_c_function_name(out,translation_unit->machines[i],translation_unit->machines[i]->starting_state);
- fprintf(out,",");
- }
- fprintf(out,"};\n");
+ fprintf(out,"={ ");
+ 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,"}");
+ }
+ fprintf(out,";\n");
- fprintf(out,"_Bool machine_states_lock=0;\n");
+ ast_to_c_print_tabs(out,indent);
+ fprintf(out,"_Bool machine_states_lock");
+ if(options->has_context==0)
+ fprintf(out,"=0");
+ fprintf(out,";\n");
}
void ast_machines_to_c_enum(FILE *out,struct AST_Translation_Unit *translation_unit)
{
@@ -348,6 +368,7 @@ void ast_to_c_print_internal_stuff_for_header(FILE *out,struct AST_Translation_U
ast_machines_to_c_enum(out,translation_unit);
fprintf(out,"\n\n");
+
if(options->providing_own_buffer_implementation)
{
fprintf(out,"typedef struct machine_buffer_t machine_buffer_t\t\n");
@@ -355,8 +376,23 @@ void ast_to_c_print_internal_stuff_for_header(FILE *out,struct AST_Translation_U
{
ast_print_machine_buffer_declarations(out);
}
+
if(!options->providing_own_queue_implementation)
- ast_to_c_print_event_queue_declaration(out);
+ ast_to_c_print_event_struct_queue_declaration(out,options);
+
+ /*the context struct should go here*/
+ if(options->has_context)
+ {
+ fprintf(out,"typedef struct machine_context_s machine_context_t;\n");
+ fprintf(out, "struct machine_context_s\n{\n");
+ ast_machines_to_c_array(out,translation_unit,options,1);
+ fprintf(out,"\tstruct machine_queue_t machine_queue;\n");
+ fprintf(out, "};\n\n");
+ fprintf(out, "void machine_context_init(machine_context_t *context);\n");
+ fprintf(out, "void machine_context_destroy(machine_context_t *context);\n");
+
+ }
+ ast_to_c_print_event_functions_queue_declaration(out,options);
ast_to_c_print_comment(out, "\tuse this function to pass an event to a machine\n"
@@ -366,43 +402,83 @@ void ast_to_c_print_internal_stuff_for_header(FILE *out,struct AST_Translation_U
"\tinput can be NULL"
);
- fprintf(out,"extern void push_event_to_machine(enum MACHINES_ENUM machine,int event,machine_buffer_t *input);\n\n");
+ if(options->has_context)
+ fprintf(out,"extern void push_event_to_machine(machine_context_t *context,enum MACHINES_ENUM machine,int event,machine_buffer_t *input);\n\n");
+ else
+ fprintf(out,"extern 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"
- );
-
}
-void ast_to_c_print_internal_stuff_for_body(FILE *out,struct Options *options)
+void ast_to_c_print_internal_stuff_for_body(FILE *out,struct AST_Translation_Unit *translation_unit,struct Options *options)
{
-
+ const char *context_arrow="";
+ const char *context_comma="";
+ const char *context="";
+ const char *global="_global";
+
+ if(options->has_context==0)
+ {
+ ast_machines_to_c_array(out,translation_unit,options,0);
+ fprintf(out,"struct machine_queue_t machine_queue_global = { .first=NULL,.last=NULL,.size=0};\n");
+ }else
+ {
+ size_t which_machine;
+
+ context_comma="context,";
+ context="context";
+ context_arrow="context->";
+ global="";
+ fprintf(out, "void machine_context_init(machine_context_t *context)\n{\n\tcontext->machine_queue=(struct machine_queue_t){ .first=NULL,.last=NULL,.size=0};\n");
+ for(which_machine=0;which_machine<translation_unit->number_of_machines;++which_machine)
+ {
+ fprintf(out,"\tcontext->machine_states[%zu]=",which_machine);
+ ast_state_to_c_function_name(out,translation_unit->machines[which_machine],translation_unit->machines[which_machine]->starting_state);
+ fprintf(out,";\n");
+ }
+ fprintf(out,"\n}\n");
+ fprintf(out, "void machine_context_destroy(machine_context_t *context)\n{\n\t"
+ "\tstruct machine_queue_node_t *hold_node;\n"
+ "\thold_node=context->machine_queue.first;\n"
+ "\twhile(hold_node!=NULL)\n"
+ "\t{\n"
+ "\t\tcontext->machine_queue.first=context->machine_queue.first->prev;\n"
+ "\t\tfree(hold_node);\n"
+ "\t\thold_node=context->machine_queue.first;\n"
+ "\t}\n"
+ "\n}\n"
+ );
+
+ }
if(!options->providing_own_queue_implementation)
- ast_to_c_print_event_queue_definition(out);
+ ast_to_c_print_event_queue_definition(out,options);
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"
+ if(options->has_context)
+ fprintf(out,"void push_event_to_machine(machine_context_t *context,enum MACHINES_ENUM machine,int event,machine_buffer_t *input)\n");
+ else
+ fprintf(out,"void push_event_to_machine(enum MACHINES_ENUM machine,int event,machine_buffer_t *input)\n");
+
+ fprintf(out, "{\n"
"\tif(machine<MACHINES_ENUM_END)"
"\n\t{"
);
if(options->has_mutex)
fprintf(out,"\t\tmachine_mutex_lock(input,event,machine);\n");
fprintf(out,
- "\n\t\tif(machine_states_lock)"
+ "\n\t\tif(%smachine_states_lock)"
"\n\t\t{"
- "\n\t\t\tmachine_push_to_global_event_queue(input,event,machine);"
+ "\n\t\t\tmachine_push_to%s_event_queue(%sinput,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\t%smachine_states[machine](%sevent,input);"
+ "\n\t\t\twhile(%smachine_queue%s.size>0)machine_pop_from%s_event_queue(%s);"
"\n\t\t}"
"\n\t}"
+ ,context_arrow,global,context_comma,context_arrow,(options->has_context?"context,":""),context_arrow,global,global,context
);
if(options->has_mutex)
fprintf(out,"\t\tmachine_mutex_unlock(event,machine);\n");
@@ -417,28 +493,28 @@ void ast_to_c_print_comment(FILE *out,char *comment)
fprintf(out,"%s\n",comment);
fprintf(out,"*/\n");
}
-void ast_statement_to_c(FILE *out,size_t indentation,struct AST *statement)
+void ast_statement_to_c(FILE *out,size_t indentation,struct AST *statement,struct Options *options)
{
if(statement==NULL)return;
if(statement->type==AST_TYPE_PIPELINE)
ast_pipeline_to_c(out,indentation,(struct AST_Pipeline*)statement);
else if(statement->type==AST_TYPE_IF)
- ast_if_to_c(out,indentation,(struct AST_If_Statement*)statement);
+ ast_if_to_c(out,indentation,(struct AST_If_Statement*)statement,options);
else
assert(0);
}
-void ast_if_to_c(FILE *out,size_t indentation,struct AST_If_Statement *statement)
+void ast_if_to_c(FILE *out,size_t indentation,struct AST_If_Statement *statement,struct Options *options)
{
ast_to_c_print_tabs(out,indentation);
fprintf(out,"if");
- ast_expression_to_c(out,statement->condition);
+ ast_expression_to_c(out,statement->condition,options);
fprintf(out,"\n");
ast_to_c_print_tabs(out,indentation);
fprintf(out,"{\n");
- ast_statement_to_c(out,indentation+1,statement->body);
+ ast_statement_to_c(out,indentation+1,statement->body,options);
ast_to_c_print_tabs(out,indentation);
fprintf(out,"}");
@@ -446,34 +522,34 @@ void ast_if_to_c(FILE *out,size_t indentation,struct AST_If_Statement *statement
{
fprintf(out,"else{\n");
- ast_statement_to_c(out,indentation+1,statement->else_statement);
+ ast_statement_to_c(out,indentation+1,statement->else_statement,options);
ast_to_c_print_tabs(out,indentation);
fprintf(out,"}");
}
fprintf(out,"\n");
}
-void ast_expression_to_c(FILE *out,struct AST *expression)
+void ast_expression_to_c(FILE *out,struct AST *expression,struct Options *options)
{
fprintf(out,"(");
switch(expression->type)
{
case AST_TYPE_OP_OR:
- ast_expression_to_c(out,AS_BIN_EXPR_PTR(expression)->left);
+ ast_expression_to_c(out,AS_BIN_EXPR_PTR(expression)->left,options);
fprintf(out,"||");
- ast_expression_to_c(out,AS_BIN_EXPR_PTR(expression)->right);
+ ast_expression_to_c(out,AS_BIN_EXPR_PTR(expression)->right,options);
break;
case AST_TYPE_OP_NOT:
fprintf(out,"!");
- ast_expression_to_c(out,AS_UN_EXPR_PTR(expression)->operand);
+ ast_expression_to_c(out,AS_UN_EXPR_PTR(expression)->operand,options);
break;
case AST_TYPE_OP_AND:
- ast_expression_to_c(out,AS_BIN_EXPR_PTR(expression)->left);
+ ast_expression_to_c(out,AS_BIN_EXPR_PTR(expression)->left,options);
fprintf(out,"&&");
- ast_expression_to_c(out,AS_BIN_EXPR_PTR(expression)->right);
+ ast_expression_to_c(out,AS_BIN_EXPR_PTR(expression)->right,options);
break;
case AST_TYPE_STATE:
- ast_expression_state_to_c(out,(struct AST_State*)expression);
+ ast_expression_state_to_c(out,(struct AST_State*)expression,options);
break;
case AST_TYPE_OP_SELECTOR:
assert(!"selector in final product!\n");
@@ -482,16 +558,17 @@ void ast_expression_to_c(FILE *out,struct AST *expression)
}
fprintf(out,")");
}
-void ast_expression_state_to_c(FILE *out,struct AST_State *state)
+void ast_expression_state_to_c(FILE *out,struct AST_State *state,struct Options *options)
{
- fprintf(out,"machine_states[");
+ fprintf(out,"%smachine_states[",(options->has_context?"context->":""));
ast_token_to_c(out,state->parent->id);
fprintf(out,"]==");
ast_state_to_c_function_name(out,state->parent,state);
}
-void ast_to_c_print_event_queue_declaration(FILE *out)
+void ast_to_c_print_event_struct_queue_declaration(FILE *out,struct Options *options)
{
+ const char *queue="global_event_queue";
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"
@@ -512,43 +589,74 @@ void ast_to_c_print_event_queue_declaration(FILE *out)
"\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)
+void ast_to_c_print_event_functions_queue_declaration(FILE *out,struct Options *options)
+{
+ const char *queue="global_event_queue";
+ if(options->has_context)
+ queue="event_queue";
+ fprintf(out, "extern void machine_push_to_%s(",queue);
+ if(options->has_context)
+ fprintf(out,"machine_context_t *context,");
+ fprintf(out,"machine_buffer_t *input,int event,enum MACHINES_ENUM target_machine);\n");
+ fprintf(out,"extern void machine_pop_from_%s(",queue);
+ if(options->has_context)
+ fprintf(out,"machine_context_t *context");
+ fprintf(out,");\n");
+}
+void ast_to_c_print_event_queue_definition(FILE *out,struct Options *options)
{
- 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"
+ const char *queue="machine_queue_global";
+ const char *machines_stuff="";
+
+ fprintf(out, "void machine_push_to_");
+ if(options->has_context)
+ {
+ fprintf(out,"event_queue(machine_context_t *context,");
+ queue="context->machine_queue";
+ machines_stuff="context->";
+ }else
+ {
+ fprintf(out,"global_event_queue(");
+ }
+
+ fprintf(out, "machine_buffer_t *input,int event,enum MACHINES_ENUM target_machine)\n"
"{\n"
- "\tif(machine_queue_global.size==0)\n"
+ "\tif(%s.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\t%s.first=%s.last=malloc(sizeof(struct machine_queue_node_t));\n"
+ "\t\t%s.last->input=input;\n"
+ "\t\t%s.last->event=event;\n"
+ "\t\t%s.last->target_machine=target_machine;\n"
+ "\t\t%s.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\t%s.last=%s.last->prev=malloc(sizeof(struct machine_queue_node_t));\n"
+ "\t\t%s.last->input=input;\n"
+ "\t\t%s.last->event=event;\n"
+ "\t\t%s.last->target_machine=target_machine;\n"
+ "\t\t++%s.size;\n"
"\t}\n"
- "}\n"
-
+ "}\n",queue,queue,queue,queue,queue,queue,queue,queue,queue,queue,queue,queue,queue,queue,queue
);
- fprintf(out, "void machine_pop_from_global_event_queue()\n"
- "{\n"
+ fprintf(out, "void machine_pop_from");
+ if(options->has_context)
+ {
+ fprintf(out,"_event_queue(machine_context_t *context)\n");
+ }else
+ {
+ fprintf(out,"_global_event_queue()\n");
+ }
+ fprintf(out, "{\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"
+ "\thold_node=%s.first;\n"
+ "\t%s.first=%s.first->prev;\n"
+ "\tif(--%s.size==0)\n"
+ "\t\t%s.last=NULL;\n"
+ "\t%smachine_states[hold_node->target_machine](%shold_node->event,hold_node->input);\n"
"\tfree(hold_node);\n"
- "}\n"
+ "}\n",queue,queue,queue,queue,queue,machines_stuff,(options->has_context?"context,":"")
);
}
void ast_print_machine_buffer_declarations(FILE *out)
@@ -557,6 +665,10 @@ void ast_print_machine_buffer_declarations(FILE *out)
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, "\tthis function creates a buffer structure in the heap\n"
+ "\tit COPIES the contents of content \n"
+ "\tsize is in bytes"
+ );
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");
diff --git a/src/backend/targets/C/ast_to_c.h b/src/backend/targets/C/ast_to_c.h
index 76b556c..7e97f02 100644
--- a/src/backend/targets/C/ast_to_c.h
+++ b/src/backend/targets/C/ast_to_c.h
@@ -22,42 +22,43 @@ void ast_translation_unit_to_c_print_footer_string(FILE *out,char *base_name,cha
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);
-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_machine_to_c(FILE *out,struct AST_Machine *machine,struct Options *options);
+void ast_machine_to_c_make_header_part(FILE *out,struct AST_Machine *machine,struct Options *options);
+void ast_machine_to_c_make_body_part(FILE *out,struct AST_Machine *machine,struct Options *options);
-void ast_events_to_c(FILE *out,struct AST_Machine *machine);
-void ast_states_to_c(FILE *out,struct AST_Machine *machine);
+void ast_events_to_c(FILE *out,struct AST_Machine *machine,struct Options *options);
+void ast_states_to_c(FILE *out,struct AST_Machine *machine,struct Options *options);
void ast_command_to_c(FILE *out,struct AST_Command *command,char *hold_buffer);
-/*note the ordering*/
+/*note the ordering of parameters*/
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_transitions_of_state_to_c(FILE *out,struct AST_Machine *machine,struct State_And_Transitions *vector,struct Options *options);
void ast_token_to_c(FILE *out,struct token *token);
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_signature(FILE *out,struct AST_Machine *machine,struct AST_State *state,struct Options *options);
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_array(FILE *out,struct AST_Translation_Unit *translation_unit,struct Options *options,short indent);
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_statement_to_c(FILE *out,size_t indentation,struct AST *statement);
-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_statement_to_c(FILE *out,size_t indentation,struct AST *statement,struct Options *options);
+void ast_if_to_c(FILE *out,size_t indentation,struct AST_If_Statement *statement,struct Options *options);
+void ast_expression_to_c(FILE *out,struct AST *expression,struct Options *options);
+void ast_expression_state_to_c(FILE *out,struct AST_State *state,struct Options *options);
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_internal_stuff_for_body(FILE *out,struct AST_Translation_Unit *translation_unit,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_to_c_print_event_struct_queue_declaration(FILE *out,struct Options *options);
+void ast_to_c_print_event_functions_queue_declaration(FILE *out,struct Options *options);
+void ast_to_c_print_event_queue_definition(FILE *out,struct Options *options);
void ast_print_machine_buffer_declarations(FILE *out);
void ast_print_machine_buffer_definitions(FILE *out);
diff --git a/src/program/program.c b/src/program/program.c
index 09650ec..a5226dc 100644
--- a/src/program/program.c
+++ b/src/program/program.c
@@ -51,6 +51,7 @@ struct Options* parse_command_line(int argc,char **argv)
ret->providing_own_queue_implementation=0;
ret->providing_own_buffer_implementation=0;
ret->has_mutex=0;
+ ret->has_context=0; /*inline is the default*/
for(i=0;i<argc;++i)
{
@@ -66,6 +67,21 @@ struct Options* parse_command_line(int argc,char **argv)
ret->providing_own_buffer_implementation=1;
else if(!strncmp(argv[i],"--extern-mutex",sizeof("--extern-mutex")))
ret->has_mutex=1;
+ else if(!strncmp(argv[i],"--with-context",sizeof("--extern-mutex")))
+ ret->has_context=1;
+ else if(!strncmp(argv[i],"--help",sizeof("--help")) || !strncmp(argv[i],"-h",sizeof("-h")))
+ {
+ printf("Wonky automata options:\n"
+ "--print-tokens Prints the tokens of the programs, used for debugging\n"
+ "--print-ast Prints the ast of the program, used for debugging\n"
+ "--print-c Transpiles to C and outputs the result to stdout ( default )\n"
+ "--extern-queue delegates the queue implementation to user\n"
+ "--extern-buffer delegates the buffer implementation to the user\n"
+ "--extern-mutex delegates the mutex implementation to the user and generates mutex guards\n"
+ "--with-context have a context struct, so you can have multiple instances of the automata\n"
+ "\n");
+ exit(0);
+ }
else if(!strncmp(argv[i],"-o",sizeof("-o")) || !strncmp(argv[i],"--output",sizeof("--output")))
{
if(++i<argc)
diff --git a/src/program/program.h b/src/program/program.h
index 214e812..370cac6 100644
--- a/src/program/program.h
+++ b/src/program/program.h
@@ -36,6 +36,7 @@ struct Options
int providing_own_queue_implementation:1;
int providing_own_buffer_implementation:1;
int has_mutex:1;
+ int has_context:1;
char *src_name;
char *output_name;
};