nitc :: AugmentedStringFormExpr
Any kind of string form with augmentations from prefixes or suffixesnitc :: LiteralPhase
nitc :: literal $ AStartStringExpr
The start of a superstring. eg"abc{
			nitc :: literal $ ASuperstringExpr
A superstring literal. eg"a{x}b{y}c"
			nitc :: literal $ AStartStringExpr
The start of a superstring. eg"abc{
			nitc :: literal $ ASuperstringExpr
A superstring literal. eg"a{x}b{y}c"
			nitc $ AugmentedStringFormExpr
Any kind of string form with augmentations from prefixes or suffixesSerializable::inspect to show more useful information
			more_collections :: more_collections
Highly specific, but useful, collections-related classes.serialization :: serialization_core
Abstract services to serialize Nit objects to different formatsnitc :: toolcontext
Common command-line tool infrastructure than handle options and error messagescore :: union_find
union–find algorithm using an efficient disjoint-set data structurenitc :: actors_generation_phase
Generate a support module for each module that contain a class annotated withis actor
			nitc :: actors_injection_phase
Injects model for the classes annotated with "is actor" sonitc :: api_metrics
nitc :: astbuilder
Instantiation and transformation of semantic nodes in the AST of expressions and statementscflags and ldflags to specify
			nitc :: commands_ini
extra_java_files to compile extra java files
			nitc :: i18n_phase
Basic support of internationalization through the generation of id-to-string tablesnitc :: light_only
Compiler support for the light FFI only, detects unsupported usage of callbacksnitc.
			nitc :: nitmetrics
A program that collects various metrics on nit programs and librariesnitc :: nitrestful
Tool generating boilerplate code linking RESTful actions to Nit methodsthreaded annotation
			nitc :: separate_erasure_compiler
Separate compilation of a Nit program with generic type erasurenitc :: serialization_code_gen_phase
Phase generating methods (code) to serialize Nit objectsnitc :: serialization_model_phase
Phase generating methods (model-only) to serialize Nit objectsclone method of the astbuilder tool
			nitc :: uml_module
Services for generation of a UML package diagram based on aModel
			
# Parsing of literal values in the abstract syntax tree.
module literal
import phase
redef class ToolContext
	# Parses literal values in the whole AST and produces errors if needed
	var literal_phase: Phase = new LiteralPhase(self, null)
end
private class LiteralPhase
	super Phase
	redef fun process_nmodule(nmodule) do nmodule.do_literal(toolcontext)
end
redef class AModule
	# Visit the module to compute the real value of the literal-related node of the AST.
	# Warnings and errors are displayed on the toolcontext.
	fun do_literal(toolcontext: ToolContext)
	do
		var v = new LiteralVisitor(toolcontext)
		v.enter_visit(self)
	end
end
private class LiteralVisitor
	super Visitor
	var toolcontext: ToolContext
	redef fun visit(n)
	do
		n.accept_literal(self)
		n.visit_all(self)
	end
end
redef class ANode
	private fun accept_literal(v: LiteralVisitor) do end
end
redef class AExpr
	# Get `self` as a `String`.
	# Return null if not a string.
	fun as_string: nullable String
	do
		if not self isa AStringFormExpr then return null
		return self.value
	end
	# Get `self` as an `Int`.
	# Return null if not an integer.
	fun as_int: nullable Int
	do
		if not self isa AIntegerExpr then return null
		return self.value.as(not null).to_i
	end
end
redef class AIntegerExpr
	# The value of the literal int once computed.
	var value: nullable Numeric
	redef fun accept_literal(v) do
		value = n_integer.text.to_num
		if value == null then
			v.toolcontext.error(hot_location, "Error: invalid literal `{n_integer.text}`")
		end
	end
end
redef class AFloatExpr
	# The value of the literal float once computed.
	var value: nullable Float
	redef fun accept_literal(v)
	do
		self.value = self.n_float.text.to_f
	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
		var npr = text.substring_from(prefix.length)
		return npr.substring(0, npr.length - suffix.length)
	end
end
redef class ACharExpr
	super AAugmentedLiteral
	# The value of the literal char once computed.
	var value: nullable Char = null
	redef fun delimiter_start do return '\''
	redef fun delimiter_end do return '\''
	# 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_code_point then return true
		if prefix != "" then return false
		return true
	end
	redef fun accept_literal(v)
	do
		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]
	end
