From: Jean Privat Date: Tue, 22 Sep 2015 19:41:29 +0000 (-0400) Subject: Merge: Migration from ascii to code_point X-Git-Tag: v0.7.8~12 X-Git-Url: http://nitlanguage.org?hp=eb7513037aa3d3263a23f64d26f8ae6a6cf937f8 Merge: Migration from ascii to code_point As complement to #1262 and #1718, this PR solves part of both issues. One does the migration from `ascii` to `code_point` since Unicode is a bit more than ASCII, let's try to use the right vocabulary when dealing with it. The `ascii` service is however kept alive, but its contract is changed from Int to Byte to be used directly on a `Char` without the need to have the old `'c'.ascii.to_b`, now a simple `'c'.ascii` will do the exact same. A further PR will be submitted later to prevent the use of `ascii` on non-ASCII literal characters. Pull-Request: #1726 Reviewed-by: Alexis Laferrière Reviewed-by: Jean Privat --- diff --git a/src/compiler/separate_compiler.nit b/src/compiler/separate_compiler.nit index ff5f3ba..00f3f00 100644 --- a/src/compiler/separate_compiler.nit +++ b/src/compiler/separate_compiler.nit @@ -998,10 +998,13 @@ class SeparateCompiler # use some Huffman coding. if t.name == "Int" then class_info[1] = t + t.mclass_type.tag_value = 1 else if t.name == "Char" then class_info[2] = t + t.mclass_type.tag_value = 2 else if t.name == "Bool" then class_info[3] = t + t.mclass_type.tag_value = 3 else continue end @@ -1858,7 +1861,7 @@ class SeparateCompilerVisitor else var mtype1 = value1.mtype.as(MClassType) self.require_declaration("class_{mtype1.c_name}") - self.add("{res} = ({value2} != NULL) && ({value2}->class == &class_{mtype1.c_name}); /* is_same_type_test */") + self.add("{res} = ({value2} != NULL) && ({class_info(value2)} == &class_{mtype1.c_name}); /* is_same_type_test */") end else self.add("{res} = ({value1} == {value2}) || ({value1} != NULL && {value2} != NULL && {class_info(value1)} == {class_info(value2)}); /* is_same_type_test */") @@ -1891,20 +1894,58 @@ class SeparateCompilerVisitor value2 = tmp end if value1.mtype.is_c_primitive then - if value2.mtype == value1.mtype then + var t1 = value1.mtype + assert t1 == value1.mcasttype + + # Fast case: same C type. + if value2.mtype == t1 then + # Same exact C primitive representation. self.add("{res} = {value1} == {value2};") - else if value2.mtype.is_c_primitive then - self.add("{res} = 0; /* incompatible types {value1.mtype} vs. {value2.mtype}*/") - else if value1.mtype.is_tagged then - self.add("{res} = ({value2} != NULL) && ({self.autobox(value2, value1.mtype)} == {value1});") + return res + end + + # Complex case: value2 has a different representation + # Thus, it should be checked if `value2` is type-compatible with `value1` + # This compatibility is done statically if possible and dynamically else + + # Conjunction (ands) of dynamic tests according to the static knowledge + var tests = new Array[String] + + var t2 = value2.mcasttype + if t2 isa MNullableType then + # The destination type cannot be null + tests.add("({value2} != NULL)") + t2 = t2.mtype + else if t2 isa MNullType then + # `value2` is known to be null, thus incompatible with a primitive + self.add("{res} = 0; /* incompatible types {t1} vs. {t2}*/") + return res + end + + if t2 == t1 then + # Same type but different representation. + else if t2.is_c_primitive then + # Type of `value2` is a different primitive type, thus incompatible + self.add("{res} = 0; /* incompatible types {t1} vs. {t2}*/") + return res + else if t1.is_tagged then + # To be equal, `value2` should also be correctly tagged + tests.add("({extract_tag(value2)} == {t1.tag_value})") else - var mtype1 = value1.mtype.as(MClassType) - self.require_declaration("class_{mtype1.c_name}") - self.add("{res} = ({value2} != NULL) && ({value2}->class == &class_{mtype1.c_name});") - self.add("if ({res}) \{") - self.add("{res} = ({self.autobox(value2, value1.mtype)} == {value1});") - self.add("\}") + # To be equal, `value2` should also be boxed with the same class + self.require_declaration("class_{t1.c_name}") + tests.add "({class_info(value2)} == &class_{t1.c_name})" end + + # Compare the unboxed `value2` with `value1` + if tests.not_empty then + self.add "if ({tests.join(" && ")}) \{" + end + self.add "{res} = {self.autobox(value2, t1)} == {value1};" + if tests.not_empty then + self.add "\} else {res} = 0;" + end + return res end var maybe_null = true @@ -2327,6 +2368,12 @@ redef class MType # Are values of `self` tagged? # If false, it means that the type is not primitive, or is boxed. var is_tagged = false + + # The tag value of the type + # + # ENSURE `is_tagged == (tag_value > 0)` + # ENSURE `not is_tagged == (tag_value == 0)` + var tag_value = 0 end redef class MEntity diff --git a/tests/base_eq_int4.nit b/tests/base_eq_int4.nit new file mode 100644 index 0000000..60144b2 --- /dev/null +++ b/tests/base_eq_int4.nit @@ -0,0 +1,196 @@ +# This file is part of NIT ( http://www.nitlanguage.org ). +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import kernel + +var i = 1 +var b = true +var f = 1u8 +var ni: nullable Int = 1 +var nb: nullable Bool = true +var nf: nullable Byte = 1u8 +var oi: nullable Object = 1 +var ob: nullable Object = true +var of: nullable Object = 1u8 + + +(i == i).output +(b == i).output +(f == i).output + +'\n'.output + +(i == ni).output +(b == ni).output +(f == ni).output + +'\n'.output + +(i == oi).output +(b == oi).output +(f == oi).output + +'\n'.output +'\n'.output + +(ni == i).output +(nb == i).output +(nf == i).output + +'\n'.output + +(ni == ni).output +(nb == ni).output +(nf == ni).output + +'\n'.output + +(ni == oi).output +(nb == oi).output +(nf == oi).output + +'\n'.output +'\n'.output + +(oi == i).output +(ob == i).output +(of == i).output + +'\n'.output + +(oi == ni).output +(ob == ni).output +(of == ni).output + +'\n'.output + +(oi == oi).output +(ob == oi).output +(of == oi).output + +'\n'.output +'\n'.output +'\n'.output + +(i == b).output +(b == b).output +(f == b).output + +'\n'.output + +(i == nb).output +(b == nb).output +(f == nb).output + +'\n'.output + +(i == ob).output +(b == ob).output +(f == ob).output + +'\n'.output +'\n'.output + +(ni == b).output +(nb == b).output +(nf == b).output + +'\n'.output + +(ni == nb).output +(nb == nb).output +(nf == nb).output + +'\n'.output + +(ni == ob).output +(nb == ob).output +(nf == ob).output + +'\n'.output +'\n'.output + +(oi == b).output +(ob == b).output +(of == b).output + +'\n'.output + +(oi == nb).output +(ob == nb).output +(of == nb).output + +'\n'.output + +(oi == ob).output +(ob == ob).output +(of == ob).output + +'\n'.output +'\n'.output +'\n'.output + +(i == f).output +(b == f).output +(f == f).output + +'\n'.output + +(i == nf).output +(b == nf).output +(f == nf).output + +'\n'.output + +(i == of).output +(b == of).output +(f == of).output + +'\n'.output +'\n'.output + +(ni == f).output +(nb == f).output +(nf == f).output + +'\n'.output + +(ni == nf).output +(nb == nf).output +(nf == nf).output + +'\n'.output + +(ni == of).output +(nb == of).output +(nf == of).output + +'\n'.output +'\n'.output + +(oi == f).output +(ob == f).output +(of == f).output + +'\n'.output + +(oi == nf).output +(ob == nf).output +(of == nf).output + +'\n'.output + +(oi == of).output +(ob == of).output +(of == of).output diff --git a/tests/base_eq_int4b.nit b/tests/base_eq_int4b.nit new file mode 100644 index 0000000..fea2020 --- /dev/null +++ b/tests/base_eq_int4b.nit @@ -0,0 +1,196 @@ +# This file is part of NIT ( http://www.nitlanguage.org ). +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import kernel + +var i = 1 +var b = true +var f = 1u8 +var ni: nullable Int = 1 +var nb: nullable Bool = true +var nf: nullable Byte = 1u8 +var oi: nullable Object = 1 +var ob: nullable Object = true +var of: nullable Object = 1u8 + + +(i.is_same_instance(i)).output +(b.is_same_instance(i)).output +(f.is_same_instance(i)).output + +'\n'.output + +(i.is_same_instance(ni)).output +(b.is_same_instance(ni)).output +(f.is_same_instance(ni)).output + +'\n'.output + +(i.is_same_instance(oi)).output +(b.is_same_instance(oi)).output +(f.is_same_instance(oi)).output + +'\n'.output +'\n'.output + +(ni.is_same_instance(i)).output +(nb.is_same_instance(i)).output +(nf.is_same_instance(i)).output + +'\n'.output + +(ni.is_same_instance(ni)).output +(nb.is_same_instance(ni)).output +(nf.is_same_instance(ni)).output + +'\n'.output + +(ni.is_same_instance(oi)).output +(nb.is_same_instance(oi)).output +(nf.is_same_instance(oi)).output + +'\n'.output +'\n'.output + +(oi.is_same_instance(i)).output +(ob.is_same_instance(i)).output +(of.is_same_instance(i)).output + +'\n'.output + +(oi.is_same_instance(ni)).output +(ob.is_same_instance(ni)).output +(of.is_same_instance(ni)).output + +'\n'.output + +(oi.is_same_instance(oi)).output +(ob.is_same_instance(oi)).output +(of.is_same_instance(oi)).output + +'\n'.output +'\n'.output +'\n'.output + +(i.is_same_instance(b)).output +(b.is_same_instance(b)).output +(f.is_same_instance(b)).output + +'\n'.output + +(i.is_same_instance(nb)).output +(b.is_same_instance(nb)).output +(f.is_same_instance(nb)).output + +'\n'.output + +(i.is_same_instance(ob)).output +(b.is_same_instance(ob)).output +(f.is_same_instance(ob)).output + +'\n'.output +'\n'.output + +(ni.is_same_instance(b)).output +(nb.is_same_instance(b)).output +(nf.is_same_instance(b)).output + +'\n'.output + +(ni.is_same_instance(nb)).output +(nb.is_same_instance(nb)).output +(nf.is_same_instance(nb)).output + +'\n'.output + +(ni.is_same_instance(ob)).output +(nb.is_same_instance(ob)).output +(nf.is_same_instance(ob)).output + +'\n'.output +'\n'.output + +(oi.is_same_instance(b)).output +(ob.is_same_instance(b)).output +(of.is_same_instance(b)).output + +'\n'.output + +(oi.is_same_instance(nb)).output +(ob.is_same_instance(nb)).output +(of.is_same_instance(nb)).output + +'\n'.output + +(oi.is_same_instance(ob)).output +(ob.is_same_instance(ob)).output +(of.is_same_instance(ob)).output + +'\n'.output +'\n'.output +'\n'.output + +(i.is_same_instance(f)).output +(b.is_same_instance(f)).output +(f.is_same_instance(f)).output + +'\n'.output + +(i.is_same_instance(nf)).output +(b.is_same_instance(nf)).output +(f.is_same_instance(nf)).output + +'\n'.output + +(i.is_same_instance(of)).output +(b.is_same_instance(of)).output +(f.is_same_instance(of)).output + +'\n'.output +'\n'.output + +(ni.is_same_instance(f)).output +(nb.is_same_instance(f)).output +(nf.is_same_instance(f)).output + +'\n'.output + +(ni.is_same_instance(nf)).output +(nb.is_same_instance(nf)).output +(nf.is_same_instance(nf)).output + +'\n'.output + +(ni.is_same_instance(of)).output +(nb.is_same_instance(of)).output +(nf.is_same_instance(of)).output + +'\n'.output +'\n'.output + +(oi.is_same_instance(f)).output +(ob.is_same_instance(f)).output +(of.is_same_instance(f)).output + +'\n'.output + +(oi.is_same_instance(nf)).output +(ob.is_same_instance(nf)).output +(of.is_same_instance(nf)).output + +'\n'.output + +(oi.is_same_instance(of)).output +(ob.is_same_instance(of)).output +(of.is_same_instance(of)).output diff --git a/tests/base_eq_int4c.nit b/tests/base_eq_int4c.nit new file mode 100644 index 0000000..89e2882 --- /dev/null +++ b/tests/base_eq_int4c.nit @@ -0,0 +1,196 @@ +# This file is part of NIT ( http://www.nitlanguage.org ). +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import kernel + +var i = 1 +var b = true +var f = 1u8 +var ni: Int = 0 +var nb: Bool = false +var nf: Byte = 0u8 +var oi: Object = 1 +var ob: Object = true +var of: Object = 1u8 + + +(i.is_same_type(i)).output +(b.is_same_type(i)).output +(f.is_same_type(i)).output + +'\n'.output + +(i.is_same_type(ni)).output +(b.is_same_type(ni)).output +(f.is_same_type(ni)).output + +'\n'.output + +(i.is_same_type(oi)).output +(b.is_same_type(oi)).output +(f.is_same_type(oi)).output + +'\n'.output +'\n'.output + +(ni.is_same_type(i)).output +(nb.is_same_type(i)).output +(nf.is_same_type(i)).output + +'\n'.output + +(ni.is_same_type(ni)).output +(nb.is_same_type(ni)).output +(nf.is_same_type(ni)).output + +'\n'.output + +(ni.is_same_type(oi)).output +(nb.is_same_type(oi)).output +(nf.is_same_type(oi)).output + +'\n'.output +'\n'.output + +(oi.is_same_type(i)).output +(ob.is_same_type(i)).output +(of.is_same_type(i)).output + +'\n'.output + +(oi.is_same_type(ni)).output +(ob.is_same_type(ni)).output +(of.is_same_type(ni)).output + +'\n'.output + +(oi.is_same_type(oi)).output +(ob.is_same_type(oi)).output +(of.is_same_type(oi)).output + +'\n'.output +'\n'.output +'\n'.output + +(i.is_same_type(b)).output +(b.is_same_type(b)).output +(f.is_same_type(b)).output + +'\n'.output + +(i.is_same_type(nb)).output +(b.is_same_type(nb)).output +(f.is_same_type(nb)).output + +'\n'.output + +(i.is_same_type(ob)).output +(b.is_same_type(ob)).output +(f.is_same_type(ob)).output + +'\n'.output +'\n'.output + +(ni.is_same_type(b)).output +(nb.is_same_type(b)).output +(nf.is_same_type(b)).output + +'\n'.output + +(ni.is_same_type(nb)).output +(nb.is_same_type(nb)).output +(nf.is_same_type(nb)).output + +'\n'.output + +(ni.is_same_type(ob)).output +(nb.is_same_type(ob)).output +(nf.is_same_type(ob)).output + +'\n'.output +'\n'.output + +(oi.is_same_type(b)).output +(ob.is_same_type(b)).output +(of.is_same_type(b)).output + +'\n'.output + +(oi.is_same_type(nb)).output +(ob.is_same_type(nb)).output +(of.is_same_type(nb)).output + +'\n'.output + +(oi.is_same_type(ob)).output +(ob.is_same_type(ob)).output +(of.is_same_type(ob)).output + +'\n'.output +'\n'.output +'\n'.output + +(i.is_same_type(f)).output +(b.is_same_type(f)).output +(f.is_same_type(f)).output + +'\n'.output + +(i.is_same_type(nf)).output +(b.is_same_type(nf)).output +(f.is_same_type(nf)).output + +'\n'.output + +(i.is_same_type(of)).output +(b.is_same_type(of)).output +(f.is_same_type(of)).output + +'\n'.output +'\n'.output + +(ni.is_same_type(f)).output +(nb.is_same_type(f)).output +(nf.is_same_type(f)).output + +'\n'.output + +(ni.is_same_type(nf)).output +(nb.is_same_type(nf)).output +(nf.is_same_type(nf)).output + +'\n'.output + +(ni.is_same_type(of)).output +(nb.is_same_type(of)).output +(nf.is_same_type(of)).output + +'\n'.output +'\n'.output + +(oi.is_same_type(f)).output +(ob.is_same_type(f)).output +(of.is_same_type(f)).output + +'\n'.output + +(oi.is_same_type(nf)).output +(ob.is_same_type(nf)).output +(of.is_same_type(nf)).output + +'\n'.output + +(oi.is_same_type(of)).output +(ob.is_same_type(of)).output +(of.is_same_type(of)).output diff --git a/tests/sav/base_eq_int4.res b/tests/sav/base_eq_int4.res new file mode 100644 index 0000000..cf1d59c --- /dev/null +++ b/tests/sav/base_eq_int4.res @@ -0,0 +1,117 @@ +true +false +false + +true +false +false + +true +false +false + + +true +false +false + +true +false +false + +true +false +false + + +true +false +false + +true +false +false + +true +false +false + + + +false +true +false + +false +true +false + +false +true +false + + +false +true +false + +false +true +false + +false +true +false + + +false +true +false + +false +true +false + +false +true +false + + + +false +false +true + +false +false +true + +false +false +true + + +false +false +true + +false +false +true + +false +false +true + + +false +false +true + +false +false +true + +false +false +true diff --git a/tests/sav/base_eq_int4b.res b/tests/sav/base_eq_int4b.res new file mode 100644 index 0000000..cf1d59c --- /dev/null +++ b/tests/sav/base_eq_int4b.res @@ -0,0 +1,117 @@ +true +false +false + +true +false +false + +true +false +false + + +true +false +false + +true +false +false + +true +false +false + + +true +false +false + +true +false +false + +true +false +false + + + +false +true +false + +false +true +false + +false +true +false + + +false +true +false + +false +true +false + +false +true +false + + +false +true +false + +false +true +false + +false +true +false + + + +false +false +true + +false +false +true + +false +false +true + + +false +false +true + +false +false +true + +false +false +true + + +false +false +true + +false +false +true + +false +false +true diff --git a/tests/sav/base_eq_int4c.res b/tests/sav/base_eq_int4c.res new file mode 100644 index 0000000..cf1d59c --- /dev/null +++ b/tests/sav/base_eq_int4c.res @@ -0,0 +1,117 @@ +true +false +false + +true +false +false + +true +false +false + + +true +false +false + +true +false +false + +true +false +false + + +true +false +false + +true +false +false + +true +false +false + + + +false +true +false + +false +true +false + +false +true +false + + +false +true +false + +false +true +false + +false +true +false + + +false +true +false + +false +true +false + +false +true +false + + + +false +false +true + +false +false +true + +false +false +true + + +false +false +true + +false +false +true + +false +false +true + + +false +false +true + +false +false +true + +false +false +true