aboutsummaryrefslogtreecommitdiffstats
path: root/src/frontend
diff options
context:
space:
mode:
authorGalin Simeonov <gts@volconst.com>2021-06-04 22:49:33 +0300
committerGalin Simeonov <gts@volconst.com>2021-07-15 18:07:29 +0300
commitc875f8795586056a676e8a643a44211041ce44d2 (patch)
tree88bfd4b4923ed30de31b130672dda65e4b18a607 /src/frontend
parenta26684a417729699e95b335a3d00798237ffba9b (diff)
downloadMEGATRON-c875f8795586056a676e8a643a44211041ce44d2.tar.gz
various stuffs
Diffstat (limited to 'src/frontend')
-rw-r--r--src/frontend/lexer.c3
-rw-r--r--src/frontend/lexer.h1
-rw-r--r--src/frontend/parser.c79
-rw-r--r--src/frontend/parser.h7
4 files changed, 61 insertions, 29 deletions
diff --git a/src/frontend/lexer.c b/src/frontend/lexer.c
index a832a17..2d9bddd 100644
--- a/src/frontend/lexer.c
+++ b/src/frontend/lexer.c
@@ -71,9 +71,10 @@ struct token* lex_step(struct Source *src,struct Translation_Data *translation_d
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);
+ 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);
diff --git a/src/frontend/lexer.h b/src/frontend/lexer.h
index 54c88fa..1134739 100644
--- a/src/frontend/lexer.h
+++ b/src/frontend/lexer.h
@@ -37,6 +37,7 @@ enum Keyword
KW_NOT,
KW_IF,
KW_ELSE,
+ KW_GRANTED,
};
struct token
{
diff --git a/src/frontend/parser.c b/src/frontend/parser.c
index 7af7af2..b38776e 100644
--- a/src/frontend/parser.c
+++ b/src/frontend/parser.c
@@ -15,6 +15,7 @@ struct AST_Translation_Unit* parse_translation_unit(struct Translation_Data *tra
struct Map *hold_command_map;
struct Map *hold_machines_map;
struct AST_Machine *hold_machine;
+ struct AST_Machine *hold_possible_duplicate;
machines=calloc(1,sizeof(struct Queue));
@@ -29,18 +30,22 @@ struct AST_Translation_Unit* parse_translation_unit(struct Translation_Data *tra
while(!get_and_check(translation_data,KW_EOF))
{
hold_machine=parse_machine(translation_data);
- /*TODO check for repeated machine ids*/
if(hold_machine)
{
- Map_Push(hold_machines_map,hold_machine->id->data,hold_machine->id->size,hold_machine);
- Queue_Push(machines,hold_machine);
+ if(hold_possible_duplicate=Map_Check(hold_machines_map,hold_machine->id->data,hold_machine->id->size))
+ {
+ push_error_with_token("duplicate machine name",hold_machine->id,translation_data);
+ push_error_with_token("conflicts with",hold_possible_duplicate->id,translation_data);
+ delete_ast_machine(hold_machine);
+ return NULL;
+ }else
+ {
+ Map_Push(hold_machines_map,hold_machine->id->data,hold_machine->id->size,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;
}
}
@@ -64,7 +69,6 @@ struct AST_Machine* parse_machine(struct Translation_Data *translation_data)
ret=(struct AST_Machine*)parse_machine_inner(hold_id,translation_data);
if(has_new_errors(translation_data))
{
- delete_ast_machine(ret);
touch_errors(translation_data);
return NULL;
@@ -76,13 +80,11 @@ struct AST_Machine* parse_machine(struct Translation_Data *translation_data)
else
{
push_parsing_error("';' expected after machine definition",translation_data);
- delete_ast_machine(ret);
return NULL;
}
}else
{
push_parsing_error("closing ']' expected",translation_data);
- delete_ast_machine(ret);
return NULL;
}
}else
@@ -232,9 +234,6 @@ struct AST_Machine* parse_machine_inner(struct token *machine_id,struct Translat
error_cleanup:
push_parsing_error("in machine",translation_data);
- if(states)delete_ast_states(states);
- if(events)delete_ast_events(events);
- if(transitions)delete_ast_transitions(transitions);
return NULL;
}
/*
@@ -255,7 +254,7 @@ struct AST_States* parse_states_inner(struct Translation_Data *translation_data)
}else
{
- return get_ast_states(ids);
+ return get_ast_states(ids,translation_data);
}
}
/*
@@ -323,7 +322,7 @@ struct AST_Transitions* parse_transitions_inner(struct Translation_Data *transla
}
}
/*
- * transition: 'from' state_id 'to' state_id 'on' 'event' event_id [ 'execute' pipeline ]
+ * transition: 'from' state_id 'to' state_id 'on' 'event' event_id [ granted-part ] [ statement-part ]
*
*/
struct AST_Transition* parse_transition(struct Translation_Data *translation_data,struct AST_States *states,struct AST_Events *events)
@@ -333,6 +332,7 @@ struct AST_Transition* parse_transition(struct Translation_Data *translation_dat
struct AST_State *hold_to;
struct AST_Event *hold_event;
struct AST *hold_statement=NULL;
+ struct AST *hold_granted=NULL;
struct token *hold_token;
if(get_and_check(translation_data,KW_FROM))
@@ -361,12 +361,13 @@ struct AST_Transition* parse_transition(struct Translation_Data *translation_dat
delete_token(hold_token);
if(hold_event!=NULL)
{
-
+ 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)
{ push_parsing_error("in statement of transition",translation_data); return NULL; }
/*GOAL!!!!!*/
- return get_ast_transition(hold_from,hold_to,hold_event,hold_statement);
+ return get_ast_transition(hold_from,hold_to,hold_event,hold_granted,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; }
@@ -379,6 +380,20 @@ struct AST_Transition* parse_transition(struct Translation_Data *translation_dat
}
/*
+ * granted-part : 'granted' expression
+ */
+struct AST* parse_transition_granted(struct Translation_Data *translation_data,struct AST_States *states,struct AST_Events *events)
+{
+ if(get_and_check(translation_data,KW_GRANTED))
+ {
+ return parse_expression(translation_data);
+ }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)
@@ -396,7 +411,6 @@ struct AST* parse_statement(struct Translation_Data *translation_data,struct AST
}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))
@@ -411,8 +425,6 @@ struct AST* parse_statement(struct Translation_Data *translation_data,struct AST
if(hold_else==NULL)
{
push_parsing_error("expected a statement after else",translation_data);
- delete_ast(hold_expression);
- delete_ast(hold_body);
return NULL;
}
}
@@ -420,8 +432,6 @@ struct AST* parse_statement(struct Translation_Data *translation_data,struct AST
}else
{
push_parsing_error("expected body statement in if",translation_data);
- if(hold_expression)
- delete_ast(hold_expression);
return NULL;
}
}else
@@ -520,7 +530,7 @@ struct AST_Event* get_ast_event(struct token *id)
return ret;
}
-struct AST_States* get_ast_states(struct Queue *states)
+struct AST_States* get_ast_states(struct Queue *states,struct Translation_Data *translation_data)
{
struct AST_States *ret;
struct AST_State *hold_state;
@@ -538,8 +548,24 @@ struct AST_States* get_ast_states(struct Queue *states)
while(states->size>0)
{
hold_state=Queue_Pop(states);
- /*TODO check for redeclaration*/
- Map_Push(ret->states_map,hold_state->name->data,hold_state->name->size,hold_state);
+
+ if(Map_Check(ret->states_map,hold_state->name->data,hold_state->name->size))
+ {
+ size_t i;
+
+ push_error_with_token("duplicate state in states definition",hold_state->name,translation_data);
+
+ for(i=states->size+1;i<ret->number_of_states;++i)
+ delete_ast_state(ret->states[i]);
+ delete_ast_state(hold_state);
+ while(states->size>0)
+ delete_ast_state(Queue_Pop(states));
+
+ return NULL;
+ }else
+ {
+ 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;
@@ -578,7 +604,7 @@ struct AST_Events* get_ast_events(struct Queue *events)
return ret;
}
-struct AST_Transition* get_ast_transition(struct AST_State *from,struct AST_State *to,struct AST_Event *event,struct AST *statement)
+struct AST_Transition* get_ast_transition(struct AST_State *from,struct AST_State *to,struct AST_Event *event,struct AST *granted,struct AST *statement)
{
struct AST_Transition *ret;
ret=malloc(sizeof(struct AST_Transition));
@@ -586,6 +612,7 @@ struct AST_Transition* get_ast_transition(struct AST_State *from,struct AST_Stat
ret->from=from;
ret->to=to;
ret->event=event;
+ ret->granted=granted;
ret->statement=statement;
return ret;
diff --git a/src/frontend/parser.h b/src/frontend/parser.h
index 4745f63..8845507 100644
--- a/src/frontend/parser.h
+++ b/src/frontend/parser.h
@@ -62,6 +62,7 @@ struct AST_Transition
struct AST_State *from;
struct AST_State *to;
struct AST_Event *event;
+ struct AST *granted;
struct AST *statement;
};
struct AST_Command
@@ -135,6 +136,8 @@ 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_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_Pipeline* parse_pipeline(struct Translation_Data *translation_data);
@@ -149,9 +152,9 @@ struct AST* parse_primary_expression(struct Translation_Data *translation_data);
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_States* get_ast_states(struct Queue *states,struct Translation_Data *translation_data);
struct AST_Events* get_ast_events(struct Queue *events);
-struct AST_Transition* get_ast_transition(struct AST_State *from,struct AST_State *to,struct AST_Event *event,struct AST *statement);
+struct AST_Transition* get_ast_transition(struct AST_State *from,struct AST_State *to,struct AST_Event *event,struct AST *granted,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);