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);
 }
Example #2
0
 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);
 }
Example #3
0
 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);
        }