summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorwszqkzqk <wszqkzqk@qq.com>2022-12-09 20:07:59 +0800
committerRico Tzschichholz <ricotz@ubuntu.com>2023-01-30 15:04:26 +0100
commit54ca3c304d252eda7fe7ee50014ca28a3b68dd19 (patch)
treed0d1e349b70e1228a66c984c5a1e9d2b72e35fc6
parent760e1041346593bec39897b21eb965f8d1f7dbd2 (diff)
downloadvala-54ca3c304d252eda7fe7ee50014ca28a3b68dd19.tar.gz
vala: Add support for Hexadecimal floating point literals
https://gcc.gnu.org/onlinedocs/gcc/Hex-Floats.html#Hex-Floats
-rw-r--r--tests/Makefile.am5
-rw-r--r--tests/basic-types/floats-hexadecimal.c-expected73
-rw-r--r--tests/basic-types/floats-hexadecimal.vala28
-rw-r--r--tests/scanner/floats-hexadecimal-invalid1.test5
-rw-r--r--tests/scanner/floats-hexadecimal-invalid2.test5
-rw-r--r--tests/semantic/realliteral-exponent-has-no-digits4.test5
-rw-r--r--tests/semantic/realliteral-exponent-has-no-digits5.test5
-rw-r--r--vala/valarealliteral.vala27
-rw-r--r--vala/valascanner.vala24
9 files changed, 172 insertions, 5 deletions
diff --git a/tests/Makefile.am b/tests/Makefile.am
index 844f4c2a7..f8ddab919 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -58,6 +58,7 @@ TESTS = \
basic-types/integers-octal.vala \
basic-types/escape-chars.vala \
basic-types/float-literals.vala \
+ basic-types/floats-hexadecimal.vala \
basic-types/floats.vala \
basic-types/floats-boxed-cast.vala \
basic-types/boolean.vala \
@@ -906,6 +907,8 @@ TESTS = \
annotations/description.vala \
annotations/noaccessormethod.test \
scanner/comment-not-closed.test \
+ scanner/floats-hexadecimal-invalid1.test \
+ scanner/floats-hexadecimal-invalid2.test \
scanner/preprocessor-invalid.test \
scanner/preprocessor-missing-paren.test \
scanner/preprocessor-unexpected.test \
@@ -1271,6 +1274,8 @@ TESTS = \
semantic/realliteral-exponent-has-no-digits.test \
semantic/realliteral-exponent-has-no-digits2.test \
semantic/realliteral-exponent-has-no-digits3.test \
+ semantic/realliteral-exponent-has-no-digits4.test \
+ semantic/realliteral-exponent-has-no-digits5.test \
semantic/reference-transfer-not-supported.test \
semantic/reference-transfer-unavailable.test \
semantic/return-in-nonvoid.test \
diff --git a/tests/basic-types/floats-hexadecimal.c-expected b/tests/basic-types/floats-hexadecimal.c-expected
new file mode 100644
index 000000000..5e6f5d96b
--- /dev/null
+++ b/tests/basic-types/floats-hexadecimal.c-expected
@@ -0,0 +1,73 @@
+/* basic_types_floats_hexadecimal.c generated by valac, the Vala compiler
+ * generated from basic_types_floats_hexadecimal.vala, do not modify */
+
+#include <glib.h>
+#include <float.h>
+#include <math.h>
+
+#define _vala_assert(expr, msg) if G_LIKELY (expr) ; else g_assertion_message_expr (G_LOG_DOMAIN, __FILE__, __LINE__, G_STRFUNC, msg);
+#define _vala_return_if_fail(expr, msg) if G_LIKELY (expr) ; else { g_return_if_fail_warning (G_LOG_DOMAIN, G_STRFUNC, msg); return; }
+#define _vala_return_val_if_fail(expr, msg, val) if G_LIKELY (expr) ; else { g_return_if_fail_warning (G_LOG_DOMAIN, G_STRFUNC, msg); return val; }
+#define _vala_warn_if_fail(expr, msg) if G_LIKELY (expr) ; else g_warn_message (G_LOG_DOMAIN, __FILE__, __LINE__, G_STRFUNC, msg);
+
+static void _vala_main (void);
+
+static void
+_vala_main (void)
+{
+ {
+ gfloat foo = 0.0F;
+ gfloat bar = 0.0F;
+ foo = 0x1.fP1F;
+ _vala_assert (foo == 3.875f, "foo == 3.875f");
+ bar = 0xab.cdp2f;
+ _vala_assert (bar == 687.203125f, "bar == 687.203125f");
+ }
+ {
+ gdouble foo = 0.0;
+ gdouble bar = 0.0;
+ gboolean _tmp0_ = FALSE;
+ foo = 0xf.ap3;
+ _vala_assert (foo == 125.0, "foo == 125.0");
+ bar = 0xdead.beefp5;
+ if (bar > 1824183.866699) {
+ _tmp0_ = bar < 1824183.8666993;
+ } else {
+ _tmp0_ = FALSE;
+ }
+ _vala_assert (_tmp0_, "bar > 1824183.866699 && bar < 1824183.8666993");
+ }
+ {
+ gdouble foo = 0.0;
+ gboolean _tmp1_ = FALSE;
+ gdouble bar = 0.0;
+ foo = 0x2022.1209p4;
+ if (foo > 131617.127197) {
+ _tmp1_ = foo < 131617.127198;
+ } else {
+ _tmp1_ = FALSE;
+ }
+ _vala_assert (_tmp1_, "foo > 131617.127197 && foo < 131617.127198");
+ bar = 0x47.11p9;
+ _vala_assert (bar == 36386.0, "bar == 36386.0");
+ }
+ {
+ gdouble foo = 0.0;
+ foo = 0x0.8P1;
+ _vala_assert (foo == 1.0, "foo == 1.0");
+ }
+ {
+ gdouble foo = 0.0;
+ foo = 0xab.cdp20;
+ _vala_assert (foo == 180146176.0, "foo == 180146176.0");
+ }
+}
+
+int
+main (int argc,
+ char ** argv)
+{
+ _vala_main ();
+ return 0;
+}
+
diff --git a/tests/basic-types/floats-hexadecimal.vala b/tests/basic-types/floats-hexadecimal.vala
new file mode 100644
index 000000000..f7f43611c
--- /dev/null
+++ b/tests/basic-types/floats-hexadecimal.vala
@@ -0,0 +1,28 @@
+void main () {
+ {
+ float foo = 0x1.fP1F;
+ assert (foo == 3.875f);
+ var bar = 0xab.cdp2f;
+ assert (bar == 687.203125f);
+ }
+ {
+ double foo = 0xf.ap3D;
+ assert (foo == 125.0);
+ var bar = 0xdead.beefp5d;
+ assert (bar > 1824183.866699 && bar < 1824183.8666993);
+ }
+ {
+ double foo = 0x2022.1209p4;
+ assert (foo > 131617.127197 && foo < 131617.127198);
+ var bar = 0x47.11p9;
+ assert (bar == 36386.0);
+ }
+ {
+ double foo = 0x0.8P1;
+ assert (foo == 1.0);
+ }
+ {
+ double foo = 0xab.cdp20;
+ assert (foo == 180146176.0);
+ }
+}
diff --git a/tests/scanner/floats-hexadecimal-invalid1.test b/tests/scanner/floats-hexadecimal-invalid1.test
new file mode 100644
index 000000000..2cb72b126
--- /dev/null
+++ b/tests/scanner/floats-hexadecimal-invalid1.test
@@ -0,0 +1,5 @@
+Invalid Code
+
+void main () {
+ double foo = 0xf.f;
+}
diff --git a/tests/scanner/floats-hexadecimal-invalid2.test b/tests/scanner/floats-hexadecimal-invalid2.test
new file mode 100644
index 000000000..96302020f
--- /dev/null
+++ b/tests/scanner/floats-hexadecimal-invalid2.test
@@ -0,0 +1,5 @@
+Invalid Code
+
+void main () {
+ double foo = 0xf.123d;
+}
diff --git a/tests/semantic/realliteral-exponent-has-no-digits4.test b/tests/semantic/realliteral-exponent-has-no-digits4.test
new file mode 100644
index 000000000..47590e231
--- /dev/null
+++ b/tests/semantic/realliteral-exponent-has-no-digits4.test
@@ -0,0 +1,5 @@
+Invalid Code
+
+void main () {
+ double foo = 0xf.fp;
+}
diff --git a/tests/semantic/realliteral-exponent-has-no-digits5.test b/tests/semantic/realliteral-exponent-has-no-digits5.test
new file mode 100644
index 000000000..66cc22a8f
--- /dev/null
+++ b/tests/semantic/realliteral-exponent-has-no-digits5.test
@@ -0,0 +1,5 @@
+Invalid Code
+
+void main () {
+ float foo = 0xf.fpf;
+}
diff --git a/vala/valarealliteral.vala b/vala/valarealliteral.vala
index 86e7cf5c1..07d28dbe8 100644
--- a/vala/valarealliteral.vala
+++ b/vala/valarealliteral.vala
@@ -65,15 +65,34 @@ public class Vala.RealLiteral : Literal {
checked = true;
string type_name;
- if (value.has_suffix ("f") || value.has_suffix ("F")) {
- type_name ="float";
- } else {
+ int suf_len = 0;
+
+ switch (value[value.length - 1]) {
+ case 'f':
+ case 'F':
+ suf_len = 1;
+ type_name = "float";
+ break;
+ case 'd':
+ case 'D':
+ suf_len = 1;
type_name = "double";
+ break;
+ default:
+ type_name = "double";
+ break;
}
- if (value.has_suffix ("e") || value.has_suffix ("E") || value.has_suffix ("+") || value.has_suffix ("-")) {
+ switch (value[value.length - suf_len - 1]) {
+ case 'e':
+ case 'E':
+ case 'p':
+ case 'P':
+ case '+':
+ case '-':
Report.error (source_reference, "exponent has no digits");
error = true;
+ break;
}
var st = (Struct) context.root.scope.lookup (type_name);
diff --git a/vala/valascanner.vala b/vala/valascanner.vala
index f6f4cd7bf..a198ed72a 100644
--- a/vala/valascanner.vala
+++ b/vala/valascanner.vala
@@ -611,11 +611,33 @@ public class Vala.Scanner {
switch (current[1]) {
case 'x':
case 'X':
- // hexadecimal integer literal
+ // hexadecimal literal
current += 2;
while (current < end && current[0].isxdigit ()) {
current++;
}
+ // fractional part
+ // hexadecimal fractional part
+ if (current < end - 1 && current[0] == '.' && current[1].isxdigit ()) {
+ type = TokenType.REAL_LITERAL;
+ current++;
+ while (current < end && current[0].isxdigit ()) {
+ current++;
+ }
+ }
+ // hexadecimal exponent part
+ if (current < end && current[0].tolower () == 'p') {
+ type = TokenType.REAL_LITERAL;
+ current++;
+ if (current < end && (current[0] == '+' || current[0] == '-')) {
+ current++;
+ }
+ while (current < end && current[0].isdigit ()) {
+ current++;
+ }
+ } else if (type == TokenType.REAL_LITERAL) {
+ Report.error (get_source_reference (1), "hexadecimal floating constants require an exponent");
+ }
break;
case 'b':
case 'B':