Beispiel #1
0
        private CFlatType TypeCheckIncrementDecrement(ASTExpression expr, string operatorName, LexLocation loc)
        {
            //totally cheating here. the grammar should not even allow this to happen.
            if (expr is ASTIdentifier)
            {
                ASTIdentifier identifier = (ASTIdentifier)expr;
                //need to set a flag so that the code generator can store back the result
                identifier.IsLeftHandSide = true;

                CFlatType t = CheckSubTree(identifier);
                if (t.IsNumeric)
                {
                    return(t);
                }
                else
                {
                    ReportError(loc, "The {0} operator requires an instance of a numeric datatype", operatorName);
                }
            }
            else
            {
                ReportError(loc, "The {0} operator requires an instance of a numeric datatype", operatorName);
            }

            /* note: the ReportError method will always throw, so this part of the code should not be reached,
             * unless of course we change the ReportError method to not throw or try to implement some error recovery
             * strategy...
             * */
            throw new InternalCompilerException("This part of the code should not be reachable.");
        }
Beispiel #2
0
        private static ASTExpression ParseExpression()
        {
            ASTExpression lhs = ParsePrimary();

            if (lhs == null)
            {
                return(null);
            }

            return(ParseRHSBinaryOperator(0, lhs));
        }
Beispiel #3
0
        private void ApplyIncrementDecrement(ASTExpression exp, OpCode op)
        {
            exp.Visit(this);
            //visit the identifier again, as the right hand side of an assignment so we emit the OpCodes for loading onto the stack
            new ASTIdentifier(null, _lastWalkedIdentifier).Visit(this);

            _gen.Emit(OpCodes.Ldc_I4_1);
            _gen.Emit(op);
            //store this back to the location
            ApplyAssignmentCallback();
        }
Beispiel #4
0
        private static ASTFunction ParseTopLevelExpression()
        {
            ASTExpression e = ParseExpression();

            if (e == null)
            {
                return(null);
            }

            // create an anonymous prototype to evaluate the expression
            ASTPrototype proto = new ASTPrototype("__proto", new List <string>());

            return(new ASTFunction(proto, e));
        }
Beispiel #5
0
        private static ASTExpression ParseParenExpression()
        {
            NextToken();    // eat first '('
            ASTExpression exp = ParseExpression();

            if (exp == null)
            {
                return(null);
            }

            if (CurrentToken.StringValue != ")")
            {
                return(LogError("Expected ')'"));
            }

            NextToken();    // eat ')'
            return(exp);
        }
        /* apply optimizations to the AST.  returns False if it runs out of memory. */
        private static void OptimizeAST(ref ASTExpression Expr)
        {
            bool DidSomething = true;

            while (DidSomething)
            {
                bool OneDidSomething;

                DidSomething = false;

                ASTExpression exprReplacement;
                Expr.FoldConst(out OneDidSomething, out exprReplacement);
                if (exprReplacement != null)
                {
                    Expr = exprReplacement;
                }
                DidSomething = DidSomething || OneDidSomething;
            }
        }
Beispiel #7
0
        private static ASTFunction ParseDefinition()
        {
            NextToken();                           // eat the 'def' keyword

            ASTPrototype proto = ParsePrototype(); // parse the definition

            if (proto == null)
            {
                return(null);
            }

            ASTExpression body = ParseExpression(); // and the body

            if (body != null)
            {
                return(new ASTFunction(proto, body));
            }

            return(null);
        }
Beispiel #8
0
        private static ASTExpression ParseRHSBinaryOperator(int prec, ASTExpression lhs)
        {
            while (true)
            {
                int tokPrec = Grammar.GetPrecedence(CurrentToken.StringValue);

                // If this is a binop that binds at least as tightly as the current binop,
                // consume it, otherwise we are done.
                if (tokPrec < prec)
                {
                    return(lhs);
                }

                // we now know this is a binary operator
                string binop = CurrentToken.StringValue;
                NextToken();    // consume op

                // parse primary expr after the operator
                ASTExpression rhs = ParsePrimary();
                if (rhs == null)
                {
                    return(null);
                }

                // If the binop binds less tightly with RHS than the operator after RHS, let
                // the pending operator take RHS as its LHS. Basically look-ahead
                int nextPrec = Grammar.GetPrecedence(CurrentToken.StringValue);
                if (tokPrec < nextPrec)
                {
                    rhs = ParseRHSBinaryOperator(prec + 1, rhs);
                    if (rhs == null)
                    {
                        return(null);
                    }
                }

                // merge lhs and rhs
                lhs = new ASTExpressionBinary(binop, lhs, rhs);
            }   // end of while loop
        }
