From: Lucas Bajolet Date: Mon, 30 Nov 2015 17:18:48 +0000 (-0500) Subject: compiler: Added prefix and suffix support for `Char` X-Git-Url: http://nitlanguage.org compiler: Added prefix and suffix support for `Char` Signed-off-by: Lucas Bajolet --- diff --git a/src/compiler/abstract_compiler.nit b/src/compiler/abstract_compiler.nit index 1fad40d..17e44c7 100644 --- a/src/compiler/abstract_compiler.nit +++ b/src/compiler/abstract_compiler.nit @@ -3549,7 +3549,11 @@ redef class AFloatExpr end redef class ACharExpr - redef fun expr(v) do return v.char_instance(self.value.as(not null)) + redef fun expr(v) do + if is_ascii then return v.byte_instance(value.as(not null).ascii) + if is_code_point then return v.int_instance(value.as(not null).code_point) + return v.char_instance(self.value.as(not null)) + end end redef class AArrayExpr diff --git a/src/literal.nit b/src/literal.nit index b183301..72df12b 100644 --- a/src/literal.nit +++ b/src/literal.nit @@ -95,17 +95,66 @@ redef class AFloatExpr end end +# Any kind of literal which supports a prefix or a suffix +class AAugmentedLiteral + # Returns the text of the token + private fun text: String is abstract + + # Is the combination of prefixes and suffixes in `self` valid ? + fun is_valid_augmentation: Bool is abstract + + private fun delimiter_start: Char is abstract + + private fun delimiter_end: Char is abstract + + # Prefix for the entity, "" if no prefix is found + protected var prefix: String is lazy do return text.substring(0, text.index_of(delimiter_start)) + + # Suffix for the entity, "" if no prefix is found + protected var suffix: String is lazy do return text.substring_from(text.last_index_of(delimiter_end) + 1) + + # Content of the entity, without prefix nor suffix + protected var content: String is lazy do return text.substring_from(text.index_of(delimiter_start)).substring(0, text.last_index_of(delimiter_end) + 1) +end + redef class ACharExpr + super AAugmentedLiteral # The value of the literal char once computed. - var value: nullable Char + var value: nullable Char = null + + redef fun delimiter_start do return '\'' + + redef fun delimiter_end do return '\'' + + # Is the expression returning an ASCII byte value ? + fun is_ascii: Bool do return prefix == "b" + + # Is the expression returning a Code Point ? + fun is_code_point: Bool do return prefix == "u" + + redef fun text do return n_char.text + + redef fun is_valid_augmentation do + if suffix != "" then return false + if is_ascii then return true + if is_code_point then return true + if prefix != "" then return false + return true + end + redef fun accept_literal(v) do - var txt = self.n_char.text.unescape_nit + if not is_valid_augmentation then + v.toolcontext.error(hot_location, "Syntax Error: invalid prefix/suffix combination {prefix}/{suffix}") + return + end + var txt = content.unescape_nit if txt.length != 3 then v.toolcontext.error(self.hot_location, "Syntax Error: invalid character literal `{txt}`.") return end self.value = txt.chars[1] + if is_ascii and txt.chars[1].code_point > 127 then v.toolcontext.error(self.hot_location, "Syntax Error: usage of byte prefix on multibyte character.") end end diff --git a/src/modelize/modelize_property.nit b/src/modelize/modelize_property.nit index 6588268..1a95c3e 100644 --- a/src/modelize/modelize_property.nit +++ b/src/modelize/modelize_property.nit @@ -1390,7 +1390,14 @@ redef class AAttrPropdef var cla = modelbuilder.try_get_mclass_by_name(nexpr, mmodule, "Float") if cla != null then mtype = cla.mclass_type else if nexpr isa ACharExpr then - var cla = modelbuilder.try_get_mclass_by_name(nexpr, mmodule, "Char") + var cla: nullable MClass + if nexpr.is_ascii then + cla = modelbuilder.try_get_mclass_by_name(nexpr, mmodule, "Byte") + else if nexpr.is_code_point then + cla = modelbuilder.try_get_mclass_by_name(nexpr, mmodule, "Int") + else + cla = modelbuilder.try_get_mclass_by_name(nexpr, mmodule, "Char") + end if cla != null then mtype = cla.mclass_type else if nexpr isa ABoolExpr then var cla = modelbuilder.try_get_mclass_by_name(nexpr, mmodule, "Bool") diff --git a/src/semantize/typing.nit b/src/semantize/typing.nit index ddc87e2..08f3d65 100644 --- a/src/semantize/typing.nit +++ b/src/semantize/typing.nit @@ -1455,9 +1455,15 @@ redef class AFloatExpr end redef class ACharExpr - redef fun accept_typing(v) - do - var mclass = v.get_mclass(self, "Char") + redef fun accept_typing(v) do + var mclass: nullable MClass = null + if is_ascii then + mclass = v.get_mclass(self, "Byte") + else if is_code_point then + mclass = v.get_mclass(self, "Int") + else + mclass = v.get_mclass(self, "Char") + end if mclass == null then return # Forward error self.mtype = mclass.mclass_type end