about summary refs log tree commit diff stats
path: root/045closure_name.cc
diff options
context:
space:
mode:
authorKartik Agaram <vc@akkartik.com>2019-03-12 18:56:55 -0700
committerKartik Agaram <vc@akkartik.com>2019-03-12 19:14:12 -0700
commit4a943d4ed313eff001504c2b5c472266e86a38af (patch)
treea5757233a8c81b303a808f251180c7344071ed51 /045closure_name.cc
parent43711b0e9f18e0225ce14687fb6ea0902aa6fc61 (diff)
downloadmu-4a943d4ed313eff001504c2b5c472266e86a38af.tar.gz
5001 - drop the :(scenario) DSL
I've been saying for a while[1][2][3] that adding extra abstractions makes
things harder for newcomers, and adding new notations doubly so. And then
I notice this DSL in my own backyard. Makes me feel like a hypocrite.

[1] https://news.ycombinator.com/item?id=13565743#13570092
[2] https://lobste.rs/s/to8wpr/configuration_files_are_canary_warning
[3] https://lobste.rs/s/mdmcdi/little_languages_by_jon_bentley_1986#c_3miuf2

The implementation of the DSL was also highly hacky:

a) It was happening in the tangle/ tool, but was utterly unrelated to tangling
layers.

b) There were several persnickety constraints on the different kinds of
lines and the specific order they were expected in. I kept finding bugs
where the translator would silently do the wrong thing. Or the error messages
sucked, and readers may be stuck looking at the generated code to figure
out what happened. Fixing error messages would require a lot more code,
which is one of my arguments against DSLs in the first place: they may
be easy to implement, but they're hard to design to go with the grain of
the underlying platform. They require lots of iteration. Is that effort
worth prioritizing in this project?

On the other hand, the DSL did make at least some readers' life easier,
the ones who weren't immediately put off by having to learn a strange syntax.
There were fewer quotes to parse, fewer backslash escapes.

Anyway, since there are also people who dislike having to put up with strange
syntaxes, we'll call that consideration a wash and tear this DSL out.

---

This commit was sheer drudgery. Hopefully it won't need to be redone with
a new DSL because I grow sick of backslashes.
Diffstat (limited to '045closure_name.cc')
-rw-r--r--045closure_name.cc139
1 files changed, 79 insertions, 60 deletions
diff --git a/045closure_name.cc b/045closure_name.cc
index b4a8ea24..d5f26f81 100644
--- a/045closure_name.cc
+++ b/045closure_name.cc
@@ -6,28 +6,33 @@
 //: todo: warn on default-space abuse. default-space for one recipe should
 //: never come from another, otherwise memory will be corrupted.
 
-:(scenario closure)
-def main [
-  default-space:space <- new location:type, 30
-  2:space/names:new-counter <- new-counter
-  10:num/raw <- increment-counter 2:space/names:new-counter
-  11:num/raw <- increment-counter 2:space/names:new-counter
-]
-def new-counter [
-  default-space:space <- new location:type, 30
-  x:num <- copy 23
-  y:num <- copy 13  # variable that will be incremented
-  return default-space:space
-]
-def increment-counter [
-  default-space:space <- new location:type, 30
-  0:space/names:new-counter <- next-ingredient  # outer space must be created by 'new-counter' above
-  y:num/space:1 <- add y:num/space:1, 1  # increment
-  y:num <- copy 234  # dummy
-  return y:num/space:1
-]
-+name: lexically surrounding space for recipe increment-counter comes from new-counter
-+mem: storing 15 in location 11
+void test_closure() {
+  run(
+      "def main [\n"
+      "  default-space:space <- new location:type, 30\n"
+      "  2:space/names:new-counter <- new-counter\n"
+      "  10:num/raw <- increment-counter 2:space/names:new-counter\n"
+      "  11:num/raw <- increment-counter 2:space/names:new-counter\n"
+      "]\n"
+      "def new-counter [\n"
+      "  default-space:space <- new location:type, 30\n"
+      "  x:num <- copy 23\n"
+      "  y:num <- copy 13\n"  // variable that will be incremented
+      "  return default-space:space\n"
+      "]\n"
+      "def increment-counter [\n"
+      "  default-space:space <- new location:type, 30\n"
+      "  0:space/names:new-counter <- next-ingredient\n"  // outer space must be created by 'new-counter' above
+      "  y:num/space:1 <- add y:num/space:1, 1\n"  // increment
+      "  y:num <- copy 234\n"  // dummy
+      "  return y:num/space:1\n"
+      "]\n"
+  );
+  CHECK_TRACE_CONTENTS(
+      "name: lexically surrounding space for recipe increment-counter comes from new-counter\n"
+      "mem: storing 15 in location 11\n"
+  );
+}
 
 //: To make this work, compute the recipe that provides names for the
 //: surrounding space of each recipe.
