allow expressions in variable definitions

This commit is contained in:
Connor Olding 2016-11-27 20:56:51 -08:00
parent 067267c313
commit de2618bb61
2 changed files with 17 additions and 28 deletions

View File

@ -48,7 +48,7 @@ function Expander:pop(kind)
end
function Expander:expand(statements)
-- fourth pass: expand pseudo-instructions and register arguments
-- third pass: expand pseudo-instructions and register arguments
self.statements = {}
for i, s in ipairs(statements) do
self.s = s

View File

@ -96,21 +96,12 @@ function Preproc:resolve(t)
end
function Preproc:check(s, i, tt)
s = s or self.s
i = i or self.i
local t = s[i]
if t == nil then
local err = ("expected another argument for %s at position %i"):format(self.s.type, self.i)
self:error(err)
end
self.fn = t.fn
self.line = t.line
if t.tt ~= tt then
self:lookup(t)
end
if t.tt ~= tt then
local err = ("argument %i of %s expected type %s"):format(i, s.type, tt)
self:error(err, t.tt)
@ -118,14 +109,30 @@ function Preproc:check(s, i, tt)
return t.tok
end
function Preproc:evaluate(t)
if t.tt == 'EXPR' then
local result, err = self.expr:eval(t.tok)
if err then
self:error('failed to evaulate ('..t.tok..')', err)
end
t.tt = 'NUM'
t.tok = result
end
self:lookup(t)
end
function Preproc:process(statements)
self.variables = {}
self.plus_labels = {} -- constructed forwards
self.minus_labels = {} -- constructed backwards
self.expr = Expression(self.variables)
-- first pass: resolve variables and collect relative labels
local new_statements = {}
for s in self:iter(statements) do
for j, t in ipairs(s) do
self:evaluate(t)
end
if s.type == '!VAR' then
local a = self:check(s, 1, 'VAR')
local b = self:check(s, 2, 'NUM')
@ -148,9 +155,6 @@ function Preproc:process(statements)
end
insert(new_statements, s)
else
for j, t in ipairs(s) do
self:lookup(t)
end
insert(new_statements, s)
end
end
@ -162,21 +166,6 @@ function Preproc:process(statements)
end
end
-- third pass: evaluate constant expressions
for s in self:iter(new_statements) do
for j, t in ipairs(s) do
if t.tt == 'EXPR' then
local expr = Expression()
local result, err = expr:eval(t.tok)
if err then
self:error('failed to evaulate ('..t.tok..')', err)
end
t.tt = 'NUM'
t.tok = result
end
end
end
return new_statements
end