Skip to content

Commit

Permalink
Merge pull request #93 from fink-lang/non-stateful-transforms
Browse files Browse the repository at this point in the history
non-stateful transforms
  • Loading branch information
kollhof authored Oct 26, 2020
2 parents 6254e7e + 0fd1576 commit 05efbe5
Show file tree
Hide file tree
Showing 43 changed files with 797 additions and 547 deletions.
30 changes: 14 additions & 16 deletions src/generate.fnk
Original file line number Diff line number Diff line change
Expand Up @@ -2,30 +2,35 @@ babel_traverse = import '@babel/traverse'
{default: traverse} = babel_traverse

{transformFromAstSync} = import '@babel/core'
{is_empty} = import '@fink/std-lib/iter.fnk'

{transform_ast} = import './lang/init.fnk'
{transform} = import './lang/transform.fnk'
{init_ctx} = import './lang/init.fnk'

{transform_do_expr} = import './js/do-expression.fnk'
{transform_async} = import './js/async.fnk'
{module_transforms} = import './js/module.fnk'



transform = fn node, code, filename, options:
ast = transform_ast node, code, filename, options
transform_file = fn fink_ast, code, filename, options:
ctx = init_ctx code, filename

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

extras = match options:
{module_type: 'cjs'}: module_transforms
else: {}

match ast:
{errors: is_empty ?}:
traverse ast, dict:
match error:
false:
traverse js_ast, dict:
DoExpression: transform_do_expr
AwaitExpression: {enter: transform_async}
...extras
ast
{...js_ast, errors: []}
else:
{errors: [error]}



Expand All @@ -51,17 +56,10 @@ babel_generate = fn ast, filename, source, options:


generate = fn ast, filename, source, options={}:
js_ast = transform ast, source, filename, options
js_ast = transform_file ast, source, filename, options

match js_ast:
{errors: [{}]}:
{code: '', source_map: '', errors: js_ast.errors}
else:
babel_generate js_ast, filename, source, options







12 changes: 8 additions & 4 deletions src/generate.test.fnk
Original file line number Diff line number Diff line change
Expand Up @@ -51,13 +51,13 @@ describe 'errors', fn:
'

it 'errors with code snippet', fn:
{errors: [{error}]} = fink2js '
{errors: [{message}]} = fink2js '
foo = bar
123 = foo
shrub = ni'

expect
error
message
to_equal '
test.fnk:2:0
1| foo = bar
Expand All @@ -66,6 +66,8 @@ describe 'errors', fn:
3| shrub = ni

Unable to transform `assign =`.

TypeError: Property left of AssignmentExpression expected node to be of a type ["LVal"] but instead got "NumericLiteral"
'

it 'errors with bad babel options', fn:
Expand All @@ -79,7 +81,7 @@ describe 'errors', fn:


it 'errors when provided with unknown tokens', fn:
{errors: [{error}]} = generate
{errors: [{message}]} = generate
dict:
type: 'test'
op: 'foobar'
Expand All @@ -90,11 +92,13 @@ describe 'errors', fn:
'test.fnk', 'foobar'

expect
error
message
to_equal '
test.fnk:1:0
1| foobar
^

Unable to transform `test foobar`.

Unknown expression.
'
16 changes: 8 additions & 8 deletions src/js/identifier.fnk
Original file line number Diff line number Diff line change
Expand Up @@ -15,15 +15,12 @@ check_ident = rx'
[_$\p{L}][_$\p{L}\p{N}]*$'



var_prefix = 'ˆ'

str_36 = base_n ?, 36



replace_chars = fn name, idx=0:
prefixed_name = '${var_prefix}${name}'
replace_chars = fn name, idx, prefix:
prefixed_name = '${prefix}${name}'

match prefixed_name:
matches ?, check_ident:
Expand All @@ -35,14 +32,17 @@ replace_chars = fn name, idx=0:
end = slice name, idx + 1
new_name = '${start}${char_replacement}${end}'

replace_chars new_name, idx + length char_replacement
replace_chars
new_name
idx + length char_replacement
prefix



escape_ident = fn name:
escape_ident = fn name, {ident_prefix}:
match name:
matches ?, check_ident:
name
else:
replace_chars name
replace_chars name, 0, ident_prefix

15 changes: 11 additions & 4 deletions src/js/types.fnk
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,16 @@ not_nullish = fn value:
and not_undef, not_null


ident = fn name: identifier escape_ident name
ident = fn name, ctx:
identifier escape_ident name, ctx



unique_ident = fn name, ctx:
{unique_id, ident_prefix} = ctx
js = ident '${ident_prefix}${name}_${unique_id}', ctx
[js, {...ctx, unique_id: unique_id + 1}]



raw_str = fn value:
Expand Down Expand Up @@ -113,9 +122,7 @@ async = true


generator = fn name, args, ...statements:
func_name = ident name

functionExpression func_name, args,
functionExpression name, args,
blockStatement list:
returnStatement
objectExpression list:
Expand Down
21 changes: 15 additions & 6 deletions src/lang/arithmitic/init.fnk
Original file line number Diff line number Diff line change
@@ -1,22 +1,31 @@
babel_types = import '@babel/types'
{binaryExpression, unaryExpression} = babel_types

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