Beispiel #9
0
    ASTExpression ParseExpression()
    {
        ASTExpression firstExpr = ParseExpressionImpl();

        if (lexer.IsReading)
        {
            if (lexer.PeekNext() == TokenType.Operator)  // Operators
            {
                Token opToken = lexer.NextToken();

                ASTExpression rightSide = ParseExpression();

                ASTOperator opNode = new ASTOperator(opToken.Source, firstExpr, rightSide);

                return(opNode);
            }
            else if (lexer.PeekNext() == TokenType.SquareBraceOpen)    // Array access
            {
                ASTIndexer upper = null;

                while (lexer.PeekNext() == TokenType.SquareBraceOpen)
                {
                    MatchNext(TokenType.SquareBraceOpen);

                    ASTExpression index = ParseExpression();

                    upper     = new ASTIndexer(firstExpr, index);
                    firstExpr = upper;

                    MatchNext(TokenType.SquareBraceClose);
                }

                return(upper);
            }
        }
        return(firstExpr);
    }
Beispiel #10
0
        /* compile a special function.  a special function has no function header, but is */
        /* simply some code to be executed.  the parameters the code is expecting are provided */
        /* in the FuncArray[] and NumParams.  the first parameter is deepest beneath the */
        /* top of stack.  the TextData is NOT altered.  if an error occurrs, *FunctionOut */
        /* will NOT contain a valid object */
        public static CompileErrors CompileSpecialFunction(
            CodeCenterRec CodeCenter,
            FunctionParamRec[] FuncArray,
            out int ErrorLineNumber,
            out DataTypes ReturnTypeOut,
            string TextData,
            bool suppressCILEmission,
            out PcodeRec FunctionOut,
            out ASTExpression ASTOut)
        {
            CompileErrors Error;

            ErrorLineNumber = -1;
            ASTOut          = null;
            FunctionOut     = null;
            ReturnTypeOut   = DataTypes.eInvalidDataType;

            ScannerRec <KeywordsType> TheScanner     = new ScannerRec <KeywordsType>(TextData, KeywordTable);
            SymbolTableRec            TheSymbolTable = new SymbolTableRec();

            // reconstitute function prototypes
            for (int i = 0; i < CodeCenter.RetainedFunctionSignatures.Length; i++)
            {
                SymbolRec functionSignature = ArgListTypesToSymbol(
                    CodeCenter.RetainedFunctionSignatures[i].Key,
                    CodeCenter.RetainedFunctionSignatures[i].Value.ArgsTypes,
                    CodeCenter.RetainedFunctionSignatures[i].Value.ReturnType);
                bool f = TheSymbolTable.Add(functionSignature);
                Debug.Assert(f); // should never fail (due to duplicate) since CodeCenter.RetainedFunctionSignatures is unique-keyed
            }

            /* build parameters into symbol table */
            int StackDepth         = 0;
            int MaxStackDepth      = 0;
            int ReturnAddressIndex = StackDepth;

            for (int i = 0; i < FuncArray.Length; i += 1)
            {
                SymbolRec TheParameter = new SymbolRec(FuncArray[i].ParameterName);
                TheParameter.SymbolBecomeVariable(FuncArray[i].ParameterType);
                /* allocate stack slot */
                StackDepth++;
                MaxStackDepth = Math.Max(MaxStackDepth, StackDepth);
                TheParameter.SymbolVariableStackLocation = StackDepth;
                if (!TheSymbolTable.Add(TheParameter)) // our own code should never pass in a formal arg list with duplicates
                {
                    Debug.Assert(false);
                    throw new InvalidOperationException();
                }
            }
            /* fence them off */
            TheSymbolTable.IncrementSymbolTableLevel();

            /* reserve spot for fake return address (so we have uniform calling convention everywhere) */
            StackDepth++;
            MaxStackDepth = Math.Max(MaxStackDepth, StackDepth);
            if (StackDepth != FuncArray.Length + 1)
            {
                // stack depth error before evaluating function
                Debug.Assert(false);
                throw new InvalidOperationException();
            }

            ASTExpressionList ListOfExpressions;

            Error = ParseExprList(
                out ListOfExpressions,
                new ParserContext(
                    TheScanner,
                    TheSymbolTable),
                out ErrorLineNumber);
            /* compile the thing */
            if (Error != CompileErrors.eCompileNoError)
            {
                return(Error);
            }
            ASTExpression TheExpressionThang = new ASTExpression(
                ListOfExpressions,
                TheScanner.GetCurrentLineNumber());

            /* make sure there is nothing after it */
            TokenRec <KeywordsType> Token = TheScanner.GetNextToken();

            if (Token.GetTokenType() != TokenTypes.eTokenEndOfInput)
            {
                ErrorLineNumber = TheScanner.GetCurrentLineNumber();
                return(CompileErrors.eCompileInputBeyondEndOfFunction);
            }

            DataTypes ResultingType;

            Error = TheExpressionThang.TypeCheck(out ResultingType, out ErrorLineNumber);
            if (Error != CompileErrors.eCompileNoError)
            {
                return(Error);
            }

            OptimizeAST(ref TheExpressionThang);

            PcodeRec TheFunctionCode = new PcodeRec();

            TheExpressionThang.PcodeGen(
                TheFunctionCode,
                ref StackDepth,
                ref MaxStackDepth);
            Debug.Assert(StackDepth <= MaxStackDepth);

            ReturnTypeOut = TheExpressionThang.ResultType;


            /* 2 extra words for retaddr, resultofexpr */
            if (StackDepth != FuncArray.Length + 1 /*retaddr*/ + 1 /*result*/)
            {
                // stack depth error after evaluating function
                Debug.Assert(false);
                throw new InvalidOperationException();
            }
            /* now put the return instruction */
            int unused;

            TheFunctionCode.AddPcodeInstruction(Pcodes.epReturnFromSubroutine, out unused, TheScanner.GetCurrentLineNumber());
            // special function returns without popping args -- so that args can be have in/out behavior
            TheFunctionCode.AddPcodeOperandInteger(0);
            StackDepth -= 1; /* pop retaddr */
            Debug.Assert(StackDepth <= MaxStackDepth);
            if (StackDepth != 1 + FuncArray.Length)
            {
                // stack depth is wrong at end of function
                Debug.Assert(false);
                throw new InvalidOperationException();
            }

            TheFunctionCode.MaxStackDepth = MaxStackDepth;

            /* optimize stupid things away */
            TheFunctionCode.OptimizePcode();


            if (CILObject.EnableCIL && !suppressCILEmission)
            {
                DataTypes[] argsTypes = new DataTypes[FuncArray.Length];
                string[]    argsNames = new string[FuncArray.Length];
                for (int i = 0; i < argsTypes.Length; i++)
                {
                    argsTypes[i] = FuncArray[i].ParameterType;
                    argsNames[i] = FuncArray[i].ParameterName;
                }
                CILAssembly cilAssembly = new CILAssembly();
                CILObject   cilObject   = new CILObject(
                    CodeCenter.ManagedFunctionLinker,
                    argsTypes,
                    argsNames,
                    TheExpressionThang.ResultType,
                    TheExpressionThang,
                    cilAssembly,
                    true /*argsByRef*/); // args by ref true for special functions to permit multiple return values
                TheFunctionCode.cilObject = cilObject;
                cilAssembly.Finish();
            }


            /* it worked, so return the dang thing */
            FunctionOut = TheFunctionCode;
            ASTOut      = TheExpressionThang;
            return(CompileErrors.eCompileNoError);
        }
