mirror of
https://github.com/notwa/lips
synced 2025-03-09 11:32:49 -07: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:
|
this allows you to have a PC value different from origin:
|
||||||
`PC = origin + base`
|
`PC = origin + base`
|
||||||
|
|
||||||
|
* `.push {vars...}` `.pop {vars...}'
|
||||||
|
pushes or pops variables with an internal stack.
|
||||||
|
supported variables: org, base, pc.
|
||||||
|
|
||||||
* `HEX { ... }`
|
* `HEX { ... }`
|
||||||
write a series of bytes given in hexadecimal.
|
write a series of bytes given in hexadecimal.
|
||||||
all numbers must be given in hex — no prefix is required.
|
all numbers must be given in hex — no prefix is required.
|
||||||
|
|
|
@ -85,6 +85,12 @@ function Collector:directive()
|
||||||
end
|
end
|
||||||
if name == 'ORG' or name == 'BASE' then
|
if name == 'ORG' or name == 'BASE' then
|
||||||
add(name, self:const(nil, 'no labels'))
|
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
|
elseif name == 'ALIGN' or name == 'SKIP' then
|
||||||
if self:is_EOL() and name == 'ALIGN' then
|
if self:is_EOL() and name == 'ALIGN' then
|
||||||
add(name)
|
add(name)
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
local floor = math.floor
|
local floor = math.floor
|
||||||
local format = string.format
|
local format = string.format
|
||||||
local insert = table.insert
|
local insert = table.insert
|
||||||
|
local remove = table.remove
|
||||||
local unpack = unpack or table.unpack
|
local unpack = unpack or table.unpack
|
||||||
|
|
||||||
local path = string.gsub(..., "[^.]+$", "")
|
local path = string.gsub(..., "[^.]+$", "")
|
||||||
|
@ -276,6 +277,7 @@ function Dumper:pc()
|
||||||
end
|
end
|
||||||
|
|
||||||
function Dumper:load(statements)
|
function Dumper:load(statements)
|
||||||
|
local valstack = {} -- for .push/.pop directives
|
||||||
local new_statements = {}
|
local new_statements = {}
|
||||||
self.pos = 0
|
self.pos = 0
|
||||||
self.base = 0
|
self.base = 0
|
||||||
|
@ -296,6 +298,51 @@ function Dumper:load(statements)
|
||||||
elseif s.type == '!BASE' then
|
elseif s.type == '!BASE' then
|
||||||
self.base = s[1].tok
|
self.base = s[1].tok
|
||||||
insert(new_statements, s)
|
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
|
elseif s.type == '!ALIGN' or s.type == '!SKIP' then
|
||||||
local length, content
|
local length, content
|
||||||
if s.type == '!ALIGN' then
|
if s.type == '!ALIGN' then
|
||||||
|
|
|
@ -30,6 +30,7 @@ data.fpu_registers = {
|
||||||
|
|
||||||
data.all_directives = {
|
data.all_directives = {
|
||||||
'ORG', 'BASE', 'ALIGN', 'SKIP',
|
'ORG', 'BASE', 'ALIGN', 'SKIP',
|
||||||
|
'PUSH', 'POP', -- experimental
|
||||||
'ASCII', 'ASCIIZ',
|
'ASCII', 'ASCIIZ',
|
||||||
'BYTE', 'HALFWORD', 'WORD',
|
'BYTE', 'HALFWORD', 'WORD',
|
||||||
--'HEX', -- excluded here due to different syntax
|
--'HEX', -- excluded here due to different syntax
|
||||||
|
|
Loading…
Add table
Reference in a new issue