Based Object Notation for Gigachags - BONG
This commit is contained in:
parent
dcaa09c859
commit
e18cf2f52e
47
src/bong.cpp
47
src/bong.cpp
@ -1,3 +1,48 @@
|
|||||||
#include "bong.hpp"
|
#include "bong.hpp"
|
||||||
|
#include "utils.hpp"
|
||||||
|
#include <cctype>
|
||||||
|
|
||||||
namespace bong { }
|
namespace bong {
|
||||||
|
|
||||||
|
auto Lexer::make_token() noexcept -> Result<Token, Error>
|
||||||
|
{
|
||||||
|
auto c = current();
|
||||||
|
if (std::isspace(c))
|
||||||
|
return make_whitespace();
|
||||||
|
else if (std::isdigit(c))
|
||||||
|
return make_number();
|
||||||
|
else if (std::isalpha(c))
|
||||||
|
return make_name();
|
||||||
|
else
|
||||||
|
return make_static();
|
||||||
|
}
|
||||||
|
|
||||||
|
auto Lexer::make_name() noexcept -> Result<Token, Error>
|
||||||
|
{
|
||||||
|
auto begin_index = index;
|
||||||
|
auto begin = location;
|
||||||
|
while (!done()
|
||||||
|
and (std ::isalpha(current()) or std::isdigit(current())
|
||||||
|
or current() == '_' or current() == '-')) {
|
||||||
|
step();
|
||||||
|
}
|
||||||
|
return Token { Tokens::Name, begin_index, index - begin_index, begin };
|
||||||
|
}
|
||||||
|
|
||||||
|
auto Lexer::make_number() noexcept -> Result<Token, Error>;
|
||||||
|
|
||||||
|
auto Lexer::make_static() noexcept -> Result<Token, Error>;
|
||||||
|
|
||||||
|
auto Lexer::make_whitespace() noexcept -> Result<Token, Error>;
|
||||||
|
|
||||||
|
auto Lexer::make_singleline_comment() noexcept -> Result<Token, Error>;
|
||||||
|
|
||||||
|
auto Lexer::make_multiline_comment() noexcept -> Result<Token, Error>;
|
||||||
|
|
||||||
|
auto Lexer::make_string() noexcept -> Result<Token, Error>;
|
||||||
|
|
||||||
|
auto Lexer::make_id() noexcept -> Result<Token, Error>;
|
||||||
|
|
||||||
|
auto Lexer::make_class() noexcept -> Result<Token, Error>;
|
||||||
|
|
||||||
|
}
|
||||||
|
91
src/bong.hpp
91
src/bong.hpp
@ -1,3 +1,92 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
namespace bong { }
|
#include "utils.hpp"
|
||||||
|
#include <optional>
|
||||||
|
#include <string_view>
|
||||||
|
|
||||||
|
namespace bong {
|
||||||
|
|
||||||
|
enum class Tokens {
|
||||||
|
Eof,
|
||||||
|
Whitespace,
|
||||||
|
SingleLineComment,
|
||||||
|
MultiLineComment,
|
||||||
|
|
||||||
|
Name,
|
||||||
|
Id,
|
||||||
|
Class,
|
||||||
|
|
||||||
|
Int,
|
||||||
|
Float,
|
||||||
|
String,
|
||||||
|
Bool,
|
||||||
|
|
||||||
|
LBrace,
|
||||||
|
RBrace,
|
||||||
|
LBracket,
|
||||||
|
RBracket,
|
||||||
|
|
||||||
|
Equal,
|
||||||
|
Colon,
|
||||||
|
SemiColon,
|
||||||
|
Comma,
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Location {
|
||||||
|
int line, col;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Token {
|
||||||
|
Tokens type;
|
||||||
|
size_t index, length;
|
||||||
|
Location location;
|
||||||
|
};
|
||||||
|
|
||||||
|
class Lexer {
|
||||||
|
public:
|
||||||
|
struct Error {
|
||||||
|
std::string message;
|
||||||
|
size_t index;
|
||||||
|
Location location;
|
||||||
|
};
|
||||||
|
|
||||||
|
Lexer(std::string_view text)
|
||||||
|
: text { text }
|
||||||
|
{
|
||||||
|
(void)next();
|
||||||
|
}
|
||||||
|
|
||||||
|
auto next() noexcept -> Result<Token, Error>
|
||||||
|
{
|
||||||
|
return current_token = make_token();
|
||||||
|
}
|
||||||
|
[[nodiscard]] auto peek() const noexcept -> Result<Token, Error>
|
||||||
|
{
|
||||||
|
return current_token;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
auto make_token() noexcept -> Result<Token, Error>;
|
||||||
|
auto make_name() noexcept -> Result<Token, Error>;
|
||||||
|
auto make_number() noexcept -> Result<Token, Error>;
|
||||||
|
auto make_static() noexcept -> Result<Token, Error>;
|
||||||
|
auto make_whitespace() noexcept -> Result<Token, Error>;
|
||||||
|
auto make_singleline_comment() noexcept -> Result<Token, Error>;
|
||||||
|
auto make_multiline_comment() noexcept -> Result<Token, Error>;
|
||||||
|
auto make_string() noexcept -> Result<Token, Error>;
|
||||||
|
auto make_id() noexcept -> Result<Token, Error>;
|
||||||
|
auto make_class() noexcept -> Result<Token, Error>;
|
||||||
|
|
||||||
|
auto current() const noexcept -> char { return text.at(index); }
|
||||||
|
auto done() const noexcept -> bool { return index >= text.size(); }
|
||||||
|
auto step() noexcept -> void { index++; }
|
||||||
|
|
||||||
|
Result<Token, Error> current_token {
|
||||||
|
Error { "next() not called first", index, location },
|
||||||
|
};
|
||||||
|
std::string_view text;
|
||||||
|
size_t index { 0 };
|
||||||
|
Location location { 1, 1 };
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
|
|
||||||
sources = files(
|
sources = files(
|
||||||
'main.cpp',
|
'main.cpp',
|
||||||
|
'bong.cpp',
|
||||||
)
|
)
|
||||||
|
@ -209,28 +209,28 @@ public:
|
|||||||
return is_ok() ? if_ok(unwrap()) : if_error(unwrap_error());
|
return is_ok() ? if_ok(unwrap()) : if_error(unwrap_error());
|
||||||
}
|
}
|
||||||
|
|
||||||
[[nodiscard]] constexpr auto flatten() noexcept
|
[[nodiscard]] constexpr auto flatten() noexcept requires
|
||||||
requires std::same_as<Error, typename Extracter<Value>::Error>
|
std::same_as<Error, typename Extracter<Value>::Error>
|
||||||
{
|
{
|
||||||
using InnerValue = typename Extracter<Value>::Value;
|
using InnerValue = typename Extracter<Value>::Value;
|
||||||
return is_ok() ? unwrap() : Result<InnerValue, Error>(unwrap_error());
|
return is_ok() ? unwrap() : Result<InnerValue, Error>(unwrap_error());
|
||||||
}
|
}
|
||||||
[[nodiscard]] constexpr auto flatten() const noexcept
|
[[nodiscard]] constexpr auto flatten() const noexcept requires
|
||||||
requires std::same_as<Error, typename Extracter<Value>::Error>
|
std::same_as<Error, typename Extracter<Value>::Error>
|
||||||
{
|
{
|
||||||
using InnerValue = typename Extracter<Value>::Value;
|
using InnerValue = typename Extracter<Value>::Value;
|
||||||
return is_ok() ? unwrap() : Result<InnerValue, Error>(unwrap_error());
|
return is_ok() ? unwrap() : Result<InnerValue, Error>(unwrap_error());
|
||||||
}
|
}
|
||||||
|
|
||||||
[[nodiscard]] constexpr auto flatten_error() noexcept
|
[[nodiscard]] constexpr auto flatten_error() noexcept requires
|
||||||
requires std::same_as<Value, typename Extracter<Error>::Value>
|
std::same_as<Value, typename Extracter<Error>::Value>
|
||||||
{
|
{
|
||||||
using InnerError = typename Extracter<Error>::Error;
|
using InnerError = typename Extracter<Error>::Error;
|
||||||
return is_error() ? unwrap_error()
|
return is_error() ? unwrap_error()
|
||||||
: Result<Value, InnerError>(unwrap());
|
: Result<Value, InnerError>(unwrap());
|
||||||
}
|
}
|
||||||
[[nodiscard]] constexpr auto flatten_error() const noexcept
|
[[nodiscard]] constexpr auto flatten_error() const noexcept requires
|
||||||
requires std::same_as<Value, typename Extracter<Error>::Value>
|
std::same_as<Value, typename Extracter<Error>::Value>
|
||||||
{
|
{
|
||||||
using InnerError = typename Extracter<Error>::Error;
|
using InnerError = typename Extracter<Error>::Error;
|
||||||
return is_error() ? unwrap_error()
|
return is_error() ? unwrap_error()
|
||||||
@ -385,14 +385,14 @@ public:
|
|||||||
return is_ok() ? if_ok(unwrap()) : if_error();
|
return is_ok() ? if_ok(unwrap()) : if_error();
|
||||||
}
|
}
|
||||||
|
|
||||||
[[nodiscard]] constexpr auto flatten() noexcept
|
[[nodiscard]] constexpr auto flatten() noexcept requires
|
||||||
requires std::same_as<void, typename Extracter<Value>::Error>
|
std::same_as<void, typename Extracter<Value>::Error>
|
||||||
{
|
{
|
||||||
using InnerValue = typename Extracter<Value>::Value;
|
using InnerValue = typename Extracter<Value>::Value;
|
||||||
return is_ok() ? unwrap() : Result<InnerValue, void>();
|
return is_ok() ? unwrap() : Result<InnerValue, void>();
|
||||||
}
|
}
|
||||||
[[nodiscard]] constexpr auto flatten() const noexcept
|
[[nodiscard]] constexpr auto flatten() const noexcept requires
|
||||||
requires std::same_as<void, typename Extracter<Value>::Error>
|
std::same_as<void, typename Extracter<Value>::Error>
|
||||||
{
|
{
|
||||||
using InnerValue = typename Extracter<Value>::Value;
|
using InnerValue = typename Extracter<Value>::Value;
|
||||||
return is_ok() ? unwrap() : Result<InnerValue, void>();
|
return is_ok() ? unwrap() : Result<InnerValue, void>();
|
||||||
@ -528,14 +528,14 @@ public:
|
|||||||
return is_ok() ? if_ok() : if_error(unwrap_error());
|
return is_ok() ? if_ok() : if_error(unwrap_error());
|
||||||
}
|
}
|
||||||
|
|
||||||
[[nodiscard]] constexpr auto flatten_error() noexcept
|
[[nodiscard]] constexpr auto flatten_error() noexcept requires
|
||||||
requires std::same_as<void, typename Extracter<Error>::Value>
|
std::same_as<void, typename Extracter<Error>::Value>
|
||||||
{
|
{
|
||||||
using InnerError = typename Extracter<Error>::Error;
|
using InnerError = typename Extracter<Error>::Error;
|
||||||
return is_error() ? unwrap_error() : Result<void, InnerError>();
|
return is_error() ? unwrap_error() : Result<void, InnerError>();
|
||||||
}
|
}
|
||||||
[[nodiscard]] constexpr auto flatten_error() const noexcept
|
[[nodiscard]] constexpr auto flatten_error() const noexcept requires
|
||||||
requires std::same_as<void, typename Extracter<Error>::Value>
|
std::same_as<void, typename Extracter<Error>::Value>
|
||||||
{
|
{
|
||||||
using InnerError = typename Extracter<Error>::Error;
|
using InnerError = typename Extracter<Error>::Error;
|
||||||
return is_error() ? unwrap_error() : Result<void, InnerError>();
|
return is_error() ? unwrap_error() : Result<void, InnerError>();
|
||||||
@ -656,12 +656,3 @@ private:
|
|||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
|
|
||||||
// #define TRY(expr) \
|
|
||||||
// ({ \
|
|
||||||
// auto result = (expr); \
|
|
||||||
// if (result.is_error()) \
|
|
||||||
// return { std::move(result.unwrap_error()) }; \
|
|
||||||
// std::move(result.unwrap()); \
|
|
||||||
// })
|
|
||||||
|
Loading…
Reference in New Issue
Block a user