Beispiel #11
0
    ASTExpression ParseExpressionImpl()
    {
        Token first = lexer.NextToken();

        switch (first.Type)
        {
        case TokenType.True:
            return(new ASTLiteral(true));

        case TokenType.False:
            return(new ASTLiteral(false));

        case TokenType.Number:
            if (first.Source.Contains("."))
            {
                return(new ASTLiteral(float.Parse(first.Source)));
            }
            try {
                int i = int.Parse(first.Source);
            } catch (System.Exception e) {
                Debug.LogError("Integer Invalid: " + first.Source + " len: " + first.Source.Length);
            }
            return(new ASTLiteral(int.Parse(first.Source)));

        case TokenType.String:
            return(new ASTLiteral(first.Source));

        case TokenType.Identifier:
        {
            if (lexer.PeekNext() == TokenType.BracketOpen)
            {
                ASTFuncCall funcCall = new ASTFuncCall(first.Source);

                lexer.NextToken();         // Eat open bracket

                while (true)
                {
                    if (lexer.PeekNext() == TokenType.BracketClose)
                    {
                        lexer.NextToken();
                        break;
                    }

                    ASTExpression arg = ParseExpression();
                    funcCall.AddArg(arg);

                    if (lexer.PeekNext() == TokenType.BracketClose)
                    {
                        lexer.NextToken();
                        break;
                    }

                    MatchNext(TokenType.Comma);
                }

                return(funcCall);
            }
            return(new ASTVariable(first.Source));
        }

        default:
            throw new Exception("Unexpected token " + first);
        }
    }
