Add var read expression
Signed-off-by: CHatingPython <chatingpython@gmail.com>
This commit is contained in:
@@ -9,6 +9,7 @@ namespace ast {
|
|||||||
|
|
||||||
enum class expression_node_t {
|
enum class expression_node_t {
|
||||||
Literal,
|
Literal,
|
||||||
|
VarRead,
|
||||||
Unaryop,
|
Unaryop,
|
||||||
Binop,
|
Binop,
|
||||||
Paren,
|
Paren,
|
||||||
@@ -27,6 +28,25 @@ protected:
|
|||||||
|
|
||||||
using expression_node_h = node_handle<expression_node>;
|
using expression_node_h = node_handle<expression_node>;
|
||||||
|
|
||||||
|
class var_read_expression_node : public expression_node {
|
||||||
|
public:
|
||||||
|
var_read_expression_node(handle<std::string_view>&& name)
|
||||||
|
: m_name(std::move(name)) {}
|
||||||
|
|
||||||
|
const handle<std::string_view>& get_name() const { return m_name; }
|
||||||
|
handle<std::string_view>&& move_name() { return std::move(m_name); }
|
||||||
|
public:
|
||||||
|
expression_node_t expression_type() const override { return expression_node_t::VarRead; }
|
||||||
|
|
||||||
|
std::ostream& print(std::ostream& os) const override;
|
||||||
|
protected:
|
||||||
|
bool equal(const node& rhs) const override;
|
||||||
|
private:
|
||||||
|
handle<std::string_view> m_name;
|
||||||
|
};
|
||||||
|
|
||||||
|
using var_read_expression_node_h = node_handle<var_read_expression_node>;
|
||||||
|
|
||||||
enum class unaryop_expression_node_t {
|
enum class unaryop_expression_node_t {
|
||||||
Positive,
|
Positive,
|
||||||
Negative,
|
Negative,
|
||||||
|
|||||||
@@ -34,6 +34,16 @@ bool expression_node::equal(const node& rhs) const {
|
|||||||
return expression_type() == reinterpret_cast<const expression_node&>(rhs).expression_type();
|
return expression_type() == reinterpret_cast<const expression_node&>(rhs).expression_type();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::ostream& var_read_expression_node::print(std::ostream& os) const {
|
||||||
|
if (m_name.present()) return os << *m_name;
|
||||||
|
return os << m_name.error();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool var_read_expression_node::equal(const node& rhsNode) const {
|
||||||
|
const auto& rhs = reinterpret_cast<const var_read_expression_node&>(rhsNode);
|
||||||
|
return expression_node::equal(rhsNode) && m_name == rhs.m_name;
|
||||||
|
}
|
||||||
|
|
||||||
std::ostream& operator<<(std::ostream& os, unaryop_expression_node_t type) {
|
std::ostream& operator<<(std::ostream& os, unaryop_expression_node_t type) {
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case unaryop_expression_node_t::Positive: return os << "+";
|
case unaryop_expression_node_t::Positive: return os << "+";
|
||||||
|
|||||||
@@ -146,6 +146,12 @@ ast::literal_node_h parser::parse_literal() {
|
|||||||
ast::expression_node_h parser::parse_expression_primary() {
|
ast::expression_node_h parser::parse_expression_primary() {
|
||||||
const auto& tok = peek_token();
|
const auto& tok = peek_token();
|
||||||
switch (tok->type) {
|
switch (tok->type) {
|
||||||
|
case token_t::Identifier: {
|
||||||
|
auto tok = next_token();
|
||||||
|
return ast::var_read_expression_node_h{ tok.location(),
|
||||||
|
m_arena,
|
||||||
|
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();
|
||||||
|
|||||||
+1
-1
@@ -5,7 +5,7 @@
|
|||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
||||||
int main(void) {
|
int main(void) {
|
||||||
furc::front::parser parser("<TEMP>", "func main() {\n return (6 - -7) * 9++;\n}");
|
furc::front::parser parser("<TEMP>", "func main() {\n return (x - -y) * z++;\n}");
|
||||||
std::cout << parser.parse() << '\n';
|
std::cout << parser.parse() << '\n';
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|||||||
+10
-3
@@ -64,7 +64,14 @@ TEST(Parser, Literals) {
|
|||||||
EXPECT_EQ(literal->literal_type(), literal_node_t::Integer); \
|
EXPECT_EQ(literal->literal_type(), literal_node_t::Integer); \
|
||||||
integer_literal_node_h intLit = literal; \
|
integer_literal_node_h intLit = literal; \
|
||||||
EXPECT_EQ(*intLit, (integer)); \
|
EXPECT_EQ(*intLit, (integer)); \
|
||||||
} while (0);
|
} while (0)
|
||||||
|
|
||||||
|
#define EXPECT_VARREAD(expr, varname) \
|
||||||
|
do { \
|
||||||
|
EXPECT_EQ((expr)->expression_type(), expression_node_t::VarRead); \
|
||||||
|
var_read_expression_node_h varRead = (expr); \
|
||||||
|
EXPECT_EQ(varRead->get_name(), (varname)); \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
// TODO: Use arena (I am too exhausted rn to do it)
|
// TODO: Use arena (I am too exhausted rn to do it)
|
||||||
TEST(Parser, OperatorPrecedence_AddMul) {
|
TEST(Parser, OperatorPrecedence_AddMul) {
|
||||||
@@ -181,7 +188,7 @@ TEST(Parser, UnaryOperator_PrePost) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
TEST(Parser, Paren) {
|
TEST(Parser, Paren) {
|
||||||
parser parser("<TEMP>", "func main() { return --(5++); }");
|
parser parser("<TEMP>", "func main() { return --(x++); }");
|
||||||
auto program = parser.parse();
|
auto program = parser.parse();
|
||||||
EXPECT_TRUE(program.present());
|
EXPECT_TRUE(program.present());
|
||||||
EXPECT_EQ(program->declarations().size(), 1);
|
EXPECT_EQ(program->declarations().size(), 1);
|
||||||
@@ -203,7 +210,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_INTLIT(inc->get_node(), 5);
|
EXPECT_VARREAD(inc->get_node(), "x");
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
Reference in New Issue
Block a user