public static LNode static_matchCode(LNode node, IMacroContext context)
		{
			if (node.AttrNamed(S.Static) == null && !node.HasSpecialName)
				return null; // handled by normal matchCode macro

			var args_body = context.GetArgsAndBody(false);
			VList<LNode> args = args_body.Item1, body = args_body.Item2;
			if (args.Count != 1)
				return Reject(context, args[1], "Expected only one expression to match");

			var expression = context.PreProcess(AutoStripBraces(args[0]));

			var cases = GetCases(body, context.Sink);
			// The `default:` case is represented by an empty list of patterns.
			if (cases.WithoutLast(1).Any(pair => pair.Key.IsEmpty))
				context.Write(Severity.Error, node, "The `default:` case must be the last one, because the cases are tested in the order they appear, so no case after `default:` can be matched.");

			MMap<Symbol, LNode> captures = new MMap<Symbol, LNode>();
			foreach (Pair<VList<LNode>, VList<LNode>> pair in cases)
			{
				var patterns = pair.Key.IsEmpty ? new VList<LNode>((LNode)null) : pair.Key;
				foreach (var pattern in patterns)
				{
					captures.Clear();
					VList<LNode> _;
					if (pattern == null || LNodeExt.MatchesPattern(expression, pattern, ref captures, out _)) {
						captures[_hash] = expression; // define $#
						captures.Remove(__);
						return ReplaceCaptures(pair.Value.AsLNode(S.Splice), captures);
					}
				}
			}
			return F.Call(S.Splice); // none of the cases matched
		}
Beispiel #2
0
 void SetData(IListSource <T> data)
 {
     _hSet = new Dictionary <T, T>(data.Count);
     _mSet = new MMap <T, T>();
     _iSet = new Map <T, T>(data.Select(P));
     foreach (T item in data)
     {
         _hSet.Add(item, item);
         _mSet.Add(item, item);
     }
 }
Beispiel #3
0
        public CMap GetCombatMap(MapInitInfo info)
        {
            var builder = new MapBuilder();
            var hexMap  = builder.GetMap(info.Rows, info.Cols, ViewParams.OFFSET, ViewParams.MAP_CENTER);
            var map     = new MMap(hexMap);

            this._map.SetMap(map);
            this.InitTiles(info);
            this.InitArmies(info);
            this.InitChars(info);
            return(this._map);
        }
Beispiel #4
0
 static void AddCapture(MMap <Symbol, LNode> captures, LNode cap, Slice_ <LNode> items)
 {
     Debug.Assert(cap.Calls(S.Substitute, 1) && cap.Args.Last.IsId);
     if (items.Count == 1)
     {
         AddCapture(captures, cap.Args.Last.Name, items[0]);
     }
     else
     {
         AddCapture(captures, cap.Args.Last.Name, F.Call(S.Splice, items));
     }
 }
Beispiel #5
0
 internal static void AddMacro(MMap <Symbol, VList <MacroInfo> > macros, MacroInfo info)
 {
     foreach (string name in info.Names)
     {
         var nameS = (Symbol)name;
         var cases = macros[nameS, VList <MacroInfo> .Empty];
         if (!cases.Any(existing => existing.Macro == info.Macro))
         {
             macros[nameS] = cases.Add(info);
         }
     }
 }
Beispiel #6
0
        public static byte[] encode_node_k(MMap mm, INode node)
        {
            var nk     = (NodeK)(object)node;
            var out1   = str_pstr(nk.name);
            var id1    = fetch(nk.nid, mm.ks);
            var stream = new MemoryStream();
            var bw     = new BinaryWriter(stream);

            bw.Write(out1);
            bw.Write(encode_i16(id1));
            return(stream.ToArray());
        }
Beispiel #7
0
 static LNode TryReplaceHere(LNode node, Pair <LNode, LNode>[] patterns, MMap <Symbol, LNode> temp)
 {
     for (int i = 0; i < patterns.Length; i++)
     {
         temp.Clear();
         LNode r = TryReplaceHere(node, patterns[i].A, patterns[i].B, temp, patterns);
         if (r != null)
         {
             return(r);
         }
     }
     return(null);
 }
Beispiel #8
0
 private static bool IsReachable(Vector3 loc)
 {
     if (!MMap.GoodVector3(loc))
     {
         return(false);
     }
     return(Main.smap.IsWalkable((int)loc.X + 1, (int)loc.Y, (int)loc.Z) ||
            Main.smap.IsWalkable((int)loc.X - 1, (int)loc.Y, (int)loc.Z) ||
            Main.smap.IsWalkable((int)loc.X, (int)loc.Y + 1, (int)loc.Z) ||
            Main.smap.IsWalkable((int)loc.X, (int)loc.Y - 1, (int)loc.Z) ||
            Main.smap.IsWalkable((int)loc.X, (int)loc.Y, (int)loc.Z + 1) ||
            Main.smap.IsWalkable((int)loc.X, (int)loc.Y, (int)loc.Z - 1));
 }
Beispiel #9
0
 static bool AttributesMatch(LNode candidate, LNode pattern, ref MMap <Symbol, LNode> captures, out LNodeList unmatchedAttrs)
 {
     if (pattern.HasPAttrs())
     {
         unmatchedAttrs = LNode.List();
         return(ListMatches(candidate.Attrs, pattern.Attrs, ref captures, ref unmatchedAttrs));
     }
     else
     {
         unmatchedAttrs = candidate.Attrs;
     }
     return(true);
 }
Beispiel #10
0
        static void AddCapture(MMap <Symbol, LNode> captures, LNode cap, Slice_ <LNode> items)
        {
            LNode capId = GetCaptureIdentifier(cap);

            if (items.Count == 1)
            {
                AddCapture(captures, capId.Name, items[0]);
            }
            else
            {
                AddCapture(captures, capId.Name, F.Call(S.Splice, items));
            }
        }
