simple function

This commit is contained in:
2023-12-23 11:47:54 +01:00
parent 2685cedba4
commit 6d324954af
2 changed files with 84 additions and 8 deletions

View File

@@ -20,8 +20,7 @@ void VM::step() {
break;
}
case CommandCell::CommandNum::LDC: {
IntCell *popped2 = dynamic_cast<IntCell *>(pop(_c));
push(_s, popped2);
push(_s, pop(_c));
break;
}
case CommandCell::CommandNum::LD: {
@@ -29,7 +28,22 @@ void VM::step() {
int64_t frame = dynamic_cast<IntCell *>(popped2->_car)->_val;
int64_t arg = dynamic_cast<IntCell *>(popped2->_cdr)->_val;
// todo
assert(frame > 0);
assert(arg > 0);
ConsCell *curFrame = _e;
for (int i = 1; i < frame; i++) {
curFrame = dynamic_cast<ConsCell *>(_e->_cdr);
}
ConsCell *curArg = dynamic_cast<ConsCell *>(curFrame->_car);
for (int i = 1; i < arg; i++) {
curArg = dynamic_cast<ConsCell *>(curArg->_cdr);
}
push(_s, curArg->_car);
break;
}
@@ -53,12 +67,37 @@ void VM::step() {
break;
}
case CommandCell::CommandNum::LDF: {
ConsCell *fn = dynamic_cast<ConsCell *>(pop(_c));
push(_s, makeCell<ConsCell>(fn, _e));
break;
}
case CommandCell::CommandNum::AP: {
ConsCell *closure = dynamic_cast<ConsCell *>(pop(_s));
ConsCell *args = dynamic_cast<ConsCell *>(pop(_s));
push(_d, _s);
push(_d, _e);
push(_d, _c);
_s = makeCell<ConsCell>();
_c = dynamic_cast<ConsCell *>(closure->_car);
_e = dynamic_cast<ConsCell *>(closure->_cdr);
push(_e, args);
break;
}
case CommandCell::CommandNum::RET: {
ConsCell *c = dynamic_cast<ConsCell *>(pop(_d));
ConsCell *e = dynamic_cast<ConsCell *>(pop(_d));
ConsCell *s = dynamic_cast<ConsCell *>(pop(_d));
Cell *ret = pop(_s);
_c = c;
_e = e;
_s = s;
push(_s, ret);
break;
}
case CommandCell::CommandNum::DUM: {
@@ -72,23 +111,31 @@ void VM::step() {
break;
}
case CommandCell::CommandNum::ADD: {
IntCell *a1 = dynamic_cast<IntCell *>(pop(_s));
IntCell *a2 = dynamic_cast<IntCell *>(pop(_s));
push(_s, makeCell<IntCell>(a1->_val + a2->_val));
break;
}
case CommandCell::CommandNum::SUB: {
break;
}
case CommandCell::CommandNum::END: {
break;
}
case CommandCell::CommandNum::READCHAR:
case CommandCell::CommandNum::READCHAR: {
char c;
_instream >> c;
push(_s, makeCell<IntCell>(c));
break;
case CommandCell::CommandNum::PUTCHAR:
}
case CommandCell::CommandNum::PUTCHAR: {
IntCell *popped2 = dynamic_cast<IntCell *>(pop(_s));
_outstream << (char) popped2->_val;
break;
}
case CommandCell::CommandNum::END: {
assert(false);
break;
}
default:
assert(false);
}
}

View File

@@ -63,4 +63,33 @@ TEST(VMTest, SelTest) {
}
ssout.flush();
EXPECT_EQ(ssout.str(), "14");
}
TEST(VMTest, SimpleFunction) {
std::stringstream ssin;
std::stringstream ssout;
{
VM vm(ssin, ssout);
vm.appendCommand(vm.makeCell<CommandCell>(CommandCell::CommandNum::STOP));
vm.appendCommand(vm.makeCell<CommandCell>(CommandCell::CommandNum::PUTCHAR));
vm.appendCommand(vm.makeCell<CommandCell>(CommandCell::CommandNum::AP));
// Add function
ConsCell *addfn = vm.makeCell<ConsCell>(vm.makeCell<CommandCell>(CommandCell::CommandNum::RET));
vm.push(addfn, vm.makeCell<CommandCell>(CommandCell::CommandNum::ADD));
vm.push(addfn, vm.makeCell<ConsCell>(vm.makeCell<IntCell>(1), vm.makeCell<IntCell>(2)));
vm.push(addfn, vm.makeCell<CommandCell>(CommandCell::CommandNum::LD));
vm.push(addfn, vm.makeCell<ConsCell>(vm.makeCell<IntCell>(1), vm.makeCell<IntCell>(1)));
vm.push(addfn, vm.makeCell<CommandCell>(CommandCell::CommandNum::LD));
vm.appendCommand(addfn);
vm.appendCommand(vm.makeCell<CommandCell>(CommandCell::CommandNum::LDF));
vm.appendCommand(
vm.makeCell<ConsCell>(vm.makeCell<IntCell>(1), vm.makeCell<ConsCell>(vm.makeCell<IntCell>('2'))));
vm.appendCommand(vm.makeCell<CommandCell>(CommandCell::CommandNum::LDC));
vm.run();
}
ssout.flush();
EXPECT_EQ(ssout.str(), "3");
}