Beispiel #12
0
 public override object Visit(ASTExpression node, object data)
 {
     return(this.ShowNode(node, data));
 }
Beispiel #13
0
 public virtual Object Visit(ASTExpression node, Object data)
 {
     data = node.ChildrenAccept(this, data);
     return(data);
 }
Beispiel #14
0
    ASTStatement ParseStatement()
    {
        if (lexer.PeekNext() == TokenType.Identifier)  // Function call
        {
            ASTFuncCall funcCall = ParseExpression() as ASTFuncCall;
            return(new ASTInlineCall(funcCall));
        }

        Token first = lexer.NextToken();

        switch (first.Type)
        {
        case TokenType.Set:
        {
            Token varNameToken            = MatchNext(TokenType.Identifier);
            List <ASTExpression> indexers = new List <ASTExpression>();

            while (lexer.PeekNext() == TokenType.SquareBraceOpen)
            {
                MatchNext(TokenType.SquareBraceOpen);

                indexers.Add(ParseExpression());

                MatchNext(TokenType.SquareBraceClose);
            }

            MatchNext(TokenType.To);

            ASTExpression expression = ParseExpression();

            return(new ASTSet(varNameToken.Source, expression, indexers));
        }

        case TokenType.If:
        {
            ASTExpression check      = ParseExpression();
            ASTStatements statements = new ASTStatements();
            ASTIf         ifStmnt    = new ASTIf(check, statements);

            MatchNext(TokenType.Do);

            while (lexer.PeekNext() != TokenType.End)
            {
                if (lexer.PeekNext() == TokenType.Else)
                {
                    lexer.NextToken();

                    statements = new ASTStatements();
                    ifStmnt.SetElse(statements);

                    MatchNext(TokenType.Do);
                }
                else if (lexer.PeekNext() == TokenType.Elif)
                {
                    lexer.NextToken();

                    statements = new ASTStatements();
                    ASTIf elseifStmnt = new ASTIf(ParseExpression(), statements);

                    ifStmnt.SetElseIf(elseifStmnt);

                    MatchNext(TokenType.Do);
                }
                statements.AddStatement(ParseStatement());
            }

            lexer.NextToken();

            return(ifStmnt);
        }

        case TokenType.While:
        {
            ASTExpression check      = ParseExpression();
            ASTStatements statements = new ASTStatements();
            ASTWhile      whileStmnt = new ASTWhile(check, statements);

            MatchNext(TokenType.Do);

            while (lexer.PeekNext() != TokenType.End)
            {
                statements.AddStatement(ParseStatement());
            }

            lexer.NextToken();

            return(whileStmnt);
        }

        case TokenType.Return:
        {
            return(new ASTReturn(ParseExpression()));
        }

        default:
            throw new Exception("Unexpected token " + first);
        }

        return(null);
    }
Beispiel #15
0
 public ASTUnaryExpression(ASTToken op, ASTExpression expr) : base("UnaryExpression")
 {
     Expression = expr;
     Operator   = op;
 }
Beispiel #16
0
 public ASTFunctionCall(ASTExpression name, List <ASTNode> args) : base("FunctionCall")
 {
     FunctionName = name;
     ArgList      = args;
 }
Beispiel #17
0
 public ASTArrayAccess(ASTExpression arrayname, List <ASTExpression> elements) : base("ArrayAccess")
 {
     ArrayName = arrayname;
     Elements  = elements;
 }
