Improve memory management for Result

This commit is contained in:
Sofia 2026-04-11 17:55:49 +03:00
parent 344b7588d8
commit 712c0bed51
2 changed files with 35 additions and 34 deletions

View File

@ -15,10 +15,10 @@ namespace parsing {
stream.m_position = inner.m_position;
auto ty = new types::FundamentalType{ types::FundamentalTypeKind::Int };
return new std::unique_ptr<types::Type>{ ty };
return std::unique_ptr<types::Type>{ ty };
}
catch (std::runtime_error& error) {
return new std::string{ error.what() };
return std::string{ error.what() };
}
}
@ -30,20 +30,20 @@ namespace parsing {
stream.m_position = inner.m_position;
auto expr = new AST::IntLiteralExpression{ token.metadata, std::stoi(token.content) };
return new std::unique_ptr<AST::Expression>{ expr };
return std::unique_ptr<AST::Expression>{ expr };
}
else if (token.type == token::Type::Ident) {
stream.m_position = inner.m_position;
auto expr = new AST::ValueReferenceExpression{ token.metadata, token.content };
return new std::unique_ptr<AST::Expression>{ expr };
return std::unique_ptr<AST::Expression>{ expr };
}
else {
throw std::runtime_error("Expected expression");
}
}
catch (std::runtime_error& error) {
return new std::string{ error.what() };
return std::string{ error.what() };
}
}
@ -67,7 +67,7 @@ namespace parsing {
inner.expect(token::Type::Symbol, ")");
auto fn_call = new AST::FunctionCallExpression{ before_meta + inner.metadata(), plain_expr.unwrap(), std::move(args) };
plain_expr = new std::unique_ptr<AST::Expression>{ fn_call };
plain_expr = std::unique_ptr<AST::Expression>{ fn_call };
}
@ -75,7 +75,7 @@ namespace parsing {
return plain_expr;
}
catch (std::runtime_error& error) {
return new std::string{ error.what() };
return std::string{ error.what() };
}
}
@ -88,29 +88,29 @@ namespace parsing {
}
else if (token.content == "=") {
stream.m_position = inner.m_position;
return new types::BinOp{ types::BinOp::Assignment };
return types::BinOp{ types::BinOp::Assignment };
}
else if (token.content == "+") {
stream.m_position = inner.m_position;
return new types::BinOp{ types::BinOp::Add };
return types::BinOp{ types::BinOp::Add };
}
else if (token.content == "-") {
stream.m_position = inner.m_position;
return new types::BinOp{ types::BinOp::Sub };
return types::BinOp{ types::BinOp::Sub };
}
else if (token.content == "<") {
stream.m_position = inner.m_position;
return new types::BinOp{ types::BinOp::LessThan };
return types::BinOp{ types::BinOp::LessThan };
}
else if (token.content == ">") {
stream.m_position = inner.m_position;
return new types::BinOp{ types::BinOp::GreaterThan };
return types::BinOp{ types::BinOp::GreaterThan };
}
throw std::runtime_error("Expected binop");
}
catch (std::runtime_error& error) {
return new std::string{ error.what() };
return std::string{ error.what() };
}
}
@ -140,10 +140,10 @@ namespace parsing {
Result<std::unique_ptr<AST::Expression>, std::string> parse_expression(token::TokenStream& stream) {
try {
auto lhs = parse_primary_expression(stream).unwrap();
return new std::unique_ptr{ parse_rhs(stream, std::move(lhs), 0) };
return std::unique_ptr{ parse_rhs(stream, std::move(lhs), 0) };
}
catch (std::runtime_error& error) {
return new std::string{ error.what() };
return std::string{ error.what() };
}
}
@ -168,10 +168,10 @@ namespace parsing {
stream.m_position = inner.m_position;
auto init = new AST::InitializationStatement{ before_meta + inner.metadata(), std::move(ty), name.content, std::move(expr) };
return new std::unique_ptr<AST::InitializationStatement>{ init };
return std::unique_ptr<AST::InitializationStatement>{ init };
}
catch (std::runtime_error& error) {
return new std::string{ error.what() };
return std::string{ error.what() };
}
}
@ -187,7 +187,7 @@ namespace parsing {
stream.m_position = inner.m_position;
auto ret = new AST::ReturnStatement{ before_meta + stream.metadata(),std::move(expression) };
return new std::unique_ptr<AST::Statement>{ ret };
return std::unique_ptr<AST::Statement>{ ret };
}
else if (inner.peek().type == token::Type::IfKeyword) {
inner.next();
@ -210,17 +210,17 @@ namespace parsing {
std::move(then_statement),
std::move(else_statement)
};
return new std::unique_ptr<AST::Statement>{ statement };
return std::unique_ptr<AST::Statement>{ statement };
}
else if (auto init = parse_init_statement(inner); init.ok()) {
stream.m_position = inner.m_position;
return new std::unique_ptr<AST::Statement>{ init.unwrap() };
return std::unique_ptr<AST::Statement>{ init.unwrap() };
}
else if (auto expr = parse_expression(inner); expr.ok()) {
stream.m_position = inner.m_position;
stream.expect(token::Type::Symbol, ";");
auto expr_statement = new AST::ExpressionStatement{ before_meta + stream.metadata(), expr.unwrap() };
return new std::unique_ptr<AST::Statement>{ expr_statement };
return std::unique_ptr<AST::Statement>{ expr_statement };
}
else {
throw std::runtime_error("Expected return-keyword");
@ -228,7 +228,7 @@ namespace parsing {
}
catch (std::runtime_error& error) {
return new std::string{ error.what() };
return std::string{ error.what() };
}
}
}
@ -268,10 +268,10 @@ namespace parsing {
stream.m_position = inner.m_position;
auto fun = new AST::Function{ before_meta + stream.metadata(), std::move(type), std::move(params), name_token.content, std::move(statements) };
return new std::unique_ptr<AST::TopLevelStatement>{ fun };
return std::unique_ptr<AST::TopLevelStatement>{ fun };
}
catch (std::runtime_error& error) {
return new std::string(error.what());
return std::string(error.what());
}
}
}

View File

@ -8,29 +8,30 @@
template<typename T, typename TErr>
class Result {
private:
std::unique_ptr<T> m_value;
std::unique_ptr<TErr> m_error;
T m_value;
TErr m_error;
bool m_has_value;
public:
Result(T* value) : m_value{ std::unique_ptr<T>{value} }, m_error{ nullptr } {}
Result(TErr* error) : m_value{ nullptr }, m_error{ std::unique_ptr<TErr>{error} } {}
Result(T value) : m_value{ std::move(value) }, m_error{ {} }, m_has_value{ true } {}
Result(TErr error) : m_value{ T{} }, m_error{ error }, m_has_value{ false } {}
bool ok() {
return !m_error;
return this->m_has_value;
}
T unwrap() {
if (m_value) {
return std::move(*m_value);
if (this->m_has_value) {
return std::move(m_value);
}
else {
throw std::runtime_error("Tried to unwrap " + *m_error + "!");
throw std::runtime_error("Tried to unwrap " + m_error + "!");
}
}
TErr unwrap_err() {
if (m_error) {
return *m_error;
if (!this->m_has_value) {
return m_error;
}
else {
throw std::runtime_error("Tried to unwrap_err a value!");