mirror of
https://github.com/ziglang/zig.git
synced 2026-02-13 04:48:20 +00:00
stage2: astgen for floats and other primitive literals
This commit is contained in:
parent
e77ca6af70
commit
da217fadeb
@ -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", .{});
|
||||
|
||||
@ -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,
|
||||
};
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user