works?
This commit is contained in:
105
src/grammar.y
105
src/grammar.y
@ -681,16 +681,10 @@ compound_statement:
|
||||
simple_statement:
|
||||
assignable{
|
||||
//updating context for reserve/release
|
||||
if(getAdInfoType((TableNode*)$1) == TYPE_ARRAY){
|
||||
|
||||
context = 1;
|
||||
if(getAdInfoType((TableNode*)$1) == TYPE_ARRAY || getAdInfoType((TableNode*)$1) == TYPE_FUNCTION_DECLARATION){
|
||||
PushContext(getTypeEntry((TableNode*)$1));
|
||||
printdebug("pushed %s to context stack in simple statement assignable rule\n",getName(getTypeEntry((TableNode*)$1)));
|
||||
}
|
||||
else if(getAdInfoType((TableNode*)$1) == TYPE_RECORD){
|
||||
context = 2;
|
||||
} else{
|
||||
context = 0;
|
||||
}
|
||||
//comparator = $1;
|
||||
S_Push(TrueList, S_Init(), 0);
|
||||
S_Push(FalseList, S_Init(), 0);
|
||||
} ASSIGN expression
|
||||
@ -733,7 +727,10 @@ simple_statement:
|
||||
}
|
||||
$$ = undefined;
|
||||
//resetting context
|
||||
context = 0;
|
||||
if(getAdInfoType((TableNode*)$1) == TYPE_ARRAY || getAdInfoType((TableNode*)$1) == TYPE_FUNCTION_DECLARATION){
|
||||
PopContext();
|
||||
printdebug("popped a context off in simplestatement assignable rule\n");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -777,9 +774,15 @@ ablock:
|
||||
;
|
||||
|
||||
|
||||
|
||||
argument_list:
|
||||
|
||||
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);
|
||||
//inside a scope of an array call if line number is -2
|
||||
if(getLine(cur)==-2){
|
||||
@ -806,6 +809,8 @@ argument_list:
|
||||
| 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);
|
||||
//inside a scope of an array call if line number is -2
|
||||
if(getLine(cur)==-2){
|
||||
@ -1127,7 +1132,7 @@ expression:
|
||||
}
|
||||
|
||||
// TODO: We need to type check this.
|
||||
| RESERVE ID {
|
||||
/*| RESERVE ID {
|
||||
char* temp = temp_var_gen();
|
||||
TableNode* node = CreateEntry(cur,TYPE_PRIMITIVE, addr, temp, NULL);
|
||||
TableNode * n = look_up(cur, $2);
|
||||
@ -1140,7 +1145,7 @@ expression:
|
||||
emit_reserve(node, tn_or_const(INTEGER, &v));
|
||||
$$ = node;
|
||||
}
|
||||
/*| RELEASE ID {
|
||||
| RELEASE ID {
|
||||
TableNode * n = look_up(cur, $2);
|
||||
if(getAdInfoType(n) != TYPE_RECORD){
|
||||
throw_error(ERROR_TYPE, "Invalid Release expression with object %s of type %s.",
|
||||
@ -1151,7 +1156,7 @@ expression:
|
||||
TableNode* node = CreateEntry(cur,TYPE_PRIMITIVE, integ, temp, NULL);
|
||||
//emit release needed here
|
||||
$$ = node;
|
||||
}*/
|
||||
}
|
||||
| RESERVE ID {
|
||||
cur = CreateScope(cur, -2,-1);
|
||||
} ablock {
|
||||
@ -1174,7 +1179,66 @@ expression:
|
||||
$$=undefined;
|
||||
}
|
||||
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;
|
||||
}
|
||||
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{
|
||||
$$ = undefined;
|
||||
}
|
||||
}
|
||||
|
||||
| RELEASE 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_release((TableNode*)$2);
|
||||
$$ = node;
|
||||
}
|
||||
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_release((TableNode*)$2);
|
||||
$$ = node;
|
||||
}else{
|
||||
$$=undefined;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
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();
|
||||
TableNode* node = CreateEntry(cur,TYPE_PRIMITIVE, integ, temp, NULL);
|
||||
@ -1232,6 +1296,14 @@ 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);
|
||||
//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
|
||||
@ -1246,16 +1318,17 @@ assignable:
|
||||
|
||||
if(getAdInfoType((TableNode*)$1) == TYPE_FUNCTION_DECLARATION){
|
||||
//the function context is created. Pushing the type of the function since that has the information needed
|
||||
PushFunction(1, getTypeEntry((TableNode*)$1));
|
||||
}
|
||||
|
||||
}
|
||||
//we have to consider emmissions in ablocks
|
||||
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)));
|
||||
PopFunction();
|
||||
int type = getAdInfoType(getTypeEntry((TableNode*)$1));
|
||||
printdebug("%stype is %d", COLOR_PURPLE, type);
|
||||
printdebug("%s", getName((TableNode*)$1));
|
||||
|
@ -190,7 +190,8 @@ void emit_binary_op(
|
||||
Op op,
|
||||
TableNode *result,
|
||||
TNodeOrConst *arg1,
|
||||
TNodeOrConst *arg2) {
|
||||
TNodeOrConst *arg2
|
||||
) {
|
||||
emit_helper();
|
||||
current->opcode = op;
|
||||
// TODO: create temp and remove result from param list
|
||||
@ -315,6 +316,9 @@ void emit_return(TNodeOrConst *value) {
|
||||
void emit_reserve(TableNode *result, TNodeOrConst *size) {
|
||||
// this needs to change
|
||||
// we need to take a int
|
||||
/*
|
||||
emit_binary_op(E_MUL, result,
|
||||
*/
|
||||
emit_parameter(size);
|
||||
emit_function_call(result, 1, tn_or_const(NODE, look_up(cur, "reserve")));
|
||||
}
|
||||
@ -345,8 +349,12 @@ void emit_address_of(TableNode *x, TNodeOrConst *y) {
|
||||
current->operand1 = y;
|
||||
}
|
||||
|
||||
void emit_field_access(char *result, char *record, char *field) {
|
||||
void emit_field_access(TableNode *result, TNodeOrConst *record, int offset){
|
||||
emit_helper();
|
||||
current->opcode = E_DEREF_RIGHT;
|
||||
current->result = result;
|
||||
current->operand1 = record;
|
||||
current->operand2 = tn_or_const(INTEGER, &offset);
|
||||
}
|
||||
|
||||
void emit_array_access(Op op, TableNode *result, TNodeOrConst *array, TNodeOrConst *index) {
|
||||
@ -587,19 +595,22 @@ void emit_as_file(FILE *out_file, Instruction *i) {
|
||||
getName(i->result),
|
||||
get_string(i->operand1));
|
||||
break;
|
||||
|
||||
case E_DEREF_RIGHT:
|
||||
fprintf(out_file,
|
||||
"%4.d: %s = *%s\n",
|
||||
"%4.d: %s = *((char * )%s + %s)\n",
|
||||
i->index,
|
||||
getName(i->result),
|
||||
get_string(i->operand1));
|
||||
get_string(i->operand1),
|
||||
get_string(i->operand2)
|
||||
);
|
||||
break;
|
||||
case E_DEREF_LEFT:
|
||||
fprintf(out_file,
|
||||
"%4.d: *%s = %s\n",
|
||||
i->index,
|
||||
getName(i->result),
|
||||
get_string(i->operand1));
|
||||
break;
|
||||
}
|
||||
|
||||
emit_as_file(out_file, i->next);
|
||||
@ -615,6 +626,12 @@ TableNode *getTN(TNodeOrConst *tnc) {
|
||||
int getConst(TNodeOrConst *tnc) {
|
||||
if (tnc->d == INTEGER) {
|
||||
return tnc->tnc_union->integer;
|
||||
} else if (tnc->d == CHARACTER) {
|
||||
return tnc->tnc_union->character;
|
||||
} else if (tnc->d == BOOLEAN) {
|
||||
return tnc->tnc_union->Boolean;
|
||||
} else if (tnc->d == ADDRESS) {
|
||||
return 0;
|
||||
}
|
||||
return -1;
|
||||
}
|
@ -143,7 +143,7 @@ void emit_function_dec(TableNode * name);
|
||||
void emit_return(TNodeOrConst *value);
|
||||
void emit_reserve(TableNode *result, TNodeOrConst *size);
|
||||
void emit_release(TableNode *pointer);
|
||||
void emit_field_access(char *result, char *record, char *field);
|
||||
void emit_field_access(TableNode *result, TNodeOrConst *record, int offset);
|
||||
void emit_array_access(Op op, TableNode *result, TNodeOrConst *array, TNodeOrConst *index);
|
||||
void emit_bounds_check(TNodeOrConst *index, TNodeOrConst *arr);
|
||||
void emit_goto(int i);
|
||||
|
@ -57,19 +57,19 @@ Constant_Stack *Push(TableNode *type, void *value, bool isConst) {
|
||||
return cs;
|
||||
}
|
||||
|
||||
Context_stack *PushContext(int context, TableNode *typeToCompare) {
|
||||
if (context != 1 && context != 2 && context != 3 && context != 0) {
|
||||
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->con = context;
|
||||
cs->typeToCompare = typeToCompare;
|
||||
if (context_head == NULL) {
|
||||
context_head = cs;
|
||||
@ -107,7 +107,7 @@ Function_Stack *PushFunction(int arg, TableNode* FunctionType) {
|
||||
|
||||
Function_Stack *PopFunction() {
|
||||
if (function_head == NULL) {
|
||||
printf("cannot pop from an empty stack. Invalid.\n");
|
||||
printf("cannot pop from an empty stack from popfunction. Invalid.\n");
|
||||
return NULL;
|
||||
}
|
||||
Function_Stack *fs = function_head;
|
||||
@ -124,6 +124,78 @@ int getArgumentNumber(Function_Stack *fs) {
|
||||
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
|
||||
@ -159,12 +231,20 @@ TableNode* getFunctionNumberType(TableNode* function, int arg){
|
||||
//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) {
|
||||
@ -178,15 +258,15 @@ TableNode* getFunctionTypeContext(Function_Stack *fs) {
|
||||
|
||||
Context_stack *PopContext() {
|
||||
if (context_head == NULL) {
|
||||
printf("cannot pop from an empty stack. Invalid.\n");
|
||||
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);
|
||||
//printf("Popped context off stack: number %d\n", cs->con);
|
||||
return cs;
|
||||
}
|
||||
|
||||
/*
|
||||
int getContextType(Context_stack *cs) {
|
||||
if (cs == NULL) {
|
||||
printdebug(
|
||||
@ -195,8 +275,7 @@ int getContextType(Context_stack *cs) {
|
||||
}
|
||||
return cs->con;
|
||||
}
|
||||
|
||||
//should be
|
||||
*/
|
||||
TableNode *getContextTypeEntry(Context_stack *cs) {
|
||||
if (cs == NULL) {
|
||||
printdebug(
|
||||
|
@ -46,7 +46,7 @@ typedef struct Constant_Stack {
|
||||
//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;
|
||||
//int con;
|
||||
TableNode *typeToCompare;
|
||||
struct Context_stack *next;
|
||||
} Context_stack;
|
||||
@ -134,14 +134,19 @@ void printdebug_impl(char *file, int line, const char *format, ...);
|
||||
|
||||
char *temp_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);
|
||||
Context_stack *PushContext(int context,TableNode *typeToCompare);
|
||||
Context_stack *PushContext(/*int context,*/TableNode *typeToCompare);
|
||||
Function_Stack *PushFunction(int arg, TableNode* FunctionType);
|
||||
Constant_Stack *Pop();
|
||||
Context_stack *PopContext();
|
||||
Function_Stack* setFunctionType(Function_Stack *fs, TableNode* functionType);
|
||||
Function_Stack *PopFunction();
|
||||
TableNode* getFunctionTypeContext(Function_Stack *fs);
|
||||
int getContextType(Context_stack *cs);
|
||||
TableNode* getFunctionType(Function_Stack *fs);
|
||||
//int getContextType(Context_stack *cs);
|
||||
Constant_Stack *Print_Stack();
|
||||
int getArgumentNumber(Function_Stack *fs);
|
||||
AdInfo *CreatePrimitiveInfo(int size);
|
||||
@ -198,6 +203,7 @@ ListOfTable *getRestOfChildren(ListOfTable *lt);
|
||||
TableNode *getFirstEntry(SymbolTable *st);
|
||||
TableNode *getNextEntry(TableNode *tn);
|
||||
TableNode *printTableNode(TableNode *tn);
|
||||
TableNode *getContextTypeEntry(Context_stack *cs);
|
||||
|
||||
extern int yylex(void);
|
||||
extern char *yytext;
|
||||
|
Reference in New Issue
Block a user