public StackFrame(string pack, string file, int l, P5Code code, Opcode.ContextValues cxt, bool eval) { Package = pack; File = file; Line = l; Code = code; Context = cxt; IsEval = eval; }
public virtual IP5ScalarBody Assign(Runtime runtime, IP5ScalarBody other) { var osb = other as P5TypeglobBody; if (osb == null) return other.CloneBody(runtime); scalar = osb.scalar; array = osb.array; hash = osb.hash; handle = osb.handle; code = osb.code; return this; }
internal P5Code GenerateSub(Subroutine sub) { if (subroutines.ContainsKey(sub)) return subroutines[sub]; if (sub.Inner != null) foreach (var inner in sub.Inner) Generate(inner); var sg = new DynamicSubGenerator(runtime, this); var body = sg.Generate(sub, sub.IsMain); var deleg = body.Compile(); P5Code code; if (sub.IsConstant) { // TODO abstract away var const_op = sub.BasicBlocks[sub.BasicBlocks.Count - 2].Opcodes[1].Childs[0]; if (const_op.Number == Opcode.OpNumber.OP_MAKE_LIST) const_op = const_op.Childs[0]; object value; int flags; if (const_op.Number == Opcode.OpNumber.OP_CONSTANT_STRING) { value = ((ConstantString)const_op).Value; flags = 1; // CONST_STRING } else if (const_op.Number == Opcode.OpNumber.OP_CONSTANT_INTEGER) { value = ((ConstantInt)const_op).Value; flags = 10; // CONST_NUMBER|NUM_INTEGER } else if (const_op.Number == Opcode.OpNumber.OP_CONSTANT_FLOAT) { value = ((ConstantFloat)const_op).Value; flags = 18; // CONST_NUMBER|NUM_FLOAT } else if (sub.IsConstantPrototype) { value = null; flags = -1; } else throw new System.Exception("Invalid constant value"); code = new P5Code(sub.Name, deleg, value, flags); } else code = new P5Code(sub.Name, sub.Prototype, deleg, sub.IsMain); if (sub.IsMain) code.ScratchPad = P5ScratchPad.CreateMainPad(runtime, sub.Lexicals, main_pad); else code.ScratchPad = P5ScratchPad.CreateSubPad(runtime, sub.Lexicals, main_pad); if (sub.Name != null) { if (sub.Name == "BEGIN" || sub.Name.EndsWith("::BEGIN")) // TODO need to set the line number for caller() code.Call(runtime, Opcode.ContextValues.VOID, new P5Array(runtime)); else runtime.SymbolTable.DefineCode(runtime, sub.Name, code); } subroutines[sub] = code; return code; }
public void SetCode(Runtime runtime, string name, P5Code code) { P5Typeglob glob = GetGlob(runtime, name, true); glob.Code = code; }
public void DefineCode(Runtime runtime, string name, P5Code code) { P5Typeglob glob = GetGlob(runtime, name, true); if (glob.Code == null) glob.Code = code; else glob.Code.Assign(runtime, code); }
public void Assign(Runtime runtime, P5Code other) { subref = other.subref; proto = other.proto; scratchpad = other.scratchpad; const_value = other.const_value; const_flags = other.const_flags; }
public virtual P5Scalar MakeClosure(Runtime runtime, P5ScratchPad outer) { P5Code closure = new P5Code(name, proto, subref, is_main); if (scratchpad != null) closure.scratchpad = scratchpad.CloseOver(runtime, outer); if (const_flags == 0) return new P5Scalar(runtime, closure); // constant sub optimization var value = closure.scratchpad.GetScalar(runtime, 0) as P5Scalar; if (value == null) return new P5Scalar(runtime, closure); var body = value.Body as P5StringNumber; if (body == null) return new P5Scalar(runtime, closure); int constant_flags = 0; object constant_value = null; if (body.IsString(runtime)) { constant_value = body.AsString(runtime); constant_flags = 1; // CONST_STRING } else if (body.IsInteger(runtime)) { constant_value = body.AsInteger(runtime); constant_flags = 10; // CONST_NUMBER|NUM_INTEGER } else if (body.IsFloat(runtime)) { constant_value = body.AsFloat(runtime); constant_flags = 18; // CONST_NUMBER|NUM_FLOAT } if (constant_flags != 0) { var const_sub = new P5Code(null, subref, constant_value, constant_flags); const_sub.scratchpad = closure.scratchpad; closure = const_sub; } return new P5Scalar(runtime, closure); }