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-17 21:51:13 -0700
committerKartik K. Agaram <vc@akkartik.com>2015-04-17 21:51:13 -0700
commitb38e581993c4e7ae001572cbdb1855bc8d8db5b3 (patch)
tree1cab4b99776abc29312757b9dd590e1d6f69b6ac /cpp/060string.mu
parent7b085072b8122450f64f4ffdb3be659bbf1fc684 (diff)
downloadmu-b38e581993c4e7ae001572cbdb1855bc8d8db5b3.tar.gz
1090
Diffstat (limited to 'cpp/060string.mu')
-rw-r--r--cpp/060string.mu100
1 files changed, 100 insertions, 0 deletions
diff --git a/cpp/060string.mu b/cpp/060string.mu
index 85ff65b6..fb1a1eb5 100644
--- a/cpp/060string.mu
+++ b/cpp/060string.mu
@@ -105,11 +105,111 @@ container buffer [
 
 recipe init-buffer [
   default-space:address:space <- new location:type, 30:literal
+#?   $print default-space:address:space
+#?   $print [
+#? ]
   result:address:buffer <- new buffer:type
   len:address:integer <- get-address result:address:buffer/deref, length:offset
   len:address:integer/deref <- copy 0:literal
   s:address:address:array:character <- get-address result:address:buffer/deref, data:offset
   capacity:integer <- next-ingredient
   s:address:address:array:character/deref <- new character:type, capacity:integer
+#?   $print s:address:address:array:character/deref
+#?   $print [
+#? ]
   reply result:address:buffer
 ]
+
+recipe grow-buffer [
+  default-space:address:space <- new location:type, 30:literal
+  in:address:buffer <- next-ingredient
+  # double buffer size
+  x:address:address:array:character <- get-address in:address:buffer/deref, data:offset
+  oldlen:integer <- length x:address:address:array:character/deref/deref
+  newlen:integer <- multiply oldlen:integer, 2:literal
+  olddata:address:array:character <- copy x:address:address:array:character/deref
+  x:address:address:array:character/deref <- new character:type, newlen:integer
+  # copy old contents
+  i:integer <- copy 0:literal
+  {
+    done?:boolean <- greater-or-equal i:integer, oldlen:integer
+    break-if done?:boolean
+    src:character <- index olddata:address:array:character/deref, i:integer
+    dest:address:character <- index-address x:address:address:array:character/deref/deref, i:integer
+    dest:address:character/deref <- copy src:character
+    i:integer <- add i:integer, 1:literal
+    loop
+  }
+  reply in:address:buffer
+]
+
+recipe buffer-full? [
+  default-space:address:space <- new location:type, 30:literal
+  in:address:buffer <- next-ingredient
+  len:integer <- get in:address:buffer/deref, length:offset
+  s:address:array:character <- get in:address:buffer/deref, data:offset
+  capacity:integer <- length s:address:array:character/deref
+  result:boolean <- greater-or-equal len:integer, capacity:integer
+  reply result:boolean
+]
+
+# in:address:buffer <- buffer-append in:address:buffer, c:character
+recipe buffer-append [
+  default-space:address:space <- new location:type, 30:literal
+  in:address:buffer <- next-ingredient
+  c:character <- next-ingredient
+  {
+    # grow buffer if necessary
+    full?:boolean <- buffer-full? in:address:buffer
+    break-unless full?:boolean
+    in:address:buffer <- grow-buffer in:address:buffer
+  }
+  len:address:integer <- get-address in:address:buffer/deref, length:offset
+  s:address:array:character <- get in:address:buffer/deref, data:offset
+  dest:address:character <- index-address s:address:array:character/deref, len:address:integer/deref
+  dest:address:character/deref <- copy c:character
+  len:address:integer/deref <- add len:address:integer/deref, 1:literal
+  reply in:address:buffer/same-as-arg:0
+]
+
+scenario buffer-append-works [
+  run [
+    default-space:address:space <- new location:type, 30:literal
+    x:address:buffer <- init-buffer 3:literal
+    s1:address:array:character <- get x:address:buffer/deref, data:offset
+    x:address:buffer <- buffer-append x:address:buffer, 97:literal  # 'a'
+    x:address:buffer <- buffer-append x:address:buffer, 98:literal  # 'b'
+    x:address:buffer <- buffer-append x:address:buffer, 99:literal  # 'c'
+    s2:address:array:character <- get x:address:buffer/deref, data:offset
+    1:boolean/raw <- equal s1:address:array:character, s2:address:array:character
+#?     $print s2:address:array:character
+#?     $print [
+#? ]
+#?     $print 1060:integer/raw
+#?     $print [
+#? ]
+#?     $print 1061:integer/raw
+#?     $print [
+#? ]
+#?     $print 1062:integer/raw
+#?     $print [
+#? ]
+#?     $print 1063:integer/raw
+#?     $print [
+#? ]
+#?     $print 1064:integer/raw
+#?     $print [
+#? ]
+#?     $print 1065:integer/raw
+#?     $print [
+#? ]
+    2:array:character/raw <- copy s2:address:array:character/deref
+  ]
+  memory should contain [
+    1 <- 1   # no change in data pointer
+    2 <- 3   # size of data
+    3 <- 97  # data
+    4 <- 98
+    5 <- 99
+  ]
+]