diff --git a/src/main.cpp b/src/main.cpp index 6630843..31b266d 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -16,26 +16,26 @@ void parse_options(int argc, char *argv[]) { { std::istringstream ins(rest); std::string cur; - while (std::getline(ins, cur, ' ')) { split.emplace_back(cur); } + while (std::getline(ins, cur, ':')) { split.emplace_back(cur); } } if (split.empty()) throw std::invalid_argument("Can't parse argument " + arg); if (split.at(0) == "log") { - if (split.size() != 3) throw std::invalid_argument("Log options must be in format --log TAG LEVEL, instead have: " + arg); + if (split.size() != 3) throw std::invalid_argument("Log options must be in format --log:TAG:LEVEL, instead have: " + arg); try { Logger::set_level(split.at(1), std::stoi(split.at(2))); - } catch (...) { throw std::invalid_argument("Log options must be in format --log TAG LEVEL, instead have: " + arg); } + } catch (...) { throw std::invalid_argument("Log options must be in format --log:TAG:LEVEL, instead have: " + arg); } } else if (split.size() == 1) { std::string str = split.at(0); - if (str.back() != '+' || str.back() != '-') { + if (str.back() != '+' && str.back() != '-') { throw std::invalid_argument("Bool options must be in format --option[+/-], instead have" + arg); } Options::set_bool(str.substr(0, str.length() - 1), str.back() == '+' ? true : false); } else if (split.size() == 2) { try { Options::set_int(split.at(0), std::stoi(split.at(1))); - } catch (...) { throw std::invalid_argument("Log options must be in format --log TAG LEVEL, instead have: " + arg); } + } catch (...) { throw std::invalid_argument("Log options must be in format --log:TAG:LEVEL, instead have: " + arg); } } else { throw std::invalid_argument("Can't parse argument " + arg); } diff --git a/src/vm/include/Command.h b/src/vm/include/Command.h index c2f0a06..3dc794b 100644 --- a/src/vm/include/Command.h +++ b/src/vm/include/Command.h @@ -39,16 +39,23 @@ namespace Command { CONS = 21, LDG = 22, + CAR = 23, + CDR = 24, + EQ = 25, + LT = 26, + GT = 27 }; static inline std::unordered_map str_to_cmd{ - {"NIL", 1}, {"LDC", 2}, {"LD", 3}, {"SEL", 4}, {"JOIN", 5}, {"LDF", 6}, {"AP", 7}, {"RET", 8}, - {"DUM", 9}, {"RAP", 10}, {"STOP", 11}, {"ATOM", 12}, {"ADD", 13}, {"SUB", 14}, {"READCHAR", 15}, {"PUTCHAR", 16}, - {"PUTNUM", 17}, {"EVAL", 18}, {"PRINT", 19}, {"READ", 20}, {"CONS", 21}, {"LDG", 22}}; + {"NIL", 1}, {"LDC", 2}, {"LD", 3}, {"SEL", 4}, {"JOIN", 5}, {"LDF", 6}, {"AP", 7}, + {"RET", 8}, {"DUM", 9}, {"RAP", 10}, {"STOP", 11}, {"ATOM", 12}, {"ADD", 13}, {"SUB", 14}, + {"READCHAR", 15}, {"PUTCHAR", 16}, {"PUTNUM", 17}, {"EVAL", 18}, {"PRINT", 19}, {"READ", 20}, {"CONS", 21}, + {"LDG", 22}, {"CAR", 23}, {"CDR", 24}, {"EQ", 25}, {"LT", 26}, {"GT", 27}}; static inline std::unordered_map cmd_to_str{ - {1, "NIL"}, {2, "LDC"}, {3, "LD"}, {4, "SEL"}, {5, "JOIN"}, {6, "LDF"}, {7, "AP"}, {8, "RET"}, - {9, "DUM"}, {10, "RAP"}, {11, "STOP"}, {12, "ATOM"}, {13, "ADD"}, {14, "SUB"}, {15, "READCHAR"}, {16, "PUTCHAR"}, - {17, "PUTNUM"}, {18, "EVAL"}, {19, "PRINT"}, {20, "READ"}, {21, "CONS"}, {22, "LDG"}}; + {1, "NIL"}, {2, "LDC"}, {3, "LD"}, {4, "SEL"}, {5, "JOIN"}, {6, "LDF"}, {7, "AP"}, + {8, "RET"}, {9, "DUM"}, {10, "RAP"}, {11, "STOP"}, {12, "ATOM"}, {13, "ADD"}, {14, "SUB"}, + {15, "READCHAR"}, {16, "PUTCHAR"}, {17, "PUTNUM"}, {18, "EVAL"}, {19, "PRINT"}, {20, "READ"}, {21, "CONS"}, + {22, "LDG"}, {23, "CAR"}, {24, "CDR"}, {25, "EQ"}, {26, "LT"}, {27, "GT"}}; static inline Handle make_cmd(CellValType cmd) { if (Options::get_bool("command_strs")) { diff --git a/src/vm/src/Compiler.cpp b/src/vm/src/Compiler.cpp index b33625d..61ba2c0 100644 --- a/src/vm/src/Compiler.cpp +++ b/src/vm/src/Compiler.cpp @@ -12,7 +12,8 @@ using namespace Command; -static std::unordered_map builtins{{"+", ADD}}; +static std::unordered_map builtins{{"+", ADD}, {"-", SUB}, {"cons", CONS}, {"car", CAR}, + {"cdr", CDR}, {"=", EQ}, {">", GT}, {"<", LT}}; Handle Compiler::compile(const Handle &src, Handle fake_env, const Handle &suffix) { Handle out; diff --git a/src/vm/src/Parser.cpp b/src/vm/src/Parser.cpp index 919dc6a..9193909 100644 --- a/src/vm/src/Parser.cpp +++ b/src/vm/src/Parser.cpp @@ -36,7 +36,8 @@ Handle Parser::parseExpr() { return out; } else { token = _tokenizer.getNext(); - if (token.find_first_not_of("-0123456789") == std::string::npos) { + if (token.find_first_not_of("0123456789") == std::string::npos || + (token.length() > 1 && token.at(0) == '0' && token.find_first_not_of("0123456789", 1) == std::string::npos)) { CellValType val = std::stoi(token); return Handle::makeNumCell(val); } else { @@ -45,7 +46,7 @@ Handle Parser::parseExpr() { } } - assert(false); + return Handle::cons(nullptr, nullptr); } std::string Parser::Tokenizer::getNext() { std::string ret = std::move(_tokens.front()); @@ -58,7 +59,7 @@ std::string_view Parser::Tokenizer::peek() const { return _tokens.front(); } void Parser::Tokenizer::load(std::string_view input) { std::string_view::size_type curpos = input.find_first_not_of(' '); - static const std::string alnum = "-+0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"; + static const std::string alnum = "-+> a1 ? 1 : 0); + } else if (poppedCmd == CAR) { + _s.push(_s.pop().car()); + } else if (poppedCmd == CDR) { + _s.push(_s.pop().cdr()); } else if (poppedCmd == CONS) { Handle h1 = _s.pop(); Handle h2 = _s.pop();