implement signed division

This commit is contained in:
David Gonzalez Martin 2023-11-13 10:26:05 -06:00
parent 8ab7a0d768
commit f96cf16a2a
6 changed files with 693 additions and 194 deletions

View File

@ -553,6 +553,7 @@ pub const BinaryOperation = struct {
logical_xor, logical_xor,
logical_or, logical_or,
multiply, multiply,
divide,
}; };
}; };

View File

@ -238,7 +238,8 @@ pub const BinaryOperation = struct {
logical_and, logical_and,
logical_xor, logical_xor,
logical_or, logical_or,
multiply, signed_multiply,
signed_divide,
}; };
pub const List = BlockList(@This()); pub const List = BlockList(@This());
@ -729,6 +730,9 @@ pub const Builder = struct {
const left = try builder.emitBinaryOperationOperand(sema_binary_operation.left); const left = try builder.emitBinaryOperationOperand(sema_binary_operation.left);
const right = try builder.emitBinaryOperationOperand(sema_binary_operation.right); const right = try builder.emitBinaryOperationOperand(sema_binary_operation.right);
const sema_type = builder.ir.module.types.get(sema_binary_operation.type).*;
const binary_operation_type = try builder.translateType(sema_binary_operation.type);
const binary_operation = try builder.ir.binary_operations.append(builder.allocator, .{ const binary_operation = try builder.ir.binary_operations.append(builder.allocator, .{
.left = left, .left = left,
.right = right, .right = right,
@ -738,9 +742,24 @@ pub const Builder = struct {
.logical_and => .logical_and, .logical_and => .logical_and,
.logical_xor => .logical_xor, .logical_xor => .logical_xor,
.logical_or => .logical_or, .logical_or => .logical_or,
.multiply => .multiply, .multiply => switch (sema_type) {
.integer => |integer| switch (integer.signedness) {
.signed => .signed_multiply,
else => |t| @panic(@tagName(t)),
},
else => |t| @panic(@tagName(t)),
},
//.multiply,
.divide => switch (sema_type) {
.integer => |integer| switch (integer.signedness) {
.signed => .signed_divide,
else => |t| @panic(@tagName(t)),
},
else => |t| @panic(@tagName(t)),
},
//.divide,
}, },
.type = try builder.translateType(sema_binary_operation.type), .type = binary_operation_type,
}); });
const instruction = try builder.append(.{ const instruction = try builder.append(.{

File diff suppressed because it is too large Load Diff

View File

@ -544,6 +544,7 @@ const Analyzer = struct {
.logical_xor => .logical_xor, .logical_xor => .logical_xor,
.logical_or => .logical_or, .logical_or => .logical_or,
.multiply => .multiply, .multiply => .multiply,
.divide => .divide,
else => |t| @panic(@tagName(t)), else => |t| @panic(@tagName(t)),
}, },
}); });
@ -1015,6 +1016,7 @@ const Analyzer = struct {
.logical_xor, .logical_xor,
.logical_or, .logical_or,
.multiply, .multiply,
.divide,
=> try analyzer.processBinaryOperation(scope_index, expect_type, node_index), => try analyzer.processBinaryOperation(scope_index, expect_type, node_index),
.expression_group => return try analyzer.resolveNode(value, scope_index, expect_type, node.left), //unreachable, .expression_group => return try analyzer.resolveNode(value, scope_index, expect_type, node.left), //unreachable,
else => |t| @panic(@tagName(t)), else => |t| @panic(@tagName(t)),

View File

@ -159,6 +159,7 @@ pub const Node = packed struct(u128) {
expression_group = 65, expression_group = 65,
logical_or = 66, logical_or = 66,
multiply = 67, multiply = 67,
divide = 68,
}; };
}; };
@ -719,6 +720,7 @@ const Analyzer = struct {
logical_xor, logical_xor,
logical_or, logical_or,
multiply, multiply,
divide,
}; };
const operator_precedence = std.EnumArray(PrecedenceOperator, i32).init(.{ const operator_precedence = std.EnumArray(PrecedenceOperator, i32).init(.{
@ -730,6 +732,7 @@ const Analyzer = struct {
.logical_xor = 40, .logical_xor = 40,
.logical_or = 40, .logical_or = 40,
.multiply = 70, .multiply = 70,
.divide = 70,
}); });
const operator_associativity = std.EnumArray(PrecedenceOperator, Associativity).init(.{ const operator_associativity = std.EnumArray(PrecedenceOperator, Associativity).init(.{
@ -741,6 +744,7 @@ const Analyzer = struct {
.logical_xor = .left, .logical_xor = .left,
.logical_or = .left, .logical_or = .left,
.multiply = .left, .multiply = .left,
.divide = .left,
}); });
const operator_node_id = std.EnumArray(PrecedenceOperator, Node.Id).init(.{ const operator_node_id = std.EnumArray(PrecedenceOperator, Node.Id).init(.{
@ -752,6 +756,7 @@ const Analyzer = struct {
.logical_xor = .logical_xor, .logical_xor = .logical_xor,
.logical_or = .logical_or, .logical_or = .logical_or,
.multiply = .multiply, .multiply = .multiply,
.divide = .divide,
}); });
fn expressionPrecedence(analyzer: *Analyzer, minimum_precedence: i32) !Node.Index { fn expressionPrecedence(analyzer: *Analyzer, minimum_precedence: i32) !Node.Index {
@ -816,6 +821,10 @@ const Analyzer = struct {
.equal => unreachable, .equal => unreachable,
else => .multiply, else => .multiply,
}, },
.slash => switch (next_token_id) {
.equal => unreachable,
else => .divide,
},
else => |t| @panic(@tagName(t)), else => |t| @panic(@tagName(t)),
}; };
} else { } else {
@ -843,6 +852,7 @@ const Analyzer = struct {
.logical_xor, .logical_xor,
.logical_or, .logical_or,
.multiply, .multiply,
.divide,
=> false, => false,
.compare_equal, .compare_equal,
.compare_not_equal, .compare_not_equal,

8
test/div/main.nat Normal file
View File

@ -0,0 +1,8 @@
const main = fn () s32 {
const dividend: s32 = 30;
const divisor: s32 = 6;
const div: s32 = dividend / divisor;
const n: s32 = 5;
return n - div;
}