|
|
|
@ -8,7 +8,12 @@ pub const BinaryOperation = enum {
|
|
|
|
|
addition,
|
|
|
|
|
subtraction,
|
|
|
|
|
multiplication,
|
|
|
|
|
division
|
|
|
|
|
division,
|
|
|
|
|
equality_comparison,
|
|
|
|
|
greater_than_comparison,
|
|
|
|
|
greater_equals_comparison,
|
|
|
|
|
less_than_comparison,
|
|
|
|
|
less_equals_comparison,
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
pub const ParsedExpression = union (enum) {
|
|
|
|
@ -16,11 +21,11 @@ pub const ParsedExpression = union (enum) {
|
|
|
|
|
invalid: []const u8,
|
|
|
|
|
|
|
|
|
|
pub fn init(allocator: coral.io.Allocator, tokenizer: *tokens.Tokenizer) coral.io.AllocationError!ParsedExpression {
|
|
|
|
|
var parsed_term_expression = try init_term(allocator, tokenizer);
|
|
|
|
|
var parsed_lhs_expression = try init_equality(allocator, tokenizer);
|
|
|
|
|
|
|
|
|
|
switch (parsed_term_expression) {
|
|
|
|
|
.valid => |*term_expression| {
|
|
|
|
|
var expression = term_expression.*;
|
|
|
|
|
switch (parsed_lhs_expression) {
|
|
|
|
|
.valid => |*lhs_expression| {
|
|
|
|
|
var expression = lhs_expression.*;
|
|
|
|
|
var is_invalid = true;
|
|
|
|
|
|
|
|
|
|
defer if (is_invalid) {
|
|
|
|
@ -32,12 +37,21 @@ pub const ParsedExpression = union (enum) {
|
|
|
|
|
return ParsedExpression{.invalid = "expected right-hand side of expression after `+`"};
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var parsed_binary_expression = try init_binary(allocator, tokenizer, &expression, .addition);
|
|
|
|
|
var parsed_rhs_expression = try init_equality(allocator, tokenizer);
|
|
|
|
|
|
|
|
|
|
switch (parsed_rhs_expression) {
|
|
|
|
|
.valid => |*rhs_expression| {
|
|
|
|
|
errdefer rhs_expression.deinit(allocator);
|
|
|
|
|
|
|
|
|
|
expression = try Expression.init_binary_operation(
|
|
|
|
|
allocator,
|
|
|
|
|
.addition,
|
|
|
|
|
lhs_expression,
|
|
|
|
|
rhs_expression);
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
expression = switch (parsed_binary_expression) {
|
|
|
|
|
.valid => |binary_expression| binary_expression,
|
|
|
|
|
.invalid => |details| return ParsedExpression{.invalid = details},
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (tokenizer.current_token == .symbol_minus) {
|
|
|
|
@ -45,12 +59,21 @@ pub const ParsedExpression = union (enum) {
|
|
|
|
|
return ParsedExpression{.invalid = "expected right-hand side of expression after `-`"};
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var parsed_binary_expression = try init_binary(allocator, tokenizer, &expression, .subtraction);
|
|
|
|
|
var parsed_rhs_expression = try init_equality(allocator, tokenizer);
|
|
|
|
|
|
|
|
|
|
switch (parsed_rhs_expression) {
|
|
|
|
|
.valid => |*rhs_expression| {
|
|
|
|
|
errdefer rhs_expression.deinit(allocator);
|
|
|
|
|
|
|
|
|
|
expression = try Expression.init_binary_operation(
|
|
|
|
|
allocator,
|
|
|
|
|
.subtraction,
|
|
|
|
|
lhs_expression,
|
|
|
|
|
rhs_expression);
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
expression = switch (parsed_binary_expression) {
|
|
|
|
|
.valid => |binary_expression| binary_expression,
|
|
|
|
|
.invalid => |details| return ParsedExpression{.invalid = details},
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
is_invalid = false;
|
|
|
|
@ -58,41 +81,172 @@ pub const ParsedExpression = union (enum) {
|
|
|
|
|
return ParsedExpression{.valid = expression};
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
.invalid => |details| {
|
|
|
|
|
return ParsedExpression{.invalid = details};
|
|
|
|
|
},
|
|
|
|
|
.invalid => |details| return ParsedExpression{.invalid = details},
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fn init_binary(allocator: coral.io.Allocator, tokenizer: *tokens.Tokenizer, lhs_expression: *const Expression, operation: BinaryOperation) coral.io.AllocationError!ParsedExpression {
|
|
|
|
|
var parsed_expression = try init_term(allocator, tokenizer);
|
|
|
|
|
pub fn init_comparison(
|
|
|
|
|
allocator: coral.io.Allocator,
|
|
|
|
|
tokenizer: *tokens.Tokenizer) coral.io.AllocationError!ParsedExpression {
|
|
|
|
|
|
|
|
|
|
switch (parsed_expression) {
|
|
|
|
|
.valid => |*expression| {
|
|
|
|
|
errdefer expression.deinit(allocator);
|
|
|
|
|
var parsed_lhs_expression = try init_term(allocator, tokenizer);
|
|
|
|
|
|
|
|
|
|
const rhs_expression = try coral.io.allocate_one(allocator, expression.*);
|
|
|
|
|
switch (parsed_lhs_expression) {
|
|
|
|
|
.valid => |*lhs_expression| {
|
|
|
|
|
var expression = lhs_expression.*;
|
|
|
|
|
var is_invalid = true;
|
|
|
|
|
|
|
|
|
|
errdefer coral.io.deallocate(allocator, rhs_expression);
|
|
|
|
|
|
|
|
|
|
return ParsedExpression{
|
|
|
|
|
.valid = .{
|
|
|
|
|
.binary_operation = .{
|
|
|
|
|
.kind = operation,
|
|
|
|
|
.lhs_expression = try coral.io.allocate_one(allocator, lhs_expression.*),
|
|
|
|
|
.rhs_expression = rhs_expression,
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
defer if (is_invalid) {
|
|
|
|
|
expression.deinit(allocator);
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
if (tokenizer.current_token == .symbol_greater_than) {
|
|
|
|
|
if (!tokenizer.step()) {
|
|
|
|
|
return ParsedExpression{.invalid = "expected right-hand side of expression after `>`"};
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var parsed_rhs_expression = try init_term(allocator, tokenizer);
|
|
|
|
|
|
|
|
|
|
switch (parsed_rhs_expression) {
|
|
|
|
|
.valid => |*rhs_expression| {
|
|
|
|
|
errdefer rhs_expression.deinit(allocator);
|
|
|
|
|
|
|
|
|
|
expression = try Expression.init_binary_operation(
|
|
|
|
|
allocator,
|
|
|
|
|
.greater_than_comparison,
|
|
|
|
|
lhs_expression,
|
|
|
|
|
rhs_expression);
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
.invalid => |details| return ParsedExpression{.invalid = details},
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (tokenizer.current_token == .symbol_greater_equals) {
|
|
|
|
|
if (!tokenizer.step()) {
|
|
|
|
|
return ParsedExpression{.invalid = "expected right-hand side of expression after `>=`"};
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var parsed_rhs_expression = try init_term(allocator, tokenizer);
|
|
|
|
|
|
|
|
|
|
switch (parsed_rhs_expression) {
|
|
|
|
|
.valid => |*rhs_expression| {
|
|
|
|
|
errdefer rhs_expression.deinit(allocator);
|
|
|
|
|
|
|
|
|
|
expression = try Expression.init_binary_operation(
|
|
|
|
|
allocator,
|
|
|
|
|
.greater_equals_comparison,
|
|
|
|
|
lhs_expression,
|
|
|
|
|
rhs_expression);
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
.invalid => |details| return ParsedExpression{.invalid = details},
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (tokenizer.current_token == .symbol_less_than) {
|
|
|
|
|
if (!tokenizer.step()) {
|
|
|
|
|
return ParsedExpression{.invalid = "expected right-hand side of expression after `<`"};
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var parsed_rhs_expression = try init_term(allocator, tokenizer);
|
|
|
|
|
|
|
|
|
|
switch (parsed_rhs_expression) {
|
|
|
|
|
.valid => |*rhs_expression| {
|
|
|
|
|
errdefer rhs_expression.deinit(allocator);
|
|
|
|
|
|
|
|
|
|
expression = try Expression.init_binary_operation(
|
|
|
|
|
allocator,
|
|
|
|
|
.less_than_comparison,
|
|
|
|
|
lhs_expression,
|
|
|
|
|
rhs_expression);
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
.invalid => |details| return ParsedExpression{.invalid = details},
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (tokenizer.current_token == .symbol_less_equals) {
|
|
|
|
|
if (!tokenizer.step()) {
|
|
|
|
|
return ParsedExpression{.invalid = "expected right-hand side of expression after `<=`"};
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var parsed_rhs_expression = try init_term(allocator, tokenizer);
|
|
|
|
|
|
|
|
|
|
switch (parsed_rhs_expression) {
|
|
|
|
|
.valid => |*rhs_expression| {
|
|
|
|
|
errdefer rhs_expression.deinit(allocator);
|
|
|
|
|
|
|
|
|
|
expression = try Expression.init_binary_operation(
|
|
|
|
|
allocator,
|
|
|
|
|
.less_equals_comparison,
|
|
|
|
|
lhs_expression,
|
|
|
|
|
rhs_expression);
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
.invalid => |details| return ParsedExpression{.invalid = details},
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
is_invalid = false;
|
|
|
|
|
|
|
|
|
|
return ParsedExpression{.valid = expression};
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
.invalid => |details| {
|
|
|
|
|
return ParsedExpression{.invalid = details};
|
|
|
|
|
},
|
|
|
|
|
.invalid => |details| return ParsedExpression{.invalid = details},
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fn init_factor(allocator: coral.io.Allocator, tokenizer: *tokens.Tokenizer) coral.io.AllocationError!ParsedExpression {
|
|
|
|
|
fn init_equality(
|
|
|
|
|
allocator: coral.io.Allocator,
|
|
|
|
|
tokenizer: *tokens.Tokenizer) coral.io.AllocationError!ParsedExpression {
|
|
|
|
|
|
|
|
|
|
var parsed_lhs_expression = try init_comparison(allocator, tokenizer);
|
|
|
|
|
|
|
|
|
|
switch (parsed_lhs_expression) {
|
|
|
|
|
.valid => |*lhs_expression| {
|
|
|
|
|
var expression = lhs_expression.*;
|
|
|
|
|
var is_invalid = true;
|
|
|
|
|
|
|
|
|
|
defer if (is_invalid) {
|
|
|
|
|
expression.deinit(allocator);
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
if (tokenizer.current_token == .symbol_double_equals) {
|
|
|
|
|
if (!tokenizer.step()) {
|
|
|
|
|
return ParsedExpression{.invalid = "expected right-hand side of expression after `==`"};
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var parsed_rhs_expression = try init_comparison(allocator, tokenizer);
|
|
|
|
|
|
|
|
|
|
switch (parsed_rhs_expression) {
|
|
|
|
|
.valid => |*rhs_expression| {
|
|
|
|
|
errdefer rhs_expression.deinit(allocator);
|
|
|
|
|
|
|
|
|
|
expression = try Expression.init_binary_operation(
|
|
|
|
|
allocator,
|
|
|
|
|
.equality_comparison,
|
|
|
|
|
lhs_expression,
|
|
|
|
|
rhs_expression);
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
.invalid => |details| return ParsedExpression{.invalid = details},
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
is_invalid = false;
|
|
|
|
|
|
|
|
|
|
return ParsedExpression{.valid = expression};
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
.invalid => |details| return ParsedExpression{.invalid = details},
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fn init_factor(
|
|
|
|
|
allocator: coral.io.Allocator,
|
|
|
|
|
tokenizer: *tokens.Tokenizer) coral.io.AllocationError!ParsedExpression {
|
|
|
|
|
|
|
|
|
|
switch (tokenizer.current_token) {
|
|
|
|
|
.symbol_paren_left => {
|
|
|
|
|
if (!tokenizer.step()) {
|
|
|
|
@ -120,9 +274,7 @@ pub const ParsedExpression = union (enum) {
|
|
|
|
|
};
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
.invalid => |details| {
|
|
|
|
|
return ParsedExpression{.invalid = details};
|
|
|
|
|
}
|
|
|
|
|
.invalid => |details| return ParsedExpression{.invalid = details},
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
@ -180,7 +332,22 @@ pub const ParsedExpression = union (enum) {
|
|
|
|
|
return ParsedExpression{.invalid = "expected expression after numeric negation (`-`)"};
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return try init_unary(allocator, tokenizer, .numeric_negation);
|
|
|
|
|
var parsed_factor_expression = try init_factor(allocator, tokenizer);
|
|
|
|
|
|
|
|
|
|
switch (parsed_factor_expression) {
|
|
|
|
|
.valid => |*factor_expression| {
|
|
|
|
|
errdefer factor_expression.deinit(allocator);
|
|
|
|
|
|
|
|
|
|
return ParsedExpression{
|
|
|
|
|
.valid = try Expression.init_unary_operation(
|
|
|
|
|
allocator,
|
|
|
|
|
.numeric_negation,
|
|
|
|
|
factor_expression),
|
|
|
|
|
};
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
.invalid => |details| return ParsedExpression{.invalid = details},
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
.symbol_bang => {
|
|
|
|
@ -188,19 +355,34 @@ pub const ParsedExpression = union (enum) {
|
|
|
|
|
return ParsedExpression{.invalid = "expected expression after boolean negation (`!`)"};
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return try init_unary(allocator, tokenizer, .boolean_negation);
|
|
|
|
|
var parsed_factor_expression = try init_factor(allocator, tokenizer);
|
|
|
|
|
|
|
|
|
|
switch (parsed_factor_expression) {
|
|
|
|
|
.valid => |*factor_expression| {
|
|
|
|
|
errdefer factor_expression.deinit(allocator);
|
|
|
|
|
|
|
|
|
|
return ParsedExpression{
|
|
|
|
|
.valid = try Expression.init_unary_operation(
|
|
|
|
|
allocator,
|
|
|
|
|
.boolean_negation,
|
|
|
|
|
factor_expression),
|
|
|
|
|
};
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
.invalid => |details| return ParsedExpression{.invalid = details},
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
else => return ParsedExpression{.invalid = "unexpected token in expression"},
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fn init_term(allocator: coral.io.Allocator, tokenizer: *tokens.Tokenizer) coral.io.AllocationError!ParsedExpression {
|
|
|
|
|
var parsed_factor_expression = try init_factor(allocator, tokenizer);
|
|
|
|
|
pub fn init_term(allocator: coral.io.Allocator, tokenizer: *tokens.Tokenizer) coral.io.AllocationError!ParsedExpression {
|
|
|
|
|
var parsed_lhs_expression = try init_factor(allocator, tokenizer);
|
|
|
|
|
|
|
|
|
|
switch (parsed_factor_expression) {
|
|
|
|
|
.valid => |*factor_expression| {
|
|
|
|
|
var expression = factor_expression.*;
|
|
|
|
|
switch (parsed_lhs_expression) {
|
|
|
|
|
.valid => |*lhs_expression| {
|
|
|
|
|
var expression = lhs_expression.*;
|
|
|
|
|
var is_invalid = true;
|
|
|
|
|
|
|
|
|
|
defer if (is_invalid) {
|
|
|
|
@ -212,12 +394,21 @@ pub const ParsedExpression = union (enum) {
|
|
|
|
|
return ParsedExpression{.invalid = "expected right-hand side of expression after `*`"};
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var parsed_binary_expression = try init_binary(allocator, tokenizer, &expression, .multiplication);
|
|
|
|
|
var parsed_rhs_expression = try init_factor(allocator, tokenizer);
|
|
|
|
|
|
|
|
|
|
switch (parsed_rhs_expression) {
|
|
|
|
|
.valid => |*rhs_expression| {
|
|
|
|
|
errdefer rhs_expression.deinit(allocator);
|
|
|
|
|
|
|
|
|
|
expression = try Expression.init_binary_operation(
|
|
|
|
|
allocator,
|
|
|
|
|
.multiplication,
|
|
|
|
|
lhs_expression,
|
|
|
|
|
rhs_expression);
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
expression = switch (parsed_binary_expression) {
|
|
|
|
|
.valid => |binary_expression| binary_expression,
|
|
|
|
|
.invalid => |details| return ParsedExpression{.invalid = details},
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (tokenizer.current_token == .symbol_forward_slash) {
|
|
|
|
@ -225,12 +416,21 @@ pub const ParsedExpression = union (enum) {
|
|
|
|
|
return ParsedExpression{.invalid = "expected right-hand side of expression after `/`"};
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var parsed_binary_expression = try init_binary(allocator, tokenizer, &expression, .division);
|
|
|
|
|
var parsed_rhs_expression = try init_equality(allocator, tokenizer);
|
|
|
|
|
|
|
|
|
|
switch (parsed_rhs_expression) {
|
|
|
|
|
.valid => |*rhs_expression| {
|
|
|
|
|
errdefer rhs_expression.deinit(allocator);
|
|
|
|
|
|
|
|
|
|
expression = try Expression.init_binary_operation(
|
|
|
|
|
allocator,
|
|
|
|
|
.division,
|
|
|
|
|
lhs_expression,
|
|
|
|
|
rhs_expression);
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
expression = switch (parsed_binary_expression) {
|
|
|
|
|
.valid => |binary_expression| binary_expression,
|
|
|
|
|
.invalid => |details| return ParsedExpression{.invalid = details},
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
is_invalid = false;
|
|
|
|
@ -238,32 +438,7 @@ pub const ParsedExpression = union (enum) {
|
|
|
|
|
return ParsedExpression{.valid = expression};
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
.invalid => |details| {
|
|
|
|
|
return ParsedExpression{.invalid = details};
|
|
|
|
|
},
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fn init_unary(allocator: coral.io.Allocator, tokenizer: *tokens.Tokenizer, operation: UnaryOperation) coral.io.AllocationError!ParsedExpression {
|
|
|
|
|
var parsed_factor_expression = try init_factor(allocator, tokenizer);
|
|
|
|
|
|
|
|
|
|
switch (parsed_factor_expression) {
|
|
|
|
|
.valid => |*factor_expression| {
|
|
|
|
|
errdefer factor_expression.deinit(allocator);
|
|
|
|
|
|
|
|
|
|
return ParsedExpression{
|
|
|
|
|
.valid = .{
|
|
|
|
|
.unary_operation = .{
|
|
|
|
|
.kind = operation,
|
|
|
|
|
.expression = try coral.io.allocate_one(allocator, factor_expression.*),
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
};
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
.invalid => |details| {
|
|
|
|
|
return ParsedExpression{.invalid = details};
|
|
|
|
|
},
|
|
|
|
|
.invalid => |details| return ParsedExpression{.invalid = details},
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
@ -393,6 +568,46 @@ pub const Expression = union (enum) {
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fn init_binary_operation(
|
|
|
|
|
allocator: coral.io.Allocator,
|
|
|
|
|
kind: BinaryOperation,
|
|
|
|
|
lhs_expression: *const Expression,
|
|
|
|
|
rhs_operation: *const Expression) coral.io.AllocationError!Expression {
|
|
|
|
|
|
|
|
|
|
const allocated_lhs_expression = try coral.io.allocate_one(allocator, lhs_expression.*);
|
|
|
|
|
|
|
|
|
|
errdefer coral.io.deallocate(allocator, allocated_lhs_expression);
|
|
|
|
|
|
|
|
|
|
const allocated_rhs_expression = try coral.io.allocate_one(allocator, rhs_operation.*);
|
|
|
|
|
|
|
|
|
|
errdefer coral.io.deallocate(allocator, allocated_rhs_expression);
|
|
|
|
|
|
|
|
|
|
return Expression{
|
|
|
|
|
.binary_operation = .{
|
|
|
|
|
.kind = kind,
|
|
|
|
|
.lhs_expression = allocated_lhs_expression,
|
|
|
|
|
.rhs_expression = allocated_rhs_expression,
|
|
|
|
|
},
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fn init_unary_operation(
|
|
|
|
|
allocator: coral.io.Allocator,
|
|
|
|
|
kind: UnaryOperation,
|
|
|
|
|
expression: *const Expression) coral.io.AllocationError!Expression {
|
|
|
|
|
|
|
|
|
|
const allocated_expression = try coral.io.allocate_one(allocator, expression.*);
|
|
|
|
|
|
|
|
|
|
errdefer coral.io.deallocate(allocator, allocated_expression);
|
|
|
|
|
|
|
|
|
|
return Expression{
|
|
|
|
|
.unary_operation = .{
|
|
|
|
|
.kind = kind,
|
|
|
|
|
.expression = allocated_expression,
|
|
|
|
|
},
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
pub const Statements = struct {
|
|
|
|
|