Beispiel #1
0
            public void Build(Token stopToken)
            {
                const int STATE_UNDEF             = 0;
                const int STATE_OPERAND_EXPECTED  = 1;
                const int STATE_FUNC_WAIT         = 2;
                const int STATE_OPERATOR_EXPECTED = 3;

                _operators = new Stack <Token>();

                int    currentState      = STATE_UNDEF;
                string waitingIdentifier = null;
                int    parCount          = 0;

                while (true)
                {
                    bool success = false;

                    if (_compiler._lastExtractedLexem.Token == stopToken)
                    {
                        if (currentState == STATE_FUNC_WAIT)
                        {
                            _compiler.BuildPushVariable(waitingIdentifier);
                        }
                        else if (currentState != STATE_OPERATOR_EXPECTED)
                        {
                            throw CompilerException.ExpressionSyntax();
                        }
                        break;
                    }

                    switch (currentState)
                    {
                    case STATE_UNDEF:
                    case STATE_OPERAND_EXPECTED:
                        if (_compiler.IsLiteral(ref _compiler._lastExtractedLexem))
                        {
                            _compiler.BuildPushConstant();
                            currentState = STATE_OPERATOR_EXPECTED;
                            success      = true;
                        }
                        else if (_compiler._lastExtractedLexem.Type == LexemType.Identifier)
                        {
                            if (_compiler._lastExtractedLexem.Token == Token.NotAToken)
                            {
                                waitingIdentifier = _compiler._lastExtractedLexem.Content;
                                currentState      = STATE_FUNC_WAIT;
                                success           = true;
                            }
                            else if (LanguageDef.IsBuiltInFunction(_compiler._lastExtractedLexem.Token))
                            {
                                _compiler.BuildBuiltinFunction();
                                currentState = STATE_OPERATOR_EXPECTED;
                                success      = true;
                            }
                            else if (_compiler._lastExtractedLexem.Token == Token.NewObject)
                            {
                                _compiler.BuildNewObjectCreation();
                                currentState = STATE_OPERATOR_EXPECTED;
                                success      = true;
                            }
                            else
                            {
                                throw CompilerException.TokenExpected(stopToken);
                            }
                        }
                        else if (_compiler._lastExtractedLexem.Token == Token.Minus)
                        {
                            PushOperator(Token.UnaryMinus);
                            currentState = STATE_OPERAND_EXPECTED;
                            success      = true;
                        }
                        else if (_compiler._lastExtractedLexem.Token == Token.OpenPar)
                        {
                            PushOperator(Token.OpenPar);
                            parCount++;
                            currentState = STATE_UNDEF;
                            success      = true;
                        }
                        else if (_compiler._lastExtractedLexem.Token == Token.Not)
                        {
                            PushOperator(Token.Not);
                            currentState = STATE_OPERAND_EXPECTED;
                            success      = true;
                        }

                        break;

                    case STATE_FUNC_WAIT:
                        if (_compiler._lastExtractedLexem.Token == Token.OpenPar)
                        {
                            _compiler.BuildFunctionCall(waitingIdentifier);
                            if (_compiler._lastExtractedLexem.Token == Token.ClosePar)
                            {
                                currentState = STATE_OPERATOR_EXPECTED;
                                success      = true;
                            }
                            else if (_compiler._lastExtractedLexem.Type == LexemType.Operator)
                            {
                                currentState = STATE_OPERATOR_EXPECTED;
                                continue;
                            }
                        }
                        else if (_compiler._lastExtractedLexem.Token == Token.OpenBracket)
                        {
                            _compiler.BuildIndexedAccess(waitingIdentifier);
                            currentState = STATE_OPERATOR_EXPECTED;
                            success      = true;
                        }
                        else if (_compiler._lastExtractedLexem.Token == Token.Dot)
                        {
                            _compiler.BuildPushVariable(waitingIdentifier);
                            int identifier;
                            _compiler.BuildResolveChain(out identifier);
                            _compiler.ProcessResolvedItem(identifier, stopToken);

                            if (_compiler._lastExtractedLexem.Type == LexemType.Operator || _compiler._lastExtractedLexem.Token == stopToken)
                            {
                                currentState = STATE_OPERATOR_EXPECTED;
                                continue;
                            }
                        }
                        else if (_compiler._lastExtractedLexem.Type == LexemType.Operator && IsBinaryOperator(_compiler._lastExtractedLexem.Token))
                        {
                            _compiler.BuildPushVariable(waitingIdentifier);
                            currentState = STATE_OPERATOR_EXPECTED;
                            continue;
                        }
                        else if (_compiler._lastExtractedLexem.Token == Token.ClosePar)
                        {
                            _compiler.BuildPushVariable(waitingIdentifier);
                            currentState = STATE_OPERATOR_EXPECTED;
                            continue;
                        }

                        break;

                    case STATE_OPERATOR_EXPECTED:
                        if (_compiler._lastExtractedLexem.Type == LexemType.Operator && IsBinaryOperator(_compiler._lastExtractedLexem.Token))
                        {
                            ProcessExpressionOperator();
                            currentState = STATE_OPERAND_EXPECTED;
                            success      = true;
                        }
                        else if (_compiler._lastExtractedLexem.Token == Token.ClosePar)
                        {
                            Token current;
                            parCount--;
                            if (parCount < 0)
                            {
                                UnwindOperators();
                                var cp = new CodePositionInfo();
                                cp.LineNumber = _compiler._parser.CurrentLine;
                                cp.Code       = _compiler._parser.GetCodeLine(cp.LineNumber);
                                throw new ExtraClosedParenthesis(cp);
                            }

                            if (_operators.Count > 0)
                            {
                                while ((current = PopOperator()) != Token.OpenPar)
                                {
                                    AddCommandForToken(current);
                                    if (_operators.Count == 0)
                                    {
                                        throw CompilerException.TokenExpected(Token.OpenPar);
                                    }
                                }

                                currentState = STATE_OPERATOR_EXPECTED;
                                success      = true;
                            }
                            else
                            {
                                throw CompilerException.TokenExpected(Token.OpenPar);
                            }
                        }
                        else if (_compiler._lastExtractedLexem.Token == Token.OpenBracket)
                        {
                            _compiler.NextToken();
                            _compiler.BuildExpression(Token.CloseBracket);
                            _compiler.AddCommand(OperationCode.PushIndexed, 0);
                            currentState = STATE_OPERATOR_EXPECTED;
                            success      = true;
                        }
                        else if (_compiler._lastExtractedLexem.Token == Token.Dot)
                        {
                            int identifier;
                            _compiler.BuildResolveChain(out identifier);
                            _compiler.ProcessResolvedItem(identifier, stopToken);

                            if (_compiler._lastExtractedLexem.Type == LexemType.Operator || _compiler._lastExtractedLexem.Token == stopToken)
                            {
                                currentState = STATE_OPERATOR_EXPECTED;
                                continue;
                            }
                        }
                        else if (_compiler._lastExtractedLexem.Token != stopToken)
                        {
                            throw CompilerException.TokenExpected(stopToken);
                        }
                        break;
                    }

                    if (success)
                    {
                        if (_compiler._lastExtractedLexem.Token != stopToken)
                        {
                            _compiler.NextToken();
                        }
                    }
                    else
                    {
                        throw CompilerException.ExpressionSyntax();
                    }
                }

                UnwindOperators();
            }
