diff --git a/.clang-format b/.clang-format new file mode 100644 index 0000000..f170fa6 --- /dev/null +++ b/.clang-format @@ -0,0 +1,66 @@ +# Generated from CLion C/C++ Code Style settings +BasedOnStyle: LLVM +AccessModifierOffset: -4 +AlignAfterOpenBracket: Align +AlignConsecutiveAssignments: None +AlignOperands: Align +AllowAllArgumentsOnNextLine: false +AllowAllConstructorInitializersOnNextLine: false +AllowAllParametersOfDeclarationOnNextLine: false +AllowShortBlocksOnASingleLine: Always +AllowShortCaseLabelsOnASingleLine: false +AllowShortFunctionsOnASingleLine: All +AllowShortIfStatementsOnASingleLine: Always +AllowShortLambdasOnASingleLine: All +AllowShortLoopsOnASingleLine: true +AlwaysBreakAfterReturnType: None +AlwaysBreakTemplateDeclarations: Yes +BreakBeforeBraces: Custom +BraceWrapping: + AfterCaseLabel: false + AfterClass: false + AfterControlStatement: Never + AfterEnum: false + AfterFunction: false + AfterNamespace: false + AfterUnion: false + BeforeCatch: false + BeforeElse: false + IndentBraces: false + SplitEmptyFunction: false + SplitEmptyRecord: true +BreakBeforeBinaryOperators: None +BreakBeforeTernaryOperators: true +BreakConstructorInitializers: BeforeColon +BreakInheritanceList: BeforeColon +ColumnLimit: 0 +CompactNamespaces: false +ContinuationIndentWidth: 8 +IndentCaseLabels: true +IndentPPDirectives: None +IndentWidth: 4 +KeepEmptyLinesAtTheStartOfBlocks: true +MaxEmptyLinesToKeep: 2 +NamespaceIndentation: All +ObjCSpaceAfterProperty: false +ObjCSpaceBeforeProtocolList: true +PointerAlignment: Right +ReflowComments: false +SpaceAfterCStyleCast: true +SpaceAfterLogicalNot: false +SpaceAfterTemplateKeyword: false +SpaceBeforeAssignmentOperators: true +SpaceBeforeCpp11BracedList: false +SpaceBeforeCtorInitializerColon: true +SpaceBeforeInheritanceColon: true +SpaceBeforeParens: ControlStatements +SpaceBeforeRangeBasedForLoopColon: false +SpaceInEmptyParentheses: false +SpacesBeforeTrailingComments: 0 +SpacesInAngles: false +SpacesInCStyleCastParentheses: false +SpacesInContainerLiterals: false +SpacesInParentheses: false +SpacesInSquareBrackets: false +TabWidth: 4 +UseTab: Never diff --git a/.idea/codeStyles/Project.xml b/.idea/codeStyles/Project.xml new file mode 100644 index 0000000..f603881 --- /dev/null +++ b/.idea/codeStyles/Project.xml @@ -0,0 +1,7 @@ + + + + + + \ No newline at end of file diff --git a/.idea/codeStyles/codeStyleConfig.xml b/.idea/codeStyles/codeStyleConfig.xml new file mode 100644 index 0000000..79ee123 --- /dev/null +++ b/.idea/codeStyles/codeStyleConfig.xml @@ -0,0 +1,5 @@ + + + + \ No newline at end of file diff --git a/src/vm/includes/Cell.h b/src/vm/includes/Cell.h index 71675a5..4360ca4 100644 --- a/src/vm/includes/Cell.h +++ b/src/vm/includes/Cell.h @@ -5,8 +5,8 @@ #ifndef PSIL_CELL_H #define PSIL_CELL_H -#include #include +#include enum class CellType { INT, @@ -19,6 +19,8 @@ struct Cell { virtual ~Cell() = 0; CellType _type; + + bool live = false; }; struct IntCell : public Cell { @@ -60,7 +62,6 @@ struct CommandCell : public IntCell { assert((_val > 0 && static_cast(_val) <= CommandNum::END)); return static_cast(_val); } - }; struct ConsCell : public Cell { @@ -74,4 +75,4 @@ struct ConsCell : public Cell { Cell *_cdr = nullptr; }; -#endif //PSIL_CELL_H +#endif//PSIL_CELL_H diff --git a/src/vm/includes/VM.h b/src/vm/includes/VM.h index 6eed788..0c2fd8e 100644 --- a/src/vm/includes/VM.h +++ b/src/vm/includes/VM.h @@ -5,9 +5,10 @@ #ifndef PSIL_VM_H #define PSIL_VM_H -#include -#include #include +#include +#include +#include #include "Cell.h" @@ -19,10 +20,10 @@ public: void step(); -// template -// void appendCommand(T cell) { -// push(_c, makeCell(std::move(cell))); -// } + // template + // void appendCommand(T cell) { + // push(_c, makeCell(std::move(cell))); + // } template void appendCommand(T *cell) { @@ -57,8 +58,10 @@ public: return what; } + uint64_t cellCount() const; + private: - std::vector _cells; + std::list _cells; ConsCell *_s = nullptr; ConsCell *_e = nullptr; ConsCell *_c = nullptr; @@ -67,7 +70,9 @@ private: std::istream &_instream; std::ostream &_outstream; + + void gc(); }; -#endif //PSIL_VM_H +#endif//PSIL_VM_H diff --git a/src/vm/src/VM.cpp b/src/vm/src/VM.cpp index 73bd488..bd0f505 100644 --- a/src/vm/src/VM.cpp +++ b/src/vm/src/VM.cpp @@ -2,10 +2,11 @@ // Created by Stepan Usatiuk on 22.12.2023. // -#include "../includes/VM.h" +#include "VM.h" -#include #include +#include +#include void VM::run() { while (!_stop) step(); @@ -113,7 +114,7 @@ void VM::step() { _s = s; push(_s, ret); - + gc(); break; } case CommandCell::CommandNum::DUM: { @@ -143,6 +144,7 @@ void VM::step() { } case CommandCell::CommandNum::STOP: { _stop = true; + gc(); break; } case CommandCell::CommandNum::ADD: { @@ -188,7 +190,46 @@ void VM::step() { default: assert(false); } - } VM::VM(std::istream &instream, std::ostream &outstream) : _instream(instream), _outstream(outstream) {} + +void VM::gc() { + std::function visit = [&](ConsCell *c) { + if (c == nullptr) return; + if (c->live) return; + + c->live = true; + + if (c->_car) { + if (c->_car->_type == CellType::CONS) visit(dynamic_cast(c->_car)); + c->_car->live = true; + } + if (c->_cdr) { + if (c->_cdr->_type == CellType::CONS) visit(dynamic_cast(c->_cdr)); + c->_cdr->live = true; + } + }; + visit(_s); + visit(_e); + visit(_c); + visit(_d); + + uint64_t freed = 0; + + _cells.remove_if([&](Cell *l) { + bool ret = !l->live; + if (ret) { + freed += 1; + delete l; + } else { + l->live = false; + } + return ret; + }); + + std::cout << "GC Freed " << freed << std::endl; +} +uint64_t VM::cellCount() const { + return _cells.size(); +} diff --git a/test/vm/VMTest.cpp b/test/vm/VMTest.cpp index 0667fb1..0ac756c 100644 --- a/test/vm/VMTest.cpp +++ b/test/vm/VMTest.cpp @@ -91,7 +91,6 @@ TEST(VMTest, SimpleFunction) { } ssout.flush(); EXPECT_EQ(ssout.str(), "3"); - } TEST(VMTest, RecursiveFunction) { @@ -171,7 +170,7 @@ TEST(VMTest, RecursiveFunction) { vm.push(fibcallfn, vm.makeCell(vm.makeCell(1), vm.makeCell(1))); vm.push(fibcallfn, vm.makeCell(CommandCell::CommandNum::LD)); vm.push(fibcallfn, vm.makeCell(CommandCell::CommandNum::CONS)); - vm.push(fibcallfn, vm.makeCell(20)); + vm.push(fibcallfn, vm.makeCell(10)); vm.push(fibcallfn, vm.makeCell(CommandCell::CommandNum::LDC)); vm.push(fibcallfn, vm.makeCell(CommandCell::CommandNum::NIL)); @@ -236,6 +235,5 @@ TEST(VMTest, RecursiveFunction) { vm.run(); } ssout.flush(); - EXPECT_EQ(ssout.str(), "2358 6765"); - + EXPECT_EQ(ssout.str(), "2358 55"); } \ No newline at end of file diff --git a/test/vm/VMWithParserTest.cpp b/test/vm/VMWithParserTest.cpp index 086f990..8583ccf 100644 --- a/test/vm/VMWithParserTest.cpp +++ b/test/vm/VMWithParserTest.cpp @@ -1,7 +1,7 @@ #include -#include "VM.h" #include "Parser.h" +#include "VM.h" TEST(VMWithParserTest, BasicHello) { std::stringstream ssin; @@ -50,9 +50,9 @@ TEST(VMWithParserTest, RecFunction) { VM vm(ssin, ssout); Parser parser(vm); parser.loadSecd( - "( DUM NIL LDF ( LD ( 1 . 1 ) SEL ( LD ( 1 . 1 ) LDC -1 ADD SEL ( NIL LD ( 1 . 1 ) LDC -1 ADD CONS LD ( 2 . 1 ) AP NIL LD ( 1 . 1 ) LDC -2 ADD CONS LD ( 2 . 1 ) AP ADD JOIN ) ( LDC 1 JOIN ) JOIN ) ( LDC 0 JOIN ) RET ) CONS LDF ( NIL LDC 20 CONS LD ( 1 . 1 ) AP RET ) RAP PUTNUM STOP )"); + "( DUM NIL LDF ( LD ( 1 . 1 ) SEL ( LD ( 1 . 1 ) LDC -1 ADD SEL ( NIL LD ( 1 . 1 ) LDC -1 ADD CONS LD ( 2 . 1 ) AP NIL LD ( 1 . 1 ) LDC -2 ADD CONS LD ( 2 . 1 ) AP ADD JOIN ) ( LDC 1 JOIN ) JOIN ) ( LDC 0 JOIN ) RET ) CONS LDF ( NIL LDC 10 CONS LD ( 1 . 1 ) AP RET ) RAP PUTNUM STOP )"); vm.run(); } ssout.flush(); - EXPECT_EQ(ssout.str(), "6765"); + EXPECT_EQ(ssout.str(), "55"); } \ No newline at end of file