mirror of
https://github.com/fluencelabs/assemblyscript
synced 2025-04-25 15:12:12 +00:00
Fixed a function expression parsing issue
Also uncovered a yet-to-be-fixed issue when immediately calling a returned function
This commit is contained in:
parent
7870e3ac18
commit
c93f0bb1fe
2
dist/assemblyscript.js
vendored
2
dist/assemblyscript.js
vendored
File diff suppressed because one or more lines are too long
2
dist/assemblyscript.js.map
vendored
2
dist/assemblyscript.js.map
vendored
File diff suppressed because one or more lines are too long
@ -124,6 +124,10 @@ export function serializeNode(node: Node, sb: string[]): void {
|
|||||||
serializeCallExpression(<CallExpression>node, sb);
|
serializeCallExpression(<CallExpression>node, sb);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case NodeKind.COMMA: {
|
||||||
|
serializeCommaExpression(<CommaExpression>node, sb);
|
||||||
|
break;
|
||||||
|
}
|
||||||
case NodeKind.ELEMENTACCESS: {
|
case NodeKind.ELEMENTACCESS: {
|
||||||
serializeElementAccessExpression(<ElementAccessExpression>node, sb);
|
serializeElementAccessExpression(<ElementAccessExpression>node, sb);
|
||||||
break;
|
break;
|
||||||
|
@ -2810,11 +2810,14 @@ export class Parser extends DiagnosticEmitter {
|
|||||||
if (!expr) return null;
|
if (!expr) return null;
|
||||||
var startPos = expr.range.start;
|
var startPos = expr.range.start;
|
||||||
|
|
||||||
// CallExpression
|
// CallExpression with type arguments
|
||||||
var typeArguments = this.tryParseTypeArgumentsBeforeArguments(tn); // skips '(' on success
|
var typeArguments: CommonTypeNode[] | null;
|
||||||
// there might be better ways to distinguish a LESSTHAN from a CALL with type arguments
|
while (
|
||||||
if (typeArguments || tn.skip(Token.OPENPAREN)) {
|
// there might be better ways to distinguish a LESSTHAN from a CALL with type arguments
|
||||||
var args = this.parseArguments(tn);
|
(typeArguments = this.tryParseTypeArgumentsBeforeArguments(tn)) ||
|
||||||
|
tn.skip(Token.OPENPAREN)
|
||||||
|
) {
|
||||||
|
let args = this.parseArguments(tn);
|
||||||
if (!args) return null;
|
if (!args) return null;
|
||||||
expr = Node.createCallExpression(expr, typeArguments, args, tn.range(startPos, tn.pos));
|
expr = Node.createCallExpression(expr, typeArguments, args, tn.range(startPos, tn.pos));
|
||||||
}
|
}
|
||||||
|
@ -1697,16 +1697,18 @@ export class Program extends DiagnosticEmitter {
|
|||||||
expression: Expression,
|
expression: Expression,
|
||||||
contextualFunction: Function
|
contextualFunction: Function
|
||||||
): ResolvedElement | null {
|
): ResolvedElement | null {
|
||||||
var classType: Class | null;
|
|
||||||
while (expression.kind == NodeKind.PARENTHESIZED) {
|
while (expression.kind == NodeKind.PARENTHESIZED) {
|
||||||
expression = (<ParenthesizedExpression>expression).expression;
|
expression = (<ParenthesizedExpression>expression).expression;
|
||||||
}
|
}
|
||||||
switch (expression.kind) {
|
switch (expression.kind) {
|
||||||
case NodeKind.ASSERTION: {
|
case NodeKind.ASSERTION: {
|
||||||
var type = this.resolveType((<AssertionExpression>expression).toType); // reports
|
let type = this.resolveType((<AssertionExpression>expression).toType); // reports
|
||||||
if (type && (classType = type.classType)) {
|
if (type) {
|
||||||
if (!resolvedElement) resolvedElement = new ResolvedElement();
|
let classType = type.classType;
|
||||||
return resolvedElement.set(classType);
|
if (classType) {
|
||||||
|
if (!resolvedElement) resolvedElement = new ResolvedElement();
|
||||||
|
return resolvedElement.set(classType);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@ -1714,7 +1716,8 @@ export class Program extends DiagnosticEmitter {
|
|||||||
throw new Error("not implemented");
|
throw new Error("not implemented");
|
||||||
}
|
}
|
||||||
case NodeKind.THIS: { // -> Class
|
case NodeKind.THIS: { // -> Class
|
||||||
if (classType = contextualFunction.instanceMethodOf) {
|
let classType = contextualFunction.instanceMethodOf;
|
||||||
|
if (classType) {
|
||||||
if (!resolvedElement) resolvedElement = new ResolvedElement();
|
if (!resolvedElement) resolvedElement = new ResolvedElement();
|
||||||
return resolvedElement.set(classType);
|
return resolvedElement.set(classType);
|
||||||
}
|
}
|
||||||
@ -1725,7 +1728,8 @@ export class Program extends DiagnosticEmitter {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
case NodeKind.SUPER: { // -> Class
|
case NodeKind.SUPER: { // -> Class
|
||||||
if ((classType = contextualFunction.instanceMethodOf) && (classType = classType.base)) {
|
let classType = contextualFunction.instanceMethodOf;
|
||||||
|
if (classType && (classType = classType.base)) {
|
||||||
if (!resolvedElement) resolvedElement = new ResolvedElement();
|
if (!resolvedElement) resolvedElement = new ResolvedElement();
|
||||||
return resolvedElement.set(classType);
|
return resolvedElement.set(classType);
|
||||||
}
|
}
|
||||||
@ -1751,21 +1755,31 @@ export class Program extends DiagnosticEmitter {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
case NodeKind.CALL: {
|
case NodeKind.CALL: {
|
||||||
var resolved = this.resolveExpression(
|
let resolved = this.resolveExpression(
|
||||||
(<CallExpression>expression).expression,
|
(<CallExpression>expression).expression,
|
||||||
contextualFunction
|
contextualFunction
|
||||||
);
|
);
|
||||||
if (resolved) {
|
if (resolved) {
|
||||||
var element = resolved.element;
|
let element = resolved.element;
|
||||||
if (element && element.kind == ElementKind.FUNCTION_PROTOTYPE) {
|
if (element && element.kind == ElementKind.FUNCTION_PROTOTYPE) {
|
||||||
var instance = (<FunctionPrototype>element).resolveUsingTypeArguments(
|
let instance = (<FunctionPrototype>element).resolveUsingTypeArguments(
|
||||||
(<CallExpression>expression).typeArguments,
|
(<CallExpression>expression).typeArguments,
|
||||||
null,
|
null,
|
||||||
expression
|
expression
|
||||||
);
|
);
|
||||||
if (instance && (classType = instance.signature.returnType.classType)) {
|
if (instance) {
|
||||||
if (!resolvedElement) resolvedElement = new ResolvedElement();
|
let returnType = instance.signature.returnType;
|
||||||
return resolvedElement.set(classType);
|
let classType = returnType.classType;
|
||||||
|
if (classType) {
|
||||||
|
if (!resolvedElement) resolvedElement = new ResolvedElement();
|
||||||
|
return resolvedElement.set(classType);
|
||||||
|
} else {
|
||||||
|
let functionType = returnType.functionType;
|
||||||
|
if (functionType) {
|
||||||
|
// TODO: Signatures aren't elements but probably should be
|
||||||
|
throw new Error("not implemented");
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,12 +2,11 @@
|
|||||||
(type $i (func (result i32)))
|
(type $i (func (result i32)))
|
||||||
(type $iii (func (param i32 i32) (result i32)))
|
(type $iii (func (param i32 i32) (result i32)))
|
||||||
(type $III (func (param i64 i64) (result i64)))
|
(type $III (func (param i64 i64) (result i64)))
|
||||||
(type $FFF (func (param f64 f64) (result f64)))
|
|
||||||
(type $v (func))
|
(type $v (func))
|
||||||
(global $function-types/i32Adder (mut i32) (i32.const 0))
|
(global $function-types/i32Adder (mut i32) (i32.const 0))
|
||||||
(global $function-types/i64Adder (mut i32) (i32.const 0))
|
(global $function-types/i64Adder (mut i32) (i32.const 0))
|
||||||
(table 3 3 anyfunc)
|
(table 2 2 anyfunc)
|
||||||
(elem (i32.const 0) $function-types/makeAdder<i32>~anonymous|0 $function-types/makeAdder<i64>~anonymous|1 $function-types/makeAdder<f64>~anonymous|2)
|
(elem (i32.const 0) $function-types/makeAdder<i32>~anonymous|0 $function-types/makeAdder<i64>~anonymous|1)
|
||||||
(memory $0 1)
|
(memory $0 1)
|
||||||
(export "memory" (memory $0))
|
(export "memory" (memory $0))
|
||||||
(start $start)
|
(start $start)
|
||||||
@ -29,16 +28,7 @@
|
|||||||
(func $function-types/makeAdder<i64> (; 3 ;) (type $i) (result i32)
|
(func $function-types/makeAdder<i64> (; 3 ;) (type $i) (result i32)
|
||||||
(i32.const 1)
|
(i32.const 1)
|
||||||
)
|
)
|
||||||
(func $function-types/makeAdder<f64>~anonymous|2 (; 4 ;) (type $FFF) (param $0 f64) (param $1 f64) (result f64)
|
(func $start (; 4 ;) (type $v)
|
||||||
(f64.add
|
|
||||||
(get_local $0)
|
|
||||||
(get_local $1)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
(func $function-types/makeAdder<f64> (; 5 ;) (type $i) (result i32)
|
|
||||||
(i32.const 2)
|
|
||||||
)
|
|
||||||
(func $start (; 6 ;) (type $v)
|
|
||||||
(set_global $function-types/i32Adder
|
(set_global $function-types/i32Adder
|
||||||
(call $function-types/makeAdder<i32>)
|
(call $function-types/makeAdder<i32>)
|
||||||
)
|
)
|
||||||
@ -59,8 +49,5 @@
|
|||||||
(get_global $function-types/i64Adder)
|
(get_global $function-types/i64Adder)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
(drop
|
|
||||||
(call $function-types/makeAdder<f64>)
|
|
||||||
)
|
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
@ -12,4 +12,5 @@ i32Adder(1, 2);
|
|||||||
var i64Adder = makeAdder<i64>();
|
var i64Adder = makeAdder<i64>();
|
||||||
i64Adder(1, 2);
|
i64Adder(1, 2);
|
||||||
|
|
||||||
makeAdder<f64>()(1, 2);
|
// TODO:
|
||||||
|
// makeAdder<f64>()(1, 2);
|
||||||
|
@ -2,13 +2,12 @@
|
|||||||
(type $i (func (result i32)))
|
(type $i (func (result i32)))
|
||||||
(type $iii (func (param i32 i32) (result i32)))
|
(type $iii (func (param i32 i32) (result i32)))
|
||||||
(type $III (func (param i64 i64) (result i64)))
|
(type $III (func (param i64 i64) (result i64)))
|
||||||
(type $FFF (func (param f64 f64) (result f64)))
|
|
||||||
(type $v (func))
|
(type $v (func))
|
||||||
(global $function-types/i32Adder (mut i32) (i32.const 0))
|
(global $function-types/i32Adder (mut i32) (i32.const 0))
|
||||||
(global $function-types/i64Adder (mut i32) (i32.const 0))
|
(global $function-types/i64Adder (mut i32) (i32.const 0))
|
||||||
(global $HEAP_BASE i32 (i32.const 4))
|
(global $HEAP_BASE i32 (i32.const 4))
|
||||||
(table 3 3 anyfunc)
|
(table 2 2 anyfunc)
|
||||||
(elem (i32.const 0) $function-types/makeAdder<i32>~anonymous|0 $function-types/makeAdder<i64>~anonymous|1 $function-types/makeAdder<f64>~anonymous|2)
|
(elem (i32.const 0) $function-types/makeAdder<i32>~anonymous|0 $function-types/makeAdder<i64>~anonymous|1)
|
||||||
(memory $0 1)
|
(memory $0 1)
|
||||||
(export "memory" (memory $0))
|
(export "memory" (memory $0))
|
||||||
(start $start)
|
(start $start)
|
||||||
@ -38,20 +37,7 @@
|
|||||||
(i32.const 1)
|
(i32.const 1)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
(func $function-types/makeAdder<f64>~anonymous|2 (; 4 ;) (type $FFF) (param $0 f64) (param $1 f64) (result f64)
|
(func $start (; 4 ;) (type $v)
|
||||||
(return
|
|
||||||
(f64.add
|
|
||||||
(get_local $0)
|
|
||||||
(get_local $1)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
(func $function-types/makeAdder<f64> (; 5 ;) (type $i) (result i32)
|
|
||||||
(return
|
|
||||||
(i32.const 2)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
(func $start (; 6 ;) (type $v)
|
|
||||||
(nop)
|
(nop)
|
||||||
(set_global $function-types/i32Adder
|
(set_global $function-types/i32Adder
|
||||||
(call $function-types/makeAdder<i32>)
|
(call $function-types/makeAdder<i32>)
|
||||||
@ -73,16 +59,5 @@
|
|||||||
(get_global $function-types/i64Adder)
|
(get_global $function-types/i64Adder)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
(drop
|
|
||||||
(call $function-types/makeAdder<f64>)
|
|
||||||
)
|
|
||||||
(block
|
|
||||||
(drop
|
|
||||||
(i32.const 1)
|
|
||||||
)
|
|
||||||
(drop
|
|
||||||
(i32.const 2)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
1
tests/parser/call-function-return.ts
Normal file
1
tests/parser/call-function-return.ts
Normal file
@ -0,0 +1 @@
|
|||||||
|
a = fn()(1, 2);
|
1
tests/parser/call-function-return.ts.fixture.ts
Normal file
1
tests/parser/call-function-return.ts.fixture.ts
Normal file
@ -0,0 +1 @@
|
|||||||
|
a = fn()(1, 2);
|
Loading…
x
Reference in New Issue
Block a user