forked from KPGPMC/furlang
@@ -95,7 +95,7 @@ public:
|
|||||||
* @param name Name of the function.
|
* @param name Name of the function.
|
||||||
* @param body Body of the function.
|
* @param body Body of the function.
|
||||||
*/
|
*/
|
||||||
function_definition_node(front::token name, body_h&& body)
|
function_definition_node(front::token name, body_r&& body)
|
||||||
: function_declaration_node(name), m_body(std::move(body)) {}
|
: function_declaration_node(name), m_body(std::move(body)) {}
|
||||||
public:
|
public:
|
||||||
/**
|
/**
|
||||||
@@ -110,7 +110,7 @@ public:
|
|||||||
*
|
*
|
||||||
* @return Body of the function.
|
* @return Body of the function.
|
||||||
*/
|
*/
|
||||||
const body_h& body() const { return m_body; }
|
const body_r& body() const { return m_body; }
|
||||||
public:
|
public:
|
||||||
void accept(visitor& visitor) const override;
|
void accept(visitor& visitor) const override;
|
||||||
|
|
||||||
@@ -118,7 +118,7 @@ public:
|
|||||||
protected:
|
protected:
|
||||||
bool equal(const node& rhs) const override;
|
bool equal(const node& rhs) const override;
|
||||||
private:
|
private:
|
||||||
body_h m_body;
|
body_r m_body;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace ast
|
} // namespace ast
|
||||||
|
|||||||
@@ -1,7 +1,9 @@
|
|||||||
#ifndef FURC_AST_FWD_HPP
|
#ifndef FURC_AST_FWD_HPP
|
||||||
#define FURC_AST_FWD_HPP
|
#define FURC_AST_FWD_HPP
|
||||||
|
|
||||||
|
#include "furc/diag.hpp"
|
||||||
#include "furc/handle.hpp"
|
#include "furc/handle.hpp"
|
||||||
|
#include "furlang/result.hpp"
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
@@ -13,6 +15,29 @@ namespace furc {
|
|||||||
*/
|
*/
|
||||||
namespace ast {
|
namespace ast {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief AST error.
|
||||||
|
*/
|
||||||
|
struct error {
|
||||||
|
location location; /**< Location of the error. */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Compares two AST errors for equality.
|
||||||
|
*
|
||||||
|
* @param other Error to compare against.
|
||||||
|
* @return true if the errors are equal.
|
||||||
|
*/
|
||||||
|
bool operator==(const error& other) const { return location == other.location; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Compares two AST errors for inequality.
|
||||||
|
*
|
||||||
|
* @param other Error to compare against.
|
||||||
|
* @return true if the errors are not equal.
|
||||||
|
*/
|
||||||
|
bool operator!=(const error& other) const { return !this->operator==(other); }
|
||||||
|
};
|
||||||
|
|
||||||
class node;
|
class node;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -162,7 +187,7 @@ struct body {
|
|||||||
* @brief Alias for body result.
|
* @brief Alias for body result.
|
||||||
* @see body
|
* @see body
|
||||||
*/
|
*/
|
||||||
using body_h = handle<body>;
|
using body_r = furlang::result<body, error>;
|
||||||
|
|
||||||
class function_declaration_node;
|
class function_declaration_node;
|
||||||
|
|
||||||
|
|||||||
@@ -150,7 +150,7 @@ public:
|
|||||||
*
|
*
|
||||||
* @param body Body handle.
|
* @param body Body handle.
|
||||||
*/
|
*/
|
||||||
compound_statement_node(body_h&& body)
|
compound_statement_node(body_r&& body)
|
||||||
: m_body(std::move(body)) {}
|
: m_body(std::move(body)) {}
|
||||||
public:
|
public:
|
||||||
/**
|
/**
|
||||||
@@ -158,7 +158,7 @@ public:
|
|||||||
*
|
*
|
||||||
* @return The body handle.
|
* @return The body handle.
|
||||||
*/
|
*/
|
||||||
const body_h& body() const { return m_body; }
|
const body_r& body() const { return m_body; }
|
||||||
public:
|
public:
|
||||||
/**
|
/**
|
||||||
* @brief Returns this node's statement type.
|
* @brief Returns this node's statement type.
|
||||||
@@ -173,7 +173,7 @@ public:
|
|||||||
protected:
|
protected:
|
||||||
bool equal(const node& rhs) const override;
|
bool equal(const node& rhs) const override;
|
||||||
private:
|
private:
|
||||||
body_h m_body; /**< The body handle. */
|
body_r m_body; /**< The body handle. */
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace ast
|
} // namespace ast
|
||||||
|
|||||||
@@ -65,7 +65,7 @@ private:
|
|||||||
ast::expression_node_h parse_expression_unary(std::uint32_t precedence);
|
ast::expression_node_h parse_expression_unary(std::uint32_t precedence);
|
||||||
ast::expression_node_h parse_expression_rhs(ast::expression_node_h&& init, std::uint32_t precedence);
|
ast::expression_node_h parse_expression_rhs(ast::expression_node_h&& init, std::uint32_t precedence);
|
||||||
|
|
||||||
ast::body_h parse_body();
|
ast::body_r parse_body();
|
||||||
private:
|
private:
|
||||||
static ast::node_handle<ast::node> error_handle(const token_r& result);
|
static ast::node_handle<ast::node> error_handle(const token_r& result);
|
||||||
private:
|
private:
|
||||||
|
|||||||
+5
-5
@@ -156,13 +156,13 @@ void function_definition_node::accept(visitor& visitor) const {
|
|||||||
|
|
||||||
std::ostream& function_definition_node::print(std::ostream& os) const {
|
std::ostream& function_definition_node::print(std::ostream& os) const {
|
||||||
function_declaration_node::print(os);
|
function_declaration_node::print(os);
|
||||||
os << ':';
|
os << ":\n";
|
||||||
if (m_body.present()) {
|
if (m_body.has_value()) {
|
||||||
for (const auto& entry : m_body->statements)
|
for (const auto& entry : m_body->statements)
|
||||||
os << '\n' << entry;
|
os << entry << '\n';
|
||||||
return os << '\n' << m_body->end << ": " << p_name->string << " end";
|
return os << m_body->end << ": " << p_name->string << " end";
|
||||||
}
|
}
|
||||||
return os << m_body.error(); // error
|
return os << m_body.error().location << ": ERROR: unknown";
|
||||||
}
|
}
|
||||||
|
|
||||||
bool function_definition_node::equal(const node& rhs) const {
|
bool function_definition_node::equal(const node& rhs) const {
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ void ir_generator::visit(const ast::function_definition_node& funcDef) {
|
|||||||
|
|
||||||
push_block();
|
push_block();
|
||||||
if (funcDef.body().has_error()) {
|
if (funcDef.body().has_error()) {
|
||||||
std::cerr << funcDef.body().error() << '\n';
|
std::cerr << funcDef.body().error().location << ": ERROR: unknown\n";
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
for (const auto& stmt : funcDef.body()->statements) {
|
for (const auto& stmt : funcDef.body()->statements) {
|
||||||
|
|||||||
@@ -59,8 +59,8 @@ ast::declaration_node_h parser::parse_declaration() {
|
|||||||
if (peek.has_error()) return error_handle(peek);
|
if (peek.has_error()) return error_handle(peek);
|
||||||
switch (peek->type) {
|
switch (peek->type) {
|
||||||
case token_t::LBrace: {
|
case token_t::LBrace: {
|
||||||
ast::body_h body = parse_body();
|
ast::body_r body = parse_body();
|
||||||
if (body.has_error()) return body;
|
if (body.has_error()) return ast::node_handle<ast::node>(body.error().location, "Body error");
|
||||||
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) };
|
||||||
}
|
}
|
||||||
case token_t::Semicolon: {
|
case token_t::Semicolon: {
|
||||||
@@ -367,11 +367,11 @@ ast::expression_node_h parser::parse_expression_rhs(ast::expression_node_h&& ini
|
|||||||
return lhs;
|
return lhs;
|
||||||
}
|
}
|
||||||
|
|
||||||
ast::body_h parser::parse_body() {
|
ast::body_r parser::parse_body() {
|
||||||
ast::body body;
|
ast::body body;
|
||||||
|
|
||||||
auto begin = eat_token(token_t::LBrace);
|
auto begin = eat_token(token_t::LBrace);
|
||||||
if (begin.has_error()) return error_handle(begin);
|
if (begin.has_error()) return ast::body_r(ast::error{ begin.error().location });
|
||||||
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) {
|
||||||
@@ -379,10 +379,10 @@ ast::body_h parser::parse_body() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
auto end = eat_token(token_t::RBrace);
|
auto end = eat_token(token_t::RBrace);
|
||||||
if (end.has_error()) return error_handle(end);
|
if (end.has_error()) return ast::body_r(ast::error{ end.error().location });
|
||||||
body.end = end->location;
|
body.end = end->location;
|
||||||
|
|
||||||
return { begin->location, body };
|
return body;
|
||||||
}
|
}
|
||||||
|
|
||||||
ast::node_handle<ast::node> parser::error_handle(const token_r& result) {
|
ast::node_handle<ast::node> parser::error_handle(const token_r& result) {
|
||||||
|
|||||||
Reference in New Issue
Block a user