aboutsummaryrefslogtreecommitdiff
path: root/spec/inputs/macro.moon
blob: 9083449061d503adbe159d62dba08b3bf0aa6405 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
macro block init = ->
	with require "moonp"
		package.moonpath = "?.moon;./spec/inputs/?.moon"
	""

$init!

import "macro_export" as {$myconfig:$config, :$showMacro, :$asserts, :$assert}

$asserts item == nil

$myconfig false

v = $assert item == nil

macro expr and = (...)->
	values = [value for value in *{...}]
	$showMacro "and", "#{ table.concat values, " and " }"

if $and f1
	print "OK"

if $and f1,f2,f3
	print "OK"

macro expr map = (items,action)->
	$showMacro "map", "[#{action} for _ in *#{items}]"

macro expr filter = (items,action)->
	$showMacro "filter", "[_ for _ in *#{items} when #{action}]"

macro expr reduce = (items,def,action)->
	$showMacro "reduce", "if ##{items} == 0
	#{def}
else
	_1 = #{def}
	for _2 in *#{items}
		_1 = #{action}
	_1"

macro block foreach = (items,action)->
	$showMacro "foreach", "for _ in *#{items}
	#{action}"

macro expr pipe = (...)->
	switch select "#", ...
		when 0 then return ""
		when 1 then return ...
	ops = {...}
	last = ops[1]
	stmts = for i = 2,#ops
		stmt = "\tlocal _#{i} = #{last} |> #{ops[i]}"
		last = "_#{i}"
		stmt
	res = "do
#{table.concat stmts, "\n"}
	#{last}"
	$showMacro "pipe", res

{1,2,3} |> $map(_ * 2) |> $filter(_ > 4) |> $foreach print _

$foreach $filter($map({1,2,3}, _ * 2), _ > 4), print _

val = $pipe(
	{1, 2, 3}
	$map(_ * 2)
	$filter(_ > 4)
	$reduce(0, _1 + _2)
)

macro expr plus = (a, b)-> "#{a} + #{b}"

$plus(1,2)\call 123

macro expr curry = (...)->
	args = {...}
	len = #args
	body = args[len]
	def = table.concat ["(#{args[i]})->" for i = 1, len - 1]
	"#{def}\n#{body\gsub "^do%s*\n",""}"

f = $curry x,y,z,do
	print x,y,z

macro expr get_inner = (var)-> "do
	a = 1
	a + 1"

macro expr get_inner_hygienic = (var)-> "(->
	local a = 1
	a + 1)!"

do
	a = 8
	a = $get_inner!
	a += $get_inner!
	print a

do
	a = 8
	a = $get_inner_hygienic!
	a += $get_inner_hygienic!
	print a

nil