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
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")
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