Beispiel #18
0
        // Compile multiple modules. (eliminates the need to do prototyping or function signature inference.)
        // CodeCenter is cleared, and if compilation succeeds, the functions are added to CodeCenter.
        public static CompileErrors CompileWholeProgram(
            out int ErrorLineNumber,
            out int ErrorModuleIndex,
            string[] TextDatas,
            object[] Signatures,
            CodeCenterRec CodeCenter,
            string[] Filenames)
        {
            Debug.Assert(TextDatas.Length == Signatures.Length);
            Debug.Assert(TextDatas.Length == Filenames.Length);

            ErrorLineNumber  = -1;
            ErrorModuleIndex = -1;

            CodeCenter.FlushAllCompiledFunctions();
            CodeCenter.RetainedFunctionSignatures = new KeyValuePair <string, FunctionSignature> [0];

            // parse

            List <SymbolRec>     SymbolTableEntriesForForm = new List <SymbolRec>();
            List <ASTExpression> FunctionBodyRecords       = new List <ASTExpression>();
            List <int>           ModuleIndices             = new List <int>();
            Dictionary <string, List <ParserContext.FunctionSymbolRefInfo> > FunctionRefSymbolList = new Dictionary <string, List <ParserContext.FunctionSymbolRefInfo> >();
            List <int> InitialLineNumbersOfForm = new List <int>();

            for (int module = 0; module < TextDatas.Length; module++)
            {
                string TextData = TextDatas[module];

                ErrorModuleIndex = module;

                ScannerRec <KeywordsType> TheScanner     = new ScannerRec <KeywordsType>(TextData, KeywordTable);
                SymbolTableRec            TheSymbolTable = new SymbolTableRec();

                /* loop until there are no more things to parse */
                while (true)
                {
                    TokenRec <KeywordsType> Token = TheScanner.GetNextToken();
                    int InitialLineNumberOfForm   = TheScanner.GetCurrentLineNumber();
                    if (Token.GetTokenType() == TokenTypes.eTokenEndOfInput)
                    {
                        /* no more functions to parse, so stop */
                        break;
                    }

                    SymbolRec     SymbolTableEntryForForm;
                    ASTExpression FunctionBodyRecord;

                    /* parse the function */
                    TheScanner.UngetToken(Token);
                    CompileErrors Error = ParseForm(
                        out SymbolTableEntryForForm,
                        out FunctionBodyRecord,
                        new ParserContext(
                            TheScanner,
                            TheSymbolTable,
                            FunctionRefSymbolList),
                        out ErrorLineNumber);
                    if (Error != CompileErrors.eCompileNoError)
                    {
                        return(Error);
                    }

                    Debug.Assert(FunctionBodyRecord != null);
                    ModuleIndices.Add(module);
                    SymbolTableEntriesForForm.Add(SymbolTableEntryForForm);
                    FunctionBodyRecords.Add(FunctionBodyRecord);
                    InitialLineNumbersOfForm.Add(InitialLineNumberOfForm);
                }

                foreach (KeyValuePair <string, List <ParserContext.FunctionSymbolRefInfo> > name in FunctionRefSymbolList)
                {
                    foreach (ParserContext.FunctionSymbolRefInfo funcRef in name.Value)
                    {
                        funcRef.module = module;
                    }
                }
            }

            // push function type signatures into function call refs

            Dictionary <string, bool> functionNamesUsed = new Dictionary <string, bool>();

            for (int i = 0; i < SymbolTableEntriesForForm.Count; i++)
            {
                ErrorModuleIndex = ModuleIndices[i];

                SymbolRec FunctionDeclarationSymbol = SymbolTableEntriesForForm[i];
                if (functionNamesUsed.ContainsKey(FunctionDeclarationSymbol.SymbolName))
                {
                    ErrorLineNumber = FunctionBodyRecords[i].LineNumber;
                    return(CompileErrors.eCompileMultiplyDeclaredFunction);
                }
                functionNamesUsed.Add(FunctionDeclarationSymbol.SymbolName, false);

                List <ParserContext.FunctionSymbolRefInfo> symbols;
                if (FunctionRefSymbolList.TryGetValue(FunctionDeclarationSymbol.SymbolName, out symbols))
                {
                    foreach (ParserContext.FunctionSymbolRefInfo functionRef in symbols)
                    {
                        functionRef.symbol.SymbolBecomeFunction2(
                            FunctionDeclarationSymbol.FunctionArgList,
                            FunctionDeclarationSymbol.FunctionReturnType);
                    }
                    FunctionRefSymbolList.Remove(FunctionDeclarationSymbol.SymbolName);
                }
            }

            foreach (KeyValuePair <string, List <ParserContext.FunctionSymbolRefInfo> > name in FunctionRefSymbolList)
            {
                foreach (ParserContext.FunctionSymbolRefInfo funcRef in name.Value)
                {
                    ErrorModuleIndex = funcRef.module;
                    ErrorLineNumber  = funcRef.lineNumber;
                    return(CompileErrors.eCompileMultiplyDeclaredFunction);
                }
            }

            // type check and type inference

            for (int i = 0; i < FunctionBodyRecords.Count; i++)
            {
                int           module = ModuleIndices[i];
                SymbolRec     SymbolTableEntryForForm = SymbolTableEntriesForForm[i];
                ASTExpression FunctionBodyRecord      = FunctionBodyRecords[i];
                int           InitialLineNumberOfForm = InitialLineNumbersOfForm[i];

                ErrorModuleIndex = module;

                /* SymbolTableEntryForForm will be the symbol table entry that */
                /* was added to the symbol table.  FunctionBodyRecord is either */
                /* an expression for a function or NIL if it was a prototype */

                Debug.Assert(!CodeCenter.CodeCenterHaveThisFunction(SymbolTableEntryForForm.SymbolName));

                /* step 1:  do type checking */
                DataTypes     ResultingType;
                CompileErrors Error = FunctionBodyRecord.TypeCheck(
                    out ResultingType,
                    out ErrorLineNumber);
                if (Error != CompileErrors.eCompileNoError)
                {
                    return(Error);
                }
                /* check to see that resulting type matches declared type */
                if (!CanRightBeMadeToMatchLeft(SymbolTableEntryForForm.FunctionReturnType, ResultingType))
                {
                    ErrorLineNumber = InitialLineNumberOfForm;
                    return(CompileErrors.eCompileTypeMismatch);
                }
                /* if it has to be promoted, then promote it */
                if (MustRightBePromotedToLeft(SymbolTableEntryForForm.FunctionReturnType, ResultingType))
                {
                    /* insert promotion operator above expression */
                    ASTExpression ReplacementExpr = PromoteTheExpression(
                        ResultingType,
                        SymbolTableEntryForForm.FunctionReturnType,
                        FunctionBodyRecord,
                        InitialLineNumberOfForm);
                    FunctionBodyRecord = ReplacementExpr;
                    /* sanity check */
                    Error = FunctionBodyRecord.TypeCheck(
                        out ResultingType,
                        out ErrorLineNumber);
                    if (Error != CompileErrors.eCompileNoError)
                    {
                        // type promotion caused failure
                        Debug.Assert(false);
                        throw new InvalidOperationException();
                    }
                    if (ResultingType != SymbolTableEntryForForm.FunctionReturnType)
                    {
                        // after type promotion, types are no longer the same
                        Debug.Assert(false);
                        throw new InvalidOperationException();
                    }
                }
            }

            // code generation

            CILAssembly cilAssembly = null;

            if (CILObject.EnableCIL)
            {
                cilAssembly = new CILAssembly();
            }

            FuncCodeRec[] TheWholeFunctionThings = new FuncCodeRec[FunctionBodyRecords.Count];
            for (int i = 0; i < FunctionBodyRecords.Count; i++)
            {
                int           module = ModuleIndices[i];
                SymbolRec     SymbolTableEntryForForm = SymbolTableEntriesForForm[i];
                ASTExpression FunctionBodyRecord      = FunctionBodyRecords[i];
                int           InitialLineNumberOfForm = InitialLineNumbersOfForm[i];

                string Filename  = Filenames[module];
                object Signature = Signatures[module];

                ErrorModuleIndex = module;

                Debug.Assert(!CodeCenter.CodeCenterHaveThisFunction(SymbolTableEntryForForm.SymbolName));

                /* step 1.5:  optimize the AST */
                OptimizeAST(ref FunctionBodyRecord);

                /* step 2:  do code generation */
                /* calling conventions:  */
                /*  - push the arguments */
                /*  - funccall pushes the return address */
                /* thus, upon entry, Stack[0] will be the return address */
                /* and Stack[-1] will be the rightmost argument */
                /* on return, args and retaddr are popped and retval replaces them */
                int           StackDepth             = 0;
                int           MaxStackDepth          = 0;
                int           ReturnValueLocation    = StackDepth; /* remember return value location */
                int           ArgumentIndex          = 0;
                SymbolListRec FormalArgumentListScan = SymbolTableEntryForForm.FunctionArgList;
                while (FormalArgumentListScan != null)
                {
                    SymbolRec TheFormalArg = FormalArgumentListScan.First;
                    StackDepth++;                                          /* allocate first */
                    MaxStackDepth = Math.Max(MaxStackDepth, StackDepth);
                    TheFormalArg.SymbolVariableStackLocation = StackDepth; /* remember */
                    ArgumentIndex++;
                    FormalArgumentListScan = FormalArgumentListScan.Rest;
                }
                /* reserve return address spot */
                StackDepth++;
                MaxStackDepth = Math.Max(MaxStackDepth, StackDepth);
                /* allocate the function code */
                PcodeRec TheFunctionCode = new PcodeRec();
                FunctionBodyRecord.PcodeGen(
                    TheFunctionCode,
                    ref StackDepth,
                    ref MaxStackDepth);
                Debug.Assert(StackDepth <= MaxStackDepth);
                /* 2 extra words for retaddr and resultofexpr */
                if (StackDepth != ArgumentIndex + 1 + 1)
                {
                    // stack depth error after evaluating function
                    Debug.Assert(false);
                    throw new InvalidOperationException();
                }
                /* now put the return instruction (pops retaddr and args, leaving retval) */
                int ignored;
                TheFunctionCode.AddPcodeInstruction(Pcodes.epReturnFromSubroutine, out ignored, InitialLineNumberOfForm);
                TheFunctionCode.AddPcodeOperandInteger(ArgumentIndex);
                StackDepth = StackDepth - (1 + ArgumentIndex);
                Debug.Assert(StackDepth <= MaxStackDepth);
                if (StackDepth != 1)
                {
                    // stack depth is wrong at end of function
                    Debug.Assert(false);
                    throw new InvalidOperationException();
                }

                TheFunctionCode.MaxStackDepth = MaxStackDepth;

                /* step 2.5:  optimize the code */
                TheFunctionCode.OptimizePcode();

                /* step 3:  create the function and save it away */
                FuncCodeRec TheWholeFunctionThing = new FuncCodeRec(
                    SymbolTableEntryForForm.SymbolName,
                    SymbolTableEntryForForm.FunctionArgList,
                    TheFunctionCode,
                    SymbolTableEntryForForm.FunctionReturnType,
                    Filename);

                TheWholeFunctionThings[i] = TheWholeFunctionThing;

                if (CILObject.EnableCIL)
                {
                    DataTypes[] argsTypes;
                    string[]    argsNames;
                    SymbolicArgListToType(SymbolTableEntryForForm, out argsTypes, out argsNames);
                    CILObject cilObject = new CILObject(
                        CodeCenter.ManagedFunctionLinker,
                        argsTypes,
                        argsNames,
                        SymbolTableEntryForForm.FunctionReturnType,
                        FunctionBodyRecord,
                        cilAssembly,
                        false /*argsByRef*/);
                    TheWholeFunctionThing.CILObject = cilObject;
                }
            }

            // register after entire assembly is emitted
            if (CILObject.EnableCIL)
            {
                cilAssembly.Finish();
            }

            for (int i = 0; i < TheWholeFunctionThings.Length; i++)
            {
                FuncCodeRec TheWholeFunctionThing = TheWholeFunctionThings[i];
                object      Signature             = Signatures[ModuleIndices[i]];

                CodeCenter.AddFunctionToCodeCenter(TheWholeFunctionThing, Signature);
            }

            // retain signatures for compilation of special functions

            CodeCenter.RetainedFunctionSignatures = new KeyValuePair <string, FunctionSignature> [SymbolTableEntriesForForm.Count];
            for (int i = 0; i < CodeCenter.RetainedFunctionSignatures.Length; i++)
            {
                DataTypes[] argsTypes;
                string[]    argsNames;
                SymbolicArgListToType(SymbolTableEntriesForForm[i], out argsTypes, out argsNames);
                CodeCenter.RetainedFunctionSignatures[i] = new KeyValuePair <string, FunctionSignature>(
                    SymbolTableEntriesForForm[i].SymbolName,
                    new FunctionSignature(
                        argsTypes,
                        SymbolTableEntriesForForm[i].FunctionReturnType));
            }

            return(CompileErrors.eCompileNoError);
        }
