internal FunctionScope(FunctionScope parent) { Parent = parent; ReturnLabel = Et.Label(typeof(object), "#return"); ScopeExpr = Et.Parameter(typeof(Scope), "#scope"); ThisExpr = Et.Parameter(typeof(IObj), "#this"); }
public Action<Scope> Build(List<Ast.Node> astNodes, Context context) { // Context we're compiling this code for Context = context; // Holds the uncompiled tuples of Expression<LambdaType> and List<string> of parameter LambdaTuples = new List<LambdaTuple>(); // Function table FuncTableExpr = Et.Parameter( typeof(FunctionTable), "#functbl" ); // Global function scope FunctionScope = new FunctionScope(); // Store the frame expr for global frame GlobalScopeExpr = Et.Parameter(typeof(Scope), "#globals"); // Stores all global expressions var globalExprs = new List<Et>(); // Store our "true" globals expression globalExprs.Add( Et.Assign( GlobalScopeExpr, FunctionScope.ScopeExpr ) ); // Walk each global node foreach (var node in astNodes) globalExprs.Add(node.Walk(this)); return Et.Lambda<Action<Scope>>( Et.Block( new[] { FuncTableExpr, GlobalScopeExpr }, // Create instance of our functable Et.Assign( FuncTableExpr, FunctionTable.EtNew() ), // Push functions into functable LambdaTuples.Count > 0 ? (Et) Et.Block( LambdaTuples.Select(x => FunctionTable.EtPush( FuncTableExpr, AstUtils.SimpleNewHelper( Lambda.Ctor1Arg, x.V1, Et.Constant(x.V2.ToArray()) ) ) ) ) : (Et) AstUtils.Empty(), // hack // Execute global scope Et.Block(globalExprs) ), FunctionScope.ScopeExpr ).Compile(); }