Skip to content

Commit

Permalink
Merge pull request #98 from fink-lang/custom-built-ins
Browse files Browse the repository at this point in the history
feat(iterables): allow overriding  builtins implementation
  • Loading branch information
kollhof authored Nov 5, 2020
2 parents bbeab51 + b0a975c commit 0f88339
Show file tree
Hide file tree
Showing 29 changed files with 15,364 additions and 515 deletions.
15,085 changes: 14,667 additions & 418 deletions package-lock.json

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions src/generate.fnk
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,10 @@ babel_traverse = import '@babel/traverse'


transform_file = fn fink_ast, code, filename, options:
ctx = init_ctx code, filename
ctx = init_ctx code, filename, options

[error, [js_ast]=[]] = try:
transform fink_ast, {...ctx, options}
transform fink_ast, ctx

extras = match options:
{module_type: 'cjs'}: module_transforms
Expand Down
4 changes: 2 additions & 2 deletions src/lang/block/init.fnk
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ babel_types = import '@babel/types'

{add, any} = import '../context.fnk'
{wrap_with_comment_loc} = import '../comments/init.fnk'
{transform, map_with_ctx} = import '../transform.fnk'
{transform, map_with_ctx, collect_with_ctx} = import '../transform.fnk'



Expand All @@ -34,7 +34,7 @@ block_statement = fn expr, ctx:
exprs_block = fn exprs, ctx:
pipe exprs:
map_with_ctx ctx, block_statement

collect_with_ctx ctx


transform_block = fn node, ctx:
Expand Down
100 changes: 100 additions & 0 deletions src/lang/builtins.fnk
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@



add_builtin = fn name, ctx:
{builtins} = ctx
rec:
...ctx
builtins: rec:
...builtins
names: [...builtins.names, name]




add_default_builtin = fn name, uri, ctx:
{builtins} = ctx
rec:
...ctx
builtins: rec:
...builtins
defaults: rec: ...builtins.defaults, (name): uri



override_builtin = fn name, uri, ctx:
{builtins} = ctx
rec:
...ctx
builtins: rec:
...builtins
overrides: rec: ...builtins.overrides, (name): uri



use_builtin = fn name, ctx:
{builtins} = ctx
rec:
...ctx
builtins: rec:
...builtins
used: seq: name, ...builtins.used | filter used_name: used_name != name



has_builtin_override = fn ident, ctx:
match ctx:
{builtins: {overrides: {(ident): {}}}}: true
else: false



builtin_provider = fn ident, ctx:
match ctx:
{builtins: {overrides: {(ident): {}}}}:
{builtins: {overrides: {(ident): uri}}} = ctx
uri
else:
{builtins: {defaults: {(ident): uri}}} = ctx
uri



is_builtin = fn name, ctx:
name in [...ctx.builtins.names]



get_builtin_imports = fn ctx:
{builtins} = ctx
pipe builtins.used:
filter name:
not has_builtin_override name, ctx

map name:
uri = builtin_provider name, ctx
left = {type: 'ident', value: name}
[uri, {type: 'rec:kv', left, right: left}]

map [uri, kv]:
rec:
type: 'assign'
op: '='
left: {type: 'rec', exprs: [kv]}
right: rec:
op: 'import'
right: rec:
type: 'string'
exprs: [{type: 'string:text', value: uri}]

[...?]



init_builtins = fn ctx:
rec:
...ctx
builtins: rec:
names: []
used: []
provided: []
4 changes: 2 additions & 2 deletions src/lang/call/call.fnk
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ babel_types = import '@babel/types'
{callExpression, identifier} = babel_types
{is_empty, length} = import '@fink/std-lib/iter.fnk'

{transform, map_with_ctx} = import '../transform.fnk'
{transform, map_with_ctx, collect_with_ctx} = import '../transform.fnk'



