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.
eon/parser/parser.c

535 lines
13 KiB

5 years ago
#include <stdio.h>
#include "parser.h"
#include "../vars/vars.h"
#include "../hashmap/map.h"
//TODO put in header
void ex();
//TODO make a seperate file for this
typedef struct print {
int opperation;
double value;
char *string;
} print;
//TODO make a seperate file for this
typedef struct logic {
int opperation;
int expr;
struct nodeInfo *if_true;
struct nodeInfo *else_false;
struct nodeInfo *while_true;
} logic;
//TODO make a seperate file for this.
typedef struct nodeInfo {
int opperation;
enum type{
ASSIGNMENT,
EXPRESSION,
STATEMENT,
LOGIC,
FUNCTION,
FUNCTION_CALL
}type;
char *name;
Variable *var;
print printExpression;
logic logicalExpression;
struct nodeInfo *next;
struct nodeInfo *_function_body;
struct nodeInfo *statement_list;
struct nodeInfo *local_list;
struct map_void_t *local_var_list;
} nodeInfo;
//linked list heads. (move to a header file.)
//TODO put in header.
struct nodeInfo *statementHead = NULL;
struct Variable *head = NULL;
struct map_void_t *_function_list = NULL;
nodeInfo *createFunctionCall(char *_name) {
nodeInfo *newNode = malloc(sizeof(nodeInfo));
newNode->type = FUNCTION_CALL;
newNode->name = _name;
newNode->next = NULL;
return newNode;
}
/**
* free's a list's links.
* @param list of linked list to be free'ed
* @return void
*/
void freeLinkedList(nodeInfo *list) {
statementHead = NULL;
}
/**
* returns a copy of list
* @param nodeInfo list to be copied
* @return copied list
*/
nodeInfo *copyLinkedList(nodeInfo *list) {
nodeInfo *newList = malloc(sizeof(nodeInfo));
newList->next = NULL;
nodeInfo *copy_list = newList;
while(list->next != NULL) {
list = list->next;
copy_list->next = list;
copy_list = copy_list->next;
}
return newList;
}
nodeInfo *createFunction(char *_name, nodeInfo *_stmts) {
nodeInfo *newNode = malloc(sizeof(nodeInfo));
newNode->type = FUNCTION;
newNode->name = _name;
newNode->_function_body = malloc(sizeof(nodeInfo));
newNode->_function_body->next = copyLinkedList(_stmts);
freeLinkedList(_stmts);
return newNode;
}
nodeInfo* createVarAssignmentString(char *name, char *string) {
nodeInfo *newNode = malloc(sizeof(nodeInfo));
Variable *newVar = makeVariableString(name, string);
newNode->type = ASSIGNMENT;
newNode->opperation = 1;
newNode->var = newVar;
return newNode;
}
nodeInfo* createVarAssignmentInt(char *name, int number) {
nodeInfo *newNode = malloc(sizeof(nodeInfo));
Variable *newVar = makeVariableInt(name, number);
newNode->type = ASSIGNMENT;
newNode->opperation = 1;
newNode->var = newVar;
return newNode;
}
nodeInfo* createVarAssignmentChar(char *name, char Char) {
nodeInfo *newNode = malloc(sizeof(nodeInfo));
Variable *newVar = makeVariableChar(name, Char);
newNode->type = ASSIGNMENT;
newNode->opperation = 1;
newNode->var = newVar;
return newNode;
}
nodeInfo* createVarAssignmentDouble(char *name, double Double) {
nodeInfo *newNode = malloc(sizeof(nodeInfo));
Variable *newVar = makeVariableDouble(name, Double);
//new node stuff
newNode->type = ASSIGNMENT;
newNode->opperation = 1;
newNode->var = newVar;
return newNode;
}
nodeInfo *createPrintVarNode(char *varname) {
nodeInfo *newNode = malloc(sizeof(nodeInfo));
newNode->opperation = 6;
newNode->name = varname;
return newNode;
}
/**
*
* @params opperation value, see print struct for info
* @params int value to be printed
* @params string to be printed
*
*
*/
nodeInfo *createPrintStatement(int opperation, int value, char *string) {
nodeInfo *n = malloc(sizeof(nodeInfo));
print a;
//if we are going to print a varibles
//or we are going to print an int
switch(opperation) {
case 1:
n->opperation = 3;//this needs to not be a magic number lol
a.value = value;
a.opperation = 1;
n->printExpression = a;
return n;
break;
//else we are printing a string
case 2:
n->opperation = 3;
a.string = string;
a.opperation = 2;
n->printExpression = a;
return n;
break;
case 3:
n->opperation = 3;
a.string = string;
a.opperation = 3;
a.value = value;
n->printExpression = a;
return n;
break;
default:
printf("Something wrong with your print statement\n");
}
}
nodeInfo *createLogic(int opperation, int expr, nodeInfo *statement_list, nodeInfo *else_false) {
nodeInfo *n = malloc(sizeof(nodeInfo));
switch (opperation) {
//if statement
case 1:
//logical expression, see nodeInfo for opperation info
n->opperation = 4;
logic a;
a.opperation = 1;
a.expr = expr;
while (statement_list->statement_list != NULL) {
statement_list = statement_list->statement_list;
}
//now that we have the statement list, we need to make the head opperation 5
nodeInfo *newNode = malloc(sizeof(nodeInfo));
newNode->opperation = 5;
newNode->next = copyLinkedList(statement_list);
freeLinkedList(statement_list);
a.if_true = newNode;
//this removes the last statement list in statementHead
statement_list = NULL;
n->logicalExpression = a;
return n;
break;
//while loop
case 2:
/*n->opperation = 4;
logic b;
b.opperation = 2;
b.expr = expr;
b.while_true = if_true;
n->logicalExpression = b;
return n;*/
break;
default:
printf("check your yacc file for logical statements\n");
}
}
nodeInfo *createCompoundStatement(nodeInfo *n) {
if(statementHead == NULL) {
statementHead = malloc(sizeof(nodeInfo));
nodeInfo *newNode = malloc(sizeof(nodeInfo));
statementHead->opperation = 5;
statementHead->next = n;
statementHead->next->next = NULL;
statementHead->statement_list = NULL;
} else {
nodeInfo *p = statementHead;
//tereverse the list for the end
while(p->statement_list != NULL) {
p = p->statement_list;
}
p->next = malloc(sizeof(nodeInfo));
p->next = n;
p->next->next = NULL;
}
return statementHead;
}
/*
Adds statement to linked list.
@param nodeInfo link to be added.
@return head of linked list.
*/
nodeInfo *addToCompoundStatement(nodeInfo *n) {
if(statementHead == NULL) {
statementHead = malloc(sizeof(nodeInfo));
statementHead->opperation = 5;
statementHead->next = n;
statementHead->next->next = NULL;
statementHead->statement_list = NULL;
} else {
nodeInfo *p = statementHead;
while (p->statement_list != NULL) {
p = p->statement_list;
}
while (p->next != NULL) {
p = p->next;
}
p->next = malloc(sizeof(nodeInfo));
p->next = n;
p->next->next = NULL;
}
return statementHead;
}
/*
Executes a statment.
@param nodeInfo statement to be executed
@return void.
*/
//TODO return bool or int detailing the status of execution.
void ex(nodeInfo *n) {
switch(n->opperation){
case 1:
addVar(n->var->name, n->var->value);
break;
//TODO expression stuff
case 2:
break;
//print
case 3:
switch(n->printExpression.opperation) {
case 1:
printf("%d\n", (int) n->printExpression.value);
break;
case 2:
printf("%s\n", n->printExpression.string);
break;
case 3:
printf("%s%lf\n", n->printExpression.string, n->printExpression.value);
break;
default:
printf("something wrong with your if statement, check yacc file\n");
}
break;
//logic (if, while, for, etc)
case 4:
switch(n->logicalExpression.opperation) {
case 1:
if (n->logicalExpression.expr == 1) {
ex(n->logicalExpression.if_true);
}
break;
case 2:
while (n->logicalExpression.expr == 1) {
ex(n->logicalExpression.while_true);
}
break;
default:
printf("something wrong with logical expression check yacc\n");
}
break;
case 5:
while(n->next != NULL) {
n = n->next;
ex(n);
}
statementHead = NULL;
break;
case 6:
;
VariableValues *value = getValue(n->name);
switch(value->type) {
case STRINGVAR:
printf("%s\n", value->String);
break;
case INT:
printf("%d\n", value->Int);
break;
case CHARVAR:
printf("%c\n", value->Char);
break;
case DOUBLE:
printf("%f\n", value->Double);
break;
default:
printf("no such variable type called , keep coding!\n");
}
break;
default:
;
//TODO add error/exit here
switch(n->type) {
case FUNCTION_CALL:
;
nodeInfo *_stmts = *map_get(&*((map_void_t* ) _function_list), n->name);
while (_stmts->next != NULL) {
_stmts = _stmts->next;
ex(_stmts);
}
break;
case FUNCTION:
if (_function_list == NULL) {
_function_list = malloc(sizeof(map_void_t));
n->local_var_list = malloc(sizeof(map_void_t));
n->next = NULL;
n->local_list = NULL;
map_init(&*((map_void_t *) _function_list));
map_init(&*((map_void_t *) n->local_var_list));
map_set(&*((map_void_t* ) _function_list), n->name, &*n->_function_body);
} else {
map_set(&*((map_void_t* ) _function_list), n->name, &*n->_function_body);
}
break;
default:
;
//TODO add error here and close
}
}
}