From 5ddbca453d823ae10584a8108203bf17eb43c9a2 Mon Sep 17 00:00:00 2001 From: steve donovan Date: Sun, 9 Jun 2013 17:09:04 +0200 Subject: [PATCH] -V option, not -D; if/else test. Bumped to 2.5 --- luam | 24 ++-- macro/Getter.lua | 5 + macro/assert.lua | 4 +- tests/atm.lua => macro/ifelse.lua | 178 +++++++++++++++--------------- tests/test-atm.lua | 25 +++-- tests/tests.lua | 12 +- 6 files changed, 135 insertions(+), 113 deletions(-) rename tests/atm.lua => macro/ifelse.lua (67%) diff --git a/luam b/luam index 4d9fc5c..bd02269 100644 --- a/luam +++ b/luam @@ -26,7 +26,7 @@ local usage = [[ LuaMacro 2.5.0, a Lua macro preprocessor and runner -l require a library -e statement to be executed - -D set a symbol (-DX or -DY=1) + -V set a variable (-VX or -VY=1) -c error context to be shown (default 2) -d dump preprocessed output to stdout -o write to this file @@ -38,7 +38,7 @@ LuaMacro 2.5.0, a Lua macro preprocessor and runner ]] -- parsing the args, the hard way: -local takes_value = {l = '', e = '', c = 2, o = '',D = ''} +local takes_value = {l = '', e = '', c = 2, o = '',V = ';'} local args = {} local idx,i = 1,1 @@ -60,6 +60,8 @@ while i <= #arg do local def = takes_value[flag] if type(def) == 'number' then val = tonumber(val) + elseif def == ';' and args[flag] then + val = args[flag]..';'..val end args[flag] = val or true else @@ -215,7 +217,7 @@ end local function interactive_loop () os.execute(arg[-1]..' -v') -- for the Lua copyright - print 'Lua Macro 2.3.0 Copyright (C) 2007-2011 Steve Donovan' + print 'Lua Macro 2.5.0 Copyright (C) 2007-2011 Steve Donovan' local function readline() io.write(_PROMPT or '> ') @@ -251,15 +253,19 @@ macro.set_package_loader() if args.l ~= '' then require(args.l) end -if args.D ~= '' then - local sym,val = args.D:match '([^=]+)=(.+)' - if not sym then - sym = args.D - val = true +if args.V ~= ';' then + for varset in args.V:gmatch '([^;]+)' do + local sym,val = varset:match '([^=]+)=(.+)' + if not sym then + sym = varset + val = true + end + _G[sym] = val end - _G[sym] = val end +require 'macro.ifelse' + if args.e ~= '' then subst_runstring(args.e,"") else diff --git a/macro/Getter.lua b/macro/Getter.lua index 1470387..b1b35ed 100644 --- a/macro/Getter.lua +++ b/macro/Getter.lua @@ -166,6 +166,11 @@ function Getter.upto(tok,k1,k2) return ltl[1],tok end +function Getter.line(tok) + return tok:upto(function(t,v) + return (t=='space' and v:match '\n') or t == 'comment' + end) +end --- get the next identifier token. -- (will be an error if the token has wrong type) diff --git a/macro/assert.lua b/macro/assert.lua index 3b66311..b25daaf 100644 --- a/macro/assert.lua +++ b/macro/assert.lua @@ -39,9 +39,7 @@ M.define('assert_',function(get,put) local testx,tok = get:upto(function(t,v) return relop[t] or (t == 'iden' and (v == 'matches' or v == 'throws')) end) - local testy,eos = get:upto (function(t,v) - return (t == 'space' and v:match '\n') or t == 'comment' - end) + local testy,eos = get:line() local otesty = testy testx = tostring(testx) testy = tostring(testy) diff --git a/tests/atm.lua b/macro/ifelse.lua similarity index 67% rename from tests/atm.lua rename to macro/ifelse.lua index e3e43ab..8beb826 100644 --- a/tests/atm.lua +++ b/macro/ifelse.lua @@ -1,88 +1,90 @@ -local M = require 'macro' - -local function get_args (get) - -- grab the expression - return (get:upto(function(t,v) - return (t=='space' and v:match '\n') or t == 'comment' - end)) -end - -local function eval (get,was_expr) - local expr = tostring(get_args(get)) - if was_expr then expr = "return "..expr end - local chunk = M.assert(loadstring(expr)) - local ok, res = pcall(chunk) - if not ok then M.error("error evaluating "..res) end - return res -end - -local function next_at_macro (get) - local t,v = get() - while t ~= '@' do t = get() end - t,v = get() - return v -end - -local function grab (get) - local ilevel = 0 - while true do - local v = next_at_macro (get) - if v == 'if' then - ilevel = ilevel + 1 - else -- 'end','elseif','else' - if ilevel > 0 and v == 'end' then - ilevel = ilevel - 1 - elseif ilevel == 0 then return '@'..v end - end - end -end - -M.define('@',function(get,put) - local t,v = get() ---~ print('got',t,v) - return put:name(v..'_') -end) - -local ifstack,push,pop = {},table.insert,table.remove - -local function push_if (res) ---~ print 'push' - push(ifstack, not (res==false or res==nil)) -end - -local function pop_if () ---~ print 'pop' - pop(ifstack) -end - -M.define('if_',function(get) - local res = eval(get,true) - push_if(res) - if not res then - return grab(get) - end -end) - -M.define('elseif_',function(get) - local res = eval(get,true) - pop_if() - push_if(res) - if not res then - return grab(get) - end -end) - -M.define('else_',function(get) - if #ifstack == 0 then M.error("mismatched else") end - if ifstack[#ifstack] then - return grab(get) - end -end) - -M.define('end_',function(get) - pop_if() -end) - -M.define('eval_',function(get) - eval(get) -end) +local M = require 'macro' + +local function eval (expr,was_expr) + expr = tostring(expr) + if was_expr then expr = "return "..expr end + local chunk = M.assert(loadstring(expr)) + local ok, res = pcall(chunk) + if not ok then M.error("error evaluating "..res) end + return res +end + +local function eval_line (get,was_expr) + local args = get:line() + return eval(args,was_expr) +end + +local function grab (get) + local ilevel = 0 + while true do + local t,v = get() + while t ~= '@' do t = get() end + t,v = get() + if v == 'if' then + ilevel = ilevel + 1 + else -- 'end','elseif','else' + if ilevel > 0 and v == 'end' then + ilevel = ilevel - 1 + elseif ilevel == 0 then return '@'..v end + end + end +end + +M.define('@',function(get,put) + local t,v = get() +--~ print('got',t,v) + return put:name(v..'_') +end) + +local ifstack,push,pop = {},table.insert,table.remove + +local function push_if (res) +--~ print 'push' + push(ifstack, not (res==false or res==nil)) +end + +local function pop_if () +--~ print 'pop' + pop(ifstack) +end + +M.define('if_',function(get) + local res = eval_line(get,true) + push_if(res) + if not res then + return grab(get) + end +end) + +M.define('elseif_',function(get) + local res + if ifstack[#ifstack] then + res = false + else + res = eval_line(get,true) + pop_if() + push_if(res) + end + if not res then + return grab(get) + end +end) + +M.define('else_',function(get) + if #ifstack == 0 then M.error("mismatched else") end + if ifstack[#ifstack] then + return grab(get) + end +end) + +M.define('end_',function(get) + pop_if() +end) + +M.define('let_',function(get) + eval_line(get) +end) + +M.define('eval_(X)',function(X) + return tostring(eval(X,true)) +end) diff --git a/tests/test-atm.lua b/tests/test-atm.lua index bf32949..7832b8d 100644 --- a/tests/test-atm.lua +++ b/tests/test-atm.lua @@ -1,12 +1,13 @@ -require_ 'atm' -@eval env = os.getenv -@if env 'P' -print 'gotcha' -@if A -print 'A was true' -@end -@else -print 'nada' -@end - - +@let env = os.getenv +@if env 'P' +print 'P env was set' +@if A +print 'Global A was true' +@end +@elseif A +print 'Global A was true, no P' +@else +print 'Neither P or A' +@end + + diff --git a/tests/tests.lua b/tests/tests.lua index cf743d6..865c928 100644 --- a/tests/tests.lua +++ b/tests/tests.lua @@ -13,5 +13,15 @@ if pcall(require,'pl') then execute 'list' end -os.execute 'luam -lcskin test-cskin.lua' +local function exec (cmd) + print (cmd) + os.execute(cmd) +end + +exec 'luam -lcskin test-cskin.lua' +exec 'luam test-atm.lua' +exec 'luam -VA test-atm.lua' +exec 'set P=1 && luam test-atm.lua' +exec 'set P=1 && luam -VA test-atm.lua' +