Expand All @@ -14,7 +14,7 @@ transform_args = fn args, ctx:
[(identifier 'undefined'), ctx]
else:
transform expr, arg_ctx

collect_with_ctx ctx


transform_single_arg = fn [expr], ctx:
Expand Down
4 changes: 2 additions & 2 deletions src/lang/call/pipe.fnk
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ babel_types = import '@babel/types'
{assign, lets, expr_block, 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} = import '../transform.fnk'
{transform, map_with_ctx, collect_with_ctx} = import '../transform.fnk'



Expand All @@ -30,7 +30,7 @@ transform_pipe = fn node, ctx:
expr

[js, next_ctx]

collect_with_ctx pipe_ctx

js = expr_block
wrap_with_comment_loc
Expand Down
7 changes: 5 additions & 2 deletions src/lang/conditionals/match.fnk
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ babel_types = import '@babel/types'
{get_key} = import '../literals/record.fnk'
{is_partial} = import '../partial/init.fnk'
{wrap_with_comment_loc} = import '../comments/init.fnk'
{transform, map_with_ctx} = import '../transform.fnk'
{transform, map_with_ctx, collect_with_ctx} = import '../transform.fnk'



Expand Down Expand Up @@ -70,6 +70,7 @@ match_obj = fn value, obj, emit_result, ctx, cond:
map_with_ctx ctx, fn prop, id_ctx:
[id, next_ctx] = unique_ident 'p', id_ctx
[{id, prop}, next_ctx]
collect_with_ctx ctx

[props, result_ctx] = pipe id_props:
map_with_ctx props_ctx, fn {id, prop}, prop_ctx:
Expand All @@ -80,6 +81,7 @@ match_obj = fn value, obj, emit_result, ctx, cond:
[computed, key, next_ctx] = get_key prop, prop_ctx
js = objectProperty key, id, computed
[js, next_ctx]
collect_with_ctx ctx

decl = objectPattern props

Expand Down Expand Up @@ -156,7 +158,7 @@ match_array = fn value, arr, emit_result, ctx, cond:
map_with_ctx ctx, fn expr, expr_ctx:
[id, next_ctx] = unique_ident 'a', expr_ctx
[{id, value: expr}, next_ctx]

collect_with_ctx ctx

[array_decl, result_ctx] = get_array_decl arr, id_elems, value, elems_ctx

Expand Down Expand Up @@ -232,6 +234,7 @@ match_all = fn value, matches, emit, ctx:
[condition, result] = split_condition expr
emit_result = fn ctx: emit result, ctx
match_condition value, condition, emit_result, expr_ctx, condition
collect_with_ctx ctx

[exprs, end_ctx]

Expand Down
3 changes: 2 additions & 1 deletion src/lang/func/init.fnk
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ babel_types = import '@babel/types'
{transform_left} = import '../../js/left.fnk'
{add, any} = import '../context.fnk'
{transform_block} = import '../block/init.fnk'
{transform, map_with_ctx} = import '../transform.fnk'
{transform, map_with_ctx, collect_with_ctx} = import '../transform.fnk'



Expand All @@ -23,6 +23,7 @@ transform_arg = fn arg, ctx:
transform_func = fn node, ctx:
[params, next_ctx] = pipe node.args:
map_with_ctx ctx, transform_arg
collect_with_ctx ctx

[body, end_ctx] = transform_block node, next_ctx
js = arrowFunctionExpression params, body
Expand Down
8 changes: 7 additions & 1 deletion src/lang/init.fnk
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
{add_arithmitic} = import './arithmitic/init.fnk'
{add_block} = import './block/init.fnk'
{add_partial} = import './partial/init.fnk'
{init_builtins} = import './builtins.fnk'



Expand Down Expand Up @@ -45,16 +46,21 @@ add_transformers = fn ctx:



init_ctx = fn code, filename:
init_ctx = fn code, filename, options:
ctx = dict:
filename
code
errors: []

options

unique_id: 1
ident_prefix: 'ˆ'

