private static string[] GetFrameworkEnum(string fullyQualifiedName) { if (frameworkEnums == null) { frameworkEnums = new Dictionary <string, string[]>(); TokenStream tokens = new TokenStream("enum data", Util.GetTextResource("TypeMetadata/FrameworkEnums.txt"), new Dictionary <string, bool>()); while (tokens.HasMore) { tokens.PopExpected("enum"); CSharpType name = CSharpType.Parse(tokens); tokens.PopExpected("{"); List <string> fields = new List <string>(); bool nextAllowed = true; while (!tokens.PopIfPresent("}")) { if (!nextAllowed) { tokens.PopExpected("}"); } fields.Add(tokens.PopWord().Value); nextAllowed = tokens.PopIfPresent(","); } frameworkEnums[name.RootTypeString] = fields.ToArray(); } } string[] output; return(frameworkEnums.TryGetValue(fullyQualifiedName, out output) ? output : null); }
private static TopLevelEntity ParseIndexProperty( ParserContext context, ClassLikeDefinition parent, Token firstToken, Dictionary <string, Token> modifiers, CSharpType type, TokenStream tokens) { tokens.PopExpected("["); CSharpType indexType = CSharpType.Parse(tokens); Token indexVariableName = tokens.PopWord(); tokens.PopExpected("]"); tokens.PopExpected("{"); PropertyDefinition indexProperty = new PropertyDefinition(firstToken, modifiers, type, null, parent); PropertyBody getter = null; PropertyBody setter = null; while (tokens.IsNext("get") || tokens.IsNext("set")) { Token getOrSetToken = tokens.Peek(); bool isGet = getOrSetToken.Value == "get"; if (!isGet && setter != null) { tokens.PopExpected("}"); // intentionally throw } if (isGet && getter != null) { tokens.PopExpected("set"); //intentionally throw } tokens.Pop(); // get/set already fetched with Peek() above. PropertyBody body = new PropertyBody(getOrSetToken, new Dictionary <string, Token>(), isGet, indexProperty); Executable[] code = ExecutableParser.ParseCodeBlock(context, tokens, body, true); body.Code = code; if (isGet) { getter = body; } else { setter = body; } } indexProperty.IndexType = indexType; indexProperty.IndexVariableName = indexVariableName; indexProperty.Getter = getter; indexProperty.Setter = setter; return(indexProperty); }
private static Executable ParseForEachLoop(ParserContext context, TokenStream tokens, TopLevelEntity parent) { Token foreachToken = tokens.PopExpected("foreach"); tokens.PopExpected("("); CSharpType type = CSharpType.Parse(tokens); Token variableToken = tokens.PopWord(); tokens.PopExpected("in"); Expression listExpression = ExpressionParser.Parse(context, tokens, parent); tokens.PopExpected(")"); Executable[] loopBody = ParseCodeBlock(context, tokens, parent, false); return(new ForEachLoop(foreachToken, type, variableToken, listExpression, loopBody, parent)); }
private static Executable ParseTryStatement(ParserContext context, TokenStream tokens, TopLevelEntity parent) { Token tryToken = tokens.PopExpected("try"); Executable[] tryCode = ExecutableParser.ParseCodeBlock(context, tokens, parent, true); List <Token> catchTokens = new List <Token>(); List <CSharpType> catchBlockTypes = new List <CSharpType>(); List <Token> catchBlockVariables = new List <Token>(); List <Executable[]> catchBlockCode = new List <Executable[]>(); Token finallyToken = null; Executable[] finallyCode = null; while (tokens.IsNext("catch")) { catchTokens.Add(tokens.Pop()); tokens.PopExpected("("); catchBlockTypes.Add(CSharpType.Parse(tokens)); if (!tokens.PopIfPresent(")")) { catchBlockVariables.Add(tokens.PopWord()); tokens.PopExpected(")"); } else { catchBlockVariables.Add(null); } catchBlockCode.Add(ParseCodeBlock(context, tokens, parent, true)); } if (tokens.IsNext("finally")) { finallyToken = tokens.Pop(); finallyCode = ParseCodeBlock(context, tokens, parent, true); } return(new TryStatement( tryToken, tryCode, catchTokens, catchBlockTypes, catchBlockVariables, catchBlockCode, finallyToken, finallyCode, parent)); }
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); }
private static Executable ParseUsingStatement(ParserContext context, TokenStream tokens, TopLevelEntity parent) { Token usingToken = tokens.PopExpected("using"); tokens.PopExpected("("); CSharpType type = null; Token variable = null; Token equalsToken = null; if (!tokens.IsNext("new")) { type = CSharpType.Parse(tokens); variable = tokens.PopWord(); equalsToken = tokens.PopExpected("="); } Expression expression = ExpressionParser.Parse(context, tokens, parent); tokens.PopExpected(")"); Executable[] code = ExecutableParser.ParseCodeBlock(context, tokens, parent, false); return(new UsingStatement(usingToken, type, variable, expression, code, parent)); }
private static void ParseArgList(List <CSharpType> typesOut, List <Token> namesOut, List <Token> modifiers, TokenStream tokens) { tokens.PopExpected("("); while (!tokens.IsNext(")")) { if (namesOut.Count > 0) { tokens.PopExpected(","); } if (tokens.IsNext("params") || tokens.IsNext("out")) { modifiers.Add(tokens.Pop()); } else { modifiers.Add(null); } typesOut.Add(CSharpType.Parse(tokens)); namesOut.Add(tokens.PopWord()); } tokens.PopExpected(")"); }
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); }