/* * 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); }
internal override GFunction ToGFunction() { return(GFunctionInterpreted.Add(cfi)); }
/* * 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); } }
internal GOpFrame(GFunctionInterpreted gf) { this.gf = gf; variables = new SortedDictionary <int, LocalVariable>(); instances = new SortedDictionary <int, LocalInstance>(); }
/* * 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); }