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; stream.m_position = inner.m_position;
auto ty = new types::FundamentalType{ types::FundamentalTypeKind::Int }; 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) { 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; stream.m_position = inner.m_position;
auto expr = new AST::IntLiteralExpression{ token.metadata, std::stoi(token.content) }; 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) { else if (token.type == token::Type::Ident) {
stream.m_position = inner.m_position; stream.m_position = inner.m_position;
auto expr = new AST::ValueReferenceExpression{ token.metadata, token.content }; 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 { else {
throw std::runtime_error("Expected expression"); throw std::runtime_error("Expected expression");
} }
} }
catch (std::runtime_error& error) { 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, ")"); inner.expect(token::Type::Symbol, ")");
auto fn_call = new AST::FunctionCallExpression{ before_meta + inner.metadata(), plain_expr.unwrap(), std::move(args) }; 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; return plain_expr;
} }
catch (std::runtime_error& error) { 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 == "=") { else if (token.content == "=") {
stream.m_position = inner.m_position; stream.m_position = inner.m_position;
return new types::BinOp{ types::BinOp::Assignment }; return types::BinOp{ types::BinOp::Assignment };
} }
else if (token.content == "+") { else if (token.content == "+") {
stream.m_position = inner.m_position; stream.m_position = inner.m_position;
return new types::BinOp{ types::BinOp::Add }; return types::BinOp{ types::BinOp::Add };
} }
else if (token.content == "-") { else if (token.content == "-") {
stream.m_position = inner.m_position; stream.m_position = inner.m_position;
return new types::BinOp{ types::BinOp::Sub }; return types::BinOp{ types::BinOp::Sub };
} }
else if (token.content == "<") { else if (token.content == "<") {
stream.m_position = inner.m_position; stream.m_position = inner.m_position;
return new types::BinOp{ types::BinOp::LessThan }; return types::BinOp{ types::BinOp::LessThan };
} }
else if (token.content == ">") { else if (token.content == ">") {
stream.m_position = inner.m_position; 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"); throw std::runtime_error("Expected binop");
} }
catch (std::runtime_error& error) { 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) { Result<std::unique_ptr<AST::Expression>, std::string> parse_expression(token::TokenStream& stream) {
try { try {
auto lhs = parse_primary_expression(stream).unwrap(); 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) { 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; stream.m_position = inner.m_position;
auto init = new AST::InitializationStatement{ before_meta + inner.metadata(), std::move(ty), name.content, std::move(expr) }; 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) { 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; stream.m_position = inner.m_position;
auto ret = new AST::ReturnStatement{ before_meta + stream.metadata(),std::move(expression) }; 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) { else if (inner.peek().type == token::Type::IfKeyword) {
inner.next(); inner.next();
@ -210,17 +210,17 @@ namespace parsing {
std::move(then_statement), std::move(then_statement),
std::move(else_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()) { else if (auto init = parse_init_statement(inner); init.ok()) {
stream.m_position = inner.m_position; 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()) { else if (auto expr = parse_expression(inner); expr.ok()) {
stream.m_position = inner.m_position; stream.m_position = inner.m_position;
stream.expect(token::Type::Symbol, ";"); stream.expect(token::Type::Symbol, ";");
auto expr_statement = new AST::ExpressionStatement{ before_meta + stream.metadata(), expr.unwrap() }; 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 { else {
throw std::runtime_error("Expected return-keyword"); throw std::runtime_error("Expected return-keyword");
@ -228,7 +228,7 @@ namespace parsing {
} }
catch (std::runtime_error& error) { 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; 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) }; 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) { 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> template<typename T, typename TErr>
class Result { class Result {
private: private:
std::unique_ptr<T> m_value; T m_value;
std::unique_ptr<TErr> m_error; TErr m_error;
bool m_has_value;
public: public:
Result(T* value) : m_value{ std::unique_ptr<T>{value} }, m_error{ nullptr } {} Result(T value) : m_value{ std::move(value) }, m_error{ {} }, m_has_value{ true } {}
Result(TErr* error) : m_value{ nullptr }, m_error{ std::unique_ptr<TErr>{error} } {} Result(TErr error) : m_value{ T{} }, m_error{ error }, m_has_value{ false } {}
bool ok() { bool ok() {
return !m_error; return this->m_has_value;
} }
T unwrap() { T unwrap() {
if (m_value) { if (this->m_has_value) {
return std::move(*m_value); return std::move(m_value);
} }
else { else {
throw std::runtime_error("Tried to unwrap " + *m_error + "!"); throw std::runtime_error("Tried to unwrap " + m_error + "!");
} }
} }
TErr unwrap_err() { TErr unwrap_err() {
if (m_error) { if (!this->m_has_value) {
return *m_error; return m_error;
} }
else { else {
throw std::runtime_error("Tried to unwrap_err a value!"); throw std::runtime_error("Tried to unwrap_err a value!");