Beispiel #1
0
        public Executable Compile()
        {
            var exe = new Executable(context.MachineInfo);

            // Put something at the zero address so we don't get 0 addresses of globals
            exe.AddGlobal("__zero__", CBasicType.SignedInt);

            //
            // Find Variables, Functions, Types
            //
            var cinitBody = new Block();

            foreach (var tu in tus)
            {
                AddStatementDeclarations(tu);
                cinitBody.Statements.AddRange(tu.InitStatements);
            }

            //
            // Generate a function to init globals
            //
            exe.Functions.Add(new CompiledFunction("__cinit", CFunctionType.VoidProcedure, cinitBody));

            //
            // Link everything together
            // This is done before compilation to make sure everything is visible (for recursion)
            //
            foreach (var tu in tus)
            {
                foreach (var g in tu.Variables)
                {
                    var v = exe.AddGlobal(g.Name, g.VariableType);
                    v.InitialValue = g.InitialValue;
                }
                exe.Functions.AddRange(tu.Functions.Where(x => x.Body != null));
            }

            //
            // Compile functions
            //
            foreach (var f in exe.Functions.OfType <CompiledFunction> ())
            {
                AddStatementDeclarations(f.Body);

                var c = new FunctionContext(exe, f, context);
                f.Body.Emit(c);
                f.LocalVariables.AddRange(c.LocalVariables);

                // Make sure it returns
                if (f.Body.Statements.Count == 0 || !f.Body.AlwaysReturns)
                {
                    if (f.FunctionType.ReturnType.IsVoid)
                    {
                        c.Emit(OpCode.Return);
                    }
                    else
                    {
                        context.Report.Error(161, "'" + f.Name + "' not all code paths return a value");
                    }
                }
            }

            return(exe);
        }
Beispiel #2
0
 public CInterpreter(Executable exe, int maxStack = 1024, int maxFrames = 24)
 {
     this.exe = exe;
     Stack    = new Value[maxStack];
     Frames   = (from i in Enumerable.Range(0, maxFrames) select new ExecutionFrame(unusedStackFrameFunction)).ToArray();
 }