Beispiel #11
0
        /// <summary>Determines whether one Loyc tree "matches" another. This is
        /// different from a simple equality test in that (1) trivia atributes do
        /// not have to match, and (2) the pattern can contain placeholders represented
        /// by calls to $ (the substitution operator) with an identifier as a parameter.
        /// Placeholders match any subtree, and are saved to the <c>captures</c> map.
        /// </summary>
        /// <param name="candidate">A node that you want to compare with a 'pattern'.</param>
        /// <param name="pattern">A syntax tree that may contain placeholders. A
        /// placeholder is a call to the $ operator with one parameter, which must
        /// be either (A) a simple identifier, or (B) the ".." operator with a simple
        /// identifier as its single parameter. Otherwise, the $ operator is treated
        /// literally as something that must exist in <c>candidate</c>). The subtree
        /// in <c>candidate</c> corresponding to the placeholder is saved in
        /// <c>captures</c>.</param>
        /// <param name="captures">A table that maps placeholder names from
        /// <c>pattern</c> to subtrees in <c>candidate</c>. You can set your map to
        /// null and a map will be created for you if necessary. If you already have
        /// a map, you should clear it before calling this method.</param>
        /// <param name="unmatchedAttrs">On return, a list of trivia attributes in
        /// <c>candidate</c> that were not present in <c>pattern</c>.</param>
        /// <returns>true if <c>pattern</c> matches <c>candidate</c>, false otherwise.</returns>
        /// <remarks>
        /// Attributes in patterns are not yet supported.
        /// <para/>
        /// This method supports multi-part captures, which are matched to
        /// placeholders whose identifier either (A) has a #params attribute or
        /// (B) has the unary ".." operator applied to it (for example, if
        /// the placeholder is called p, this is written as <c>$(params p)</c> in
        /// EC#.) A placeholder that looks like this can match multiple arguments or
        /// multiple statements in the <c>candidate</c> (or <i>no</i> arguments, or
        /// no statements), and will become a #splice(...) node in <c>captures</c>
        /// if it matches multiple items. Multi-part captures are often useful for
        /// getting lists of statements before and after some required element,
        /// e.g. <c>{ $(params before); MatchThis($something); $(params after); }</c>
        /// <para/>
        /// If the same placeholder appears twice then the two matching items are
        /// combined into a single output node (calling #splice).
        /// <para/>
        /// If matching is unsuccessful, <c>captures</c> and <c>unmatchedAttrs</c>
        /// may contain irrelevant information gathered during the attempt to match.
        /// <para/>
        /// In EC#, the quote(...) macro can be used to create the LNode object for
        /// a pattern.
        /// </remarks>
        public static bool MatchesPattern(this LNode candidate, LNode pattern, ref MMap <Symbol, LNode> captures, out LNodeList unmatchedAttrs)
        {
            // [$capture] (...)
            if (!AttributesMatch(candidate, pattern, ref captures, out unmatchedAttrs))
            {
                return(false);
            }

            // $capture or $(..capture)
            LNode sub = GetCaptureIdentifier(pattern);

            if (sub != null)
            {
                captures = captures ?? new MMap <Symbol, LNode>();
                AddCapture(captures, sub.Name, candidate);
                unmatchedAttrs = LNodeList.Empty;                 // The attrs (if any) were captured
                return(true);
            }

            var kind = candidate.Kind;

            if (kind != pattern.Kind)
            {
                return(false);
            }

            if (kind == LNodeKind.Id && candidate.Name != pattern.Name)
            {
                return(false);
            }
            if (kind == LNodeKind.Literal)
            {
                return(object.Equals(candidate.Value, pattern.Value));
            }
            else if (kind == LNodeKind.Call)
            {
                if (!MatchesPatternNested(candidate.Target, pattern.Target, ref captures, ref unmatchedAttrs))
                {
                    return(false);
                }
                var cArgs = candidate.Args;
                var pArgs = pattern.Args;

                return(ListMatches(cArgs, pArgs, ref captures, ref unmatchedAttrs));
            }
            else             // kind == Id
            {
                return(true);
            }
        }
Beispiel #12
0
        static bool MatchesPatternNested(LNode candidate, LNode pattern, ref MMap <Symbol, LNode> captures, ref RVList <LNode> trivia)
        {
            RVList <LNode> unmatchedAttrs;

            if (!MatchesPattern(candidate, pattern, ref captures, out unmatchedAttrs))
            {
                return(false);
            }
            if (unmatchedAttrs.Any(a => !a.IsTrivia))
            {
                return(false);
            }
            trivia.AddRange(unmatchedAttrs);
            return(true);
        }
Beispiel #13
0
		public static LNode staticMatches(LNode node, IMacroContext context)
		{
			if (node.ArgCount != 2)
				return null;

			LNode candidate = context.PreProcess(AutoStripBraces(node[0]));
			LNode pattern = AutoStripBraces(node[1]);
			MMap<Symbol, LNode> captures = new MMap<Symbol, LNode>();
			VList<LNode> _;
			if (LNodeExt.MatchesPattern(candidate, pattern, ref captures, out _)) {
				SetSyntaxVariables(captures, context);
				return F.True;
			}
			return F.False;
		}
Beispiel #14
0
        protected Precedence FindPrecedence(MMap <object, Precedence> table, object symbol, Precedence @default, bool cacheWordOp)
        {
            // You can see the official rules in the LesPrecedence documentation.
            // Rule 1 (for >= <= != ==) is covered by the pre-populated contents
            // of the table, and the pre-populated table helps interpret rules
            // 3-4 also.
            Precedence prec;

            if (table.TryGetValue(symbol, out prec))
            {
                return(prec);
            }

            string sym = (symbol ?? "").ToString();

            if (sym == "")
            {
                return(@default);                       // empty operator!
            }
            // Note: all one-character operators should have been found in the table
            char first = sym[0], last = sym[sym.Length - 1];

            if (last == '=' && first != '=' && table == this[OperatorShape.Infix].A)
            {
                return(table[symbol] = table[S.Assign]);
            }

            var twoCharOp = GSymbol.Get(first.ToString() + last);

            if (table.TryGetValue(twoCharOp, out prec))
            {
                return(table[symbol] = prec);
            }

            var oneCharOp = GSymbol.Get(last.ToString());

            if (table.TryGetValue(oneCharOp, out prec))
            {
                return(table[symbol] = prec);
            }

            // Default precedence is used for word operators
            if (cacheWordOp)
            {
                table[symbol] = @default;
            }
            return(@default);
        }
Beispiel #15
0
        internal static void AddMacro(MMap <Symbol, List <MacroInfo> > macros, MacroInfo info)
        {
            List <MacroInfo> cases;

            if (!macros.TryGetValue(info.Name, out cases))
            {
                macros[info.Name] = cases = new List <MacroInfo>();
                cases.Add(info);
            }
            else
            {
                if (!cases.Any(existing => existing.Macro == info.Macro))
                {
                    cases.Add(info);
                }
            }
        }
Beispiel #16
0
 static LNode ReplaceCaptures(LNode node, MMap <Symbol, LNode> captures)
 {
     if (captures.Count != 0)
     {
         // TODO: EXPAND SPLICES! Generally it works anyway though because
         // the macro processor has built-in support for #splice.
         return(node.ReplaceRecursive(n => {
             LNode sub, cap;
             if (n.Calls(S.Substitute, 1) && (sub = n.Args.Last).IsId && captures.TryGetValue(sub.Name, out cap))
             {
                 return cap;
             }
             return null;
         }));
     }
     return(node);
 }
        public async void SizedButton_Clicked(object sender, EventArgs e)
        {
            //JsonValue value = JsonValue.Parse(@"{ ""name"":""Prince Charming"", ...");
            //JsonObject result = value as JsonObject;
            Location startLocation = await Geolocation.GetLastKnownLocationAsync();

            NetworkAccess current = Connectivity.NetworkAccess;

            if (current == NetworkAccess.Internet)
            {
                double            shortestDistance = 0;
                Models.Directions directions       = new Models.Directions();
                Location          neareatPark      = new Location();
                foreach (Pin pin in MMap.Pins)
                {
                    Location          endLocation    = new Location(pin.Position.Latitude, pin.Position.Longitude);
                    Models.Directions tempDirections = await DirectionsMethods.GetDirectionsInfo(startLocation.Latitude,
                                                                                                 endLocation.Latitude, startLocation.Longitude, endLocation.Longitude);

                    if (tempDirections != null)
                    {
                        double tempDistance = DirectionsMethods.GetDistance(tempDirections);
                        if (shortestDistance == 0 || shortestDistance > tempDistance)
                        {
                            neareatPark      = endLocation;
                            shortestDistance = tempDistance;
                            directions       = tempDirections;
                        }
                    }
                }

                //map.MoveToRegion(MapSpan.FromCenterAndRadius(new Position(neareatPark.Latitude, neareatPark.Longitude),
                //                                Distance.FromKilometers(.1)));
                //foreach (Models.Route route in directions.Routes)
                //{
                //    foreach (Models.Leg leg in route.legs)
                //    {
                //        map.LoadRoutes(leg.steps);
                //    }
                //}
                foreach (Models.Route route in directions.Routes)
                {
                    MMap.LoadRoutes(route.overview_polyline);
                }
            }
        }
