about summary refs log tree commit diff stats
path: root/baremetal/504test-screen.mu
diff options
context:
space:
mode:
authorKartik Agaram <vc@akkartik.com>2021-02-07 00:17:17 -0800
committerKartik Agaram <vc@akkartik.com>2021-02-07 00:20:29 -0800
commit74f1512ff113cf35706af57e9d40c78b7d77f49e (patch)
tree7c7acb23e1a26387117e464ec6ab01126dbc8ae8 /baremetal/504test-screen.mu
parent6c4c25555c7df0d78ad41c813345f63cae1819de (diff)
downloadmu-74f1512ff113cf35706af57e9d40c78b7d77f49e.tar.gz
7690
Convert comments about magic constants into metadata.
Diffstat (limited to 'baremetal/504test-screen.mu')
-rw-r--r--baremetal/504test-screen.mu94
1 files changed, 47 insertions, 47 deletions
diff --git a/baremetal/504test-screen.mu b/baremetal/504test-screen.mu
index 614edd9d..07efcc7f 100644
--- a/baremetal/504test-screen.mu
+++ b/baremetal/504test-screen.mu
@@ -5,7 +5,7 @@
 # Tab characters (that translate into multiple screen cells) not supported.
 
 fn check-screen-row screen: (addr screen), y: int, expected: (addr array byte), msg: (addr array byte) {
-  check-screen-row-from screen, y, 0, expected, msg
+  check-screen-row-from screen, y, 0/row, expected, msg
 }
 
 fn check-screen-row-from screen-on-stack: (addr screen), x: int, y: int, expected: (addr array byte), msg: (addr array byte) {
@@ -35,23 +35,23 @@ fn check-screen-row-from screen-on-stack: (addr screen), x: int, y: int, expecte
       compare g, expected-grapheme
       {
         break-if-!=
-        draw-text-wrapping-right-then-down-from-cursor-over-full-screen 0, ".", 3  # 3=cyan
+        draw-text-wrapping-right-then-down-from-cursor-over-full-screen 0/screen, ".", 3/cyan
         break $check-screen-row-from:compare-graphemes
       }
       # otherwise print an error
       count-test-failure
-      draw-text-wrapping-right-then-down-from-cursor-over-full-screen 0, msg, 3  # 3=cyan
-      draw-text-wrapping-right-then-down-from-cursor-over-full-screen 0, ": expected '", 3
-      draw-grapheme-at-cursor 0, expected-grapheme, 3
-      move-cursor-rightward-and-downward 0, 0, 0x80  # screen-width
-      draw-text-wrapping-right-then-down-from-cursor-over-full-screen 0, "' at (", 3
-      draw-int32-hex-wrapping-right-then-down-from-cursor-over-full-screen 0, x, 3
-      draw-text-wrapping-right-then-down-from-cursor-over-full-screen 0, ", ", 3
-      draw-int32-hex-wrapping-right-then-down-from-cursor-over-full-screen 0, y, 3
-      draw-text-wrapping-right-then-down-from-cursor-over-full-screen 0, ") but observed '", 3
-      draw-grapheme-at-cursor 0, g, 3
-      move-cursor-rightward-and-downward 0, 0, 0x80  # screen-width
-      draw-text-wrapping-right-then-down-from-cursor-over-full-screen 0, "'", 3
+      draw-text-wrapping-right-then-down-from-cursor-over-full-screen 0/screen, msg, 3/cyan
+      draw-text-wrapping-right-then-down-from-cursor-over-full-screen 0/screen, ": expected '", 3
+      draw-grapheme-at-cursor 0/screen, expected-grapheme, 3/cyan
+      move-cursor-rightward-and-downward 0/screen, 0/xmin, 0x80/xmax=screen-width
+      draw-text-wrapping-right-then-down-from-cursor-over-full-screen 0/screen, "' at (", 3
+      draw-int32-hex-wrapping-right-then-down-from-cursor-over-full-screen 0/screen, x, 3
+      draw-text-wrapping-right-then-down-from-cursor-over-full-screen 0/screen, ", ", 3
+      draw-int32-hex-wrapping-right-then-down-from-cursor-over-full-screen 0/screen, y, 3
+      draw-text-wrapping-right-then-down-from-cursor-over-full-screen 0/screen, ") but observed '", 3
+      draw-grapheme-at-cursor 0/screen, g, 3/cyan
+      move-cursor-rightward-and-downward 0/screen, 0/xmin, 0x80/xmax=screen-width
+      draw-text-wrapping-right-then-down-from-cursor-over-full-screen 0/screen, "'", 3
     }
     idx <- increment
     increment x
