From 34b8ee8a4e898461d350cb015f88708c7bdefdd3 Mon Sep 17 00:00:00 2001 From: brettlangdon Date: Fri, 9 Oct 2015 15:59:20 -0700 Subject: [PATCH] make more progress on compiler/assembler --- compiler/compiler.go | 20 ++++++++++++-------- compiler/instruction.go | 22 ++++++++++++++++++++++ compiler/scope.go | 15 ++++++++++++++- 3 files changed, 48 insertions(+), 9 deletions(-) create mode 100644 compiler/instruction.go diff --git a/compiler/compiler.go b/compiler/compiler.go index dfd48a9..c8d4e91 100644 --- a/compiler/compiler.go +++ b/compiler/compiler.go @@ -45,28 +45,32 @@ func (compiler *Compiler) exitScope() *Scope { func (compiler *Compiler) assemble(addNone bool) *gython.CodeObject { if addNone { - // compiler.addOp(bytecode.LOAD_CONST) - // compiler.addOp(bytecode.RETURN_VALUE) + compiler.addOpWithObject(bytecode.LOAD_CONST, gython.None, compiler.currentScope.Constants) + compiler.addOp(bytecode.RETURN_VALUE) } codeobject := gython.NewCodeObject([]byte{}, []byte{}, 0) return codeobject } -func (compiler *Compiler) addOp(op bytecode.Opcode, value gython.Object) bool { - // TODO: add `value` object and get oparg - oparg := 0 +func (compiler *Compiler) addOp(op bytecode.Opcode) { + instr := NewInstruction(op, nil, false) + compiler.currentScope.AddInstruction(instr) +} + +func (compiler *Compiler) addOpWithObject(op bytecode.Opcode, value gython.Object, args *gython.Dict) { + oparg := args.Length() + args.SetItem(oparg, value) instr := NewInstruction(op, oparg, true) compiler.currentScope.AddInstruction(instr) - return true } func (compiler *Compiler) visitExpression(expr ast.Expression) bool { switch expr := expr.(type) { case *ast.Num: - compiler.addOp(bytecode.LOAD_CONST, expr.Value) + compiler.addOpWithObject(bytecode.LOAD_CONST, expr.Value, compiler.currentScope.Constants) case *ast.Name: - compiler.addOp(bytecode.STORE_NAME, expr.Identifier) + compiler.addOpWithObject(bytecode.STORE_NAME, expr.Identifier, compiler.currentScope.Constants) default: fmt.Println(expr) } diff --git a/compiler/instruction.go b/compiler/instruction.go new file mode 100644 index 0000000..48f126c --- /dev/null +++ b/compiler/instruction.go @@ -0,0 +1,22 @@ +package compiler + +import ( + "github.com/brettlangdon/gython/bytecode" + "github.com/brettlangdon/gython/gython" +) + +type Instruction struct { + Opcode bytecode.Opcode + Oparg *gython.Float + Hasarg bool + Line int +} + +func NewInstruction(opcode bytecode.Opcode, oparg *gython.Float, hasarg bool) *Instruction { + return &Instruction{ + Opcode: opcode, + Oparg: oparg, + Hasarg: hasarg, + Line: 0, + } +} diff --git a/compiler/scope.go b/compiler/scope.go index a6bd9c6..1e4de54 100644 --- a/compiler/scope.go +++ b/compiler/scope.go @@ -1,12 +1,25 @@ package compiler +import "github.com/brettlangdon/gython/gython" + type Scope struct { Instructions []*Instruction + + Constants *gython.Dict + Names *gython.Dict + VariableNames *gython.Dict + FreeVariableNames *gython.Dict + CellVariableNames *gython.Dict } func NewScope() *Scope { return &Scope{ - Instructions: make([]*Instruction, 0), + Instructions: make([]*Instruction, 0), + Constants: gython.NewDict(), + Names: gython.NewDict(), + VariableNames: gython.NewDict(), + FreeVariableNames: gython.NewDict(), + CellVariableNames: gython.NewDict(), } }