Beispiel #18
0
        Precedence FindPrecedence(MMap <object, Precedence> table, object symbol, Precedence @default)
        {
            // You can see the official rules in the LesPrecedence documentation.
            // Rule 1 (for >= <= != ==) is covered by the pre-populated contents
            // of the table, and the pre-populated table helps interpret rules
            // 3-4 also.
            Precedence prec;

            if (table.TryGetValue(symbol, out prec))
            {
                return(prec);
            }

            string sym = symbol.ToString();

            if (sym == "")
            {
                return(prec);                       // yikes!
            }
            char first = sym[0], last = sym[sym.Length - 1];

            // All one-character operators should be found in the table

            if (table == _infixPrecedence && last == '=')
            {
                return(table[symbol] = table[S.Assign]);
            }

            var twoCharOp = GSymbol.Get(first.ToString() + last);

            if (table.TryGetValue(twoCharOp, out prec))
            {
                return(table[symbol] = prec);
            }

            var oneCharOp = GSymbol.Get(last.ToString());

            if (table.TryGetValue(oneCharOp, out prec))
            {
                return(table[symbol] = prec);
            }

            // Default precedence is used for word operators
            return(table[symbol] = @default);
        }
Beispiel #19
0
        public static LNode staticMatches(LNode node, IMacroContext context)
        {
            if (node.ArgCount != 2)
            {
                return(null);
            }

            LNode candidate = context.PreProcess(UnwrapBraces(node[0]));
            LNode pattern   = UnwrapBraces(node[1]);
            MMap <Symbol, LNode> captures = new MMap <Symbol, LNode>();

            if (LNodeExt.MatchesPattern(candidate, pattern, ref captures, out LNodeList _))
            {
                SetSyntaxVariables(captures, context);
                return(F.True);
            }
            return(F.False);
        }
Beispiel #20
0
        static LNode TryReplaceHere(LNode node, LNode pattern, LNode replacement, MMap <Symbol, LNode> captures, Pair <LNode, LNode>[] allPatterns)
        {
            if (LNodeExt.MatchesPattern(node, pattern, ref captures, out LNodeList attrs))
            {
                foreach (var pair in captures)
                {
                    var input = pair.Value.AsList(S.Splice);
                    int c;
                    var output = Replace(input, allPatterns, out c);
                    if (output != input)
                    {
                        captures[pair.Key] = output.AsLNode(S.Splice);
                    }
                }
                return(ReplaceCaptures(replacement, captures).PlusAttrs(attrs));
            }

            return(null);
        }
Beispiel #21
0
        ToiletTip tip;//弹窗
        // 构造函数
        public MainPage()
        {
            InitializeComponent();
            this.mapPanel.Children.Add(map = new MMap());
            mapLocationLayer = new MapLayer();
            map.Children.Add(mapLocationLayer);
            map.Children.Add(mapWalkingLayer = new MapLayer());
            mapToiletLayer = new MapLayer();
            map.Children.Add(mapToiletLayer);
            map.Zoom = 11d;
            map.ToolBar = Visibility.Visible;

            // 用于本地化 ApplicationBar 的示例代码
            //BuildLocalizedApplicationBar();
            this.Loaded += MainPage_Loaded;
            map.MapLoaded += map_MapLoaded;
            // map.Hold += map_Hold;
            Canvas.SetTop(btnLoaction, this.LayoutRoot.ActualHeight - 20);
        }
Beispiel #22
0
        public static LNode static_matchCode(LNode node, IMacroContext context)
        {
            if (node.AttrNamed(S.Static) == null && !node.HasSpecialName)
            {
                return(null);                // handled by normal matchCode macro
            }
            var           args_body = context.GetArgsAndBody(false);
            VList <LNode> args = args_body.Item1, body = args_body.Item2;

            if (args.Count != 1)
            {
                return(Reject(context, args[1], "Expected only one expression to match"));
            }

            var expression = context.PreProcess(AutoStripBraces(args[0]));

            var cases = GetCases(body, context.Sink);

            // The `default:` case is represented by an empty list of patterns.
            if (cases.WithoutLast(1).Any(pair => pair.Key.IsEmpty))
            {
                context.Write(Severity.Error, node, "The `default:` case must be the last one, because the cases are tested in the order they appear, so no case after `default:` can be matched.");
            }

            MMap <Symbol, LNode> captures = new MMap <Symbol, LNode>();

            foreach (Pair <VList <LNode>, VList <LNode> > pair in cases)
            {
                var patterns = pair.Key.IsEmpty ? new VList <LNode>((LNode)null) : pair.Key;
                foreach (var pattern in patterns)
                {
                    captures.Clear();
                    VList <LNode> _;
                    if (pattern == null || LNodeExt.MatchesPattern(expression, pattern, ref captures, out _))
                    {
                        captures[_hash] = expression;                         // define $#
                        captures.Remove(__);
                        return(ReplaceCaptures(pair.Value.AsLNode(S.Splice), captures));
                    }
                }
            }
            return(F.Call(S.Splice));            // none of the cases matched
        }
Beispiel #23
0
		/// <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;
		}
Beispiel #24
0
 /// <summary>Finds capture variables like <c>$x</c> and replaces them with values
 /// from <c>captures</c> (e.g. <c>captures[(Symbol)"x"]</c> for <c>$x</c>)</summary>
 public static LNode ReplaceCaptures(LNode outputSpec, MMap <Symbol, LNode> captures)
 {
     if (captures.Count != 0)
     {
         // TODO: EXPAND SPLICES! Generally it works anyway though because
         // the macro processor has built-in support for #splice.
         return(outputSpec.ReplaceRecursive(n => {
             LNode id, cap;
             if ((id = LNodeExt.GetCaptureIdentifier(n)) != null)
             {
                 if (captures.TryGetValue(id.Name, out cap))
                 {
                     return cap;
                 }
             }
             return null;
         }));
     }
     return(outputSpec);
 }
