Skip to content

Commit

Permalink
Merge pull request #125 from fink-lang/partial-enhancements
Browse files Browse the repository at this point in the history
feat(partial): improve partial handling
  • Loading branch information
kollhof authored Jul 18, 2021
2 parents 70e5620 + 7383f43 commit cfb9667
Show file tree
Hide file tree
Showing 37 changed files with 445 additions and 201 deletions.
159 changes: 107 additions & 52 deletions package-lock.json

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@
"@fink/cli": "^8.0.0",
"@fink/jest": "^7.2.0",
"@fink/larix": "^19.0.0",
"@fink/loxia": "^21.6.1",
"@fink/loxia": "^22.0.0",
"commitizen": "^4.1.2",
"cz-conventional-changelog": "^3.1.0",
"jest-cli": "^27.0.0",
Expand Down
16 changes: 10 additions & 6 deletions src/lang/arithmitic/init.fnk
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@ babel_types = import '@babel/types'
{binaryExpression, unaryExpression} = babel_types

{add, any} = import '../context.fnk'
{transform} = import '../transform.fnk'

{transform_with_partial_lr, transform_with_partial} = import '../partial/init.fnk'



Expand All @@ -14,19 +15,22 @@ transform_op = rec:
transform_arithmitic = fn {op, left, right}, ctx:
{(op): operator=op} = transform_op

[left_js, right_ctx] = transform left, ctx
[right_js, end_ctx] = transform right, right_ctx
[left_js, right_js, next_ctx, wrap_partial] = transform_with_partial_lr left, right, ctx

js = binaryExpression operator, left_js, right_js

[js, end_ctx]
wrap_partial js, next_ctx





transform_unary = fn {op, right}, ctx:
[right_js, next_ctx] = transform right, ctx
[wrap_partial, right_js, next_ctx] = transform_with_partial right, ctx

js = unaryExpression op, right_js

[js, next_ctx]
wrap_partial js, next_ctx



Expand Down
10 changes: 10 additions & 0 deletions src/lang/arithmitic/init.test.fnk
Original file line number Diff line number Diff line change
Expand Up @@ -19,3 +19,13 @@ describe 'binary', fn:
'
to_match_snapshot


it 'compiles as partial', fn:
expect
fink2js '
add = a + ?
b + ?
-?
'
to_match_snapshot

