internal void OnModuleInclude(ModuleEventArgs e) { var h = ModuleInclude; if (h != null) { h(this, e); } }
//Includes a module reference (used for user references, Prelude and Components module). private CodeFrame IncludeModule(string alias, string name, string dllName, string[] path, int line, int col, bool reqQual, ElaExpression exp, bool addVar, bool noPrelude) { var modIndex = frame.HandleMap.Count; var modRef = new ModuleReference(frame, name, dllName, path, line, col, reqQual, modIndex); modRef.NoPrelude = noPrelude; frame.AddReference(alias, modRef); //Handles are filled by linker for module indexing at run-time frame.HandleMap.Add(-1); if (exp != null) { AddLinePragma(exp); } cw.Emit(Op.Runmod, modIndex); var addr = -1; if (addVar) { //Create a variable and bind to it module instance cw.Emit(Op.Newmod, modIndex); addr = AddVariable(alias, exp, ElaVariableFlags.Module | ElaVariableFlags.Private, modIndex); } //An event is handled by linker and a module is compiled/deserialized var ev = new ModuleEventArgs(modRef); comp.OnModuleInclude(ev); refs.Add(ev.Frame); if (addr != -1) { PopVar(addr); } return(ev.Frame); }
//Entry point internal void CompileUnit(ElaProgram prog) { frame.Layouts.Add(new MemoryLayout(0, 0, 1)); //top level layout cw.StartFrame(0); //Handles and references should be of the same length. This might not //be the case, if we are resuming in interactive mode. We should "align" them, //so they are of the same length. if (refs.Count != frame.HandleMap.Count) { for (var i = 0; i < frame.HandleMap.Count; i++) { refs.Add(null); } } //Determine whether this is fresh session. var scratch = cw.Offset == 0; //We always include prelude, but a module variable is created just once //(We check if we are not resuming in interactive mode (cw.Offset==0) and if yes //we don't create a variable 'prelude'. if (!String.IsNullOrEmpty(options.Prelude) && scratch) { IncludePrelude(prog, scratch); } //Always include arguments module if (scratch) { IncludeArguments(); } //Another workaround that is needed for interactive mode. We need //to restore a reference list with correct indices (LogicalHandle). //It can be done by working through the reference map and requesting all referenced //modules one more time. if (cw.Offset != 0) { var arr = new ModuleReference[frame.References.Count]; foreach (var kv in frame.References) { arr[kv.Value.LogicalHandle] = kv.Value; } for (var i = 0; i < arr.Length; i++) { var e = new ModuleEventArgs(arr[i]); comp.OnModuleInclude(e); refs[i] = e.Frame; } } var map = new LabelMap(); //Main compilation routine CompileProgram(prog, map); //Forcing evaluation of a program retval cw.Emit(Op.Force); //Every Ela module should end with a Stop op typeId cw.Emit(Op.Stop); cw.CompileOpList(); frame.Layouts[0].Size = currentCounter; frame.Layouts[0].StackSize = cw.FinishFrame(); }