diff --git a/package-lock.json b/package-lock.json index 959d85c..088be82 100644 --- a/package-lock.json +++ b/package-lock.json @@ -999,18 +999,18 @@ } }, "@fink/larix": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/@fink/larix/-/larix-4.2.0.tgz", - "integrity": "sha512-PWfLR8pGnd7PMEhMLeUhbnBHulsUuh5gqRhyfSI7Ux57jtK6pb2XhbRugeXGx/rZ7YF6nDSaAJk8gu5va6QoyA==", + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/@fink/larix/-/larix-4.3.0.tgz", + "integrity": "sha512-ApEnQQN9TF7Fird165S3GHhxtOdJM80cf60VT8nb/m6tllESJbsZL7afw8t5Zvbwl8A+W3tDeJ0vD5w1mo1LqQ==", "dev": true, "requires": { "@fink/prattler": "^1.0.0" } }, "@fink/prattler": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@fink/prattler/-/prattler-1.0.1.tgz", - "integrity": "sha512-+7rTrsmFNHi0WpzL3f8hIjbiH6muH+kTxc0CqtpRRd5jQ7qbosN4TTWzzGj5cogu2W3guZQzPz8ISw5HOxYVjA==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@fink/prattler/-/prattler-1.1.0.tgz", + "integrity": "sha512-kU0pzsDeELojzwoFuJHx3ZnTgBQpLLordP1+l1vMjw3o/Yvu0tXZXAufEqTfQsEcuRJGwsujv0CF3/hZkPoVNg==", "dev": true, "requires": { "@fink/snippet": "^1.0.1" diff --git a/package.json b/package.json index cb20442..adb2be6 100644 --- a/package.json +++ b/package.json @@ -38,7 +38,7 @@ "@babel/cli": "^7.2.3", "@babel/plugin-proposal-pipeline-operator": "^7.3.2", "@babel/preset-env": "^7.8.6", - "@fink/larix": "^4.2.0", + "@fink/larix": "^4.3.0", "@nearmap/eslint-config-base": "^1.1.0", "babel-eslint": "^10.1.0", "commitizen": "^4.0.3", diff --git a/src/index.js b/src/index.js index c134900..c9ce7a9 100644 --- a/src/index.js +++ b/src/index.js @@ -12,6 +12,7 @@ import {transform_map} from './transform/map'; import {transform_flat_map} from './transform/map'; import {transform_filter} from './transform/filter'; import {transform_while} from './transform/while'; +import {transform_find} from './transform/find'; import {transform_fold} from './transform/fold'; import {transform_unfold} from './transform/unfold'; import {transform_call} from './transform/call'; @@ -33,6 +34,8 @@ import {transform_inifx} from './transform/infix'; import {transform_import} from './transform/import'; import {transform_ident, escape_ident, var_prefix} from './transform/other'; import {transform_number} from './transform/number'; +import {transform_new} from './transform/new'; +import {transform_throw} from './transform/throw'; import { transform_jsx_elem, transform_jsx_attr, transform_jsx_str, @@ -41,8 +44,6 @@ import { import transform_do_expr from './transform/js/do-expression'; import {transform_async} from './transform/js/async'; -import {transform_new} from './transform/new'; -import {transform_throw} from './transform/throw'; const jsx = { @@ -113,7 +114,8 @@ const iterables = { map: transform_map, flat_map: transform_flat_map, filter: transform_filter, - while: transform_while + while: transform_while, + find: transform_find }; diff --git a/src/transform/__snapshots__/find.test.js.snap b/src/transform/__snapshots__/find.test.js.snap new file mode 100644 index 0000000..adad49e --- /dev/null +++ b/src/transform/__snapshots__/find.test.js.snap @@ -0,0 +1,55 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`compiles fold compiles complex find 1`] = ` +"ˆitems_2 => { + for (const ˆitem_1 of ˆitems_2) { + const { + \\"item\\": item + } = ˆitem_1; + + let _do_result; + + ˆmatch_5: { + const ˆvalue_4 = item; + + if (ˆvalue_4 !== undefined && ˆvalue_4 !== null) { + const { + \\"spam\\": ˆp_6 + } = ˆvalue_4; + + if (ˆp_6 === spam) { + _do_result = shrub; + break ˆmatch_5; + } + } + + { + _do_result = ni; + break ˆmatch_5; + } + } + + const ˆfound_3 = _do_result; + _do_result = undefined; + if (ˆfound_3) return ˆitem_1; + } + + return undefined; +}; + +Object.assign(module.exports, {});" +`; + +exports[`compiles fold compiles simple find 1`] = ` +"ˆitems_2 => { + for (const ˆitem_1 of ˆitems_2) { + const item = ˆitem_1; + const ˆfound_3 = item > 3; + if (ˆfound_3) return ˆitem_1; + } + + return undefined; +}; + +Object.assign(module.exports, {});" +`; diff --git a/src/transform/find.js b/src/transform/find.js new file mode 100644 index 0000000..a26c37c --- /dev/null +++ b/src/transform/find.js @@ -0,0 +1,34 @@ +import { + params, for_of, split_last, func, returns, iff, consts, undef +} from '../types'; +import {block_statement} from './block'; + + +export const transform_find = (node, {transform, unique_ident})=> { + const [item_param] = node.args.map(transform); + const [init] = params([item_param]); + + const item = unique_ident('item'); + const items = unique_ident('items'); + const found = unique_ident('found'); + + const [expressions, last_expr] = split_last(node.exprs); + + return func(items)( + + for_of(item, items)( + consts(init, item), + + ...expressions.map(block_statement({transform})), + + consts(found, transform(last_expr)), + + iff(found)( + returns(item) + ) + ), + + undef() + ); +}; + diff --git a/src/transform/find.test.js b/src/transform/find.test.js new file mode 100644 index 0000000..1f869e2 --- /dev/null +++ b/src/transform/find.test.js @@ -0,0 +1,26 @@ +import {fink2js} from '../testing'; + + +describe('compiles fold', ()=> { + it('compiles simple find', ()=> { + expect( + fink2js(` + find item: + item > 3 + `) + ).toMatchSnapshot(); + }); + + it('compiles complex find', ()=> { + expect( + fink2js(` + find {item}: + match item: + {spam}: shrub + else: ni + `) + ).toMatchSnapshot(); + }); +}); + +