feat: folding logical operations
This commit is contained in:
parent
92e8bcd866
commit
2260ccda25
24 changed files with 310 additions and 151 deletions
|
|
@ -630,38 +630,11 @@ fn binaryOp(
|
|||
op: Ir.Inst.Tag,
|
||||
) InnerError!Ir.Inst.Ref {
|
||||
const data = expr_node.data.bin;
|
||||
assert(data.lhs != null and data.rhs != null);
|
||||
const lhs = try expr(gi, scope, data.lhs.?);
|
||||
const rhs = try expr(gi, scope, data.rhs.?);
|
||||
return gi.addBinaryNode(op, lhs, rhs);
|
||||
}
|
||||
|
||||
fn logicalOp(
|
||||
gen: *GenIr,
|
||||
scope: *Scope,
|
||||
node: *const Ast.Node,
|
||||
op: Story.Opcode,
|
||||
) InnerError!void {
|
||||
const data = node.data.bin;
|
||||
assert(data.lhs != null and data.rhs != null);
|
||||
try expr(gen, scope, data.lhs);
|
||||
|
||||
const else_label = try gen.makeLabel();
|
||||
const fixup_offset = try gen.emitJumpInst(op);
|
||||
_ = try gen.makeFixup(.{
|
||||
.mode = .relative,
|
||||
.label_index = else_label,
|
||||
.code_offset = fixup_offset,
|
||||
});
|
||||
|
||||
try gen.emitSimpleInst(.pop);
|
||||
const rhs_label = try gen.makeLabel();
|
||||
gen.setLabel(rhs_label);
|
||||
|
||||
try expr(gen, scope, data.rhs);
|
||||
gen.setLabel(else_label);
|
||||
}
|
||||
|
||||
fn parseNumberLiteral(bytes: []const u8) union(enum) {
|
||||
int: i64,
|
||||
float: f64,
|
||||
|
|
@ -731,39 +704,39 @@ fn identifier(
|
|||
return block.addStrTok(.decl_ref, str.index, node.loc.start);
|
||||
}
|
||||
|
||||
fn expr(gi: *GenIr, scope: *Scope, optional_expr: ?*const Ast.Node) InnerError!Ir.Inst.Ref {
|
||||
const expr_node = optional_expr.?;
|
||||
switch (expr_node.tag) {
|
||||
fn expr(gi: *GenIr, scope: *Scope, optional_node: ?*const Ast.Node) InnerError!Ir.Inst.Ref {
|
||||
const node = optional_node.?;
|
||||
switch (node.tag) {
|
||||
.file => unreachable,
|
||||
.true_literal => return .bool_true,
|
||||
.false_literal => return .bool_false,
|
||||
.number_literal => return numberLiteral(gi, expr_node),
|
||||
.string_literal => return stringLiteral(gi, expr_node),
|
||||
.string_expr => return stringExpr(gi, expr_node),
|
||||
.empty_string => return stringLiteral(gi, expr_node),
|
||||
.identifier => return identifier(gi, scope, expr_node),
|
||||
.add_expr => return binaryOp(gi, scope, expr_node, .add),
|
||||
.subtract_expr => return binaryOp(gi, scope, expr_node, .sub),
|
||||
.multiply_expr => return binaryOp(gi, scope, expr_node, .mul),
|
||||
.divide_expr => return binaryOp(gi, scope, expr_node, .div),
|
||||
.mod_expr => return binaryOp(gi, scope, expr_node, .mod),
|
||||
.negate_expr => return unaryOp(gi, scope, expr_node, .neg),
|
||||
.logical_and_expr => unreachable,
|
||||
.logical_or_expr => unreachable,
|
||||
.logical_not_expr => return unaryOp(gi, scope, expr_node, .not),
|
||||
.logical_equality_expr => return binaryOp(gi, scope, expr_node, .cmp_eq),
|
||||
.logical_inequality_expr => return binaryOp(gi, scope, expr_node, .cmp_neq),
|
||||
.logical_greater_expr => return binaryOp(gi, scope, expr_node, .cmp_gt),
|
||||
.logical_greater_or_equal_expr => return binaryOp(gi, scope, expr_node, .cmp_gte),
|
||||
.logical_lesser_expr => return binaryOp(gi, scope, expr_node, .cmp_lt),
|
||||
.logical_lesser_or_equal_expr => return binaryOp(gi, scope, expr_node, .cmp_lte),
|
||||
.number_literal => return numberLiteral(gi, node),
|
||||
.string_literal => return stringLiteral(gi, node),
|
||||
.string_expr => return stringExpr(gi, node),
|
||||
.empty_string => return stringLiteral(gi, node),
|
||||
.identifier => return identifier(gi, scope, node),
|
||||
.add_expr => return binaryOp(gi, scope, node, .add),
|
||||
.subtract_expr => return binaryOp(gi, scope, node, .sub),
|
||||
.multiply_expr => return binaryOp(gi, scope, node, .mul),
|
||||
.divide_expr => return binaryOp(gi, scope, node, .div),
|
||||
.mod_expr => return binaryOp(gi, scope, node, .mod),
|
||||
.negate_expr => return unaryOp(gi, scope, node, .neg),
|
||||
.logical_not_expr => return unaryOp(gi, scope, node, .not),
|
||||
.logical_and_expr => return binaryOp(gi, scope, node, .bool_and),
|
||||
.logical_or_expr => return binaryOp(gi, scope, node, .bool_or),
|
||||
.logical_equality_expr => return binaryOp(gi, scope, node, .cmp_eq),
|
||||
.logical_inequality_expr => return binaryOp(gi, scope, node, .cmp_neq),
|
||||
.logical_greater_expr => return binaryOp(gi, scope, node, .cmp_gt),
|
||||
.logical_greater_or_equal_expr => return binaryOp(gi, scope, node, .cmp_gte),
|
||||
.logical_lesser_expr => return binaryOp(gi, scope, node, .cmp_lt),
|
||||
.logical_lesser_or_equal_expr => return binaryOp(gi, scope, node, .cmp_lte),
|
||||
.call_expr => unreachable,
|
||||
.choice_expr => unreachable,
|
||||
.choice_start_expr => unreachable,
|
||||
.choice_option_expr => unreachable,
|
||||
.choice_inner_expr => unreachable,
|
||||
.divert_expr => unreachable,
|
||||
.selector_expr => return fieldAccess(gi, scope, expr_node),
|
||||
.selector_expr => return fieldAccess(gi, scope, node),
|
||||
.assign_stmt => unreachable,
|
||||
.block_stmt => unreachable,
|
||||
.content_stmt => unreachable,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue