Merge pull request #70 from UB-CSE443/side_branch

Side branch
This commit is contained in:
Moroseui
2025-05-07 00:12:59 -04:00
committed by GitHub
7 changed files with 441 additions and 116 deletions

View File

@ -8,9 +8,11 @@
#include "../src/symbol_table.h" #include "../src/symbol_table.h"
extern FILE *asc_flag; extern FILE *asc_flag;
extern bool tc_flag; extern bool tc_flag;
extern bool entry_flag;
extern void insert_code_line(char *error_message, int line_number); extern void insert_code_line(char *error_message, int line_number);
extern bool contains_errors; extern bool contains_errors;
extern int context;
//extern TableNode* comparator;
typedef enum { typedef enum {
ERROR_RUNTIME = 1, ERROR_RUNTIME = 1,
ERROR_SYNTAX = 2, ERROR_SYNTAX = 2,

View File

@ -170,6 +170,10 @@ definition:
} }
| ID { | ID {
if(strcmp($1, "entry") == 0){
//seen entry function
entry_flag = true;
}
emit_function_start(table_lookup(cur,$1)); emit_function_start(table_lookup(cur,$1));
//printf("ID: %s\n", $1); //printf("ID: %s\n", $1);
//printf("Type: %s\n", getType(table_lookup(getAncestor(cur), $1))); //printf("Type: %s\n", getType(table_lookup(getAncestor(cur), $1)));
@ -222,7 +226,7 @@ definition:
} }
if(type_of_param_type == TYPE_PRIMITIVE_TYPE){ if(type_of_param_type == TYPE_PRIMITIVE_TYPE){
CreateEntry(cur, TYPE_PRIMITIVE, parameter,NULL, getAdInfo(parameter))==undefined; CreateEntry(cur, TYPE_PRIMITIVE, parameter,NULL, getAdInfo(parameter));//==undefined;
// throw_error(ERROR_TYPE, "Duplicate defination of parameter in function definition.");} // throw_error(ERROR_TYPE, "Duplicate defination of parameter in function definition.");}
} }
@ -309,6 +313,7 @@ function_declaration:
if (CreateEntry(cur,TYPE_FUNCTION_DECLARATION, table_lookup(cur, $4), $2, CreateFunctionDeclarationInfo(-1, false,NULL)) == undefined) { if (CreateEntry(cur,TYPE_FUNCTION_DECLARATION, table_lookup(cur, $4), $2, CreateFunctionDeclarationInfo(-1, false,NULL)) == undefined) {
throw_error(ERROR_TYPE, "Duplicate defination of function in function declaration"); throw_error(ERROR_TYPE, "Duplicate defination of function in function declaration");
} }
} }
else{ else{
throw_error(ERROR_TYPE, "Function declatation (%s) is not a valid function type", $2); throw_error(ERROR_TYPE, "Function declatation (%s) is not a valid function type", $2);
@ -679,6 +684,12 @@ compound_statement:
simple_statement: simple_statement:
assignable{ assignable{
//updating context for reserve/release
if(getAdInfoType((TableNode*)$1) == TYPE_ARRAY || getAdInfoType((TableNode*)$1) == TYPE_FUNCTION_DECLARATION){
PushContext(getTypeEntry((TableNode*)$1));
printf("pushed %s to context stack in simple statement assignable rule\n",getName(getContextTypeEntry(context_head)));
}
S_Push(TrueList, S_Init(), 0); S_Push(TrueList, S_Init(), 0);
S_Push(FalseList, S_Init(), 0); S_Push(FalseList, S_Init(), 0);
} ASSIGN expression } ASSIGN expression
@ -722,15 +733,23 @@ simple_statement:
throw_error(ERROR_TYPE, "Assignable Assign Expression - Object %s of type %s != Object %s of type %s", getName(node), getType(node), getName((TableNode*)$4), getType((TableNode*)$4)); throw_error(ERROR_TYPE, "Assignable Assign Expression - Object %s of type %s != Object %s of type %s", getName(node), getType(node), getName((TableNode*)$4), getType((TableNode*)$4));
} }
$$ = undefined; $$ = undefined;
//resetting context
if(getAdInfoType((TableNode*)$1) == TYPE_ARRAY || getAdInfoType((TableNode*)$1) == TYPE_FUNCTION_DECLARATION){
PopContext();
printdebug("popped a context off in simplestatement assignable rule\n");
}
} }
| RETURN expression { | RETURN expression {
$$ = getTypeEntry((TableNode*)$2); $$ = getTypeEntry((TableNode*)$2);
emit_return(tn_or_const(NODE,(TableNode*)$2));} emit_return(tn_or_const(NODE,(TableNode*)$2));}
// | assignable ASSIGN RESERVE assignable{ }
|simple_statement error {yyerrok; yyclearin; printdebug("error in simple statement");} |simple_statement error {yyerrok; yyclearin; printdebug("error in simple statement");}
; ;
@ -762,10 +781,17 @@ ablock:
; ;
argument_list: argument_list:
expression{ expression{
PopContext();
printdebug("popped a context off in argument list\n");
incrementArgumentNumber(function_head);
TableNode* typeOfArg = getFunctionNumberType(getFunctionType(function_head), getArgumentNumber(function_head));
PushContext(typeOfArg);
printdebug("pushed %s to context stack\n",getName(typeOfArg));
TableNode * arg = CreateEntry(cur, getAdInfoType((TableNode*)$1), getTypeEntry((TableNode*)$1), arg_var_gen(), NULL); TableNode * arg = CreateEntry(cur, getAdInfoType((TableNode*)$1), getTypeEntry((TableNode*)$1), arg_var_gen(), NULL);
//inside a scope of an array call if line number is -2
if(getLine(cur)==-2){ if(getLine(cur)==-2){
if(getTypeEntry(arg) != integ){ if(getTypeEntry(arg) != integ){
throw_error(ERROR_TYPE, "Argument %s of type %s is not of type integer for an array argument", getName(arg), getType(arg)); throw_error(ERROR_TYPE, "Argument %s of type %s is not of type integer for an array argument", getName(arg), getType(arg));
@ -790,7 +816,10 @@ argument_list:
| expression | expression
{ {
PopContext();
printdebug("popped a context off in argument list (single arg rule)\n");
TableNode* arg = CreateEntry(cur, getAdInfoType((TableNode*)$1), getTypeEntry((TableNode*)$1), arg_var_gen(), NULL); TableNode* arg = CreateEntry(cur, getAdInfoType((TableNode*)$1), getTypeEntry((TableNode*)$1), arg_var_gen(), NULL);
//inside a scope of an array call if line number is -2
if(getLine(cur)==-2){ if(getLine(cur)==-2){
if(getTypeEntry(arg) != integ){ if(getTypeEntry(arg) != integ){
throw_error(ERROR_TYPE, "Argument %s of type %s is not of type integer for an array argument", getName(arg), getType(arg)); throw_error(ERROR_TYPE, "Argument %s of type %s is not of type integer for an array argument", getName(arg), getType(arg));
@ -1110,7 +1139,7 @@ expression:
} }
// TODO: We need to type check this. // TODO: We need to type check this.
| RESERVE ID { /*| RESERVE ID {
char* temp = temp_var_gen(); char* temp = temp_var_gen();
TableNode* node = CreateEntry(cur,TYPE_PRIMITIVE, addr, temp, NULL); TableNode* node = CreateEntry(cur,TYPE_PRIMITIVE, addr, temp, NULL);
TableNode * n = look_up(cur, $2); TableNode * n = look_up(cur, $2);
@ -1157,50 +1186,76 @@ expression:
$$=undefined; $$=undefined;
} }
cur = getParent(cur); cur = getParent(cur);
}*/
| RESERVE assignable{
if(getTypeEntry((TableNode*)$2) == getContextTypeEntry(context_head)
&& (/*getAdInfoType((TableNode*)$2)==TYPE_ARRAY ||*/ getAdInfoType(getTypeEntry((TableNode*)$2)) == TYPE_RECORD)){
char* temp = temp_var_gen();
//does this have integer?
TableNode* node = CreateEntry(cur,TYPE_RECORD, getContextTypeEntry(context_head), temp, NULL);
emit_reserve(node, tn_or_const(NODE,$2));
$$ = node;
}
else if(((getTypeEntry((TableNode*)$2)) == getArrType(getContextTypeEntry(context_head)))
&& (getAdInfoType(getContextTypeEntry(context_head)) == TYPE_ARRAY_TYPE)){
char* temp = temp_var_gen();
//does this have integer?
TableNode* node = CreateEntry(cur,TYPE_ARRAY, getContextTypeEntry(context_head), temp, NULL);
emit_reserve(node, tn_or_const(NODE,$2));
$$ = node;
}else if(((getTypeEntry((TableNode*)$2)) == getArrType(getContextTypeEntry(context_head)))
&& (getAdInfoType(getContextTypeEntry(context_head)) == TYPE_ARRAY_TYPE)){
char* temp = temp_var_gen();
//does this have integer?
TableNode* node = CreateEntry(cur,TYPE_ARRAY, getContextTypeEntry(context_head), temp, NULL);
emit_reserve(node, tn_or_const(NODE,$2));
$$ = node;
}else{
printf("%s on right %s on left\n",getType((TableNode*)$2),getName(getArrType(getContextTypeEntry(context_head))));
printf("%s is the name of the left\n",getName(getContextTypeEntry(context_head)));
$$ = undefined;
}
}
| RELEASE assignable{
/*TableNode * t = getFirstEntry(cur); if(getTypeEntry((TableNode*)$2) == getContextTypeEntry(context_head)
TableNode * n = look_up(cur, $2); && (/*getAdInfoType((TableNode*)$2)==TYPE_ARRAY ||*/ getAdInfoType(getTypeEntry((TableNode*)$2)) == TYPE_RECORD)){
if(getAdInfoType(n) == TYPE_ARRAY){ char* temp = temp_var_gen();
int array_dims = getNumArrDim(getTypeEntry(n)); //does this have integer?
if ($5 != array_dims) { TableNode* node = CreateEntry(cur,TYPE_RECORD, getContextTypeEntry(context_head), temp, NULL);
throw_error(ERROR_SYNTAX, "expected %d dimensions for this array but got %d", array_dims, $5); emit_release((TableNode*)$2);
}else{ $$ = node;
int traverse = 0; }
while(t != NULL && t != undefined && getName(t)[0] != '&'){ else if(((getTypeEntry((TableNode*)$2)) == getArrType(getContextTypeEntry(context_head)))
t = getNextEntry(t); && (getAdInfoType(getContextTypeEntry(context_head)) == TYPE_ARRAY_TYPE)){
} char* temp = temp_var_gen();
if(getTypeEntry(t) != integ){ //does this have integer?
throw_error(ERROR_TYPE, "Arg for an array is not of type integer"); TableNode* node = CreateEntry(cur,TYPE_ARRAY, getContextTypeEntry(context_head), temp, NULL);
$$= undefined; emit_release((TableNode*)$2);
}else{ $$ = node;
//seen first number }else{
traverse++; $$=undefined;
t = getNextEntry(t); }
while(traverse<array_dims){
while(t !=NULL && t!=undefined && getName(t)[0]!='&'){
t = getNextEntry(t);
}
if(getTypeEntry(t) != integ){
throw_error(ERROR_TYPE, "Arg for an array is not of type integer");
$$= undefined;
break;
}
traverse++;
t = getNextEntry(t);
}
if(traverse != array_dims){
throw_error(ERROR_TYPE, "Invalid number of arguments for array %s. Expected %d but got %d", getName(n), array_dims, traverse);
$$= undefined;}
}
}
}
*/
} }
| RELEASE ID {
cur = CreateScope(cur, -2,-1); /*
} ablock { TableNode* node = CreateEntry(cur,getAdInfoType((TableNode*)$2), getTypeEntry(), temp, NULL);
int a = S_Size(S_Peek(stack)) + 1;
emit_push_all(S_Peek(stack));
S_Pop(stack);
emit_function_call(node, a, tn_or_const(NODE, $2));
$$ = node;
TableNode * n = look_up(cur, $2);
if(getAdInfoType(n) != TYPE_ARRAY){
throw_error(ERROR_TYPE, "Invalid Reserve expression with object %s of type %s.",
getName(n), getType(n));
$$=undefined;
}
*/
/*
| RELEASE assignable{
char* temp = temp_var_gen(); char* temp = temp_var_gen();
TableNode* node = CreateEntry(cur,TYPE_PRIMITIVE, integ, temp, NULL); TableNode* node = CreateEntry(cur,TYPE_PRIMITIVE, integ, temp, NULL);
int a = S_Size(S_Peek(stack)) + 1; int a = S_Size(S_Peek(stack)) + 1;
@ -1215,49 +1270,11 @@ expression:
$$=undefined; $$=undefined;
} }
//doing more complicated type checking in a block //doing more complicated type checking in a block
if(getNumArrDim(getTypeEntry(n)) != $4){ //if(getNumArrDim(getTypeEntry(n)) != $4){
throw_error(ERROR_SYNTAX, "expected %d dimensions for this array but got %d", getNumArrDim(getTypeEntry(n)), $4); // throw_error(ERROR_SYNTAX, "expected %d dimensions for this array but got %d", getNumArrDim(getTypeEntry(n)), $4);
$$=undefined; // $$=undefined;
} //}
cur = getParent(cur);
/*
TableNode * t = getFirstEntry(cur);
TableNode * n = look_up(cur, $2);
if(getAdInfoType(n) == TYPE_ARRAY){
int array_dims = getNumArrDim(getTypeEntry(n));
if ($5 != array_dims) {
throw_error(ERROR_SYNTAX, "expected %d dimensions for this array but got %d", array_dims, $5);
}else{
int traverse = 0;
while(t != NULL && t != undefined && getName(t)[0] != '&'){
t = getNextEntry(t);
}
if(getTypeEntry(t) != integ){
throw_error(ERROR_TYPE, "Arg for an array is not of type integer");
$$= undefined;
}else{
//seen first number
traverse++;
t = getNextEntry(t);
while(traverse<array_dims){
while(t !=NULL && t!=undefined && getName(t)[0]!='&'){
t = getNextEntry(t);
}
if(getTypeEntry(t) != integ){
throw_error(ERROR_TYPE, "Arg for an array is not of type integer");
$$= undefined;
break;
}
traverse++;
t = getNextEntry(t);
}
if(traverse != array_dims){
throw_error(ERROR_TYPE, "Invalid number of arguments for array %s. Expected %d but got %d", getName(n), array_dims, traverse);
$$= undefined;}
}
}
}
*/
} }
/* /*
| RELEASE assignable | RELEASE assignable
@ -1295,14 +1312,38 @@ assignable:
} }
| assignable | assignable
{ {
//TableNode* pass = look_up(cur,$1);
//if(pass == undefined){
// throw_error(ERROR_TYPE, "Undefined variable %s", $1);
if(getAdInfoType((TableNode*)$1) == TYPE_ARRAY|| getAdInfoType((TableNode*)$1) == TYPE_FUNCTION_DECLARATION){
PushFunction(1,(TableNode*)$1);
PushContext(getFunctionNumberType(getFunctionType(function_head), getArgumentNumber(function_head)));
printdebug("pushed %s to function stack\n",getName((TableNode*)$1));
}
printdebug("%sBeginning rule 2 of assignable.", COLOR_CYAN); printdebug("%sBeginning rule 2 of assignable.", COLOR_CYAN);
//Creating a dummy scope where we create entries for all the arguments of a function call //Creating a dummy scope where we create entries for all the arguments of a function call
//Must also consider that we might be in an array access //Must also consider that we might be in an array access
if(getAdInfoType((TableNode*)$1) == TYPE_ARRAY){
//PushContext(3);
printdebug("%sCreating scope for array access", COLOR_CYAN);
//special scope for numbers for array access scope
cur = CreateScope(cur, -2,-1);
}else{
cur = CreateScope(cur, -1,-1); cur = CreateScope(cur, -1,-1);
}
if(getAdInfoType((TableNode*)$1) == TYPE_FUNCTION_DECLARATION){
//the function context is created. Pushing the type of the function since that has the information needed
}
} }
//we have to consider emmissions in ablocks //we have to consider emmissions in ablocks
ablock ablock
{ {
if(getAdInfoType((TableNode*)$1) == TYPE_ARRAY|| getAdInfoType((TableNode*)$1) == TYPE_FUNCTION_DECLARATION){
PopFunction();
}
//PopContext();
//int type = getAdInfoType(look_up(getParent(cur), getName((TableNode*)$1))); //int type = getAdInfoType(look_up(getParent(cur), getName((TableNode*)$1)));
int type = getAdInfoType(getTypeEntry((TableNode*)$1)); int type = getAdInfoType(getTypeEntry((TableNode*)$1));
printdebug("%stype is %d", COLOR_PURPLE, type); printdebug("%stype is %d", COLOR_PURPLE, type);

View File

@ -634,4 +634,4 @@ int getConst(TNodeOrConst *tnc) {
return 0; return 0;
} }
return -1; return -1;
} }

View File

@ -56,6 +56,9 @@ FILE *ir_flag = NULL;
FILE *cg_flag = NULL; FILE *cg_flag = NULL;
bool tc_flag = false; bool tc_flag = false;
bool DEBUG = false; bool DEBUG = false;
bool entry_flag = false;
//1 is for default, 2 is in array context, 3 is in record context
int context = 1;
int no_flag = 0; int no_flag = 0;
int arg; int arg;
bool contains_errors = false; bool contains_errors = false;

View File

@ -4,6 +4,10 @@
#include "symbol_table.h" #include "symbol_table.h"
Constant_Stack *head = NULL; Constant_Stack *head = NULL;
Context_stack *context_head = NULL;
//TableNode* comparator = NULL;
Function_Stack *function_head = NULL;
int temp2_count = 0; int temp2_count = 0;
int temp3_count = 0; int temp3_count = 0;
@ -53,6 +57,234 @@ Constant_Stack *Push(TableNode *type, void *value, bool isConst) {
return cs; return cs;
} }
Context_stack *PushContext(/*int context, */TableNode *typeToCompare) {
/*if (context != 1 && context != 2 && context != 3 && context != 0) {
printdebug(
"invalid context passed in");
return NULL;
}*/
if(typeToCompare == NULL) {
printdebug(
"passed a NULL reference to PushContext. Invalid.");
return NULL;
}
Context_stack *cs = (Context_stack *)calloc(1,sizeof(Context_stack));
//cs->con = context;
cs->typeToCompare = typeToCompare;
if (context_head == NULL) {
context_head = cs;
cs->next = NULL;
} else {
cs->next = context_head;
context_head = cs;
}
return cs;
}
Function_Stack *PushFunction(int arg, TableNode* FunctionType) {
if (FunctionType == NULL) {
printdebug(
"passed a NULL reference to PushFunction. Invalid.");
return NULL;
}
if(FunctionType == undefined) {
printdebug(
"passed an undefined reference to PushFunction. Invalid.");
return NULL;
}
Function_Stack *fs = (Function_Stack *)calloc(1,sizeof(Function_Stack));
fs->arg = arg;
fs->FunctionType = FunctionType;
if (function_head == NULL) {
function_head = fs;
fs->next = NULL;
} else {
fs->next = function_head;
function_head = fs;
}
return fs;
}
Function_Stack *PopFunction() {
if (function_head == NULL) {
printf("cannot pop from an empty stack from popfunction. Invalid.\n");
return NULL;
}
Function_Stack *fs = function_head;
function_head = function_head->next;
return fs;
}
int getArgumentNumber(Function_Stack *fs) {
if (fs == NULL) {
printdebug(
"passed a NULL reference to getArgumentNumber. Invalid.");
return -1;
}
return fs->arg;
}
int getTotalNumberArguments(TableNode* function) {
if (function == NULL) {
printdebug(
"passed a NULL reference to getTotalNumberArguments. Invalid.");
return -1;
}
if (getAdInfoType(function) != TYPE_FUNCTION_DECLARATION) {
printdebug(
"passed an invalid reference to getTotalNumberArguments. Invalid.");
return -1;
}
TableNode* functionType = getParameter(getTypeEntry(function));
if(functionType != undefined){
return -1;
}
if(getAdInfoType(functionType) != TYPE_RECORD_TYPE){
return 1;
}else{
return getRecLength(functionType);
}
}
Function_Stack* setArgumentNumber(Function_Stack *fs, int arg) {
if (fs == NULL) {
printdebug(
"passed a NULL reference to setArgumentNumber. Invalid.");
return NULL;
}
if(arg<getTotalNumberArguments(fs->FunctionType)){
//case where invalid argument number is being passed
return NULL;
}
fs->arg = arg;
return fs;
}
Function_Stack* setFunctionType(Function_Stack *fs, TableNode* functionType) {
if (fs == NULL) {
printdebug(
"passed a NULL reference to setFunctionType. Invalid.");
return NULL;
}
if (functionType == NULL) {
printdebug(
"passed a NULL reference to setFunctionType. Invalid.");
return NULL;
}
fs->FunctionType = functionType;
return fs;
}
TableNode* getFunctionType(Function_Stack *fs) {
if (fs == NULL) {
printdebug(
"passed a NULL reference to getFunctionType. Invalid.");
return undefined;
}
TableNode* tn = fs->FunctionType;
return tn;
}
Function_Stack* incrementArgumentNumber(Function_Stack *fs) {
if (fs == NULL) {
printdebug(
"passed a NULL reference to incrementArgumentNumber. Invalid.");
return NULL;
}
int cur=getArgumentNumber(fs);
setArgumentNumber(fs, cur+1);
//setFunctionType(fs, getFunctionNumberType(getFunctionType(fs), cur+1));
return fs;
}
TableNode* getRecordNumberType(TableNode* record, int arg){
if(record == NULL){
//case where NULL is being passed in
return undefined;
}
if(getAdInfoType(record) != TYPE_RECORD_TYPE){
//case where invalid argument number is being passed
return undefined;
}
if(arg<getRecLength(record)){
//case where invalid argument number is being passed
return undefined;
}
int count = 1;
TableNode* this = getFirstEntry(getRecList(record));
while(this != NULL && count<arg){
this = getNextEntry(this);
count++;
}
if(this == NULL){
//something went wrong. traversal is off
return undefined;
}
return getTypeEntry(this);
}
TableNode* getFunctionNumberType(TableNode* function, int arg){
if(function ==NULL){
//case where NULL is being passed in
return undefined;
}
if(arg<1){
//case where invalid argument number is being passed
return undefined;
}
if(getAdInfoType(function) == TYPE_FUNCTION_DECLARATION){
if(getAdInfoType(getParameter(function)) != TYPE_RECORD_TYPE){
return getParameter(function);
}else{
return getRecordNumberType(getParameter(function), arg);
}
} else if(getAdInfoType(function) == TYPE_ARRAY_TYPE){
return getArrType(function);
}else{
return undefined;
}
}
TableNode* getFunctionTypeContext(Function_Stack *fs) {
if (fs == NULL) {
printdebug(
"passed a NULL reference to getFunctionTypeContext. Invalid.");
return undefined;
}
TableNode* tn = fs->FunctionType;
return tn;
}
Context_stack *PopContext() {
if (context_head == NULL) {
printf("cannot pop from an empty stack from popcontext. Invalid.\n");
return NULL;
}
Context_stack *cs = context_head;
context_head = context_head->next;
//printf("Popped context off stack: number %d\n", cs->con);
return cs;
}
/*
int getContextType(Context_stack *cs) {
if (cs == NULL) {
printdebug(
"passed a NULL reference to getContextType. Invalid.");
return -1;
}
return cs->con;
}
*/
TableNode *getContextTypeEntry(Context_stack *cs) {
if (cs == NULL) {
printdebug(
"passed a NULL reference to getContextTypeEntry. Invalid.");
return undefined;
}
TableNode* tn = cs->typeToCompare;
return tn;
}
Constant_Stack *Pop() { Constant_Stack *Pop() {
if (head == NULL) { if (head == NULL) {
printf("cannot pop from an empty stack. Invalid.\n"); printf("cannot pop from an empty stack. Invalid.\n");
@ -824,31 +1056,31 @@ SymbolTable *init(SymbolTable *start) {
chara = (TableNode *)calloc(1, sizeof(TableNode)); chara = (TableNode *)calloc(1, sizeof(TableNode));
stri = (TableNode *)calloc(1, sizeof(TableNode)); stri = (TableNode *)calloc(1, sizeof(TableNode));
boo = (TableNode *)calloc(1, sizeof(TableNode)); boo = (TableNode *)calloc(1, sizeof(TableNode));
TableNode *reservetype = (TableNode *)calloc(1, sizeof(TableNode)); //TableNode *reservetype = (TableNode *)calloc(1, sizeof(TableNode));
TableNode *reserve = (TableNode *)calloc(1, sizeof(TableNode)); //TableNode *reserve = (TableNode *)calloc(1, sizeof(TableNode));
TableNode *releasetype = (TableNode *)calloc(1, sizeof(TableNode)); //TableNode *releasetype = (TableNode *)calloc(1, sizeof(TableNode));
TableNode *release = (TableNode *)calloc(1, sizeof(TableNode)); //TableNode *release = (TableNode *)calloc(1, sizeof(TableNode));
// TableNode* arr = (TableNode*)malloc(sizeof(SymbolTable)); // TableNode* arr = (TableNode*)malloc(sizeof(SymbolTable));
start->entries = integ; start->entries = integ;
integ->next = addr; integ->next = addr;
addr->next = chara; addr->next = chara;
chara->next = stri; chara->next = stri;
stri->next = boo; stri->next = boo;
boo->next = reservetype; boo->next = NULL;//reservetype;
reservetype->next = reserve; //reservetype->next = reserve;
reserve->next = releasetype; //reserve->next = releasetype;
releasetype->next = release; //releasetype->next = release;
release->next = NULL; //release->next = NULL;
integ->theName = "integer"; integ->theName = "integer";
addr->theName = "address"; addr->theName = "address";
chara->theName = "character"; chara->theName = "character";
boo->theName = "Boolean"; boo->theName = "Boolean";
stri->theName = "string"; stri->theName = "string";
reserve->theName = "reserve"; //reserve->theName = "reserve";
reservetype->theName = "reserve type"; //reservetype->theName = "reserve type";
releasetype->theName = "release type"; //releasetype->theName = "release type";
release->theName = "release"; //release->theName = "release";
// arr->theName= "array" // arr->theName= "array"
// root TableNode that all are pointing to but not in table // root TableNode that all are pointing to but not in table
@ -915,10 +1147,10 @@ SymbolTable *init(SymbolTable *start) {
chara->theType = prime; chara->theType = prime;
stri->theType = arrayprim; stri->theType = arrayprim;
boo->theType = prime; boo->theType = prime;
reserve->theType = reservetype; //reserve->theType = reservetype;
reservetype->theType = funtypeprime; //reservetype->theType = funtypeprime;
releasetype->theType = funtypeprime; //releasetype->theType = funtypeprime;
release->theType = releasetype; //release->theType = releasetype;
// arr->theType=arrayprim; // arr->theType=arrayprim;
@ -932,20 +1164,20 @@ SymbolTable *init(SymbolTable *start) {
chara->additionalinfo = CreatePrimitiveInfo(SIZE_CHAR); chara->additionalinfo = CreatePrimitiveInfo(SIZE_CHAR);
stri->additionalinfo = CreateArrayInfo(1, chara); stri->additionalinfo = CreateArrayInfo(1, chara);
boo->additionalinfo = CreatePrimitiveInfo(SIZE_BOOL); boo->additionalinfo = CreatePrimitiveInfo(SIZE_BOOL);
reserve->additionalinfo = CreateFunctionDeclarationInfo(0, false, NULL); //reserve->additionalinfo = CreateFunctionDeclarationInfo(0, false, NULL);
reservetype->additionalinfo = CreateFunctionTypeInfo(integ, addr); //reservetype->additionalinfo = CreateFunctionTypeInfo(integ, addr);
releasetype->additionalinfo = CreateFunctionTypeInfo(addr, integ); //releasetype->additionalinfo = CreateFunctionTypeInfo(addr, integ);
release->additionalinfo = CreateFunctionDeclarationInfo(0, false, NULL); //release->additionalinfo = CreateFunctionDeclarationInfo(0, false, NULL);
integ->tag = TYPE_PRIMITIVE_TYPE; // explicitly set the type for integ integ->tag = TYPE_PRIMITIVE_TYPE; // explicitly set the type for integ
addr->tag = TYPE_PRIMITIVE_TYPE; // explicitly set the type for addr addr->tag = TYPE_PRIMITIVE_TYPE; // explicitly set the type for addr
chara->tag = TYPE_PRIMITIVE_TYPE; // explicitly set the type for chara chara->tag = TYPE_PRIMITIVE_TYPE; // explicitly set the type for chara
stri->tag = TYPE_ARRAY_TYPE; // explicitly set the type for stri stri->tag = TYPE_ARRAY_TYPE; // explicitly set the type for stri
boo->tag = TYPE_PRIMITIVE_TYPE; // explicitly set the type for boo boo->tag = TYPE_PRIMITIVE_TYPE; // explicitly set the type for boo
reserve->tag = TYPE_FUNCTION_DECLARATION; //reserve->tag = TYPE_FUNCTION_DECLARATION;
reservetype->tag = TYPE_FUNCTION_TYPE; //reservetype->tag = TYPE_FUNCTION_TYPE;
releasetype->tag = TYPE_FUNCTION_TYPE; //releasetype->tag = TYPE_FUNCTION_TYPE;
release->tag = TYPE_FUNCTION_DECLARATION; //release->tag = TYPE_FUNCTION_DECLARATION;
// addr->additionalinfo = CreatePrimitiveInfo(8); // addr->additionalinfo = CreatePrimitiveInfo(8);
start->Line_Number = 1; start->Line_Number = 1;

View File

@ -17,10 +17,12 @@
extern FILE *ir_flag; extern FILE *ir_flag;
struct TableNode; typedef struct TableNode TableNode;
typedef struct TFList TFList; typedef struct TFList TFList;
typedef struct CGNode CGNode; typedef struct CGNode CGNode;
typedef struct SymbolTable SymbolTable; typedef struct SymbolTable SymbolTable;
typedef struct Function_Stack Function_Stack;
typedef struct Context_stack Context_stack;
typedef struct Constant_Stack { typedef struct Constant_Stack {
struct TableNode *theType; struct TableNode *theType;
@ -28,6 +30,32 @@ typedef struct Constant_Stack {
struct Constant_Stack *next; struct Constant_Stack *next;
bool isConst; bool isConst;
} Constant_Stack; } Constant_Stack;
//explanation about context stack
//If we have an array context, it means that we are expecting an array, either on the left side of assignable or as the (one of the) arguments that needs to be passed in for a function
//with the array context, either we are initializing the array OR we are reserving space for an element of the array. Can only reserve a record or an array so that element must be a record or an array.
//if we have a record context, that means we are expecting a record on the left side of the assignable assignment or we are expecting a record passed as an argument for a function call.
//we push and pop these contexts as needed.
//we can also push the table node of the thing that we are trying to look at. If it is supposed to be an array, for example, we can push that array onto the stack
//if it is a record, we can push that record onto the stack so that we can approperiately type check
//0 - no expecting array or record
//1 - expecting an array
//2 - expecting a record
//we also have a function call stack to look at what function call we are inside (what parameters it is expecting)
//This is distinct from the context stack. We don't necessarily add to the function call stack. After every valid argument, we simply add one to what argument we are seeing
//This lets us update the context stack as needed with the next tablenode type that we are comparing against
//we can also simply add to the function call stack if we have functions inside functions and then update as needed
typedef struct Context_stack {
//int con;
TableNode *typeToCompare;
struct Context_stack *next;
} Context_stack;
typedef struct Function_Stack{
int arg;
TableNode *FunctionType;
struct Function_Stack *next;
} Function_Stack;
typedef struct { typedef struct {
int size; int size;
@ -106,14 +134,28 @@ void printdebug_impl(char *file, int line, const char *format, ...);
char *temp_var_gen(); char *temp_var_gen();
char *arg_var_gen(); char *arg_var_gen();
int getTotalNumberArguments(TableNode* function);
Function_Stack* incrementArgumentNumber(Function_Stack *fs);
Function_Stack* setArgumentNumber(Function_Stack *fs, int arg);
Constant_Stack *Push(TableNode *type, void *value, bool isConst); Constant_Stack *Push(TableNode *type, void *value, bool isConst);
Context_stack *PushContext(/*int context,*/TableNode *typeToCompare);
Function_Stack *PushFunction(int arg, TableNode* FunctionType);
Constant_Stack *Pop(); Constant_Stack *Pop();
Context_stack *PopContext();
Function_Stack* setFunctionType(Function_Stack *fs, TableNode* functionType);
Function_Stack *PopFunction();
TableNode* getFunctionTypeContext(Function_Stack *fs);
TableNode* getFunctionType(Function_Stack *fs);
//int getContextType(Context_stack *cs);
Constant_Stack *Print_Stack(); Constant_Stack *Print_Stack();
int getArgumentNumber(Function_Stack *fs);
AdInfo *CreatePrimitiveInfo(int size); AdInfo *CreatePrimitiveInfo(int size);
int getPrimSize(TableNode *definition); int getPrimSize(TableNode *definition);
AdInfo *CreateArrayInfo(int dim, TableNode *type); AdInfo *CreateArrayInfo(int dim, TableNode *type);
int getNumArrDim(TableNode *definition); int getNumArrDim(TableNode *definition);
TableNode *getArrType(TableNode *definition); TableNode *getArrType(TableNode *definition);
TableNode* getRecordNumberType(TableNode* record, int arg);
TableNode* getFunctionNumberType(TableNode* function, int arg);
AdInfo *CreateRecordInfo(int length, SymbolTable *recordScope); AdInfo *CreateRecordInfo(int length, SymbolTable *recordScope);
int getRecTotal(TableNode *node); int getRecTotal(TableNode *node);
TableNode *setRecOffsetInfo(SymbolTable *scope, TableNode *node); TableNode *setRecOffsetInfo(SymbolTable *scope, TableNode *node);
@ -161,10 +203,14 @@ ListOfTable *getRestOfChildren(ListOfTable *lt);
TableNode *getFirstEntry(SymbolTable *st); TableNode *getFirstEntry(SymbolTable *st);
TableNode *getNextEntry(TableNode *tn); TableNode *getNextEntry(TableNode *tn);
TableNode *printTableNode(TableNode *tn); TableNode *printTableNode(TableNode *tn);
TableNode *getContextTypeEntry(Context_stack *cs);
int getElementOffset(TableNode *rec, char* id); int getElementOffset(TableNode *rec, char* id);
int getRecPosition(TableNode* rec, char* id); int getRecPosition(TableNode* rec, char* id);
int getStackSize(); int getStackSize();
extern int yylex(void); extern int yylex(void);
extern char *yytext; extern char *yytext;
extern int yyleng; extern int yyleng;
@ -188,6 +234,8 @@ extern TableNode *recprime;
extern TableNode *funtypeprime; extern TableNode *funtypeprime;
extern TableNode *undefined; extern TableNode *undefined;
extern Constant_Stack *head; extern Constant_Stack *head;
extern Context_stack *context_head;
extern Function_Stack *function_head;
extern char *COLOR_RED; extern char *COLOR_RED;
extern char *COLOR_GREEN; extern char *COLOR_GREEN;

View File

@ -1,5 +1,4 @@
#include "std.alpha" #include "../../library/std.alpha"
type main: string -> integer type main: string -> integer
function entry: main function entry: main