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(); }
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()); }