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