Skip to content

Instantly share code, notes, and snippets.

@natefaubion
Last active January 5, 2017 23:58
Show Gist options
  • Star 5 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save natefaubion/c70704618bb618cc636c to your computer and use it in GitHub Desktop.
Save natefaubion/c70704618bb618cc636c to your computer and use it in GitHub Desktop.
Sweet.js threading macro
arg |> foo[0].bar(42)
|> baz("hello", "there")
|> quux.foo().bar()
|> new Foo()
// Expands to:
// new Foo(quux.foo().bar(baz('hello', 'there', foo[0].bar(42, arg))));
arg |> foo() |> bar
// SyntaxError: [|>] Expected function call
// 31: arg |> foo() |> bar
// ^
macro test {
rule { } => { to_fn_call(42) }
}
arg |> foo() |> test
// Expands to:
// to_fn_call(42, foo(arg));
operator (|>) 14 left { $lhs, $rhs } => #{ thread $lhs $rhs }
export (|>);
macro thread {
rule { $lhs ($method:part()) } => {
$method($lhs)
}
rule { $lhs ($method:part($args:expr (,) ...)) } => {
$method($args (,) ..., $lhs)
}
case { _ _ ($tok ...) } => {
throwSyntaxError('|>', 'Expected function call', #{ $tok ... })
}
}
// We can be a little loose with our parsing since `operator` guarantees
// that we have a fully expanded, valid expression.
macro part {
rule { ($e ...) . $next:part }
rule { ($e ...) }
rule { $name:ident[$e ...] . $next:part }
rule { $name:ident($e ...) . $next:part }
rule { $name:ident . $next:part }
rule { $name:ident[$e ...] }
rule { $name:ident }
rule { new $ctr:part }
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment