From a50a3bceb3c7f8825cc4d6b12599918e465388ff Mon Sep 17 00:00:00 2001 From: VaclavT Date: Wed, 14 Apr 2021 07:55:55 +0200 Subject: [PATCH] set! added --- ml.cpp | 28 ++++++++++++++++++++++++++++ ml.h | 4 ++++ 2 files changed, 32 insertions(+) diff --git a/ml.cpp b/ml.cpp index 3c2294d..c183af1 100644 --- a/ml.cpp +++ b/ml.cpp @@ -652,6 +652,22 @@ void MlEnvironment::set(const std::string &name, MlValue value) { } +void MlEnvironment::setX(const std::string &name, MlValue value) { + MlEnvironment* e = this; + do { + std::map::const_iterator itr = e->defs.find(name); + if (itr != e->defs.end()) { + e->set(name, value); + return; + } + e = e->parent_scope; + } while (e != nullptr); + + // not found so define + this->set(name, value); +} + + MlValue MlValue::apply(std::vector args, MlEnvironment &env) { MlEnvironment e; std::vector params; @@ -936,6 +952,16 @@ namespace builtin { return f; } + // Sets (if exists) or define a variable with a value (SPECIAL FORM) + MlValue setx(std::vector args, MlEnvironment &env) { + if (args.size() != 2) + throw MlError(MlValue("set!", define), env, args.size() > 2 ? TOO_MANY_ARGS : TOO_FEW_ARGS); + + MlValue result = args[1].eval(env); + env.setX(args[0].display(), result); + return result; + } + // Loop over a list of expressions with a condition (SPECIAL FORM) MlValue while_loop(std::vector args, MlEnvironment &env) { MlValue acc; @@ -1796,6 +1822,7 @@ MlValue MlEnvironment::get(const std::string &name) const { if (name == "benchmark") return MlValue("benchmark", builtin::benchmark); if (name == "and") return MlValue("and", builtin::do_and); if (name == "or") return MlValue("or", builtin::do_or); + if (name == "set!") return MlValue("set!", builtin::setx); // Comparison operations if (name == "=") return MlValue("=", builtin::eq); @@ -1976,3 +2003,4 @@ int main(int argc, char *argv[]) { return 1; } + diff --git a/ml.h b/ml.h index f5e5cd0..45faf33 100644 --- a/ml.h +++ b/ml.h @@ -42,6 +42,10 @@ public: // Set the value associated with this name in this scope void set(const std::string &name, MlValue value); + // Set the value associated with this name in this scope and parent scopes + // and if not exists sets in this scope + void setX(const std::string &name, MlValue value); + // Get vector of executables in this scope std::vector get_lambdas_list() const;