diff options
Diffstat (limited to 'src/backend')
-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 |
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); |