From 964f1a1741d7ba740cae01f06ca00c1f57178ba7 Mon Sep 17 00:00:00 2001 From: Rain Mark Date: Thu, 24 Feb 2022 13:26:09 +0800 Subject: [PATCH] fmt code Signed-off-by: Rain Mark --- build.sh | 2 + src/core.h | 191 +++++++++++++++++++++++-------------------------- src/lispoo.cpp | 5 +- src/lispoo.h | 89 +++++++++++------------ 4 files changed, 140 insertions(+), 147 deletions(-) diff --git a/build.sh b/build.sh index 9894bb1..abea8a0 100755 --- a/build.sh +++ b/build.sh @@ -1,3 +1,5 @@ #!/bin/bash +# git-clang-format --style=Google HEAD^ + g++ -Werror -std=c++20 -Isrc src/lispoo.cpp -o lispoo diff --git a/src/core.h b/src/core.h index 1f9f2ff..a3e2e63 100644 --- a/src/core.h +++ b/src/core.h @@ -6,13 +6,12 @@ namespace lispoo { inline std::shared_ptr sum(const std::shared_ptr& a, const std::shared_ptr& b) { - if (a->type() == Type::Float - && b->type() == Type::Float) { + if (a->type() == Type::Float && b->type() == Type::Float) { return std::make_shared(get_value(a) + get_value(b)); } - if (a->type() == Type::Integer - && b->type() == Type::Integer) { - return std::make_shared(get_value(a) + get_value(b)); + if (a->type() == Type::Integer && b->type() == Type::Integer) { + return std::make_shared(get_value(a) + + get_value(b)); } if (a->type() == Type::Float) { return std::make_shared(get_value(a) + get_value(b)); @@ -65,103 +64,93 @@ inline std::shared_ptr message(const std::shared_ptr& expr) { inline void init() { // syntax - putenv("quote", - [](auto expr, auto env) { - assert_len(expr, 2); - auto value = get_value(expr); - return value[1]; - }); - putenv("define", - [](auto expr, auto env) { - assert_len(expr, 3); - auto value = get_value(expr); - assert_type(value[1]); - auto symbol = get_value(value[1]); - if (!is_nil(env->get(symbol))) { - oops("symbol defined: " + symbol); - } - env->put(symbol, eval(value[2], env)); - return nil; - }); - putenv("set!", - [](auto expr, auto env) { - assert_len(expr, 3); - auto value = get_value(expr); - assert_type(value[1]); - auto symbol = get_value(value[1]); - env->put(symbol, eval(value[2], env)); - return nil; - }); - putenv("progn", - [](auto expr, auto env) { - auto val = nil; - auto value = get_value(expr); - for (auto i = 1; i < value.size(); ++i) { - val = eval(value[i], env); - } - return val; - }); - putenv("if", - [](auto expr, auto env) { - // (if (cond) (then body) (else body)) - assert_len(expr, 4); - auto value = get_value(expr); - if (is_true(eval(value[1], env))) { - return eval(value[2], env); - } else { - return eval(value[3], env); - } - }); - putenv("while", - [](auto expr, auto env) { - // (while (cond) (loop body)) - assert_len(expr, 3); - auto value = get_value(expr); - while (is_true(eval(value[1], env))) { - eval(value[2], env); - } - return nil; - }); - putenv("lambda", - [](auto expr, auto env) { - // (lambda (args) (body)) - assert_len(expr, 3); - auto lambda = - [expr, parent = env](auto args, auto) { - auto value = get_value(expr); - auto symbols = get_value(value[1]); - // arguments bind - auto args_value = get_value(args); - if (symbols.size() != args_value.size() - 1) { - oops("arguments error"); - } - auto env = std::make_shared(parent); - for (auto i = 0; i < symbols.size(); ++i) { - auto symbol = get_value(symbols[i]); - env->put(symbol, eval(args_value[i + 1], parent)); - } - // eval body - return eval(value[2], env); - }; - return std::make_shared(std::move(lambda)); - }); + putenv("quote", [](auto expr, auto env) { + assert_len(expr, 2); + auto value = get_value(expr); + return value[1]; + }); + putenv("define", [](auto expr, auto env) { + assert_len(expr, 3); + auto value = get_value(expr); + assert_type(value[1]); + auto symbol = get_value(value[1]); + if (!is_nil(env->get(symbol))) { + oops("symbol defined: " + symbol); + } + env->put(symbol, eval(value[2], env)); + return nil; + }); + putenv("set!", [](auto expr, auto env) { + assert_len(expr, 3); + auto value = get_value(expr); + assert_type(value[1]); + auto symbol = get_value(value[1]); + env->put(symbol, eval(value[2], env)); + return nil; + }); + putenv("progn", [](auto expr, auto env) { + auto val = nil; + auto value = get_value(expr); + for (auto i = 1; i < value.size(); ++i) { + val = eval(value[i], env); + } + return val; + }); + putenv("if", [](auto expr, auto env) { + // (if (cond) (then body) (else body)) + assert_len(expr, 4); + auto value = get_value(expr); + if (is_true(eval(value[1], env))) { + return eval(value[2], env); + } else { + return eval(value[3], env); + } + }); + putenv("while", [](auto expr, auto env) { + // (while (cond) (loop body)) + assert_len(expr, 3); + auto value = get_value(expr); + while (is_true(eval(value[1], env))) { + eval(value[2], env); + } + return nil; + }); + putenv("lambda", [](auto expr, auto env) { + // (lambda (args) (body)) + assert_len(expr, 3); + auto lambda = [expr, parent = env](auto args, auto) { + auto value = get_value(expr); + auto symbols = get_value(value[1]); + // arguments bind + auto args_value = get_value(args); + if (symbols.size() != args_value.size() - 1) { + oops("arguments error"); + } + auto env = std::make_shared(parent); + for (auto i = 0; i < symbols.size(); ++i) { + auto symbol = get_value(symbols[i]); + env->put(symbol, eval(args_value[i + 1], parent)); + } + // eval body + return eval(value[2], env); + }; + return std::make_shared(std::move(lambda)); + }); // normal builtin function - putenv("+", - [](auto expr, auto env) { - assert_len(expr, 3); - auto value = get_value(expr); - return sum(eval(value[1], env), eval(value[2], env)); - }); - putenv("message", - [](auto expr, auto env) { - auto value = get_value(expr); - for (auto i = 1; i < value.size(); ++i) { - message(eval(value[i], env)); - std::cout << std::endl; - } - return nil; - }); + putenv("+", [](auto expr, auto env) { + assert_len(expr, 3); + auto value = get_value(expr); + return sum(eval(value[1], env), eval(value[2], env)); + }); + putenv("message", [](auto expr, auto env) { + auto value = get_value(expr); + for (auto i = 1; i < value.size(); ++i) { + message(eval(value[i], env)); + std::cout << std::endl; + } + return nil; + }); } -} // namespace lispoo +} // namespace lispoo diff --git a/src/lispoo.cpp b/src/lispoo.cpp index 6b1a1f9..6b8e7da 100644 --- a/src/lispoo.cpp +++ b/src/lispoo.cpp @@ -1,7 +1,8 @@ -#include #include -#include +#include + #include +#include int main(int argc, char* argv[]) { if (argc != 2) { diff --git a/src/lispoo.h b/src/lispoo.h index f391411..7069b3e 100644 --- a/src/lispoo.h +++ b/src/lispoo.h @@ -1,13 +1,12 @@ #pragma once -#include #include - -#include -#include -#include #include +#include +#include +#include #include +#include namespace lispoo { @@ -28,75 +27,73 @@ enum class Type { }; class Expr { -public: + public: virtual Type type() = 0; }; template -class Atom: public Expr { -public: +class Atom : public Expr { + public: explicit Atom(const T& value) : value_(value) {} Type type() override { return Type::Atom; } const T& value() const { return value_; } -private: + private: T value_; }; -class Symbol: public Atom { -public: +class Symbol : public Atom { + public: explicit Symbol(const std::string& value) : Atom(value) {} Type type() override { return Type::Symbol; } }; -class Integer: public Atom { -public: +class Integer : public Atom { + public: explicit Integer(const long& value) : Atom(value) {} Type type() override { return Type::Integer; } }; -class Float: public Atom { -public: +class Float : public Atom { + public: explicit Float(const double& value) : Atom(value) {} Type type() override { return Type::Float; } }; -class Null: public Expr { -public: +class Null : public Expr { + public: Type type() override { return Type::Null; } }; static const std::shared_ptr nil = std::make_shared(); -class List: public Expr { -public: +class List : public Expr { + public: Type type() override { return Type::List; } const std::vector>& value() const { return value_; } void append(const std::shared_ptr& expr) { value_.emplace_back(expr); } -private: + private: std::vector> value_; }; class Env; -class Callable: public Expr { -public: - using Fn = std::function(const std::shared_ptr&, - const std::shared_ptr& env)>; +class Callable : public Expr { + public: + using Fn = std::function( + const std::shared_ptr&, const std::shared_ptr& env)>; explicit Callable(Fn&& lambda) : lambda_(lambda) {} Type type() override { return Type::Callable; } - const Fn& value() const { - return lambda_; - } + const Fn& value() const { return lambda_; } -private: + private: Fn lambda_; }; // environment class Env { -public: + public: Env(const std::shared_ptr& env) : env_(env) {} std::shared_ptr get(const std::string& symbol) const { @@ -113,20 +110,20 @@ public: expr_map_[symbol] = expr; } -private: + private: std::unordered_map> expr_map_; std::shared_ptr env_; }; -static std::shared_ptr global = std::make_shared(std::shared_ptr()); +static std::shared_ptr global = + std::make_shared(std::shared_ptr()); inline void putenv(const std::string& symbol, Callable::Fn&& lambda) { - global->put(symbol, std::make_shared(std::forward(lambda))); + global->put(symbol, + std::make_shared(std::forward(lambda))); } // type utils -inline bool is_par(char ch) { - return ch == '(' || ch == ')'; -} +inline bool is_par(char ch) { return ch == '(' || ch == ')'; } template inline decltype(auto) get_value(const std::shared_ptr& expr) { return std::static_pointer_cast(expr)->value(); @@ -184,13 +181,15 @@ inline void tokenize(const std::string& str, std::vector& tokens) { continue; } auto s = i; - for (; !(std::isspace(str[i]) || is_par(str[i])); ++i); + for (; !(std::isspace(str[i]) || is_par(str[i])); ++i) + ; tokens.emplace_back(str.c_str() + s, i - s); i--; } } -inline std::shared_ptr parse_atom(const std::vector& tokens, long& cursor) { +inline std::shared_ptr parse_atom(const std::vector& tokens, + long& cursor) { auto token = tokens[cursor]; auto type = Type::Symbol; if (std::isdigit(token[0]) || token[0] == '-') { @@ -210,18 +209,19 @@ inline std::shared_ptr parse_atom(const std::vector& tokens, } switch (type) { case Type::Symbol: - return std::make_shared(token); + return std::make_shared(token); case Type::Integer: - return std::make_shared(std::stol(token)); + return std::make_shared(std::stol(token)); case Type::Float: - return std::make_shared(std::stod(token)); + return std::make_shared(std::stod(token)); default: - break; + break; } return nil; } -inline std::shared_ptr parse(const std::vector& tokens, long& cursor) { +inline std::shared_ptr parse(const std::vector& tokens, + long& cursor) { if (cursor >= tokens.size()) { oops("parse error"); } @@ -235,7 +235,8 @@ inline std::shared_ptr parse(const std::vector& tokens, long& return parse_atom(tokens, cursor); } -inline std::shared_ptr eval(const std::shared_ptr& expr, const std::shared_ptr& env) { +inline std::shared_ptr eval(const std::shared_ptr& expr, + const std::shared_ptr& env) { if (!expr) { oops("syntax error"); return nil; @@ -262,4 +263,4 @@ inline std::shared_ptr eval(const std::shared_ptr& expr, const std:: return get_value(callable)(expr, env); } -} // namespace lispoo +} // namespace lispoo