public StdSimpleCallNode(Loyc.Syntax.Lexing.Token targetToken, RVList <LNode> args, SourceRange range, NodeStyle style = NodeStyle.Default) : base(args, range, style) { _name = (Symbol)(targetToken.Value ?? GSymbol.Empty); _targetOffs = ClipUShort(targetToken.StartIndex - RAS.StartIndex); _targetLen = ClipUShort(targetToken.Length); }
static RVList <LNode> Replace(RVList <LNode> stmts, Pair <LNode, LNode>[] patterns) { var temp = new MMap <Symbol, LNode>(); var output = stmts.SmartSelect(stmt => stmt.ReplaceRecursive(n => TryReplaceHere(n, patterns, temp))); return(output); }
public void ScanClassBody(RVList<LNode> body) { foreach (var stmt in body) { int i; { LNode altName; RVList<LNode> attrs, childBody = default(RVList<LNode>), parts, rest; if ((attrs = stmt.Attrs).IsEmpty | true && stmt.Calls(CodeSymbols.Fn, 3) && stmt.Args[0].IsIdNamed((Symbol) "alt") && (altName = stmt.Args[1]) != null && stmt.Args[2].Calls(CodeSymbols.AltList) && (parts = stmt.Args[2].Args).IsEmpty | true || (attrs = stmt.Attrs).IsEmpty | true && stmt.Calls(CodeSymbols.Fn, 4) && stmt.Args[0].IsIdNamed((Symbol) "alt") && (altName = stmt.Args[1]) != null && stmt.Args[2].Calls(CodeSymbols.AltList) && (parts = stmt.Args[2].Args).IsEmpty | true && stmt.Args[3].Calls(CodeSymbols.Braces) && (childBody = stmt.Args[3].Args).IsEmpty | true) { LNode genericAltName = altName; if (altName.CallsMin(CodeSymbols.Of, 1)) { } else if (_genericArgs.Count > 0) genericAltName = LNode.Call(CodeSymbols.Of, new RVList<LNode>().Add(altName).AddRange(_genericArgs)); var child = new AltType(attrs, genericAltName, LNode.List(), this); child.AddParts(parts); child.ScanClassBody(childBody); _children.Add(child); } else if ((attrs = stmt.Attrs).IsEmpty | true && (i = attrs.IndexWhere(a => a.IsIdNamed(__alt))) > -1 && stmt.CallsMin(CodeSymbols.Cons, 3) && stmt.Args[1].IsIdNamed((Symbol) "#this") && stmt.Args[2].Calls(CodeSymbols.AltList) && (rest = new RVList<LNode>(stmt.Args.Slice(3))).IsEmpty | true && rest.Count <= 1) { parts = stmt.Args[2].Args; attrs.RemoveAt(i); _constructorAttrs.AddRange(attrs); if (rest.Count > 0 && rest[0].Calls(S.Braces)) _extraConstrLogic.AddRange(rest[0].Args); AddParts(parts); } else _classBody.Add(stmt); } } }
protected virtual LNode MakeSuperExpr(LNode lhs, ref LNode primary, RVList <LNode> rhs) { if (primary == null) { return(lhs); // an error should have been printed already } if (lhs == primary) { if (primary.BaseStyle == NodeStyle.Operator) { primary = F.Call(primary, rhs); } else { primary = lhs.WithArgs(lhs.Args.AddRange(rhs)); } MarkSpecial(primary); return(primary); } else { Debug.Assert(lhs != null && lhs.IsCall && lhs.ArgCount > 0); Debug.Assert(lhs.BaseStyle != NodeStyle.Special); int c = lhs.ArgCount - 1; LNode ce = MakeSuperExpr(lhs.Args[c], ref primary, rhs); return(lhs.WithArgChanged(c, ce)); } }
static LNode MaybeQuoteList(RVList <LNode> list, bool substitutions) { if (list.IsEmpty) { return(null); } else if (substitutions && list.Any(a => VarArgExpr(a) != null)) { if (list.Count == 1) { return(F.Call(S.New, F.Call(F.Of(F.Id("RVList"), F.Id("LNode")), VarArgExpr(list[0])))); } // If you write something like quote(Foo($x, $(..y), $z)), a special // output style is used to accommodate the variable argument list. LNode argList = F.Call(S.New, F.Call(F.Of(F.Id("RVList"), F.Id("LNode")))); foreach (LNode arg in list) { var vae = VarArgExpr(arg); if (vae != null) { argList = F.Call(F.Dot(argList, F.Id("AddRange")), vae); } else { argList = F.Call(F.Dot(argList, F.Id("Add")), QuoteOne(arg, substitutions)); } } return(argList); } else { return(F.Call(LNode_List, list.Select(item => QuoteOne(item, substitutions)))); } }
/// <summary>Searches a list of expressions/statements for one or more /// patterns, and performs replacements.</summary> /// <param name="stmts">A list of expressions/statements in which to search.</param> /// <param name="patterns">Each pair consists of (A) something to search /// for and (B) a replacement expression. Part A can use the substitution /// operator with an identifier inside (e.g. $Foo) to "capture" any /// subexpression, and part B can use the same substitution (e.g. $Foo) /// to insert the captured subexpression(s) into the output.</param> /// <param name="replacementCount">Number of replacements that occurred.</param> /// <returns>The result of applying the replacements.</returns> /// <remarks><see cref="LNodeExt.MatchesPattern"/> is used for matching.</remarks> public static RVList <LNode> Replace(RVList <LNode> stmts, Pair <LNode, LNode>[] patterns, out int replacementCount) { // This list is used to support simple token replacement in TokenTrees _tokenTreeRepls = InternalList <Triplet <Symbol, LNode, int> > .Empty; foreach (var pair in patterns) // Look for Id => Id or Id => Literal { if (pair.A.IsId && (pair.B.IsId || pair.B.IsLiteral)) { _tokenTreeRepls.Add(new Triplet <Symbol, LNode, int>(pair.A.Name, pair.B, 0)); } } // Scan the syntax tree for things to replace... int count = 0; var temp = new MMap <Symbol, LNode>(); var output = stmts.SmartSelect(stmt => stmt.ReplaceRecursive(n => { LNode r = TryReplaceHere(n, patterns, temp); if (r != null) { count++; } return(r); })); replacementCount = count; return(output); }
public static LNode static_if(LNode @if, IMessageSink sink) { if (!MathEx.IsInRange(@if.ArgCount, 2, 3)) { return(null); } RVList <LNode> conds = MacroProcessor.Current.ProcessSynchronously(@if.Args[0]); object @bool; if (conds.Count == 1 && (@bool = conds[0].Value) is bool) { LNode output = (bool)@bool ? @if.Args[1] : @if.Args.TryGet(2, null) ?? F.Call(S.Splice); if (output.Calls(S.Braces)) { return(output.WithTarget(S.Splice)); } else { return(output); } } else { return(Reject(sink, @if.Args[0], "'static if' is incredibly limited right now. Currently it only supports a literal boolean or (x `tree==` y)")); } }
static bool MatchThenParams(RVList <LNode> cArgs, RVList <LNode> pArgs, LNode paramsCap, ref MMap <Symbol, LNode> captures, ref RVList <LNode> attrs) { // This helper function of MatchesPattern() is called when pArgs is followed // by a $(params capture). cArgs is the list of candidate.Args that have not // yet been matched; pArgs is the list of pattern.Args that have not yet been // matched, and paramsCap is the $(params capture) node that follows pArgs. captures = captures ?? new MMap <Symbol, LNode>(); int c = 0, p = 0; restart: for (; p < pArgs.Count; p++, c++) { if (IsParamsCapture(pArgs[p])) { if (!CaptureGroup(ref c, ref p, cArgs, pArgs, ref captures, ref attrs)) { return(false); } goto restart; } else { if (c >= cArgs.Count) { return(false); } if (!MatchesPatternNested(cArgs[c], pArgs[p], ref captures, ref attrs)) { return(false); } } } AddCapture(captures, paramsCap, new Slice_ <LNode>(cArgs, c)); return(true); }
public DescendantsFrame(LNode node, NodeScanMode mode) { _node = node; _mode = mode; _children = RVList <LNode> .Empty; _step = _index = 0; }
/// <summary>Decodes options in the format <c>option1(v1), option2(v2)</c> /// or <c>option1 = v1, option2 = v2</c>. If the format of a given /// node is invalid, this function yields <c>(null, node)</c>.</summary> static IEnumerable <KeyValuePair <Symbol, LNode> > DecodeOptions(RVList <LNode> optionList) { foreach (var option in optionList) { Symbol key; LNode value; if (option.ArgCount == 1 || option.Calls(S.NamedArg, 2) || option.Calls(S.Assign, 2)) { value = option.Args.Last; if (option.ArgCount == 1) { key = option.Name; } else { key = option.Args[0].Name; } yield return(new KeyValuePair <Symbol, LNode>(key, value)); } else { yield return(new KeyValuePair <Symbol, LNode>(null, option)); } } }
public void AddParts(RVList <LNode> parts) { foreach (var part in parts) { Parts.Add(new AdtParam(part, this)); } }
public static bool MatchesPattern(LNode candidate, LNode pattern, out MMap <Symbol, LNode> captures) { RVList <LNode> unmatchedAttrs = RVList <LNode> .Empty; captures = null; return(MatchesPattern(candidate, pattern, ref captures, out unmatchedAttrs)); }
RVList <LNode> ApplyMacrosToList(RVList <LNode> list, int maxExpansions) { RVList <LNode> results = list; LNode result = null; int i, c; // Share as much of the original RVList as is left unchanged for (i = 0, c = list.Count; i < c; i++) { if ((result = ApplyMacros(list[i], maxExpansions)) != null || (result = list[i]).Calls(S.Splice)) { results = list.WithoutLast(c - i); Add(ref results, result); break; } } // Prepare a modified list from now on for (i++; i < c; i++) { LNode input = list[i]; if ((result = ApplyMacros(input, maxExpansions)) != null) { Add(ref results, result); } else { results.Add(input); } } return(results); }
public override CallNode WithArgs(RVList <LNode> args) { var copy = cov_Clone(); copy._args = args; return(copy); }
public LNode Call(Token target, RVList <LNode> args, int startIndex = -1, int endIndex = -1) { if (endIndex < startIndex) { endIndex = startIndex; } return(new StdSimpleCallNode(target, args, new SourceRange(_file, startIndex, endIndex - startIndex))); }
public RVList <LNode> StmtList() { RVList <LNode> result = default(RVList <LNode>); var endMarker = TT.Semicolon; result = ExprList(ref endMarker); return(result); }
public Transition(Pred prevPosition, IPGTerminalSet set, RVList <AndPred> andPreds, GrammarPos position) { PrevPosition = prevPosition; Debug.Assert(position != null); Set = set; Position = position; AndPreds = andPreds; }
public LNode Tuple(RVList <LNode> contents, int startIndex = -1, int endIndex = -1) { if (endIndex < startIndex) { endIndex = startIndex; } return(new StdSimpleCallNode(S.Tuple, contents, new SourceRange(_file, startIndex, endIndex - startIndex))); }
public LNode Call(string target, RVList <LNode> args, int startIndex = -1, int endIndex = -1) { if (endIndex < startIndex) { endIndex = startIndex; } return(Call(GSymbol.Get(target), args, startIndex, endIndex)); }
public override LNode WithAttrs(RVList <LNode> attrs) { if (attrs.Count == 0) { return(this); } throw new NotImplementedException(); }
public override LNode WithAttrs(RVList <LNode> attrs) { if (attrs.Count == 0) { return(this); } return(new StdLiteralNodeWithAttrs(attrs, _value, this)); }
public override LNode WithAttrs(RVList <LNode> attrs) { if (attrs.Count == 0) { return(this); } return(new StdIdNodeWithAttrs(attrs, _name, this)); }
public override LNode WithAttrs(RVList <LNode> attrs) { if (attrs.Count == 0) { return(this); } return(new StdSimpleCallNodeWithAttrs(attrs, _name, _args, this)); }
public override LNode WithAttrs(RVList <LNode> attrs) { if (attrs.Count == 0) { return(this); } return(new StdComplexCallNodeWithAttrs(attrs, _target, _args, this)); }
protected override void WriteOutput(InputOutput io) { Results = io.Output; Output = new StringBuilder(); foreach (LNode node in Results) { LNode.Printer(node, Output, Sink, null, IndentString, NewlineString); Output.Append(NewlineString); } }
public RVList<LNode> ExprList(ref TokenType endMarker, RVList<LNode> list = default(RVList<LNode>)) { TT la0; LNode e = default(LNode); Token end = default(Token); // line 57 if ((LT0.Value is string)) { endMarker = TT.EOF; } // Line 1: ( / TopExpr) switch ((TT) LA0) { case EOF: case TT.Comma: case TT.Dedent: case TT.RBrace: case TT.RBrack: case TT.RParen: case TT.Semicolon: { } break; default: e = TopExpr(); break; } // Line 59: ((TT.Comma|TT.Semicolon) ( / TopExpr))* for (;;) { la0 = (TT) LA0; if (la0 == TT.Comma || la0 == TT.Semicolon) { end = MatchAny(); list.Add(e ?? MissingExpr()); CheckEndMarker(ref endMarker, ref end); // Line 62: ( / TopExpr) switch ((TT) LA0) { case EOF: case TT.Comma: case TT.Dedent: case TT.RBrace: case TT.RBrack: case TT.RParen: case TT.Semicolon: // line 62 e = null; break; default: e = TopExpr(); break; } } else break; } if ((e != null || end.Type() == TT.Comma)) { list.Add(e ?? MissingExpr()); } return list; }
public static LNode use_symbols(LNode input, IMacroContext context) { var args_body = context.GetArgsAndBody(true); // Decode options (TODO: invent a simpler approach) string prefix = "sy_"; var inherited = new HashSet <Symbol>(); foreach (var pair in MacroContext.GetOptions(args_body.A)) { if (pair.Key.Name == "prefix" && pair.Value.IsId) { prefix = pair.Value.Name.Name; } else if (pair.Key.Name == "inherit" && pair.Value.Value is Symbol) { inherited.Add((Symbol)pair.Value.Value); } else if (pair.Key.Name == "inherit" && (pair.Value.Calls(S.Braces) || pair.Value.Calls(S.Tuple)) && pair.Value.Args.All(n => n.Value is Symbol)) { foreach (var arg in pair.Value.Args) { inherited.Add((Symbol)arg.Value); } } else { context.Sink.Write(Severity.Warning, pair.Value, "Unrecognized parameter. Expected prefix:id or inherit:{@@A; @@B; ...})"); } } // Replace all symbols while collecting a list of them var symbols = new Dictionary <Symbol, LNode>(); RVList <LNode> output = args_body.B.SmartSelect(stmt => stmt.ReplaceRecursive(n => { var sym = n.Value as Symbol; if (n.IsLiteral && sym != null) { return(symbols[sym] = LNode.Id(prefix + Ecs.EcsNodePrinter.SanitizeIdentifier(sym.Name))); } return(null); })); // Return updated code with variable declaration at the top for all non-inherit symbols used. var _Symbol = F.Id("Symbol"); var vars = (from sym in symbols where !inherited.Contains(sym.Key) select F.Call(S.Assign, sym.Value, F.Call(S.Cast, F.Literal(sym.Key.Name), _Symbol))).ToList(); if (vars.Count > 0) { output.Insert(0, F.Call(S.Var, Range.Single(_Symbol).Concat(vars)) .WithAttrs(input.Attrs.Add(F.Id(S.Static)).Add(F.Id(S.Readonly)))); } return(F.Call(S.Splice, output)); }
/// <summary>Converts this list of <see cref="Token"/> to a list of <see cref="LNode"/>.</summary> /// <remarks>See <see cref="Token.ToLNode(ISourceFile)"/> for more information.</remarks> public RVList <LNode> ToLNodes() { RVList <LNode> list = RVList <LNode> .Empty; foreach (var item in (DList <Token>) this) { list.Add(item.ToLNode(File)); } return(list); }
public override LNode WithArgs(Func <LNode, Maybe <LNode> > selector) { RVList <LNode> args = Args, newArgs = args.WhereSelect(selector); if (args == newArgs) { return(this); } return(WithArgs(newArgs)); }
// Restructures an RVList if it has degraded severely. Time: O(Count) void AutoOptimize <T>(ref RVList <T> v) { // Check if the chain length substantially exceeds Sqrt(v.Count) if ((v.BlockChainLength - 10) * (v.BlockChainLength - 10) > v.Count) { RWList <T> w = v.ToRWList(); // This is basically a no-op w[0] = w[0]; // Restructure & make mutable v = w.ToRVList(); // Mark immutable again } }
public static RVList <LNode> WithSpliced(this RVList <LNode> list, LNode node, Symbol listName) { if (node.Calls(listName)) { return(list.AddRange(node.Args)); } else { return(list.Add(node)); } }
public static RVList <LNode> WithSpliced(this RVList <LNode> list, int index, LNode node, Symbol listName) { if (node.Calls(listName)) { return(list.InsertRange(index, node.Args)); } else { return(list.Insert(index, node)); } }
public AltType(RVList<LNode> typeAttrs, LNode typeName, RVList<LNode> baseTypes, AltType parentType) { _typeAttrs = typeAttrs; TypeName = typeName; BaseTypes = baseTypes; ParentType = parentType; if (ParentType != null) BaseTypes.Add(ParentType.TypeName); { LNode stem; RVList<LNode> a = default(RVList<LNode>); if (TypeName.CallsMin(CodeSymbols.Of, 1) && (stem = TypeName.Args[0]) != null && (a = new RVList<LNode>(TypeName.Args.Slice(1))).IsEmpty | true || (stem = TypeName) != null) { _typeNameStem = stem; _genericArgs = a; } } }
/// <summary>Searches a list of expressions/statements for one or more /// patterns, and performs replacements.</summary> /// <param name="stmts">A list of expressions/statements in which to search.</param> /// <param name="patterns">Each pair consists of (A) something to search /// for and (B) a replacement expression. Part A can use the substitution /// operator with an identifier inside (e.g. $Foo) to "capture" any /// subexpression, and part B can use the same substitution (e.g. $Foo) /// to insert the captured subexpression(s) into the output.</param> /// <param name="replacementCount">Number of replacements that occurred.</param> /// <returns>The result of applying the replacements.</returns> /// <remarks><see cref="LNodeExt.MatchesPattern"/> is used for matching.</remarks> public static RVList<LNode> Replace(RVList<LNode> stmts, Pair<LNode, LNode>[] patterns, out int replacementCount) { // This list is used to support simple token replacement in TokenTrees _tokenTreeRepls = InternalList<Triplet<Symbol, LNode, int>>.Empty; foreach (var pair in patterns) // Look for Id => Id or Id => Literal if (pair.A.IsId && (pair.B.IsId || pair.B.IsLiteral)) _tokenTreeRepls.Add(new Triplet<Symbol,LNode,int>(pair.A.Name, pair.B, 0)); // Scan the syntax tree for things to replace... int count = 0; var temp = new MMap<Symbol, LNode>(); var output = stmts.SmartSelect(stmt => stmt.ReplaceRecursive(n => { LNode r = TryReplaceHere(n, patterns, temp); if (r != null) count++; return r; })); replacementCount = count; return output; }
[LexicalMacro("e.g. alt class Tree<T> { alt Node(Tree<T> Left, Tree<T> Right); alt Leaf(T Value); }", "Expands a short description of an 'algebraic data type' into a set of classes with a common base class.", "#class", Mode = MacroMode.Passive | MacroMode.Normal)] public static LNode AlgebraicDataType(LNode classDecl, IMacroContext context) { int i; { LNode baseName; RVList<LNode> attrs, baseTypes, body; if ((attrs = classDecl.Attrs).IsEmpty | true && (i = attrs.IndexWhere(a => a.IsIdNamed(__alt))) > -1 && classDecl.Calls(CodeSymbols.Class, 3) && (baseName = classDecl.Args[0]) != null && classDecl.Args[1].Calls(CodeSymbols.AltList) && classDecl.Args[2].Calls(CodeSymbols.Braces)) { baseTypes = classDecl.Args[1].Args; body = classDecl.Args[2].Args; attrs = attrs.RemoveAt(i); var adt = new AltType(attrs, baseName, baseTypes, null); adt.ScanClassBody(body); var output = new RVList<LNode>(); adt.GenerateOutput(ref output); return LNode.Call(CodeSymbols.Splice, new RVList<LNode>(output)); } } return null; }
LNode TraitDecl(int startIndex, RVList<LNode> attrs) { Check(Is(0, _trait), "Is($LI, _trait)"); var t = Match((int) TT.ContextualKeyword); var r = RestOfSpaceDecl(startIndex, S.Trait, attrs); #line 1078 "EcsParserGrammar.les" return r; #line default }
LNode AliasDecl(int startIndex, RVList<LNode> attrs) { Check(Is(0, _alias), "Is($LI, _alias)"); var t = Match((int) TT.ContextualKeyword); var newName = ComplexNameDecl(); var r = RestOfAlias(startIndex, newName); #line 1097 "EcsParserGrammar.les" return r.WithAttrs(attrs); #line default }
public RVList<LNode> ProcessSynchronously(RVList<LNode> stmts) { return new MacroProcessorTask(this).ProcessRoot(stmts); }
public LNode GetWithFn(AdtParam part, bool isAbstract, Symbol virtualOverride, IEnumerable<AdtParam> allParts) { LNode genericClassName = this.TypeName; int totalParts = allParts.Count(); var withField = F.Id("With" + part.NameId.Name); var args = LNode.List(); foreach (AdtParam otherPart in allParts) { if (part == otherPart) args.Add(F.Id("newValue")); else args.Add(otherPart.NameId); } var attrs = new RVList<LNode>(F.Id(S.Public)); if (isAbstract) attrs.Add(F.Id(S.Abstract)); if (virtualOverride != null && (!isAbstract || virtualOverride == S.Override)) attrs.Add(F.Id(virtualOverride)); LNode method; LNode type = part.Type; LNode retType = part.ContainingType.TypeName; if (isAbstract) { method = LNode.Call(new RVList<LNode>(attrs), CodeSymbols.Fn, LNode.List(retType, withField, LNode.Call(CodeSymbols.AltList, LNode.List(LNode.Call(new RVList<LNode>(part.OriginalDecl.Attrs), CodeSymbols.Var, LNode.List(type, LNode.Id((Symbol) "newValue"))))))); } else { method = LNode.Call(new RVList<LNode>(attrs), CodeSymbols.Fn, LNode.List(retType, withField, LNode.Call(CodeSymbols.AltList, LNode.List(LNode.Call(new RVList<LNode>(part.OriginalDecl.Attrs), CodeSymbols.Var, LNode.List(type, LNode.Id((Symbol) "newValue"))))), LNode.Call(CodeSymbols.Braces, LNode.List(LNode.Call(CodeSymbols.Return, LNode.List(LNode.Call(CodeSymbols.New, LNode.List(LNode.Call(genericClassName, new RVList<LNode>(args)))))))).SetStyle(NodeStyle.Statement))); } return method; }
LNode InParens_ExprOrTuple(bool allowUnassignedVarDecl, int startIndex, int endIndex) { TokenType la0, la1; // Line 773: (ExprStart (TT.Comma (~(EOF))* => (TT.Comma ExprStart | TT.Comma)*)? | ) la0 = LA0; if (InParens_ExprOrTuple_set0.Contains((int) la0)) { var e = ExprStart(allowUnassignedVarDecl); // Line 774: (TT.Comma (~(EOF))* => (TT.Comma ExprStart | TT.Comma)*)? la0 = LA0; if (la0 == TT.Comma) { #line 775 "EcsParserGrammar.les" var list = new RVList<LNode> { e }; #line default // Line 776: (TT.Comma ExprStart | TT.Comma)* for (;;) { la0 = LA0; if (la0 == TT.Comma) { la1 = LA(1); if (InParens_ExprOrTuple_set0.Contains((int) la1)) { Skip(); list.Add(ExprStart(allowUnassignedVarDecl)); } else Skip(); } else break; } #line 779 "EcsParserGrammar.les" return F.Tuple(list, startIndex, endIndex); #line default } #line 781 "EcsParserGrammar.les" return F.InParens(e, startIndex, endIndex); #line default } else { #line 783 "EcsParserGrammar.les" return F.Tuple(RVList<LNode>.Empty, startIndex, endIndex); #line default } Match((int) EOF); }
LNode MethodArgListAndBody(int startIndex, RVList<LNode> attrs, Symbol kind, LNode type, LNode name) { TokenType la0; var lp = Match((int) TT.LParen); var rp = Match((int) TT.RParen); WhereClausesOpt(ref name); #line 1279 "EcsParserGrammar.les" LNode r, baseCall = null; #line default // Line 1280: (TT.Colon (@`.`(TT, noMacro(@base))|@`.`(TT, noMacro(@this))) TT.LParen TT.RParen)? la0 = LA0; if (la0 == TT.Colon) { Skip(); var target = Match((int) TT.@base, (int) TT.@this); var baselp = Match((int) TT.LParen); var baserp = Match((int) TT.RParen); #line 1282 "EcsParserGrammar.les" baseCall = F.Call((Symbol) target.Value, ExprListInside(baselp), target.StartIndex, baserp.EndIndex); if ((kind != S.Cons)) { Error(baseCall, "This is not a constructor declaration, so there should be no ':' clause."); } #line default } #line 1289 "EcsParserGrammar.les" for (int i = 0; i < attrs.Count; i++) { var attr = attrs[i]; if (IsNamedArg(attr) && attr.Args[0].IsIdNamed(S.Return)) { type = type.PlusAttr(attr.Args[1]); attrs.RemoveAt(i); i--; } } #line default // Line 1298: (default TT.Semicolon | MethodBodyOrForward) do { switch (LA0) { case TT.Semicolon: goto match1; case TT.At: case TT.Forward: case TT.LambdaArrow: case TT.LBrace: { var body = MethodBodyOrForward(); #line 1310 "EcsParserGrammar.les" if (kind == S.Delegate) { Error("A 'delegate' is not expected to have a method body."); } if (baseCall != null) { body = body.WithArgs(body.Args.Insert(0, baseCall)).WithRange(baseCall.Range.StartIndex, body.Range.EndIndex); } #line 1314 "EcsParserGrammar.les" var parts = new RVList<LNode> { type, name, ArgList(lp, rp), body }; r = F.Call(kind, parts, startIndex, body.Range.EndIndex); #line default } break; default: goto match1; } break; match1: { var end = Match((int) TT.Semicolon); #line 1300 "EcsParserGrammar.les" if (kind == S.Cons && baseCall != null) { Error(baseCall, "A method body is required."); var parts = new RVList<LNode> { type, name, ArgList(lp, rp), LNode.Call(S.Braces, new RVList<LNode>(baseCall), baseCall.Range) }; return F.Call(kind, parts, startIndex, baseCall.Range.EndIndex); } #line 1306 "EcsParserGrammar.les" r = F.Call(kind, type, name, ArgList(lp, rp), startIndex, end.EndIndex); #line default } } while (false); #line 1318 "EcsParserGrammar.les" return r.PlusAttrs(attrs); #line default }
LNode OperatorCast(int startIndex, RVList<LNode> attrs) { #line 1269 "EcsParserGrammar.les" LNode r; #line default var op = MatchAny(); var type = DataType(); #line 1271 "EcsParserGrammar.les" var name = F.Attr(_triviaUseOperatorKeyword, F.Id(S.Cast, op.StartIndex, op.EndIndex)); #line default r = MethodArgListAndBody(startIndex, attrs, S.Fn, type, name); #line 1273 "EcsParserGrammar.les" return r; #line default }
LNode MethodOrPropertyOrVar(int startIndex, RVList<LNode> attrs) { TokenType la0; #line 1243 "EcsParserGrammar.les" LNode r; #line default var type = DataType(); // Line 1247: (&(IdAtom (TT.Comma|TT.Semicolon|TT.Set)) NameAndMaybeInit (TT.Comma NameAndMaybeInit)* TT.Semicolon / ComplexNameDecl (MethodArgListAndBody | WhereClausesOpt MethodBodyOrForward)) if (Try_MethodOrPropertyOrVar_Test0(0)) { MaybeRecognizeVarAsKeyword(ref type); var parts = new RVList<LNode> { type }; parts.Add(NameAndMaybeInit(IsArrayType(type))); // Line 1251: (TT.Comma NameAndMaybeInit)* for (;;) { la0 = LA0; if (la0 == TT.Comma) { Skip(); parts.Add(NameAndMaybeInit(IsArrayType(type))); } else break; } var end = Match((int) TT.Semicolon); #line 1252 "EcsParserGrammar.les" r = F.Call(S.Var, parts, type.Range.StartIndex, end.EndIndex).PlusAttrs(attrs); #line default } else { var name = ComplexNameDecl(); // Line 1255: (MethodArgListAndBody | WhereClausesOpt MethodBodyOrForward) switch (LA0) { case TT.LParen: r = MethodArgListAndBody(startIndex, attrs, S.Fn, type, name); break; case TT.At: case TT.ContextualKeyword: case TT.Forward: case TT.LambdaArrow: case TT.LBrace: { WhereClausesOpt(ref name); var body = MethodBodyOrForward(); #line 1259 "EcsParserGrammar.les" r = F.Call(S.Property, type, name, body, type.Range.StartIndex, body.Range.EndIndex).PlusAttrs(attrs); #line default } break; default: { ScanToEndOfStmt(); Error("Syntax error in method, property, or variable declaration"); r = F._Missing.PlusAttrs(attrs); } break; } } #line 1265 "EcsParserGrammar.les" return r; #line default }
LNode AssemblyOrModuleAttribute(int startIndex, RVList<LNode> attrs) { Check(Down(0) && Up(Try_Scan_AsmOrModLabel(0)), "Down($LI) && Up(Try_Scan_AsmOrModLabel(0))"); var lb = MatchAny(); var rb = Match((int) TT.RBrack); #line 1226 "EcsParserGrammar.les" Down(lb); #line default var kind = AsmOrModLabel(); #line 1228 "EcsParserGrammar.les" var list = new RWList<LNode>(); #line default ExprList(list); #line 1231 "EcsParserGrammar.les" Up(); var r = F.Call(kind.Value == _module ? S.Module : S.Assembly, list.ToRVList(), startIndex, rb.EndIndex); return r.WithAttrs(attrs); #line default }
LNode BaseListOpt() { TokenType la0; // Line 1137: (TT.Colon DataType (TT.Comma DataType)* | ) la0 = LA0; if (la0 == TT.Colon) { #line 1137 "EcsParserGrammar.les" var bases = new RVList<LNode>(); #line default Skip(); bases.Add(DataType()); // Line 1139: (TT.Comma DataType)* for (;;) { la0 = LA0; if (la0 == TT.Comma) { Skip(); bases.Add(DataType()); } else break; } #line 1140 "EcsParserGrammar.les" return F.List(bases); #line default } else { #line 1141 "EcsParserGrammar.les" return F.List(); #line default } }
LNode EnumDecl(int startIndex, RVList<LNode> attrs) { TokenType la0; var t = MatchAny(); var id = Match((int) TT.Id); #line 1123 "EcsParserGrammar.les" var name = IdNode(id); #line default var bases = BaseListOpt(); // Line 1125: (TT.Semicolon | TT.LBrace TT.RBrace) la0 = LA0; if (la0 == TT.Semicolon) { var end = MatchAny(); #line 1126 "EcsParserGrammar.les" return F.Call(S.Enum, name, bases, startIndex, end.EndIndex).WithAttrs(attrs); #line default } else { var lb = Match((int) TT.LBrace); var rb = Match((int) TT.RBrace); #line 1129 "EcsParserGrammar.les" var list = ExprListInside(lb, true); var body = F.Braces(list, lb.StartIndex, rb.EndIndex); return F.Call(S.Enum, name, bases, body, startIndex, body.Range.EndIndex).WithAttrs(attrs); #line default } }
LNode UsingDirective(int startIndex, RVList<LNode> attrs) { TokenType la0; Match((int) TT.@using); var nsName = ComplexNameDecl(); // Line 1102: (RestOfAlias | TT.Semicolon) la0 = LA0; if (la0 == TT.QuickBindSet || la0 == TT.Set) { var r = RestOfAlias(startIndex, nsName); #line 1103 "EcsParserGrammar.les" return r.WithAttrs(attrs).PlusAttr(_filePrivate); #line default } else { Match((int) TT.Semicolon); #line 1105 "EcsParserGrammar.les" return F.Call(S.Import, nsName); #line default } }
public virtual LNode CreateRuleMethod(Rule rule, RVList<LNode> methodBody) { return rule.CreateMethod(methodBody); }
LNode Constructor(int startIndex, RVList<LNode> attrs) { TokenType la0; #line 1374 "EcsParserGrammar.les" LNode r; #line 1374 "EcsParserGrammar.les" Token n; #line default // Line 1375: ( &{_spaceName == LT($LI).Value} (TT.ContextualKeyword|TT.Id) &(TT.LParen TT.RParen (TT.LBrace|TT.Semicolon)) / &{_spaceName != S.Fn || LA($LI + 3) == TT.LBrace} @`.`(TT, noMacro(@this)) &(TT.LParen TT.RParen (TT.LBrace|TT.Semicolon)) / (@`.`(TT, noMacro(@this))|TT.ContextualKeyword|TT.Id) &(TT.LParen TT.RParen TT.Colon) ) do { la0 = LA0; if (la0 == TT.ContextualKeyword || la0 == TT.Id) { if (_spaceName == LT(0).Value) { if (Try_Constructor_Test0(1)) n = MatchAny(); else goto match3; } else goto match3; } else { if (_spaceName != S.Fn || LA(0 + 3) == TT.LBrace) { if (Try_Constructor_Test1(1)) n = Match((int) TT.@this); else goto match3; } else goto match3; } break; match3: { n = Match((int) TT.@this, (int) TT.ContextualKeyword, (int) TT.Id); Check(Try_Constructor_Test2(0), "TT.LParen TT.RParen TT.Colon"); } } while (false); #line 1384 "EcsParserGrammar.les" LNode name = F.Id((Symbol) n.Value, n.StartIndex, n.EndIndex); #line default r = MethodArgListAndBody(startIndex, attrs, S.Cons, F._Missing, name); #line 1386 "EcsParserGrammar.les" return r; #line default }
public void AddParts(RVList<LNode> parts) { foreach (var part in parts) Parts.Add(new AdtParam(part, this)); }
LNode Destructor(int startIndex, RVList<LNode> attrs) { TokenType la0; #line 1390 "EcsParserGrammar.les" LNode r; #line 1390 "EcsParserGrammar.les" Token n; #line default var tilde = MatchAny(); // Line 1392: ((&{LT($LI).Value == _spaceName}) (TT.ContextualKeyword|TT.Id) | @`.`(TT, noMacro(@this))) la0 = LA0; if (la0 == TT.ContextualKeyword || la0 == TT.Id) { // Line 1392: (&{LT($LI).Value == _spaceName}) la0 = LA0; if (la0 == TT.ContextualKeyword || la0 == TT.Id) Check(LT(0).Value == _spaceName, "LT($LI).Value == _spaceName"); else { #line 1393 "EcsParserGrammar.les" Error("Unexpected destructor '{0}'", LT(0).Value); #line default } n = MatchAny(); } else n = Match((int) TT.@this); #line 1397 "EcsParserGrammar.les" LNode name = F.Call(S.NotBits, F.Id((Symbol) n.Value, n.StartIndex, n.EndIndex), tilde.StartIndex, n.EndIndex); #line default r = MethodArgListAndBody(startIndex, attrs, S.Fn, F._Missing, name); #line 1399 "EcsParserGrammar.les" return r; #line default }
LNode DelegateDecl(int startIndex, RVList<LNode> attrs) { Skip(); var type = DataType(); var name = ComplexNameDecl(); var r = MethodArgListAndBody(startIndex, attrs, S.Delegate, type, name); #line 1409 "EcsParserGrammar.les" return r.WithAttrs(attrs); #line default }
LNode EventDecl(int startIndex, RVList<LNode> attrs) { TokenType la0; #line 1413 "EcsParserGrammar.les" LNode r; #line default Skip(); var type = DataType(); var name = ComplexNameDecl(); // Line 1415: (default (TT.Comma ComplexNameDecl)* TT.Semicolon | BracedBlock) do { la0 = LA0; if (la0 == TT.Comma || la0 == TT.Semicolon) goto match1; else if (la0 == TT.LBrace) { var body = BracedBlock(S.Fn); #line 1421 "EcsParserGrammar.les" r = F.Call(S.Event, type, name, body, startIndex, body.Range.EndIndex); #line default } else goto match1; break; match1: { #line 1416 "EcsParserGrammar.les" var parts = new RVList<LNode>(type, name); #line default // Line 1417: (TT.Comma ComplexNameDecl)* for (;;) { la0 = LA0; if (la0 == TT.Comma) { Skip(); parts.Add(ComplexNameDecl()); } else break; } var end = Match((int) TT.Semicolon); #line 1419 "EcsParserGrammar.les" r = F.Call(S.Event, parts, startIndex, end.EndIndex); #line default } } while (false); #line 1423 "EcsParserGrammar.les" return r.WithAttrs(attrs); #line default }
public void GenerateOutput(ref RVList<LNode> list) { bool isAbstract = _typeAttrs.Any(a => a.IsIdNamed(S.Abstract)); var baseParts = new List<AdtParam>(); for (var type = ParentType; type != null; type = type.ParentType) baseParts.InsertRange(0, type.Parts); var allParts = baseParts.Concat(Parts); var initialization = Parts.Select(p => LNode.Call(CodeSymbols.Assign, LNode.List(LNode.Call(CodeSymbols.Dot, LNode.List(LNode.Id(CodeSymbols.This), p.NameId)), p.NameId)).SetStyle(NodeStyle.Operator)).ToList(); if (baseParts.Count > 0) initialization.Insert(0, F.Call(S.Base, baseParts.Select(p => p.NameId))); var args = new RVList<LNode>(allParts.Select(p => p.OriginalDecl)); if (!_constructorAttrs.Any(a => a.IsIdNamed(S.Public))) _constructorAttrs.Add(F.Id(S.Public)); LNode constructor = LNode.Call(new RVList<LNode>(_constructorAttrs), CodeSymbols.Cons, LNode.List(LNode.Missing, _typeNameStem, LNode.Call(CodeSymbols.AltList, new RVList<LNode>(args)), LNode.Call(CodeSymbols.Braces, new RVList<LNode>().AddRange(initialization).AddRange(_extraConstrLogic)).SetStyle(NodeStyle.Statement))); var outBody = new RVList<LNode>(); outBody.Add(constructor); outBody.AddRange(Parts.Select(p => p.GetFieldDecl())); outBody.AddRange(baseParts.Select(p => GetWithFn(p, isAbstract, S.Override, allParts))); outBody.AddRange(Parts.Select(p => GetWithFn(p, isAbstract, _children.Count > 0 ? S.Virtual : null, allParts))); outBody.AddRange(Parts.WithIndexes().Where(kvp => kvp.Value.NameId.Name.Name != "Item" + (baseParts.Count + kvp.Key + 1)).Select(kvp => kvp.Value.GetItemDecl(baseParts.Count + kvp.Key + 1))); outBody.AddRange(_classBody); list.Add(LNode.Call(new RVList<LNode>(_typeAttrs), CodeSymbols.Class, LNode.List(TypeName, LNode.Call(CodeSymbols.AltList, new RVList<LNode>(BaseTypes)), LNode.Call(CodeSymbols.Braces, new RVList<LNode>(outBody)).SetStyle(NodeStyle.Statement)))); if (_genericArgs.Count > 0 && Parts.Count > 0) { var argNames = allParts.Select(p => p.NameId); list.Add(LNode.Call(new RVList<LNode>().AddRange(_typeAttrs).Add(LNode.Id(CodeSymbols.Static)).Add(LNode.Id(LNode.List(LNode.Id(CodeSymbols.TriviaWordAttribute)), CodeSymbols.Partial)), CodeSymbols.Class, LNode.List(_typeNameStem, LNode.Call(CodeSymbols.AltList), LNode.Call(CodeSymbols.Braces, LNode.List(LNode.Call(LNode.List(LNode.Id(CodeSymbols.Public), LNode.Id(CodeSymbols.Static)), CodeSymbols.Fn, LNode.List(TypeName, LNode.Call(CodeSymbols.Of, new RVList<LNode>().Add(LNode.Id((Symbol) "New")).AddRange(_genericArgs)), LNode.Call(CodeSymbols.AltList, new RVList<LNode>(args)), LNode.Call(CodeSymbols.Braces, LNode.List(LNode.Call(CodeSymbols.Return, LNode.List(LNode.Call(CodeSymbols.New, LNode.List(LNode.Call(TypeName, new RVList<LNode>(argNames)))))))).SetStyle(NodeStyle.Statement))))).SetStyle(NodeStyle.Statement)))); } foreach (var child in _children) child.GenerateOutput(ref list); }
LNode ForStmt(int startIndex) { Skip(); var p = Match((int) TT.LParen); Match((int) TT.RParen); var block = Stmt(); #line 1560 "EcsParserGrammar.les" Down(p); #line default var init = ExprOpt(true); Match((int) TT.Semicolon); var cond = ExprOpt(false); Match((int) TT.Semicolon); var inc = ExprOpt(false); #line 1562 "EcsParserGrammar.les" Up(); #line default #line 1564 "EcsParserGrammar.les" var parts = new RVList<LNode> { init, cond, inc, block }; return F.Call(S.For, parts, startIndex, block.Range.EndIndex); #line default }
private void Test(string input, IParsingService inLang, string expected, IParsingService outLang, int maxExpand = 0xFFFF) { var lemp = NewLemp(maxExpand); var inputCode = new RVList<LNode>(inLang.Parse(input, _sink)); var results = lemp.ProcessSynchronously(inputCode); var expectCode = outLang.Parse(expected, _sink); if (!results.SequenceEqual(expectCode)) { // TEST FAILED, print error string resultStr = results.Select(n => outLang.Print(n, _sink)).Join("\n"); Assert.AreEqual(TestCompiler.StripExtraWhitespace(expected), TestCompiler.StripExtraWhitespace(resultStr)); } }
LNode TryStmt(int startIndex) { TokenType la0, la1; Skip(); var header = Stmt(); #line 1641 "EcsParserGrammar.les" var parts = new RVList<LNode> { header }; LNode expr; #line 1642 "EcsParserGrammar.les" LNode handler; #line default // Line 1644: greedy(TT.@catch (TT.LParen TT.RParen Stmt / Stmt))* for (;;) { la0 = LA0; if (la0 == TT.@catch) { la1 = LA(1); if (IfStmt_set0.Contains((int) la1)) { var kw = MatchAny(); // Line 1645: (TT.LParen TT.RParen Stmt / Stmt) la0 = LA0; if (la0 == TT.LParen) { var p = MatchAny(); Match((int) TT.RParen); handler = Stmt(); #line 1645 "EcsParserGrammar.les" expr = SingleExprInside(p, "catch (...)", null, true); #line default } else { handler = Stmt(); #line 1646 "EcsParserGrammar.les" expr = F.Id(S.Missing, kw.EndIndex, kw.EndIndex); #line default } #line 1648 "EcsParserGrammar.les" parts.Add(F.Call(S.Catch, expr, handler, kw.StartIndex, handler.Range.EndIndex)); #line default } else break; } else break; } // Line 1651: greedy(TT.@finally Stmt)* for (;;) { la0 = LA0; if (la0 == TT.@finally) { la1 = LA(1); if (IfStmt_set0.Contains((int) la1)) { var kw = MatchAny(); handler = Stmt(); #line 1652 "EcsParserGrammar.les" parts.Add(F.Call(S.Finally, handler, kw.StartIndex, handler.Range.EndIndex)); #line default } else break; } else break; } #line 1655 "EcsParserGrammar.les" var result = F.Call(S.Try, parts, startIndex, parts.Last.Range.EndIndex); if (parts.Count == 1) { Error(result, "'try': At least one 'catch' or 'finally' clause is required"); } #line 1659 "EcsParserGrammar.les" return result; #line default }
LNode SpaceDecl(int startIndex, RVList<LNode> attrs) { var t = MatchAny(); #line 1070 "EcsParserGrammar.les" var kind = (Symbol) t.Value; #line default var r = RestOfSpaceDecl(startIndex, kind, attrs); #line 1072 "EcsParserGrammar.les" return r; #line default }
LNode RestOfSpaceDecl(int startIndex, Symbol kind, RVList<LNode> attrs) { TokenType la0; var name = ComplexNameDecl(); var bases = BaseListOpt(); WhereClausesOpt(ref name); // Line 1085: (TT.Semicolon | BracedBlock) la0 = LA0; if (la0 == TT.Semicolon) { var end = MatchAny(); #line 1086 "EcsParserGrammar.les" return F.Call(kind, name, bases, startIndex, end.EndIndex).WithAttrs(attrs); #line default } else { var body = BracedBlock(CoreName(name).Name); #line 1088 "EcsParserGrammar.les" return F.Call(kind, name, bases, body, startIndex, body.Range.EndIndex).WithAttrs(attrs); #line default } }