mirror of
https://github.com/safiire/n65.git
synced 2025-03-03 01:30:07 +00:00
I made it so starting a named scope serves the dual purpose of creating a symbolic reference to the current PC
This commit is contained in:
parent
4edbff55a5
commit
8f2500dd60
@ -25,9 +25,14 @@ module Assembler6502
|
||||
|
||||
|
||||
####
|
||||
## Execute on the assembler
|
||||
## Execute on the assembler, also create a symbol referring to
|
||||
## the current pc which contains a hyphen, and is impossible for
|
||||
## the user to create. This makes a scope simultaneously act as
|
||||
## a label to the current PC. If someone tries to use a scope
|
||||
## name as a label, it can return the address when the scope opened.
|
||||
def exec(assembler)
|
||||
assembler.symbol_table.enter_scope(@name)
|
||||
assembler.symbol_table.define_symbol("-#{@name}", assembler.program_counter)
|
||||
end
|
||||
|
||||
|
||||
|
@ -1,3 +1,4 @@
|
||||
|
||||
module Assembler6502
|
||||
|
||||
class SymbolTable
|
||||
@ -61,15 +62,22 @@ module Assembler6502
|
||||
## To go backwards in scope you need to write the full path
|
||||
## like global.sprite.x or whatever
|
||||
def resolve_symbol(name)
|
||||
|
||||
value = if name.include?('.')
|
||||
path_ary = name.split('.').map(&:to_sym)
|
||||
symbol = path_ary.pop
|
||||
path_ary.shift if path_ary.first == :global
|
||||
scope = retreive_scope(path_ary)
|
||||
scope[symbol]
|
||||
## We also try to look up the address associated with the scope
|
||||
root = "-#{symbol}".to_sym
|
||||
v = scope[symbol]
|
||||
v.kind_of?(Hash) ? v[root] : v
|
||||
else
|
||||
root = "-#{name}".to_sym
|
||||
scope = current_scope
|
||||
scope[name.to_sym]
|
||||
## We also try to look up the address associated with the scope
|
||||
v = scope[name.to_sym] || scope[root]
|
||||
v.kind_of?(Hash) ? v[root] : v
|
||||
end
|
||||
|
||||
if value.nil?
|
||||
|
@ -7,10 +7,9 @@
|
||||
.segment prog 0
|
||||
.org $8000
|
||||
|
||||
.scope yay
|
||||
main:
|
||||
sei
|
||||
cld
|
||||
.scope main
|
||||
sei
|
||||
cld
|
||||
loop:
|
||||
ldx $00
|
||||
inx
|
||||
@ -27,5 +26,5 @@ irq:
|
||||
.org $FFFA
|
||||
|
||||
.dw vblank
|
||||
.dw yay.main
|
||||
.dw main
|
||||
.dw irq
|
||||
|
@ -3,6 +3,7 @@ require 'minitest/autorun'
|
||||
require 'minitest/unit'
|
||||
|
||||
require_relative '../lib/symbol_table.rb'
|
||||
require_relative '../lib/assembler.rb'
|
||||
|
||||
|
||||
class TestSymbolTable < MiniTest::Test
|
||||
@ -10,7 +11,7 @@ class TestSymbolTable < MiniTest::Test
|
||||
|
||||
####
|
||||
## Test that we can make simple global symbols
|
||||
def _test_define_global_symbols
|
||||
def test_define_global_symbols
|
||||
st = SymbolTable.new
|
||||
st.define_symbol('dog', 'woof')
|
||||
assert_equal('woof', st.resolve_symbol('dog'))
|
||||
@ -19,7 +20,7 @@ class TestSymbolTable < MiniTest::Test
|
||||
|
||||
####
|
||||
## Test entering into a sub scope, and setting and retrieving values
|
||||
def _test_enter_scope
|
||||
def test_enter_scope
|
||||
st = SymbolTable.new
|
||||
st.enter_scope('animals')
|
||||
st.define_symbol('dog', 'woof')
|
||||
@ -29,7 +30,7 @@ class TestSymbolTable < MiniTest::Test
|
||||
|
||||
####
|
||||
## Test exiting a sub scope, and seeing that the variable is unavailable by simple name
|
||||
def _test_exit_scope
|
||||
def test_exit_scope
|
||||
st = SymbolTable.new
|
||||
st.enter_scope('animals')
|
||||
st.define_symbol('dog', 'woof')
|
||||
@ -124,5 +125,33 @@ class TestSymbolTable < MiniTest::Test
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
####
|
||||
## I would like the name of the scope to take on the
|
||||
## value of the program counter at that location.
|
||||
def test_scope_as_symbol
|
||||
program = <<-ASM
|
||||
.ines {"prog": 1, "char": 0, "mapper": 0, "mirror": 0}
|
||||
.org $8000
|
||||
.segment prog 0
|
||||
.scope main
|
||||
sei
|
||||
cld
|
||||
lda \#$00
|
||||
jmp main
|
||||
.
|
||||
jmp main
|
||||
jmp global.main
|
||||
ASM
|
||||
|
||||
#### There really should be an evaluate string method
|
||||
assembler = Assembler.new
|
||||
program.split(/\n/).each do |line|
|
||||
assembler.assemble_one_line(line)
|
||||
end
|
||||
assembler.fulfill_promises
|
||||
assert_equal(0x8000, assembler.symbol_table.resolve_symbol('global.main'))
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user