From 13ba3defe91b4de6ab3da7e937ee448c49909725 Mon Sep 17 00:00:00 2001 From: "Kartik K. Agaram" Date: Sat, 18 Jul 2015 13:48:49 -0700 Subject: 1814 - save code in editor Very rudimentary ability to read/write from file+version control. No control over name. Recipes now saved. But what to do about sandboxes? --- 010vm.cc | 4 ++-- 020run.cc | 2 +- 082persist.cc | 50 ++++++++++++++++++++++++++++++++++++++++++++++++++ 999spaces.cc | 6 ++++-- edit.mu | 14 +++++--------- 5 files changed, 62 insertions(+), 14 deletions(-) create mode 100644 082persist.cc diff --git a/010vm.cc b/010vm.cc index f1fb2f17..9e348492 100644 --- a/010vm.cc +++ b/010vm.cc @@ -158,8 +158,8 @@ void setup_recipes() { //: itself. :(before "End One-time Setup") setup_recipes(); -assert(MAX_PRIMITIVE_RECIPES < 100); // level 0 is primitives; until 99 -Next_recipe_ordinal = 100; +assert(MAX_PRIMITIVE_RECIPES < 200); // level 0 is primitives; until 199 +Next_recipe_ordinal = 200; // End Load Recipes :(before "End Test Run Initialization") assert(Next_recipe_ordinal < 1000); // recipes being tested didn't overflow into test space diff --git a/020run.cc b/020run.cc index 5969a27d..8cc76614 100644 --- a/020run.cc +++ b/020run.cc @@ -86,7 +86,7 @@ void run_current_routine() } } if (SIZE(products) < SIZE(current_instruction().products)) - raise << "failed to write to all products! " << current_instruction().to_string(); + raise << SIZE(products) << " vs " << SIZE(current_instruction().products) << ": failed to write to all products! " << current_instruction().to_string(); for (long long int i = 0; i < SIZE(current_instruction().products); ++i) { write_memory(current_instruction().products.at(i), products.at(i)); } diff --git a/082persist.cc b/082persist.cc new file mode 100644 index 00000000..3f9850fe --- /dev/null +++ b/082persist.cc @@ -0,0 +1,50 @@ +//: Dead simple persistence. +//: 'read' - reads string from a hardcoded file +//: 'save' - writes string to a hardcoded file + +:(before "End Primitive Recipe Declarations") +READ, +:(before "End Primitive Recipe Numbers") +Recipe_ordinal["read"] = READ; +:(before "End Primitive Recipe Implementations") +case READ: { + products.resize(1); + products.at(0).push_back(new_string(slurp("lesson/recipe.mu"))); + break; +} + +:(code) +string slurp(const string& filename) { + ostringstream result; + ifstream fin(filename.c_str()); + fin.peek(); + if (!fin) return result.str(); // don't bother checking errno + const int N = 1024; + char buf[N]; + while (!fin.eof()) { + bzero(buf, N); + fin.read(buf, N-1); // leave at least one null + result << buf; + } + fin.close(); + return result.str(); +} + +:(before "End Primitive Recipe Declarations") +SAVE, +:(before "End Primitive Recipe Numbers") +Recipe_ordinal["save"] = SAVE; +:(before "End Primitive Recipe Implementations") +case SAVE: { + if (!scalar(ingredients.at(0))) + raise << "save: illegal operand " << current_instruction().ingredients.at(0).to_string() << '\n'; + string contents = to_string(ingredients.at(0).at(0)); + ofstream fout("lesson/recipe.mu"); + fout << contents; + fout.close(); + // bug in git: git diff -q messes up --exit-code + int status = system("cd lesson; git diff --exit-code >/dev/null || git commit -a -m . >/dev/null"); + if (status != 0) + raise << "error in commit: contents " << contents << '\n'; + break; +} diff --git a/999spaces.cc b/999spaces.cc index 4c09712d..f3e3771e 100644 --- a/999spaces.cc +++ b/999spaces.cc @@ -17,8 +17,10 @@ assert(Reserved_for_tests == 1000); //:: Recipes //: //: 0 - unused (IDLE; do nothing) -//: 1-99 - primitives -//: 100-999 - defined in .mu files as sequences of primitives +//: 1-199 - primitives +assert(MAX_PRIMITIVE_RECIPES < 200); +//: 200-999 - defined in .mu files as sequences of primitives +assert(Next_recipe_ordinal < 1000); //: 1000 onwards - reserved for tests, cleared between tests //:: Depths for tracing diff --git a/edit.mu b/edit.mu index ae6dcc47..b66011a1 100644 --- a/edit.mu +++ b/edit.mu @@ -3,13 +3,7 @@ recipe main [ local-scope open-console - initial-recipe:address:array:character <- new [# example: add two numbers -recipe test [ - x:number <- next-ingredient - y:number <- next-ingredient - z:number <- add x:number, y:number - reply z:number -]] + initial-recipe:address:array:character <- read initial-sandbox:address:array:character <- new [test 2, 2] env:address:programming-environment-data <- new-programming-environment 0:literal/screen, initial-recipe:address:array:character, initial-sandbox:address:array:character event-loop 0:literal/screen, 0:literal/console, env:address:programming-environment-data @@ -2774,15 +2768,17 @@ recipe run-sandboxes [ env:address:programming-environment-data <- next-ingredient recipes:address:editor-data <- get env:address:programming-environment-data/deref, recipes:offset current-sandbox:address:editor-data <- get env:address:programming-environment-data/deref, current-sandbox:offset - # load code from recipe editor, save any warnings + # copy code from recipe editor, persist, load into mu, save any warnings in:address:array:character <- editor-contents recipes:address:editor-data + save in:address:array:character recipe-warnings:address:address:array:character <- get-address env:address:programming-environment-data/deref, recipe-warnings:offset recipe-warnings:address:address:array:character/deref <- reload in:address:array:character # check contents of right editor (sandbox) { sandbox-contents:address:array:character <- editor-contents current-sandbox:address:editor-data break-unless sandbox-contents:address:array:character - # if contents exist, run them and turn them into a new sandbox-data + # if contents exist, first save them + # run them and turn them into a new sandbox-data new-sandbox:address:sandbox-data <- new sandbox-data:type data:address:address:array:character <- get-address new-sandbox:address:sandbox-data/deref, data:offset data:address:address:array:character/deref <- copy sandbox-contents:address:array:character -- cgit 1.4.1-2-gfad0