aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGalin Simeonov <gts@volconst.com>2021-07-14 01:43:40 +0300
committerGalin Simeonov <gts@volconst.com>2021-07-15 18:07:29 +0300
commitfbb038282af00eb09bc5a8ef7a0e7a7b76998683 (patch)
treef36565027c4da5edd5c03b53a78db4998b5cfb7c
parent3877ff9860d2cbeda7127d932e45573ff0d9600b (diff)
downloadMEGATRON-fbb038282af00eb09bc5a8ef7a0e7a7b76998683.tar.gz
added ability to attach statements to entry and exit of a given state
-rw-r--r--src/backend/targets/C/ast_to_c.c5
-rw-r--r--src/backend/targets/print/print.c6
-rw-r--r--src/frontend/lexer.c4
-rw-r--r--src/frontend/lexer.h2
-rw-r--r--src/frontend/parser.c56
-rw-r--r--src/frontend/parser.h6
6 files changed, 68 insertions, 11 deletions
diff --git a/src/backend/targets/C/ast_to_c.c b/src/backend/targets/C/ast_to_c.c
index 9b8f95c..cd01e67 100644
--- a/src/backend/targets/C/ast_to_c.c
+++ b/src/backend/targets/C/ast_to_c.c
@@ -209,7 +209,9 @@ void ast_transitions_of_state_to_c(FILE *out,struct AST_Machine *machine,struct
if(vector->number_of_transitions>0)
{
- fprintf(out,"\n\t%smachine_states_lock=1;\n",context_arrow);
+ fprintf(out,"\n\t%smachine_states_lock=1;\n\n",context_arrow);
+ ast_statement_to_c(out,1,vector->state->on_exit_statement,options);
+ fprintf(out,"\n");
fprintf(out,"\tswitch(event)\n\t{\n");
for(i=0;i<vector->number_of_transitions;++i)
{
@@ -227,6 +229,7 @@ void ast_transitions_of_state_to_c(FILE *out,struct AST_Machine *machine,struct
//ast_pipeline_to_c(out,3,vector->transitions[i]->pipeline);
ast_statement_to_c(out,indentation,vector->transitions[i]->statement,options);
+ ast_statement_to_c(out,indentation,vector->transitions[i]->to->on_entry_statement,options);
ast_to_c_print_tabs(out,indentation);
fprintf(out,"%smachine_states[",context_arrow);
ast_token_to_c(out,machine->id);
diff --git a/src/backend/targets/print/print.c b/src/backend/targets/print/print.c
index cfe22e9..162031f 100644
--- a/src/backend/targets/print/print.c
+++ b/src/backend/targets/print/print.c
@@ -90,6 +90,12 @@ void print_keyword_enum(enum Keyword code)
case KW_GRANTED:
printf("KW_GRANTED");
break;
+ case KW_ENTERING:
+ printf("KW_ENTERING");
+ break;
+ case KW_EXITING:
+ printf("KW_EXITING");
+ break;
default:
printf("LEXERROR");
}
diff --git a/src/frontend/lexer.c b/src/frontend/lexer.c
index 2d9bddd..10bb1c4 100644
--- a/src/frontend/lexer.c
+++ b/src/frontend/lexer.c
@@ -75,6 +75,10 @@ struct token* lex_step(struct Source *src,struct Translation_Data *translation_d
return get_token(src->src+src->where_in_src-sizeof("else")+1,sizeof("else")-1,KW_ELSE,src->current_row,src->current_column);
if(check_and_move_if_on_word("granted",sizeof("granted")-1,src,1))
return get_token(src->src+src->where_in_src-sizeof("granted")+1,sizeof("granted")-1,KW_GRANTED,src->current_row,src->current_column);
+ if(check_and_move_if_on_word("entering",sizeof("entering")-1,src,1))
+ return get_token(src->src+src->where_in_src-sizeof("entering")+1,sizeof("entering")-1,KW_ENTERING,src->current_row,src->current_column);
+ if(check_and_move_if_on_word("exiting",sizeof("exiting")-1,src,1))
+ return get_token(src->src+src->where_in_src-sizeof("exiting")+1,sizeof("exiting")-1,KW_EXITING,src->current_row,src->current_column);
diff --git a/src/frontend/lexer.h b/src/frontend/lexer.h
index 1134739..995a807 100644
--- a/src/frontend/lexer.h
+++ b/src/frontend/lexer.h
@@ -38,6 +38,8 @@ enum Keyword
KW_IF,
KW_ELSE,
KW_GRANTED,
+ KW_ENTERING,
+ KW_EXITING,
};
struct token
{
diff --git a/src/frontend/parser.c b/src/frontend/parser.c
index b38776e..4e370c0 100644
--- a/src/frontend/parser.c
+++ b/src/frontend/parser.c
@@ -258,15 +258,51 @@ struct AST_States* parse_states_inner(struct Translation_Data *translation_data)
}
}
/*
- * state : id
+ * state : id [ '[' ( 'on' 'entering' statement | 'on 'exiting' statement )* ']' ]
*
*/
struct AST_State* parse_state(struct Translation_Data *translation_data)
{
+ struct token *hold_id;
+ struct AST *hold_entry=NULL;
+ struct AST *hold_exit=NULL;
+ int i;
+
if(get_kw(translation_data)==KW_ID)
- return get_ast_state(Queue_Pop(translation_data->tokens));
- else
+ {
+ hold_id=Queue_Pop(translation_data->tokens);
+
+ if(get_and_check(translation_data,KW_OPEN_SQUARE))
+ {
+ for(i=0;i<2;++i)
+ if(get_and_check(translation_data,KW_ON))
+ {
+ if(get_and_check(translation_data,KW_ENTERING))
+ hold_entry=parse_statement(translation_data);
+ else if(get_and_check(translation_data,KW_EXITING))
+ hold_exit=parse_statement(translation_data);
+ else
+ break;
+ }
+ if(get_and_check(translation_data,KW_CLOSE_SQUARE))
+ {
+ }else
+ {
+ if(hold_entry)
+ delete_ast(hold_entry);
+ if(hold_exit)
+ delete_ast(hold_exit);
+ delete_token(hold_id);
+ push_parsing_error("missing closing ']' in state definition",translation_data);
+ return NULL;
+ }
+
+ }
+ return get_ast_state(hold_id,hold_entry,hold_exit);
+ }else
+ {
return NULL;
+ }
}
/*
* events-inner: id (, id)*
@@ -363,7 +399,7 @@ struct AST_Transition* parse_transition(struct Translation_Data *translation_dat
{
hold_granted=parse_transition_granted(translation_data,states,events);
- if(!get_and_check(translation_data,KW_SEMI_COLUMN) && (hold_statement=parse_statement(translation_data,states,events))==NULL)
+ if(!get_and_check(translation_data,KW_SEMI_COLUMN) && (hold_statement=parse_statement(translation_data))==NULL)
{ push_parsing_error("in statement of transition",translation_data); return NULL; }
/*GOAL!!!!!*/
@@ -396,7 +432,7 @@ struct AST* parse_transition_granted(struct Translation_Data *translation_data,s
/*
* 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* parse_statement(struct Translation_Data *translation_data)
{
struct AST *hold_expression;
struct AST *hold_body;
@@ -416,12 +452,12 @@ struct AST* parse_statement(struct Translation_Data *translation_data,struct AST
}else if(get_and_check(translation_data,KW_IF))
{
hold_expression=parse_expression(translation_data);
- hold_body=parse_statement(translation_data,states,events);
+ hold_body=parse_statement(translation_data);
if(hold_body)
{
if(get_and_check(translation_data,KW_ELSE))
{
- hold_else=parse_statement(translation_data,states,events);
+ hold_else=parse_statement(translation_data);
if(hold_else==NULL)
{
push_parsing_error("expected a statement after else",translation_data);
@@ -507,13 +543,17 @@ struct AST_State* parse_start_on(struct Translation_Data *translation_data,struc
}else { push_parsing_error("expected an identifier for starting state",translation_data); return NULL; }
}else { push_parsing_error("expected 'on'",translation_data); return NULL; }
}
-struct AST_State* get_ast_state(struct token *id)
+struct AST_State* get_ast_state(struct token *id,struct AST *entry,struct AST *exit)
{
struct AST_State *ret;
+ assert(entry==NULL || entry->type==AST_TYPE_COMMAND || entry->type==AST_TYPE_PIPELINE || entry->type==AST_TYPE_IF);
+ assert(exit==NULL || exit->type==AST_TYPE_COMMAND || exit->type==AST_TYPE_PIPELINE || exit->type==AST_TYPE_IF);
ret=malloc(sizeof(struct AST_State));
ret->type=AST_TYPE_STATE;
ret->name=id;
+ ret->on_entry_statement=entry;
+ ret->on_exit_statement=exit;
/*number is assigned in get_ast_states*/
/*parent machine is determined in anotation stage*/
diff --git a/src/frontend/parser.h b/src/frontend/parser.h
index 8845507..17e64e3 100644
--- a/src/frontend/parser.h
+++ b/src/frontend/parser.h
@@ -37,6 +37,8 @@ struct AST_State
struct token *name;
struct AST_Machine *parent;
size_t number;
+ struct AST *on_entry_statement;
+ struct AST *on_exit_statement;
};
struct AST_Event
{
@@ -138,7 +140,7 @@ struct AST_Transition* parse_transition(struct Translation_Data *translation_dat
struct AST* parse_transition_granted(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* parse_statement(struct Translation_Data *translation_data);
struct AST_Pipeline* parse_pipeline(struct Translation_Data *translation_data);
struct AST_Command* parse_command(struct Translation_Data *translation_data);
@@ -150,7 +152,7 @@ struct AST* parse_and_expression(struct Translation_Data *translation_data);
struct AST* parse_not_expression(struct Translation_Data *translation_data);
struct AST* parse_primary_expression(struct Translation_Data *translation_data);
-struct AST_State* get_ast_state(struct token *id);
+struct AST_State* get_ast_state(struct token *id,struct AST *entry,struct AST *exit);
struct AST_Event* get_ast_event(struct token *id);
struct AST_States* get_ast_states(struct Queue *states,struct Translation_Data *translation_data);
struct AST_Events* get_ast_events(struct Queue *events);