authorgravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2020-07-20 18:34:06+03:00
committergravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2020-07-21 22:29:28+03:00
logda217fadeb888ba1286e36ab42bdbe9918426a0a
tree75468edb505301396c5b993ab8cbc4abea8c5027
parente77ca6af7083da6723dfeb83d3788ebf7012c64e
signaturelock-open Commit is signed but in an unrecognized format.

stage2: astgen for floats and other primitive literals


2 files changed, 56 insertions(+), 1 deletions(-)

src-self-hosted/astgen.zig+48
......@@ -38,6 +38,8 @@ pub fn expr(mod: *Module, scope: *Scope, node: *ast.Node) InnerError!*zir.Inst {
3838 .Period => return field(mod, scope, node.castTag(.Period).?),
3939 .Deref => return deref(mod, scope, node.castTag(.Deref).?),
4040 .BoolNot => return boolNot(mod, scope, node.castTag(.BoolNot).?),
41 .FloatLiteral => return floatLiteral(mod, scope, node.castTag(.FloatLiteral).?),
42 .UndefinedLiteral, .BoolLiteral, .NullLiteral => return primitiveLiteral(mod, scope, node),
4143 else => return mod.failNode(scope, node, "TODO implement astgen.Expr for {}", .{@tagName(node.tag)}),
4244 }
4345}
......@@ -405,6 +407,52 @@ fn integerLiteral(mod: *Module, scope: *Scope, int_lit: *ast.Node.IntegerLiteral
405407 }
406408}
407409
410fn floatLiteral(mod: *Module, scope: *Scope, float_lit: *ast.Node.FloatLiteral) InnerError!*zir.Inst {
411 const arena = scope.arena();
412 const tree = scope.tree();
413 const bytes = tree.tokenSlice(float_lit.token);
414 if (bytes.len > 2 and bytes[1] == 'x') {
415 return mod.failTok(scope, float_lit.token, "TODO hex floats", .{});
416 }
417
418 const val = std.fmt.parseFloat(f128, bytes) catch |e| switch (e) {
419 error.InvalidCharacter => unreachable, // validated by tokenizer
420 };
421 const float_payload = try arena.create(Value.Payload.Float_128);
422 float_payload.* = .{ .val = val };
423 const src = tree.token_locs[float_lit.token].start;
424 return mod.addZIRInstConst(scope, src, .{
425 .ty = Type.initTag(.comptime_float),
426 .val = Value.initPayload(&float_payload.base),
427 });
428}
429
430fn primitiveLiteral(mod: *Module, scope: *Scope, node: *ast.Node) InnerError!*zir.Inst {
431 const arena = scope.arena();
432 const tree = scope.tree();
433 const src = tree.token_locs[node.firstToken()].start;
434
435 if (node.cast(ast.Node.BoolLiteral)) |bool_node| {
436 return mod.addZIRInstConst(scope, src, .{
437 .ty = Type.initTag(.bool),
438 .val = if (tree.token_ids[bool_node.token] == .Keyword_true)
439 Value.initTag(.bool_true)
440 else
441 Value.initTag(.bool_false),
442 });
443 } else if (node.tag == .UndefinedLiteral) {
444 return mod.addZIRInstConst(scope, src, .{
445 .ty = Type.initTag(.@"undefined"),
446 .val = Value.initTag(.undef),
447 });
448 } else if (node.tag == .NullLiteral) {
449 return mod.addZIRInstConst(scope, src, .{
450 .ty = Type.initTag(.@"null"),
451 .val = Value.initTag(.null_value),
452 });
453 } else unreachable;
454}
455
408456fn assembly(mod: *Module, scope: *Scope, asm_node: *ast.Node.Asm) InnerError!*zir.Inst {
409457 if (asm_node.outputs.len != 0) {
410458 return mod.failNode(scope, &asm_node.base, "TODO implement asm with an output", .{});
src-self-hosted/value.zig+8-1
......@@ -554,13 +554,20 @@ pub const Value = extern union {
554554 };
555555 }
556556
557 /// Asserts that the value is a float.
557 /// Asserts that the value is a float or an integer.
558558 pub fn toF128(self: Value) f128 {
559559 return switch (self.tag()) {
560560 .float_16 => self.cast(Payload.Float_16).?.val,
561561 .float_32 => self.cast(Payload.Float_32).?.val,
562562 .float_64 => self.cast(Payload.Float_64).?.val,
563563 .float_128, .float => self.cast(Payload.Float_128).?.val,
564
565 .zero, .the_one_possible_value => 0,
566 .int_u64 => @intToFloat(f128, self.cast(Payload.Int_u64).?.int),
567 // .int_i64 => @intToFloat(f128, self.cast(Payload.Int_i64).?.int),
568 .int_i64 => @panic("TODO lld: error: undefined symbol: __floatditf"),
569
570 .int_big_positive, .int_big_negative => @panic("big int to f128"),
564571 else => unreachable,
565572 };
566573 }