You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

257 lines
7.4 KiB

#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