コード例 #1
0
ファイル: ForwardingMacro.cs プロジェクト: murven/Loyc
        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);
        }
コード例 #2
0
        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);
        }
コード例 #3
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)));
                    }
                }
            }
コード例 #4
0
ファイル: Literals.out.cs プロジェクト: dadhi/ecsharp
        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);
        }
コード例 #5
0
ファイル: LNodeFactory.cs プロジェクト: bel-uwa/Loyc
 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);
     }
 }
コード例 #6
0
        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);
        }
コード例 #7
0
        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));
        }
コード例 #8
0
ファイル: Prelude.Les.cs プロジェクト: jonathanvdc/Loyc
 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)));
         }
     }
 }
コード例 #9
0
ファイル: LNodeFactory.cs プロジェクト: jonathanvdc/Loyc
		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;
		}
コード例 #10
0
ファイル: EcsParserGrammar.cs プロジェクト: BingjieGao/Loyc
		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
		}
コード例 #11
0
ファイル: Prelude.cs プロジェクト: BingjieGao/Loyc
		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));
			}
		}
コード例 #12
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));
					}
				}
			}
コード例 #13
0
		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);
		}
コード例 #14
0
        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);
                }
            }
        }
コード例 #15
0
ファイル: LNodeFactory.cs プロジェクト: jonathanvdc/Loyc
 public LNode Attr(LNode attr, LNode node)
 {
     return(node.PlusAttr(attr));
 }
コード例 #16
0
        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);
        }
コード例 #17
0
        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);
        }
コード例 #18
0
ファイル: LNodeFactory.cs プロジェクト: jonathanvdc/Loyc
		public LNode Attr(LNode attr, LNode node)
		{
			return node.PlusAttr(attr);
		}
コード例 #19
0
ファイル: Prelude.cs プロジェクト: Shaykh/Loyc
		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));
			}
		}