diff options
Diffstat (limited to 'src/backend')
-rw-r--r-- | src/backend/backend.c | 37 | ||||
-rw-r--r-- | src/backend/backend.h | 18 | ||||
-rw-r--r-- | src/backend/targets/C/ast_to_c.c | 155 | ||||
-rw-r--r-- | src/backend/targets/C/ast_to_c.h | 29 | ||||
-rw-r--r-- | src/backend/targets/print/print.c (renamed from src/backend/print.c) | 5 | ||||
-rw-r--r-- | src/backend/targets/print/print.h (renamed from src/backend/print.h) | 0 |
6 files changed, 242 insertions, 2 deletions
diff --git a/src/backend/backend.c b/src/backend/backend.c new file mode 100644 index 0000000..122e84c --- /dev/null +++ b/src/backend/backend.c @@ -0,0 +1,37 @@ +#ifndef BACKEND_C +#define BACKEND_C BACKEND_C +#include <backend.h> + +/*returns an array of pointers to state_and_transition structs*/ +struct State_And_Transitions** extract_transition_table(struct AST_States *states,struct AST_Transitions *transitions) +{ + struct State_And_Transitions **ret; + struct Queue *qs; + size_t i; + + ret=malloc(sizeof(struct State_And_Transitions)*states->number_of_states); + + /*calloc also initialises the queues + *i-th queue is for transitions starting from the i-th state + * */ + qs=calloc(sizeof(struct Queue),states->number_of_states); + + /*traverse transitions and push them into the queue of their coresponding state*/ + for(i=0;i<transitions->size;++i) + Queue_Push(qs+transitions->transitions[i]->from->number,transitions->transitions[i]); + + /*condense the queues into the arrays*/ + for(i=0;i<states->number_of_states;++i) + { + ret[i]=malloc(sizeof(struct State_And_Transitions)+sizeof(struct AST_Transitions *[qs[i].size])); + ret[i]->state=states->states[i]; + ret[i]->number_of_transitions=qs[i].size; + pointer_array_fill((void**)ret[i]->transitions,qs+i); + } + + free(qs); + + return ret; +} + +#endif diff --git a/src/backend/backend.h b/src/backend/backend.h new file mode 100644 index 0000000..1857cd0 --- /dev/null +++ b/src/backend/backend.h @@ -0,0 +1,18 @@ +#ifndef BACKEND_H +#define BACKEND_H BACKEND_H +#include <parser.h> +#include <ast_to_c.h> + +/* + * describes a given state and the transitions coming out of it + * I should probbably have done this in the parsing stage + */ +struct State_And_Transitions +{ + struct AST_State *state; + size_t number_of_transitions; + struct AST_Transition *transitions[]; +}; +/*returns an array of state_and_transition structs*/ +struct State_And_Transitions** extract_transition_table(struct AST_States *states,struct AST_Transitions *transitions); +#endif diff --git a/src/backend/targets/C/ast_to_c.c b/src/backend/targets/C/ast_to_c.c new file mode 100644 index 0000000..346801c --- /dev/null +++ b/src/backend/targets/C/ast_to_c.c @@ -0,0 +1,155 @@ +#ifndef AST_TO_C_C +#define AST_TO_C_C AST_TO_C_C +#include <ast_to_c.h> +#include <print.h> + +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;i<machine->states->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;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); + 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;i<machine->states->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;i<vector->number_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;i<token->size;++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;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,";\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<number_of_tabs;++i) + fprintf(out,"\t"); +} +#endif diff --git a/src/backend/targets/C/ast_to_c.h b/src/backend/targets/C/ast_to_c.h new file mode 100644 index 0000000..8c86687 --- /dev/null +++ b/src/backend/targets/C/ast_to_c.h @@ -0,0 +1,29 @@ +#ifndef AST_TO_C_H +#define AST_TO_C_H AST_TO_C_H +#include <stdio.h> +#include <parser.h> +#include <backend.h> +#include <ctype.h> + +struct State_And_Transitions; + +void ast_to_c(FILE *out,struct AST *tree); +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); + +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_state_to_c_signature(FILE *out,struct AST_Machine *machine,struct AST_State *state); +/* :X */ +void ast_to_c_print_tabs(FILE *out,size_t number_of_tabs); + +#endif diff --git a/src/backend/print.c b/src/backend/targets/print/print.c index 614a6c9..8eae3dd 100644 --- a/src/backend/print.c +++ b/src/backend/targets/print/print.c @@ -169,7 +169,8 @@ void print_ast_state(struct AST_State* tree) assert(tree); printf("[ STATE: "); - print_ast_enum(tree->type); + print_token(tree->name); + printf(" %ld",tree->number); printf("]"); } void print_ast_event(struct AST_Event* tree) @@ -177,7 +178,7 @@ void print_ast_event(struct AST_Event* tree) assert(tree); printf("[ EVENT: "); - print_ast_enum(tree->type); + print_token(tree->name); printf("]"); } void print_ast_states(struct AST_States* tree) diff --git a/src/backend/print.h b/src/backend/targets/print/print.h index 54d47ce..54d47ce 100644 --- a/src/backend/print.h +++ b/src/backend/targets/print/print.h |