From f74403ebaca76bbefc8383699984c8e3696cd4bf Mon Sep 17 00:00:00 2001 From: Ary Borenszweig <aborenszweig@manas.com.ar> Date: Mon, 29 Jul 2013 00:10:29 -0300 Subject: [PATCH] Started updating bootstrap's lexer to latest version --- bootstrap/crystal/ast.cr | 46 +-- bootstrap/crystal/lexer.cr | 28 +- bootstrap/crystal/llvm.cr | 4 +- bootstrap/crystal/parser.cr | 24 +- bootstrap/crystal/to_s.cr | 14 +- bootstrap/crystal/token.cr | 1 + .../spec/crystal/codegen/primitives_spec.cr | 8 +- bootstrap/spec/crystal/lexer/lexer_spec.cr | 66 ++--- bootstrap/spec/crystal/parser/parser_spec.cr | 278 +++++++++--------- bootstrap/spec/std/string_spec.cr | 5 +- std/float32.cr | 2 +- std/float64.cr | 2 +- std/int.cr | 4 +- std/math.cr | 44 +-- std/string.cr | 6 +- 15 files changed, 241 insertions(+), 291 deletions(-) diff --git a/bootstrap/crystal/ast.cr b/bootstrap/crystal/ast.cr index 0db65e0734..fbb0003321 100644 --- a/bootstrap/crystal/ast.cr +++ b/bootstrap/crystal/ast.cr @@ -82,53 +82,21 @@ module Crystal end end - abstract class NumberLiteral < ASTNode + # Any number literal. + # kind stores a symbol indicating which type is it: i32, u16, f32, f64, etc. + class NumberLiteral < ASTNode attr_accessor :value + attr_accessor :kind attr_accessor :has_sign - def initialize(value) + def initialize(value, kind) @has_sign = value[0] == '+' || value[0] == '-' @value = value + @kind = kind end - end - - # An integer literal. - # - # \d+ - # - class IntLiteral < NumberLiteral - def ==(other : self) - other.value.to_i == value.to_i - end - end - - # A long literal. - # - # \d+L - # - class LongLiteral < NumberLiteral - def ==(other : self) - other.value.to_i == value.to_i - end - end - # A float literal. - # - # \d+.\d+f - # - class FloatLiteral < NumberLiteral - def ==(other : self) - other.value.to_f == value.to_f - end - end - - # A double literal. - # - # \d+.\d+f - # - class DoubleLiteral < NumberLiteral def ==(other : self) - other.value.to_d == value.to_d + other.value.to_f64 == value.to_f64 && other.kind == kind end end diff --git a/bootstrap/crystal/lexer.cr b/bootstrap/crystal/lexer.cr index dbb05ac2ea..6c619848c3 100644 --- a/bootstrap/crystal/lexer.cr +++ b/bootstrap/crystal/lexer.cr @@ -34,9 +34,9 @@ module Crystal # Skip comments if @buffer.value == '#' - char = next_char + char = next_char_no_column_increment while char != '\n' && char != '\0' - char = next_char + char = next_char_no_column_increment end end @@ -633,9 +633,12 @@ module Crystal end def scan_number(start, count) + @token.type = :NUMBER + while next_char.digit? count += 1 end + case @buffer.value when '.' if (@buffer + 1).value.digit? @@ -646,31 +649,35 @@ module Crystal end if @buffer.value == 'f' || @buffer.value == 'F' next_char - @token.type = :FLOAT + @token.number_kind = :f32 else - @token.type = :DOUBLE + @token.number_kind = :f64 end else - @token.type = :INT + @token.number_kind = :i32 end when 'f', 'F' next_char - @token.type = :FLOAT + @token.number_kind = :f32 when 'L' next_char - @token.type = :LONG + @token.number_kind = :i64 else - @token.type = :INT + @token.number_kind = :i32 end @token.value = String.from_cstr(start, count) end - def next_char + def next_char_no_column_increment @buffer += 1 - @column_number += 1 @buffer.value end + def next_char + @column_number += 1 + next_char_no_column_increment + end + def next_char(token_type) next_char @token.type = token_type @@ -680,7 +687,6 @@ module Crystal @token.line_number = @line_number @token.column_number = @column_number @token.filename = @filename - @token.value = nil end def next_token_skip_space diff --git a/bootstrap/crystal/llvm.cr b/bootstrap/crystal/llvm.cr index 2dcf2d7104..90d49995fb 100644 --- a/bootstrap/crystal/llvm.cr +++ b/bootstrap/crystal/llvm.cr @@ -185,11 +185,11 @@ module LLVM to_i != 0 end - def to_f + def to_f32 LibLLVM.generic_value_to_float(LLVM::Float.type, @value) end - def to_d + def to_f64 LibLLVM.generic_value_to_float(LLVM::Double.type, @value) end end diff --git a/bootstrap/crystal/parser.cr b/bootstrap/crystal/parser.cr index 074d1f282b..f7dc0a964c 100644 --- a/bootstrap/crystal/parser.cr +++ b/bootstrap/crystal/parser.cr @@ -239,19 +239,13 @@ module Crystal next_token_skip_space_or_newline right = parse_mul_or_div left = Call.new left, method, [right] of ASTNode, nil, method_column_number - when :INT, :LONG, :FLOAT, :DOUBLE - type = case @token.type - when :INT then IntLiteral - when :LONG then LongLiteral - when :FLOAT then FloatLiteral - else DoubleLiteral - end + when :NUMBER case @token.value.to_s[0] when '+' - left = Call.new left, @token.value.to_s[0].to_s, [type.new(@token.value.to_s)] of ASTNode, nil, @token.column_number + left = Call.new left, @token.value.to_s[0].to_s, [NumberLiteral.new(@token.value.to_s, @token.number_kind)] of ASTNode, nil, @token.column_number next_token_skip_space_or_newline when '-' - left = Call.new left, @token.value.to_s[0].to_s, [type.new(@token.value.to_s[1, @token.value.to_s.length - 1])] of ASTNode, nil, @token.column_number + left = Call.new left, @token.value.to_s[0].to_s, [NumberLiteral.new(@token.value.to_s[1, @token.value.to_s.length - 1], @token.number_kind)] of ASTNode, nil, @token.column_number next_token_skip_space_or_newline else return left @@ -387,14 +381,8 @@ module Crystal parse_array_literal when :"::" parse_ident - when :INT - node_and_next_token IntLiteral.new(@token.value.to_s) - when :LONG - node_and_next_token LongLiteral.new(@token.value.to_s) - when :FLOAT - node_and_next_token FloatLiteral.new(@token.value.to_s) - when :DOUBLE - node_and_next_token DoubleLiteral.new(@token.value.to_s) + when :NUMBER + node_and_next_token NumberLiteral.new(@token.value.to_s, @token.number_kind) when :CHAR node_and_next_token CharLiteral.new(@token.value.to_s) when :STRING, :STRING_START @@ -873,7 +861,7 @@ module Crystal def parse_args_space_consumed(allow_plus_and_minus = false) case @token.type - when :CHAR, :STRING, :STRING_START, :STRING_ARRAY_START, :INT, :LONG, :FLOAT, :DOUBLE, :IDENT, :SYMBOL, :INSTANCE_VAR, :CONST, :GLOBAL, :GLOBAL_MATCH, :REGEXP, :"(", :"!", :"[", :"[]", :"+", :"-" + when :CHAR, :STRING, :STRING_START, :STRING_ARRAY_START, :NUMBER, :IDENT, :SYMBOL, :INSTANCE_VAR, :CONST, :GLOBAL, :GLOBAL_MATCH, :REGEXP, :"(", :"!", :"[", :"[]", :"+", :"-" if !allow_plus_and_minus && (@token.type == :"+" || @token.type == :"-") return nil end diff --git a/bootstrap/crystal/to_s.cr b/bootstrap/crystal/to_s.cr index 7caf70b0c4..7175685f9f 100644 --- a/bootstrap/crystal/to_s.cr +++ b/bootstrap/crystal/to_s.cr @@ -22,16 +22,12 @@ module Crystal @str << (node.value ? "true" : "false") end - def visit(node : IntLiteral) - @str << node.value - end - - def visit(node : LongLiteral) - @str << node.value << "L" - end - - def visit(node : FloatLiteral) + def visit(node : NumberLiteral) @str << node.value + if node.kind != :i32 && node.kind != :f64 + @str << "_" + @str << node.kind.to_s + end end def visit(node : CharLiteral) diff --git a/bootstrap/crystal/token.cr b/bootstrap/crystal/token.cr index d904fe2569..0a77609686 100644 --- a/bootstrap/crystal/token.cr +++ b/bootstrap/crystal/token.cr @@ -4,6 +4,7 @@ module Crystal class Token attr_accessor :type attr_accessor :value + attr_accessor :number_kind attr_accessor :line_number attr_accessor :column_number attr_accessor :filename diff --git a/bootstrap/spec/crystal/codegen/primitives_spec.cr b/bootstrap/spec/crystal/codegen/primitives_spec.cr index 085fba2a1b..f4bfb2b305 100644 --- a/bootstrap/spec/crystal/codegen/primitives_spec.cr +++ b/bootstrap/spec/crystal/codegen/primitives_spec.cr @@ -21,11 +21,11 @@ describe "Code gen: primitives" do run("'a'").to_i.should eq('a'.ord) end - it "codegens float" do - run("1; 2.5f").to_f.should eq(2.5_f32) + it "codegens f32" do + run("1; 2.5f").to_f32.should eq(2.5_f32) end - it "codegens double" do - run("1; 2.5").to_d.should eq(2.5) + it "codegens f64" do + run("1; 2.5").to_f64.should eq(2.5_f64) end end \ No newline at end of file diff --git a/bootstrap/spec/crystal/lexer/lexer_spec.cr b/bootstrap/spec/crystal/lexer/lexer_spec.cr index 5bc827e7ff..130dc78645 100755 --- a/bootstrap/spec/crystal/lexer/lexer_spec.cr +++ b/bootstrap/spec/crystal/lexer/lexer_spec.cr @@ -19,6 +19,16 @@ def it_lexes(string, type, value) end end +def it_lexes(string, type, value, number_kind) + it "lexes #{string}" do + lexer = Crystal::Lexer.new string + token = lexer.next_token + token.type.should eq(type) + token.value.should eq(value) + token.number_kind.should eq(number_kind) + end +end + def it_lexes_many(values, type) values.each do |value| it_lexes value, type, value @@ -37,52 +47,28 @@ def it_lexes_idents(idents) end end -def it_lexes_ints(values) - values.each { |value| it_lexes_int value } -end - -def it_lexes_int(value : Array) - it_lexes value[0], :INT, value[1] -end - -def it_lexes_int(value : String) - it_lexes value, :INT, value -end - -def it_lexes_floats(values) - values.each { |value| it_lexes_float value } -end - -def it_lexes_float(value : Array) - it_lexes value[0], :FLOAT, value[1][0, value[1].length - 1] -end - -def it_lexes_float(value : String) - it_lexes value, :FLOAT, value[0, value.length - 1] -end - -def it_lexes_doubles(values) - values.each { |value| it_lexes_double value } +def it_lexes_i32(values) + values.each { |value| it_lexes_number :i32, value } end -def it_lexes_double(value : Array) - it_lexes value[0], :DOUBLE, value[1] +def it_lexes_i64(values) + values.each { |value| it_lexes_number :i64, value } end -def it_lexes_double(value : String) - it_lexes value, :DOUBLE, value +def it_lexes_f32(values) + values.each { |value| it_lexes_number :f32, value } end -def it_lexes_longs(values) - values.each { |value| it_lexes_long value } +def it_lexes_f64(values) + values.each { |value| it_lexes_number :f64, value } end -def it_lexes_long(value : Array) - it_lexes value[0], :LONG, value[1] +def it_lexes_number(number_kind, value : Array) + it_lexes value[0], :NUMBER, value[1], number_kind end -def it_lexes_long(value : String) - it_lexes value, :LONG, value[0, value.length - 1] +def it_lexes_number(number_kind, value : String) + it_lexes value, :NUMBER, value, number_kind end def it_lexes_char(string, value) @@ -141,10 +127,10 @@ describe "Lexer" do it_lexes_idents ["ident", "something", "with_underscores", "with_1", "foo?", "bar!"] it_lexes_idents ["def?", "if?", "else?", "elsif?", "end?", "true?", "false?", "class?", "while?", "nil?", "do?", "yield?", "return?", "unless?", "next?", "break?", "begin?"] it_lexes_idents ["def!", "if!", "else!", "elsif!", "end!", "true!", "false!", "class!", "while!", "nil!", "do!", "yield!", "return!", "unless!", "next!", "break!", "begin!"] - it_lexes_ints ["1", ["1hello", "1"], "+1", "-1", "1234", "+1234", "-1234", ["1.foo", "1"]] - it_lexes_floats ["1f", "1.0f", ["1.0fhello", "1.0f"], "+1.0f", "-1.0f"] - it_lexes_doubles ["1.0", ["1.0hello", "1.0"], "+1.0", "-1.0"] - it_lexes_longs ["1L", ["1Lhello", "1"], "+1L", "-1L"] + it_lexes_i32 ["1", ["1hello", "1"], "+1", "-1", "1234", "+1234", "-1234", ["1.foo", "1"]] + it_lexes_i64 [["1L", "1"], ["1Lhello", "1"], ["+1L", "+1"], ["-1L", "-1"]] + it_lexes_f32 [["1f", "1"], ["1.0f", "1.0"], ["1.0fhello", "1.0"], ["+1.0f", "+1.0"], ["-1.0f", "-1.0"]] + it_lexes_f64 ["1.0", ["1.0hello", "1.0"], "+1.0", "-1.0"] it_lexes_char "'a'", 'a' it_lexes_char "'\\n'", '\n' it_lexes_char "'\\t'", '\t' diff --git a/bootstrap/spec/crystal/parser/parser_spec.cr b/bootstrap/spec/crystal/parser/parser_spec.cr index c1fcf38a05..a5f6610f35 100755 --- a/bootstrap/spec/crystal/parser/parser_spec.cr +++ b/bootstrap/spec/crystal/parser/parser_spec.cr @@ -6,20 +6,20 @@ require "../../../../bootstrap/crystal/to_s" include Crystal class Numeric - def int - IntLiteral.new to_s + def i32 + NumberLiteral.new to_s, :i32 end - def long - LongLiteral.new to_s + def i64 + NumberLiteral.new to_s, :i64 end - def float - FloatLiteral.new to_f.to_s + def f32 + NumberLiteral.new to_f32.to_s, :f32 end - def double - DoubleLiteral.new to_d.to_s + def f64 + NumberLiteral.new to_f64.to_s, :f64 end end @@ -104,21 +104,21 @@ describe "Parser" do it_parses "true", true.bool it_parses "false", false.bool - it_parses "1", 1.int - it_parses "+1", 1.int - it_parses "-1", -1.int + it_parses "1", 1.i32 + it_parses "+1", 1.i32 + it_parses "-1", -1.i32 - it_parses "1L", 1.long - it_parses "+1L", 1.long - it_parses "-1L", -1.long + it_parses "1L", 1.i64 + it_parses "+1L", 1.i64 + it_parses "-1L", -1.i64 - it_parses "1.0", 1.0.double - it_parses "+1.0", 1.0.double - it_parses "-1.0", -1.0.double + it_parses "1.0", 1.0.f64 + it_parses "+1.0", 1.0.f64 + it_parses "-1.0", -1.0.f64 - it_parses "1.0f", 1.0.float - it_parses "+1.0f", 1.0.float - it_parses "-1.0f", -1.0.float + it_parses "1.0f", 1.0.f32 + it_parses "+1.0f", 1.0.f32 + it_parses "-1.0f", -1.0.f32 it_parses "'a'", CharLiteral.new("a") @@ -128,48 +128,48 @@ describe "Parser" do it_parses ":foo", SymbolLiteral.new("foo") it_parses "[]", ([] of ASTNode).array - it_parses "[1, 2]", ASTNode[1.int, 2.int].array - it_parses "[\n1, 2]", ASTNode[1.int, 2.int].array - it_parses "[1,\n 2,]", ASTNode[1.int, 2.int].array - - it_parses "1 + 2", Call.new(1.int, "+", ASTNode[2.int]) - it_parses "1 +\n2", Call.new(1.int, "+", ASTNode[2.int]) - it_parses "1 +2", Call.new(1.int, "+", ASTNode[2.int]) - it_parses "1 -2", Call.new(1.int, "-", ASTNode[2.int]) - it_parses "1 +2.0", Call.new(1.int, "+", ASTNode[2.double]) - it_parses "1 -2.0", Call.new(1.int, "-", ASTNode[2.double]) - it_parses "1 +2L", Call.new(1.int, "+", ASTNode[2.long]) - it_parses "1 -2L", Call.new(1.int, "-", ASTNode[2.long]) - it_parses "1\n+2", ASTNode[1.int, 2.int] - it_parses "1;+2", ASTNode[1.int, 2.int] - it_parses "1 - 2", Call.new(1.int, "-", ASTNode[2.int]) - it_parses "1 -\n2", Call.new(1.int, "-", ASTNode[2.int]) - it_parses "1\n-2", ASTNode[1.int, -2.int] - it_parses "1;-2", ASTNode[1.int, -2.int] - it_parses "1 * 2", Call.new(1.int, "*", ASTNode[2.int]) - it_parses "1 * -2", Call.new(1.int, "*", ASTNode[-2.int]) - it_parses "2 * 3 + 4 * 5", Call.new(Call.new(2.int, "*", ASTNode[3.int]), "+", ASTNode[Call.new(4.int, "*", ASTNode[5.int])]) - it_parses "1 / 2", Call.new(1.int, "/", ASTNode[2.int]) - it_parses "1 / -2", Call.new(1.int, "/", ASTNode[-2.int]) - it_parses "2 / 3 + 4 / 5", Call.new(Call.new(2.int, "/", ASTNode[3.int]), "+", ASTNode[Call.new(4.int, "/", ASTNode[5.int])]) - it_parses "2 * (3 + 4)", Call.new(2.int, "*", ASTNode[Call.new(3.int, "+", ASTNode[4.int])]) - - it_parses "!1", Call.new(1.int, "!@") - it_parses "1 && 2", And.new(1.int, 2.int) - it_parses "1 || 2", Or.new(1.int, 2.int) - - it_parses "1 <=> 2", Call.new(1.int, "<=>", ASTNode[2.int]) - - it_parses "a = 1", Assign.new("a".var, 1.int) - it_parses "a = b = 2", Assign.new("a".var, Assign.new("b".var, 2.int)) - - # # it_parses "a, b = 1, 2", MultiAssign.new(["a".var, "b".var], [1.int, 2.int]) - # # it_parses "a, b = 1", MultiAssign.new(["a".var, "b".var], [1.int]) - # # it_parses "a = 1, 2", MultiAssign.new(["a".var], [1.int, 2.int]) - - it_parses "def foo\n1\nend", Def.new("foo", [] of Arg, ASTNode[1.int]) - it_parses "def downto(n)\n1\nend", Def.new("downto", ["n".arg], ASTNode[1.int]) - it_parses "def foo ; 1 ; end", Def.new("foo", [] of Arg, ASTNode[1.int]) + it_parses "[1, 2]", ASTNode[1.i32, 2.i32].array + it_parses "[\n1, 2]", ASTNode[1.i32, 2.i32].array + it_parses "[1,\n 2,]", ASTNode[1.i32, 2.i32].array + + it_parses "1 + 2", Call.new(1.i32, "+", ASTNode[2.i32]) + it_parses "1 +\n2", Call.new(1.i32, "+", ASTNode[2.i32]) + it_parses "1 +2", Call.new(1.i32, "+", ASTNode[2.i32]) + it_parses "1 -2", Call.new(1.i32, "-", ASTNode[2.i32]) + it_parses "1 +2.0", Call.new(1.i32, "+", ASTNode[2.f64]) + it_parses "1 -2.0", Call.new(1.i32, "-", ASTNode[2.f64]) + it_parses "1 +2L", Call.new(1.i32, "+", ASTNode[2.i64]) + it_parses "1 -2L", Call.new(1.i32, "-", ASTNode[2.i64]) + it_parses "1\n+2", ASTNode[1.i32, 2.i32] + it_parses "1;+2", ASTNode[1.i32, 2.i32] + it_parses "1 - 2", Call.new(1.i32, "-", ASTNode[2.i32]) + it_parses "1 -\n2", Call.new(1.i32, "-", ASTNode[2.i32]) + it_parses "1\n-2", ASTNode[1.i32, -2.i32] + it_parses "1;-2", ASTNode[1.i32, -2.i32] + it_parses "1 * 2", Call.new(1.i32, "*", ASTNode[2.i32]) + it_parses "1 * -2", Call.new(1.i32, "*", ASTNode[-2.i32]) + it_parses "2 * 3 + 4 * 5", Call.new(Call.new(2.i32, "*", ASTNode[3.i32]), "+", ASTNode[Call.new(4.i32, "*", ASTNode[5.i32])]) + it_parses "1 / 2", Call.new(1.i32, "/", ASTNode[2.i32]) + it_parses "1 / -2", Call.new(1.i32, "/", ASTNode[-2.i32]) + it_parses "2 / 3 + 4 / 5", Call.new(Call.new(2.i32, "/", ASTNode[3.i32]), "+", ASTNode[Call.new(4.i32, "/", ASTNode[5.i32])]) + it_parses "2 * (3 + 4)", Call.new(2.i32, "*", ASTNode[Call.new(3.i32, "+", ASTNode[4.i32])]) + + it_parses "!1", Call.new(1.i32, "!@") + it_parses "1 && 2", And.new(1.i32, 2.i32) + it_parses "1 || 2", Or.new(1.i32, 2.i32) + + it_parses "1 <=> 2", Call.new(1.i32, "<=>", ASTNode[2.i32]) + + it_parses "a = 1", Assign.new("a".var, 1.i32) + it_parses "a = b = 2", Assign.new("a".var, Assign.new("b".var, 2.i32)) + + # # it_parses "a, b = 1, 2", MultiAssign.new(["a".var, "b".var], [1.i32, 2.i32]) + # # it_parses "a, b = 1", MultiAssign.new(["a".var, "b".var], [1.i32]) + # # it_parses "a = 1, 2", MultiAssign.new(["a".var], [1.i32, 2.i32]) + + it_parses "def foo\n1\nend", Def.new("foo", [] of Arg, ASTNode[1.i32]) + it_parses "def downto(n)\n1\nend", Def.new("downto", ["n".arg], ASTNode[1.i32]) + it_parses "def foo ; 1 ; end", Def.new("foo", [] of Arg, ASTNode[1.i32]) it_parses "def foo; end", Def.new("foo", [] of Arg, nil) it_parses "def foo(var); end", Def.new("foo", ["var".arg], nil) it_parses "def foo(\nvar); end", Def.new("foo", ["var".arg], nil) @@ -180,24 +180,24 @@ describe "Parser" do it_parses "def foo var\n end", Def.new("foo", ["var".arg], nil) it_parses "def foo var1, var2\n end", Def.new("foo", ["var1".arg, "var2".arg], nil) it_parses "def foo var1,\nvar2\n end", Def.new("foo", ["var1".arg, "var2".arg], nil) - it_parses "def foo; 1; 2; end", Def.new("foo", [] of Arg, ASTNode[1.int, 2.int]) + it_parses "def foo; 1; 2; end", Def.new("foo", [] of Arg, ASTNode[1.i32, 2.i32]) it_parses "def foo=(value); end", Def.new("foo=", ["value".arg], [] of ASTNode) - it_parses "def foo(n); foo(n -1); end", Def.new("foo", ["n".arg], "foo".call(ASTNode[Call.new("n".var, "-", ASTNode[1.int])])) + it_parses "def foo(n); foo(n -1); end", Def.new("foo", ["n".arg], "foo".call(ASTNode[Call.new("n".var, "-", ASTNode[1.i32])])) it_parses "def type(type); end", Def.new("type", ["type".arg], nil) - it_parses "def self.foo\n1\nend", Def.new("foo", [] of Arg, 1.int, "self".var) - it_parses "def Foo.foo\n1\nend", Def.new("foo", [] of Arg, 1.int, "Foo".ident) - it_parses "def Foo::Bar.foo\n1\nend", Def.new("foo", [] of Arg, 1.int, ["Foo", "Bar"].ident) + it_parses "def self.foo\n1\nend", Def.new("foo", [] of Arg, 1.i32, "self".var) + it_parses "def Foo.foo\n1\nend", Def.new("foo", [] of Arg, 1.i32, "Foo".ident) + it_parses "def Foo::Bar.foo\n1\nend", Def.new("foo", [] of Arg, 1.i32, ["Foo", "Bar"].ident) it_parses "def foo; a; end", Def.new("foo", [] of Arg, "a".call) it_parses "def foo(a); a; end", Def.new("foo", ["a".arg], "a".var) - it_parses "def foo; a = 1; a; end", Def.new("foo", [] of Arg, [Assign.new("a".var, 1.int), "a".var]) - it_parses "def foo; a = 1; a {}; end", Def.new("foo", [] of Arg, [Assign.new("a".var, 1.int), Call.new(nil, "a", [] of ASTNode, Block.new)]) - it_parses "def foo; a = 1; x { a }; end", Def.new("foo", [] of Arg, [Assign.new("a".var, 1.int), Call.new(nil, "x", [] of ASTNode, Block.new([] of ASTNode, ["a".var]))]) + it_parses "def foo; a = 1; a; end", Def.new("foo", [] of Arg, [Assign.new("a".var, 1.i32), "a".var]) + it_parses "def foo; a = 1; a {}; end", Def.new("foo", [] of Arg, [Assign.new("a".var, 1.i32), Call.new(nil, "a", [] of ASTNode, Block.new)]) + it_parses "def foo; a = 1; x { a }; end", Def.new("foo", [] of Arg, [Assign.new("a".var, 1.i32), Call.new(nil, "x", [] of ASTNode, Block.new([] of ASTNode, ["a".var]))]) it_parses "def foo; x { |a| a }; end", Def.new("foo", [] of Arg, [Call.new(nil, "x", [] of ASTNode, Block.new(ASTNode["a".var], ["a".var]))]) - it_parses "def foo(var = 1); end", Def.new("foo", [Arg.new("var", 1.int)], nil) - it_parses "def foo var = 1; end", Def.new("foo", [Arg.new("var", 1.int)], nil) + it_parses "def foo(var = 1); end", Def.new("foo", [Arg.new("var", 1.i32)], nil) + it_parses "def foo var = 1; end", Def.new("foo", [Arg.new("var", 1.i32)], nil) it_parses "def foo(var : Int); end", Def.new("foo", [Arg.new("var", nil, "Int".ident)], nil) it_parses "def foo var : Int; end", Def.new("foo", [Arg.new("var", nil, "Int".ident)], nil) it_parses "def foo(var : self); end", Def.new("foo", [Arg.new("var", nil, SelfRestriction.new)], nil) @@ -206,22 +206,22 @@ describe "Parser" do it_parses "foo", "foo".call it_parses "foo()", "foo".call - it_parses "foo(1)", "foo".call(ASTNode[1.int]) - it_parses "foo 1", "foo".call(ASTNode[1.int]) - it_parses "foo 1\n", "foo".call(ASTNode[1.int]) - it_parses "foo 1;", "foo".call(ASTNode[1.int]) - it_parses "foo 1, 2", "foo".call(ASTNode[1.int, 2.int]) - it_parses "foo (1 + 2), 3", "foo".call(ASTNode[Call.new(1.int, "+", ASTNode[2.int]), 3.int]) - it_parses "foo(1 + 2)", "foo".call(ASTNode[Call.new(1.int, "+", ASTNode[2.int])]) - it_parses "foo -1.0, -2.0", "foo".call(ASTNode[-1.double, -2.double]) - it_parses "foo(\n1)", "foo".call(ASTNode[1.int]) - - it_parses "foo + 1", Call.new("foo".call, "+", ASTNode[1.int]) - it_parses "foo +1", Call.new(nil, "foo", ASTNode[1.int]) - it_parses "foo +1.0", Call.new(nil, "foo", ASTNode[1.double]) - it_parses "foo +1L", Call.new(nil, "foo", ASTNode[1.long]) - it_parses "foo = 1; foo +1", [Assign.new("foo".var, 1.int), Call.new("foo".var, "+", ASTNode[1.int])] - it_parses "foo = 1; foo -1", [Assign.new("foo".var, 1.int), Call.new("foo".var, "-", ASTNode[1.int])] + it_parses "foo(1)", "foo".call(ASTNode[1.i32]) + it_parses "foo 1", "foo".call(ASTNode[1.i32]) + it_parses "foo 1\n", "foo".call(ASTNode[1.i32]) + it_parses "foo 1;", "foo".call(ASTNode[1.i32]) + it_parses "foo 1, 2", "foo".call(ASTNode[1.i32, 2.i32]) + it_parses "foo (1 + 2), 3", "foo".call(ASTNode[Call.new(1.i32, "+", ASTNode[2.i32]), 3.i32]) + it_parses "foo(1 + 2)", "foo".call(ASTNode[Call.new(1.i32, "+", ASTNode[2.i32])]) + it_parses "foo -1.0, -2.0", "foo".call(ASTNode[-1.f64, -2.f64]) + it_parses "foo(\n1)", "foo".call(ASTNode[1.i32]) + + it_parses "foo + 1", Call.new("foo".call, "+", ASTNode[1.i32]) + it_parses "foo +1", Call.new(nil, "foo", ASTNode[1.i32]) + it_parses "foo +1.0", Call.new(nil, "foo", ASTNode[1.f64]) + it_parses "foo +1L", Call.new(nil, "foo", ASTNode[1.i64]) + it_parses "foo = 1; foo +1", [Assign.new("foo".var, 1.i32), Call.new("foo".var, "+", ASTNode[1.i32])] + it_parses "foo = 1; foo -1", [Assign.new("foo".var, 1.i32), Call.new("foo".var, "-", ASTNode[1.i32])] it_parses "foo !false", Call.new(nil, "foo", ASTNode[Call.new(false.bool, "!@")]) it_parses "!a && b", And.new(Call.new("a".call, "!@"), "b".call) @@ -229,10 +229,10 @@ describe "Parser" do it_parses "foo.bar.baz", Call.new(Call.new("foo".call, "bar"), "baz") it_parses "f.x Foo.new", Call.new("f".call, "x", ASTNode[Call.new("Foo".ident, "new")]) it_parses "f.x = Foo.new", Call.new("f".call, "x=", ASTNode[Call.new("Foo".ident, "new")]) - it_parses "f.x = - 1", Call.new("f".call, "x=", ASTNode[Call.new(1.int, "-@")]) + it_parses "f.x = - 1", Call.new("f".call, "x=", ASTNode[Call.new(1.i32, "-@")]) ["+", "-", "*", "/", "%", "|", "&", "^", "**", "<<", ">>"].each do |op| - it_parses "f.x #{op}= 2", Call.new("f".call, "x=", ASTNode[Call.new(Call.new("f".call, "x"), op, ASTNode[2.int])]) + it_parses "f.x #{op}= 2", Call.new("f".call, "x=", ASTNode[Call.new(Call.new("f".call, "x"), op, ASTNode[2.i32])]) end ["/", "<", "<=", "==", "!=", ">", ">=", "+", "-", "*", "/", "%", "&", "|", "^", "**", "+@", "-@", "~@", "!@", "==="].each do |op| @@ -240,33 +240,33 @@ describe "Parser" do end ["<<", "<", "<=", "==", ">>", ">", ">=", "+", "-", "*", "/", "%", "|", "&", "^", "**", "==="].each do |op| - it_parses "1 #{op} 2", Call.new(1.int, op, ASTNode[2.int]) - it_parses "n #{op} 2", Call.new("n".call, op, ASTNode[2.int]) + it_parses "1 #{op} 2", Call.new(1.i32, op, ASTNode[2.i32]) + it_parses "n #{op} 2", Call.new("n".call, op, ASTNode[2.i32]) end ["bar", "+", "-", "*", "/", "<", "<=", "==", ">", ">=", "%", "|", "&", "^", "**", "==="].each do |name| it_parses "foo.#{name}", Call.new("foo".call, name) - it_parses "foo.#{name} 1, 2", Call.new("foo".call, name, ASTNode[1.int, 2.int]) + it_parses "foo.#{name} 1, 2", Call.new("foo".call, name, ASTNode[1.i32, 2.i32]) end ["+", "-", "*", "/", "%", "|", "&", "^", "**", "<<", ">>"].each do |op| - it_parses "a = 1; a #{op}= 1", [Assign.new("a".var, 1.int), Assign.new("a".var, Call.new("a".var, op, ASTNode[1.int]))] + it_parses "a = 1; a #{op}= 1", [Assign.new("a".var, 1.i32), Assign.new("a".var, Call.new("a".var, op, ASTNode[1.i32]))] end - it_parses "a = 1; a &&= 1", [Assign.new("a".var, 1.int), And.new("a".var, Assign.new("a".var, 1.int))] - it_parses "a = 1; a ||= 1", [Assign.new("a".var, 1.int), Or.new("a".var, Assign.new("a".var, 1.int))] + it_parses "a = 1; a &&= 1", [Assign.new("a".var, 1.i32), And.new("a".var, Assign.new("a".var, 1.i32))] + it_parses "a = 1; a ||= 1", [Assign.new("a".var, 1.i32), Or.new("a".var, Assign.new("a".var, 1.i32))] - it_parses "if foo; 1; end", If.new("foo".call, 1.int) - it_parses "if foo\n1\nend", If.new("foo".call, 1.int) - it_parses "if foo; 1; else; 2; end", If.new("foo".call, 1.int, 2.int) - it_parses "if foo\n1\nelse\n2\nend", If.new("foo".call, 1.int, 2.int) - it_parses "if foo; 1; elsif bar; 2; else 3; end", If.new("foo".call, 1.int, If.new("bar".call, 2.int, 3.int)) + it_parses "if foo; 1; end", If.new("foo".call, 1.i32) + it_parses "if foo\n1\nend", If.new("foo".call, 1.i32) + it_parses "if foo; 1; else; 2; end", If.new("foo".call, 1.i32, 2.i32) + it_parses "if foo\n1\nelse\n2\nend", If.new("foo".call, 1.i32, 2.i32) + it_parses "if foo; 1; elsif bar; 2; else 3; end", If.new("foo".call, 1.i32, If.new("bar".call, 2.i32, 3.i32)) it_parses "include Foo", Include.new("Foo".ident) it_parses "include Foo\nif true; end", [Include.new("Foo".ident), If.new(true.bool)] - it_parses "unless foo; 1; end", If.new("foo".call.not, 1.int) - it_parses "unless foo; 1; else; 2; end", If.new("foo".call.not, 1.int, 2.int) + it_parses "unless foo; 1; end", If.new("foo".call.not, 1.i32) + it_parses "unless foo; 1; else; 2; end", If.new("foo".call.not, 1.i32, 2.i32) it_parses "class Foo; end", ClassDef.new("Foo") it_parses "class Foo\nend", ClassDef.new("Foo") @@ -277,49 +277,49 @@ describe "Parser" do it_parses "module Foo\ndef foo; end; end", ModuleDef.new("Foo", [Def.new("foo", [] of Arg, nil)]) it_parses "while true; end;", While.new(true.bool) - it_parses "while true; 1; end;", While.new(true.bool, 1.int) + it_parses "while true; 1; end;", While.new(true.bool, 1.i32) - it_parses "foo do; 1; end", Call.new(nil, "foo", [] of ASTNode, Block.new([] of ASTNode, 1.int)) - it_parses "foo do |a|; 1; end", Call.new(nil, "foo", [] of ASTNode, Block.new(["a".var], 1.int)) + it_parses "foo do; 1; end", Call.new(nil, "foo", [] of ASTNode, Block.new([] of ASTNode, 1.i32)) + it_parses "foo do |a|; 1; end", Call.new(nil, "foo", [] of ASTNode, Block.new(["a".var], 1.i32)) - it_parses "foo { 1 }", Call.new(nil, "foo", [] of ASTNode, Block.new([] of ASTNode, 1.int)) - it_parses "foo { |a| 1 }", Call.new(nil, "foo", [] of ASTNode, Block.new(["a".var], 1.int)) - it_parses "foo { |a, b| 1 }", Call.new(nil, "foo", [] of ASTNode, Block.new(["a".var, "b".var], 1.int)) - it_parses "1.foo do; 1; end", Call.new(1.int, "foo", [] of ASTNode, Block.new([] of ASTNode, 1.int)) + it_parses "foo { 1 }", Call.new(nil, "foo", [] of ASTNode, Block.new([] of ASTNode, 1.i32)) + it_parses "foo { |a| 1 }", Call.new(nil, "foo", [] of ASTNode, Block.new(["a".var], 1.i32)) + it_parses "foo { |a, b| 1 }", Call.new(nil, "foo", [] of ASTNode, Block.new(["a".var, "b".var], 1.i32)) + it_parses "1.foo do; 1; end", Call.new(1.i32, "foo", [] of ASTNode, Block.new([] of ASTNode, 1.i32)) - it_parses "1 ? 2 : 3", If.new(1.int, 2.int, 3.int) - it_parses "1 ? a : b", If.new(1.int, "a".call, "b".call) + it_parses "1 ? 2 : 3", If.new(1.i32, 2.i32, 3.i32) + it_parses "1 ? a : b", If.new(1.i32, "a".call, "b".call) - it_parses "1 if 3", If.new(3.int, 1.int) - it_parses "1 unless 3", If.new(3.int.not, 1.int) - it_parses "1 while 3", While.new(3.int, 1.int, true) - it_parses "a = 1; a += 10 if a += 20", [Assign.new("a".var, 1.int), If.new(Assign.new("a".var, Call.new("a".var, "+", [20.int] of ASTNode)), Assign.new("a".var, Call.new("a".var, "+", [10.int] of ASTNode)))] + it_parses "1 if 3", If.new(3.i32, 1.i32) + it_parses "1 unless 3", If.new(3.i32.not, 1.i32) + it_parses "1 while 3", While.new(3.i32, 1.i32, true) + it_parses "a = 1; a += 10 if a += 20", [Assign.new("a".var, 1.i32), If.new(Assign.new("a".var, Call.new("a".var, "+", [20.i32] of ASTNode)), Assign.new("a".var, Call.new("a".var, "+", [10.i32] of ASTNode)))] it_parses "puts a if true", If.new(true.bool, Call.new(nil, "puts", ["a".call] of ASTNode)) it_parses "puts a unless true", If.new(true.bool.not, Call.new(nil, "puts", ["a".call] of ASTNode)) it_parses "puts a while true", While.new(true.bool, Call.new(nil, "puts", ["a".call] of ASTNode), true) it_parses "return", Return.new it_parses "return;", Return.new - it_parses "return 1", Return.new([1.int]) - it_parses "return 1 if true", If.new(true.bool, Return.new([1.int])) + it_parses "return 1", Return.new([1.i32]) + it_parses "return 1 if true", If.new(true.bool, Return.new([1.i32])) it_parses "return if true", If.new(true.bool, Return.new) it_parses "break", Break.new it_parses "break;", Break.new - it_parses "break 1", Break.new([1.int]) - it_parses "break 1 if true", If.new(true.bool, Break.new([1.int])) + it_parses "break 1", Break.new([1.i32]) + it_parses "break 1 if true", If.new(true.bool, Break.new([1.i32])) it_parses "break if true", If.new(true.bool, Break.new) it_parses "next", Next.new it_parses "next;", Next.new - it_parses "next 1", Next.new([1.int]) - it_parses "next 1 if true", If.new(true.bool, Next.new([1.int])) + it_parses "next 1", Next.new([1.i32]) + it_parses "next 1 if true", If.new(true.bool, Next.new([1.i32])) it_parses "next if true", If.new(true.bool, Next.new) it_parses "yield", Yield.new it_parses "yield;", Yield.new - it_parses "yield 1", Yield.new([1.int]) - it_parses "yield 1 if true", If.new(true.bool, Yield.new([1.int])) + it_parses "yield 1", Yield.new([1.i32]) + it_parses "yield 1 if true", If.new(true.bool, Yield.new([1.i32])) it_parses "yield if true", If.new(true.bool, Yield.new) it_parses "Int", "Int".ident @@ -329,37 +329,37 @@ describe "Parser" do it_parses "def []=(value); end", Def.new("[]=", ["value".arg], nil) it_parses "def self.[]; end", Def.new("[]", [] of Arg, nil, "self".var) - it_parses "Int[8]", Call.new("Int".ident, "[]", [8.int] of ASTNode) - it_parses "Int[8, 4]", Call.new("Int".ident, "[]", [8.int, 4.int] of ASTNode) - it_parses "Int[8, 4,]", Call.new("Int".ident, "[]", [8.int, 4.int] of ASTNode) + it_parses "Int[8]", Call.new("Int".ident, "[]", [8.i32] of ASTNode) + it_parses "Int[8, 4]", Call.new("Int".ident, "[]", [8.i32, 4.i32] of ASTNode) + it_parses "Int[8, 4,]", Call.new("Int".ident, "[]", [8.i32, 4.i32] of ASTNode) it_parses "def [](x); end", Def.new("[]", ["x".arg], nil) - it_parses "foo[0] = 1", Call.new("foo".call, "[]=", [0.int, 1.int] of ASTNode) + it_parses "foo[0] = 1", Call.new("foo".call, "[]=", [0.i32, 1.i32] of ASTNode) - it_parses "begin; 1; 2; 3; end;", Expressions.new([1.int, 2.int, 3.int]) + it_parses "begin; 1; 2; 3; end;", Expressions.new([1.i32, 2.i32, 3.i32]) it_parses "self", "self".var it_parses "@foo", "@foo".instance_var - it_parses "@foo = 1", Assign.new("@foo".instance_var, 1.int) + it_parses "@foo = 1", Assign.new("@foo".instance_var, 1.i32) it_parses "call @foo.bar", Call.new(nil, "call", [Call.new("@foo".instance_var, "bar")] of ASTNode) it_parses "call \"foo\"", Call.new(nil, "call", ["foo".string] of ASTNode) - it_parses "def foo; end; if false; 1; else; 2; end", [Def.new("foo", [] of Arg), If.new(false.bool, 1.int, 2.int)] + it_parses "def foo; end; if false; 1; else; 2; end", [Def.new("foo", [] of Arg), If.new(false.bool, 1.i32, 2.i32)] it_parses "A.new(\"x\", B.new(\"y\"))", Call.new("A".ident, "new", ["x".string, Call.new("B".ident, "new", ["y".string] of ASTNode)] of ASTNode) it_parses "foo []", Call.new(nil, "foo", [([] of ASTNode).array] of ASTNode) - it_parses "foo [1]", Call.new(nil, "foo", [([1.int] of ASTNode).array] of ASTNode) + it_parses "foo [1]", Call.new(nil, "foo", [([1.i32] of ASTNode).array] of ASTNode) it_parses "foo.bar []", Call.new("foo".call, "bar", [([] of ASTNode).array] of ASTNode) - it_parses "foo.bar [1]", Call.new("foo".call, "bar", [([1.int] of ASTNode).array] of ASTNode) + it_parses "foo.bar [1]", Call.new("foo".call, "bar", [([1.i32] of ASTNode).array] of ASTNode) it_parses "class Foo; end\nwhile true; end", [ClassDef.new("Foo"), While.new(true.bool)] it_parses "while true; end\nif true; end", [While.new(true.bool), If.new(true.bool)] - it_parses "(1)\nif true; end", [1.int, If.new(true.bool)] - it_parses "begin\n1\nend\nif true; end", [1.int, If.new(true.bool)] + it_parses "(1)\nif true; end", [1.i32, If.new(true.bool)] + it_parses "begin\n1\nend\nif true; end", [1.i32, If.new(true.bool)] it_parses "Foo::Bar", ["Foo", "Bar"].ident @@ -383,13 +383,13 @@ describe "Parser" do it_parses "lib C; struct Foo; x : Int; y : Float; end end", LibDef.new("C", nil, [StructDef.new("Foo", [FunDefArg.new("x", "Int".ident), FunDefArg.new("y", "Float".ident)])]) it_parses "lib C; struct Foo; x : Int*; end end", LibDef.new("C", nil, [StructDef.new("Foo", [FunDefArg.new("x", "Int".ident, 1)])]) it_parses "lib C; struct Foo; x : Int**; end end", LibDef.new("C", nil, [StructDef.new("Foo", [FunDefArg.new("x", "Int".ident, 2)])]) - it_parses "lib C; Foo = 1; end", LibDef.new("C", nil, [Assign.new("Foo".ident, 1.int)]) + it_parses "lib C; Foo = 1; end", LibDef.new("C", nil, [Assign.new("Foo".ident, 1.i32)]) it_parses "lib C\nfun getch = GetChar\nend", LibDef.new("C", nil, [FunDef.new("getch", [] of ASTNode, nil, 0, false, "GetChar")]) - it_parses "1 .. 2", RangeLiteral.new(1.int, 2.int, false) - it_parses "1 ... 2", RangeLiteral.new(1.int, 2.int, true) + it_parses "1 .. 2", RangeLiteral.new(1.i32, 2.i32, false) + it_parses "1 ... 2", RangeLiteral.new(1.i32, 2.i32, true) - it_parses "A = 1", Assign.new("A".ident, 1.int) + it_parses "A = 1", Assign.new("A".ident, 1.i32) # # it_parses "puts %w(one)", Call.new(nil, "puts", [["one".string].array]) diff --git a/bootstrap/spec/std/string_spec.cr b/bootstrap/spec/std/string_spec.cr index 8c46fff92d..0fb0575af6 100755 --- a/bootstrap/spec/std/string_spec.cr +++ b/bootstrap/spec/std/string_spec.cr @@ -42,10 +42,11 @@ describe "String" do it "does to_f" do "1234.56".to_f.should eq(1234.56_f32) + "1234.56".to_f32.should eq(1234.56_f32) end - it "does to_d" do - "1234.56".to_d.should eq(1234.56) + it "does to_f64" do + "1234.56".to_f64.should eq(1234.56_f64) end it "compares strings: different length" do diff --git a/std/float32.cr b/std/float32.cr index d9728fdd76..f5100d0906 100644 --- a/std/float32.cr +++ b/std/float32.cr @@ -15,6 +15,6 @@ class Float32 end def to_s - to_d.to_s + to_f64.to_s end end \ No newline at end of file diff --git a/std/float64.cr b/std/float64.cr index b848e4edef..3d7e910b1c 100644 --- a/std/float64.cr +++ b/std/float64.cr @@ -11,7 +11,7 @@ class Float64 end def **(other) - self ** other.to_d + self ** other.to_f64 end def to_s diff --git a/std/int.cr b/std/int.cr index 6ae5452145..e72fa4888b 100644 --- a/std/int.cr +++ b/std/int.cr @@ -17,11 +17,11 @@ class Int end def **(other : Int) - (to_d ** other).to_i + (to_f64 ** other).to_i end def **(other) - to_d ** other + to_f64 ** other end def [](bit) diff --git a/std/math.cr b/std/math.cr index ef6af95c89..fbb504d517 100644 --- a/std/math.cr +++ b/std/math.cr @@ -28,63 +28,63 @@ module Math PI = 3.14159265358979323846 def self.acos(value) - C.acos(value.to_d) + C.acos(value.to_f64) end def self.acosh(value) - C.acosh(value.to_d) + C.acosh(value.to_f64) end def self.asin(value) - C.asin(value.to_d) + C.asin(value.to_f64) end def self.asinh(value) - C.asinh(value.to_d) + C.asinh(value.to_f64) end def self.atan(value) - C.atan(value.to_d) + C.atan(value.to_f64) end def self.atan2(y, x) - C.atan2(y.to_d, x.to_d) + C.atan2(y.to_f64, x.to_f64) end def self.cbrt(value) - C.cbrt(value.to_d) + C.cbrt(value.to_f64) end def self.cos(value) - C.cos(value.to_d) + C.cos(value.to_f64) end def self.erf(value) - C.erf(value.to_d) + C.erf(value.to_f64) end def self.erfc(value) - C.erfc(value.to_d) + C.erfc(value.to_f64) end def self.exp(value) - C.exp(value.to_d) + C.exp(value.to_f64) end def self.gamma(value) - C.tgamma(value.to_d) + C.tgamma(value.to_f64) end def self.hypot(x, y) - C.hypot(x.to_d, y.to_d) + C.hypot(x.to_f64, y.to_f64) end def self.ldexp(flt, int : Int) - C.ldexp(flt.to_d, int) + C.ldexp(flt.to_f64, int) end def self.log(numeric) - C.log(numeric.to_d) + C.log(numeric.to_f64) end def self.log(numeric, base) @@ -92,11 +92,11 @@ module Math end def self.log10(numeric) - C.log10(numeric.to_d) + C.log10(numeric.to_f64) end def self.log2(numeric) - C.log2(numeric.to_d) + C.log2(numeric.to_f64) end def self.min(value1, value2) @@ -108,22 +108,22 @@ module Math end def self.sin(value) - C.sin(value.to_d) + C.sin(value.to_f64) end def self.sinh(value) - C.sinh(value.to_d) + C.sinh(value.to_f64) end def self.tan(value) - C.tan(value.to_d) + C.tan(value.to_f64) end def self.tanh(value) - C.tanh(value.to_d) + C.tanh(value.to_f64) end def self.sqrt(value : Int) - sqrt value.to_d + sqrt value.to_f64 end end \ No newline at end of file diff --git a/std/string.cr b/std/string.cr index 9a42f2f924..3a5e147682 100644 --- a/std/string.cr +++ b/std/string.cr @@ -64,10 +64,14 @@ class String end def to_f + to_f64 + end + + def to_f32 C.strtof @c.ptr, nil end - def to_d + def to_f64 C.atof @c.ptr end -- GitLab