mirror of
https://github.com/usatiuk/psil.git
synced 2025-10-28 18:57:48 +01:00
hopefully correct rap
This commit is contained in:
@@ -92,4 +92,150 @@ TEST(VMTest, SimpleFunction) {
|
||||
ssout.flush();
|
||||
EXPECT_EQ(ssout.str(), "3");
|
||||
|
||||
}
|
||||
|
||||
TEST(VMTest, RecursiveFunction) {
|
||||
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::RAP));
|
||||
|
||||
// Fib function
|
||||
ConsCell *fibfn = vm.makeCell<ConsCell>(vm.makeCell<CommandCell>(CommandCell::CommandNum::RET));
|
||||
|
||||
// 0 case
|
||||
ConsCell *zcase = vm.makeCell<ConsCell>(vm.makeCell<CommandCell>(CommandCell::CommandNum::JOIN));
|
||||
vm.push(zcase, vm.makeCell<IntCell>(0));
|
||||
vm.push(zcase, vm.makeCell<CommandCell>(CommandCell::CommandNum::LDC));
|
||||
|
||||
// 1 case
|
||||
ConsCell *ocase = vm.makeCell<ConsCell>(vm.makeCell<CommandCell>(CommandCell::CommandNum::JOIN));
|
||||
vm.push(ocase, vm.makeCell<IntCell>(1));
|
||||
vm.push(ocase, vm.makeCell<CommandCell>(CommandCell::CommandNum::LDC));
|
||||
|
||||
// >1 case
|
||||
ConsCell *gocase = vm.makeCell<ConsCell>(vm.makeCell<CommandCell>(CommandCell::CommandNum::JOIN));
|
||||
vm.push(gocase, vm.makeCell<CommandCell>(CommandCell::CommandNum::ADD));
|
||||
|
||||
vm.push(gocase, vm.makeCell<CommandCell>(CommandCell::CommandNum::AP));
|
||||
vm.push(gocase, vm.makeCell<ConsCell>(vm.makeCell<IntCell>(2), vm.makeCell<IntCell>(1)));
|
||||
vm.push(gocase, vm.makeCell<CommandCell>(CommandCell::CommandNum::LD));
|
||||
|
||||
vm.push(gocase, vm.makeCell<CommandCell>(CommandCell::CommandNum::CONS));
|
||||
vm.push(gocase, vm.makeCell<CommandCell>(CommandCell::CommandNum::ADD));
|
||||
vm.push(gocase, vm.makeCell<IntCell>(-2));
|
||||
vm.push(gocase, vm.makeCell<CommandCell>(CommandCell::CommandNum::LDC));
|
||||
vm.push(gocase, vm.makeCell<ConsCell>(vm.makeCell<IntCell>(1), vm.makeCell<IntCell>(1)));
|
||||
vm.push(gocase, vm.makeCell<CommandCell>(CommandCell::CommandNum::LD));
|
||||
vm.push(gocase, vm.makeCell<CommandCell>(CommandCell::CommandNum::NIL));
|
||||
|
||||
vm.push(gocase, vm.makeCell<CommandCell>(CommandCell::CommandNum::AP));
|
||||
vm.push(gocase, vm.makeCell<ConsCell>(vm.makeCell<IntCell>(2), vm.makeCell<IntCell>(1)));
|
||||
vm.push(gocase, vm.makeCell<CommandCell>(CommandCell::CommandNum::LD));
|
||||
|
||||
vm.push(gocase, vm.makeCell<CommandCell>(CommandCell::CommandNum::CONS));
|
||||
vm.push(gocase, vm.makeCell<CommandCell>(CommandCell::CommandNum::ADD));
|
||||
vm.push(gocase, vm.makeCell<IntCell>(-1));
|
||||
vm.push(gocase, vm.makeCell<CommandCell>(CommandCell::CommandNum::LDC));
|
||||
vm.push(gocase, vm.makeCell<ConsCell>(vm.makeCell<IntCell>(1), vm.makeCell<IntCell>(1)));
|
||||
vm.push(gocase, vm.makeCell<CommandCell>(CommandCell::CommandNum::LD));
|
||||
vm.push(gocase, vm.makeCell<CommandCell>(CommandCell::CommandNum::NIL));
|
||||
|
||||
// >=1 case
|
||||
ConsCell *geocase = vm.makeCell<ConsCell>(vm.makeCell<CommandCell>(CommandCell::CommandNum::JOIN));
|
||||
vm.push(geocase, ocase);
|
||||
vm.push(geocase, gocase);
|
||||
vm.push(geocase, vm.makeCell<CommandCell>(CommandCell::CommandNum::SEL));
|
||||
vm.push(geocase, vm.makeCell<CommandCell>(CommandCell::CommandNum::ADD));
|
||||
vm.push(geocase, vm.makeCell<IntCell>(-1));
|
||||
vm.push(geocase, vm.makeCell<CommandCell>(CommandCell::CommandNum::LDC));
|
||||
vm.push(geocase, vm.makeCell<ConsCell>(vm.makeCell<IntCell>(1), vm.makeCell<IntCell>(1)));
|
||||
vm.push(geocase, vm.makeCell<CommandCell>(CommandCell::CommandNum::LD));
|
||||
|
||||
vm.push(fibfn, zcase);
|
||||
vm.push(fibfn, geocase);
|
||||
vm.push(fibfn, vm.makeCell<CommandCell>(CommandCell::CommandNum::SEL));
|
||||
vm.push(fibfn, vm.makeCell<ConsCell>(vm.makeCell<IntCell>(1), vm.makeCell<IntCell>(1)));
|
||||
vm.push(fibfn, vm.makeCell<CommandCell>(CommandCell::CommandNum::LD));
|
||||
|
||||
// Fib caller function
|
||||
ConsCell *fibcallfn = vm.makeCell<ConsCell>(vm.makeCell<CommandCell>(CommandCell::CommandNum::RET));
|
||||
vm.push(fibcallfn, vm.makeCell<CommandCell>(CommandCell::CommandNum::PUTNUM));
|
||||
vm.push(fibcallfn, vm.makeCell<CommandCell>(CommandCell::CommandNum::PUTCHAR));
|
||||
vm.push(fibcallfn, vm.makeCell<IntCell>(' '));
|
||||
vm.push(fibcallfn, vm.makeCell<CommandCell>(CommandCell::CommandNum::LDC));
|
||||
vm.push(fibcallfn, vm.makeCell<CommandCell>(CommandCell::CommandNum::AP));
|
||||
vm.push(fibcallfn, vm.makeCell<ConsCell>(vm.makeCell<IntCell>(1), vm.makeCell<IntCell>(1)));
|
||||
vm.push(fibcallfn, vm.makeCell<CommandCell>(CommandCell::CommandNum::LD));
|
||||
vm.push(fibcallfn, vm.makeCell<CommandCell>(CommandCell::CommandNum::CONS));
|
||||
vm.push(fibcallfn, vm.makeCell<IntCell>(20));
|
||||
vm.push(fibcallfn, vm.makeCell<CommandCell>(CommandCell::CommandNum::LDC));
|
||||
vm.push(fibcallfn, vm.makeCell<CommandCell>(CommandCell::CommandNum::NIL));
|
||||
|
||||
vm.push(fibcallfn, vm.makeCell<CommandCell>(CommandCell::CommandNum::PUTCHAR));
|
||||
vm.push(fibcallfn, vm.makeCell<CommandCell>(CommandCell::CommandNum::ADD));
|
||||
vm.push(fibcallfn, vm.makeCell<IntCell>('0'));
|
||||
vm.push(fibcallfn, vm.makeCell<CommandCell>(CommandCell::CommandNum::LDC));
|
||||
vm.push(fibcallfn, vm.makeCell<CommandCell>(CommandCell::CommandNum::AP));
|
||||
vm.push(fibcallfn, vm.makeCell<ConsCell>(vm.makeCell<IntCell>(1), vm.makeCell<IntCell>(1)));
|
||||
vm.push(fibcallfn, vm.makeCell<CommandCell>(CommandCell::CommandNum::LD));
|
||||
vm.push(fibcallfn, vm.makeCell<CommandCell>(CommandCell::CommandNum::CONS));
|
||||
vm.push(fibcallfn, vm.makeCell<IntCell>(6));
|
||||
vm.push(fibcallfn, vm.makeCell<CommandCell>(CommandCell::CommandNum::LDC));
|
||||
vm.push(fibcallfn, vm.makeCell<CommandCell>(CommandCell::CommandNum::NIL));
|
||||
|
||||
vm.push(fibcallfn, vm.makeCell<CommandCell>(CommandCell::CommandNum::PUTCHAR));
|
||||
vm.push(fibcallfn, vm.makeCell<CommandCell>(CommandCell::CommandNum::ADD));
|
||||
vm.push(fibcallfn, vm.makeCell<IntCell>('0'));
|
||||
vm.push(fibcallfn, vm.makeCell<CommandCell>(CommandCell::CommandNum::LDC));
|
||||
vm.push(fibcallfn, vm.makeCell<CommandCell>(CommandCell::CommandNum::AP));
|
||||
vm.push(fibcallfn, vm.makeCell<ConsCell>(vm.makeCell<IntCell>(1), vm.makeCell<IntCell>(1)));
|
||||
vm.push(fibcallfn, vm.makeCell<CommandCell>(CommandCell::CommandNum::LD));
|
||||
vm.push(fibcallfn, vm.makeCell<CommandCell>(CommandCell::CommandNum::CONS));
|
||||
vm.push(fibcallfn, vm.makeCell<IntCell>(5));
|
||||
vm.push(fibcallfn, vm.makeCell<CommandCell>(CommandCell::CommandNum::LDC));
|
||||
vm.push(fibcallfn, vm.makeCell<CommandCell>(CommandCell::CommandNum::NIL));
|
||||
|
||||
vm.push(fibcallfn, vm.makeCell<CommandCell>(CommandCell::CommandNum::PUTCHAR));
|
||||
vm.push(fibcallfn, vm.makeCell<CommandCell>(CommandCell::CommandNum::ADD));
|
||||
vm.push(fibcallfn, vm.makeCell<IntCell>('0'));
|
||||
vm.push(fibcallfn, vm.makeCell<CommandCell>(CommandCell::CommandNum::LDC));
|
||||
vm.push(fibcallfn, vm.makeCell<CommandCell>(CommandCell::CommandNum::AP));
|
||||
vm.push(fibcallfn, vm.makeCell<ConsCell>(vm.makeCell<IntCell>(1), vm.makeCell<IntCell>(1)));
|
||||
vm.push(fibcallfn, vm.makeCell<CommandCell>(CommandCell::CommandNum::LD));
|
||||
vm.push(fibcallfn, vm.makeCell<CommandCell>(CommandCell::CommandNum::CONS));
|
||||
vm.push(fibcallfn, vm.makeCell<IntCell>(4));
|
||||
vm.push(fibcallfn, vm.makeCell<CommandCell>(CommandCell::CommandNum::LDC));
|
||||
vm.push(fibcallfn, vm.makeCell<CommandCell>(CommandCell::CommandNum::NIL));
|
||||
|
||||
vm.push(fibcallfn, vm.makeCell<CommandCell>(CommandCell::CommandNum::PUTCHAR));
|
||||
vm.push(fibcallfn, vm.makeCell<CommandCell>(CommandCell::CommandNum::ADD));
|
||||
vm.push(fibcallfn, vm.makeCell<IntCell>('0'));
|
||||
vm.push(fibcallfn, vm.makeCell<CommandCell>(CommandCell::CommandNum::LDC));
|
||||
vm.push(fibcallfn, vm.makeCell<CommandCell>(CommandCell::CommandNum::AP));
|
||||
vm.push(fibcallfn, vm.makeCell<ConsCell>(vm.makeCell<IntCell>(1), vm.makeCell<IntCell>(1)));
|
||||
vm.push(fibcallfn, vm.makeCell<CommandCell>(CommandCell::CommandNum::LD));
|
||||
vm.push(fibcallfn, vm.makeCell<CommandCell>(CommandCell::CommandNum::CONS));
|
||||
vm.push(fibcallfn, vm.makeCell<IntCell>(3));
|
||||
vm.push(fibcallfn, vm.makeCell<CommandCell>(CommandCell::CommandNum::LDC));
|
||||
vm.push(fibcallfn, vm.makeCell<CommandCell>(CommandCell::CommandNum::NIL));
|
||||
|
||||
|
||||
vm.appendCommand(fibcallfn);
|
||||
vm.appendCommand(vm.makeCell<CommandCell>(CommandCell::CommandNum::LDF));
|
||||
|
||||
vm.appendCommand(vm.makeCell<CommandCell>(CommandCell::CommandNum::CONS));
|
||||
vm.appendCommand(fibfn);
|
||||
vm.appendCommand(vm.makeCell<CommandCell>(CommandCell::CommandNum::LDF));
|
||||
vm.appendCommand(vm.makeCell<CommandCell>(CommandCell::CommandNum::NIL));
|
||||
|
||||
vm.appendCommand(vm.makeCell<CommandCell>(CommandCell::CommandNum::DUM));
|
||||
vm.run();
|
||||
}
|
||||
ssout.flush();
|
||||
EXPECT_EQ(ssout.str(), "2358 6765");
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user