stage2: astgen for floats and other primitive literals

This commit is contained in:
Vexu 2020-07-20 18:34:06 +03:00
parent e77ca6af70
commit da217fadeb
No known key found for this signature in database
GPG Key ID: 59AEB8936E16A6AC
2 changed files with 56 additions and 1 deletions

View File

@ -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", .{});

View File

@ -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,
};
}