Skip to content

Commit

Permalink
fix(function-call): make lambda function calls chainable
Browse files Browse the repository at this point in the history
  • Loading branch information
kantord committed Oct 8, 2018
1 parent f74b69c commit 5e3928b
Show file tree
Hide file tree
Showing 8 changed files with 806 additions and 20 deletions.
765 changes: 763 additions & 2 deletions src/__tests__/__snapshots__/interpreter.test.js.snap

Large diffs are not rendered by default.

20 changes: 20 additions & 0 deletions src/__tests__/interpreter.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import execute from '../interpreter'
import compile from '../compiler'
import parse from '../parsers/parser'

const tests = [
{
Expand Down Expand Up @@ -130,6 +131,21 @@ const tests = [
sourceCode: `map \\" "`,
input: ['Hello', 'World'],
output: [' ', ' ']
},
{
sourceCode: `{"original": $.foo} | {"new": $}`,
input: { foo: 42 },
output: { new: { original: 42 } }
},
{
sourceCode: `map $ => {"original": $.foo} | map $=> {"new": $}`,
input: [{ foo: 42 }, { foo: 'hello' }],
output: [{ new: { original: 42 } }, { new: { original: 'hello' } }]
},
{
sourceCode: `map $ => {"original": $.foo} | "foo"`,
input: [{ foo: 42 }, { foo: 'hello' }],
output: 'foo'
}
]

Expand All @@ -151,6 +167,10 @@ describe('interpreter', () => {
it(`correct target code ${sourceCode}`, () => {
expect(compile(sourceCode)).toMatchSnapshot()
})

it(`correct target tree ${sourceCode}`, () => {
expect(parse(sourceCode)).toMatchSnapshot()
})
}
)

Expand Down
4 changes: 2 additions & 2 deletions src/generators/__tests__/functionCallLambda.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ describe('functionCallLambda generator', () => {
it('generates correct code', () => {
const fakeGenerator = (
{ type } // eslint-disable-line flowtype/require-parameter-type
): string => '[]'
): string => 'input[0]'
expect(
functionCallLambda(fakeGenerator)({
type: 'functionCallLambda',
Expand All @@ -21,6 +21,6 @@ describe('functionCallLambda generator', () => {
}
}
})
).toEqual('_.foo(function(input) {return []})(input)')
).toEqual('(_.foo(function(input) {return input[0]})(input))')
})
})
4 changes: 2 additions & 2 deletions src/generators/functionCallLambda.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,6 @@ export default (
): (FunctionCallLambdaNodeType => GeneratedCodeType) => ({
value
}: FunctionCallLambdaNodeType): GeneratedCodeType =>
`_.${value.left.value}(function(input) {return ${Generator(
`(_.${value.left.value}(function(input) {return ${Generator(
value.right
)}})(input)`
)}})(input))`
16 changes: 12 additions & 4 deletions src/parsers/functionCall.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,25 @@

import Parsimmon from 'parsimmon'

import type { FunctionCallNodeType, NodeType, IdentifierNodeType } from '../types'
import type {
FunctionCallNodeType,
NodeType,
IdentifierNodeType
} from '../types'

const FunctionCallParser = Parsimmon.lazy((): mixed => {
const ProgramParser = require('./program').default
const TupleParser = require('./tuple/tuple').default
const IdentifierParser = require('./identifier').default
return Parsimmon.seq(
IdentifierParser,
Parsimmon.optWhitespace,
ProgramParser
TupleParser
).map(
([left, _, right]: [IdentifierNodeType, mixed, NodeType]): FunctionCallNodeType => ({
([left, _, right]: [
IdentifierNodeType,
mixed,
NodeType
]): FunctionCallNodeType => ({
type: 'functionCall',
value: {
left,
Expand Down
4 changes: 2 additions & 2 deletions src/parsers/functionCallLambda.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,14 @@ import type {
} from '../types'

const FunctionCallLambdaParser = Parsimmon.lazy((): mixed => {
const ProgramParser = require('./program').default
const TupleParser = require('./tuple/tuple').default
const IdentifierParser = require('./identifier').default
return Parsimmon.seq(
IdentifierParser,
Parsimmon.optWhitespace,
Parsimmon.alt(Parsimmon.regexp(/\$\s*=>\s*/), Parsimmon.string('\\')),
Parsimmon.optWhitespace,
ProgramParser
TupleParser
).map(
([left, _, __, ___, right]: [
IdentifierNodeType,
Expand Down
9 changes: 1 addition & 8 deletions src/parsers/program.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,9 @@ import Parsimmon from 'parsimmon'
import TupleParser from './tuple/tuple'
import PipeParser from './pipe/pipe'
import type { NodeType } from '../types'
import FunctionCallParser from './functionCall'
import FunctionCallLambdaParser from './functionCallLambda'

export default Parsimmon.seq(
Parsimmon.optWhitespace,
Parsimmon.alt(
FunctionCallLambdaParser,
FunctionCallParser,
PipeParser,
TupleParser
),
Parsimmon.alt(PipeParser, TupleParser),
Parsimmon.optWhitespace
).map((value: [mixed, NodeType, mixed]): NodeType => value[1])
4 changes: 4 additions & 0 deletions src/parsers/section.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,12 @@
import Parsimmon from 'parsimmon'
import ProjectionParser from './projection'
import ProjectableParser from './projectable'
import FunctionCallParser from './functionCall'
import FunctionCallLambdaParser from './functionCallLambda'

export default Parsimmon.alt(
FunctionCallLambdaParser,
FunctionCallParser,
ProjectionParser,
ProjectableParser
)

0 comments on commit 5e3928b

Please sign in to comment.