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)); }
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)); } }
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()); }
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()); }
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); } }
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()); }
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()); }
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)); }
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); }); }
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]); }