/Compiler.cs
C# | 1616 lines | 1062 code | 318 blank | 236 comment | 424 complexity | b064b864656753df0051ab6bdab7d4a1 MD5 | raw file
Large files files are truncated, but you can click here to view the full file
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Text;
- using System.IO;
- namespace Compiler_
- {
- class Compiler
- {
- public Scanner scan;
- private Grammar grammar;
- private Token CURRENT_TOKEN;
- private Stack<Dictionary<string, Record>> SYMBOL_TABLE_STACK;
- private Dictionary<string, GotoRecord> GOTO_RECORDS;
- private int ADDRESS = 0;
- private RunTimeModule runtimemod;
- //TK_GOTO
- private int OLD_LEVEL;
- private string CURRENT_STRING;
- private int CURRENT_LEVEL;
- private bool incremented = false;
- public Compiler(string FILE)
- {
- StreamReader reader = new StreamReader(FILE);
- char[] INPUT = reader.ReadToEnd().ToLower().ToCharArray();
-
- SYMBOL_TABLE_STACK = new Stack<Dictionary<string, Record>>();
- scan = new Scanner(FILE, INPUT, SYMBOL_TABLE_STACK);
- runtimemod = new RunTimeModule();
- GOTO_RECORDS = new Dictionary<string, GotoRecord>();
- //grammar = new Grammar();
- //Add the System calls table
- SystemC sys = new SystemC();
- SYMBOL_TABLE_STACK.Push(sys.SystemCalls);
- //For GOTO
- OLD_LEVEL = 0;
- CURRENT_LEVEL = 0;
- CURRENT_STRING = "";
-
- }
- public void Run()
- {
- CURRENT_TOKEN = Scanner.ScanAndRet(scan);
- try {
- do
- {
-
- switch (CURRENT_TOKEN.TOKEN_TYPE)
- {
- //Handle the Program grammar
- case(TOKEN_TYPES.TK_PROGRAM) :
- ProgramGrammar();
- break;
- //Handle the Variable grammar
- case(TOKEN_TYPES.TK_VAR) :
- VarDeclGrammar();
- break;
- //Handle the Label grammar
- case(TOKEN_TYPES.TK_LABEL) :
- LabelDeclGrammar();
- break;
- //Handle the Procedure grammar
- case(TOKEN_TYPES.TK_PROCEDURE) :
- ProcedureDeclGrammar();
- break;
- //Hande the Begin Grammar
- case(TOKEN_TYPES.TK_BEGIN) :
- BeginGrammar();
- CURRENT_TOKEN = Scanner.ScanAndRet(scan);
- break;
- }
- if (CURRENT_TOKEN.TOKEN_TYPE == TOKEN_TYPES.TK_SEMICOLON || CURRENT_TOKEN.TOKEN_TYPE == TOKEN_TYPES.TK_END)
- CURRENT_TOKEN = Scanner.ScanAndRet(scan);
- } while (scan.TOKEN.TOKEN_TYPE != TOKEN_TYPES.TK_EOF && scan.TOKEN.TOKEN_TYPE != TOKEN_TYPES.TK_ERROR && scan.TOKEN.TOKEN_TYPE != TOKEN_TYPES.TK_DOTOP);
- }
- catch(SyntaxErrorException ex)
- {
- Console.WriteLine(ex.Message);
-
- }
-
- //Patch Up Holes from the Gotos
- PatchUp();
- //END PROGRAM
- runtimemod.CodeStackPush(OPCODES.OP_HALT.ToString());
- //Reverse Stack
- if(runtimemod.Stack.Count!=0)
- {
- Queue<object> derp = new Queue<object>();
- for(int i=runtimemod.Stack.Count; i>0; i--)
- derp.Enqueue(runtimemod.Stack.Pop());
- for (int i=derp.Count; i>0; i--)
- runtimemod.Stack.Push(derp.Dequeue());
- }
- //RUN CS
- runtimemod.Run();
- }
- public void DeclarationGrammar()
- {
- do
- {
- CURRENT_TOKEN = Scanner.ScanAndRet(scan);
- switch (CURRENT_TOKEN.TOKEN_TYPE)
- {
- case(TOKEN_TYPES.TK_VAR) :
- VarDeclGrammar();
- break;
- case(TOKEN_TYPES.TK_LABEL) :
- LabelDeclGrammar();
- break;
- }
- } while (CURRENT_TOKEN.TOKEN_TYPE != TOKEN_TYPES.TK_BEGIN);
- }
- public void ProgramGrammar()
- {
-
- do
- {
- CURRENT_TOKEN = Scanner.ScanAndRet(scan);
- }
- while (CURRENT_TOKEN.TOKEN_TYPE != TOKEN_TYPES.TK_SEMICOLON);
- CURRENT_TOKEN = Scanner.ScanAndRet(scan);
-
- }
- #region DECLARATION
- //----------------------DECLARATION GRAMMAR----------------------------------
- //Declarations
- public void LabelDeclGrammar()
- {
- List<string> NAMELIST = new List<string>();
-
- //Variable expression grammar, keep looping until we hit semicolon
- while (CURRENT_TOKEN.TOKEN_TYPE != TOKEN_TYPES.TK_SEMICOLON)
- {
- //Scan for a TK_ID type
- CURRENT_TOKEN = Scanner.ScanAndRet(scan);
- if (CURRENT_TOKEN.TOKEN_TYPE != TOKEN_TYPES.TK_ID)
- {
- throw new SyntaxErrorException("Bad Formatting on Line " + CURRENT_TOKEN.TOKEN_LINE + " column " + CURRENT_TOKEN.TOKEN_COL);
- }
- else
- {
- //Add the TK_ID to NameList
- NAMELIST.Add(CURRENT_TOKEN.TOKEN_VALUE.ToString());
- }
- //Scan for a comma or a semi-colon
- CURRENT_TOKEN = Scanner.ScanAndRet(scan);
- if (CURRENT_TOKEN.TOKEN_TYPE != TOKEN_TYPES.TK_COMMAOP && CURRENT_TOKEN.TOKEN_TYPE != TOKEN_TYPES.TK_SEMICOLON)
- {
- throw new SyntaxErrorException("Bad Formatting on Line " + CURRENT_TOKEN.TOKEN_LINE + " column " + CURRENT_TOKEN.TOKEN_COL);
- }
- }
- //Check No repeats in nameList
- if (!noRepeatedIdentifiers(NAMELIST))
- throw new SyntaxErrorException("Invalid repition of identifiers on Line " + CURRENT_TOKEN.TOKEN_LINE);
- //Create Symbol Table!
- CreateDeclLabelSymbolTable(NAMELIST, TYPE.Label);
-
- }
- public void ProcedureDeclGrammar()
- {
- //Get Name
- CURRENT_TOKEN = Scanner.ScanAndRet(scan);
- //Save the base of the Symbol Table Stack
- int count = SYMBOL_TABLE_STACK.Count;
- //Create Symbol table for this procedure
- CreateDeclProcSymbolTable((string)CURRENT_TOKEN.TOKEN_VALUE);
- //Declaration Grammar
- DeclarationGrammar();
-
- BeginGrammar();
- //Patch up the holes up to a certain call
- PatchUp(SYMBOL_TABLE_STACK.Count - count);
- //Get rid of the symbol Table
- RenderDataSegment(count);
- runtimemod.CodeStackPush(OPCODES.OP_RETURN.ToString());
- runtimemod.StartIP = runtimemod.IP;
- }
- //Pop Symbol table till we get rid of all procedure information
- public void RenderDataSegment(int count)
- {
- for (int i = SYMBOL_TABLE_STACK.Count - 1; i > count; i--)
- {
- SYMBOL_TABLE_STACK.Pop();
- }
- }
- public void VarDeclGrammar()
- {
- List<NameList> varList = new List<NameList>();
- List<string> NAMELIST = new List<string>();
- //Variable expression grammar, keep looping until we hit TK begin
- while (CURRENT_TOKEN.TOKEN_TYPE != TOKEN_TYPES.TK_BEGIN && CURRENT_TOKEN.TOKEN_TYPE != TOKEN_TYPES.TK_PROCEDURE)
- {
- //Scan for a TK_ID type
- if(CURRENT_TOKEN.TOKEN_TYPE != TOKEN_TYPES.TK_ID)
- CURRENT_TOKEN = Scanner.ScanAndRet(scan);
- if (CURRENT_TOKEN.TOKEN_TYPE == TOKEN_TYPES.TK_SEMICOLON)
- CURRENT_TOKEN = Scanner.ScanAndRet(scan);
- if (CURRENT_TOKEN.TOKEN_TYPE != TOKEN_TYPES.TK_ID)
- {
- throw new SyntaxErrorException("Bad Formatting on Line " + CURRENT_TOKEN.TOKEN_LINE + " column " + CURRENT_TOKEN.TOKEN_COL);
- }
- else
- {
- //Add the TK_ID to NameList
- NAMELIST.Add(CURRENT_TOKEN.TOKEN_VALUE.ToString());
- }
- //Scan for a comma
- CURRENT_TOKEN = Scanner.ScanAndRet(scan);
- if (CURRENT_TOKEN.TOKEN_TYPE != TOKEN_TYPES.TK_COMMAOP && CURRENT_TOKEN.TOKEN_TYPE != TOKEN_TYPES.TK_COLONOP)
- {
- throw new SyntaxErrorException("Bad Formatting on Line " + CURRENT_TOKEN.TOKEN_LINE + " column " + CURRENT_TOKEN.TOKEN_COL);
- }
- //Scan for terminator(TK_COLONOP)
- if (CURRENT_TOKEN.TOKEN_TYPE == TOKEN_TYPES.TK_COLONOP)
- {
-
- CURRENT_TOKEN = Scanner.ScanAndRet(scan);
- //Check if array
- if (CURRENT_TOKEN.TOKEN_TYPE == TOKEN_TYPES.TK_ARRAY)
- {
- CURRENT_TOKEN = Scanner.ScanAndRet(scan);
- //Match [
- if (CURRENT_TOKEN.TOKEN_TYPE != TOKEN_TYPES.TK_LARRAYBRACK)
- throw new TokenTypeMismatchException("Expected [ ");
- CURRENT_TOKEN = Scanner.ScanAndRet(scan);
- //Match if a character or a int literal
- if(CURRENT_TOKEN.TOKEN_TYPE != TOKEN_TYPES.TK_INTLIT &&
- CURRENT_TOKEN.TOKEN_TYPE != TOKEN_TYPES.TK_ID )
- throw new TokenTypeMismatchException("Expected [ ");
- int lo;
- if (CURRENT_TOKEN.TOKEN_TYPE == TOKEN_TYPES.TK_INTLIT)
- {
- lo = Convert.ToInt32(CURRENT_TOKEN.TOKEN_VALUE);
- if (lo < 0)
- throw new ArrayTypeMismatchException("Range must be greater than 0");
- }
- else
- {
- lo = (char)CURRENT_TOKEN.TOKEN_VALUE;
- }
- CURRENT_TOKEN = Scanner.ScanAndRet(scan);
- //Match ..
- if (CURRENT_TOKEN.TOKEN_TYPE != TOKEN_TYPES.TK_ARRAYRNGOP)
- throw new TokenTypeMismatchException("Expected .. ");
- CURRENT_TOKEN = Scanner.ScanAndRet(scan);
- //Match if a character or a int literal
- if (CURRENT_TOKEN.TOKEN_TYPE != TOKEN_TYPES.TK_INTLIT &&
- CURRENT_TOKEN.TOKEN_TYPE != TOKEN_TYPES.TK_ID)
- throw new TokenTypeMismatchException("Expected [ ");
- int hi;
- if (CURRENT_TOKEN.TOKEN_TYPE == TOKEN_TYPES.TK_INTLIT)
- {
- hi = Convert.ToInt32(CURRENT_TOKEN.TOKEN_VALUE);
- if (lo < 0)
- throw new ArrayTypeMismatchException("Range must be greater than 0");
- }
- else
- {
- hi = (char)CURRENT_TOKEN.TOKEN_VALUE;
- }
- // ]
- CURRENT_TOKEN = Scanner.ScanAndRet(scan);
- if (CURRENT_TOKEN.TOKEN_TYPE != TOKEN_TYPES.TK_RARRAYBRACK)
- throw new TokenTypeMismatchException("Expected ]");
- CURRENT_TOKEN = Scanner.ScanAndRet(scan);
- if (CURRENT_TOKEN.TOKEN_TYPE != TOKEN_TYPES.TK_OF)
- throw new TokenTypeMismatchException("Expected TK_OF");
- CURRENT_TOKEN = Scanner.ScanAndRet(scan);
- TYPE t = GetType(CURRENT_TOKEN);
- foreach (string name in NAMELIST)
- varList.Add(new NameList(name, t, lo, hi, hi-lo+1,true ));
- NAMELIST.Clear();
- CURRENT_TOKEN = Scanner.ScanAndRet(scan);
- if(CURRENT_TOKEN.TOKEN_TYPE==TOKEN_TYPES.TK_SEMICOLON)
- CURRENT_TOKEN = Scanner.ScanAndRet(scan);
-
- }
- else
- {
- //NEED TO CHECK FOR BOOLEAN OR CHAR OR STRING OR REAL
- TYPE T = GetType(CURRENT_TOKEN);
- foreach (string name in NAMELIST)
- varList.Add(new NameList(name, T));
- NAMELIST.Clear();
- CURRENT_TOKEN = Scanner.ScanAndRet(scan);
- if (CURRENT_TOKEN.TOKEN_TYPE == TOKEN_TYPES.TK_SEMICOLON)
- CURRENT_TOKEN = Scanner.ScanAndRet(scan);
-
- }
-
- }
- }
- //Check No repeats in nameList
- if (!noRepeatedIdentifiers(varList))
- throw new SyntaxErrorException("Invalid repition of identifiers on Line " + CURRENT_TOKEN.TOKEN_LINE);
- //Pass the right token Type)
- //Create Symbol Table!
- CreateDeclVarSymbolTable(varList);
- }
- //----------------------DECLARATION GRAMMAR----------------------------------
- #endregion
- public void BeginGrammar()
- {
- //CURRENT_TOKEN = Scanner.ScanAndRet(scan);
- if (CURRENT_TOKEN.TOKEN_TYPE == TOKEN_TYPES.TK_SEMICOLON)
- CURRENT_TOKEN = Scanner.ScanAndRet(scan);
- StatementGrammar(true);
-
- if (CURRENT_TOKEN.TOKEN_TYPE == TOKEN_TYPES.TK_SEMICOLON || CURRENT_TOKEN.TOKEN_TYPE==TOKEN_TYPES.TK_END)
- CURRENT_TOKEN = Scanner.ScanAndRet(scan);
- if (CURRENT_TOKEN.TOKEN_TYPE == TOKEN_TYPES.TK_SEMICOLON)
- CURRENT_TOKEN = Scanner.ScanAndRet(scan);
- }
- #region STATEMENT
- //----------------------STATEMENT GRAMMAR----------------------------------
- /** <Statement> -->
- * <If>;<STATEMENT>
- * <Repeat>;<STATEMENT>
- * <Assignment>;<STATEMENT>
- * <While>;<STATEMENT>
- */
- public void StatementGrammar(bool begin=false)
- {
- CURRENT_TOKEN = Scanner.ScanAndRet(scan);
- if (CURRENT_TOKEN.TOKEN_TYPE == TOKEN_TYPES.TK_SEMICOLON)
- CURRENT_TOKEN = Scanner.ScanAndRet(scan);
- bool statement = true;
- while (statement)
- {
- switch (CURRENT_TOKEN.TOKEN_TYPE)
- {
- case (TOKEN_TYPES.TK_BEGIN):
- OpenLevel();
- BeginGrammar();
- CloseLevel();
- break;
- case (TOKEN_TYPES.TK_IF):
- OpenLevel();
- IfGrammar();
- CloseLevel();
- break;
- case (TOKEN_TYPES.TK_VAR):
- case (TOKEN_TYPES.TK_ID):
- AssignmentGrammar();
- break;
- case (TOKEN_TYPES.TK_REPEAT):
- OpenLevel();
- RepeatGrammar();
- CloseLevel();
- break;
- case (TOKEN_TYPES.TK_WHILE) :
- OpenLevel();
- WhileGrammar();
- CloseLevel();
- break;
- case (TOKEN_TYPES.TK_FOR) :
- OpenLevel();
- ForGrammar();
- CloseLevel();
- break;
- case (TOKEN_TYPES.TK_LABEL) :
- LabelGrammar();
- break;
- case (TOKEN_TYPES.TK_GOTO) :
- GotoGrammar();
- break;
- case (TOKEN_TYPES.TK_SYS_PROC):
- case (TOKEN_TYPES.TK_SYS_FUNC):
- SysCallGrammar();
- break;
- case (TOKEN_TYPES.TK_PROCEDURE):
- ProcCallGrammar();
- break;
- default:
- statement = false;
- break;
- }
- if (!begin)
- return;
- }
- }
- /**
- * TK_PROCEDURE -->
- *
- *
- */
- public void ProcCallGrammar()
- {
- Token tk = new Token(CURRENT_TOKEN);
- int address = -1;
- TYPE type = TYPE.E;
- Lookup(tk, ref address, ref type);
- if (address != -1)
- {
- runtimemod.CodeStackPush(address.ToString());
- runtimemod.CodeStackPush(OPCODES.OP_JMP.ToString());
- runtimemod.StackPush(runtimemod.IP);
- }
- else
- throw new TokenTypeMismatchException("Procedure not found");
- CURRENT_TOKEN = Scanner.ScanAndRet(scan);
- if (CURRENT_TOKEN.TOKEN_TYPE != TOKEN_TYPES.TK_LPARENOP)
- throw new TokenTypeMismatchException("Expecting left paren");
- CURRENT_TOKEN = Scanner.ScanAndRet(scan);
- if (CURRENT_TOKEN.TOKEN_TYPE != TOKEN_TYPES.TK_RPARENOP)
- throw new TokenTypeMismatchException("Expecting right paren");
- CURRENT_TOKEN = Scanner.ScanAndRet(scan);
- if (CURRENT_TOKEN.TOKEN_TYPE == TOKEN_TYPES.TK_SEMICOLON)
- CURRENT_TOKEN = Scanner.ScanAndRet(scan);
-
- }
- /**
- * <Procedure> -->
- * TK_SYS_PROC | TK_SYS_FUNC
- *
- */
- public void SysCallGrammar()
- {
- Token tk = new Token(CURRENT_TOKEN);
- CURRENT_TOKEN = Scanner.ScanAndRet(scan);
- if (CURRENT_TOKEN.TOKEN_TYPE != TOKEN_TYPES.TK_LPARENOP)
- throw new TokenTypeMismatchException("Expecting open paren");
- TYPE t = Expression();
- if (CURRENT_TOKEN.TOKEN_TYPE != TOKEN_TYPES.TK_RPARENOP)
- throw new TokenTypeMismatchException("Expecting close paren");
-
- switch (tk.VALUE)
- {
- case ("abs") :
- if (t != TYPE.Real && t != TYPE.Integer)
- throw new TokenTypeMismatchException("Expecting a Real or Integer type inside abs function");
- runtimemod.CodeStackPush(OPCODES.OP_ABS.ToString());
- break;
- case ("write") :
- if (t != TYPE.String && t != TYPE.Integer && t != TYPE.Character && t != TYPE.Boolean)
- throw new TokenTypeMismatchException("Not a valid function to use to write");
- runtimemod.CodeStackPush(OPCODES.OP_WRITE.ToString());
- break;
- case ("writeln") :
- if (t != TYPE.String && t != TYPE.Integer && t != TYPE.Character && t != TYPE.Boolean)
- throw new TokenTypeMismatchException("Not a valid function to use to write");
- runtimemod.CodeStackPush(OPCODES.OP_WRITELN.ToString());
- break;
- }
- CURRENT_TOKEN = Scanner.ScanAndRet(scan);
- if (CURRENT_TOKEN.TOKEN_TYPE == TOKEN_TYPES.TK_SEMICOLON)
- CURRENT_TOKEN = Scanner.ScanAndRet(scan);
- }
-
- /**
- * <For> -->
- * for <VAR> := <EXPRESSION> [to|downto] do <STATEMENT>
- *
- */
- public void ForGrammar()
- {
- //Get a value
- CURRENT_TOKEN = Scanner.ScanAndRet(scan);
- //address of token
- int TOKEN_ADR=-1;
- TYPE TOKEN_TYPE = TYPE.E;
- //Check the symbol table for the CURRENT_TOKEN
- Lookup(CURRENT_TOKEN, ref TOKEN_ADR, ref TOKEN_TYPE);
- //Check if value was declared AND it's of type integer
- if ((CURRENT_TOKEN.TOKEN_TYPE != TOKEN_TYPES.TK_VAR && CURRENT_TOKEN.TOKEN_TYPE != TOKEN_TYPES.TK_ID)
- || TOKEN_TYPE != TYPE.Integer)
- throw new TokenTypeMismatchException("Not a valid var identifier");
- // :=
- CURRENT_TOKEN = Scanner.ScanAndRet(scan);
- if (CURRENT_TOKEN.TOKEN_TYPE!=TOKEN_TYPES.TK_COLEQOP)
- throw new TokenTypeMismatchException("Expecting COLEQOP identifier");
- //Push the value into the Code stack
- Expression();
- //Push address of LHS
- runtimemod.CodeStackPush("@" + TOKEN_ADR.ToString());
- //Set Equal
- runtimemod.CodeStackPush(OPCODES.OP_ASSIGN.ToString());
- //target
- int target = runtimemod.IP;
-
- //Advance CURRENT TOKEN to check for TK_TO or TK_DOWNTO
- if(CURRENT_TOKEN.TOKEN_TYPE != TOKEN_TYPES.TK_TO && CURRENT_TOKEN.TOKEN_TYPE != TOKEN_TYPES.TK_DOWNTO)
- throw new TokenTypeMismatchException("Expected either TK_TO or TK_DOWNTO");
- TOKEN_TYPES TypeOfFor = CURRENT_TOKEN.TOKEN_TYPE;
- //Push address of LHS
- runtimemod.CodeStackPush("@" + TOKEN_ADR.ToString());
- //Get stop for the loop
- Expression();
- //Check the Equal
- if (TypeOfFor == TOKEN_TYPES.TK_TO)
- runtimemod.CodeStackPush(OPCODES.OP_GT.ToString());
- else
- runtimemod.CodeStackPush(OPCODES.OP_LT.ToString());
- //Generate hole
- int hole = runtimemod.IP;
- //hole location
- runtimemod.CodeStackPush("0");
- //Jump out if true
- runtimemod.CodeStackPush(OPCODES.OP_JTRUE.ToString());
- if(CURRENT_TOKEN.TOKEN_TYPE!=TOKEN_TYPES.TK_DO)
- throw new TokenTypeMismatchException("Expected TK_DO");
- StatementGrammar();
- runtimemod.CodeStackPush("@" + TOKEN_ADR.ToString());
- runtimemod.CodeStackPush("1");
-
- //Add 1
- if (TypeOfFor == TOKEN_TYPES.TK_TO)
- runtimemod.CodeStackPush(OPCODES.OP_ADD.ToString());
- else
- runtimemod.CodeStackPush(OPCODES.OP_SUBTRACT.ToString());
- runtimemod.CodeStackPush("@" + TOKEN_ADR.ToString());
- runtimemod.CodeStackPush(OPCODES.OP_ASSIGN.ToString());
- //Jump to target
- runtimemod.CodeStackPush(target.ToString());
- //JMP
- runtimemod.CodeStackPush(OPCODES.OP_JMP.ToString());
- int save_ip = runtimemod.IP;
- runtimemod.IP = hole;
- runtimemod.CodeStackPush(save_ip.ToString());
- runtimemod.IP = save_ip;
- }
- /**
- * <Label> -->
- * TK_LABEL <Statement>
- *
- */
- public void LabelGrammar()
- {
- //Get the record for this grammar
- LabelRecord rec = (LabelRecord)Lookup(CURRENT_TOKEN);
- if (rec == null)
- throw new TokenTypeMismatchException("This label does not exist");
- if (rec.seen)
- throw new TokenTypeMismatchException("This label exists more than once!");
- else
- {
- rec.seen = true;
- rec.address = runtimemod.IP;
- rec.scope = CURRENT_STRING;
- }
- CURRENT_TOKEN = Scanner.ScanAndRet(scan);
- if (CURRENT_TOKEN.TOKEN_TYPE != TOKEN_TYPES.TK_COLONOP)
- throw new TokenTypeMismatchException("Expected a colon");
- StatementGrammar();
- }
- /**
- * PatchUp
- *
- */
- public void PatchUp()
- {
- Stack<Dictionary<string, Record>> tempStack = new Stack<Dictionary<string, Record>>();
- int STACK_COUNT = SYMBOL_TABLE_STACK.Count;
- //return if the SYMBOL TABLE IS EMPTY
- if (SYMBOL_TABLE_STACK.Count == 0)
- return;
- while (SYMBOL_TABLE_STACK.Count != 0)
- {
- Dictionary<string, Record> symbolTable = SYMBOL_TABLE_STACK.Pop();
- tempStack.Push(symbolTable);
- foreach (KeyValuePair<string, Record> keyV in symbolTable)
- if (keyV.Value.TYPE_LT == TOKEN_TYPES.TK_LABEL)
- {
- LabelRecord rec = (LabelRecord)keyV.Value;
- if (!rec.seen && rec.GOTO_RECORDS.Count != 0)
- throw new TokenTypeMismatchException("Error: something with labels");
- else if(rec.seen)
- {
- //Fill up the hole
- int save_ip = runtimemod.IP;
- runtimemod.IP = rec.GOTO_RECORDS[rec.value.ToString()].hole;
- runtimemod.CodeStackPush(rec.address.ToString());
- runtimemod.IP = save_ip;
- if (!rec.GOTO_RECORDS[rec.value.ToString()].scope.Contains(rec.scope))
- throw new Exception("Error jumping to that scope friend!");
- }
- }
- }
- //Pop SymbolTables back into the SYMBOL_TABLE_STACK
- for (int i = 0; i < STACK_COUNT; i++)
- SYMBOL_TABLE_STACK.Push(tempStack.Pop());
-
- }
- /**
- * PatchUp
- *
- */
- public void PatchUp(int limit)
- {
- Stack<Dictionary<string, Record>> tempStack = new Stack<Dictionary<string, Record>>();
- int STACK_COUNT = SYMBOL_TABLE_STACK.Count;
- //return if the SYMBOL TABLE IS EMPTY
- if (SYMBOL_TABLE_STACK.Count == 0)
- return;
- for(int i=0; i<limit; i++)
- {
- Dictionary<string, Record> symbolTable = SYMBOL_TABLE_STACK.Pop();
- tempStack.Push(symbolTable);
- foreach (KeyValuePair<string, Record> keyV in symbolTable)
- if (keyV.Value.TYPE_LT == TOKEN_TYPES.TK_LABEL)
- {
- LabelRecord rec = (LabelRecord)keyV.Value;
- if (!rec.seen && rec.GOTO_RECORDS.Count != 0)
- throw new TokenTypeMismatchException("Error: something with labels");
- else if (rec.seen)
- {
- //Fill up the hole
- int save_ip = runtimemod.IP;
- runtimemod.IP = rec.GOTO_RECORDS[rec.value.ToString()].hole;
- runtimemod.CodeStackPush(rec.address.ToString());
- runtimemod.IP = save_ip;
- }
- }
- }
- //Pop SymbolTables back into the SYMBOL_TABLE_STACK
- for (int i = 0; i < limit; i++)
- SYMBOL_TABLE_STACK.Push(tempStack.Pop());
- }
- /**
- * <Goto> -->
- * TK_GOTO TK_LABEL
- *
- */
- public void GotoGrammar()
- {
- //TK_GOTO SHOULD ALREADY BE MATCHED
- //Match TK_LABEL
- CURRENT_TOKEN = Scanner.ScanAndRet(scan);
- if (CURRENT_TOKEN.TOKEN_TYPE != TOKEN_TYPES.TK_LABEL)
- throw new TokenTypeMismatchException("Error Expected a label to be referenced after GOTO");
- //Generate hole
- int hole = runtimemod.IP;
- //hole location
- runtimemod.CodeStackPush("0");
- //Jump out if true
- runtimemod.CodeStackPush(OPCODES.OP_JMP.ToString());
- //TODO: Append to GOTO_RECORDS
- GotoRecord record = new GotoRecord();
- record.hole = hole;
- record.scope = CURRENT_STRING;
- //TODO: SET THIS record.scope
- //TODO: SET THIS record.secRef
- GOTO_RECORDS.Add(CURRENT_TOKEN.TOKEN_VALUE.ToString(), record);
- //Match TK_LABEL
- CURRENT_TOKEN = Scanner.ScanAndRet(scan);
- if (CURRENT_TOKEN.TOKEN_TYPE == TOKEN_TYPES.TK_SEMICOLON)
- CURRENT_TOKEN = Scanner.ScanAndRet(scan);
-
- }
- /**
- * <If> -->
- * <COND> THEN <STAT>
- * <COND> THEN <STAT> ELSE <STAT>
- */
- public void IfGrammar()
- {
- int save_ip;
- //Get the Expression
- Condition();
- //Set the hole to IP
- int hole = runtimemod.IP;
- //Generate Address -- Generate hole
- runtimemod.CodeStackPush("0");
- //Generate the JFALSE
- runtimemod.CodeStackPush(OPCODES.OP_JFALSE.ToString());
- //Forward CURRENT_TOKEN to check the TK_THEN
- if (CURRENT_TOKEN.TOKEN_TYPE != TOKEN_TYPES.TK_THEN)
- CURRENT_TOKEN = Scanner.ScanAndRet(scan);
- if (CURRENT_TOKEN.TOKEN_TYPE != TOKEN_TYPES.TK_THEN)
- throw new TokenTypeMismatchException("Expecting THEN statement not found");
- //Statement grammars
- StatementGrammar();
- //Advance if we find a semicolon
- if (CURRENT_TOKEN.TOKEN_TYPE == TOKEN_TYPES.TK_SEMICOLON)
- CURRENT_TOKEN = Scanner.ScanAndRet(scan);
- if (CURRENT_TOKEN.TOKEN_TYPE == TOKEN_TYPES.TK_ELSE)
- {
- //Create hole 2
- int hole2 = runtimemod.IP;
- //Generate Address -- Second hole
- runtimemod.CodeStackPush("0");
- //OPCODE
- runtimemod.CodeStackPush(OPCODES.OP_JMP.ToString());
- //Save_IP
- save_ip = runtimemod.IP;
- runtimemod.IP = hole;
- //Generate address
- runtimemod.CodeStackPush(save_ip.ToString());
- runtimemod.IP = save_ip;
- hole = hole2;
- StatementGrammar();
- }
- save_ip = runtimemod.IP;
- runtimemod.IP = hole;
- runtimemod.CodeStackPush(save_ip.ToString());
- runtimemod.IP = save_ip;
-
- }
- /**
- * <Assignment> -->
- * <LHS> = <RHS>
- * <LHS> = TK_A_VAR
- * <RHS> = <Expression>
- */
- public void AssignmentGrammar()
- {
- //Check if current TK_VAR or TK_ID is in symbol table
- if (!VarExists(CURRENT_TOKEN.VALUE))
- throw new TokenTypeMismatchException("Value doesn't exist");
- //Array
- int address = -1;
- TYPE type = TYPE.E;
- //Lookup the array type.
- Lookup(CURRENT_TOKEN, ref address, ref type);
- if (type == TYPE.Array)
- {
- //Store the array identifier
- Token arrayT = new Token(CURRENT_TOKEN);
- CURRENT_TOKEN = Scanner.ScanAndRet(scan);
- if (CURRENT_TOKEN.TOKEN_TYPE != TOKEN_TYPES.TK_LARRAYBRACK)
- throw new TokenTypeMismatchException("Left Bracket expected");
- TYPE t = Expression();
- if (t != TYPE.Integer)
- throw new TokenTypeMismatchException("Expected Array Index of Integer type");
- if (CURRENT_TOKEN.TOKEN_TYPE != TOKEN_TYPES.TK_RARRAYBRACK)
- throw new TokenTypeMismatchException("Right Bracket expected");
- ArrayRecord rec = (ArrayRecord)Lookup(arrayT);
-
- if (rec.lo != 0)
- runtimemod.CodeStackPush(rec.lo.ToString());
- runtimemod.CodeStackPush(OPCODES.OP_SUBTRACT.ToString());
- runtimemod.CodeStackPush(rec.address.ToString());
- runtimemod.CodeStackPush(OPCODES.OP_ADD.ToString());
- //Get the Type of Token Operator should only support COLEQOP for now
- CURRENT_TOKEN = Scanner.ScanAndRet(scan);
- if (CURRENT_TOKEN.TOKEN_TYPE == TOKEN_TYPES.TK_COLEQOP)
- {
- TYPE RHS = Expression();
- //Make sure expression is terminated by comma
- if (CURRENT_TOKEN.TOKEN_TYPE == TOKEN_TYPES.TK_SEMICOLON)
- {
- if (TypeCheck(rec.TYPE, RHS, TOKEN_TYPES.TK_COLEQOP))
- {
- //Push the value we get for the LHS
- runtimemod.CodeStackPush(OPCODES.OP_ARRAYASSIGN.ToString());
- }
- }
- }
- else
- throw new TokenTypeMismatchException("Command not recognized");
- }
- else
- {
- //Store Left Hand Side
- Token LHS = new Token(CURRENT_TOKEN);
- //Get the record for this Token.
- Record LHSRec = Lookup(LHS);
-
- //Get the Type of Token Operator should only support COLEQOP for now
- CURRENT_TOKEN = Scanner.ScanAndRet(scan);
- if (CURRENT_TOKEN.TOKEN_TYPE == TOKEN_TYPES.TK_COLEQOP)
- {
- TYPE RHS = Expression();
- //Make sure expression is terminated by comma
- if (CURRENT_TOKEN.TOKEN_TYPE == TOKEN_TYPES.TK_SEMICOLON)
- {
- if (TypeCheck(LHSRec.TYPE, RHS, TOKEN_TYPES.TK_COLEQOP))
- {
- //Push the value we get for the LHS
- runtimemod.CodeStackPush("@" + LHSRec.address);
- runtimemod.CodeStackPush(OPCODES.OP_ASSIGN.ToString());
- }
- }
- }
- else
- throw new TokenTypeMismatchException("Command not recognized");
- }
- CURRENT_TOKEN = Scanner.ScanAndRet(scan);
- if (CURRENT_TOKEN.TOKEN_TYPE == TOKEN_TYPES.TK_SEMICOLON)
- CURRENT_TOKEN = Scanner.ScanAndRet(scan);
- }
- /** <Repeat> -->
- * Repeat <STATEMENT> Until <CONDITION>
- *
- */
- public void RepeatGrammar()
- {
- //Temporarily targit the runtime instruction pointer
- int target = runtimemod.IP;
- //Call statement grammar to parse next statement on line
- StatementGrammar();
- //Match TK_UNTIL
- if (CURRENT_TOKEN.TOKEN_TYPE != TOKEN_TYPES.TK_UNTIL)
- throw new TokenTypeMismatchException("until keyword missing. exiting program");
- //Ensure there's a condition expression after TK_UNTIL
- Condition();
- //GEN_ADDRESS
- runtimemod.CodeStackPush(target.ToString());
- //GEN_OPCODE
- runtimemod.CodeStackPush(OPCODES.OP_JFALSE.ToString());
- CURRENT_TOKEN = Scanner.ScanAndRet(scan);
- if (CURRENT_TOKEN.TOKEN_TYPE == TOKEN_TYPES.TK_SEMICOLON)
- CURRENT_TOKEN = Scanner.ScanAndRet(scan);
- }
- public void WhileGrammar()
- {
- //get the target
- int target = runtimemod.IP;
- //Condition
- Condition();
- int hole = runtimemod.IP;
- //Generate Address
- runtimemod.CodeStackPush("0");
- //Generate OPCODE
- runtimemod.CodeStackPush(OPCODES.OP_JFALSE.ToString());
- //run statements
- StatementGrammar();
- //Generate Address
- runtimemod.CodeStackPush(target.ToString());
- //Generate Opcode
- runtimemod.CodeStackPush(OPCODES.OP_JMP.ToString());
- //switch target
- target = runtimemod.IP;
- //Patch up hole
- runtimemod.IP = hole;
- //Gen address
- runtimemod.CodeStackPush(target.ToString());
- //Reset target
- runtimemod.IP = target;
- }
- //Checks the conditional is valid in a repeat grammar
- //Do we add this to everything else?
- public void Condition()
- {
- TYPE t = Expression();
- if (t != TYPE.Boolean)
- throw new TokenTypeMismatchException("Not a boolean expression. exiting program");
- }
- //----------------------STATEMENT GRAMMAR----------------------------------
- #endregion
- #region Expression
- //----------------------EXPRESSION GRAMMAR----------------------------------
- public TYPE Expression()
- {
- CURRENT_TOKEN = Scanner.ScanAndRet(scan);
- TYPE t1 = TermExpression();
- TYPE t2;
- while(CURRENT_TOKEN.TOKEN_TYPE == TOKEN_TYPES.TK_PLUSOP || CURRENT_TOKEN.TOKEN_TYPE== TOKEN_TYPES.TK_MINUSOP ||
- CURRENT_TOKEN.TOKEN_TYPE == TOKEN_TYPES.TK_OR)
- {
- if (CURRENT_TOKEN.TOKEN_TYPE == TOKEN_TYPES.TK_PLUSOP)
- {
- CURRENT_TOKEN = Scanner.ScanAndRet(scan);
- t2 = TermExpression();
- if(TypeCheck(t1, t2, TOKEN_TYPES.TK_PLUSOP))
- runtimemod.CodeStackPush(OPCODES.OP_ADD.ToString());
- }
- else if (CURRENT_TOKEN.VALUE == "-")
- {
- CURRENT_TOKEN = Scanner.ScanAndRet(scan);
- t2 = TermExpression();
- if (TypeCheck(t1, t2, TOKEN_TYPES.TK_MINUSOP))
- runtimemod.CodeStackPush(OPCODES.OP_SUBTRACT.ToString());
- }
- else if (CURRENT_TOKEN.VALUE == "or")
- {
- CURRENT_TOKEN = Scanner.ScanAndRet(scan);
- t2 = TermExpression();
- if (TypeCheck(t1, t2, TOKEN_TYPES.TK_OR))
- runtimemod.CodeStackPush(OPCODES.OP_OR.ToString());
- }
- }
- //Relational Operator
-
- if (CURRENT_TOKEN.TOKEN_TYPE == TOKEN_TYPES.TK_NOTEQOP ||
- CURRENT_TOKEN.TOKEN_TYPE == TOKEN_TYPES.TK_NOTEQ2OP ||
- CURRENT_TOKEN.TOKEN_TYPE == TOKEN_TYPES.TK_LTEQOP ||
- CURRENT_TOKEN.TOKEN_TYPE == TOKEN_TYPES.TK_GTEQOP ||
- CURRENT_TOKEN.TOKEN_TYPE == TOKEN_TYPES.TK_EQUALOP ||
- CURRENT_TOKEN.TOKEN_TYPE == TOKEN_TYPES.TK_LTOP ||
- CURRENT_TOKEN.TOKEN_TYPE == TOKEN_TYPES.TK_GTOP)
- {
- Token tempCurr = new Token(CURRENT_TOKEN);
- Expression();
- if (tempCurr.TOKEN_TYPE == TOKEN_TYPES.TK_NOTEQOP || tempCurr.TOKEN_TYPE == TOKEN_TYPES.TK_NOTEQ2OP)
- runtimemod.CodeStackPush(OPCODES.OP_NOTEQ.ToString());
- if (tempCurr.TOKEN_TYPE == TOKEN_TYPES.TK_LTEQOP)
- runtimemod.CodeStackPush(OPCODES.OP_LTEQ.ToString());
- if (tempCurr.TOKEN_TYPE == TOKEN_TYPES.TK_GTEQOP)
- runtimemod.CodeStackPush(OPCODES.OP_GTEQ.ToString());
- if (tempCurr.TOKEN_TYPE == TOKEN_TYPES.TK_GTOP)
- runtimemod.CodeStackPush(OPCODES.OP_GT.ToString());
- if (tempCurr.TOKEN_TYPE == TOKEN_TYPES.TK_LTOP)
- runtimemod.CodeStackPush(OPCODES.OP_LT.ToString());
- if (tempCurr.TOKEN_TYPE == TOKEN_TYPES.TK_EQUALOP)
- runtimemod.CodeStackPush(OPCODES.OP_EQ.ToString());
- return TYPE.Boolean;
- }
-
- return t1;
- }
- public TYPE TermExpression()
- {
- TYPE f1 = Factor();
- TYPE f2;
- while(CURRENT_TOKEN.VALUE == "*" || CURRENT_TOKEN.VALUE == "/" || CURRENT_TOKEN.VALUE == "div" ||
- CURRENT_TOKEN.VALUE == "and" || CURRENT_TOKEN.VALUE == "mod")
- {
- if (CURRENT_TOKEN.VALUE == "*")
- {
- CURRENT_TOKEN = Scanner.ScanAndRet(scan);
- f2 = Factor();
- if(TypeCheck(f1, f2, TOKEN_TYPES.TK_MULTOP))
- runtimemod.CodeStackPush(OPCODES.OP_MULT.ToString());
- }
- else if (CURRENT_TOKEN.VALUE == "/")
- {
- CURRENT_TOKEN = Scanner.ScanAndRet(scan);
- f2 = Factor();
- if(TypeCheck(f1, f2, TOKEN_TYPES.TK_DIVOP))
- runtimemod.CodeStackPush(OPCODES.OP_DIV.ToString());
- }
- else if (CURRENT_TOKEN.VALUE == "div")
- {
- CURRENT_TOKEN = Scanner.ScanAndRet(scan);
- f2 = Factor();
- if (TypeCheck(f1, f2, TOKEN_TYPES.TK_DIV))
- runtimemod.CodeStackPush(OPCODES.OP_DIV.ToString());
- }
- else if (CURRENT_TOKEN.VALUE == "and")
- {
- CURRENT_TOKEN = Scanner.ScanAndRet(scan);
- f2 = Factor();
- if (TypeCheck(f1, f2, TOKEN_TYPES.TK_AND))
- runtimemod.CodeStackPush(OPCODES.OP_AND.ToString());
- }
- else if (CURRENT_TOKEN.VALUE == "mod")
- {
- CURRENT_TOKEN = Scanner.ScanAndRet(scan);
- f2 = Factor();
- if (TypeCheck(f1, f2, TOKEN_TYPES.TK_MOD))
- runtimemod.CodeStackPush(OPCODES.OP_MOD.ToString());
- }
- }
- return (f1);
- }
- public TYPE Factor()
- {
- TYPE t = TYPE.E;
- if(CURRENT_TOKEN.TOKEN_TYPE == TOKEN_TYPES.TK_VAR || CURRENT_TOKEN.TOKEN_TYPE == TOKEN_TYPES.TK_ID)
- {
- int address = -1;
- TYPE ty = TYPE.E;
- bool noErr = Lookup(CURRENT_TOKEN, ref address, ref ty);
- if (ty == TYPE.Array)
- {
- Token arrayT = new Token(CURRENT_TOKEN);
- CURRENT_TOKEN = Scanner.ScanAndRet(scan);
- if (CURRENT_TOKEN.TOKEN_TYPE != TOKEN_TYPES.TK_LARRAYBRACK)
- throw new TokenTypeMismatchException("Left Bracket expected");
- TYPE t2 = Expression();
- if (t2 != TYPE.Integer)
- throw new TokenTypeMismatchException("Expected Array Index of Integer type");
- if (CURRENT_TOKEN.TOKEN_TYPE != TOKEN_TYPES.TK_RARRAYBRACK)
- throw new TokenTypeMismatchException("Right Bracket expected");
- ArrayRecord rec = (ArrayRecord)Lookup(arrayT);
- if (rec.lo != 0)
- runtimemod.CodeStackPush(rec.lo.ToString());
- runtimemod.CodeStackPush(OPCODES.OP_SUBTRACT.ToString());
- runtimemod.CodeStackPush(rec.address.ToString());
- runtimemod.CodeStackPush(OPCODES.OP_ADD.ToString());
- runtimemod.CodeStackPush(OPCODES.OP_GET.ToString());
- ty = rec.eltype;
-
- }
- else if (noErr) runtimemod.CodeStackPush("@" + address.ToString());
- else throw new Exception("Bad variable declaration");
- CURRENT_TOKEN = Scanner.ScanAndRet(scan);
- t = ty;
- }
- else if (CURRENT_TOKEN.TOKEN_TYPE == TOKEN_TYPES.TK_INTLIT)
- {
- runtimemod.CodeStackPush(CURRENT_TOKEN.VALUE);
- CURRENT_TOKEN = Scanner.ScanAndRet(scan);
- t = TYPE.Integer;
- }
- else if (CURRENT_TOKEN.TOKEN_TYPE == TOKEN_TYPES.TK_REALLIT)
- {
- runtimemod.CodeStackPush(CURRENT_TOKEN.VALUE);
- CURRENT_TOKEN = Scanner.ScanAndRet(scan);
- t = TYPE.Real;
- }
- //Boolean types
- else if (CURRENT_TOKEN.TOKEN_TYPE == TOKEN_TYPES.TK_TRUE ||
- CURRENT_TOKEN.TOKEN_TYPE == TOKEN_TYPES.TK_FALSE)
- {
- runtimemod.CodeStackPush((CURRENT_TOKEN.TOKEN_TYPE==TOKEN_TYPES.TK_TRUE ? 1 : 0).ToString());
- CURRENT_TOKEN = Scanner.ScanAndRet(scan);
- t = TYPE.Boolean;
- }
- //Negative Values
- else if (CURRENT_TOKEN.TOKEN_TYPE == TOKEN_TYPES.TK_MINUSOP)
- {
- CURRENT_TOKEN = Scanner.ScanAndRet(scan);
- t = Factor();
- runtimemod.CodeStackPush(OPCODES.OP_FNEG.ToString());
- }
- else if (CURRENT_TOKEN.TOKEN_TYPE == TOKEN_TYPES.TK_LARRAYBRACK)
- {
- CURRENT_TOKEN = Scanner.ScanAndRet(scan);
- }
- else if (CURRENT_TOKEN.TOKEN_TYPE == TOKEN_TYPES.TK_LPARENOP)
- {
- t = Expression();
- if (CURRENT_TOKEN.TOKEN_TYPE != TOKEN_TYPES.TK_RPARENOP)
- throw new TokenTypeMismatchException("Missing right paren");
- CURRENT_TOKEN = Scanner.ScanAndRet(scan);
- }
- else if (CURRENT_TOKEN.TOKEN_TYPE == TOKEN_TYPES.TK_STRING)
- {
- runtimemod.CodeStackPush(CURRENT_TOKEN.TOKEN_VALUE.ToString());
- CURRENT_TOKEN = Scanner.ScanAndRet(scan);
- t = TYPE.String;
- }
- else if (CURRENT_TOKEN.TOKEN_TYPE == TOKEN_TYPES.TK_NOT)
- {
- CURRENT_TOKEN = Scanner.ScanAndRet(scan);
- t = Factor();
- runtimemod.CodeStackPush(OPCODES.OP_NOT.ToString());
- }
- else if (CURRENT_TOKEN.TOKEN_TYPE == TOKEN_TYPES.TK_LPARENOP)
- {
- t = Expression();
- if (CURRENT_TOKEN.TOKEN_TYPE != TOKEN_TYPES.TK_RPARENOP)
- throw new TokenTypeMismatchException("Missing close bracket.");
- }
-
- return t;
-
- }
- //----------------------EXPRESSION GRAMMAR----------------------------------
- #endregion
- //Var Exist - Check symbol table to see if variable exists
- public bool VarExists(string token)
- {
- bool VariableExists = false;
- //Create temporary stack to push values into
- Stack<Dictionary<string, Record>> tempStack = new Stack<Dictionary<string, Record>>();
- int STACK_COUNT = SYMBOL_TABLE_STACK.Count;
- //cycle through the SYMBOL TABLE STACK
- for (int i = 0; i < STACK_COUNT; i++)
- {
- //Create reference to top symbol table
- Dictionary<string, Record> SymbTab = SYMBOL_TABLE_STACK.Pop();
- //Check if variable exists in symbol table
- if(!VariableExists)
- VariableExists = SymbTab.ContainsKey(token);
-
- //Push the stack we pop into symbol table
- tempStack.Push(SymbTab);
- }
- //Pop all Symbol Tables back into the stack
- for (int i = 0; i < STACK_COUNT; i++)
- SYMBOL_TABLE_STACK.Push(tempStack.Pop());
- return VariableExists;
- }
- //Keep popping symbol tables till we find the proper TK_VAR
- //Do we need to implement code for multiple symbol tables???
- //CHANGE as necessary
- public bool Lookup(Token tt, ref int address, ref TYPE type)
- {
- /*Dictionary<string, Record> rec = SYMBOL_TABLE_STACK.Pop();
- Record tempRec;
- rec.TryGetValue(tt.VALUE, out tempRec);
- if (tempRec!=null)
- {
- address = tempRec.address;
- type = tempRec.TYPE;
- SYMBOL_TABLE_STACK.Push(rec); // return it back
- return true;
- }
- return false;*/
- Record rec = new Record();
- rec.TYPE_LT = TOKEN_TYPES.TK_ID;
- Stack<Dictionary<string, Record>> tempStack = new Stack<Dictionary<string, Record>>();
- bool found = false;
- int STACK_COUNT = SYMBOL_TABLE_STACK.Count;
- //return if the SYMBOL TABLE IS EMPTY
- if (SYMBOL_TABLE_STACK.Count == 0)
- return false;
- while (SYMBOL_TABLE_STACK.Count != 0)
- {
- Dictionary<string, Record> symbolTable = SYMBOL_TABLE_STACK.Pop();
- tempStack.Push(symbolTable);
- foreach (KeyValuePair<string, Record> keyV in symbolTable)
- if (keyV.Key == tt.VALUE)
- {
- rec = keyV.Value;
- found = true;
- }
- }
- //Pop SymbolTables back into the SYMBOL_TABLE_STACK
- for (int i = 0; i < STACK_COUNT; i++)
- SYMBOL_TABLE_STACK.Push(tempStack.Pop());
- address = rec.address;
- …
Large files files are truncated, but you can click here to view the full file