# Don't edit this file. This is generated by iset_gen.py

class Instruction(object):
    __slots__ = ('opcode',
                 'name',
                 'tags',
                 'desc',
                 'operands',
                 'stack_before',
                 'stack_after',
                 'code')
    def __init__(self, opcode, name, tags, desc, operands,
                 stack_before, stack_after, code):
        self.opcode = opcode
        self.name = name
        self.tags = tags
        self.desc = desc
        self.operands = operands
        self.stack_before = stack_before
        self.stack_after = stack_after
        self.code = code

    def length_get(self):
        return len(self.operands)+1
    def length_set(self):
        raise AttributeError('length attribute is read only')
    length = property(length_get, length_set, 'length of the instruction')

INSTRUCTIONS = [
Instruction(0,
            'ret',
            ['ctx_switch', 'ctrl_flow'],
            'Return from a procedure.',
            [],
            [],
            [],
            'pctx = ctx.parent\nretval = ctx.pop()\npctx.push(retval)\nreturn pctx\n'),
Instruction(1,
            'call',
            ['ctx_switch', 'ctrl_flow'],
            'Call a procedure.',
            ['argc'],
            ['...', 'proc'],
            ['retval'],
            'argc = get_param(ctx, 1)\nnctx = make_call(ctx, argc)\n\nctx.ip += $(insn_len)\nreturn nctx\n'),
Instruction(2,
            'tail_call',
            ['ctx_switch', 'ctrl_flow'],
            'Call a procedure with tail-call.',
            ['argc'],
            ['...', 'proc'],
            ['retval'],
            'argc = get_param(ctx, 1)\nnctx = make_call(ctx, argc, tail=True)\n\nctx.ip += $(insn_len)\nreturn nctx\n'),
Instruction(3,
            'call_cc',
            ['ctx_switch', 'ctrl_flow'],
            'Call with current continuation.',
            [],
            ['lambda'],
            ['return_value'],
            'cc = Continuation(ctx, $(insn_len), 1)\nctx.insert(-1, cc)\n\nnctx = make_call(ctx, 1)\nctx.ip += $(insn_len)\nreturn nctx\n'),
Instruction(4,
            'pop',
            [],
            'Pop the value off from the operand stack.',
            [],
            ['value'],
            [],
            'ctx.pop()\n'),
Instruction(5,
            'push_local',
            [],
            'Push value of a local variable to operand stack.',
            ['local'],
            [],
            ['value'],
            'idx = get_param(ctx, 1)\nloc = ctx.env.read_local(idx)\nctx.push(loc)\n'),
Instruction(6,
            'set_local',
            [],
            'Pop the stack top and assign it to a local variable.',
            ['local'],
            ['value'],
            [],
            'idx = get_param(ctx, 1)\nval = ctx.pop()\nctx.env.assign_local(idx, val)\n'),
Instruction(7,
            'push_local_depth',
            [],
            'Push value of a local in lexical parent to operand stack.',
            ['depth', 'local'],
            [],
            ['value'],
            'depth = get_param(ctx, 1)\nidx = get_param(ctx, 2)\n\npenv = ctx.env\nwhile depth > 0:\n    penv = penv.parent\n    depth -= 1\nloc = penv.read_local(idx)\nctx.push(loc)\n'),
Instruction(8,
            'set_local_depth',
            [],
            'Pop a value and assign to a local variable of lexical parent.',
            ['depth', 'local'],
            ['value'],
            [],
            'depth = get_param(ctx, 1)\nidx = get_param(ctx, 2)\nvalue = ctx.pop()\n\npenv = ctx.env\nwhile depth > 0:\n    penv = penv.parent\n    depth -= 1\npenv.assign_local(idx, value)\n'),
Instruction(9,
            'push_literal',
            [],
            'Push a literal to operand stack.',
            ['literal'],
            [],
            ['value'],
            'idx = get_param(ctx, 1)\nlit = ctx.form.literals[idx]\nctx.push(lit)\n'),
Instruction(10,
            'push_0',
            [],
            'Push 0 to operand stack.',
            [],
            [],
            [0],
            'ctx.push(0)\n'),
Instruction(11,
            'push_1',
            [],
            'Push 1 to operand stack.',
            [],
            [],
            [0],
            'ctx.push(1)\n'),
Instruction(12,
            'push_nil',
            [],
            'Push None to oeprand stack.',
            [],
            [],
            ['None'],
            'ctx.push(None)\n'),
Instruction(13,
            'push_true',
            [],
            'Push True to oeprand stack.',
            [],
            [],
            [True],
            'ctx.push(True)\n'),
Instruction(14,
            'push_false',
            [],
            'Push False to oeprand stack.',
            [],
            [],
            [False],
            'ctx.push(False)\n'),
Instruction(15,
            'dup',
            [],
            'Duplicate the stack top object.',
            [],
            [],
            ['value'],
            'ctx.push(ctx.top())\n'),
Instruction(16,
            'goto',
            ['ctrl_flow'],
            'Unconditional jump.',
            ['ip'],
            [],
            [],
            'ip = get_param(ctx, 1)\nctx.ip = ip\n'),
Instruction(17,
            'goto_if_not_false',
            ['ctrl_flow'],
            'Jump if the stack top is not False.',
            ['ip'],
            ['condition'],
            [],
            'ip = get_param(ctx, 1)\ncond = ctx.pop()\nif cond is not False:\n    ctx.ip = ip\nelse:\n    ctx.ip += $(insn_len)\n'),
Instruction(18,
            'goto_if_false',
            ['ctrl_flow'],
            'Jump if the stack top is False.',
            ['ip'],
            ['condition'],
            [],
            'ip = get_param(ctx, 1)\ncond = ctx.pop()\nif cond is False:\n    ctx.ip = ip\nelse:\n    ctx.ip += $(insn_len)\n'),
Instruction(19,
            'fix_lexical',
            [],
            'Fix the lexical_parent of an object.',
            [],
            ['obj'],
            ['obj'],
            'proc = ctx.top()\nproc.lexical_parent = ctx.env\n'),
Instruction(20,
            'fix_lexical_pop',
            [],
            'Like fix_literal, but pop the object off after fixing.',
            [],
            ['obj'],
            [],
            'proc = ctx.pop()\nproc.lexical_parent = ctx.env\n'),
Instruction(21,
            'fix_lexical_depth',
            [],
            'Fix the lexical_parent of an object.',
            ['depth'],
            ['obj'],
            ['obj'],
            'depth = get_param(ctx, 1)\nproc = ctx.top()\nenv = ctx.env\nwhile depth > 0:\n    env = env.parent\n    depth -= 1\nproc.lexical_parent = env\n'),
Instruction(22,
            'dynamic_eval',
            [],
            'Evaluate a DynamicClosure and push the result.',
            [],
            ['dynamic_closure'],
            ['result'],
            'dc = ctx.pop()\nform = dc.form\nenv = dc.lexical_parent\nctx.push(form.eval(env, ctx.vm))\n'),
Instruction(23,
            'dynamic_set_local',
            [],
            'Assignment of SymbolClosure.',
            ['idx'],
            ['value', 'sym_closure'],
            [],
            'idx = get_param(ctx, 1)\nsym_closure = ctx.pop()\nvalue = ctx.pop()\n\nenv = sym_closure.lexical_parent\nenv.assign_local(idx, value)\n'),
Instruction(24,
            'dynamic_set_local_depth',
            [],
            'Assignment of SymbolClosure.',
            ['depth', 'idx'],
            ['value', 'sym_closure'],
            [],
            'depth = get_param(ctx, 1)\nidx = get_param(ctx, 2)\nsym_closure = ctx.pop()\nvalue = ctx.pop()\n\nenv = sym_closure.lexical_parent\nwhile depth > 0:\n    env = env.parent\n    depth -= 1\nenv.assign_local(idx, value)\n')]