@@ -62,7 +62,7 @@ fn check-screen-row-from screen-on-stack: (addr screen), x: int, y: int, expecte
 # various variants by screen-cell attribute; spaces in the 'expected' data should not match the attribute
 
 fn check-screen-row-in-color screen: (addr screen), fg: int, y: int, expected: (addr array byte), msg: (addr array byte) {
-  check-screen-row-in-color-from screen, fg, y, 0, expected, msg
+  check-screen-row-in-color-from screen, fg, y, 0/x, expected, msg
 }
 
 fn check-screen-row-in-color-from screen-on-stack: (addr screen), fg: int, y: int, x: int, expected: (addr array byte), msg: (addr array byte) {
@@ -102,46 +102,46 @@ fn check-screen-row-in-color-from screen-on-stack: (addr screen), fg: int, y: in
         compare g, expected-grapheme
         {
           break-if-!=
-          draw-text-wrapping-right-then-down-from-cursor-over-full-screen 0, ".", 3  # 3=cyan
+          draw-text-wrapping-right-then-down-from-cursor-over-full-screen 0/screen, ".", 3/cyan
           break $check-screen-row-in-color-from:compare-graphemes
         }
         # otherwise print an error
         count-test-failure
-        draw-text-wrapping-right-then-down-from-cursor-over-full-screen 0, msg, 3  # 3=cyan
-        draw-text-wrapping-right-then-down-from-cursor-over-full-screen 0, ": expected '", 3
-        draw-grapheme-at-cursor 0, expected-grapheme, 3
-        move-cursor-rightward-and-downward 0, 0, 0x80  # screen-width
-        draw-text-wrapping-right-then-down-from-cursor-over-full-screen 0, "' at (", 3
-        draw-int32-hex-wrapping-right-then-down-from-cursor-over-full-screen 0, x, 3
-        draw-text-wrapping-right-then-down-from-cursor-over-full-screen 0, ", ", 3
-        draw-int32-hex-wrapping-right-then-down-from-cursor-over-full-screen 0, y, 3
-        draw-text-wrapping-right-then-down-from-cursor-over-full-screen 0, ") but observed '", 3
-        draw-grapheme-at-cursor 0, g, 3
-        move-cursor-rightward-and-downward 0, 0, 0x80  # screen-width
-        draw-text-wrapping-right-then-down-from-cursor-over-full-screen 0, "'", 3
+        draw-text-wrapping-right-then-down-from-cursor-over-full-screen 0/screen, msg, 3/cyan
+        draw-text-wrapping-right-then-down-from-cursor-over-full-screen 0/screen, ": expected '", 3
+        draw-grapheme-at-cursor 0/screen, expected-grapheme, 3/cyan
+        move-cursor-rightward-and-downward 0/screen, 0/xmin, 0x80/xmax=screen-width
+        draw-text-wrapping-right-then-down-from-cursor-over-full-screen 0/screen, "' at (", 3
+        draw-int32-hex-wrapping-right-then-down-from-cursor-over-full-screen 0/screen, x, 3
+        draw-text-wrapping-right-then-down-from-cursor-over-full-screen 0/screen, ", ", 3
+        draw-int32-hex-wrapping-right-then-down-from-cursor-over-full-screen 0/screen, y, 3
+        draw-text-wrapping-right-then-down-from-cursor-over-full-screen 0/screen, ") but observed '", 3
+        draw-grapheme-at-cursor 0/screen, g, 3/cyan
+        move-cursor-rightward-and-downward 0/screen, 0/xmin, 0x80/xmax=screen-width
+        draw-text-wrapping-right-then-down-from-cursor-over-full-screen 0/screen, "'", 3
       }
       $check-screen-row-in-color-from:compare-colors: {
         var color/eax: int <- screen-color-at-idx screen, idx
         compare fg, color
         {
           break-if-!=
-          draw-text-wrapping-right-then-down-from-cursor-over-full-screen 0, ".", 3  # 3=cyan
+          draw-text-wrapping-right-then-down-from-cursor-over-full-screen 0/screen, ".", 3/cyan
           break $check-screen-row-in-color-from:compare-colors
         }
         # otherwise print an error
         count-test-failure
-        draw-text-wrapping-right-then-down-from-cursor-over-full-screen 0, msg, 3  # 3=cyan
-        draw-text-wrapping-right-then-down-from-cursor-over-full-screen 0, ": expected '", 3
-        draw-grapheme-at-cursor 0, expected-grapheme, 3
-        move-cursor-rightward-and-downward 0, 0, 0x80  # screen-width
-        draw-text-wrapping-right-then-down-from-cursor-over-full-screen 0, "' at (", 3
-        draw-int32-hex-wrapping-right-then-down-from-cursor-over-full-screen 0, x, 3
-        draw-text-wrapping-right-then-down-from-cursor-over-full-screen 0, ", ", 3
-        draw-int32-hex-wrapping-right-then-down-from-cursor-over-full-screen 0, y, 3
-        draw-text-wrapping-right-then-down-from-cursor-over-full-screen 0, ") in color ", 3
-        draw-int32-hex-wrapping-right-then-down-from-cursor-over-full-screen 0, fg, 3
-        draw-text-wrapping-right-then-down-from-cursor-over-full-screen 0, " but observed color ", 3
-        draw-int32-hex-wrapping-right-then-down-from-cursor-over-full-screen 0, color, 3
+        draw-text-wrapping-right-then-down-from-cursor-over-full-screen 0/screen, msg, 3/cyan
+        draw-text-wrapping-right-then-down-from-cursor-over-full-screen 0/screen, ": expected '", 3
+        draw-grapheme-at-cursor 0/screen, expected-grapheme, 3/cyan
+        move-cursor-rightward-and-downward 0/screen, 0/xmin, 0x80/xmax=screen-width
+        draw-text-wrapping-right-then-down-from-cursor-over-full-screen 0/screen, "' at (", 3
+        draw-int32-hex-wrapping-right-then-down-from-cursor-over-full-screen 0/screen, x, 3
+        draw-text-wrapping-right-then-down-from-cursor-over-full-screen 0/screen, ", ", 3
+        draw-int32-hex-wrapping-right-then-down-from-cursor-over-full-screen 0/screen, y, 3
+        draw-text-wrapping-right-then-down-from-cursor-over-full-screen 0/screen, ") in color ", 3
+        draw-int32-hex-wrapping-right-then-down-from-cursor-over-full-screen 0/screen, fg, 3
+        draw-text-wrapping-right-then-down-from-cursor-over-full-screen 0/screen, " but observed color ", 3
+        draw-int32-hex-wrapping-right-then-down-from-cursor-over-full-screen 0/screen, color, 3
       }
     }
     idx <- increment
@@ -154,15 +154,15 @@ fn test-draw-single-grapheme {
   var screen-on-stack: screen
   var screen/esi: (addr screen) <- address screen-on-stack
   initialize-screen screen, 5, 4
-  var c/eax: grapheme <- copy 0x61  # 'a'
-  draw-grapheme screen, c, 0, 0, 1  # color=1
-  check-screen-row screen, 0, "a", "F - test-draw-single-grapheme"  # top-left corner of the screen
+  var c/eax: grapheme <- copy 0x61/a
+  draw-grapheme screen, c, 0/x, 0/y, 1/color
+  check-screen-row screen, 0/row, "a", "F - test-draw-single-grapheme"  # top-left corner of the screen
 }
 
 fn test-draw-multiple-graphemes {
   var screen-on-stack: screen
   var screen/esi: (addr screen) <- address screen-on-stack
-  initialize-screen screen, 0x10, 4
-  draw-text-wrapping-right-then-down-from-cursor-over-full-screen screen, "Hello, 世界", 1  # color=1
-  check-screen-row screen, 0, "Hello, 世界", "F - test-draw-multiple-graphemes"
+  initialize-screen screen, 0x10/rows, 4/cols
+  draw-text-wrapping-right-then-down-from-cursor-over-full-screen screen, "Hello, 世界", 1/color
+  check-screen-row screen, 0/screen, "Hello, 世界", "F - test-draw-multiple-graphemes"
 }
>
c9a5a7ba ^
3a982057 ^


78c50205 ^
9dcbec39 ^
3a982057 ^
81c87f08 ^

53ba69a7 ^
691b529e ^
1fa53058 ^
0487a30e ^
67573caf ^
ac0e9db5 ^
0487a30e ^
67573caf ^
69f04c3f ^
4be9a93b ^
3e849f11 ^
9dcbec39 ^
75aa3a98 ^
0487a30e ^
75aa3a98 ^
2d29369f ^
0487a30e ^
4be9a93b ^
69f04c3f ^

717ab659 ^
4a943d4e ^














3e849f11 ^
4a943d4e ^


















717ab659 ^



795f5244 ^
4a48bedc ^
166e3c0d ^



717ab659 ^

67573caf ^
717ab659 ^


23d3a022 ^

4a943d4e ^















717ab659 ^



795f5244 ^
4a48bedc ^
166e3c0d ^
717ab659 ^
166e3c0d ^
2b250717 ^
e4630643 ^

5f98a10c ^
9dcbec39 ^
e4630643 ^

166e3c0d ^



b24eb476 ^
67573caf ^
0487a30e ^
67573caf ^
ac0e9db5 ^
827898fc ^
67573caf ^
717ab659 ^

ac0e9db5 ^
0487a30e ^

827898fc ^
717ab659 ^



c9a5a7ba ^
78c50205 ^
c9a5a7ba ^
78c50205 ^

c9a5a7ba ^
af023b32 ^

1fb0cf9e ^
af023b32 ^


1fb0cf9e ^
af023b32 ^
93d4cc93 ^
1fb0cf9e ^
93d4cc93 ^
c9a5a7ba ^
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
                                                                         
                                       
 













                                       
 












                                        
 
                           
                                         
                            
                               

                                
 
                                 
                                               
                                                               
                                                                  
                                
                                                   
                                 
 
 

                                             
                                        
                                                        
                                                   
                                       
                       
                                  
                                                                                                                                                

          



                                                
                                          
                                                                                          
                                                                   
                                             


                                                                                                    
                               
                                                                                                  
     

                                                                                                          
                                                                                                                                                                                                                              
                                                
     
                       
                                                                                       
                                                                           
                                
                                                
   
        
                                                 
                                                                                                                                                      
                                                      
                       
                                                                    
                                                                         
                                
   

        
 














                                                     
 


















                                                                            



                                             
                                                              
                                                         



                                       

                                                
                                                


        

                                                     















                                                                                         



                                             
                                              
                                         
                                       
                  
                                    
                                                                                                                                                  

          
                                                                                     
                                                                                                                                                              

          



                                                
                                                                                          
                                                                        
                       
                                                                                       
                                                                           
                                
                                                

        
                                                   

                                                                                                 
                                  



        
 
                                                                            
       

                                         
               

                           
                                                    


                                  
                                                         
                             
                                    
                                                                    
                                             
 
//: Calls can take ingredients just like primitives. To access a recipe's
//: ingredients, use 'next-ingredient'.

