Array and Table Literal Expressions for Kym #11
|
@ -9,6 +9,32 @@ arena: coral.arena.Stacking,
|
|||
statements: StatementList,
|
||||
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) {
|
||||
nil_literal,
|
||||
true_literal,
|
||||
|
@ -26,13 +52,13 @@ pub const Expression = union (enum) {
|
|||
grouped_expression: *Expression,
|
||||
|
||||
binary_operation: struct {
|
||||
operator: tokens.Token,
|
||||
operator: BinaryOperator,
|
||||
lhs_expression: *Expression,
|
||||
rhs_expression: *Expression,
|
||||
},
|
||||
|
||||
unary_operation: struct {
|
||||
operator: tokens.Token,
|
||||
operator: UnaryOperator,
|
||||
expression: *Expression,
|
||||
},
|
||||
};
|
||||
|
@ -48,12 +74,12 @@ pub const Statement = union (enum) {
|
|||
|
||||
const StatementList = coral.list.Stack(Statement);
|
||||
|
||||
const UnaryOperation = enum {
|
||||
const UnaryOperator = enum {
|
||||
boolean_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 {
|
||||
fn parse(self: *Self, tokenizer: *tokens.Tokenizer) types.ParseError!Expression {
|
||||
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();
|
||||
|
||||
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(
|
||||
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 = .{
|
||||
.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, &.{
|
||||
.symbol_greater_than,
|
||||
.symbol_greater_equals,
|
||||
.symbol_less_than,
|
||||
.symbol_less_equals
|
||||
.greater_than_comparison,
|
||||
.greater_equals_comparison,
|
||||
.less_than_comparison,
|
||||
.less_equals_comparison
|
||||
});
|
||||
|
||||
const parse_equality = binary_operation_parser(parse_comparison, &.{
|
||||
.symbol_double_equals,
|
||||
.equals_comparison,
|
||||
});
|
||||
|
||||
const parse_expression = binary_operation_parser(parse_equality, &.{
|
||||
.symbol_plus,
|
||||
.symbol_minus,
|
||||
.addition,
|
||||
.subtraction,
|
||||
});
|
||||
|
||||
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(),
|
||||
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(),
|
||||
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, &.{
|
||||
.symbol_asterisk,
|
||||
.symbol_forward_slash,
|
||||
.multiplication,
|
||||
.divsion,
|
||||
});
|
||||
|
||||
pub fn reset(self: *Self) void {
|
||||
|
|
|
@ -151,16 +151,15 @@ pub fn compile_expression(self: *Self, expression: Ast.Expression) types.Runtime
|
|||
try self.compile_expression(operation.rhs_expression.*);
|
||||
|
||||
try self.emit_opcode(switch (operation.operator) {
|
||||
.symbol_plus => .add,
|
||||
.symbol_minus => .sub,
|
||||
.symbol_asterisk => .mul,
|
||||
.symbol_forward_slash => .div,
|
||||
.symbol_double_equals => .compare_eq,
|
||||
.symbol_greater_than => .compare_gt,
|
||||
.symbol_greater_equals => .compare_ge,
|
||||
.symbol_less_than => .compare_lt,
|
||||
.symbol_less_equals => .compare_le,
|
||||
else => unreachable,
|
||||
.addition => .add,
|
||||
.subtraction => .sub,
|
||||
.multiplication => .mul,
|
||||
.divsion => .div,
|
||||
.greater_equals_comparison => .compare_eq,
|
||||
.greater_than_comparison => .compare_gt,
|
||||
.equals_comparison => .compare_ge,
|
||||
.less_than_comparison => .compare_lt,
|
||||
.less_equals_comparison => .compare_le,
|
||||
});
|
||||
},
|
||||
|
||||
|
@ -168,9 +167,8 @@ pub fn compile_expression(self: *Self, expression: Ast.Expression) types.Runtime
|
|||
try self.compile_expression(operation.expression.*);
|
||||
|
||||
try self.emit_opcode(switch (operation.operator) {
|
||||
.symbol_bang => .not,
|
||||
.symbol_minus => .neg,
|
||||
else => unreachable,
|
||||
.boolean_negation => .not,
|
||||
.numeric_negation => .neg,
|
||||
});
|
||||
},
|
||||
|
||||
|
|
Loading…
Reference in New Issue