예제 #1
0
        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>();
            VList <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 + 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, ListExt.Single(_Symbol).Concat(vars))
                              .WithAttrs(input.Attrs.Add(F.Id(S.Static)).Add(F.Id(S.Readonly))));
            }
            return(F.Call(S.Splice, output));
        }
예제 #2
0
 public static VList <LNode> WithSpliced(this VList <LNode> list, int index, LNode node, Symbol listName = null)
 {
     if (node.Calls(listName ?? CodeSymbols.Splice))
     {
         return(list.InsertRange(index, node.Args));
     }
     else
     {
         return(list.Insert(index, node));
     }
 }
예제 #3
0
 public AltType(VList <LNode> classAttrs, LNode typeName, VList <LNode> baseTypes, AltType parentType)
 {
     _classAttrs = classAttrs;
     TypeName    = typeName;
     BaseTypes   = baseTypes;
     ParentType  = parentType;
     {
         LNode         stem;
         VList <LNode> a = default(VList <LNode>);
         if (TypeName.CallsMin(CodeSymbols.Of, 1) && (stem = TypeName.Args[0]) != null && (a = new VList <LNode>(TypeName.Args.Slice(1))).IsEmpty | true || (stem = TypeName) != null)
         {
             _typeNameStem = stem;
             _genericArgs  = a.ToWList();
         }
         else
         {
             _genericArgs = new WList <LNode>();
         }
     }
     if (ParentType != null)
     {
         BaseTypes.Insert(0, ParentType.TypeNameWithoutAttrs);
         bool changed = false;
         for (int i = 0; i < _genericArgs.Count; i++)
         {
             var arg       = _genericArgs[i];
             var parentArg = ParentType._genericArgs.FirstOrDefault(a => a.IsIdNamed(arg.Name));
             if (parentArg != null)
             {
                 var wheres       = new HashSet <LNode>(WhereTypes(arg));
                 int oldCount     = wheres.Count;
                 var parentWheres = WhereTypes(parentArg);
                 foreach (var where in parentWheres)
                 {
                     wheres.Add(where);
                 }
                 if (wheres.Count > oldCount)
                 {
                     arg             = arg.WithAttrs(arg.Attrs.Where(a => !a.Calls(S.Where)).Add(LNode.Call(S.Where, LNode.List(wheres))));
                     _genericArgs[i] = arg;
                     changed         = true;
                 }
             }
         }
         if (changed)
         {
             TypeName = LNode.Call(CodeSymbols.Of, LNode.List().Add(_typeNameStem).AddRange(_genericArgs));
         }
     }
     TypeNameWithoutAttrs = TypeName.Select(n => n.WithoutAttrs());
 }
예제 #4
0
			public AltType(VList<LNode> classAttrs, LNode typeName, VList<LNode> baseTypes, AltType parentType)
			{
				_classAttrs = classAttrs;
				TypeName = typeName;
				BaseTypes = baseTypes;
				ParentType = parentType;
				//matchCode (TypeName) {
				//	case $stem<$(..a)>, $stem: 
				//		_typeNameStem = stem;
				//		_genericArgs = a; 
				//  default:
				//		_genericArgs = new WList<LNode>();
				//}
				{	// Above matchCode expanded:
					LNode stem;
					VList<LNode> a = default(VList<LNode>);
					if (TypeName.CallsMin(CodeSymbols.Of, 1) && (stem = TypeName.Args[0]) != null && (a = new VList<LNode>(TypeName.Args.Slice(1))).IsEmpty | true || (stem = TypeName) != null) {
						_typeNameStem = stem;
						_genericArgs = a.ToWList();
					} else {
						_genericArgs = new WList<LNode>();
					}
				}
				if (ParentType != null) {
					BaseTypes.Insert(0, ParentType.TypeNameWithoutAttrs);
				
					// Search for all 'where' clauses on the ParentType and make sure OUR generic args have them too.
					bool changed = false;
					for (int i = 0; i < _genericArgs.Count; i++) {
						var arg = _genericArgs[i];
						var parentArg = ParentType._genericArgs.FirstOrDefault(a => a.IsIdNamed(arg.Name));
						if (parentArg != null) {
							var wheres = new HashSet<LNode>(WhereTypes(arg));
							int oldCount = wheres.Count;
							var parentWheres = WhereTypes(parentArg);
							foreach (var where in parentWheres)
								wheres.Add(where);
							if (wheres.Count > oldCount) {
								arg = arg.WithAttrs(arg.Attrs.SmartWhere(a => !a.Calls(S.Where))
								.Add(LNode.Call(S.Where, LNode.List(wheres))));
								_genericArgs[i] = arg;
								changed = true;
							}
						}
					}
					if (changed)
						TypeName = LNode.Call(CodeSymbols.Of, LNode.List().Add(_typeNameStem).AddRange(_genericArgs)).SetStyle(NodeStyle.Operator);
				}
				TypeNameWithoutAttrs = TypeName.Select(n => n.WithoutAttrs());
			}
