about summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorKartik K. Agaram <vc@akkartik.com>2015-05-06 12:13:04 -0700
committerKartik K. Agaram <vc@akkartik.com>2015-05-06 12:15:25 -0700
commit768bdb4dbf4e8943fe1c3fcf7f8840372ba79ec6 (patch)
treedbe277341a84707b927c322ba6ba95d9f40cf037
parent4680525f84ab44e6df1b032ee4eeb7ef6ca3e466 (diff)
downloadmu-768bdb4dbf4e8943fe1c3fcf7f8840372ba79ec6.tar.gz
1293 - start porting the chessboard app over
Just to put all our new test primitives through their paces, and iron
out any kinks.

Just the one chessboard scenario is taking 1.5-2.5x all the tests we've
written so far. But we're starting from a faster baseline, that was the
point of the C++ port. I also have -O3 optimizations in my back-pocket.
-rw-r--r--020run.cc1
-rw-r--r--035call.cc2
-rw-r--r--071print.mu76
-rw-r--r--072scenario_screen.cc1
-rw-r--r--chessboard.mu142
5 files changed, 215 insertions, 7 deletions
diff --git a/020run.cc b/020run.cc
index ee0bbb61..d8fdcf55 100644
--- a/020run.cc
+++ b/020run.cc
@@ -55,6 +55,7 @@ void run_current_routine()
     if (current_instruction().is_label) { ++current_step_index(); continue; }
     trace("run") << "instruction " << current_recipe_name() << '/' << current_step_index();
     trace("run") << current_instruction().to_string();
+//?     trace("run") << Memory[1033] << '\n'; //? 1
 //?     cout << "operation " << current_instruction().operation << '\n'; //? 3
     switch (current_instruction().operation) {
       // Primitive Recipe Implementations
diff --git a/035call.cc b/035call.cc
index 2cb40af8..c88a16db 100644
--- a/035call.cc
+++ b/035call.cc
@@ -72,7 +72,7 @@ inline const instruction& current_instruction() {
 default: {
   // not a primitive; try to look up the book of recipes
   if (Recipe.find(current_instruction().operation) == Recipe.end()) {
-    raise << "undefined operation " << current_instruction().operation << ": " << current_instruction().name << '\n';
+    raise << "undefined operation " << current_instruction().operation << ": " << current_instruction().to_string() << '\n';
     break;
   }
   Current_routine->calls.push(call(current_instruction().operation));
diff --git a/071print.mu b/071print.mu
index 2bf1df0b..e02e8483 100644
--- a/071print.mu
+++ b/071print.mu
@@ -66,6 +66,13 @@ recipe print-character [
 #? ] #? 1
     # save character in fake screen
     row:address:integer <- get-address x:address:screen/deref, cursor-row:offset
+#?     $print [CCC: ] #? 1
+#?     $print row:address:integer #? 1
+#?     $print [ -> ] #? 1
+#?     $print row:address:integer/deref #? 1
+#?     $print [ #? 1
+#? ] #? 1
+#?     $stop-tracing #? 1
     column:address:integer <- get-address x:address:screen/deref, cursor-column:offset
     width:integer <- get x:address:screen/deref, num-columns:offset
     index:integer <- multiply row:address:integer/deref, width:integer
@@ -137,10 +144,10 @@ recipe cursor-position [
     break-unless x:address:screen
     row:integer <- get x:address:screen/deref, cursor-row:offset
     column:integer <- get x:address:screen/deref, cursor-column:offset
-    reply row:integer, column:integer
+    reply row:integer, column:integer, x:address:screen/same-as-ingredient:0
   }
   row:integer, column:integer <- cursor-position-on-display
-  reply row:integer, column:integer
+  reply row:integer, column:integer, x:address:screen/same-as-ingredient:0
 ]
 
 recipe move-cursor [
@@ -200,7 +207,20 @@ recipe cursor-down [
       at-bottom?:boolean <- greater-or-equal row:address:integer/deref, height:integer
       break-if at-bottom?:boolean
       # row = row+1
-      row:address:integer/deref <- add row:address:integer, 1:literal
+#?       $print [AAA: ] #? 1
+#?       $print row:address:integer #? 1
+#?       $print [ -> ] #? 1
+#?       $print row:address:integer/deref #? 1
+#?       $print [ #? 1
+#? ] #? 1
+      row:address:integer/deref <- add row:address:integer/deref, 1:literal
+#?       $print [BBB: ] #? 1
+#?       $print row:address:integer #? 1
+#?       $print [ -> ] #? 1
+#?       $print row:address:integer/deref #? 1
+#?       $print [ #? 1
+#? ] #? 1
+#?       $start-tracing #? 1
     }
     reply x:address:screen/same-as-ingredient:0
   }
@@ -221,7 +241,7 @@ recipe cursor-up [
       at-top?:boolean <- lesser-than row:address:integer/deref, 0:literal
       break-if at-top?:boolean
       # row = row-1
-      row:address:integer/deref <- subtract row:address:integer, 1:literal
+      row:address:integer/deref <- subtract row:address:integer/deref, 1:literal
     }
     reply x:address:screen/same-as-ingredient:0
   }
@@ -243,7 +263,7 @@ recipe cursor-right [
       at-bottom?:boolean <- greater-or-equal column:address:integer/deref, width:integer
       break-if at-bottom?:boolean
       # column = column+1
-      column:address:integer/deref <- add column:address:integer, 1:literal
+      column:address:integer/deref <- add column:address:integer/deref, 1:literal
     }
     reply x:address:screen/same-as-ingredient:0
   }
@@ -264,7 +284,7 @@ recipe cursor-left [
       at-top?:boolean <- lesser-than column:address:integer/deref, 0:literal
       break-if at-top?:boolean
       # column = column-1
-      column:address:integer/deref <- subtract column:address:integer, 1:literal
+      column:address:integer/deref <- subtract column:address:integer/deref, 1:literal
     }
     reply x:address:screen/same-as-ingredient:0
   }
