IR generation #3
@@ -16,12 +16,12 @@ enum class token_t {
|
|||||||
String,
|
String,
|
||||||
Keyword,
|
Keyword,
|
||||||
Integer,
|
Integer,
|
||||||
Lparen,
|
LParen,
|
||||||
Rparen,
|
RParen,
|
||||||
Lbrace,
|
LBrace,
|
||||||
Rbrace,
|
RBrace,
|
||||||
Lbracket,
|
LBracket,
|
||||||
Rbracket,
|
RBracket,
|
||||||
Semicolon,
|
Semicolon,
|
||||||
Colon,
|
Colon,
|
||||||
Comma,
|
Comma,
|
||||||
@@ -57,12 +57,12 @@ static inline std::ostream& operator<<(std::ostream& os, token_t type) {
|
|||||||
case token_t::String: return os << "string";
|
case token_t::String: return os << "string";
|
||||||
case token_t::Keyword: return os << "keyword";
|
case token_t::Keyword: return os << "keyword";
|
||||||
case token_t::Integer: return os << "integer";
|
case token_t::Integer: return os << "integer";
|
||||||
case token_t::Lparen: return os << "'('";
|
case token_t::LParen: return os << "'('";
|
||||||
case token_t::Rparen: return os << "')'";
|
case token_t::RParen: return os << "')'";
|
||||||
case token_t::Lbrace: return os << "'{'";
|
case token_t::LBrace: return os << "'{'";
|
||||||
case token_t::Rbrace: return os << "'}'";
|
case token_t::RBrace: return os << "'}'";
|
||||||
case token_t::Lbracket: return os << "'['";
|
case token_t::LBracket: return os << "'['";
|
||||||
case token_t::Rbracket: return os << "']'";
|
case token_t::RBracket: return os << "']'";
|
||||||
case token_t::Semicolon: return os << "';'";
|
case token_t::Semicolon: return os << "';'";
|
||||||
case token_t::Colon: return os << "':'";
|
case token_t::Colon: return os << "':'";
|
||||||
case token_t::Comma: return os << "','";
|
case token_t::Comma: return os << "','";
|
||||||
@@ -97,12 +97,12 @@ static inline std::string operator+(const std::string& str, token_t type) {
|
|||||||
case token_t::String: return str + "string";
|
case token_t::String: return str + "string";
|
||||||
case token_t::Keyword: return str + "keyword";
|
case token_t::Keyword: return str + "keyword";
|
||||||
case token_t::Integer: return str + "integer";
|
case token_t::Integer: return str + "integer";
|
||||||
case token_t::Lparen: return str + "'('";
|
case token_t::LParen: return str + "'('";
|
||||||
case token_t::Rparen: return str + "')'";
|
case token_t::RParen: return str + "')'";
|
||||||
case token_t::Lbrace: return str + "'{'";
|
case token_t::LBrace: return str + "'{'";
|
||||||
case token_t::Rbrace: return str + "'}'";
|
case token_t::RBrace: return str + "'}'";
|
||||||
case token_t::Lbracket: return str + "'['";
|
case token_t::LBracket: return str + "'['";
|
||||||
case token_t::Rbracket: return str + "']'";
|
case token_t::RBracket: return str + "']'";
|
||||||
case token_t::Semicolon: return str + "';'";
|
case token_t::Semicolon: return str + "';'";
|
||||||
case token_t::Colon: return str + "':'";
|
case token_t::Colon: return str + "':'";
|
||||||
case token_t::Comma: return str + "','";
|
case token_t::Comma: return str + "','";
|
||||||
|
|||||||
@@ -106,12 +106,12 @@ token_handle<> lexer::next_token() {
|
|||||||
};
|
};
|
||||||
|
|
||||||
static std::map<std::string_view, token_t, compare> s_tokens = {
|
static std::map<std::string_view, token_t, compare> s_tokens = {
|
||||||
{ "(", token_t::Lparen },
|
{ "(", token_t::LParen },
|
||||||
{ ")", token_t::Rparen },
|
{ ")", token_t::RParen },
|
||||||
{ "{", token_t::Lbrace },
|
{ "{", token_t::LBrace },
|
||||||
{ "}", token_t::Rbrace },
|
{ "}", token_t::RBrace },
|
||||||
{ "[", token_t::Lbracket },
|
{ "[", token_t::LBracket },
|
||||||
{ "]", token_t::Rbracket },
|
{ "]", token_t::RBracket },
|
||||||
{ ";", token_t::Semicolon },
|
{ ";", token_t::Semicolon },
|
||||||
{ ":", token_t::Colon },
|
{ ":", token_t::Colon },
|
||||||
{ ",", token_t::Comma },
|
{ ",", token_t::Comma },
|
||||||
|
|||||||
+17
-17
@@ -46,15 +46,15 @@ ast::declaration_node_h parser::parse_declaration() {
|
|||||||
token_handle<> name = eat_token(token_t::Identifier);
|
token_handle<> name = eat_token(token_t::Identifier);
|
||||||
if (name.has_error()) return { name.location(), name.error() };
|
if (name.has_error()) return { name.location(), name.error() };
|
||||||
|
|
||||||
auto tok = eat_token(token_t::Lparen);
|
auto tok = eat_token(token_t::LParen);
|
||||||
if (tok.has_error()) return tok;
|
if (tok.has_error()) return tok;
|
||||||
tok = eat_token(token_t::Rparen);
|
tok = eat_token(token_t::RParen);
|
||||||
if (tok.has_error()) return tok;
|
if (tok.has_error()) return tok;
|
||||||
|
|
||||||
const auto& peek = peek_token();
|
const auto& peek = peek_token();
|
||||||
if (peek.has_error()) return peek;
|
if (peek.has_error()) return peek;
|
||||||
switch (peek->type) {
|
switch (peek->type) {
|
||||||
case token_t::Lbrace: {
|
case token_t::LBrace: {
|
||||||
ast::body_h body = parse_body();
|
ast::body_h body = parse_body();
|
||||||
if (body.has_error()) return body;
|
if (body.has_error()) return body;
|
||||||
return ast::function_definition_node_h{ first.location(), m_arena, *name, std::move(body) };
|
return ast::function_definition_node_h{ first.location(), m_arena, *name, std::move(body) };
|
||||||
@@ -72,12 +72,12 @@ ast::declaration_node_h parser::parse_declaration() {
|
|||||||
case token_t::None:
|
case token_t::None:
|
||||||
case token_t::Identifier:
|
case token_t::Identifier:
|
||||||
case token_t::Integer:
|
case token_t::Integer:
|
||||||
case token_t::Lparen:
|
case token_t::LParen:
|
||||||
case token_t::Rparen:
|
case token_t::RParen:
|
||||||
case token_t::Lbrace:
|
case token_t::LBrace:
|
||||||
case token_t::Rbrace:
|
case token_t::RBrace:
|
||||||
case token_t::Lbracket:
|
case token_t::LBracket:
|
||||||
case token_t::Rbracket:
|
case token_t::RBracket:
|
||||||
case token_t::Semicolon:
|
case token_t::Semicolon:
|
||||||
case token_t::Colon:
|
case token_t::Colon:
|
||||||
default: {
|
default: {
|
||||||
@@ -107,12 +107,12 @@ ast::statement_node_h parser::parse_statement() {
|
|||||||
}
|
}
|
||||||
case keyword_token::If: {
|
case keyword_token::If: {
|
||||||
auto tok = next_token();
|
auto tok = next_token();
|
||||||
auto err = eat_token(token_t::Lparen);
|
auto err = eat_token(token_t::LParen);
|
||||||
if (err.has_error()) return err;
|
if (err.has_error()) return err;
|
||||||
|
|
||||||
auto cond = parse_expression();
|
auto cond = parse_expression();
|
||||||
|
|
||||||
err = eat_token(token_t::Rparen);
|
err = eat_token(token_t::RParen);
|
||||||
if (err.has_error()) return err;
|
if (err.has_error()) return err;
|
||||||
|
|
||||||
auto then = parse_statement();
|
auto then = parse_statement();
|
||||||
@@ -136,7 +136,7 @@ ast::statement_node_h parser::parse_statement() {
|
|||||||
default: break;
|
default: break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
case token_t::Lbrace: return ast::compound_statement_node_h{ location, m_arena, parse_body() };
|
case token_t::LBrace: return ast::compound_statement_node_h{ location, m_arena, parse_body() };
|
||||||
default: break;
|
default: break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -187,10 +187,10 @@ ast::expression_node_h parser::parse_expression_primary() {
|
|||||||
m_arena,
|
m_arena,
|
||||||
handle<std::string_view>{ tok.location(), (*tok)->string } };
|
handle<std::string_view>{ tok.location(), (*tok)->string } };
|
||||||
}
|
}
|
||||||
case token_t::Lparen: {
|
case token_t::LParen: {
|
||||||
auto tok = next_token();
|
auto tok = next_token();
|
||||||
auto node = parse_expression();
|
auto node = parse_expression();
|
||||||
auto err = eat_token(token_t::Rparen);
|
auto err = eat_token(token_t::RParen);
|
||||||
if (err.has_error()) return err;
|
if (err.has_error()) return err;
|
||||||
return node;
|
return node;
|
||||||
}
|
}
|
||||||
@@ -366,15 +366,15 @@ ast::expression_node_h parser::parse_expression_rhs(ast::expression_node_h&& ini
|
|||||||
ast::body_h parser::parse_body() {
|
ast::body_h parser::parse_body() {
|
||||||
ast::body body;
|
ast::body body;
|
||||||
|
|
||||||
token_handle<> begin = eat_token(token_t::Lbrace);
|
token_handle<> begin = eat_token(token_t::LBrace);
|
||||||
if (begin.has_error()) return begin;
|
if (begin.has_error()) return begin;
|
||||||
body.begin = begin.location();
|
body.begin = begin.location();
|
||||||
|
|
||||||
while (!peek_token().has_error() && peek_token()->type != token_t::None && peek_token()->type != token_t::Rbrace) {
|
while (!peek_token().has_error() && peek_token()->type != token_t::None && peek_token()->type != token_t::RBrace) {
|
||||||
body.statements.push_back(parse_statement());
|
body.statements.push_back(parse_statement());
|
||||||
}
|
}
|
||||||
|
|
||||||
token_handle<> end = eat_token(token_t::Rbrace);
|
token_handle<> end = eat_token(token_t::RBrace);
|
||||||
if (end.has_error()) return end;
|
if (end.has_error()) return end;
|
||||||
body.end = end.location();
|
body.end = end.location();
|
||||||
|
|
||||||
|
|||||||
+9
-9
@@ -18,13 +18,13 @@ using namespace std::string_view_literals;
|
|||||||
|
|
||||||
TEST(Lexer, Tokens) {
|
TEST(Lexer, Tokens) {
|
||||||
lexer lexer("<TEMP>", "()\n\t\t{\n}[\"shto-to\"]; :,.main return func");
|
lexer lexer("<TEMP>", "()\n\t\t{\n}[\"shto-to\"]; :,.main return func");
|
||||||
EXPECT_TOKEN(lexer, (token{ token_t::Lparen }));
|
EXPECT_TOKEN(lexer, (token{ token_t::LParen }));
|
||||||
EXPECT_TOKEN(lexer, (token{ token_t::Rparen }));
|
EXPECT_TOKEN(lexer, (token{ token_t::RParen }));
|
||||||
EXPECT_TOKEN(lexer, (token{ token_t::Lbrace }));
|
EXPECT_TOKEN(lexer, (token{ token_t::LBrace }));
|
||||||
EXPECT_TOKEN(lexer, (token{ token_t::Rbrace }));
|
EXPECT_TOKEN(lexer, (token{ token_t::RBrace }));
|
||||||
EXPECT_TOKEN(lexer, (token{ token_t::Lbracket }));
|
EXPECT_TOKEN(lexer, (token{ token_t::LBracket }));
|
||||||
EXPECT_TOKEN(lexer, (token{ token_t::String, "shto-to"sv }));
|
EXPECT_TOKEN(lexer, (token{ token_t::String, "shto-to"sv }));
|
||||||
EXPECT_TOKEN(lexer, (token{ token_t::Rbracket }));
|
EXPECT_TOKEN(lexer, (token{ token_t::RBracket }));
|
||||||
EXPECT_TOKEN(lexer, (token{ token_t::Semicolon }));
|
EXPECT_TOKEN(lexer, (token{ token_t::Semicolon }));
|
||||||
EXPECT_TOKEN(lexer, (token{ token_t::Colon }));
|
EXPECT_TOKEN(lexer, (token{ token_t::Colon }));
|
||||||
EXPECT_TOKEN(lexer, (token{ token_t::Comma }));
|
EXPECT_TOKEN(lexer, (token{ token_t::Comma }));
|
||||||
@@ -37,10 +37,10 @@ TEST(Lexer, Tokens) {
|
|||||||
|
|
||||||
TEST(Lexer, Comments) {
|
TEST(Lexer, Comments) {
|
||||||
lexer lexer("<TEMP>", "(/** skibidi **/func{//)\n}");
|
lexer lexer("<TEMP>", "(/** skibidi **/func{//)\n}");
|
||||||
EXPECT_TOKEN(lexer, (token{ token_t::Lparen, "("sv })); // left out the string-view deliberately
|
EXPECT_TOKEN(lexer, (token{ token_t::LParen, "("sv })); // left out the string-view deliberately
|
||||||
EXPECT_TOKEN(lexer, (token{ keyword_token::Func }));
|
EXPECT_TOKEN(lexer, (token{ keyword_token::Func }));
|
||||||
EXPECT_TOKEN(lexer, (token{ token_t::Lbrace }));
|
EXPECT_TOKEN(lexer, (token{ token_t::LBrace }));
|
||||||
EXPECT_TOKEN(lexer, (token{ token_t::Rbrace }));
|
EXPECT_TOKEN(lexer, (token{ token_t::RBrace }));
|
||||||
EXPECT_EOF(lexer);
|
EXPECT_EOF(lexer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user