1
0
Fork 0
mirror of https://github.com/notwa/lips synced 2024-11-14 19: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 -- 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 last_statement = self.statements[#self.statements]
local s local s
if last_statement and last_statement.type == '!DATA' then if last_statement and last_statement.type == '!DATA' then
@ -44,16 +48,25 @@ function Collector:push_data(datum, size)
insert(self.statements, s) insert(self.statements, s)
end 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 if size ~= 'BYTE' and size ~= 'HALFWORD' and size ~= 'WORD' then
error('Internal Error: unknown data size argument') error('Internal Error: unknown data size argument')
end 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 sizes = size..'S'
local last_token = s[#s] local last_token = s[#s]
@ -65,7 +78,7 @@ function Collector:push_data(datum, size)
insert(s, t) insert(s, t)
s:validate() s:validate()
end end
insert(t.tok, datum) insert(t.tok, datum.tok)
end end
function Collector:variable() function Collector:variable()
@ -104,10 +117,10 @@ function Collector:directive()
end end
end end
elseif name == 'BYTE' or name == 'HALFWORD' or name == 'WORD' then 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 while not self:is_EOL() do
self:optional_comma() self:optional_comma()
self:push_data(self:const().tok, name) self:push_data(self:const(), name)
end end
elseif name == 'HEX' then elseif name == 'HEX' then
if self.tt ~= 'OPEN' then if self.tt ~= 'OPEN' then
@ -119,7 +132,7 @@ function Collector:directive()
if self.tt == 'EOL' then if self.tt == 'EOL' then
self:advance() self:advance()
else else
self:push_data(self:const().tok, 'BYTE') self:push_data(self:const(), 'BYTE')
end end
end end
self:advance() self:advance()

View file

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

View file

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