public void AddGlobalVariable(VariableSym newVariable) { foreach (VariableSym variable in globalVars) { if (variable.anchorToken.Lexeme == newVariable.anchorToken.Lexeme) { throw new SemanticError("Name collision", newVariable.anchorToken); } } globalVars.Add(newVariable); }
public void AddLocalVariable(VariableSym newVariable) { foreach (VariableSym variable in localVars) { if (variable.lexeme == newVariable.lexeme) { if (newVariable.anchorToken != null) { throw new SemanticError("Name collision", newVariable.anchorToken); } else { throw new Exception("Error of name collision with a variable symbol that has no anchor token, which probably means that it was created for aid during code generation. This should not happen. Try checking if in your code is an identifier (variable or function parameter) with lexeme: " + newVariable.lexeme + "."); } } } localVars.Add(newVariable); }
public void Visit(NFunDefList node) { foreach (NFunDef funDef in node) { FunctionSym newFuncSym = new FunctionSym(funDef.AnchorToken, FunctionSymKind.USER_DEFINED); // Add parameters to local scope foreach (NParameter param in funDef[0]) { VariableSym newParam = new VariableSym(param.AnchorToken, VariableSymKind.PARAMETER); newFuncSym.AddLocalVariable(newParam); } // Add variables to local scope foreach (NVarDef variable in funDef[1]) { VariableSym newVariable = new VariableSym(variable.AnchorToken, VariableSymKind.REGULAR); newFuncSym.AddLocalVariable(newVariable); } semanticAnalyzer.AddFunction(newFuncSym); } }
// Stores value from top of the stack (and pops) by resolving if it is a local, global or parameter one string storeVariable(string lexeme) { VariableSym varSym = currentFunction.GetLocalVariableSymbolByLexeme(lexeme); if (varSym != null) // Lexeme represents local variable or parameter { if (varSym.kind == VariableSymKind.PARAMETER) { return("\t\tstarg '" + lexeme + "'\n"); } else { return("\t\tstloc '" + lexeme + "'\n"); } } else // Lexeme represents global variable { return("\t\tstsfld int64 Int64Program::'" + lexeme + "'\n"); } }
public string Visit(NForStmt nForStmt) { Token anchorToken = nForStmt.AnchorToken; string lexeme = anchorToken.Lexeme; string retVal = ""; string continueLabel = GenerateLabel(); string breakLabel = GenerateLabel(); string lastContinueLabel = currentContinueLabel; string lastBreakLabel = currentBreakLabel; currentContinueLabel = continueLabel; currentBreakLabel = breakLabel; string sizeLocalVariable = GenerateLabel(); VariableSym sizeLocalVarSym = new VariableSym(sizeLocalVariable, VariableSymKind.REGULAR); currentFunction.AddLocalVariable(sizeLocalVarSym); retVal += "\t\t.locals init (int64 '" + sizeLocalVariable + "')\n"; string indexLocalVariable = GenerateLabel(); VariableSym indexLocalVarSym = new VariableSym(indexLocalVariable, VariableSymKind.REGULAR); currentFunction.AddLocalVariable(indexLocalVarSym); retVal += "\t\t.locals init (int64 '" + indexLocalVariable + "')\n"; string arrayHandleLocalVariable = GenerateLabel(); VariableSym arrayHandleLocalVarSym = new VariableSym(arrayHandleLocalVariable, VariableSymKind.REGULAR); currentFunction.AddLocalVariable(arrayHandleLocalVarSym); retVal += "\t\t.locals init (int64 '" + arrayHandleLocalVariable + "')\n"; Node nExpr = nForStmt[0]; Node nStmtList = nForStmt[1]; retVal += Visit((dynamic)nExpr); retVal += storeVariable(arrayHandleLocalVariable); retVal += loadVariable(arrayHandleLocalVariable); retVal += "\t\tcall int64 class ['int64lib']'Int64'.'Utils'::'size'(int64)\n"; retVal += storeVariable(sizeLocalVariable); retVal += "\t\tldc.i8 -1\n"; retVal += storeVariable(indexLocalVariable); retVal += continueLabel + ":\n"; retVal += loadVariable(indexLocalVariable); retVal += "\t\tldc.i8 1\n"; retVal += "\t\tadd\n"; retVal += storeVariable(indexLocalVariable); retVal += loadVariable(indexLocalVariable); retVal += loadVariable(sizeLocalVariable); retVal += "\t\tclt\n"; retVal += "\t\tbrfalse " + breakLabel + "\n"; retVal += loadVariable(arrayHandleLocalVariable); retVal += loadVariable(indexLocalVariable); retVal += "\t\tcall int64 class ['int64lib']'Int64'.'Utils'::'get'(int64, int64)\n"; retVal += storeVariable(lexeme); retVal += Visit((dynamic)nStmtList); retVal += "\t\tbr " + continueLabel + "\n"; retVal += breakLabel + ":\n"; currentContinueLabel = lastContinueLabel; currentBreakLabel = lastBreakLabel; return(retVal); }