Skip to content

Commit

Permalink
start working on local type parameters
Browse files Browse the repository at this point in the history
  • Loading branch information
Simn committed Jul 11, 2023
1 parent 8583bb1 commit 096c5a7
Show file tree
Hide file tree
Showing 9 changed files with 145 additions and 93 deletions.
43 changes: 35 additions & 8 deletions src/compiler/hxb/hxbReader.ml
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ class hxb_reader
val vars = Hashtbl.create 0
val mutable type_type_parameters = Array.make 0 (mk_type_param "" t_dynamic None)
val mutable field_type_parameters = Array.make 0 (mk_type_param "" t_dynamic None)
val mutable local_type_parameters = []

val mutable tvoid = None
method get_tvoid =
Expand Down Expand Up @@ -594,6 +595,18 @@ class hxb_reader
let i = self#read_uleb128 in
(* Printf.eprintf " Get type type param %d\n" i; *)
(type_type_parameters.(i)).ttp_type
| 7 ->
let k = self#read_uleb128 in
let i = self#read_uleb128 in
let rec loop left params = match params with
| _ :: params when left > 0 ->
loop (left - 1) params
| params :: _ ->
params.(i).ttp_type
| _ ->
error (Printf.sprintf "Bad index into local params: %i" k)
in
loop k local_type_parameters
| 10 ->
TInst(self#read_class_ref,[])
| 11 ->
Expand Down Expand Up @@ -735,6 +748,7 @@ class hxb_reader
let args = self#read_list (fun () -> self#read_tfunction_arg) in
let r = self#read_type_instance in
let e = self#read_texpr in
let args = List.map (fun ((v,close),cto) -> close(); (v,cto)) args in
{
tf_args = args;
tf_type = r;
Expand All @@ -757,17 +771,24 @@ class hxb_reader
| _ -> assert false

method read_var =
let close = ref (fun () -> ()) in (* TODO: awkward *)
let id = IO.read_i32 ch in
let name = self#read_string in
let t = self#read_type_instance in
let kind = self#read_var_kind in
let extra = self#read_option (fun () ->
let params = ref [] in
self#read_type_parameters null_module ([],name) (fun a ->
local_type_parameters <- a :: local_type_parameters;
params := Array.to_list a;
close := (fun () -> local_type_parameters <- List.tl local_type_parameters)
);
let vexpr = self#read_option (fun () -> self#read_texpr) in
{
v_params = []; (* TODO *)
v_params = !params;
v_expr = vexpr;
};
) in
let t = self#read_type_instance in
let kind = self#read_var_kind in
let flags = IO.read_i32 ch in
let meta = self#read_metadata in
let pos = self#read_pos in
Expand All @@ -782,7 +803,7 @@ class hxb_reader
v_flags = flags;
} in
Hashtbl.add vars id v;
v
v,!close

method read_texpr =
let t = self#read_type_instance in
Expand All @@ -803,10 +824,14 @@ class hxb_reader

(* vars 20-29 *)
| 20 -> TLocal (Hashtbl.find vars (IO.read_i32 ch))
| 21 -> TVar (self#read_var,None)
| 21 ->
let v,close = self#read_var in
close();
TVar (v,None)
| 22 ->
let v = self#read_var in
let v,close = self#read_var in
let e = self#read_texpr in
close();
TVar (v, Some e)

(* blocks 30-49 *)
Expand Down Expand Up @@ -887,8 +912,9 @@ class hxb_reader
| 83 ->
let e1 = self#read_texpr in
let catches = self#read_list (fun () ->
let v = self#read_var in
let v,close = self#read_var in
let e = self#read_texpr in
close();
(v,e)
) in
TTry(e1,catches)
Expand All @@ -901,9 +927,10 @@ class hxb_reader
let e2 = self#read_texpr in
TWhile(e1,e2,DoWhile)
| 86 ->
let v = self#read_var in
let v,close = self#read_var in
let e1 = self#read_texpr in
let e2 = self#read_texpr in
close();
TFor(v,e1,e2)

