Exemple #1
0
    /*
     * Turn a function call into the corresponding GFunctionInterpreted.
     * This applies recursively on all the the call sub-tree.
     */
    internal static GFunctionInterpreted Add(CCFunctionInterpreted cfi)
    {
        GFunctionInterpreted ngf = new GFunctionInterpreted(cfi);

        /*
         * Find the GFunction already existing for this function.
         */
        SortedSet <GFunctionInterpreted> ss;

        if (!ALL.TryGetValue(cfi.fi, out ss))
        {
            ss = new SortedSet <GFunctionInterpreted>();
            ss.Add(ngf);
            ALL[cfi.fi] = ss;
            return(ngf);
        }

        /*
         * If the new function can be merged into any of the
         * existing GFunction, do it; otherwise, add it as a
         * new GFunction.
         */
        foreach (GFunctionInterpreted gf in ss)
        {
            if (gf.Merge(ngf))
            {
                return(gf);
            }
        }
        ss.Add(ngf);
        return(ngf);
    }
Exemple #2
0
 internal override GFunction ToGFunction()
 {
     return(GFunctionInterpreted.Add(cfi));
 }
Exemple #3
0
    /*
     * Perform compilation.
     */
    internal static void DoCompile()
    {
        string[] eps;
        if (entryPoints.Count == 0)
        {
            eps = new string[] { "def::main" };
        }
        else
        {
            eps = entryPoints.ToArray();
        }

        if (Verbose)
        {
            Console.WriteLine("+++++ Type Analysis +++++");
        }
        List <CCNode> roots = new List <CCNode>();

        foreach (string name in eps)
        {
            if (Verbose)
            {
                Console.WriteLine("--- Entry point: {0}", name);
            }
            Function f = Function.LookupNoArgs(name);
            if (f == null)
            {
                throw new Exception(string.Format("no such entry point: {0}", name));
            }
            roots.Add(CCNode.BuildTree(f));
        }
        if (PrintTrees != null)
        {
            PrintTrees.WriteLine("Call trees:");
            foreach (CCNode node in roots)
            {
                Indent(PrintTrees, 1);
                PrintTrees.WriteLine("*****");
                node.Print(PrintTrees, 2);
            }
        }

        if (Verbose)
        {
            Console.WriteLine("+++++ Code Generation +++++");
        }
        foreach (CCNode root in roots)
        {
            var ne = root as CCNodeEntry;
            if (ne != null)
            {
                GFunctionInterpreted.Add(ne.cfi);
            }
        }
        if (PrintTrees != null)
        {
            PrintTrees.WriteLine("Generated functions:");
            GFunctionInterpreted.PrintAll(PrintTrees);
        }

        using (TextWriter tw = File.CreateText(OutputBase + ".c")) {
            CCValues.PrintAll(tw);
        }
    }
Exemple #4
0
 internal GOpFrame(GFunctionInterpreted gf)
 {
     this.gf   = gf;
     variables = new SortedDictionary <int, LocalVariable>();
     instances = new SortedDictionary <int, LocalInstance>();
 }
Exemple #5
0
    /*
     * Merge the provided GFunctionInterpreted into this one. If the
     * merge is not possible, this instance is not modified, and
     * false is returned.
     */
    bool Merge(GFunctionInterpreted gf)
    {
        /*
         * Normally, Merge() is not invoked for a distinct function,
         * but an extra test here is cheap.
         */
        if (fi != gf.fi)
        {
            return(false);
        }

        /*
         * We first test the frames, but do not complete their
         * merge until the operation is confirmed.
         */
        if (!frame.CanMerge(gf.frame))
        {
            return(false);
        }

        /*
         * Since the two GFunctionInterpreted relate to the same
         * interpreted function, all opcodes are naturally
         * compatible, except possibly the Call opcodes, which
         * must be checked.
         */
        GOp[] spec3 = new GOp[spec.Length];
        for (int i = 0; i < spec.Length; i++)
        {
            GOp g1 = spec[i];
            GOp g2 = gf.spec[i];
            if ((g1 is GOpCall) && (g2 is GOpCall))
            {
                GOpCall g3 = ((GOpCall)g1).Merge((GOpCall)g2);
                if (g3 == null)
                {
                    return(false);
                }
                spec3[i] = g3;
            }
            else
            {
                if (g1 is GOpZero)
                {
                    spec3[i] = g2;
                }
                else
                {
                    spec3[i] = g1;
                }
            }
        }
        spec = spec3;
        AdjustJumps();

        /*
         * Merge the frames.
         */
        frame.Merge(gf.frame);
        return(true);
    }