This commit is contained in:
2024-01-03 16:27:50 +01:00
parent d7805aa7e7
commit 7ae83db728
6 changed files with 84 additions and 15 deletions

View File

@@ -14,7 +14,7 @@
class Logger {
public:
enum LogLevel { DISABLED = 0, ERROR = 1, INFO = 2, DEBUG = 3, TRACE = 4 };
enum LogLevel { ALWAYS = 0, ERROR = 1, INFO = 2, DEBUG = 3, TRACE = 4 };
static void log(const std::string &tag, const std::string &what, int level);
static void log(const std::string &tag, const std::function<void(std::ostream &)> &fn, int level);
@@ -34,10 +34,7 @@ private:
std::unordered_map<std::string, int> _levels;
static inline std::unordered_map<int, std::string> _level_names{
{ERROR, "ERROR"},
{INFO, "INFO"},
{DEBUG, "DEBUG"},
{TRACE, "TRACE"},
{ALWAYS, "ALWAYS"}, {ERROR, "ERROR"}, {INFO, "INFO"}, {DEBUG, "DEBUG"}, {TRACE, "TRACE"},
};
int _default_level = 1;
std::chrono::time_point<std::chrono::high_resolution_clock> _start_time = std::chrono::high_resolution_clock::now();

View File

@@ -36,6 +36,7 @@ namespace Command {
READ = 20,
CONS = 21,
LDG = 22,
};
static inline std::unordered_map<std::string_view, CellValType> str_to_cmd{

View File

@@ -27,8 +27,10 @@ public:
void step();
private:
Handle _globals_names = Handle::cons(Handle::cons(nullptr, nullptr), nullptr);
Handle _globals_vals = Handle::cons(nullptr, nullptr);
Handle _s = Handle::cons(nullptr, nullptr);
Handle _e = Handle::cons(nullptr, nullptr);
Handle _e = Handle::cons(_globals_vals, nullptr);
Handle _c = Handle::cons(nullptr, nullptr);
Handle _d = Handle::cons(nullptr, nullptr);
bool _stop = false;

View File

@@ -69,6 +69,10 @@ Handle Compiler::compile(Handle src, Handle fake_env, Handle suffix) {
out.append(Handle(SEL));
out.append(compile(cdr.cdr().car(), fake_env, Handle(JOIN)));
out.append(compile(cdr.cdr().cdr().car(), fake_env, Handle(JOIN)));
} else if (car.strval() == "define") {
fake_env.car().append(Handle(std::string(cdr.car().car().strval())));
out.append(Handle(LDG));
out.append(compile(cdr.cdr().car(), Handle::cons(cdr.car().cdr(), fake_env), Handle(RET)));
} else if (car.strval() == "let" || car.strval() == "letrec") {
std::vector<std::pair<Handle, Handle>> argBody;
@@ -87,17 +91,18 @@ Handle Compiler::compile(Handle src, Handle fake_env, Handle suffix) {
}
Handle newenv = Handle::cons(argNames, fake_env);
if (car.strval() == "let") out.splice(compileArgsList(argBodies, fake_env));
else if (car.strval() == "letrec") {
if (car.strval() == "let") {
out.splice(compileArgsList(argBodies, fake_env));
out.append(Handle(LDF));
out.append(compile(body, newenv, Handle(RET)));
out.append(Handle(AP));
} else if (car.strval() == "letrec") {
out.append(Handle(DUM));
out.splice(compileArgsList(argBodies, newenv));
}
out.append(Handle(LDF));
out.append(compile(body, newenv, Handle(RET)));
if (car.strval() == "let") out.append(Handle(AP));
else
out.append(Handle(LDF));
out.append(compile(body, newenv, Handle(RET)));
out.append(Handle(RAP));
}
} else {
out.splice(compileArgsList(cdr, fake_env));

View File

@@ -129,7 +129,7 @@ void VM::step() {
_outstream << _s.pop().val();
} else if (poppedCmd == EVAL) {
Handle code = _s.pop();
Handle newc = Compiler::compile(code, nullptr);
Handle newc = Compiler::compile(code, _globals_names);
Logger::log(
"Compiler",
[&](std::ostream &out) {
@@ -140,6 +140,8 @@ void VM::step() {
Logger::DEBUG);
newc.splice(_c);
_c = newc;
} else if (poppedCmd == LDG) {
_globals_vals.append(Handle::cons(_c.pop(), _e));
} else if (poppedCmd == PRINT) {
_outstream << _s.pop();
} else if (poppedCmd == READ) {

View File

@@ -94,4 +94,66 @@ TEST(CompilerTest, RecursiveFn) {
}
ssout.flush();
EXPECT_EQ(ssout.str(), "55");
}
TEST(CompilerTest, GlobalDefine) {
std::stringstream ssin;
std::stringstream ssout;
{
VM vm(ssin, ssout);
Parser parser;
parser.loadStr("(LDC (define (one) 1) EVAL LDC (one) EVAL PRINT STOP)");
vm.loadControl(parser.parseExpr());
vm.run();
}
ssout.flush();
EXPECT_EQ(ssout.str(), "1");
}
TEST(CompilerTest, GlobalDefineFn) {
std::stringstream ssin;
std::stringstream ssout;
{
VM vm(ssin, ssout);
Parser parser;
parser.loadStr("(LDC (define (one x y) (+ x y)) EVAL LDC (one 2 3) EVAL PRINT STOP)");
vm.loadControl(parser.parseExpr());
vm.run();
}
ssout.flush();
EXPECT_EQ(ssout.str(), "5");
}
TEST(CompilerTest, GlobalDefineFnMulti) {
std::stringstream ssin;
std::stringstream ssout;
{
VM vm(ssin, ssout);
Parser parser;
parser.loadStr("(LDC (define (one x y) (+ x y)) EVAL LDC (define (two x y) (one (+ x 1) y)) EVAL LDC (two 2 3) EVAL PRINT STOP)");
vm.loadControl(parser.parseExpr());
vm.run();
}
ssout.flush();
EXPECT_EQ(ssout.str(), "6");
}
TEST(CompilerTest, GlobalDefineFnRec) {
std::stringstream ssin;
std::stringstream ssout;
{
VM vm(ssin, ssout);
Parser parser;
parser.loadStr(
"(LDC (define (fib n) (if n (if (+ n -1) (+ (fib (+ n -1)) (fib(+ n -2))) 1) 0) ) EVAL LDC (fib 10) EVAL PRINT STOP)");
vm.loadControl(parser.parseExpr());
vm.run();
}
ssout.flush();
EXPECT_EQ(ssout.str(), "55");
}