MEGATRON



LOG | FILES | OVERVIEW


F diff --git a/CMakeLists.txt b/CMakeLists.txt --- a/CMakeLists.txt +++ b/CMakeLists.txt
include_directories(src/)
include_directories(src/backend/)
+ include_directories(src/backend/targets/)
+ include_directories(src/backend/targets/print/)
+ include_directories(src/backend/targets/C/)
include_directories(src/frontend/)
include_directories(src/misc/)
include_directories(src/program/)
set(SOURCES
- src/program/program.h
- src/program/program.c
- src/misc/queue.h
- src/misc/stack.h
- src/misc/map.h
- src/misc/queue.c
- src/misc/map.c
- src/misc/stack.c
+ src/backend/targets/C/ast_to_c.c
+ src/backend/targets/C/ast_to_c.h
+ src/backend/targets/print/print.c
+ src/backend/targets/print/print.h
+ src/backend/backend.c
+ src/backend/backend.h
+ src/frontend/lexer.c
src/frontend/lexer.h
src/frontend/parser.c
- src/frontend/lexer.c
src/frontend/parser.h
- src/backend/print.h
- src/backend/print.c
src/main.c
+ src/misc/map.c
+ src/misc/map.h
+ src/misc/queue.c
+ src/misc/queue.h
+ src/misc/stack.c
+ src/misc/stack.h
+ src/program/program.c
+ src/program/program.h
)
add_executable(main ${SOURCES})
F diff --git a/src/backend/backend.c b/src/backend/backend.c new file mode 100644 --- /dev/null +++ b/src/backend/backend.c
+ #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
F diff --git a/src/backend/backend.h b/src/backend/backend.h new file mode 100644 --- /dev/null +++ b/src/backend/backend.h
+ #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
F diff --git a/src/backend/print.c b/src/backend/print.c deleted file mode 100644 --- a/src/backend/print.c +++ /dev/null
- #ifndef PRINT_C
- #define PRINT_C PRINT_C
- #include<print.h>
-
- void print_keyword_enum(enum Keyword code)
- {
- switch(code)
- {
- case KW_MACHINE:
- printf("KW_MACHINE");
- break;
- case KW_FROM:
- printf("KW_FROM");
- break;
- case KW_TO:
- printf("KW_TO");
- break;
- case KW_ON:
- printf("KW_ON");
- break;
- case KW_ID:
- printf("KW_ID");
- break;
- case KW_STRING:
- printf("KW_STRING");
- break;
- case KW_NOP:
- printf("KW_NOP");
- break;
- case KW_EOF:
- printf("KW_EOF");
- break;
- case KW_OPEN_SQUARE:
- printf("KW_OPEN_SQUARE");
- break;
- case KW_CLOSE_SQUARE:
- printf("KW_CLOSE_SQUARE");
- break;
- case KW_PIPE:
- printf("KW_PIPE");
- break;
- case KW_SEMI_COLUMN:
- printf("KW_SEMI_COLUMN");
- break;
- case KW_STARTING:
- printf("KW_STARTING");
- break;
- case KW_STATES:
- printf("KW_STATES");
- break;
- case KW_EVENTS:
- printf("KW_EVENTS");
- break;
- case KW_EVENT:
- printf("KW_EVENT");
- break;
- case KW_TRANSITIONS:
- printf("KW__TRANSITIONS");
- break;
- case KW_EXECUTE:
- printf("KW_EXECUTE");
- break;
- case KW_COMMA:
- printf("KW_COMMA");
- break;
- default:
- printf("LEXERROR");
- }
- }
- void print_token(struct token *token)
- {
- size_t i;
- assert(token);
-
- printf("[ ");
- print_keyword_enum(token->type);
- printf(" ");
- for(i=0;i<token->size;++i)
- printf("%c",token->data[i]);
- printf(" ] ");
-
- }
- void print_tokens(struct Queue *tokens)
- {
- struct Queue_Node *it;
- assert(tokens);
-
- for(it=tokens->first;it!=NULL;it=it->prev)
- {
- print_token( (struct token*)(it->data));
- printf(" ");
- }
- }
- void print_ast_enum(enum AST_Type type)
- {
- switch(type)
- {
- case AST_TYPE_MACHINE:
- printf("AST_TYPE_MACHINE");
- break;
- case AST_TYPE_STATE:
- printf("AST_TYPE_STATE");
- break;
- case AST_TYPE_STATES:
- printf("AST_TYPE_STATES");
- break;
- case AST_TYPE_EVENT:
- printf("AST_TYPE_EVENT");
- break;
- case AST_TYPE_EVENTS:
- printf("AST_TYPE_EVENTS");
- break;
- case AST_TYPE_TRANSITION:
- printf("AST_TYPE_TRANSITION");
- break;
- case AST_TYPE_TRANSITIONS:
- printf("AST_TYPE_TRANSITIONS");
- break;
- case AST_TYPE_COMMAND:
- printf("AST_TYPE_COMMAND");
- break;
- case AST_TYPE_PIPELINE:
- printf("AST_TYPE_PIPELINE");
- break;
- default:
- printf("AST_NOP");
- }
-
- }
- void print_ast(struct AST *tree)
- {
- assert(tree);
-
- switch(tree->type)
- {
- case AST_TYPE_MACHINE:
- print_ast_machine((struct AST_Machine*)tree);
- break;
- case AST_TYPE_STATE:
- print_ast_state((struct AST_State*)tree);
- break;
- case AST_TYPE_STATES:
- print_ast_states((struct AST_States*)tree);
- break;
- case AST_TYPE_EVENT:
- print_ast_event((struct AST_Event*)tree);
- break;
- case AST_TYPE_EVENTS:
- print_ast_events((struct AST_Events*)tree);
- break;
- case AST_TYPE_TRANSITION:
- print_ast_transition((struct AST_Transition*)tree);
- break;
- case AST_TYPE_TRANSITIONS:
- print_ast_transitions((struct AST_Transitions*)tree);
- break;
- case AST_TYPE_COMMAND:
- print_ast_command((struct AST_Command*)tree);
- break;
- case AST_TYPE_PIPELINE:
- print_ast_pipeline((struct AST_Pipeline*)tree);
- break;
- default:
- printf("noast");
- }
- }
- void print_ast_state(struct AST_State* tree)
- {
- assert(tree);
-
- printf("[ STATE: ");
- print_ast_enum(tree->type);
- printf("]");
- }
- void print_ast_event(struct AST_Event* tree)
- {
- assert(tree);
-
- printf("[ EVENT: ");
- print_ast_enum(tree->type);
- printf("]");
- }
- void print_ast_states(struct AST_States* tree)
- {
- size_t i;
- assert(tree);
-
- printf("STATES [\n");
- for(i=0;i<tree->number_of_states;++i)
- {
- print_ast_state(tree->states[i]);
- printf(" ");
- }
- printf("\n ] END STATES \n");
- }
- void print_ast_events(struct AST_Events* tree)
- {
- size_t i;
- assert(tree);
-
- printf("EVENTS [\n");
- for(i=0;i<tree->number_of_events;++i)
- {
- print_ast_event(tree->events[i]);
- printf(" ");
- }
- printf("\n ] END EVENTS \n");
- }
- void print_ast_transition(struct AST_Transition* tree)
- {
- assert(tree);
-
- printf("TRANSITION [\nFROM");
- print_ast_state(tree->from);
- printf(" TO ");
- print_ast_state(tree->to);
- printf(" COMMAND {");
- if(tree->pipeline==NULL)
- {
- printf("NULL");
- }else
- {
- print_ast_pipeline(tree->pipeline);
- }
-
- }
- void print_ast_command(struct AST_Command* tree)
- {
- assert(tree);
-
- printf("( command ");
- print_token(tree->function_name);
- if(tree->argument==NULL)
- {
- printf(" NOARGUMENTS ");
- }else
- {
- printf(" \"");
- print_token(tree->argument);
- printf("\" ");
- }
- printf(")");
- }
- void print_ast_pipeline(struct AST_Pipeline* tree)
- {
- size_t i;
- assert(tree);
- printf("PIPELINE <");
- for(i=0;i<tree->size;++i)
- {
- print_ast_command(tree->pipeline[i]);
- printf(" | ");
- }
- printf("> PIPELINE_END");
- }
- void print_ast_machine(struct AST_Machine* tree)
- {
- assert(tree);
- printf("MACHINE ");
- print_token(tree->id);
- printf(" [\n");
- print_ast_states(tree->states);
- print_ast_events(tree->events);
- print_ast_transitions(tree->transitions);
- printf("] MACHINE_END\n");
- }
- void print_ast_transitions(struct AST_Transitions* tree)
- {
- size_t i;
- assert(tree);
- printf("TRANSITIONS [\n");
- for(i=0;i<tree->size;++i)
- {
- print_ast_transition(tree->transitions[i]);
- printf("\n");
- }
- printf("] TRANSITIONS_END\n");
- }
- void print_error(struct Error *error)
- {
- assert(error);
- printf("Error: %s, line %ld row %ld\n",error->message,error->row,error->column);
- }
- void print_errors(struct Translation_Data *translation_data)
- {
- struct Queue_Node *it;
- assert(translation_data);
-
- for(it=translation_data->errors->first;it!=NULL;it=it->prev)
- {
- print_error(it->data);
- }
- }
- #endif
F diff --git a/src/backend/print.h b/src/backend/print.h deleted file mode 100644 --- a/src/backend/print.h +++ /dev/null
- #ifndef PRINT_H
- #define PRINT_H PRINT_H
- #include <stdio.h>
- #include <lexer.h>
- #include <parser.h>
- #include <queue.h>
-
-
- void print_keyword_enum(enum Keyword code);
- void print_token(struct token *token);
- void print_tokens(struct Queue *tokens);
-
- void print_ast_enum(enum AST_Type type);
- void print_ast(struct AST *tree);
- void print_ast_state(struct AST_State* tree);
- void print_ast_event(struct AST_Event* tree);
- void print_ast_states(struct AST_States* tree);
- void print_ast_events(struct AST_Events* tree);
- void print_ast_transition(struct AST_Transition* tree);
- void print_ast_command(struct AST_Command* tree);
- void print_ast_pipeline(struct AST_Pipeline* tree);
- void print_ast_machine(struct AST_Machine* tree);
- void print_ast_transitions(struct AST_Transitions* tree);
-
- void print_error(struct Error *error);
- void print_errors(struct Translation_Data *translation_data);
- #endif
F diff --git a/src/backend/targets/C/ast_to_c.c b/src/backend/targets/C/ast_to_c.c new file mode 100644 --- /dev/null +++ b/src/backend/targets/C/ast_to_c.c
+ #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
F diff --git a/src/backend/targets/C/ast_to_c.h b/src/backend/targets/C/ast_to_c.h new file mode 100644 --- /dev/null +++ b/src/backend/targets/C/ast_to_c.h
+ #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
F diff --git a/src/backend/targets/print/print.c b/src/backend/targets/print/print.c new file mode 100644 --- /dev/null +++ b/src/backend/targets/print/print.c
+ #ifndef PRINT_C
+ #define PRINT_C PRINT_C
+ #include<print.h>
+
+ void print_keyword_enum(enum Keyword code)
+ {
+ switch(code)
+ {
+ case KW_MACHINE:
+ printf("KW_MACHINE");
+ break;
+ case KW_FROM:
+ printf("KW_FROM");
+ break;
+ case KW_TO:
+ printf("KW_TO");
+ break;
+ case KW_ON:
+ printf("KW_ON");
+ break;
+ case KW_ID:
+ printf("KW_ID");
+ break;
+ case KW_STRING:
+ printf("KW_STRING");
+ break;
+ case KW_NOP:
+ printf("KW_NOP");
+ break;
+ case KW_EOF:
+ printf("KW_EOF");
+ break;
+ case KW_OPEN_SQUARE:
+ printf("KW_OPEN_SQUARE");
+ break;
+ case KW_CLOSE_SQUARE:
+ printf("KW_CLOSE_SQUARE");
+ break;
+ case KW_PIPE:
+ printf("KW_PIPE");
+ break;
+ case KW_SEMI_COLUMN:
+ printf("KW_SEMI_COLUMN");
+ break;
+ case KW_STARTING:
+ printf("KW_STARTING");
+ break;
+ case KW_STATES:
+ printf("KW_STATES");
+ break;
+ case KW_EVENTS:
+ printf("KW_EVENTS");
+ break;
+ case KW_EVENT:
+ printf("KW_EVENT");
+ break;
+ case KW_TRANSITIONS:
+ printf("KW__TRANSITIONS");
+ break;
+ case KW_EXECUTE:
+ printf("KW_EXECUTE");
+ break;
+ case KW_COMMA:
+ printf("KW_COMMA");
+ break;
+ default:
+ printf("LEXERROR");
+ }
+ }
+ void print_token(struct token *token)
+ {
+ size_t i;
+ assert(token);
+
+ printf("[ ");
+ print_keyword_enum(token->type);
+ printf(" ");
+ for(i=0;i<token->size;++i)
+ printf("%c",token->data[i]);
+ printf(" ] ");
+
+ }
+ void print_tokens(struct Queue *tokens)
+ {
+ struct Queue_Node *it;
+ assert(tokens);
+
+ for(it=tokens->first;it!=NULL;it=it->prev)
+ {
+ print_token( (struct token*)(it->data));
+ printf(" ");
+ }
+ }
+ void print_ast_enum(enum AST_Type type)
+ {
+ switch(type)
+ {
+ case AST_TYPE_MACHINE:
+ printf("AST_TYPE_MACHINE");
+ break;
+ case AST_TYPE_STATE:
+ printf("AST_TYPE_STATE");
+ break;
+ case AST_TYPE_STATES:
+ printf("AST_TYPE_STATES");
+ break;
+ case AST_TYPE_EVENT:
+ printf("AST_TYPE_EVENT");
+ break;
+ case AST_TYPE_EVENTS:
+ printf("AST_TYPE_EVENTS");
+ break;
+ case AST_TYPE_TRANSITION:
+ printf("AST_TYPE_TRANSITION");
+ break;
+ case AST_TYPE_TRANSITIONS:
+ printf("AST_TYPE_TRANSITIONS");
+ break;
+ case AST_TYPE_COMMAND:
+ printf("AST_TYPE_COMMAND");
+ break;
+ case AST_TYPE_PIPELINE:
+ printf("AST_TYPE_PIPELINE");
+ break;
+ default:
+ printf("AST_NOP");
+ }
+
+ }
+ void print_ast(struct AST *tree)
+ {
+ assert(tree);
+
+ switch(tree->type)
+ {
+ case AST_TYPE_MACHINE:
+ print_ast_machine((struct AST_Machine*)tree);
+ break;
+ case AST_TYPE_STATE:
+ print_ast_state((struct AST_State*)tree);
+ break;
+ case AST_TYPE_STATES:
+ print_ast_states((struct AST_States*)tree);
+ break;
+ case AST_TYPE_EVENT:
+ print_ast_event((struct AST_Event*)tree);
+ break;
+ case AST_TYPE_EVENTS:
+ print_ast_events((struct AST_Events*)tree);
+ break;
+ case AST_TYPE_TRANSITION:
+ print_ast_transition((struct AST_Transition*)tree);
+ break;
+ case AST_TYPE_TRANSITIONS:
+ print_ast_transitions((struct AST_Transitions*)tree);
+ break;
+ case AST_TYPE_COMMAND:
+ print_ast_command((struct AST_Command*)tree);
+ break;
+ case AST_TYPE_PIPELINE:
+ print_ast_pipeline((struct AST_Pipeline*)tree);
+ break;
+ default:
+ printf("noast");
+ }
+ }
+ void print_ast_state(struct AST_State* tree)
+ {
+ assert(tree);
+
+ printf("[ STATE: ");
+ print_token(tree->name);
+ printf(" %ld",tree->number);
+ printf("]");
+ }
+ void print_ast_event(struct AST_Event* tree)
+ {
+ assert(tree);
+
+ printf("[ EVENT: ");
+ print_token(tree->name);
+ printf("]");
+ }
+ void print_ast_states(struct AST_States* tree)
+ {
+ size_t i;
+ assert(tree);
+
+ printf("STATES [\n");
+ for(i=0;i<tree->number_of_states;++i)
+ {
+ print_ast_state(tree->states[i]);
+ printf(" ");
+ }
+ printf("\n ] END STATES \n");
+ }
+ void print_ast_events(struct AST_Events* tree)
+ {
+ size_t i;
+ assert(tree);
+
+ printf("EVENTS [\n");
+ for(i=0;i<tree->number_of_events;++i)
+ {
+ print_ast_event(tree->events[i]);
+ printf(" ");
+ }
+ printf("\n ] END EVENTS \n");
+ }
+ void print_ast_transition(struct AST_Transition* tree)
+ {
+ assert(tree);
+
+ printf("TRANSITION [\nFROM");
+ print_ast_state(tree->from);
+ printf(" TO ");
+ print_ast_state(tree->to);
+ printf(" COMMAND {");
+ if(tree->pipeline==NULL)
+ {
+ printf("NULL");
+ }else
+ {
+ print_ast_pipeline(tree->pipeline);
+ }
+
+ }
+ void print_ast_command(struct AST_Command* tree)
+ {
+ assert(tree);
+
+ printf("( command ");
+ print_token(tree->function_name);
+ if(tree->argument==NULL)
+ {
+ printf(" NOARGUMENTS ");
+ }else
+ {
+ printf(" \"");
+ print_token(tree->argument);
+ printf("\" ");
+ }
+ printf(")");
+ }
+ void print_ast_pipeline(struct AST_Pipeline* tree)
+ {
+ size_t i;
+ assert(tree);
+ printf("PIPELINE <");
+ for(i=0;i<tree->size;++i)
+ {
+ print_ast_command(tree->pipeline[i]);
+ printf(" | ");
+ }
+ printf("> PIPELINE_END");
+ }
+ void print_ast_machine(struct AST_Machine* tree)
+ {
+ assert(tree);
+ printf("MACHINE ");
+ print_token(tree->id);
+ printf(" [\n");
+ print_ast_states(tree->states);
+ print_ast_events(tree->events);
+ print_ast_transitions(tree->transitions);
+ printf("] MACHINE_END\n");
+ }
+ void print_ast_transitions(struct AST_Transitions* tree)
+ {
+ size_t i;
+ assert(tree);
+ printf("TRANSITIONS [\n");
+ for(i=0;i<tree->size;++i)
+ {
+ print_ast_transition(tree->transitions[i]);
+ printf("\n");
+ }
+ printf("] TRANSITIONS_END\n");
+ }
+ void print_error(struct Error *error)
+ {
+ assert(error);
+ printf("Error: %s, line %ld row %ld\n",error->message,error->row,error->column);
+ }
+ void print_errors(struct Translation_Data *translation_data)
+ {
+ struct Queue_Node *it;
+ assert(translation_data);
+
+ for(it=translation_data->errors->first;it!=NULL;it=it->prev)
+ {
+ print_error(it->data);
+ }
+ }
+ #endif
F diff --git a/src/backend/targets/print/print.h b/src/backend/targets/print/print.h new file mode 100644 --- /dev/null +++ b/src/backend/targets/print/print.h
+ #ifndef PRINT_H
+ #define PRINT_H PRINT_H
+ #include <stdio.h>
+ #include <lexer.h>
+ #include <parser.h>
+ #include <queue.h>
+
+
+ void print_keyword_enum(enum Keyword code);
+ void print_token(struct token *token);
+ void print_tokens(struct Queue *tokens);
+
+ void print_ast_enum(enum AST_Type type);
+ void print_ast(struct AST *tree);
+ void print_ast_state(struct AST_State* tree);
+ void print_ast_event(struct AST_Event* tree);
+ void print_ast_states(struct AST_States* tree);
+ void print_ast_events(struct AST_Events* tree);
+ void print_ast_transition(struct AST_Transition* tree);
+ void print_ast_command(struct AST_Command* tree);
+ void print_ast_pipeline(struct AST_Pipeline* tree);
+ void print_ast_machine(struct AST_Machine* tree);
+ void print_ast_transitions(struct AST_Transitions* tree);
+
+ void print_error(struct Error *error);
+ void print_errors(struct Translation_Data *translation_data);
+ #endif
F diff --git a/src/frontend/lexer.h b/src/frontend/lexer.h --- a/src/frontend/lexer.h +++ b/src/frontend/lexer.h
};
struct token
{
- size_t size;
enum Keyword type;
+ size_t size;
char *data;
size_t row;
size_t column;
F diff --git a/src/frontend/parser.c b/src/frontend/parser.c --- a/src/frontend/parser.c +++ b/src/frontend/parser.c
#define PARSER_C PARSER_C
#include <parser.h>
+ struct AST* parse_source(struct Translation_Data *translation_data)
+ {
+ return (struct AST*)parse_translation_unit(translation_data);
+ }
/*
- * parse-unit: machine
- *
+ * translation-unit: (machine)*
*/
- struct AST* parse_unit(struct Translation_Data *translation_data)
+ struct AST_Translation_Unit* parse_translation_unit(struct Translation_Data *translation_data)
{
- return (struct AST*)parse_machine(translation_data);
+ struct Queue *machines;
+ struct Map *hold_command_map;
+ struct AST_Machine *hold_machine;
+
+ machines=calloc(1,sizeof(struct Queue));
+ hold_command_map=malloc(sizeof(struct Map));
+ Map_Init(hold_command_map);
+
+ translation_data->hold_command_map=hold_command_map;
+
+ while(!get_and_check(translation_data,KW_EOF))
+ {
+ hold_machine=parse_machine(translation_data);
+ if(hold_machine)
+ {
+ Queue_Push(machines,hold_machine);
+ }
+ else
+ {
+ Map_Map(hold_command_map,(void (*)(void*))delete_ast_command);
+ Map_Destroy(hold_command_map);
+ while(machines->size>0)
+ delete_ast_machine(Queue_Pop(machines));
+ return NULL;
+ }
+ }
+ return get_ast_translation_unit(machines,hold_command_map);
}
/*
* machine: 'machine' id '[' machine-inner ']' ';'
{
struct token *id;
struct token *string=NULL;
+ struct AST_Command *ret;
+
if(get_kw(translation_data)==KW_ID)
{
id=Queue_Pop(translation_data->tokens);
if(get_kw(translation_data)==KW_STRING)
string=Queue_Pop(translation_data->tokens);
- return get_ast_command(id,string);
+ ret=get_ast_command(id,string);
+ Map_Push(translation_data->hold_command_map,ret->argument->data,ret->argument->size,ret);
+
+ return ret;
}else
{
push_parsing_error("expected command id",translation_data);
struct AST_State *ret;
ret=malloc(sizeof(struct AST_State));
- ret->type=AST_TYPE_STATE;
- ret->id=id;
+ ret->name=id;
+ /*number is assigned in get_ast_states*/
return ret;
}
struct AST_Event *ret;
ret=malloc(sizeof(struct AST_Event));
- ret->type=AST_TYPE_EVENT;
- ret->id=id;
+
+ ret->name=id;
return ret;
}
while(states->size>0)
{
hold_state=Queue_Pop(states);
- Map_Push(ret->states_map,hold_state->id->data,hold_state->id->size,hold_state);
+ Map_Push(ret->states_map,hold_state->name->data,hold_state->name->size,hold_state);
ret->states[states->size]=hold_state;
+ hold_state->number=states->size;
}
assert(states->size==0);
while(events->size>0)
{
hold_event=Queue_Pop(events);
- Map_Push(ret->events_map,hold_event->id->data,hold_event->id->size,hold_event);
+ Map_Push(ret->events_map,hold_event->name->data,hold_event->name->size,hold_event);
ret->events[events->size]=hold_event;
}
void delete_ast_event(struct AST_Event* ast)
{
if(ast==NULL)return;
- delete_token(ast->id);
+ delete_token(ast->name);
free(ast);
}
void delete_ast_states(struct AST_States* ast)
void delete_ast_state(struct AST_State* ast)
{
if(ast==NULL)return;
- if(ast->id!=NULL)
- delete_token(ast->id);
+ if(ast->name!=NULL)
+ delete_token(ast->name);
free(ast);
}
void pointer_array_fill(void **array,struct Queue *q)
return q;
}
+ void delete_ast_translation_unit(struct AST_Translation_Unit *ast)
+ {
+ size_t i;
+ Map_Map(ast->used_commands_map,(void (*)(void*))delete_ast_command);
+ Map_Destroy(ast->used_commands_map);
+ for(i=0;i<ast->number_of_machines;++i)
+ {
+ delete_ast_machine(ast->machines[i]);
+ }
+ free(ast->used_commands_map);
+ free(ast);
+ }
+ struct AST_Translation_Unit* get_ast_translation_unit(struct Queue *machines,struct Map *command_map)
+ {
+ struct AST_Translation_Unit *ret;
+ struct AST_Machine *hold_machine;
+
+ ret=malloc(sizeof(struct AST_Translation_Unit)+sizeof(struct AST_Machine *[machines->size]));
+ ret->type=AST_TYPE_TRANSLATION_UNIT;
+ ret->used_commands_map=command_map;
+ ret->number_of_machines=machines->size;
+
+ while(machines->size>0)
+ {
+ hold_machine=Queue_Pop(machines);
+ ret->machines[machines->size]=hold_machine;
+ }
+
+ return ret;
+ }
#endif
F diff --git a/src/frontend/parser.h b/src/frontend/parser.h --- a/src/frontend/parser.h +++ b/src/frontend/parser.h
enum AST_Type
{
+ AST_TYPE_TRANSLATION_UNIT,
AST_TYPE_MACHINE,
AST_TYPE_STATE,
AST_TYPE_STATES,
};
struct AST_State
{
- enum AST_Type type;
- struct token *id;
+ struct token *name;
+ size_t number;
};
struct AST_Event
{
- enum AST_Type type;
- struct token *id;
+ struct token *name;
};
struct AST_States
{
size_t size;
struct AST_Command *pipeline[];
};
+ struct AST_Transitions
+ {
+ enum AST_Type type;
+ size_t size;
+ struct AST_Transition *transitions[];
+ };
struct AST_Machine
{
enum AST_Type type;
struct AST_Events *events;
struct AST_Transitions *transitions;
};
- struct AST_Transitions
+ struct AST_Translation_Unit
{
enum AST_Type type;
- size_t size;
- struct AST_Transition *transitions[];
+ struct Map *used_commands_map;
+ size_t number_of_machines;
+ struct AST_Machine *machines[];
};
- struct AST* parse_unit(struct Translation_Data *translation_data);
+ struct AST* parse_source(struct Translation_Data *translation_data);
+ struct AST_Translation_Unit* parse_translation_unit(struct Translation_Data *translation_data);
struct AST_Machine* parse_machine(struct Translation_Data *translation_data);
struct AST_Machine* parse_machine_inner(struct token *machine_id,struct Translation_Data *translation_data);
struct AST_States* parse_states_inner(struct Translation_Data *translation_data);
struct AST_Pipeline* get_ast_pipeline(struct Queue *pipeline);
struct AST_Machine* get_ast_machine(struct token *id,struct AST_States *states,struct AST_Events *events,struct AST_Transitions *transitions,struct AST_State *starting_state);
struct AST_Transitions* get_ast_transitions(struct Queue *transitions);
+ struct AST_Translation_Unit* get_ast_translation_unit(struct Queue *machines,struct Map *command_map);
void delete_ast(struct AST* ast);
void delete_ast_pipeline(struct AST_Pipeline* ast);
void delete_ast_machine(struct AST_Machine* ast);
void delete_ast_transitions(struct AST_Transitions* ast);
+ void delete_ast_translation_unit(struct AST_Translation_Unit *ast);
void pointer_array_fill(void **array,struct Queue *q);
F diff --git a/src/main.c b/src/main.c --- a/src/main.c +++ b/src/main.c
#include <lexer.h>
#include <string.h>
#include <parser.h>
+ #include <backend.h>
#include <print.h>
source=extract_source(strndup(options->src_name,100));
translation_data=get_translation_data();
- if(options->target==OPTION_TARGET_TOKENS || options->target==OPTION_TARGET_AST)
+ if(options->target==OPTION_TARGET_TOKENS || options->target==OPTION_TARGET_AST || options->target==OPTION_TARGET_C)
{
lex(translation_data->tokens,source,translation_data);
if(translation_data->errors->size>0)
}else if(options->target==OPTION_TARGET_TOKENS)
{
print_tokens(translation_data->tokens);
- }else if(options->target==OPTION_TARGET_AST) //we check because we will probably add more options
+ }else if(options->target==OPTION_TARGET_AST || options->target==OPTION_TARGET_C)
{
- translation_unit=parse_unit(translation_data);
+ //we check because we will probably add more options
+
+
+ translation_unit=parse_source(translation_data);
if(has_new_errors(translation_data))
{
print_errors(translation_data);
return 1;
- }else
+ }
+ if(options->target==OPTION_TARGET_AST)
{
print_ast(translation_unit);
- delete_ast(translation_unit);
+ }else if(options->target==OPTION_TARGET_C)
+ {
+ ast_to_c(stdout,translation_unit);
}
+ delete_ast(translation_unit);
}
}else
F diff --git a/src/program/program.c b/src/program/program.c --- a/src/program/program.c +++ b/src/program/program.c
ret->target=OPTION_TARGET_TOKENS;
else if(!strncmp(argv[i],"--print-ast",sizeof("--print-ast")))
ret->target=OPTION_TARGET_AST;
+ else if(!strncmp(argv[i],"--print-c",sizeof("--print-c")))
+ ret->target=OPTION_TARGET_C;
else if(!strncmp(argv[i],"-o",sizeof("-o")) || !strncmp(argv[i],"--output",sizeof("--output")))
{
if(++i<argc)
}
if(ret->target==OPTION_DEFAULT)
- ret->target=OPTION_TARGET_AST;
+ ret->target=OPTION_TARGET_C;
return ret;
}
F diff --git a/src/program/program.h b/src/program/program.h --- a/src/program/program.h +++ b/src/program/program.h
{
OPTION_TARGET_TOKENS,
OPTION_TARGET_AST,
+ OPTION_TARGET_C,
OPTION_DEFAULT,
};
struct Queue *errors;
struct Queue *tokens;
size_t hold_number_of_errors;
+ struct Map *hold_command_map;
};
struct Program
{
F diff --git a/tests/output.c b/tests/output.c new file mode 100644 --- /dev/null +++ b/tests/output.c
+ enum
+ {
+ EVENT_ONE_SECOND,
+ }MACHINE_FLICKER_EVENT;
+
+ enum
+ {
+ MACHINE_FLICKER,
+ }MACHINES;
+
+ extern void machine_flicker_light_off(enum MACHINE_FLICKER_EVENT event);
+ extern void machine_flicker_light_on(enum MACHINE_FLICKER_EVENT event);
+
+ extern machine_buffer_t* turn_on_light(machine_buffer_t *arguments,machine_buffer_t *input);
+ extern machine_buffer_t* turn_off_light(machine_buffer_t *arguments,machine_buffer_t *input);
+
+ void machine_flicker_push_event(enum MACHINE_FLICKER_EVENT event);
+
+
+
+ void (*machine_states[])()={machine_flicker_light_on};
+
+
+
+ void machine_flicker_push_event(enum MACHINE_FLICKER_EVENT event)
+ {
+ machine_states[MACHINE_FLICKER](event);
+ }
+
+ void machine_flicker_light_off(enum MACHINE_FLICKER_EVENT event)
+ {
+ switch(event)
+ {
+ case EVENT_ONE_SECOND:
+ turn_on_light(get_machine_buffer(""));
+ machine_states[MACHINE_FLICKER]=machine_flicker_light_on;
+ break;
+ }
+ }
+ void machine_flicker_light_on(enum MACHINE_FLICKER_EVENT event)
+ {
+ switch(event)
+ {
+ case EVENT_ONE_SECOND:
+ turn_off_light(get_machine_buffer(""));
+ machine_states[MACHINE_FLICKER]=machine_flicker_light_off;
+ break;
+ }
+ }
F diff --git a/tests/test b/tests/test --- a/tests/test +++ b/tests/test
+
machine flicker
[
states [ light_off , light_on ];
+ events [ one_second ];
starting on light_on;
- events [ one_second ];
transitions
[
from light_on to light_off on event one_second