e99ac8ce1ce7 — Leonard Ritter 21 days ago
* fixed dot notation accidentally matching infix notation
2 files changed, 71 insertions(+), 57 deletions(-)

M lib/scopes/core.sc
M testing/test_dots.sc
M lib/scopes/core.sc +65 -57
@@ 2723,62 2723,6 @@ fn pointer-ras (T vT)
     __as = (box-pointer (spice-cast-macro pointer-as))
     __ras = (box-pointer (spice-cast-macro pointer-ras))
 
-# dotted symbol expander
-# --------------------------------------------------------------------------
-
-let dot-char = 46:i8 # "."
-let dot-sym = '.
-
-fn dotted-symbol? (env head)
-    if (== head dot-sym)
-        return false
-    let s = (as head string)
-    let sz = (countof s)
-    loop (i = 0:usize)
-        if (== i sz)
-            return false
-        elseif (== (@ s i) dot-char)
-            return true
-        + i 1:usize
-
-fn split-dotted-symbol (name)
-    let anchor = ('anchor name)
-    let s = (as (as name Symbol) string)
-    let sz = (countof s)
-    loop (i = sz)
-        if (== i 0:usize)
-            # did not find a dot - return as-is
-            return name
-        let _i = i
-        let i = (- i 1:usize)
-        if (== (@ s i) dot-char)
-            # skip trailing dot
-            if (== _i sz)
-                repeat i
-            # if a dot followed this dot, skip it
-            if (== (@ s _i) dot-char)
-                repeat i
-            # ignore prefix dot - return as-is
-            if (== i 0:usize)
-                return name
-            let k = (- i 1:usize)
-            # if a dot precedes this dot, skip it
-            if (== (@ s k) dot-char)
-                repeat i
-            # we found a good solo dot inbetween two characters
-            let ltoken = (Symbol (lslice s i))
-            let rtoken = (Symbol (rslice s _i))
-            let manchor = (sc_anchor_offset anchor (as i i32))
-            let ranchor = (sc_anchor_offset anchor (as _i i32))
-            # build expression
-            let expr =
-                list
-                    'tag `dot-sym manchor
-                    'tag `ltoken anchor
-                    'tag `rtoken ranchor
-            return ('tag `expr manchor)
-        i
-
 # infix notation support
 # --------------------------------------------------------------------------
 

          
@@ 2895,6 2839,70 @@ fn parse-infix-expr (infix-table lhs sta
 let parse-infix-expr =
     static-typify parse-infix-expr Scope Value list i32
 
+# dotted symbol expander
+# --------------------------------------------------------------------------
+
+let dot-char = 46:i8 # "."
+let dot-sym = '.
+
+fn dotted-symbol? (env head)
+    if (== head dot-sym)
+        return false
+    let s = (as head string)
+    let sz = (countof s)
+    loop (i = 0:usize)
+        if (== i sz)
+            return false
+        elseif (== (@ s i) dot-char)
+            return true
+        + i 1:usize
+
+fn split-dotted-symbol (env name)
+    let anchor = ('anchor name)
+    let s = (as (as name Symbol) string)
+    let sz = (countof s)
+    loop (i = sz)
+        if (== i 0:usize)
+            # did not find a dot - return as-is
+            return name
+        let _i = i
+        let i = (- i 1:usize)
+        if (== (@ s i) dot-char)
+            # skip trailing dot
+            if (== _i sz)
+                repeat i
+            # if a dot followed this dot, skip it
+            if (== (@ s _i) dot-char)
+                repeat i
+            # ignore prefix dot - return as-is
+            if (== i 0:usize)
+                return name
+            let k = (- i 1:usize)
+            # if a dot precedes this dot, skip it
+            if (== (@ s k) dot-char)
+                repeat i
+            # we found a good solo dot inbetween two characters
+            let ltoken = (Symbol (lslice s i))
+            let rtoken = (Symbol (rslice s _i))
+            let infix? =
+                try
+                    get-ifx-op env ltoken
+                    true
+                else false
+            let manchor = (sc_anchor_offset anchor (as i i32))
+            let ranchor = (sc_anchor_offset anchor (as _i i32))
+            # build expression
+            let ltoken = ('tag `ltoken anchor)
+            let expr =
+                list
+                    'tag `dot-sym manchor
+                    if infix?
+                        'tag `[(list _ ltoken)] anchor
+                    else ltoken
+                    'tag `rtoken ranchor
+            return ('tag `expr manchor)
+        i
+
 #---------------------------------------------------------------------------
 
 # install general list hook for this scope

          
@@ 2970,7 2978,7 @@ fn symbol-handler (topexpr env)
             ;
     if (dotted-symbol? env name)
         let expr =
-            split-dotted-symbol sxname
+            split-dotted-symbol env sxname
         return (cons expr next) env
     label skip
         let handler =

          
M testing/test_dots.sc +6 -0
@@ 78,3 78,9 @@ test
     ==
         split-test '...a...b...c...
         '(...a...b...c...)
+
+do
+    let * = (tupleof (x = 1) (y = 2))
+    # ensure dot notation does not accidentally turn into infix notation
+    test (*.x == 1)
+