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:
parent
f851540b24
commit
693294bef2
3 changed files with 45 additions and 13 deletions
|
@ -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()
|
||||
|
|
|
@ -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))
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in a new issue