INSN_MAP = {
    'ret' : INSTRUCTIONS[0],
    'call' : INSTRUCTIONS[1],
    'tail_call' : INSTRUCTIONS[2],
    'call_cc' : INSTRUCTIONS[3],
    'pop' : INSTRUCTIONS[4],
    'push_local' : INSTRUCTIONS[5],
    'set_local' : INSTRUCTIONS[6],
    'push_local_depth' : INSTRUCTIONS[7],
    'set_local_depth' : INSTRUCTIONS[8],
    'push_literal' : INSTRUCTIONS[9],
    'push_0' : INSTRUCTIONS[10],
    'push_1' : INSTRUCTIONS[11],
    'push_nil' : INSTRUCTIONS[12],
    'push_true' : INSTRUCTIONS[13],
    'push_false' : INSTRUCTIONS[14],
    'dup' : INSTRUCTIONS[15],
    'goto' : INSTRUCTIONS[16],
    'goto_if_not_false' : INSTRUCTIONS[17],
    'goto_if_false' : INSTRUCTIONS[18],
    'fix_lexical' : INSTRUCTIONS[19],
    'fix_lexical_pop' : INSTRUCTIONS[20],
    'fix_lexical_depth' : INSTRUCTIONS[21],
    'dynamic_eval' : INSTRUCTIONS[22],
    'dynamic_set_local' : INSTRUCTIONS[23],
    'dynamic_set_local_depth' : INSTRUCTIONS[24]
}