예제 #5
0
 public void InsertItemInViewList <T>(object item)
 {
     if (VList != null)
     {
         try
         {
             VList.Insert(RemovedAt, (T)item);
         }
         catch (ArgumentOutOfRangeException)
         {
             VList.Add((T)item);
         }
         RemovedAt = -1;
     }
     else
     {
         AddItemToViewList <T>(item);
     }
 }
예제 #6
0
			public AltType(VList<LNode> classAttrs, LNode typeName, VList<LNode> baseTypes, AltType parentType)
			{
				_classAttrs = classAttrs;
				TypeName = typeName;
				BaseTypes = baseTypes;
				ParentType = parentType;
				{
					LNode stem;
					VList<LNode> a = default(VList<LNode>);
					if (TypeName.CallsMin(CodeSymbols.Of, 1) && (stem = TypeName.Args[0]) != null && (a = new VList<LNode>(TypeName.Args.Slice(1))).IsEmpty | true || (stem = TypeName) != null) {
						_typeNameStem = stem;
						_genericArgs = a.ToWList();
					} else {
						_genericArgs = new WList<LNode>();
					}
				}
				if (ParentType != null) {
					BaseTypes.Insert(0, ParentType.TypeNameWithoutAttrs);
					bool changed = false;
					for (int i = 0; i < _genericArgs.Count; i++) {
						var arg = _genericArgs[i];
						var parentArg = ParentType._genericArgs.FirstOrDefault(a => a.IsIdNamed(arg.Name));
						if (parentArg != null) {
							var wheres = new HashSet<LNode>(WhereTypes(arg));
							int oldCount = wheres.Count;
							var parentWheres = WhereTypes(parentArg);
							foreach (var where in parentWheres)
								wheres.Add(where);
							if (wheres.Count > oldCount) {
								arg = arg.WithAttrs(arg.Attrs.Where(a => !a.Calls(S.Where)).Add(LNode.Call(S.Where, LNode.List(wheres))));
								_genericArgs[i] = arg;
								changed = true;
							}
						}
					}
					if (changed)
						TypeName = LNode.Call(CodeSymbols.Of, LNode.List().Add(_typeNameStem).AddRange(_genericArgs));
				}
				TypeNameWithoutAttrs = TypeName.Select(n => n.WithoutAttrs());
			}
예제 #7
0
            public AltType(VList <LNode> classAttrs, LNode typeName, VList <LNode> baseTypes, AltType parentType)
            {
                _classAttrs = classAttrs;
                TypeName    = typeName;
                BaseTypes   = baseTypes;
                ParentType  = parentType;
                //matchCode (TypeName) {
                //	case $stem<$(..a)>, $stem:
                //		_typeNameStem = stem;
                //		_genericArgs = a;
                //  default:
                //		_genericArgs = new WList<LNode>();
                //}
                {                       // Above matchCode expanded:
                    LNode         stem;
                    VList <LNode> a = default(VList <LNode>);
                    if (TypeName.CallsMin(CodeSymbols.Of, 1) && (stem = TypeName.Args[0]) != null && (a = new VList <LNode>(TypeName.Args.Slice(1))).IsEmpty | true || (stem = TypeName) != null)
                    {
                        _typeNameStem = stem;
                        _genericArgs  = a.ToWList();
                    }
                    else
                    {
                        _genericArgs = new WList <LNode>();
                    }
                }
                if (ParentType != null)
                {
                    BaseTypes.Insert(0, ParentType.TypeNameWithoutAttrs);

                    // Search for all 'where' clauses on the ParentType and make sure OUR generic args have them too.
                    bool changed = false;
                    for (int i = 0; i < _genericArgs.Count; i++)
                    {
                        var arg       = _genericArgs[i];
                        var parentArg = ParentType._genericArgs.FirstOrDefault(a => a.IsIdNamed(arg.Name));
                        if (parentArg != null)
                        {
                            var wheres       = new HashSet <LNode>(WhereTypes(arg));
                            int oldCount     = wheres.Count;
                            var parentWheres = WhereTypes(parentArg);
                            foreach (var where in parentWheres)
                            {
                                wheres.Add(where);
                            }
                            if (wheres.Count > oldCount)
                            {
                                arg = arg.WithAttrs(arg.Attrs.SmartWhere(a => !a.Calls(S.Where))
                                                    .Add(LNode.Call(S.Where, LNode.List(wheres))));
                                _genericArgs[i] = arg;
                                changed         = true;
                            }
                        }
                    }
                    if (changed)
                    {
                        TypeName = LNode.Call(CodeSymbols.Of, LNode.List().Add(_typeNameStem).AddRange(_genericArgs)).SetStyle(NodeStyle.Operator);
                    }
                }
                TypeNameWithoutAttrs = TypeName.Select(n => n.WithoutAttrs());
            }
