Strength compile-time guarantees of AST operators
continuous-integration/drone/push Build is passing Details
continuous-integration/drone/pr Build is passing Details

This commit is contained in:
kayomn 2023-06-03 14:16:02 +00:00
parent 071d890391
commit bff3db0720
2 changed files with 56 additions and 30 deletions

View File

@ -9,6 +9,32 @@ arena: coral.arena.Stacking,
statements: StatementList, statements: StatementList,
error_message: []const u8, error_message: []const u8,
pub const BinaryOperator = enum {
addition,
subtraction,
multiplication,
divsion,
equals_comparison,
greater_than_comparison,
greater_equals_comparison,
less_than_comparison,
less_equals_comparison,
fn token(self: BinaryOperator) tokens.Token {
return switch (self) {
.addition => .symbol_plus,
.subtraction => .symbol_minus,
.multiplication => .symbol_asterisk,
.divsion => .symbol_forward_slash,
.equals_comparison => .symbol_double_equals,
.greater_than_comparison => .symbol_greater_than,
.greater_equals_comparison => .symbol_greater_equals,
.less_than_comparison => .symbol_less_than,
.less_equals_comparison => .symbol_less_equals,
};
}
};
pub const Expression = union (enum) { pub const Expression = union (enum) {
nil_literal, nil_literal,
true_literal, true_literal,
@ -26,13 +52,13 @@ pub const Expression = union (enum) {
grouped_expression: *Expression, grouped_expression: *Expression,
binary_operation: struct { binary_operation: struct {
operator: tokens.Token, operator: BinaryOperator,
lhs_expression: *Expression, lhs_expression: *Expression,
rhs_expression: *Expression, rhs_expression: *Expression,
}, },
unary_operation: struct { unary_operation: struct {
operator: tokens.Token, operator: UnaryOperator,
expression: *Expression, expression: *Expression,
}, },
}; };
@ -48,12 +74,12 @@ pub const Statement = union (enum) {
const StatementList = coral.list.Stack(Statement); const StatementList = coral.list.Stack(Statement);
const UnaryOperation = enum { const UnaryOperator = enum {
boolean_negation, boolean_negation,
numeric_negation, numeric_negation,
}; };
fn binary_operation_parser(comptime parse_next: ExpressionParser, comptime operators: []const tokens.Token) ExpressionParser { fn binary_operation_parser(comptime parse_next: ExpressionParser, comptime operators: []const BinaryOperator) ExpressionParser {
return struct { return struct {
fn parse(self: *Self, tokenizer: *tokens.Tokenizer) types.ParseError!Expression { fn parse(self: *Self, tokenizer: *tokens.Tokenizer) types.ParseError!Expression {
var expression = try parse_next(self, tokenizer); var expression = try parse_next(self, tokenizer);
@ -62,10 +88,12 @@ fn binary_operation_parser(comptime parse_next: ExpressionParser, comptime opera
const allocator = self.arena.as_allocator(); const allocator = self.arena.as_allocator();
inline for (operators) |operator| { inline for (operators) |operator| {
if (tokenizer.current_token == coral.io.tag_of(operator)) { const token = comptime operator.token();
if (tokenizer.current_token == coral.io.tag_of(token)) {
try self.check_syntax( try self.check_syntax(
tokenizer.step(.{.include_newlines = true}), tokenizer.step(.{.include_newlines = true}),
"expected right-hand side of expression after `" ++ comptime operator.text() ++ "`"); "expected right-hand side of expression after `" ++ comptime token.text() ++ "`");
expression = .{ expression = .{
.binary_operation = .{ .binary_operation = .{
@ -156,19 +184,19 @@ pub fn parse(self: *Self, tokenizer: *tokens.Tokenizer) types.ParseError!void {
} }
const parse_comparison = binary_operation_parser(parse_term, &.{ const parse_comparison = binary_operation_parser(parse_term, &.{
.symbol_greater_than, .greater_than_comparison,
.symbol_greater_equals, .greater_equals_comparison,
.symbol_less_than, .less_than_comparison,
.symbol_less_equals .less_equals_comparison
}); });
const parse_equality = binary_operation_parser(parse_comparison, &.{ const parse_equality = binary_operation_parser(parse_comparison, &.{
.symbol_double_equals, .equals_comparison,
}); });
const parse_expression = binary_operation_parser(parse_equality, &.{ const parse_expression = binary_operation_parser(parse_equality, &.{
.symbol_plus, .addition,
.symbol_minus, .subtraction,
}); });
fn parse_factor(self: *Self, tokenizer: *tokens.Tokenizer) types.ParseError!Expression { fn parse_factor(self: *Self, tokenizer: *tokens.Tokenizer) types.ParseError!Expression {
@ -305,7 +333,7 @@ fn parse_factor(self: *Self, tokenizer: *tokens.Tokenizer) types.ParseError!Expr
self.arena.as_allocator(), self.arena.as_allocator(),
try self.parse_factor(tokenizer)), try self.parse_factor(tokenizer)),
.operator = .symbol_minus, .operator = .numeric_negation,
}, },
}; };
}, },
@ -321,7 +349,7 @@ fn parse_factor(self: *Self, tokenizer: *tokens.Tokenizer) types.ParseError!Expr
self.arena.as_allocator(), self.arena.as_allocator(),
try self.parse_factor(tokenizer)), try self.parse_factor(tokenizer)),
.operator = .symbol_bang, .operator = .boolean_negation,
}, },
}; };
}, },
@ -331,8 +359,8 @@ fn parse_factor(self: *Self, tokenizer: *tokens.Tokenizer) types.ParseError!Expr
} }
const parse_term = binary_operation_parser(parse_factor, &.{ const parse_term = binary_operation_parser(parse_factor, &.{
.symbol_asterisk, .multiplication,
.symbol_forward_slash, .divsion,
}); });
pub fn reset(self: *Self) void { pub fn reset(self: *Self) void {

View File

@ -151,16 +151,15 @@ pub fn compile_expression(self: *Self, expression: Ast.Expression) types.Runtime
try self.compile_expression(operation.rhs_expression.*); try self.compile_expression(operation.rhs_expression.*);
try self.emit_opcode(switch (operation.operator) { try self.emit_opcode(switch (operation.operator) {
.symbol_plus => .add, .addition => .add,
.symbol_minus => .sub, .subtraction => .sub,
.symbol_asterisk => .mul, .multiplication => .mul,
.symbol_forward_slash => .div, .divsion => .div,
.symbol_double_equals => .compare_eq, .greater_equals_comparison => .compare_eq,
.symbol_greater_than => .compare_gt, .greater_than_comparison => .compare_gt,
.symbol_greater_equals => .compare_ge, .equals_comparison => .compare_ge,
.symbol_less_than => .compare_lt, .less_than_comparison => .compare_lt,
.symbol_less_equals => .compare_le, .less_equals_comparison => .compare_le,
else => unreachable,
}); });
}, },
@ -168,9 +167,8 @@ pub fn compile_expression(self: *Self, expression: Ast.Expression) types.Runtime
try self.compile_expression(operation.expression.*); try self.compile_expression(operation.expression.*);
try self.emit_opcode(switch (operation.operator) { try self.emit_opcode(switch (operation.operator) {
.symbol_bang => .not, .boolean_negation => .not,
.symbol_minus => .neg, .numeric_negation => .neg,
else => unreachable,
}); });
}, },