Beispiel #1
0
 protected SelType GetSelType(Shape shape)
 {
     if (shape == null)
     {
         return(SelType.No);
     }
     if (shape == _partialSelShape)
     {
         return(SelType.Partial);
     }
     return(_selectedShapes.Contains(shape) ? SelType.Yes : SelType.No);
 }
        public virtual LNode GenerateSwitch(IPGTerminalSet[] branchSets, MSet <int> casesToInclude, LNode[] branchCode, LNode defaultBranch, LNode laVar)
        {
            Debug.Assert(branchSets.Length == branchCode.Length);

            WList <LNode> stmts = new WList <LNode>();

            for (int i = 0; i < branchSets.Length; i++)
            {
                if (casesToInclude.Contains(i))
                {
                    foreach (LNode value in GetCases(branchSets[i]))
                    {
                        stmts.Add(F.Call(S.Case, value));
                        if (stmts.Count > 65535)                         // sanity check
                        {
                            throw new InvalidOperationException("switch is too large to generate");
                        }
                    }
                    AddSwitchHandler(branchCode[i], stmts);
                }
            }

            if (!defaultBranch.IsIdNamed(S.Missing))
            {
                stmts.Add(F.Call(S.Label, F.Id(S.Default)));
                AddSwitchHandler(defaultBranch, stmts);
            }

            return(F.Call(S.Switch, (LNode)laVar, F.Braces(stmts.ToVList())));
        }
Beispiel #3
0
 private void AutoAddBranchForAndPred(ref InternalList <PredictionBranch> children, AndPred andPred, List <KthSet> alts, Set <AndPred> matched, MSet <AndPred> falsified)
 {
     if (!falsified.Contains(andPred))
     {
         var innerMatched = matched.With(andPred);
         var result       = new PredictionBranch(new Set <AndPred>().With(andPred),
                                                 ComputeAssertionTree2(alts, innerMatched));
         falsified.Add(andPred);
         RemoveFalsifiedCases(alts, falsified);
         children.Add(result);
     }
 }
Beispiel #4
0
 public LNode OnImport(LNode node, IMessageSink sink, bool expectMacros)
 {
     AutoInitScope().BeforeImport();
     foreach (var arg in node.Args)
     {
         var namespaceSym = NamespaceToSymbol(arg);
         _curScope.OpenNamespaces.Add(namespaceSym);
         if (expectMacros && !_macroNamespaces.Contains(namespaceSym))
         {
             sink.Write(Severity.Warning, node, "Namespace '{0}' does not contain any macros. Use #printKnownMacros to put a list of known macros in the output.", namespaceSym);
         }
     }
     return(null);
 }
Beispiel #5
0
            private LNode GenerateIfElseChain(PredictionTree tree, LNode[] branchCode, ref LNode laVar, MSet <int> switchCases)
            {
                // From the prediction table, generate a chain of if-else
                // statements in reverse, starting with the final "else" clause.
                // Skip any branches that have been claimed for use in a switch()
                LNode ifChain  = null;
                bool  usedTest = false;

                for (int i = tree.Children.Count - 1; i >= 0; i--)
                {
                    if (switchCases.Contains(i))
                    {
                        continue;
                    }

                    if (ifChain == null)
                    {
                        ifChain = branchCode[i];
                    }
                    else
                    {
                        usedTest = true;
                        var   branch = tree.Children[i];
                        LNode test;
                        if (tree.IsAssertionLevel)
                        {
                            test = GenerateTest(branch.AndPreds, tree.Lookahead, laVar);
                        }
                        else
                        {
                            var set = CGH.Optimize(branch.Set, branch.Covered);
                            test = CGH.GenerateTest(set, laVar);
                        }

                        LNode @if = F.Call(S.If, test, branchCode[i]);
                        if (!ifChain.IsIdWithoutPAttrs(S.Missing))
                        {
                            @if = @if.PlusArg(ifChain);
                        }
                        ifChain = @if;
                    }
                }
                if (!usedTest)
                {
                    laVar = null;                     // unnecessary
                }
                return(ifChain);
            }
