1
0
Fork 0
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:
Connor Olding 2016-04-23 02:06:43 -07:00
parent 515a5f7635
commit 87c210d617
4 changed files with 58 additions and 0 deletions

View file

@ -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.

View file

@ -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)

View file

@ -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

View file

@ -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