Added label and origin commands.
This commit is contained in:
parent
aedc605445
commit
5b3e5737b8
3 changed files with 112 additions and 1 deletions
48
internal/commands/label.go
Normal file
48
internal/commands/label.go
Normal file
|
|
@ -0,0 +1,48 @@
|
|||
package commands
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"c65gm/internal/compiler"
|
||||
"c65gm/internal/preproc"
|
||||
"c65gm/internal/utils"
|
||||
)
|
||||
|
||||
// LabelCommand handles LABEL declarations
|
||||
// Syntax: LABEL name
|
||||
// Emits an assembly label for GOTO/GOSUB/CALL to target
|
||||
type LabelCommand struct {
|
||||
labelName string
|
||||
}
|
||||
|
||||
func (c *LabelCommand) WillHandle(line preproc.Line) bool {
|
||||
params, err := utils.ParseParams(line.Text)
|
||||
if err != nil || len(params) == 0 {
|
||||
return false
|
||||
}
|
||||
return strings.ToUpper(params[0]) == "LABEL"
|
||||
}
|
||||
|
||||
func (c *LabelCommand) Interpret(line preproc.Line, _ *compiler.CompilerContext) error {
|
||||
params, err := utils.ParseParams(line.Text)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if len(params) != 2 {
|
||||
return fmt.Errorf("LABEL: expected 2 parameters, got %d", len(params))
|
||||
}
|
||||
|
||||
c.labelName = params[1]
|
||||
|
||||
if len(c.labelName) < 2 {
|
||||
return fmt.Errorf("LABEL: label name must be at least 2 characters long")
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *LabelCommand) Generate(_ *compiler.CompilerContext) ([]string, error) {
|
||||
return []string{c.labelName}, nil
|
||||
}
|
||||
62
internal/commands/origin.go
Normal file
62
internal/commands/origin.go
Normal file
|
|
@ -0,0 +1,62 @@
|
|||
package commands
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"c65gm/internal/compiler"
|
||||
"c65gm/internal/preproc"
|
||||
"c65gm/internal/utils"
|
||||
)
|
||||
|
||||
// OriginCommand handles ORIGIN declarations
|
||||
// Syntax: ORIGIN <address>
|
||||
// Sets the assembly origin address (ACME: *= address)
|
||||
type OriginCommand struct {
|
||||
address uint16
|
||||
}
|
||||
|
||||
func (c *OriginCommand) WillHandle(line preproc.Line) bool {
|
||||
params, err := utils.ParseParams(line.Text)
|
||||
if err != nil || len(params) == 0 {
|
||||
return false
|
||||
}
|
||||
upper := strings.ToUpper(params[0])
|
||||
return upper == "ORIGIN" || upper == "ORGIN" // Support common typo
|
||||
}
|
||||
|
||||
func (c *OriginCommand) Interpret(line preproc.Line, ctx *compiler.CompilerContext) error {
|
||||
params, err := utils.ParseParams(line.Text)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if len(params) != 2 {
|
||||
return fmt.Errorf("ORIGIN: expected 2 parameters, got %d", len(params))
|
||||
}
|
||||
|
||||
scope := ctx.CurrentScope()
|
||||
constLookup := func(name string) (int64, bool) {
|
||||
sym := ctx.SymbolTable.Lookup(name, scope)
|
||||
if sym != nil && sym.IsConst() {
|
||||
return int64(sym.Value), true
|
||||
}
|
||||
return 0, false
|
||||
}
|
||||
|
||||
val, err := utils.EvaluateExpression(params[1], constLookup)
|
||||
if err != nil {
|
||||
return fmt.Errorf("ORIGIN: invalid address expression: %w", err)
|
||||
}
|
||||
|
||||
if val < 0 || val > 65535 {
|
||||
return fmt.Errorf("ORIGIN: address %d out of range (0-65535)", val)
|
||||
}
|
||||
|
||||
c.address = uint16(val)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *OriginCommand) Generate(_ *compiler.CompilerContext) ([]string, error) {
|
||||
return []string{fmt.Sprintf("*= $%04x", c.address)}, nil
|
||||
}
|
||||
3
main.go
3
main.go
|
|
@ -96,7 +96,8 @@ func registerCommands(comp *compiler.Compiler) {
|
|||
comp.Registry().Register(&commands.IncrCommand{})
|
||||
comp.Registry().Register(&commands.DecrCommand{})
|
||||
comp.Registry().Register(&commands.GotoCommand{})
|
||||
|
||||
comp.Registry().Register(&commands.LabelCommand{})
|
||||
comp.Registry().Register(&commands.OriginCommand{})
|
||||
}
|
||||
|
||||
func writeOutput(filename string, lines []string) error {
|
||||
|
|
|
|||
Loading…
Reference in a new issue