aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLi Jin <dragon-fly@qq.com>2020-01-18 18:15:24 +0800
committerLi Jin <dragon-fly@qq.com>2020-01-18 18:15:24 +0800
commit8d1af508f4173e4af6a4ea98584c1a86619f6a20 (patch)
tree0264c4b01f1152d8114cf46aea6fd773276c0b01
parentf53ccb373efbf6f6f40284111df309e351c2c18f (diff)
downloadyuescript-8d1af508f4173e4af6a4ea98584c1a86619f6a20.tar.gz
yuescript-8d1af508f4173e4af6a4ea98584c1a86619f6a20.tar.bz2
yuescript-8d1af508f4173e4af6a4ea98584c1a86619f6a20.zip
fix Moonscript issue 122, add support for ? operator.
-rw-r--r--makefile2
-rw-r--r--spec/inputs/assign.moon2
-rw-r--r--spec/inputs/class.moon30
-rw-r--r--spec/inputs/comprehension.moon14
-rw-r--r--spec/inputs/cond.moon12
-rw-r--r--spec/inputs/destructure.moon2
-rw-r--r--spec/inputs/do.moon2
-rw-r--r--spec/inputs/existential.moon8
-rw-r--r--spec/inputs/funcs.moon30
-rw-r--r--spec/inputs/lists.moon8
-rw-r--r--spec/inputs/literals.moon62
-rw-r--r--spec/inputs/local.moon2
-rw-r--r--spec/inputs/loops.moon12
-rw-r--r--spec/inputs/return.moon8
-rw-r--r--spec/inputs/string.moon2
-rw-r--r--spec/inputs/switch.moon10
-rw-r--r--spec/inputs/syntax.moon42
-rw-r--r--spec/inputs/tables.moon2
-rw-r--r--spec/inputs/using.moon8
-rw-r--r--spec/inputs/whitespace.moon22
-rw-r--r--spec/inputs/with.moon4
-rw-r--r--src/MoonP/ast.hpp6
-rw-r--r--src/MoonP/moon_ast.cpp1
-rw-r--r--src/MoonP/moon_ast.h5
-rw-r--r--src/MoonP/moon_compiler.cpp508
-rw-r--r--src/MoonP/moon_parser.cpp15
-rw-r--r--src/moonc.cpp12
27 files changed, 523 insertions, 308 deletions
diff --git a/makefile b/makefile
index 5042b08..a3379a4 100644
--- a/makefile
+++ b/makefile
@@ -206,7 +206,7 @@ clean:
206.PHONY: test 206.PHONY: test
207test: release 207test: release
208 @echo "Compiling Moonscript codes..." 208 @echo "Compiling Moonscript codes..."
209 @./$(BIN_NAME) $(TEST_INPUT)/*.moon -a -s -t $(TEST_OUTPUT) 209 @./$(BIN_NAME) $(TEST_INPUT)/*.moon -l -t $(TEST_OUTPUT)
210 210
211# Main rule, checks the executable and symlinks to the output 211# Main rule, checks the executable and symlinks to the output
212all: $(BIN_PATH)/$(BIN_NAME) 212all: $(BIN_PATH)/$(BIN_NAME)
diff --git a/spec/inputs/assign.moon b/spec/inputs/assign.moon
index 1e5e7a6..3e66491 100644
--- a/spec/inputs/assign.moon
+++ b/spec/inputs/assign.moon
@@ -1,5 +1,5 @@
1 1
2-> 2_ = ->
3 joop = 2302 3 joop = 2302
4 4
5 (hi) -> 5 (hi) ->
diff --git a/spec/inputs/class.moon b/spec/inputs/class.moon
index 9a98055..2290bc7 100644
--- a/spec/inputs/class.moon
+++ b/spec/inputs/class.moon
@@ -73,11 +73,11 @@ class CoolSuper
73 hi: => 73 hi: =>
74 super(1,2,3,4) 1,2,3,4 74 super(1,2,3,4) 1,2,3,4
75 super.something 1,2,3,4 75 super.something 1,2,3,4
76 super.something(1,2,3,4).world 76 _ = super.something(1,2,3,4).world
77 super\yeah"world".okay hi, hi, hi 77 super\yeah"world".okay hi, hi, hi
78 something.super 78 _ = something.super
79 super.super.super.super 79 _ = super.super.super.super
80 super\hello 80 _ = super\hello
81 nil 81 nil
82 82
83 83
@@ -114,11 +114,11 @@ y = @@
114@ = 343 114@ = 343
115@.hello 2,3,4 115@.hello 2,3,4
116 116
117hello[@].world 117_ = hello[@].world
118 118
119 119
120class Whacko 120class Whacko
121 @hello 121 _ = @hello
122 if something 122 if something
123 print "hello world" 123 print "hello world"
124 124
@@ -132,20 +132,20 @@ print "hello"
132 132
133yyy = -> 133yyy = ->
134 class Cool 134 class Cool
135 nil 135 _ = nil
136 136
137 137
138-- 138--
139 139
140class a.b.c.D 140class a.b.c.D
141 nil 141 _ = nil
142 142
143 143
144class a.b["hello"] 144class a.b["hello"]
145 nil 145 _ = nil
146 146
147class (-> require "moon")!.Something extends Hello.World 147class (-> require "moon")!.Something extends Hello.World
148 nil 148 _ = nil
149 149
150-- 150--
151 151
@@ -160,7 +160,7 @@ print (class WhatsUp).__name
160 160
161export ^ 161export ^
162class Something 162class Something
163 nil 163 _ = nil
164 164
165 165
166-- 166--
@@ -197,17 +197,17 @@ class Whack extends Thing
197class Wowha extends Thing 197class Wowha extends Thing
198 @butt: -> 198 @butt: ->
199 super! 199 super!
200 super.hello 200 _ = super.hello
201 super\hello! 201 super\hello!
202 super\hello 202 _ = super\hello
203 203
204 204
205 @zone: cool { 205 @zone: cool {
206 -> 206 ->
207 super! 207 super!
208 super.hello 208 _ = super.hello
209 super\hello! 209 super\hello!
210 super\hello 210 _ = super\hello
211 } 211 }
212 212
213nil 213nil
diff --git a/spec/inputs/comprehension.moon b/spec/inputs/comprehension.moon
index 1609d79..f07cf89 100644
--- a/spec/inputs/comprehension.moon
+++ b/spec/inputs/comprehension.moon
@@ -11,11 +11,11 @@ copy = {k,v for k,v in pairs x when k != "okay"}
11 11
12-- 12--
13 13
14{ unpack(x) for x in yes } 14_ = { unpack(x) for x in yes }
15{ unpack(x) for x in *yes } 15_ = { unpack(x) for x in *yes }
16 16
17{ xxxx for x in yes } 17_ = { xxxx for x in yes }
18{ unpack [a*i for i, a in ipairs x] for x in *{{1,2}, {3,4}} } 18_ = { unpack [a*i for i, a in ipairs x] for x in *{{1,2}, {3,4}} }
19 19
20 20
21-- 21--
@@ -28,7 +28,7 @@ bb = [y for thing in y for i=1,10]
28cc = [y for i=1,10 for thing in y] 28cc = [y for i=1,10 for thing in y]
29dd = [y for i=1,10 when cool for thing in y when x > 3 when c + 3] 29dd = [y for i=1,10 when cool for thing in y when x > 3 when c + 3]
30 30
31{"hello", "world" for i=1,10} 31_ = {"hello", "world" for i=1,10}
32 32
33-- 33--
34 34
@@ -44,8 +44,8 @@ ok(a,b,c) for {a,b,c} in things
44 44
45-- 45--
46 46
47[item for item in *items[1 + 2,3+4]] 47_ = [item for item in *items[1 + 2,3+4]]
48[item for item in *items[hello! * 4, 2 - thing[4]]] 48_ = [item for item in *items[hello! * 4, 2 - thing[4]]]
49 49
50 50
51 51
diff --git a/spec/inputs/cond.moon b/spec/inputs/cond.moon
index 18e42b9..e8b6283 100644
--- a/spec/inputs/cond.moon
+++ b/spec/inputs/cond.moon
@@ -1,25 +1,25 @@
1 1
2you_cool = false 2you_cool = false
3 3
4if cool 4_ = if cool
5 if you_cool 5 if you_cool
6 one 6 one
7 else if eatdic 7 else if eatdic
8 yeah 8 yeah
9 else 9 else
10 two 10 _ = two
11 three 11 three
12else 12else
13 no 13 no
14 14
15if cool then no 15_ = if cool then no
16if cool then no else yes 16_ = if cool then no else yes
17 17
18if cool then wow cool else 18if cool then wow cool else
19 noso cool 19 noso cool
20 20
21if working 21if working
22 if cool then if cool then okay else what else nah 22 _ = if cool then if cool then okay else what else nah
23 23
24 24
25if yeah then no day elseif cool me then okay ya else u way 25if yeah then no day elseif cool me then okay ya else u way
@@ -70,7 +70,7 @@ hello = 5 + if something = 10
70 70
71z = false 71z = false
72 72
73if false 73_ = if false
74 one 74 one
75elseif x = true 75elseif x = true
76 two 76 two
diff --git a/spec/inputs/destructure.moon b/spec/inputs/destructure.moon
index beb79d6..2509968 100644
--- a/spec/inputs/destructure.moon
+++ b/spec/inputs/destructure.moon
@@ -90,7 +90,7 @@ do
90do 90do
91 {a,b,c} = z 91 {a,b,c} = z
92 92
93(z) -> 93_ = (z) ->
94 {a,b,c} = z 94 {a,b,c} = z
95 95
96do 96do
diff --git a/spec/inputs/do.moon b/spec/inputs/do.moon
index 334e68f..21e2127 100644
--- a/spec/inputs/do.moon
+++ b/spec/inputs/do.moon
@@ -11,7 +11,7 @@ y = do
11 things = "shhh" 11 things = "shhh"
12 -> "hello: " .. things 12 -> "hello: " .. things
13 13
14-> if something then do "yeah" 14_ = -> if something then do "yeah"
15 15
16t = { 16t = {
17 y: do 17 y: do
diff --git a/spec/inputs/existential.moon b/spec/inputs/existential.moon
new file mode 100644
index 0000000..97e8de0
--- /dev/null
+++ b/spec/inputs/existential.moon
@@ -0,0 +1,8 @@
1if {:x} = a?.if?\then?(123)? @?\function 998
2 print x
3
4with abc?!\func?!
5 if \p? "abc"
6 return 123
7
8@?\func 998
diff --git a/spec/inputs/funcs.moon b/spec/inputs/funcs.moon
index 08a29b6..7a4d5d6 100644
--- a/spec/inputs/funcs.moon
+++ b/spec/inputs/funcs.moon
@@ -2,9 +2,9 @@
2 2
3x = -> print what 3x = -> print what
4 4
5-> 5_ = ->
6 6
7-> -> -> 7_ = -> -> ->
8 8
9go to the barn 9go to the barn
10 10
@@ -27,29 +27,29 @@ x = (...) ->
27hello! 27hello!
28hello.world! 28hello.world!
29 29
30hello!.something 30_ = hello!.something
31what!["ofefe"] 31_ = what!["ofefe"]
32 32
33what! the! heck! 33what! the! heck!
34 34
35(a,b,c,d,e) -> 35_ = (a,b,c,d,e) ->
36 36
37(a,a,a,a,a) -> 37_ = (a,a,a,a,a) ->
38 print a 38 print a
39 39
40(x=23023) -> 40_ = (x=23023) ->
41 41
42(x=(y=()->) ->) -> 42_ = (x=(y=()->) ->) ->
43 43
44(x = if something then yeah else no) -> 44_ = (x = if something then yeah else no) ->
45 45
46something = (hello=100, world=(x=[[yeah cool]])-> print "eat rice") -> 46something = (hello=100, world=(x=[[yeah cool]])-> print "eat rice") ->
47 print hello 47 print hello
48 48
49(x, y) => 49_ = (x, y) =>
50(@x, @y) => 50_ = (@x, @y) =>
51(x=1) => 51_ = (x=1) =>
52(@x=1,y,@z="hello world") => 52_ = (@x=1,y,@z="hello world") =>
53 53
54 54
55x -> return 55x -> return
@@ -57,7 +57,7 @@ y -> return 1
57z -> return 1, "hello", "world" 57z -> return 1, "hello", "world"
58k -> if yes then return else return 58k -> if yes then return else return
59 59
60-> real_name if something 60_ = -> real_name if something
61 61
62-- 62--
63 63
@@ -97,7 +97,7 @@ f(
97 97
98x = (a, 98x = (a,
99 b) -> 99 b) ->
100 print "what" 100 print "what"
101 101
102 102
103y = (a="hi", 103y = (a="hi",
diff --git a/spec/inputs/lists.moon b/spec/inputs/lists.moon
index c119185..e377d5e 100644
--- a/spec/inputs/lists.moon
+++ b/spec/inputs/lists.moon
@@ -3,14 +3,14 @@ hi = [x*2 for _, x in ipairs{1,2,3,4}]
3 3
4items = {1,2,3,4,5,6} 4items = {1,2,3,4,5,6}
5 5
6[z for z in ipairs items when z > 4] 6_ = [z for z in ipairs items when z > 4]
7 7
8rad = [{a} for a in ipairs { 8rad = [{a} for a in ipairs {
9 1,2,3,4,5,6, 9 1,2,3,4,5,6,
10} when good_number a] 10} when good_number a]
11 11
12 12
13[z for z in items for j in list when z > 4] 13_ = [z for z in items for j in list when z > 4]
14 14
15require "util" 15require "util"
16 16
@@ -32,7 +32,7 @@ print x,y for x in ipairs{1,2,4} for y in ipairs{1,2,3} when x != 2
32 32
33print "hello", x for x in items 33print "hello", x for x in items
34 34
35[x for x in x] 35_ = [x for x in x]
36x = [x for x in x] 36x = [x for x in x]
37 37
38print x,y for x in ipairs{1,2,4} for y in ipairs{1,2,3} when x != 2 38print x,y for x in ipairs{1,2,4} for y in ipairs{1,2,3} when x != 2
@@ -67,6 +67,6 @@ normal = (hello) ->
67test = x 1,2,3,4,5 67test = x 1,2,3,4,5
68print thing for thing in *test 68print thing for thing in *test
69 69
70-> a = b for row in *rows 70_ = -> a = b for row in *rows
71 71
72 72
diff --git a/spec/inputs/literals.moon b/spec/inputs/literals.moon
index c3a24a6..d4b0326 100644
--- a/spec/inputs/literals.moon
+++ b/spec/inputs/literals.moon
@@ -1,46 +1,46 @@
1 1
2_ = {
3 121
4 121.2323
5 121.2323e-1
6 121.2323e13434
7 2323E34
8 0x12323
2 9
3121 10 0xfF2323
4121.2323 11 0xabcdef
5121.2323e-1 12 0xABCDEF
6121.2323e13434
72323E34
80x12323
9 13
100xfF2323 14 .2323
110xabcdef 15 .2323e-1
120xABCDEF 16 .2323e13434
13 17
14.2323
15.2323e-1
16.2323e13434
17 18
19 1LL
20 1ULL
21 9332LL
22 9332
23 0x2aLL
24 0x2aULL
18 25
191LL 26 [[ hello world ]]
201ULL
219332LL
229332
230x2aLL
240x2aULL
25 27
26[[ hello world ]] 28 [=[ hello world ]=]
29 [====[ hello world ]====]
27 30
28[=[ hello world ]=] 31 "another world"
29[====[ hello world ]====]
30 32
31"another world" 33 'what world'
32 34
33'what world'
34 35
36 "
37 hello world
38 "
35 39
36" 40 'yeah
37hello world 41 what is going on
38" 42 here is something cool'
39
40'yeah
41what is going on
42here is something cool'
43
44 43
44}
45nil 45nil
46 46
diff --git a/spec/inputs/local.moon b/spec/inputs/local.moon
index fec78b1..f14f575 100644
--- a/spec/inputs/local.moon
+++ b/spec/inputs/local.moon
@@ -89,6 +89,6 @@ do
89do 89do
90 local * 90 local *
91 -- this generates a nil value in the body 91 -- this generates a nil value in the body
92 for a in *{} do a 92 for a in *{} do _ = a
93 93
94g = 2323 -- test if anything leaked 94g = 2323 -- test if anything leaked
diff --git a/spec/inputs/loops.moon b/spec/inputs/loops.moon
index a704e56..130570e 100644
--- a/spec/inputs/loops.moon
+++ b/spec/inputs/loops.moon
@@ -33,7 +33,7 @@ for x in y, z, k
33 33
34x = -> 34x = ->
35 for x in y 35 for x in y
36 y 36 _ = y
37 37
38hello = {1,2,3,4,5} 38hello = {1,2,3,4,5}
39 39
@@ -43,7 +43,7 @@ x = for y in *hello
43 43
44x = -> 44x = ->
45 for x in *hello 45 for x in *hello
46 y 46 _ = y
47 47
48t = for i=10,20 do i * 2 48t = for i=10,20 do i * 2
49 49
@@ -52,11 +52,11 @@ y = for j = 3,30, 8
52 hmm += 1 52 hmm += 1
53 j * hmm 53 j * hmm
54 54
55-> 55_ = ->
56 for k=10,40 56 for k=10,40
57 "okay" 57 _ = "okay"
58 58
59-> 59_ = ->
60 return for k=10,40 60 return for k=10,40
61 "okay" 61 "okay"
62 62
@@ -68,7 +68,7 @@ while 5 + 5
68 68
69while also do 69while also do
70 i work too 70 i work too
71 "okay" 71 _ = "okay"
72 72
73i = 0 73i = 0
74x = while i < 10 74x = while i < 10
diff --git a/spec/inputs/return.moon b/spec/inputs/return.moon
index 61d3dca..98c3104 100644
--- a/spec/inputs/return.moon
+++ b/spec/inputs/return.moon
@@ -1,7 +1,7 @@
1-- testing `return` propagation 1-- testing `return` propagation
2 2
3-> x for x in *things 3_ = -> _ = x for x in *things
4-> [x for x in *things] 4_ = -> [x for x in *things]
5 5
6 6
7-- doesn't make sense on purpose 7-- doesn't make sense on purpose
@@ -14,7 +14,7 @@ do
14do 14do
15 return {x,y for x,y in *things} 15 return {x,y for x,y in *things}
16 16
17-> 17_ = ->
18 if a 18 if a
19 if a 19 if a
20 a 20 a
@@ -49,7 +49,7 @@ do
49 else 49 else
50 b 50 b
51 51
52-> a\b 52_ = -> a\b
53do a\b 53do a\b
54 54
55 55
diff --git a/spec/inputs/string.moon b/spec/inputs/string.moon
index 897056a..5d8f772 100644
--- a/spec/inputs/string.moon
+++ b/spec/inputs/string.moon
@@ -52,7 +52,7 @@ c = 'hello #{hello}'
52 52
53-- 53--
54 54
55"hello" 55_ = "hello"
56"hello"\format 1 56"hello"\format 1
57"hello"\format(1,2,3) 57"hello"\format(1,2,3)
58"hello"\format(1,2,3) 1,2,3 58"hello"\format(1,2,3) 1,2,3
diff --git a/spec/inputs/switch.moon b/spec/inputs/switch.moon
index 3bc179b..a028f98 100644
--- a/spec/inputs/switch.moon
+++ b/spec/inputs/switch.moon
@@ -15,7 +15,7 @@ switch value
15 when "cool" 15 when "cool"
16 print "hello world" 16 print "hello world"
17 when "yeah" 17 when "yeah"
18 [[FFFF]] + [[MMMM]] 18 _ = [[FFFF]] + [[MMMM]]
19 when 2323 + 32434 19 when 2323 + 32434
20 print "okay" 20 print "okay"
21 else 21 else
@@ -33,9 +33,9 @@ out = switch value
33with something 33with something
34 switch \value! 34 switch \value!
35 when .okay 35 when .okay
36 "world" 36 _ = "world"
37 else 37 else
38 "yesh" 38 _ = "yesh"
39 39
40fix this 40fix this
41call_func switch something 41call_func switch something
@@ -46,7 +46,7 @@ call_func switch something
46 46
47switch hi 47switch hi
48 when hello or world 48 when hello or world
49 greene 49 _ = greene
50 50
51-- 51--
52 52
@@ -54,7 +54,7 @@ switch hi
54 when "one", "two" 54 when "one", "two"
55 print "cool" 55 print "cool"
56 when "dad" 56 when "dad"
57 no 57 _ = no
58 58
59switch hi 59switch hi
60 when 3+1, hello!, (-> 4)! 60 when 3+1, hello!, (-> 4)!
diff --git a/spec/inputs/syntax.moon b/spec/inputs/syntax.moon
index 854f629..351b22c 100644
--- a/spec/inputs/syntax.moon
+++ b/spec/inputs/syntax.moon
@@ -27,7 +27,7 @@ what(the)[3243] world, yeck heck
27 27
28hairy[hands][are](gross) okay okay[world] 28hairy[hands][are](gross) okay okay[world]
29 29
30(get[something] + 5)[years] 30_ = (get[something] + 5)[years]
31 31
32i,x = 200, 300 32i,x = 200, 300
33 33
@@ -37,27 +37,27 @@ yeah = ((1+5)*3)/2 + i % 100
37 37
38whoa = (1+2) * (3+4) * (4+5) 38whoa = (1+2) * (3+4) * (4+5)
39 39
40-> 40_ = ->
41 if something 41 if something
42 return 1,2,4 42 return 1,2,4
43 43
44 print "hello" 44 print "hello"
45 45
46-> 46_ = ->
47 if hello 47 if hello
48 "heloo", "world" 48 "heloo", "world"
49 else 49 else
50 no, way 50 no, way
51 51
52 52
53-> 1,2,34 53_ = -> 1,2,34
54 54
55return 5 + () -> 4 + 2 55return 5 + () -> 4 + 2
56 56
57return 5 + (() -> 4) + 2 57return 5 + (() -> 4) + 2
58 58
59print 5 + () -> 59print 5 + () ->
60 34 60 _ = 34
61 good nads 61 good nads
62 62
63 63
@@ -66,19 +66,19 @@ something 'else', "ya"
66something'else' 66something'else'
67something"else" 67something"else"
68 68
69something[[hey]] * 2 69_ = something[[hey]] * 2
70something[======[hey]======] * 2 70_ = something[======[hey]======] * 2
71 71
72 72
73something'else', 2 73_ = something'else', 2
74something"else", 2 74_ = something"else", 2
75something[[else]], 2 75_ = something[[else]], 2
76 76
77something 'else', 2 77something 'else', 2
78something "else", 2 78something "else", 2
79something [[else]], 2 79something [[else]], 2
80 80
81here(we)"go"[12123] 81_ = here(we)"go"[12123]
82 82
83-- this runs 83-- this runs
84something = 84something =
@@ -120,9 +120,9 @@ print "hello" for i=1,10
120 120
121print "nutjob" 121print "nutjob"
122 122
123if hello then 343 123if hello then _ = 343
124 124
125print "what" if cool else whack 125print "what" if cool else whack!
126 126
127arg = {...} 127arg = {...}
128 128
@@ -139,7 +139,7 @@ y = #"hello"
139 139
140x = #{#{},#{1},#{1,2}} 140x = #{#{},#{1},#{1,2}}
141 141
142hello, world 142_ = hello, world
143 143
144something\hello(what) a,b 144something\hello(what) a,b
145something\hello what 145something\hello what
@@ -163,7 +163,7 @@ a["hello#{tostring ff}"] += 10
163a[four].x += 10 163a[four].x += 10
164 164
165x = 0 165x = 0
166(if ntype(v) == "fndef" then x += 1) for v in *values 166_ = (if ntype(v) == "fndef" then x += 1) for v in *values
167 167
168 168
169hello = 169hello =
@@ -176,10 +176,10 @@ hello =
176 176
177div class: "cool" 177div class: "cool"
178 178
1795 + what wack 179_ = 5 + what wack
180what whack + 5 180what whack + 5
181 181
1825 - what wack 182_ = 5 - what wack
183what whack - 5 183what whack - 5
184 184
185x = hello - world - something 185x = hello - world - something
@@ -189,16 +189,16 @@ x = hello - world - something
189 print something)! 189 print something)!
190 190
191if something 191if something
192 03589 192 _ = 03589
193 193
194-- okay what about this 194-- okay what about this
195 195
196else 196else
197 3434 197 _ = 3434
198 198
199 199
200if something 200if something
201 yeah 201 _ = yeah
202 202
203 203
204elseif "ymmm" 204elseif "ymmm"
@@ -207,7 +207,7 @@ elseif "ymmm"
207 207
208else 208else
209 209
210 okay 210 _ = okay
211 211
212 212
213-- test names containing keywords 213-- test names containing keywords
diff --git a/spec/inputs/tables.moon b/spec/inputs/tables.moon
index 2bf66d7..10bccde 100644
--- a/spec/inputs/tables.moon
+++ b/spec/inputs/tables.moon
@@ -138,7 +138,7 @@ thing what:
138thing what: 138thing what:
139 "great", no: 139 "great", no:
140 "more" 140 "more"
141okay: 123 -- a anon table 141_ = okay: 123 -- a anon table
142 142
143 143
144-- 144--
diff --git a/spec/inputs/using.moon b/spec/inputs/using.moon
index 55a16a7..e407983 100644
--- a/spec/inputs/using.moon
+++ b/spec/inputs/using.moon
@@ -2,18 +2,18 @@
2hello = "hello" 2hello = "hello"
3world = "world" 3world = "world"
4 4
5(using nil) -> 5_ = (using nil) ->
6 hello = 3223 6 hello = 3223
7 7
8(a using nil) -> 8_ = (a using nil) ->
9 hello = 3223 9 hello = 3223
10 a = 323 10 a = 323
11 11
12(a,b,c using a,b,c) -> 12_ = (a,b,c using a,b,c) ->
13 a,b,c = 1,2,3 13 a,b,c = 1,2,3
14 world = 12321 14 world = 12321
15 15
16(a,e,f using a,b,c, hello) -> 16_ = (a,e,f using a,b,c, hello) ->
17 a,b,c = 1,2,3 17 a,b,c = 1,2,3
18 hello = 12321 18 hello = 12321
19 world = "yeah" 19 world = "yeah"
diff --git a/spec/inputs/whitespace.moon b/spec/inputs/whitespace.moon
index 4a2ff1f..e505b1b 100644
--- a/spec/inputs/whitespace.moon
+++ b/spec/inputs/whitespace.moon
@@ -1,42 +1,42 @@
1 1
2{ 2_ = {
3 1, 2 3 1, 2
4} 4}
5 5
6{ 1, 2 6_ = { 1, 2
7} 7}
8 8
9{ 1, 2 } 9_ = { 1, 2 }
10 10
11{1,2} 11_ = {1,2}
12 12
13{ 13_ = {
141,2 141,2
15 15
16} 16}
17 17
18{ something 1,2, 18_ = { something 1,2,
19 4,5,6, 19 4,5,6,
20 3,4,5 20 3,4,5
21} 21}
22 22
23{ 23_ = {
24 a 1,2,3, 24 a 1,2,3,
25 4,5,6 25 4,5,6
26 1,2,3 26 1,2,3
27} 27}
28 28
29 29
30{ 30_ = {
31 b 1,2,3, 31 b 1,2,3,
32 4,5,6 32 4,5,6
33 1,2,3, 33 1,2,3,
34 1,2,3 34 1,2,3
35} 35}
36 36
37{ 1,2,3 } 37_ = { 1,2,3 }
38 38
39{ c 1,2,3, 39_ = { c 1,2,3,
40} 40}
41 41
42 42
@@ -58,7 +58,7 @@ hello 1,2,3,
58 9,9 58 9,9
59 59
60 60
61{ 61_ = {
62 hello 1,2, 62 hello 1,2,
63 3,4, 63 3,4,
64 5, 6 64 5, 6
diff --git a/spec/inputs/with.moon b/spec/inputs/with.moon
index ae3c8c0..f543356 100644
--- a/spec/inputs/with.moon
+++ b/spec/inputs/with.moon
@@ -37,7 +37,7 @@ do
37 37
38do 38do
39 with foo 39 with foo
40 \prop"something".hello 40 _ = \prop"something".hello
41 .prop\send(one) 41 .prop\send(one)
42 .prop\send one 42 .prop\send one
43 43
@@ -107,7 +107,7 @@ do
107 print .c 107 print .c
108 108
109do 109do
110 -> 110 _ = ->
111 with hi 111 with hi
112 return .a, .b 112 return .a, .b
113 113
diff --git a/src/MoonP/ast.hpp b/src/MoonP/ast.hpp
index f2ef76c..0b5ffca 100644
--- a/src/MoonP/ast.hpp
+++ b/src/MoonP/ast.hpp
@@ -392,6 +392,12 @@ public:
392 node->release(); 392 node->release();
393 } 393 }
394 394
395 void pop_back() {
396 auto node = m_objects.back();
397 m_objects.pop_back();
398 node->release();
399 }
400
395 const node_container& objects() const { 401 const node_container& objects() const {
396 return m_objects; 402 return m_objects;
397 } 403 }
diff --git a/src/MoonP/moon_ast.cpp b/src/MoonP/moon_ast.cpp
index 0ccd0ed..f3fe31e 100644
--- a/src/MoonP/moon_ast.cpp
+++ b/src/MoonP/moon_ast.cpp
@@ -79,6 +79,7 @@ AST_IMPL(ColonChainItem)
79AST_IMPL(default_value) 79AST_IMPL(default_value)
80AST_IMPL(Slice) 80AST_IMPL(Slice)
81AST_IMPL(Invoke) 81AST_IMPL(Invoke)
82AST_IMPL(existential_op)
82AST_IMPL(TableLit) 83AST_IMPL(TableLit)
83AST_IMPL(TableBlock) 84AST_IMPL(TableBlock)
84AST_IMPL(class_member_list) 85AST_IMPL(class_member_list)
diff --git a/src/MoonP/moon_ast.h b/src/MoonP/moon_ast.h
index a614465..8b80af3 100644
--- a/src/MoonP/moon_ast.h
+++ b/src/MoonP/moon_ast.h
@@ -407,11 +407,14 @@ AST_NODE(Invoke, "Invoke"_id)
407 AST_MEMBER(Invoke, &sep, &args) 407 AST_MEMBER(Invoke, &sep, &args)
408AST_END(Invoke) 408AST_END(Invoke)
409 409
410AST_LEAF(existential_op, "existential_op"_id)
411AST_END(existential_op)
412
410class InvokeArgs_t; 413class InvokeArgs_t;
411 414
412AST_NODE(ChainValue, "ChainValue"_id) 415AST_NODE(ChainValue, "ChainValue"_id)
413 ast_ptr<true, Seperator_t> sep; 416 ast_ptr<true, Seperator_t> sep;
414 ast_sel_list<true, Callable_t, Invoke_t, DotChainItem_t, ColonChainItem_t, Slice_t, Exp_t, String_t, InvokeArgs_t> items; 417 ast_sel_list<true, Callable_t, Invoke_t, DotChainItem_t, ColonChainItem_t, Slice_t, Exp_t, String_t, InvokeArgs_t, existential_op_t> items;
415 AST_MEMBER(ChainValue, &sep, &items) 418 AST_MEMBER(ChainValue, &sep, &items)
416AST_END(ChainValue) 419AST_END(ChainValue)
417 420
diff --git a/src/MoonP/moon_compiler.cpp b/src/MoonP/moon_compiler.cpp
index d30f413..9164f6a 100644
--- a/src/MoonP/moon_compiler.cpp
+++ b/src/MoonP/moon_compiler.cpp
@@ -15,6 +15,7 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
15#include <memory> 15#include <memory>
16#include <sstream> 16#include <sstream>
17#include <string_view> 17#include <string_view>
18#include <iostream>
18using namespace std::string_view_literals; 19using namespace std::string_view_literals;
19#include "MoonP/parser.hpp" 20#include "MoonP/parser.hpp"
20#include "MoonP/moon_ast.h" 21#include "MoonP/moon_ast.h"
@@ -426,6 +427,35 @@ private:
426 return ast_is<InvokeArgs_t, Invoke_t>(chainValue->items.back()); 427 return ast_is<InvokeArgs_t, Invoke_t>(chainValue->items.back());
427 } 428 }
428 429
430 bool isSpecialChainValue(ChainValue_t* chainValue) {
431 if (ast_is<ColonChainItem_t>(chainValue->items.back())) {
432 return true;
433 }
434 for (auto item : chainValue->items.objects()) {
435 if (auto colonChain = ast_cast<ColonChainItem_t>(item)) {
436 if (ast_is<LuaKeyword_t>(colonChain->name)) {
437 return true;
438 }
439 } else if (ast_is<existential_op_t>(item) && item != chainValue->items.back()) {
440 return true;
441 }
442 }
443 return false;
444 }
445
446 std::string singleVariableFrom(ChainValue_t* chainValue) {
447 BLOCK_START
448 BREAK_IF(!chainValue);
449 BREAK_IF(chainValue->items.size() != 1);
450 auto callable = ast_cast<Callable_t>(chainValue->items.front());
451 BREAK_IF(!callable || !(callable->item.is<Variable_t>() || callable->getByPath<SelfName_t,self_t>()));
452 str_list tmp;
453 transformCallable(callable, tmp);
454 return tmp.back();
455 BLOCK_END
456 return Empty;
457 }
458
429 std::string singleVariableFrom(ast_node* expList) { 459 std::string singleVariableFrom(ast_node* expList) {
430 if (!ast_is<Exp_t, ExpList_t>(expList)) return Empty; 460 if (!ast_is<Exp_t, ExpList_t>(expList)) return Empty;
431 BLOCK_START 461 BLOCK_START
@@ -435,7 +465,7 @@ private:
435 BREAK_IF(!chainValue); 465 BREAK_IF(!chainValue);
436 BREAK_IF(chainValue->items.size() != 1); 466 BREAK_IF(chainValue->items.size() != 1);
437 auto callable = ast_cast<Callable_t>(chainValue->items.front()); 467 auto callable = ast_cast<Callable_t>(chainValue->items.front());
438 BREAK_IF(!callable || !callable->item.is<Variable_t>()); 468 BREAK_IF(!callable || !(callable->item.is<Variable_t>() || callable->getByPath<SelfName_t,self_t>()));
439 str_list tmp; 469 str_list tmp;
440 transformCallable(callable, tmp); 470 transformCallable(callable, tmp);
441 return tmp.back(); 471 return tmp.back();
@@ -443,22 +473,6 @@ private:
443 return Empty; 473 return Empty;
444 } 474 }
445 475
446 bool isColonChain(ChainValue_t* chainValue) {
447 return ast_is<ColonChainItem_t>(chainValue->items.back());
448 }
449
450 bool hasKeywordColonChainItem(ChainValue_t* chainValue) {
451 const auto& chainList = chainValue->items.objects();
452 for (auto it = chainList.begin(); it != chainList.end(); ++it) {
453 if (auto colonItem = ast_cast<ColonChainItem_t>(*it)) {
454 if (colonItem->name.is<LuaKeyword_t>()) {
455 return true;
456 }
457 }
458 }
459 return false;
460 }
461
462 bool isAssignable(const node_container& chainItems) { 476 bool isAssignable(const node_container& chainItems) {
463 if (chainItems.size() == 1) { 477 if (chainItems.size() == 1) {
464 auto firstItem = chainItems.back(); 478 auto firstItem = chainItems.back();
@@ -539,7 +553,7 @@ private:
539 } 553 }
540 auto line = _converter.to_bytes(std::wstring(begin, end)); 554 auto line = _converter.to_bytes(std::wstring(begin, end));
541 int oldCol = loc->m_begin.m_col; 555 int oldCol = loc->m_begin.m_col;
542 int col = loc->m_begin.m_col - 1; 556 int col = std::max(0, oldCol - 1);
543 auto it = begin; 557 auto it = begin;
544 for (int i = 0; i < oldCol; ++i) { 558 for (int i = 0; i < oldCol; ++i) {
545 if (*it > ASCII) { 559 if (*it > ASCII) {
@@ -558,7 +572,7 @@ private:
558 auto x = statement; 572 auto x = statement;
559 if (statement->appendix) { 573 if (statement->appendix) {
560 if (auto assignment = assignmentFrom(statement)) { 574 if (auto assignment = assignmentFrom(statement)) {
561 auto preDefine = getPredefine(transformAssignDefs(assignment->expList)); 575 auto preDefine = getPredefine(assignment);
562 if (!preDefine.empty()) out.push_back(preDefine + nll(statement)); 576 if (!preDefine.empty()) out.push_back(preDefine + nll(statement));
563 } 577 }
564 auto appendix = statement->appendix.get(); 578 auto appendix = statement->appendix.get();
@@ -790,7 +804,7 @@ private:
790 } 804 }
791 805
792 std::string getDestrucureDefine(ExpListAssign_t* assignment) { 806 std::string getDestrucureDefine(ExpListAssign_t* assignment) {
793 auto info = extractDestructureInfo(assignment); 807 auto info = extractDestructureInfo(assignment, true);
794 if (!info.first.empty()) { 808 if (!info.first.empty()) {
795 for (const auto& destruct : info.first) { 809 for (const auto& destruct : info.first) {
796 str_list defs; 810 str_list defs;
@@ -909,11 +923,10 @@ private:
909 } 923 }
910 case "With"_id: { 924 case "With"_id: {
911 auto withNode = static_cast<With_t*>(value); 925 auto withNode = static_cast<With_t*>(value);
912 str_list temp;
913 auto expList = assignment->expList.get(); 926 auto expList = assignment->expList.get();
914 std::string preDefine = getPredefine(assignment); 927 std::string preDefine = getPredefine(assignment);
915 transformWith(withNode, temp, expList); 928 transformWith(withNode, out, expList);
916 out.push_back(preDefine + temp.back()); 929 out.back() = preDefine + out.back();
917 return; 930 return;
918 } 931 }
919 case "Do"_id: { 932 case "Do"_id: {
@@ -940,50 +953,42 @@ private:
940 return; 953 return;
941 } 954 }
942 case "For"_id: { 955 case "For"_id: {
943 str_list temp;
944 auto expList = assignment->expList.get(); 956 auto expList = assignment->expList.get();
945 std::string preDefine = getPredefine(assignment); 957 std::string preDefine = getPredefine(assignment);
946 transformForInPlace(static_cast<For_t*>(value), temp, expList); 958 transformForInPlace(static_cast<For_t*>(value), out, expList);
947 out.push_back(preDefine + temp.back()); 959 out.back() = preDefine + out.back();
948 return; 960 return;
949 } 961 }
950 case "ForEach"_id: { 962 case "ForEach"_id: {
951 str_list temp;
952 auto expList = assignment->expList.get(); 963 auto expList = assignment->expList.get();
953 std::string preDefine = getPredefine(assignment); 964 std::string preDefine = getPredefine(assignment);
954 transformForEachInPlace(static_cast<ForEach_t*>(value), temp, expList); 965 transformForEachInPlace(static_cast<ForEach_t*>(value), out, expList);
955 out.push_back(preDefine + temp.back()); 966 out.back() = preDefine + out.back();
956 return; 967 return;
957 } 968 }
958 case "ClassDecl"_id: { 969 case "ClassDecl"_id: {
959 str_list temp;
960 auto expList = assignment->expList.get(); 970 auto expList = assignment->expList.get();
961 std::string preDefine = getPredefine(assignment); 971 std::string preDefine = getPredefine(assignment);
962 transformClassDecl(static_cast<ClassDecl_t*>(value), temp, ExpUsage::Assignment, expList); 972 transformClassDecl(static_cast<ClassDecl_t*>(value), out, ExpUsage::Assignment, expList);
963 out.push_back(preDefine + temp.back()); 973 out.back() = preDefine + out.back();
964 return; 974 return;
965 } 975 }
966 case "While"_id: { 976 case "While"_id: {
967 str_list temp;
968 auto expList = assignment->expList.get(); 977 auto expList = assignment->expList.get();
969 std::string preDefine = getPredefine(assignment); 978 std::string preDefine = getPredefine(assignment);
970 transformWhileInPlace(static_cast<While_t*>(value), temp, expList); 979 transformWhileInPlace(static_cast<While_t*>(value), out, expList);
971 out.push_back(preDefine + temp.back()); 980 out.back() = preDefine + out.back();
972 return; 981 return;
973 } 982 }
974 } 983 }
975 auto exp = ast_cast<Exp_t>(value); 984 auto exp = ast_cast<Exp_t>(value);
976 BREAK_IF(!exp); 985 BREAK_IF(!exp);
977 if (auto chainValue = exp->value->item.as<ChainValue_t>()) { 986 if (auto chainValue = exp->value->item.as<ChainValue_t>()) {
978 if (isColonChain(chainValue)) { 987 if (isSpecialChainValue(chainValue)) {
979 auto assignable = assignment->expList.get(); 988 auto expList = assignment->expList.get();
980 std::string preDefine = getPredefine(transformAssignDefs(assignable)); 989 std::string preDefine = getPredefine(assignment);
981 transformColonChain(chainValue, out, ExpUsage::Assignment, assignable); 990 transformChainValue(chainValue, out, ExpUsage::Assignment, expList);
982 auto nl = preDefine.empty() ? Empty : nll(chainValue); 991 out.back() = preDefine + out.back();
983 if (!preDefine.empty()) out.back() = preDefine + nl + out.back();
984 return;
985 } else if (hasKeywordColonChainItem(chainValue)) {
986 transformChainValue(chainValue, out, ExpUsage::Assignment, assignment->expList);
987 return; 992 return;
988 } 993 }
989 } 994 }
@@ -1169,7 +1174,7 @@ private:
1169 } 1174 }
1170 1175
1171 std::pair<std::list<Destructure>, ast_ptr<false, ExpListAssign_t>> 1176 std::pair<std::list<Destructure>, ast_ptr<false, ExpListAssign_t>>
1172 extractDestructureInfo(ExpListAssign_t* assignment) { 1177 extractDestructureInfo(ExpListAssign_t* assignment, bool varDefOnly = false) {
1173 auto x = assignment; 1178 auto x = assignment;
1174 std::list<Destructure> destructs; 1179 std::list<Destructure> destructs;
1175 if (!assignment->action.is<Assign_t>()) return { destructs, nullptr }; 1180 if (!assignment->action.is<Assign_t>()) return { destructs, nullptr };
@@ -1187,19 +1192,21 @@ private:
1187 while (values.size() < size) values.emplace_back(nullNode); 1192 while (values.size() < size) values.emplace_back(nullNode);
1188 } 1193 }
1189 using iter = node_container::iterator; 1194 using iter = node_container::iterator;
1190 std::vector<std::pair<iter, iter>> destructPairs; 1195 std::vector<std::pair<iter,iter>> destructPairs;
1191 str_list temp; 1196 str_list temp;
1192 for (auto i = exprs.begin(), j = values.begin(); i != exprs.end(); ++i, ++j) { 1197 for (auto i = exprs.begin(), j = values.begin(); i != exprs.end(); ++i, ++j) {
1193 auto expr = *i; 1198 auto expr = *i;
1194 ast_node* destructNode = expr->getByPath<Value_t, SimpleValue_t, TableLit_t>(); 1199 ast_node* destructNode = expr->getByPath<Value_t, SimpleValue_t, TableLit_t>();
1195 if (destructNode || (destructNode = expr->getByPath<Value_t, simple_table_t>())) { 1200 if (destructNode || (destructNode = expr->getByPath<Value_t, simple_table_t>())) {
1196 destructPairs.push_back({i,j}); 1201 destructPairs.push_back({i,j});
1197 pushScope();
1198 transformAssignItem(*j, temp);
1199 popScope();
1200 auto& destruct = destructs.emplace_back(); 1202 auto& destruct = destructs.emplace_back();
1201 destruct.value = temp.back(); 1203 if (!varDefOnly) {
1202 temp.pop_back(); 1204 pushScope();
1205 transformAssignItem(*j, temp);
1206 destruct.value = temp.back();
1207 temp.pop_back();
1208 popScope();
1209 }
1203 auto pairs = destructFromExp(expr); 1210 auto pairs = destructFromExp(expr);
1204 destruct.items = std::move(pairs); 1211 destruct.items = std::move(pairs);
1205 } 1212 }
@@ -1244,7 +1251,7 @@ private:
1244 BREAK_IF(!exp); 1251 BREAK_IF(!exp);
1245 auto var = singleVariableFrom(exp); 1252 auto var = singleVariableFrom(exp);
1246 BREAK_IF(!var.empty()); 1253 BREAK_IF(!var.empty());
1247 auto upVar = getUnusedName("_update_"); 1254 auto upVar = getUnusedName("_update_"sv);
1248 auto assignment = x->new_ptr<ExpListAssign_t>(); 1255 auto assignment = x->new_ptr<ExpListAssign_t>();
1249 assignment->expList.set(toAst<ExpList_t>(upVar, ExpList, x)); 1256 assignment->expList.set(toAst<ExpList_t>(upVar, ExpList, x));
1250 auto assign = x->new_ptr<Assign_t>(); 1257 auto assign = x->new_ptr<Assign_t>();
@@ -1532,11 +1539,7 @@ private:
1532 case "simple_table"_id: transform_simple_table(static_cast<simple_table_t*>(item), out); break; 1539 case "simple_table"_id: transform_simple_table(static_cast<simple_table_t*>(item), out); break;
1533 case "ChainValue"_id: { 1540 case "ChainValue"_id: {
1534 auto chainValue = static_cast<ChainValue_t*>(item); 1541 auto chainValue = static_cast<ChainValue_t*>(item);
1535 if (isColonChain(chainValue)) { 1542 transformChainValue(chainValue, out);
1536 transformColonChainClosure(chainValue, out);
1537 } else {
1538 transformChainValue(chainValue, out);
1539 }
1540 break; 1543 break;
1541 } 1544 }
1542 case "String"_id: transformString(static_cast<String_t*>(item), out); break; 1545 case "String"_id: transformString(static_cast<String_t*>(item), out); break;
@@ -1689,7 +1692,7 @@ private:
1689 any->decls.push_back(var); 1692 any->decls.push_back(var);
1690 } 1693 }
1691 } 1694 }
1692 auto info = extractDestructureInfo(assignment); 1695 auto info = extractDestructureInfo(assignment, true);
1693 if (!info.first.empty()) { 1696 if (!info.first.empty()) {
1694 for (const auto& destruct : info.first) 1697 for (const auto& destruct : info.first)
1695 for (const auto& item : destruct.items) 1698 for (const auto& item : destruct.items)
@@ -1803,12 +1806,10 @@ private:
1803 } 1806 }
1804 } 1807 }
1805 if (auto chainValue = singleValue->item.as<ChainValue_t>()) { 1808 if (auto chainValue = singleValue->item.as<ChainValue_t>()) {
1806 if (isColonChain(chainValue)) { 1809 if (isSpecialChainValue(chainValue)) {
1807 transformColonChain(chainValue, out, ExpUsage::Return);
1808 } else {
1809 transformChainValue(chainValue, out, ExpUsage::Return); 1810 transformChainValue(chainValue, out, ExpUsage::Return);
1811 return;
1810 } 1812 }
1811 return;
1812 } 1813 }
1813 transformValue(singleValue, out); 1814 transformValue(singleValue, out);
1814 out.back() = indent() + s("return "sv) + out.back() + nlr(returnNode); 1815 out.back() = indent() + s("return "sv) + out.back() + nlr(returnNode);
@@ -1980,111 +1981,292 @@ private:
1980 } 1981 }
1981 } 1982 }
1982 1983
1983 void transformColonChainClosure(ChainValue_t* chainValue, str_list& out) { 1984 bool transformChainEndWithEOP(const node_container& chainList, str_list& out, ExpUsage usage, ExpList_t*) {
1984 str_list temp; 1985 auto x = chainList.front();
1985 temp.push_back(s("(function()"sv) + nll(chainValue)); 1986 if (ast_cast<existential_op_t>(chainList.back())) {
1986 pushScope(); 1987 auto parens = x->new_ptr<Parens_t>();
1987 transformColonChain(chainValue, temp, ExpUsage::Return); 1988 {
1988 popScope(); 1989 auto chainValue = x->new_ptr<ChainValue_t>();
1989 temp.push_back(indent() + s("end)()"sv)); 1990 for (auto item : chainList) {
1990 out.push_back(join(temp)); 1991 chainValue->items.push_back(item);
1992 }
1993 chainValue->items.pop_back();
1994 auto value = x->new_ptr<Value_t>();
1995 value->item.set(chainValue);
1996 auto opValue = x->new_ptr<exp_op_value_t>();
1997 opValue->op.set(toAst<BinaryOperator_t>("!="sv, BinaryOperator, x));
1998 opValue->value.set(toAst<Value_t>("nil"sv, Value, x));
1999 auto exp = x->new_ptr<Exp_t>();
2000 exp->value.set(value);
2001 exp->opValues.push_back(opValue);
2002 parens->expr.set(exp);
2003 }
2004 transformParens(parens, out);
2005 if (usage == ExpUsage::Return) {
2006 out.back().insert(0, indent() + s("return "sv));
2007 out.back().append(nlr(x));
2008 }
2009 return true;
2010 }
2011 return false;
1991 } 2012 }
1992 2013
1993 void transformColonChain(ChainValue_t* chainValue, str_list& out, ExpUsage usage = ExpUsage::Common, ExpList_t* expList = nullptr) { 2014 bool transformChainWithEOP(const node_container& chainList, str_list& out, ExpUsage usage, ExpList_t* assignList) {
1994 auto x = chainValue; 2015 auto opIt = std::find_if(chainList.begin(), chainList.end(), [](ast_node* node) { return ast_is<existential_op_t>(node); });
1995 const auto& chainList = chainValue->items.objects(); 2016 if (opIt != chainList.end()) {
1996 auto baseChain = x->new_ptr<ChainValue_t>(); 2017 auto x = chainList.front();
1997 switch (chainList.front()->getId()) { 2018 str_list temp;
1998 case "DotChainItem"_id: 2019 if (usage == ExpUsage::Closure) {
1999 case "ColonChainItem"_id: 2020 temp.push_back(s("(function()"sv) + nll(x));
2000 if (_withVars.empty()) { 2021 pushScope();
2001 throw std::logic_error(debugInfo("Short dot/colon syntax must be called within a with block."sv, chainList.front())); 2022 }
2002 } else { 2023 auto partOne = x->new_ptr<ChainValue_t>();
2003 baseChain->items.push_back(toAst<Callable_t>(_withVars.top(), Callable, x)); 2024 for (auto it = chainList.begin();it != opIt;++it) {
2004 } 2025 partOne->items.push_back(*it);
2026 }
2027 BLOCK_START
2028 auto back = ast_cast<Callable_t>(partOne->items.back());
2029 BREAK_IF(!back);
2030 auto selfName = ast_cast<SelfName_t>(back->item);
2031 BREAK_IF(!selfName);
2032 if (auto sname = ast_cast<self_name_t>(selfName->name)) {
2033 auto colonItem = x->new_ptr<ColonChainItem_t>();
2034 colonItem->name.set(sname->name);
2035 partOne->items.pop_back();
2036 partOne->items.push_back(toAst<Callable_t>("@"sv, Callable, x));
2037 partOne->items.push_back(colonItem);
2005 break; 2038 break;
2006 } 2039 }
2007 auto end = --chainList.end(); 2040 if (auto cname = ast_cast<self_class_name_t>(selfName->name)) {
2008 for (auto it = chainList.begin(); it != end; ++it) { 2041 auto colonItem = x->new_ptr<ColonChainItem_t>();
2009 baseChain->items.push_back(*it); 2042 colonItem->name.set(cname->name);
2010 } 2043 partOne->items.pop_back();
2011 auto colonChainItem = static_cast<ColonChainItem_t*>(chainList.back()); 2044 partOne->items.push_back(toAst<Callable_t>("@@"sv, Callable, x));
2012 auto funcName = toString(colonChainItem->name); 2045 partOne->items.push_back(colonItem);
2013 if (usage != ExpUsage::Return) pushScope();
2014 auto baseVar = getUnusedName("_base_"sv);
2015 auto fnVar = getUnusedName("_fn_"sv);
2016 str_list temp;
2017 {
2018 auto value = x->new_ptr<Value_t>();
2019 value->item.set(baseChain);
2020 auto exp = x->new_ptr<Exp_t>();
2021 exp->value.set(value);
2022 auto assign = x->new_ptr<Assign_t>();
2023 assign->values.push_back(exp);
2024 auto assignment = x->new_ptr<ExpListAssign_t>();
2025 assignment->expList.set(toAst<ExpList_t>(baseVar, ExpList, x));
2026 assignment->action.set(assign);
2027 transformAssignment(assignment, temp);
2028 }
2029 {
2030 auto assign = x->new_ptr<Assign_t>();
2031 assign->values.push_back(toAst<Exp_t>(baseVar + "." + funcName, Exp, x));
2032 auto assignment = x->new_ptr<ExpListAssign_t>();
2033 assignment->expList.set(toAst<ExpList_t>(fnVar, ExpList, x));
2034 assignment->action.set(assign);
2035 transformAssignment(assignment, temp);
2036 }
2037 auto funLit = toAst<Exp_t>(s("(...)-> "sv) + fnVar + s(" "sv) + baseVar + s(", ..."sv), Exp, x);
2038 switch (usage) {
2039 case ExpUsage::Return:
2040 transformExp(funLit, temp);
2041 _buf << temp.front();
2042 _buf << *(++temp.begin());
2043 _buf << indent() << "return " << temp.back() << nll(chainValue);
2044 break; 2046 break;
2045 case ExpUsage::Assignment: { 2047 }
2048 BLOCK_END
2049 auto objVar = singleVariableFrom(partOne);
2050 if (objVar.empty()) {
2051 objVar = getUnusedName("_obj_"sv);
2052 if (auto colonItem = ast_cast<ColonChainItem_t>(partOne->items.back())) {
2053 auto chainValue = x->new_ptr<ChainValue_t>();
2054 chainValue->items.dup(partOne->items);
2055 chainValue->items.pop_back();
2056 if (chainValue->items.empty()) {
2057 if (_withVars.empty()) {
2058 throw std::logic_error(debugInfo("Short dot/colon syntax must be called within a with block."sv, x));
2059 }
2060 chainValue->items.push_back(toAst<Callable_t>(_withVars.top(), Callable, x));
2061 }
2062 auto newObj = singleVariableFrom(chainValue);
2063 if (!newObj.empty()) {
2064 objVar = newObj;
2065 } else {
2066 auto value = x->new_ptr<Value_t>();
2067 value->item.set(chainValue);
2068 auto exp = x->new_ptr<Exp_t>();
2069 exp->value.set(value);
2070 auto assign = x->new_ptr<Assign_t>();
2071 assign->values.push_back(exp);
2072 auto expListAssign = x->new_ptr<ExpListAssign_t>();
2073 expListAssign->expList.set(toAst<ExpList_t>(objVar, ExpList, x));
2074 expListAssign->action.set(assign);
2075 transformAssignment(expListAssign, temp);
2076 }
2077 auto dotItem = x->new_ptr<DotChainItem_t>();
2078 auto name = colonItem->name.get();
2079 if (auto keyword = ast_cast<LuaKeyword_t>(name)) {
2080 name = keyword->name.get();
2081 }
2082 dotItem->name.set(name);
2083 partOne->items.clear();
2084 partOne->items.push_back(toAst<Callable_t>(objVar, Callable, x));
2085 partOne->items.push_back(dotItem);
2086 auto it = opIt; ++it;
2087 if (it != chainList.end() && ast_is<Invoke_t, InvokeArgs_t>(*it)) {
2088
2089 if (auto invoke = ast_cast<Invoke_t>(*it)) {
2090 invoke->args.push_front(toAst<Exp_t>(objVar, Exp, x));
2091 } else {
2092 auto invokeArgs = static_cast<InvokeArgs_t*>(*it);
2093 invokeArgs->args.push_front(toAst<Exp_t>(objVar, Exp, x));
2094 }
2095 }
2096 objVar = getUnusedName("_obj_"sv);
2097 }
2098 auto value = x->new_ptr<Value_t>();
2099 value->item.set(partOne);
2100 auto exp = x->new_ptr<Exp_t>();
2101 exp->value.set(value);
2102 auto assign = x->new_ptr<Assign_t>();
2103 assign->values.push_back(exp);
2104 auto expListAssign = x->new_ptr<ExpListAssign_t>();
2105 expListAssign->expList.set(toAst<ExpList_t>(objVar, ExpList, x));
2106 expListAssign->action.set(assign);
2107 transformAssignment(expListAssign, temp);
2108 }
2109 _buf << indent() << "if "sv << objVar << " ~= nil then"sv << nll(x);
2110 temp.push_back(clearBuf());
2111 pushScope();
2112 auto partTwo = x->new_ptr<ChainValue_t>();
2113 partTwo->items.push_back(toAst<Callable_t>(objVar, Callable, x));
2114 for (auto it = ++opIt;it != chainList.end();++it) {
2115 partTwo->items.push_back(*it);
2116 }
2117 switch (usage) {
2118 case ExpUsage::Common:
2119 transformChainValue(partTwo, temp, ExpUsage::Common);
2120 break;
2121 case ExpUsage::Assignment: {
2122 auto value = x->new_ptr<Value_t>();
2123 value->item.set(partTwo);
2124 auto exp = x->new_ptr<Exp_t>();
2125 exp->value.set(value);
2126 auto assign = x->new_ptr<Assign_t>();
2127 assign->values.push_back(exp);
2128 auto assignment = x->new_ptr<ExpListAssign_t>();
2129 assignment->expList.set(assignList);
2130 assignment->action.set(assign);
2131 transformAssignment(assignment, temp);
2132 break;
2133 }
2134 case ExpUsage::Return:
2135 case ExpUsage::Closure: {
2136 auto value = x->new_ptr<Value_t>();
2137 value->item.set(partTwo);
2138 auto exp = x->new_ptr<Exp_t>();
2139 exp->value.set(value);
2140 auto ret = x->new_ptr<Return_t>();
2141 auto expListLow = x->new_ptr<ExpListLow_t>();
2142 expListLow->exprs.push_back(exp);
2143 ret->valueList.set(expListLow);
2144 transformReturn(ret, temp);
2145 break;
2146 }
2147 }
2148 popScope();
2149 temp.push_back(indent() + s("end"sv) + nlr(x));
2150 switch (usage) {
2151 case ExpUsage::Return:
2152 temp.push_back(indent() + s("return nil"sv) + nlr(x));
2153 break;
2154 case ExpUsage::Closure:
2155 temp.push_back(indent() + s("return nil"sv) + nlr(x));
2156 popScope();
2157 temp.push_back(indent() + s("end)()"sv));
2158 break;
2159 default:
2160 break;
2161 }
2162 out.push_back(join(temp));
2163 return true;
2164 }
2165 return false;
2166 }
2167
2168 bool transformChainEndWithColonItem(const node_container& chainList, str_list& out, ExpUsage usage, ExpList_t* assignList) {
2169 if (ast_is<ColonChainItem_t>(chainList.back())) {
2170 auto x = chainList.front();
2171 str_list temp;
2172 switch (usage) {
2173 case ExpUsage::Assignment:
2174 temp.push_back(indent() + s("do"sv) + nll(x));
2175 pushScope();
2176 break;
2177 case ExpUsage::Closure:
2178 temp.push_back(s("(function()"sv) + nll(x));
2179 pushScope();
2180 break;
2181 default:
2182 break;
2183 }
2184 auto baseChain = x->new_ptr<ChainValue_t>();
2185 switch (chainList.front()->getId()) {
2186 case "DotChainItem"_id:
2187 case "ColonChainItem"_id:
2188 if (_withVars.empty()) {
2189 throw std::logic_error(debugInfo("Short dot/colon syntax must be called within a with block."sv, chainList.front()));
2190 } else {
2191 baseChain->items.push_back(toAst<Callable_t>(_withVars.top(), Callable, x));
2192 }
2193 break;
2194 }
2195 auto end = --chainList.end();
2196 for (auto it = chainList.begin(); it != end; ++it) {
2197 baseChain->items.push_back(*it);
2198 }
2199 auto colonChainItem = static_cast<ColonChainItem_t*>(chainList.back());
2200 auto funcName = toString(colonChainItem->name);
2201 auto baseVar = getUnusedName("_base_"sv);
2202 auto fnVar = getUnusedName("_fn_"sv);
2203 {
2204 auto value = x->new_ptr<Value_t>();
2205 value->item.set(baseChain);
2206 auto exp = x->new_ptr<Exp_t>();
2207 exp->value.set(value);
2046 auto assign = x->new_ptr<Assign_t>(); 2208 auto assign = x->new_ptr<Assign_t>();
2047 assign->values.push_back(funLit); 2209 assign->values.push_back(exp);
2048 auto assignment = x->new_ptr<ExpListAssign_t>(); 2210 auto assignment = x->new_ptr<ExpListAssign_t>();
2049 assignment->expList.set(expList); 2211 assignment->expList.set(toAst<ExpList_t>(baseVar, ExpList, x));
2050 assignment->action.set(assign); 2212 assignment->action.set(assign);
2051 transformAssignment(assignment, temp); 2213 transformAssignment(assignment, temp);
2052 _buf << indent(-1) << "do"sv << nll(chainValue);
2053 _buf << temp.front();
2054 _buf << *(++temp.begin());
2055 _buf << temp.back();
2056 popScope();
2057 _buf << indent() << "end"sv << nll(chainValue);
2058 break;
2059 } 2214 }
2060 case ExpUsage::Common: { 2215 {
2061 auto assign = x->new_ptr<Assign_t>(); 2216 auto assign = x->new_ptr<Assign_t>();
2062 assign->values.push_back(funLit); 2217 assign->values.push_back(toAst<Exp_t>(baseVar + "." + funcName, Exp, x));
2063 auto assignment = x->new_ptr<ExpListAssign_t>(); 2218 auto assignment = x->new_ptr<ExpListAssign_t>();
2064 assignment->expList.set(toAst<ExpList_t>("_"sv, ExpList, x)); 2219 assignment->expList.set(toAst<ExpList_t>(fnVar, ExpList, x));
2065 assignment->action.set(assign); 2220 assignment->action.set(assign);
2066 transformAssignment(assignment, temp); 2221 transformAssignment(assignment, temp);
2067 _buf << indent(-1) << "do"sv << nll(chainValue);
2068 _buf << temp.front();
2069 _buf << *(++temp.begin());
2070 _buf << temp.back();
2071 popScope();
2072 _buf << indent() << "end"sv << nll(chainValue);
2073 break;
2074 } 2222 }
2075 default: break; 2223 auto funLit = toAst<Exp_t>(s("(...)-> "sv) + fnVar + s(" "sv) + baseVar + s(", ..."sv), Exp, x);
2224 switch (usage) {
2225 case ExpUsage::Closure:
2226 case ExpUsage::Return:
2227 transformExp(funLit, temp);
2228 _buf << temp.front();
2229 _buf << *(++temp.begin());
2230 _buf << indent() << "return " << temp.back() << nll(x);
2231 break;
2232 case ExpUsage::Assignment: {
2233 auto assign = x->new_ptr<Assign_t>();
2234 assign->values.push_back(funLit);
2235 auto assignment = x->new_ptr<ExpListAssign_t>();
2236 assignment->expList.set(assignList);
2237 assignment->action.set(assign);
2238 transformAssignment(assignment, temp);
2239 break;
2240 }
2241 default:
2242 break;
2243 }
2244 switch (usage) {
2245 case ExpUsage::Assignment:
2246 popScope();
2247 temp.push_back(indent() + s("end"sv) + nlr(x));
2248 break;
2249 case ExpUsage::Closure:
2250 popScope();
2251 temp.push_back(indent() + s("end)()"sv));
2252 break;
2253 default:
2254 break;
2255 }
2256 out.push_back(join(temp));
2257 return true;
2076 } 2258 }
2077 out.push_back(clearBuf()); 2259 return false;
2078 } 2260 }
2079 2261
2080 void transformChainList(const node_container& chainList, str_list& out, ExpUsage usage, ExpList_t* assignList = nullptr) { 2262 void transformChainList(const node_container& chainList, str_list& out, ExpUsage usage, ExpList_t* assignList = nullptr) {
2081 auto x = chainList.front(); 2263 auto x = chainList.front();
2082 str_list temp; 2264 str_list temp;
2083 switch (chainList.front()->getId()) { 2265 switch (x->getId()) {
2084 case "DotChainItem"_id: 2266 case "DotChainItem"_id:
2085 case "ColonChainItem"_id: 2267 case "ColonChainItem"_id:
2086 if (_withVars.empty()) { 2268 if (_withVars.empty()) {
2087 throw std::logic_error(debugInfo("Short dot/colon syntax must be called within a with block."sv, chainList.front())); 2269 throw std::logic_error(debugInfo("Short dot/colon syntax must be called within a with block."sv, x));
2088 } else { 2270 } else {
2089 temp.push_back(_withVars.top()); 2271 temp.push_back(_withVars.top());
2090 } 2272 }
@@ -2101,8 +2283,20 @@ private:
2101 break; 2283 break;
2102 case "ColonChainItem"_id: { 2284 case "ColonChainItem"_id: {
2103 auto colonItem = static_cast<ColonChainItem_t*>(item); 2285 auto colonItem = static_cast<ColonChainItem_t*>(item);
2104 auto next = it; ++next; 2286 auto current = it;
2287 auto next = current; ++next;
2105 auto followItem = next != chainList.end() ? *next : nullptr; 2288 auto followItem = next != chainList.end() ? *next : nullptr;
2289 if (current != chainList.begin()) {
2290 --current;
2291 if (!ast_is<existential_op_t>(*current)) {
2292 ++current;
2293 }
2294 }
2295 if (ast_is<existential_op_t>(followItem)) {
2296 ++next;
2297 followItem = next != chainList.end() ? *next : nullptr;
2298 --next;
2299 }
2106 if (!ast_is<Invoke_t, InvokeArgs_t>(followItem)) { 2300 if (!ast_is<Invoke_t, InvokeArgs_t>(followItem)) {
2107 throw std::logic_error(debugInfo("Colon chain item must be followed by invoke arguments."sv, colonItem)); 2301 throw std::logic_error(debugInfo("Colon chain item must be followed by invoke arguments."sv, colonItem));
2108 } 2302 }
@@ -2117,7 +2311,7 @@ private:
2117 chainValue->items.push_back(toAst<Callable_t>(_withVars.top(), Callable, x)); 2311 chainValue->items.push_back(toAst<Callable_t>(_withVars.top(), Callable, x));
2118 break; 2312 break;
2119 } 2313 }
2120 for (auto i = chainList.begin(); i != it; ++i) { 2314 for (auto i = chainList.begin(); i != current; ++i) {
2121 chainValue->items.push_back(*i); 2315 chainValue->items.push_back(*i);
2122 } 2316 }
2123 auto value = x->new_ptr<Value_t>(); 2317 auto value = x->new_ptr<Value_t>();
@@ -2141,6 +2335,9 @@ private:
2141 auto name = toString(colonItem->name); 2335 auto name = toString(colonItem->name);
2142 auto chainValue = x->new_ptr<ChainValue_t>(); 2336 auto chainValue = x->new_ptr<ChainValue_t>();
2143 chainValue->items.push_back(toAst<Callable_t>(callVar, Callable, x)); 2337 chainValue->items.push_back(toAst<Callable_t>(callVar, Callable, x));
2338 if (ast_is<existential_op_t>(*current)) {
2339 chainValue->items.push_back(x->new_ptr<existential_op_t>());
2340 }
2144 chainValue->items.push_back(toAst<Exp_t>(s("\""sv) + name + s("\""sv), Exp, x)); 2341 chainValue->items.push_back(toAst<Exp_t>(s("\""sv) + name + s("\""sv), Exp, x));
2145 if (auto invoke = ast_cast<Invoke_t>(followItem)) { 2342 if (auto invoke = ast_cast<Invoke_t>(followItem)) {
2146 invoke->args.push_front(toAst<Exp_t>(callVar, Exp, x)); 2343 invoke->args.push_front(toAst<Exp_t>(callVar, Exp, x));
@@ -2148,8 +2345,7 @@ private:
2148 auto invokeArgs = static_cast<InvokeArgs_t*>(followItem); 2345 auto invokeArgs = static_cast<InvokeArgs_t*>(followItem);
2149 invokeArgs->args.push_front(toAst<Exp_t>(callVar, Exp, x)); 2346 invokeArgs->args.push_front(toAst<Exp_t>(callVar, Exp, x));
2150 } 2347 }
2151 chainValue->items.push_back(followItem); 2348 for (auto i = next; i != chainList.end(); ++i) {
2152 for (auto i = ++next; i != chainList.end(); ++i) {
2153 chainValue->items.push_back(*i); 2349 chainValue->items.push_back(*i);
2154 } 2350 }
2155 auto value = x->new_ptr<Value_t>(); 2351 auto value = x->new_ptr<Value_t>();
@@ -2244,7 +2440,17 @@ private:
2244 } 2440 }
2245 2441
2246 void transformChainValue(ChainValue_t* chainValue, str_list& out, ExpUsage usage = ExpUsage::Closure, ExpList_t* assignList = nullptr) { 2442 void transformChainValue(ChainValue_t* chainValue, str_list& out, ExpUsage usage = ExpUsage::Closure, ExpList_t* assignList = nullptr) {
2247 transformChainList(chainValue->items.objects(), out, usage, assignList); 2443 const auto& chainList = chainValue->items.objects();
2444 if (transformChainEndWithEOP(chainList, out, usage, assignList)) {
2445 return;
2446 }
2447 if (transformChainWithEOP(chainList, out, usage, assignList)) {
2448 return;
2449 }
2450 if (transformChainEndWithColonItem(chainList, out, usage, assignList)) {
2451 return;
2452 }
2453 transformChainList(chainList, out, usage, assignList);
2248 } 2454 }
2249 2455
2250 void transformAssignableChain(AssignableChain_t* chain, str_list& out) { 2456 void transformAssignableChain(AssignableChain_t* chain, str_list& out) {
@@ -2957,7 +3163,7 @@ private:
2957 if (auto assignment = assignmentFrom(statement)) { 3163 if (auto assignment = assignmentFrom(statement)) {
2958 auto names = transformAssignDefs(assignment->expList.get()); 3164 auto names = transformAssignDefs(assignment->expList.get());
2959 varDefs.insert(varDefs.end(), names.begin(), names.end()); 3165 varDefs.insert(varDefs.end(), names.begin(), names.end());
2960 auto info = extractDestructureInfo(assignment); 3166 auto info = extractDestructureInfo(assignment, true);
2961 if (!info.first.empty()) { 3167 if (!info.first.empty()) {
2962 for (const auto& destruct : info.first) 3168 for (const auto& destruct : info.first)
2963 for (const auto& item : destruct.items) 3169 for (const auto& item : destruct.items)
@@ -3342,7 +3548,7 @@ private:
3342 if (!names.empty()) { 3548 if (!names.empty()) {
3343 return traversal::Stop; 3549 return traversal::Stop;
3344 } 3550 }
3345 auto info = extractDestructureInfo(assignment); 3551 auto info = extractDestructureInfo(assignment, true);
3346 if (!info.first.empty()) { 3552 if (!info.first.empty()) {
3347 for (const auto& destruct : info.first) 3553 for (const auto& destruct : info.first)
3348 for (const auto& item : destruct.items) 3554 for (const auto& item : destruct.items)
diff --git a/src/MoonP/moon_parser.cpp b/src/MoonP/moon_parser.cpp
index 1005463..7cc4129 100644
--- a/src/MoonP/moon_parser.cpp
+++ b/src/MoonP/moon_parser.cpp
@@ -289,9 +289,9 @@ extern rule Value;
289rule exp_op_value = Space >> BinaryOperator >> *SpaceBreak >> Value; 289rule exp_op_value = Space >> BinaryOperator >> *SpaceBreak >> Value;
290rule Exp = Value >> *exp_op_value; 290rule Exp = Value >> *exp_op_value;
291 291
292extern rule Chain, Callable, InvokeArgs; 292extern rule Chain, Callable, InvokeArgs, existential_op;
293 293
294rule ChainValue = Seperator >> (Chain | Callable) >> -InvokeArgs; 294rule ChainValue = Seperator >> (Chain | Callable) >> -existential_op >> -InvokeArgs;
295 295
296extern rule KeyValue, String, SimpleValue; 296extern rule KeyValue, String, SimpleValue;
297 297
@@ -345,9 +345,10 @@ rule FnArgs = (symx('(') >> *SpaceBreak >> -FnArgsExpList >> *SpaceBreak >> sym(
345 345
346extern rule ChainItems, DotChainItem, ColonChain; 346extern rule ChainItems, DotChainItem, ColonChain;
347 347
348rule chain_call = (Callable | String) >> ChainItems; 348rule existential_op = expr('?');
349rule chain_call = (Callable | String) >> -existential_op >> ChainItems;
349rule chain_item = and_(set(".\\")) >> ChainItems; 350rule chain_item = and_(set(".\\")) >> ChainItems;
350rule chain_dot_chain = DotChainItem >> -ChainItems; 351rule chain_dot_chain = DotChainItem >> -existential_op >> -ChainItems;
351 352
352rule Chain = chain_call | chain_item | 353rule Chain = chain_call | chain_item |
353 Space >> (chain_dot_chain | ColonChain); 354 Space >> (chain_dot_chain | ColonChain);
@@ -362,11 +363,11 @@ rule ChainItems = chain_with_colon | ColonChain;
362extern rule Invoke, Slice; 363extern rule Invoke, Slice;
363 364
364rule Index = symx('[') >> Exp >> sym(']'); 365rule Index = symx('[') >> Exp >> sym(']');
365rule ChainItem = Invoke | DotChainItem | Slice | Index; 366rule ChainItem = Invoke >> -existential_op | DotChainItem >> -existential_op | Slice | Index >> -existential_op;
366rule DotChainItem = symx('.') >> Name; 367rule DotChainItem = symx('.') >> Name;
367rule ColonChainItem = symx('\\') >> (LuaKeyword | Name); 368rule ColonChainItem = symx('\\') >> (LuaKeyword | Name);
368rule invoke_chain = Invoke >> -ChainItems; 369rule invoke_chain = Invoke >> -existential_op >> -ChainItems;
369rule ColonChain = ColonChainItem >> -invoke_chain; 370rule ColonChain = ColonChainItem >> -existential_op >> -invoke_chain;
370 371
371rule default_value = true_(); 372rule default_value = true_();
372rule Slice = 373rule Slice =
diff --git a/src/moonc.cpp b/src/moonc.cpp
index 02d5275..4498bee 100644
--- a/src/moonc.cpp
+++ b/src/moonc.cpp
@@ -22,14 +22,13 @@ int main(int narg, const char** args) {
22" -p Write output to standard out\n" 22" -p Write output to standard out\n"
23" -b Dump compile time (doesn't write output)\n" 23" -b Dump compile time (doesn't write output)\n"
24" -l Write line numbers from source codes\n" 24" -l Write line numbers from source codes\n"
25" -a Allow expression list not in the end of body block\n"
26" -s Use space over tab\n"
27" -v Print version\n"; 25" -v Print version\n";
28 if (narg == 0) { 26 if (narg == 0) {
29 std::cout << help; 27 std::cout << help;
30 return 0; 28 return 0;
31 } 29 }
32 MoonP::MoonConfig config; 30 MoonP::MoonConfig config;
31 config.reserveLineNumber = false;
33 bool writeToFile = true; 32 bool writeToFile = true;
34 bool dumpCompileTime = false; 33 bool dumpCompileTime = false;
35 std::string targetPath; 34 std::string targetPath;
@@ -37,18 +36,9 @@ int main(int narg, const char** args) {
37 std::list<std::string> files; 36 std::list<std::string> files;
38 for (int i = 1; i < narg; ++i) { 37 for (int i = 1; i < narg; ++i) {
39 switch (hash(args[i])) { 38 switch (hash(args[i])) {
40 case "-a"_id:
41 config.allowExprNotInTheEndOfBody = true;
42 break;
43 case "-s"_id:
44 config.spaceOverTab = true;
45 break;
46 case "-l"_id: 39 case "-l"_id:
47 config.reserveLineNumber = true; 40 config.reserveLineNumber = true;
48 break; 41 break;
49 case "-r"_id:
50 config.reuseVariable = true;
51 break;
52 case "-p"_id: 42 case "-p"_id:
53 writeToFile = false; 43 writeToFile = false;
54 break; 44 break;