#include "value.hpp" #include #include #include using namespace std; template T pop_and_front(deque &dq) { T t = dq.front(); dq.pop_front(); return t; } TEST_CASE("Lexer lexes doubles correctly", "[Lexer]") { SECTION("double and negative syntax") { Lexer l("(1.0 0.1 -.1 -1. . - -. .-)"); REQUIRE(l.next() == Token({TokenType::OpenParen, nullopt})); REQUIRE(l.next() == Token({TokenType::Double, 1.0})); REQUIRE(l.next() == Token({TokenType::Double, 0.1})); REQUIRE(l.next() == Token({TokenType::Double, -0.1})); REQUIRE(l.next() == Token({TokenType::Double, -1.0})); REQUIRE(l.next() == Token({TokenType::Symbol, "."})); REQUIRE(l.next() == Token({TokenType::Symbol, "-"})); REQUIRE(l.next() == Token({TokenType::Symbol, "-."})); REQUIRE(l.next() == Token({TokenType::Symbol, ".-"})); REQUIRE(l.next() == Token({TokenType::CloseParen, nullopt})); } } TEST_CASE("Parser parses correctly", "[Parser]") { SECTION("hello world") { Parser p (Lexer("(print \"hello world\")")); auto dq = get(*p.next()).list; REQUIRE(get(pop_and_front(dq)).value == "PRINT"); REQUIRE(get(pop_and_front(dq)).value == "hello world"); } SECTION("doubles") { Parser p (Lexer("(1.0 0.1 -.1 -1. . - -. .-)")); auto dq = get(*p.next()).list; REQUIRE(get(pop_and_front(dq)).value == 1.0); REQUIRE(get(pop_and_front(dq)).value == 0.1); REQUIRE(get(pop_and_front(dq)).value == -0.1); REQUIRE(get(pop_and_front(dq)).value == -1.0); REQUIRE(get(pop_and_front(dq)).value == "."); REQUIRE(get(pop_and_front(dq)).value == "-"); REQUIRE(get(pop_and_front(dq)).value == "-."); REQUIRE(get(pop_and_front(dq)).value == ".-"); } SECTION("Nested lists") { Parser p(Lexer("((((0) (1) (2) (3))))")); auto l0 = get(*p.next()).list; auto l1 = get(pop_and_front(l0)).list; auto l2 = get(pop_and_front(l1)).list; auto l20 = get(pop_and_front(l2)).list; auto l21 = get(pop_and_front(l2)).list; auto l22 = get(pop_and_front(l2)).list; auto l23 = get(pop_and_front(l2)).list; REQUIRE(get(pop_and_front(l20)).value == 0); REQUIRE(get(pop_and_front(l21)).value == 1); REQUIRE(get(pop_and_front(l22)).value == 2); REQUIRE(get(pop_and_front(l23)).value == 3); } SECTION("Nested quotes") { Parser p(Lexer("((('a 'b 'c 'd)))")); auto l0 = get(*p.next()).list; auto l1 = get(pop_and_front(l0)).list; auto l2 = get(pop_and_front(l1)).list; auto l20 = get(pop_and_front(l2)).list; auto l21 = get(pop_and_front(l2)).list; auto l22 = get(pop_and_front(l2)).list; auto l23 = get(pop_and_front(l2)).list; REQUIRE(get(pop_and_front(l20)).value == "QUOTE"); REQUIRE(get(pop_and_front(l20)).value == "A"); REQUIRE(get(pop_and_front(l21)).value == "QUOTE"); REQUIRE(get(pop_and_front(l21)).value == "B"); REQUIRE(get(pop_and_front(l22)).value == "QUOTE"); REQUIRE(get(pop_and_front(l22)).value == "C"); REQUIRE(get(pop_and_front(l23)).value == "QUOTE"); REQUIRE(get(pop_and_front(l23)).value == "D"); } }