Permalink
Browse files

Generate the instructions from yaml file.

  • Loading branch information...
1 parent 0a211b4 commit d10eb346b5d9aa66fcb2823b7916220ba6c40046 @pluskid committed Jul 4, 2008
Showing with 363 additions and 140 deletions.
  1. +3 −0 .gitignore
  2. +2 −14 codec.py
  3. +0 −124 iseq.py
  4. +204 −0 iset.yml
  5. +152 −0 iset_gen.py
  6. +2 −2 vm.py
View
@@ -0,0 +1,3 @@
+*.pyc
+insns.py
+iset.py
View
@@ -1,21 +1,9 @@
-import iseq
-
-class Instruction(object):
- def __init__(self, opcode, data):
- self.opcode = opcode
- self.name = data[1]
- self.length = data[0]
- self.tag = data[3]
-
-INSN_MAP = {}
-for i in range(len(iseq.INSNS)):
- insn = Instruction(i, iseq.INSNS[i])
- INSN_MAP[insn.name] = insn
+import iset
def inplace_encode(asm):
i = 0
while i < len(asm):
- insn = INSN_MAP[asm[i]]
+ insn = iset.INSN_MAP[asm[i]]
asm[i] = insn.opcode
i += insn.length
return asm
View
124 iseq.py
@@ -1,124 +0,0 @@
-def op_ret(ctx):
- ctx.vm.ret()
-
-def op_call(ctx):
- proc_name = get_param(1)
- argc = get_param(2)
-
-def op_push_local(ctx):
- pass
-
-def op_push_literal(ctx):
- idx = get_param(ctx, 1)
- lit = ctx.proc.literals[idx]
- ctx.vm.stk_push(lit)
-
-def op_push_0(ctx):
- ctx.vm.stk_push(0)
-
-def op_push_1(ctx):
- ctx.vm.stk_push(1)
-
-def op_dup(ctx):
- ctx.vm.stk_push(ctx.vm.stk_top())
-
-def op_plus(ctx):
- res = ctx.vm.stk_pop() + ctx.vm.stk_pop()
- ctx.vm.stk_push(res)
-
-def op_minus(ctx):
- res = ctx.vm.stk_pop() - ctx.vm.stk_pop()
- ctx.vm.stk_push(res)
-
-def op_multiply(ctx):
- res = ctx.vm.stk_pop() * ctx.vm.stk_pop()
- ctx.vm.stk_push(res)
-
-def op_divide(ctx):
- res = ctx.vm.stk_pop() / ctx.vm.stk_pop()
- ctx.vm.stk_push(res)
-
-def op_equal(ctx):
- res = (ctx.vm.stk_pop() == ctx.vm.stk_pop())
- ctx.vm.stk_push(res)
-
-def op_goto(ctx):
- ip = get_param(ctx, 1)
- ctx.ip = ip
-
-def op_goto_if_true(ctx):
- ip = get_param(ctx, 1)
- cond = ctx.vm.stk_pop()
- if cond is True:
- ctx.ip = ip
- else:
- ctx.ip += 2 # insn length = 2
-
-def op_goto_if_not_true(ctx):
- ip = get_param(ctx, 1)
- cond = ctx.vm.stk_pop()
- if cond is not True:
- ctx.ip = ip
- else:
- ctx.ip += 2 # insn length = 2
-
-def op_push_local(ctx):
- idx = get_param(ctx, 1)
- loc = ctx.proc.locals[idx]
- ctx.vm.stk_push(loc)
-
-def op_set_local(ctx):
- idx = get_param(ctx, 1)
- val = ctx.vm.stk_pop()
- ctx.proc.locals[idx] = val
-
-# Instruction Tags
-TAG_NORMAL = 0
-TAG_CTL_FLOW = 1
-
-INSNS = [
- # length name action tag
- ( 1, "ret", op_ret, TAG_NORMAL),
- ( 3, "call", op_call, TAG_NORMAL),
- ( 2, "goto", op_goto, TAG_NORMAL),
- ( 2, "push_local", op_push_local, TAG_NORMAL),
- ( 1, "push_0", op_push_0, TAG_NORMAL),
- ( 1, "push_1", op_push_1, TAG_NORMAL),
- ( 2, "push_literal", op_push_literal, TAG_NORMAL),
- ( 1, "dup", op_dup, TAG_NORMAL),
- ( 1, "plus", op_plus, TAG_NORMAL),
- ( 1, "minus", op_minus, TAG_NORMAL),
- ( 1, "multiply", op_multiply, TAG_NORMAL),
- ( 1, "divide", op_divide, TAG_NORMAL),
- ( 1, "equal", op_equal, TAG_NORMAL),
- ( 2, "goto", op_goto, TAG_CTL_FLOW),
- ( 2, "goto_if_true", op_goto_if_true, TAG_CTL_FLOW),
- ( 2, "goto_if_not_true", op_goto_if_not_true, TAG_CTL_FLOW),
- ( 2, "push_local", op_push_local, TAG_NORMAL),
- ( 2, "set_local", op_set_local, TAG_NORMAL)
- ]
-
-def run(vm):
- ctx = vm.ctx
- while ctx.ip < len(ctx.bytecode):
- opcode = ctx.bytecode[ctx.ip]
- insn_action(opcode)(ctx)
- if not has_tag(opcode, TAG_CTL_FLOW):
- ctx.ip = ctx.ip + insn_length(opcode)
-
-
-
-def insn_length(insn):
- return INSNS[insn][0]
-
-def insn_action(insn):
- return INSNS[insn][2]
-
-def insn_tag(insn):
- return INSNS[insn][3]
-
-def get_param(ctx, n):
- return ctx.bytecode[ctx.ip+n]
-
-def has_tag(opcode, tag):
- return (insn_tag(opcode) & tag) == tag
View
204 iset.yml
@@ -0,0 +1,204 @@
+tags:
+ - ctrl_flow
+ - ctx_switch
+
+# Instructions
+#
+# The opcode is the index of each instruction. Stack before and after
+# instruction is only for documenting purpose. The elements are
+# specified from bottom to top. E.g:
+#
+# stack_before: [a, b]
+# stack_after: [b-a]
+#
+# will be
+#
+# +---------+
+# | b |
+# +---------+ ==> +---------+
+# | a | | b-a |
+# +---------+ +---------+
+#
+
+instructions:
+ -
+ name: ret
+ tags: [ctx_switch, ctrl_flow]
+ desc: Return from a procedure.
+ operands: []
+ stack_before: [return_value]
+ stack_after: []
+ code: |
+ pass
+
+ -
+ name: call
+ tags: [ctx_switch, ctrl_flow]
+ desc: Call a procedure.
+ operands: []
+ stack_before: []
+ stack_after: []
+ code: |
+ pass
+
+ -
+ name: push_local
+ tags: []
+ desc: Push value of a local variable to operand stack.
+ operands: [local]
+ stack_before: []
+ stack_after: [value]
+ code: |
+ idx = get_param(ctx, 1)
+ loc = ctx.proc.locals[idx]
+ ctx.vm.stk_push(loc)
+
+ -
+ name: set_local
+ tags: []
+ desc: Pop the stack top and assign it to a local variable.
+ operands: [local]
+ stack_before: [value]
+ stack_after: []
+ code: |
+ idx = get_param(ctx, 1)
+ val = ctx.vm.stk_pop()
+ ctx.proc.locals[idx] = val
+
+ -
+ name: push_literal
+ tags: []
+ desc: Push a literal to operand stack.
+ operands: [literal]
+ stack_before: []
+ stack_after: [value]
+ code: |
+ idx = get_param(ctx, 1)
+ lit = ctx.proc.literals[idx]
+ ctx.vm.stk_push(lit)
+
+ -
+ name: push_0
+ tags: []
+ desc: Push 0 to operand stack.
+ operands: []
+ stack_before: []
+ stack_after: [0]
+ code: |
+ ctx.vm.stk_push(0)
+
+ -
+ name: push_1
+ tags: []
+ desc: Push 1 to operand stack.
+ operands: []
+ stack_before: []
+ stack_after: [0]
+ code: |
+ ctx.vm.stk_push(1)
+
+ -
+ name: dup
+ tags: []
+ desc: Duplicate the stack top object.
+ operands: []
+ stack_before: []
+ stack_after: [value]
+ code: |
+ ctx.vm.stk_push(ctx.vm.stk_top())
+
+ -
+ name: plus
+ tags: []
+ desc: Performan arithmetic +
+ operands: []
+ stack_before: [a, b]
+ stack_after: [b+a]
+ code: |
+ res = ctx.vm.stk_pop() + ctx.vm.stk_pop()
+ ctx.vm.stk_push(res)
+
+ -
+ name: minus
+ tags: []
+ desc: Performan arithmetic -
+ operands: []
+ stack_before: [a, b]
+ stack_after: [b-a]
+ code: |
+ res = ctx.vm.stk_pop() - ctx.vm.stk_pop()
+ ctx.vm.stk_push(res)
+
+ -
+ name: multiply
+ tags: []
+ desc: Performan arithmetic *
+ operands: []
+ stack_before: [a, b]
+ stack_after: [b*a]
+ code: |
+ res = ctx.vm.stk_pop() * ctx.vm.stk_pop()
+ ctx.vm.stk_push(res)
+
+ -
+ name: divide
+ tags: []
+ desc: Performance arithmetic /
+ operands: []
+ stack_before: [a, b]
+ stack_after: [b/a]
+ code: |
+ res = ctx.vm.stk_pop() / ctx.vm.stk_pop()
+ ctx.vm.stk_push(res)
+
+ -
+ name: equal
+ tags: []
+ desc: Test equality.
+ operands: []
+ stack_before: [a, b]
+ stack_after: [b==a]
+ code: |
+ res = (ctx.vm.stk_pop() == ctx.vm.stk_pop())
+ ctx.vm.stk_push(res)
+
+ -
+ name: goto
+ tags: [ctrl_flow]
+ desc: Unconditional jump.
+ operands: [ip]
+ stack_before: []
+ stack_after: []
+ code: |
+ ip = get_param(ctx, 1)
+ ctx.ip = ip
+
+ -
+ name: goto_if_true
+ tags: [ctrl_flow]
+ desc: Jump if the stack top is true.
+ operands: [ip]
+ stack_before: [condition]
+ stack_after: []
+ code: |
+ ip = get_param(ctx, 1)
+ cond = ctx.vm.stk_pop()
+ if cond is True:
+ ctx.ip = ip
+ else:
+ ctx.ip += $(insn_len)
+
+ -
+ name: goto_if_not_true
+ tags: [ctrl_flow]
+ desc: Jump if the stack top is not true.
+ operands: [ip]
+ stack_before: [condition]
+ stack_after: []
+ code: |
+ ip = get_param(ctx, 1)
+ cond = ctx.vm.stk_pop()
+ if cond is not True:
+ ctx.ip = ip
+ else:
+ ctx.ip += $(insn_len)
Oops, something went wrong.

0 comments on commit d10eb34

Please sign in to comment.