(* control flow 90-99 *)
Expand Down
51 changes: 40 additions & 11 deletions src/compiler/hxb/hxbWriter.ml
Original file line number Diff line number Diff line change
Expand Up @@ -229,6 +229,7 @@ class ['a] hxb_writer
val mutable ttp_key = None
val mutable type_type_parameters = new pool
val mutable field_type_parameters = new pool
val mutable local_type_parameters = []

(* Chunks *)

Expand Down Expand Up @@ -330,10 +331,25 @@ class ['a] hxb_writer
let i = type_type_parameters#get (snd c.cl_path) in
chunk#write_byte 6;
chunk#write_uleb128 i
with Not_found -> try
let rec loop k l = match l with
| [] ->
raise Not_found
| pool :: l ->
begin try
let i = pool#get (snd c.cl_path) in
chunk#write_byte 7;
chunk#write_uleb128 k;
chunk#write_uleb128 i
with Not_found ->
loop (k + 1) l
end
in
loop 0 local_type_parameters
with Not_found ->
(* error ("Unbound type parameter " ^ (s_type_path c.cl_path)) *)
Printf.eprintf "%s Unbound type parameter %s\n" todo_error (s_type_path c.cl_path);
chunk#write_byte 0
chunk#write_byte 40
end
| TInst(c,[]) ->
chunk#write_byte 10;
Expand Down Expand Up @@ -738,19 +754,30 @@ class ['a] hxb_writer
in
chunk#write_byte b

method set_local_type_parameters (params : typed_type_param list) =
let pool = new pool in
local_type_parameters <- pool :: local_type_parameters;
List.iter (fun ttp ->
ignore(pool#add ttp.ttp_name ttp);
) params

method write_var v =
let close = ref (fun () -> ()) in (* TODO: awkward *)
chunk#write_i32 v.v_id;
chunk#write_string v.v_name;
self#write_type_instance v.v_type;
self#write_var_kind v.v_kind;
chunk#write_option v.v_extra (fun ve ->
(* TODO *)
(* chunk#write_list ve.v_params self#write_typed_type_param; *)
self#set_local_type_parameters ve.v_params;
chunk#write_list ve.v_params self#write_type_parameter_forward;
chunk#write_list ve.v_params self#write_type_parameter_data;
chunk#write_option ve.v_expr self#write_texpr;
close := (fun () -> local_type_parameters <- List.tl local_type_parameters)
);
self#write_type_instance v.v_type;
self#write_var_kind v.v_kind;
chunk#write_i32 v.v_flags;
self#write_metadata v.v_meta;
self#write_pos v.v_pos;
!close

method write_texpr (e : texpr) =
let rec loop e =
Expand Down Expand Up @@ -787,11 +814,12 @@ class ['a] hxb_writer
chunk#write_i32 v.v_id;
| TVar(v,None) ->
chunk#write_byte 21;
self#write_var v;
self#write_var v ()
| TVar(v,Some e1) ->
chunk#write_byte 22;
self#write_var v;
let close = self#write_var v in
loop e1;
close()
(* blocks 30-49 *)
| TBlock [] ->
chunk#write_byte 30;
Expand Down Expand Up @@ -820,8 +848,9 @@ class ['a] hxb_writer
| TFunction tf ->
chunk#write_byte 50;
chunk#write_list tf.tf_args (fun (v,eo) ->
self#write_var v;
chunk#write_option eo loop
let close = self#write_var v in
chunk#write_option eo loop;
close();
);
self#write_type_instance tf.tf_type;
loop tf.tf_expr;
Expand Down Expand Up @@ -877,7 +906,7 @@ class ['a] hxb_writer
chunk#write_byte 83;
loop e1;
chunk#write_list catches (fun (v,e) ->
self#write_var v;
self#write_var v ();
loop e
);
| TWhile(e1,e2,flag) ->
Expand All @@ -886,7 +915,7 @@ class ['a] hxb_writer
loop e2;
| TFor(v,e1,e2) ->
chunk#write_byte 86;
self#write_var v;
self#write_var v ();
loop e1;
loop e2;
(* control flow 90-99 *)
Expand Down
13 changes: 6 additions & 7 deletions tests/unit/src/unit/issues/Issue10124.hx
Original file line number Diff line number Diff line change
Expand Up @@ -30,12 +30,11 @@ class Issue10124 extends Test {
}

function test3() {
// function rest<T>(...values:T):Array<T> {
// return values.toArray();
// }
// var a = rest(5, 6.2, 7);
// aeq([5, 6.2, 7], a);
// eq('Array<Float>', HelperMacros.typeString(a));
Assert.pass();
function rest<T>(...values:T):Array<T> {
return values.toArray();
}
var a = rest(5, 6.2, 7);
aeq([5, 6.2, 7], a);
eq('Array<Float>', HelperMacros.typeString(a));
}
}
25 changes: 11 additions & 14 deletions tests/unit/src/unit/issues/Issue2889.hx
Original file line number Diff line number Diff line change
@@ -1,16 +1,14 @@
package unit.issues;

class Issue2889 extends Test {
public function test()
{
// function mapMappable <A,B>(m:Mappable<A>, f:A->B):Mappable<B> {
// return m.map(f);
// }
// var r = mapMappable([1], function (y) return y+1);
// var r:Array<Int> = cast r;
// eq(r.length,1);
// eq(2,r[0]);
utest.Assert.pass();
public function test() {
function mapMappable<A, B>(m:Mappable<A>, f:A->B):Mappable<B> {
return m.map(f);
}
var r = mapMappable([1], function(y) return y + 1);
var r:Array<Int> = cast r;
eq(r.length, 1);
eq(2, r[0]);
}

function testDynamic() {
Expand All @@ -25,14 +23,14 @@ class Issue2889 extends Test {
}

function testFilterStructure() {
var a:{ function filter(f:Int->Bool):Array<Int>; } = [1, 2];
var a:{function filter(f:Int->Bool):Array<Int>;} = [1, 2];
var b = a.filter(function(x) return x % 2 == 0);
eq(1, b.length);
eq(2, b[0]);
}

function testMapStructure() {
var a:{ function map(f:Int->Int):Array<Int>; } = [1, 2];
var a:{function map(f:Int->Int):Array<Int>;} = [1, 2];
var b = a.map(function(x) return x * 2);
eq(2, b.length);
eq(2, b[0]);
Expand All @@ -41,6 +39,5 @@ class Issue2889 extends Test {
}

private typedef Mappable<Y> = {
public function map <X>(f:Y->X):Array<X>;
public function map<X>(f:Y->X):Array<X>;
}

39 changes: 19 additions & 20 deletions tests/unit/src/unit/issues/Issue5793.hx
Original file line number Diff line number Diff line change
@@ -1,25 +1,24 @@
package unit.issues;

class Issue5793 extends Test {
public function test() {
// function run1() {
// function foo <T> (expected:Array<T>, a:T) {
// eq(expected[0], a);
// }
// foo([2], 2);
// }
// run1();
public function test() {
function run1() {
function foo<T>(expected:Array<T>, a:T) {
eq(expected[0], a);
}
foo([2], 2);
}
run1();

// function run2() {
// function bar<A>(expected:Array<A>, a:A) {
// function baz<B>(expected:Array<B>, b:B) {
// eq(expected[0], b);
// }
// baz(expected,a);
// }
// bar([42],42);
// }
// run2();
utest.Assert.pass();
}
function run2() {
function bar<A>(expected:Array<A>, a:A) {
function baz<B>(expected:Array<B>, b:B) {
eq(expected[0], b);
}
baz(expected, a);
}
bar([42], 42);
}
run2();
}
}
11 changes: 6 additions & 5 deletions tests/unit/src/unit/issues/Issue6106.hx
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,13 @@ package unit.issues;
class Issue6106 extends unit.Test {
function test() {
var code = 0;
// function assertEquals<T>(expected:T, actual:T) {
// if(expected != actual) code++;
// }
function assertEquals<T>(expected:T, actual:T) {
if (expected != actual)
code++;
}

// var f = function() assertEquals(1, 1);
// f();
var f = function() assertEquals(1, 1);
f();
noAssert();
}
}
17 changes: 8 additions & 9 deletions tests/unit/src/unit/issues/Issue6304.hx
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,15 @@ package unit.issues;

class Issue6304 extends unit.Test {
function test() {
// eq(2, main1([], 1));
utest.Assert.pass();
eq(2, main1([], 1));
}

static function main1 (arr:Array<{}>, multiplier:Int) {
// function doSomething <T>() {
// var mul:Int = multiplier;
// arr.push({});
// return arr.length + mul;
// };
// return doSomething();
static function main1(arr:Array<{}>, multiplier:Int) {
function doSomething<T>() {
var mul:Int = multiplier;
arr.push({});
return arr.length + mul;
};
return doSomething();
}
}
Loading

0 comments on commit 096c5a7

Please sign in to comment.