aboutsummaryrefslogtreecommitdiffstats
path: root/src/backend/targets/C
diff options
context:
space:
mode:
authorGalin Simeonov <gts@volconst.com>2021-06-03 12:38:37 +0300
committerGalin Simeonov <gts@volconst.com>2021-07-15 18:04:02 +0300
commit76fc38b3cdfded2911b464baa7b182b5102318d1 (patch)
tree389223f76086bff07a3cd762683e5a16d34d12d2 /src/backend/targets/C
parent85b23fbee717f047af5a89eac6f4dba8e7812524 (diff)
downloadMEGATRON-76fc38b3cdfded2911b464baa7b182b5102318d1.tar.gz
work on generated C code
Diffstat (limited to 'src/backend/targets/C')
-rw-r--r--src/backend/targets/C/ast_to_c.c288
-rw-r--r--src/backend/targets/C/ast_to_c.h36
2 files changed, 285 insertions, 39 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
diff --git a/src/backend/targets/C/ast_to_c.h b/src/backend/targets/C/ast_to_c.h
index 8c86687..6e4006f 100644
--- a/src/backend/targets/C/ast_to_c.h
+++ b/src/backend/targets/C/ast_to_c.h
@@ -4,25 +4,53 @@
#include <parser.h>
#include <backend.h>
#include <ctype.h>
+#include <stdio.h>
+#include <string.h>
struct State_And_Transitions;
-void ast_to_c(FILE *out,struct AST *tree);
+void ast_to_c(char *output_name,struct AST *tree);
+
+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_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(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_events_to_c(FILE *out,struct AST_Machine *machine);
void ast_states_to_c(FILE *out,struct AST_Machine *machine);
-void ast_pipeline_to_c(FILE *out,size_t indentation,struct AST_Pipeline *pipeline);
void ast_command_to_c(FILE *out,struct AST_Command *command,char *hold_buffer);
-void ast_command_to_c_signature(FILE *out,struct AST_Command *command);
+
+/*note the ordering*/
+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_token_to_c(FILE *out,struct token *token);
-void ast_event_name_to_c(FILE *out,struct AST_Machine *machine);
+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_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_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_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_comment(FILE *out,char *comment);
+
+
+
/* :X */
void ast_to_c_print_tabs(FILE *out,size_t number_of_tabs);