Compare commits
No commits in common. "1dc0c7f225683ce601ae14e88660087c2fd2f555" and "4291bc28dc3ddd7ffaf08e09bcfc3c7c15db0b84" have entirely different histories.
1dc0c7f225
...
4291bc28dc
@ -34,12 +34,6 @@ const Opcode = enum (u8) {
|
|||||||
sub,
|
sub,
|
||||||
mul,
|
mul,
|
||||||
div,
|
div,
|
||||||
|
|
||||||
compare_eq,
|
|
||||||
compare_gt,
|
|
||||||
compare_lt,
|
|
||||||
compare_ge,
|
|
||||||
compare_le,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const Self = @This();
|
const Self = @This();
|
||||||
@ -150,11 +144,6 @@ pub fn compile_expression(self: *Self, expression: ast.Expression) types.Runtime
|
|||||||
.subtraction => .sub,
|
.subtraction => .sub,
|
||||||
.multiplication => .mul,
|
.multiplication => .mul,
|
||||||
.division => .div,
|
.division => .div,
|
||||||
.equality_comparison => .compare_eq,
|
|
||||||
.greater_than_comparison => .compare_gt,
|
|
||||||
.greater_equals_comparison => .compare_ge,
|
|
||||||
.less_than_comparison => .compare_lt,
|
|
||||||
.less_equals_comparison => .compare_le,
|
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -8,12 +8,7 @@ pub const BinaryOperation = enum {
|
|||||||
addition,
|
addition,
|
||||||
subtraction,
|
subtraction,
|
||||||
multiplication,
|
multiplication,
|
||||||
division,
|
division
|
||||||
equality_comparison,
|
|
||||||
greater_than_comparison,
|
|
||||||
greater_equals_comparison,
|
|
||||||
less_than_comparison,
|
|
||||||
less_equals_comparison,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
pub const ParsedExpression = union (enum) {
|
pub const ParsedExpression = union (enum) {
|
||||||
@ -21,11 +16,11 @@ pub const ParsedExpression = union (enum) {
|
|||||||
invalid: []const u8,
|
invalid: []const u8,
|
||||||
|
|
||||||
pub fn init(allocator: coral.io.Allocator, tokenizer: *tokens.Tokenizer) coral.io.AllocationError!ParsedExpression {
|
pub fn init(allocator: coral.io.Allocator, tokenizer: *tokens.Tokenizer) coral.io.AllocationError!ParsedExpression {
|
||||||
var parsed_lhs_expression = try init_equality(allocator, tokenizer);
|
var parsed_term_expression = try init_term(allocator, tokenizer);
|
||||||
|
|
||||||
switch (parsed_lhs_expression) {
|
switch (parsed_term_expression) {
|
||||||
.valid => |*lhs_expression| {
|
.valid => |*term_expression| {
|
||||||
var expression = lhs_expression.*;
|
var expression = term_expression.*;
|
||||||
var is_invalid = true;
|
var is_invalid = true;
|
||||||
|
|
||||||
defer if (is_invalid) {
|
defer if (is_invalid) {
|
||||||
@ -37,21 +32,12 @@ pub const ParsedExpression = union (enum) {
|
|||||||
return ParsedExpression{.invalid = "expected right-hand side of expression after `+`"};
|
return ParsedExpression{.invalid = "expected right-hand side of expression after `+`"};
|
||||||
}
|
}
|
||||||
|
|
||||||
var parsed_rhs_expression = try init_equality(allocator, tokenizer);
|
var parsed_binary_expression = try init_binary(allocator, tokenizer, &expression, .addition);
|
||||||
|
|
||||||
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},
|
.invalid => |details| return ParsedExpression{.invalid = details},
|
||||||
}
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
if (tokenizer.current_token == .symbol_minus) {
|
if (tokenizer.current_token == .symbol_minus) {
|
||||||
@ -59,133 +45,12 @@ pub const ParsedExpression = union (enum) {
|
|||||||
return ParsedExpression{.invalid = "expected right-hand side of expression after `-`"};
|
return ParsedExpression{.invalid = "expected right-hand side of expression after `-`"};
|
||||||
}
|
}
|
||||||
|
|
||||||
var parsed_rhs_expression = try init_equality(allocator, tokenizer);
|
var parsed_binary_expression = try init_binary(allocator, tokenizer, &expression, .subtraction);
|
||||||
|
|
||||||
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},
|
.invalid => |details| return ParsedExpression{.invalid = details},
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
is_invalid = false;
|
|
||||||
|
|
||||||
return ParsedExpression{.valid = expression};
|
|
||||||
},
|
|
||||||
|
|
||||||
.invalid => |details| return ParsedExpression{.invalid = details},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn init_comparison(
|
|
||||||
allocator: coral.io.Allocator,
|
|
||||||
tokenizer: *tokens.Tokenizer) coral.io.AllocationError!ParsedExpression {
|
|
||||||
|
|
||||||
var parsed_lhs_expression = try init_term(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_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;
|
is_invalid = false;
|
||||||
@ -193,60 +58,41 @@ pub const ParsedExpression = union (enum) {
|
|||||||
return ParsedExpression{.valid = expression};
|
return ParsedExpression{.valid = expression};
|
||||||
},
|
},
|
||||||
|
|
||||||
.invalid => |details| return ParsedExpression{.invalid = details},
|
.invalid => |details| {
|
||||||
|
return ParsedExpression{.invalid = details};
|
||||||
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn init_equality(
|
fn init_binary(allocator: coral.io.Allocator, tokenizer: *tokens.Tokenizer, lhs_expression: *const Expression, operation: BinaryOperation) coral.io.AllocationError!ParsedExpression {
|
||||||
allocator: coral.io.Allocator,
|
var parsed_expression = try init_term(allocator, tokenizer);
|
||||||
tokenizer: *tokens.Tokenizer) coral.io.AllocationError!ParsedExpression {
|
|
||||||
|
|
||||||
var parsed_lhs_expression = try init_comparison(allocator, tokenizer);
|
switch (parsed_expression) {
|
||||||
|
.valid => |*expression| {
|
||||||
|
errdefer expression.deinit(allocator);
|
||||||
|
|
||||||
switch (parsed_lhs_expression) {
|
const rhs_expression = try coral.io.allocate_one(allocator, expression.*);
|
||||||
.valid => |*lhs_expression| {
|
|
||||||
var expression = lhs_expression.*;
|
|
||||||
var is_invalid = true;
|
|
||||||
|
|
||||||
defer if (is_invalid) {
|
errdefer coral.io.deallocate(allocator, rhs_expression);
|
||||||
expression.deinit(allocator);
|
|
||||||
|
return ParsedExpression{
|
||||||
|
.valid = .{
|
||||||
|
.binary_operation = .{
|
||||||
|
.kind = operation,
|
||||||
|
.lhs_expression = try coral.io.allocate_one(allocator, lhs_expression.*),
|
||||||
|
.rhs_expression = rhs_expression,
|
||||||
|
},
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
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},
|
.invalid => |details| {
|
||||||
}
|
return ParsedExpression{.invalid = details};
|
||||||
}
|
|
||||||
|
|
||||||
is_invalid = false;
|
|
||||||
|
|
||||||
return ParsedExpression{.valid = expression};
|
|
||||||
},
|
},
|
||||||
|
|
||||||
.invalid => |details| return ParsedExpression{.invalid = details},
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn init_factor(
|
fn init_factor(allocator: coral.io.Allocator, tokenizer: *tokens.Tokenizer) coral.io.AllocationError!ParsedExpression {
|
||||||
allocator: coral.io.Allocator,
|
|
||||||
tokenizer: *tokens.Tokenizer) coral.io.AllocationError!ParsedExpression {
|
|
||||||
|
|
||||||
switch (tokenizer.current_token) {
|
switch (tokenizer.current_token) {
|
||||||
.symbol_paren_left => {
|
.symbol_paren_left => {
|
||||||
if (!tokenizer.step()) {
|
if (!tokenizer.step()) {
|
||||||
@ -274,7 +120,9 @@ pub const ParsedExpression = union (enum) {
|
|||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|
||||||
.invalid => |details| return ParsedExpression{.invalid = details},
|
.invalid => |details| {
|
||||||
|
return ParsedExpression{.invalid = details};
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -332,22 +180,7 @@ pub const ParsedExpression = union (enum) {
|
|||||||
return ParsedExpression{.invalid = "expected expression after numeric negation (`-`)"};
|
return ParsedExpression{.invalid = "expected expression after numeric negation (`-`)"};
|
||||||
}
|
}
|
||||||
|
|
||||||
var parsed_factor_expression = try init_factor(allocator, tokenizer);
|
return try init_unary(allocator, tokenizer, .numeric_negation);
|
||||||
|
|
||||||
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 => {
|
.symbol_bang => {
|
||||||
@ -355,34 +188,19 @@ pub const ParsedExpression = union (enum) {
|
|||||||
return ParsedExpression{.invalid = "expected expression after boolean negation (`!`)"};
|
return ParsedExpression{.invalid = "expected expression after boolean negation (`!`)"};
|
||||||
}
|
}
|
||||||
|
|
||||||
var parsed_factor_expression = try init_factor(allocator, tokenizer);
|
return try init_unary(allocator, tokenizer, .boolean_negation);
|
||||||
|
|
||||||
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"},
|
else => return ParsedExpression{.invalid = "unexpected token in expression"},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn init_term(allocator: coral.io.Allocator, tokenizer: *tokens.Tokenizer) coral.io.AllocationError!ParsedExpression {
|
fn init_term(allocator: coral.io.Allocator, tokenizer: *tokens.Tokenizer) coral.io.AllocationError!ParsedExpression {
|
||||||
var parsed_lhs_expression = try init_factor(allocator, tokenizer);
|
var parsed_factor_expression = try init_factor(allocator, tokenizer);
|
||||||
|
|
||||||
switch (parsed_lhs_expression) {
|
switch (parsed_factor_expression) {
|
||||||
.valid => |*lhs_expression| {
|
.valid => |*factor_expression| {
|
||||||
var expression = lhs_expression.*;
|
var expression = factor_expression.*;
|
||||||
var is_invalid = true;
|
var is_invalid = true;
|
||||||
|
|
||||||
defer if (is_invalid) {
|
defer if (is_invalid) {
|
||||||
@ -394,21 +212,12 @@ pub const ParsedExpression = union (enum) {
|
|||||||
return ParsedExpression{.invalid = "expected right-hand side of expression after `*`"};
|
return ParsedExpression{.invalid = "expected right-hand side of expression after `*`"};
|
||||||
}
|
}
|
||||||
|
|
||||||
var parsed_rhs_expression = try init_factor(allocator, tokenizer);
|
var parsed_binary_expression = try init_binary(allocator, tokenizer, &expression, .multiplication);
|
||||||
|
|
||||||
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},
|
.invalid => |details| return ParsedExpression{.invalid = details},
|
||||||
}
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
if (tokenizer.current_token == .symbol_forward_slash) {
|
if (tokenizer.current_token == .symbol_forward_slash) {
|
||||||
@ -416,21 +225,12 @@ pub const ParsedExpression = union (enum) {
|
|||||||
return ParsedExpression{.invalid = "expected right-hand side of expression after `/`"};
|
return ParsedExpression{.invalid = "expected right-hand side of expression after `/`"};
|
||||||
}
|
}
|
||||||
|
|
||||||
var parsed_rhs_expression = try init_equality(allocator, tokenizer);
|
var parsed_binary_expression = try init_binary(allocator, tokenizer, &expression, .division);
|
||||||
|
|
||||||
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},
|
.invalid => |details| return ParsedExpression{.invalid = details},
|
||||||
}
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
is_invalid = false;
|
is_invalid = false;
|
||||||
@ -438,7 +238,32 @@ pub const ParsedExpression = union (enum) {
|
|||||||
return ParsedExpression{.valid = expression};
|
return ParsedExpression{.valid = expression};
|
||||||
},
|
},
|
||||||
|
|
||||||
.invalid => |details| return ParsedExpression{.invalid = details},
|
.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};
|
||||||
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -568,46 +393,6 @@ 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 {
|
pub const Statements = struct {
|
||||||
|
@ -22,13 +22,7 @@ pub const Token = union(enum) {
|
|||||||
symbol_bracket_left,
|
symbol_bracket_left,
|
||||||
symbol_bracket_right,
|
symbol_bracket_right,
|
||||||
symbol_period,
|
symbol_period,
|
||||||
symbol_lambda,
|
symbol_arrow,
|
||||||
symbol_less_than,
|
|
||||||
symbol_less_equals,
|
|
||||||
symbol_greater_than,
|
|
||||||
symbol_greater_equals,
|
|
||||||
symbol_equals,
|
|
||||||
symbol_double_equals,
|
|
||||||
|
|
||||||
integer: []const u8,
|
integer: []const u8,
|
||||||
real: []const u8,
|
real: []const u8,
|
||||||
@ -317,60 +311,9 @@ pub const Tokenizer = struct {
|
|||||||
},
|
},
|
||||||
|
|
||||||
'=' => {
|
'=' => {
|
||||||
|
self.current_token = .symbol_assign;
|
||||||
cursor += 1;
|
cursor += 1;
|
||||||
|
|
||||||
if (self.has_next()) {
|
|
||||||
switch (self.source[cursor]) {
|
|
||||||
'=' => {
|
|
||||||
cursor += 1;
|
|
||||||
self.current_token = .symbol_double_equals;
|
|
||||||
|
|
||||||
return true;
|
|
||||||
},
|
|
||||||
|
|
||||||
'>' => {
|
|
||||||
cursor += 1;
|
|
||||||
self.current_token = .symbol_lambda;
|
|
||||||
|
|
||||||
return true;
|
|
||||||
},
|
|
||||||
|
|
||||||
else => {},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
self.current_token = .symbol_equals;
|
|
||||||
|
|
||||||
return true;
|
|
||||||
},
|
|
||||||
|
|
||||||
'<' => {
|
|
||||||
cursor += 1;
|
|
||||||
|
|
||||||
if (self.has_next() and (self.source[cursor] == '=')) {
|
|
||||||
cursor += 1;
|
|
||||||
self.current_token = .symbol_less_equals;
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
self.current_token = .symbol_less_than;
|
|
||||||
|
|
||||||
return true;
|
|
||||||
},
|
|
||||||
|
|
||||||
'>' => {
|
|
||||||
cursor += 1;
|
|
||||||
|
|
||||||
if (self.has_next() and (self.source[cursor] == '=')) {
|
|
||||||
cursor += 1;
|
|
||||||
self.current_token = .symbol_greater_equals;
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
self.current_token = .symbol_greater_than;
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -38,6 +38,38 @@ pub const RuntimeError = coral.io.AllocationError || CheckError || error {
|
|||||||
BadSyntax,
|
BadSyntax,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
pub fn SmallStack(comptime Element: type, comptime default: Element) type {
|
||||||
|
const maximum = 255;
|
||||||
|
|
||||||
|
return struct {
|
||||||
|
buffer: [maximum]Element = [_]Element{default} ** maximum,
|
||||||
|
count: u8 = 0,
|
||||||
|
|
||||||
|
const Self = @This();
|
||||||
|
|
||||||
|
fn peek(self: Self) ?Element {
|
||||||
|
if (self.count == 0) return null;
|
||||||
|
|
||||||
|
return self.buffer[self.count - 1];
|
||||||
|
}
|
||||||
|
|
||||||
|
fn pop(self: *Self) ?Element {
|
||||||
|
if (self.count == 0) return null;
|
||||||
|
|
||||||
|
self.count -= 1;
|
||||||
|
|
||||||
|
return self.buffer[self.count];
|
||||||
|
}
|
||||||
|
|
||||||
|
fn push(self: *Self, element: Element) !void {
|
||||||
|
if (self.count == maximum) return error.OutOfMemory;
|
||||||
|
|
||||||
|
self.buffer[self.count] = element;
|
||||||
|
self.count += 1;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
pub const Val = union (Primitive) {
|
pub const Val = union (Primitive) {
|
||||||
nil,
|
nil,
|
||||||
false,
|
false,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user