| 1 | #include "vminsns.hpp" |
|---|
| 2 | |
|---|
| 3 | vm_assembler::vm_assembler(){ |
|---|
| 4 | this->label_index = 0; |
|---|
| 5 | } |
|---|
| 6 | |
|---|
| 7 | vm_assembler & vm_assembler::add(vm_insn_type type, const SrcPos & p){ |
|---|
| 8 | vm_inst inst = {type, NULL, &p}; |
|---|
| 9 | |
|---|
| 10 | this->insns.push_back(inst); |
|---|
| 11 | this->label_index++; |
|---|
| 12 | return *this; |
|---|
| 13 | } |
|---|
| 14 | |
|---|
| 15 | vm_assembler & vm_assembler::add(vm_insn_type type, vm_operand operand, const SrcPos & p){ |
|---|
| 16 | |
|---|
| 17 | vm_inst inst = {type, NULL, &p}; |
|---|
| 18 | |
|---|
| 19 | switch(operand.kind){ |
|---|
| 20 | case vm_operand_pyval: |
|---|
| 21 | inst.operand = operand.u.pyval; |
|---|
| 22 | break; |
|---|
| 23 | case vm_operand_int: |
|---|
| 24 | inst.operand = (void*) operand.u.i; |
|---|
| 25 | break; |
|---|
| 26 | case vm_operand_name: |
|---|
| 27 | inst.operand = (void*) operand.u.name; |
|---|
| 28 | break; |
|---|
| 29 | } |
|---|
| 30 | this->insns.push_back(inst); |
|---|
| 31 | |
|---|
| 32 | this->label_index++; |
|---|
| 33 | |
|---|
| 34 | return *this; |
|---|
| 35 | } |
|---|
| 36 | |
|---|
| 37 | void vm_assembler::fundef(const symbol_t name, int arity, int locals, Env & genv, const SrcPos & pos){ |
|---|
| 38 | genv.set_sym(name, Py_val::mk_vm_ifun(name, arity, locals, this->label_index, pos)); |
|---|
| 39 | } |
|---|
| 40 | |
|---|
| 41 | vm_assembler & vm_assembler::label(const string & str){ |
|---|
| 42 | this->labels[Symbol::get(str)] = this->label_index; |
|---|
| 43 | return *this; |
|---|
| 44 | } |
|---|
| 45 | |
|---|
| 46 | vm_inst * vm_assembler::assemble(){ |
|---|
| 47 | vm_inst * ret; |
|---|
| 48 | ret = new vm_inst[this->insns.size()]; |
|---|
| 49 | |
|---|
| 50 | // do it later |
|---|
| 51 | |
|---|
| 52 | return ret; |
|---|
| 53 | } |
|---|
| 54 | |
|---|
| 55 | |
|---|
| 56 | void vm_assembler::print(Env & genv){ |
|---|
| 57 | // genv.debug_print_all(); |
|---|
| 58 | #include "vminsns_print.inc" |
|---|
| 59 | } |
|---|
| 60 | |
|---|
| 61 | string vm_assembler::operand_str(vm_insn_type type, py_val_t operand, Env & genv){ |
|---|
| 62 | stringstream ss; |
|---|
| 63 | stack<Stack_trace_entry> bt; SrcPos p; // dummy |
|---|
| 64 | |
|---|
| 65 | switch(type){ |
|---|
| 66 | case VM_GREF_CALL: |
|---|
| 67 | { |
|---|
| 68 | py_val_t f = genv.lookup_sym((symbol_t)operand); |
|---|
| 69 | ss << *((symbol_t)operand); |
|---|
| 70 | if (f == py_val_not_found){ |
|---|
| 71 | ss << ": not found"; |
|---|
| 72 | } else if (f->type == py_type_vm_ifun){ |
|---|
| 73 | ss << ": start at " << f->u.vm_i->addr; |
|---|
| 74 | } else { |
|---|
| 75 | ss << ": native function"; |
|---|
| 76 | } |
|---|
| 77 | } |
|---|
| 78 | break; |
|---|
| 79 | case VM_LDEFUN: |
|---|
| 80 | { |
|---|
| 81 | py_val_t f = operand; |
|---|
| 82 | ss << f->u.vm_i->name << ": start at " |
|---|
| 83 | << f->u.vm_i->addr; |
|---|
| 84 | |
|---|
| 85 | } |
|---|
| 86 | break; |
|---|
| 87 | case VM_GDEFUN: |
|---|
| 88 | case VM_GREF: |
|---|
| 89 | case VM_GSET: |
|---|
| 90 | case VM_GINC: |
|---|
| 91 | case VM_GREF_PUSH: |
|---|
| 92 | ss << *((symbol_t)operand); |
|---|
| 93 | break; |
|---|
| 94 | case VM_GOTO: |
|---|
| 95 | case VM_GOTOIF: |
|---|
| 96 | case VM_GOTOIFNOT: |
|---|
| 97 | case VM_LSET: |
|---|
| 98 | case VM_LINC: |
|---|
| 99 | case VM_LREF: |
|---|
| 100 | case VM_LREF_ADD2: |
|---|
| 101 | case VM_LREF_SUB2: |
|---|
| 102 | case VM_LREF_MUL2: |
|---|
| 103 | case VM_LREF_DIV2: |
|---|
| 104 | case VM_LREF_CALL: |
|---|
| 105 | case VM_LREF_PUSH: |
|---|
| 106 | case VM_MKLIST: |
|---|
| 107 | case VM_MKTUPLE: |
|---|
| 108 | case VM_MKDICT: |
|---|
| 109 | ss << (int)operand; |
|---|
| 110 | break; |
|---|
| 111 | default: |
|---|
| 112 | { |
|---|
| 113 | Py_val::to_str(ss, operand, bt, p); |
|---|
| 114 | } |
|---|
| 115 | } |
|---|
| 116 | |
|---|
| 117 | return ss.str(); |
|---|
| 118 | } |
|---|
| 119 | |
|---|
| 120 | vm_operand vm_operand::name(const symbol_t name){ |
|---|
| 121 | vm_operand ret; |
|---|
| 122 | ret.kind = vm_operand_name; |
|---|
| 123 | ret.u.name = name; |
|---|
| 124 | |
|---|
| 125 | return ret; |
|---|
| 126 | } |
|---|
| 127 | |
|---|
| 128 | vm_operand vm_operand::pyval(py_val_t pyval){ |
|---|
| 129 | vm_operand ret; |
|---|
| 130 | ret.kind = vm_operand_pyval; |
|---|
| 131 | ret.u.pyval = pyval; |
|---|
| 132 | |
|---|
| 133 | return ret; |
|---|
| 134 | } |
|---|
| 135 | |
|---|
| 136 | |
|---|
| 137 | vm_operand vm_operand::integer(int i){ |
|---|
| 138 | vm_operand ret; |
|---|
| 139 | ret.kind = vm_operand_int; |
|---|
| 140 | ret.u.i = i; |
|---|
| 141 | |
|---|
| 142 | return ret; |
|---|
| 143 | } |
|---|