ignoreable_imports: []

pipe ctx:
init_builtins
add_transformers


45 changes: 42 additions & 3 deletions src/lang/iterable/common.fnk
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
babe_types = import '@babel/types'
{
conditionalExpression
} = babe_types
{conditionalExpression} = babe_types


{length} = import '@fink/std-lib/iter.fnk'
Expand All @@ -12,6 +10,47 @@ babe_types = import '@babel/types'



transform_with_std_lib = fn node, ctx:
iter_func = '_${node.op}_'

use_accu = match node:
{op: 'fold', args: 3 == length ?}:
{type: 'literal', value: 'true', loc: node.loc}
{op: 'fold'}:
{type: 'literal', value: 'false', loc: node.loc}
{args: 2 == length ?}:
{type: 'literal', value: 'true', loc: node.loc}
else:
{type: 'literal', value: 'false', loc: node.loc}

[use_spread, exprs] = match node.exprs:
[..., {type: 'spread'}]:
spread = {type: 'literal', value: 'true', loc: node.loc}
[...exprs, last] = node.exprs
[spread, [...exprs, last.right]]
else:
spread = {type: 'literal', value: 'false', loc: node.loc}
[spread, node.exprs]

[result, end_ctx] = transform
rec:
type: 'call'
callee: {type: 'ident', value : iter_func}
args: seq:
rec:
type: 'fn'
args: node.args
exprs: exprs
loc: node.loc
use_accu
use_spread

loc: node.loc
ctx
[result, end_ctx]



transform_init = fn left, right, ctx:
true_left = match left:
{type: 'assign'}:
Expand Down
21 changes: 21 additions & 0 deletions src/lang/iterable/filter.test.fnk
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,27 @@
{describe, it, expect, to_match_snapshot} = import '@fink/jest/test.fnk'



describe 'gen 2', fn:
it 'compiles', fn:
expect
fink2js '
{_filter_} = import "@fink/js-interop/iter.js"
filter item:
item % 2 == 0
'
to_match_snapshot

expect
fink2js '
{_filter_} = import "@fink/js-interop/iter.js"
filter item, cntr=0:
[item < 1 and cntr % 2 == 0, cntr + 1]
'
to_match_snapshot



describe 'filter', fn:
it 'compiles', fn:
expect
Expand Down
12 changes: 12 additions & 0 deletions src/lang/iterable/filter.test.fnk.snap
Original file line number Diff line number Diff line change
Expand Up @@ -118,3 +118,15 @@ exports[`filter compiles with accu 3`] = `
};
});"
`;

exports[`gen 2 compiles 1`] = `
"import { _filter_ } from \\"@fink/js-interop/iter.js\\";
_filter_((item) => item % 2 === 0, false, false);"
`;

exports[`gen 2 compiles 2`] = `
"import { _filter_ } from \\"@fink/js-interop/iter.js\\";
_filter_((item, cntr = 0) => [item < 1 && cntr % 2 === 0, cntr + 1], true, false);"
`;
31 changes: 31 additions & 0 deletions src/lang/iterable/fold.test.fnk
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,37 @@
{describe, it, expect, to_match_snapshot} = import '@fink/jest/test.fnk'



describe 'gen 2', fn:
it 'compiles', fn:
expect
fink2js '
{_fold_} = import "@fink/js-interop/iter.js"
fold item, prev=0:
ni = item + prev
item * ni
'
to_match_snapshot

expect
fink2js '
{_fold_} = import "@fink/js-interop/iter.js"
fold item, prev=0, acc=1:
[item * acc + prev, acc + 1]
'
to_match_snapshot

expect
fink2js '
{_fold_} = import "@fink/js-interop/iter.js"
fold item:
item
'
to_match_snapshot




describe 'fold', fn:
it 'compiles', fn:
expect
Expand Down
Loading

0 comments on commit 0f88339

Please sign in to comment.