Browse Source

fmt code

Signed-off-by: Rain Mark <rain.by.zhou@gmail.com>
main
Rain Mark 4 years ago
parent
commit
964f1a1741
  1. 2
      build.sh
  2. 39
      src/core.h
  3. 5
      src/lispoo.cpp
  4. 79
      src/lispoo.h

2
build.sh

@ -1,3 +1,5 @@
#!/bin/bash #!/bin/bash
# git-clang-format --style=Google HEAD^
g++ -Werror -std=c++20 -Isrc src/lispoo.cpp -o lispoo g++ -Werror -std=c++20 -Isrc src/lispoo.cpp -o lispoo

39
src/core.h

@ -6,13 +6,12 @@ namespace lispoo {
inline std::shared_ptr<Expr> sum(const std::shared_ptr<Expr>& a, inline std::shared_ptr<Expr> sum(const std::shared_ptr<Expr>& a,
const std::shared_ptr<Expr>& b) { const std::shared_ptr<Expr>& b) {
if (a->type() == Type::Float if (a->type() == Type::Float && b->type() == Type::Float) {
&& b->type() == Type::Float) {
return std::make_shared<Float>(get_value<Float>(a) + get_value<Float>(b)); return std::make_shared<Float>(get_value<Float>(a) + get_value<Float>(b));
} }
if (a->type() == Type::Integer if (a->type() == Type::Integer && b->type() == Type::Integer) {
&& b->type() == Type::Integer) { return std::make_shared<Integer>(get_value<Integer>(a) +
return std::make_shared<Integer>(get_value<Integer>(a) + get_value<Integer>(b)); get_value<Integer>(b));
} }
if (a->type() == Type::Float) { if (a->type() == Type::Float) {
return std::make_shared<Float>(get_value<Float>(a) + get_value<Integer>(b)); return std::make_shared<Float>(get_value<Float>(a) + get_value<Integer>(b));
@ -65,14 +64,12 @@ inline std::shared_ptr<Expr> message(const std::shared_ptr<Expr>& expr) {
inline void init() { inline void init() {
// syntax // syntax
putenv("quote", putenv("quote", [](auto expr, auto env) {
[](auto expr, auto env) {
assert_len(expr, 2); assert_len(expr, 2);
auto value = get_value<List>(expr); auto value = get_value<List>(expr);
return value[1]; return value[1];
}); });
putenv("define", putenv("define", [](auto expr, auto env) {
[](auto expr, auto env) {
assert_len(expr, 3); assert_len(expr, 3);
auto value = get_value<List>(expr); auto value = get_value<List>(expr);
assert_type<Type::Symbol>(value[1]); assert_type<Type::Symbol>(value[1]);
@ -83,8 +80,7 @@ inline void init() {
env->put(symbol, eval(value[2], env)); env->put(symbol, eval(value[2], env));
return nil; return nil;
}); });
putenv("set!", putenv("set!", [](auto expr, auto env) {
[](auto expr, auto env) {
assert_len(expr, 3); assert_len(expr, 3);
auto value = get_value<List>(expr); auto value = get_value<List>(expr);
assert_type<Type::Symbol>(value[1]); assert_type<Type::Symbol>(value[1]);
@ -92,8 +88,7 @@ inline void init() {
env->put(symbol, eval(value[2], env)); env->put(symbol, eval(value[2], env));
return nil; return nil;
}); });
putenv("progn", putenv("progn", [](auto expr, auto env) {
[](auto expr, auto env) {
auto val = nil; auto val = nil;
auto value = get_value<List>(expr); auto value = get_value<List>(expr);
for (auto i = 1; i < value.size(); ++i) { for (auto i = 1; i < value.size(); ++i) {
@ -101,8 +96,7 @@ inline void init() {
} }
return val; return val;
}); });
putenv("if", putenv("if", [](auto expr, auto env) {
[](auto expr, auto env) {
// (if (cond) (then body) (else body)) // (if (cond) (then body) (else body))
assert_len(expr, 4); assert_len(expr, 4);
auto value = get_value<List>(expr); auto value = get_value<List>(expr);
@ -112,8 +106,7 @@ inline void init() {
return eval(value[3], env); return eval(value[3], env);
} }
}); });
putenv("while", putenv("while", [](auto expr, auto env) {
[](auto expr, auto env) {
// (while (cond) (loop body)) // (while (cond) (loop body))
assert_len(expr, 3); assert_len(expr, 3);
auto value = get_value<List>(expr); auto value = get_value<List>(expr);
@ -122,12 +115,10 @@ inline void init() {
} }
return nil; return nil;
}); });
putenv("lambda", putenv("lambda", [](auto expr, auto env) {
[](auto expr, auto env) {
// (lambda (args) (body)) // (lambda (args) (body))
assert_len(expr, 3); assert_len(expr, 3);
auto lambda = auto lambda = [expr, parent = env](auto args, auto) {
[expr, parent = env](auto args, auto) {
auto value = get_value<List>(expr); auto value = get_value<List>(expr);
auto symbols = get_value<List>(value[1]); auto symbols = get_value<List>(value[1]);
// arguments bind // arguments bind
@ -147,14 +138,12 @@ inline void init() {
}); });
// normal builtin function // normal builtin function
putenv("+", putenv("+", [](auto expr, auto env) {
[](auto expr, auto env) {
assert_len(expr, 3); assert_len(expr, 3);
auto value = get_value<List>(expr); auto value = get_value<List>(expr);
return sum(eval(value[1], env), eval(value[2], env)); return sum(eval(value[1], env), eval(value[2], env));
}); });
putenv("message", putenv("message", [](auto expr, auto env) {
[](auto expr, auto env) {
auto value = get_value<List>(expr); auto value = get_value<List>(expr);
for (auto i = 1; i < value.size(); ++i) { for (auto i = 1; i < value.size(); ++i) {
message(eval(value[i], env)); message(eval(value[i], env));

5
src/lispoo.cpp

@ -1,7 +1,8 @@
#include <lispoo.h>
#include <core.h> #include <core.h>
#include <sstream> #include <lispoo.h>
#include <fstream> #include <fstream>
#include <sstream>
int main(int argc, char* argv[]) { int main(int argc, char* argv[]) {
if (argc != 2) { if (argc != 2) {

79
src/lispoo.h

@ -1,13 +1,12 @@
#pragma once #pragma once
#include <iostream>
#include <exception> #include <exception>
#include <string>
#include <vector>
#include <memory>
#include <functional> #include <functional>
#include <iostream>
#include <memory>
#include <string>
#include <unordered_map> #include <unordered_map>
#include <vector>
namespace lispoo { namespace lispoo {
@ -28,75 +27,73 @@ enum class Type {
}; };
class Expr { class Expr {
public: public:
virtual Type type() = 0; virtual Type type() = 0;
}; };
template <typename T> template <typename T>
class Atom: public Expr { class Atom : public Expr {
public: public:
explicit Atom(const T& value) : value_(value) {} explicit Atom(const T& value) : value_(value) {}
Type type() override { return Type::Atom; } Type type() override { return Type::Atom; }
const T& value() const { return value_; } const T& value() const { return value_; }
private: private:
T value_; T value_;
}; };
class Symbol: public Atom<std::string> { class Symbol : public Atom<std::string> {
public: public:
explicit Symbol(const std::string& value) : Atom(value) {} explicit Symbol(const std::string& value) : Atom(value) {}
Type type() override { return Type::Symbol; } Type type() override { return Type::Symbol; }
}; };
class Integer: public Atom<long> { class Integer : public Atom<long> {
public: public:
explicit Integer(const long& value) : Atom(value) {} explicit Integer(const long& value) : Atom(value) {}
Type type() override { return Type::Integer; } Type type() override { return Type::Integer; }
}; };
class Float: public Atom<double> { class Float : public Atom<double> {
public: public:
explicit Float(const double& value) : Atom(value) {} explicit Float(const double& value) : Atom(value) {}
Type type() override { return Type::Float; } Type type() override { return Type::Float; }
}; };
class Null: public Expr { class Null : public Expr {
public: public:
Type type() override { return Type::Null; } Type type() override { return Type::Null; }
}; };
static const std::shared_ptr<Expr> nil = std::make_shared<Null>(); static const std::shared_ptr<Expr> nil = std::make_shared<Null>();
class List: public Expr { class List : public Expr {
public: public:
Type type() override { return Type::List; } Type type() override { return Type::List; }
const std::vector<std::shared_ptr<Expr>>& value() const { return value_; } const std::vector<std::shared_ptr<Expr>>& value() const { return value_; }
void append(const std::shared_ptr<Expr>& expr) { value_.emplace_back(expr); } void append(const std::shared_ptr<Expr>& expr) { value_.emplace_back(expr); }
private: private:
std::vector<std::shared_ptr<Expr>> value_; std::vector<std::shared_ptr<Expr>> value_;
}; };
class Env; class Env;
class Callable: public Expr { class Callable : public Expr {
public: public:
using Fn = std::function<std::shared_ptr<Expr>(const std::shared_ptr<Expr>&, using Fn = std::function<std::shared_ptr<Expr>(
const std::shared_ptr<Env>& env)>; const std::shared_ptr<Expr>&, const std::shared_ptr<Env>& env)>;
explicit Callable(Fn&& lambda) : lambda_(lambda) {} explicit Callable(Fn&& lambda) : lambda_(lambda) {}
Type type() override { return Type::Callable; } Type type() override { return Type::Callable; }
const Fn& value() const { const Fn& value() const { return lambda_; }
return lambda_;
}
private: private:
Fn lambda_; Fn lambda_;
}; };
// environment // environment
class Env { class Env {
public: public:
Env(const std::shared_ptr<Env>& env) : env_(env) {} Env(const std::shared_ptr<Env>& env) : env_(env) {}
std::shared_ptr<Expr> get(const std::string& symbol) const { std::shared_ptr<Expr> get(const std::string& symbol) const {
@ -113,20 +110,20 @@ public:
expr_map_[symbol] = expr; expr_map_[symbol] = expr;
} }
private: private:
std::unordered_map<std::string, std::shared_ptr<Expr>> expr_map_; std::unordered_map<std::string, std::shared_ptr<Expr>> expr_map_;
std::shared_ptr<Env> env_; std::shared_ptr<Env> env_;
}; };
static std::shared_ptr<Env> global = std::make_shared<Env>(std::shared_ptr<Env>()); static std::shared_ptr<Env> global =
std::make_shared<Env>(std::shared_ptr<Env>());
inline void putenv(const std::string& symbol, Callable::Fn&& lambda) { inline void putenv(const std::string& symbol, Callable::Fn&& lambda) {
global->put(symbol, std::make_shared<Callable>(std::forward<Callable::Fn>(lambda))); global->put(symbol,
std::make_shared<Callable>(std::forward<Callable::Fn>(lambda)));
} }
// type utils // type utils
inline bool is_par(char ch) { inline bool is_par(char ch) { return ch == '(' || ch == ')'; }
return ch == '(' || ch == ')';
}
template <typename T> template <typename T>
inline decltype(auto) get_value(const std::shared_ptr<Expr>& expr) { inline decltype(auto) get_value(const std::shared_ptr<Expr>& expr) {
return std::static_pointer_cast<T>(expr)->value(); return std::static_pointer_cast<T>(expr)->value();
@ -184,13 +181,15 @@ inline void tokenize(const std::string& str, std::vector<std::string>& tokens) {
continue; continue;
} }
auto s = i; 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); tokens.emplace_back(str.c_str() + s, i - s);
i--; i--;
} }
} }
inline std::shared_ptr<Expr> parse_atom(const std::vector<std::string>& tokens, long& cursor) { inline std::shared_ptr<Expr> parse_atom(const std::vector<std::string>& tokens,
long& cursor) {
auto token = tokens[cursor]; auto token = tokens[cursor];
auto type = Type::Symbol; auto type = Type::Symbol;
if (std::isdigit(token[0]) || token[0] == '-') { if (std::isdigit(token[0]) || token[0] == '-') {
@ -221,7 +220,8 @@ inline std::shared_ptr<Expr> parse_atom(const std::vector<std::string>& tokens,
return nil; return nil;
} }
inline std::shared_ptr<Expr> parse(const std::vector<std::string>& tokens, long& cursor) { inline std::shared_ptr<Expr> parse(const std::vector<std::string>& tokens,
long& cursor) {
if (cursor >= tokens.size()) { if (cursor >= tokens.size()) {
oops("parse error"); oops("parse error");
} }
@ -235,7 +235,8 @@ inline std::shared_ptr<Expr> parse(const std::vector<std::string>& tokens, long&
return parse_atom(tokens, cursor); return parse_atom(tokens, cursor);
} }
inline std::shared_ptr<Expr> eval(const std::shared_ptr<Expr>& expr, const std::shared_ptr<Env>& env) { inline std::shared_ptr<Expr> eval(const std::shared_ptr<Expr>& expr,
const std::shared_ptr<Env>& env) {
if (!expr) { if (!expr) {
oops("syntax error"); oops("syntax error");
return nil; return nil;

Loading…
Cancel
Save