Skip to content

Commit

Permalink
TCO OK.
Browse files Browse the repository at this point in the history
  • Loading branch information
hhorikawa committed Oct 1, 2024
1 parent ee78567 commit e721cda
Show file tree
Hide file tree
Showing 6 changed files with 106 additions and 6 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ C++17
+ ✅ Special operator `IF`
+ macro `DO`

- Tail Call Optimization (TCO). 実装したがテスト未了
- Tail Call Optimization (TCO). トランポリン trampoline で相互再帰もOK.

- Files

Expand Down
6 changes: 3 additions & 3 deletions environment.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -101,9 +101,9 @@ FuncPtr Environment::find_function(const UnicodeString& symbol)
void Environment::set_value(const UnicodeString& symbol, const value_t& value,
bool constant)
{
std::cout << __func__ << " at " << __LINE__ << ": ";
std::cout << symbol << " = " ;
PRINT(value, std::cout); std::cout << "\n"; // DEBUG
//std::cout << __func__ << " at " << __LINE__ << ": ";
//std::cout << symbol << " = " ;
//PRINT(value, std::cout); std::cout << "\n"; // DEBUG

// insert() は更新しない!
m_values[symbol] = BoundValue { .val = value, .constant = constant};
Expand Down
2 changes: 1 addition & 1 deletion my_debug.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@

// 不要のときはコメントアウト
//#define DEBUG_OBJECT_LIFETIMES 1
#define DEBUG_ENV_LIFETIMES 1
//#define DEBUG_ENV_LIFETIMES 1
#define DEBUG_TRACE_FILE stderr


Expand Down
5 changes: 4 additions & 1 deletion test/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
.PHONY: all clean

TARGETS = ref_counted_test reader_test edit_line_test environment_test \
macro_test evaluation_test block_test
macro_test evaluation_test block_test tco_test

all: $(TARGETS)

Expand Down Expand Up @@ -49,6 +49,9 @@ macro_test: macro_test.o ../macros.o ../environment.o ../object_print.o ../reade
evaluation_test: evaluation_test.o ../evaluation.o ../environment.o ../object_print.o ../reader.o ../macros.o ../builtin-functions.o
$(CXX) $^ $(LDFLAGS) $(LDLIBS) -lstdc++ -licuuc -licuio -ledit -o $@

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

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

Expand Down
27 changes: 27 additions & 0 deletions test/tco.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@

#include <iostream>
using namespace std;

// -S オプションでアセンブラ出力

bool isodd(int n) ;

// 偶数のとき true
bool iseven(int n) {
return n > 0 ? isodd(n - 1) : true;
}

// 奇数のとき true
bool isodd(int n) {
return n > 0 ? iseven(n - 1) : false;
}

int main()
{
// オプションなし = segfault, -O3 => 結果 1 OK
cout << "iseven(1'000'000) = " << iseven(1'000'000) << "\n";

// ちょっとだけ間があく = 計算したうえで, 結果 1 OK
cout << "isodd(2'000'000'001) = " << isodd(2'000'000'001) << "\n";
return 0;
}
70 changes: 70 additions & 0 deletions test/tco_test.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@

#include "../environment.h"
#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


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))";
my::value_t astv = my::read_from_string(ast);
my::EVAL1(astv, env);

// 奇数 = true
ast = "(defun isodd (n) (if (> n 0) (iseven (1- n)) nil))";
astv = my::read_from_string(ast);
my::EVAL1(astv, env);

ast = "(print (iseven 10))";
astv = my::read_from_string(ast);
my::EVAL1(astv, env); //=> T

ast = "(print (isodd 10))";
astv = my::read_from_string(ast);
my::EVAL1(astv, env); //=> NIL

ast = "(print (iseven 9))";
astv = my::read_from_string(ast);
my::EVAL1(astv, env); //=> NIL

ast = "(print (isodd 9))";
astv = my::read_from_string(ast);
my::EVAL1(astv, env); //=> T

astv = my::read_from_string("(print (iseven 1000000))");
my::EVAL1(astv, env); //=> T

return 0;
}

0 comments on commit e721cda

Please sign in to comment.