Beispiel #25
0
        public static void Main(params string[] args)
        {
            MMap <string, Pair <string, string> > KnownOptions = LeMP.Compiler.KnownOptions;

            if (args.Length != 0)
            {
                Severity minSeverity = Severity.NoteDetail;
                                #if DEBUG
                minSeverity = Severity.DebugDetail;
                                #endif
                var filter = new SeverityMessageFilter(ConsoleMessageSink.Value, minSeverity - 1);

                LeMP.Compiler c       = new LeMP.Compiler(filter, typeof(LeMP.Prelude.BuiltinMacros));
                var           argList = args.ToList();
                var           options = c.ProcessArguments(argList, false, true);
                if (!LeMP.Compiler.MaybeShowHelp(options, KnownOptions))
                {
                    LeMP.Compiler.WarnAboutUnknownOptions(options, ConsoleMessageSink.Value,
                                                          KnownOptions.With("nologo", Pair.Create("", "")));
                    if (c.Files.Count == 0)
                    {
                        ConsoleMessageSink.Value.Warning(null, "No files specified, stopping.");
                    }
                    else
                    {
                        c.MacroProcessor.PreOpenedNamespaces.Add(GSymbol.Get("LeMP.Prelude.Les"));
                        c.MacroProcessor.PreOpenedNamespaces.Add(GSymbol.Get("LeMP.Prelude"));
                        c.MacroProcessor.PreOpenedNamespaces.Add(Loyc.LLPG.Macros.MacroNamespace);
                        c.AddMacros(typeof(LeMP.StandardMacros).Assembly);
                        c.AddMacros(Assembly.GetExecutingAssembly());
                        c.Run();
                    }
                }
            }
            else
            {
                LeMP.Compiler.ShowHelp(KnownOptions.OrderBy(p => p.Key));
                Test_LLLPG();
            }
        }
Beispiel #26
0
        public static byte[] encode_node_u(MMap mm, INode node)
        {
            var stream = new MemoryStream();
            var bw     = new BinaryWriter(stream);
            var nu     = ((NodeU)node);
            var len1   = nu.inputs.l.Count;
            var len2   = nu.outputs.Count;

            bw.Write(Osc.str_pstr(nu.name));
            bw.Write(Osc.encode_i8((int)nu.rate));
            bw.Write(Osc.encode_i16(len1));
            bw.Write(Osc.encode_i16(len2));
            for (var ind = 0; ind < len1; ind = ind + 1)
            {
                bw.Write(encode_input(mk_input(mm, nu.inputs.l[ind])));
            }
            for (var ind = 0; ind < len2; ind = ind + 1)
            {
                bw.Write(Osc.encode_i8((int)nu.outputs[ind]));
            }
            return(stream.ToArray());
        }
Beispiel #27
0
 public void SetMap(MMap m)
 {
     this._map = m;
 }
        public MapPage()
        {
            try
            {
                InitializeComponent();
                if (AlreadyLoaded)
                {
                    MProgressBar.IsVisible = false;
                }
                else
                {
//                    MMap.IsVisible = false;
                    Device.StartTimer(TimeSpan.FromSeconds(.5), () =>
                    {
                        if (!(MProgressBar.Progress < 1))
                        {
                            return(false);
                        }
                        Device.BeginInvokeOnMainThread(() =>
                                                       MProgressBar.ProgressTo(MProgressBar.Progress + 0.005, 500, Easing.Linear));
                        return(true);
                    });
                }
#if __ANDROID__
                NavigationPage.SetHasNavigationBar(this, false);
#endif
#if __IOS__
                StackLayout NavStack = new StackLayout()
                {
                    Children =
                    {
                        new Label()
                        {
                            Text = "Cycles"
                        }
                    }
                };
                NavigationPage.SetTitleView(this, NavStack);
#endif
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
//                Crashlytics.Crashlytics.LogException(Java.Lang.Throwable.FromException(ex));
            }

            BindingContext = this;

            var pin = new CustomPin
            {
                Type     = PinType.Place,
                PinType  = CustomPin.CustomType.Park,
                Position = new Position(6.672219, 3.161639),
                Label    = "Cycles Point @Cafe 2",
                Address  = "Cafeteria 2, Goodness Rd, Canaan Land, Ota",
                MarkerId = "P2"
            };
            var pin2 = new CustomPin
            {
                Type     = PinType.Place,
                PinType  = CustomPin.CustomType.Park,
                Position = new Position(6.67369, 3.15922),
                Label    = "Cycles Point @CST",
                Address  = "College of Science and Tech, CU, Canaan Land, Ota",
                MarkerId = "P3"
            };
            MMap.CustomPins = new List <CustomPin> {
                pin, pin2
            };
            MMap.MoveToRegion(MapSpan.FromCenterAndRadius(new Position(LAGOS_LATITUDE, LAGOS_LONGITUDE), new Distance(15000d)));

//            MMap.Pins.Add(pin);
//            MMap.Pins.Add(pin2);
            MessagingCenter.Subscribe <MapPageRenderer>(this, "Scanner Opened", async(mainActivity) =>
            {
                var scanPage = new CustomBarcodeScanner();
                if (Application.Current.MainPage.Navigation.ModalStack.Count == 0)
                {
                    await Application.Current.MainPage.Navigation.PushModalAsync(scanPage);
                }
            });
            MessagingCenter.Subscribe <MainActivity>(this, "Close Scanner", async(sender) =>
            {
                if (Application.Current.MainPage.Navigation.ModalStack.Count > 0)
                {
                    await Application.Current.MainPage.Navigation.PopModalAsync();
                }
            });
            MessagingCenter.Subscribe <GraphicBarcodeTracker>(this, "Close Scanner", async(sender) =>
            {
                if (Application.Current.MainPage.Navigation.ModalStack.Count > 0)
                {
                    await Application.Current.MainPage.Navigation.PopModalAsync();
                }
            });
        }
Beispiel #29
0
        static bool CaptureGroup(ref int c, ref int p, RVList <LNode> cArgs, RVList <LNode> pArgs, ref MMap <Symbol, LNode> captures, ref RVList <LNode> attrs)
        {
            Debug.Assert(IsParamsCapture(pArgs[p]));
            // The goal now is to find a sequence of nodes in cArgs that matches
            // the sequence pArgs[p+1 .. p+x] where x is the maximum value such
            // that none of the nodes in the sequence are $(params caps).
            int saved_p = p, saved_c = c;
            var savedCaptures = captures.AsImmutable();
            var savedAttrs    = attrs;
            int captureSize   = 0;

            for (;; captureSize++)
            {
                for (p++, c += captureSize; ; c++, p++)
                {
                    // If we run out of pArgs, great, we're done; if we run out
                    // of cArgs, the match fails, unless all remaining pArgs are
                    // $(params caps).
                    if (p >= pArgs.Count || IsParamsCapture(pArgs[p]))
                    {
                        goto done_group;
                    }
                    else
                    {
                        if (c >= cArgs.Count)
                        {
                            return(false);
                        }
                        if (!MatchesPatternNested(cArgs[c], pArgs[p], ref captures, ref attrs))
                        {
                            goto continue_group;
                        }
                    }
                }
                continue_group :;
                p        = saved_p;
                c        = saved_c;
                attrs    = savedAttrs;
                captures = savedCaptures.AsMutable();
            }
done_group:
            AddCapture(captures, pArgs[saved_p], cArgs.Slice(saved_c, captureSize));
            return(true);
        }
Beispiel #30
0
		/// <summary>Finds capture variables like <c>$x</c> and replaces them with values
		/// from <c>captures</c> (e.g. <c>captures[(Symbol)"x"]</c> for <c>$x</c>)</summary>
		public static LNode ReplaceCaptures(LNode outputSpec, MMap<Symbol, LNode> captures)
		{
			if (captures.Count != 0)
			{
				// TODO: EXPAND SPLICES! Generally it works anyway though because 
				// the macro processor has built-in support for #splice.
				return outputSpec.ReplaceRecursive(n => {
					LNode id, cap;
					if ((id = LNodeExt.GetCaptureIdentifier(n)) != null) {
						if (captures.TryGetValue(id.Name, out cap))
							return cap;
					}
					return null;
				});
			}
			return outputSpec;
		}
