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.
535 lines
13 KiB
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
|
||
|
|
||
|
}
|
||
|
|
||
|
|
||
|
}
|
||
|
|
||
|
}
|