blob: 05bf0c325a375b1ee93472586b6facdf3e7ffe3c [file] [log] [blame]
/**** parser.c ***************************************************/
#include "global.h"
extern void emit(int t, int tval, float rval);
extern void error(char *m);
extern int lexan(void);
extern int GlobalInsert(char s[], int tok, int type, int size, int function,
int functionlabel);
extern void CheckMain(void);
extern void AllBodsParsed(void);
extern void LocalReset(void);
extern int LocalInsert(char s[], int tok, int type, int size,int function,
int functionlabel);
extern void ParamInt(void);
int term(void);
void match(int t);
int expr(void);
void PushArrayCellAddr(void);
void DeclOrF(void);
void GlobalScopeAndInsert(int type);
void GlobalVarList(int type);
void exprTest(void);
void exprAssg(void);
void parseAStmt(void);
void parse(void);
int factor(void);
void ExprList(void);
void FunctionList(void);
void FunctionDef(int type);
void MoreParams(void);
void ParamList(void);
void DecList(void);
void VarList(int type);
void FstmtList(void);
int term(void)
{
int t; /* temporary holder of tokens */
int leftExpr, rightExpr;
leftExpr = factor();
if (ErrorFlag)
return -99;
while(lookahead == '*' || lookahead == '/')
{
t = lookahead;
match(lookahead);
if (ErrorFlag)
return -99;
rightExpr = factor();
if (ErrorFlag)
return -99;
if (leftExpr == rightExpr)
{
if (leftExpr)
{
if (t == '*')
emit(RMUL, 0, 0.0);
else
emit(RDIV, 0, 0.0);
leftExpr = 1;
}
else
{
if (t == '*')
emit(MUL, 0, 0.0);
else
emit(DIV, 0, 0.0);
leftExpr = 0;
}
}
else
{
if (leftExpr)
{
emit(FLOAT, 0, 0.0);
if (t == '*')
emit(RMUL, 0, 0.0);
else
emit(RDIV, 0, 0.0);
}
else
{
emit(NUM, 1, 0.0);
emit(IST, 0, 0.0);
emit(FLOAT, 0, 0.0);
emit(NUM, 1, 0.0);
emit(VAL, 0, 0.0);
if (t == '*')
emit(RMUL, 0, 0.0);
else
emit(RDIV, 0, 0.0);
}
leftExpr = 1;
} /* end else leftExpr == rightExpr */
}
if (FloatFlag)
return(1);
else
return (leftExpr);
}
/* ========================================================================= */
void match(int t) /* verify that t was the last token, then get next token */
/* token to verify as last found */
{
if (lookahead == t)
{
PreviousLookahead = lookahead;
PreviousTokenval = tokenval;
PreviousFtokenval = ftokenval;
lookahead = NextLookahead;
tokenval = NextTokenval;
ftokenval = NextFtokenval;
if (NextLookahead != DONE)
NextLookahead = lexan();
}
else
{
switch (lookahead)
{
case WHILE:
case IF:
error("Missing ; at end of previous statement");
break;
}
if (ErrorFlag)
return;
switch (t)
{
case ')':
error("Missing right parenthesis or illegal operator");
break;
default:
printf("\n In default of match lookahead = %d",lookahead);
error("syntax error");
break;
} /* end switch */
} /* else */
}
/* ------------------------------------------------------------------- */
int expr(void)
{
int t; /* temporary holder of tokens */
int leftExpr, rightExpr;
leftExpr = term();
if (ErrorFlag)
return -99;
while(lookahead == '+' || lookahead == '-')
{
t = lookahead;
match(lookahead);
if (ErrorFlag)
return -99;
rightExpr = term();
if (ErrorFlag)
return -99;
if (leftExpr == rightExpr)
{
if (leftExpr)
{
if (t == '+')
emit(RADD, 0, 0.0);
else
emit(RSUB, 0, 0.0);
leftExpr = 1;
}
else
{
if (t == '+')
emit(ADD, 0, 0.0);
else
emit(SUB, 0, 0.0);
leftExpr = 0;
}
}
else
{
if (leftExpr)
{
emit(FLOAT, 0, 0.0);
if (t == '+')
emit(RADD, 0, 0.0);
else
emit(RSUB, 0, 0.0);
}
else
{
emit(NUM, 1, 0.0);
emit(IST, 0, 0.0);
emit(FLOAT, 0, 0.0);
emit(NUM, 1, 0.0);
emit(VAL, 0, 0.0);
if (t == '+')
emit(RADD, 0, 0.0);
else
emit(RSUB, 0, 0.0);
}
leftExpr = 1;
} /* end else leftExpr == rightExpr */
}
if (FloatFlag)
return(1);
else
return(leftExpr);
}
/* ========================================================================= */
void PushArrayCellAddr(void) /* calculate address of array cell on stack */
{
int tempTokenval;
if ( !(ArrayParsed))
{
ArrayParsed = 1;
tempTokenval = tokenval;
if (LocalIndex)
emit(PUSH_LOC_VAR_ADDR, LocalIndex, 0.0);
else if (GlobalIndex)
emit(PUSH_GLO_VAR_ADDR, GlobalIndex, 0.0);
else
{
error("Compiler error, array lexeme not found in any table");
return;
}
match(ARRAY);
if (ErrorFlag)
return;
match('[');
if (ErrorFlag)
return;
FloatFlag = 0;
FloatFlag = expr();
if (ErrorFlag)
return;
if (lookahead != ']')
{
error("Missing ']'");
return;
}
if (FloatFlag)
{
error("Array index must be an integer value");
return;
}
emit(ADD, 0, 0.0);
lookahead = ARRAY;
tokenval = tempTokenval;
} /* end if !ArrayParsed */
else
ArrayParsed = 0;
} /* end PushArrayCellAddr */
/* ============================================================= */
void DeclOrF(void)
{
int type; /* stores type to call other functions with */
int temp;
Scope = 0; /* set scope to zero to mean global variables */
while(1)
{
if (lookahead == ID)
{
emit(BEGIN, 0, 0.0);
LabelCounter = 4; /* first 3 label used by emit BEGIN */
/* insert an implicit call to main into the symbol tabel */
temp = GlobalInsert ("main",ID,INT,0,1,1);
if (ErrorFlag)
return;
if (strcmp("main", lexbuf) == 0)
GlobalIndex = temp;
FunctionDef (INT);
if (ErrorFlag)
return;
return;
}
else if (lookahead == INT)
{
match (INT);
if (ErrorFlag)
return;
}
else
{
match (FLOAT);
if (ErrorFlag)
return;
}
if (NextLookahead == '(')
{
emit(BEGIN, 0, 0.0);
LabelCounter = 4; /* first 3 labels used by emit BAGIN */
/* insert an implicit call to main into the symbol tabel */
temp = GlobalInsert ("main",ID,INT,0,1,1);
if (ErrorFlag)
return;
if (strcmp("main", lexbuf) == 0)
GlobalIndex = temp;
FunctionDef(PreviousLookahead);
if (ErrorFlag)
return;
return;
}
else
{
type = PreviousLookahead;
GlobalScopeAndInsert (type);
if (ErrorFlag)
return;
GlobalVarList (type);
if (ErrorFlag)
return;
match(';');
if (ErrorFlag)
return;
} /* end if != '(' */
} /* end while(1) */
} /* end DeclOrF */
/* ============================================================= */
void GlobalScopeAndInsert(int type)
{
int tempGlobalIndex;
if (LocalIndex)
{
error("Compiler error! global lexeme found in local symbol table");
return;
} /* end LocalIndex */
else if (GlobalIndex)
{
if (GlobalTable[GlobalIndex].function)
{
error("Attempting to define a function name as an identifier");
return;
} /* end if */
else
{
error("Attempting to define a global variable twice");
return;
} /* end else */
} /* end else ifGlobalIndex */
else
{
if (NextLookahead == '[')
{
tempGlobalIndex = GlobalIndex = GlobalInsert(lexbuf, ARRAY, type,0,0,0);
if (ErrorFlag)
return;
match(ID);
if (ErrorFlag)
return;
match('[');
if (ErrorFlag)
return;
if (lookahead == NUM)
{
GlobalTable[tempGlobalIndex].size = tokenval;
match(NUM);
} /* end if (lookahead == num) */
else
{
error("Improperly formed array definition");
return;
} /* end else */
match(']');
if (ErrorFlag)
return;
emit(GLO_DECL, tempGlobalIndex, 0.0);
DecCount += GlobalTable[tempGlobalIndex].size;
} /* end if next == '[' */
else /* regular ID */
{
GlobalIndex = GlobalInsert(lexbuf, ID, type, 1, 0, 0);
if (ErrorFlag)
return;
emit(GLO_DECL, GlobalIndex, 0.0);
++DecCount;
match(ID);
if (ErrorFlag)
return;
} /* end else */
} /* end else */
} /* end GlobalScopeAndInsert */
/* ============================================================= */
void GlobalVarList(int type)
{
while (lookahead == ',')
{
match(',');
if (ErrorFlag)
return;
if (lookahead == ID || lookahead == ARRAY)
{
GlobalScopeAndInsert (type);
if (ErrorFlag)
return;
} /* end if ID or ARRAY */
else
{
error("Expected an identifier or array");
return;
} /* end else */
} /* end while loop */
} /* end GlobalVarList */
/* ============================================================= */
void exprTest(void)
{
int tempTrue, tempDone;
int tempOperation;
int TempFloatFlag;
FloatFlag = 0;
FloatFlag = expr();
if (ErrorFlag)
return;
while ((lookahead == EQUAL) || (lookahead == NEQUAL))
{
tempOperation = lookahead;
if (lookahead == EQUAL)
match(EQUAL);
else
match(NEQUAL);
if (ErrorFlag)
return;
TempFloatFlag = FloatFlag;
if (TempFloatFlag)
{
FloatFlag = 0;
FloatFlag = expr();
if (!(FloatFlag))
{ emit(FLOAT, 0, 0.0);
FloatFlag = 1;
}
}
else
{
FloatFlag = expr();
if (FloatFlag)
{
emit(NUM, 1, 0.0);
emit(IST, 0, 0.0);
emit(FLOAT, 0, 0.0);
emit(NUM, 1, 0.0);
emit(VAL, 0, 0.0);
}
}
if (ErrorFlag)
return;
emit(COMP, 0, 0.0);
tempTrue = LabelCounter;
++LabelCounter;
tempDone = LabelCounter;
++LabelCounter;
emit(PUSH_CODE_LABEL, tempTrue, 0.0);
if (tempOperation == EQUAL)
emit(BEQ, 0, 0.0);
else
emit(BNE, 0, 0.0);
emit(NUM, 0, 0.0);
emit(PUSH_CODE_LABEL, tempDone, 0.0);
emit(B, 0, 0.0);
emit(LABEL_CODE, tempTrue, 0.0);
emit(NUM, 1, 0.0);
emit(LABEL_CODE, tempDone, 0.0);
} /* end if */
} /* end exprTest */
/* ========================================================================= */
void exprAssg(void)
{
int tempLocalIndex, tempGlobalIndex; /* temp indices during recursion */
switch (lookahead)
{
case ARRAY:
tempLocalIndex = LocalIndex;
tempGlobalIndex = GlobalIndex;
PushArrayCellAddr();
if (ErrorFlag)
return;
if (NextLookahead == '=')
{
ArrayParsed = 0;
match(ARRAY);
if (ErrorFlag)
return;
match('=');
if (ErrorFlag)
return;
FloatFlag = 0;
exprAssg();
if (ErrorFlag)
return;
if (tempLocalIndex)
{
if ((LocalTable[tempLocalIndex].type == INT) && (FloatFlag))
{
emit(INT, 0, 0.0);
FloatFlag = 0;
}
else if ((LocalTable[tempLocalIndex].type == FLOAT) && ( !FloatFlag))
{
emit(FLOAT, 0, 0.0);
FloatFlag = 1;
}
emit(STHB ,0 ,0.0);
}
else if (tempGlobalIndex)
{
if ((GlobalTable[tempGlobalIndex].type == INT) && (FloatFlag))
{
emit(INT, 0, 0.0);
FloatFlag = 0;
}
else if((GlobalTable[tempGlobalIndex].type == FLOAT) && (!FloatFlag))
{
emit(FLOAT, 0, 0.0);
FloatFlag = 1;
}
emit(STH, 0, 0.0);
}
emit(SWAP, 0, 0.0);
emit(POP, 0, 0.0);
} /* end if NextLookahead == '=' */
else
{
exprTest();
if (ErrorFlag)
return;
} /* end else of if lookahead == '=' */
break;
case ID:
tempLocalIndex = LocalIndex;
tempGlobalIndex = GlobalIndex;
if (NextLookahead == '=')
{
if (LocalIndex)
emit(PUSH_LOC_VAR_ADDR, LocalIndex, 0.0);
else if (GlobalIndex)
emit(PUSH_GLO_VAR_ADDR, GlobalIndex, 0.0);
else
{
error("Compiler error, variable lexeme not found in any table");
return;
}
match(ID);
if (ErrorFlag)
return;
match('=');
if (ErrorFlag)
return;
FloatFlag = 0;
exprAssg();
if (ErrorFlag)
return;
if (tempLocalIndex)
{
if ((LocalTable[tempLocalIndex].type == INT) && (FloatFlag))
{
emit(INT, 0, 0.0);
FloatFlag = 0;
}
else if ((LocalTable[tempLocalIndex].type == FLOAT) && ( !FloatFlag))
{
emit(FLOAT, 0, 0.0);
FloatFlag = 1;
}
emit(STHB, 0, 0.0);
}
else if (tempGlobalIndex)
{
if ((GlobalTable[tempGlobalIndex].type == INT) && (FloatFlag))
{
emit(INT, 0, 0.0);
FloatFlag = 0;
}
else if((GlobalTable[tempGlobalIndex].type == FLOAT) && (!FloatFlag))
{
emit(FLOAT, 0, 0.0);
FloatFlag = 1;
}
emit(STH, 0, 0.0);
}
emit(SWAP, 0, 0.0);
emit(POP, 0, 0.0);
}
else
{
exprTest();
if (ErrorFlag)
return;
}
break;
default:
exprTest();
if (ErrorFlag)
return;
} /* end switch */
return;
} /* end exprAssg */
/* ========================================================================= */
void parseAStmt(void) /* parse a single statement */
{
int tempLabel1, tempLabel2;
switch (lookahead)
{
case WHILE:
match(WHILE);
if (ErrorFlag)
return;
tempLabel1 = LabelCounter;
++LabelCounter;
tempLabel2 = LabelCounter;
++LabelCounter;
emit(LABEL_CODE, tempLabel1, 0.0);
emit(PUSH_CODE_LABEL, tempLabel2, 0.0);
match('(');
if (ErrorFlag)
return;
FloatFlag = 0;
exprAssg();
if (ErrorFlag)
return;
match(')');
if (ErrorFlag)
return;
if (FloatFlag)
emit(RNUM, 0, 0.0); /* push 0.0 */
else
emit(NUM, 0 ,0.0); /* push 0 */
emit(COMP, 0, 0.0);
emit(BEQ, 0, 0.0);
parseAStmt();
if (ErrorFlag)
return;
emit(PUSH_CODE_LABEL, tempLabel1, 0.0);
emit(B, 0, 0.0);
emit(LABEL_CODE, tempLabel2, 0.0);
break;
case IF:
match(IF);
if (ErrorFlag)
return;
tempLabel1 = LabelCounter;
++LabelCounter;
emit(PUSH_CODE_LABEL, tempLabel1, 0.0);
match('(');
if (ErrorFlag)
return;
FloatFlag = 0;
exprAssg();
if (ErrorFlag)
return;
match(')');
if (ErrorFlag)
return;
if (FloatFlag)
emit(RNUM, 0, 0.0); /* push 0.0 */
else
emit(NUM, 0, 0.0); /* push 0 */
emit(COMP, 0, 0.0);
emit(BEQ, 0, 0.0);
parseAStmt();
if (ErrorFlag)
return;
if (lookahead == ELSE)
{
match (ELSE);
if (ErrorFlag)
return;
tempLabel2 = LabelCounter;
++LabelCounter;
emit(PUSH_CODE_LABEL, tempLabel2, 0.0);
emit(B, 0, 0.0);
emit(LABEL_CODE, tempLabel1, 0.0);
parseAStmt();
if (ErrorFlag)
return;
emit(LABEL_CODE, tempLabel2, 0.0);
} /* end if lookahead == ELSE */
else
{
emit(LABEL_CODE, tempLabel1, 0.0);
} /* end else lookahead == ELSE */
break;
case '{':
match('{');
do
{
parseAStmt();
if (ErrorFlag)
ErrorFlag = 0;
} while ((lookahead != '}') && (lookahead != DONE));
match('}');
if (ErrorFlag)
return;
break;
case RETURN:
if (NextLookahead == ';')
{
match(RETURN);
if (ErrorFlag)
return;
match(';');
if (ErrorFlag)
return;
if (GlobalTable[FuncNameIndex].type == INT)
emit(NUM, 1, 0.0);
else
emit(RNUM, 0, 1.0);
} /* end if */
else
{
match(RETURN);
if (ErrorFlag)
return;
exprAssg();
if (ErrorFlag)
return;
match(';');
if (ErrorFlag)
return;
} /* end else */
emit(PUSH_CODE_LABEL, ReturnLabel, 0.0);
emit(B, 0, 0.0);
break;
default: /* assignment statement */
exprAssg();
if (ErrorFlag)
return;
emit(POP, 0, 0.0);
match(';');
return;
} /* end switch */
return;
} /* end parseAStmt */
/* ========================================================================= */
void parse(void) /* parse a list of functions */
{
/* prime NextLookahead */
lookahead = 1;
match (lookahead);
if (ErrorFlag)
ErrorFlag = 0;
/* prime lookahead */
lookahead = 1;
match (lookahead);
if (ErrorFlag)
ErrorFlag = 0;
DeclOrF(); /* parses the global var. declarations and the first function */
if (ErrorFlag)
return;
FunctionList();
if (ErrorFlag)
return;
CheckMain();
AllBodsParsed();
if (ErrorFlag)
return;
emit(END, 0, 0.0);
return;
} /* end parse */
/* ========================================================================= */
int factor(void)
{
int temp;
int tempLocalIndex, tempGlobalIndex;
char templexbuf[30];
switch(lookahead) {
case '(':
match('(');
if (ErrorFlag)
return -99;
switch (lookahead)
{
case INT:
match (INT);
if (ErrorFlag)
return -99;
match (')');
if (ErrorFlag)
return -99;
temp = factor();
if (ErrorFlag)
return -99;
if (temp)
emit(INT, 0, 0.0);
return(0);
break;
case FLOAT:
match (FLOAT);
if (ErrorFlag)
return -99;
match (')');
if (ErrorFlag)
return -99;
temp = factor();
if (ErrorFlag)
return -99;
if ( !temp)
emit(FLOAT, 0, 0.0);
return(1);
break;
default:
FloatFlag = 0;
exprAssg();
if (ErrorFlag)
return -99;
match(')');
if (ErrorFlag)
return -99;
if (FloatFlag)
return(1);
else
return(0);
break;
} /* end switch */
break;
case NUM:
emit(NUM, tokenval, 0.0);
match(NUM);
if (ErrorFlag)
return -99;
return(0); /* meaning false float flag */
break;
case RNUM:
emit(RNUM, tokenval, ftokenval);
match(RNUM);
if (ErrorFlag)
return -99;
return(1); /* meaning true float flag */
break;
case ID:
if (NextLookahead == '(')
{
/* function call */
tempLocalIndex = LocalIndex;
tempGlobalIndex = GlobalIndex;
strcpy (templexbuf, lexbuf);
match(ID);
if (ErrorFlag)
return -99;
match('(');
if (ErrorFlag)
return -99;
ExprList();
if (ErrorFlag)
return -99;
match(')');
if (ErrorFlag)
return -99;
/* prepare to branch to function */
CallReturnAddr = LabelCounter;
++LabelCounter;
emit(PUSH_CODE_LABEL, CallReturnAddr, 0.0);
emit(PUSH_FRAMESIZE, FuncNameIndex, 0.0);
emit(IB, 0, 0.0);
/* branch to function */
if (tempLocalIndex)
{
error("Function called is to a local variable");
return -99;
} /* end LocalIndex */
else if (tempGlobalIndex)
{
if (!(GlobalTable[tempGlobalIndex].function))
{
error("Function called is to a global variable");
return -99;
} /* end if !function */
else
{
emit(PUSH_CODE_LABEL,GlobalTable[tempGlobalIndex].functionlabel,0.0);
} /* end else !function */
} /* end GlobalIndex */
else /* lexeme not in any symbol table */
{
tempGlobalIndex = GlobalInsert (templexbuf,ID,INT,0,1,LabelCounter);
if (ErrorFlag)
ErrorFlag = 0;
++LabelCounter;
emit(PUSH_CODE_LABEL, GlobalTable[tempGlobalIndex].functionlabel, 0.0);
} /* end insert function name */
emit(B, 0, 0.0);
/* return sequence */
emit(LABEL_CODE, CallReturnAddr, 0.0);
emit(PUSH_FRAMESIZE, FuncNameIndex, 0.0);
emit(DB, 0, 0.0);
if (GlobalTable[tempGlobalIndex].function < 0) /* function defined */
{
if (GlobalTable[tempGlobalIndex].type == INT)
return(0);
else
return(1);
}
else /* default return type of undefined function is INT */
return(0);
} /* end if NextLookahead == ')' */
else if ( !(LocalIndex || GlobalIndex))
{
error("attempting to use an undefined variable");
return -99;
}
if (LocalIndex)
emit(PUSH_LOC_VAR_VALUE, LocalIndex, 0.0);
else if (GlobalIndex)
emit(PUSH_GLO_VAR_VALUE, GlobalIndex, 0.0);
else
{
error("Compiler error, lexeme was not found in any table");
break;
}
tempLocalIndex = LocalIndex;
tempGlobalIndex = GlobalIndex;
match(ID);
if (ErrorFlag)
return -99;
if (tempLocalIndex)
{
if (LocalTable[tempLocalIndex].type == FLOAT)
return(1);
else
return(0);
}
else
{
if (GlobalTable[tempGlobalIndex].type == FLOAT)
return(1);
else
return(0);
}
break;
case ARRAY:
tempLocalIndex = LocalIndex;
tempGlobalIndex = GlobalIndex;
PushArrayCellAddr();
if (ErrorFlag)
return -99;
ArrayParsed = 0;
match(ARRAY);
if (ErrorFlag)
return -99;
if (tempLocalIndex)
emit(VALB, 0, 0.0);
else if (tempGlobalIndex)
emit(VAL, 0, 0.0);
else
{
error("using an undefined array referance");
return -99;
}
if (tempLocalIndex)
{
if (LocalTable[tempLocalIndex].type == FLOAT)
return(1);
else
return(0);
}
else
{
if (GlobalTable[tempGlobalIndex].type == FLOAT)
return(1);
else
return(0);
}
break;
case '-':
match('-');
if (ErrorFlag)
return -99;
temp=factor();
if (ErrorFlag)
return -99;
if (temp)
emit(RNEG, 0, 0.0);
else
emit(NEG, 0, 0.0);
return(temp);
break;
case READF:
match(READF);
if (ErrorFlag)
return -99;
match ('(');
if (ErrorFlag)
return -99;
match (')');
if (ErrorFlag)
return -99;
emit(READ, 0, 0.0);
emit(FLOAT, 0, 0.0);
return(1);
break;
case READI:
match(READI);
if (ErrorFlag)
return -99;
match('(');
if (ErrorFlag)
return -99;
match(')');
if (ErrorFlag)
return -99;
emit(READ, 0, 0.0);
emit(INT, 0, 0.0);
return(0);
break;
case WRITEF:
match (WRITEF);
if (ErrorFlag)
return -99;
match('(');
if (ErrorFlag)
return -99;
FloatFlag = 0;
exprAssg();
if (ErrorFlag)
return -99;
if ( !(FloatFlag))
{
emit(FLOAT, 0, 0.0);
FloatFlag = 1;
}
match(')');
if (ErrorFlag)
return -99;
emit(WRITEF, 0, 0.0);
emit(RNUM, 1, 1.0);
return(1);
break;
case WRITEI:
match(WRITEI);
if (ErrorFlag)
return -99;
match('(');
if (ErrorFlag)
return -99;
FloatFlag = 0;
exprAssg();
if (ErrorFlag)
return -99;
if (FloatFlag)
{
emit(INT, 0, 0.0);
FloatFlag = 0;
}
match(')');
if (ErrorFlag)
return -99;
emit(WRITEI, 0, 0.0);
emit(NUM, 1, 0.0);
return(0);
break;
case WRITELN:
match(WRITELN);
if (ErrorFlag)
return -99;
match('(');
if (ErrorFlag)
return -99;
match(')');
if (ErrorFlag)
return -99;
emit(WRITELN, 0, 0.0);
emit(NUM, 1, 0.0);
return(0);
break;
default:
/* error used to be called from here */
error("Illegal operator");
return(0);
}
return -99;
}
/* ------------------------------------------------------------------ */
void ExprList(void)
{
if (lookahead != ')')
{
exprAssg();
if (ErrorFlag)
return;
while (lookahead == ',')
{
match(',');
if (ErrorFlag)
return;
exprAssg();
if (ErrorFlag)
return;
} /* end while */
} /* end if ) */
} /* end ExprList */
/* ========================================================================= */
void FunctionList(void)
{
do
{
ErrorFlag = 0;
FloatFlag = 0;
LocalReset();
switch(lookahead)
{
case ID:
FunctionDef(INT);
if (ErrorFlag)
return;
break;
case INT:
match(INT);
if (ErrorFlag)
return;
FunctionDef(INT);
if (ErrorFlag)
return;
break;
case FLOAT:
match(FLOAT);
if (ErrorFlag)
return;
FunctionDef(FLOAT);
if (ErrorFlag)
return;
case DONE:
break;
default:
error("Unexpected token found");
return;
break;
} /* end for switch statement */
}
while (lookahead != DONE);
} /* end FunctionList */
/* ----------------------------------------------------------------------- */
void FunctionDef(int type)
{
offset = 1;
if (lookahead != ID)
{
error("Invalid function defintion structure. Expected ID");
return;
} /* end if lookahead */
if (LocalIndex)
{
error("Compiler error, function name in local symbol table");
return;
} /* end if LocalIndex */
else if (GlobalIndex)
{
if (!(GlobalTable[GlobalIndex].function))
{
error("Attempting to redefine a global variable as a function name");
return;
} /* end if GlobalTable */
else if (GlobalTable[GlobalIndex].function < 0)
{
error("Redefining a function.");
return;
} /* end else if GlobalTable */
else if (GlobalTable[GlobalIndex].function > 0)
/* function is a postive value, already called not defined */
{
GlobalTable[GlobalIndex].type = type;
FuncNameIndex = GlobalIndex;
GlobalTable[GlobalIndex].function = -1;
} /* end else if function > 0 */
else
{
error("Compiler error, functiondef is confused");
return;
}
} /* end else if (GlobalIndex) */
else /* ID not in any tabel */
{
GlobalIndex = GlobalInsert (lexbuf,ID,type,0,-1,LabelCounter);
if (ErrorFlag)
ErrorFlag = 0;
FuncNameIndex = GlobalIndex;
++LabelCounter;
} /* end else */
Scope = GlobalTable[GlobalIndex].functionlabel;
/* label function */
emit(LABEL_FUNC, GlobalIndex, 0.0);
emit(LABEL_CODE, Scope, 0.0);
/* store return address */
emit(STORE_RA, FuncNameIndex, 0.0);
ReturnLabel = LabelCounter;
++LabelCounter;
match(ID);
if (ErrorFlag)
ErrorFlag = 0;
match('(');
if (ErrorFlag)
ErrorFlag = 0;
if ( strcmp(GlobalTable[FuncNameIndex].lexptr, "main") == 0)
{
if (lookahead == ')')
{
match(')');
if (ErrorFlag)
return;
} /* end if lookahead == ')' */
else
{
error("Function main cannot have parameters.");
return;
} /* end else */
} /* end if function is main */
else
{
ParamList();
if (ErrorFlag)
ErrorFlag = 0;
match(')');
if (ErrorFlag)
ErrorFlag = 0;
} /* end else (function is something other than main) */
DecList();
if (ErrorFlag)
ErrorFlag = 0;
emit(SAVE_FRAMESIZE, FuncNameIndex, 0.0);
FstmtList();
if (ErrorFlag)
return;
if (GlobalTable[FuncNameIndex].type == INT)
emit(NUM, 1, 0.0);
else
emit(RNUM, 0, 1.0);
emit(LABEL_CODE, ReturnLabel, 0.0);
emit(PUSH_RA, FuncNameIndex, 0.0);
emit(B, 0, 0.0);
} /* end function Def */
/* ---------------------------------------------------------------------- */
void MoreParams(void)
{
int tempLocalIndex;
if (lookahead == ',')
{
match(',');
if (ErrorFlag)
return;
if (lookahead != ID)
{
error("Improperly formed parameter list");
return;
}
if (GlobalIndex)
{
if (GlobalTable[GlobalIndex].function)
{
error("Cannot use a function name as parameter");
return;
} /* end if GlobalTable */
} /* GlobalIndex */
if (LocalIndex)
{
error("Trying to use a prameter twice");
return;
} /* end else if (LocalIndex) */
else
{
tempLocalIndex = LocalIndex = LocalInsert (lexbuf,ID,PARAM,1,0,0);
if (ErrorFlag)
return;
} /* end else */
match (ID);
if (ErrorFlag)
return;
MoreParams();
if (ErrorFlag)
return;
emit(LOC_DECL, tempLocalIndex, 0.0);
emit(PUSH_LOC_VAR_ADDR, tempLocalIndex, 0.0);
emit(ISTB, 0, 0.0);
++offset;
} /* end if lookahead == ',' */
} /* end MoreParams() */
/* ---------------------------------------------------------------------- */
void ParamList(void)
{
int tempLocalIndex;
if (lookahead == ID)
{
if (GlobalIndex)
{
if (GlobalTable[GlobalIndex].function)
{
error("Cannot use a function name as parameter");
return;
} /* end if GlobalTable */
} /* GlobalIndex */
if (LocalIndex)
{
error("Trying to use a parameter twice");
return;
} /* end else if (LocalIndex) */
else
{
tempLocalIndex = LocalIndex = LocalInsert (lexbuf,ID,PARAM,1,0,0);
if (ErrorFlag)
return;
} /* end else */
match (ID);
if (ErrorFlag)
return;
MoreParams();
if (ErrorFlag)
return;
emit(LOC_DECL, tempLocalIndex, 0.0);
emit(PUSH_LOC_VAR_ADDR, tempLocalIndex, 0.0);
emit(ISTB, 0, 0.0);
++offset;
} /* end if lookahead == ID */
} /* end paramlist() */
/* ------------------------------------------------------------------ */
void DecList(void)
{
while ((lookahead == INT) || (lookahead == FLOAT))
{
match (lookahead); /* obviously must be INT or FLOAT */
if (ErrorFlag)
return;
VarList (PreviousLookahead);
if (ErrorFlag)
return;
} /* end while ((lookahead == INT) || (loookahead == FLOAT)) */
ParamInt();
} /* end function DecList */
/* --------------------------------------------------------------------- */
void VarList(int type)
{
int tempLocalIndex;
do
{
if (GlobalIndex)
{
if (GlobalTable[GlobalIndex].function)
{
error ("Cannot use a function name as a parameter");
return;
} /* end if GlogalTable */
} /* end if (GlobalIndex) */
if (LocalIndex)
{
if (LocalTable[LocalIndex].type == PARAM)
{
if (NextLookahead == '[')
error ("Cannot pass an array as a parameter");
else
{
LocalTable[LocalIndex].type = type;
match(ID);
if (ErrorFlag)
return;
} /* end else */
} /* end if LocalTable[LocalIndex] */
else
{
error ("Trying to redefine a variable");
return;
} /* end else */
} /* end if LocalIndex */
else /* variable is not entered as a local so insert */
{
if (NextLookahead == '[')
{
tempLocalIndex = LocalIndex = LocalInsert (lexbuf,ARRAY,type,0,0,0);
if (ErrorFlag)
return;
lookahead = ARRAY;
match (ARRAY);
if (ErrorFlag)
return;
match ('[');
if (ErrorFlag)
return;
if (lookahead == NUM)
{
LocalTable[tempLocalIndex].size = tokenval;
if (ErrorFlag)
return;
}
else
{
error("Array declarations requires an integer within []");
return;
}
match (NUM);
if (ErrorFlag)
return;
match (']');
if (ErrorFlag)
return;
emit(LOC_DECL, tempLocalIndex, 0.0);
offset += LocalTable[tempLocalIndex].size;
} /* end if nextlook */
else
{
LocalIndex = LocalInsert(lexbuf,ID,type,1,0,0);
if (ErrorFlag)
return;
emit(LOC_DECL, LocalIndex, 0.0);
++offset;
match (ID);
if (ErrorFlag)
return;
} /* end else */
} /* end else */
switch (lookahead)
{
case ',':
match (',');
if (ErrorFlag)
return;
break;
case ';':
match (';');
if (ErrorFlag)
return;
return;
break;
default:
error ("badly formed declarations");
return;
} /* end switch (lookahead) */
} while ((lookahead == ID) || (lookahead == ARRAY));
error("can only use ID or ARRAAY");
return;
} /* end function VarList */
/* ------------------------------------------------------------------- */
void FstmtList(void)
{
match ('{');
if (ErrorFlag)
ErrorFlag = 0;
do
{
parseAStmt();
if (ErrorFlag)
ErrorFlag = 0;
}
while ((lookahead != '}') && (lookahead != DONE));
if (lookahead == DONE)
{
error("Unexpected end of file");
return;
} /* end if */
else
{
match ('}');
if (ErrorFlag)
return;
} /* end else */
} /* end function FstmtList */