Beispiel #31
0
		public static LNode replaceFn(LNode node, IMacroContext context1)
		{
			var retType = node.Args[0, LNode.Missing].Name;
			if (retType != _replace && retType != _define)
				return null;
			LNode replaceKw, macroName, args, body;
			if (EcsValidators.MethodDefinitionKind(node, out replaceKw, out macroName, out args, out body, allowDelegate: false) != S.Fn || body == null)
				return null;

			MacroMode mode, modes = 0;
			var leftoverAttrs = node.Attrs.SmartWhere(attr =>
			{
				if (attr.IsId && Loyc.Compatibility.EnumStatic.TryParse(attr.Name.Name, out mode))
				{
					modes |= mode;
					return false;
				}
				return true;
			});

			LNode pattern = F.Call(macroName, args.Args).PlusAttrs(leftoverAttrs);
			LNode replacement = body.AsList(S.Braces).AsLNode(S.Splice).PlusAttrs(replaceKw.Attrs);
			replacement.Style &= ~NodeStyle.OneLiner;

			WarnAboutMissingDollarSigns(args, context1, pattern, replacement);

			// Note: we could fill out the macro's Syntax and Description with the 
			// pattern and replacement converted to strings, but it's generally a 
			// waste of CPU time as those strings are usually not requested.
			var lma = new LexicalMacroAttribute(
				string.Concat(macroName.Name, "(", args.Args.Count.ToString(), " args)"), "", macroName.Name.Name);
			var macroInfo = new MacroInfo(null, lma, (candidate, context2) =>
			{
				MMap<Symbol, LNode> captures = new MMap<Symbol, LNode>();
				VList<LNode> unmatchedAttrs;
				if (candidate.MatchesPattern(pattern, ref captures, out unmatchedAttrs))
				{
					return ReplaceCaptures(replacement, captures).PlusAttrsBefore(unmatchedAttrs);
				}
				return null;
			}) {
				Mode = modes
			};
			context1.RegisterMacro(macroInfo);
			return F.Splice();
		}
Beispiel #32
0
		static bool MatchThenParams(VList<LNode> cArgs, VList<LNode> pArgs, LNode paramsCap, ref MMap<Symbol, LNode> captures, ref VList<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;
		}
Beispiel #33
0
		static bool MatchesPatternNested(LNode candidate, LNode pattern, ref MMap<Symbol, LNode> captures, ref VList<LNode> trivia)
		{
			VList<LNode> unmatchedAttrs;
			if (!MatchesPattern(candidate, pattern, ref captures, out unmatchedAttrs))
				return false;
			if (unmatchedAttrs.Any(a => !a.IsTrivia))
				return false;
			trivia.AddRange(unmatchedAttrs);
			return true;
		}
Beispiel #34
0
		static void AddCapture(MMap<Symbol, LNode> captures, LNode cap, Slice_<LNode> items)
		{
			LNode capId = GetCaptureIdentifier(cap);
			if (items.Count == 1)
				AddCapture(captures, capId.Name, items[0]);
			else
				AddCapture(captures, capId.Name, F.Call(S.Splice, items));
		}
Beispiel #35
0
		protected Precedence FindPrecedence(MMap<object,Precedence> table, object symbol, Precedence @default, bool cacheWordOp)
		{
			// You can see the official rules in the LesPrecedence documentation.
			// Rule 1 (for >= <= != ==) is covered by the pre-populated contents 
			// of the table, and the pre-populated table helps interpret rules 
			// 3-4 also.
			Precedence prec;
			if (table.TryGetValue(symbol, out prec))
				return prec;

			string sym = (symbol ?? "").ToString();
			if (sym == "") return @default; // empty operator!
			// Note: all one-character operators should have been found in the table
			char first = sym[0], last = sym[sym.Length - 1];

			if (last == '=' && first != '=' && table == this[OperatorShape.Infix].A)
				return table[symbol] = table[S.Assign];
			
			var twoCharOp = GSymbol.Get(first.ToString() + last);
			if (table.TryGetValue(twoCharOp, out prec))
				return table[symbol] = prec;

			var oneCharOp = GSymbol.Get(last.ToString());
			if (table.TryGetValue(oneCharOp, out prec))
				return table[symbol] = prec;

			// Default precedence is used for word operators
			if (cacheWordOp)
				table[symbol] = @default;
			return @default;
		}
Beispiel #36
0
		/// <summary>Determines whether one Loyc tree "matches" another. This is 
		/// different from a simple equality test in that (1) trivia atributes do 
		/// not have to match, and (2) the pattern can contain placeholders represented
		/// by calls to $ (the substitution operator) with an identifier as a parameter.
		/// Placeholders match any subtree, and are saved to the <c>captures</c> map.
		/// </summary>
		/// <param name="candidate">A node that you want to compare with a 'pattern'.</param>
		/// <param name="pattern">A syntax tree that may contain placeholders. A 
		/// placeholder is a call to the $ operator with one parameter, which must 
		/// be a simple identifier (otherwise the $ operator is treated literally as
		/// something that must exist in <c>candidate</c>). The subtree in 
		/// <c>candidate</c> corresponding to the placeholder is saved in <c>captures</c>.</param>
		/// <param name="captures">A table that maps placeholder names from 
		/// <c>pattern</c> to subtrees in <c>candidate</c>. You can set your map to 
		/// null and a map will be created for you if necessary. If you already have
		/// a map, you should clear it before calling this method.</param>
		/// <param name="unmatchedAttrs">On return, a list of trivia attributes in 
		/// <c>candidate</c> that were not present in <c>pattern</c>.</param>
		/// <returns>true if <c>pattern</c> matches <c>candidate</c>, false otherwise.</returns>
		/// <remarks>
		/// Attributes in patterns are not yet supported.
		/// <para/>
		/// This method supports multi-part captures, which are matched to 
		/// placeholders whose identifier has a #params attribute (for example, if 
		/// the placeholder is called p, this is written as <c>$(params p)</c> in 
		/// EC#.) A placeholder that looks like this can match multiple arguments or
		/// multiple statements in the <c>candidate</c> (or <i>no</i> arguments, or
		/// no statements), and will become a #splice(...) node in <c>captures</c>
		/// if it matches multiple items. Multi-part captures are often useful for
		/// getting lists of statements before and after some required element,
		/// e.g. <c>{ $(params before); MatchThis($something); $(params after); }</c>
		/// <para/>
		/// If the same placeholder appears twice then the two matching items are 
		/// combined into a single output node (calling #splice).
		/// <para/>
		/// If matching is unsuccessful, <c>captures</c> and <c>unmatchedAttrs</c>
		/// may contain irrelevant information gathered during the attempt to match.
		/// <para/>
		/// In EC#, the quote(...) macro can be used to create the LNode object for 
		/// a pattern.
		/// </remarks>
		public static bool MatchesPattern(LNode candidate, LNode pattern, ref MMap<Symbol, LNode> captures, out RVList<LNode> unmatchedAttrs)
		{
			// [$capture] (...)
			if (!AttributesMatch(candidate, pattern, ref captures, out unmatchedAttrs))
				return false;

			// $capture
			LNode sub;
			if (pattern.Calls(S.Substitute, 1) && (sub = pattern.Args.Last).IsId)
			{
				captures = captures ?? new MMap<Symbol, LNode>();
				AddCapture(captures, sub.Name, candidate);
				unmatchedAttrs = RVList<LNode>.Empty; // The attrs (if any) were captured
				return true;
			}

			var kind = candidate.Kind;
			if (kind != pattern.Kind)
				return false;

			if (candidate.Name != pattern.Name)
				return false;
			if (kind == LNodeKind.Literal)
				return object.Equals(candidate.Value, pattern.Value);
			else if (kind == LNodeKind.Call) {
				if (!MatchesPatternNested(candidate.Target, pattern.Target, ref captures, ref unmatchedAttrs))
					return false;
				var cArgs = candidate.Args;
				var pArgs = pattern.Args;

				if (pArgs.Count != cArgs.Count && !pArgs.Any(IsParamsCapture))
					return false;

				// Scan from the end of the list to the beginning (RVLists is good at this),
				// matching args one-by-one. Use MatchThenParams() in case of $(params capture).
				while (!pArgs.IsEmpty) {
					LNode pArg = pArgs.Pop();
					if (IsParamsCapture(pArg))
						return MatchThenParams(cArgs, pArgs, pArg, ref captures, ref unmatchedAttrs);
					if (cArgs.IsEmpty)
						return false;
					if (!MatchesPatternNested(cArgs.Pop(), pArg, ref captures, ref unmatchedAttrs))
						return false;
				}
				return true;
			} else // kind == Id
				return true;
		}
