diff --git a/vlib/toml/parser/parser.v b/vlib/toml/parser/parser.v index 358308b99e..221b0ba9b6 100644 --- a/vlib/toml/parser/parser.v +++ b/vlib/toml/parser/parser.v @@ -1232,13 +1232,9 @@ pub fn (mut p Parser) dotted_key_value() ?(DottedKey, ast.Value) { // value parse and returns an `ast.Value` type. // values are the token(s) appearing after an assignment operator (=). pub fn (mut p Parser) value() ?ast.Value { - util.printdbg(@MOD + '.' + @STRUCT + '.' + @FN, 'parsing value...') - // println('parsed comment "${p.tok.lit}"') - + util.printdbg(@MOD + '.' + @STRUCT + '.' + @FN, 'parsing value from token "$p.tok.kind" "$p.tok.lit"...') mut value := ast.Value(ast.Null{}) - util.printdbg(@MOD + '.' + @STRUCT + '.' + @FN, 'parsing token "$p.tok.kind" "$p.tok.lit"') - // mut value := ast.Value{} if p.tok.kind == .number { number_or_date := p.number_or_date() ? value = number_or_date @@ -1257,7 +1253,6 @@ pub fn (mut p Parser) value() ?ast.Value { p.ignore_while(parser.space_formatting) mut t := map[string]ast.Value{} p.inline_table(mut t) ? - // table[key_str] = ast.Value(t) ast.Value(t) } else { diff --git a/vlib/toml/scanner/scanner.v b/vlib/toml/scanner/scanner.v index e576417d9c..09d78a0961 100644 --- a/vlib/toml/scanner/scanner.v +++ b/vlib/toml/scanner/scanner.v @@ -93,22 +93,23 @@ pub fn (mut s Scanner) scan() ?token.Token { ascii := byte_c.ascii_str() util.printdbg(@MOD + '.' + @STRUCT + '.' + @FN, 'current char "$ascii"') - is_sign := byte_c in [`+`, `-`] - is_signed_number := is_sign && byte(s.at()).is_digit() && !byte(s.peek(-1)).is_digit() + is_sign := c == `+` || c == `-` // (+/-)nan & (+/-)inf - is_nan := byte_c == `n` && s.at() == `a` && s.peek(1) == `n` && s.peek(2) == `\n` - is_inf := byte_c == `i` && s.at() == `n` && s.peek(1) == `f` && s.peek(2) == `\n` - is_signed_nan := is_sign && s.at() == `n` && s.peek(1) == `a` && s.peek(2) == `n` - && s.peek(3) == `\n` - is_signed_inf := is_sign && s.at() == `i` && s.peek(1) == `n` && s.peek(2) == `f` - && s.peek(3) == `\n` - if is_nan || is_inf || is_signed_nan || is_signed_inf { + peek_1 := s.peek(1) + peek_2 := s.peek(2) + is_nan := c == `n` && s.at() == `a` && peek_1 == `n` + is_inf := !is_nan && c == `i` && s.at() == `n` && peek_1 == `f` + is_signed_nan := is_sign && s.at() == `n` && peek_1 == `a` && peek_2 == `n` + is_signed_inf := !is_signed_nan && is_sign && s.at() == `i` && peek_1 == `n` + && peek_2 == `f` + if !s.is_left_of_assign && (is_nan || is_inf || is_signed_nan || is_signed_inf) { num := s.extract_nan_or_inf_number() ? util.printdbg(@MOD + '.' + @STRUCT + '.' + @FN, 'identified a special number "$num" ($num.len)') return s.new_token(.number, num, num.len) } + is_signed_number := is_sign && byte(s.at()).is_digit() && !byte(s.peek(-1)).is_digit() is_digit := byte_c.is_digit() if is_digit || is_signed_number { num := s.extract_number() ? @@ -118,7 +119,8 @@ pub fn (mut s Scanner) scan() ?token.Token { if util.is_key_char(byte_c) { key := s.extract_key() - if key.to_lower() in ['true', 'false'] { + key_lower_case := key.to_lower() + if key_lower_case == 'true' || key_lower_case == 'false' { util.printdbg(@MOD + '.' + @STRUCT + '.' + @FN, 'identified a boolean "$key" ($key.len)') return s.new_token(.boolean, key, key.len) } diff --git a/vlib/toml/tests/iarna.toml-spec-tests_test.v b/vlib/toml/tests/iarna.toml-spec-tests_test.v index 11b85707ab..c471bd532e 100644 --- a/vlib/toml/tests/iarna.toml-spec-tests_test.v +++ b/vlib/toml/tests/iarna.toml-spec-tests_test.v @@ -5,8 +5,7 @@ import x.json2 // Instructions for developers: // The actual tests and data can be obtained by doing: -// `cd vlib/toml/tests/testdata` -// `git clone --depth 1 https://github.com/iarna/toml-spec-tests.git iarna/toml-test` +// `git clone --depth 1 https://github.com/iarna/toml-spec-tests.git vlib/toml/tests/testdata/iarna/toml-test` // See also the CI toml tests const ( // Can be set to `true` to skip tests that stress test the parser @@ -14,14 +13,7 @@ const ( skip_large_files = false // Kept for easier handling of future updates to the tests - valid_exceptions = [ - 'values/spec-float-10.toml', - 'values/spec-float-11.toml', - 'values/spec-float-12.toml', - 'values/spec-float-13.toml', - 'values/spec-float-14.toml', - 'values/spec-float-15.toml', - ] + valid_exceptions = []string{} invalid_exceptions = [ 'errors/table-3.toml', 'errors/table-4.toml', diff --git a/vlib/toml/tests/testdata/.gitignore b/vlib/toml/tests/testdata/.gitignore new file mode 100644 index 0000000000..f743971c54 --- /dev/null +++ b/vlib/toml/tests/testdata/.gitignore @@ -0,0 +1 @@ +iarna/toml-test/ diff --git a/vlib/toml/tests/types_test.v b/vlib/toml/tests/types_test.v index f8b930fd25..c870d6970d 100644 --- a/vlib/toml/tests/types_test.v +++ b/vlib/toml/tests/types_test.v @@ -1,4 +1,5 @@ import toml +import strconv fn test_string() { str_value := 'test string' @@ -90,3 +91,33 @@ test = 42 assert value as i64 == 42 assert value.i64() == 42 } + +fn test_nan_and_inf_values() { + mut toml_doc := toml.parse('nan = nan') or { panic(err) } + mut value := toml_doc.value('nan') + assert value.string() == 'nan' + + toml_doc = toml.parse('nan = nan#comment') or { panic(err) } + value = toml_doc.value('nan') + assert value.string() == 'nan' + + toml_doc = toml.parse('nan = -nan') or { panic(err) } + value = toml_doc.value('nan') + assert value.string() == 'nan' + + toml_doc = toml.parse('nan = +nan') or { panic(err) } + value = toml_doc.value('nan') + assert value.string() == 'nan' + + toml_doc = toml.parse('inf = inf') or { panic(err) } + value = toml_doc.value('inf') + assert value.u64() == strconv.double_plus_infinity + + toml_doc = toml.parse('inf = +inf') or { panic(err) } + value = toml_doc.value('inf') + assert value.u64() == strconv.double_plus_infinity + + toml_doc = toml.parse('inf = -inf') or { panic(err) } + value = toml_doc.value('inf') + assert value.u64() == strconv.double_minus_infinity +}