Added WORD command
This commit is contained in:
parent
ff64cc6b93
commit
8c0056365e
3 changed files with 647 additions and 1 deletions
184
internal/commands/word.go
Normal file
184
internal/commands/word.go
Normal file
|
|
@ -0,0 +1,184 @@
|
|||
package commands
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"c65gm/internal/compiler"
|
||||
"c65gm/internal/preproc"
|
||||
"c65gm/internal/utils"
|
||||
)
|
||||
|
||||
// WordCommand handles WORD variable declarations
|
||||
// Syntax:
|
||||
//
|
||||
// WORD varname # word with init = 0
|
||||
// WORD varname = value # word with init value
|
||||
// WORD varname = "string" # word pointer to constant string
|
||||
// WORD varname @ address # word at absolute address
|
||||
// WORD CONST varname = value # constant word
|
||||
type WordCommand struct {
|
||||
varName string
|
||||
value uint16
|
||||
isConst bool
|
||||
isAbs bool
|
||||
}
|
||||
|
||||
func (c *WordCommand) WillHandle(line preproc.Line) bool {
|
||||
params, err := utils.ParseParams(line.Text)
|
||||
if err != nil || len(params) == 0 {
|
||||
return false
|
||||
}
|
||||
return strings.ToUpper(params[0]) == "WORD"
|
||||
}
|
||||
|
||||
func (c *WordCommand) Interpret(line preproc.Line, ctx *compiler.CompilerContext) error {
|
||||
// Clear state
|
||||
c.varName = ""
|
||||
c.value = 0
|
||||
c.isConst = false
|
||||
c.isAbs = false
|
||||
|
||||
params, err := utils.ParseParams(line.Text)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
paramCount := len(params)
|
||||
|
||||
// Validate parameter count
|
||||
if paramCount != 2 && paramCount != 4 && paramCount != 5 {
|
||||
return fmt.Errorf("WORD: wrong number of parameters (%d)", paramCount)
|
||||
}
|
||||
|
||||
var varName string
|
||||
var value int64
|
||||
scope := ctx.FunctionHandler.CurrentFunction()
|
||||
|
||||
// Create constant lookup function
|
||||
constLookup := func(name string) (int64, bool) {
|
||||
sym := ctx.SymbolTable.Lookup(name, ctx.CurrentScope())
|
||||
if sym != nil && sym.IsConst() {
|
||||
return int64(sym.Value), true
|
||||
}
|
||||
return 0, false
|
||||
}
|
||||
|
||||
switch paramCount {
|
||||
case 2:
|
||||
// WORD varname
|
||||
varName = params[1]
|
||||
value = 0
|
||||
|
||||
if !utils.ValidateIdentifier(varName) {
|
||||
return fmt.Errorf("WORD: invalid identifier %q", varName)
|
||||
}
|
||||
|
||||
err = ctx.SymbolTable.AddVar(varName, scope, compiler.KindWord, uint16(value))
|
||||
|
||||
case 4:
|
||||
// WORD varname = value OR WORD varname @ address OR WORD varname = "string"
|
||||
varName = params[1]
|
||||
operator := params[2]
|
||||
valueStr := params[3]
|
||||
|
||||
if !utils.ValidateIdentifier(varName) {
|
||||
return fmt.Errorf("WORD: invalid identifier %q", varName)
|
||||
}
|
||||
|
||||
// Check for string literal
|
||||
if utils.IsStringLiteral(valueStr) {
|
||||
if operator != "=" {
|
||||
return fmt.Errorf("WORD: expected '=' when assigning string pointer, got %q", operator)
|
||||
}
|
||||
|
||||
// Generate label for the string
|
||||
label := ctx.GeneralStack.Push()
|
||||
|
||||
// Get pragma set for this line
|
||||
pragmaSet := ctx.Pragma.GetPragmaSetByIndex(line.PragmaSetIndex)
|
||||
|
||||
// Add string to constant string handler
|
||||
ctx.ConstStrHandler.AddConstStr(label, valueStr, false, pragmaSet)
|
||||
|
||||
err = ctx.SymbolTable.AddLabel(varName, scope, label)
|
||||
if err != nil {
|
||||
return fmt.Errorf("WORD: %w", err)
|
||||
}
|
||||
|
||||
c.varName = varName
|
||||
c.value = 0 // label refs don't have numeric values
|
||||
return nil
|
||||
}
|
||||
|
||||
// Not a string, evaluate as expression
|
||||
value, err = utils.EvaluateExpression(valueStr, constLookup)
|
||||
if err != nil {
|
||||
return fmt.Errorf("WORD: invalid value %q: %w", valueStr, err)
|
||||
}
|
||||
|
||||
if operator == "=" {
|
||||
// WORD varname = value
|
||||
if value < 0 || value > 65535 {
|
||||
return fmt.Errorf("WORD: init value %d out of range (0-65535)", value)
|
||||
}
|
||||
err = ctx.SymbolTable.AddVar(varName, scope, compiler.KindWord, uint16(value))
|
||||
|
||||
} else if operator == "@" {
|
||||
// WORD varname @ address
|
||||
if value < 0 || value > 0xFFFF {
|
||||
return fmt.Errorf("WORD: absolute address $%X out of range", value)
|
||||
}
|
||||
c.isAbs = true
|
||||
err = ctx.SymbolTable.AddAbsolute(varName, scope, compiler.KindWord, uint16(value))
|
||||
|
||||
} else {
|
||||
return fmt.Errorf("WORD: expected '=' or '@', got %q", operator)
|
||||
}
|
||||
|
||||
case 5:
|
||||
// WORD CONST varname = value
|
||||
constKeyword := strings.ToUpper(params[1])
|
||||
varName = params[2]
|
||||
operator := params[3]
|
||||
valueStr := params[4]
|
||||
|
||||
if constKeyword != "CONST" {
|
||||
return fmt.Errorf("WORD: expected CONST keyword, got %q", params[1])
|
||||
}
|
||||
|
||||
if operator != "=" {
|
||||
return fmt.Errorf("WORD: expected '=', got %q", operator)
|
||||
}
|
||||
|
||||
if !utils.ValidateIdentifier(varName) {
|
||||
return fmt.Errorf("WORD: invalid identifier %q", varName)
|
||||
}
|
||||
|
||||
value, err = utils.EvaluateExpression(valueStr, constLookup)
|
||||
if err != nil {
|
||||
return fmt.Errorf("WORD: invalid value %q: %w", valueStr, err)
|
||||
}
|
||||
|
||||
if value < 0 || value > 65535 {
|
||||
return fmt.Errorf("WORD: const value %d out of range (0-65535)", value)
|
||||
}
|
||||
|
||||
c.isConst = true
|
||||
err = ctx.SymbolTable.AddConst(varName, scope, compiler.KindWord, uint16(value))
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
return fmt.Errorf("WORD: %w", err)
|
||||
}
|
||||
|
||||
c.varName = varName
|
||||
c.value = uint16(value)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *WordCommand) Generate(_ *compiler.CompilerContext) ([]string, error) {
|
||||
// Variables are rendered by assembleOutput, not by individual commands
|
||||
return nil, nil
|
||||
}
|
||||
462
internal/commands/word_test.go
Normal file
462
internal/commands/word_test.go
Normal file
|
|
@ -0,0 +1,462 @@
|
|||
package commands
|
||||
|
||||
import (
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"c65gm/internal/compiler"
|
||||
"c65gm/internal/preproc"
|
||||
)
|
||||
|
||||
func TestWordCommand_WillHandle(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
text string
|
||||
want bool
|
||||
}{
|
||||
{
|
||||
name: "handles WORD",
|
||||
text: "WORD x",
|
||||
want: true,
|
||||
},
|
||||
{
|
||||
name: "handles word lowercase",
|
||||
text: "word x",
|
||||
want: true,
|
||||
},
|
||||
{
|
||||
name: "handles WORD with init",
|
||||
text: "WORD x = 1000",
|
||||
want: true,
|
||||
},
|
||||
{
|
||||
name: "handles WORD with string",
|
||||
text: `WORD ptr = "hello"`,
|
||||
want: true,
|
||||
},
|
||||
{
|
||||
name: "handles WORD at absolute",
|
||||
text: "WORD x @ $C000",
|
||||
want: true,
|
||||
},
|
||||
{
|
||||
name: "handles WORD CONST",
|
||||
text: "WORD CONST x = 1000",
|
||||
want: true,
|
||||
},
|
||||
{
|
||||
name: "does not handle BYTE",
|
||||
text: "BYTE x",
|
||||
want: false,
|
||||
},
|
||||
{
|
||||
name: "does not handle empty",
|
||||
text: "",
|
||||
want: false,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
cmd := &WordCommand{}
|
||||
line := preproc.Line{Text: tt.text}
|
||||
got := cmd.WillHandle(line)
|
||||
if got != tt.want {
|
||||
t.Errorf("WillHandle() = %v, want %v", got, tt.want)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestWordCommand_Interpret(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
text string
|
||||
wantErr bool
|
||||
errContains string
|
||||
checkVar func(*testing.T, *compiler.CompilerContext)
|
||||
}{
|
||||
{
|
||||
name: "simple word",
|
||||
text: "WORD x",
|
||||
wantErr: false,
|
||||
checkVar: func(t *testing.T, ctx *compiler.CompilerContext) {
|
||||
sym := ctx.SymbolTable.Lookup("x", nil)
|
||||
if sym == nil {
|
||||
t.Fatal("Expected variable x to be declared")
|
||||
}
|
||||
if !sym.IsWord() {
|
||||
t.Error("Expected word variable")
|
||||
}
|
||||
if sym.IsConst() {
|
||||
t.Error("Expected regular variable, not const")
|
||||
}
|
||||
if sym.Value != 0 {
|
||||
t.Errorf("Expected init value 0, got %d", sym.Value)
|
||||
}
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "word with decimal init",
|
||||
text: "WORD counter = 1000",
|
||||
wantErr: false,
|
||||
checkVar: func(t *testing.T, ctx *compiler.CompilerContext) {
|
||||
sym := ctx.SymbolTable.Lookup("counter", nil)
|
||||
if sym == nil {
|
||||
t.Fatal("Expected variable counter to be declared")
|
||||
}
|
||||
if sym.Value != 1000 {
|
||||
t.Errorf("Expected init value 1000, got %d", sym.Value)
|
||||
}
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "word with hex init",
|
||||
text: "WORD status = $FFFF",
|
||||
wantErr: false,
|
||||
checkVar: func(t *testing.T, ctx *compiler.CompilerContext) {
|
||||
sym := ctx.SymbolTable.Lookup("status", nil)
|
||||
if sym == nil {
|
||||
t.Fatal("Expected variable status to be declared")
|
||||
}
|
||||
if sym.Value != 65535 {
|
||||
t.Errorf("Expected init value 65535, got %d", sym.Value)
|
||||
}
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "word with string pointer",
|
||||
text: `WORD msg = "hello world"`,
|
||||
wantErr: false,
|
||||
checkVar: func(t *testing.T, ctx *compiler.CompilerContext) {
|
||||
sym := ctx.SymbolTable.Lookup("msg", nil)
|
||||
if sym == nil {
|
||||
t.Fatal("Expected variable msg to be declared")
|
||||
}
|
||||
if !sym.Has(compiler.FlagLabelRef) {
|
||||
t.Error("Expected label reference")
|
||||
}
|
||||
if sym.LabelRef == "" {
|
||||
t.Error("Expected non-empty label reference")
|
||||
}
|
||||
// Check that string was added to handler
|
||||
strs := ctx.ConstStrHandler.GenerateConstStrDecls()
|
||||
if len(strs) == 0 {
|
||||
t.Error("Expected string to be added to ConstStrHandler")
|
||||
}
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "word at absolute address",
|
||||
text: "WORD ptr @ $C000",
|
||||
wantErr: false,
|
||||
checkVar: func(t *testing.T, ctx *compiler.CompilerContext) {
|
||||
sym := ctx.SymbolTable.Lookup("ptr", nil)
|
||||
if sym == nil {
|
||||
t.Fatal("Expected variable ptr to be declared")
|
||||
}
|
||||
if !sym.IsAbsolute() {
|
||||
t.Error("Expected absolute variable")
|
||||
}
|
||||
if sym.AbsAddr != 0xC000 {
|
||||
t.Errorf("Expected address $C000, got $%04X", sym.AbsAddr)
|
||||
}
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "word at zero page",
|
||||
text: "WORD zpvar @ $80",
|
||||
wantErr: false,
|
||||
checkVar: func(t *testing.T, ctx *compiler.CompilerContext) {
|
||||
sym := ctx.SymbolTable.Lookup("zpvar", nil)
|
||||
if sym == nil {
|
||||
t.Fatal("Expected variable zpvar to be declared")
|
||||
}
|
||||
if !sym.IsZeroPage() {
|
||||
t.Error("Expected zero page variable")
|
||||
}
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "const word",
|
||||
text: "WORD CONST maxval = 65535",
|
||||
wantErr: false,
|
||||
checkVar: func(t *testing.T, ctx *compiler.CompilerContext) {
|
||||
sym := ctx.SymbolTable.Lookup("maxval", nil)
|
||||
if sym == nil {
|
||||
t.Fatal("Expected constant maxval to be declared")
|
||||
}
|
||||
if !sym.IsConst() {
|
||||
t.Error("Expected constant")
|
||||
}
|
||||
if sym.Value != 65535 {
|
||||
t.Errorf("Expected value 65535, got %d", sym.Value)
|
||||
}
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "const word with hex",
|
||||
text: "WORD CONST flag = $FFFF",
|
||||
wantErr: false,
|
||||
checkVar: func(t *testing.T, ctx *compiler.CompilerContext) {
|
||||
sym := ctx.SymbolTable.Lookup("flag", nil)
|
||||
if sym == nil {
|
||||
t.Fatal("Expected constant flag to be declared")
|
||||
}
|
||||
if !sym.IsConst() {
|
||||
t.Error("Expected constant")
|
||||
}
|
||||
if sym.Value != 65535 {
|
||||
t.Errorf("Expected value 65535, got %d", sym.Value)
|
||||
}
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "word with expression",
|
||||
text: "WORD x = 100+200",
|
||||
wantErr: false,
|
||||
checkVar: func(t *testing.T, ctx *compiler.CompilerContext) {
|
||||
sym := ctx.SymbolTable.Lookup("x", nil)
|
||||
if sym == nil {
|
||||
t.Fatal("Expected variable x to be declared")
|
||||
}
|
||||
if sym.Value != 300 {
|
||||
t.Errorf("Expected value 300, got %d", sym.Value)
|
||||
}
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "word with binary",
|
||||
text: "WORD x = !1111111111111111",
|
||||
wantErr: false,
|
||||
checkVar: func(t *testing.T, ctx *compiler.CompilerContext) {
|
||||
sym := ctx.SymbolTable.Lookup("x", nil)
|
||||
if sym == nil {
|
||||
t.Fatal("Expected variable x to be declared")
|
||||
}
|
||||
if sym.Value != 65535 {
|
||||
t.Errorf("Expected value 65535, got %d", sym.Value)
|
||||
}
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "word with bitwise OR",
|
||||
text: "WORD x = $FF00|$00FF",
|
||||
wantErr: false,
|
||||
checkVar: func(t *testing.T, ctx *compiler.CompilerContext) {
|
||||
sym := ctx.SymbolTable.Lookup("x", nil)
|
||||
if sym == nil {
|
||||
t.Fatal("Expected variable x to be declared")
|
||||
}
|
||||
if sym.Value != 65535 {
|
||||
t.Errorf("Expected value 65535, got %d", sym.Value)
|
||||
}
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "word with bitwise AND",
|
||||
text: "WORD x = $FFFF&$00FF",
|
||||
wantErr: false,
|
||||
checkVar: func(t *testing.T, ctx *compiler.CompilerContext) {
|
||||
sym := ctx.SymbolTable.Lookup("x", nil)
|
||||
if sym == nil {
|
||||
t.Fatal("Expected variable x to be declared")
|
||||
}
|
||||
if sym.Value != 255 {
|
||||
t.Errorf("Expected value 255, got %d", sym.Value)
|
||||
}
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "word with out of range value",
|
||||
text: "WORD x = 65536",
|
||||
wantErr: true,
|
||||
errContains: "out of range",
|
||||
},
|
||||
{
|
||||
name: "const word out of range",
|
||||
text: "WORD CONST x = 65536",
|
||||
wantErr: true,
|
||||
errContains: "out of range",
|
||||
},
|
||||
{
|
||||
name: "word without name",
|
||||
text: "WORD",
|
||||
wantErr: true,
|
||||
errContains: "wrong number of parameters",
|
||||
},
|
||||
{
|
||||
name: "word with invalid identifier",
|
||||
text: "WORD 123invalid",
|
||||
wantErr: true,
|
||||
errContains: "invalid identifier",
|
||||
},
|
||||
{
|
||||
name: "word with wrong operator",
|
||||
text: "WORD x + 10",
|
||||
wantErr: true,
|
||||
errContains: "expected '=' or '@'",
|
||||
},
|
||||
{
|
||||
name: "word string with wrong operator",
|
||||
text: `WORD x @ "hello"`,
|
||||
wantErr: true,
|
||||
errContains: "expected '=' when assigning string pointer",
|
||||
},
|
||||
{
|
||||
name: "const without equals",
|
||||
text: "WORD CONST x 10",
|
||||
wantErr: true,
|
||||
errContains: "expected '='",
|
||||
},
|
||||
{
|
||||
name: "wrong keyword instead of CONST",
|
||||
text: "WORD VAR x = 10",
|
||||
wantErr: true,
|
||||
errContains: "expected CONST keyword",
|
||||
},
|
||||
{
|
||||
name: "duplicate declaration",
|
||||
text: "WORD x",
|
||||
wantErr: true,
|
||||
errContains: "already declared",
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
pragma := preproc.NewPragma()
|
||||
ctx := compiler.NewCompilerContext(pragma)
|
||||
|
||||
// For duplicate test, pre-declare the variable
|
||||
if tt.name == "duplicate declaration" {
|
||||
ctx.SymbolTable.AddVar("x", "", compiler.KindWord, 0)
|
||||
}
|
||||
|
||||
cmd := &WordCommand{}
|
||||
line := preproc.Line{
|
||||
Text: tt.text,
|
||||
Filename: "test.c65",
|
||||
LineNo: 1,
|
||||
Kind: preproc.Source,
|
||||
PragmaSetIndex: pragma.GetCurrentPragmaSetIndex(),
|
||||
}
|
||||
|
||||
err := cmd.Interpret(line, ctx)
|
||||
|
||||
if tt.wantErr {
|
||||
if err == nil {
|
||||
t.Fatal("Expected error, got nil")
|
||||
}
|
||||
if tt.errContains != "" && !strings.Contains(err.Error(), tt.errContains) {
|
||||
t.Errorf("Error %q does not contain %q", err.Error(), tt.errContains)
|
||||
}
|
||||
} else {
|
||||
if err != nil {
|
||||
t.Fatalf("Unexpected error: %v", err)
|
||||
}
|
||||
if tt.checkVar != nil {
|
||||
tt.checkVar(t, ctx)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestWordCommand_Generate(t *testing.T) {
|
||||
pragma := preproc.NewPragma()
|
||||
ctx := compiler.NewCompilerContext(pragma)
|
||||
|
||||
cmd := &WordCommand{}
|
||||
line := preproc.Line{
|
||||
Text: "WORD x = 1000",
|
||||
Filename: "test.c65",
|
||||
LineNo: 1,
|
||||
Kind: preproc.Source,
|
||||
PragmaSetIndex: 0,
|
||||
}
|
||||
|
||||
// Interpret first
|
||||
if err := cmd.Interpret(line, ctx); err != nil {
|
||||
t.Fatalf("Interpret failed: %v", err)
|
||||
}
|
||||
|
||||
// Generate should return nil (variables handled by assembleOutput)
|
||||
output, err := cmd.Generate(ctx)
|
||||
if err != nil {
|
||||
t.Errorf("Generate returned error: %v", err)
|
||||
}
|
||||
if output != nil {
|
||||
t.Errorf("Generate should return nil, got %v", output)
|
||||
}
|
||||
}
|
||||
|
||||
func TestWordCommand_WithConstantExpression(t *testing.T) {
|
||||
pragma := preproc.NewPragma()
|
||||
ctx := compiler.NewCompilerContext(pragma)
|
||||
|
||||
// First, declare a constant
|
||||
ctx.SymbolTable.AddConst("MAXVAL", "", compiler.KindWord, 1000)
|
||||
ctx.SymbolTable.AddConst("OFFSET", "", compiler.KindWord, 500)
|
||||
|
||||
// Now declare a word using the constant in an expression
|
||||
cmd := &WordCommand{}
|
||||
line := preproc.Line{
|
||||
Text: "WORD x = MAXVAL+OFFSET",
|
||||
Filename: "test.c65",
|
||||
LineNo: 1,
|
||||
Kind: preproc.Source,
|
||||
PragmaSetIndex: 0,
|
||||
}
|
||||
|
||||
if err := cmd.Interpret(line, ctx); err != nil {
|
||||
t.Fatalf("Interpret failed: %v", err)
|
||||
}
|
||||
|
||||
// Check value
|
||||
sym := ctx.SymbolTable.Lookup("x", nil)
|
||||
if sym == nil {
|
||||
t.Fatal("Expected variable x to be declared")
|
||||
}
|
||||
if sym.Value != 1500 {
|
||||
t.Errorf("Expected value 1500 (1000+500), got %d", sym.Value)
|
||||
}
|
||||
}
|
||||
|
||||
func TestWordCommand_MultipleStrings(t *testing.T) {
|
||||
pragma := preproc.NewPragma()
|
||||
ctx := compiler.NewCompilerContext(pragma)
|
||||
|
||||
// Create multiple string pointers
|
||||
stringsd := []string{
|
||||
`WORD msg1 = "hello"`,
|
||||
`WORD msg2 = "world"`,
|
||||
`WORD msg3 = "test"`,
|
||||
}
|
||||
|
||||
for i, text := range stringsd {
|
||||
cmd := &WordCommand{}
|
||||
line := preproc.Line{
|
||||
Text: text,
|
||||
Filename: "test.c65",
|
||||
LineNo: i + 1,
|
||||
Kind: preproc.Source,
|
||||
PragmaSetIndex: 0,
|
||||
}
|
||||
|
||||
if err := cmd.Interpret(line, ctx); err != nil {
|
||||
t.Fatalf("Failed to interpret line %d: %v", i+1, err)
|
||||
}
|
||||
}
|
||||
|
||||
// Check all were added
|
||||
if ctx.SymbolTable.Count() != 3 {
|
||||
t.Errorf("Expected 3 variables, got %d", ctx.SymbolTable.Count())
|
||||
}
|
||||
|
||||
// Check string declarations were generated
|
||||
strDecls := ctx.ConstStrHandler.GenerateConstStrDecls()
|
||||
if len(strDecls) < 9 { // Each string needs at least 3 lines (label, data, terminator)
|
||||
t.Errorf("Expected at least 9 lines of string declarations, got %d", len(strDecls))
|
||||
}
|
||||
}
|
||||
2
main.go
2
main.go
|
|
@ -77,9 +77,9 @@ func registerCommands(comp *compiler.Compiler) {
|
|||
// This is the single place where all commands are wired up
|
||||
|
||||
comp.Registry().Register(&commands.ByteCommand{})
|
||||
comp.Registry().Register(&commands.WordCommand{})
|
||||
|
||||
// TODO: Add more commands as they're implemented:
|
||||
// comp.Registry().Register(&commands.WordCommand{})
|
||||
// comp.Registry().Register(&commands.LetCommand{})
|
||||
// comp.Registry().Register(&commands.IfCommand{})
|
||||
// comp.Registry().Register(&commands.WhileCommand{})
|
||||
|
|
|
|||
Loading…
Reference in a new issue