transform_op = dict:
'^': '**'


transform_arithmitic = fn {op, left, right}, {transform}:

transform_arithmitic = fn {op, left, right}, ctx:
{(op): operator=op} = transform_op

binaryExpression operator,
transform left
transform right
[left_js, right_ctx] = transform left, ctx
[right_js, end_ctx] = transform right, right_ctx
js = binaryExpression operator, left_js, right_js

[js, end_ctx]



transform_unary = fn {op, right}, ctx:
[right_js, next_ctx] = transform right, ctx
js = unaryExpression op, right_js

transform_unary = fn {op, right}, {transform}:
unaryExpression op, transform right
[js, next_ctx]



Expand Down
86 changes: 54 additions & 32 deletions src/lang/assignment/init.fnk
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,19 @@ babel_types = import '@babel/types'
} = babel_types
{length, is_empty} = import '@fink/std-lib/iter.fnk'

{transform_left} = import '../../js/left.fnk'
{unique_ident} = import '../../js/types.fnk'
{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'



transform_left = fn node, ctx:
[left, next_ctx] = transform node, ctx
js = xform_left left
[js, next_ctx]



Expand All @@ -30,7 +39,7 @@ has_spread_not_last = fn {left}:
false


transform_spread_left = fn {left}, {transform}:
transform_spread_left = fn {left}, ctx:
[before, middle, end] = pipe left.exprs:
fold expr, [before=[], middle=false, end=[]]=[]:
match expr:
Expand All @@ -53,7 +62,8 @@ transform_spread_left = fn {left}, {transform}:
# TODO missing loc
[{type: 'list', exprs: before}, middle, {type: 'list', exprs: end}]

transform_left transform {...left, exprs}
transform_left {...left, exprs}, ctx



slice = fn items, start, end=false:
Expand All @@ -76,15 +86,17 @@ slice = fn items, start, end=false:

transform_spread_right = fn expr, ctx:
{left, right} = expr
items = ctx.unique_ident 'items'
[items, init_ctx] = unique_ident 'items', ctx
# TODO: wrap declarator?
[init, next_ctx] = transform_value right, init_ctx

items_init = wrap_with_comment_loc
variableDeclaration
'const'
list:
variableDeclarator
arrayPattern [restElement items]
transform_value right, ctx
init
left

len = (length left.exprs) - 1
Expand All @@ -102,14 +114,13 @@ transform_spread_right = fn expr, ctx:
0: slices
else: [items, ...slices]

result = expressionStatement
arrayExpression result_items

doExpression
js = doExpression
wrap_with_comment_loc
blockStatement [items_init, result]
blockStatement list:
items_init
expressionStatement arrayExpression result_items
left

[js, next_ctx]


has_await = fn node:
Expand All @@ -124,22 +135,20 @@ has_await = fn node:
transform_await_left = fn node, ctx:
{left: {exprs: [{right: expr}, ...rest_exprs], ...rest_left}} = node
left = {...rest_left, exprs: [expr, ...rest_exprs]}
transform_left ctx.transform left
transform_left left, ctx




transform_await_right = fn expr, ctx:
{left, right} = expr
items = ctx.unique_ident 'items'
iter = ctx.unique_ident 'iter'
[items, iter_ctx] = unique_ident 'items', ctx
[iter, init_ctx] = unique_ident 'iter', iter_ctx

[init, next_ctx] = transform_value right, init_ctx

items_init = wrap_with_comment_loc
variableDeclaration
'const'
list:
variableDeclarator
items
transform_value right, ctx
variableDeclaration 'const', [variableDeclarator items, init]
right

iter_init = wrap_with_comment_loc
Expand Down Expand Up @@ -183,8 +192,7 @@ transform_await_right = fn expr, ctx:
identifier 'value'
expr


doExpression
js = doExpression
wrap_with_comment_loc
blockStatement list:
items_init
Expand All @@ -193,24 +201,38 @@ transform_await_right = fn expr, ctx:
arrayExpression right_exprs
right

[js, next_ctx]



transform_assign_left = fn node, ctx:
transform_left node.left, ctx



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




transform_assign = fn node, ctx:
match node:
[left_transform, right_transform] = match node:
has_await ?:
left = transform_await_left node, ctx
right = transform_await_right node, ctx
assignmentExpression '=', left, right
[transform_await_left, transform_await_right]

has_spread_not_last ?:
left = transform_spread_left node, ctx
right = transform_spread_right node, ctx
assignmentExpression '=', left, right
[transform_spread_left, transform_spread_right]

else:
left = transform_left ctx.transform node.left
right = transform_value node.right, ctx
assignmentExpression '=', left, right
[transform_assign_left, transform_assign_right]


[left, right_ctx] = left_transform node, ctx
[right, next_ctx] = right_transform node, right_ctx

js = assignmentExpression '=', left, right
[js, next_ctx]



Expand Down
Loading

0 comments on commit 05efbe5

Please sign in to comment.