protected Executable ParseFor(TokenStream tokens, Node owner) { Token forToken = tokens.PopExpected(this.parser.Keywords.FOR); tokens.PopExpected("("); tokens.EnsureNotEof(); if (this.IsForEachLoopParenthesisContents(tokens)) { Pair <AType, Token> iteratorVariable = this.ParseForEachLoopIteratorVariable(tokens, owner); AType iteratorVariableType = iteratorVariable.First; Token iteratorToken = iteratorVariable.Second; tokens.PopExpected(":"); Expression iterationExpression = this.parser.ExpressionParser.Parse(tokens, owner); tokens.PopExpected(")"); IList <Executable> body = this.ParseBlock(tokens, false, owner); return(new ForEachLoop(forToken, iteratorVariableType, iteratorVariable.Second, iterationExpression, body, owner)); } else { ForLoopComponents parts = this.ParseForLoopComponents(tokens, owner); IList <Executable> body = this.ParseBlock(tokens, false, owner); return(new ForLoop(forToken, parts.Init, parts.Condition, parts.Step, body, owner)); } }
public virtual AType Parse(TokenStream tokens) { tokens.EnsureNotEof(); Token throwToken = tokens.Peek(); AType type = this.TryParse(tokens); if (type == null) { throw new ParserException(throwToken, "Type name expected"); } return(type); }
private Expression ParseEntityWithoutSuffixChain(TokenStream tokens, Node owner) { tokens.EnsureNotEof(); Token nextToken = tokens.Peek(); string next = nextToken.Value; if (next == this.parser.Keywords.NULL) { return(new NullConstant(tokens.Pop(), owner)); } if (next == this.parser.Keywords.TRUE) { return(new BooleanConstant(tokens.Pop(), true, owner)); } if (next == this.parser.Keywords.FALSE) { return(new BooleanConstant(tokens.Pop(), false, owner)); } if (next == this.parser.Keywords.THIS) { return(new ThisKeyword(tokens.Pop(), owner)); } if (next == this.parser.Keywords.BASE) { return(new BaseKeyword(tokens.Pop(), owner)); } Token peekToken = tokens.Peek(); if (next.StartsWith("'")) { return(new StringConstant(tokens.Pop(), StringConstant.ParseOutRawValue(peekToken), owner)); } if (next.StartsWith("\"")) { return(new StringConstant(tokens.Pop(), StringConstant.ParseOutRawValue(peekToken), owner)); } if (next == "@") // Raw strings (no escape sequences, a backslash is a literal backslash) { Token atToken = tokens.Pop(); Token stringToken = tokens.Pop(); char stringTokenChar = stringToken.Value[0]; if (stringTokenChar != '"' && stringTokenChar != '\'') { throw new ParserException(atToken, "Unexpected token: '@'"); } string stringValue = stringToken.Value.Substring(1, stringToken.Value.Length - 2); return(new StringConstant(atToken, stringValue, owner)); } if (next == this.parser.Keywords.NEW) { return(this.ParseInstantiate(tokens, owner)); } char firstChar = next[0]; if (nextToken.Type == TokenType.WORD) { Token varToken = tokens.Pop(); if (tokens.IsNext("=>")) { return(this.ParseLambda( tokens, varToken, new AType[] { AType.Any() }, new Token[] { varToken }, owner)); } else { return(new Variable(varToken, varToken.Value, owner)); } } if (firstChar == '[' && nextToken.File.CompilationScope.IsCrayon) { Token bracketToken = tokens.PopExpected("["); List <Expression> elements = new List <Expression>(); bool previousHasCommaOrFirst = true; while (!tokens.PopIfPresent("]")) { if (!previousHasCommaOrFirst) { tokens.PopExpected("]"); // throws appropriate error } elements.Add(Parse(tokens, owner)); previousHasCommaOrFirst = tokens.PopIfPresent(","); } return(new ListDefinition(bracketToken, elements, AType.Any(), owner, false, null)); } if (firstChar == '{' && nextToken.File.CompilationScope.IsCrayon) { Token braceToken = tokens.PopExpected("{"); List <Expression> keys = new List <Expression>(); List <Expression> values = new List <Expression>(); bool previousHasCommaOrFirst = true; while (!tokens.PopIfPresent("}")) { if (!previousHasCommaOrFirst) { tokens.PopExpected("}"); // throws appropriate error } keys.Add(Parse(tokens, owner)); tokens.PopExpected(":"); values.Add(Parse(tokens, owner)); previousHasCommaOrFirst = tokens.PopIfPresent(","); } return(new DictionaryDefinition(braceToken, AType.Any(), AType.Any(), keys, values, owner)); } if (nextToken.Type == TokenType.NUMBER) { if (next.Contains(".")) { double floatValue; if (double.TryParse(next, out floatValue)) { return(new FloatConstant(tokens.Pop(), floatValue, owner)); } throw new ParserException(nextToken, "Invalid float literal."); } return(new IntegerConstant( tokens.Pop(), IntegerConstant.ParseIntConstant(nextToken, next), owner)); } throw new ParserException(tokens.Peek(), "Encountered unexpected token: '" + tokens.PeekValue() + "'"); }