diff --git a/compiler/compiler.go b/compiler/compiler.go index c8d4e91..93016ae 100644 --- a/compiler/compiler.go +++ b/compiler/compiler.go @@ -50,6 +50,27 @@ func (compiler *Compiler) assemble(addNone bool) *gython.CodeObject { } codeobject := gython.NewCodeObject([]byte{}, []byte{}, 0) + for _, instr := range compiler.currentScope.Instructions { + arg := 0 + ext := 0 + size := instr.Size() + if instr.Hasarg { + arg = int(instr.Oparg.Value) + ext = arg >> 16 + } + + if size == 6 { + codeobject.AppendOpcode(bytecode.EXTENDED_ARG) + codeobject.AppendInt(ext & 0xff) + codeobject.AppendInt(ext >> 8) + arg &= 0xffff + } + codeobject.AppendOpcode(instr.Opcode) + if instr.Hasarg { + codeobject.AppendInt(arg & 0xff) + codeobject.AppendInt(arg >> 8) + } + } return codeobject } diff --git a/compiler/instruction.go b/compiler/instruction.go index 48f126c..ca6e4a2 100644 --- a/compiler/instruction.go +++ b/compiler/instruction.go @@ -20,3 +20,15 @@ func NewInstruction(opcode bytecode.Opcode, oparg *gython.Float, hasarg bool) *I Line: 0, } } + +func (instruction *Instruction) Size() int { + if instruction.Hasarg == false { + // 1 byte for the opcode + return 1 + } else if instruction.Oparg.Value > 0xffff { + // 1 (opcode) + 1 (EXTENDED_ARG opcode) + 2 (oparg) + 2(oparg extended) + return 6 + } + // 1 (opcode) + 2 (oparg) + return 3 +} diff --git a/gython/bytes.go b/gython/bytes.go index 2090d1d..8a9bece 100644 --- a/gython/bytes.go +++ b/gython/bytes.go @@ -1,10 +1,22 @@ package gython type Bytes struct { + value []byte } -func (bytes *Bytes) object() {} - func NewBytes() *Bytes { - return &Bytes{} + return &Bytes{ + value: make([]byte, 0), + } +} + +func (bytes *Bytes) object() {} +func (bytes *Bytes) Append(b byte) { + bytes.value = append(bytes.value, b) +} +func (bytes *Bytes) String() string { + return string(bytes.value) +} +func (bytes *Bytes) Value() []byte { + return bytes.value } diff --git a/gython/codeobject.go b/gython/codeobject.go index 0319d6e..b6d7b2a 100644 --- a/gython/codeobject.go +++ b/gython/codeobject.go @@ -1,5 +1,7 @@ package gython +import "github.com/brettlangdon/gython/bytecode" + type CodeObject struct { ArgCount int KeywordOnlyArgCount int @@ -43,3 +45,9 @@ func NewCodeObject(filename []byte, name []byte, firstLineNumber int) *CodeObjec } func (codeobject *CodeObject) object() {} +func (codeobject *CodeObject) AppendOpcode(op bytecode.Opcode) { + codeobject.Code.Append(byte(op)) +} +func (codeobject *CodeObject) AppendInt(i int) { + codeobject.Code.Append(byte(i)) +}