aboutsummaryrefslogtreecommitdiffstats
path: root/src/backend
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend')
-rw-r--r--src/backend/backend.c31
-rw-r--r--src/backend/backend.h1
-rw-r--r--src/backend/targets/C/ast_to_c.c76
-rw-r--r--src/backend/targets/C/ast_to_c.h4
-rw-r--r--src/backend/targets/print/print.c27
-rw-r--r--src/backend/targets/print/print.h1
6 files changed, 129 insertions, 11 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);