forked from KPGPMC/furlang
@@ -51,13 +51,15 @@ protected:
|
|||||||
* @brief Var read expression AST node.
|
* @brief Var read expression AST node.
|
||||||
*/
|
*/
|
||||||
class var_read_expression_node final : public expression_node {
|
class var_read_expression_node final : public expression_node {
|
||||||
|
public:
|
||||||
|
using name_type = furlang::result<std::string_view, error>; /**< Name type alias. */
|
||||||
public:
|
public:
|
||||||
/**
|
/**
|
||||||
* @brief Construct a new var read expression node object from a name handle.
|
* @brief Construct a new var read expression node object from a name handle.
|
||||||
*
|
*
|
||||||
* @param name Handle to the name.
|
* @param name Handle to the name.
|
||||||
*/
|
*/
|
||||||
var_read_expression_node(handle<std::string_view>&& name)
|
var_read_expression_node(name_type&& name)
|
||||||
: m_name(std::move(name)) {}
|
: m_name(std::move(name)) {}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -65,14 +67,14 @@ public:
|
|||||||
*
|
*
|
||||||
* @return Name of the variable.
|
* @return Name of the variable.
|
||||||
*/
|
*/
|
||||||
const handle<std::string_view>& get_name() const { return m_name; }
|
const name_type& get_name() const { return m_name; }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Returns the variable's name.
|
* @brief Returns the variable's name.
|
||||||
*
|
*
|
||||||
* @return Name of the variable.
|
* @return Name of the variable.
|
||||||
*/
|
*/
|
||||||
handle<std::string_view>&& move_name() { return std::move(m_name); }
|
name_type&& move_name() { return std::move(m_name); }
|
||||||
public:
|
public:
|
||||||
/**
|
/**
|
||||||
* @brief Returns this node's expression type.
|
* @brief Returns this node's expression type.
|
||||||
@@ -87,7 +89,7 @@ public:
|
|||||||
protected:
|
protected:
|
||||||
bool equal(const node& rhs) const override;
|
bool equal(const node& rhs) const override;
|
||||||
private:
|
private:
|
||||||
handle<std::string_view> m_name;
|
name_type m_name;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -49,13 +49,15 @@ protected:
|
|||||||
* @brief String literal AST node.
|
* @brief String literal AST node.
|
||||||
*/
|
*/
|
||||||
class string_literal_node final : public literal_node {
|
class string_literal_node final : public literal_node {
|
||||||
|
public:
|
||||||
|
using value_type = furlang::result<std::string_view, error>; /**< Value type. */
|
||||||
public:
|
public:
|
||||||
/**
|
/**
|
||||||
* @brief Construct a new string literal node object from a handle.
|
* @brief Construct a new string literal node object from a handle.
|
||||||
*
|
*
|
||||||
* @param value A handle to value.
|
* @param value A string view result.
|
||||||
*/
|
*/
|
||||||
string_literal_node(handle<std::string_view>&& value)
|
string_literal_node(value_type&& value)
|
||||||
: m_value(std::move(value)) {}
|
: m_value(std::move(value)) {}
|
||||||
public:
|
public:
|
||||||
/**
|
/**
|
||||||
@@ -68,9 +70,9 @@ public:
|
|||||||
/**
|
/**
|
||||||
* @brief Returns this node's value.
|
* @brief Returns this node's value.
|
||||||
*
|
*
|
||||||
* @return A handle to the value.
|
* @return A string view result.
|
||||||
*/
|
*/
|
||||||
const handle<std::string_view>& value() const { return m_value; }
|
const value_type& value() const { return m_value; }
|
||||||
public:
|
public:
|
||||||
void accept(visitor& visitor) const override;
|
void accept(visitor& visitor) const override;
|
||||||
|
|
||||||
@@ -78,20 +80,22 @@ public:
|
|||||||
protected:
|
protected:
|
||||||
bool equal(const node& rhs) const override;
|
bool equal(const node& rhs) const override;
|
||||||
private:
|
private:
|
||||||
handle<std::string_view> m_value;
|
value_type m_value;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Integer literal AST node.
|
* @brief Integer literal AST node.
|
||||||
*/
|
*/
|
||||||
class integer_literal_node final : public literal_node {
|
class integer_literal_node final : public literal_node {
|
||||||
|
public:
|
||||||
|
using value_type = furlang::result<front::integer_token, error>; /**< Value type. */
|
||||||
public:
|
public:
|
||||||
/**
|
/**
|
||||||
* @brief Construct a new integer literal node object from a handle.
|
* @brief Construct a new integer literal node object from a handle.
|
||||||
*
|
*
|
||||||
* @param value A handle to the value.
|
* @param value An integer result.
|
||||||
*/
|
*/
|
||||||
integer_literal_node(handle<front::integer_token>&& value)
|
integer_literal_node(value_type&& value)
|
||||||
: m_value(std::move(value)) {}
|
: m_value(std::move(value)) {}
|
||||||
public:
|
public:
|
||||||
/**
|
/**
|
||||||
@@ -104,9 +108,9 @@ public:
|
|||||||
/**
|
/**
|
||||||
* @brief Returns this node's value.
|
* @brief Returns this node's value.
|
||||||
*
|
*
|
||||||
* @return A handle to the value.
|
* @return An integer result.
|
||||||
*/
|
*/
|
||||||
const handle<front::integer_token>& value() const { return m_value; }
|
const value_type& value() const { return m_value; }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Compares this node with an integer token for equality.
|
* @brief Compares this node with an integer token for equality.
|
||||||
@@ -122,7 +126,7 @@ public:
|
|||||||
protected:
|
protected:
|
||||||
bool equal(const node& rhs) const override;
|
bool equal(const node& rhs) const override;
|
||||||
private:
|
private:
|
||||||
handle<front::integer_token> m_value;
|
value_type m_value;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace ast
|
} // namespace ast
|
||||||
|
|||||||
@@ -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().location << ": ERROR: unknown\n";
|
std::cerr << funcDef.body().error() << '\n';
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
for (const auto& stmt : funcDef.body()->statements) {
|
for (const auto& stmt : funcDef.body()->statements) {
|
||||||
|
|||||||
@@ -166,15 +166,13 @@ ast::literal_node_h parser::parse_literal() {
|
|||||||
switch (tok->type) {
|
switch (tok->type) {
|
||||||
case token_t::String: {
|
case token_t::String: {
|
||||||
auto tok = next_token();
|
auto tok = next_token();
|
||||||
return ast::string_literal_node_h{ tok->location,
|
if (tok.has_error()) return error_handle(tok);
|
||||||
m_arena,
|
return ast::string_literal_node_h{ tok->location, m_arena, (*tok)->string };
|
||||||
handle<std::string_view>{ tok->location, (*tok)->string } };
|
|
||||||
}
|
}
|
||||||
case token_t::Integer: {
|
case token_t::Integer: {
|
||||||
auto tok = next_token();
|
auto tok = next_token();
|
||||||
return ast::integer_literal_node_h{ tok->location,
|
if (tok.has_error()) return error_handle(tok);
|
||||||
m_arena,
|
return ast::integer_literal_node_h{ tok->location, m_arena, (*tok)->integer };
|
||||||
handle<integer_token>{ tok->location, (*tok)->integer } };
|
|
||||||
}
|
}
|
||||||
default: break;
|
default: break;
|
||||||
}
|
}
|
||||||
@@ -187,9 +185,8 @@ ast::expression_node_h parser::parse_expression_primary() {
|
|||||||
switch (tok->type) {
|
switch (tok->type) {
|
||||||
case token_t::Identifier: {
|
case token_t::Identifier: {
|
||||||
auto tok = next_token();
|
auto tok = next_token();
|
||||||
return ast::var_read_expression_node_h{ tok->location,
|
if (tok.has_error()) return error_handle(tok);
|
||||||
m_arena,
|
return ast::var_read_expression_node_h{ tok->location, m_arena, (*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();
|
||||||
|
|||||||
+13
-19
@@ -36,6 +36,15 @@ TEST(Parser, EmptyFunctions) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define EXPECT_INTLIT(expr, integer) \
|
||||||
|
do { \
|
||||||
|
EXPECT_EQ((expr)->expression_type(), expression_node_t::Literal); \
|
||||||
|
literal_node_h literal = (expr); \
|
||||||
|
EXPECT_EQ(literal->literal_type(), literal_node_t::Integer); \
|
||||||
|
integer_literal_node_h intLit = literal; \
|
||||||
|
EXPECT_EQ(intLit->value(), integer_token((integer))); \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
TEST(Parser, Literals) {
|
TEST(Parser, Literals) {
|
||||||
parser parser("<TEMP>", R"(
|
parser parser("<TEMP>", R"(
|
||||||
func test1() { return 67; }
|
func test1() { return 67; }
|
||||||
@@ -52,7 +61,7 @@ TEST(Parser, Literals) {
|
|||||||
EXPECT_EQ(funcDef->name()->string, "test1");
|
EXPECT_EQ(funcDef->name()->string, "test1");
|
||||||
EXPECT_EQ(funcDef->body()->statements.size(), 1);
|
EXPECT_EQ(funcDef->body()->statements.size(), 1);
|
||||||
return_statement_node_h ret = funcDef->body()->statements[0];
|
return_statement_node_h ret = funcDef->body()->statements[0];
|
||||||
EXPECT_EQ(ret->value(), integer_literal_node({ furc::location{ "<TEMP>", 1, 26 }, 67 }));
|
EXPECT_INTLIT(ret->value(), 67);
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
auto test2 = program->declarations()[1];
|
auto test2 = program->declarations()[1];
|
||||||
@@ -63,15 +72,6 @@ TEST(Parser, Literals) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#define EXPECT_INTLIT(expr, integer) \
|
|
||||||
do { \
|
|
||||||
EXPECT_EQ((expr)->expression_type(), expression_node_t::Literal); \
|
|
||||||
literal_node_h literal = (expr); \
|
|
||||||
EXPECT_EQ(literal->literal_type(), literal_node_t::Integer); \
|
|
||||||
integer_literal_node_h intLit = literal; \
|
|
||||||
EXPECT_EQ(*intLit, (integer)); \
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
#define EXPECT_VARREAD(expr, varname) \
|
#define EXPECT_VARREAD(expr, varname) \
|
||||||
do { \
|
do { \
|
||||||
EXPECT_EQ((expr)->expression_type(), expression_node_t::VarRead); \
|
EXPECT_EQ((expr)->expression_type(), expression_node_t::VarRead); \
|
||||||
@@ -216,7 +216,7 @@ TEST(Parser, Paren) {
|
|||||||
EXPECT_EQ(dec->get_node()->expression_type(), expression_node_t::Unaryop);
|
EXPECT_EQ(dec->get_node()->expression_type(), expression_node_t::Unaryop);
|
||||||
unaryop_expression_node_h inc = dec->get_node();
|
unaryop_expression_node_h inc = dec->get_node();
|
||||||
EXPECT_EQ(inc->type(), unaryop_expression_node_t::PostfixIncrement);
|
EXPECT_EQ(inc->type(), unaryop_expression_node_t::PostfixIncrement);
|
||||||
EXPECT_VARREAD(inc->get_node(), "x");
|
EXPECT_VARREAD(inc->get_node(), "x"sv);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(Parser, Assignment) {
|
TEST(Parser, Assignment) {
|
||||||
@@ -238,10 +238,7 @@ TEST(Parser, Assignment) {
|
|||||||
var_assign_expression_node_h assign = expr;
|
var_assign_expression_node_h assign = expr;
|
||||||
EXPECT_EQ(assign->compound(), binop_expression_node_t::None);
|
EXPECT_EQ(assign->compound(), binop_expression_node_t::None);
|
||||||
|
|
||||||
expression_node_h lhs = assign->lhs();
|
EXPECT_VARREAD(assign->lhs(), "x"sv);
|
||||||
EXPECT_EQ(lhs->expression_type(), expression_node_t::VarRead);
|
|
||||||
var_read_expression_node_h varRead = lhs;
|
|
||||||
EXPECT_EQ(varRead->get_name(), "x");
|
|
||||||
|
|
||||||
expression_node_h rhs = assign->rhs();
|
expression_node_h rhs = assign->rhs();
|
||||||
EXPECT_EQ(rhs->expression_type(), expression_node_t::Literal);
|
EXPECT_EQ(rhs->expression_type(), expression_node_t::Literal);
|
||||||
@@ -267,10 +264,7 @@ TEST(Parser, CompoundAssignment) {
|
|||||||
var_assign_expression_node_h assign = expr;
|
var_assign_expression_node_h assign = expr;
|
||||||
EXPECT_EQ(assign->compound(), binop_expression_node_t::Add);
|
EXPECT_EQ(assign->compound(), binop_expression_node_t::Add);
|
||||||
|
|
||||||
expression_node_h lhs = assign->lhs();
|
EXPECT_VARREAD(assign->lhs(), "x"sv);
|
||||||
EXPECT_EQ(lhs->expression_type(), expression_node_t::VarRead);
|
|
||||||
var_read_expression_node_h varRead = lhs;
|
|
||||||
EXPECT_EQ(varRead->get_name(), "x");
|
|
||||||
|
|
||||||
expression_node_h rhs = assign->rhs();
|
expression_node_h rhs = assign->rhs();
|
||||||
EXPECT_EQ(rhs->expression_type(), expression_node_t::Literal);
|
EXPECT_EQ(rhs->expression_type(), expression_node_t::Literal);
|
||||||
|
|||||||
Reference in New Issue
Block a user