feat: introduce pointerof operation

Introduce pointerof operation and do some side-quests along the way.

Refs: #34
Closes: #17
This commit is contained in:
2026-07-05 14:54:16 +02:00
parent 9690ac3617
commit 642d57622a
13 changed files with 290 additions and 141 deletions
+26 -10
View File
@@ -9,6 +9,7 @@
#include "furc/front/token.hpp"
#include <fstream>
#include <optional>
#include <string>
#include <unordered_map>
#include <vector>
@@ -313,27 +314,42 @@ struct unaryop_info {
std::uint32_t precedence;
};
ast::expression_node_r parser::parse_expression_unary(std::uint32_t precedence) {
static inline std::optional<unaryop_info> get_unaryop_info(const token_r& token) {
static std::unordered_map<token_t, unaryop_info> s_prefixes = {
{ token_t::Plus, unaryop_info{ ast::unaryop_expression_node_t::Positive, 3 } },
{ token_t::Minus, unaryop_info{ ast::unaryop_expression_node_t::Negative, 3 } },
{ token_t::Plus, unaryop_info{ ast::unaryop_expression_node_t::Positive, 2 } },
{ token_t::Minus, unaryop_info{ ast::unaryop_expression_node_t::Negative, 2 } },
{ token_t::DPlus, unaryop_info{ ast::unaryop_expression_node_t::PrefixIncrement, 2 } },
{ token_t::DMinus, unaryop_info{ ast::unaryop_expression_node_t::PrefixDecrement, 2 } },
};
static std::unordered_map<keyword_token, unaryop_info> s_keywords = {
{ keyword_token::Pointerof, unaryop_info{ ast::unaryop_expression_node_t::Pointerof, 2 } },
};
if (token->type == token_t::Keyword) {
auto it = s_keywords.find(token->value.keyword);
if (it == s_keywords.end()) return {};
return it->second;
}
auto it = s_prefixes.find(token->type);
if (it == s_prefixes.end()) return {};
return it->second;
}
ast::expression_node_r parser::parse_expression_unary(std::uint32_t precedence) {
std::shared_ptr<ast::unary_op_expression_node> result;
while (true) {
auto it = s_prefixes.find(peek_token()->type);
if (it == s_prefixes.end()) break;
auto current = it->second;
auto opt = get_unaryop_info(peek_token());
if (!opt.has_value()) break;
unaryop_info current = opt.value();
if (current.precedence >= precedence) break;
auto token = next_token();
ast::expression_node_p expression;
auto nextIt = s_prefixes.find(peek_token()->type);
if (nextIt != s_prefixes.end()) {
auto next = nextIt->second;
opt = get_unaryop_info(peek_token());
if (opt.has_value()) {
auto next = opt.value();
auto expr = parse_expression_unary(current.precedence + 1);
if (expr.has_error()) {
return ast::expression_node_r(ast::error{ expr.error().location });
@@ -464,7 +480,7 @@ ast::expression_node_r parser::parse_expression_rhs(ast::expression_node_p&& ini
} else if (current.type == rhsop_info_t::FuncCall && peek_token().has_value()) {
if (peek_token()->type != token_t::RParen) {
while (true) {
auto expr = parse_expression_unary(current.precedence + 1);
auto expr = parse_expression_unary(16);
if (expr.has_error()) {
return ast::expression_node_r(ast::error{ expr.error().location });
}