Skip to content

Commit

Permalink
for v0.6 release
Browse files Browse the repository at this point in the history
  • Loading branch information
hhorikawa committed Oct 2, 2024
1 parent e721cda commit 782f182
Show file tree
Hide file tree
Showing 10 changed files with 125 additions and 59 deletions.
41 changes: 41 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@

.PHONY: all clean

TARGETS = mylisp

all: $(TARGETS)

# コンパイラオプション:
# https://best.openssf.org/Compiler-Hardening-Guides/Compiler-Options-Hardening-Guide-for-C-and-C++
# 英語版のほうが更新されている。

# GDB でデバグする場合, `-g` オプションよりも `-g3` のほうが便利.
# リリースビルド = -DNDEBUG
DEBUG = -g3 -D_DEBUG

# _FORTIFY_SOURCE は副作用がありうる
CXXFLAGS = -Wall -Wextra -Wno-unused-parameter -Wno-format-extra-args \
-O2 -Wformat -Wformat=2 -Wimplicit-fallthrough -Werror=format-security \
$(DEBUG) \
-U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=3 \
-D_GLIBCXX_ASSERTIONS \
-fstrict-flex-arrays=3 \
-fstack-clash-protection -fstack-protector-strong \
-Wl,-z,nodlopen -Wl,-z,noexecstack \
-Wl,-z,relro -Wl,-z,now \
-Wl,--as-needed -Wl,--no-copy-dt-needed-entries \
-fPIE -pie

mylisp: main.o edit_line.o reader.o object_print.o environment.o evaluation.o macros.o builtin-functions.o
$(CXX) $^ $(LDFLAGS) $(LDLIBS) -lstdc++ -licuuc -licuio -ledit -o $@

reader.o: reader.cpp s_expr.h
object_print.o: object_print.cpp s_expr.h
s_expr.h: my_debug.h
environment.o: environment.cpp environment.h s_expr.h
evaluation.o: evaluation.cpp environment.h s_expr.h
builtin-functions.o: builtin-functions.cpp environment.h s_expr.h

clean:
rm -f *.o $(TARGETS)

19 changes: 19 additions & 0 deletions builtin-functions.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,20 @@ value_t do_multiply(EnvPtr args)
return xv * yv;
}

my::value_t do_1minus(my::EnvPtr args) {
my::value_t x = args->find_value("X");
double v = std::get<double>(x);

return v - 1;
}

// @return T or NIL
my::value_t do_gt(my::EnvPtr args) {
double x = std::get<double>(args->find_value("X"));
double y = std::get<double>(args->find_value("Y"));
return x > y ? trueValue : nilValue;
}


//////////////////////////////////////////////////////////////////////////
// <function>
Expand Down Expand Up @@ -112,12 +126,17 @@ static const BuiltinFunc funcs[] = {
// <number>
{"+", "(x y)", my::do_add },
{"*", "(x y)", my::do_multiply },
{"1-", "(x)", my::do_1minus },
{">", "(x y)", my::do_gt },
// <function>
{"MAPCAR", "(func list)", do_mapcar },
};

void setup_functions()
{
my::globalEnv->set_value("T", my::trueValue, true);
my::globalEnv->set_value("NIL", my::nilValue, true);

for (const auto& f : funcs)
define_function(f.name, f.params, f.func);
}
Expand Down
21 changes: 21 additions & 0 deletions eval.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@

#ifndef MYLISP_EVAL_H
#define MYLISP_EVAL_H

#include "s_expr.h"
#include "environment.h"

namespace my {

extern value_t EVAL1(value_t ast, EnvPtr env);
extern bool value_isTrue(const value_t& value) ;

extern void setup_functions();

extern void define_macro(const icu::UnicodeString& name,
const icu::UnicodeString& params,
ListPtr body);

} // namespace my

#endif // !MYLISP_EVAL_H
26 changes: 26 additions & 0 deletions main.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@

#include "edit_line.h"
#include "environment.h"
#include "s_expr.h"
#include "eval.h"
#include <iostream>
#include <unicode/unistr.h>
using namespace icu;