end
# Any kind of string form with augmentations from prefixes or suffixes
class AugmentedStringFormExpr
	super AAugmentedLiteral
	redef var delimiter_start = '"'
	redef var delimiter_end = '"'
	# Is `self` a regular String object ?
	fun is_string: Bool do return prefix == "" or prefix == "raw"
	# Is `self` a Regular Expression ?
	fun is_re: Bool do return prefix == "re"
	# Is `self` a Byte String ?
	fun is_bytestring: Bool do return prefix == "b"
	redef fun is_valid_augmentation do
		if is_string and suffix == "" then return true
		if is_bytestring and suffix == "" then return true
		if is_re then
			var suf = suffix
			for i in suf.chars do
				if i == 'i' then continue
				if i == 'm' then continue
				if i == 'b' then continue
				return false
			end
			return true
		end
		if prefix != "" or suffix != "" then return false
		return true
	end
end
redef class AStringFormExpr
	super AugmentedStringFormExpr
	# The value of the literal string once computed.
	var value: String is noinit
	# The underlying bytes of the String, non-cleaned for UTF-8
	var bytes: Bytes is noinit
	redef fun text do return n_string.text
	# Returns the raw text read by the lexer
	var raw_text: String is lazy do
		var txt = content
		var behead = 1
		var betail = 1
		if txt.chars[0] == txt.chars[1] and txt.length >= 6 then
			behead = 3
			betail = 3
			if txt.chars[0] == delimiter_start and txt.chars[3] == '\n' then behead = 4 # ignore first \n in """
		end
		return txt.substring(behead, txt.length - behead - betail)
	end
	redef fun accept_literal(v) do
		value = raw_text
		bytes = raw_text.to_bytes
	end
end
redef class AEndStringExpr
	redef var delimiter_end is lazy do return '"'
	redef fun prefix do return ""
end
redef class AStartStringExpr
	redef var delimiter_start is lazy do
		var str = n_string.text
		for i in [0 .. str.length[ do
			var c = str[i]
			if c == '"' or c == '\'' then
				return c
			end
		end
		# Cannot happen, unless the parser is bugged
		abort
	end
	redef fun suffix do return ""
end
redef class AMidStringExpr
	redef fun prefix do return ""
	redef fun suffix do return ""
end
redef class AStringExpr
	redef var delimiter_start is lazy do
		var str = text
		for i in [0 .. str.length[ do
			var c = str[i]
			if c == '"' or c == '\'' then
				delimiter_end = c
				return c
			end
		end
		# Cannot happen, unless the parser is bugged
		abort
	end
	redef var delimiter_end is lazy do return delimiter_start
	redef fun accept_literal(v)
	do
		super
		if not is_valid_augmentation then
			v.toolcontext.error(hot_location, "Error: invalid prefix/suffix combination {prefix}/{suffix}")
			return
		end
		if prefix != "raw" then
			bytes = raw_text.unescape_to_bytes
			value = bytes.to_s
		end
	end
end
redef class ASuperstringExpr
	super AugmentedStringFormExpr
	redef var prefix is lazy do
		var fst = n_exprs.first
		if fst isa AugmentedStringFormExpr then
			var prf = fst.prefix
			delimiter_start = fst.delimiter_start
			delimiter_end = delimiter_start
			return prf
		end
		return ""
	end
	redef var suffix is lazy do
		var lst = n_exprs.last
		# Forces the system to update the delimiter's value
		prefix
		if lst isa AugmentedStringFormExpr then
			lst.delimiter_end = delimiter_start
			return lst.suffix
		end
		return ""
	end
	redef fun accept_literal(v)
	do
		if is_bytestring then
			v.toolcontext.error(hot_location, "Error: cannot produce a ByteString on a Superstring")
			return
		end
		if not is_valid_augmentation then
			v.toolcontext.error(hot_location, "Error: invalid prefix/suffix combination {prefix}/{suffix}")
			return
		end
	end
	redef fun visit_all(v) do
		super
		if prefix != "raw" then
			for i in n_exprs do
				if not i isa AStringFormExpr then continue
				i.bytes = i.raw_text.unescape_to_bytes
				i.value = i.bytes.to_s
			end
		end
	end
end
src/literal.nit:17,1--326,3