示例#1
0
 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;
 }
示例#2
0
        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;
        }
示例#4
0
 public void SetCode(Runtime runtime, string name, P5Code code)
 {
     P5Typeglob glob = GetGlob(runtime, name, true);
     glob.Code = code;
 }
示例#5
0
        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);
        }
示例#6
0
 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;
 }
示例#7
0
        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);
        }