From 8f744397988a981768ed8194265d441ca7ae5ef0 Mon Sep 17 00:00:00 2001 From: yhirose Date: Thu, 23 Jul 2015 22:06:01 -0400 Subject: [PATCH] Refactoring. --- language/interpreter.cc | 58 +++---------- language/interpreter.hpp | 171 ++++++++++++++++++++++++--------------- 2 files changed, 114 insertions(+), 115 deletions(-) diff --git a/language/interpreter.cc b/language/interpreter.cc index a7255f0..a13a196 100644 --- a/language/interpreter.cc +++ b/language/interpreter.cc @@ -82,7 +82,7 @@ private: } static Value eval_function(const Ast& ast, shared_ptr env) { - std::vector params; + std::vector params; for (auto node: ast.nodes[0]->nodes) { auto mut = node->nodes[0]->token == "mut"; const auto& name = node->nodes[1]->token; @@ -91,7 +91,7 @@ private: auto body = ast.nodes[1]; - auto f = Value::FunctionValue( + auto f = FunctionValue( params, [=](shared_ptr callEnv) { callEnv->append_outer(env); @@ -136,8 +136,8 @@ private: // Array reference const auto& arr = val.to_array(); auto idx = eval(n, env).to_long(); - if (0 <= idx && idx < static_cast(arr.data->values.size())) { - val = arr.data->values.at(idx); + if (0 <= idx && idx < static_cast(arr.values->size())) { + val = arr.values->at(idx); } } else if (n.original_tag == AstTag::Dot) { // Property @@ -147,7 +147,7 @@ private: if (prop.get_type() == Value::Function) { const auto& pf = prop.to_function(); - auto f = Value::FunctionValue( + auto f = FunctionValue( pf.data->params, [=](shared_ptr callEnv) { callEnv->initialize("this", val, false); @@ -280,25 +280,25 @@ private: }; static Value eval_object(const Ast& ast, shared_ptr env) { - Value::ObjectValue obj; + ObjectValue obj; for (auto i = 0u; i < ast.nodes.size(); i++) { const auto& prop = *ast.nodes[i]; const auto& name = prop.nodes[0]->token; auto val = eval(*prop.nodes[1], env); - obj.data->props.emplace(name, val); + obj.properties->emplace(name, val); } return Value(std::move(obj)); } static Value eval_array(const Ast& ast, shared_ptr env) { - Value::ArrayValue arr; + ArrayValue arr; for (auto i = 0u; i < ast.nodes.size(); i++) { auto expr = ast.nodes[i]; auto val = eval(*expr, env); - arr.data->values.push_back(val); + arr.values->push_back(val); } return Value(std::move(arr)); @@ -322,46 +322,6 @@ private: }; }; -std::map Value::ObjectValue::prototypes = { - { - "size", - Value(FunctionValue( - {}, - [](shared_ptr callEnv) { - const auto& val = callEnv->get("this"); - long n = val.to_object().data->props.size(); - return Value(n); - } - )) - } -}; - -std::map Value::ArrayValue::prototypes = { - { - "size", - Value(FunctionValue( - {}, - [](shared_ptr callEnv) { - const auto& val = callEnv->get("this"); - long n = val.to_array().data->values.size(); - return Value(n); - } - )) - }, - { - "push", - Value(FunctionValue { - { {"arg", false} }, - [](shared_ptr callEnv) { - const auto& val = callEnv->get("this"); - const auto& arg = callEnv->get("arg"); - val.to_array().data->values.push_back(arg); - return Value(); - } - }) - } -}; - bool run( const string& path, shared_ptr env, diff --git a/language/interpreter.hpp b/language/interpreter.hpp index 5f9bae4..950a7b1 100644 --- a/language/interpreter.hpp +++ b/language/interpreter.hpp @@ -2,74 +2,51 @@ #include #include +struct Value; struct Environment; -struct Value -{ - enum Type { Undefined, Bool, Long, String, Object, Array, Function }; - - struct FunctionValue { - struct Parameter { - std::string name; - bool mut; - }; - - struct Data { - std::vector params; - std::function env)> eval; - }; - - FunctionValue( - const std::vector& params, - const std::function env)>& eval) { - - data = std::make_shared(); - data->params = params; - data->eval = eval; - } +struct FunctionValue { + struct Parameter { + std::string name; + bool mut; + }; - std::shared_ptr data; + struct Data { + std::vector params; + std::function env)> eval; }; - struct ObjectValue { - bool has_property(const std::string& name) const { - if (data->props.find(name) == data->props.end()) { - return prototypes.find(name) != prototypes.end(); - } - return true; - } + FunctionValue( + const std::vector& params, + const std::function env)>& eval) { - Value get_property(const std::string& name) const { - if (data->props.find(name) == data->props.end()) { - return prototypes.at(name); - } - return data->props.at(name); - } + data = std::make_shared(); + data->params = params; + data->eval = eval; + } - struct Data { - std::map props; - }; - std::shared_ptr data = std::make_shared(); + std::shared_ptr data; +}; - static std::map prototypes; - }; +struct ObjectValue { + bool has_property(const std::string& name) const; + Value get_property(const std::string& name) const; + virtual std::map& builtins(); - struct ArrayValue { - Value get_property(const std::string& name) const { - if (data->props.find(name) == data->props.end()) { - return prototypes.at(name); - } - return data->props.at(name); - } + std::shared_ptr> properties = + std::make_shared>(); +}; - struct Data { - std::map props; - std::vector values; - }; - std::shared_ptr data = std::make_shared(); +struct ArrayValue : public ObjectValue { + std::map& builtins() override; - static std::map prototypes; - }; + std::shared_ptr> values = + std::make_shared>(); +}; + +struct Value +{ + enum Type { Undefined, Bool, Long, String, Object, Array, Function }; Value() : type(Undefined) { //std::cout << "Val::def ctor: " << std::endl; @@ -163,11 +140,11 @@ struct Value } std::string str_object() const { - const auto& props = to_object().data->props; + const auto& properties = *to_object().properties; std::string s = "{"; - auto it = props.begin(); - for (; it != props.end(); ++it) { - if (it != props.begin()) { + auto it = properties.begin(); + for (; it != properties.end(); ++it) { + if (it != properties.begin()) { s += ", "; } s += '"' + it->first + '"'; @@ -179,7 +156,7 @@ struct Value } std::string str_array() const { - const auto& values = to_array().data->values; + const auto& values = *to_array().values; std::string s = "["; for (auto i = 0u; i < values.size(); i++) { if (i != 0) { @@ -299,7 +276,7 @@ struct Environment { Environment() = default; - void set_object(const Value::ObjectValue& obj) { + void set_object(const ObjectValue& obj) { obj_ = obj; } @@ -371,12 +348,74 @@ private: std::shared_ptr outer_; std::map dic_; - Value::ObjectValue obj_; + ObjectValue obj_; }; +inline bool ObjectValue::has_property(const std::string& name) const { + if (properties->find(name) == properties->end()) { + const auto& proto = const_cast(this)->builtins(); + return proto.find(name) != proto.end(); + } + return true; +} + +inline Value ObjectValue::get_property(const std::string& name) const { + if (properties->find(name) == properties->end()) { + const auto& proto = const_cast(this)->builtins(); + return proto.at(name); + } + return properties->at(name); +} + +inline std::map& ObjectValue::builtins() { + static std::map proto_ = { + { + "size", + Value(FunctionValue( + {}, + [](std::shared_ptr callEnv) { + const auto& val = callEnv->get("this"); + long n = val.to_object().properties->size(); + return Value(n); + } + )) + } + }; + return proto_; +} + +inline std::map& ArrayValue::builtins() { + static std::map proto_ = { + { + "size", + Value(FunctionValue( + {}, + [](std::shared_ptr callEnv) { + const auto& val = callEnv->get("this"); + long n = val.to_array().values->size(); + return Value(n); + } + )) + }, + { + "push", + Value(FunctionValue { + { {"arg", false} }, + [](std::shared_ptr callEnv) { + const auto& val = callEnv->get("this"); + const auto& arg = callEnv->get("arg"); + val.to_array().values->push_back(arg); + return Value(); + } + }) + } + }; + return proto_; +} + inline void setup_built_in_functions(Environment& env) { { - auto f = Value::FunctionValue( + auto f = FunctionValue( { {"arg", true} }, [](std::shared_ptr env) { std::cout << env->get("arg").str() << std::endl; @@ -387,7 +426,7 @@ inline void setup_built_in_functions(Environment& env) { } { - auto f = Value::FunctionValue( + auto f = FunctionValue( { {"arg", true} }, [](std::shared_ptr env) { auto cond = env->get("arg").to_bool();