@@ -142,44 +147,58 @@ bool already_transformed(const reagent& r, const map<string, int>& names) {
   return contains_key(names, r.name);
 }
 
-:(scenario missing_surrounding_space)
-% Hide_errors = true;
-def f [
-  local-scope
-  x:num/space:1 <- copy 34
-]
-+error: don't know surrounding recipe of 'f'
-+error: f: can't find a place to store 'x'
+:(code)
+void test_missing_surrounding_space() {
+  Hide_errors = true;
+  run(
+      "def f [\n"
+      "  local-scope\n"
+      "  x:num/space:1 <- copy 34\n"
+      "]\n"
+  );
+  CHECK_TRACE_CONTENTS(
+      "error: don't know surrounding recipe of 'f'\n"
+      "error: f: can't find a place to store 'x'\n"
+  );
+}
 
 //: extra test for try_reclaim_locals() from previous layers
-:(scenario local_scope_ignores_nonlocal_spaces)
-def new-scope [
-  local-scope
-  x:&:num <- new number:type
-  *x:&:num <- copy 34
-  return default-space:space
-]
-def use-scope [
-  local-scope
-  outer:space/names:new-scope <- next-ingredient
-  0:space/names:new-scope <- copy outer:space
-  return *x:&:num/space:1
-]
-def main [
-  1:space/raw <- new-scope
-  3:num/raw <- use-scope 1:space/raw
-]
-+mem: storing 34 in location 3
+void test_local_scope_ignores_nonlocal_spaces() {
+  run(
+      "def new-scope [\n"
+      "  local-scope\n"
+      "  x:&:num <- new number:type\n"
+      "  *x:&:num <- copy 34\n"
+      "  return default-space:space\n"
+      "]\n"
+      "def use-scope [\n"
+      "  local-scope\n"
+      "  outer:space/names:new-scope <- next-ingredient\n"
+      "  0:space/names:new-scope <- copy outer:space\n"
+      "  return *x:&:num/space:1\n"
+      "]\n"
+      "def main [\n"
+      "  1:space/raw <- new-scope\n"
+      "  3:num/raw <- use-scope 1:space/raw\n"
+      "]\n"
+  );
+  CHECK_TRACE_CONTENTS(
+      "mem: storing 34 in location 3\n"
+  );
+}
 
-:(scenario recursive_transform_names)
-def foo [
-  local-scope
-  x:num <- copy 0
-  return default-space:space/names:foo
-]
-def main [
-  local-scope
-  0:space/names:foo <- foo
-  x:num/space:1 <- copy 34
-]
-$error: 0
+void test_recursive_transform_names() {
+  run(
+      "def foo [\n"
+      "  local-scope\n"
+      "  x:num <- copy 0\n"
+      "  return default-space:space/names:foo\n"
+      "]\n"
+      "def main [\n"
+      "  local-scope\n"
+      "  0:space/names:foo <- foo\n"
+      "  x:num/space:1 <- copy 34\n"
+      "]\n"
+  );
+  CHECK_TRACE_COUNT("error", 0);
+}