From 6e5c35c9ee4d6b1d3495e6d140cb22d09e248aab Mon Sep 17 00:00:00 2001 From: Sky Johnson Date: Tue, 6 May 2025 12:09:17 -0500 Subject: [PATCH] move types to types --- compiler/compiler.go | 46 ++++++++++++++++++------------------ main.go => repl.go | 0 types/types.go | 30 +++++++++++++++++++++++- vm/vm.go | 56 +++++++++++--------------------------------- 4 files changed, 66 insertions(+), 66 deletions(-) rename main.go => repl.go (100%) diff --git a/compiler/compiler.go b/compiler/compiler.go index d87a544..de83107 100644 --- a/compiler/compiler.go +++ b/compiler/compiler.go @@ -2,14 +2,14 @@ package compiler import ( "git.sharkk.net/Sharkk/Mako/parser" - "git.sharkk.net/Sharkk/Mako/vm" + "git.sharkk.net/Sharkk/Mako/types" ) // Compile converts AST to bytecode -func Compile(program *parser.Program) *vm.Bytecode { +func Compile(program *parser.Program) *types.Bytecode { c := &compiler{ constants: []any{}, - instructions: []vm.Instruction{}, + instructions: []types.Instruction{}, scopes: []scope{}, } @@ -22,7 +22,7 @@ func Compile(program *parser.Program) *vm.Bytecode { c.exitScope() - return &vm.Bytecode{ + return &types.Bytecode{ Constants: c.constants, Instructions: c.instructions, } @@ -34,7 +34,7 @@ type scope struct { type compiler struct { constants []any - instructions []vm.Instruction + instructions []types.Instruction scopes []scope } @@ -42,12 +42,12 @@ func (c *compiler) enterScope() { c.scopes = append(c.scopes, scope{ variables: make(map[string]bool), }) - c.emit(vm.OpEnterScope, 0) + c.emit(types.OpEnterScope, 0) } func (c *compiler) exitScope() { c.scopes = c.scopes[:len(c.scopes)-1] - c.emit(vm.OpExitScope, 0) + c.emit(types.OpExitScope, 0) } func (c *compiler) declareVariable(name string) { @@ -73,21 +73,21 @@ func (c *compiler) compileStatement(stmt parser.Statement) { // Use SetGlobal for top-level variables to persist between REPL lines if len(c.scopes) <= 1 { - c.emit(vm.OpSetGlobal, nameIndex) + c.emit(types.OpSetGlobal, nameIndex) } else { c.declareVariable(s.Name.Value) - c.emit(vm.OpSetLocal, nameIndex) + c.emit(types.OpSetLocal, nameIndex) } case *parser.IndexAssignmentStatement: c.compileExpression(s.Left) c.compileExpression(s.Index) c.compileExpression(s.Value) - c.emit(vm.OpSetIndex, 0) + c.emit(types.OpSetIndex, 0) case *parser.EchoStatement: c.compileExpression(s.Value) - c.emit(vm.OpEcho, 0) + c.emit(types.OpEcho, 0) case *parser.BlockStatement: c.enterScope() @@ -102,48 +102,48 @@ func (c *compiler) compileExpression(expr parser.Expression) { switch e := expr.(type) { case *parser.StringLiteral: constIndex := c.addConstant(e.Value) - c.emit(vm.OpConstant, constIndex) + c.emit(types.OpConstant, constIndex) case *parser.NumberLiteral: constIndex := c.addConstant(e.Value) - c.emit(vm.OpConstant, constIndex) + c.emit(types.OpConstant, constIndex) case *parser.Identifier: nameIndex := c.addConstant(e.Value) // Check if it's a local variable first if c.isLocalVariable(e.Value) { - c.emit(vm.OpGetLocal, nameIndex) + c.emit(types.OpGetLocal, nameIndex) } else { // Otherwise treat as global - c.emit(vm.OpGetGlobal, nameIndex) + c.emit(types.OpGetGlobal, nameIndex) } case *parser.TableLiteral: - c.emit(vm.OpNewTable, 0) + c.emit(types.OpNewTable, 0) for key, value := range e.Pairs { - c.emit(vm.OpDup, 0) + c.emit(types.OpDup, 0) // Special handling for identifier keys in tables if ident, ok := key.(*parser.Identifier); ok { // Treat identifiers as string literals in table keys strIndex := c.addConstant(ident.Value) - c.emit(vm.OpConstant, strIndex) + c.emit(types.OpConstant, strIndex) } else { // For other expressions, compile normally c.compileExpression(key) } c.compileExpression(value) - c.emit(vm.OpSetIndex, 0) - c.emit(vm.OpPop, 0) + c.emit(types.OpSetIndex, 0) + c.emit(types.OpPop, 0) } case *parser.IndexExpression: c.compileExpression(e.Left) c.compileExpression(e.Index) - c.emit(vm.OpGetIndex, 0) + c.emit(types.OpGetIndex, 0) } } @@ -152,8 +152,8 @@ func (c *compiler) addConstant(value any) int { return len(c.constants) - 1 } -func (c *compiler) emit(op vm.Opcode, operand int) { - instruction := vm.Instruction{ +func (c *compiler) emit(op types.Opcode, operand int) { + instruction := types.Instruction{ Opcode: op, Operand: operand, } diff --git a/main.go b/repl.go similarity index 100% rename from main.go rename to repl.go diff --git a/types/types.go b/types/types.go index 78e6210..dcf4d44 100644 --- a/types/types.go +++ b/types/types.go @@ -7,9 +7,37 @@ const ( TypeNumber TypeString TypeBoolean - TypeTable // New type for tables + TypeTable ) +type Opcode byte + +const ( + OpConstant Opcode = iota + OpSetLocal + OpGetLocal + OpSetGlobal + OpGetGlobal + OpEcho + OpNewTable + OpSetIndex + OpGetIndex + OpDup + OpPop + OpEnterScope + OpExitScope +) + +type Instruction struct { + Opcode Opcode + Operand int +} + +type Bytecode struct { + Constants []any + Instructions []Instruction +} + type Value struct { Type ValueType Data any diff --git a/vm/vm.go b/vm/vm.go index c7e3c5f..7548108 100644 --- a/vm/vm.go +++ b/vm/vm.go @@ -6,34 +6,6 @@ import ( "git.sharkk.net/Sharkk/Mako/types" ) -type Opcode byte - -const ( - OpConstant Opcode = iota - OpSetLocal // Set local variable - OpGetLocal // Get local variable - OpSetGlobal // Set global variable - OpGetGlobal // Get global variable - OpEcho - OpNewTable - OpSetIndex - OpGetIndex - OpDup - OpPop - OpEnterScope // New opcode for entering a block - OpExitScope // New opcode for exiting a block -) - -type Instruction struct { - Opcode Opcode - Operand int -} - -type Bytecode struct { - Constants []any - Instructions []Instruction -} - // Scope represents a lexical scope type Scope struct { Variables map[string]types.Value @@ -56,14 +28,14 @@ func New() *VM { } } -func (vm *VM) Run(bytecode *Bytecode) { +func (vm *VM) Run(bytecode *types.Bytecode) { vm.constants = bytecode.Constants for ip := 0; ip < len(bytecode.Instructions); ip++ { instruction := bytecode.Instructions[ip] switch instruction.Opcode { - case OpConstant: + case types.OpConstant: constIndex := instruction.Operand constant := vm.constants[constIndex] @@ -74,7 +46,7 @@ func (vm *VM) Run(bytecode *Bytecode) { vm.push(types.NewNumber(v)) } - case OpSetLocal: + case types.OpSetLocal: constIndex := instruction.Operand name := vm.constants[constIndex].(string) value := vm.pop() @@ -87,7 +59,7 @@ func (vm *VM) Run(bytecode *Bytecode) { vm.globals[name] = value } - case OpGetLocal: + case types.OpGetLocal: constIndex := instruction.Operand name := vm.constants[constIndex].(string) @@ -110,13 +82,13 @@ func (vm *VM) Run(bytecode *Bytecode) { } } - case OpSetGlobal: + case types.OpSetGlobal: constIndex := instruction.Operand name := vm.constants[constIndex].(string) value := vm.pop() vm.globals[name] = value - case OpGetGlobal: + case types.OpGetGlobal: constIndex := instruction.Operand name := vm.constants[constIndex].(string) if val, ok := vm.globals[name]; ok { @@ -125,22 +97,22 @@ func (vm *VM) Run(bytecode *Bytecode) { vm.push(types.NewNull()) } - case OpEnterScope: + case types.OpEnterScope: // Push a new scope vm.scopes = append(vm.scopes, Scope{ Variables: make(map[string]types.Value), }) - case OpExitScope: + case types.OpExitScope: // Pop the current scope if len(vm.scopes) > 0 { vm.scopes = vm.scopes[:len(vm.scopes)-1] } - case OpNewTable: + case types.OpNewTable: vm.push(types.NewTableValue()) - case OpSetIndex: + case types.OpSetIndex: value := vm.pop() key := vm.pop() tableVal := vm.pop() @@ -155,7 +127,7 @@ func (vm *VM) Run(bytecode *Bytecode) { table.Set(key, value) vm.push(tableVal) - case OpGetIndex: + case types.OpGetIndex: key := vm.pop() tableVal := vm.pop() @@ -169,15 +141,15 @@ func (vm *VM) Run(bytecode *Bytecode) { value := table.Get(key) vm.push(value) - case OpDup: + case types.OpDup: if vm.sp > 0 { vm.push(vm.stack[vm.sp-1]) } - case OpPop: + case types.OpPop: vm.pop() - case OpEcho: + case types.OpEcho: value := vm.pop() switch value.Type { case types.TypeString: