about summary refs log tree commit diff stats
path: root/cpp/020array
blob: 96591366b4701330a3bc4a636bc99177ae7ac2aa (plain) (blame)
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
//: Support for arrays.
:(before "End Mu Types Initialization")
//: We'll use this array as a running example:
int integer_array = Type_number["integer-array"] = Next_type_number++;
Type[integer_array].is_array = true;
Type[integer_array].element.push_back(integer);
Type[integer_array].name = "integer-array";

//: update size mismatch check
:(replace "if (size_of(x) != data.size())" following "void write_memory(reagent x, vector<int> data)")
if (!Type[x.types[0]].is_array && size_of(x) != data.size())

//: Arrays can be copied around with a single instruction just like integers,
//: no matter how large they are.

:(scenario copy_array)
recipe main [
  1:integer <- copy 3:literal
  2:integer <- copy 14:literal
  3:integer <- copy 15:literal
  4:integer <- copy 16:literal
  5:integer-array <- copy 1:integer-array
]
+run: instruction main/4
+run: ingredient 0 is 1
+mem: location 1 is 3
+mem: location 2 is 14
+mem: location 3 is 15
+mem: location 4 is 16
+mem: storing 3 in location 5
+mem: storing 14 in location 6
+mem: storing 15 in location 7
+mem: storing 16 in location 8

:(before "End size_of Cases")
if (t.is_array) {
  int base = r.value;
  if (Memory[base] == 0) return 0;
  reagent x;
  x.set_value(base+1);
  x.types.push_back(t.element[0]);
  return 1 + Memory[base]*size_of(x);
}

:(before "End Globals")
// Operator to look at elements of arrays.
const int INDEX = 20;
:(before "End Primitive Recipe Numbers")
Recipe_number["index"] = INDEX;
assert(Next_recipe_number == INDEX);
Next_recipe_number++;
:(before "End Primitive Recipe Implementations")
case INDEX: {
  trace("run") << "ingredient 0 is " << instructions[pc].ingredients[0].name;
  reagent base = canonize(instructions[pc].ingredients[0]);
  int base_address = base.value;
  int base_type = base.types[0];
  assert(Type[base_type].is_array);
  trace("run") << "ingredient 1 is " << instructions[pc].ingredients[1].name;
  size_t offset = instructions[pc].ingredients[1].value;
  reagent elem;
  elem.types.push_back(Type[base_type].element[0]);
  int src = base_address + 1 + offset*size_of(elem);
  trace("run") << "address to copy is " << src;
  int src_type = Type[base_type].element[0];
  trace("run") << "its type is " << src_type;
  reagent tmp;
  tmp.set_value(src);
  tmp.types.push_back(src_type);
  vector<int> result(read_memory(tmp));
  trace("run") << "product 0 is " << result[0];
  write_memory(instructions[pc].products[0], result);
  break;
}

:(scenario "index")
recipe main [
  1:integer <- copy 3:literal
  2:integer <- copy 14:literal
  3:integer <- copy 15:literal
  4:integer <- copy 16:literal
  5:integer <- index 1:integer-array, 0:literal
]
+run: instruction main/4
+run: ingredient 0 is 1
+run: ingredient 1 is 0
+run: address to copy is 2
+run: its type is 1
+mem: location 2 is 14
+run: product 0 is 14
+mem: storing 14 in location 5

:(before "End Globals")
// To write to fields of records, you need their address.
const int INDEX_ADDRESS = 21;
:(before "End Primitive Recipe Numbers")
Recipe_number["index-address"] = INDEX_ADDRESS;
assert(Next_recipe_number == INDEX_ADDRESS);
Next_recipe_number++;
:(before "End Primitive Recipe Implementations")
case INDEX_ADDRESS: {
  trace("run") << "ingredient 0 is " << instructions[pc].ingredients[0].name;
  reagent base = canonize(instructions[pc].ingredients[0]);
  int base_address = base.value;
  int base_type = base.types[0];
  assert(Type[base_type].is_array);
  trace("run") << "ingredient 1 is " << instructions[pc].ingredients[1].name;
  size_t offset = instructions[pc].ingredients[1].value;
  reagent elem;
  elem.types.push_back(Type[base_type].element[0]);
  int src = base_address + 1 + offset*size_of(elem);
  trace("run") << "address to copy is " << src;
  vector<int> result;
  result.push_back(src);
  trace("run") << "product 0 is " << result[0];
  write_memory(instructions[pc].products[0], result);
  break;
}

:(scenario "index_address")
recipe main [
  1:integer <- copy 3:literal
  2:integer <- copy 14:literal
  3:integer <- copy 15:literal
  4:integer <- copy 16:literal
  5:integer <- index-address 1:integer-array, 0:literal
]
+run: instruction main/4
+run: ingredient 0 is 1
+run: ingredient 1 is 0
+run: address to copy is 2
+mem: storing 2 in location 5