Beispiel #1
0
        internal override bool NameAnalysis(SymbolTable table)
        {
            if (SecondPassAnalysis)
            {
                table.AddScope();
                CurrentFunction = this;
                parameterList.NameAnalysis(table); // only add new symbol, no possible error
                bool pass = statementList.NameAnalysis(table);
                CurrentFunction = null;
                table.RemoveScope();
                return(pass);
            }

            // first pass for function definition
            if (table.GlobalSearch(functionName) is not null)
            {
                Error($"{functionName} is declared in the same scope");
                return(false);
            }
            List <Type> parameterType = new List <Type>();

            table.AddSymbol(functionName, new Symbol(returnType, functionName, true, parameterType, this));
            foreach (var type in parameterList.Types()) // must take care of parameter type before type checking
            {
                parameterType.Add(type);
            }
            return(true);
        }
Beispiel #2
0
    /// <summary>
    /// func-decl -> DEF ID LP type-list RP optional-return-spec brace-block
    /// </summary>
    /// <param name="n"></param>
    private void funcdeclNodeCode(TreeNode n, bool justPutFunctionNameInSymtable)
    {
        var     fname = n.Children[1].Token.Lexeme;
        VarType retType;

        optionalreturnspecNodeCode(n.Children[5], out retType);

        List <VarType> argTypes;
        List <string>  argNames;

        optionaltypelistNodeCode(n.Children[3], out argNames, out argTypes);

        VarType funcType = new FuncVarType(argTypes, retType);

        if (justPutFunctionNameInSymtable)
        {
            if (symtable.ContainsInCurrentScope(fname))
            {
                throw new Exception("Error!! duplicate function decleration in scope!! DupFuncName: " + fname);
            }
            symtable[fname] = new VarInfo(funcType, label());
        }
        else
        {
            symtable.AddScope();
            addParametersToSymbolTable(argNames, argTypes);
            emit("{0}:  ;{1}", symtable[fname].Label, fname);
            prologueCode();
            emit("; braceblock for {0}", fname);
            braceblockNodeCode(n.Children[6], 0);
            emit("; final epilogue for {0}", fname);
            epilogueCode();
            symtable.DeleteScope();
        }
    }
Beispiel #3
0
    static void braceblockNodeCode(TreeNode n, int sizeOfVariablesInEnclosingBlocks)
    {
        symtable.AddScope();
        int sizeOfVariablesInThisBlock;

        vardecllistNodeCode(n.Children[1], sizeOfVariablesInEnclosingBlocks, out sizeOfVariablesInThisBlock);
        if (sizeOfVariablesInThisBlock > 0)
        {
            emit("sub rsp,{0}", sizeOfVariablesInThisBlock);
        }
        stmtsNodeCode(n.Children[2], sizeOfVariablesInEnclosingBlocks + sizeOfVariablesInThisBlock);
        if (sizeOfVariablesInThisBlock > 0)
        {
            emit("add rsp,{0}", sizeOfVariablesInThisBlock);
        }
        symtable.DeleteScope();
    }
Beispiel #4
0
        internal override bool NameAnalysis(SymbolTable table)
        {
            table.AddScope();
            bool pass = statementList.NameAnalysis(table);

            table.RemoveScope();
            return(pass);
        }
Beispiel #5
0
        internal override bool NameAnalysis(SymbolTable table)
        {
            bool pass = true;

            table.AddScope(); // possible nested two scope with block statement, but no real problem
            pass &= (initialStatement?.NameAnalysis(table) ?? true);
            pass &= condition.NameAnalysis(table);
            pass &= (iterateStatement?.NameAnalysis(table) ?? true);
            pass &= loopBody.NameAnalysis(table);
            table.RemoveScope();
            return(pass);
        }