Esempio n. 1
0
 public void RevertContextualsIn(FrameScope fs, CodeGen cg)
 {
     foreach (var varname in MangledContextuals.Values)
     {
         if (fs.AssignedContextuals.Contains(varname))
         {
             if (cg.This().Type.Name != "TopLevelFrame")
             {
                 cg.If(cg.This().Field("_assigned_" + fs.ID + "_" + varname) > 0);
                 {
                     cg.Assign(cg.This().Field("TopLevelFrame").Field("_ctxl_" + varname), cg.This().Field("TopLevelFrame").Field("_stack_" + varname).Invoke("Pop"));
                     cg.Assign(cg.This().Field("_assigned_" + fs.ID + "_" + varname), 0);
                 }
                 cg.End();
             }
             else
             {
                 cg.If(cg.This().Field("_assigned_" + fs.ID + "_" + varname) > 0);
                 {
                     cg.Assign(cg.This().Field("_ctxl_" + varname), cg.This().Field("_stack_" + varname).Invoke("Pop"));
                     cg.Assign(cg.This().Field("_assigned_" + fs.ID + "_" + varname), 0);
                 }
                 cg.End();
             }
         }
     }
 }
Esempio n. 2
0
        // this routine runs at parser-runtime (not parser-compiletime nor program-runtime)
        public string GetMangledContextual(TypeGen currentFrameBuilder, FrameScope currentScope, FrameScope topLevelScope, string varname)
        {
            string mangledName;

            if (!MangledContextuals.TryGetValue(varname, out mangledName))
            {
                throw new InvalidOperationException("you must declare the contextual " + varname + ", including its type annotation");
            }
            return(GetMangledContextual(currentFrameBuilder, currentScope, topLevelScope, topLevelScope[varname].Type, varname));
        }
Esempio n. 3
0
 // generates code that resets the lexical slots in the enclosing frame for re-entering
 //   a block (such as in a loop).  Effectively emulates a parameterless closure.
 public void RevertLexicalsIn(FrameScope fs, CodeGen cg)
 {
     foreach (var varname in fs.OwnKeysList)
     {
         if (fs[varname].Type.IsValueType)
         {
             cg.This().Field(fs[varname].MangledName).ForceEmitAddress(cg);
             cg.IL.Emit(OpCodes.Initobj, fs[varname].Type);
         }
         else
         {
             cg.Assign(cg.This().Field(fs[varname].MangledName), null);
         }
     }
 }
Esempio n. 4
0
        // this routine runs at parser-runtime (not parser-compiletime nor program-runtime)
        public string GetMangledContextual(TypeGen currentFrameBuilder, FrameScope currentScope, FrameScope topLevelScope, Type type, string varname)
        {
            string mangledName;

            if (!MangledContextuals.TryGetValue(varname, out mangledName))
            {
                var frameLocal = new FrameLocal(varname, type, topLevelScope);
                topLevelScope.AddHere(varname, frameLocal);
                currentFrameBuilder.FrameGen.MangledContextuals.Add(varname, mangledName = frameLocal.MangledName);
                // create a field in the toplevel frame class for the current contextual value
                Public.Field(type, "_ctxl_" + mangledName);
                // and create a runtime type representing the type of the Stack<TypeOfThisContextual>
                var stack_type = typeof(Stack <>).MakeGenericType(type);
                // create a field in the toplevel frame class for the stack of previously assigned dynamic
                //   values of the contextual variable.
                Public.Field(stack_type, "_stack_" + mangledName);
                // push a closure that will run (parser-runtime) at the end of the toplevel routine declaration
                //   (but at program-runtime will run as a prologue to the program) that initializes this stack
                PrologueEvents.Add((CodeGen cg) => {
                    if (cg.This().Type.Name == "TopLevelFrame")
                    {
                        cg.Assign(cg.This().Field("_stack_" + mangledName), Exp.New(stack_type));
                    }
                    else
                    {
                        cg.Assign(cg.This().Field("TopLevelFrame").Field("_stack_" + mangledName), Exp.New(stack_type));
                    }
                });
            }
            // if we haven't already added a flag assigned slot for this contextual-scope tuple in this frame,
            if (!currentScope.AssignedContextuals.Contains(mangledName))
            {
                // record that we've done so,
                currentScope.AssignedContextuals.Add(mangledName);
                // and create a field in the current frame class for a flag representing whether to pop the
                //   contextual stack upon leaving this scope,
                currentFrameBuilder.FrameGen.Public.Field(typeof(int), "_assigned_" + currentScope.ID + "_" + mangledName);
            }
            return(mangledName);
        }