Beispiel #2
0
        public override Lexem ReadNextLexem(ParseIterator iterator)
        {
            bool isEndOfText = false;
            Char cs          = '\0';

            while (true)
            {
                if (!isEndOfText)
                {
                    cs = iterator.CurrentSymbol;
                }
                if (SpecialChars.IsDelimiter(cs) || isEndOfText)
                {
                    var content = iterator.GetContents().content;

                    Lexem lex;

                    if (_booleanOperators.Contains(content))
                    {
                        lex = new Lexem()
                        {
                            Type    = LexemType.Operator,
                            Token   = LanguageDef.GetToken(content),
                            Content = content
                        };
                    }
                    else if (_booleanLiterals.Contains(content))
                    {
                        lex = new Lexem()
                        {
                            Type    = LexemType.BooleanLiteral,
                            Content = content
                        };
                    }
                    else if (_undefined.Contains(content))
                    {
                        lex = new Lexem()
                        {
                            Type    = LexemType.UndefinedLiteral,
                            Content = content
                        };
                    }
                    else if (String.Compare(content, "null", true) == 0)
                    {
                        lex = new Lexem()
                        {
                            Type    = LexemType.NullLiteral,
                            Content = content
                        };
                    }
                    else
                    {
                        lex = new Lexem()
                        {
                            Type    = LexemType.Identifier,
                            Content = content,
                            Token   = LanguageDef.GetToken(content)
                        };

                        if (LanguageDef.IsBuiltInFunction(lex.Token))
                        {
                            iterator.SkipSpaces();
                            if (iterator.CurrentSymbol != '(')
                            {
                                lex.Token = Token.NotAToken;
                            }
                        }
                    }

                    return(lex);
                }

                if (!iterator.MoveNext())
                {
                    if (isEndOfText)
                    {
                        break;
                    }
                    else
                    {
                        isEndOfText = true;
                    }
                }
            }

            return(Lexem.Empty());
        }