Commit da217fadeb
Changed files (2)
src-self-hosted
src-self-hosted/astgen.zig
@@ -38,6 +38,8 @@ pub fn expr(mod: *Module, scope: *Scope, node: *ast.Node) InnerError!*zir.Inst {
.Period => return field(mod, scope, node.castTag(.Period).?),
.Deref => return deref(mod, scope, node.castTag(.Deref).?),
.BoolNot => return boolNot(mod, scope, node.castTag(.BoolNot).?),
+ .FloatLiteral => return floatLiteral(mod, scope, node.castTag(.FloatLiteral).?),
+ .UndefinedLiteral, .BoolLiteral, .NullLiteral => return primitiveLiteral(mod, scope, node),
else => return mod.failNode(scope, node, "TODO implement astgen.Expr for {}", .{@tagName(node.tag)}),
}
}
@@ -405,6 +407,52 @@ fn integerLiteral(mod: *Module, scope: *Scope, int_lit: *ast.Node.IntegerLiteral
}
}
+fn floatLiteral(mod: *Module, scope: *Scope, float_lit: *ast.Node.FloatLiteral) InnerError!*zir.Inst {
+ const arena = scope.arena();
+ const tree = scope.tree();
+ const bytes = tree.tokenSlice(float_lit.token);
+ if (bytes.len > 2 and bytes[1] == 'x') {
+ return mod.failTok(scope, float_lit.token, "TODO hex floats", .{});
+ }
+
+ const val = std.fmt.parseFloat(f128, bytes) catch |e| switch (e) {
+ error.InvalidCharacter => unreachable, // validated by tokenizer
+ };
+ const float_payload = try arena.create(Value.Payload.Float_128);
+ float_payload.* = .{ .val = val };
+ const src = tree.token_locs[float_lit.token].start;
+ return mod.addZIRInstConst(scope, src, .{
+ .ty = Type.initTag(.comptime_float),
+ .val = Value.initPayload(&float_payload.base),
+ });
+}
+
+fn primitiveLiteral(mod: *Module, scope: *Scope, node: *ast.Node) InnerError!*zir.Inst {
+ const arena = scope.arena();
+ const tree = scope.tree();
+ const src = tree.token_locs[node.firstToken()].start;
+
+ if (node.cast(ast.Node.BoolLiteral)) |bool_node| {
+ return mod.addZIRInstConst(scope, src, .{
+ .ty = Type.initTag(.bool),
+ .val = if (tree.token_ids[bool_node.token] == .Keyword_true)
+ Value.initTag(.bool_true)
+ else
+ Value.initTag(.bool_false),
+ });
+ } else if (node.tag == .UndefinedLiteral) {
+ return mod.addZIRInstConst(scope, src, .{
+ .ty = Type.initTag(.@"undefined"),
+ .val = Value.initTag(.undef),
+ });
+ } else if (node.tag == .NullLiteral) {
+ return mod.addZIRInstConst(scope, src, .{
+ .ty = Type.initTag(.@"null"),
+ .val = Value.initTag(.null_value),
+ });
+ } else unreachable;
+}
+
fn assembly(mod: *Module, scope: *Scope, asm_node: *ast.Node.Asm) InnerError!*zir.Inst {
if (asm_node.outputs.len != 0) {
return mod.failNode(scope, &asm_node.base, "TODO implement asm with an output", .{});
src-self-hosted/value.zig
@@ -554,13 +554,20 @@ pub const Value = extern union {
};
}
- /// Asserts that the value is a float.
+ /// Asserts that the value is a float or an integer.
pub fn toF128(self: Value) f128 {
return switch (self.tag()) {
.float_16 => self.cast(Payload.Float_16).?.val,
.float_32 => self.cast(Payload.Float_32).?.val,
.float_64 => self.cast(Payload.Float_64).?.val,
.float_128, .float => self.cast(Payload.Float_128).?.val,
+
+ .zero, .the_one_possible_value => 0,
+ .int_u64 => @intToFloat(f128, self.cast(Payload.Int_u64).?.int),
+ // .int_i64 => @intToFloat(f128, self.cast(Payload.Int_i64).?.int),
+ .int_i64 => @panic("TODO lld: error: undefined symbol: __floatditf"),
+
+ .int_big_positive, .int_big_negative => @panic("big int to f128"),
else => unreachable,
};
}