Beispiel #19
0
 public ASTExpressionBinary(string op, ASTExpression lhs, ASTExpression rhs)
 {
     Operator = op;
     LHS      = lhs;
     RHS      = rhs;
 }
Beispiel #20
0
 public ASTFunction(ASTPrototype prototype, ASTExpression body)
 {
     Prototype = prototype;
     Body      = body;
 }
Beispiel #21
0
 public virtual System.Object visit(ASTExpression node, System.Object data)
 {
     data = node.childrenAccept(this, data);
     return(data);
 }
Beispiel #22
0
 public ASTBinaryExpression(ASTToken op, ASTExpression e1, ASTExpression e2) : base("BinaryExpression")
 {
     Operator = op;
     Expr1    = e1;
     Expr2    = e2;
 }
Beispiel #23
0
 public ASTOperator(string op, ASTExpression left, ASTExpression right)
 {
     this.op    = op;
     this.left  = left;
     this.right = right;
 }
Beispiel #24
0
 public ASTPostfixExpression(ASTExpression expr, ASTToken op) : base("PostfixExpression")
 {
     Expression = expr;
     Operator   = op;
 }
Beispiel #25
0
 public void AddArg(ASTExpression expression)
 {
     expressions.Add(expression);
 }
Beispiel #26
0
 public ASTArrayDeclarator(ASTDeclarator declarator, ASTExpression expressions) : base("ArrayDeclarator")
 {
     Declarator = declarator;
     Expression = expressions;
 }