int main()
{
my::EditLine editLine("~/my-lisp.history");

my::EnvPtr toplevel = std::make_shared<my::Environment>();
my::setup_functions();

UnicodeString line;
bool f;
while ( editLine.get("* ", &line) ) {
my::value_t astv = my::read_from_string(line);
my::value_t r = my::EVAL1(astv, toplevel);
PRINT(r, std::cout); std::cout << "\n";
}

return 0;
}
14 changes: 11 additions & 3 deletions object_print.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ namespace my {

// TODO: 定数リストに格納
const std::shared_ptr<null> nilValue = std::make_shared<null>();
const std::shared_ptr<symbol> trueValue = std::make_shared<symbol>("T");
const std::shared_ptr<object> trueValue = std::make_shared<object>();


static void indent(std::ostream& out, int level) {
Expand All @@ -26,6 +26,10 @@ void object::write_indented(std::ostream& out, int level) const {
out << s;
}

UnicodeString object::print() const {
return "T";
}

////////////////////////////////////////////////////////
// class symbol

Expand Down Expand Up @@ -138,10 +142,14 @@ void cons::write_indented(std::ostream& out, int level) const
throw std::out_of_range("empty");

WriteVisitor v = WriteVisitor(out, level + 1);
PrintVisitor p = PrintVisitor();

indent(out, level); out << "(\n";
indent(out, level); out << "(";
for (auto i = list_.begin(); i != list_.end(); ++i) {
std::visit(v, *i);
if (i == list_.begin())
out << std::visit(p, *i);
else
std::visit(v, *i);
out << '\n';
}

Expand Down
6 changes: 3 additions & 3 deletions s_expr.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ No direct slots.
*/
class object //: public RefCounted
{
protected:
public:
object() {
TRACE_OBJECT("Creating object %p\n", this);
}
Expand All @@ -55,7 +55,7 @@ class object //: public RefCounted
// 数値には function =, 文字には char=, 文字列には string= 関数を使え.
//bool isEqualTo(const malValue* rhs) const;
public:
virtual icu::UnicodeString print() const = 0;
virtual icu::UnicodeString print() const ;
virtual void write_indented(std::ostream& out, int level) const ;
};

Expand Down Expand Up @@ -144,7 +144,7 @@ typedef std::variant< bool, int64_t, double, ObjectPtr > value_t;
extern bool value_isa(const value_t& , const icu::UnicodeString& klass);

extern const std::shared_ptr<class null> nilValue;
extern const std::shared_ptr<class symbol> trueValue;
extern const std::shared_ptr<class object> trueValue;

extern value_t READ(std::istream& stream);
extern value_t read_from_string(const icu::UnicodeString& str);
Expand Down
8 changes: 1 addition & 7 deletions test/block_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,8 @@
#include <sstream>
#include <iostream>
#include <fstream>
#include "../eval.h"

namespace my {
extern value_t EVAL1(value_t ast, EnvPtr env);
extern bool value_isTrue(const value_t& value) ;

extern void setup_functions();

} // namespace my

int main() {
my::setup_functions();
Expand Down
9 changes: 1 addition & 8 deletions test/evaluation_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,7 @@
#include <sstream>
#include <iostream>
#include <fstream>

namespace my {
extern value_t EVAL1(value_t ast, EnvPtr env);
extern bool value_isTrue(const value_t& value) ;

extern void setup_functions();

} // namespace my
#include "../eval.h"


my::value_t func1(my::EnvPtr args) {
Expand Down
13 changes: 1 addition & 12 deletions test/macro_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,7 @@
// マクロのテスト
#include "../environment.h"
#include <iostream>

namespace my {

extern value_t EVAL1(value_t ast, EnvPtr env);

extern void define_macro(const icu::UnicodeString& name,
const icu::UnicodeString& params,
ListPtr body);

extern void setup_functions();

} // namespace my
#include "../eval.h"


// quasiquote の呼び出し
Expand Down
27 changes: 1 addition & 26 deletions test/tco_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,39 +3,14 @@
#include <sstream>
#include <iostream>
#include <fstream>

namespace my {
extern value_t EVAL1(value_t ast, EnvPtr env);
extern bool value_isTrue(const value_t& value) ;

extern void setup_functions();

my::value_t do_1minus(my::EnvPtr args) {
my::value_t x = args->find_value("X");
double v = std::get<double>(x);

return v - 1;
}

// @return T or NIL
my::value_t do_gt(my::EnvPtr args) {
double x = std::get<double>(args->find_value("X"));
double y = std::get<double>(args->find_value("Y"));
return x > y ? trueValue : nilValue;
}

} // namespace my
#include "../eval.h"


int main()
{
my::EnvPtr env = std::make_shared<my::Environment>();

my::setup_functions();
my::define_function("1-", "(x)", my::do_1minus);
my::define_function(">", "(x y)", my::do_gt);
my::globalEnv->set_value("T", my::trueValue, true);
my::globalEnv->set_value("NIL", my::nilValue, true);

// 偶数 = true
icu::UnicodeString ast = "(defun iseven (n) (if (> n 0) (isodd (1- n)) t))";
Expand Down

0 comments on commit 782f182

Please sign in to comment.