Skip to content

Commit

Permalink
Add the |>1 operator, the |>1? operator and "pipeline(<exp>, ...)" macro
Browse files Browse the repository at this point in the history
  • Loading branch information
i2y committed Dec 10, 2014
1 parent f010825 commit d7db215
Show file tree
Hide file tree
Showing 3 changed files with 51 additions and 21 deletions.
12 changes: 12 additions & 0 deletions examples/macro_example.mochi
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,15 @@ macro rest_if_first_is_true(first, &args):

print(rest_if_first_is_true(True, 1, 2, 3))
print(rest_if_first_is_true("foo", 1, 2, 3))

macro pipeline(&args):
[Symbol('|>')] + args

pipeline([1, 2, 3],
map(-> $1 * 2),
filter(-> $1 != 2),
pvector())
# => pvector([4, 6])



37 changes: 20 additions & 17 deletions mochi/mochi.py
Original file line number Diff line number Diff line change
Expand Up @@ -469,9 +469,9 @@ def __init__(self, port):
self.port = port
self.nest_level = 0
self.line = 1
self.commands = ("'", '(', ',', '`', '"', ';', '@', '|', '[', '{')
self.commands = ("'", '(', ',', '`', '"', ';', '@', '~', '[', '{')
self.white_spaces = (' ', '\r', '\n', '\t')
self.separations = self.commands + self.white_spaces + (')', '|', ']', '}', EOF, '#')
self.separations = self.commands + self.white_spaces + (')', '~', ']', '}', EOF, '#')
self.reader = SexpReader
self.reader_macro_table = {
'(': self.make_list_macro,
Expand Down Expand Up @@ -605,8 +605,8 @@ def get_sexp(self, tkn=None):
return COMMENT
elif self.port.next_char() == '(':
return self.read_delimited_list(')')
elif self.port.next_char() == '|':
rest_exps = self.read_delimited_list('|')
elif self.port.next_char() == '~':
rest_exps = self.read_delimited_list('~')
return [FN, self._create_underscore_args(rest_exps), rest_exps]
elif self.port.next_char() == '[':
sexp = [MAKE_TUPLE]
Expand Down Expand Up @@ -3278,7 +3278,7 @@ def main():
(_val sym-num-seq (ref 0))
(def gensym-match ()
(set! sym-num-seq |+ _ 1|)
(set! sym-num-seq ~+ _ 1~)
(Symbol (+ "m" (str #!sym-num-seq))))
(def table-pattern-bind (pattern target)
Expand Down Expand Up @@ -3340,7 +3340,7 @@ def main():
(mac let (args & body)
`((fn ()
,@(doall (map |cons 'val _| args))
,@(doall (map ~cons 'val _~ args))
,@body)))
;(mac and args
Expand All @@ -3364,7 +3364,7 @@ def main():
(mac accum (accfn & body)
(w/uniq gacc
`(let ((,gacc #())
(,accfn |append ,gacc _|))
(,accfn ~append ,gacc _~))
,@body
(tuple ,gacc))))
Expand All @@ -3379,23 +3379,26 @@ def main():
(mac defseq (name iterable)
`(_val ,name (lazyseq ,iterable)))
(mac -> (operand & operators)
(mac |>1 (operand & operators)
(if (== (len operators) 0)
operand
(let ((operator (first operators))
(rest-operators (rest operators)))
(if (isinstance operator tuple)
`(-> (,(first operator) ,operand ,@(rest operator)) ,@rest-operators)
`(-> (,operator ,operand) ,@rest-operators)))))
(if (isinstance operator tuple)
`(|>1 (,(first operator) ,operand ,@(rest operator)) ,@rest-operators)
`(|>1 (,operator ,operand) ,@rest-operators)))))
(mac ->> (operand & operators)
(mac |> (operand & operators)
(if (== (len operators) 0)
operand
(let ((operator (first operators))
(rest-operators (rest operators)))
(if (isinstance operator tuple)
`(->> (,(first operator) ,@(rest operator) ,operand) ,@rest-operators)
`(->> (,operator ,operand) ,@rest-operators)))))
`(|> (,(first operator) ,@(rest operator) ,operand) ,@rest-operators)
`(|> (,operator ,operand) ,@rest-operators)))))
(mac pipeline (& exps)
`(|> ,@exps))
;(mac import (& targets)
; `(_require_py_module (quote ,targets)))
Expand Down Expand Up @@ -3495,7 +3498,7 @@ def main():
(_val sym-num-seq (ref 0))
(def gensym-match ()
(set! sym-num-seq |+ _ 1|)
(set! sym-num-seq ~+ _ 1~)
(Symbol (+ "m" (str #!sym-num-seq))))
(def table-pattern-bind (pattern target)
Expand Down Expand Up @@ -3581,13 +3584,13 @@ def main():
(mac data (base-record-name & record-defs)
`(do (record ,base-record-name ())
,@(map |quasiquote (record ,(get _ 0) ,base-record-name ,(get _ 1 None))| record-defs)))
,@(map ~quasiquote (record ,(get _ 0) ,base-record-name ,(get _ 1 None))~ record-defs)))
(mac make-module (export & body)
(def symbol->keyword (sym)
(Keyword sym.name))
(def make-exported-table (exported-symbols)
(+ '(table) (tuple (flatten (map |make-tuple (symbol->keyword _) _| exported-symbols)))))
(+ '(table) (tuple (flatten (map ~make-tuple (symbol->keyword _) _~ exported-symbols)))))
(def make-exported-tuple (exported-symbols)
(val tuple-name (gensym))
(make-tuple
Expand Down
23 changes: 19 additions & 4 deletions mochi/parser.py
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,8 @@ def __hash__(self):
lg.add('UNTERMINATED_STRING', r"[\"\'].*")
lg.add('NUMBER', r'-?[0-9]+(?:\.[0-9]+)?')
lg.add('NAME', r'\&?[_a-zA-Z$][-_a-zA-Z0-9]*')
lg.add('PIPELINE_FIRST_BIND', r'\|>1\?')
lg.add('PIPELINE_FIRST', r'\|>1')
lg.add('PIPELINE_BIND', r'\|>\?')
lg.add('PIPELINE', r'\|>')
lg.add('BAR', r'\|')
Expand Down Expand Up @@ -154,15 +156,16 @@ def __hash__(self):
'OPLT', 'OPGT', 'OPAND', 'OPOR', 'OPIS', 'NOT', 'NEWLINE', 'PERCENT', 'EXPORT',
'LPAREN', 'RPAREN', 'TRUE', 'FALSE', 'DQUOTE_STR', 'SQUOTE_STR', 'AT', 'BANG',
'NAME', 'EQUALS', 'IF', 'ELSEIF', 'ELSE', 'COLON', 'SEMI', 'DATA', 'IMPORT', 'REQUIRE',
'LBRACK', 'RBRACK', 'COMMA', 'DEF', 'DOC', 'CALET', 'PIPELINE', 'PIPELINE_BIND', 'RETURN',
'LBRACK', 'RBRACK', 'COMMA', 'DEF', 'DOC', 'CALET', 'PIPELINE', 'PIPELINE_BIND', 'PIPELINE_FIRST',
'PIPELINE_FIRST_BIND', 'RETURN',
'LBRACE', 'RBRACE', 'MATCH', 'DEFM', 'RECORD', 'AMP', 'FN', 'THINARROW', 'RECEIVE',
'YIELD', 'FROM', 'FOR', 'IN', 'DOT', 'INDENT', 'DEDENT', 'TRY', 'FINALLY', 'EXCEPT',
'MODULE', 'AS', 'RAISE', 'WITH', 'MACRO', 'QUOTE', 'QUASI_QUOTE', 'UNQUOTE', 'UNQUOTE_SPLICING'],
precedence=[('left', ['EQUALS']),
('left', ['NOT']),
('left', ['OPIS']),
('left', ['OPEQ', 'OPLEQ', 'OPGEQ', 'OPNEQ', 'OPLT', 'OPGT', 'OPAND', 'OPOR',
'PIPELINE', 'PIPELINE_BIND']),
'PIPELINE', 'PIPELINE_BIND', 'PIPELINE_FIRST', 'PIPELINE_FIRST_BIND']),
('left', ['OPPLUS', 'OPMINUS']),
('left', ['LBRACK', 'RBRACK']),
('left', ['OPTIMES', 'OPDIV', 'PERCENT'])],
Expand Down Expand Up @@ -1050,13 +1053,25 @@ def binop_expr(p):

@pg.production('binop_expr : binop_expr PIPELINE binop_expr')
def binop_expr(p):
return [Symbol('->>'), p[0], p[2]]
return [Symbol('|>'), p[0], p[2]]


@pg.production('binop_expr : binop_expr PIPELINE_BIND binop_expr')
def binop_expr(p):
left, _, right = p
return [Symbol('->>'), p[0], [Symbol('bind'),
return [Symbol('|>'), p[0], [Symbol('bind'),
[Symbol('fn'), [Symbol('input')], p[2] + [Symbol('input')]]]]


@pg.production('binop_expr : binop_expr PIPELINE_FIRST binop_expr')
def binop_expr(p):
return [Symbol('|>1'), p[0], p[2]]


@pg.production('binop_expr : binop_expr PIPELINE_FIRST_BIND binop_expr')
def binop_expr(p):
left, _, right = p
return [Symbol('|>1'), p[0], [Symbol('bind'),
[Symbol('fn'), [Symbol('input')], p[2] + [Symbol('input')]]]]


Expand Down

0 comments on commit d7db215

Please sign in to comment.