Skip to content
Permalink
master
Switch branches/tags

Name already in use

A tag already exists with the provided branch name. Many Git commands accept both tag and branch names, so creating this branch may cause unexpected behavior. Are you sure you want to create this branch?
Go to file
 
 
Cannot retrieve contributors at this time
--------------------
-- `forall` statement.
-- The syntax is `forall VAR SELECT [if CONDN] do` where
-- `SELECT` is either `in TBL` or `= START,FINISH`
--
-- For example,
--
-- forall name in {'one','two'} do print(name) end
--
-- forall obj in get_objects() if obj:alive() then
-- obj:action()
-- end
--
-- Using `forall`, we also define _list comprehensions_ like
-- `L{s:upper() | s in names if s:match '%S+'}`
--
-- @module macro.forall
local M = require 'macro'
--- extended for statement.
-- @macro forall
M.define('forall',function(get,put)
local var = get:iden()
local t,v = get:next()
local rest,endt = get:list(M.upto_keywords('do','if'))
put:keyword 'for'
if v == 'in' then
put:iden '_' ',' :iden(var):keyword 'in'
put:iden 'ipairs' '(' :list(rest) ')'
elseif v == '=' then
put:iden(var) '=' :list(rest)
else
M.error("expecting in or =")
end
put:keyword 'do'
if endt[2] == 'if' then
rest,endt = get:list(M.upto_keywords('do'))
put:keyword 'if':list(rest):keyword 'then':iden '_END_END_'
end
return put
end)
--- list comprehension.
-- Syntax is `L{expr | select}` where `select` is as in `forall`,
-- or `L{expr for select}` where `select` is as in the regular `for` statement.
-- @macro L
-- @return a list of values
-- @usage L{2*x | x in {1,2,3}} == {1,4,9}
-- @usage L{2*x|x = 1,3} == {1,4,9}
-- @usage L{{k,v} for k,v in pairs(t)}
-- @see forall
M.define('L',function(get,put)
local t,v = get:next() -- must be '{'
local expr,endt = get:list(function(t,v)
return t == '|' or t == 'keyword' and v == 'for'
end,'')
local select = get:list('}','')
put '(' : keyword 'function' '(' ')' :keyword 'local':iden 'res' '=' '{' '}'
if endt[2] == '|' then
put:iden'forall'
else
put:keyword 'for'
end
put:list(select):space():keyword'do'
put:iden'res' '[' '#' :iden'res' '+' :number(1) ']' '=' :list(expr):space()
put:keyword 'end' :keyword 'return' : iden 'res' :keyword 'end' ')' '(' ')'
put:iden '_POP_':string'L'
return put
end)