From c495d2ac7ca0d7f1c1a9bbb7d1ad5072a7eface5 Mon Sep 17 00:00:00 2001 From: "Kartik K. Agaram" Date: Fri, 17 Apr 2015 11:00:56 -0700 Subject: 1075 --- cpp/020run | 187 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 187 insertions(+) create mode 100644 cpp/020run (limited to 'cpp/020run') diff --git a/cpp/020run b/cpp/020run new file mode 100644 index 00000000..91e242a7 --- /dev/null +++ b/cpp/020run @@ -0,0 +1,187 @@ +:(scenarios run) +:(scenario copy_literal) +recipe main [ + 1:integer <- copy 23:literal +] ++run: instruction main/0 ++run: ingredient 0 is 23 ++mem: storing 23 in location 1 + +:(scenario copy) +recipe main [ + 1:integer <- copy 23:literal + 2:integer <- copy 1:integer +] ++run: instruction main/1 ++run: ingredient 0 is 1 ++mem: location 1 is 23 ++mem: storing 23 in location 2 + +:(before "End Types") +// Book-keeping while running a recipe. +//: Later layers will change this. +struct routine { + recipe_number running_recipe; + size_t running_at; + routine(recipe_number r) :running_recipe(r), running_at(0) {} +}; + +:(before "End Globals") +routine* Current_routine = NULL; + +:(code) +void run(recipe_number r) { + run(routine(r)); +} + +void run(routine rr) { + Current_routine = &rr; + while (!done(rr)) { + vector& instructions = steps(rr); + size_t& pc = running_at(rr); + // Running one instruction. + if (instructions[pc].is_label) { ++pc; continue; } +//? cout << "AAA " << Trace_stream << " ^" << Trace_stream->dump_layer << "$\n"; //? 1 + trace("run") << "instruction " << recipe_name(rr) << '/' << pc; +//? cout << "operation " << instructions[pc].operation << '\n'; //? 3 +//? if (!instructions[pc].products.empty()) trace("foo") << "AAA product 0 is " << instructions[pc].products[0].to_string(); //? 1 + switch (instructions[pc].operation) { + // Primitive Recipe Implementations + case COPY: { + trace("run") << "ingredient 0 is " << instructions[pc].ingredients[0].name; + vector data = read_memory(instructions[pc].ingredients[0]); + write_memory(instructions[pc].products[0], data); + break; + } + // End Primitive Recipe Implementations + default: { + cout << "not a primitive op: " << instructions[pc].operation << '\n'; + } + } + ++pc; + } + Current_routine = NULL; +} + +//: Some helpers. +//: We'll need to override these later as we change the definition of routine. +//: Important that they return referrences into the routine. +inline size_t& running_at(routine& rr) { + return rr.running_at; +} + +inline string recipe_name(routine& rr) { + return Recipe[rr.running_recipe].name; +} + +inline vector& steps(routine& rr) { + return Recipe[rr.running_recipe].steps; +} + +inline bool done(routine& rr) { + return running_at(rr) >= steps(rr).size(); +} + +:(before "End Main") +if (argc > 1) { + setup(); + for (int i = 1; i < argc; ++i) { + load(argv[i]); + } + + Trace_stream = new trace_stream; +//? Trace_stream->dump_layer = "all"; //? 2 + transform_all(); + recipe_number r = Recipe_number[string("main")]; + if (r) run(r); + dump_memory(); +} + +:(code) +void load(string filename) { + ifstream fin(filename.c_str()); + if (!fin) { + raise << "no such file " << filename << '\n'; + return; + } + fin >> std::noskipws; + add_recipes(fin); + transform_all(); + fin.close(); +} + +//: On startup, load everything in core.mu +:(before "End Load Recipes") +load("core.mu"); +recently_added_recipes.clear(); // freeze everything so it doesn't get cleared by tests + +//: helper for tests + +:(code) +void run(string form) { + vector tmp = add_recipes(form); + transform_all(); + run(tmp.front()); +} + +:(code) +vector read_memory(reagent x) { +//? cout << "read_memory: " << x.to_string() << '\n'; //? 1 + vector result; + if (isa_literal(x)) { + result.push_back(x.value); + return result; + } + int base = x.value; + size_t size = size_of(x); + for (size_t offset = 0; offset < size; ++offset) { + int val = Memory[base+offset]; + trace("mem") << "location " << base+offset << " is " << val; + result.push_back(val); + } + return result; +} + +void write_memory(reagent x, vector data) { + if (is_dummy(x)) return; + int base = x.value; + if (size_of(x) != data.size()) + raise << "size mismatch in storing to " << x.to_string() << '\n'; + for (size_t offset = 0; offset < data.size(); ++offset) { + trace("mem") << "storing " << data[offset] << " in location " << base+offset; + Memory[base+offset] = data[offset]; + } +} + +:(code) +size_t size_of(const reagent& r) { + return size_of(r.types); +} +size_t size_of(const vector& types) { + // End size_of(types) Cases + return 1; +} + +bool is_dummy(const reagent& x) { + return x.name == "_"; +} + +bool isa_literal(const reagent& r) { + return r.types.size() == 1 && r.types[0] == 0; +} + +:(scenario run_label) +recipe main [ + +foo + 1:integer <- copy 23:literal + 2:integer <- copy 1:integer +] ++run: instruction main/1 ++run: instruction main/2 +-run: instruction main/0 + +:(scenario run_dummy) +recipe main [ + _ <- copy 0:literal +] ++run: instruction main/0 -- cgit 1.4.1-2-gfad0 a id='n66' href='#n66'>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