Skip to content
This repository has been archived by the owner on Jan 8, 2025. It is now read-only.

Commit

Permalink
4266 - space for alloc-id in heap allocations
Browse files Browse the repository at this point in the history
This has taken me almost 6 weeks :(
  • Loading branch information
akkartik committed Jun 24, 2018
1 parent ad66ee6 commit ad42d19
Show file tree
Hide file tree
Showing 36 changed files with 926 additions and 648 deletions.
39 changes: 38 additions & 1 deletion 020run.cc
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,10 @@ void run_current_routine() {
// Primitive Recipe Implementations
case COPY: {
copy(ingredients.begin(), ingredients.end(), inserter(products, products.begin()));
for (int i = 0; i < SIZE(current_instruction().products); ++i) {
if (is_mu_scalar(current_instruction().products.at(i)) && is_mu_address(current_instruction().ingredients.at(i)))
products.at(i).erase(products.at(i).begin()); // ignore alloc id
}
break;
}
// End Primitive Recipe Implementations
Expand Down Expand Up @@ -125,6 +129,33 @@ bool should_copy_ingredients() {
return true;
}

bool is_mu_scalar(reagent/*copy*/ r) {
return is_mu_scalar(r.type);
}
bool is_mu_scalar(const type_tree* type) {
if (!type) return false;
if (is_mu_address(type)) return false;
if (!type->atom) return false;
if (is_literal(type))
return type->name != "literal-string";
return size_of(type) == 1;
}

bool is_mu_address(reagent/*copy*/ r) {
// End Preprocess is_mu_address(reagent r)
return is_mu_address(r.type);
}
bool is_mu_address(const type_tree* type) {
if (!type) return false;
if (is_literal(type)) return false;
if (type->atom) return false;
if (!type->left->atom) {
raise << "invalid type " << to_string(type) << '\n' << end();
return false;
}
return type->left->value == Address_type_ordinal;
}

//: Some helpers.
//: Important that they return references into the current routine.

Expand Down Expand Up @@ -299,6 +330,7 @@ bool ends_with(const string& s, const string& pat) {
vector<double> read_memory(reagent/*copy*/ x) {
// Begin Preprocess read_memory(x)
vector<double> result;
if (x.name == "null") result.push_back(/*alloc id*/0);
if (is_literal(x)) {
result.push_back(x.value);
return result;
Expand Down Expand Up @@ -358,7 +390,7 @@ int size_of(const type_tree* type) {
raise << "invalid type " << to_string(type) << '\n' << end();
return 0;
}
if (type->left->value == Address_type_ordinal) return 1;
if (type->left->value == Address_type_ordinal) return 2; // address and alloc id
// End size_of(type) Non-atom Special-cases
}
// End size_of(type) Special-cases
Expand Down Expand Up @@ -421,6 +453,11 @@ def main [
]
+run: _ <- copy {0: "literal"}

:(scenario run_null)
def main [
1:&:num <- copy null
]

:(scenario write_to_0_disallowed)
% Hide_errors = true;
def main [
Expand Down
50 changes: 17 additions & 33 deletions 021check_instruction.cc
Original file line number Diff line number Diff line change
Expand Up @@ -88,30 +88,36 @@ def main [
:(code)
// types_match with some leniency
bool types_coercible(const reagent& to, const reagent& from) {
if (types_match(to, from)) return true;
bool types_coercible(reagent/*copy*/ to, reagent/*copy*/ from) {
// Begin types_coercible(reagent to, reagent from)
if (types_match_sub(to, from)) return true;
if (is_real_mu_number(from) && is_mu_character(to)) return true;
// End types_coercible Special-cases
return false;
}
bool types_match(const reagent& to, const reagent& from) {
bool types_match_sub(const reagent& to, const reagent& from) {
// to sidestep type-checking, use /unsafe in the source.
// this will be highlighted in red inside vim. just for setting up some tests.
if (is_unsafe(from)) return true;
if (is_literal(from)) {
if (is_mu_array(to)) return false;
// End Matching Types For Literal(to)
if (!to.type) return false;
// allow writing null to any address
if (is_mu_address(to)) return from.name == "null";
return size_of(to) == 1; // literals are always scalars
}
return types_strictly_match(to, from);
return types_strictly_match_sub(to, from);
}
// variant for others to call
bool types_match(reagent/*copy*/ to, reagent/*copy*/ from) {
// Begin types_match(reagent to, reagent from)
return types_match_sub(to, from);
}
//: copy arguments for later layers
bool types_strictly_match(reagent/*copy*/ to, reagent/*copy*/ from) {
// End Preprocess types_strictly_match(reagent to, reagent from)
bool types_strictly_match_sub(const reagent& to, const reagent& from) {
if (to.type == NULL) return false; // error
if (is_literal(from) && to.type->value == Number_type_ordinal) return true;
// to sidestep type-checking, use /unsafe in the source.
Expand All @@ -122,6 +128,11 @@ bool types_strictly_match(reagent/*copy*/ to, reagent/*copy*/ from) {
if (!to.type) return !from.type;
return types_strictly_match(to.type, from.type);
}
// variant for others to call
bool types_strictly_match(reagent/*copy*/ to, reagent/*copy*/ from) {
// Begin types_strictly_match(reagent to, reagent from)
return types_strictly_match_sub(to, from);
}
bool types_strictly_match(const type_tree* to, const type_tree* from) {
if (from == to) return true;
Expand Down Expand Up @@ -185,21 +196,6 @@ bool is_mu_array(const type_tree* type) {
return type->left->value == Array_type_ordinal;
}
bool is_mu_address(reagent/*copy*/ r) {
// End Preprocess is_mu_address(reagent r)
return is_mu_address(r.type);
}
bool is_mu_address(const type_tree* type) {
if (!type) return false;
if (is_literal(type)) return false;
if (type->atom) return false;
if (!type->left->atom) {
raise << "invalid type " << to_string(type) << '\n' << end();
return false;
}
return type->left->value == Address_type_ordinal;
}
bool is_mu_boolean(reagent/*copy*/ r) {
// End Preprocess is_mu_boolean(reagent r)
if (!r.type) return false;
Expand Down Expand Up @@ -234,15 +230,3 @@ bool is_mu_character(const type_tree* type) {
if (is_literal(type)) return false;
return type->value == Character_type_ordinal;
}
bool is_mu_scalar(reagent/*copy*/ r) {
return is_mu_scalar(r.type);
}
bool is_mu_scalar(const type_tree* type) {
if (!type) return false;
if (is_mu_address(type)) return true;
if (!type->atom) return false;
if (is_literal(type))
return type->name != "literal-string";
return size_of(type) == 1;
}
5 changes: 0 additions & 5 deletions 022arithmetic.cc
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,6 @@ case SUBTRACT: {
break;
}
for (int i = 0; i < SIZE(inst.ingredients); ++i) {
if (is_raw(inst.ingredients.at(i))) continue; // permit address offset computations in tests
if (!is_mu_number(inst.ingredients.at(i))) {
raise << maybe(get(Recipe, r).name) << "'subtract' requires number ingredients, but got '" << inst.ingredients.at(i).original_string << "'\n" << end();
goto finish_checking_instruction;
Expand All @@ -104,10 +103,6 @@ case SUBTRACT: {
products.at(0).push_back(result);
break;
}
:(code)
bool is_raw(const reagent& r) {
return has_property(r, "raw");
}

:(scenario subtract_literal)
def main [
Expand Down
16 changes: 11 additions & 5 deletions 023boolean.cc
Original file line number Diff line number Diff line change
Expand Up @@ -26,11 +26,17 @@ case AND: {
case AND: {
bool result = true;
for (int i = 0; i < SIZE(ingredients); ++i)
result = result && ingredients.at(i).at(0);
result = result && scalar_ingredient(ingredients, i);
products.resize(1);
products.at(0).push_back(result);
break;
}
:(code)
double scalar_ingredient(const vector<vector<double> >& ingredients, int i) {
if (is_mu_address(current_instruction().ingredients.at(i)))
return ingredients.at(i).at(/*skip alloc id*/1);
return ingredients.at(i).at(0);
}

:(scenario and)
def main [
Expand Down Expand Up @@ -84,7 +90,7 @@ case OR: {
case OR: {
bool result = false;
for (int i = 0; i < SIZE(ingredients); ++i)
result = result || ingredients.at(i).at(0);
result = result || scalar_ingredient(ingredients, i);
products.resize(1);
products.at(0).push_back(result);
break;
Expand Down Expand Up @@ -127,8 +133,8 @@ case NOT: {
break;
}
for (int i = 0; i < SIZE(inst.ingredients); ++i) {
if (!is_mu_scalar(inst.ingredients.at(i))) {
raise << maybe(get(Recipe, r).name) << "'not' requires boolean ingredients, but got '" << inst.ingredients.at(i).original_string << "'\n" << end();
if (!is_mu_scalar(inst.ingredients.at(i)) && !is_mu_address(inst.ingredients.at(i))) {
raise << maybe(get(Recipe, r).name) << "'not' requires ingredients that can be interpreted as boolean, but got '" << inst.ingredients.at(i).original_string << "'\n" << end();
goto finish_checking_instruction;
}
}
Expand All @@ -145,7 +151,7 @@ case NOT: {
case NOT: {
products.resize(SIZE(ingredients));
for (int i = 0; i < SIZE(ingredients); ++i) {
products.at(i).push_back(!ingredients.at(i).at(0));
products.at(i).push_back(!scalar_ingredient(ingredients, i));
}
break;
}
Expand Down
21 changes: 16 additions & 5 deletions 024jump.cc
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ case JUMP_IF: {
raise << maybe(get(Recipe, r).name) << "'" << to_original_string(inst) << "' should get exactly two ingredients\n" << end();
break;
}
if (!is_mu_scalar(inst.ingredients.at(0))) {
if (!is_mu_address(inst.ingredients.at(0)) && !is_mu_scalar(inst.ingredients.at(0))) {
raise << maybe(get(Recipe, r).name) << "'" << to_original_string(inst) << "' requires a boolean for its first ingredient, but '" << inst.ingredients.at(0).name << "' has type '" << names_to_string_without_quotes(inst.ingredients.at(0).type) << "'\n" << end();
break;
}
Expand All @@ -90,7 +90,7 @@ case JUMP_IF: {
:(before "End Primitive Recipe Implementations")
case JUMP_IF: {
assert(current_instruction().ingredients.at(1).initialized);
if (!ingredients.at(0).at(0)) {
if (!scalar_ingredient(ingredients, 0)) {
trace(9998, "run") << "jump-if fell through" << end();
break;
}
Expand All @@ -109,7 +109,7 @@ def main [
]
+run: jump-if {999: "literal"}, {1: "offset"}
+run: jumping to instruction 2
-run: {1: "number"} <- copy {1: "literal"}
-run: {123: "number"} <- copy {1: "literal"}
-mem: storing 1 in location 123

:(scenario jump_if_fallthrough)
Expand All @@ -122,6 +122,17 @@ def main [
+run: {123: "number"} <- copy {1: "literal"}
+mem: storing 1 in location 123

:(scenario jump_if_on_address)
def main [
10:num/alloc-id, 11:num <- copy 0, 999
jump-if 10:&:number, 1:offset
123:num <- copy 1
]
+run: jump-if {10: ("address" "number")}, {1: "offset"}
+run: jumping to instruction 3
-run: {123: "number"} <- copy {1: "literal"}
-mem: storing 1 in location 123

:(before "End Primitive Recipe Declarations")
JUMP_UNLESS,
:(before "End Primitive Recipe Numbers")
Expand All @@ -132,7 +143,7 @@ case JUMP_UNLESS: {
raise << maybe(get(Recipe, r).name) << "'" << to_original_string(inst) << "' should get exactly two ingredients\n" << end();
break;
}
if (!is_mu_scalar(inst.ingredients.at(0))) {
if (!is_mu_address(inst.ingredients.at(0)) && !is_mu_scalar(inst.ingredients.at(0))) {
raise << maybe(get(Recipe, r).name) << "'" << to_original_string(inst) << "' requires a boolean for its first ingredient, but '" << inst.ingredients.at(0).name << "' has type '" << names_to_string_without_quotes(inst.ingredients.at(0).type) << "'\n" << end();
break;
}
Expand All @@ -150,7 +161,7 @@ case JUMP_UNLESS: {
:(before "End Primitive Recipe Implementations")
case JUMP_UNLESS: {
assert(current_instruction().ingredients.at(1).initialized);
if (ingredients.at(0).at(0)) {
if (scalar_ingredient(ingredients, 0)) {
trace(9998, "run") << "jump-unless fell through" << end();
break;
}
Expand Down
8 changes: 8 additions & 0 deletions 025compare.cc
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,10 @@ case EQUAL: {
vector<double>& exemplar = ingredients.at(0);
bool result = true;
for (int i = /*skip exemplar*/1; i < SIZE(ingredients); ++i) {
if (SIZE(ingredients.at(i)) != SIZE(exemplar)) {
result = false;
break;
}
if (!equal(ingredients.at(i).begin(), ingredients.at(i).end(), exemplar.begin())) {
result = false;
break;
Expand Down Expand Up @@ -103,6 +107,10 @@ case NOT_EQUAL: {
case NOT_EQUAL: {
vector<double>& exemplar = ingredients.at(0);
products.resize(1);
if (SIZE(ingredients.at(1)) != SIZE(exemplar)) {
products.at(0).push_back(true);
break;
}
bool equal_ingredients = equal(ingredients.at(1).begin(), ingredients.at(1).end(), exemplar.begin());
products.at(0).push_back(!equal_ingredients);
break;
Expand Down
2 changes: 2 additions & 0 deletions 027call_ingredient.cc
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,8 @@ case REWIND_INGREDIENTS: {
break;
}

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

:(scenario ingredient)
def main [
f 1, 2
Expand Down
Loading

0 comments on commit ad42d19

Please sign in to comment.