1
0
mirror of https://github.com/zellyn/go6502.git synced 2025-01-15 06:30:28 +00:00
go6502/asm/context/context.go

188 lines
3.9 KiB
Go
Raw Normal View History

2014-03-04 17:42:51 -08:00
package context
import "fmt"
type Context interface {
Set(name string, value uint16)
Get(name string) (uint16, bool)
SetAddr(uint16)
GetAddr() (uint16, bool)
2014-08-19 08:22:34 -07:00
DivZero() (uint16, error)
2014-03-04 17:42:51 -08:00
RemoveChanged()
Clear()
2014-06-03 08:46:49 -07:00
SettingOn(name string) error
SettingOff(name string) error
Setting(name string) bool
HasSetting(name string) bool
2014-06-16 08:24:42 -07:00
AddMacroName(name string)
HasMacroName(name string) bool
2014-08-19 08:22:34 -07:00
PushMacroCall(name string, number int, locals map[string]bool)
PopMacroCall() bool
GetMacroCall() (string, int, map[string]bool)
LastLabel() string
SetLastLabel(label string)
}
type macroCall struct {
name string
number int
locals map[string]bool
2014-03-04 17:42:51 -08:00
}
type SimpleContext struct {
2014-06-16 08:24:42 -07:00
symbols map[string]symbolValue
addr int32
lastLabel string
2014-08-19 08:22:34 -07:00
highbit byte // OR-mask for ASCII high bit
2014-06-16 08:24:42 -07:00
onOff map[string]bool
onOffDefaults map[string]bool
macroNames map[string]bool
2014-08-19 08:22:34 -07:00
macroCalls []macroCall
2014-03-04 17:42:51 -08:00
}
type symbolValue struct {
v uint16
changed bool // Did the value ever change?
}
func (sc *SimpleContext) fix() {
if sc.symbols == nil {
sc.symbols = make(map[string]symbolValue)
}
}
2014-08-19 08:22:34 -07:00
func (sc *SimpleContext) DivZero() (uint16, error) {
return 0, fmt.Errorf("Not implemented: context.SimpleContext.DivZero()")
2014-03-04 17:42:51 -08:00
}
func (sc *SimpleContext) Get(name string) (uint16, bool) {
if name == "*" {
return sc.GetAddr()
}
sc.fix()
s, found := sc.symbols[name]
return s.v, found
}
func (sc *SimpleContext) SetAddr(addr uint16) {
sc.addr = int32(addr)
}
func (sc *SimpleContext) GetAddr() (uint16, bool) {
if sc.addr == -1 {
return 0, false
}
return uint16(sc.addr), true
}
func (sc *SimpleContext) Set(name string, value uint16) {
sc.fix()
s, found := sc.symbols[name]
if found && s.v != value {
s.changed = true
}
s.v = value
sc.symbols[name] = s
}
func (sc *SimpleContext) RemoveChanged() {
sc.fix()
for n, s := range sc.symbols {
if s.changed {
delete(sc.symbols, n)
}
}
}
func (sc *SimpleContext) Clear() {
sc.symbols = make(map[string]symbolValue)
2014-05-31 12:55:36 -07:00
sc.highbit = 0x00
2014-06-16 08:24:42 -07:00
sc.macroNames = nil
sc.resetOnOff()
2014-03-04 17:42:51 -08:00
}
2014-06-03 08:46:49 -07:00
func (sc *SimpleContext) SettingOn(name string) error {
if !sc.HasSetting(name) {
return fmt.Errorf("no settable variable named '%s'", name)
}
2014-06-16 08:24:42 -07:00
if sc.onOff == nil {
sc.onOff = map[string]bool{name: true}
2014-06-03 08:46:49 -07:00
} else {
2014-06-16 08:24:42 -07:00
sc.onOff[name] = true
2014-06-03 08:46:49 -07:00
}
return nil
}
func (sc *SimpleContext) SettingOff(name string) error {
if !sc.HasSetting(name) {
return fmt.Errorf("no settable variable named '%s'", name)
}
2014-06-16 08:24:42 -07:00
if sc.onOff == nil {
sc.onOff = map[string]bool{name: false}
2014-06-03 08:46:49 -07:00
} else {
2014-06-16 08:24:42 -07:00
sc.onOff[name] = false
2014-06-03 08:46:49 -07:00
}
return nil
}
func (sc *SimpleContext) Setting(name string) bool {
2014-06-16 08:24:42 -07:00
return sc.onOff[name]
2014-06-03 08:46:49 -07:00
}
func (sc *SimpleContext) HasSetting(name string) bool {
2014-06-16 08:24:42 -07:00
_, ok := sc.onOff[name]
2014-06-03 08:46:49 -07:00
return ok
}
2014-06-16 08:24:42 -07:00
func (sc *SimpleContext) AddMacroName(name string) {
if sc.macroNames == nil {
sc.macroNames = make(map[string]bool)
}
sc.macroNames[name] = true
}
func (sc *SimpleContext) HasMacroName(name string) bool {
return sc.macroNames[name]
}
func (sc *SimpleContext) resetOnOff() {
sc.onOff = make(map[string]bool)
for k, v := range sc.onOffDefaults {
sc.onOff[k] = v
}
}
func (sc *SimpleContext) SetOnOffDefaults(defaults map[string]bool) {
sc.onOffDefaults = defaults
sc.resetOnOff()
}
2014-08-19 08:22:34 -07:00
func (sc *SimpleContext) PushMacroCall(name string, number int, locals map[string]bool) {
sc.macroCalls = append(sc.macroCalls, macroCall{name, number, locals})
}
func (sc *SimpleContext) PopMacroCall() bool {
if len(sc.macroCalls) == 0 {
return false
}
sc.macroCalls = sc.macroCalls[0 : len(sc.macroCalls)-1]
return true
}
func (sc *SimpleContext) GetMacroCall() (string, int, map[string]bool) {
if len(sc.macroCalls) == 0 {
return "", 0, nil
}
mc := sc.macroCalls[len(sc.macroCalls)-1]
return mc.name, mc.number, mc.locals
}
func (sc *SimpleContext) LastLabel() string {
return sc.lastLabel
}
func (sc *SimpleContext) SetLastLabel(l string) {
sc.lastLabel = l
}