Beispiel #37
0
		protected Precedence FindPrecedence(MMap<object,Precedence> table, object symbol, Precedence @default, bool cacheWordOp, bool les3InfixOp = false)
		{
			// You can see the official rules in the LesPrecedence documentation.
			
			// Rule 1 (for >= <= != ==) is covered by the pre-populated contents 
			// of the table, and the pre-populated table helps interpret other 
			// rules too.
			CheckParam.IsNotNull("symbol", symbol);
			Precedence prec;
			if (table.TryGetValue(symbol, out prec))
				return prec;

			string sym = symbol.ToString();
			if (sym.Length <= 1 || sym[0] != '\'')
				return @default; // empty or non-operator

			// Note: all one-character operators should have been found in the table
			char first = sym[1], last = sym[sym.Length - 1];
			bool isInfix = table == this[OperatorShape.Infix].A;

			if (les3InfixOp)
			{
				// Check for lowercase word prefix
				int i = 1;
				while (first >= 'a' && first <= 'z' || first == '_') {
					if (++i == sym.Length) {
						if (cacheWordOp)
							table[symbol] = P.LowerKeyword;
						return P.LowerKeyword;
					}
					first = sym[i];
				}
				
				if (i + 1 == sym.Length) {
					// After the word is a one-character op. See if it is in the table
					var oneCharOp_ = GSymbol.Get("'" + first);
					if (table.TryGetValue(oneCharOp_, out prec))
						return prec;
				}
			}

			if (isInfix && last == '=') {
				if (first == '=' || first == '!')
					return table[symbol] = P.Compare;
				else
					return table[symbol] = P.Assign;
			}

			var twoCharOp = GSymbol.Get("'" + first + last);
			if (table.TryGetValue(twoCharOp, out prec))
				return table[symbol] = prec;

			var oneCharOp = GSymbol.Get("'" + first);
			if (table.TryGetValue(oneCharOp, out prec))
				return table[symbol] = prec;

			if (isInfix && char.IsLower(first))
				return table[symbol] = P.LowerKeyword;

			// Default precedence is used for anything else
			if (cacheWordOp)
				return table[symbol] = @default;
			return @default;
		}
Beispiel #38
0
		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);
		}
Beispiel #39
0
		static void AddCapture(MMap<Symbol, LNode> captures, LNode cap, Slice_<LNode> items)
		{
			Debug.Assert(cap.Calls(S.Substitute, 1) && cap.Args.Last.IsId);
			if (items.Count == 1)
				AddCapture(captures, cap.Args.Last.Name, items[0]);
			else
				AddCapture(captures, cap.Args.Last.Name, F.Call(S.Splice, items));
		}
Beispiel #40
0
		static bool AttributesMatch(LNode candidate, LNode pattern, ref MMap<Symbol, LNode> captures, out RVList<LNode> unmatchedAttrs)
		{
			if (pattern.HasPAttrs())
				throw new NotImplementedException("TODO: attributes in patterns are not yet supported");
			unmatchedAttrs = candidate.Attrs;
			return true;
		}
Beispiel #41
0
		static void AddCapture(MMap<Symbol, LNode> captures, Symbol capName, LNode candidate)
		{
			LNode oldCap = captures.TryGetValue(capName, null);
			captures[capName] = LNode.MergeLists(oldCap, candidate, S.Splice);
		}
Beispiel #42
0
		/// <summary>Get a dictionary of commands from the methods in the specified 
		/// object that have a [Command] attribute.</summary>
		public static MMap<Symbol, ICommand> GetCommandMap(object obj, Type type = null)
		{
			var list = GetCommandList(obj, type);
			var dict = new MMap<Symbol, ICommand>();
			foreach (var c in list)
				dict.Add(c.Name, c);
			return dict;
		}
Beispiel #43
0
		static bool AttributesMatch(LNode candidate, LNode pattern, ref MMap<Symbol, LNode> captures, out VList<LNode> unmatchedAttrs)
		{
			if (pattern.HasPAttrs()) {
				unmatchedAttrs = LNode.List();
				return ListMatches(candidate.Attrs, pattern.Attrs, ref captures, ref unmatchedAttrs);
			} else {
				unmatchedAttrs = candidate.Attrs;
			}
			return true;
		}
Beispiel #44
0
		internal static void AddMacro(MMap<Symbol, List<MacroInfo>> macros, MacroInfo info)
		{
			List<MacroInfo> cases;
			if (!macros.TryGetValue(info.Name, out cases)) {
				macros[info.Name] = cases = new List<MacroInfo>();
				cases.Add(info);
			} else {
				if (!cases.Any(existing => existing.Macro == info.Macro))
					cases.Add(info);
			}
		}
Beispiel #45
0
		static bool CaptureGroup(ref int c, ref int p, VList<LNode> cArgs, VList<LNode> pArgs, ref MMap<Symbol, LNode> captures, ref VList<LNode> attrs)
		{
			Debug.Assert(IsParamsCapture(pArgs[p]));
			// The goal now is to find a sequence of nodes in cArgs that matches
			// the sequence pArgs[p+1 .. p+x] where x is the maximum value such
			// that none of the nodes in the sequence are $(params caps).
			int saved_p = p, saved_c = c;
			var savedCaptures = captures.AsImmutable();
			var savedAttrs = attrs;
			int captureSize = 0;
			for (;; captureSize++) {
				for (p++, c += captureSize; ; c++, p++) {
					// If we run out of pArgs, great, we're done; if we run out 
					// of cArgs, the match fails, unless all remaining pArgs are 
					// $(params caps).
					if (p >= pArgs.Count || IsParamsCapture(pArgs[p])) {
						goto done_group;
					} else {
						if (c >= cArgs.Count)
							return false;
						if (!MatchesPatternNested(cArgs[c], pArgs[p], ref captures, ref attrs))
							goto continue_group;
					}
				}
				continue_group:;
				p = saved_p;
				c = saved_c;
				attrs = savedAttrs;
				captures = savedCaptures.AsMutable();
			}
		done_group:
			AddCapture(captures, pArgs[saved_p], cArgs.Slice(saved_c, captureSize));
			return true;
		}
