feat(furc/parser): add function calls
This commit is contained in:
@@ -134,6 +134,7 @@ public:
|
|||||||
Literal,
|
Literal,
|
||||||
|
|
||||||
VarRead,
|
VarRead,
|
||||||
|
FunctionCall,
|
||||||
Group,
|
Group,
|
||||||
BinaryOp,
|
BinaryOp,
|
||||||
UnaryOp,
|
UnaryOp,
|
||||||
@@ -156,6 +157,13 @@ struct var_read_expr_node final : public expr_node {
|
|||||||
: name(std::move(name)) {}
|
: name(std::move(name)) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct func_call_expr_node final : public expr_node {
|
||||||
|
expr_type_e expr_type() const override { return FunctionCall; }
|
||||||
|
|
||||||
|
expr_node* lhs = nullptr;
|
||||||
|
std::vector<expr_node*> args;
|
||||||
|
};
|
||||||
|
|
||||||
struct group_expr_node final : public expr_node {
|
struct group_expr_node final : public expr_node {
|
||||||
expr_type_e expr_type() const override { return Group; }
|
expr_type_e expr_type() const override { return Group; }
|
||||||
|
|
||||||
|
|||||||
+53
-31
@@ -314,30 +314,37 @@ expr_node* parser::parse_expr_unary() {
|
|||||||
|
|
||||||
expr_node* parser::parse_expr_right(expr_node* lhs, std::uint32_t precedence) {
|
expr_node* parser::parse_expr_right(expr_node* lhs, std::uint32_t precedence) {
|
||||||
struct op_info {
|
struct op_info {
|
||||||
binary_op_expr_node::binary_op_type type;
|
enum type_e {
|
||||||
std::uint32_t precedence;
|
Binary = 0,
|
||||||
bool right = false;
|
FunctionCall,
|
||||||
|
} type;
|
||||||
|
std::uint32_t precedence;
|
||||||
|
union {
|
||||||
|
binary_op_expr_node::binary_op_type binary;
|
||||||
|
};
|
||||||
|
bool right = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
static std::unordered_map<token_t, op_info> s_ops = {
|
static std::unordered_map<token_t, op_info> s_ops = {
|
||||||
{ token::Plus, { binary_op_expr_node::Add, 4 } },
|
{ token::Plus, { op_info::Binary, 4, binary_op_expr_node::Add } },
|
||||||
{ token::Minus, { binary_op_expr_node::Sub, 4 } },
|
{ token::Minus, { op_info::Binary, 4, binary_op_expr_node::Sub } },
|
||||||
{ token::Star, { binary_op_expr_node::Mul, 3 } },
|
{ token::Star, { op_info::Binary, 3, binary_op_expr_node::Mul } },
|
||||||
{ token::Slash, { binary_op_expr_node::Div, 3 } },
|
{ token::Slash, { op_info::Binary, 3, binary_op_expr_node::Div } },
|
||||||
{ token::Percent, { binary_op_expr_node::Mod, 3 } },
|
{ token::Percent, { op_info::Binary, 3, binary_op_expr_node::Mod } },
|
||||||
{ token::DblLT, { binary_op_expr_node::Shl, 5 } },
|
{ token::DblLT, { op_info::Binary, 5, binary_op_expr_node::Shl } },
|
||||||
{ token::DblGT, { binary_op_expr_node::Shr, 5 } },
|
{ token::DblGT, { op_info::Binary, 5, binary_op_expr_node::Shr } },
|
||||||
{ token::Ampersand, { binary_op_expr_node::BinAnd, 8 } },
|
{ token::Ampersand, { op_info::Binary, 8, binary_op_expr_node::BinAnd } },
|
||||||
{ token::Pipe, { binary_op_expr_node::BinOr, 10 } },
|
{ token::Pipe, { op_info::Binary, 10, binary_op_expr_node::BinOr } },
|
||||||
{ token::Hat, { binary_op_expr_node::BinXor, 9 } },
|
{ token::Hat, { op_info::Binary, 9, binary_op_expr_node::BinXor } },
|
||||||
{ token::DblAmpersand, { binary_op_expr_node::And, 11 } },
|
{ token::DblAmpersand, { op_info::Binary, 11, binary_op_expr_node::And } },
|
||||||
{ token::DblPipe, { binary_op_expr_node::Or, 12 } },
|
{ token::DblPipe, { op_info::Binary, 12, binary_op_expr_node::Or } },
|
||||||
{ token::DblEquals, { binary_op_expr_node::Equals, 7 } },
|
{ token::DblEquals, { op_info::Binary, 7, binary_op_expr_node::Equals } },
|
||||||
{ token::ExEquals, { binary_op_expr_node::NotEquals, 7 } },
|
{ token::ExEquals, { op_info::Binary, 7, binary_op_expr_node::NotEquals } },
|
||||||
{ token::LessThan, { binary_op_expr_node::LessThan, 6 } },
|
{ token::LessThan, { op_info::Binary, 6, binary_op_expr_node::LessThan } },
|
||||||
{ token::LessEquals, { binary_op_expr_node::LessEquals, 6 } },
|
{ token::LessEquals, { op_info::Binary, 6, binary_op_expr_node::LessEquals } },
|
||||||
{ token::GreaterThan, { binary_op_expr_node::GreaterThan, 6 } },
|
{ token::GreaterThan, { op_info::Binary, 6, binary_op_expr_node::GreaterThan } },
|
||||||
{ token::GreaterEquals, { binary_op_expr_node::GreaterEquals, 6 } },
|
{ token::GreaterEquals, { op_info::Binary, 6, binary_op_expr_node::GreaterEquals } },
|
||||||
|
{ token::LParen, { op_info::FunctionCall, 1 } },
|
||||||
};
|
};
|
||||||
|
|
||||||
while (true) {
|
while (true) {
|
||||||
@@ -346,17 +353,32 @@ expr_node* parser::parse_expr_right(expr_node* lhs, std::uint32_t precedence) {
|
|||||||
auto op = it->second;
|
auto op = it->second;
|
||||||
m_lexer.next_token();
|
m_lexer.next_token();
|
||||||
|
|
||||||
expr_node* rhs = parse_expr_unary();
|
if (op.type == op_info::FunctionCall) {
|
||||||
auto nextIt = s_ops.find(m_lexer.peek_token().type);
|
func_call_expr_node funcCall;
|
||||||
if (nextIt != s_ops.end()) {
|
funcCall.lhs = lhs;
|
||||||
rhs = parse_expr_right(rhs, op.precedence + (op.right ? 1 : 0));
|
|
||||||
}
|
|
||||||
|
|
||||||
binary_op_expr_node binary;
|
if (m_lexer.peek_token().type != token::RParen) {
|
||||||
binary.lhs = lhs;
|
do {
|
||||||
binary.rhs = rhs;
|
funcCall.args.push_back(parse_expr());
|
||||||
binary.type = op.type;
|
} while (eat_token(token::Comma, token::RParen).type == token::Comma);
|
||||||
lhs = m_arena->allocate<binary_op_expr_node>(std::move(binary));
|
} else {
|
||||||
|
m_lexer.next_token();
|
||||||
|
}
|
||||||
|
|
||||||
|
lhs = m_arena->allocate<func_call_expr_node>(std::move(funcCall));
|
||||||
|
} else {
|
||||||
|
binary_op_expr_node binary;
|
||||||
|
binary.lhs = lhs;
|
||||||
|
binary.rhs = parse_expr_unary();
|
||||||
|
binary.type = op.binary;
|
||||||
|
|
||||||
|
auto nextIt = s_ops.find(m_lexer.peek_token().type);
|
||||||
|
if (nextIt != s_ops.end()) {
|
||||||
|
binary.rhs = parse_expr_right(binary.rhs, op.precedence + (op.right ? 1 : 0));
|
||||||
|
}
|
||||||
|
|
||||||
|
lhs = m_arena->allocate<binary_op_expr_node>(std::move(binary));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ int main(void) {
|
|||||||
std::string_view content = R"(
|
std::string_view content = R"(
|
||||||
func main(argc: u64) -> s32 pre(arc > 1) {
|
func main(argc: u64) -> s32 pre(arc > 1) {
|
||||||
x: s32 = 1 + 2 * 3;
|
x: s32 = 1 + 2 * 3;
|
||||||
|
println(x);
|
||||||
return if (x == 9) 1 else 0;
|
return if (x == 9) 1 else 0;
|
||||||
}
|
}
|
||||||
)";
|
)";
|
||||||
|
|||||||
Reference in New Issue
Block a user