1
0
Fork 0
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:
Connor Olding 2015-11-26 19:15:15 -08:00
parent 76fe45adee
commit 3ea0184fb6
2 changed files with 73 additions and 6 deletions

View file

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

View file

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