Beispiel #46
0
		public static LNode TryReplaceHere(LNode node, LNode pattern, LNode replacement, MMap<Symbol, LNode> captures, Pair<LNode, LNode>[] allPatterns)
		{
			RVList<LNode> attrs;
			if (LNodeExt.MatchesPattern(node, pattern, ref captures, out attrs)) {
				foreach (var pair in captures) {
					var input = pair.Value.AsList(S.Splice);
					int c;
					var output = Replace(input, allPatterns, out c);
					if (output != input)
						captures[pair.Key] = output.AsLNode(S.Splice);
				}
				return ReplaceCaptures(replacement, captures).PlusAttrs(attrs);
			}

			return null;
		}
Beispiel #47
0
        /// <summary>Determines whether one Loyc tree "matches" another. This is
        /// different from a simple equality test in that (1) trivia atributes do
        /// not have to match, and (2) the pattern can contain placeholders represented
        /// by calls to $ (the substitution operator) with an identifier as a parameter.
        /// Placeholders match any subtree, and are saved to the <c>captures</c> map.
        /// </summary>
        /// <param name="candidate">A node that you want to compare with a 'pattern'.</param>
        /// <param name="pattern">A syntax tree that may contain placeholders. A
        /// placeholder is a call to the $ operator with one parameter, which must
        /// be a simple identifier (otherwise the $ operator is treated literally as
        /// something that must exist in <c>candidate</c>). The subtree in
        /// <c>candidate</c> corresponding to the placeholder is saved in <c>captures</c>.</param>
        /// <param name="captures">A table that maps placeholder names from
        /// <c>pattern</c> to subtrees in <c>candidate</c>. You can set your map to
        /// null and a map will be created for you if necessary. If you already have
        /// a map, you should clear it before calling this method.</param>
        /// <param name="unmatchedAttrs">On return, a list of trivia attributes in
        /// <c>candidate</c> that were not present in <c>pattern</c>.</param>
        /// <returns>true if <c>pattern</c> matches <c>candidate</c>, false otherwise.</returns>
        /// <remarks>
        /// Attributes in patterns are not yet supported.
        /// <para/>
        /// This method supports multi-part captures, which are matched to
        /// placeholders whose identifier has a #params attribute (for example, if
        /// the placeholder is called p, this is written as <c>$(params p)</c> in
        /// EC#.) A placeholder that looks like this can match multiple arguments or
        /// multiple statements in the <c>candidate</c> (or <i>no</i> arguments, or
        /// no statements), and will become a #splice(...) node in <c>captures</c>
        /// if it matches multiple items. Multi-part captures are often useful for
        /// getting lists of statements before and after some required element,
        /// e.g. <c>{ $(params before); MatchThis($something); $(params after); }</c>
        /// <para/>
        /// If the same placeholder appears twice then the two matching items are
        /// combined into a single output node (calling #splice).
        /// <para/>
        /// If matching is unsuccessful, <c>captures</c> and <c>unmatchedAttrs</c>
        /// may contain irrelevant information gathered during the attempt to match.
        /// <para/>
        /// In EC#, the quote(...) macro can be used to create the LNode object for
        /// a pattern.
        /// </remarks>
        public static bool MatchesPattern(LNode candidate, LNode pattern, ref MMap <Symbol, LNode> captures, out RVList <LNode> unmatchedAttrs)
        {
            // [$capture] (...)
            if (!AttributesMatch(candidate, pattern, ref captures, out unmatchedAttrs))
            {
                return(false);
            }

            // $capture
            LNode sub;

            if (pattern.Calls(S.Substitute, 1) && (sub = pattern.Args.Last).IsId)
            {
                captures = captures ?? new MMap <Symbol, LNode>();
                AddCapture(captures, sub.Name, candidate);
                unmatchedAttrs = RVList <LNode> .Empty;               // The attrs (if any) were captured
                return(true);
            }

            var kind = candidate.Kind;

            if (kind != pattern.Kind)
            {
                return(false);
            }

            if (candidate.Name != pattern.Name)
            {
                return(false);
            }
            if (kind == LNodeKind.Literal)
            {
                return(object.Equals(candidate.Value, pattern.Value));
            }
            else if (kind == LNodeKind.Call)
            {
                if (!MatchesPatternNested(candidate.Target, pattern.Target, ref captures, ref unmatchedAttrs))
                {
                    return(false);
                }
                var cArgs = candidate.Args;
                var pArgs = pattern.Args;

                if (pArgs.Count != cArgs.Count && !pArgs.Any(IsParamsCapture))
                {
                    return(false);
                }

                // Scan from the end of the list to the beginning (RVLists is good at this),
                // matching args one-by-one. Use MatchThenParams() in case of $(params capture).
                while (!pArgs.IsEmpty)
                {
                    LNode pArg = pArgs.Pop();
                    if (IsParamsCapture(pArg))
                    {
                        return(MatchThenParams(cArgs, pArgs, pArg, ref captures, ref unmatchedAttrs));
                    }
                    if (cArgs.IsEmpty)
                    {
                        return(false);
                    }
                    if (!MatchesPatternNested(cArgs.Pop(), pArg, ref captures, ref unmatchedAttrs))
                    {
                        return(false);
                    }
                }
                return(true);
            }
            else               // kind == Id
            {
                return(true);
            }
        }
Beispiel #48
0
		static LNode ReplaceCaptures(LNode node, MMap<Symbol, LNode> captures)
		{
			if (captures.Count != 0)
			{
				// TODO: EXPAND SPLICES! Generally it works anyway though because 
				// the macro processor has built-in support for #splice.
				return node.ReplaceRecursive(n => {
					LNode sub, cap;
					if (n.Calls(S.Substitute, 1) && (sub = n.Args.Last).IsId && captures.TryGetValue(sub.Name, out cap))
						return cap;
					return null;
				});
			}
			return node;
		}
Beispiel #49
0
        static void AddCapture(MMap <Symbol, LNode> captures, Symbol capName, LNode candidate)
        {
            LNode oldCap = captures.TryGetValue(capName, null);

            captures[capName] = LNode.MergeLists(oldCap, candidate, S.Splice);
        }
Beispiel #50
0
		static LNode TryReplaceHere(LNode node, Pair<LNode, LNode>[] patterns, MMap<Symbol, LNode> temp)
		{
			for (int i = 0; i < patterns.Length; i++)
			{
				temp.Clear();
				LNode r = TryReplaceHere(node, patterns[i].A, patterns[i].B, temp, patterns);
				if (r != null) return r;
			}

			// Support simple token replacement in TokenTrees
			TokenTree tt;
			if (node.IsLiteral && (tt = node.Value as TokenTree) != null) {
				bool modified = ReplaceInTokenTree(ref tt, _tokenTreeRepls);
				if (modified)
					return node.WithValue(tt);
			}
	
			return null;
		}
Beispiel #51
0
        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);
        }