예제 #8
0
        public static LNode UseSymbolsCore(VList <LNode> symbolAttrs, VList <LNode> options, VList <LNode> body, IMacroContext context, bool inType)
        {
            // Decode options (TODO: invent a simpler approach)
            string prefix    = "sy_";
            var    inherited = new HashSet <Symbol>();

            foreach (var pair in MacroContext.GetOptions(options))
            {
                if (pair.Key.Name.Name == "prefix" && pair.Value.IsId)
                {
                    prefix = pair.Value.Name.Name;
                }
                else if (pair.Key.Name.Name == "inherit" && pair.Value.Value is Symbol)
                {
                    inherited.Add((Symbol)pair.Value.Value);
                }
                else if (pair.Key.Name.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.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>();
            VList <LNode> output  = body.SmartSelect(stmt => stmt.ReplaceRecursive(n => {
                if (!inType && n.ArgCount == 3)
                {
                    // Since we're outside any type, we must avoid creating symbol
                    // fields. When we cross into a type then we can start making
                    // Symbols by calling ourself recursively with inType=true
                    var kind = EcsValidators.SpaceDefinitionKind(n);
                    if (kind == S.Class || kind == S.Struct || kind == S.Interface || kind == S.Alias || kind == S.Trait)
                    {
                        var body2 = n.Args[2];
                        return(n.WithArgChanged(2, UseSymbolsCore(symbolAttrs, options, body2.Args, context, true).WithName(body2.Name)));
                    }
                }
                var sym = n.Value as Symbol;
                if (n.IsLiteral && sym != null)
                {
                    return(symbols[sym] = LNode.Id(prefix + 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, ListExt.Single(_Symbol).Concat(vars))
                              .WithAttrs(symbolAttrs.Add(F.Id(S.Static)).Add(F.Id(S.Readonly))));
            }
            return(F.Call(S.Splice, output));
        }
예제 #9
0
		public void TestEmptyListOperations()
		{
			VList<int> a = new VList<int>();
			VList<int> b = new VList<int>();
			a.AddRange(b);
			a.InsertRange(0, b);
			a.RemoveRange(0, 0);
			Assert.That(!a.Remove(0));
			Assert.That(a.IsEmpty);

			a.Add(1);
			b.AddRange(a);
			ExpectList(b, 1);
			b.RemoveAt(0);
			Assert.That(b.IsEmpty);
			b.InsertRange(0, a);
			ExpectList(b, 1);
			b.RemoveRange(0, 1);
			Assert.That(b.IsEmpty);
			b.Insert(0, a[0]);
			ExpectList(b, 1);
			b.Remove(a.Last);
			Assert.That(b.IsEmpty);
			
			AssertThrows<InvalidOperationException>(delegate() { a.NextIn(b); });
		}
예제 #10
0
		public void TestInsertRemove()
		{
			VList<int> list = new VList<int>(9);
			VList<int> list2 = new VList<int>(10, 11);
			list.Insert(0, 12);
			list.Insert(1, list2[1]);
			list.Insert(2, list2[0]);
			ExpectList(list, 12, 11, 10, 9);
			for (int i = 0; i < 9; i++)
				list.Insert(4, i);
			ExpectList(list, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);

			list2 = list;
			for (int i = 1; i <= 6; i++)
				list2.RemoveAt(i);
			ExpectList(list2, 12, 10, 8, 6, 4, 2, 0);
			ExpectList(list, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); // unchanged

			Assert.AreEqual(0, list2.Pop());
			list2.Insert(5, -2);
			ExpectList(list2, 12, 10, 8, 6, 4, -2, 2);
			list2.Insert(5, -1);
			ExpectList(list2, 12, 10, 8, 6, 4, -1, -2, 2);

			// Test changing items
			list = list2;
			for (int i = 0; i < list.Count; i++)
				list[i] = i;
			ExpectList(list, 0, 1, 2, 3, 4, 5, 6, 7);
			ExpectList(list2, 12, 10, 8, 6, 4, -1, -2, 2);

			list2.Clear();
			ExpectList(list2);
			Assert.AreEqual(5, list[5]);
		}