#ifndef BACKEND_C #define BACKEND_C BACKEND_C #include /*returns an array of pointers to state_and_transition structs*/ struct State_And_Transitions** extract_transition_table(struct AST_States *states,struct AST_Transitions *transitions) { struct State_And_Transitions **ret; struct AST_State *hold_state; struct Queue *qs; size_t i; ret=malloc(sizeof(struct State_And_Transitions)*states->number_of_states); /*calloc also initialises the queues *i-th queue is for transitions starting from the i-th state * */ qs=calloc(sizeof(struct Queue),states->number_of_states); /*traverse transitions and push them into the queue of their coresponding state*/ for(i=0;isize;++i) { hold_state=transitions->transitions[i]->from; Queue_Push(qs+hold_state->number,transitions->transitions[i]); } /*condense the queues into the arrays*/ for(i=0;inumber_of_states;++i) { ret[i]=malloc(sizeof(struct State_And_Transitions)+sizeof(struct AST_Transitions *[qs[i].size])); ret[i]->state=states->states[i]; ret[i]->number_of_transitions=qs[i].size; pointer_array_fill((void**)ret[i]->transitions,qs+i); } free(qs); return ret; } _Bool expression_is_binary(struct AST* expression) { return (expression->type==AST_TYPE_OP_OR || expression->type==AST_TYPE_OP_AND || expression->type==AST_TYPE_OP_SELECTOR); } _Bool expression_is_unary(struct AST* expression) { return (expression->type==AST_TYPE_OP_NOT); } _Bool state_is_in_states(struct AST_State *state,struct AST_States *states) { return state==Map_Check(states->states_map,state->name->data,state->name->size); } struct AST_State* extract_state(struct AST *expression,struct AST_States *states) { struct AST_State *hold_state; assert(expression->type==AST_TYPE_OP_NOT || expression->type==AST_TYPE_OP_AND || expression->type==AST_TYPE_OP_OR || expression->type==AST_TYPE_STATE ); if(expression->type==AST_TYPE_STATE) { if(state_is_in_states((struct AST_State*)expression,states)) return (struct AST_State*)expression; else return NULL; }else if(expression_is_binary(expression)) { hold_state=extract_state(((struct AST_Binary_Expression*)expression)->left,states); if(hold_state) return hold_state; else return extract_state(((struct AST_Binary_Expression*)expression)->right,states); }else { return extract_state(((struct AST_Unary_Expression*)expression)->operand,states); } } _Bool check_expression(struct AST *state,struct AST_Translation_Unit *unit) { } _Bool check_transition(struct AST *state,struct AST_Translation_Unit *unit) { } void anotate_unchecked_states(struct AST_Translation_Unit *unit,struct Translation_Data *translation_data) { size_t i; for(i=0;inumber_of_machines;++i) { anotate_machine(unit->machines[i],unit,translation_data); } } void anotate_machine(struct AST_Machine *machine,struct AST_Translation_Unit *unit,struct Translation_Data *translation_data) { size_t i; for(i=0;itransitions->size;++i) { machine->transitions->transitions[i]->statement=anotate_statement(machine->transitions->transitions[i]->statement,unit,machine,translation_data); } if(has_new_errors(translation_data)) { push_error_with_token("in machine",machine->id,translation_data); 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; struct AST *hold_left; struct AST *hold_right; if(expression_is_binary(expression)) { hold_left=((struct AST_Binary_Expression*)expression)->left; hold_right=((struct AST_Binary_Expression*)expression)->right; if(expression->type==AST_TYPE_OP_SELECTOR) { hold_machine=Map_Check(unit->machines_map,((struct AST_Unchecked_State*)hold_left)->name->data,((struct AST_Unchecked_State*)hold_left)->name->size); if(hold_machine==NULL) { push_error_with_token("machine id is undefined",((struct AST_Unchecked_State*)hold_left)->name,translation_data); delete_ast(expression); return NULL; }else { hold_left=(struct AST*)ast_check_state((struct AST_Unchecked_State*)hold_right,hold_machine->states,translation_data); 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 { AS_BIN_EXPR_PTR(expression)->right=anotate_expression(AS_BIN_EXPR_PTR(expression)->right,unit,current_machine,translation_data); AS_BIN_EXPR_PTR(expression)->left=anotate_expression(AS_BIN_EXPR_PTR(expression)->left,unit,current_machine,translation_data); return expression; } }else if(expression_is_unary(expression)) { AS_UN_EXPR_PTR(expression)->operand=anotate_expression(AS_UN_EXPR_PTR(expression)->operand,unit,current_machine,translation_data); }else if(expression->type==AST_TYPE_UNFINISHED_STATE) { hold_left=(struct AST*)ast_check_state((struct AST_Unchecked_State*)expression,current_machine->states,translation_data); ((struct AST_State*)hold_left)->parent=current_machine; return hold_left; } } #endif