diff --git a/src/ir/assignment/init.fnk b/src/ir/assignment/init.fnk index dc7b59f..1998cf1 100644 --- a/src/ir/assignment/init.fnk +++ b/src/ir/assignment/init.fnk @@ -197,7 +197,7 @@ transform_assign = fn node, , ctx: {type: 'ident'}: r_ctx = {...ctx, self_name: node.left.value} - [right, l_id, bind_ctx] = transform node.right, node.left.value, r_ctx + [right, l_id, {self_name: _, ...bind_ctx}] = transform node.right, node.left.value, r_ctx end_ctx = bind_x node.left, l_id, bind_ctx [right, end_ctx] diff --git a/src/ir/func/init.test.fnk b/src/ir/func/init.test.fnk index 21e3ba3..6c9a322 100644 --- a/src/ir/func/init.test.fnk +++ b/src/ir/func/init.test.fnk @@ -97,17 +97,8 @@ describe 'func', fn: to_match_snapshot - it 'eliminates tail calls', fn: - expect - fink2lir ' - fun = fn a, b: - match a: - b: a - else: fun a - 1 - ' - to_match_snapshot - +describe 'recursive funcs', fn: it 'compiles recursive calls', fn: expect fink2lir ' diff --git a/src/ir/func/init.test.fnk.snap b/src/ir/func/init.test.fnk.snap index 64330bf..f1b381d 100644 --- a/src/ir/func/init.test.fnk.snap +++ b/src/ir/func/init.test.fnk.snap @@ -290,43 +290,6 @@ rec_e fn exports_0: mod exports_1, drctvs_0, fn mod_0:" `; -exports[`func compiles recursive calls 1`] = ` -" -rec_e fn exports_0: - z (fn args_0, ret_1, fun_0_0: #fn - lst_h args_0, fn a_0: - lst_t args_0, fn tail_0: - lst_h tail_0, fn b_0: - lst_t tail_0, fn tail_1: - id a_0, fn value_0: - id (fn ret_0: #cn - id (fn: #cn - id fun_0_0, fn callee_0: - lst_e fn cargs_0: - id a_0, fn left_0: - int '1', fn right_0: - sub left_0, right_0, fn arg_0: - lst_a cargs_0, arg_0, fn cargs_1: - af callee_0, cargs_1, fn result_1: - cc ret_0, result_1 - ), fn else_0: - id b_0, fn val_0: - eq value_0, val_0, fn cond_0: - id (fn: #cn - id a_0, fn result_2: - cc ret_0, result_2 - ), fn match_res_0: - cif cond_0, match_res_0, else_0 - ), fn match_0: - ac match_0, fn result_0: - cc ret_1, result_0 - ), fn fun_0: - str 'fun', fn key_0: - rec_s exports_0, key_0, fun_0, fn exports_1: - lst_e fn drctvs_0: - mod exports_1, drctvs_0, fn mod_0:" -`; - exports[`func compiles spread 1`] = ` " rec_e fn exports_0: @@ -377,7 +340,7 @@ rec_e fn exports_0: mod exports_1, drctvs_0, fn mod_0:" `; -exports[`func eliminates tail calls 1`] = ` +exports[`recursive funcs compiles recursive calls 1`] = ` " rec_e fn exports_0: z (fn args_0, ret_1, fun_0_0: #fn @@ -413,34 +376,3 @@ rec_e fn exports_0: lst_e fn drctvs_0: mod exports_1, drctvs_0, fn mod_0:" `; - -exports[`func handles mutually recursive calls 1`] = ` -" -rec >> exports_0: - fn args_0, ret_0: - lst_h args_0 >> a_0: - lst_t args_0 >> tail_0: - = bar_0 >> callee_0: - lst >> cargs_0: - = a_0 >> arg_0: - lst_a cargs_0, arg_0 >> cargs_1: - af callee_0, cargs_1 >> result_0: - cc ret_0, result_0 - >> foo_0: - str 'foo' >> key_0 - rec_s exports_0, key_0, foo_0 >> exports_1: - fn args_1, ret_1: - lst_h args_1 >> b_0: - lst_t args_1 >> tail_1: - = foo_0 >> callee_1: - lst >> cargs_2: - = b_0 >> arg_1: - lst_a cargs_2, arg_1 >> cargs_3: - af callee_1, cargs_3 >> result_1: - cc ret_1, result_1 - >> bar_0: - str 'bar' >> key_1 - rec_s exports_1, key_1, bar_0 >> exports_2: - lst >> drctvs_0: - mod exports_2, drctvs_0 >> mod_0:" -`; diff --git a/src/js/call/call.test.fnk b/src/js/call/call.test.fnk index 13bc04c..52d5ddc 100644 --- a/src/js/call/call.test.fnk +++ b/src/js/call/call.test.fnk @@ -3,6 +3,7 @@ describe 'call', fn: + it 'compiles', fn: expect fink2js ' diff --git a/src/js/func/init.test.fnk b/src/js/func/init.test.fnk index 31c3583..448b98b 100644 --- a/src/js/func/init.test.fnk +++ b/src/js/func/init.test.fnk @@ -1,4 +1,4 @@ -{describe, it, expect, to_match_snapshot} = import '@fink/jest/test.fnk' +{skip, describe, it, expect, to_match_snapshot} = import '@fink/jest/test.fnk' {fink2js} = import '../../testing/generate.fnk' @@ -108,3 +108,39 @@ describe 'func', fn: to_match_snapshot + +describe 'recursive functions', fn: + it 'compiles with self reference', fn: + expect + fink2js ' + foo = fn cntr: + match cntr: + 0: [cntr] + 1: [...foo cntr - 1] + else: [cntr, ...foo cntr - 1] + ' + to_match_snapshot + + + it 'compiles to while loop', fn: + expect + fink2js ' + gcd = fn x, y: + match y: + 0: x + else: gcd y, x % y + ' + to_match_snapshot + + + skip.it 'compiles spread', fn: + expect + fink2js ' + fun = fn a, b, ...args: + match a: + b: fun ...args + else: b + ' + to_match_snapshot + + diff --git a/src/js/func/init.test.fnk.snap b/src/js/func/init.test.fnk.snap index 6e84446..0395815 100644 --- a/src/js/func/init.test.fnk.snap +++ b/src/js/func/init.test.fnk.snap @@ -124,3 +124,40 @@ exports[`func compiles no args 1`] = ` export const fun = fun_0;" `; + +exports[`recursive functions compiles to while loop 1`] = ` +"const gcd_0 = (...args_0) => { + gcd_0: do { + const x_0 = args_0[0]; + const y_0 = args_0[1]; + + /* istanbul ignore else */ + if (y_0 === 0) { + return x_0; + } + + args_0 = [y_0, x_0 % y_0]; + continue gcd_0; + } while (true); +}; + +export const gcd = gcd_0;" +`; + +exports[`recursive functions compiles with self reference 1`] = ` +"const foo_0 = cntr_0 => { + /* istanbul ignore else */ + if (cntr_0 === 0) { + return [cntr_0]; + } + + /* istanbul ignore else */ + if (cntr_0 === 1) { + return [...foo_0(cntr_0 - 1)]; + } + + return [cntr_0, ...foo_0(cntr_0 - 1)]; +}; + +export const foo = foo_0;" +`;