From de2618bb618b84af1edbee4448bb8985d3524073 Mon Sep 17 00:00:00 2001 From: Connor Olding Date: Sun, 27 Nov 2016 20:56:51 -0800 Subject: [PATCH] allow expressions in variable definitions --- lips/Expander.lua | 2 +- lips/Preproc.lua | 43 ++++++++++++++++--------------------------- 2 files changed, 17 insertions(+), 28 deletions(-) diff --git a/lips/Expander.lua b/lips/Expander.lua index 6664654..08e885f 100644 --- a/lips/Expander.lua +++ b/lips/Expander.lua @@ -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 diff --git a/lips/Preproc.lua b/lips/Preproc.lua index 469b4d5..8c4c515 100644 --- a/lips/Preproc.lua +++ b/lips/Preproc.lua @@ -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