diff options
author | Kartik K. Agaram <vc@akkartik.com> | 2015-07-13 17:20:56 -0700 |
---|---|---|
committer | Kartik K. Agaram <vc@akkartik.com> | 2015-07-13 17:20:56 -0700 |
commit | 385d3080066bc22d264b1ae30ee2505cab6cc202 (patch) | |
tree | 7bcba1addf558d70cc4b4605a253d7b12abd31fb | |
parent | f59ccc4652bfdb7faf7d77a1685e795342e28fa2 (diff) | |
download | mu-385d3080066bc22d264b1ae30ee2505cab6cc202.tar.gz |
1769 - routines can now have global variables
-rw-r--r-- | 044space.cc | 6 | ||||
-rw-r--r-- | 045space_surround.cc | 6 | ||||
-rw-r--r-- | 047global.cc | 54 |
3 files changed, 54 insertions, 12 deletions
diff --git a/044space.cc b/044space.cc index e32fbceb..9a975147 100644 --- a/044space.cc +++ b/044space.cc @@ -49,17 +49,12 @@ default_space = 0; reagent r = absolutize(x); :(code) reagent absolutize(reagent x) { -//? if (Recipe_ordinal.find("increment-counter") != Recipe_ordinal.end()) //? 1 -//? cout << "AAA " << "increment-counter/2: " << Recipe[Recipe_ordinal["increment-counter"]].steps.at(2).products.at(0).to_string() << '\n'; //? 1 //? cout << "absolutize " << x.to_string() << '\n'; //? 4 -//? cout << is_raw(x) << '\n'; //? 1 if (is_raw(x) || is_dummy(x)) return x; -//? cout << "not raw: " << x.to_string() << '\n'; //? 1 if (!x.initialized) raise << current_instruction().to_string() << ": reagent not initialized: " << x.to_string() << die(); reagent r = x; r.set_value(address(r.value, space_base(r))); -//? cout << "after absolutize: " << r.value << '\n'; //? 1 r.properties.push_back(pair<string, vector<string> >("raw", vector<string>())); assert(is_raw(r)); return r; @@ -127,7 +122,6 @@ long long int address(long long int offset, long long int base) { if (x.name == "default-space") { assert(scalar(data)); Current_routine->calls.front().default_space = data.at(0); -//? cout << "AAA " << Current_routine->calls.front().default_space << '\n'; //? 1 return; } diff --git a/045space_surround.cc b/045space_surround.cc index 61521013..b90d464f 100644 --- a/045space_surround.cc +++ b/045space_surround.cc @@ -27,24 +27,18 @@ recipe main [ :(replace{} "long long int space_base(const reagent& x)") long long int space_base(const reagent& x) { -//? cerr << "space_base: " << x.to_string() << '\n'; //? 1 return space_base(x, space_index(x), Current_routine->calls.front().default_space); } long long int space_base(const reagent& x, long long int space_index, long long int base) { -//? trace("foo") << "base of space " << space_index << '\n'; //? 1 -//? cerr << "space_base sub: " << x.to_string() << '\n'; //? 1 if (space_index == 0) { -//? trace("foo") << "base of space " << space_index << " is " << base << '\n'; //? 1 return base; } -//? trace("foo") << "base of space " << space_index << " is " << Memory[base+1] << '\n'; //? 1 long long int result = space_base(x, space_index-1, Memory[base+1]); return result; } long long int space_index(const reagent& x) { -//? cerr << "space_index: " << x.to_string() << '\n'; //? 1 for (long long int i = /*skip name:type*/1; i < SIZE(x.properties); ++i) { if (x.properties.at(i).first == "space") { assert(SIZE(x.properties.at(i).second) == 1); diff --git a/047global.cc b/047global.cc new file mode 100644 index 00000000..1ab77eec --- /dev/null +++ b/047global.cc @@ -0,0 +1,54 @@ +// So far we have local variables, and we can nest local variables of short +// lifetimes inside longer ones. Now let's support 'global' variables that +// last for the life of a routine. If we create multiple routines they won't +// have access to each other's globals. + +:(scenario global_space) +recipe main [ + # pretend arrays; in practice we'll use new + 10:number <- copy 5:literal + 20:number <- copy 5:literal + # actual start of this recipe + default-space:address:array:location <- copy 10:literal + 1:number <- copy 23:literal + global-space:address:array:location <- copy 20:literal + 1:number/space:global <- copy 24:literal +] ++mem: storing 23 in location 12 ++mem: storing 24 in location 22 + +//: to support it, create another special variable called global space +:(before "End Disqualified Reagents") +if (x.name == "global-space") + x.initialized = true; +:(before "End is_special_name Cases") +if (s == "global-space") return true; + +//: writes to this variable go to a field in the current routine +:(before "End routine Fields") +long long int global_space; +:(before "End routine Constructor") +global_space = 0; +:(after "void write_memory(reagent x, vector<double> data)") + if (x.name == "global-space") { + assert(scalar(data)); + Current_routine->global_space = data.at(0); + return; + } + +//: now marking variables as /space:global looks them up inside this field +:(after "long long int space_base(const reagent& x)") + if (is_global(x)) { + if (!Current_routine->global_space) + raise << "routine has no global space\n" << die(); + return Current_routine->global_space; + } + +:(code) +bool is_global(const reagent& x) { + for (long long int i = /*skip name:type*/1; i < SIZE(x.properties); ++i) { + if (x.properties.at(i).first == "space") + return x.properties.at(i).second.at(0) == "global"; + } + return false; +} |