mirror of
https://github.com/usatiuk/psil.git
synced 2025-10-28 10:47:49 +01:00
Globals!
This commit is contained in:
@@ -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();
|
||||
|
||||
@@ -36,6 +36,7 @@ namespace Command {
|
||||
READ = 20,
|
||||
|
||||
CONS = 21,
|
||||
LDG = 22,
|
||||
};
|
||||
|
||||
static inline std::unordered_map<std::string_view, CellValType> str_to_cmd{
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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));
|
||||
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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");
|
||||
}
|
||||
Reference in New Issue
Block a user