added a lot of new fucntions

This commit is contained in:
Partho
2025-05-06 14:16:21 -04:00
parent 8b177b2807
commit 07255a5193
4 changed files with 125 additions and 13 deletions

View File

@ -12,7 +12,7 @@ extern bool entry_flag;
extern void insert_code_line(char *error_message, int line_number);
extern bool contains_errors;
extern int context;
extern TableNode* comparator;
//extern TableNode* comparator;
typedef enum {
ERROR_RUNTIME = 1,
ERROR_SYNTAX = 2,

View File

@ -682,12 +682,15 @@ simple_statement:
assignable{
//updating context for reserve/release
if(getAdInfoType((TableNode*)$1) == TYPE_ARRAY){
context = 1;
}
if(getAdInfoType((TableNode*)$1) == TYPE_RECORD){
else if(getAdInfoType((TableNode*)$1) == TYPE_RECORD){
context = 2;
} else{
context = 0;
}
comparator = $1;
//comparator = $1;
S_Push(TrueList, S_Init(), 0);
S_Push(FalseList, S_Init(), 0);
} ASSIGN expression
@ -1233,7 +1236,7 @@ assignable:
//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
if(getAdInfoType((TableNode*)$1) == TYPE_ARRAY){
PushContext(3);
//PushContext(3);
printdebug("%sCreating scope for array access", COLOR_CYAN);
//special scope for numbers for array access scope
cur = CreateScope(cur, -2,-1);
@ -1243,7 +1246,7 @@ assignable:
//we have to consider emmissions in ablocks
ablock
{
PopContext();
//PopContext();
//int type = getAdInfoType(look_up(getParent(cur), getName((TableNode*)$1)));
int type = getAdInfoType(getTypeEntry((TableNode*)$1));
printdebug("%stype is %d", COLOR_PURPLE, type);

View File

@ -5,7 +5,9 @@
Constant_Stack *head = NULL;
Context_stack *context_head = NULL;
TableNode* comparator = NULL;
//TableNode* comparator = NULL;
Function_Stack *function_head = NULL;
int temp2_count = 0;
int temp3_count = 0;
@ -55,14 +57,20 @@ Constant_Stack *Push(TableNode *type, void *value, bool isConst) {
return cs;
}
Context_stack *PushContext(int context) {
Context_stack *PushContext(int context, TableNode *typeToCompare) {
if (context != 1 && context != 2 && context != 3 && context != 0) {
printdebug(
"invalid context passed in");
return NULL;
}
Context_stack *cs = (Context_stack *)malloc(sizeof(Context_stack));
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;
@ -73,17 +81,89 @@ Context_stack *PushContext(int context) {
return cs;
}
int PopContext() {
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. 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;
}
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. Invalid.\n");
return -1;
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;
}
//should be
TableNode *getContextTypeEntry(Context_stack *cs) {
if (cs == NULL) {
printdebug(
"passed a NULL reference to getContextTypeEntry. Invalid.");
return undefined;
}
TableNode* tn = cs->typeToCompare;
return NULL;
}
Constant_Stack *Pop() {
if (head == NULL) {
printf("cannot pop from an empty stack. Invalid.\n");

View File

@ -17,10 +17,12 @@
extern FILE *ir_flag;
struct TableNode;
typedef struct TableNode TableNode;
typedef struct TFList TFList;
typedef struct CGNode CGNode;
typedef struct SymbolTable SymbolTable;
typedef struct Function_Stack Function_Stack;
typedef struct Context_stack Context_stack;
typedef struct Constant_Stack {
struct TableNode *theType;
@ -28,12 +30,33 @@ typedef struct Constant_Stack {
struct Constant_Stack *next;
bool isConst;
} 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 {
int size;
} primitive_info;
@ -112,10 +135,15 @@ void printdebug_impl(char *file, int line, const char *format, ...);
char *temp_var_gen();
char *arg_var_gen();
Constant_Stack *Push(TableNode *type, void *value, bool isConst);
Context_stack *PushContext(int context);
Context_stack *PushContext(int context,TableNode *typeToCompare);
Function_Stack *PushFunction(int arg, TableNode* FunctionType);
Constant_Stack *Pop();
int PopContext();
Context_stack *PopContext();
Function_Stack *PopFunction();
TableNode* getFunctionTypeContext(Function_Stack *fs);
int getContextType(Context_stack *cs);
Constant_Stack *Print_Stack();
int getArgumentNumber(Function_Stack *fs);
AdInfo *CreatePrimitiveInfo(int size);
int getPrimSize(TableNode *definition);
AdInfo *CreateArrayInfo(int dim, TableNode *type);
@ -192,6 +220,7 @@ extern TableNode *funtypeprime;
extern TableNode *undefined;
extern Constant_Stack *head;
extern Context_stack *context_head;
extern Function_Stack *function_head;
extern char *COLOR_RED;
extern char *COLOR_GREEN;