diff --git a/src/code/Code.cpp b/src/code/Code.cpp index 986c1fc..c7d8e05 100644 --- a/src/code/Code.cpp +++ b/src/code/Code.cpp @@ -17,7 +17,7 @@ InstrPtr Code::pushCode(const uint8_t code, const unsigned int lineNum) { return byteCodes.size() - 1; } -uint8_t Code::pushConst(const SExpr &sExpr) { +uint8_t Code::pushConst(const SExpr *sExpr) { consts.push_back(sExpr); return consts.size() - 1; } @@ -89,9 +89,9 @@ std::ostream &code::operator<<(std::ostream &o, const Code &code) { switch (byte) { case OpCode::MAKE_CLOSURE: { - const auto &fn = cast(code.consts[READ_BYTE()].get()); + const auto fn = cast(code.consts[READ_BYTE()]); o << "MAKE_CLOSURE" << fn; - for (unsigned int i{0}; i < fn.numUpvals; i++) { + for (unsigned int i{0}; i < fn->numUpvals; i++) { const auto isLocal = unsigned(READ_BYTE()); const auto idx = unsigned(READ_BYTE()); o << std::endl diff --git a/src/code/Code.hpp b/src/code/Code.hpp index 10ec533..cee283d 100644 --- a/src/code/Code.hpp +++ b/src/code/Code.hpp @@ -14,13 +14,13 @@ class Code { public: std::vector byteCodes; - std::vector> consts; + std::vector consts; std::vector lineNums; InstrPtr pushCode(const uint8_t code); InstrPtr pushCode(const uint8_t code, const unsigned int lineNum); - uint8_t pushConst(const sexpr::SExpr &sExpr); + uint8_t pushConst(const sexpr::SExpr *sExpr); void patchJump(const InstrPtr idx); }; diff --git a/src/compile/Compiler.cpp b/src/compile/Compiler.cpp index 5a9a3c2..f523045 100644 --- a/src/compile/Compiler.cpp +++ b/src/compile/Compiler.cpp @@ -42,7 +42,8 @@ Compiler::tokenize(std::string line, const unsigned int row) { { row, (unsigned int)match.position(), - }}); + } + }); } return tokens; } @@ -56,82 +57,82 @@ bool Compiler::isNum(const std::string s) { return true; } -const SExprs &Compiler::parse() { +const SExprs *Compiler::parse() { auto tokens = tokenize(source); auto it = tokens.cbegin(); return cast(parseLists(it, tokens.cend())); } -const SExpr &Compiler::parseLists(TokenIter &it, const TokenIter &end) { +const SExpr *Compiler::parseLists(TokenIter &it, const TokenIter &end) { if (it == end) { return vm.freeStore.alloc(); } const auto [row, col] = it->srcLoc; - const auto &cur = parseList(it, end); - const auto &sexprs = vm.freeStore.alloc(cur, parseLists(it, end)); - srcMap[&sexprs] = {row, col}; + const auto cur = parseList(it, end); + const auto sexprs = vm.freeStore.alloc(cur, parseLists(it, end)); + srcMap[sexprs] = {row, col}; return sexprs; } -const SExpr &Compiler::parseList(TokenIter &it, const TokenIter &end) { +const SExpr *Compiler::parseList(TokenIter &it, const TokenIter &end) { auto token = *it; it += 1; if (token.str == "(") { - const auto &sExprs = parseElem(it, end); - srcMap.insert({&sExprs, {token.srcLoc.row, token.srcLoc.col}}); + const auto sExprs = parseElem(it, end); + srcMap.insert({sExprs, {token.srcLoc.row, token.srcLoc.col}}); return sExprs; } if (token.str == "'" || token.str == "`" || token.str == "," || token.str == ",@") { - const auto &rest = vm.freeStore.alloc( + const auto rest = vm.freeStore.alloc( parseList(it, end), vm.freeStore.alloc() ); - srcMap.insert({&rest, {token.srcLoc.row, token.srcLoc.col}}); - const auto &sExprs = vm.freeStore.alloc(parseAtom(token), rest); - srcMap.insert({&sExprs, {token.srcLoc.row, token.srcLoc.col}}); + srcMap.insert({rest, {token.srcLoc.row, token.srcLoc.col}}); + const auto sExprs = vm.freeStore.alloc(parseAtom(token), rest); + srcMap.insert({sExprs, {token.srcLoc.row, token.srcLoc.col}}); return sExprs; } - const auto &atom = parseAtom(token); + const auto atom = parseAtom(token); return atom; } -const SExpr &Compiler::parseElem(TokenIter &it, const TokenIter &end) { +const SExpr *Compiler::parseElem(TokenIter &it, const TokenIter &end) { auto token = *it; if (token.str == ")") { it += 1; return vm.freeStore.alloc(); } else if (token.str == "(") { it += 1; - const auto &first = parseElem(it, end); - const auto &rest = parseElem(it, end); - const auto &sExprs = vm.freeStore.alloc(first, rest); - srcMap.insert({&sExprs, {token.srcLoc.row, token.srcLoc.col}}); + const auto first = parseElem(it, end); + const auto rest = parseElem(it, end); + const auto sExprs = vm.freeStore.alloc(first, rest); + srcMap.insert({sExprs, {token.srcLoc.row, token.srcLoc.col}}); return sExprs; } return parseSexprs(it, end); } -const SExpr &Compiler::parseSexprs(TokenIter &it, const TokenIter &end) { +const SExpr *Compiler::parseSexprs(TokenIter &it, const TokenIter &end) { auto token = *it; - const auto &first = parseList(it, end); + const auto first = parseList(it, end); if (it->str == ".") { it += 1; - const auto &rest = parseList(it, end); + const auto rest = parseList(it, end); if (it == end) { handleTypeError(dotGrammer, "datum", rest); } it += 1; - const auto &sExprs = vm.freeStore.alloc(first, rest); - srcMap.insert({&sExprs, {token.srcLoc.row, token.srcLoc.col}}); + const auto sExprs = vm.freeStore.alloc(first, rest); + srcMap.insert({sExprs, {token.srcLoc.row, token.srcLoc.col}}); return sExprs; } - const auto &rest = parseElem(it, end); - const auto &sExprs = vm.freeStore.alloc(first, rest); - srcMap.insert({&sExprs, {token.srcLoc.row, token.srcLoc.col}}); + const auto rest = parseElem(it, end); + const auto sExprs = vm.freeStore.alloc(first, rest); + srcMap.insert({sExprs, {token.srcLoc.row, token.srcLoc.col}}); return sExprs; } -const SExpr &Compiler::parseAtom(Token token) { +const SExpr *Compiler::parseAtom(Token token) { if (isNum(token.str)) { return vm.freeStore.alloc(std::stod(token.str)); } @@ -173,8 +174,8 @@ void Compiler::handleUnexpectedToken( Compiler::Compiler( const std::vector source, SrcMap sourceLoc, - const SExpr ¶m, - const SExprs &body, + const SExpr *param, + const SExprs *body, Compiler &enclosing, VM &vm ) @@ -182,7 +183,7 @@ Compiler::Compiler( enclosing(enclosing), source(source), srcMap(sourceLoc), - curSrcLoc({srcMap[¶m].row, srcMap[¶m].col}), + curSrcLoc({srcMap[param].row, srcMap[param].col}), param(param), arity(countArity()), variadic(isVariadic()), @@ -190,14 +191,14 @@ Compiler::Compiler( stackOffset(1) { if (isa(param)) { - visitEach(cast(param), [this](const auto &sExpr) { - const auto &sym = cast(sExpr); + visitEach(cast(param), [this](const auto sExpr) { + const auto sym = cast(sExpr); locals.push_back({sym, stackOffset, false}); stackOffset += 1; }); } - const auto &lastParam = last(param); + const auto lastParam = last(param); if (isa(lastParam)) { locals.push_back({cast(lastParam), stackOffset, false}); @@ -205,14 +206,14 @@ Compiler::Compiler( } } -void Compiler::updateCurSrcLoc(const sexpr::SExprs &sExpr) { - curSrcLoc = srcMap[&sExpr]; +void Compiler::updateCurSrcLoc(const sexpr::SExprs *sExpr) { + curSrcLoc = srcMap[sExpr]; } -std::optional Compiler::resolveLocal(const Sym &sym) { +std::optional Compiler::resolveLocal(const Sym *sym) { auto it = std::find_if(locals.rbegin(), locals.rend(), [&sym](const auto &local) { - return local.symbol == sym; + return *local.symbol == *sym; }); if (it == locals.rend()) { return std::nullopt; @@ -221,7 +222,7 @@ std::optional Compiler::resolveLocal(const Sym &sym) { } std::optional -Compiler::resolveUpvalue(Compiler &caller, const Sym &sym) { +Compiler::resolveUpvalue(Compiler &caller, const Sym *sym) { if (!enclosing.has_value()) { return std::nullopt; } @@ -257,67 +258,67 @@ uint8_t Compiler::countArity() { if (isa(param) || isa(param)) { return 0; } - return visitEach(cast(param), [](const auto &) {}); + return visitEach(cast(param), [](const auto) {}); } -code::InstrPtr Compiler::emitConst(const sexpr::SExpr &sExpr) { +code::InstrPtr Compiler::emitConst(const sexpr::SExpr *sExpr) { return code.pushConst(sExpr); } void Compiler::patchJump(const code::InstrPtr idx) { code.patchJump(idx); } -const SExpr &Compiler::last(const SExpr &sExpr) { +const SExpr *Compiler::last(const SExpr *sExpr) { if (isa(sExpr)) { return sExpr; } - const auto &sExprs = cast(sExpr); + const auto sExprs = cast(sExpr); updateCurSrcLoc(sExprs); - return last(sExprs.rest); + return last(sExprs->rest); } -unsigned int Compiler::visitEach(const SExpr &sExpr, Visitor visitor) { +unsigned int Compiler::visitEach(const SExpr *sExpr, Visitor visitor) { if (isa(sExpr)) { return 0; } - const auto &sExprs = cast(sExpr); + const auto sExprs = cast(sExpr); updateCurSrcLoc(sExprs); - visitor(sExprs.first); - return 1 + visitEach(sExprs.rest, visitor); + visitor(sExprs->first); + return 1 + visitEach(sExprs->rest, visitor); } -void Compiler::traverse(const SExpr &sExpr, Visitor visitor) { +void Compiler::traverse(const SExpr *sExpr, Visitor visitor) { if (isa(sExpr)) { - const auto &sexprs = cast(sExpr); - traverse(sexprs.first, visitor); - traverse(sexprs.rest, visitor); + const auto sexprs = cast(sExpr); + traverse(sexprs->first, visitor); + traverse(sexprs->rest, visitor); } visitor(sExpr); } -void Compiler::compileStmts(const SExpr &sExpr) { +void Compiler::compileStmts(const SExpr *sExpr) { emitCode(OpCode::MAKE_NIL); - visitEach(sExpr, [this](const auto &sExpr) { + visitEach(sExpr, [this](const auto sExpr) { stackOffset += 1; compileStmt(sExpr); }); } -void Compiler::compileExprs(const SExpr &sExpr) { +void Compiler::compileExprs(const SExpr *sExpr) { emitCode(OpCode::MAKE_NIL); - visitEach(sExpr, [this](const auto &sExpr) { + visitEach(sExpr, [this](const auto sExpr) { emitCode(OpCode::POP_TOP); compileExpr(sExpr); }); } -void Compiler::compileStmt(const SExpr &sExpr) { +void Compiler::compileStmt(const SExpr *sExpr) { if (matchForm( sExpr, { - {DEFINE_SYM, [this](const auto &matched) { emitDef(matched); }}, - {DEFMACRO_SYM, + {&DEFINE_SYM, [this](const auto &matched) { emitDef(matched); }}, + {&DEFMACRO_SYM, [this](const auto &matched) { execDefMacro(matched); }}, - {BEGIN_SYM, + {&BEGIN_SYM, [this](const auto &matched) { compileStmts(matched.get()); }}, }, [this, &sExpr](const auto &sym, const auto) { @@ -333,16 +334,16 @@ void Compiler::compileStmt(const SExpr &sExpr) { compileExpr(sExpr); } -void Compiler::compileExpr(const SExpr &sExpr) { +void Compiler::compileExpr(const SExpr *sExpr) { if (matchForm( sExpr, - {{DEFINE_SYM, [this](const auto &) { handleInvalidDef(); }}, - {DEFMACRO_SYM, [this](const auto &) { handleInvalidDef(); }}, - {QUOTE_SYM, [this](const auto &matched) { emitQuote(matched); }}, - {SET_SYM, [this](const auto &matched) { emitSet(matched); }}, - {IF_SYM, [this](const auto &matched) { emitIf(matched); }}, - {LAMBDA_SYM, [this](const auto &matched) { emitLambda(matched); }}, - {BEGIN_SYM, + {{&DEFINE_SYM, [this](const auto &) { handleInvalidDef(); }}, + {&DEFMACRO_SYM, [this](const auto &) { handleInvalidDef(); }}, + {"E_SYM, [this](const auto &matched) { emitQuote(matched); }}, + {&SET_SYM, [this](const auto &matched) { emitSet(matched); }}, + {&IF_SYM, [this](const auto &matched) { emitIf(matched); }}, + {&LAMBDA_SYM, [this](const auto &matched) { emitLambda(matched); }}, + {&BEGIN_SYM, [this](const auto &matched) { compileExprs(matched.get()); }}}, [this, &sExpr](const auto sym, const auto) { if (vm.env.isMacro(sym.get())) { @@ -361,7 +362,7 @@ void Compiler::compileExpr(const SExpr &sExpr) { compileCall(cast(sExpr)); } -void Compiler::compileAtom(const Atom &atom) { +void Compiler::compileAtom(const Atom *atom) { if (isa(atom)) { throw error::SyntaxError( "Expected a non-empty list.", @@ -377,10 +378,11 @@ void Compiler::compileAtom(const Atom &atom) { emitCode(OpCode::LOAD_CONST, emitConst(atom)); } -void Compiler::compileCall(const SExprs &sExprs) { - compileExpr(sExprs.first); - const auto argc = - visitEach(sExprs.rest, [this](const auto &sExpr) { compileExpr(sExpr); }); +void Compiler::compileCall(const SExprs *sExprs) { + compileExpr(sExprs->first); + const auto argc = visitEach(sExprs->rest, [this](const auto &sExpr) { + compileExpr(sExpr); + }); try { cast(last(sExprs)); @@ -409,7 +411,7 @@ void Compiler::emitLambda(const MatchedSExpr matched) { *this, vm ); - const auto &function = compiler.compile(); + const auto function = compiler.compile(); emitCode(OpCode::MAKE_CLOSURE, emitConst(function)); for (const auto &upValue : compiler.upValues) { @@ -420,7 +422,7 @@ void Compiler::emitLambda(const MatchedSExpr matched) { } } -void Compiler::emitSym(const sexpr::Sym &sym) { +void Compiler::emitSym(const sexpr::Sym *sym) { if (vm.env.isNatFn(sym)) { emitCode(OpCode::LOAD_CONST, emitConst(vm.env.load(sym))); return; @@ -566,15 +568,15 @@ void Compiler::emitRet() { emitCode(OpCode::RETURN); } -const SExpr &Compiler::execMacro(const SExpr &sExpr) { +const SExpr *Compiler::execMacro(const SExpr *sExpr) { Code fExpr; - const auto &sExprs = cast(sExpr); + const auto sExprs = cast(sExpr); fExpr.pushCode(OpCode::LOAD_SYM, curSrcLoc.row); - fExpr.pushCode(fExpr.pushConst(sExprs.first)); + fExpr.pushCode(fExpr.pushConst(sExprs->first)); - const auto argc = visitEach(sExprs.rest, [this, &fExpr](const auto &sExpr) { + const auto argc = visitEach(sExprs->rest, [this, &fExpr](const auto &sExpr) { fExpr.pushCode(OpCode::LOAD_CONST, curSrcLoc.row); fExpr.pushCode(fExpr.pushConst(sExpr)); }); @@ -583,11 +585,11 @@ const SExpr &Compiler::execMacro(const SExpr &sExpr) { fExpr.pushCode(argc); fExpr.pushCode(OpCode::RETURN, curSrcLoc.row); - const auto &res = + const auto res = vm.eval(vm.freeStore.alloc(0, 0, false, fExpr), true); traverse(res, [this](const auto &sExpr) { - srcMap.insert({&sExpr, curSrcLoc}); + srcMap.insert({sExpr, curSrcLoc}); }); return res; @@ -605,7 +607,7 @@ void Compiler::handleInvalidDef() { } void Compiler::handleTypeError( - const std::string grammar, const std::string expected, const SExpr &actual + const std::string grammar, const std::string expected, const SExpr *actual ) { std::stringstream ss; ss << "Invalid syntax for " << grammar << "." << std::endl @@ -624,7 +626,7 @@ Compiler::Compiler(std::vector source, VM &vm) body(parse()), stackOffset(1) {} -const Prototype &Compiler::compile() { +const Prototype *Compiler::compile() { if (variadic) { emitCode(OpCode::MAKE_LIST, arity + 1); } diff --git a/src/compile/Compiler.hpp b/src/compile/Compiler.hpp index 4bf2793..4e6fc9c 100644 --- a/src/compile/Compiler.hpp +++ b/src/compile/Compiler.hpp @@ -33,7 +33,7 @@ class Compiler { private: using SrcMap = std::unordered_map; using TokenIter = std::vector::const_iterator; - using Visitor = std::function; + using Visitor = std::function; runtime::VM &vm; const std::optional> enclosing; @@ -42,11 +42,11 @@ class Compiler { SrcMap srcMap; SrcLoc curSrcLoc; - const sexpr::SExpr ¶m; + const sexpr::SExpr *param; const uint8_t arity; const bool variadic; - const sexpr::SExprs &body; + const sexpr::SExprs *body; std::vector locals; std::vector upValues; @@ -60,22 +60,22 @@ class Compiler { static void handleUnexpectedToken(const Token &token, const std::string &line); - const sexpr::SExprs &parse(); - const sexpr::SExpr &parseLists(TokenIter &it, const TokenIter &end); - const sexpr::SExpr &parseList(TokenIter &it, const TokenIter &end); - const sexpr::SExpr &parseElem(TokenIter &it, const TokenIter &end); - const sexpr::SExpr &parseSexprs(TokenIter &it, const TokenIter &end); - const sexpr::SExpr &parseAtom(Token token); + const sexpr::SExprs *parse(); + const sexpr::SExpr *parseLists(TokenIter &it, const TokenIter &end); + const sexpr::SExpr *parseList(TokenIter &it, const TokenIter &end); + const sexpr::SExpr *parseElem(TokenIter &it, const TokenIter &end); + const sexpr::SExpr *parseSexprs(TokenIter &it, const TokenIter &end); + const sexpr::SExpr *parseAtom(Token token); template class MatchedSExpr { private: - const T &sExpr; + const T *sExpr; const std::function callBack; public: - MatchedSExpr(const T &sExpr, const std::function callBack) + MatchedSExpr(const T *sExpr, const std::function callBack) : sExpr(sExpr), callBack(callBack) {} - const T &get() const { + const T *get() const { callBack(); return sExpr; } @@ -83,22 +83,22 @@ class Compiler { template std::tuple, const MatchedSExpr...> - unpack(const sexpr::SExpr &sExpr) { - const auto &sExprs = sexpr::cast(sExpr); + unpack(const sexpr::SExpr *sExpr) { + const auto sExprs = sexpr::cast(sExpr); updateCurSrcLoc(sExprs); if constexpr (sizeof...(Rest) != 0) { return std::tuple_cat( std::tuple>(MatchedSExpr( - cast(sExprs.first), - [this, &sExprs]() { updateCurSrcLoc(sExprs); } + cast(sExprs->first), + [this, sExprs]() { updateCurSrcLoc(sExprs); } )), - unpack(sExprs.rest) + unpack(sExprs->rest) ); } else { - assertType(sExprs.rest); + assertType(sExprs->rest); return std::tuple>(MatchedSExpr( - cast(sExprs.first), - [this, &sExprs]() { updateCurSrcLoc(sExprs); } + cast(sExprs->first), + [this, sExprs]() { updateCurSrcLoc(sExprs); } )); } } @@ -108,47 +108,47 @@ class Compiler { const MatchedSExpr, const MatchedSExpr..., const MatchedSExpr> - unpackPartial(const sexpr::SExpr &sExpr) { - const auto &sExprs = sexpr::cast(sExpr); + unpackPartial(const sexpr::SExpr *sExpr) { + const auto sExprs = sexpr::cast(sExpr); updateCurSrcLoc(sExprs); if constexpr (sizeof...(Rest) != 0) { return std::tuple_cat( std::tuple>(MatchedSExpr( - cast(sExprs.first), - [this, &sExprs]() { updateCurSrcLoc(sExprs); } + cast(sExprs->first), + [this, sExprs]() { updateCurSrcLoc(sExprs); } )), - unpackPartial(sExprs.rest) + unpackPartial(sExprs->rest) ); } else { return std::tuple, MatchedSExpr>( MatchedSExpr( - cast(sExprs.first), - [this, &sExprs]() { updateCurSrcLoc(sExprs); } + cast(sExprs->first), + [this, sExprs]() { updateCurSrcLoc(sExprs); } ), MatchedSExpr( - sExprs.rest, [this, &sExprs]() { updateCurSrcLoc(sExprs); } + sExprs->rest, [this, sExprs]() { updateCurSrcLoc(sExprs); } ) ); } } template - bool check(const sexpr::SExpr &sExpr) { + bool check(const sexpr::SExpr *sExpr) { if (!isa(sExpr)) { return false; } - const auto &sExprs = cast(sExpr); + const auto sExprs = cast(sExpr); if constexpr (sizeof...(Rest) != 0) { - return isa(sExprs.first) && check(sExprs.rest); + return isa(sExprs->first) && check(sExprs->rest); } else { - return isa(sExprs.first); + return isa(sExprs->first); } } bool matchForm( - const sexpr::SExpr &sExpr, + const sexpr::SExpr *sExpr, std::initializer_list)>>> rules, std::optional, MatchedSExpr)>> @@ -159,7 +159,7 @@ class Compiler { } const auto &[sym, rest] = unpackPartial(sExpr); for (const auto &[name, handler] : rules) { - if (name == sym.get()) { + if (*name == *sym.get()) { handler(rest); return true; } @@ -174,16 +174,16 @@ class Compiler { Compiler( const std::vector source, SrcMap sourceLoc, - const sexpr::SExpr ¶m, - const sexpr::SExprs &body, + const sexpr::SExpr *param, + const sexpr::SExprs *body, Compiler &enclosing, runtime::VM &vm ); - void updateCurSrcLoc(const sexpr::SExprs &sExpr); - std::optional resolveLocal(const sexpr::Sym &sym); + void updateCurSrcLoc(const sexpr::SExprs *sExpr); + std::optional resolveLocal(const sexpr::Sym *sym); std::optional - resolveUpvalue(Compiler &caller, const sexpr::Sym &sym); + resolveUpvalue(Compiler &caller, const sexpr::Sym *sym); std::size_t addUpvalue(int idx, bool isLocal); bool isVariadic(); uint8_t countArity(); @@ -197,39 +197,39 @@ class Compiler { emitCode(args...); return idx; } - code::InstrPtr emitConst(const sexpr::SExpr &sExpr); + code::InstrPtr emitConst(const sexpr::SExpr *sExpr); void patchJump(const code::InstrPtr idx); - const sexpr::SExpr &last(const sexpr::SExpr &sExpr); - unsigned int visitEach(const sexpr::SExpr &sExpr, Visitor visitor); - void traverse(const sexpr::SExpr &sExpr, Visitor visitor); - void compileStmts(const sexpr::SExpr &sExpr); - void compileExprs(const sexpr::SExpr &sExpr); - void compileStmt(const sexpr::SExpr &sExpr); - void compileExpr(const sexpr::SExpr &sExpr); - void compileAtom(const sexpr::Atom &atom); - void compileCall(const sexpr::SExprs &sExprs); + const sexpr::SExpr *last(const sexpr::SExpr *sExpr); + unsigned int visitEach(const sexpr::SExpr *sExpr, Visitor visitor); + void traverse(const sexpr::SExpr *sExpr, Visitor visitor); + void compileStmts(const sexpr::SExpr *sExpr); + void compileExprs(const sexpr::SExpr *sExpr); + void compileStmt(const sexpr::SExpr *sExpr); + void compileExpr(const sexpr::SExpr *sExpr); + void compileAtom(const sexpr::Atom *atom); + void compileCall(const sexpr::SExprs *sExprs); void emitDef(const MatchedSExpr matched); void emitSet(const MatchedSExpr matched); - void emitSym(const sexpr::Sym &sym); + void emitSym(const sexpr::Sym *sym); void emitQuote(const MatchedSExpr matched); void emitIf(const MatchedSExpr matched); void emitLambda(const MatchedSExpr matched); void emitRet(); void execDefMacro(const MatchedSExpr matched); - const sexpr::SExpr &execMacro(const sexpr::SExpr ¯o); + const sexpr::SExpr *execMacro(const sexpr::SExpr *macro); void handleInvalidDef(); void handleTypeError( const std::string grammar, const std::string expected, - const sexpr::SExpr &actual + const sexpr::SExpr *actual ); public: Compiler(std::vector source, runtime::VM &vm); - const sexpr::Prototype &compile(); + const sexpr::Prototype *compile(); static void verifyLex( const std::string &line, diff --git a/src/compile/Local.hpp b/src/compile/Local.hpp index 3bf6594..06d1d04 100644 --- a/src/compile/Local.hpp +++ b/src/compile/Local.hpp @@ -6,7 +6,7 @@ namespace compile { struct Local { - const sexpr::Sym &symbol; + const sexpr::Sym *symbol; const uint8_t stackOffset; bool isCaptured; }; diff --git a/src/error/RuntimeError.cpp b/src/error/RuntimeError.cpp index e272d2c..78bd370 100644 --- a/src/error/RuntimeError.cpp +++ b/src/error/RuntimeError.cpp @@ -8,7 +8,7 @@ using namespace error; RuntimeError::RuntimeError( const std::string &msg, Env globals, - std::vector> stack, + std::vector stack, std::vector frames ) : _msg(msg), globals(globals), stack(stack), frames(frames) {} @@ -16,10 +16,9 @@ RuntimeError::RuntimeError( const char *RuntimeError::what() const noexcept { return _msg.c_str(); } std::ostream &error::operator<<(std::ostream &o, const RuntimeError &re) { - std::unordered_map> - sExprSyms; + std::unordered_map sExprSyms; for (const auto &p : re.globals.getSymTable()) { - sExprSyms.insert({&p.second.get(), p.first}); + sExprSyms.insert({p.second, p.first}); } const unsigned int PADDING_WIDTH = 4; @@ -28,14 +27,14 @@ std::ostream &error::operator<<(std::ostream &o, const RuntimeError &re) { o << "In code object with ip: " << re.frames.back().ip << std::endl; o << std::setw(PADDING_WIDTH) << std::right - << re.frames.back().closure.fn.code << "Call stack:"; + << re.frames.back().closure->proto->code << "Call stack:"; for (unsigned int idx = 0; const auto &stackFrame : re.frames) { o << std::endl << std::setw(PADDING_WIDTH) << "" << std::setw(IDX_WIDTH) << std::left << idx << ""; idx += 1; - auto it = sExprSyms.find(&stackFrame.closure); + auto it = sExprSyms.find(stackFrame.closure); if (it != sExprSyms.end()) { o << " (" << it->second << ")"; } @@ -45,9 +44,9 @@ std::ostream &error::operator<<(std::ostream &o, const RuntimeError &re) { for (unsigned int idx = 0; const auto &sexpr : re.stack) { o << std::endl << std::setw(PADDING_WIDTH) << "" << std::setw(IDX_WIDTH) << std::left - << idx << sexpr; + << idx << *sexpr; idx += 1; - auto it = sExprSyms.find(&sexpr.get()); + auto it = sExprSyms.find(sexpr); if (it != sExprSyms.end()) { o << " (" << it->second << ")"; } diff --git a/src/error/RuntimeError.hpp b/src/error/RuntimeError.hpp index 8b7e3f6..97e59dc 100644 --- a/src/error/RuntimeError.hpp +++ b/src/error/RuntimeError.hpp @@ -14,14 +14,14 @@ class RuntimeError : public std::exception { private: std::string _msg; const runtime::Env globals; - const std::vector> stack; + const std::vector stack; const std::vector frames; public: RuntimeError( const std::string &msg, runtime::Env globals, - std::vector> stack, + std::vector stack, std::vector frames ); diff --git a/src/error/TypeError.cpp b/src/error/TypeError.cpp index 5ee636d..0c1904b 100644 --- a/src/error/TypeError.cpp +++ b/src/error/TypeError.cpp @@ -6,7 +6,7 @@ using namespace sexpr; using namespace error; TypeError::TypeError( - const std::string &msg, const std::string expected, const SExpr &actual + const std::string &msg, const std::string expected, const SExpr *actual ) : _msg(msg), expected(expected), actual(actual) {} diff --git a/src/error/TypeError.hpp b/src/error/TypeError.hpp index 24f7cda..3217b63 100644 --- a/src/error/TypeError.hpp +++ b/src/error/TypeError.hpp @@ -17,13 +17,13 @@ class TypeError : public std::exception { TypeError( const std::string &msg, const std::string expected, - const sexpr::SExpr &actual + const sexpr::SExpr *actual ); virtual const char *what() const noexcept override; const std::string expected; - const sexpr::SExpr &actual; + const sexpr::SExpr *actual; }; std::ostream &operator<<(std::ostream &o, const TypeError &pe); diff --git a/src/fn/CPPFn.hpp b/src/fn/CPPFn.hpp index a6457aa..01208a0 100644 --- a/src/fn/CPPFn.hpp +++ b/src/fn/CPPFn.hpp @@ -18,7 +18,7 @@ class VM; namespace fn { -using CPPFn = const sexpr::SExpr &( +using CPPFn = const sexpr::SExpr *( runtime::StackIter params, const uint8_t argc, runtime::VM &vm ); diff --git a/src/fn/CPPFnImpls.cpp b/src/fn/CPPFnImpls.cpp index 1ddfdbe..f33a112 100644 --- a/src/fn/CPPFnImpls.cpp +++ b/src/fn/CPPFnImpls.cpp @@ -18,7 +18,7 @@ using namespace fn; using namespace runtime; long genSymCnt = 0; -const SExpr &fn::genSym( +const SExpr *fn::genSym( [[maybe_unused]] StackIter params, [[maybe_unused]] const uint8_t argc, VM &vm @@ -29,97 +29,97 @@ const SExpr &fn::genSym( return vm.freeStore.alloc(ss.str()); } -const SExpr & +const SExpr * fn::numAbs(StackIter params, [[maybe_unused]] const uint8_t argc, VM &vm) { - return vm.freeStore.alloc(abs(cast(params->get()).val)); + return vm.freeStore.alloc(abs(cast(*params)->val)); } -const SExpr & +const SExpr * fn::numMod(StackIter params, [[maybe_unused]] const uint8_t argc, VM &vm) { - const auto lhs = cast(params->get()).val; + const auto lhs = cast(*params)->val; ++params; - const auto rhs = cast(params->get()).val; + const auto rhs = cast(*params)->val; return vm.freeStore.alloc(std::fmod(lhs, rhs)); } -const SExpr & +const SExpr * fn::strLen(StackIter params, [[maybe_unused]] const uint8_t argc, VM &vm) { - return vm.freeStore.alloc(cast(params->get()).escaped.size()); + return vm.freeStore.alloc(cast(*params)->escaped.size()); } -const SExpr &fn::strApp(StackIter params, const uint8_t argc, VM &vm) { +const SExpr *fn::strApp(StackIter params, const uint8_t argc, VM &vm) { std::stringstream ss; ss << "\""; for (uint8_t i{0}; i < argc; ++i) { - ss << cast(params->get()).escaped; + ss << cast(*params)->escaped; ++params; } ss << "\""; return vm.freeStore.alloc(ss.str()); } -const SExpr & +const SExpr * fn::substr(StackIter params, [[maybe_unused]] const uint8_t argc, VM &vm) { - const auto &str = cast(params->get()); - const auto &pos = cast((params + 1)->get()).val; - const auto &end = cast((params + 2)->get()).val; + const auto str = cast(*params); + const auto &pos = cast(*(params + 1))->val; + const auto &end = cast(*(params + 2))->val; std::stringstream ss; try { - ss << "\"" << str.escaped.substr(pos, end - pos) << "\""; + ss << "\"" << str->escaped.substr(pos, end - pos) << "\""; } catch (std::out_of_range &ofr) { std::stringstream ess; - ess << "Invalid range to substring for " << str.val << " (" << pos << ", " + ess << "Invalid range to substring for " << str->val << " (" << pos << ", " << end << ")"; throw std::invalid_argument(ess.str()); } return vm.freeStore.alloc(ss.str()); } -const SExpr &fn::toStr(StackIter params, const uint8_t argc, VM &vm) { - if (isa(params->get())) { - return params->get(); +const SExpr *fn::toStr(StackIter params, const uint8_t argc, VM &vm) { + if (isa(*params)) { + return *params; } std::stringstream ss; ss << "\""; for (uint8_t i{0}; i < argc; ++i) { - ss << params->get(); + ss << **params; ++params; } ss << "\""; return vm.freeStore.alloc(ss.str()); } -const SExpr & +const SExpr * fn::cons(StackIter params, [[maybe_unused]] const uint8_t argc, VM &vm) { - return vm.freeStore.alloc(params->get(), *(params + 1)); + return vm.freeStore.alloc(*params, *(params + 1)); } -const SExpr &fn::car( +const SExpr *fn::car( StackIter params, [[maybe_unused]] const uint8_t argc, [[maybe_unused]] VM &vm ) { - return cast(params->get()).first; + return cast(*params)->first; } -const SExpr &fn::cdr( +const SExpr *fn::cdr( StackIter params, [[maybe_unused]] const uint8_t argc, [[maybe_unused]] VM &vm ) { - return cast(params->get()).rest; + return cast(*params)->rest; } -const SExpr & +const SExpr * fn::dis(StackIter params, [[maybe_unused]] const uint8_t argc, VM &vm) { - cast(params->get()).dissassemble(std::cout); + cast(*params)->dissassemble(std::cout); return vm.freeStore.alloc(); } -const SExpr & +const SExpr * fn::display(StackIter params, [[maybe_unused]] const uint8_t argc, VM &vm) { - if (isa(params->get())) { - const auto &stringAtom = cast(params->get()); - std::cout << stringAtom.escaped; + if (isa(*params)) { + const auto &stringAtom = cast(*params); + std::cout << stringAtom->escaped; } else { - std::cout << params->get(); + std::cout << **params; } return vm.freeStore.alloc(); } -const SExpr &fn::newline( +const SExpr *fn::newline( [[maybe_unused]] StackIter params, [[maybe_unused]] const uint8_t argc, VM &vm @@ -128,7 +128,7 @@ const SExpr &fn::newline( return vm.freeStore.alloc(); } -const SExpr &fn::quit( +const SExpr *fn::quit( [[maybe_unused]] StackIter params, [[maybe_unused]] const uint8_t argc, [[maybe_unused]] VM &vm @@ -136,43 +136,43 @@ const SExpr &fn::quit( std::cout << "Farewell." << std::endl; exit(0); } -const SExpr &fn::error( +const SExpr *fn::error( StackIter params, [[maybe_unused]] const uint8_t argc, [[maybe_unused]] VM &vm ) { std::stringstream ss; - ss << params->get(); + ss << *params; throw std::runtime_error(ss.str()); } -const SExpr & +const SExpr * fn::eq(StackIter params, [[maybe_unused]] const uint8_t argc, VM &vm) { - const auto &lhs = params->get(); - const auto &rhs = (params + 1)->get(); + const auto lhs = *params; + const auto rhs = *(params + 1); if (isa(lhs)) { - return vm.freeStore.alloc(lhs == rhs); + return vm.freeStore.alloc(*lhs == *rhs); } - return vm.freeStore.alloc(&lhs == &rhs); + return vm.freeStore.alloc(lhs == rhs); } -const SExpr & +const SExpr * fn::eqv(StackIter params, [[maybe_unused]] const uint8_t argc, VM &vm) { - const auto &lhs = params->get(); - const auto &rhs = (params + 1)->get(); + const auto lhs = *params; + const auto rhs = *(params + 1); if (isa(lhs) || isa(lhs)) { - return vm.freeStore.alloc(lhs == rhs); + return vm.freeStore.alloc(*lhs == *rhs); } - return vm.freeStore.alloc(&lhs == &rhs); + return vm.freeStore.alloc(lhs == rhs); } -const SExpr & +const SExpr * fn::equal(StackIter params, [[maybe_unused]] const uint8_t argc, VM &vm) { - const auto &lhs = params->get(); - const auto &rhs = (params + 1)->get(); - return vm.freeStore.alloc(lhs == rhs); + const auto lhs = *params; + const auto rhs = *(params + 1); + return vm.freeStore.alloc(*lhs == *rhs); } -const SExpr &fn::apply(StackIter params, const uint8_t argc, VM &vm) { - const auto &newArgs = (params + argc - 1)->get(); +const SExpr *fn::apply(StackIter params, const uint8_t argc, VM &vm) { + const auto newArgs = *(params + argc - 1); vm.stack.erase(params + argc - 1); vm.stack.erase(params - 1); diff --git a/src/fn/CPPFnImpls.hpp b/src/fn/CPPFnImpls.hpp index 89392cc..8ce9e94 100644 --- a/src/fn/CPPFnImpls.hpp +++ b/src/fn/CPPFnImpls.hpp @@ -12,13 +12,13 @@ namespace fn { template typename Op> -const sexpr::SExpr & +const sexpr::SExpr * compare(runtime::StackIter params, const uint8_t argc, runtime::VM &vm) { Op op; - typename T::ValueType prev = cast(params->get()).val; + typename T::ValueType prev = cast(*params)->val; ++params; for (uint8_t i{1}; i < argc; ++i) { - typename T::ValueType cur = cast(params->get()).val; + typename T::ValueType cur = cast(*params)->val; if (!op(prev, cur)) { return vm.freeStore.alloc(false); } @@ -29,12 +29,12 @@ compare(runtime::StackIter params, const uint8_t argc, runtime::VM &vm) { } template typename Op, auto init> -const sexpr::SExpr & +const sexpr::SExpr * accum(runtime::StackIter params, const uint8_t argc, runtime::VM &vm) { Op op; typename T::ValueType acc = init; for (uint8_t i{0}; i < argc; ++i) { - acc = op(acc, cast(params->get()).val); + acc = op(acc, cast(*params)->val); ++params; } return vm.freeStore.alloc(acc); @@ -46,29 +46,29 @@ template < typename BinOp, template typename UniOp> -const sexpr::SExpr & +const sexpr::SExpr * dimi(runtime::StackIter params, const uint8_t argc, runtime::VM &vm) { UniOp uniOp; - typename T::ValueType acc = cast(params->get()).val; + typename T::ValueType acc = cast(*params)->val; if (argc == 1) { return vm.freeStore.alloc(uniOp(acc)); } ++params; BinOp biOp; for (uint8_t i{1}; i < argc; ++i) { - acc = biOp(acc, cast(params->get()).val); + acc = biOp(acc, cast(*params)->val); ++params; } return vm.freeStore.alloc(acc); } template -const sexpr::SExpr &typePred( +const sexpr::SExpr *typePred( runtime::StackIter params, [[maybe_unused]] const uint8_t argc, runtime::VM &vm ) { - return vm.freeStore.alloc((isa(params->get()) || ...)); + return vm.freeStore.alloc((isa(*params) || ...)); } template struct inverse { diff --git a/src/repl/repl.cpp b/src/repl/repl.cpp index e81cd08..ed828f9 100644 --- a/src/repl/repl.cpp +++ b/src/repl/repl.cpp @@ -75,7 +75,7 @@ int execFile(const std::string filePath, VM &vm) { try { if (getFileInput(fs, lines)) { Compiler compiler(lines, vm); - const auto &main = compiler.compile(); + const auto main = compiler.compile(); vm.eval(main); } } catch (error::SyntaxError &se) { @@ -125,10 +125,10 @@ int repl::repl() { try { if (getConsoleInput(lines, "lisp> ", " ... ")) { Compiler compiler(lines, vm); - const auto &main = compiler.compile(); - const auto &res = vm.eval(main); + const auto main = compiler.compile(); + const auto res = vm.eval(main); if (!isa(res)) { - std::cout << res << std::endl; + std::cout << *res << std::endl; } } else { std::cout << std::endl << "Farewell." << std::endl; diff --git a/src/runtime/CallFrame.hpp b/src/runtime/CallFrame.hpp index ce49a40..af54057 100644 --- a/src/runtime/CallFrame.hpp +++ b/src/runtime/CallFrame.hpp @@ -8,7 +8,7 @@ namespace runtime { struct CallFrame { - const sexpr::Closure &closure; + const sexpr::Closure *closure; const runtime::StackPtr bp; const code::InstrPtr ip; }; diff --git a/src/runtime/Env.cpp b/src/runtime/Env.cpp index 7994711..d662bc3 100644 --- a/src/runtime/Env.cpp +++ b/src/runtime/Env.cpp @@ -9,66 +9,66 @@ using namespace sexpr; using namespace runtime; -void Env::regMacro(const Sym &sym) { macros.insert(sym); } +void Env::regMacro(const Sym *sym) { macros.insert(sym); } -void Env::regNative(const Sym &sym) { natFns.insert(sym); } +void Env::regNative(const Sym *sym) { natFns.insert(sym); } -void Env::guardMutation(const Sym &sym) { +void Env::guardMutation(const Sym *sym) { if (auto it = macros.find(sym); it != macros.end()) [[unlikely]] { throw std::invalid_argument( - "Cannot mutate macro symbol \"" + sym.val + "\'." + "Cannot mutate macro symbol \"" + sym->val + "\'." ); } if (auto it = natFns.find(sym); it != natFns.end()) [[unlikely]] { throw std::invalid_argument( - "Cannot mutate native symbol \"" + sym.val + "\'." + "Cannot mutate native symbol \"" + sym->val + "\'." ); } } -void Env::def(const Sym &sym, const SExpr &val) { +void Env::def(const Sym *sym, const SExpr *val) { guardMutation(sym); symTable.insert_or_assign(sym, val); } -void Env::defMacro(const Sym &sym, const SExpr ¯o) { +void Env::defMacro(const Sym *sym, const SExpr *macro) { def(sym, macro); regMacro(sym); } -void Env::defNatFn(const sexpr::Sym &sym, const sexpr::NatFn &natFn) { +void Env::defNatFn(const sexpr::Sym *sym, const sexpr::NatFn *natFn) { def(sym, natFn); regNative(sym); } void Env::defNatFns(const std::initializer_list< - std::tuple> natFns + std::tuple> natFns ) { for (const auto &[sym, natFn] : natFns) { defNatFn(sym, natFn); } } -void Env::set(const Sym &sym, const SExpr &val) { +void Env::set(const Sym *sym, const SExpr *val) { guardMutation(sym); auto it = symTable.find(sym); if (it == symTable.end()) [[unlikely]] { - throw std::invalid_argument("Symbol \"" + sym.val + "\" is not defined."); + throw std::invalid_argument("Symbol \"" + sym->val + "\" is not defined."); } it->second = val; } -const SExpr &Env::load(const Sym &sym) { +const SExpr *Env::load(const Sym *sym) { auto it = symTable.find(sym); if (it == symTable.end()) [[unlikely]] { - throw std::invalid_argument("Symbol \"" + sym.val + "\" is not defined."); + throw std::invalid_argument("Symbol \"" + sym->val + "\" is not defined."); } return it->second; } -bool Env::isMacro(const Sym &sym) { return macros.find(sym) != macros.end(); } +bool Env::isMacro(const Sym *sym) { return macros.find(sym) != macros.end(); } -bool Env::isNatFn(const sexpr::Sym &sym) { +bool Env::isNatFn(const sexpr::Sym *sym) { return natFns.find(sym) != natFns.end(); } diff --git a/src/runtime/Env.hpp b/src/runtime/Env.hpp index 13f6cb9..dedbcf9 100644 --- a/src/runtime/Env.hpp +++ b/src/runtime/Env.hpp @@ -14,13 +14,13 @@ namespace runtime { class Env { using SymTable = std::unordered_map< - std::reference_wrapper, - std::reference_wrapper, + const sexpr::Sym *, + const sexpr::SExpr *, sexpr::Sym::HashFunction, sexpr::Sym::EqualFunction>; using SymSet = std::unordered_set< - std::reference_wrapper, + const sexpr::Sym *, sexpr::Sym::HashFunction, sexpr::Sym::EqualFunction>; @@ -29,23 +29,23 @@ class Env { SymSet macros; SymSet natFns; - void regMacro(const sexpr::Sym &sym); - void regNative(const sexpr::Sym &sym); - void guardMutation(const sexpr::Sym &sym); + void regMacro(const sexpr::Sym *sym); + void regNative(const sexpr::Sym *sym); + void guardMutation(const sexpr::Sym *sym); public: - void def(const sexpr::Sym &sym, const sexpr::SExpr &val); - void defMacro(const sexpr::Sym &sym, const sexpr::SExpr &val); - void defNatFn(const sexpr::Sym &sym, const sexpr::NatFn &natFn); + void def(const sexpr::Sym *sym, const sexpr::SExpr *val); + void defMacro(const sexpr::Sym *sym, const sexpr::SExpr *val); + void defNatFn(const sexpr::Sym *sym, const sexpr::NatFn *natFn); void defNatFns(const std::initializer_list< - std::tuple> natFns); + std::tuple> natFns); - void set(const sexpr::Sym &sym, const sexpr::SExpr &val); - const sexpr::SExpr &load(const sexpr::Sym &sym); + void set(const sexpr::Sym *sym, const sexpr::SExpr *val); + const sexpr::SExpr *load(const sexpr::Sym *sym); - bool isMacro(const sexpr::Sym &sym); - bool isNatFn(const sexpr::Sym &sym); + bool isMacro(const sexpr::Sym *sym); + bool isNatFn(const sexpr::Sym *sym); const SymTable &getSymTable() const; }; diff --git a/src/runtime/FreeStore.cpp b/src/runtime/FreeStore.cpp index 192032e..97a1ad9 100644 --- a/src/runtime/FreeStore.cpp +++ b/src/runtime/FreeStore.cpp @@ -21,7 +21,7 @@ void FreeStore::gc() { black.clear(); - grey.push_back(&closure->get()); + grey.push_back(closure.value()); markGlobals(); markStack(); markCallFrames(); @@ -31,7 +31,7 @@ void FreeStore::gc() { const auto sexpr = grey.front(); black.emplace(sexpr); grey.pop_front(); - trace(*sexpr); + trace(sexpr); } std::erase_if(heap, [&](const auto &unique) { @@ -41,34 +41,34 @@ void FreeStore::gc() { gcHeapSize = heap.size() * FREESTORE_HEAP_GROWTH_FACTOR; } -void FreeStore::mark(const SExpr &sexpr) { - if (!black.contains(&sexpr)) { - grey.push_back(&sexpr); +void FreeStore::mark(const SExpr *sexpr) { + if (!black.contains(sexpr)) { + grey.push_back(sexpr); } } -void FreeStore::trace(const SExpr &sexpr) { +void FreeStore::trace(const SExpr *sexpr) { if (isa(sexpr)) { - const auto &sexprs = cast(sexpr); - mark(sexprs.first); - mark(sexprs.rest); + const auto sexprs = cast(sexpr); + mark(sexprs->first); + mark(sexprs->rest); return; } if (isa(sexpr)) { - const auto &fnAtom = cast(sexpr); + const auto fnAtom = cast(sexpr); std::for_each( - fnAtom.code.consts.cbegin(), - fnAtom.code.consts.cend(), + fnAtom->code.consts.cbegin(), + fnAtom->code.consts.cend(), [&](const auto &sexpr) { mark(sexpr); } ); return; } if (isa(sexpr)) { - const auto &closureAtom = cast(sexpr); - mark(closureAtom.fn); + const auto closureAtom = cast(sexpr); + mark(closureAtom->proto); std::for_each( - closureAtom.upvalues.cbegin(), - closureAtom.upvalues.cend(), + closureAtom->upvalues.cbegin(), + closureAtom->upvalues.cend(), [&](const auto &upvalue) { mark(upvalue->get()); } ); return; @@ -81,8 +81,8 @@ void FreeStore::markGlobals() { globals.getSymTable().cend(), [&](const auto &it) { const auto &[sym, sexpr] = it; - grey.push_back(&sym.get()); - grey.push_back(&sexpr.get()); + grey.push_back(sym); + grey.push_back(sexpr); } ); } @@ -92,7 +92,7 @@ void FreeStore::markStack() { stack.cbegin(), stack.cend(), std::back_inserter(grey), - [](const auto &sexpr) { return &sexpr.get(); } + [](const auto &sexpr) { return sexpr; } ); } @@ -101,7 +101,7 @@ void FreeStore::markCallFrames() { callFrames.cbegin(), callFrames.cend(), std::back_inserter(grey), - [](const auto &callFrame) { return &callFrame.closure; } + [](const auto &callFrame) { return callFrame.closure; } ); } @@ -110,14 +110,14 @@ void FreeStore::markOpenUpvalues() { openUpvals.cbegin(), openUpvals.cend(), std::back_inserter(grey), - [](const auto &it) { return &it.second->get(); } + [](const auto &it) { return it.second->get(); } ); } FreeStore::FreeStore( Env &globals, - std::optional> &closure, - std::vector> &stack, + std::optional &closure, + std::vector &stack, std::vector &callFrames, std::unordered_map> &openUpvals ) diff --git a/src/runtime/FreeStore.hpp b/src/runtime/FreeStore.hpp index c65c35b..def6ea0 100644 --- a/src/runtime/FreeStore.hpp +++ b/src/runtime/FreeStore.hpp @@ -25,8 +25,8 @@ namespace runtime { class FreeStore { private: Env &globals; - std::optional> &closure; - std::vector> &stack; + std::optional &closure; + std::vector &stack; std::vector &callFrames; std::unordered_map> &openUpvals; @@ -40,8 +40,8 @@ class FreeStore { std::deque grey; void gc(); - void mark(const sexpr::SExpr &sexpr); - void trace(const sexpr::SExpr &sexpr); + void mark(const sexpr::SExpr *sexpr); + void trace(const sexpr::SExpr *sexpr); void markGlobals(); void markStack(); void markCallFrames(); @@ -50,8 +50,8 @@ class FreeStore { public: FreeStore( Env &globals, - std::optional> &closure, - std::vector> &stack, + std::optional &closure, + std::vector &stack, std::vector &callFrames, std::unordered_map> &openUpvals ); @@ -59,37 +59,37 @@ class FreeStore { GCGuard startGC(); GCGuard pauseGC(); - template const T &alloc(Args &&...args) { + template const T *alloc(Args &&...args) { gc(); auto unique = std::make_unique(std::forward(args)...); const auto &ref = *unique.get(); heap.emplace_back(std::move(unique)); - return ref; + return &ref; } }; -template <> inline const sexpr::Undefined &FreeStore::alloc() { +template <> inline const sexpr::Undefined *FreeStore::alloc() { return sexpr::Undefined::getInstance(); } -template <> inline const sexpr::Nil &FreeStore::alloc() { +template <> inline const sexpr::Nil *FreeStore::alloc() { return sexpr::Nil::getInstance(); } template <> -inline const sexpr::Bool &FreeStore::alloc(sexpr::Bool::ValueType &&val) { +inline const sexpr::Bool *FreeStore::alloc(sexpr::Bool::ValueType &&val) { return sexpr::Bool::getInstance(val); } template <> -inline const sexpr::Num &FreeStore::alloc(sexpr::Num::ValueType &val) { +inline const sexpr::Num *FreeStore::alloc(sexpr::Num::ValueType &val) { if (val >= FREESTORE_INT_CACHE_MIN && val <= FREESTORE_INT_CACHE_MAX && floor(val) == val) { - return *numCache.at(val - FREESTORE_INT_CACHE_MIN).get(); + return numCache.at(val - FREESTORE_INT_CACHE_MIN).get(); } gc(); auto unique = std::make_unique(val); const auto &ref = *unique; heap.emplace_back(std::move(unique)); - return ref; + return &ref; } -template <> inline const sexpr::Num &FreeStore::alloc(double &&val) { +template <> inline const sexpr::Num *FreeStore::alloc(double &&val) { return alloc(val); } diff --git a/src/runtime/StackIter.hpp b/src/runtime/StackIter.hpp index 5a08286..0e013ab 100644 --- a/src/runtime/StackIter.hpp +++ b/src/runtime/StackIter.hpp @@ -6,8 +6,7 @@ namespace runtime { -using StackIter = - std::vector>::iterator; +using StackIter = std::vector::iterator; } diff --git a/src/runtime/StackPtr.hpp b/src/runtime/StackPtr.hpp index b46dc4c..8d16af9 100644 --- a/src/runtime/StackPtr.hpp +++ b/src/runtime/StackPtr.hpp @@ -7,8 +7,7 @@ namespace runtime { -using StackPtr = - std::vector>::size_type; +using StackPtr = std::vector::size_type; } diff --git a/src/runtime/Upvalue.cpp b/src/runtime/Upvalue.cpp index 4738e95..3707904 100644 --- a/src/runtime/Upvalue.cpp +++ b/src/runtime/Upvalue.cpp @@ -5,23 +5,22 @@ using namespace sexpr; using namespace runtime; Upvalue::Upvalue( - const StackPtr stackPos, - std::vector> &stack + const StackPtr stackPos, std::vector &stack ) : stackPos(stackPos), stack(stack) {} bool Upvalue::isOpen() const { return !ref.has_value(); } -void Upvalue::close() { ref = stack[stackPos].get(); } +void Upvalue::close() { ref = stack[stackPos]; } -const SExpr &Upvalue::get() const { +const SExpr *Upvalue::get() const { if (isOpen()) { return stack[stackPos]; } - return ref->get(); + return ref.value(); } -void Upvalue::set(const SExpr &sexpr) { +void Upvalue::set(const SExpr *sexpr) { if (isOpen()) { stack[stackPos] = sexpr; return; diff --git a/src/runtime/Upvalue.hpp b/src/runtime/Upvalue.hpp index acdcd76..86d98a8 100644 --- a/src/runtime/Upvalue.hpp +++ b/src/runtime/Upvalue.hpp @@ -15,22 +15,19 @@ class Upvalue { private: const StackPtr stackPos; - std::vector> &stack; + std::vector &stack; - std::optional> ref; + std::optional ref; bool isOpen() const; public: - Upvalue( - const StackPtr stackPos, - std::vector> &stack - ); + Upvalue(const StackPtr stackPos, std::vector &stack); void close(); - const sexpr::SExpr &get() const; - void set(const sexpr::SExpr &sexpr); + const sexpr::SExpr *get() const; + void set(const sexpr::SExpr *sexpr); }; bool operator==(const Upvalue &lhs, const Upvalue &rhs); diff --git a/src/runtime/VM.cpp b/src/runtime/VM.cpp index ab363da..f04c4ae 100644 --- a/src/runtime/VM.cpp +++ b/src/runtime/VM.cpp @@ -25,32 +25,32 @@ using namespace fn; using namespace sexpr; using namespace runtime; -const sexpr::SExpr &VM::readConst() { - return closure->get().fn.code.consts[readByte()].get(); +const sexpr::SExpr *VM::readConst() { + return closure.value()->proto->code.consts[readByte()]; } -uint8_t VM::readByte() { return closure->get().fn.code.byteCodes[ip++]; } +uint8_t VM::readByte() { return closure.value()->proto->code.byteCodes[ip++]; } uint16_t VM::readShort() { ip += 2; return (uint16_t)(( - closure->get().fn.code.byteCodes[ip - 2] << 8 | - closure->get().fn.code.byteCodes[ip - 1] + closure.value()->proto->code.byteCodes[ip - 2] << 8 | + closure.value()->proto->code.byteCodes[ip - 1] )); } void VM::call(const uint8_t argc) { const auto &callee = peak(argc); if (isa(callee)) { - callFrames.push_back({closure->get(), bp, ip}); + callFrames.push_back({closure.value(), bp, ip}); ip = 0; bp = stack.size() - argc - 1; closure = cast(callee); - closure->get().assertArity(argc); + closure.value()->assertArity(argc); return; } if (isa(callee)) { - const auto &natFn = cast(callee); - const auto &res = natFn.invoke(stack.end() - argc, argc, *this); - if (!natFn.abandonsCont) { + const auto natFn = cast(callee); + const auto res = natFn->invoke(stack.end() - argc, argc, *this); + if (!natFn->abandonsCont) { stack.erase(stack.end() - argc - 1, stack.end()); stack.push_back(res); } @@ -72,24 +72,22 @@ std::shared_ptr VM::captureUpvalue(StackPtr pos) { return openUpvals[pos]; } -const SExpr &VM::peak(StackPtr distance) { - return stack.rbegin()[distance].get(); -} +const SExpr *VM::peak(StackPtr distance) { return stack.rbegin()[distance]; } -const SExpr &VM::makeList(StackIter start) { +const SExpr *VM::makeList(StackIter start) { if (start == stack.cend()) { return freeStore.alloc(); } return freeStore.alloc(*start, makeList(start + 1)); } -unsigned int VM::unpackList(const SExpr &sexpr) { +unsigned int VM::unpackList(const SExpr *sexpr) { if (isa(sexpr)) { return 0; } - const auto &sexprs = cast(sexpr); - stack.push_back(sexprs.first); - return 1 + unpackList(sexprs.rest); + const auto sexprs = cast(sexpr); + stack.push_back(sexprs->first); + return 1 + unpackList(sexprs->rest); } void VM::reset() { @@ -100,7 +98,7 @@ void VM::reset() { callFrames.clear(); } -const SExpr &VM::exec() { +const SExpr *VM::exec() { void *dispatchTable[] = { &&MAKE_CLOSURE, @@ -121,32 +119,33 @@ const SExpr &VM::exec() { &&JUMP, &&POP_JUMP_IF_FALSE, &&MAKE_LIST, - &&MAKE_NIL}; + &&MAKE_NIL + }; call(0); goto *dispatchTable[readByte()]; -MAKE_CLOSURE : { - const auto &fnAtom = cast(readConst()); +MAKE_CLOSURE: { + const auto fnAtom = cast(readConst()); std::vector> upvalues; - for (unsigned int i{0}; i < fnAtom.numUpvals; ++i) { + for (unsigned int i{0}; i < fnAtom->numUpvals; ++i) { auto isLocal = readByte(); auto idx = readByte(); if (isLocal == 1) { upvalues.push_back(captureUpvalue(bp + idx)); } else { - upvalues.push_back(closure->get().upvalues[idx]); + upvalues.push_back(closure.value()->upvalues[idx]); } } stack.push_back(freeStore.alloc(fnAtom, upvalues)); } goto *dispatchTable[readByte()]; -CALL : { call(readByte()); } +CALL: { call(readByte()); } goto *dispatchTable[readByte()]; -RETURN : { +RETURN: { if (callFrames.size() == 1) [[unlikely]] { const auto res = stack.back(); reset(); @@ -159,13 +158,13 @@ RETURN : { } goto *dispatchTable[readByte()]; -POP_TOP : { stack.pop_back(); } +POP_TOP: { stack.pop_back(); } goto *dispatchTable[readByte()]; -POP : { stack.erase(stack.end() - readByte(), stack.end()); } +POP: { stack.erase(stack.end() - readByte(), stack.end()); } goto *dispatchTable[readByte()]; -CLOSE_UPVALUE : { +CLOSE_UPVALUE: { auto it = openUpvals.find(bp + readByte()); if (it != openUpvals.end()) [[unlikely]] { it->second->close(); @@ -174,11 +173,11 @@ CLOSE_UPVALUE : { } goto *dispatchTable[readByte()]; -LOAD_CONST : { stack.push_back(readConst()); } +LOAD_CONST: { stack.push_back(readConst()); } goto *dispatchTable[readByte()]; -LOAD_SYM : { - const auto &sym = cast(readConst()); +LOAD_SYM: { + const auto sym = cast(readConst()); stack.push_back(env.load(sym)); if (isa(stack.back())) [[unlikely]] { std::stringstream ss; @@ -188,39 +187,39 @@ LOAD_SYM : { } goto *dispatchTable[readByte()]; -DEF_MACRO : { - const auto &sym = cast(readConst()); +DEF_MACRO: { + const auto sym = cast(readConst()); env.defMacro(sym, stack.back()); } goto *dispatchTable[readByte()]; -DEF_SYM : { +DEF_SYM: { env.def(cast(readConst()), stack.back()); stack.back() = freeStore.alloc(); } goto *dispatchTable[readByte()]; -SET_SYM : { +SET_SYM: { env.set(cast(readConst()), stack.back()); stack.back() = freeStore.alloc(); } goto *dispatchTable[readByte()]; -LOAD_UPVALUE : { - stack.push_back(closure->get().upvalues[readByte()]->get()); +LOAD_UPVALUE: { + stack.push_back(closure.value()->upvalues[readByte()]->get()); if (isa(stack.back())) [[unlikely]] { throw std::invalid_argument("Access of an undefined upvalue."); } } goto *dispatchTable[readByte()]; -SET_UPVALUE : { - closure->get().upvalues[readByte()]->set(stack.back()); +SET_UPVALUE: { + closure.value()->upvalues[readByte()]->set(stack.back()); stack.back() = freeStore.alloc(); } goto *dispatchTable[readByte()]; -LOAD_STACK : { +LOAD_STACK: { stack.push_back(stack[bp + readByte()]); if (isa(stack.back())) [[unlikely]] { throw std::invalid_argument("Access of an undefined local."); @@ -228,16 +227,16 @@ LOAD_STACK : { } goto *dispatchTable[readByte()]; -SET_STACK : { +SET_STACK: { stack[bp + readByte()] = stack.back(); stack.back() = freeStore.alloc(); } goto *dispatchTable[readByte()]; -JUMP : { ip += readShort(); } +JUMP: { ip += readShort(); } goto *dispatchTable[readByte()]; -POP_JUMP_IF_FALSE : { +POP_JUMP_IF_FALSE: { auto offset = readShort(); if (!Bool::toBool(stack.back())) { ip += offset; @@ -246,7 +245,7 @@ POP_JUMP_IF_FALSE : { } goto *dispatchTable[readByte()]; -MAKE_LIST : { +MAKE_LIST: { auto gcGuard = freeStore.pauseGC(); const auto start = stack.begin() + bp + readByte(); @@ -256,7 +255,7 @@ MAKE_LIST : { } goto *dispatchTable[readByte()]; -MAKE_NIL : { stack.push_back(freeStore.alloc()); } +MAKE_NIL: { stack.push_back(freeStore.alloc()); } goto *dispatchTable[readByte()]; } @@ -265,8 +264,8 @@ VM::VM() env.defNatFns( {{freeStore.alloc("symbol?"), freeStore.alloc(typePred, 1, false)}, - {freeStore.alloc("gensym"), - freeStore.alloc(genSym, 0, false)}} + {freeStore.alloc("gensym"), freeStore.alloc(genSym, 0, false) + }} ); env.defNatFns( {{freeStore.alloc("number?"), @@ -290,8 +289,8 @@ VM::VM() {freeStore.alloc("/"), freeStore.alloc(dimi, 1, true)}, {freeStore.alloc("abs"), freeStore.alloc(numAbs, 1, false)}, - {freeStore.alloc("modulo"), - freeStore.alloc(numMod, 2, false)}} + {freeStore.alloc("modulo"), freeStore.alloc(numMod, 2, false) + }} ); env.defNatFns( {{freeStore.alloc("string?"), @@ -337,8 +336,8 @@ VM::VM() env.defNatFns( {{freeStore.alloc("eq?"), freeStore.alloc(eq, 2, false)}, {freeStore.alloc("eqv?"), freeStore.alloc(eqv, 2, false)}, - {freeStore.alloc("equal?"), - freeStore.alloc(equal, 2, false)}} + {freeStore.alloc("equal?"), freeStore.alloc(equal, 2, false)} + } ); env.defNatFns({ {freeStore.alloc("procedure?"), @@ -349,9 +348,9 @@ VM::VM() }); } -const SExpr &VM::eval(const Prototype &main, bool disableGC) { +const SExpr *VM::eval(const Prototype *main, bool disableGC) { closure = freeStore.alloc(main); - stack.push_back(closure->get()); + stack.push_back(closure.value()); try { if (disableGC) { return exec(); diff --git a/src/runtime/VM.hpp b/src/runtime/VM.hpp index 87d6f27..a758334 100644 --- a/src/runtime/VM.hpp +++ b/src/runtime/VM.hpp @@ -36,24 +36,24 @@ class VM { private: code::InstrPtr ip; runtime::StackPtr bp; - std::optional> closure; + std::optional closure; - std::vector> stack; + std::vector stack; std::vector callFrames; std::unordered_map> openUpvals; - const sexpr::SExpr &readConst(); + const sexpr::SExpr *readConst(); uint8_t readByte(); uint16_t readShort(); void call(const uint8_t argc); std::shared_ptr captureUpvalue(StackPtr pos); - const sexpr::SExpr &peak(StackPtr distance); - const sexpr::SExpr &makeList(StackIter start); - unsigned int unpackList(const sexpr::SExpr &sexpr); + const sexpr::SExpr *peak(StackPtr distance); + const sexpr::SExpr *makeList(StackIter start); + unsigned int unpackList(const sexpr::SExpr *sexpr); void reset(); - const sexpr::SExpr &exec(); + const sexpr::SExpr *exec(); public: VM(); @@ -61,8 +61,8 @@ class VM { FreeStore freeStore; Env env; - const sexpr::SExpr & - eval(const sexpr::Prototype &main, bool disableGC = false); + const sexpr::SExpr * + eval(const sexpr::Prototype *main, bool disableGC = false); }; } // namespace runtime diff --git a/src/sexpr/Atom.cpp b/src/sexpr/Atom.cpp index eaf8907..eaf760a 100644 --- a/src/sexpr/Atom.cpp +++ b/src/sexpr/Atom.cpp @@ -4,8 +4,8 @@ using namespace sexpr; Atom::Atom(SExpr::Type type) : SExpr(type) {} -bool Atom::classOf(const SExpr &sExpr) { - return sExpr.type != SExpr::Type::SEXPRS; +bool Atom::classOf(const SExpr *sExpr) { + return sExpr->type != SExpr::Type::SEXPRS; } std::string Atom::getTypeName() { return ""; } diff --git a/src/sexpr/Atom.hpp b/src/sexpr/Atom.hpp index 8c827dc..471ea6b 100644 --- a/src/sexpr/Atom.hpp +++ b/src/sexpr/Atom.hpp @@ -9,7 +9,7 @@ class Atom : public SExpr { public: explicit Atom(SExpr::Type type); - static bool classOf(const SExpr &sExpr); + static bool classOf(const SExpr *sExpr); static std::string getTypeName(); }; diff --git a/src/sexpr/Bool.cpp b/src/sexpr/Bool.cpp index b27285f..3be5336 100644 --- a/src/sexpr/Bool.cpp +++ b/src/sexpr/Bool.cpp @@ -21,17 +21,17 @@ bool Bool::equals(const SExpr &other) const { return false; } -Bool &Bool::getInstance(const Bool::ValueType val) { +Bool *Bool::getInstance(const Bool::ValueType val) { if (val) { - return Bool::_true; + return &Bool::_true; } - return Bool::_false; + return &Bool::_false; } -bool Bool::toBool(const SExpr &sExpr) { return &sExpr != &_false; } +bool Bool::toBool(const SExpr *sExpr) { return sExpr != &_false; } -bool Bool::classOf(const SExpr &sExpr) { - return sExpr.type == SExpr::Type::BOOL; +bool Bool::classOf(const SExpr *sExpr) { + return sExpr->type == SExpr::Type::BOOL; } std::string Bool::getTypeName() { return ""; } diff --git a/src/sexpr/Bool.hpp b/src/sexpr/Bool.hpp index fbe39d5..17de2a8 100644 --- a/src/sexpr/Bool.hpp +++ b/src/sexpr/Bool.hpp @@ -24,9 +24,9 @@ class Bool final : public Atom { public: const ValueType val; - static Bool &getInstance(const ValueType val); - static bool toBool(const SExpr &sExpr); - static bool classOf(const SExpr &sExpr); + static Bool *getInstance(const ValueType val); + static bool toBool(const SExpr *sExpr); + static bool classOf(const SExpr *sExpr); static std::string getTypeName(); }; diff --git a/src/sexpr/Cast.cpp b/src/sexpr/Cast.cpp index 0c894b4..fb4ff70 100644 --- a/src/sexpr/Cast.cpp +++ b/src/sexpr/Cast.cpp @@ -8,9 +8,11 @@ namespace sexpr { -template bool isa(const SExpr &f) { return T::classOf(f); } +template bool isa(const SExpr *f) { return T::classOf(f); } -template void assertType(const SExpr &f) { +template bool isa(const SExpr &f) { return T::classOf(&f); } + +template void assertType(const SExpr *f) { if (!isa(f)) { std::stringstream ss; ss << "Mismatched types. Expected " << T::getTypeName() << ", but got " << f @@ -19,8 +21,12 @@ template void assertType(const SExpr &f) { } } +template void assertType(const SExpr &f) { + return assertType(&f); +} + template -void assertType(const SExpr &f) { +void assertType(const SExpr *f) { if (!(isa(f) || isa(f) || (isa(f) || ...))) { std::string typeName = "one of: (" + First::getTypeName() + ", " + Next::getTypeName(); @@ -32,11 +38,18 @@ void assertType(const SExpr &f) { } } -template const T &cast(const SExpr &f) { +template +void assertType(const SExpr &f) { + return assertType(&f); +} + +template const T *cast(const SExpr *f) { assertType(f); - return static_cast(f); + return static_cast(f); } +template const T &cast(const SExpr &f) { return *cast(&f); } + } // namespace sexpr #endif diff --git a/src/sexpr/Closure.cpp b/src/sexpr/Closure.cpp index e2e02a4..77d329a 100644 --- a/src/sexpr/Closure.cpp +++ b/src/sexpr/Closure.cpp @@ -15,7 +15,7 @@ std::ostream &Closure::serialize(std::ostream &o) const { bool Closure::equals(const SExpr &other) const { if (isa(other)) { const auto &closure = cast(other); - if (fn != closure.fn) { + if (proto != closure.proto) { return false; } return std::equal( @@ -29,20 +29,20 @@ bool Closure::equals(const SExpr &other) const { return false; } -Closure::Closure(const Prototype &fnAtom) - : Atom(SExpr::Type::CLOSURE), fn(fnAtom) {} +Closure::Closure(const Prototype *proto) + : Atom(SExpr::Type::CLOSURE), proto(proto) {} Closure::Closure( - const Prototype &fnAtom, - const std::vector> upvalues + const Prototype *proto, const std::vector> upvalues ) - : Atom(SExpr::Type::CLOSURE), fn(fnAtom), upvalues(upvalues) {} + : Atom(SExpr::Type::CLOSURE), proto(proto), upvalues(upvalues) {} void Closure::assertArity(const uint8_t argc) const { - if ((!fn.variadic && fn.arity != argc) || (fn.variadic && argc < fn.arity)) { + if ((!proto->variadic && proto->arity != argc) || + (proto->variadic && argc < proto->arity)) { std::stringstream ss; - ss << "Invalid number of arguments. Expected " << unsigned(fn.arity); - if (fn.variadic) { + ss << "Invalid number of arguments. Expected " << unsigned(proto->arity); + if (proto->variadic) { ss << " or more"; } ss << " arguments, but got " << unsigned(argc) << "."; @@ -54,12 +54,12 @@ std::ostream &Closure::dissassemble(std::ostream &o) const { const unsigned int PADDING_WIDTH = 4; o << ", instance of:" << std::endl << std::setw(PADDING_WIDTH) << ""; - fn.dissassemble(o); + proto->dissassemble(o); return o; } -bool Closure::classOf(const SExpr &sExpr) { - return sExpr.type == SExpr::Type::CLOSURE; +bool Closure::classOf(const SExpr *sExpr) { + return sExpr->type == SExpr::Type::CLOSURE; } std::string Closure::getTypeName() { return ""; } diff --git a/src/sexpr/Closure.hpp b/src/sexpr/Closure.hpp index 1ce0e08..6803169 100644 --- a/src/sexpr/Closure.hpp +++ b/src/sexpr/Closure.hpp @@ -16,19 +16,19 @@ class Closure final : public Atom { bool equals(const SExpr &other) const override; public: - explicit Closure(const Prototype &fnAtom); + explicit Closure(const Prototype *proto); Closure( - const Prototype &fnAtom, + const Prototype *proto, const std::vector> upvalues ); - const Prototype &fn; + const Prototype *proto; const std::vector> upvalues; void assertArity(const uint8_t arity) const; std::ostream &dissassemble(std::ostream &o) const; - static bool classOf(const SExpr &sExpr); + static bool classOf(const SExpr *sExpr); static std::string getTypeName(); }; diff --git a/src/sexpr/NatFn.cpp b/src/sexpr/NatFn.cpp index 8f652b8..fbf101e 100644 --- a/src/sexpr/NatFn.cpp +++ b/src/sexpr/NatFn.cpp @@ -31,7 +31,7 @@ NatFn::NatFn( variadic(variadic), abandonsCont(abandonsCont) {} -const SExpr &NatFn::invoke(StackIter params, const uint8_t argc, VM &vm) const { +const SExpr *NatFn::invoke(StackIter params, const uint8_t argc, VM &vm) const { if ((!variadic && argc != arity) || (variadic && argc < arity)) { std::stringstream ss; ss << "Invalid number of arguments. Expected " << unsigned(arity); @@ -44,8 +44,8 @@ const SExpr &NatFn::invoke(StackIter params, const uint8_t argc, VM &vm) const { return fn(params, argc, vm); } -bool NatFn::classOf(const SExpr &sExpr) { - return sExpr.type == SExpr::Type::NATIVE_FN; +bool NatFn::classOf(const SExpr *sExpr) { + return sExpr->type == SExpr::Type::NATIVE_FN; } std::string NatFn::getTypeName() { return ""; } diff --git a/src/sexpr/NatFn.hpp b/src/sexpr/NatFn.hpp index cd03503..a84e069 100644 --- a/src/sexpr/NatFn.hpp +++ b/src/sexpr/NatFn.hpp @@ -29,10 +29,10 @@ class NatFn final : public Atom { const bool variadic; const bool abandonsCont; - const SExpr & + const SExpr * invoke(runtime::StackIter params, const uint8_t argc, runtime::VM &vm) const; - static bool classOf(const SExpr &sExpr); + static bool classOf(const SExpr *sExpr); static std::string getTypeName(); }; diff --git a/src/sexpr/Nil.cpp b/src/sexpr/Nil.cpp index 58c8902..b0f4596 100644 --- a/src/sexpr/Nil.cpp +++ b/src/sexpr/Nil.cpp @@ -14,8 +14,10 @@ bool Nil::equals(const SExpr &other) const { return isa(other); } Nil Nil::instance; -Nil &Nil::getInstance() { return instance; } +Nil *Nil::getInstance() { return &instance; } -bool Nil::classOf(const SExpr &sExpr) { return sExpr.type == SExpr::Type::NIL; } +bool Nil::classOf(const SExpr *sExpr) { + return sExpr->type == SExpr::Type::NIL; +} std::string Nil::getTypeName() { return "()"; } diff --git a/src/sexpr/Nil.hpp b/src/sexpr/Nil.hpp index f84398c..edea60f 100644 --- a/src/sexpr/Nil.hpp +++ b/src/sexpr/Nil.hpp @@ -16,8 +16,8 @@ class Nil final : public Atom { static Nil instance; public: - static Nil &getInstance(); - static bool classOf(const SExpr &sExpr); + static Nil *getInstance(); + static bool classOf(const SExpr *sExpr); static std::string getTypeName(); }; diff --git a/src/sexpr/Num.cpp b/src/sexpr/Num.cpp index d27c95f..e5b826d 100644 --- a/src/sexpr/Num.cpp +++ b/src/sexpr/Num.cpp @@ -23,6 +23,8 @@ bool Num::equals(const SExpr &other) const { Num::Num(const Num::ValueType val) : Atom(SExpr::Type::NUM), val(val) {} -bool Num::classOf(const SExpr &sExpr) { return sExpr.type == SExpr::Type::NUM; } +bool Num::classOf(const SExpr *sExpr) { + return sExpr->type == SExpr::Type::NUM; +} std::string Num::getTypeName() { return ""; } diff --git a/src/sexpr/Num.hpp b/src/sexpr/Num.hpp index a058cfb..abac46b 100644 --- a/src/sexpr/Num.hpp +++ b/src/sexpr/Num.hpp @@ -19,7 +19,7 @@ class Num final : public Atom { const ValueType val; - static bool classOf(const SExpr &sExpr); + static bool classOf(const SExpr *sExpr); static std::string getTypeName(); }; diff --git a/src/sexpr/Prototype.cpp b/src/sexpr/Prototype.cpp index b77f93b..4c9efb9 100644 --- a/src/sexpr/Prototype.cpp +++ b/src/sexpr/Prototype.cpp @@ -28,16 +28,16 @@ std::ostream &Prototype::dissassemble(std::ostream &o) const { << ", upvalues: " << numUpvals << ">" << std::endl << code << std::endl; for (auto i = code.consts.cbegin(); i != code.consts.end(); ++i) { - if (isa(i->get())) { - const auto &fnAtom = cast(i->get()); - fnAtom.dissassemble(o); + if (isa(*i)) { + const auto fnAtom = cast(*i); + fnAtom->dissassemble(o); } } return o; } -bool Prototype::classOf(const SExpr &sExpr) { - return sExpr.type == SExpr::Type::PROTO; +bool Prototype::classOf(const SExpr *sExpr) { + return sExpr->type == SExpr::Type::PROTO; } std::string Prototype::getTypeName() { return ""; } diff --git a/src/sexpr/Prototype.hpp b/src/sexpr/Prototype.hpp index 5c2e315..9688e2e 100644 --- a/src/sexpr/Prototype.hpp +++ b/src/sexpr/Prototype.hpp @@ -26,7 +26,7 @@ class Prototype final : public Atom { std::ostream &dissassemble(std::ostream &o) const; - static bool classOf(const SExpr &sExpr); + static bool classOf(const SExpr *sExpr); static std::string getTypeName(); }; diff --git a/src/sexpr/SExpr.cpp b/src/sexpr/SExpr.cpp index a667c9b..40e6db5 100644 --- a/src/sexpr/SExpr.cpp +++ b/src/sexpr/SExpr.cpp @@ -7,7 +7,7 @@ SExpr::SExpr(SExpr::Type type) : type(type) {} SExpr::~SExpr() {} -bool SExpr::classOf([[maybe_unused]] const SExpr &sExpr) { return true; } +bool SExpr::classOf([[maybe_unused]] const SExpr *sExpr) { return true; } std::string SExpr::getTypeName() { return ""; } diff --git a/src/sexpr/SExpr.hpp b/src/sexpr/SExpr.hpp index 5280271..b679c26 100644 --- a/src/sexpr/SExpr.hpp +++ b/src/sexpr/SExpr.hpp @@ -38,7 +38,7 @@ class SExpr { SExpr(const SExpr &&) = delete; SExpr &operator=(const SExpr &) = delete; - static bool classOf(const SExpr &sExpr); + static bool classOf(const SExpr *sExpr); static std::string getTypeName(); }; diff --git a/src/sexpr/SExprs.cpp b/src/sexpr/SExprs.cpp index e710a77..c812c3c 100644 --- a/src/sexpr/SExprs.cpp +++ b/src/sexpr/SExprs.cpp @@ -14,29 +14,29 @@ std::ostream &SExprs::serialize(std::ostream &o) const { } std::ostream &SExprs::_serialize(std::ostream &o) const { - first.serialize(o); + first->serialize(o); if (isa(rest)) { return o << ")"; } else if (isa(rest)) { - return rest.serialize(o << " . ") << ")"; + return rest->serialize(o << " . ") << ")"; } - const auto &sexprs = cast(rest); - return sexprs._serialize(o << " "); + const auto sexprs = cast(rest); + return sexprs->_serialize(o << " "); } bool SExprs::equals(const SExpr &other) const { if (isa(other)) { const auto &sExprs = cast(other); - return first.equals(sExprs.first) && rest.equals(sExprs.rest); + return first->equals(*sExprs.first) && rest->equals(*sExprs.rest); } return false; } -SExprs::SExprs(const SExpr &first, const SExpr &rest) +SExprs::SExprs(const SExpr *first, const SExpr *rest) : SExpr(SExpr::Type::SEXPRS), first(first), rest(rest) {} -bool SExprs::classOf(const SExpr &sExpr) { - return sExpr.type == SExpr::Type::SEXPRS; +bool SExprs::classOf(const SExpr *sExpr) { + return sExpr->type == SExpr::Type::SEXPRS; } std::string SExprs::getTypeName() { return ""; } diff --git a/src/sexpr/SExprs.hpp b/src/sexpr/SExprs.hpp index 0ba688f..17d761a 100644 --- a/src/sexpr/SExprs.hpp +++ b/src/sexpr/SExprs.hpp @@ -16,12 +16,12 @@ class SExprs final : public SExpr { bool equals(const SExpr &other) const override; public: - const SExpr &first; - const SExpr &rest; + const SExpr *first; + const SExpr *rest; - SExprs(const SExpr &first, const SExpr &rest); + SExprs(const SExpr *first, const SExpr *rest); - static bool classOf(const SExpr &sExpr); + static bool classOf(const SExpr *sExpr); static std::string getTypeName(); }; diff --git a/src/sexpr/String.cpp b/src/sexpr/String.cpp index 9e1b488..40711a2 100644 --- a/src/sexpr/String.cpp +++ b/src/sexpr/String.cpp @@ -24,8 +24,8 @@ bool String::equals(const SExpr &other) const { String::String(const String::ValueType literal) : Atom(SExpr::Type::STR), val(literal), escaped(escape(literal)) {} -bool String::classOf(const SExpr &sExpr) { - return sExpr.type == SExpr::Type::STR; +bool String::classOf(const SExpr *sExpr) { + return sExpr->type == SExpr::Type::STR; } std::string String::getTypeName() { return ""; } diff --git a/src/sexpr/String.hpp b/src/sexpr/String.hpp index 5691ebc..7d40f45 100644 --- a/src/sexpr/String.hpp +++ b/src/sexpr/String.hpp @@ -24,7 +24,7 @@ class String final : public Atom { const ValueType val; const ValueType escaped; - static bool classOf(const SExpr &sExpr); + static bool classOf(const SExpr *sExpr); static std::string getTypeName(); }; diff --git a/src/sexpr/Sym.cpp b/src/sexpr/Sym.cpp index a009ef9..746b0db 100644 --- a/src/sexpr/Sym.cpp +++ b/src/sexpr/Sym.cpp @@ -14,15 +14,17 @@ bool Sym::equals(const SExpr &other) const { return false; } -size_t Sym::HashFunction::operator()(const Sym &sym) const { return sym.hash; } +size_t Sym::HashFunction::operator()(const Sym *sym) const { return sym->hash; } -bool Sym::EqualFunction::operator()(const Sym &lhs, const Sym &rhs) const { - return lhs.hash == rhs.hash; +bool Sym::EqualFunction::operator()(const Sym *lhs, const Sym *rhs) const { + return lhs->hash == rhs->hash; } Sym::Sym(const ValueType val) : Atom(SExpr::Type::SYM), val(val), hash(std::hash()(val)) {} -bool Sym::classOf(const SExpr &sExpr) { return sExpr.type == SExpr::Type::SYM; } +bool Sym::classOf(const SExpr *sExpr) { + return sExpr->type == SExpr::Type::SYM; +} std::string Sym::getTypeName() { return ""; } diff --git a/src/sexpr/Sym.hpp b/src/sexpr/Sym.hpp index 75656ad..69ab22a 100644 --- a/src/sexpr/Sym.hpp +++ b/src/sexpr/Sym.hpp @@ -15,12 +15,12 @@ class Sym final : public Atom { public: class HashFunction { public: - size_t operator()(const Sym &sym) const; + size_t operator()(const Sym *sym) const; }; class EqualFunction { public: - bool operator()(const Sym &lhs, const Sym &rhs) const; + bool operator()(const Sym *lhs, const Sym *rhs) const; }; using ValueType = std::string; @@ -30,7 +30,7 @@ class Sym final : public Atom { explicit Sym(const ValueType val); - static bool classOf(const SExpr &sExpr); + static bool classOf(const SExpr *sExpr); static std::string getTypeName(); }; diff --git a/src/sexpr/Undefined.cpp b/src/sexpr/Undefined.cpp index 2404982..35ec514 100644 --- a/src/sexpr/Undefined.cpp +++ b/src/sexpr/Undefined.cpp @@ -16,10 +16,10 @@ bool Undefined::equals(const SExpr &other) const { Undefined Undefined::instance; -Undefined &Undefined::getInstance() { return instance; } +Undefined *Undefined::getInstance() { return &instance; } -bool Undefined::classOf(const SExpr &sExpr) { - return sExpr.type == SExpr::Type::UNDEFINED; +bool Undefined::classOf(const SExpr *sExpr) { + return sExpr->type == SExpr::Type::UNDEFINED; } std::string Undefined::getTypeName() { return "#"; } diff --git a/src/sexpr/Undefined.hpp b/src/sexpr/Undefined.hpp index 8588306..fdd7b94 100644 --- a/src/sexpr/Undefined.hpp +++ b/src/sexpr/Undefined.hpp @@ -15,8 +15,8 @@ class Undefined final : public Atom { static Undefined instance; public: - static Undefined &getInstance(); - static bool classOf(const SExpr &sExpr); + static Undefined *getInstance(); + static bool classOf(const SExpr *sExpr); static std::string getTypeName(); };