about summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--mu.arc51
-rw-r--r--mu.arc.t70
2 files changed, 120 insertions, 1 deletions
diff --git a/mu.arc b/mu.arc
index 43ed756e..fc1efb32 100644
--- a/mu.arc
+++ b/mu.arc
@@ -2232,11 +2232,32 @@
   (reply result:string-address-array-address)
 )
 
+(init-fn split-first-at-substring/variant:split-first  ; string text, string delim -> string first, string rest
+  (default-space:space-address <- new space:literal 30:literal)
+  (text:string-address <- next-input)
+  (delim:string-address <- next-input)
+  ; empty string? return empty strings
+  (len:integer <- length text:string-address/deref)
+  { begin
+    (empty?:boolean <- equal len:integer 0:literal)
+    (break-unless empty?:boolean)
+    (x:string-address <- new "")
+    (y:string-address <- new "")
+    (reply x:string-address y:string-address)
+  }
+  (idx:integer <- find-substring text:string-address delim:string-address 0:literal)
+  (x:string-address <- string-copy text:string-address 0:literal idx:integer)
+  (k:integer <- length delim:string-address/deref)
+  (idx:integer <- add idx:integer k:integer)
+  (y:string-address <- string-copy text:string-address idx:integer len:integer)
+  (reply x:string-address y:string-address)
+)
+
 (init-fn split-first  ; string text, character delim -> string first, string rest
   (default-space:space-address <- new space:literal 30:literal)
   (text:string-address <- next-input)
   (delim:character <- next-input)
-  ; empty string? return empty array
+  ; empty string? return empty strings
   (len:integer <- length text:string-address/deref)
   { begin
     (empty?:boolean <- equal len:integer 0:literal)
@@ -2263,6 +2284,10 @@
 ;?   ($print (("-" literal))) ;? 1
 ;?   ($print end:integer) ;? 1
 ;?   ($print (("\n" literal))) ;? 1
+  ; if end is out of bounds, trim it
+  (len:integer <- length buf:string-address/deref)
+  (end:integer <- min len:integer end:integer)
+  ; allocate space for result
   (len:integer <- subtract end:integer start:integer)
   (result:string-address <- new string:literal len:integer)
   ; copy start..end into result[curr-result]
@@ -2284,6 +2309,30 @@
   (reply result:string-address)
 )
 
+(init-fn min
+  (default-space:space-address <- new space:literal 30:literal)
+  (x:integer <- next-input)
+  (y:integer <- next-input)
+  { begin
+    (return-x?:boolean <- less-than x:integer y:integer)
+    (break-if return-x?:boolean)
+    (reply y:integer)
+  }
+  (reply x:integer)
+)
+
+(init-fn max
+  (default-space:space-address <- new space:literal 30:literal)
+  (x:integer <- next-input)
+  (y:integer <- next-input)
+  { begin
+    (return-x?:boolean <- greater-than x:integer y:integer)
+    (break-if return-x?:boolean)
+    (reply y:integer)
+  }
+  (reply x:integer)
+)
+
 (init-fn init-stream
   (default-space:space-address <- new space:literal 30:literal)
   (in:string-address <- next-input)
diff --git a/mu.arc.t b/mu.arc.t
index 28b7fbe4..08ff3535 100644
--- a/mu.arc.t
+++ b/mu.arc.t
@@ -4542,6 +4542,76 @@
   (prn "F - 'split-first' cuts string at first occurrence of delimiter"))
 
 (reset)
+(new-trace "string-split-first-at-substring")
+(add-code
+  '((function main [
+      (1:string-address <- new "a//b")
+      (2:string-address <- new "//")
+      (3:string-address 4:string-address <- split-first-at-substring 1:string-address 2:string-address)
+     ])))
+(run 'main)
+(each routine completed-routines*
+  (aif rep.routine!error (prn "error - " it)))
+;? (prn int-canon.memory*) ;? 1
+(when (or (~memory-contains-array memory*.3 "a")
+          (~memory-contains-array memory*.4 "b"))
+  (prn "F - 'split-first-at-substring' is like split-first but with a string delimiter"))
+
+(reset)
+(new-trace "string-copy")
+(add-code
+  '((function main [
+      (1:string-address <- new "abc")
+      (2:string-address <- string-copy 1:string-address 1:literal 3:literal)
+     ])))
+(run 'main)
+(each routine completed-routines*
+  (aif rep.routine!error (prn "error - " it)))
+(when (~memory-contains-array memory*.2 "bc")
+  (prn "F - 'string-copy' returns a copy of a substring"))
+
+(reset)
+(new-trace "string-copy-out-of-bounds")
+(add-code
+  '((function main [
+      (1:string-address <- new "abc")
+      (2:string-address <- string-copy 1:string-address 2:literal 4:literal)
+     ])))
+(run 'main)
+(each routine completed-routines*
+  (aif rep.routine!error (prn "error - " it)))
+(when (~memory-contains-array memory*.2 "c")
+  (prn "F - 'string-copy' stops at bounds"))
+
+(reset)
+(new-trace "string-copy-out-of-bounds-2")
+(add-code
+  '((function main [
+      (1:string-address <- new "abc")
+      (2:string-address <- string-copy 1:string-address 3:literal 3:literal)
+     ])))
+(run 'main)
+(each routine completed-routines*
+  (aif rep.routine!error (prn "error - " it)))
+(when (~memory-contains-array memory*.2 "")
+  (prn "F - 'string-copy' returns empty string when range is out of bounds"))
+
+(reset)
+(new-trace "min")
+(add-code
+  '((function main [
+      (1:integer <- min 3:literal 4:literal)
+     ])))
+(run 'main)
+(each routine completed-routines*
+  (aif rep.routine!error (prn "error - " it)))
+;? (prn int-canon.memory*) ;? 1
+(when (~is memory*.1 3)
+  (prn "F - 'min' returns smaller of two numbers"))
+
+;? (quit) ;? 2
+
+(reset)
 (new-trace "integer-to-decimal-string")
 (add-code
   '((function main [