Beispiel #52
0
		/// <summary>Determines whether one Loyc tree "matches" another. This is 
		/// different from a simple equality test in that (1) trivia atributes do 
		/// not have to match, and (2) the pattern can contain placeholders represented
		/// by calls to $ (the substitution operator) with an identifier as a parameter.
		/// Placeholders match any subtree, and are saved to the <c>captures</c> map.
		/// </summary>
		/// <param name="candidate">A node that you want to compare with a 'pattern'.</param>
		/// <param name="pattern">A syntax tree that may contain placeholders. A 
		/// placeholder is a call to the $ operator with one parameter, which must 
		/// be either (A) a simple identifier, or (B) the ".." operator with a simple
		/// identifier as its single parameter. Otherwise, the $ operator is treated 
		/// literally as something that must exist in <c>candidate</c>). The subtree 
		/// in <c>candidate</c> corresponding to the placeholder is saved in 
		/// <c>captures</c>.</param>
		/// <param name="captures">A table that maps placeholder names from 
		/// <c>pattern</c> to subtrees in <c>candidate</c>. You can set your map to 
		/// null and a map will be created for you if necessary. If you already have
		/// a map, you should clear it before calling this method.</param>
		/// <param name="unmatchedAttrs">On return, a list of trivia attributes in 
		/// <c>candidate</c> that were not present in <c>pattern</c>.</param>
		/// <returns>true if <c>pattern</c> matches <c>candidate</c>, false otherwise.</returns>
		/// <remarks>
		/// Attributes in patterns are not yet supported.
		/// <para/>
		/// This method supports multi-part captures, which are matched to 
		/// placeholders whose identifier either (A) has a #params attribute or
		/// (B) has the unary ".." operator applied to it (for example, if 
		/// the placeholder is called p, this is written as <c>$(params p)</c> in 
		/// EC#.) A placeholder that looks like this can match multiple arguments or
		/// multiple statements in the <c>candidate</c> (or <i>no</i> arguments, or
		/// no statements), and will become a #splice(...) node in <c>captures</c>
		/// if it matches multiple items. Multi-part captures are often useful for
		/// getting lists of statements before and after some required element,
		/// e.g. <c>{ $(params before); MatchThis($something); $(params after); }</c>
		/// <para/>
		/// If the same placeholder appears twice then the two matching items are 
		/// combined into a single output node (calling #splice).
		/// <para/>
		/// If matching is unsuccessful, <c>captures</c> and <c>unmatchedAttrs</c>
		/// may contain irrelevant information gathered during the attempt to match.
		/// <para/>
		/// In EC#, the quote(...) macro can be used to create the LNode object for 
		/// a pattern.
		/// </remarks>
		public static bool MatchesPattern(this LNode candidate, LNode pattern, ref MMap<Symbol, LNode> captures, out VList<LNode> unmatchedAttrs)
		{
			// [$capture] (...)
			if (!AttributesMatch(candidate, pattern, ref captures, out unmatchedAttrs))
				return false;

			// $capture or $(..capture)
			LNode sub = GetCaptureIdentifier(pattern);
			if (sub != null)
			{
				captures = captures ?? new MMap<Symbol, LNode>();
				AddCapture(captures, sub.Name, candidate);
				unmatchedAttrs = VList<LNode>.Empty; // The attrs (if any) were captured
				return true;
			}

			var kind = candidate.Kind;
			if (kind != pattern.Kind)
				return false;

			if (kind == LNodeKind.Id && candidate.Name != pattern.Name)
				return false;
			if (kind == LNodeKind.Literal)
				return object.Equals(candidate.Value, pattern.Value);
			else if (kind == LNodeKind.Call)
			{
				if (!MatchesPatternNested(candidate.Target, pattern.Target, ref captures, ref unmatchedAttrs))
					return false;
				var cArgs = candidate.Args;
				var pArgs = pattern.Args;

				return ListMatches(cArgs, pArgs, ref captures, ref unmatchedAttrs);
			}
			else // kind == Id
				return true;
		}
Beispiel #53
0
		internal static void AddMacro(MMap<Symbol, VList<MacroInfo>> macros, MacroInfo info)
		{
			foreach (string name in info.Names) {
				var nameS = (Symbol)name;
				var cases = macros[nameS, VList<MacroInfo>.Empty];
				if (!cases.Any(existing => existing.Macro == info.Macro))
					macros[nameS] = cases.Add(info);
			}
		}
Beispiel #54
0
		private static bool ListMatches(VList<LNode> candidates, VList<LNode> patterns, ref MMap<Symbol, LNode> captures, ref VList<LNode> unmatchedAttrs)
		{
			if (patterns.Count != candidates.Count && !patterns.Any(IsParamsCapture))
				return false;

			// Scan from the end of the list to the beginning (RVLists is good at this),
			// matching args one-by-one. Use MatchThenParams() in case of $(params capture).
			while (!patterns.IsEmpty)
			{
				LNode pArg = patterns.Pop();
				if (IsParamsCapture(pArg))
					return MatchThenParams(candidates, patterns, pArg, ref captures, ref unmatchedAttrs);
				if (candidates.IsEmpty)
					return false;
				if (!MatchesPatternNested(candidates.Pop(), pArg, ref captures, ref unmatchedAttrs))
					return false;
			}
			return true;
		}
Beispiel #55
0
        protected Precedence FindPrecedence(MMap <object, Precedence> table, object symbol, Precedence @default, bool cacheWordOp)
        {
            // You can see the official rules in the LesPrecedence documentation.

            // Rule 1 (for >= <= != ==) is covered by the pre-populated contents
            // of the table, and the pre-populated table helps interpret other
            // rules too.
            CheckParam.IsNotNull("symbol", symbol);
            Precedence prec;

            if (table.TryGetValue(symbol, out prec))
            {
                return(prec);
            }

            string sym = symbol.ToString();

            if (sym.Length <= 1 || sym[0] != '\'')
            {
                return(P.Other);                // empty or non-operator
            }
            // Note: all one-character operators should have been found in the table
            char first = sym[1], last = sym[sym.Length - 1];

            bool isInfix = table == this[OperatorShape.Infix].A;

            if (isInfix && last == '=')
            {
                if (first == '=' || first == '!')
                {
                    return(table[symbol] = P.Compare);
                }
                else
                {
                    return(table[symbol] = P.Assign);
                }
            }

            var twoCharOp = GSymbol.Get("'" + first + last);

            if (table.TryGetValue(twoCharOp, out prec))
            {
                return(table[symbol] = prec);
            }

            var oneCharOp = GSymbol.Get("'" + last);

            if (table.TryGetValue(oneCharOp, out prec))
            {
                return(table[symbol] = prec);
            }

            if (isInfix && first >= 'A' && first <= 'Z')
            {
                return(table[symbol] = P.UpperWord);
            }

            // Default precedence is used for anything else (lowercase word ops)
            if (cacheWordOp)
            {
                return(table[symbol] = @default);
            }
            return(@default);
        }
Beispiel #56
0
 public Scope(MSet <Symbol> openNamespaces, MMap <object, object> scopedProperties, MacroProcessorTask task, bool isRoot = false)
 {
     OpenNamespaces = openNamespaces; _scopedProperties = scopedProperties; _task = task; _propertiesCopied = _namespacesCopied = isRoot;
 }