mirror of
https://github.com/notwa/lips
synced 2024-11-14 14:59:03 -08:00
implement HEX directives; a couple misc fixes
This commit is contained in:
parent
76fe45adee
commit
3ea0184fb6
2 changed files with 73 additions and 6 deletions
11
README.md
11
README.md
|
@ -127,6 +127,17 @@ set the current address for writing to; seek.
|
|||
until lips is a little more optimized,
|
||||
be cautious of seeking to large addresses.
|
||||
|
||||
* `HEX { ... }`
|
||||
write a series of bytes given in hexadecimal.
|
||||
all numbers must be given in hex — no prefix is required.
|
||||
```
|
||||
butts: HEX {
|
||||
F0 0D
|
||||
DE AD BE EF
|
||||
}
|
||||
.align
|
||||
```
|
||||
|
||||
### Unimplemented
|
||||
|
||||
* FLOAT: writes a list of 32-bit floating point numbers until end-of-line.
|
||||
|
|
68
lips.lua
68
lips.lua
|
@ -549,7 +549,7 @@ function Lexer:lex_block_comment(yield)
|
|||
self:nextc()
|
||||
yield('EOL', '\n')
|
||||
elseif self.ord == self.EOF then
|
||||
self:error('incomplete block comment')
|
||||
self:error('unexpected EOF; incomplete block comment')
|
||||
elseif self.chrchr == '*/' then
|
||||
self:nextc()
|
||||
self:nextc()
|
||||
|
@ -584,6 +584,60 @@ function Lexer:read_number()
|
|||
end
|
||||
end
|
||||
|
||||
function Lexer:lex_hex(yield)
|
||||
local hexmatch = '[0-9A-Fa-f]'
|
||||
local entered = false
|
||||
while true do
|
||||
if self.chr == '\n' then
|
||||
self:nextc()
|
||||
yield('EOL', '\n')
|
||||
elseif self.ord == self.EOF then
|
||||
self:error('unexpected EOF; incomplete hex directive')
|
||||
elseif self.chr == ';' then
|
||||
self:skip_to_EOL()
|
||||
elseif self.chrchr == '//' then
|
||||
self:skip_to_EOL()
|
||||
elseif self.chrchr == '/*' then
|
||||
self:nextc()
|
||||
self:nextc()
|
||||
self:lex_block_comment(yield)
|
||||
elseif self.chr:find('%s') then
|
||||
self:nextc()
|
||||
elseif self.chr == '{' then
|
||||
if entered then
|
||||
self:error('unexpected opening brace')
|
||||
end
|
||||
self:nextc()
|
||||
entered = true
|
||||
elseif self.chr == '}' then
|
||||
if not entered then
|
||||
self:error('expected opening brace')
|
||||
end
|
||||
self:nextc()
|
||||
break
|
||||
elseif self.chr == ',' then
|
||||
self:error('commas are not allowed in HEX directives')
|
||||
elseif self.chr:find(hexmatch) and self.chr2:find(hexmatch) then
|
||||
local num = tonumber(self.chrchr, 16)
|
||||
self:nextc()
|
||||
self:nextc()
|
||||
if self.chr:find(hexmatch) then
|
||||
self:error('too many hex digits to be a single byte')
|
||||
end
|
||||
yield('DIR', 'BYTE')
|
||||
yield('NUM', num)
|
||||
elseif self.chr:find(hexmatch) then
|
||||
self:error('expected two hex digits to make a byte')
|
||||
else
|
||||
if entered then
|
||||
self:error('expected bytes given in hex or closing brace')
|
||||
else
|
||||
self:error('expected opening brace')
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function Lexer:lex(yield)
|
||||
while true do
|
||||
if self.chr == '\n' then
|
||||
|
@ -637,7 +691,7 @@ function Lexer:lex(yield)
|
|||
self:error('not a directive')
|
||||
end
|
||||
if up == 'INC' or up == 'INCASM' or up == 'INCLUDE' then
|
||||
yield('DIR', 'UP')
|
||||
yield('DIR', 'INC')
|
||||
else
|
||||
yield('DIR', up)
|
||||
end
|
||||
|
@ -655,7 +709,7 @@ function Lexer:lex(yield)
|
|||
self:nextc()
|
||||
yield('LABEL', buff)
|
||||
elseif up == 'HEX' then
|
||||
yield('DIR', up)
|
||||
self:lex_hex(yield)
|
||||
elseif all_registers[up] then
|
||||
yield('REG', up)
|
||||
elseif all_instructions[up] then
|
||||
|
@ -1083,11 +1137,13 @@ function Parser:tokenize()
|
|||
|
||||
local lex = function()
|
||||
local t = {line=line}
|
||||
local ok
|
||||
ok, t.tt, t.tok = coroutine.resume(routine)
|
||||
local ok, a, b = coroutine.resume(routine)
|
||||
if not ok then
|
||||
error('Internal Error: lexer coroutine has stopped')
|
||||
a = a or 'Internal Error: lexer coroutine has stopped'
|
||||
error(a)
|
||||
end
|
||||
t.tt = a
|
||||
t.tok = b
|
||||
table.insert(self.tokens, t)
|
||||
return t.tt, t.tok
|
||||
end
|
||||
|
|
Loading…
Reference in a new issue