8 changes: 8 additions & 0 deletions src/lang/arithmitic/init.test.fnk.snap
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,11 @@ export const multi_line_assign = 123 + 234 + (-567 - 1111);
export const group1 = (1 + 2) * 3;
export const group2 = 34234 ** -34234 + 1;"
`;

exports[`binary compiles as partial 1`] = `
"export const add = ˆpartial => a + ˆpartial;
ˆpartial => b + ˆpartial;
ˆpartial => -ˆpartial;"
`;
13 changes: 5 additions & 8 deletions src/lang/assignment/init.fnk
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ babel_types = import '@babel/types'
{transform_left: xform_left} = import '../../js/left.fnk'
{wrap_with_comment_loc} = import '../comments/init.fnk'
{add, any} = import '../context.fnk'
{transform_value} = import '../partial/init.fnk'
{transform} = import '../transform.fnk'


Expand All @@ -31,10 +30,8 @@ has_spread_not_last = fn {left}:
[...exprs, ] = left.exprs

[spread=false] = pipe exprs:
# TODO map ?.type == 'spread'
map fn {type}: type == 'spread'
#TODO filter is_spread
filter fn is_spread: is_spread
# TODO filter ?.type == 'spread'
filter fn {type}: type == 'spread'

spread
else:
Expand Down Expand Up @@ -90,7 +87,7 @@ transform_spread_right = fn expr, ctx:
{left, right} = expr
[items, init_ctx] = unique_ident 'items', ctx
# TODO: wrap declarator?
[init, next_ctx] = transform_value right, init_ctx
[init, next_ctx] = transform right, init_ctx

items_init = wrap_with_comment_loc
variableDeclaration
Expand Down Expand Up @@ -148,7 +145,7 @@ transform_await_right = fn expr, ctx:
[items, iter_ctx] = unique_ident 'items', ctx
[iter, init_ctx] = unique_ident 'iter', iter_ctx

[init, next_ctx] = transform_value right, init_ctx
[init, next_ctx] = transform right, init_ctx

items_init = wrap_with_comment_loc
variableDeclaration 'const', [variableDeclarator items, init]
Expand Down Expand Up @@ -214,7 +211,7 @@ transform_assign_left = fn node, ctx:


transform_assign_right = fn node, ctx:
transform_value node.right, ctx
transform node.right, ctx



Expand Down
1 change: 0 additions & 1 deletion src/lang/block/init.fnk
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,6 @@ block_statement = fn expr, ctx:
[js, next_ctx]



exprs_block = fn exprs, ctx:
pipe exprs:
map_with_ctx block_statement
Expand Down
48 changes: 35 additions & 13 deletions src/lang/call/call.fnk
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
babel_types = import '@babel/types'
{callExpression, identifier} = babel_types
{is_empty, length} = import '@fink/std-lib/iter.fnk'

{map, filter, zip, is_empty, length} = import '@fink/std-lib/iter.fnk'

{transform, map_with_ctx, collect_with_ctx} = import '../transform.fnk'
{transform_with_partial, partial_wrapper, no_wrapper} = import '../partial/init.fnk'



transform_args = fn args, ctx:
transform_multiple_args = fn args, ctx:
pipe args:
map_with_ctx fn expr, arg_ctx:
match expr:
Expand All @@ -21,26 +23,46 @@ transform_args = fn args, ctx:
transform_single_arg = fn [expr], ctx:
match expr:
{type: 'empty'}:
[[], ctx]
# remove in favour of using _ as empty?
[[], ctx]
# TODO: remove in favour of using _ as empty?
{type: 'group', exprs: is_empty ?}:
[[], ctx]
else:
[arg, next_ctx] = transform expr, ctx
[[arg], next_ctx]

transform_multiple_args [expr], ctx


transform_call = fn node, ctx:
[callee, args_ctx] = transform node.callee, ctx

[args, end_ctx] = match node.args:
transform_args = fn args, ctx, default_wrap_partial:
[js_args, next_ctx] = match args:
1 == length ?:
transform_single_arg node.args, args_ctx
transform_single_arg args, ctx
else:
transform_multiple_args args, ctx

[wrap_partial=default_wrap_partial] = pipe zip args, js_args:
filter fn [arg, js_arg]: match arg:
{type: 'partial'}: true
{type: 'spread', right: {type: 'partial'}}: true
{type: 'spread'}: js_arg.is_partial
else: false
map fn: partial_wrapper

[wrap_partial, js_args, next_ctx]




transform_call = fn node, ctx:
[callee, wrap_partial, args, end_ctx] = match node.callee:
# TODO: small pipe foo | bar ?, spam
{type: 'call'}:
[callee, args_ctx] = transform node.callee, ctx
[callee, ...transform_args node.args, args_ctx, no_wrapper]
else:
transform_args node.args, args_ctx
[wrap_partial_callee, callee, args_ctx] = transform_with_partial node.callee, ctx
[callee, ...transform_args node.args, args_ctx, wrap_partial_callee]

js = callExpression callee, args

[js, end_ctx]
wrap_partial js, end_ctx

26 changes: 25 additions & 1 deletion src/lang/call/call.test.fnk
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@

describe 'call', fn:
it 'compiles', fn:

expect
fink2js '
call1 = a ni, x=123, ...x
Expand All @@ -17,4 +16,29 @@ describe 'call', fn:
to_match_snapshot


it 'compiles as partial', fn:
expect
fink2js '
foo ?
foo ?, 123
foo ...?
foo ...?.bar
? 123
? bar, spam
?.bar spam
'
to_match_snapshot


it 'compiles with partial args', fn:
expect
fink2js '
filter ? == 1
filter ? or foo ?
filter not ?
map ?.foo
map ? % 2 == 0
'
to_match_snapshot


24 changes: 24 additions & 0 deletions src/lang/call/call.test.fnk.snap
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,27 @@ export const call4 = a();
export const call5 = a(x => x * 2);
export const call6 = a(foo, undefined, bar);"
`;

exports[`call compiles as partial 1`] = `
"ˆpartial => foo(ˆpartial);
ˆpartial => foo(ˆpartial, 123);
ˆpartial => foo(...ˆpartial);
ˆpartial => foo(...ˆpartial.bar);
ˆpartial => ˆpartial(123);
ˆpartial => ˆpartial(bar, spam);
ˆpartial => ˆpartial.bar(spam);"
`;