void test_next_ingredient() {
  run(
      "def main [\n"
      "  f 2\n"
      "]\n"
      "def f [\n"
      "  12:num <- next-ingredient\n"
      "  13:num <- add 1, 12:num\n"
      "]\n"
  );
  CHECK_TRACE_CONTENTS(
      "mem: storing 3 in location 13\n"
  );
}

void test_next_ingredient_missing() {
  run(
      "def main [\n"
      "  f\n"
      "]\n"
      "def f [\n"
      "  _, 12:num <- next-ingredient\n"
      "]\n"
  );
  CHECK_TRACE_CONTENTS(
      "mem: storing 0 in location 12\n"
  );
}

:(before "End call Fields")
vector<vector<double> > ingredient_atoms;
vector<reagent> ingredients;
int next_ingredient_to_process;
:(before "End call Constructor")
next_ingredient_to_process = 0;

:(before "End Call Housekeeping")
for (int i = 0;  i < SIZE(ingredients);  ++i) {
  current_call().ingredient_atoms.push_back(ingredients.at(i));
  reagent/*copy*/ ingredient = call_instruction.ingredients.at(i);
  // End Compute Call Ingredient
  current_call().ingredients.push_back(ingredient);
  // End Populate Call Ingredient
}

:(before "End Primitive Recipe Declarations")
NEXT_INGREDIENT,
:(before "End Primitive Recipe Numbers")
put(Recipe_ordinal, "next-ingredient", NEXT_INGREDIENT);
put(Recipe_ordinal, "next-input", NEXT_INGREDIENT);
:(before "End Primitive Recipe Checks")
case NEXT_INGREDIENT: {
  if (!inst.ingredients.empty()) {
    raise << maybe(get(Recipe, r).name) << "'next-ingredient' didn't expect any ingredients in '" << to_original_string(inst) << "'\n" << end();
    break;
  }
  break;
}
:(before "End Primitive Recipe Implementations")
case NEXT_INGREDIENT: {
  assert(!Current_routine->calls.empty());
  if (current_call().next_ingredient_to_process < SIZE(current_call().ingredient_atoms)) {
    reagent/*copy*/ product = current_instruction().products.at(0);
    // End Preprocess NEXT_INGREDIENT product
    if (current_recipe_name() == "main") {
      // no ingredient types since the call might be implicit; assume ingredients are always strings
      // todo: how to test this?
      if (!is_mu_text(product))
        raise << "main: wrong type for ingredient '" << product.original_string << "'\n" << end();
    }
    else if (!types_coercible(product,
                              current_call().ingredients.at(current_call().next_ingredient_to_process))) {
      raise << maybe(current_recipe_name()) << "wrong type for ingredient '" << product.original_string << "': " << current_call().ingredients.at(current_call().next_ingredient_to_process).original_string << '\n' << end();
      // End next-ingredient Type Mismatch Error
    }
    products.push_back(
        current_call().ingredient_atoms.at(current_call().next_ingredient_to_process));
    assert(SIZE(products) == 1);  products.resize(2);  // push a new vector
    products.at(1).push_back(1);
    ++current_call().next_ingredient_to_process;
  }
  else {
    if (SIZE(current_instruction().products) < 2)
      raise << maybe(current_recipe_name()) << "no ingredient to save in '" << current_instruction().products.at(0).original_string << "'\n" << end();
    if (current_instruction().products.empty()) break;
    products.resize(2);
    // pad the first product with sufficient zeros to match its type
    products.at(0).resize(size_of(current_instruction().products.at(0)));
    products.at(1).push_back(0);
  }
  break;
}

:(code)
void test_next_ingredient_fail_on_missing() {
  Hide_errors = true;
  run(
      "def main [\n"
      "  f\n"
      "]\n"
      "def f [\n"
      "  11:num <- next-ingredient\n"
      "]\n"
  );
  CHECK_TRACE_CONTENTS(
      "error: f: no ingredient to save in '11:num'\n"
  );
}

