diff options
author | Galin Simeonov <gts@volconst.com> | 2021-06-04 16:42:52 +0300 |
---|---|---|
committer | Galin Simeonov <gts@volconst.com> | 2021-07-15 18:04:59 +0300 |
commit | a26684a417729699e95b335a3d00798237ffba9b (patch) | |
tree | 6cd73bc90fbe5fd435b8cc721455d0a70420a4ac | |
parent | b845e4754be86d2216733d9bea75cb301f38739d (diff) | |
download | MEGATRON-a26684a417729699e95b335a3d00798237ffba9b.tar.gz |
added the if statement
-rw-r--r-- | src/backend/backend.c | 31 | ||||
-rw-r--r-- | src/backend/backend.h | 1 | ||||
-rw-r--r-- | src/backend/targets/C/ast_to_c.c | 76 | ||||
-rw-r--r-- | src/backend/targets/C/ast_to_c.h | 4 | ||||
-rw-r--r-- | src/backend/targets/print/print.c | 27 | ||||
-rw-r--r-- | src/backend/targets/print/print.h | 1 | ||||
-rw-r--r-- | src/frontend/lexer.c | 8 | ||||
-rw-r--r-- | src/frontend/lexer.h | 2 | ||||
-rw-r--r-- | src/frontend/parser.c | 159 | ||||
-rw-r--r-- | src/frontend/parser.h | 21 | ||||
-rw-r--r-- | tests/.test6.swp (renamed from tests/.test5.swp) | bin | 12288 -> 12288 bytes | |||
-rw-r--r-- | tests/test4 | 4 | ||||
-rw-r--r-- | tests/test5 | 7 | ||||
-rw-r--r-- | tests/test6 | 26 |
14 files changed, 306 insertions, 61 deletions
diff --git a/src/backend/backend.c b/src/backend/backend.c index 512d247..ff9d0bf 100644 --- a/src/backend/backend.c +++ b/src/backend/backend.c @@ -20,10 +20,7 @@ struct State_And_Transitions** extract_transition_table(struct AST_States *state /*traverse transitions and push them into the queue of their coresponding state*/ for(i=0;i<transitions->size;++i) { - hold_state=extract_state(transitions->transitions[i]->from,states); - - assert(hold_state!=NULL); - + hold_state=transitions->transitions[i]->from; Queue_Push(qs+hold_state->number,transitions->transitions[i]); } @@ -101,7 +98,7 @@ void anotate_machine(struct AST_Machine *machine,struct AST_Translation_Unit *un size_t i; for(i=0;i<machine->transitions->size;++i) { - machine->transitions->transitions[i]->from=anotate_expression(machine->transitions->transitions[i]->from,unit,machine,translation_data); + machine->transitions->transitions[i]->statement=anotate_statement(machine->transitions->transitions[i]->statement,unit,machine,translation_data); } if(has_new_errors(translation_data)) { @@ -109,6 +106,17 @@ void anotate_machine(struct AST_Machine *machine,struct AST_Translation_Unit *un delete_ast_machine(machine); } } +struct AST* anotate_statement(struct AST *statement,struct AST_Translation_Unit *unit,struct AST_Machine *current_machine,struct Translation_Data *translation_data) +{ + if(statement==NULL)return NULL; + if(statement->type==AST_TYPE_IF) + { + ((struct AST_If_Statement*)statement)->condition=anotate_expression(((struct AST_If_Statement*)statement)->condition,unit,current_machine,translation_data); + }else + { + return statement; + } +} struct AST* anotate_expression(struct AST *expression,struct AST_Translation_Unit *unit,struct AST_Machine *current_machine,struct Translation_Data *translation_data) { struct AST_Machine *hold_machine; @@ -131,8 +139,17 @@ struct AST* anotate_expression(struct AST *expression,struct AST_Translation_Uni }else { hold_left=(struct AST*)ast_check_state((struct AST_Unchecked_State*)hold_right,hold_machine->states,translation_data); - ((struct AST_State*)hold_left)->parent=hold_machine; - return hold_left; + if(hold_left) + { + ((struct AST_State*)hold_left)->parent=hold_machine; + delete_ast(hold_right); + return hold_left; + }else + { + push_error_with_token("state id from foreign machine is undefined",((struct AST_Unchecked_State*)hold_right)->name,translation_data); + delete_ast(hold_right); + return NULL; + } } }else { diff --git a/src/backend/backend.h b/src/backend/backend.h index 8b865fd..d292776 100644 --- a/src/backend/backend.h +++ b/src/backend/backend.h @@ -21,6 +21,7 @@ struct AST_State* extract_state(struct AST *expression,struct AST_States *states void anotate_unchecked_states(struct AST_Translation_Unit *unit,struct Translation_Data *translation_data); void anotate_machine(struct AST_Machine *machine,struct AST_Translation_Unit *unit,struct Translation_Data *translation_data); +struct AST* anotate_statement(struct AST *statement,struct AST_Translation_Unit *unit,struct AST_Machine *current_machine,struct Translation_Data *translation_data); struct AST* anotate_expression(struct AST *expression,struct AST_Translation_Unit *unit,struct AST_Machine *current_machine,struct Translation_Data *translation_data); _Bool expression_is_binary(struct AST* expression); diff --git a/src/backend/targets/C/ast_to_c.c b/src/backend/targets/C/ast_to_c.c index 3ce923d..9c8b38d 100644 --- a/src/backend/targets/C/ast_to_c.c +++ b/src/backend/targets/C/ast_to_c.c @@ -189,7 +189,8 @@ void ast_transitions_of_state_to_c(FILE *out,struct AST_Machine *machine,struct ast_event_to_c_enum(out,machine,vector->transitions[i]->event); fprintf(out,":\n"); - ast_pipeline_to_c(out,3,vector->transitions[i]->pipeline); + //ast_pipeline_to_c(out,3,vector->transitions[i]->pipeline); + ast_statement_to_c(out,3,vector->transitions[i]->statement); fprintf(out,"\t\t\tmachine_states["); ast_token_to_c(out,machine->id); fprintf(out,"]="); @@ -370,4 +371,77 @@ 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) +{ + 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); + else + assert(0); + +} +void ast_if_to_c(FILE *out,size_t indentation,struct AST_If_Statement *statement) +{ + ast_to_c_print_tabs(out,indentation); + fprintf(out,"if"); + ast_expression_to_c(out,statement->condition); + fprintf(out,"\n"); + + ast_to_c_print_tabs(out,indentation); + fprintf(out,"{\n"); + + ast_statement_to_c(out,indentation+1,statement->body); + + ast_to_c_print_tabs(out,indentation); + fprintf(out,"}"); + if(statement->else_statement) + { + fprintf(out,"else{\n"); + + ast_statement_to_c(out,indentation+1,statement->else_statement); + + ast_to_c_print_tabs(out,indentation); + fprintf(out,"}"); + } + fprintf(out,"\n"); +} +void ast_expression_to_c(FILE *out,struct AST *expression) +{ + fprintf(out,"("); + switch(expression->type) + { + case AST_TYPE_OP_OR: + ast_expression_to_c(out,AS_BIN_EXPR_PTR(expression)->left); + fprintf(out,"||"); + ast_expression_to_c(out,AS_BIN_EXPR_PTR(expression)->right); + break; + case AST_TYPE_OP_NOT: + fprintf(out,"!"); + ast_expression_to_c(out,AS_UN_EXPR_PTR(expression)->operand); + break; + case AST_TYPE_OP_AND: + ast_expression_to_c(out,AS_BIN_EXPR_PTR(expression)->left); + fprintf(out,"&&"); + ast_expression_to_c(out,AS_BIN_EXPR_PTR(expression)->right); + break; + case AST_TYPE_STATE: + ast_expression_state_to_c(out,(struct AST_State*)expression); + break; + case AST_TYPE_OP_SELECTOR: + assert(!"selector in final product!\n"); + default: + assert(0); + } + fprintf(out,")"); +} +void ast_expression_state_to_c(FILE *out,struct AST_State *state) +{ + fprintf(out,"machine_states["); + ast_token_to_c(out,state->parent->id); + fprintf(out,"]=="); + ast_state_to_c_function_name(out,state->parent,state); + +} #endif diff --git a/src/backend/targets/C/ast_to_c.h b/src/backend/targets/C/ast_to_c.h index fb3e729..299d6db 100644 --- a/src/backend/targets/C/ast_to_c.h +++ b/src/backend/targets/C/ast_to_c.h @@ -44,6 +44,10 @@ void ast_machines_to_c_array(FILE *out,struct AST_Translation_Unit *translation_ 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_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); diff --git a/src/backend/targets/print/print.c b/src/backend/targets/print/print.c index 7649b91..3c33438 100644 --- a/src/backend/targets/print/print.c +++ b/src/backend/targets/print/print.c @@ -81,6 +81,12 @@ void print_keyword_enum(enum Keyword code) case KW_NOT: printf("KW_NOT"); break; + case KW_IF: + printf("KW_IF"); + break; + case KW_ELSE: + printf("KW_ELSE"); + break; default: printf("LEXERROR"); } @@ -158,6 +164,9 @@ void print_ast_enum(enum AST_Type type) case AST_TYPE_UNFINISHED_STATE: printf("AST_TYPE_UNFINISHED_STATE"); break; + case AST_TYPE_IF: + printf("AST_TYPE_IF"); + break; default: printf("AST_NOP"); } @@ -210,6 +219,9 @@ void print_ast(struct AST *tree) case AST_TYPE_UNFINISHED_STATE: print_ast_unchecked_state((struct AST_Unchecked_State*)tree); break; + case AST_TYPE_IF: + print_ast_if_statement((struct AST_If_Statement*)tree); + break; default: printf("noast"); } @@ -262,16 +274,16 @@ void print_ast_transition(struct AST_Transition* tree) assert(tree); printf("TRANSITION [\nFROM"); - print_ast(tree->from); + print_ast_state(tree->from); printf(" TO "); print_ast_state(tree->to); printf(" COMMAND {"); - if(tree->pipeline==NULL) + if(tree->statement==NULL) { printf("NULL"); }else { - print_ast_pipeline(tree->pipeline); + print_ast(tree->statement); } } @@ -381,4 +393,13 @@ void print_ast_unchecked_state(struct AST_Unchecked_State *tree) { print_token(tree->name); } +void print_ast_if_statement(struct AST_If_Statement *tree) +{ + printf("if <"); + print_ast(tree->condition); + printf(">\n"); + print_ast(tree->body); + if(tree->else_statement) + print_ast(tree->else_statement); +} #endif diff --git a/src/backend/targets/print/print.h b/src/backend/targets/print/print.h index d318792..b21a00c 100644 --- a/src/backend/targets/print/print.h +++ b/src/backend/targets/print/print.h @@ -25,6 +25,7 @@ void print_ast_translation_unit(struct AST_Translation_Unit *tree); void print_ast_binary_expression(struct AST_Binary_Expression *tree); void print_ast_unary_expression(struct AST_Unary_Expression *tree); void print_ast_unchecked_state(struct AST_Unchecked_State *tree); +void print_ast_if_statement(struct AST_If_Statement *tree); void print_error(struct Error *error); void print_errors(struct Translation_Data *translation_data); diff --git a/src/frontend/lexer.c b/src/frontend/lexer.c index 668d7cd..a832a17 100644 --- a/src/frontend/lexer.c +++ b/src/frontend/lexer.c @@ -8,7 +8,7 @@ #define LEX_ERROR(x) {push_lexing_error(x,src,translation_data); return get_token(src->src+src->where_in_src,0,KW_NOP,src->current_row,src->current_column);} /* - * placeholder very slow lexer that I will probabbly not replace + * placeholder very slow ( and very very bad ) lexer that I will probabbly not replace */ void lex(struct Queue *token_destination,struct Source *src,struct Translation_Data *translation_data) { @@ -69,9 +69,11 @@ struct token* lex_step(struct Source *src,struct Translation_Data *translation_d return get_token(src->src+src->where_in_src-sizeof("event")+1,sizeof("event")-1,KW_EVENT,src->current_row,src->current_column); if(check_and_move_if_on_word("transitions",sizeof("transitions")-1,src,1)) return get_token(src->src+src->where_in_src-sizeof("transitions")+1,sizeof("transitions")-1,KW_TRANSITIONS,src->current_row,src->current_column); + if(check_and_move_if_on_word("if",sizeof("if")-1,src,1)) + return get_token(src->src+src->where_in_src-sizeof("if")+1,sizeof("if")-1,KW_IF,src->current_row,src->current_column); - - + if(check_and_move_if_on_word("else",sizeof("else")-1,src,1)) + return get_token(src->src+src->where_in_src-sizeof("else")+1,sizeof("else")-1,KW_ELSE,src->current_row,src->current_column); diff --git a/src/frontend/lexer.h b/src/frontend/lexer.h index 266beea..54c88fa 100644 --- a/src/frontend/lexer.h +++ b/src/frontend/lexer.h @@ -35,6 +35,8 @@ enum Keyword KW_AND, KW_OR, KW_NOT, + KW_IF, + KW_ELSE, }; struct token { diff --git a/src/frontend/parser.c b/src/frontend/parser.c index fa692f5..7af7af2 100644 --- a/src/frontend/parser.c +++ b/src/frontend/parser.c @@ -30,9 +30,9 @@ struct AST_Translation_Unit* parse_translation_unit(struct Translation_Data *tra { hold_machine=parse_machine(translation_data); /*TODO check for repeated machine ids*/ - Map_Push(hold_machines_map,hold_machine->id->data,hold_machine->id->size,hold_machine); if(hold_machine) { + Map_Push(hold_machines_map,hold_machine->id->data,hold_machine->id->size,hold_machine); Queue_Push(machines,hold_machine); } else @@ -307,8 +307,6 @@ struct AST_Transitions* parse_transitions_inner(struct Translation_Data *transla while((hold_transition=parse_transition(translation_data,states,events))!=NULL) { Queue_Push(transitions,hold_transition); - if(!get_and_check(translation_data,KW_SEMI_COLUMN)) - break; } if(transitions->size==0) @@ -331,49 +329,106 @@ struct AST_Transitions* parse_transitions_inner(struct Translation_Data *transla struct AST_Transition* parse_transition(struct Translation_Data *translation_data,struct AST_States *states,struct AST_Events *events) { struct AST_Transition *ret; - struct AST *hold_from; + struct AST_State *hold_from; struct AST_State *hold_to; struct AST_Event *hold_event; - struct AST_Pipeline *hold_pipeline=NULL; + struct AST *hold_statement=NULL; struct token *hold_token; if(get_and_check(translation_data,KW_FROM)) { - hold_from=parse_expression(translation_data); - if(hold_from!=NULL) + if(get_kw(translation_data)==KW_ID) { - if(get_and_check(translation_data,KW_TO)) + hold_token=Queue_Pop(translation_data->tokens); + hold_from=Map_Check(states->states_map,hold_token->data,hold_token->size); + if(hold_from!=NULL) { - if(get_kw(translation_data)==KW_ID) + if(get_and_check(translation_data,KW_TO)) { - hold_token=Queue_Pop(translation_data->tokens); - hold_to=Map_Check(states->states_map,hold_token->data,hold_token->size); - delete_token(hold_token); - if(hold_to!=NULL) + if(get_kw(translation_data)==KW_ID) { - if(get_and_check(translation_data,KW_ON) && get_and_check(translation_data,KW_EVENT) ) + hold_token=Queue_Pop(translation_data->tokens); + hold_to=Map_Check(states->states_map,hold_token->data,hold_token->size); + delete_token(hold_token); + if(hold_to!=NULL) { - if(get_kw(translation_data)==KW_ID) + if(get_and_check(translation_data,KW_ON) && get_and_check(translation_data,KW_EVENT) ) { - hold_token=Queue_Pop(translation_data->tokens); - hold_event=Map_Check(events->events_map,hold_token->data,hold_token->size); - delete_token(hold_token); - if(hold_event!=NULL) + if(get_kw(translation_data)==KW_ID) { - if(get_and_check(translation_data,KW_EXECUTE)) - if((hold_pipeline=parse_pipeline(translation_data))==NULL) - { push_parsing_error("after execute",translation_data); return NULL; } - /*GOAL*/ - return get_ast_transition(hold_from,hold_to,hold_event,hold_pipeline); - }else { push_parsing_error("event not defined",translation_data); return NULL; } - }else { push_parsing_error("no event name given in transition",translation_data); return NULL; } - }else { push_parsing_error("expected 'on event'",translation_data); return NULL; } - }else { push_parsing_error("using undefined to state in transition",translation_data); } - }else { push_parsing_error("expected id in transition expression",translation_data); return NULL; } - }else { push_parsing_error("expected 'to'",translation_data); return NULL; } - }else { push_parsing_error("using undefined from state in transition",translation_data); return NULL; } + hold_token=Queue_Pop(translation_data->tokens); + hold_event=Map_Check(events->events_map,hold_token->data,hold_token->size); + delete_token(hold_token); + if(hold_event!=NULL) + { + + if(!get_and_check(translation_data,KW_SEMI_COLUMN) && (hold_statement=parse_statement(translation_data,states,events))==NULL) + { push_parsing_error("in statement of transition",translation_data); return NULL; } + + /*GOAL!!!!!*/ + return get_ast_transition(hold_from,hold_to,hold_event,hold_statement); + }else { push_parsing_error("event not defined",translation_data); return NULL; } + }else { push_parsing_error("no event name given in transition",translation_data); return NULL; } + }else { push_parsing_error("expected 'on event'",translation_data); return NULL; } + }else { push_parsing_error("using undefined to state in transition",translation_data); } + }else { push_parsing_error("expected id in transition expression",translation_data); return NULL; } + }else { push_parsing_error("expected 'to'",translation_data); return NULL; } + }else { push_parsing_error("using undefined from state in transition",translation_data); return NULL; } + }else { push_parsing_error("expected state id in from field",translation_data); return NULL; } }else { return NULL; } } + +/* + * statement : 'execute' pipeline ; | 'if' expression statement [ else statement ] + */ +struct AST* parse_statement(struct Translation_Data *translation_data,struct AST_States *states,struct AST_Events *events) +{ + struct AST *hold_expression; + struct AST *hold_body; + struct AST *hold_else=NULL; + + if(get_and_check(translation_data,KW_EXECUTE)) + { + hold_body=(struct AST*)parse_pipeline(translation_data); + if(get_and_check(translation_data,KW_SEMI_COLUMN)) + { + return hold_body; + }else + { + push_parsing_error("expected ';' at the end of pipeline",translation_data); + delete_ast(hold_body); + return NULL; + } + }else if(get_and_check(translation_data,KW_IF)) + { + hold_expression=parse_expression(translation_data); + hold_body=parse_statement(translation_data,states,events); + if(hold_body) + { + if(get_and_check(translation_data,KW_ELSE)) + { + hold_else=parse_statement(translation_data,states,events); + if(hold_else==NULL) + { + push_parsing_error("expected a statement after else",translation_data); + delete_ast(hold_expression); + delete_ast(hold_body); + return NULL; + } + } + return (struct AST*)get_ast_if_statement(hold_expression,hold_body,hold_else); + }else + { + push_parsing_error("expected body statement in if",translation_data); + if(hold_expression) + delete_ast(hold_expression); + return NULL; + } + }else + { + return NULL; + } +} /* * pipeline: [ command ( | command )* ] * @@ -523,7 +578,7 @@ struct AST_Events* get_ast_events(struct Queue *events) return ret; } -struct AST_Transition* get_ast_transition(struct AST *from,struct AST_State *to,struct AST_Event *event,struct AST_Pipeline *pipeline) +struct AST_Transition* get_ast_transition(struct AST_State *from,struct AST_State *to,struct AST_Event *event,struct AST *statement) { struct AST_Transition *ret; ret=malloc(sizeof(struct AST_Transition)); @@ -531,7 +586,7 @@ struct AST_Transition* get_ast_transition(struct AST *from,struct AST_State *to, ret->from=from; ret->to=to; ret->event=event; - ret->pipeline=pipeline; + ret->statement=statement; return ret; } @@ -632,7 +687,9 @@ void delete_ast(struct AST* ast) case AST_TYPE_UNFINISHED_STATE: delete_ast_unchecked_state((struct AST_Unchecked_State*)ast); break; - + case AST_TYPE_IF: + delete_ast_if_statement((struct AST_If_Statement*)ast); + break; } } void delete_ast_event(struct AST_Event* ast) @@ -660,8 +717,8 @@ void delete_ast_events(struct AST_Events* ast) void delete_ast_transition(struct AST_Transition* ast) { if(ast==NULL)return; - if(ast->pipeline!=NULL) - delete_ast_pipeline(ast->pipeline); + if(ast->statement!=NULL) + delete_ast(ast->statement); free(ast); } void delete_ast_command(struct AST_Command* ast) @@ -842,7 +899,7 @@ struct AST* parse_not_expression(struct Translation_Data *translation_data) return parse_primary_expression(translation_data); } /* - * primary-expression: (expression) | id | id.id + * primary-expression: (expression) | id.id */ struct AST* parse_primary_expression(struct Translation_Data *translation_data) { @@ -880,7 +937,9 @@ struct AST* parse_primary_expression(struct Translation_Data *translation_data) } }else { - return (struct AST*)hold_id1; + delete_ast((struct AST*)hold_id1); + push_parsing_error("expected a selector",translation_data); + return NULL; } }else { @@ -921,18 +980,31 @@ struct AST_Unchecked_State* get_ast_unchecked_state(struct token *name) return ret; } +struct AST_If_Statement* get_ast_if_statement(struct AST *condition,struct AST *body,struct AST *else_statement) +{ + struct AST_If_Statement *ret; + + ret=malloc(sizeof(struct AST_If_Statement)); + ret->type=AST_TYPE_IF; + ret->condition=condition; + ret->body=body; + ret->else_statement=else_statement; + + return ret; +} struct AST_State* ast_check_state(struct AST_Unchecked_State *state,struct AST_States *states,struct Translation_Data *translation_data) { struct AST_State *ret; ret=Map_Check(states->states_map,state->name->data,state->name->size); - delete_ast_unchecked_state(state); if(ret==NULL) { - push_parsing_error("undefined state",translation_data); + push_error_with_token("undefined state",state->name,translation_data); + delete_ast_unchecked_state(state); return NULL; }else { + delete_ast_unchecked_state(state); return ret; } } @@ -956,4 +1028,11 @@ void delete_ast_unchecked_state(struct AST_Unchecked_State *ast) delete_token(ast->name); free(ast); } +void delete_ast_if_statement(struct AST_If_Statement *ast) +{ + delete_ast(ast->condition); + delete_ast(ast->body); + if(ast->else_statement) + delete_ast(ast->else_statement); +} #endif diff --git a/src/frontend/parser.h b/src/frontend/parser.h index a9f6b89..4745f63 100644 --- a/src/frontend/parser.h +++ b/src/frontend/parser.h @@ -25,6 +25,7 @@ enum AST_Type AST_TYPE_OP_NOT, AST_TYPE_OP_SELECTOR, AST_TYPE_UNFINISHED_STATE, + AST_TYPE_IF, }; struct AST { @@ -58,10 +59,10 @@ struct AST_Events struct AST_Transition { enum AST_Type type; - struct AST *from; + struct AST_State *from; struct AST_State *to; struct AST_Event *event; - struct AST_Pipeline *pipeline; + struct AST *statement; }; struct AST_Command { @@ -114,6 +115,13 @@ struct AST_Unchecked_State enum AST_Type type; struct token *name; }; +struct AST_If_Statement +{ + enum AST_Type type; + struct AST *condition; + struct AST *body; + struct AST *else_statement; +}; struct AST* parse_source(struct Translation_Data *translation_data); @@ -126,6 +134,9 @@ struct AST_Events* parse_events_inner(struct Translation_Data *translation_data) struct AST_Event* parse_event(struct Translation_Data *translation_data); struct AST_Transitions* parse_transitions_inner(struct Translation_Data *translation_data,struct AST_States *states,struct AST_Events *events ); struct AST_Transition* parse_transition(struct Translation_Data *translation_data,struct AST_States *states,struct AST_Events *events); + +struct AST* parse_statement(struct Translation_Data *translation_data,struct AST_States *states,struct AST_Events *events); + struct AST_Pipeline* parse_pipeline(struct Translation_Data *translation_data); struct AST_Command* parse_command(struct Translation_Data *translation_data); struct AST_State* parse_start_on(struct Translation_Data *translation_data,struct AST_States *states); @@ -140,16 +151,17 @@ struct AST_State* get_ast_state(struct token *id); struct AST_Event* get_ast_event(struct token *id); struct AST_States* get_ast_states(struct Queue *states); struct AST_Events* get_ast_events(struct Queue *events); -struct AST_Transition* get_ast_transition(struct AST *from,struct AST_State *to,struct AST_Event *event,struct AST_Pipeline *pipeline); +struct AST_Transition* get_ast_transition(struct AST_State *from,struct AST_State *to,struct AST_Event *event,struct AST *statement); struct AST_Command* get_ast_command(struct token *function_name,struct token *argument); 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,struct Map *machines_map); - struct AST_Binary_Expression* get_ast_binary_expression(struct AST *left,struct AST *right,enum AST_Type type); struct AST_Unary_Expression* get_ast_unary_expression(struct AST *operand,enum AST_Type type); struct AST_Unchecked_State* get_ast_unchecked_state(struct token *name); +struct AST_If_Statement* get_ast_if_statement(struct AST *condition,struct AST *body,struct AST *else_statement); + struct AST_State* ast_check_state(struct AST_Unchecked_State *state,struct AST_States *states,struct Translation_Data *translation_data); @@ -168,6 +180,7 @@ void delete_ast_translation_unit(struct AST_Translation_Unit *ast); void delete_ast_binary_expression(struct AST_Binary_Expression *ast); void delete_ast_unary_expression(struct AST_Unary_Expression *ast); void delete_ast_unchecked_state(struct AST_Unchecked_State *ast); +void delete_ast_if_statement(struct AST_If_Statement *ast); void pointer_array_fill(void **array,struct Queue *q); diff --git a/tests/.test5.swp b/tests/.test6.swp Binary files differindex 6e03612..dc85c11 100644 --- a/tests/.test5.swp +++ b/tests/.test6.swp diff --git a/tests/test4 b/tests/test4 index 579e54d..4610e2c 100644 --- a/tests/test4 +++ b/tests/test4 @@ -19,6 +19,8 @@ machine temp_switch starting on A; transitions [ - from ( !A && !light_on ) to B on event A execute kek; + from A to B on event A + if !light_bulb.light_on + execute kek; ]; ]; diff --git a/tests/test5 b/tests/test5 index fc9ff67..fb72d41 100644 --- a/tests/test5 +++ b/tests/test5 @@ -5,7 +5,10 @@ machine A starting on A; transitions [ - from A to A on event A given (B.C && !C.D) - execute eke; + from A to A on event A + if (A.A && !A.A) + execute eke; + else + execute asdf; ]; ]; diff --git a/tests/test6 b/tests/test6 new file mode 100644 index 0000000..3fed6d3 --- /dev/null +++ b/tests/test6 @@ -0,0 +1,26 @@ +machine light_bulb +[ + states [ light_on , light_off ]; + events [ turn_on , turn_off , switch ]; + starting on light_off; + transitions + [ + from light_on to light_off on event turn_off execute kek2 | kek; + from light_on to light_off on event switch; + from light_off to light_on on event turn_on; + from light_off to light_on on event switch execute kek; + + ]; +]; +machine temp_switch +[ + states [A,B]; + events [A]; + starting on A; + transitions + [ + from A to B on event A granted !light_bulb.light_on + if !light_bulb.light_on + execute kek; + ]; +]; |