exports[`call compiles with partial args 1`] = `
"filter(ˆpartial => ˆpartial === 1);
filter(ˆpartial => ˆpartial || foo(ˆpartial));
filter(ˆpartial => !ˆpartial);
map(ˆpartial => ˆpartial.foo);
map(ˆpartial => ˆpartial % 2 === 0);"
`;
3 changes: 1 addition & 2 deletions src/lang/call/pipe.fnk
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,13 @@ babel_types = import '@babel/types'
{is_empty} = import '@fink/std-lib/iter.fnk'

{assign, lets, undef, unique_ident} = import '../../js/types.fnk'
{transform_value} = import '../partial/init.fnk'
{wrap_with_comment_loc} = import '../comments/init.fnk'
{transform, map_with_ctx, collect_with_ctx} = import '../transform.fnk'



transform_callee = fn result: fn expr, ctx:
[callee, next_ctx] = transform_value expr, ctx
[callee, next_ctx] = transform expr, ctx

js = wrap_with_comment_loc
assign result, callExpression callee, [result]
Expand Down
3 changes: 2 additions & 1 deletion src/lang/call/pipe.test.fnk
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,15 @@
{describe, it, expect, to_match_snapshot} = import '@fink/jest/test.fnk'



describe 'pipe', fn:
it 'compiles', fn:

expect
fink2js '
pipe:
foo
bar ?, {foo, ...?}
bar ?, {foo}
spam
[...?]

Expand Down
5 changes: 2 additions & 3 deletions src/lang/call/pipe.test.fnk.snap
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,7 @@ exports[`pipe compiles 1`] = `
ˆpipe_result_1 = foopipe_result_1);
ˆpipe_result_1 =partial => barpartial, {
foo,
...ˆpartial
foo
}))(ˆpipe_result_1);
ˆpipe_result_1 = spampipe_result_1);
Expand All @@ -21,7 +20,7 @@ exports[`pipe compiles 1`] = `
`;

exports[`small pipe | handles precedence 1`] = `
"export const foo = ˆpartial => matches(rx\`[a-z]\`, ˆpartial)(\`foo\`);
"export const foo = (ˆpartial => matches(rx\`[a-z]\`, ˆpartial))(\`foo\`);
export const bar = [ham(spam), ni(shrub)];"
`;

Expand Down
7 changes: 3 additions & 4 deletions src/lang/comparison/init.fnk
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ babel_types = import '@babel/types'
{binaryExpression, logicalExpression} = babel_types

{add, any} = import '../context.fnk'
{transform} = import '../transform.fnk'
{transform_with_partial_lr} = import '../partial/init.fnk'



Expand All @@ -15,8 +15,7 @@ transform_op = rec:
transform_comp = fn {op, left, right}, ctx:
{(op): operator=op} = transform_op

[bin_left, next_ctx] = transform left, ctx
[bin_right, end_ctx] = transform right, next_ctx
[bin_left, bin_right, next_ctx, wrap_partial] = transform_with_partial_lr left, right, ctx

js = match left:
{op: ? in ['<', '>', '<=', '>=', '==', '!=']}:
Expand All @@ -26,7 +25,7 @@ transform_comp = fn {op, left, right}, ctx:
else:
binaryExpression operator, bin_left, bin_right

[js, end_ctx]
wrap_partial js, next_ctx



Expand Down
11 changes: 11 additions & 0 deletions src/lang/comparison/init.test.fnk
Original file line number Diff line number Diff line change
Expand Up @@ -27,3 +27,14 @@ describe 'comparison', fn:
lteq = a <= b <= c
"
to_match_snapshot


it 'compiles as partials', fn:
expect
fink2js "
1 == len ?
? != 123
? > 3
1 < ? <= 3
"
to_match_snapshot
10 changes: 10 additions & 0 deletions src/lang/comparison/init.test.fnk.snap
Original file line number Diff line number Diff line change
@@ -1,5 +1,15 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`comparison compiles as partials 1`] = `
"ˆpartial => 1 === len(ˆpartial);
ˆpartial => ˆpartial !== 123;
ˆpartial => ˆpartial > 3;
ˆpartial => 1 < ˆpartial && ˆpartial <= 3;"
`;

exports[`comparison compiles combined 1`] = `
"export const lt = a < b && b < c;
export const gt = a > b && b > c;
Expand Down
Loading

0 comments on commit cfb9667

Please sign in to comment.