public BracketIndex(Expression root, Token openBracket, Expression index, TopLevelEntity parent) : base(root.FirstToken, parent) { this.Root = root; this.OpenBracket = openBracket; this.Index = index; }
protected override FunctionDefinition ParseFunction( TokenStream tokens, TopLevelEntity nullableOwner, FileScope fileScope, ModifierCollection modifiers, AnnotationCollection annotations) { AType returnType = this.parser.TypeParser.Parse(tokens); Token firstToken = modifiers.FirstToken ?? returnType.FirstToken; Token functionNameToken = tokens.Pop(); this.parser.VerifyIdentifier(functionNameToken); FunctionDefinition fd = new FunctionDefinition(firstToken, returnType, nullableOwner, functionNameToken, modifiers, annotations, fileScope); tokens.PopExpected("("); List <AType> argTypes = new List <AType>(); List <Token> argNames = new List <Token>(); List <Expression> defaultValues = new List <Expression>(); this.ParseArgumentListDeclaration(tokens, fd, argTypes, argNames, defaultValues); fd.ArgTypes = argTypes.ToArray(); fd.ArgNames = argNames.ToArray(); fd.DefaultValues = defaultValues.ToArray(); fd.FinalizeArguments(); IList <Executable> code = this.parser.ExecutableParser.ParseBlock(tokens, true, fd); fd.Code = code.ToArray(); return(fd); }
internal ClassDefinition DoClassLookup(Node fromWhere, Token nameToken, string name, bool failSilently) { TopLevelEntity ex = this.FileScopeEntityLookup.DoEntityLookup(name, fromWhere); if (ex == null) { if (failSilently) { return(null); } string message = "No class named '" + name + "' was found."; if (name.Contains(".")) { message += " Did you forget to import a library?"; } throw new ParserException(nameToken, message); } if (ex is ClassDefinition) { return((ClassDefinition)ex); } // Still throw an exception if the found item is not a class. This is used by code to check if // something is a valid variable name or a class name. Colliding with something else is bad. throw new ParserException(nameToken, "This is not a class."); }
private void BuildEntityMapImpl(TopLevelEntity tle, string prefix) { if (tle is ClassLikeDefinition) { string name = ((ClassLikeDefinition)tle).Name.Value; this.entityMap[prefix + name] = tle; ClassDefinition cd = tle as ClassDefinition; if (cd != null) { string nestedPrefix = prefix + name + "."; foreach (ClassLikeDefinition nestedClass in cd.NestedClasses) { this.BuildEntityMapImpl(nestedClass, nestedPrefix); } foreach (EnumDefinition enumDef in cd.NestedEnums) { this.BuildEntityMapImpl(enumDef, nestedPrefix); } } } else if (tle is EnumDefinition) { string name = ((EnumDefinition)tle).Name.Value; this.entityMap[prefix + name] = tle; } else { throw new System.NotImplementedException(); } }
public static TopLevelEntity Parse(ParserContext context, TokenStream tokens, TopLevelEntity parent) { TopLevelEntity tle = ParseImpl(context, tokens, parent); tle.FileContext = context.ActiveFileContext; return(tle); }
public StringConstant(Token firstToken, string actualValue, TopLevelEntity parent) : base(firstToken, parent) { if (firstToken.Value[0] == '\'') { throw new System.Exception(); } this.Value = Value; }
public CharConstant(Token firstToken, string value, TopLevelEntity parent) : base(firstToken, parent) { if (value.Length > 1) { throw new ParserException(firstToken, "This character is longer than 1 character."); } this.Value = value[0]; }
public StaticFrameworkClassReference(Token firstToken, TopLevelEntity parent, ResolvedType frameworkType) : base(firstToken, parent) { if (frameworkType.FrameworkClass == null) { throw new System.InvalidOperationException(); } this.ResolvedType = frameworkType; }
protected virtual Namespace ParseNamespace( TokenStream tokens, Node owner, FileScope fileScope, AnnotationCollection annotations) { Token namespaceToken = tokens.PopExpected(this.parser.Keywords.NAMESPACE); Token first = tokens.Pop(); this.parser.VerifyIdentifier(first); List <Token> namespacePieces = new List <Token>() { first }; string namespaceBuilder = first.Value; parser.RegisterNamespace(namespaceBuilder); while (tokens.PopIfPresent(".")) { Token nsToken = tokens.Pop(); this.parser.VerifyIdentifier(nsToken); namespacePieces.Add(nsToken); namespaceBuilder += "." + nsToken.Value; parser.RegisterNamespace(namespaceBuilder); } string name = string.Join(".", namespacePieces.Select <Token, string>(t => t.Value)); Namespace namespaceInstance = new Namespace(namespaceToken, name, owner, fileScope, ModifierCollection.EMPTY, annotations); tokens.PopExpected("{"); List <TopLevelEntity> namespaceMembers = new List <TopLevelEntity>(); while (!tokens.PopIfPresent("}")) { TopLevelEntity executable = this.Parse(tokens, namespaceInstance, fileScope); if (executable is FunctionDefinition || executable is ClassDefinition || executable is EnumDefinition || executable is ConstDefinition || executable is Namespace) { namespaceMembers.Add(executable); } else { throw new ParserException(executable, "Only function, class, and nested namespace declarations may exist as direct members of a namespace."); } } namespaceInstance.Code = namespaceMembers.ToArray(); return(namespaceInstance); }
public TernaryExpression( Expression condition, Token ternaryToken, Expression trueExpression, Expression falseExpression, TopLevelEntity parent) : base(condition.FirstToken, parent) { this.Condition = condition; this.TernaryToken = ternaryToken; this.TrueExpression = trueExpression; this.FalseExpression = falseExpression; }
internal void CompileTopLevelEntity(ParserContext parser, ByteBuffer buffer, TopLevelEntity entity) { if (entity is FunctionDefinition) { FunctionDefinitionEncoder.Compile(this, parser, buffer, (FunctionDefinition)entity, false); } else if (entity is ClassDefinition) { this.CompileClass(parser, buffer, (ClassDefinition)entity); } else { throw new NotImplementedException("Invalid target for byte code compilation"); } }
public void AddExecutable(TopLevelEntity executable) { if (executable is Namespace) { Namespace ns = (Namespace)executable; this.namespaceFlattener.AddNamespace(ns); foreach (TopLevelEntity tlc in ns.Code) { this.AddExecutable(tlc); } } else { this.executables.Add(executable); } }
internal void AddExecutable(TopLevelEntity entity) { if (entity is Namespace) { Namespace ns = (Namespace)entity; this.namespaceFlattener.AddNamespace(ns); foreach (TopLevelEntity tlc in ns.Code) { this.AddExecutable(tlc); } } else { this.entities.Add(entity); } }
private static TopLevelEntity ParseConstDefinition( ParserContext context, TopLevelEntity parent, Token firstToken, Dictionary <string, Token> modifiers, TokenStream tokens) { Token constToken = tokens.PopExpected("const"); CSharpType constType = CSharpType.Parse(tokens); Token name = tokens.PopWord(); tokens.PopExpected("="); ConstDefinition constDef = new ConstDefinition(firstToken, modifiers, constType, name, parent); Expression value = ExpressionParser.Parse(context, tokens, constDef); tokens.PopExpected(";"); constDef.Value = value; return(constDef); }
public static ClassLikeDefinition ParseClass(ParserContext context, TopLevelEntity parent, Token firstToken, Dictionary <string, Token> modifiers, TokenStream tokens) { if (!tokens.IsNext("class") && !tokens.IsNext("interface")) { tokens.PopExpected("class"); // intentionally throw } Token classToken = tokens.Pop(); bool isInterface = classToken.Value == "interface"; Token classNameToken = tokens.PopWord(); List <CSharpType> subClassesAndSuch = new List <CSharpType>(); if (tokens.PopIfPresent(":")) { while (!tokens.IsNext("{")) { if (subClassesAndSuch.Count > 0) { tokens.PopExpected(","); } subClassesAndSuch.Add(CSharpType.Parse(tokens)); } } tokens.PopExpected("{"); ClassLikeDefinition cd; if (isInterface) { cd = new InterfaceDefinition(firstToken, modifiers, classToken, classNameToken, subClassesAndSuch, parent); } else { cd = new ClassDefinition(firstToken, modifiers, classToken, classNameToken, subClassesAndSuch, parent); } while (!tokens.PopIfPresent("}")) { TopLevelEntity classMember = ParseClassMember(cd, classNameToken, context, tokens); cd.AddMember(classMember); } return(cd); }
public static Namespace ParseNamespace(ParserContext context, TopLevelEntity parent, TokenStream tokens) { Token namespaceToken = tokens.PopExpected("namespace"); List <Token> nsNameParts = new List <Token>(); nsNameParts.Add(tokens.PopWord()); while (tokens.IsNext(".")) { tokens.PopExpected("."); nsNameParts.Add(tokens.PopWord()); } Namespace ns = new Namespace(namespaceToken, nsNameParts, parent); tokens.PopExpected("{"); while (!tokens.PopIfPresent("}")) { TopLevelEntity tle = Parse(context, tokens, ns); ns.AddMember(tle); } return(ns); }
public void ParseFile(string fileName, string code) { this.ActiveFileContext = new FileContext(fileName); TokenStream tokens = new TokenStream( fileName, code, buildConstants); while (tokens.HasMore) { TopLevelEntity tle = TopLevelParser.Parse(this, tokens, null); if (tle is UsingDirective) { this.ActiveFileContext.AddUsing((UsingDirective)tle); } else { this.topLevelEntities.Add(tle); } } this.ActiveFileContext = null; }
// Generally this is used with the name resolver. So for example, you have a refernce to a ClassDefinition // instance from the resolver, but you want to turn it into a ClassReference instance. // TODO: put this in a method on these classes and implement an interface. The function signatures are all close enough. public static Expression ConvertStaticReferenceToExpression(TopLevelEntity item, Token primaryToken, Node owner) { Expression output = null; TopLevelEntity referencedEntity = null; if (item is ClassDefinition) { ClassDefinition classDef = (ClassDefinition)item; output = new ClassReference(primaryToken, classDef, owner); referencedEntity = classDef; } else if (item is EnumDefinition) { EnumDefinition enumDef = (EnumDefinition)item; output = new EnumReference(primaryToken, enumDef, owner); referencedEntity = enumDef; } else if (item is ConstDefinition) { ConstDefinition constDef = (ConstDefinition)item; output = new ConstReference(primaryToken, constDef, owner); referencedEntity = constDef; } else if (item is FunctionDefinition) { FunctionDefinition funcDef = (FunctionDefinition)item; output = new FunctionReference(primaryToken, funcDef, owner); referencedEntity = funcDef; } else { throw new InvalidOperationException(); } Node.EnsureAccessIsAllowed(primaryToken, owner, referencedEntity); return(output); }
private static void BuildAncestorLookupForClassImpl(string className, ParserContext parserContext, HashSet <string> lookup) { lookup.Add(className); if (FRAMEWORK_CLASSES_AND_PARENTS.ContainsKey(className)) { foreach (string parent in FRAMEWORK_CLASSES_AND_PARENTS[className]) { BuildAncestorLookupForClassImpl(parent, parserContext, lookup); } } else { TopLevelEntity tle = parserContext.DoLookup(className); if (tle is ClassLikeDefinition) { ClassLikeDefinition cd = (ClassLikeDefinition)tle; foreach (ResolvedType parentType in cd.ParentClasses) { if (parentType.CustomType != null) { BuildAncestorLookupForClassImpl(parentType.CustomType.FullyQualifiedName, parserContext, lookup); } else if (parentType.FrameworkClass != null) { BuildAncestorLookupForClassImpl(parentType.FrameworkClass, parserContext, lookup); } else { throw new System.NotImplementedException(); } } } else { throw new System.NotImplementedException(); } } }
internal ClassDefinition DoClassLookup(Node fromWhere, Token nameToken, string name, bool failSilently) { TopLevelEntity ex = this.FileScopeEntityLookup.DoEntityLookup(name, fromWhere); if (ex == null) { if (failSilently) { return(null); } string message = "No class named '" + name + "' was found."; if (name.Contains(".")) { string[] nameParts = name.Split('.'); string rootNamespace = nameParts[0]; object didTheyImportTheNamespace = this.FileScopeEntityLookup.DoLookupImpl(rootNamespace, fromWhere); if (didTheyImportTheNamespace == null) { message += " Did you forget to import a library?"; } else { message = "The namespace '" + rootNamespace + "' does not include a class named '" + (nameParts.Length == 2 ? nameParts[1] : name) + "'."; } } throw new ParserException(nameToken, message); } if (ex is ClassDefinition) { return((ClassDefinition)ex); } // Still throw an exception if the found item is not a class. This is used by code to check if // something is a valid variable name or a class name. Colliding with something else is bad. throw new ParserException(nameToken, "This is not a class."); }
protected override FunctionDefinition ParseFunction( TokenStream tokens, TopLevelEntity nullableOwner, FileScope fileScope, ModifierCollection modifiers, AnnotationCollection annotations) { bool isStatic = nullableOwner != null && nullableOwner is ClassDefinition && tokens.PopIfPresent(this.parser.Keywords.STATIC); Token functionToken = tokens.PopExpected(this.parser.Keywords.FUNCTION); Token functionNameToken = tokens.Pop(); this.parser.VerifyIdentifier(functionNameToken); FunctionDefinition fd = new FunctionDefinition(functionToken, AType.Any(functionToken), nullableOwner, functionNameToken, modifiers, annotations, fileScope); tokens.PopExpected("("); List <Token> argNames = new List <Token>(); List <Expression> defaultValues = new List <Expression>(); List <AType> argTypes = new List <AType>(); this.ParseArgumentListDeclaration(tokens, fd, argTypes, argNames, defaultValues); fd.ArgTypes = argTypes.ToArray(); fd.ArgNames = argNames.ToArray(); fd.DefaultValues = defaultValues.ToArray(); fd.FinalizeArguments(); IList <Executable> code = this.parser.ExecutableParser.ParseBlock(tokens, true, fd); fd.Code = code.ToArray(); return(fd); }
private static TopLevelEntity ParseEnumDefinition( ParserContext context, TopLevelEntity parent, Token firstToken, Dictionary <string, Token> modifiers, TokenStream tokens) { Token enumToken = tokens.PopExpected("enum"); Token enumName = tokens.PopWord(); List <Token> fieldNames = new List <Token>(); List <Expression> fieldValues = new List <Expression>(); tokens.PopExpected("{"); bool nextAllowed = true; EnumDefinition enumDef = new EnumDefinition(firstToken, modifiers, enumName, parent); while (!tokens.PopIfPresent("}")) { if (!nextAllowed) { tokens.PopExpected("}"); // intentionally throw } Token enumFieldName = tokens.PopWord(); Expression enumFieldValue = null; if (tokens.PopIfPresent("=")) { enumFieldValue = ExpressionParser.Parse(context, tokens, enumDef); } fieldNames.Add(enumFieldName); fieldValues.Add(enumFieldValue); nextAllowed = tokens.PopIfPresent(","); } enumDef.FieldNames = fieldNames.ToArray(); enumDef.FieldValues = fieldValues.ToArray(); return(enumDef); }
public IntegerConstant(Token firstToken, int value, TopLevelEntity parent) : base(firstToken, parent) { this.Value = value; }
private static Expression ParseEqualityComparison(ParserContext context, TokenStream tokens, TopLevelEntity parent) { Expression root = ParseInequalityComparison(context, tokens, parent); string next = tokens.PeekValue(); if (next == "==" || next == "!=") { List <Token> ops = new List <Token>() { tokens.Pop() }; List <Expression> expressions = new List <Expression>() { root, ParseInequalityComparison(context, tokens, parent) }; return(new OpChain(expressions, ops, parent)); } return(root); }
public static Expression Parse(ParserContext context, TokenStream tokens, TopLevelEntity parent) { return(ParseTernary(context, tokens, parent)); }
private static Expression ParseBitwiseOps(ParserContext context, TokenStream tokens, TopLevelEntity parent) { Expression root = ParseEqualityComparison(context, tokens, parent); string next = tokens.PeekValue(); if (next == "|" || next == "&" || next == "^") { List <Expression> expressions = new List <Expression>() { root }; List <Token> ops = new List <Token>(); while (tokens.IsNext("|") || tokens.IsNext("&") || tokens.IsNext("^")) { ops.Add(tokens.Pop()); expressions.Add(ParseEqualityComparison(context, tokens, parent)); } return(new OpChain(expressions, ops, parent)); } return(root); }
private static Expression ParseAtom(ParserContext context, TokenStream tokens, TopLevelEntity parent) { string next = tokens.PeekValue(); switch (next) { case "true": case "false": Token booleanToken = tokens.Pop(); return(new BooleanConstant(booleanToken, booleanToken.Value == "true", parent)); case "null": Token nullToken = tokens.Pop(); return(new NullConstant(nullToken, parent)); case "new": Token newToken = tokens.Pop(); CSharpType className = CSharpType.TryParse(tokens); if (className == null) { throw new ParserException(newToken, "'new' keyword must be followed by a className"); } if (!tokens.IsNext("(")) { // could be a new array of which there are two ways to define it... if (className.IsArray && tokens.IsNext("{")) { List <Expression> arrayItems = new List <Expression>(); tokens.PopExpected("{"); bool nextAllowed = true; while (!tokens.PopIfPresent("}")) { if (!nextAllowed) { tokens.PopExpected("}"); } arrayItems.Add(ExpressionParser.Parse(context, tokens, parent)); nextAllowed = tokens.PopIfPresent(","); } return(new ArrayInitialization(newToken, className.Generics[0], null, arrayItems, parent)); } if (tokens.IsNext("[")) { // a new array with specified length tokens.PopExpected("["); Expression arrayLength = ExpressionParser.Parse(context, tokens, parent); tokens.PopExpected("]"); return(new ArrayInitialization(newToken, className, arrayLength, null, parent)); } // if this isn't an array construction, then give a reasonable error message... tokens.PopExpected("("); } return(new ConstructorInvocationFragment(newToken, className, parent)); case "@": // raw string Token rawStringAt = tokens.Pop(); Token stringValue = tokens.Pop(); string stringValueActual = stringValue.Value; if (stringValueActual[0] != '"') { throw new ParserException(stringValue, "Expected a string value"); } return(new StringConstant(rawStringAt, stringValueActual.Substring(1, stringValueActual.Length - 2), parent)); default: break; } Token token = tokens.Pop(); char c = next[0]; if (c == '"' || c == '\'') { string stringValue = StringUtil.ConvertStringTokenToValue(token); if (c == '"') { return(new StringConstant(token, stringValue, parent)); } else { return(new CharConstant(token, stringValue, parent)); } } if (c == '0' && next.Length > 2 && next[1] == 'x') { string hex = next.Substring(2); int parsedValue = 0; for (int i = 0; i < hex.Length; ++i) { c = hex[i]; if (c >= '0' && c <= '9') { parsedValue = parsedValue * 16 + (c - '0'); } else if (c >= 'a' && c <= 'f') { parsedValue = parsedValue * 16 + (10 + c - 'a'); } else if (c >= 'A' && c <= 'F') { parsedValue = parsedValue * 16 + (10 + c - 'A'); } else { throw new ParserException(token, "Invalid hexidecimal value: '" + hex + "'"); } } return(new IntegerConstant(token, parsedValue, parent)); } if (c == '.' && next.Length > 1) { double value; if (!double.TryParse(next, out value)) { throw new ParserException(token, "Invalid double constant: '" + next + "'"); } return(new DoubleConstant(token, value, parent)); } if (c >= '0' && c <= '9') { if (next.Contains('.')) { if (next.EndsWith("f") || next.EndsWith("F")) { throw new NotImplementedException(); } double floatValue; if (!double.TryParse(next, out floatValue)) { throw new ParserException(token, "Invalid number: '" + next + "'"); } return(new DoubleConstant(token, floatValue, parent)); } else { if (next.EndsWith("f") || next.EndsWith("F")) { throw new NotImplementedException(); } int intValue; if (!int.TryParse(next, out intValue)) { throw new ParserException(token, "Invalid number: '" + next + "'"); } return(new IntegerConstant(token, intValue, parent)); } } if ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || c == '_') { if (tokens.IsNext("=>")) { List <Token> args = new List <Token>() { token }; Token arrowToken = tokens.Pop(); Executable[] lambdaBody; if (tokens.IsNext("{")) { lambdaBody = ExecutableParser.ParseCodeBlock(context, tokens, parent, true); } else { Expression lambdaBodyExpr = Parse(context, tokens, parent); lambdaBody = new Executable[] { new ReturnStatement(lambdaBodyExpr.FirstToken, lambdaBodyExpr, parent), }; } return(new Lambda(token, args, arrowToken, lambdaBody, parent)); } return(new Variable(token, parent)); } throw new ParserException(token, "Unexpected token: '" + token.Value + "'"); }
private static Expression ParseAtomWithSuffix(ParserContext context, TokenStream tokens, TopLevelEntity parent) { Expression root; if (tokens.IsNext("(")) { Token openParen = tokens.Pop(); switch (IdentifyParenthesisSituation(tokens)) { case ParenthesisSituation.CAST: CSharpType castType = CSharpType.Parse(tokens); tokens.PopExpected(")"); Expression castValue = ParseAtomWithSuffix(context, tokens, parent); return(new CastExpression(openParen, castType, castValue, parent)); case ParenthesisSituation.LAMBDA_ARG: List <Token> lambdaArgs = new List <Token>() { tokens.PopWord() }; while (tokens.PopIfPresent(",")) { lambdaArgs.Add(tokens.PopWord()); } tokens.PopExpected(")"); Token arrowToken = tokens.PopExpected("=>"); Executable[] lambdaBody; if (tokens.IsNext("{")) { lambdaBody = ExecutableParser.ParseCodeBlock(context, tokens, parent, true); } else { Expression expr = Parse(context, tokens, parent); lambdaBody = new Executable[] { new ReturnStatement(expr.FirstToken, expr, parent) }; } return(new Lambda(openParen, lambdaArgs, arrowToken, lambdaBody, parent)); case ParenthesisSituation.WRAPPED_EXPRESSION: root = Parse(context, tokens, parent); tokens.PopExpected(")"); break; default: throw new Exception(); // not valid } } else { root = ParseAtom(context, tokens, parent); } bool anythingInteresting = true; string next = tokens.PeekValue(); while (anythingInteresting) { switch (next) { case ".": Token dotToken = tokens.Pop(); Token fieldName = tokens.PopWord(); root = new DotField(root.FirstToken, root, dotToken, fieldName, parent); break; case "[": Token openBracket = tokens.Pop(); Expression index = Parse(context, tokens, parent); tokens.PopExpected("]"); root = new BracketIndex(root, openBracket, index, parent); break; case "<": if (root is DotField) { CSharpType[] functionInvocationTypeSpecification = MaybeParseOutOneOfThoseInlineTypeSpecificationsForFunctionInvocations(tokens); if (functionInvocationTypeSpecification != null) { ((DotField)root).InlineTypeSpecification = functionInvocationTypeSpecification; } else { anythingInteresting = false; } } else { anythingInteresting = false; } break; case "(": Token openParen = tokens.Pop(); List <Expression> args = new List <Expression>(); List <Token> outTokens = new List <Token>(); while (!tokens.PopIfPresent(")")) { if (args.Count > 0) { tokens.PopExpected(","); } if (tokens.IsNext("out")) { outTokens.Add(tokens.Pop()); } else { outTokens.Add(null); } args.Add(Parse(context, tokens, parent)); } root = new FunctionInvocation(root.FirstToken, root, openParen, args, outTokens, parent); break; case "{": // e.g. new List<int>() { 1, 2, 3 }. This only follows a constructor. FunctionInvocation fi = root as FunctionInvocation; ConstructorInvocationFragment cif = fi == null ? null : (ConstructorInvocationFragment)fi.Root; if (root is FunctionInvocation && ((FunctionInvocation)root).Root is ConstructorInvocationFragment) { tokens.Pop(); // { ConstructorSuffixData format = DetermineConstructorSuffixDataFormat(tokens); bool nextAllowed = true; List <Expression> values = new List <Expression>(); List <Expression> kvpKeys = new List <Expression>(); List <Token> propertyNames = new List <Token>(); while (!tokens.PopIfPresent("}")) { if (!nextAllowed) { tokens.PopExpected("}"); // intentionally throw } switch (format) { case ConstructorSuffixData.KVP_ENTRIES: tokens.PopExpected("{"); kvpKeys.Add(Parse(context, tokens, parent)); tokens.PopExpected(","); values.Add(Parse(context, tokens, parent)); tokens.PopExpected("}"); break; case ConstructorSuffixData.PROPERTIES: propertyNames.Add(tokens.PopWord()); tokens.PopExpected("="); values.Add(Parse(context, tokens, parent)); break; case ConstructorSuffixData.SEQUENTIAL_ITEMS: values.Add(Parse(context, tokens, parent)); break; } nextAllowed = tokens.PopIfPresent(","); } cif.InitialDataValues = values.ToArray(); int t = cif.InitialDataValues.Length; if (kvpKeys.Count == t) { cif.InitialDataKeys = kvpKeys.ToArray(); } if (propertyNames.Count == t) { cif.InitialDataPropertyNames = propertyNames.ToArray(); } } else { throw new ParserException(tokens.Peek(), "Unexpected '{'"); } break; default: anythingInteresting = false; break; } next = tokens.PeekValue(); } if (next == "++" || next == "--") { Token incrementToken = tokens.Pop(); root = new InlineIncrement(root.FirstToken, incrementToken, false, root, parent); } return(root); }
private static Expression ParseNullCoalescer(ParserContext context, TokenStream tokens, TopLevelEntity parent) { Expression root = ParseBooleanCombination(context, tokens, parent); if (tokens.IsNext("??")) { List <Expression> expressions = new List <Expression>() { root }; List <Token> ops = new List <Token>(); while (tokens.IsNext("??")) { ops.Add(tokens.Pop()); expressions.Add(ParseBooleanCombination(context, tokens, parent)); } return(new OpChain(expressions, ops, parent)); } return(root); }
private static Expression ParseUnary(ParserContext context, TokenStream tokens, TopLevelEntity parent) { string next = tokens.PeekValue(); if (next == "!" || next == "-" || next == "--" || next == "++") { Token unaryToken = tokens.Pop(); Expression root = ParseAtomWithSuffix(context, tokens, parent); switch (next) { case "!": return(new BooleanNot(unaryToken, root, parent)); case "-": return(new NegativeSign(unaryToken, root, parent)); case "++": case "--": return(new InlineIncrement(unaryToken, unaryToken, true, root, parent)); default: throw new NotImplementedException(); } } return(ParseAtomWithSuffix(context, tokens, parent)); }