@@ -272,3 +292,47 @@ recipe cursor-left [
   move-cursor-left-on-display
   reply x:address:screen/same-as-ingredient:0
 ]
+
+recipe cursor-to-start-of-line [
+  default-space:address:array:location <- new location:type, 30:literal
+  x:address:screen <- next-ingredient
+  row:integer, _, x:address:screen <- cursor-position x:address:screen
+  column:integer <- copy 0:literal
+  x:address:screen <- move-cursor x:address:screen, row:integer, column:integer
+  reply x:address:screen/same-as-ingredient:0
+]
+
+recipe cursor-to-next-line [
+  default-space:address:array:location <- new location:type, 30:literal
+  x:address:screen <- next-ingredient
+  x:address:screen <- cursor-down x:address:screen
+  x:address:screen <- cursor-to-start-of-line x:address:screen
+  reply x:address:screen/same-as-ingredient:0
+]
+
+recipe print-string [
+  default-space:address:array:location <- new location:type, 30:literal
+  x:address:screen <- next-ingredient
+  s:address:array:character <- next-ingredient
+  len:integer <- length s:address:array:character/deref
+  i:integer <- copy 0:literal
+  {
+    done?:boolean <- greater-or-equal i:integer, len:integer
+    break-if done?:boolean
+    c:character <- index s:address:array:character/deref, i:integer
+    print-character x:address:screen c:character
+    i:integer <- add i:integer, 1:literal
+    loop
+  }
+  reply x:address:screen/same-as-ingredient:0
+]
+
+recipe print-integer [
+  default-space:address:array:location <- new location:type, 30:literal
+  x:address:screen <- next-ingredient
+  n:integer <- next-ingredient
+  # todo: other bases besides decimal
+  s:address:array:character <- integer-to-decimal-string n:integer
+  print-string x:address:screen, s:address:array:character
+  reply x:address:screen/same-as-ingredient:0
+]
diff --git a/072scenario_screen.cc b/072scenario_screen.cc
index 43266e78..993639dd 100644
--- a/072scenario_screen.cc
+++ b/072scenario_screen.cc
@@ -117,6 +117,7 @@ void check_screen(const string& contents) {
   ++screen_data_start;  // now skip length
   for (index_t i = 0; i < expected_contents.size(); ++i) {
     trace("run") << "checking location " << screen_data_start+i;
+//?     cerr << "comparing " << i/screen_width << ", " << i%screen_width << ": " << Memory[screen_data_start+i] << " vs " << (int)expected_contents[i] << '\n'; //? 1
     if ((!Memory[screen_data_start+i] && !isspace(expected_contents[i]))  // uninitialized memory => spaces
         || (Memory[screen_data_start+i] && Memory[screen_data_start+i] != expected_contents[i])) {
 //?       cerr << "CCC " << Trace_stream << " " << Hide_warnings << '\n'; //? 1
diff --git a/chessboard.mu b/chessboard.mu
new file mode 100644
index 00000000..d4b00b6f
--- /dev/null
+++ b/chessboard.mu
@@ -0,0 +1,142 @@
+recipe init-board [
+  default-space:address:array:location <- new location:type, 30:literal
+  initial-position:address:array:integer <- next-ingredient
+  # assert(length(initial-position) == 64)
+  len:integer <- length initial-position:address:array:integer/deref
+  correct-length?:boolean <- equal len:integer, 64:literal
+  assert correct-length?:boolean, [chessboard had incorrect size]
+  # board is an array of pointers to files; file is an array of characters
+  board:address:array:address:array:character <- new location:type, 8:literal
+  col:integer <- copy 0:literal
+  {
+    done?:boolean <- equal col:integer, 8:literal
+    break-if done?:boolean
+    file:address:address:array:character <- index-address board:address:array:address:array:character/deref, col:integer
+    file:address:address:array:character/deref <- init-file initial-position:address:array:integer, col:integer
+    col:integer <- add col:integer, 1:literal
+    loop
+  }
+  reply board:address:array:address:array:character
+]
+
+recipe init-file [
+  default-space:address:array:location <- new location:type, 30:literal
+  position:address:array:integer <- next-ingredient
+  index:integer <- next-ingredient
+  index:integer <- multiply index:integer, 8:literal
+  result:address:array:character <- new character:type, 8:literal
+  row:integer <- copy 0:literal
+  {
+    done?:boolean <- equal row:integer, 8:literal
+    break-if done?:boolean
+    dest:address:character <- index-address result:address:array:character/deref, row:integer
+    dest:address:character/deref <- index position:address:array:integer/deref, index:integer
+    row:integer <- add row:integer, 1:literal
+    index:integer <- add index:integer, 1:literal
+    loop
+  }
+  reply result:address:array:character
+]
+
+recipe print-board [
+  default-space:address:array:location <- new location:type, 30:literal
+  screen:address <- next-ingredient
+  board:address:array:address:array:character <- next-ingredient
+  row:integer <- copy 7:literal  # start printing from the top of the board
+  # print each row
+  {
+    done?:boolean <- lesser-than row:integer, 0:literal
+    break-if done?:boolean
+    # print rank number as a legend
+    rank:integer <- add row:integer, 1:literal
+    print-integer screen:address, rank:integer
+    s:address:array:character <- new [ | ]
+    print-string screen:address, s:address:array:character
+    # print each square in the row
+    col:integer <- copy 0:literal
+    {
+      done?:boolean <- equal col:integer, 8:literal
+      break-if done?:boolean
+      f:address:array:character <- index board:address:array:address:array:character/deref, col:integer
+      s:character <- index f:address:array:character/deref, row:integer
+      print-character screen:address, s:character
+      print-character screen:address, 32:literal  # ' '
+      col:integer <- add col:integer, 1:literal
+      loop
+    }
+    row:integer <- subtract row:integer, 1:literal
+    cursor-to-next-line screen:address
+    loop
+  }
+  # print file letters as legend
+  s:address:array:character <- new [  +----------------]
+  print-string screen:address, s:address:array:character
+  screen:address <- cursor-to-next-line screen:address
+#?   screen:address <- print-character screen:address, 97:literal #? 1
+  s:address:array:character <- new [    a b c d e f g h]
+  screen:address <- print-string screen:address, s:address:array:character
+  screen:address <- cursor-to-next-line screen:address
+]
+
+scenario printing-the-board [
+  assume-screen 30:literal/width, 24:literal/height
+  run [
+#?     $print [AAA #? 1
+#? ] #? 1
+    # layout in memory:
+    #   R P _ _ _ _ p r
+    #   N P _ _ _ _ p n
+    #   B P _ _ _ _ p b
+    #   Q P _ _ _ _ p q
+    #   K P _ _ _ _ p k
+    #   B P _ _ _ _ p B
+    #   N P _ _ _ _ p n
+    #   R P _ _ _ _ p r
+    1:address:array:integer/initial-position <- init-array 82:literal/R, 80:literal/P, 32:literal/blank, 32:literal/blank, 32:literal/blank, 32:literal/blank, 112:literal/p, 114:literal/r, 78:literal/N, 80:literal/P, 32:literal/blank, 32:literal/blank, 32:literal/blank, 32:literal/blank, 112:literal/p, 110:literal/n, 66:literal/B, 80:literal/P, 32:literal/blank, 32:literal/blank, 32:literal/blank, 32:literal/blank, 112:literal/p, 98:literal/b, 81:literal/Q, 80:literal/P, 32:literal/blank, 32:literal/blank, 32:literal/blank, 32:literal/blank, 112:literal/p, 113:literal/q, 75:literal/K, 80:literal/P, 32:literal/blank, 32:literal/blank, 32:literal/blank, 32:literal/blank, 112:literal/p, 107:literal/k, 66:literal/B, 80:literal/P, 32:literal/blank, 32:literal/blank, 32:literal/blank, 32:literal/blank, 112:literal/p, 98:literal/b, 78:literal/N, 80:literal/P, 32:literal/blank, 32:literal/blank, 32:literal/blank, 32:literal/blank, 112:literal/p, 110:literal/n, 82:literal/R, 80:literal/P, 32:literal/blank, 32:literal/blank, 32:literal/blank, 32:literal/blank, 112:literal/p, 114:literal/r
+#?       82:literal/R, 80:literal/P, 32:literal/blank, 32:literal/blank, 32:literal/blank, 32:literal/blank, 112:literal/p, 114:literal/r,
+#?       78:literal/N, 80:literal/P, 32:literal/blank, 32:literal/blank, 32:literal/blank, 32:literal/blank, 112:literal/p, 110:literal/n,
+#?       66:literal/B, 80:literal/P, 32:literal/blank, 32:literal/blank, 32:literal/blank, 32:literal/blank, 112:literal/p, 98:literal/b, 
+#?       81:literal/Q, 80:literal/P, 32:literal/blank, 32:literal/blank, 32:literal/blank, 32:literal/blank, 112:literal/p, 113:literal/q,
+#?       75:literal/K, 80:literal/P, 32:literal/blank, 32:literal/blank, 32:literal/blank, 32:literal/blank, 112:literal/p, 107:literal/k,
+#?       66:literal/B, 80:literal/P, 32:literal/blank, 32:literal/blank, 32:literal/blank, 32:literal/blank, 112:literal/p, 98:literal/b,
+#?       78:literal/N, 80:literal/P, 32:literal/blank, 32:literal/blank, 32:literal/blank, 32:literal/blank, 112:literal/p, 110:literal/n,
+#?       82:literal/R, 80:literal/P, 32:literal/blank, 32:literal/blank, 32:literal/blank, 32:literal/blank, 112:literal/p, 114:literal/r
+#?     $print [BBB #? 1
+#? ] #? 1
+#?     $start-tracing #? 1
+    2:address:array:address:array:character/board <- init-board 1:address:array:integer/initial-position
+#?     $print [CCC #? 1
+#? ] #? 1
+    screen:address <- print-board screen:address, 2:address:array:address:array:character/board
+#?     $print [DDD #? 1
+#? ] #? 1
+  ]
+  screen-should-contain [
+  #  012345678901234567890123456789
+    .8 | r n b q k b n r           .
+    .7 | p p p p p p p p           .
+    .6 |                           .
+    .5 |                           .
+    .4 |                           .
+    .3 |                           .
+    .2 | P P P P P P P P           .
+    .1 | R N B Q K B N R           .
+    .  +----------------           .
+    .    a b c d e f g h           .
+    .                              .
+    .                              .
+    .                              .
+    .                              .
+    .                              .
+    .                              .
+    .                              .
+    .                              .
+    .                              .
+    .                              .
+    .                              .
+    .                              .
+    .                              .
+    .                              .
+    .                              .
+  ]
+]