1
0
Fork 0
mirror of https://github.com/notwa/lips synced 2024-11-14 09:29:03 -08:00

fix labels and variables in data directives

This commit is contained in:
Connor Olding 2016-04-24 04:41:30 -07:00
parent f851540b24
commit 693294bef2
3 changed files with 45 additions and 13 deletions

View file

@ -35,6 +35,10 @@ function Collector:push_data(datum, size)
-- TODO: consider not scrunching data statements, just their tokens
if type(datum) == 'number' then
datum = self:token(datum)
end
local last_statement = self.statements[#self.statements]
local s
if last_statement and last_statement.type == '!DATA' then
@ -44,16 +48,25 @@ function Collector:push_data(datum, size)
insert(self.statements, s)
end
if type(datum) == 'string' and size == 'WORD' then
-- labels will be assembled to words
insert(s, Token('LABEL', datum))
return
end
if size ~= 'BYTE' and size ~= 'HALFWORD' and size ~= 'WORD' then
error('Internal Error: unknown data size argument')
end
if datum.tt == 'LABELSYM' then
if size == 'WORD' then
-- labels will be assembled to words
insert(s, datum)
return
else
self:error('labels are too large to be used in this directive')
end
elseif datum.tt == 'VARSYM' then
insert(s, datum:set('size', size))
return
elseif datum.tt ~= 'NUM' then
self:error('unsupported data type', datum.tt)
end
local sizes = size..'S'
local last_token = s[#s]
@ -65,7 +78,7 @@ function Collector:push_data(datum, size)
insert(s, t)
s:validate()
end
insert(t.tok, datum)
insert(t.tok, datum.tok)
end
function Collector:variable()
@ -104,10 +117,10 @@ function Collector:directive()
end
end
elseif name == 'BYTE' or name == 'HALFWORD' or name == 'WORD' then
self:push_data(self:const().tok, name)
self:push_data(self:const(), name)
while not self:is_EOL() do
self:optional_comma()
self:push_data(self:const().tok, name)
self:push_data(self:const(), name)
end
elseif name == 'HEX' then
if self.tt ~= 'OPEN' then
@ -119,7 +132,7 @@ function Collector:directive()
if self.tt == 'EOL' then
self:advance()
else
self:push_data(self:const().tok, 'BYTE')
self:push_data(self:const(), 'BYTE')
end
end
self:advance()

View file

@ -365,13 +365,17 @@ function Dumper:load(statements)
insert(new_statements, new)
elseif s.type == '!DATA' then
for i, t in ipairs(s) do
if t.tt == 'LABEL' then
if t.tt == 'LABELSYM' then
local label = self.labels[t.tok]
if label == nil then
self:error('undefined label', t.tok)
end
t.tt = 'WORDS'
t.tok = {label}
elseif t.tt == 'NUM' then
t.tt = t.size..'S'
t.tok = {t.tok}
t.size = nil
end
end
self.pos = self.pos + (s.length or util.measure_data(s))

View file

@ -39,12 +39,27 @@ else -- 5.2, 5.3
end
end
local data_sizes = {
BYTE = 1,
HALFWORD = 2,
WORD = 4,
}
local function measure_data(s)
assert(s and s.type == '!DATA', 'Internal Error: expected !DATA statement')
local n = 0
for i, t in ipairs(s) do
if t.tt == 'LABEL' then
if t.tt == 'LABELSYM' then
n = n + 4
elseif t.tt == 'NUM' then
if t.size == nil then
error('Internal Error: unspecified data size in NUM')
end
local size = data_sizes[t.size]
if size == nil then
error('Internal Error: unknown data size in NUM, got '..tostring(t.size))
end
n = n + size
elseif t.tt == 'WORDS' then
n = n + #t.tok * 4
elseif t.tt == 'HALFWORDS' then
@ -52,7 +67,7 @@ local function measure_data(s)
elseif t.tt == 'BYTES' then
n = n + #t.tok * 1
else
error('Internal Error: unknown data type in !DATA')
error('Internal Error: unknown data type in !DATA, got '..tostring(t.tt))
end
end
return n