mirror of
https://github.com/notwa/lips
synced 2024-11-14 09:29:03 -08:00
add .push/.pop directives for basic states
This commit is contained in:
parent
515a5f7635
commit
87c210d617
4 changed files with 58 additions and 0 deletions
|
@ -224,6 +224,10 @@ defaults to 0x80000000.
|
|||
this allows you to have a PC value different from origin:
|
||||
`PC = origin + base`
|
||||
|
||||
* `.push {vars...}` `.pop {vars...}'
|
||||
pushes or pops variables with an internal stack.
|
||||
supported variables: org, base, pc.
|
||||
|
||||
* `HEX { ... }`
|
||||
write a series of bytes given in hexadecimal.
|
||||
all numbers must be given in hex — no prefix is required.
|
||||
|
|
|
@ -85,6 +85,12 @@ function Collector:directive()
|
|||
end
|
||||
if name == 'ORG' or name == 'BASE' then
|
||||
add(name, self:const(nil, 'no labels'))
|
||||
elseif name == 'PUSH' or name == 'POP' then
|
||||
add(name, self:const())
|
||||
while not self:is_EOL() do
|
||||
self:optional_comma()
|
||||
add(name, self:const())
|
||||
end
|
||||
elseif name == 'ALIGN' or name == 'SKIP' then
|
||||
if self:is_EOL() and name == 'ALIGN' then
|
||||
add(name)
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
local floor = math.floor
|
||||
local format = string.format
|
||||
local insert = table.insert
|
||||
local remove = table.remove
|
||||
local unpack = unpack or table.unpack
|
||||
|
||||
local path = string.gsub(..., "[^.]+$", "")
|
||||
|
@ -276,6 +277,7 @@ function Dumper:pc()
|
|||
end
|
||||
|
||||
function Dumper:load(statements)
|
||||
local valstack = {} -- for .push/.pop directives
|
||||
local new_statements = {}
|
||||
self.pos = 0
|
||||
self.base = 0
|
||||
|
@ -296,6 +298,51 @@ function Dumper:load(statements)
|
|||
elseif s.type == '!BASE' then
|
||||
self.base = s[1].tok
|
||||
insert(new_statements, s)
|
||||
elseif s.type == '!PUSH' or s.type == '!POP' then
|
||||
local thistype = s.type:sub(2):lower()
|
||||
for i, t in ipairs(s) do
|
||||
local name = t.tok
|
||||
if type(name) ~= 'string' then
|
||||
self:error('expected state to '..thistype, name)
|
||||
end
|
||||
|
||||
name = name:lower()
|
||||
local pushing = s.type == '!PUSH'
|
||||
if name == 'org' then
|
||||
if pushing then
|
||||
insert(valstack, self.pos)
|
||||
else
|
||||
self.pos = remove(valstack)
|
||||
end
|
||||
elseif name == 'base' then
|
||||
if pushing then
|
||||
insert(valstack, self.base)
|
||||
else
|
||||
self.base = remove(valstack)
|
||||
end
|
||||
elseif name == 'pc' then
|
||||
if pushing then
|
||||
insert(valstack, self.pos)
|
||||
insert(valstack, self.base)
|
||||
else
|
||||
self.base = remove(valstack)
|
||||
self.pos = remove(valstack)
|
||||
end
|
||||
else
|
||||
self:error('unknown state to '..thistype, name)
|
||||
end
|
||||
|
||||
if self.pos == nil or self.base == nil then
|
||||
self:error('ran out of values to pop')
|
||||
end
|
||||
|
||||
if not pushing then
|
||||
local s = Statement(self.fn, self.line, '!ORG', self.pos)
|
||||
insert(new_statements, s)
|
||||
local s = Statement(self.fn, self.line, '!BASE', self.base)
|
||||
insert(new_statements, s)
|
||||
end
|
||||
end
|
||||
elseif s.type == '!ALIGN' or s.type == '!SKIP' then
|
||||
local length, content
|
||||
if s.type == '!ALIGN' then
|
||||
|
|
|
@ -30,6 +30,7 @@ data.fpu_registers = {
|
|||
|
||||
data.all_directives = {
|
||||
'ORG', 'BASE', 'ALIGN', 'SKIP',
|
||||
'PUSH', 'POP', -- experimental
|
||||
'ASCII', 'ASCIIZ',
|
||||
'BYTE', 'HALFWORD', 'WORD',
|
||||
--'HEX', -- excluded here due to different syntax
|
||||
|
|
Loading…
Reference in a new issue