mirror of
https://github.com/usatiuk/psil.git
synced 2025-10-28 18:57:48 +01:00
init
This commit is contained in:
77
.gitignore
vendored
Normal file
77
.gitignore
vendored
Normal file
@@ -0,0 +1,77 @@
|
|||||||
|
# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio, WebStorm and Rider
|
||||||
|
# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839
|
||||||
|
|
||||||
|
# User-specific stuff
|
||||||
|
.idea/**/workspace.xml
|
||||||
|
.idea/**/tasks.xml
|
||||||
|
.idea/**/usage.statistics.xml
|
||||||
|
.idea/**/dictionaries
|
||||||
|
.idea/**/shelf
|
||||||
|
|
||||||
|
# AWS User-specific
|
||||||
|
.idea/**/aws.xml
|
||||||
|
|
||||||
|
# Generated files
|
||||||
|
.idea/**/contentModel.xml
|
||||||
|
|
||||||
|
# Sensitive or high-churn files
|
||||||
|
.idea/**/dataSources/
|
||||||
|
.idea/**/dataSources.ids
|
||||||
|
.idea/**/dataSources.local.xml
|
||||||
|
.idea/**/sqlDataSources.xml
|
||||||
|
.idea/**/dynamic.xml
|
||||||
|
.idea/**/uiDesigner.xml
|
||||||
|
.idea/**/dbnavigator.xml
|
||||||
|
|
||||||
|
# Gradle
|
||||||
|
.idea/**/gradle.xml
|
||||||
|
.idea/**/libraries
|
||||||
|
|
||||||
|
# Gradle and Maven with auto-import
|
||||||
|
# When using Gradle or Maven with auto-import, you should exclude module files,
|
||||||
|
# since they will be recreated, and may cause churn. Uncomment if using
|
||||||
|
# auto-import.
|
||||||
|
# .idea/artifacts
|
||||||
|
# .idea/compiler.xml
|
||||||
|
# .idea/jarRepositories.xml
|
||||||
|
# .idea/modules.xml
|
||||||
|
# .idea/*.iml
|
||||||
|
# .idea/modules
|
||||||
|
# *.iml
|
||||||
|
# *.ipr
|
||||||
|
|
||||||
|
# CMake
|
||||||
|
cmake-build-*/
|
||||||
|
|
||||||
|
# Mongo Explorer plugin
|
||||||
|
.idea/**/mongoSettings.xml
|
||||||
|
|
||||||
|
# File-based project format
|
||||||
|
*.iws
|
||||||
|
|
||||||
|
# IntelliJ
|
||||||
|
out/
|
||||||
|
|
||||||
|
# mpeltonen/sbt-idea plugin
|
||||||
|
.idea_modules/
|
||||||
|
|
||||||
|
# JIRA plugin
|
||||||
|
atlassian-ide-plugin.xml
|
||||||
|
|
||||||
|
# Cursive Clojure plugin
|
||||||
|
.idea/replstate.xml
|
||||||
|
|
||||||
|
# SonarLint plugin
|
||||||
|
.idea/sonarlint/
|
||||||
|
|
||||||
|
# Crashlytics plugin (for Android Studio and IntelliJ)
|
||||||
|
com_crashlytics_export_strings.xml
|
||||||
|
crashlytics.properties
|
||||||
|
crashlytics-build.properties
|
||||||
|
fabric.properties
|
||||||
|
|
||||||
|
# Editor-based Rest Client
|
||||||
|
.idea/httpRequests
|
||||||
|
|
||||||
|
# Android studio 3.1+ serialized cache file
|
||||||
|
.idea/caches/build_file_checksums.ser
|
||||||
8
.idea/.gitignore
generated
vendored
Normal file
8
.idea/.gitignore
generated
vendored
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
# Default ignored files
|
||||||
|
/shelf/
|
||||||
|
/workspace.xml
|
||||||
|
# Editor-based HTTP Client requests
|
||||||
|
/httpRequests/
|
||||||
|
# Datasource local storage ignored files
|
||||||
|
/dataSources/
|
||||||
|
/dataSources.local.xml
|
||||||
8
.idea/cmake.xml
generated
Normal file
8
.idea/cmake.xml
generated
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="CMakeSharedSettings">
|
||||||
|
<configurations>
|
||||||
|
<configuration PROFILE_NAME="Debug" ENABLED="true" CONFIG_NAME="Debug" GENERATION_OPTIONS="-DSANITIZE=YES" />
|
||||||
|
</configurations>
|
||||||
|
</component>
|
||||||
|
</project>
|
||||||
4
.idea/misc.xml
generated
Normal file
4
.idea/misc.xml
generated
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="CMakeWorkspace" PROJECT_DIR="$PROJECT_DIR$" />
|
||||||
|
</project>
|
||||||
8
.idea/modules.xml
generated
Normal file
8
.idea/modules.xml
generated
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="ProjectModuleManager">
|
||||||
|
<modules>
|
||||||
|
<module fileurl="file://$PROJECT_DIR$/.idea/psil.iml" filepath="$PROJECT_DIR$/.idea/psil.iml" />
|
||||||
|
</modules>
|
||||||
|
</component>
|
||||||
|
</project>
|
||||||
2
.idea/psil.iml
generated
Normal file
2
.idea/psil.iml
generated
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<module classpath="CMake" type="CPP_MODULE" version="4" />
|
||||||
27
CMakeLists.txt
Normal file
27
CMakeLists.txt
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
cmake_minimum_required(VERSION 3.27)
|
||||||
|
project(psil)
|
||||||
|
|
||||||
|
if (SANITIZE STREQUAL "YES")
|
||||||
|
message(WARNING "Enabling sanitizers!")
|
||||||
|
add_compile_options(-Wall -Wextra -pedantic -Wshadow -Wformat=2 -Wfloat-equal -D_GLIBCXX_DEBUG -Wconversion -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=2)
|
||||||
|
add_compile_options(-fsanitize=address -fsanitize=undefined -fno-sanitize-recover)
|
||||||
|
add_link_options(-fsanitize=address -fsanitize=undefined -fno-sanitize-recover)
|
||||||
|
endif ()
|
||||||
|
|
||||||
|
if (CMAKE_BUILD_TYPE STREQUAL "Release")
|
||||||
|
add_compile_options(-flto)
|
||||||
|
add_link_options(-flto)
|
||||||
|
endif ()
|
||||||
|
|
||||||
|
if (NOT CMAKE_BUILD_TYPE STREQUAL "Debug")
|
||||||
|
add_compile_options(-O3)
|
||||||
|
add_link_options(-O3)
|
||||||
|
endif ()
|
||||||
|
|
||||||
|
set(CMAKE_CXX_STANDARD 20)
|
||||||
|
|
||||||
|
add_subdirectory(src)
|
||||||
|
|
||||||
|
enable_testing()
|
||||||
|
|
||||||
|
add_subdirectory(test)
|
||||||
8
src/CMakeLists.txt
Normal file
8
src/CMakeLists.txt
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
set(CMAKE_CXX_STANDARD 20)
|
||||||
|
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
||||||
|
|
||||||
|
add_subdirectory(vm)
|
||||||
|
|
||||||
|
add_executable(psil main.cpp)
|
||||||
|
|
||||||
|
target_link_libraries(psil PRIVATE vm)
|
||||||
6
src/main.cpp
Normal file
6
src/main.cpp
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
#include <iostream>
|
||||||
|
#include "vm/includes/VM.h"
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
3
src/vm/CMakeLists.txt
Normal file
3
src/vm/CMakeLists.txt
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
add_library(vm src/VM.cpp src/Cell.cpp)
|
||||||
|
|
||||||
|
target_include_directories(vm PUBLIC includes)
|
||||||
74
src/vm/includes/Cell.h
Normal file
74
src/vm/includes/Cell.h
Normal file
@@ -0,0 +1,74 @@
|
|||||||
|
//
|
||||||
|
// Created by Stepan Usatiuk on 22.12.2023.
|
||||||
|
//
|
||||||
|
|
||||||
|
#ifndef PSIL_CELL_H
|
||||||
|
#define PSIL_CELL_H
|
||||||
|
|
||||||
|
#include <cstdint>
|
||||||
|
#include <cassert>
|
||||||
|
|
||||||
|
enum class CellType {
|
||||||
|
INT,
|
||||||
|
CONS
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Cell {
|
||||||
|
explicit Cell(CellType type) : _type(type) {}
|
||||||
|
|
||||||
|
virtual ~Cell() = 0;
|
||||||
|
|
||||||
|
CellType _type;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct IntCell : public Cell {
|
||||||
|
IntCell() : Cell(CellType::INT) {}
|
||||||
|
|
||||||
|
IntCell(int64_t val) : Cell(CellType::INT), _val(val) {}
|
||||||
|
|
||||||
|
int64_t _val{};
|
||||||
|
};
|
||||||
|
|
||||||
|
struct CommandCell : public IntCell {
|
||||||
|
enum class CommandNum {
|
||||||
|
NIL = 1,
|
||||||
|
LDC = 2,
|
||||||
|
LD = 3,
|
||||||
|
SEL = 4,
|
||||||
|
JOIN = 5,
|
||||||
|
LDF = 6,
|
||||||
|
AP = 7,
|
||||||
|
RET = 8,
|
||||||
|
DUM = 9,
|
||||||
|
RAP = 10,
|
||||||
|
STOP = 11,
|
||||||
|
|
||||||
|
ADD = 100,
|
||||||
|
SUB = 101,
|
||||||
|
|
||||||
|
READCHAR = 201,
|
||||||
|
PUTCHAR = 202,
|
||||||
|
END = 1000
|
||||||
|
};
|
||||||
|
|
||||||
|
CommandCell(CommandNum cmd) : IntCell(static_cast<int64_t>(cmd)) {}
|
||||||
|
|
||||||
|
CommandNum intToCmd() {
|
||||||
|
assert((_val > 0 && static_cast<CommandNum>(_val) <= CommandNum::END));
|
||||||
|
return static_cast<CommandNum>(_val);
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
struct ConsCell : public Cell {
|
||||||
|
ConsCell() : Cell(CellType::CONS) {}
|
||||||
|
|
||||||
|
ConsCell(Cell *car) : Cell(CellType::CONS), _car(car) {}
|
||||||
|
|
||||||
|
ConsCell(Cell *car, Cell *cdr) : Cell(CellType::CONS), _car(car), _cdr(cdr) {}
|
||||||
|
|
||||||
|
Cell *_car = nullptr;
|
||||||
|
Cell *_cdr = nullptr;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif //PSIL_CELL_H
|
||||||
73
src/vm/includes/VM.h
Normal file
73
src/vm/includes/VM.h
Normal file
@@ -0,0 +1,73 @@
|
|||||||
|
//
|
||||||
|
// Created by Stepan Usatiuk on 22.12.2023.
|
||||||
|
//
|
||||||
|
|
||||||
|
#ifndef PSIL_VM_H
|
||||||
|
#define PSIL_VM_H
|
||||||
|
|
||||||
|
#include <vector>
|
||||||
|
#include<utility>
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
#include "Cell.h"
|
||||||
|
|
||||||
|
class VM {
|
||||||
|
public:
|
||||||
|
VM(std::istream &instream = std::cin, std::ostream &outstream = std::cout);
|
||||||
|
|
||||||
|
void run();
|
||||||
|
|
||||||
|
void step();
|
||||||
|
|
||||||
|
// template<typename T>
|
||||||
|
// void appendCommand(T cell) {
|
||||||
|
// push(_c, makeCell<T>(std::move(cell)));
|
||||||
|
// }
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
void appendCommand(T *cell) {
|
||||||
|
push(_c, cell);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename CT, typename... Args>
|
||||||
|
CT *makeCell(Args... args) {
|
||||||
|
return static_cast<CT *>(_cells.emplace_back(new CT(std::forward<Args>(args)...)));
|
||||||
|
}
|
||||||
|
|
||||||
|
Cell *car(ConsCell *cell) {
|
||||||
|
return cell->_car;
|
||||||
|
}
|
||||||
|
|
||||||
|
Cell *cdr(ConsCell *cell) {
|
||||||
|
return cell->_cdr;
|
||||||
|
}
|
||||||
|
|
||||||
|
ConsCell *cons(Cell *car, Cell *cdr) {
|
||||||
|
return dynamic_cast<ConsCell *>(makeCell<ConsCell>(car, cdr));
|
||||||
|
}
|
||||||
|
|
||||||
|
Cell *pop(ConsCell *&what) {
|
||||||
|
Cell *ret = what->_car;
|
||||||
|
what = dynamic_cast<ConsCell *>(cdr(what));
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
Cell *push(ConsCell *&what, Cell *toAppend) {
|
||||||
|
what = cons(toAppend, what);
|
||||||
|
return what;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::vector<Cell *> _cells;
|
||||||
|
ConsCell *_s = nullptr;
|
||||||
|
ConsCell *_e = nullptr;
|
||||||
|
ConsCell *_c = nullptr;
|
||||||
|
ConsCell *_d = nullptr;
|
||||||
|
bool _stop = false;
|
||||||
|
|
||||||
|
std::istream &_instream;
|
||||||
|
std::ostream &_outstream;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#endif //PSIL_VM_H
|
||||||
7
src/vm/src/Cell.cpp
Normal file
7
src/vm/src/Cell.cpp
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
//
|
||||||
|
// Created by Stepan Usatiuk on 22.12.2023.
|
||||||
|
//
|
||||||
|
|
||||||
|
#include "../includes/Cell.h"
|
||||||
|
|
||||||
|
Cell::~Cell() = default;
|
||||||
101
src/vm/src/VM.cpp
Normal file
101
src/vm/src/VM.cpp
Normal file
@@ -0,0 +1,101 @@
|
|||||||
|
//
|
||||||
|
// Created by Stepan Usatiuk on 22.12.2023.
|
||||||
|
//
|
||||||
|
|
||||||
|
#include "../includes/VM.h"
|
||||||
|
|
||||||
|
#include <utility>
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
void VM::run() {
|
||||||
|
while (!_stop) step();
|
||||||
|
}
|
||||||
|
|
||||||
|
void VM::step() {
|
||||||
|
CommandCell *popped = dynamic_cast<CommandCell *>(pop(_c));
|
||||||
|
|
||||||
|
switch (popped->intToCmd()) {
|
||||||
|
case CommandCell::CommandNum::NIL: {
|
||||||
|
push(_s, nullptr);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case CommandCell::CommandNum::LDC: {
|
||||||
|
IntCell *popped2 = dynamic_cast<IntCell *>(pop(_c));
|
||||||
|
push(_s, popped2);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case CommandCell::CommandNum::LD: {
|
||||||
|
ConsCell *popped2 = dynamic_cast<ConsCell *>(pop(_c));
|
||||||
|
|
||||||
|
int64_t frame = dynamic_cast<IntCell *>(popped2->_car)->_val;
|
||||||
|
int64_t arg = dynamic_cast<IntCell *>(popped2->_cdr)->_val;
|
||||||
|
// todo
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case CommandCell::CommandNum::SEL: {
|
||||||
|
IntCell *popped2 = dynamic_cast<IntCell *>(pop(_s));
|
||||||
|
ConsCell *ct = dynamic_cast<ConsCell *>(pop(_c));
|
||||||
|
ConsCell *cf = dynamic_cast<ConsCell *>(pop(_c));
|
||||||
|
ConsCell *ret = _c;
|
||||||
|
push(_d, ret);
|
||||||
|
if (popped2->_val > 0) {
|
||||||
|
_c = ct;
|
||||||
|
} else {
|
||||||
|
_c = cf;
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case CommandCell::CommandNum::JOIN: {
|
||||||
|
ConsCell *ret = dynamic_cast<ConsCell *>(pop(_d));
|
||||||
|
_c = ret;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case CommandCell::CommandNum::LDF: {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case CommandCell::CommandNum::AP: {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case CommandCell::CommandNum::RET: {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case CommandCell::CommandNum::DUM: {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case CommandCell::CommandNum::RAP: {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case CommandCell::CommandNum::STOP: {
|
||||||
|
_stop = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case CommandCell::CommandNum::ADD: {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case CommandCell::CommandNum::SUB: {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case CommandCell::CommandNum::END: {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case CommandCell::CommandNum::READCHAR:
|
||||||
|
char c;
|
||||||
|
_instream >> c;
|
||||||
|
push(_s, makeCell<IntCell>(c));
|
||||||
|
break;
|
||||||
|
case CommandCell::CommandNum::PUTCHAR:
|
||||||
|
IntCell *popped2 = dynamic_cast<IntCell *>(pop(_s));
|
||||||
|
_outstream << (char) popped2->_val;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
VM::VM(std::istream &instream, std::ostream &outstream) : _instream(instream), _outstream(outstream) {
|
||||||
|
_s = dynamic_cast<ConsCell *>(makeCell<ConsCell>(nullptr));
|
||||||
|
_e = dynamic_cast<ConsCell *>(makeCell<ConsCell>(nullptr));
|
||||||
|
_c = dynamic_cast<ConsCell *>(makeCell<ConsCell>(nullptr));
|
||||||
|
_d = dynamic_cast<ConsCell *>(makeCell<ConsCell>(nullptr));
|
||||||
|
}
|
||||||
13
test/CMakeLists.txt
Normal file
13
test/CMakeLists.txt
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
set(CMAKE_CXX_STANDARD 20)
|
||||||
|
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
||||||
|
|
||||||
|
include(FetchContent)
|
||||||
|
FetchContent_Declare(
|
||||||
|
googletest
|
||||||
|
URL https://github.com/google/googletest/archive/03597a01ee50ed33e9dfd640b249b4be3799d395.zip
|
||||||
|
)
|
||||||
|
# For Windows: Prevent overriding the parent project's compiler/linker settings
|
||||||
|
set(gtest_force_shared_crt ON CACHE BOOL "" FORCE)
|
||||||
|
FetchContent_MakeAvailable(googletest)
|
||||||
|
|
||||||
|
add_subdirectory(vm)
|
||||||
12
test/vm/CMakeLists.txt
Normal file
12
test/vm/CMakeLists.txt
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
add_executable(
|
||||||
|
VMTest
|
||||||
|
VMTest.cpp
|
||||||
|
)
|
||||||
|
target_link_libraries(
|
||||||
|
VMTest
|
||||||
|
vm
|
||||||
|
GTest::gtest_main
|
||||||
|
)
|
||||||
|
|
||||||
|
include(GoogleTest)
|
||||||
|
gtest_discover_tests(VMTest)
|
||||||
66
test/vm/VMTest.cpp
Normal file
66
test/vm/VMTest.cpp
Normal file
@@ -0,0 +1,66 @@
|
|||||||
|
#include <gtest/gtest.h>
|
||||||
|
|
||||||
|
#include "VM.h"
|
||||||
|
|
||||||
|
TEST(VMTest, BasicHello) {
|
||||||
|
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<IntCell>('h'));
|
||||||
|
vm.appendCommand(vm.makeCell<CommandCell>(CommandCell::CommandNum::LDC));
|
||||||
|
vm.appendCommand(vm.makeCell<CommandCell>(CommandCell::CommandNum::NIL));
|
||||||
|
vm.run();
|
||||||
|
}
|
||||||
|
ssout.flush();
|
||||||
|
EXPECT_EQ(ssout.str(), "h");
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(VMTest, SelTest) {
|
||||||
|
std::stringstream ssin;
|
||||||
|
std::stringstream ssout;
|
||||||
|
{
|
||||||
|
VM vm(ssin, ssout);
|
||||||
|
vm.appendCommand(vm.makeCell<CommandCell>(CommandCell::CommandNum::STOP));
|
||||||
|
|
||||||
|
// True branch true test
|
||||||
|
ConsCell *tbtt = vm.makeCell<ConsCell>(vm.makeCell<CommandCell>(CommandCell::CommandNum::JOIN));
|
||||||
|
vm.push(tbtt, vm.makeCell<CommandCell>(CommandCell::CommandNum::PUTCHAR));
|
||||||
|
vm.push(tbtt, vm.makeCell<IntCell>('1'));
|
||||||
|
vm.push(tbtt, vm.makeCell<CommandCell>(CommandCell::CommandNum::LDC));
|
||||||
|
|
||||||
|
// False branch true test
|
||||||
|
ConsCell *fbtt = vm.makeCell<ConsCell>(vm.makeCell<CommandCell>(CommandCell::CommandNum::JOIN));
|
||||||
|
vm.push(fbtt, vm.makeCell<CommandCell>(CommandCell::CommandNum::PUTCHAR));
|
||||||
|
vm.push(fbtt, vm.makeCell<IntCell>('2'));
|
||||||
|
vm.push(fbtt, vm.makeCell<CommandCell>(CommandCell::CommandNum::LDC));
|
||||||
|
|
||||||
|
// True branch false test
|
||||||
|
ConsCell *tbft = vm.makeCell<ConsCell>(vm.makeCell<CommandCell>(CommandCell::CommandNum::JOIN));
|
||||||
|
vm.push(tbft, vm.makeCell<CommandCell>(CommandCell::CommandNum::PUTCHAR));
|
||||||
|
vm.push(tbft, vm.makeCell<IntCell>('3'));
|
||||||
|
vm.push(tbft, vm.makeCell<CommandCell>(CommandCell::CommandNum::LDC));
|
||||||
|
|
||||||
|
// False branch false test
|
||||||
|
ConsCell *fbft = vm.makeCell<ConsCell>(vm.makeCell<CommandCell>(CommandCell::CommandNum::JOIN));
|
||||||
|
vm.push(fbft, vm.makeCell<CommandCell>(CommandCell::CommandNum::PUTCHAR));
|
||||||
|
vm.push(fbft, vm.makeCell<IntCell>('4'));
|
||||||
|
vm.push(fbft, vm.makeCell<CommandCell>(CommandCell::CommandNum::LDC));
|
||||||
|
|
||||||
|
vm.appendCommand(fbft);
|
||||||
|
vm.appendCommand(tbft);
|
||||||
|
vm.appendCommand(vm.makeCell<CommandCell>(CommandCell::CommandNum::SEL));
|
||||||
|
vm.appendCommand(vm.makeCell<IntCell>(0));
|
||||||
|
vm.appendCommand(vm.makeCell<CommandCell>(CommandCell::CommandNum::LDC));
|
||||||
|
vm.appendCommand(fbtt);
|
||||||
|
vm.appendCommand(tbtt);
|
||||||
|
vm.appendCommand(vm.makeCell<CommandCell>(CommandCell::CommandNum::SEL));
|
||||||
|
vm.appendCommand(vm.makeCell<IntCell>(1));
|
||||||
|
vm.appendCommand(vm.makeCell<CommandCell>(CommandCell::CommandNum::LDC));
|
||||||
|
vm.run();
|
||||||
|
}
|
||||||
|
ssout.flush();
|
||||||
|
EXPECT_EQ(ssout.str(), "14");
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user