Beispiel #27
0
 public ASTIndexer(ASTExpression baseExpr, ASTExpression indexExpr)
 {
     this.baseExpr  = baseExpr;
     this.indexExpr = indexExpr;
 }
Beispiel #28
0
 /// <summary>Display an ASTExpression node
 /// </summary>
 public override Object Visit(ASTExpression node, Object data)
 {
     return(ShowNode(node, data));
 }
Beispiel #29
0
 /// <summary>Display an ASTExpression node
 /// </summary>
 public override System.Object visit(ASTExpression node, System.Object data)
 {
     return(showNode(node, data));
 }
Beispiel #30
0
		/* -----------------------------------------------------------------------
		* 
		*  Expression Syntax
		* 
		* ----------------------------------------------------------------------*/

		public void Expression()
		{
			/*@bgen(jjtree) Expression */
			ASTExpression jjtn000 = new ASTExpression(this, ParserTreeConstants.EXPRESSION);
			bool jjtc000 = true;
			nodeTree.OpenNodeScope(jjtn000);
			//UPGRADE_NOTE: Exception 'java.lang.Throwable' was converted to ' ' which has different behavior. 'ms-help://MS.VSCC/commoner/redir/redirect.htm?keyword="jlca1100"'
			try
			{
				if (jj_2_10(2147483647))
				{
					Assignment();
				}
				else
				{
					switch(GetCurrentTokenKind())
					{
						case ParserConstants.LBRACKET:
						case ParserConstants.LPAREN:
						case ParserConstants.WHITESPACE:
						case ParserConstants.STRING_LITERAL:
						case ParserConstants.TRUE:
						case ParserConstants.FALSE:
						case ParserConstants.LOGICAL_NOT:
						case ParserConstants.NUMBER_LITERAL:
						case ParserConstants.IDENTIFIER:
						case ParserConstants.LCURLY:
							ConditionalOrExpression();
							break;

						default:
							jj_la1[36] = jj_gen;
							ConsumeToken(-1);
							throw new ParseException();
					}
				}
			}
			catch(Exception exception)
			{
				nodeTree.ClearNodeScope(jjtn000);
				jjtc000 = false;
				if (exception is SystemException)
				{
					throw;
				}
				if (exception is ParseException)
				{
					throw;
				}
				throw (ApplicationException) exception;
			}
			finally
			{
				if (jjtc000)
				{
					nodeTree.CloseNodeScope(jjtn000, true);
				}
			}
		}
Beispiel #31
0
 public ASTSet(string varName, ASTExpression expression, List <ASTExpression> indexers)
 {
     this.varName    = varName;
     this.expression = expression;
     this.indexers   = indexers;
 }