about summary refs log tree commit diff stats
path: root/cpp/060string.mu
diff options
context:
space:
mode:
authorKartik K. Agaram <vc@akkartik.com>2015-04-18 20:11:59 -0700
committerKartik K. Agaram <vc@akkartik.com>2015-04-18 20:11:59 -0700
commit0b82eef7140123e29e2628232e3cc7f740d094f2 (patch)
tree16057bdbcd64d1b365e9ee67a3cd2b36cec16ce0 /cpp/060string.mu
parent49073ebeef77aea075728953a9fb05d968e1c46a (diff)
downloadmu-0b82eef7140123e29e2628232e3cc7f740d094f2.tar.gz
1099 - new recipe: convert integer to decimal string
Diffstat (limited to 'cpp/060string.mu')
-rw-r--r--cpp/060string.mu93
1 files changed, 93 insertions, 0 deletions
diff --git a/cpp/060string.mu b/cpp/060string.mu
index a0d2757d..d81cdf13 100644
--- a/cpp/060string.mu
+++ b/cpp/060string.mu
@@ -230,3 +230,96 @@ scenario buffer-append-works [
     18 <- 0
   ]
 ]
+
+# result:address:array:character <- integer-to-decimal-string n:integer
+recipe integer-to-decimal-string [
+  default-space:address:space <- new location:type, 30:literal
+  n:integer <- next-ingredient
+  # is it zero?
+  {
+    break-if n:integer
+    result:address:array:character <- new [0]
+    reply result:address:array:character
+  }
+  # save sign
+  negate-result:boolean <- copy 0:literal
+  {
+    negative?:boolean <- less-than n:integer, 0:literal
+    break-unless negative?:boolean
+    negate-result:boolean <- copy 1:literal
+    n:integer <- multiply n:integer -1:literal
+  }
+  # add digits from right to left into intermediate buffer
+  tmp:address:buffer <- init-buffer 30:literal
+  digit-base:integer <- copy 48:literal  # '0'
+  {
+    done?:boolean <- equal n:integer, 0:literal
+    break-if done?:boolean
+    n:integer, digit:integer <- divide-with-remainder n:integer, 10:literal
+    c:character <- add digit-base:integer, digit:integer
+    tmp:address:buffer <- buffer-append tmp:address:buffer, c:character
+    loop
+  }
+  # add sign
+  {
+    break-unless negate-result:boolean
+    tmp:address:buffer <- buffer-append tmp:address:buffer, 45:literal  # '-'
+  }
+  # reverse buffer into string result
+  len:integer <- get tmp:address:buffer/deref, length:offset
+  buf:address:array:character <- get tmp:address:buffer/deref data:offset
+  result:address:array:character <- new character:type, len:integer
+  i:integer <- subtract len:integer, 1:literal
+  j:integer <- copy 0:literal
+  {
+    # while i >= 0
+    done?:boolean <- less-than i:integer, 0:literal
+    break-if done?:boolean
+    # result[j] = tmp[i]
+    src:character <- index buf:address:array:character/deref, i:integer
+    dest:address:character <- index-address result:address:array:character/deref, j:integer
+    dest:address:character/deref <- copy src:character
+    # ++i
+    i:integer <- subtract i:integer, 1:literal
+    # --j
+    j:integer <- add j:integer, 1:literal
+    loop
+  }
+  reply result:address:array:character
+]
+
+scenario integer-to-decimal-digit-zero [
+  run [
+    1:address:array:character/raw <- integer-to-decimal-string 0:literal
+    2:array:character/raw <- copy 1:address:array:character/deref/raw
+  ]
+  memory should contain [
+    2 <- 1
+    3 <- 48  # '0'
+  ]
+]
+
+scenario integer-to-decimal-digit-positive [
+  run [
+    1:address:array:character/raw <- integer-to-decimal-string 234:literal
+    2:array:character/raw <- copy 1:address:array:character/deref/raw
+  ]
+  memory should contain [
+    2 <- 3
+    3 <- 50  # '2'
+    4 <- 51  # '3'
+    5 <- 52  # '4'
+  ]
+]
+
+scenario integer-to-decimal-digit-negative [
+  run [
+    1:address:array:character/raw <- integer-to-decimal-string -1:literal
+    2:array:character/raw <- copy 1:address:array:character/deref/raw
+  ]
+  memory should contain [
+    2 <- 2
+    3 <- 45  # '-'
+    4 <- 49  # '1'
+  ]
+]