void test_rewind_ingredients() {
  run(
      "def main [\n"
      "  f 2\n"
      "]\n"
      "def f [\n"
      "  12:num <- next-ingredient\n"  // consume ingredient
      "  _, 1:bool <- next-ingredient\n"  // will not find any ingredients
      "  rewind-ingredients\n"
      "  13:num, 2:bool <- next-ingredient\n"  // will find ingredient again
      "]\n"
  );
  CHECK_TRACE_CONTENTS(
      "mem: storing 2 in location 12\n"
      "mem: storing 0 in location 1\n"
      "mem: storing 2 in location 13\n"
      "mem: storing 1 in location 2\n"
  );
}

:(before "End Primitive Recipe Declarations")
REWIND_INGREDIENTS,
:(before "End Primitive Recipe Numbers")
put(Recipe_ordinal, "rewind-ingredients", REWIND_INGREDIENTS);
put(Recipe_ordinal, "rewind-inputs", REWIND_INGREDIENTS);
:(before "End Primitive Recipe Checks")
case REWIND_INGREDIENTS: {
  break;
}
:(before "End Primitive Recipe Implementations")
case REWIND_INGREDIENTS: {
  current_call().next_ingredient_to_process = 0;
  break;
}

//: another primitive: 'ingredient' for random access

:(code)
void test_ingredient() {
  run(
      "def main [\n"
      "  f 1, 2\n"
      "]\n"
      "def f [\n"
      "  12:num <- ingredient 1\n"  // consume second ingredient first
      "  13:num, 1:bool <- next-ingredient\n"  // next-ingredient tries to scan past that
      "]\n"
  );
  CHECK_TRACE_CONTENTS(
      "mem: storing 2 in location 12\n"
      "mem: storing 0 in location 1\n"
  );
}

:(before "End Primitive Recipe Declarations")
INGREDIENT,
:(before "End Primitive Recipe Numbers")
put(Recipe_ordinal, "ingredient", INGREDIENT);
put(Recipe_ordinal, "input", INGREDIENT);
:(before "End Primitive Recipe Checks")
case INGREDIENT: {
  if (SIZE(inst.ingredients) != 1) {
    raise << maybe(get(Recipe, r).name) << "'ingredient' expects exactly one ingredient, but got '" << to_original_string(inst) << "'\n" << end();
    break;
  }
  if (!is_literal(inst.ingredients.at(0)) && !is_mu_number(inst.ingredients.at(0))) {
    raise << maybe(get(Recipe, r).name) << "'ingredient' expects a literal ingredient, but got '" << inst.ingredients.at(0).original_string << "'\n" << end();
    break;
  }
  break;
}
:(before "End Primitive Recipe Implementations")
case INGREDIENT: {
  if (static_cast<int>(ingredients.at(0).at(0)) < SIZE(current_call().ingredient_atoms)) {
    current_call().next_ingredient_to_process = ingredients.at(0).at(0);
    products.push_back(
        current_call().ingredient_atoms.at(current_call().next_ingredient_to_process));
    assert(SIZE(products) == 1);  products.resize(2);  // push a new vector
    products.at(1).push_back(1);
    ++current_call().next_ingredient_to_process;
  }
  else {
    if (SIZE(current_instruction().products) > 1) {
      products.resize(2);
      products.at(0).push_back(0);  // todo: will fail noisily if we try to read a compound value
      products.at(1).push_back(0);
    }
  }
  break;
}

//: a particularly common array type is the text, or address:array:character
:(code)
bool is_mu_text(reagent/*copy*/ x) {
  // End Preprocess is_mu_text(reagent x)
  return x.type
      && !x.type->atom
      && x.type->left->atom
      && x.type->left->value == Address_type_ordinal
      && x.type->right
      && !x.type->right->atom
      && x.type->right->left->atom
      && x.type->right->left->value == Array_type_ordinal
      && x.type->right->right
      && !x.type->right->right->atom
      && x.type->right->right->left->value == Character_type_ordinal
      && x.type->right->right->right == NULL;
}