diff --git a/src/generate.test.fnk.snap b/src/generate.test.fnk.snap
index 5301c36..bdb9087 100644
--- a/src/generate.test.fnk.snap
+++ b/src/generate.test.fnk.snap
@@ -45,33 +45,31 @@ export default ni_0;"
`;
exports[`source maps compiles to mjs 1`] = `
-"const nanu_0 = 345;
-const foo_0 = {
+"const foo_0 = {
bar: 12345,
- \\"spam ni\\": nanu_0,
- nanu: nanu_0
+ \\"spam ni\\": 345,
+ nanu: 345
};
const bar_0 = \`foo\`;
const ham_0 = \`foo: \${foo_0} bar:\${bar_0}\`;
-const el_0 = bar {123} ;
+const el_0 = bar {123} ;
const ni_0 = spam + fooᜭbar;
-const item_1 = 1;
const item_0 = \`ni\`;
-const a_0 = [item_1, item_0];
-const out_0 = [a_0, item_1, item_0];
+const a_0 = [1, item_0];
+const out_0 = [a_0, 1, item_0];
const func_0 = (x_0, y_0) => {
- return x_0 + y_0 + item_1;
+ return x_0 + y_0 + 1;
};
-const y_1 = func_0(bar_0, a_0, item_1);
+const y_1 = func_0(bar_0, a_0, 1);
spam(ham_0);
const r1_0 = {
foo: foo_0,
bar: bar_0,
spam: 123
};
-export const nanu = nanu_0,
+export const nanu = 345,
foo = foo_0,
bar = bar_0,
ham = ham_0,
@@ -88,9 +86,9 @@ export const nanu = nanu_0,
\\"test.fnk\\"
],
\\"names\\": [
- \\"nanu\\",
\\"foo\\",
\\"bar\\",
+ \\"nanu\\",
\\"ham\\",
\\"el\\",
\\"div\\",
@@ -106,7 +104,7 @@ export const nanu = nanu_0,
\\"y\\",
\\"r1\\"
],
- \\"mappings\\": \\"AAAAA,MAAAA,MAAI,GAAG,GAAPA;AACAC,MAAAA,KAAG,GAAiC;AAA7BC,EAAAA,GAA6B,EAAxB,KAAwB;AAAjB,WAAiB,EAANF,MAAM;AAAAA,EAAAA,IAAI,EAAJA;AAAA,CAApCC;AACAC,MAAAA,KAAG,GAAI,KAAPA;AACAC,MAAAA,KAAG,GAAI,QAAOF,KAAI,QAAOC,KAAG,EAA5BC;AACAC,MAAAA,IAAE,GAAG,KAAK,IAAI,KAAK,CAAC,CAACC,GAAD,CAAKJ,GAAL,CAAS,KAAT,CAAaC,GAAb,CAAaA,CAAAA,KAAG,CAAhB,CAAiBI,IAAjB,CAAsBN,CAAAA,MAAI,CAA1B,GAAf,MAALI;AACAG,MAAAA,IAAE,GAAGD,IAAI,GAAGE,OAAZD;AACK,MAAA,MAAC,GAAD;AAAG,MAAA,MAAI,GAAH,IAAD;AAARE,MAAAA,GAAC,GAAO,CAAH,MAAG,EAAA,MAAI,CAAZA;AAEAC,MAAAA,KAAG,GAAUC,CAANF,GAAME,EAAHC,MAAGD,EAAAA,MAAC,CAAdD;;AACAG,MAAAA,MAAI,GAAG,CAAGC,GAAH,EAAMC,GAAN;AACL,SAAAD,GAAC,GAAGC,GAAJ,GAAQH,MAAR;AADK,CAAPC;;AAEAE,MAAAA,GAAC,GAAGF,MAAI,CAACX,KAAD,EAAMO,GAAN,EAASG,MAAT,CAARG;AACAT,IAAI,CAACH,KAAD,CAAJ;AACAa,MAAAA,IAAE,GAAc;AAAVf,EAAAA,GAAU,EAAVA,KAAU;AAALC,EAAAA,GAAK,EAALA,KAAK;AAAAI,EAAAA,IAAI,EAAE;AAAN,CAAhBU;aAbAhB,IAAI,GAAJA,M;MACAC,GAAG,GAAHA,K;MACAC,GAAG,GAAHA,K;MACAC,GAAG,GAAHA,K;MACAC,EAAE,GAAFA,I;MACAG,EAAE,GAAFA,I;MACAE,CAAC,GAADA,G;MAEAC,GAAG,GAAHA,K;MACAG,IAAI,GAAJA,M;MAEAE,CAAC,GAADA,G;MAEAC,EAAE,GAAFA,I\\"
+ \\"mappings\\": \\"AACAA,MAAAA,KAAG,GAAiC;AAA7BC,EAAAA,GAA6B,EAAxB,KAAwB;AAAjB,WAAiB,EAANC,GAAM;AAAAA,EAAAA,IAAI,EAAJA;AAAA,CAApCF;AACAC,MAAAA,KAAG,GAAI,KAAPA;AACAE,MAAAA,KAAG,GAAI,QAAOH,KAAI,QAAOC,KAAG,EAA5BE;AACAC,MAAAA,IAAE,GAAG,KAAK,IAAI,KAAK,CAAC,CAACC,GAAD,CAAKL,GAAL,CAAS,KAAT,CAAaC,GAAb,CAAaA,CAAAA,KAAG,CAAhB,CAAiBK,IAAjB,CAAsBJ,KAAtB,GAAf,MAALE;AACAG,MAAAA,IAAE,GAAGD,IAAI,GAAGE,OAAZD;AACQ,MAAA,MAAI,GAAH,IAAD;AAARE,MAAAA,GAAC,GAAO,CAAH,CAAG,EAAA,MAAI,CAAZA;AAEAC,MAAAA,KAAG,GAAUC,CAANF,GAAME,EAAHC,CAAGD,EAAAA,MAAC,CAAdD;;AACAG,MAAAA,MAAI,GAAG,CAAGC,GAAH,EAAMC,GAAN;AACL,SAAAD,GAAC,GAAGC,GAAJ,GAAQH,CAAR;AADK,CAAPC;;AAEAE,MAAAA,GAAC,GAAGF,MAAI,CAACZ,KAAD,EAAMQ,GAAN,EAASG,CAAT,CAARG;AACAT,IAAI,CAACH,KAAD,CAAJ;AACAa,MAAAA,IAAE,GAAc;AAAVhB,EAAAA,GAAU,EAAVA,KAAU;AAALC,EAAAA,GAAK,EAALA,KAAK;AAAAK,EAAAA,IAAI,EAAE;AAAN,CAAhBU;aAbAd,IAAI,GAAJA,G;MACAF,GAAG,GAAHA,K;MACAC,GAAG,GAAHA,K;MACAE,GAAG,GAAHA,K;MACAC,EAAE,GAAFA,I;MACAG,EAAE,GAAFA,I;MACAE,CAAC,GAADA,G;MAEAC,GAAG,GAAHA,K;MACAG,IAAI,GAAJA,M;MAEAE,CAAC,GAADA,G;MAEAC,EAAE,GAAFA,I\\"
}
"
`;
diff --git a/src/ir/block/init.fnk b/src/ir/block/init.fnk
index 10b3fc2..d312b69 100644
--- a/src/ir/block/init.fnk
+++ b/src/ir/block/init.fnk
@@ -16,7 +16,11 @@ transform_exprs = fn [expr, ...exprs], res_id, ctx, out=[]:
transform_block = fn expr, res_id, ctx:
- transform_exprs expr.exprs, res_id, ctx
+ {scopes} = ctx
+ block_ctx = {...ctx, scopes: [{}, ...scopes]}
+ [out, next_ctx] = transform_exprs expr.exprs, res_id, block_ctx
+ [out, {...next_ctx, scopes}]
+
add_block = fn ctx:
diff --git a/src/ir/conditionals/match.fnk b/src/ir/conditionals/match.fnk
index 07af853..0e67a52 100644
--- a/src/ir/conditionals/match.fnk
+++ b/src/ir/conditionals/match.fnk
@@ -227,9 +227,12 @@ match_expr = fn val, expr, gen_true, else_id, ctx:
match_res_exprs = fn exprs, name, ret_id, {loc}, ctx:
- [block, res_id, ret_ctx] = transform_exprs exprs, ctx, []
+ {scopes} = ctx
+ cond_ctx = {...ctx, scopes: [{}, ...scopes]}
+ [block, res_id, ret_ctx] = transform_exprs exprs, cond_ctx, []
[ret, , next_ctx] = cc ret_id, res_id, , {loc}, ret_ctx
- cn [], [...block, ...ret], name, {loc}, next_ctx
+ [a, b, todo] = cn [], [...block, ...ret], name, {loc}, next_ctx
+ [a, b, {...todo, scopes}]
diff --git a/src/ir/literals/list.test.fnk b/src/ir/literals/list.test.fnk
index 29fca3f..44917bf 100644
--- a/src/ir/literals/list.test.fnk
+++ b/src/ir/literals/list.test.fnk
@@ -1,5 +1,5 @@
-{fink2lir, fink2js} = import '../../testing/generate.fnk'
{skip, describe, it, expect, to_match_snapshot} = import '@fink/jest/test.fnk'
+{fink2lir, fink2js} = import '../../testing/generate.fnk'
describe 'list', fn:
@@ -124,3 +124,13 @@ describe 'optimizations', fn:
spam = [foo, ...ham]
', {optimize: {refs: true, tails: true, unused: true}}
to_match_snapshot
+
+
+ it 'removes tails', fn:
+ expect
+ fink2lir '
+ [bar, spam, ham] = [...shrub]
+ ni = bar + spam + ham
+ ', {optimize: {refs: true, tails: true, unused: true}}
+ to_match_snapshot
+
diff --git a/src/ir/literals/list.test.fnk.snap b/src/ir/literals/list.test.fnk.snap
index 73eaf4d..f34cd62 100644
--- a/src/ir/literals/list.test.fnk.snap
+++ b/src/ir/literals/list.test.fnk.snap
@@ -87,53 +87,58 @@ rec_e fn exports_0:
exports[`optimizations ignores empty concats 1`] = `
"
rec_e fn exports_0:
- lst_e fn lst_0:
+ tpl, fn lst_0:
lst_c lst_0, b, fn foo_0:
str 'foo', fn key_0:
rec_s exports_0, key_0, foo_0, fn exports_1:
- lst_e fn ham_0:
+ tpl, fn ham_0:
str 'ham', fn key_1:
rec_s exports_1, key_1, ham_0, fn exports_2:
- lst_e fn lst_2:
- lst_a lst_2, foo_0, fn lst_1:
- str 'spam', fn key_2:
- rec_s exports_2, key_2, lst_1, fn exports_3:
- lst_e fn drctvs_0:
- mod exports_3, drctvs_0, fn mod_0:"
+ tpl foo_0, fn spam_0:
+ str 'spam', fn key_2:
+ rec_s exports_2, key_2, spam_0, fn exports_3:
+ tpl, fn drctvs_0:
+ mod exports_3, drctvs_0, fn mod_0:"
`;
exports[`optimizations optimizes spreads 1`] = `
"const y_0 = [1, 2];
-const item_4 = 1;
-log(item_4, y_0, lala, lala, [item_4, 2], 3);
+log(1, y_0, lala, lala, [1, 2], 3);
export const y = y_0;"
`;
+exports[`optimizations removes tails 1`] = `
+"
+rec_e fn exports_0:
+ tpl, fn lst_0:
+ lst_c lst_0, shrub, fn dlst_0:
+ tpl_i dlst_0, 0, fn bar_0:
+ tpl_i dlst_0, 1, fn spam_0:
+ tpl_i dlst_0, 2, fn ham_0:
+ add bar_0, spam_0, fn left_0:
+ add left_0, ham_0, fn ni_0:
+ str 'ni', fn key_0:
+ rec_s exports_0, key_0, ni_0, fn exports_1:
+ tpl, fn drctvs_0:
+ mod exports_1, drctvs_0, fn mod_0:"
+`;
+
exports[`optimizations reuses item refs 1`] = `
"
rec_e fn exports_0:
int '1', fn item_3:
int '2', fn item_2:
int '3', fn item_1:
- lst_e fn lst_5:
- lst_a lst_5, item_2, fn lst_4:
- lst_a lst_4, item_3, fn foo_0:
- str 'foo', fn key_0:
- rec_s exports_0, key_0, foo_0, fn exports_1:
- int '1', fn left_1:
- int '2', fn right_1:
- add left_1, right_1, fn item_7:
- lst_e fn cargs_0:
- lst_a cargs_0, item_3, fn cargs_1:
- lst_a cargs_1, item_2, fn cargs_2:
- lst_a cargs_2, item_1, fn cargs_3:
- lst_a cargs_3, foo_0, fn cargs_4:
- lst_a cargs_4, item_7, fn cargs_5:
- lst_a cargs_5, item_2, fn cargs_6:
- lst_a cargs_6, item_3, fn cargs_7:
- af log, cargs_7, fn mex_3:
- lst_e fn drctvs_0:
- mod exports_1, drctvs_0, fn mod_0:"
+ tpl item_2, item_3, fn foo_0:
+ str 'foo', fn key_0:
+ rec_s exports_0, key_0, foo_0, fn exports_1:
+ int '1', fn left_1:
+ int '2', fn right_1:
+ add left_1, right_1, fn item_7:
+ tpl item_3, item_2, item_1, foo_0, item_7, item_2, item_3, fn cargs_7:
+ af log, cargs_7, fn mex_3:
+ tpl, fn drctvs_0:
+ mod exports_1, drctvs_0, fn mod_0:"
`;
exports[`unpacking list destructures recs 1`] = `
diff --git a/src/ir/literals/record.test.fnk.snap b/src/ir/literals/record.test.fnk.snap
index 8b57304..e559676 100644
--- a/src/ir/literals/record.test.fnk.snap
+++ b/src/ir/literals/record.test.fnk.snap
@@ -12,7 +12,7 @@ rec_e fn exports_0:
rec_s rec_0, key_0, foo-bar, fn foo_0:
str 'foo', fn key_3:
rec_s exports_0, key_3, foo_0, fn exports_1:
- lst_e fn drctvs_0:
+ tpl, fn drctvs_0:
mod exports_1, drctvs_0, fn mod_0:"
`;
diff --git a/src/ir/serialize.fnk b/src/ir/serialize.fnk
index 685c63f..e924a78 100644
--- a/src/ir/serialize.fnk
+++ b/src/ir/serialize.fnk
@@ -8,7 +8,10 @@ a2s = fn [arg=false, ...args], out=[]:
false: match out:
[?]: ' ${out | join ', '}'
else: ''
- else: a2s args, [...out, arg.i]
+ {i: ?}:
+ a2s args, [...out, arg.i]
+ else:
+ a2s args, [...out, arg]
diff --git a/src/js/assignment/init.test.fnk.snap b/src/js/assignment/init.test.fnk.snap
index 1015201..89ea345 100644
--- a/src/js/assignment/init.test.fnk.snap
+++ b/src/js/assignment/init.test.fnk.snap
@@ -1,12 +1,10 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`assignment compiles 1`] = `
-"const assign_0 = 1;
-const no_clash_with_await_0 = 13;
-const multi_line_assign_0 = 123 + 234 + (-567 - 1111);
-export const assign = assign_0,
- assign2 = assign_0,
- no_clash_with_await = no_clash_with_await_0,
+"const multi_line_assign_0 = 123 + 234 + (-567 - 1111);
+export const assign = 1,
+ assign2 = 1,
+ no_clash_with_await = 13,
assign_lang_const1 = true,
assign_lang_const2 = false,
multi_line_assign = multi_line_assign_0,
diff --git a/src/js/conditionals/init.fnk b/src/js/conditionals/init.fnk
index 83b6eee..ecd4f42 100644
--- a/src/js/conditionals/init.fnk
+++ b/src/js/conditionals/init.fnk
@@ -48,6 +48,7 @@ transform_is_rec = fn expr, ctx:
set_js2 expr, js, ctx
+
transform_is_lst = fn expr, ctx:
[{args: [val_id]}] = expr
val = get_js val_id, ctx
diff --git a/src/js/conditionals/match.test.fnk b/src/js/conditionals/match.test.fnk
index 349656b..f3faf16 100644
--- a/src/js/conditionals/match.test.fnk
+++ b/src/js/conditionals/match.test.fnk
@@ -121,6 +121,20 @@ describe 'match', fn:
to_match_snapshot
+ it 'handles scoping', fn:
+ expect
+ fink2js '
+ foo = nanu
+
+ test = fn foo, bar:
+ match foo:
+ bar:
+ foo
+ spam:
+ foo = bar * 2
+ [foo, bar, foo]
+ '
+ to_match_snapshot
describe 'match iterables', fn:
it 'matches values', fn:
diff --git a/src/js/conditionals/match.test.fnk.snap b/src/js/conditionals/match.test.fnk.snap
index ad6b658..994f757 100644
--- a/src/js/conditionals/match.test.fnk.snap
+++ b/src/js/conditionals/match.test.fnk.snap
@@ -6,8 +6,7 @@ exports[`match compiles match with ref 1`] = `
ret_0: {
/* istanbul ignore else */
if (foo === 1) {
- const x_0 = 123;
- ret_0 = [1, x_0, x_0];
+ ret_0 = [1, 123, 123];
/* istanbul ignore next */
break ret_0;
@@ -37,8 +36,7 @@ exports[`match compiles match with ref 2`] = `
ret_0: {
/* istanbul ignore else */
if (foo === 1) {
- const x_0 = 123;
- ret_0 = [1, x_0, x_0];
+ ret_0 = [1, 123, 123];
/* istanbul ignore next */
break ret_0;
@@ -46,8 +44,7 @@ ret_0: {
/* istanbul ignore else */
if (foo === 2) {
- const y_0 = 45678;
- ret_0 = [2, foo, y_0, y_0];
+ ret_0 = [2, foo, 45678, 45678];
/* istanbul ignore next */
break ret_0;
@@ -69,8 +66,7 @@ exports[`match compiles match with ref 3`] = `
ret_0: {
/* istanbul ignore else */
if (foo === 1) {
- const x_0 = 123;
- ret_0 = [1, x_0, x_0];
+ ret_0 = [1, 123, 123];
/* istanbul ignore next */
break ret_0;
@@ -78,15 +74,13 @@ ret_0: {
/* istanbul ignore else */
if (foo === 2) {
- const y_0 = 45678;
- ret_0 = [2, foo, y_0, y_0];
+ ret_0 = [2, foo, 45678, 45678];
/* istanbul ignore next */
break ret_0;
}
- const z_0 = 1234;
- ret_0 = [3, foo, z_0, z_0];
+ ret_0 = [3, foo, 1234, 1234];
/* istanbul ignore next */
break ret_0;
@@ -102,8 +96,7 @@ exports[`match compiles match with ref 4`] = `
ret_0: {
/* istanbul ignore else */
if (foo === 1) {
- const x_0 = 123;
- ret_0 = [1, x_0, x_0];
+ ret_0 = [1, 123, 123];
/* istanbul ignore next */
break ret_0;
@@ -117,8 +110,7 @@ ret_0: {
break ret_0;
}
- const z_0 = 1234;
- ret_0 = [3, foo, z_0, z_0];
+ ret_0 = [3, foo, 1234, 1234];
/* istanbul ignore next */
break ret_0;
@@ -171,6 +163,27 @@ ret_0: {
const mex_0 = ret_0;"
`;
+exports[`match handles scoping 1`] = `
+"const test_0 = (foo_1, bar_0) => {
+ /* istanbul ignore else */
+ if (foo_1 === bar_0) {
+ return foo_1;
+ }
+
+ /* istanbul ignore else */
+ if (foo_1 === spam) {
+ const foo_2 = bar_0 * 2;
+ return [foo_2, bar_0, foo_2];
+ }
+
+ /* istanbul ignore next */
+ return;
+};
+
+export const foo = nanu,
+ test = test_0;"
+`;
+
exports[`match iterables handles non iterables 1`] = `
"import { _in_ } from \\"@fink/js-interop/runtime.js\\";
const hdm_0 = args[0];
@@ -231,7 +244,7 @@ ret_0: {
/* istanbul ignore else */
if (shrub[0] === 1) {
/* istanbul ignore else */
- if ([...shrub.slice(1)].reverse()[0] === 3) {
+ if (shrub.at(-1) === 3) {
ret_0 = foo;
/* istanbul ignore next */
@@ -243,7 +256,7 @@ ret_0: {
/* istanbul ignore else */
if (null != shrub) {
/* istanbul ignore else */
- if ([...shrub].reverse()[0] === 4) {
+ if (shrub.at(-1) === 4) {
ret_0 = foo;
/* istanbul ignore next */
@@ -255,10 +268,8 @@ ret_0: {
if (null != shrub) {
/* istanbul ignore else */
if (shrub[0] === 5) {
- const tail_0 = shrub.slice(1);
-
/* istanbul ignore else */
- if (null != tail_0) {
+ if (null != shrub.slice(1)) {
/* istanbul ignore else */
if (shrub[1] === 6) {
/* istanbul ignore else */
@@ -410,8 +421,6 @@ ret_0: {
if (null != shrub) {
/* istanbul ignore else */
if (shrub[0] === 1) {
- const tail_15 = shrub.slice(1);
-
/* istanbul ignore else */
if (shrub[1] === 2) {
const itm_17 = shrub[2];
@@ -434,7 +443,6 @@ ret_0: {
if (null != shrub) {
/* istanbul ignore else */
if (shrub[0] === 1) {
- const tail_10 = shrub.slice(1);
const itm_11 = shrub[1];
/* istanbul ignore else */
@@ -460,7 +468,6 @@ ret_0: {
if (null != shrub) {
/* istanbul ignore else */
if (shrub[0] === 1) {
- const tail_0 = shrub.slice(1);
const itm_1 = shrub[1];
/* istanbul ignore else */
@@ -475,7 +482,6 @@ ret_0: {
if (itm_3[0] === 3) {
/* istanbul ignore else */
if (itm_3[1] === 4) {
- const tail_1 = tail_0.slice(1);
const itm_6 = shrub[2];
/* istanbul ignore else */
@@ -550,12 +556,11 @@ const mex_0 = ret_0;"
`;
exports[`match matches value assertions 1`] = `
-"const value_0 = 123;
-let ret_0;
+"let ret_0;
ret_0: {
/* istanbul ignore else */
- if (true === !value_0) {
+ if (true === !123) {
ret_0 = ni;
/* istanbul ignore next */
@@ -563,14 +568,14 @@ ret_0: {
}
/* istanbul ignore else */
- if (true === value_0 > 123) {
+ if (true === 123 > 123) {
ret_0 = ni;
/* istanbul ignore next */
break ret_0;
}
- const val_1 = value_0();
+ const val_1 = 123();
/* istanbul ignore else */
if (true === val_1) {
@@ -580,7 +585,7 @@ ret_0: {
break ret_0;
}
- const val_0 = shrub(value_0);
+ const val_0 = shrub(123);
/* istanbul ignore else */
if (true === val_0) {
@@ -591,7 +596,7 @@ ret_0: {
}
/* istanbul ignore else */
- if (undefined !== value_0) {
+ if (undefined !== 123) {
ret_0 = true;
/* istanbul ignore next */
diff --git a/src/js/context.fnk b/src/js/context.fnk
index a73971c..26d3537 100644
--- a/src/js/context.fnk
+++ b/src/js/context.fnk
@@ -18,7 +18,9 @@ with_loc = fn {loc}, expr:
get_js = fn id, ctx:
val = get_value id, ctx
match val:
+ # TODO: use inline: true?
{ignore_refs: true}: with_loc id, val.js
+ {inline: true}: with_loc id, val.js
{inline: false}: ident id
{refs: ? > 1}: ident id
{js: ?}: with_loc id, val.js
diff --git a/src/js/func/init.fnk b/src/js/func/init.fnk
index df76668..e47962f 100644
--- a/src/js/func/init.fnk
+++ b/src/js/func/init.fnk
@@ -4,70 +4,69 @@ types = import '@babel/types'
labeledStatement, doWhileStatement, booleanLiteral
} = types
-{map, is_empty} = import '@fink/std-lib/iter.fnk'
-
-{get_refs, update_value} = import '../../ir/context.fnk'
+{get_refs, dec_ref, update_value} = import '../../ir/context.fnk'
{transform_exprs} = import '../transform.fnk'
-{add, set_js, set_js2, with_loc} = import '../context.fnk'
+{add, set_js, set_js2} = import '../context.fnk'
{ident} = import '../identifier/init.fnk'
+clean_args = fn args, body, ctx, out=[]:
+ match args:
+ {c: ? < 0}:
+ [out, body, ctx]
-clean_args = fn args_id, args, body, ctx:
- fn_args = match [args, get_refs args_id, ctx]:
- [(is_empty ?), ? > 0]:
- [with_loc args_id, restElement ident args_id, ctx]
- else:
- [..., last] = args
- pipe args:
- map fn arg: match arg:
- last: arg
- {type: 'RestElement'}: arg.argument
- else: arg
- [...?]
+ {(args.c): ?}:
+ clean_args {...args, c: args.c - 1}, body, ctx, [args.(args.c), ...out]
- [fn_args, body, ctx]
+ else:
+ # TODO: unique id
+ unused = ident {i: '_${args.c}'}
+ clean_args {...args, c: args.c - 1}, body, ctx, [unused, ...out]
# These are mostly ir transformations, should this be done as a prep step
-split_args_body = fn [expr=false, ...exprs], args_id, ctx, args=[], body=[]:
+split_args_body = fn [expr=false, ...exprs], args_id, ctx, args={c: -1}, body=[]:
match expr:
false:
- [args_id, args, body, ctx]
-
- [{f: 'lst_h', args: [{i: args_id.i}]}]:
- [...prev, ] = match args:
- [?, ?]: args
- else: [...args, ]
-
- [, [head_id]] = expr
- arg = ident head_id
- next_ctx = set_js2 expr, arg, ctx
- split_args_body exprs, args_id, next_ctx, [...prev, arg], body
-
- [{f: 'lst_r', args: [{i: args_id.i}]}]:
- split_args_body [], args_id, ctx, args, [...body, expr, ...exprs]
-
- [{f: 'lst_t', args: [{i: args_id.i}]}]:
- [, [tail_id]] = expr
- arg = ident tail_id
- rest = with_loc arg, restElement arg
-
- match get_refs tail_id, ctx:
- # the rest is used for more than just getting next arg and tail
- ? > 2:
- split_args_body [], tail_id, ctx, [...args, rest], [...body, ...exprs]
- # this is an ignored arg or last spread
+ [args, body, ctx]
+
+ [{f: 'tpl_i', args: [{i: args_id.i}]}]:
+ [{args: [tpl_id, idx]}, [arg_id]] = expr
+
+ match idx:
+ ? < 0:
+ split_args_body exprs, args_id, ctx, args, [...body, expr]
+ else: match args:
+ {foo: true}:
+ [foo] = expr
+ nexpr = [{...foo, args: [tpl_id, idx - args.c - 1]}, [arg_id]]
+ split_args_body exprs, args_id, ctx, args, [...body, nexpr]
+ else:
+ arg = ident arg_id
+ nargs = {...args, c: idx, (idx): arg}
+ next_ctx = pipe ctx:
+ set_js2 expr, arg, ?
+ dec_ref args_id, ?
+ split_args_body exprs, args_id, next_ctx, nargs, body
+
+ [{f: 'tpl_s', args: [{i: args_id.i}]}]:
+ [{args: [args_id, start, end], ...rex}, res] = expr
+ [foo, next_ctx] = match [start, end]:
+ [args.c + 1, 0]:
+ slc = ident args_id
+ next_ctx = set_js2 expr, slc, ctx
+ [[], next_ctx]
else:
- split_args_body exprs, tail_id, ctx, [...args, rest], body
+ [[[{...rex, args: [args_id, start - args.c - 1, end]}, res]], ctx]
+ split_args_body exprs, args_id, next_ctx, {...args, foo: true}, [...body, ...foo]
[{f: ? in ['fn', 'cn']}]:
[foo, bar] = expr
{args: [fargs, fbody]} = foo
- [next_args_id, next_args, next_body, next_ctx] = split_args_body fbody, args_id, ctx, args
+ [next_args, next_body, next_ctx] = split_args_body fbody, args_id, ctx, args
nexpr = [{...foo, args: [fargs, next_body]}, bar]
- split_args_body exprs, next_args_id, next_ctx, next_args, [...body, nexpr]
+ split_args_body exprs, args_id, next_ctx, next_args, [...body, nexpr]
else:
split_args_body exprs, args_id, ctx, args, [...body, expr]
@@ -98,9 +97,13 @@ transform_normal_fn = fn expr, ctx:
split_args_body fn_block, args_id, ?
clean_args ...?
+ all_args = match get_refs args_id, fn_ctx:
+ ? > 0: [...args, restElement ident args_id]
+ else: args
+
[body, next_ctx] = transform_exprs block, fn_ctx
- js = arrowFunctionExpression args, blockStatement body
+ js = arrowFunctionExpression all_args, blockStatement body
set_js2 expr, js, next_ctx
diff --git a/src/js/func/init.test.fnk.snap b/src/js/func/init.test.fnk.snap
index edea596..814567e 100644
--- a/src/js/func/init.test.fnk.snap
+++ b/src/js/func/init.test.fnk.snap
@@ -28,15 +28,15 @@ export const fun = fun_0;"
`;
exports[`func compiles destructuring args in body 1`] = `
-"const fun_0 = (a_0, b_0, ...tail_1) => {
- return [a_0 + b_0, tail_1, tail_1[0], tail_1[1]];
+"const fun_0 = (a_0, b_0, ...args_0) => {
+ return [a_0 + b_0, args_0, args_0[0], args_0[1]];
};
export const fun = fun_0;"
`;
exports[`func compiles empty arg 1`] = `
-"const fun_0 = (a_0, tail_0, tail_1, b_0) => {
+"const fun_0 = (a_0, _1, _2, b_0) => {
return a_0 + b_0;
};
@@ -44,7 +44,7 @@ export const fun = fun_0;"
`;
exports[`func compiles empty arg 2`] = `
-"const fun_0 = (tail_0, tail_1, b_0) => {
+"const fun_0 = (_0, _1, _2, b_0) => {
return b_0;
};
@@ -52,7 +52,7 @@ export const fun = fun_0;"
`;
exports[`func compiles empty arg 3`] = `
-"const fun_0 = (tail_0, a_0) => {
+"const fun_0 = (_0, a_0) => {
return a_0;
};
@@ -95,9 +95,8 @@ export const fun5 = fun5_0;"
`;
exports[`func compiles middle spread 1`] = `
-"const fun_0 = (a_0, b_0, ...tail_1) => {
- const rtail_0 = [...tail_1].reverse();
- return [a_0 + b_0, [...rtail_0.slice(1)].reverse(), rtail_0[0]];
+"const fun_0 = (a_0, b_0, ...args_0) => {
+ return [a_0 + b_0, args_0.slice(0, -1), args_0.at(-1)];
};
export const fun = fun_0;"
@@ -120,16 +119,16 @@ export const fun = fun_0;"
`;
exports[`func compiles spread 1`] = `
-"const fun_0 = (a_0, b_0, ...tail_1) => {
- return [a_0 + b_0, tail_1];
+"const fun_0 = (a_0, b_0, ...args_0) => {
+ return [a_0 + b_0, args_0];
};
export const fun = fun_0;"
`;
exports[`func compiles spread 2`] = `
-"const fun_0 = (a_0, ...tail_0) => {
- return [a_0, tail_0];
+"const fun_0 = (a_0, ...args_0) => {
+ return [a_0, args_0];
};
export const fun = fun_0;"
@@ -159,12 +158,11 @@ export const fun = fun_0;"
exports[`recursive functions compiles spread 1`] = `
"const fun_0 = (...args_0) => {
fun_0: do {
- const tail_0 = args_0.slice(1);
const b_0 = args_0[1];
/* istanbul ignore else */
if (args_0[0] === b_0) {
- args_0 = [...tail_0.slice(1)];
+ args_0 = [...args_0.slice(2)];
continue fun_0;
}
diff --git a/src/js/identifier/init.fnk b/src/js/identifier/init.fnk
index 774847e..3e08a12 100644
--- a/src/js/identifier/init.fnk
+++ b/src/js/identifier/init.fnk
@@ -69,6 +69,14 @@ safe_names = fn [curr=false, ...exprs], renames={}, out=[]:
[nres, next_ren] = rename res, renames
safe_names exprs, next_ren, [...out, [expr, nres]]
+ [{f: ? in ['tpl_i', 'tpl_s']}]:
+ [expr, res] = curr
+ {args: [tpl_id, ...rest_args]} = expr
+ nargs = replace_refs [tpl_id], renames
+ nexpr = {...expr, args: [...nargs, ...rest_args]}
+ [nres, next_ren] = rename res, renames
+ safe_names exprs, next_ren, [...out, [nexpr, nres]]
+
[{f: ? in ['fn', 'cn']}]:
[expr, res] = curr
{args: [args, body]} = expr
diff --git a/src/js/identifier/init.test.fnk.snap b/src/js/identifier/init.test.fnk.snap
index 7841c58..3680a22 100644
--- a/src/js/identifier/init.test.fnk.snap
+++ b/src/js/identifier/init.test.fnk.snap
@@ -6,10 +6,9 @@ export const foo = foo_0;"
`;
exports[`identifiers does not escapes unicode names 1`] = `
-"const ಠ_ಠ_0 = 1234;
-export const ƒ = shrub,
+"export const ƒ = shrub,
π = ni,
- ಠ_ಠ = ಠ_ಠ_0;"
+ ಠ_ಠ = 1234;"
`;
exports[`identifiers escapes hyphenated idents 1`] = `
@@ -18,87 +17,46 @@ export const fooᜭbar = fooᜭbar_0;"
`;
exports[`identifiers escapes reserved JS identifiers 1`] = `
-"const do_0 = 1;
-const if_0 = 1;
-const in_0 = 1;
-const for_0 = 1;
-const let_0 = 1;
-const new_0 = 1;
-const try_0 = 1;
-const var_0 = 1;
-const case_0 = 1;
-const enum_0 = 1;
-const void_0 = 1;
-const with_0 = 1;
-const break_0 = 1;
-const catch_0 = 1;
-const class_0 = 1;
-const const_0 = 1;
-const super_0 = 1;
-const while_0 = 1;
-const yield_0 = 1;
-const delete_0 = 1;
-const export_0 = 1;
-const import_0 = 1;
-const public_0 = 1;
-const return_0 = 1;
-const static_0 = 1;
-const switch_0 = 1;
-const typeof_0 = 1;
-const default_0 = 1;
-const extends_0 = 1;
-const finally_0 = 1;
-const package_0 = 1;
-const private_0 = 1;
-const continue_0 = 1;
-const function_0 = 1;
-const arguments_0 = 1;
-const interface_0 = 1;
-const protected_0 = 1;
-const implements_0 = 1;
-const instanceof_0 = 1;
-const undefined_0 = 1;
-const null_0 = 1;
-export const ˆdo = do_0,
- ˆif = if_0,
- ˆin = in_0,
- ˆfor = for_0,
- ˆlet = let_0,
- ˆnew = new_0,
- ˆtry = try_0,
- ˆvar = var_0,
- ˆcase = case_0,
- ˆenum = enum_0,
- ˆvoid = void_0,
- ˆwith = with_0,
- ˆbreak = break_0,
- ˆcatch = catch_0,
- ˆclass = class_0,
- ˆconst = const_0,
- ˆsuper = super_0,
- ˆwhile = while_0,
- ˆyield = yield_0,
- ˆdelete = delete_0,
- ˆexport = export_0,
- ˆimport = import_0,
- ˆpublic = public_0,
- ˆreturn = return_0,
- ˆstatic = static_0,
- ˆswitch = switch_0,
- ˆtypeof = typeof_0,
- ˆdefault = default_0,
- ˆextends = extends_0,
- ˆfinally = finally_0,
- ˆpackage = package_0,
- ˆprivate = private_0,
- ˆcontinue = continue_0,
- ˆfunction = function_0,
- ˆarguments = arguments_0,
- ˆinterface = interface_0,
- ˆprotected = protected_0,
- ˆimplements = implements_0,
- ˆinstanceof = instanceof_0,
- ˆundefined = undefined_0,
- ˆnull = null_0;
-export default default_0;"
+"export const ˆdo = 1,
+ ˆif = 1,
+ ˆin = 1,
+ ˆfor = 1,
+ ˆlet = 1,
+ ˆnew = 1,
+ ˆtry = 1,
+ ˆvar = 1,
+ ˆcase = 1,
+ ˆenum = 1,
+ ˆvoid = 1,
+ ˆwith = 1,
+ ˆbreak = 1,
+ ˆcatch = 1,
+ ˆclass = 1,
+ ˆconst = 1,
+ ˆsuper = 1,
+ ˆwhile = 1,
+ ˆyield = 1,
+ ˆdelete = 1,
+ ˆexport = 1,
+ ˆimport = 1,
+ ˆpublic = 1,
+ ˆreturn = 1,
+ ˆstatic = 1,
+ ˆswitch = 1,
+ ˆtypeof = 1,
+ ˆdefault = 1,
+ ˆextends = 1,
+ ˆfinally = 1,
+ ˆpackage = 1,
+ ˆprivate = 1,
+ ˆcontinue = 1,
+ ˆfunction = 1,
+ ˆarguments = 1,
+ ˆinterface = 1,
+ ˆprotected = 1,
+ ˆimplements = 1,
+ ˆinstanceof = 1,
+ ˆundefined = 1,
+ ˆnull = 1;
+export default 1;"
`;
diff --git a/src/js/init.fnk b/src/js/init.fnk
index 3223c37..c96ace1 100644
--- a/src/js/init.fnk
+++ b/src/js/init.fnk
@@ -90,6 +90,7 @@ prepare_imports = fn [expr=false, ...exprs], ctx:
[{f: 'imp'}]:
[{args: [sr_id]}] = expr
+ # TODO: is there a better option than setting ref?
next_ctx = update_value sr_id, {refs: 1}, ctx
prepare_imports exprs, next_ctx
@@ -127,6 +128,11 @@ prepare_non_inlinable = fn [expr=false, ...exprs], ctx:
prepare_non_inlinable exprs, next_ctx
+ [{f: ? in ['int', 'float']}]:
+ [, [res_id]] = expr
+ next_ctx = update_value res_id, {inline: true}, ctx
+ prepare_non_inlinable exprs, next_ctx
+
[{f: ? in ['fn', 'cn']}]:
[{args: [, body]}] = expr
prepare_non_inlinable [...body, ...exprs], ctx
diff --git a/src/js/literals/list.fnk b/src/js/literals/list.fnk
index 1186af7..b78a323 100644
--- a/src/js/literals/list.fnk
+++ b/src/js/literals/list.fnk
@@ -10,18 +10,60 @@ types = import '@babel/types'
-set_tail_of = fn items_id, tail_of, {tails={}, ...ctx}:
- {...ctx, tails: {...tails, (items_id.i): tail_of}}
+ids_to_js = fn [id=false, ...rest], ctx, out=[]:
+ match id:
+ false:
+ out
+ {i: '_'}:
+ ids_to_js rest, ctx, [...out, null]
+ else:
+ item = get_js id, ctx
+ # console.log id, arg
+ ids_to_js rest, ctx, [...out, item]
+
+
+
+transform_tpl = fn expr, ctx:
+ [{args: items_ids}] = expr
+ js = arrayExpression
+ ids_to_js items_ids, ctx
+ set_js2 expr, js, ctx
+
+
+
+transform_tpl_i = fn expr, ctx:
+ [{args: [tpl_id, idx]}] = expr
+ js = match idx:
+ ? < 0:
+ callExpression
+ memberExpression
+ get_js tpl_id, ctx
+ identifier 'at'
+ [numericLiteral idx]
+ else:
+ memberExpression
+ get_js tpl_id, ctx
+ numericLiteral idx
+ true
+
+ set_js2 expr, js, ctx
+
-get_tail_of = fn items_id, {tails={}}:
- {(items_id.i): tail_of=[items_id, 0]} = tails
- tail_of
+transform_tpl_s = fn expr, ctx:
+ [{args: [items_id, start_idx, end_idx]}] = expr
+ items = get_js items_id, ctx
+ start = numericLiteral start_idx
+ args = match end_idx:
+ ? >= 0: [start]
+ else: [start, numericLiteral end_idx]
+
+ js = callExpression
+ memberExpression items, identifier 'slice'
+ args
-transform_empty_list = fn expr, ctx:
- js = arrayExpression []
set_js2 expr, js, ctx
@@ -38,7 +80,6 @@ elems_or_spread = fn expr:
transform_list_append = fn expr, ctx:
[{args: [items_id, val_id]}] = expr
elems = elems_or_spread get_js items_id, ctx
-
elem = match val_id:
{i: '_'}: null
else: get_js val_id, ctx
@@ -52,58 +93,21 @@ transform_list_chain = fn expr, ctx:
[{args: [items1_id, items2_id]}] = expr
elems1 = elems_or_spread get_js items1_id, ctx
elems2 = elems_or_spread get_js items2_id, ctx
-
- js = arrayExpression [...elems1, ...elems2]
- set_js2 expr, js, ctx
-
-
-
-transform_list_head = fn expr, ctx:
- [{args: [items_id]}] = expr
- [tail_src, idx] = get_tail_of items_id, ctx
- arr = get_js tail_src, ctx
- js_idx = numericLiteral idx
- js = memberExpression arr, js_idx, true
- set_js2 expr, js, ctx
-
-
-
-transform_list_reverse = fn expr, ctx:
- [{args: [items_id]}] = expr
- arr = get_js items_id, ctx
-
- js = callExpression
- memberExpression
- arrayExpression [spreadElement arr]
- identifier 'reverse'
- []
+ js = arrayExpression [...elems1, ...elems2]
set_js2 expr, js, ctx
-transform_list_tail = fn expr, ctx:
- [{args: [items_id]}, [result_id]] = expr
-
- items = get_js items_id, ctx
- [tail_src, idx] = get_tail_of items_id, ctx
-
- js = callExpression
- memberExpression items, identifier 'slice'
- [numericLiteral 1]
-
- pipe ctx:
- set_tail_of result_id, [tail_src, idx + 1], ?
- set_js2 expr, js, ?
-
-
-
-
add_list = fn ctx:
pipe ctx:
- add 'lst', transform_empty_list
+ add 'tpl', transform_tpl
+ add 'tpl_i', transform_tpl_i
+ add 'tpl_s', transform_tpl_s
+
+ # add 'lst', transform_empty_list
add 'lst_a', transform_list_append
add 'lst_c', transform_list_chain
- add 'lst_h', transform_list_head
- add 'lst_t', transform_list_tail
- add 'lst_r', transform_list_reverse
+ # add 'lst_h', transform_list_head
+ # add 'lst_t', transform_list_tail
+ # add 'lst_r', transform_list_reverse
diff --git a/src/js/literals/list.test.fnk b/src/js/literals/list.test.fnk
index 5d6fa5a..564b1c0 100644
--- a/src/js/literals/list.test.fnk
+++ b/src/js/literals/list.test.fnk
@@ -1,6 +1,7 @@
-{fink2js} = import '../../testing/generate.fnk'
{skip, describe, it, expect, to_match_snapshot} = import '@fink/jest/test.fnk'
+{fink2js} = import '../../testing/generate.fnk'
+
describe 'list', fn:
it 'compiles', fn:
@@ -35,6 +36,7 @@ describe 'list', fn:
spam = [7]
shrub = [...bar, ...spam]
ni = [...nu, na]
+ nie = [...nu, , na]
ham = [...nu, ...na]
'
to_match_snapshot
@@ -50,18 +52,19 @@ describe 'list', fn:
describe 'unpacking list', fn:
- it 'destructures simple', fn:
+ it 'destructures known tuples', fn:
expect
fink2js '
[a, [b, c]] = [1, [2, 3]]
foo = [b, a]
[z] = [1 + 2, 3 * 4]
[x, y] = foo
- out = [a, b, c, foo, z, x, y]
+ [, ...w] = []
+ out = [a, b, c, foo, z, x, y, w]
'
to_match_snapshot
- it 'destructures empty', fn:
+ it 'destructures missing item', fn:
expect
fink2js '
[a, , b] = foo
@@ -70,6 +73,13 @@ describe 'unpacking list', fn:
to_match_snapshot
it 'destructures spread', fn:
+ expect
+ fink2js '
+ [..., a] = foo
+ out = a
+ '
+ to_match_snapshot
+
expect
fink2js '
[a, ..., b] = foo
@@ -98,6 +108,20 @@ describe 'unpacking list', fn:
'
to_match_snapshot
+ expect
+ fink2js '
+ [a, b, ...c, d] = foo
+ out = [a, b, c, d]
+ '
+ to_match_snapshot
+
+ expect
+ fink2js '
+ [a, b, ...c, d, e] = foo
+ out = [a, b, c, d, e]
+ '
+ to_match_snapshot
+
it 'destructures recs', fn:
expect
@@ -122,3 +146,13 @@ describe 'unpacking list', fn:
out = [a, b, c]
'
to_match_snapshot
+
+
+ it 'TODO', fn:
+ expect
+ fink2js "
+ [bar, spam, ham] = [...shrub]
+ ni = bar + spam + ham
+ "
+ to_match_snapshot
+
diff --git a/src/js/literals/list.test.fnk.snap b/src/js/literals/list.test.fnk.snap
index 7f1a51b..81c042a 100644
--- a/src/js/literals/list.test.fnk.snap
+++ b/src/js/literals/list.test.fnk.snap
@@ -30,20 +30,35 @@ export const foo = foo_0,
exports[`list compiles spread 2`] = `
"const foo_0 = [1, 2, 3];
-const bar_0 = [...foo_0, 4, 5, 6];
+const bar_0 = [1, 2, 3, 4, 5, 6];
const spam_0 = [7];
-const shrub_0 = [...bar_0, ...spam_0];
+const shrub_0 = [1, 2, 3, 4, 5, 6, 7];
const ni_0 = [...nu, na];
+const nie_0 = [...nu,, na];
const ham_0 = [...nu, ...na];
export const foo = foo_0,
bar = bar_0,
spam = spam_0,
shrub = shrub_0,
ni = ni_0,
+ nie = nie_0,
ham = ham_0;"
`;
-exports[`unpacking list destructures empty 1`] = `
+exports[`unpacking list TODO 1`] = `
+"const dlst_0 = [...shrub];
+const ni_0 = dlst_0[0] + dlst_0[1] + dlst_0[2];
+export const ni = ni_0;"
+`;
+
+exports[`unpacking list destructures known tuples 1`] = `
+"const foo_0 = [2, 1];
+const out_0 = [1, 2, 3, foo_0, 1 + 2, 2, 1, []];
+export const foo = foo_0,
+ out = out_0;"
+`;
+
+exports[`unpacking list destructures missing item 1`] = `
"const out_0 = [foo[0], foo[2]];
export const out = out_0;"
`;
@@ -54,34 +69,38 @@ const out_0 = [drec_0.a, drec_0.b, ni[1]];
export const out = out_0;"
`;
-exports[`unpacking list destructures simple 1`] = `
-"const item_3 = 1;
-const item_2 = 2;
-const foo_0 = [item_2, item_3];
-const out_0 = [item_3, item_2, 3, foo_0, 1 + 2, item_2, item_3];
-export const foo = foo_0,
- out = out_0;"
-`;
-
exports[`unpacking list destructures spread 1`] = `
-"const out_0 = [foo[0], [...foo.slice(1)].reverse()[0]];
-export const out = out_0;"
+"const a_0 = foo.at(-1);
+export const out = a_0;"
`;
exports[`unpacking list destructures spread 2`] = `
-"const rtail_0 = [...foo.slice(1)].reverse();
-const out_0 = [foo[0], rtail_0[1], rtail_0[0]];
+"const out_0 = [foo[0], foo.at(-1)];
export const out = out_0;"
`;
exports[`unpacking list destructures spread 3`] = `
-"const out_0 = [foo[0], ...foo.slice(1)];
+"const out_0 = [foo[0], foo.at(-2), foo.at(-1)];
export const out = out_0;"
`;
exports[`unpacking list destructures spread 4`] = `
-"const rtail_0 = [...foo.slice(1)].reverse();
-const out_0 = [foo[0], [...rtail_0.slice(1)].reverse(), rtail_0[0]];
+"const out_0 = [foo[0], ...foo.slice(1)];
+export const out = out_0;"
+`;
+
+exports[`unpacking list destructures spread 5`] = `
+"const out_0 = [foo[0], foo.slice(1, -1), foo.at(-1)];
+export const out = out_0;"
+`;
+
+exports[`unpacking list destructures spread 6`] = `
+"const out_0 = [foo[0], foo[1], foo.slice(2, -1), foo.at(-1)];
+export const out = out_0;"
+`;
+
+exports[`unpacking list destructures spread 7`] = `
+"const out_0 = [foo[0], foo[1], foo.slice(2, -2), foo.at(-2), foo.at(-1)];
export const out = out_0;"
`;
diff --git a/src/js/literals/number.test.fnk.snap b/src/js/literals/number.test.fnk.snap
index c3b03e3..b92adf3 100644
--- a/src/js/literals/number.test.fnk.snap
+++ b/src/js/literals/number.test.fnk.snap
@@ -1,30 +1,20 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`numbers transforms floats 1`] = `
-"const x_0 = 1.234578;
-const y_0 = 1.23e+45;
-const z_0 = 1.23e-45;
-const a_0 = 1.23e+45;
-export const x = x_0,
- y = y_0,
- z = z_0,
- a = a_0;"
+"export const x = 1.234578,
+ y = 1.23e+45,
+ z = 1.23e-45,
+ a = 1.23e+45;"
`;
exports[`numbers transforms hex, octet, binary 1`] = `
-"const h_0 = 0x123456789ABCDEF0;
-const o_0 = 0o12345670;
-const b_0 = 0b01010;
-export const h = h_0,
- o = o_0,
- b = b_0;"
+"export const h = 0x123456789ABCDEF0,
+ o = 0o12345670,
+ b = 0b01010;"
`;
exports[`numbers transforms integers 1`] = `
-"const x_0 = 1234578;
-const y_0 = 0123;
-const z_0 = 123_456_789;
-export const x = x_0,
- y = y_0,
- z = z_0;"
+"export const x = 1234578,
+ y = 0123,
+ z = 123_456_789;"
`;
diff --git a/src/js/module/init.test.fnk.snap b/src/js/module/init.test.fnk.snap
index e2550f3..0ed37db 100644
--- a/src/js/module/init.test.fnk.snap
+++ b/src/js/module/init.test.fnk.snap
@@ -2,8 +2,7 @@
exports[`module handles directives 1`] = `
"#!/usr/bin/env node
-const foo_0 = 1234;
-export const foo = foo_0;"
+export const foo = 1234;"
`;
exports[`module handles exports 1`] = `
@@ -15,15 +14,12 @@ const π_0 = () => {
return true;
};
-const foo_bar_0 = 1234;
-const fooᜭbar_0 = 1234;
-const default_0 = 456;
export const ˆdelete = delete_0,
π = π_0,
- foo_bar = foo_bar_0,
- fooᜭbar = fooᜭbar_0,
- ˆdefault = default_0;
-export default default_0;"
+ foo_bar = 1234,
+ fooᜭbar = 1234,
+ ˆdefault = 456;
+export default 456;"
`;
exports[`module handles exports 2`] = `
@@ -35,15 +31,12 @@ const π_0 = () => {
return true;
};
-const foo_bar_0 = 1234;
-const fooᜭbar_0 = 1234;
-const default_0 = 456;
-module.exports = default_0;
+module.exports = 456;
exports.ˆdelete = delete_0;
exports.π = π_0;
-exports.foo_bar = foo_bar_0;
-exports.fooᜭbar = fooᜭbar_0;
-exports.ˆdefault = default_0;"
+exports.foo_bar = 1234;
+exports.fooᜭbar = 1234;
+exports.ˆdefault = 456;"
`;
exports[`module handles side effects 1`] = `
diff --git a/src/js/transform.fnk b/src/js/transform.fnk
index 87bd877..17b8bd2 100644
--- a/src/js/transform.fnk
+++ b/src/js/transform.fnk
@@ -72,7 +72,7 @@ transform_body_expr = fn expr, ctx:
[[js], next_ctx]
- [, {refs: ? > 1}]:
+ [, {inline: ? != true, refs: ? > 1}]:
val = get_js_literal res_id, next_ctx
js = match val:
{type: 'VariableDeclaration'}:
diff --git a/src/optimize/init.test.fnk b/src/optimize/init.test.fnk
index 2c2337d..173dd8f 100644
--- a/src/optimize/init.test.fnk
+++ b/src/optimize/init.test.fnk
@@ -86,11 +86,14 @@ describe 'optimize', fn:
nanu = fn foo, bar:
foo + bar + ham
- ni = fn spam, ham, ni:
- [spam, ham, ni]
+ ni = fn foo, bar, spam, ham, ni:
+ [foo, bar, spam, ham, ni]
- na = fn spam, ham, ni:
- [spam, ham, ni]
+ na = fn foo, bar, spam, ham, ni:
+ [foo, bar, spam, ham, ni]
+
+ nu = fn foo, bar, spam, ham, ni:
+ [foo, bar, spam, ham, ni]
', {optimize: {refs: true, tails: true, unused: true, names: true}}
to_match_snapshot
diff --git a/src/optimize/init.test.fnk.snap b/src/optimize/init.test.fnk.snap
index 2433a57..0ac37a3 100644
--- a/src/optimize/init.test.fnk.snap
+++ b/src/optimize/init.test.fnk.snap
@@ -9,42 +9,37 @@ rec_e fn exports_0:
int '2', fn b_0:
str 'b', fn key_1:
rec_s exports_1, key_1, b_0, fn exports_2:
- lst_e fn lst_1:
- lst_a lst_1, a_0, fn lst_0:
- lst_a lst_0, b_0, fn c_0:
- str 'c', fn key_2:
- rec_s exports_2, key_2, c_0, fn exports_3:
- add a_0, b_0, fn f_0:
- str 'f', fn key_3:
- rec_s exports_3, key_3, f_0, fn exports_4:
- lst_e fn drctvs_0:
- mod exports_4, drctvs_0, fn mod_0:"
+ tpl a_0, b_0, fn c_0:
+ str 'c', fn key_2:
+ rec_s exports_2, key_2, c_0, fn exports_3:
+ add a_0, b_0, fn f_0:
+ str 'f', fn key_3:
+ rec_s exports_3, key_3, f_0, fn exports_4:
+ tpl, fn drctvs_0:
+ mod exports_4, drctvs_0, fn mod_0:"
`;
exports[`optimize optimizes ac ...>> res: cc ..., res 1`] = `
"
rec_e fn exports_0:
z (fn args_0, ret_1, gcd_0_0: #fn
- lst_h args_0, fn x_0:
- lst_t args_0, fn tail_0:
- lst_h tail_0, fn y_0:
- id (fn: #cn
- lst_e fn cargs_0:
- lst_a cargs_0, y_0, fn cargs_1:
- rem x_0, y_0, fn arg_1:
- lst_a cargs_1, arg_1, fn cargs_2:
- cf gcd_0_0, cargs_2
- ), fn else_0:
- int '0', fn val_0:
- eq y_0, val_0, fn cond_0:
- id (fn: #cn
- cc ret_1, x_0
- ), fn match_res_0:
- cif cond_0, match_res_0, else_0
+ tpl_i args_0, 0, fn x_0:
+ tpl_i args_0, 1, fn y_0:
+ id (fn: #cn
+ rem x_0, y_0, fn arg_1:
+ tpl y_0, arg_1, fn cargs_2:
+ cf gcd_0_0, cargs_2
+ ), fn else_0:
+ int '0', fn val_0:
+ eq y_0, val_0, fn cond_0:
+ id (fn: #cn
+ cc ret_1, x_0
+ ), fn match_res_0:
+ cif cond_0, match_res_0, else_0
), fn gcd_0:
str 'gcd', fn key_0:
rec_s exports_0, key_0, gcd_0, fn exports_1:
- lst_e fn drctvs_0:
+ tpl, fn drctvs_0:
mod exports_1, drctvs_0, fn mod_0:"
`;
@@ -55,45 +50,37 @@ rec_e fn exports_0:
str 'ni', fn key_0:
rec_s exports_0, key_0, ni_0, fn exports_1:
id (fn args_0, ret_1: #fn
- lst_h args_0, fn foo_0:
- lst_t args_0, fn tail_0:
- lst_h tail_0, fn bar_0:
- id (fn ret_0: #cn
- id (fn: #cn
- lst_e fn lst_1:
- int '2', fn item_1:
- lst_a lst_1, item_1, fn lst_0:
- int '2', fn right_0:
- mul ni_0, right_0, fn item_0:
- lst_a lst_0, item_0, fn result_1:
- cc ret_0, result_1
- ), fn else_0:
- eq foo_0, bar_0, fn cond_0:
- id (fn: #cn
- lst_e fn lst_3:
- int '1', fn item_3:
- lst_a lst_3, item_3, fn lst_2:
- lst_a lst_2, ni_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 dlst_0:
- lst_h dlst_0, fn spam_1:
- lst_t dlst_0, fn tail_2:
- lst_h tail_2, fn ham_0:
- add spam_1, ni_0, fn left_1:
- add left_1, ham_0, fn result_3:
- cc ret_1, result_3
+ tpl_i args_0, 0, fn foo_0:
+ tpl_i args_0, 1, fn bar_0:
+ id (fn ret_0: #cn
+ id (fn: #cn
+ int '2', fn item_1:
+ int '2', fn right_0:
+ mul ni_0, right_0, fn item_0:
+ tpl item_1, item_0, fn result_1:
+ cc ret_0, result_1
+ ), fn else_0:
+ eq foo_0, bar_0, fn cond_0:
+ id (fn: #cn
+ int '1', fn item_3:
+ tpl item_3, ni_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 dlst_0:
+ tpl_i dlst_0, 0, fn spam_1:
+ tpl_i dlst_0, 1, fn ham_0:
+ add spam_1, ni_0, fn left_1:
+ add left_1, ham_0, fn result_3:
+ cc ret_1, result_3
), fn spam_0:
str 'spam', fn key_1:
rec_s exports_1, key_1, spam_0, fn exports_2:
- lst_e fn cargs_0:
- lst_a cargs_0, foo, fn cargs_1:
- lst_a cargs_1, bar, fn cargs_2:
- af spam_0, cargs_2, fn mex_0:
- lst_e fn drctvs_0:
- mod exports_2, drctvs_0, fn mod_0:"
+ tpl foo, bar, fn cargs_2:
+ af spam_0, cargs_2, fn mex_0:
+ tpl, fn drctvs_0:
+ mod exports_2, drctvs_0, fn mod_0:"
`;
exports[`optimize optimizes functions 1`] = `
@@ -103,21 +90,18 @@ rec_e fn exports_0:
str 'ni', fn key_0:
rec_s exports_0, key_0, ni_0, fn exports_1:
id (fn args_0, ret_0: #fn
- lst_h args_0, fn foo_0:
- lst_t args_0, fn tail_0:
- lst_h tail_0, fn bar_0:
- add bar_0, foo_0, fn left_0:
- add left_0, ni_0, fn result_1:
- cc ret_0, result_1
+ tpl_i args_0, 0, fn foo_0:
+ tpl_i args_0, 1, fn bar_0:
+ add bar_0, foo_0, fn left_0:
+ add left_0, ni_0, fn result_1:
+ cc ret_0, result_1
), fn spam_0:
str 'spam', fn key_1:
rec_s exports_1, key_1, spam_0, fn exports_2:
- lst_e fn cargs_0:
- lst_a cargs_0, foo, fn cargs_1:
- lst_a cargs_1, bar, fn cargs_2:
- af spam_0, cargs_2, fn mex_0:
- lst_e fn drctvs_0:
- mod exports_2, drctvs_0, fn mod_0:"
+ tpl foo, bar, fn cargs_2:
+ af spam_0, cargs_2, fn mex_0:
+ tpl, fn drctvs_0:
+ mod exports_2, drctvs_0, fn mod_0:"
`;
exports[`optimize optimizes using short names 1`] = `
@@ -130,87 +114,78 @@ rec_e fn a:
str 'foobar', fn f:
rec_s d, f, e, fn g:
id (fn h, i: #fn
- lst_h h, fn j:
- lst_t h, fn k:
- lst_h k, fn l:
- add j, l, fn m:
- cc i, m
- ), fn n:
- str 'shrurb', fn o:
- rec_s g, o, n, fn p:
- id (fn q, r: #fn
- lst_h q, fn s:
- lst_t q, fn t:
- lst_h t, fn u:
- add s, u, fn v:
- add v, b, fn w:
- cc r, w
- ), fn x:
- str 'nanu', fn y:
- rec_s p, y, x, fn z:
- id (fn A, B: #fn
- lst_h A, fn C:
- lst_t A, fn D:
- lst_h D, fn E:
- lst_t D, fn F:
- lst_h F, fn G:
- lst_e fn H:
- lst_a H, C, fn I:
- lst_a I, E, fn J:
- lst_a J, G, fn K:
- cc B, K
- ), fn L:
- str 'ni', fn M:
- rec_s z, M, L, fn N:
- id (fn O, P: #fn
- lst_h O, fn Q:
- lst_t O, fn R:
- lst_h R, fn S:
- lst_t R, fn T:
- lst_h T, fn U:
- lst_e fn V:
- lst_a V, Q, fn W:
- lst_a W, S, fn X:
- lst_a X, U, fn Y:
- cc P, Y
- ), fn Z:
- str 'na', fn aa:
- rec_s N, aa, Z, fn ab:
- lst_e fn ac:
- mod ab, ac, fn ad:"
+ tpl_i h, 0, fn j:
+ tpl_i h, 1, fn k:
+ add j, k, fn l:
+ cc i, l
+ ), fn m:
+ str 'shrurb', fn n:
+ rec_s g, n, m, fn o:
+ id (fn p, q: #fn
+ tpl_i p, 0, fn r:
+ tpl_i p, 1, fn s:
+ add r, s, fn t:
+ add t, b, fn u:
+ cc q, u
+ ), fn v:
+ str 'nanu', fn w:
+ rec_s o, w, v, fn x:
+ id (fn y, z: #fn
+ tpl_i y, 0, fn A:
+ tpl_i y, 1, fn B:
+ tpl_i y, 2, fn C:
+ tpl_i y, 3, fn D:
+ tpl_i y, 4, fn E:
+ tpl A, B, C, D, E, fn F:
+ cc z, F
+ ), fn G:
+ str 'ni', fn H:
+ rec_s x, H, G, fn I:
+ id (fn J, K: #fn
+ tpl_i J, 0, fn L:
+ tpl_i J, 1, fn M:
+ tpl_i J, 2, fn N:
+ tpl_i J, 3, fn O:
+ tpl_i J, 4, fn P:
+ tpl L, M, N, O, P, fn Q:
+ cc K, Q
+ ), fn R:
+ str 'na', fn S:
+ rec_s I, S, R, fn T:
+ id (fn U, V: #fn
+ tpl_i U, 0, fn W:
+ tpl_i U, 1, fn X:
+ tpl_i U, 2, fn Y:
+ tpl_i U, 3, fn Z:
+ tpl_i U, 4, fn aa:
+ tpl W, X, Y, Z, aa, fn ab:
+ cc V, ab
+ ), fn ac:
+ str 'nu', fn ad:
+ rec_s T, ad, ac, fn ae:
+ tpl, fn af:
+ mod ae, af, fn ag:"
`;
exports[`optimize optimizes values 1`] = `
"
rec_e fn exports_0:
- lst_e fn lst_1:
- int '1', fn item_1:
- lst_a lst_1, item_1, fn lst_0:
- int '2', fn item_0:
- lst_a lst_0, item_0, fn y_0:
- str 'y', fn key_0:
- rec_s exports_0, key_0, y_0, fn exports_1:
- int '3', fn x_0:
- str 'x', fn key_1:
- rec_s exports_1, key_1, x_0, fn exports_2:
- int '4', fn item_6:
- int '5', fn item_4:
- int '1', fn item_9:
- int '2', fn item_8:
- int '3', fn item_7:
- lst_e fn sp_0_1:
- lst_a sp_0_1, item_9, fn sp_0_0:
- lst_a sp_0_0, item_8, fn sp_0:
- lst_e fn cargs_0:
- lst_a cargs_0, item_6, fn cargs_1:
- lst_a cargs_1, x_0, fn cargs_2:
- lst_a cargs_2, item_4, fn cargs_3:
- lst_a cargs_3, y_0, fn cargs_4:
- lst_a cargs_4, item_7, fn cargs_5:
- lst_a cargs_5, sp_0, fn cargs_6:
- lst_a cargs_6, item_9, fn cargs_7:
- lst_a cargs_7, lala, fn cargs_8:
- af log, cargs_8, fn mex_5:
- lst_e fn drctvs_0:
- mod exports_2, drctvs_0, fn mod_0:"
+ int '1', fn item_1:
+ int '2', fn item_0:
+ tpl item_1, item_0, fn y_0:
+ str 'y', fn key_0:
+ rec_s exports_0, key_0, y_0, fn exports_1:
+ int '3', fn x_0:
+ str 'x', fn key_1:
+ rec_s exports_1, key_1, x_0, fn exports_2:
+ int '4', fn item_6:
+ int '5', fn item_4:
+ int '1', fn item_9:
+ int '2', fn item_8:
+ int '3', fn item_7:
+ tpl item_9, item_8, fn sp_0:
+ tpl item_6, x_0, item_4, y_0, item_7, sp_0, item_9, lala, fn cargs_8:
+ af log, cargs_8, fn mex_5:
+ tpl, fn drctvs_0:
+ mod exports_2, drctvs_0, fn mod_0:"
`;
diff --git a/src/optimize/refs.fnk b/src/optimize/refs.fnk
index 87a324e..98210ca 100644
--- a/src/optimize/refs.fnk
+++ b/src/optimize/refs.fnk
@@ -1,6 +1,6 @@
{reverse} = import '@fink/std-lib/iter.fnk'
-{update_value, get_value, unique_name} = import '../ir/context.fnk'
+{update_value, get_value} = import '../ir/context.fnk'
@@ -39,23 +39,29 @@ add_alias = fn id, target, ctx:
optimize_lst = fn [expr, res], ctx:
[res_id] = res
- opt_expr = optimize_args expr, ctx
- next_ctx = update_value res_id, {empty_tpl: true, item_aliases: []}, ctx
+ opt_expr = {...expr, f: 'tpl', args: []}
+ next_ctx = update_value res_id, {type: 'tpl', items: []}, ctx
[[opt_expr, res], next_ctx]
-add_lst_aliases = fn {args: [lst_id, val_id]}, res_id, ctx:
- {item_aliases=[]} = get_value lst_id, ctx
- update_value res_id, {item_aliases: [...item_aliases, val_id]}, ctx
-
-
-
optimize_lst_a = fn [expr, res], ctx:
[res_id] = res
opt_expr = optimize_args expr, ctx
- next_ctx = add_lst_aliases opt_expr, res_id, ctx
- [[[opt_expr, res]], next_ctx]
+ {args: [lst_id, val_id]} = opt_expr
+ info = get_value lst_id, ctx
+
+ match info:
+ {type: 'tpl', items: ?}:
+ {items} = get_value lst_id, ctx
+
+ next_ctx = update_value res_id, {type: 'tpl', items: [...items, val_id]}, ctx
+ expr = {...opt_expr, f: 'tpl', args: [...items, val_id]}
+ [[[expr, res]], next_ctx]
+
+ else:
+ next_ctx = update_value res_id, {type: 'lst'}, ctx
+ [[[opt_expr, res]], next_ctx]
@@ -65,12 +71,23 @@ optimize_lst_h = fn [expr, res], ctx:
{args: [lst_id]} = opt_expr
info = get_value lst_id, ctx
match info:
- {item_aliases: [?]}:
- {item_aliases: [val_id]} = info
+ {type: 'tpl', items: [?]}:
+ {items: [val_id]} = info
next_ctx = add_alias res_id, val_id, ctx
[[], next_ctx]
+
+ {type: 'tpl', slice_of: ?}:
+ [lst_id, start, end, inc] = info.slice_of
+ idx = match inc:
+ 1: start
+ else: end - 1
+ [[[{...opt_expr, f: 'tpl_i', args: [lst_id, idx]}, res]], ctx]
+
+ {type: 'tpl'}:
+ [[[{...opt_expr, f: 'tpl_i', args: [lst_id, 0]}, res]], ctx]
+
else:
- [[[opt_expr, res]], ctx]
+ [[[{...opt_expr, f: 'tpl_i', args: [lst_id, 0]}, res]], ctx]
@@ -78,21 +95,38 @@ optimize_lst_t = fn [expr, res], ctx:
[res_id] = res
opt_expr = optimize_args expr, ctx
{args: [lst_id]} = opt_expr
+
info = get_value lst_id, ctx
match info:
- {item_aliases: [?]}:
- {item_aliases: [, ...item_aliases]} = info
- next_ctx = update_value res_id, {item_aliases}, ctx
- [[[opt_expr, res]], next_ctx]
- else:
- [[[opt_expr, res]], ctx]
+ {type: 'tpl', items: [?]}:
+ {items: [, ...items]} = info
+ foo = {...opt_expr, f: 'tpl', args: items}
+ next_ctx = update_value res_id, {type: 'tpl', items}, ctx
+ [[[foo, res]], next_ctx]
+
+ {type: 'tpl', items: ?}:
+ next_ctx = add_alias res_id, lst_id, ctx
+ [[], next_ctx]
+ {type: 'tpl', slice_of: ?}:
+ [lst_id, start, end, inc] = info.slice_of
+ args = match inc:
+ 1: [lst_id, start + 1, end]
+ else: [lst_id, start, end - 1]
+ next_ctx = update_value res_id, {type: 'tpl', slice_of: [...args, inc]}, ctx
+ foo = {...opt_expr, f: 'tpl_s', args}
+ [[[foo, res]], next_ctx]
-is_empty_lst = fn id, ctx:
- match get_value id, ctx:
- {empty_tpl: true}: true
- else: false
+ {type: 'tpl'}:
+ next_ctx = update_value res_id, {type: 'tpl', slice_of: [lst_id, 1, 0, 1]}, ctx
+ foo = {...opt_expr, f: 'tpl_s', args: [lst_id, 1, 0]}
+ [[[foo, res]], next_ctx]
+
+ else:
+ next_ctx = update_value res_id, {type: 'tpl', slice_of: [lst_id, 1, 0, 1]}, ctx
+ foo = {...opt_expr, f: 'tpl_s', args: [lst_id, 1, 0]}
+ [[[foo, res]], next_ctx]
@@ -100,25 +134,21 @@ optimize_lst_c = fn [expr, res], ctx:
[res_id] = res
opt_expr = optimize_args expr, ctx
{args: [lst1_id, lst2_id]} = opt_expr
-
- match ctx:
- is_empty_lst lst2_id, ?:
- next_ctx = add_alias res_id, lst1_id, ctx
- [[], next_ctx]
- else:
- [[[opt_expr, res]], ctx]
-
-
-
-create_lst = fn [id=false, ...ids], lst_id, tmp_id, ctx, out=[]:
- match id:
- false:
- [[[{f: 'lst', args: [], loc: lst_id.loc}, [tmp_id]], ...out], ctx]
+ info1 = get_value lst1_id, ctx
+ info2 = get_value lst2_id, ctx
+
+ match [info1, info2]:
+ [{type: 'tpl', items: ?}, {type: 'tpl', items: ?}]:
+ {items: [...items1]} = info1
+ {items: [...items2]} = info2
+ items = [...items1, ...items2]
+ next_ctx = update_value res_id, {type: 'tpl', items}, ctx
+ foo = {...opt_expr, f: 'tpl', args: items}
+ [[[foo, res]], next_ctx]
else:
- [next_tmp_id, end_ctx] = unique_name lst_id.i, lst_id, ctx
- lst = [{f: 'lst_a', args: [next_tmp_id, id], loc: id.loc}, [tmp_id]]
- create_lst ids, lst_id, next_tmp_id, end_ctx, [lst, ...out]
+ next_ctx = update_value res_id, {type: 'tpl'}, ctx
+ [[[opt_expr, res]], next_ctx]
@@ -134,22 +164,47 @@ optimize_lst_r = fn [expr, res], ctx:
next_ctx = add_alias res_id, tpr, ctx
[[], next_ctx]
- {item_aliases: ?}:
- {item_aliases: rev_aliases} = info
+ {type: 'tpl', items: ?}:
# find existing tpl instead of creating
- item_aliases = reverse rev_aliases
- lst_ctx = update_value res_id, {item_aliases, tpr: lst_id}, ctx
- create_lst rev_aliases, res_id, res_id, lst_ctx
+ items = reverse info.items
+ next_ctx = update_value res_id, {type: 'tpl', items, tpr: lst_id}, ctx
+ foo = {...opt_expr, f: 'tpl', args: items}
+ [[[foo, res]], next_ctx]
+
+ {type: 'tpl', slice_of: ?}:
+ [tpl_id, start_idx, end_idx, inc] = info.slice_of
+
+ slice_of = match inc:
+ 1: [tpl_id, start_idx, end_idx, -inc]
+ else: [tpl_id, start_idx, end_idx, -inc]
+
+ next_ctx = update_value res_id, {type: 'tpl', slice_of, tpr: lst_id}, ctx
+
+ match inc:
+ 1:
+ [[[opt_expr, res]], next_ctx]
+ else:
+ foo = {...opt_expr, f: 'tpl_s', args: [tpl_id, start_idx, end_idx]}
+ [[[foo, res]], next_ctx]
else:
- next_ctx = update_value res_id, {tpr: lst_id}, ctx
+ slice_of = [lst_id, 0, 0, -1]
+ next_ctx = update_value res_id, {type: 'tpl', slice_of, tpr: lst_id}, ctx
[[[opt_expr, res]], next_ctx]
optimize_body = fn [expr, res], ctx, optimize_refs:
{args: [args, body]} = expr
- [o_body, next_ctx] = optimize_refs body, ctx, []
+
+ body_ctx = match expr:
+ {f: 'fn'}:
+ [args_id] = args
+ update_value args_id, {type: 'tpl'}, ctx
+ else:
+ ctx
+
+ [o_body, next_ctx] = optimize_refs body, body_ctx, []
[[[{...expr, args: [args, o_body]}, res]], next_ctx]
diff --git a/src/optimize/short-ids.fnk b/src/optimize/short-ids.fnk
index 4e7953e..28f5218 100644
--- a/src/optimize/short-ids.fnk
+++ b/src/optimize/short-ids.fnk
@@ -52,6 +52,13 @@ shorten_names = fn [curr=false, ...rest], renames={}, out=[]:
[nres, next_ren] = rename res, renames
shorten_names rest, next_ren, [...out, [expr, nres]]
+ [{f: ? in ['tpl_i', 'tpl_s']}]:
+ [expr, res] = curr
+ {args: [tpl_id, ...args]} = expr
+ [ntpl_id] = replace_refs [tpl_id], renames
+ [nres, next_ren] = rename res, renames
+ shorten_names rest, next_ren, [...out, [{...expr, args: [ntpl_id, ...args]}, nres]]
+
[{f: ? in ['fn', 'cn']}]:
[expr, res] = curr
[args, body] = expr.args
diff --git a/src/optimize/unused.fnk b/src/optimize/unused.fnk
index 0290fa9..424934a 100644
--- a/src/optimize/unused.fnk
+++ b/src/optimize/unused.fnk
@@ -8,6 +8,9 @@
get_ref_args = fn [{f: op, args}]:
match op:
? in ['int', 'float', 'str']: []
+ ? in ['tpl_i', 'tpl_s']:
+ [tpl_id] = args
+ [tpl_id]
else: args