Compare commits
	
		
			2 Commits
		
	
	
		
			d0eae97771
			...
			a40487f84d
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 
						 | 
					a40487f84d | ||
| 
						 | 
					47f33f3dc0 | 
@@ -1,6 +1,10 @@
 | 
			
		||||
cmake_minimum_required(VERSION 3.16)
 | 
			
		||||
project(lispy_stuff)
 | 
			
		||||
 | 
			
		||||
# we'll use a recent c++ standard.
 | 
			
		||||
set(CMAKE_CXX_STANDARD 23)
 | 
			
		||||
set(CMAKE_CXX_STANDARD_REQUIRED ON)
 | 
			
		||||
 | 
			
		||||
# we'll use catch2 as testing library.
 | 
			
		||||
include(FetchContent)
 | 
			
		||||
FetchContent_Declare(
 | 
			
		||||
@@ -14,17 +18,21 @@ include(Catch)
 | 
			
		||||
 | 
			
		||||
set(HEADER_FILES src/include/lex.hpp)
 | 
			
		||||
set(SOURCE_FILES src/lex.cpp)
 | 
			
		||||
set(CXX_WARNING_FLAGS -Wall -Wextra -Wpedantic -pedantic -Werror)
 | 
			
		||||
 | 
			
		||||
# we're not actually shipping a library yet,
 | 
			
		||||
# this is so we don't have to compile twice for main and tests.
 | 
			
		||||
add_library(libmash STATIC ${SOURCE_FILES} ${HEADER_FILES})
 | 
			
		||||
target_include_directories(libmash PUBLIC src/include/)
 | 
			
		||||
target_compile_options(libmash PRIVATE ${CXX_WARNING_FLAGS})
 | 
			
		||||
 | 
			
		||||
# Main target
 | 
			
		||||
add_executable(main src/main.cpp)
 | 
			
		||||
target_link_libraries(main libmash)
 | 
			
		||||
target_compile_options(main PRIVATE ${CXX_WARNING_FLAGS})
 | 
			
		||||
 | 
			
		||||
# tests
 | 
			
		||||
add_executable(test src/tests/test.cpp)
 | 
			
		||||
target_link_libraries(test PRIVATE libmash Catch2::Catch2WithMain)
 | 
			
		||||
target_compile_options(test PRIVATE ${CXX_WARNING_FLAGS})
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -3,6 +3,7 @@
 | 
			
		||||
#include <vector>
 | 
			
		||||
#include <stdint.h>
 | 
			
		||||
#include <variant>
 | 
			
		||||
#include <optional>
 | 
			
		||||
 | 
			
		||||
enum TokenType {
 | 
			
		||||
    OpenParen,
 | 
			
		||||
@@ -18,7 +19,7 @@ enum TokenType {
 | 
			
		||||
// Plain Old Data
 | 
			
		||||
struct Token {
 | 
			
		||||
    enum TokenType type;
 | 
			
		||||
    std::variant<int64_t, double, std::string> value;
 | 
			
		||||
    std::optional<std::variant<int64_t, double, std::string>> value;
 | 
			
		||||
};
 | 
			
		||||
bool operator==(Token const& one, Token const& other);
 | 
			
		||||
std::ostream &operator<<(std::ostream &os, Token const &t);
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										16
									
								
								src/lex.cpp
									
									
									
									
									
								
							
							
						
						
									
										16
									
								
								src/lex.cpp
									
									
									
									
									
								
							@@ -12,10 +12,10 @@ std::ostream &operator<<(std::ostream &os, Token const &t) {
 | 
			
		||||
    case TokenType::OpenParen: os << "OpenParen)"; break;
 | 
			
		||||
    case TokenType::CloseParen: os << "CloseParen)"; break;
 | 
			
		||||
    case TokenType::Dollar: os << "Dollar)"; break;
 | 
			
		||||
    case TokenType::Symbol: os << "Symbol, " << get<string>(t.value) << ")"; break;
 | 
			
		||||
    case TokenType::String: os << "String, \"" << get<string>(t.value) << "\")"; break;
 | 
			
		||||
    case TokenType::Int: os << "Int, " << get<int64_t>(t.value) << ")"; break;
 | 
			
		||||
    case TokenType::Double: os << "Double, " << get<double>(t.value) << ")"; break;
 | 
			
		||||
    case TokenType::Symbol: os << "Symbol, " << get<string>(*t.value) << ")"; break;
 | 
			
		||||
    case TokenType::String: os << "String, \"" << get<string>(*t.value) << "\")"; break;
 | 
			
		||||
    case TokenType::Int: os << "Int, " << get<int64_t>(*t.value) << ")"; break;
 | 
			
		||||
    case TokenType::Double: os << "Double, " << get<double>(*t.value) << ")"; break;
 | 
			
		||||
    case TokenType::End: os << "END)"; break;
 | 
			
		||||
    default:
 | 
			
		||||
        os << ")";
 | 
			
		||||
@@ -131,14 +131,14 @@ Token Lexer::next() {
 | 
			
		||||
        // character while at EOF, even if we have exhausted the stream.
 | 
			
		||||
        char c = ss.get();
 | 
			
		||||
        if (ss.eof())
 | 
			
		||||
            return {TokenType::End};
 | 
			
		||||
            return {TokenType::End, nullopt};
 | 
			
		||||
 | 
			
		||||
        if (isspace(c))
 | 
			
		||||
            continue;
 | 
			
		||||
        switch (c) {
 | 
			
		||||
        case '(': return {TokenType::OpenParen};
 | 
			
		||||
        case ')': return {TokenType::CloseParen};
 | 
			
		||||
        case '$': return {TokenType::Dollar};
 | 
			
		||||
        case '(': return {TokenType::OpenParen, nullopt};
 | 
			
		||||
        case ')': return {TokenType::CloseParen, nullopt};
 | 
			
		||||
        case '$': return {TokenType::Dollar, nullopt};
 | 
			
		||||
        default:
 | 
			
		||||
            ss.unget();
 | 
			
		||||
            return lexNonSpecial();
 | 
			
		||||
 
 | 
			
		||||
@@ -6,7 +6,7 @@ TEST_CASE("Lexer lexes doubles correctly", "[Lexer]") {
 | 
			
		||||
    
 | 
			
		||||
    SECTION("double and negative syntax") {
 | 
			
		||||
        Lexer l("(1.0 0.1 -.1 -1. . - -. .-)");
 | 
			
		||||
        REQUIRE(l.next() == Token({OpenParen}));
 | 
			
		||||
        REQUIRE(l.next() == Token({OpenParen, nullopt}));
 | 
			
		||||
        REQUIRE(l.next() == Token({Double, 1.0}));
 | 
			
		||||
        REQUIRE(l.next() == Token({Double, 0.1}));
 | 
			
		||||
        REQUIRE(l.next() == Token({Double, -0.1}));
 | 
			
		||||
@@ -15,7 +15,7 @@ TEST_CASE("Lexer lexes doubles correctly", "[Lexer]") {
 | 
			
		||||
        REQUIRE(l.next() == Token({Symbol, "-"}));
 | 
			
		||||
        REQUIRE(l.next() == Token({Symbol, "-."}));
 | 
			
		||||
        REQUIRE(l.next() == Token({Symbol, ".-"}));
 | 
			
		||||
        REQUIRE(l.next() == Token({CloseParen}));
 | 
			
		||||
        REQUIRE(l.next() == Token({CloseParen, nullopt}));
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user