mirror of
https://github.com/fluencelabs/assemblyscript
synced 2025-06-12 06:21:29 +00:00
Initial type parameter inference, see #61
This catches the most common cases but doesn't yet implement inference involving the return type because some prequesites are not yet in place (see test case).
This commit is contained in:
@ -311,4 +311,4 @@ assert(f64.EPSILON == 2.2204460492503131e-16);
|
||||
|
||||
// should be importable
|
||||
import { isNaN as isItNaN } from "builtins";
|
||||
isItNaN(1);
|
||||
isItNaN<f64>(1);
|
||||
|
91
tests/compiler/call-inferred.optimized.wat
Normal file
91
tests/compiler/call-inferred.optimized.wat
Normal file
@ -0,0 +1,91 @@
|
||||
(module
|
||||
(type $ii (func (param i32) (result i32)))
|
||||
(type $iiiiv (func (param i32 i32 i32 i32)))
|
||||
(type $FF (func (param f64) (result f64)))
|
||||
(type $ff (func (param f32) (result f32)))
|
||||
(type $v (func))
|
||||
(import "env" "abort" (func $abort (param i32 i32 i32 i32)))
|
||||
(memory $0 1)
|
||||
(data (i32.const 4) "\10\00\00\00c\00a\00l\00l\00-\00i\00n\00f\00e\00r\00r\00e\00d\00.\00t\00s")
|
||||
(export "memory" (memory $0))
|
||||
(start $start)
|
||||
(func $call-inferred/foo<i32> (; 1 ;) (type $ii) (param $0 i32) (result i32)
|
||||
(get_local $0)
|
||||
)
|
||||
(func $call-inferred/foo<f64> (; 2 ;) (type $FF) (param $0 f64) (result f64)
|
||||
(get_local $0)
|
||||
)
|
||||
(func $call-inferred/foo<f32> (; 3 ;) (type $ff) (param $0 f32) (result f32)
|
||||
(get_local $0)
|
||||
)
|
||||
(func $start (; 4 ;) (type $v)
|
||||
(if
|
||||
(i32.ne
|
||||
(call $call-inferred/foo<i32>
|
||||
(i32.const 42)
|
||||
)
|
||||
(i32.const 42)
|
||||
)
|
||||
(block
|
||||
(call $abort
|
||||
(i32.const 0)
|
||||
(i32.const 4)
|
||||
(i32.const 5)
|
||||
(i32.const 0)
|
||||
)
|
||||
(unreachable)
|
||||
)
|
||||
)
|
||||
(if
|
||||
(f64.ne
|
||||
(call $call-inferred/foo<f64>
|
||||
(f64.const 42)
|
||||
)
|
||||
(f64.const 42)
|
||||
)
|
||||
(block
|
||||
(call $abort
|
||||
(i32.const 0)
|
||||
(i32.const 4)
|
||||
(i32.const 6)
|
||||
(i32.const 0)
|
||||
)
|
||||
(unreachable)
|
||||
)
|
||||
)
|
||||
(if
|
||||
(f32.ne
|
||||
(call $call-inferred/foo<f32>
|
||||
(f32.const 42)
|
||||
)
|
||||
(f32.const 42)
|
||||
)
|
||||
(block
|
||||
(call $abort
|
||||
(i32.const 0)
|
||||
(i32.const 4)
|
||||
(i32.const 7)
|
||||
(i32.const 0)
|
||||
)
|
||||
(unreachable)
|
||||
)
|
||||
)
|
||||
(if
|
||||
(f32.ne
|
||||
(call $call-inferred/foo<f32>
|
||||
(f32.const 42)
|
||||
)
|
||||
(f32.const 42)
|
||||
)
|
||||
(block
|
||||
(call $abort
|
||||
(i32.const 0)
|
||||
(i32.const 4)
|
||||
(i32.const 13)
|
||||
(i32.const 0)
|
||||
)
|
||||
(unreachable)
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
25
tests/compiler/call-inferred.ts
Normal file
25
tests/compiler/call-inferred.ts
Normal file
@ -0,0 +1,25 @@
|
||||
function foo<T>(a: T): T {
|
||||
return a;
|
||||
}
|
||||
|
||||
assert(foo(42) == 42);
|
||||
assert(foo(42.0) == 42);
|
||||
assert(foo(<f32>42.0) == 42);
|
||||
|
||||
function bar<T>(a: T = <f32>42.0): T {
|
||||
return a;
|
||||
}
|
||||
|
||||
assert(bar() == 42);
|
||||
|
||||
// TODO: this'd require return type inference, i.e., omitted return type
|
||||
// function baz<T>(a: i32): T {
|
||||
// return a;
|
||||
// }
|
||||
// baz(42);
|
||||
|
||||
// TODO: this'd ideally be inferred by matching contextualType, avoiding conversions
|
||||
// function baz<T>(): T {
|
||||
// return 1;
|
||||
// }
|
||||
// baz(42);
|
111
tests/compiler/call-inferred.untouched.wat
Normal file
111
tests/compiler/call-inferred.untouched.wat
Normal file
@ -0,0 +1,111 @@
|
||||
(module
|
||||
(type $ii (func (param i32) (result i32)))
|
||||
(type $iiiiv (func (param i32 i32 i32 i32)))
|
||||
(type $FF (func (param f64) (result f64)))
|
||||
(type $ff (func (param f32) (result f32)))
|
||||
(type $v (func))
|
||||
(import "env" "abort" (func $abort (param i32 i32 i32 i32)))
|
||||
(global $HEAP_BASE i32 (i32.const 40))
|
||||
(memory $0 1)
|
||||
(data (i32.const 4) "\10\00\00\00c\00a\00l\00l\00-\00i\00n\00f\00e\00r\00r\00e\00d\00.\00t\00s\00")
|
||||
(export "memory" (memory $0))
|
||||
(start $start)
|
||||
(func $call-inferred/foo<i32> (; 1 ;) (type $ii) (param $0 i32) (result i32)
|
||||
(return
|
||||
(get_local $0)
|
||||
)
|
||||
)
|
||||
(func $call-inferred/foo<f64> (; 2 ;) (type $FF) (param $0 f64) (result f64)
|
||||
(return
|
||||
(get_local $0)
|
||||
)
|
||||
)
|
||||
(func $call-inferred/foo<f32> (; 3 ;) (type $ff) (param $0 f32) (result f32)
|
||||
(return
|
||||
(get_local $0)
|
||||
)
|
||||
)
|
||||
(func $call-inferred/bar<f32> (; 4 ;) (type $ff) (param $0 f32) (result f32)
|
||||
(return
|
||||
(get_local $0)
|
||||
)
|
||||
)
|
||||
(func $start (; 5 ;) (type $v)
|
||||
(if
|
||||
(i32.eqz
|
||||
(i32.eq
|
||||
(call $call-inferred/foo<i32>
|
||||
(i32.const 42)
|
||||
)
|
||||
(i32.const 42)
|
||||
)
|
||||
)
|
||||
(block
|
||||
(call $abort
|
||||
(i32.const 0)
|
||||
(i32.const 4)
|
||||
(i32.const 5)
|
||||
(i32.const 0)
|
||||
)
|
||||
(unreachable)
|
||||
)
|
||||
)
|
||||
(if
|
||||
(i32.eqz
|
||||
(f64.eq
|
||||
(call $call-inferred/foo<f64>
|
||||
(f64.const 42)
|
||||
)
|
||||
(f64.const 42)
|
||||
)
|
||||
)
|
||||
(block
|
||||
(call $abort
|
||||
(i32.const 0)
|
||||
(i32.const 4)
|
||||
(i32.const 6)
|
||||
(i32.const 0)
|
||||
)
|
||||
(unreachable)
|
||||
)
|
||||
)
|
||||
(if
|
||||
(i32.eqz
|
||||
(f32.eq
|
||||
(call $call-inferred/foo<f32>
|
||||
(f32.const 42)
|
||||
)
|
||||
(f32.const 42)
|
||||
)
|
||||
)
|
||||
(block
|
||||
(call $abort
|
||||
(i32.const 0)
|
||||
(i32.const 4)
|
||||
(i32.const 7)
|
||||
(i32.const 0)
|
||||
)
|
||||
(unreachable)
|
||||
)
|
||||
)
|
||||
(if
|
||||
(i32.eqz
|
||||
(f32.eq
|
||||
(call $call-inferred/bar<f32>
|
||||
(f32.const 42)
|
||||
)
|
||||
(f32.const 42)
|
||||
)
|
||||
)
|
||||
(block
|
||||
(call $abort
|
||||
(i32.const 0)
|
||||
(i32.const 4)
|
||||
(i32.const 13)
|
||||
(i32.const 0)
|
||||
)
|
||||
(unreachable)
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
Reference in New Issue
Block a user