Skip to content

Commit ccb4478

Browse files
committed
Fix 'new' parsing precedence & allow omitting parenthesis
1 parent 2e55465 commit ccb4478

File tree

5 files changed

+384
-1
lines changed

5 files changed

+384
-1
lines changed

src/parser.ts

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3266,7 +3266,7 @@ export class Parser extends DiagnosticEmitter {
32663266

32673267
// NewExpression
32683268
if (token == Token.NEW) {
3269-
operand = this.parseExpression(tn, Precedence.CALL);
3269+
operand = this.parseExpression(tn, Precedence.GROUPING);
32703270
if (!operand) return null;
32713271
if (operand.kind == NodeKind.CALL) {
32723272
return Node.createNewExpression(
@@ -3275,6 +3275,11 @@ export class Parser extends DiagnosticEmitter {
32753275
(<CallExpression>operand).arguments,
32763276
tn.range(startPos, tn.pos)
32773277
);
3278+
} else if (operand.kind == NodeKind.IDENTIFIER) { // new Class;
3279+
return Node.createNewExpression(
3280+
operand, null, [],
3281+
tn.range(startPos, tn.pos)
3282+
);
32783283
} else {
32793284
this.error(
32803285
DiagnosticCode.This_expression_is_not_constructable,

tests/compiler/new.json

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
{
2+
"asc_flags": [
3+
"--runtime none"
4+
]
5+
}

tests/compiler/new.optimized.wat

Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,108 @@
1+
(module
2+
(type $FUNCSIG$vi (func (param i32)))
3+
(type $FUNCSIG$v (func))
4+
(type $FUNCSIG$ii (func (param i32) (result i32)))
5+
(memory $0 0)
6+
(global $new/ref (mut i32) (i32.const 0))
7+
(global $~lib/rt/stub/startOffset (mut i32) (i32.const 0))
8+
(global $~lib/rt/stub/offset (mut i32) (i32.const 0))
9+
(global $new/gen (mut i32) (i32.const 0))
10+
(export "memory" (memory $0))
11+
(start $start)
12+
(func $~lib/rt/stub/maybeGrowMemory (; 0 ;) (type $FUNCSIG$vi) (param $0 i32)
13+
(local $1 i32)
14+
(local $2 i32)
15+
local.get $0
16+
memory.size
17+
local.tee $2
18+
i32.const 16
19+
i32.shl
20+
local.tee $1
21+
i32.gt_u
22+
if
23+
local.get $2
24+
local.get $0
25+
local.get $1
26+
i32.sub
27+
i32.const 65535
28+
i32.add
29+
i32.const -65536
30+
i32.and
31+
i32.const 16
32+
i32.shr_u
33+
local.tee $1
34+
local.get $2
35+
local.get $1
36+
i32.gt_s
37+
select
38+
memory.grow
39+
i32.const 0
40+
i32.lt_s
41+
if
42+
local.get $1
43+
memory.grow
44+
i32.const 0
45+
i32.lt_s
46+
if
47+
unreachable
48+
end
49+
end
50+
end
51+
local.get $0
52+
global.set $~lib/rt/stub/offset
53+
)
54+
(func $~lib/rt/stub/__alloc (; 1 ;) (type $FUNCSIG$ii) (param $0 i32) (result i32)
55+
(local $1 i32)
56+
(local $2 i32)
57+
global.get $~lib/rt/stub/offset
58+
i32.const 16
59+
i32.add
60+
local.tee $2
61+
i32.const 16
62+
i32.add
63+
call $~lib/rt/stub/maybeGrowMemory
64+
local.get $2
65+
i32.const 16
66+
i32.sub
67+
local.tee $1
68+
i32.const 16
69+
i32.store
70+
local.get $1
71+
i32.const -1
72+
i32.store offset=4
73+
local.get $1
74+
local.get $0
75+
i32.store offset=8
76+
local.get $1
77+
i32.const 0
78+
i32.store offset=12
79+
local.get $2
80+
)
81+
(func $start:new (; 2 ;) (type $FUNCSIG$v)
82+
i32.const 16
83+
global.set $~lib/rt/stub/startOffset
84+
i32.const 16
85+
global.set $~lib/rt/stub/offset
86+
i32.const 3
87+
call $~lib/rt/stub/__alloc
88+
global.set $new/ref
89+
i32.const 3
90+
call $~lib/rt/stub/__alloc
91+
global.set $new/ref
92+
i32.const 3
93+
call $~lib/rt/stub/__alloc
94+
global.set $new/ref
95+
i32.const 4
96+
call $~lib/rt/stub/__alloc
97+
global.set $new/gen
98+
i32.const 4
99+
call $~lib/rt/stub/__alloc
100+
global.set $new/gen
101+
)
102+
(func $start (; 3 ;) (type $FUNCSIG$v)
103+
call $start:new
104+
)
105+
(func $null (; 4 ;) (type $FUNCSIG$v)
106+
nop
107+
)
108+
)

tests/compiler/new.ts

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
class Ref {
2+
get ref(): Ref { return this; }
3+
}
4+
5+
var ref: Ref;
6+
ref = new Ref();
7+
ref = new Ref;
8+
ref = new Ref().ref;
9+
10+
class Gen<T> {
11+
get gen(): Gen<T> { return this; }
12+
}
13+
14+
var gen: Gen<i32>;
15+
gen = new Gen<i32>();
16+
gen = new Gen<i32>().gen;

0 commit comments

Comments
 (0)