Implement array functions with just an expression body

This commit is contained in:
dcodeIO 2018-03-19 01:22:19 +01:00
parent 0fef69e445
commit 5323e64af9
6 changed files with 74 additions and 18 deletions

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -836,21 +836,28 @@ export class Compiler extends DiagnosticEmitter {
var typeRef = this.ensureFunctionType(instance.signature);
var module = this.module;
if (body) {
let returnType = instance.signature.returnType;
// compile body
let previousFunction = this.currentFunction;
this.currentFunction = instance;
let stmt = this.compileStatement(body);
let flow = instance.flow;
let stmt: ExpressionRef;
if (body.kind == NodeKind.EXPRESSION) { // () => expression
stmt = this.compileExpression((<ExpressionStatement>body).expression, returnType);
flow.set(FlowFlags.RETURNS);
} else {
assert(body.kind == NodeKind.BLOCK);
stmt = this.compileStatement(body);
// make sure all branches return
let allBranchesReturn = instance.flow.finalize();
let returnType = instance.signature.returnType;
let allBranchesReturn = flow.finalize();
if (returnType != Type.void && !allBranchesReturn) {
this.error(
DiagnosticCode.A_function_whose_declared_type_is_not_void_must_return_a_value,
assert(declaration.signature.returnType, "return type expected").range
);
}
}
this.currentFunction = previousFunction;
// create the function

View File

@ -2,12 +2,14 @@
(type $ii (func (param i32) (result i32)))
(type $iiiiv (func (param i32 i32 i32 i32)))
(type $v (func))
(type $i (func (result i32)))
(import "env" "abort" (func $abort (param i32 i32 i32 i32)))
(global $function-expression/f1 (mut i32) (i32.const 0))
(global $function-expression/f2 (mut i32) (i32.const 1))
(global $function-expression/f3 (mut i32) (i32.const 2))
(table 3 3 anyfunc)
(elem (i32.const 0) $start~anonymous|0 $start~anonymous|0 $start~someName|2)
(global $function-expression/f4 (mut i32) (i32.const 3))
(table 4 4 anyfunc)
(elem (i32.const 0) $start~anonymous|0 $start~anonymous|0 $start~someName|2 $start~anonymous|3)
(memory $0 1)
(data (i32.const 4) "\16\00\00\00f\00u\00n\00c\00t\00i\00o\00n\00-\00e\00x\00p\00r\00e\00s\00s\00i\00o\00n\00.\00t\00s")
(export "memory" (memory $0))
@ -18,7 +20,10 @@
(func $start~someName|2 (; 2 ;) (type $v)
(nop)
)
(func $start (; 3 ;) (type $v)
(func $start~anonymous|3 (; 3 ;) (type $i) (result i32)
(i32.const 1)
)
(func $start (; 4 ;) (type $v)
(if
(i32.ne
(call_indirect (type $ii)
@ -58,5 +63,22 @@
(call_indirect (type $v)
(get_global $function-expression/f3)
)
(if
(i32.ne
(call_indirect (type $i)
(get_global $function-expression/f4)
)
(i32.const 1)
)
(block
(call $abort
(i32.const 0)
(i32.const 4)
(i32.const 16)
(i32.const 0)
)
(unreachable)
)
)
)
)

View File

@ -11,3 +11,6 @@ assert(f2(2) == 2);
var f3 = function someName(): void {
};
f3();
var f4 = (): i32 => 1;
assert(f4() == 1);

View File

@ -2,13 +2,15 @@
(type $ii (func (param i32) (result i32)))
(type $iiiiv (func (param i32 i32 i32 i32)))
(type $v (func))
(type $i (func (result i32)))
(import "env" "abort" (func $abort (param i32 i32 i32 i32)))
(global $function-expression/f1 (mut i32) (i32.const 0))
(global $function-expression/f2 (mut i32) (i32.const 1))
(global $function-expression/f3 (mut i32) (i32.const 2))
(global $function-expression/f4 (mut i32) (i32.const 3))
(global $HEAP_BASE i32 (i32.const 52))
(table 3 3 anyfunc)
(elem (i32.const 0) $start~anonymous|0 $start~anonymous|1 $start~someName|2)
(table 4 4 anyfunc)
(elem (i32.const 0) $start~anonymous|0 $start~anonymous|1 $start~someName|2 $start~anonymous|3)
(memory $0 1)
(data (i32.const 4) "\16\00\00\00f\00u\00n\00c\00t\00i\00o\00n\00-\00e\00x\00p\00r\00e\00s\00s\00i\00o\00n\00.\00t\00s\00")
(export "memory" (memory $0))
@ -25,7 +27,10 @@
)
(func $start~someName|2 (; 3 ;) (type $v)
)
(func $start (; 4 ;) (type $v)
(func $start~anonymous|3 (; 4 ;) (type $i) (result i32)
(i32.const 1)
)
(func $start (; 5 ;) (type $v)
(if
(i32.eqz
(i32.eq
@ -69,5 +74,24 @@
(call_indirect (type $v)
(get_global $function-expression/f3)
)
(if
(i32.eqz
(i32.eq
(call_indirect (type $i)
(get_global $function-expression/f4)
)
(i32.const 1)
)
)
(block
(call $abort
(i32.const 0)
(i32.const 4)
(i32.const 16)
(i32.const 0)
)
(unreachable)
)
)
)
)