#ifndef PARSER_C #define PARSER_C #include "parser.h" /* Author: xerox Updated: 1/19/2020 create variable given name, value, and type. */ static node_info* create_variable_const(char* p_name, void* value, variable_type var_type) { node_info* new_node = malloc(sizeof(*new_node)); if (!new_node) return NULL; memset(new_node, NULL, sizeof(*new_node)); variable* new_var = make_variable(p_name, value, var_type); if (!new_var) return NULL; new_node->assignment = (assignment_operation*)malloc(sizeof(assignment_operation)); if (!new_node->assignment) return NULL; memset(new_node->assignment, NULL, sizeof(*new_node->assignment)); new_node->operation = ASSIGNMENT_OPERATION; new_node->operation_type.assignment = ASSIGN_FROM_CONST; new_node->assignment->var = new_var; return new_node; } /* Author: xerox Updated: 1/20/2020 Move value from one variable to another. */ static node_info* move_value(char* to, char* from) { node_info* new_node = (node_info *)malloc(sizeof(node_info)); if (!from || !new_node || !to) return NULL; memset(new_node, NULL, sizeof(*new_node)); new_node->assignment = (assignment_operation*)malloc(sizeof(*new_node->assignment)); if (!new_node->assignment) return NULL; memset(new_node->assignment, NULL, sizeof(*new_node->assignment)); new_node->operation = ASSIGNMENT_OPERATION; new_node->operation_type.assignment = ASSIGN_FROM_VAR; new_node->assignment->from = from; new_node->assignment->to = to; return new_node; } /* Author: xerox Updated: 1/19/2020 create logic node (logical expression) */ static node_info* create_logic_node(logic* logic_expr) { node_info* new_node = malloc(sizeof(node_info)); if (!new_node || !logic_expr) return NULL; memset(new_node, NULL, sizeof(*new_node)); new_node->operation = LOGIC_OPERATION; new_node->logical_expr = logic_expr; return new_node; } /* Author: xerox Updated: 1/20/2020 Executes a statment. @param nodeInfo statement to be executed @return void. */ static void exec_stmt(node_info *exec_node) { if (!exec_node) return; switch (exec_node->operation) { case ASSIGNMENT_OPERATION: switch (exec_node->operation_type.assignment) { case ASSIGN_FROM_CONST: add_var(exec_node->assignment->var->name, exec_node->assignment->var->value, _var_map); break; case ASSIGN_FROM_VAR: add_var(exec_node->assignment->to, get_value(exec_node->assignment->from, _var_map), _var_map); break; default: ; #if DEON_DEBUGGING printf("[error] unkown assignment operation: 0x%x", exec_node->operation_type.assignment); #endif } break; case LOGIC_OPERATION: { switch (exec_node->logical_expr->type) { case IF_LOGIC: { variable_values* p_var_values = get_value(exec_node->logical_expr->condition_var, _var_map); if (!p_var_values) return; if (*(unsigned char*)p_var_values->data_ptr) exec_stmt(exec_node->logical_expr->stmt_list); break; } case WHILE_LOGIC: { variable_values* p_var_values = get_value(exec_node->logical_expr->condition_var, _var_map); if (!p_var_values) return; while (*(unsigned char*)p_var_values->data_ptr) { exec_stmt(exec_node->logical_expr->stmt_list); p_var_values = get_value(exec_node->logical_expr->condition_var, _var_map); } break; } default: ; #if DEON_DEBUGGING printf("[error] unknown logic operation\n"); #endif } } // execute statement list. case EXEC_STMT_LIST_OPERATION: { if(exec_node->statement_list) exec_node = exec_node->statement_list; while (exec_node->next) { exec_node = exec_node->next; exec_stmt(exec_node); } break; } // print statement case PRINT_OPERATION: { switch (exec_node->operation_type.print) { case PRINT_CONSTANT: { switch (exec_node->print_expr->type) { case VAR_STRING: printf("%s\n", (char*)exec_node->print_expr->value); break; case VAR_INT: printf("%d\n", *(int*)exec_node->print_expr->value); break; case VAR_BYTE: printf("%c\n", *(char*)exec_node->print_expr->value); break; case VAR_DOUBLE: printf("%f\n", *(double*)exec_node->print_expr->value); break; case VAR_VOID: //TODO add void variable type break; default: ; #if DEON_DEBUGGING printf("[error] unable to print variable of type: 0x%x\n", exec_node->print_expr->type); #endif } break; } case PRINT_VARIABLE: { variable_values* p_var = get_value(exec_node->var->name, _var_map); switch (p_var->type) { case VAR_STRING: printf("%s\n", (char*)p_var->data_ptr); break; case VAR_INT: printf("%d\n", *(int*)p_var->data_ptr); break; case VAR_BYTE: printf("%c\n", *(char*)p_var->data_ptr); break; case VAR_DOUBLE: printf("%f\n", *(double*)p_var->data_ptr); break; case VAR_VOID: //TODO add void variable type break; default: ; #if DEON_DEBUGGING printf("[error] unable to print variable of type: 0x%x\n", p_var->type); #endif } break; } default: ; #if DEON_DEBUGGING printf("[error] unknown print type: 0x%x\n", exec_node->operation_type.print); #endif } break; } case FUNCTION_OPERATION: { switch (exec_node->operation_type.func) { case FUNCTION_CALL: { node_info* _stmts = *map_get(&*((map_void_t*)_function_list), exec_node->name); _stmts = _stmts->statement_list; while (_stmts->statement_list) { _stmts = _stmts->statement_list; exec_stmt(_stmts); } break; } case FUNCTION: { if (!_function_list) { _function_list = malloc(sizeof(map_void_t)); map_init(_function_list); map_set(_function_list, exec_node->name, exec_node->function_body); } else //else we dont malloc, we just put the function inside of the hashmap. map_set(_function_list, exec_node->name, exec_node->function_body); break; } default: ; #if DEON_DEBUGGING printf("[error] unknown function operation: 0x%x\n", exec_node->operation_type.func); #endif } break; } default: ; #if DEON_DEBUGGING printf("[error] unknown operation: 0x%x\n", exec_node->operation); #endif } } #endif