diff options
-rw-r--r-- | cpp/.traces/new_string | 22 | ||||
-rw-r--r-- | cpp/.traces/string_literal | 2 | ||||
-rw-r--r-- | cpp/029string | 36 |
3 files changed, 58 insertions, 2 deletions
diff --git a/cpp/.traces/new_string b/cpp/.traces/new_string new file mode 100644 index 00000000..d9d75df4 --- /dev/null +++ b/cpp/.traces/new_string @@ -0,0 +1,22 @@ +parse/0: instruction: 24 +parse/0: ingredient: {name: "abc def", value: 0, type: 0, properties: ["abc def": "literal-string"]} +parse/0: product: {name: "1", value: 0, type: 2-4-7, properties: ["1": "address":"array":"character"]} +parse/0: instruction: 20 +parse/0: ingredient: {name: "1", value: 0, type: 2-4-7, properties: ["1": "address":"array":"character", "deref": ]} +parse/0: ingredient: {name: "5", value: 0, type: 0, properties: ["5": "literal"]} +parse/0: product: {name: "2", value: 0, type: 7, properties: ["2": "character"]} +new/0: abc def -> 0 +after-brace/0: recipe main +after-brace/0: new ... +after-brace/0: index ... +run/0: instruction main/0 +mem/0: storing 1000 in location 1 +run/0: instruction main/1 +run/0: ingredient 0 is 1 +mem/0: location 1 is 1000 +run/0: ingredient 1 is 5 +run/0: address to copy is 1006 +run/0: its type is 7 +mem/0: location 1006 is 101 +run/0: product 0 is 101 +mem/0: storing 101 in location 2 diff --git a/cpp/.traces/string_literal b/cpp/.traces/string_literal index b989b04a..3f7ff417 100644 --- a/cpp/.traces/string_literal +++ b/cpp/.traces/string_literal @@ -1,6 +1,6 @@ parse/0: instruction: 24 parse/0: ingredient: {name: "abc def", value: 0, type: 0, properties: ["abc def": "literal-string"]} -parse/0: product: {name: "s", value: 0, type: 2-4-0, properties: ["s": "address":"array":"character"]} +parse/0: product: {name: "s", value: 0, type: 2-4-7, properties: ["s": "address":"array":"character"]} new/0: abc def -> 0 name/0: assign s 1 after-brace/0: recipe main diff --git a/cpp/029string b/cpp/029string index fd6b2824..209a1e7f 100644 --- a/cpp/029string +++ b/cpp/029string @@ -1,6 +1,13 @@ +//: Some instructions can take string literals for convenience. +//: +//: Instead of quotes, we'll use [] to delimit strings. That'll reduce the +//: need for escaping. And we can also imagine that 'recipe' might one day +//: itself be defined in mu, doing its own parsing. + +//: First extend the mu parser to support string literals. :(scenario "string_literal") recipe main [ - s:address:array:character <- new [abc def] + 1:address:array:character <- new [abc def] ] +parse: ingredient: {name: "abc def", value: 0, type: 0, properties: ["abc def": "literal-string"]} @@ -27,3 +34,30 @@ string slurp_quoted(istream& in) { } return out.str(); } + +//: Next, extend 'new' to handle a string literal argument. +:(scenario "new_string") +recipe main [ + 1:address:array:character <- new [abc def] + 2:character <- index 1:address:array:character/deref, 5:literal +] +# integer code for 'e' ++mem: storing 101 in location 2 + +:(before "End Mu Types Initialization") +Type_number["character"] = Next_type_number++; + +:(after "case NEW" following "Primitive Recipe Implementations") +if (instructions[pc].ingredients[0].properties[0].second[0] == "literal-string") { + // allocate an array just large enough for it + vector<int> result; + result.push_back(Current_routine.alloc); + write_memory(instructions[pc].products[0], result); + // assume that all characters fit in a single location + Memory[Current_routine.alloc++] = instructions[0].name.size(); + for (size_t i = 0; i < instructions[pc].ingredients[0].name.size(); ++i) { + Memory[Current_routine.alloc++] = instructions[pc].ingredients[0].name[i]; + } + // mu strings are not null-terminated in memory + break; +} |