internal static VList <LNode> GetArgNamesFromFormalArgList(LNode args, Action <LNode> onError) { VList <LNode> formalArgs = args.Args; VList <LNode> argList = VList <LNode> .Empty; foreach (var formalArg in formalArgs) { if (!formalArg.Calls(S.Var, 2)) { onError(formalArg); } else { LNode argName = formalArg.Args[1]; if (argName.Calls(S.Assign, 2)) { argName = argName.Args[0]; } LNode @ref = formalArg.AttrNamed(S.Ref) ?? formalArg.AttrNamed(S.Out); if (@ref != null) { argName = argName.PlusAttr(@ref); } argList.Add(argName); } } return(argList); }
public void TriviaTest_Comments() { LNode node; node = Foo.PlusAttr(F.Trivia(S.TriviaMLComment, " before ")).PlusTrailingTrivia(F.Trivia(S.TriviaMLComment, " after ")); Exact("/* before */Foo; /* after */", node); node = one.PlusAttr(F.Trivia(S.TriviaSLComment, " before ")).PlusTrailingTrivia(F.Trivia(S.TriviaSLComment, " after ")); Exact("// before \n1;\t// after ", node); node = F.Call(F.Id(S.Eq).PlusAttr(F.Trivia(S.TriviaMLComment, "[")).PlusTrailingTrivia(F.Trivia(S.TriviaSLComment, "]")), Foo, x.PlusAttrs(F.TriviaNewline, F.Trivia(S.TriviaMLComment, "{")).PlusTrailingTrivia(F.Trivia(S.TriviaMLComment, "}")) ).PlusAttr(F.Trivia(S.TriviaMLComment, " before ")).PlusTrailingTrivia(F.Trivia(S.TriviaMLComment, " after ")); Exact("/* before */Foo /*[*/== //]\n /*{*/x /*}*/; /* after */", node); node = F.Call(Foo).PlusAttrs(a.PlusTrailingTrivia(F.Trivia(S.TriviaSLComment, "Comment after a")), b, F.Trivia(S.TriviaMLComment, "Comment before c"), c); Exact("@[a\t//Comment after a\n" + " , b] /*Comment before c*/@[c] Foo();", node); // TODO: The following example parses as shown but is printed out differently. // Either we should change AbstractTriviaInjector to emit the comment at the // "top level" of the attribute list (not attached to `a`) or we should change // the node printer to print the comma before it prints trailing trivia. node = F.Call(Foo).PlusAttrs(a, F.Trivia(S.TriviaSLComment, "Comment after a"), b, F.Trivia(S.TriviaMLComment, "Comment before c"), c); Exact("@[a] //Comment after a\n" + "@[b] /*Comment before c*/@[c] Foo();", node); }
LNode ConvertVarDeclToRunSequence(VList <LNode> attrs, LNode varType, LNode varName, LNode initValue) { initValue = BubbleUpBlocks(initValue); varType = varType ?? F.Missing; LNode @ref; attrs = attrs.WithoutNodeNamed(S.Ref, out @ref); var varName_apos = varName.PlusAttr(_trivia_isTmpVar); if (@ref != null) { varName_apos = varName_apos.PlusAttr(@ref); } { LNode resultValue; VList <LNode> stmts; if (initValue.CallsMin((Symbol)"#runSequence", 1) && (resultValue = initValue.Args[initValue.Args.Count - 1]) != null) { stmts = initValue.Args.WithoutLast(1); var newVarDecl = LNode.Call(LNode.List(attrs), CodeSymbols.Var, LNode.List(varType, LNode.Call(CodeSymbols.Assign, LNode.List(varName, resultValue)))); return(initValue.WithArgs(stmts.Add(newVarDecl).Add(varName_apos))); } else { var newVarDecl = LNode.Call(LNode.List(attrs), CodeSymbols.Var, LNode.List(varType, LNode.Call(CodeSymbols.Assign, LNode.List(varName, initValue)))); return(LNode.Call((Symbol)"#runSequence", LNode.List(newVarDecl, varName_apos))); } } }
public static LNode ArrayLiteral(LNode node, IMacroContext context) { var value = node.Value; if (value is Array array) { Type elementType = value.GetType().GetElementType(); string elementTypeName = elementType.NameWithGenericArgs(); LNode elementTypeN = LNode.Call(S.CsRawText, LNode.List(LNode.Literal(elementTypeName))); Func <object, LNode, LNode> newLiteral = (el, pnode) => LNode.Literal(el, pnode); // Reduce output text size by preventing the printer from using casts // e.g. print `23` instead of `(byte) 23` or `(short) 23`. Also, unbox // ints to save memory (ideally we'd do this for all Value Types) if (elementType == typeof(byte)) { newLiteral = (el, pnode) => LNode.Literal((int)(byte)el, pnode); } if (elementType == typeof(sbyte)) { newLiteral = (el, pnode) => LNode.Literal((int)(sbyte)el, pnode); } if (elementType == typeof(short)) { newLiteral = (el, pnode) => LNode.Literal((int)(short)el, pnode); } if (elementType == typeof(ushort)) { newLiteral = (el, pnode) => LNode.Literal((int)(ushort)el, pnode); } if (elementType == typeof(int)) { newLiteral = (el, pnode) => LNode.Literal((int)(int)el, pnode); } if (array.Rank == 1) { var initializers = new List <LNode>(); int count = 0; foreach (object element in array) { LNode elemNode = newLiteral(element, node); if ((count++ & 7) == 0 && array.Length > 8) { elemNode = elemNode.PlusAttr(LNode.Id(S.TriviaNewline)); } initializers.Add(elemNode); } return(LNode.Call(CodeSymbols.New, LNode.List().Add(LNode.Call(LNode.Call(CodeSymbols.Of, LNode.List(LNode.Id(CodeSymbols.Array), elementTypeN)))).AddRange(initializers))); } else { return(null); // TODO //Stmt("int[,] Foo = new[,] { {\n 0 }, {\n 1,\n 2, }, };", F.Call(S.Var, F.Of(S.TwoDimensionalArray, S.Int32), // F.Call(S.Assign, Foo, F.Call(S.New, F.Call(S.TwoDimensionalArray), F.Braces(zero), F.Braces(one, two))))); } } return(null); }
public LNode InParens(LNode inner, int startIndex = -1, int endIndex = -1) { Debug.Assert(endIndex >= startIndex); _inParens = _inParens ?? Id(S.TriviaInParens); inner = inner.PlusAttr(_inParens); if (startIndex != -1 && endIndex != -1) { return(inner.WithRange(startIndex, endIndex)); } else { return(inner); } }
public void TriviaTest_Comments() { LNode node; node = Foo.PlusAttr(F.Trivia(S.TriviaMLComment, " before ")).PlusTrailingTrivia(F.Trivia(S.TriviaMLComment, " after ")); Exact("/* before */Foo /* after */", node); node = one.PlusAttr(F.Trivia(S.TriviaSLComment, " before ")).PlusTrailingTrivia(F.Trivia(S.TriviaSLComment, " after ")); Exact("// before \n1\t// after ", node); Exact("Foo(a,\t// Commentary\n b)", F.Call(Foo, a.PlusTrailingTrivia(F.Trivia(S.TriviaSLComment, " Commentary")), OnNewLine(b))); node = F.Call(F.Id(S.Eq).PlusAttr(F.Trivia(S.TriviaMLComment, "[")).PlusTrailingTrivia(F.Trivia(S.TriviaSLComment, "]")), Foo, x.PlusAttrs(F.TriviaNewline, F.Trivia(S.TriviaMLComment, "x")) ).PlusAttr(F.Trivia(S.TriviaMLComment, " before ")).PlusTrailingTrivia(F.Trivia(S.TriviaMLComment, " after ")); Exact("/* before */Foo /*[*/==\t//]\n/*x*/x /* after */", node); node = F.Call(Foo).PlusAttrs(a, F.Trivia(S.TriviaSLComment, "Comment after a"), b, F.Trivia(S.TriviaMLComment, "Comment before c"), c); Exact("@a //Comment after a\n" + "@b /*Comment before c*/@c Foo()", node); }
public static LNode ForwardMethod(LNode fn, IMessageSink sink) { LNode args, fwd, body; if (fn.ArgCount != 4 || !(fwd = fn.Args[3]).Calls(S.Forward, 1) || !(args = fn.Args[2]).Calls(S.List)) { return(null); } RVList <LNode> formalArgs = args.Args; RVList <LNode> argList = RVList <LNode> .Empty; foreach (var formalArg in formalArgs) { if (!formalArg.Calls(S.Var, 2)) { return(Reject(sink, formalArg, "'==>' expected a variable declaration here")); } LNode argName = formalArg.Args[1]; if (argName.Calls(S.Assign, 2)) { argName = argName.Args[0]; } LNode @ref = formalArg.AttrNamed(S.Ref) ?? formalArg.AttrNamed(S.Out); if (@ref != null) { argName = argName.PlusAttr(@ref); } argList.Add(argName); } LNode target = GetForwardingTarget(fwd, fn.Args[1]); LNode call = F.Call(target, argList); bool isVoidFn = fn.Args[0].IsIdNamed(S.Void); body = F.Braces(isVoidFn ? call : F.Call(S.Return, call)); return(fn.WithArgChanged(3, body)); }
static LNode TranslateWordAttr(LNode node, IMacroContext ctx, Symbol attr) { if (node.ArgCount == 0) { if (node.IsId && ctx.IsAttribute) { return(node.WithName(attr)); } return(null); } else { if (node.ArgCount == 1) { return(node.Args[0].PlusAttrs(node.Attrs.Add(F.Id(attr)))); } else // designed for LESv1; this branch is not very useful in LESv2 { return(node.PlusAttr(F.Id(attr)).With(node.Args[0], node.Args.RemoveAt(0))); } } }
public LNode InParens(LNode inner, int startIndex = -1, int endIndex = -1) { if (endIndex < startIndex) endIndex = startIndex; _inParens = _inParens ?? Id(S.TriviaInParens); inner = inner.PlusAttr(_inParens); if (startIndex != -1 && endIndex != -1) return inner.WithRange(startIndex, endIndex); else return inner; }
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 }
static LNode TranslateWordAttr(LNode node, IMacroContext ctx, Symbol attr) { if (node.ArgCount == 0) { if (node.IsId && ctx.IsAttribute) return node.WithName(attr); return null; } else { if (node.ArgCount == 1) return node.Args[0].PlusAttrs(node.Attrs.Add(F.Id(attr))); else // designed for LESv1; this branch is not very useful in LESv2 return node.PlusAttr(F.Id(attr)).With(node.Args[0], node.Args.RemoveAt(0)); } }
LNode ConvertVarDeclToRunSequence(VList<LNode> attrs, LNode varType, LNode varName, LNode initValue) { initValue = BubbleUpBlocks(initValue); varType = varType ?? F.Missing; LNode @ref; attrs = attrs.WithoutNodeNamed(S.Ref, out @ref); var varName_apos = varName.PlusAttr(_trivia_isTmpVar); if (@ref != null) varName_apos = varName_apos.PlusAttr(@ref); { LNode resultValue; VList<LNode> stmts; if (initValue.CallsMin((Symbol) "#runSequence", 1) && (resultValue = initValue.Args[initValue.Args.Count - 1]) != null) { stmts = initValue.Args.WithoutLast(1); var newVarDecl = LNode.Call(LNode.List(attrs), CodeSymbols.Var, LNode.List(varType, LNode.Call(CodeSymbols.Assign, LNode.List(varName, resultValue)))); return initValue.WithArgs(stmts.Add(newVarDecl).Add(varName_apos)); } else { var newVarDecl = LNode.Call(LNode.List(attrs), CodeSymbols.Var, LNode.List(varType, LNode.Call(CodeSymbols.Assign, LNode.List(varName, initValue)))); return LNode.Call((Symbol) "#runSequence", LNode.List(newVarDecl, varName_apos)); } } }
LNode MethodArgListAndBody(int startIndex, int targetIndex, VList<LNode> attrs, Symbol kind, LNode type, LNode name) { TokenType la0; Token lit_colon = default(Token); var lp = Match((int) TT.LParen); var rp = Match((int) TT.RParen); WhereClausesOpt(ref name); // line 1686 LNode r, _, baseCall = null; // line 1686 int consCallIndex = -1; // Line 1687: (TT.Colon (TT.Base|TT.This) TT.LParen TT.RParen)? la0 = LA0; if (la0 == TT.Colon) { lit_colon = MatchAny(); var target = Match((int) TT.Base, (int) TT.This); var baselp = Match((int) TT.LParen); var baserp = Match((int) TT.RParen); // line 1689 baseCall = F.Call((Symbol) target.Value, ExprListInside(baselp), target.StartIndex, baserp.EndIndex, target.StartIndex, target.EndIndex); if ((kind != S.Constructor)) { Error(baseCall, "This is not a constructor declaration, so there should be no ':' clause."); } consCallIndex = lit_colon.StartIndex; } // line 1697 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 1706: (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(false, out _, false, consCallIndex); // line 1720 if (kind == S.Delegate) { Error("A 'delegate' is not expected to have a method body."); } if (baseCall != null) { if ((!body.Calls(S.Braces))) { body = F.Braces(LNode.List(body), startIndex, body.Range.EndIndex); } body = body.WithArgs(body.Args.Insert(0, baseCall)); } var parts = new VList<LNode> { type, name, ArgList(lp, rp), body }; r = F.Call(kind, parts, startIndex, body.Range.EndIndex, targetIndex, targetIndex); } break; default: goto match1; } break; match1: { var end = Match((int) TT.Semicolon); // line 1708 if (kind == S.Constructor && baseCall != null) { Error(baseCall, "A method body is required."); var parts = LNode.List(type, name, ArgList(lp, rp), LNode.Call(S.Braces, new VList<LNode>(baseCall), baseCall.Range)); r = F.Call(kind, parts, startIndex, baseCall.Range.EndIndex, targetIndex, targetIndex); } else { var parts = LNode.List(type, name, ArgList(lp, rp)); r = F.Call(kind, parts, startIndex, end.EndIndex, targetIndex, targetIndex); } } } while (false); // line 1731 return r.PlusAttrs(attrs); }
public static LNode Prop(LNode node, IMacroContext context) { LNode visibility = node.Target; if (visibility.Name != sy__numprop) { node = node.PlusAttr(visibility); } { LNode getExpr, init = null, name, tmp_12 = null, tmp_13 = null, tmp_14, tmp_15, type; LNodeList content; if (node.Args.Count == 2 && (tmp_12 = node.Args[0]) != null && tmp_12.Calls(CodeSymbols.Colon, 2) && (name = tmp_12.Args[0]) != null && (type = tmp_12.Args[1]) != null && node.Args[1].Calls(CodeSymbols.Braces) && (content = node.Args[1].Args).IsEmpty | true || node.Args.Count == 3 && (tmp_13 = node.Args[0]) != null && tmp_13.Calls(CodeSymbols.Colon, 2) && (name = tmp_13.Args[0]) != null && (type = tmp_13.Args[1]) != null && node.Args[1].Calls(CodeSymbols.Braces) && (content = node.Args[1].Args).IsEmpty | true && node.Args[2].Calls((Symbol)"#initially", 1) && (init = node.Args[2].Args[0]) != null) { LNode args = GetArgList(ref name); var newBody = LNode.List(); foreach (var part_ in content) { LNode part = part_; { LNode body, value; if (part.Calls((Symbol)"#get", 0)) { part = LNode.Id(S.get, part); } else if (part.Calls((Symbol)"#get", 1) && (body = part.Args[0]) != null) { part = part.WithName(S.get); if (body.Calls(S.Braces)) { part = part.SetBaseStyle(NodeStyle.Special); } else { part = part.With(S.Lambda, part.Target, body); } } else if (part.Calls((Symbol)"#set", 0)) { part = LNode.Id(S.set, part); } else if (part.Calls((Symbol)"#set", 1) && (body = part.Args[0]) != null) { part = part.WithName(S.set); if (body.Calls(S.Braces)) { part = part.SetBaseStyle(NodeStyle.Special); } else { part = part.With(S.Lambda, part.Target, body); } } else if (part.Calls((Symbol)"#init", 1) && (value = part.Args[0]) != null) { init = value; part = null; } } if (part != null) { newBody.Add(part); } } if (init != null) { if (newBody.IsEmpty) { newBody.Add(F.Id(S.get)); } return(node.With(S.Property, type, name, args, F.Braces(newBody), init)); } else { return(node.With(S.Property, type, name, args, F.Braces(newBody))); } } else if (node.Args.Count == 1 && (tmp_14 = node.Args[0]) != null && tmp_14.Calls(CodeSymbols.Colon, 2) && (name = tmp_14.Args[0]) != null && (tmp_15 = tmp_14.Args[1]) != null && tmp_15.Calls(CodeSymbols.Lambda, 2) && (type = tmp_15.Args[0]) != null && (getExpr = tmp_15.Args[1]) != null) { var args = GetArgList(ref name); return(node.With(S.Property, type, name, args, getExpr)); } } return(Les2.Reject(context, node, "Unrecognized property syntax")); LNode GetArgList(ref LNode name_apos) { if (name_apos.Calls(S.IndexBracks)) { var args = name_apos.Args.RemoveAt(0); name_apos = name_apos[0].PlusAttrs(name_apos.Attrs); return(F.Call(S.AltList, args)); } else { return(LNode.Missing); } } }
public LNode Attr(LNode attr, LNode node) { return(node.PlusAttr(attr)); }
private static bool DetectSetOrCreateMember(LNode arg, out Symbol relevantAttribute, out Symbol fieldName, out Symbol paramName, out LNode plainArg, out LNode propOrFieldDecl) { relevantAttribute = null; fieldName = null; paramName = null; plainArg = null; propOrFieldDecl = null; LNode _, type, name, defaultValue, propArgs; if (EcsValidators.IsPropertyDefinition(arg, out type, out name, out propArgs, out _, out defaultValue) && propArgs.ArgCount == 0) { // #property(Type, Name<T>, {...}) relevantAttribute = S.Property; fieldName = EcsNodePrinter.KeyNameComponentOf(name); paramName = ChooseArgName(fieldName); if (defaultValue != null) // initializer is Args[4] { plainArg = F.Var(type, paramName, defaultValue); propOrFieldDecl = arg.WithArgs(arg.Args.First(4)); } else { plainArg = F.Var(type, paramName); propOrFieldDecl = arg; } return(true); } else if (IsVar(arg, out type, out paramName, out defaultValue)) { int a_i = 0; foreach (var attr in arg.Attrs) { if (attr.IsId) { var a = attr.Name; if (a == _set || a == S.Public || a == S.Internal || a == S.Protected || a == S.Private || a == S.ProtectedIn || a == S.Static || a == S.Partial) { relevantAttribute = a; fieldName = paramName; paramName = ChooseArgName(fieldName); if (a == _set) { plainArg = F.Var(type, paramName, defaultValue).WithAttrs(arg.Attrs.Without(attr)); } else { // in case of something like "[A] public params T arg = value", // assume that "= value" represents a default value, not a field // initializer, that [A] belongs on the field, except `params` // which stays on the argument. plainArg = F.Var(type, paramName, defaultValue); propOrFieldDecl = arg; if (arg.Args[1].Calls(S.Assign, 2)) { propOrFieldDecl = arg.WithArgChanged(1, arg.Args[1].Args[0]); } int i_params = arg.Attrs.IndexWithName(S.Params); if (i_params > -1) { plainArg = plainArg.PlusAttr(arg.Attrs[i_params]); propOrFieldDecl = propOrFieldDecl.WithAttrs(propOrFieldDecl.Attrs.RemoveAt(i_params)); } } break; } } a_i++; } return(plainArg != null); } return(false); }
public static LNode SetOrCreateMember(LNode fn, IMessageSink sink) { // Expecting #fn(Type, Name, #(args), {body}) if (fn.ArgCount < 3 || !fn.Args[2].Calls(S.AltList)) { return(null); } var args = fn.Args[2].Args; LNode body = null; VList <LNode> propOrFieldDecls = VList <LNode> .Empty; VList <LNode> setStmts = VList <LNode> .Empty; for (int i = 0; i < args.Count; i++) { var arg = args[i]; Symbol a = S.Property; Symbol fieldName = null; Symbol paramName = null; LNode plainArg = null; LNode propOrFieldDecl = null; if (arg.CallsMin(S.Property, 4)) { // #property(Type, Name<T>, {...}) var name = arg.Args[1]; fieldName = EcsNodePrinter.KeyNameComponentOf(name); paramName = ChooseArgName(fieldName); if (arg.ArgCount == 5) // initializer is Args[4] { plainArg = F.Var(arg.Args[0], F.Call(S.Assign, F.Id(paramName), arg.Args[4])); propOrFieldDecl = arg.WithArgs(arg.Args.First(4)); } else { plainArg = F.Var(arg.Args[0], paramName); propOrFieldDecl = arg; } } else { LNode type, defaultValue; if (IsVar(arg, out type, out paramName, out defaultValue)) { int a_i = 0; foreach (var attr in arg.Attrs) { if (attr.IsId) { a = attr.Name; if (a == _set || a == S.Public || a == S.Internal || a == S.Protected || a == S.Private || a == S.ProtectedIn || a == S.Static || a == S.Partial) { fieldName = paramName; paramName = ChooseArgName(fieldName); if (a == _set) { plainArg = F.Var(type, paramName, defaultValue).WithAttrs(arg.Attrs.RemoveAt(a_i)); } else { // in case of something like "[A] public params T arg = value", // assume that "= value" represents a default value, not a field // initializer, that [A] belongs on the field, except `params` // which stays on the argument. plainArg = F.Var(type, paramName, defaultValue); propOrFieldDecl = arg; if (arg.Args[1].Calls(S.Assign, 2)) { propOrFieldDecl = arg.WithArgChanged(1, arg.Args[1].Args[0]); } int i_params = arg.Attrs.IndexWithName(S.Params); if (i_params > -1) { plainArg = plainArg.PlusAttr(arg.Attrs[i_params]); propOrFieldDecl = propOrFieldDecl.WithAttrs(propOrFieldDecl.Attrs.RemoveAt(i_params)); } } break; } } a_i++; } } } if (plainArg != null) { if (body == null) { if (fn.ArgCount < 4 || !fn.Args[3].Calls(S.Braces)) { return(Reject(sink, arg, Localize.Localized("'{0}': to set or create a field or property, the method must have a body in braces {{}}.", a))); } body = fn.Args[3]; } args[i] = plainArg; LNode assignment; if (fieldName == paramName) { assignment = F.Call(S.Assign, F.Dot(F.@this, F.Id(fieldName)), F.Id(paramName)); } else { assignment = F.Call(S.Assign, F.Id(fieldName), F.Id(paramName)); } setStmts.Add(assignment); if (propOrFieldDecl != null) { propOrFieldDecls.Add(propOrFieldDecl); } } } if (body != null) // if this macro has been used... { var parts = fn.Args; parts[2] = parts[2].WithArgs(args); parts[3] = body.WithArgs(body.Args.InsertRange(0, setStmts)); fn = fn.WithArgs(parts); if (propOrFieldDecls.IsEmpty) { return(fn); } else { propOrFieldDecls.Add(fn); return(F.Call(S.Splice, propOrFieldDecls)); } } return(null); }
public LNode Attr(LNode attr, LNode node) { return node.PlusAttr(attr); }
static LNode TranslateWordAttr(LNode node, IMessageSink sink, Symbol attr) { //LNode result = TranslateId(node, attr); //if (result == null && node.ArgCount >= 1) { if (node.ArgCount < 1) return null; else { if (node.ArgCount > 1) return node.PlusAttr(F.Id(attr)).With(node.Args[0], node.Args.RemoveAt(0)); else return node.Args[0].PlusAttr(F.Id(attr)); } }