Beispiel #6
0
        public virtual LNode GenerateSwitch(IPGTerminalSet[] branchSets, LNode[] branchCode, MSet <int> casesToInclude, LNode defaultBranch, LNode laVar)
        {
            Debug.Assert(branchSets.Length == branchCode.Length);
            Debug.Assert(casesToInclude.Count <= branchCode.Length);

            WList <LNode> stmts = new WList <LNode>();

            for (int i = 0; i < branchCode.Length; i++)
            {
                if (casesToInclude.Contains(i))
                {
                    int index = -1;
                    foreach (LNode value in GetCases(branchSets[i]))
                    {
                        var label = F.Call(S.Case, value);
                        if (++index > 0 && (index % 4) != 0)                         // write 4 cases per line
                        {
                            label = label.PlusAttr(F.Id(S.TriviaAppendStatement));
                        }
                        stmts.Add(label);
                        if (stmts.Count > 65535)                         // sanity check
                        {
                            throw new InvalidOperationException("switch is too large to generate");
                        }
                    }
                    AddSwitchHandler(branchCode[i], stmts);
                }
            }

            if (!defaultBranch.IsIdNamed(GSymbol.Empty))
            {
                stmts.Add(F.Call(S.Label, F.Id(S.Default)));
                AddSwitchHandler(defaultBranch, stmts);
            }

            return(F.Call(S.Switch, (LNode)laVar, F.Braces(stmts.ToVList())));
        }
Beispiel #7
0
			private LNode GenerateIfElseChain(PredictionTree tree, LNode[] branchCode, ref LNode laVar, MSet<int> switchCases)
			{
				// From the prediction table, generate a chain of if-else 
				// statements in reverse, starting with the final "else" clause.
				// Skip any branches that have been claimed for use in a switch()
				LNode ifChain = null;
				bool usedTest = false;

				for (int i = tree.Children.Count - 1; i >= 0; i--) {
					if (switchCases.Contains(i))
						continue;

					if (ifChain == null)
						ifChain = branchCode[i];
					else {
						usedTest = true;
						var branch = tree.Children[i];
						LNode test;
						if (tree.IsAssertionLevel)
							test = GenerateTest(branch.AndPreds, tree.Lookahead, laVar);
						else {
							var set = CGH.Optimize(branch.Set, branch.Covered);
							test = CGH.GenerateTest(set, laVar);
						}

						LNode @if = F.Call(S.If, test, branchCode[i]);
						if (!ifChain.IsIdWithoutPAttrs(S.Missing))
							@if = @if.PlusArg(ifChain);
						ifChain = @if;
					}
				}
				if (!usedTest)
					laVar = null; // unnecessary

				return ifChain;
			}
Beispiel #8
0
		public virtual LNode GenerateSwitch(IPGTerminalSet[] branchSets, MSet<int> casesToInclude, LNode[] branchCode, LNode defaultBranch, LNode laVar)
		{
			Debug.Assert(branchSets.Length == branchCode.Length);

			RWList<LNode> stmts = new RWList<LNode>();
			for (int i = 0; i < branchSets.Length; i++)
			{
				if (casesToInclude.Contains(i))
				{
					foreach (LNode value in GetCases(branchSets[i]))
					{
						stmts.Add(F.Call(S.Case, value));
						if (stmts.Count > 65535) // sanity check
							throw new InvalidOperationException("switch is too large to generate");
					}
					AddSwitchHandler(branchCode[i], stmts);
				}
			}

			if (!defaultBranch.IsIdNamed(S.Missing))
			{
				stmts.Add(F.Call(S.Label, F.Id(S.Default)));
				AddSwitchHandler(defaultBranch, stmts);
			}

			return F.Call(S.Switch, (LNode)laVar, F.Braces(stmts.ToRVList()));
		}
Beispiel #9
0
		public virtual LNode GenerateSwitch(IPGTerminalSet[] branchSets, MSet<int> casesToInclude, LNode[] branchCode, LNode defaultBranch, LNode laVar)
		{
			Debug.Assert(branchSets.Length == branchCode.Length);

			WList<LNode> stmts = new WList<LNode>();
			for (int i = 0; i < branchSets.Length; i++)
			{
				if (casesToInclude.Contains(i))
				{
					int index = -1;
					foreach (LNode value in GetCases(branchSets[i]))
					{
						var label = F.Call(S.Case, value);
						if (++index > 0 && (index % 4) != 0) // write 4 cases per line
							label = label.PlusAttr(F.Id(S.TriviaAppendStatement));
						stmts.Add(label);
						if (stmts.Count > 65535) // sanity check
							throw new InvalidOperationException("switch is too large to generate");
					}
					AddSwitchHandler(branchCode[i], stmts);
				}
			}

			if (!defaultBranch.IsIdNamed(S.Missing))
			{
				stmts.Add(F.Call(S.Label, F.Id(S.Default)));
				AddSwitchHandler(defaultBranch, stmts);
			}

			return F.Call(S.Switch, (LNode)laVar, F.Braces(stmts.ToVList()));
		}
Beispiel #10
0
			private void AutoAddBranchForAndPred(ref InternalList<PredictionBranch> children, AndPred andPred, List<KthSet> alts, Set<AndPred> matched, MSet<AndPred> falsified)
			{
				if (!falsified.Contains(andPred)) {
					var innerMatched = matched.With(andPred);
					var result = new PredictionBranch(new Set<AndPred>().With(andPred),
						ComputeAssertionTree2(alts, innerMatched));
					falsified.Add(andPred);
					RemoveFalsifiedCases(alts, falsified);
					children.Add(result);
				}
			}
