aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGalin Simeonov <gts@volconst.com>2021-06-01 18:21:02 +0300
committerGalin Simeonov <gts@volconst.com>2021-07-15 18:03:43 +0300
commit85b23fbee717f047af5a89eac6f4dba8e7812524 (patch)
treedc88ef3f4cb826f4f3a3c9e12c67562878460aa5
parent255a49ba5a41b3854dbdfebdec75fb6229450507 (diff)
downloadMEGATRON-85b23fbee717f047af5a89eac6f4dba8e7812524.tar.gz
restructuring
-rw-r--r--CMakeLists.txt29
-rw-r--r--src/backend/backend.c37
-rw-r--r--src/backend/backend.h18
-rw-r--r--src/backend/targets/C/ast_to_c.c155
-rw-r--r--src/backend/targets/C/ast_to_c.h29
-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
-rw-r--r--src/frontend/lexer.h2
-rw-r--r--src/frontend/parser.c93
-rw-r--r--src/frontend/parser.h26
-rw-r--r--src/main.c18
-rw-r--r--src/program/program.c4
-rw-r--r--src/program/program.h2
-rw-r--r--tests/output.c49
-rw-r--r--tests/test3
15 files changed, 427 insertions, 43 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 415816f..f4561cb 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -3,25 +3,32 @@ project (AUTOMATA)
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})
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
diff --git a/src/frontend/lexer.h b/src/frontend/lexer.h
index 320146c..d102540 100644
--- a/src/frontend/lexer.h
+++ b/src/frontend/lexer.h
@@ -32,8 +32,8 @@ enum Keyword
};
struct token
{
- size_t size;
enum Keyword type;
+ size_t size;
char *data;
size_t row;
size_t column;
diff --git a/src/frontend/parser.c b/src/frontend/parser.c
index 3e4e449..45752e7 100644
--- a/src/frontend/parser.c
+++ b/src/frontend/parser.c
@@ -2,13 +2,42 @@
#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 ']' ';'
@@ -365,12 +394,17 @@ struct AST_Command* parse_command(struct Translation_Data *translation_data)
{
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);
@@ -406,8 +440,8 @@ struct AST_State* get_ast_state(struct token *id)
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;
}
@@ -416,8 +450,8 @@ struct AST_Event* get_ast_event(struct token *id)
struct AST_Event *ret;
ret=malloc(sizeof(struct AST_Event));
- ret->type=AST_TYPE_EVENT;
- ret->id=id;
+
+ ret->name=id;
return ret;
}
@@ -439,8 +473,9 @@ struct AST_States* get_ast_states(struct Queue *states)
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);
@@ -466,7 +501,7 @@ struct AST_Events* get_ast_events(struct Queue *events)
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;
}
@@ -574,7 +609,7 @@ void delete_ast(struct AST* ast)
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)
@@ -639,8 +674,8 @@ void delete_ast_transitions(struct AST_Transitions* 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)
@@ -666,4 +701,34 @@ struct Queue* parse_list(struct AST *(*parser)(struct Translation_Data*),struct
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
diff --git a/src/frontend/parser.h b/src/frontend/parser.h
index ef82184..eaede84 100644
--- a/src/frontend/parser.h
+++ b/src/frontend/parser.h
@@ -7,6 +7,7 @@
enum AST_Type
{
+ AST_TYPE_TRANSLATION_UNIT,
AST_TYPE_MACHINE,
AST_TYPE_STATE,
AST_TYPE_STATES,
@@ -23,13 +24,12 @@ struct AST
};
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
{
@@ -65,6 +65,12 @@ struct AST_Pipeline
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;
@@ -73,15 +79,17 @@ struct AST_Machine
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);
@@ -104,6 +112,7 @@ struct AST_Command* get_ast_command(struct token *function_name,struct token *ar
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);
@@ -116,6 +125,7 @@ void delete_ast_command(struct AST_Command* 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);
diff --git a/src/main.c b/src/main.c
index 438f282..1001c51 100644
--- a/src/main.c
+++ b/src/main.c
@@ -3,6 +3,7 @@
#include <lexer.h>
#include <string.h>
#include <parser.h>
+#include <backend.h>
#include <print.h>
@@ -24,7 +25,7 @@ int main(int argc,char **argv)
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)
@@ -35,18 +36,25 @@ int main(int argc,char **argv)
}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
diff --git a/src/program/program.c b/src/program/program.c
index 5cf8cc3..1e7882d 100644
--- a/src/program/program.c
+++ b/src/program/program.c
@@ -48,6 +48,8 @@ struct Options* parse_command_line(int argc,char **argv)
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)
@@ -78,7 +80,7 @@ struct Options* parse_command_line(int argc,char **argv)
}
if(ret->target==OPTION_DEFAULT)
- ret->target=OPTION_TARGET_AST;
+ ret->target=OPTION_TARGET_C;
return ret;
}
diff --git a/src/program/program.h b/src/program/program.h
index d5e45b7..99a02c3 100644
--- a/src/program/program.h
+++ b/src/program/program.h
@@ -14,6 +14,7 @@ enum Options_Target_Type
{
OPTION_TARGET_TOKENS,
OPTION_TARGET_AST,
+ OPTION_TARGET_C,
OPTION_DEFAULT,
};
@@ -47,6 +48,7 @@ struct Translation_Data
struct Queue *errors;
struct Queue *tokens;
size_t hold_number_of_errors;
+ struct Map *hold_command_map;
};
struct Program
{
diff --git a/tests/output.c b/tests/output.c
new file mode 100644
index 0000000..713c329
--- /dev/null
+++ b/tests/output.c
@@ -0,0 +1,49 @@
+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;
+ }
+}
diff --git a/tests/test b/tests/test
index c976a6d..90d5353 100644
--- a/tests/test
+++ b/tests/test
@@ -1,10 +1,11 @@
+
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