# HG changeset patch # User Leonard Ritter # Date 1669313435 -3600 # Thu Nov 24 19:10:35 2022 +0100 # Node ID d55be3e129f63cc216c9949167a3717b6eae2713 # Parent 205e3aab065051253db09118fbf2f928cb5d4a5a * `:=` has now precedence over infix expressions * `:=` expands expression as block, supporting use of `if` and other block macros diff --git a/lib/scopes/core.sc b/lib/scopes/core.sc --- a/lib/scopes/core.sc +++ b/lib/scopes/core.sc @@ -3056,7 +3056,7 @@ return true repeat next -fn parse-binding-expr (anchor expr) +fn parse-binding-expr (anchor expr next-expr env) loop (lhs rhs = '() expr) if (empty? rhs) error str"unexpected end of binding expression" @@ -3065,13 +3065,16 @@ let at = (as at Symbol) if (== at ':=) let rhs = - if (== (countof rhs) 1) rhs - else (list rhs) + if (== (countof rhs) 1) + let rhs = (decons rhs) + rhs + else `rhs + let rhs next-expr env = (sc_expand ('tag rhs anchor) next-expr env) let newexpr = 'join cons let ('reverse lhs) - cons '= rhs - return newexpr + list '= rhs + return (cons newexpr next-expr) env repeat (cons at lhs) rhs # infix notation support @@ -3292,7 +3295,9 @@ sc_error_append_calltrace err ('tag msg expr-anchor) raise err return expr env - if (has-infix-ops? env expr) + if (has-binding-operator? expr) + return (parse-binding-expr expr-anchor expr topexpr-next env) + elseif (has-infix-ops? env expr) let at next = ('decons expr) let expr = try @@ -3302,8 +3307,6 @@ hide-traceback; error@+ err ('anchor topexpr-at) "while expanding infix expression" return (cons expr topexpr-next) env - elseif (has-binding-operator? expr) - return (cons (parse-binding-expr expr-anchor expr) topexpr-next) env else return topexpr env @@ -3865,18 +3868,6 @@ ^= = (make-inplace-op ^) ..= = (make-inplace-op ..) - # also supported within infix expressions - := = - sugar-macro - fn expand-infix-let (expr) - raising Error - let name value = (decons expr) - let value = - if (== (countof value) 1) - let k = (decons value) - k - else `value - qq [let] [name] = [value] as:= = (make-inplace-let-op as) <- = sugar-macro diff --git a/testing/test_operators.sc b/testing/test_operators.sc --- a/testing/test_operators.sc +++ b/testing/test_operators.sc @@ -68,11 +68,20 @@ test (x == 4) x y z := 1, 2, 3 test (and (x == 1) (y == 2) (z == 3)) + +# := also support block sugars like `if` +# right hand side is evaluated in same scope +x := if ((z := 10) == 10) + 20 +else + 30 +test (and (x == 20) (z == 10)) + + +# as:= auto-wraps right hand side as well x := 1.0 -# as:= auto-wraps right hand side as well x as:= integer 32 test (x == 1) - ; \ No newline at end of file