Beispiel #11
0
 static MExpr Conv(MExpr expr, ClosureConversionContext ctx, MSet <string> locals, bool istail)
 {
     if (expr is MInt || expr is MDouble || expr is MString || expr is MChar ||
         expr is MUnit || expr is MBool)
     {
         return(expr);
     }
     else if (expr is MVar)
     {
         var e = (MVar)expr;
         if (e.IsTag)
         {
             return(expr);
         }
         else if (e.Name == ctx.ArgName)
         {
             return(new MGetArg());
         }
         else
         {
             if (locals.Contains(e.Name))
             {
                 return(expr);
             }
             else
             {
                 var index = ctx.GetCaptureIndex(e.Name);
                 if (index == -1)
                 {
                     return(expr);
                 }
                 else
                 {
                     return(new MGetEnv(index));
                 }
             }
         }
     }
     else if (expr is MLambda)
     {
         var   e   = (MLambda)expr;
         var   set = e.Body.FreeVars().Diff(e.ArgPat.FreeVars());
         var   fv  = set.ToArray();
         MExpr body;
         if (e.ArgPat is PVar)
         {
             var ctx2 = new ClosureConversionContext(((PVar)e.ArgPat).Name, fv);
             body = Conv(e.Body, ctx2, new MSet <string>(), true);
         }
         else
         {
             var arg_name = GenArgName();
             var ctx2     = new ClosureConversionContext(arg_name, fv);
             body = Conv(new MMatch(e.Pos, e.ArgPat, new MBool(e.Pos, true), new MVar(arg_name), e.Body,
                                    new MRuntimeError(e.Pos, "パターンマッチ失敗")), ctx2, new MSet <string>(), true);
         }
         var fun_name = GenFunctionName();
         _function_table.Add(fun_name, body);
         var args = fv.Select(x => Conv(new MVarClos(x), ctx, new MSet <string>(), false)).ToArray();
         return(new MMakeClos(fun_name, args));
     }
     else if (expr is MApp)
     {
         var e   = (MApp)expr;
         var fun = Conv(e.FunExpr, ctx, locals, false);
         var arg = Conv(e.ArgExpr, ctx, locals, false);
         var app = new MApp(e.Pos, fun, arg);
         app.TailCall = istail;
         return(app);
     }
     else if (expr is MIf)
     {
         var e         = (MIf)expr;
         var cond_expr = Conv(e.CondExpr, ctx, locals, false);
         var then_expr = Conv(e.ThenExpr, ctx, locals, istail);
         var else_expr = Conv(e.ElseExpr, ctx, locals, istail);
         return(new MIf(e.Pos, cond_expr, then_expr, else_expr));
     }
     else if (expr is MMatch)
     {
         var e         = (MMatch)expr;
         var locals2   = locals.Union(e.Pat.FreeVars());
         var expr1     = Conv(e.Expr, ctx, locals, false);
         var guard     = Conv(e.Guard, ctx, locals2, false);
         var then_expr = Conv(e.ThenExpr, ctx, locals2, istail);
         var else_expr = Conv(e.ElseExpr, ctx, locals, istail);
         return(new MMatch(e.Pos, e.Pat, guard, expr1, then_expr, else_expr));
     }
     else if (expr is MNil)
     {
         return(expr);
     }
     else if (expr is MCons)
     {
         var e    = (MCons)expr;
         var head = Conv(e.Head, ctx, locals, false);
         var tail = Conv(e.Tail, ctx, locals, false);
         return(new MCons(e.Pos, head, tail));
     }
     else if (expr is MTuple)
     {
         var e    = (MTuple)expr;
         var list = e.Items.Select(x => Conv(x, ctx, locals, false)).ToList();
         return(new MTuple("", list));
     }
     else if (expr is MDo)
     {
         var e  = (MDo)expr;
         var e1 = Conv(e.E1, ctx, locals, false);
         var e2 = Conv(e.E2, ctx, locals, istail);
         return(new MDo(e.Pos, e1, e2));
     }
     else if (expr is MLet)
     {
         var e       = (MLet)expr;
         var locals2 = locals.Union(e.Pat.FreeVars());
         var e1      = Conv(e.E1, ctx, locals, false);
         var e2      = Conv(e.E2, ctx, locals2, istail);
         return(new MLet(e.Pos, e.Pat, e1, e2));
     }
     else if (expr is MFun)
     {
         var e       = (MFun)expr;
         var locals2 = FunPats(e).Union(locals);
         var items   = e.Items.Select(item =>
                                      new MFunItem(item.Name, Conv(item.Expr, ctx, locals2, true))).ToList();
         var e2 = Conv(e.E2, ctx, locals2, istail);
         return(new MFun(e.Pos, items, e2));
     }
     else if (expr is MFource)
     {
         var e = (MFource)expr;
         return(Conv(e.Expr, ctx, locals, istail));
     }
     else if (expr is MRuntimeError)
     {
         return(expr);
     }
     else if (expr is MPrim)
     {
         var e    = (MPrim)expr;
         var list = e.Args.Select(x => Conv(x, ctx, locals, false)).ToList();
         return(new MPrim(e.Pos, e.Name, list, e.ArgTypes, e.RetType));
     }
     else if (expr is MCallStatic)
     {
         var e    = (MCallStatic)expr;
         var list = e.Args.Select(x => Conv(x, ctx, locals, false)).ToList();
         return(new MCallStatic(e.Pos, e.ClassName, e.MethodName, list, e.Types, e.Info));
     }
     else if (expr is MCast)
     {
         var e = (MCast)expr;
         return(new MCast(e.Pos, e.SrcTypeName, e.SrcType,
                          e.DstTypeName, e.DstType, Conv(e.Expr, ctx, locals, false)));
     }
     else if (expr is MIsType)
     {
         var e = (MIsType)expr;
         return(new MIsType(e.Pos, e.TypeName, e.Type, Conv(e.Expr, ctx, locals, false)));
     }
     else if (expr is MNewClass)
     {
         var e    = (MNewClass)expr;
         var list = e.Args.Select(x => Conv(x, ctx, locals, false)).ToList();
         return(new MNewClass(e.Pos, e.ClassName, list, e.Types, e.Info));
     }
     else if (expr is MInvoke)
     {
         var e    = (MInvoke)expr;
         var e2   = Conv(e.Expr, ctx, locals, false);
         var list = e.Args.Select(x => Conv(x, ctx, locals, false)).ToList();
         return(new MInvoke(e.Pos, e2, e.ExprType, e.MethodName, list, e.Types, e.Info));
     }
     else if (expr is MDelegate)
     {
         var e  = (MDelegate)expr;
         var e2 = Conv(e.Expr, ctx, locals, false);
         return(new MDelegate(e.Pos, e.ClassName, e2, e.ExprType,
                              e.ParamType, e.ClassType, e.CstrInfo));
     }
     else if (expr is MVarClos)
     {
         var e = (MVarClos)expr;
         if (e.Name == ctx.ArgName)
         {
             return(new MGetArg());
         }
         else
         {
             var index = ctx.GetCaptureIndex(e.Name);
             if (index == -1)
             {
                 return(expr);
             }
             else
             {
                 return(new MGetEnv(index));
             }
         }
     }
     else if (expr is MSet)
     {
         var e  = (MSet)expr;
         var e1 = Conv(e.Expr, ctx, locals, false);
         var e2 = Conv(e.Arg, ctx, locals, false);
         return(new MSet(e.Pos, e1, e.ExprType, e.FieldName, e2, e.ArgType, e.Info));
     }
     else if (expr is MGet)
     {
         var e  = (MGet)expr;
         var e1 = Conv(e.Expr, ctx, locals, false);
         return(new MGet(e.Pos, e1, e.ExprType, e.FieldName, e.Info));
     }
     else if (expr is MSSet)
     {
         var e  = (MSSet)expr;
         var e1 = Conv(e.Arg, ctx, locals, false);
         return(new MSSet(e.Pos, e.ClassName, e.FieldName, e1, e.ArgType, e.Info));
     }
     else if (expr is MSGet)
     {
         return(expr);
     }
     else if (expr is MNewArr)
     {
         var e = (MNewArr)expr;
         return(new MNewArr(e.Pos, e.TypeName, e.Type, Conv(e.Size, ctx, locals, false)));
     }
     else if (expr is MLdElem)
     {
         var e   = (MLdElem)expr;
         var ary = Conv(e.Ary, ctx, locals, false);
         var idx = Conv(e.Idx, ctx, locals, false);
         return(new MLdElem(e.Pos, e.TypeName, e.Type, ary, idx));
     }
     else if (expr is MStElem)
     {
         var e   = (MStElem)expr;
         var ary = Conv(e.Ary, ctx, locals, false);
         var idx = Conv(e.Idx, ctx, locals, false);
         var val = Conv(e.Val, ctx, locals, false);
         return(new MStElem(e.Pos, e.TypeName, e.Type, ary, idx, val));
     }
     else if (expr is MTry)
     {
         var e  = (MTry)expr;
         var e2 = Conv(e.Expr, ctx, locals, false);
         var e3 = Conv(e.Handler, ctx, locals, false);
         return(new MTry(e.Pos, e2, e3));
     }
     else
     {
         throw new NotImplementedException();
     }
 }