ni_nitdoc: added fast copy past utility to signatures.
[nit.git] / src / literal.nit
1 # This file is part of NIT ( http://www.nitlanguage.org ).
2 #
3 # Copyright 2012 Jean Privat <jean@pryen.org>
4 #
5 # Licensed under the Apache License, Version 2.0 (the "License");
6 # you may not use this file except in compliance with the License.
7 # You may obtain a copy of the License at
8 #
9 # http://www.apache.org/licenses/LICENSE-2.0
10 #
11 # Unless required by applicable law or agreed to in writing, software
12 # distributed under the License is distributed on an "AS IS" BASIS,
13 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 # See the License for the specific language governing permissions and
15 # limitations under the License.
16
17 # Parsing of literal values in the abstract syntax tree.
18 module literal
19
20 import parser
21 import toolcontext
22 import phase
23
24 import modelbuilder #FIXME useless
25
26 redef class ToolContext
27 var literal_phase: Phase = new LiteralPhase(self, null)
28 end
29
30 private class LiteralPhase
31 super Phase
32
33 redef fun process_nmodule(nmodule) do nmodule.do_literal(toolcontext)
34 end
35
36 redef class AModule
37 # Visit the module to compute the real value of the literal-related node of the AST.
38 # Warnings and errors are displayed on the toolcontext.
39 fun do_literal(toolcontext: ToolContext)
40 do
41 var v = new LiteralVisitor(toolcontext)
42 v.enter_visit(self)
43 end
44 end
45
46 private class LiteralVisitor
47 super Visitor
48
49 var toolcontext: ToolContext
50
51 init(toolcontext: ToolContext)
52 do
53 self.toolcontext = toolcontext
54 end
55
56 redef fun visit(n)
57 do
58 if n != null then
59 n.accept_literal(self)
60 n.visit_all(self)
61 end
62 end
63 end
64
65 redef class ANode
66 private fun accept_literal(v: LiteralVisitor) do end
67 end
68
69 redef class AIntExpr
70 # The value of the literal int once computed.
71 var value: nullable Int
72 redef fun accept_literal(v)
73 do
74 self.value = self.n_number.text.to_i
75 end
76 end
77
78 redef class AFloatExpr
79 # The value of the literal float once computed.
80 var value: nullable Float
81 redef fun accept_literal(v)
82 do
83 self.value = self.n_float.text.to_f
84 end
85 end
86
87 redef class ACharExpr
88 # The value of the literal char once computed.
89 var value: nullable Char
90 redef fun accept_literal(v)
91 do
92 var txt = self.n_char.text.unescape_nit
93 if txt.length != 3 then
94 v.toolcontext.error(self.hot_location, "Invalid character literal {txt}")
95 return
96 end
97 self.value = txt[1]
98 end
99 end
100
101 redef class AStringFormExpr
102 # The value of the literal string once computed.
103 var value: nullable String
104 redef fun accept_literal(v)
105 do
106 var txt = self.n_string.text
107 var skip = 1
108 if txt[0] == txt[1] and txt.length >= 6 then skip = 3
109 self.value = txt.substring(skip, txt.length-(2*skip)).unescape_nit
110 end
111 end
112
113 redef class String
114 # Return a string where Nit escape sequences are transformed.
115 #
116 # Example:
117 # var s = "\\n"
118 # print s.length # -> 2
119 # var u = s.unescape_nit
120 # print s.length # -> 1
121 # print s[0].ascii # -> 10 (the ASCII value of the "new line" character)
122 fun unescape_nit: String
123 do
124 var res = new Buffer.with_capacity(self.length)
125 var was_slash = false
126 for c in self do
127 if not was_slash then
128 if c == '\\' then
129 was_slash = true
130 else
131 res.add(c)
132 end
133 continue
134 end
135 was_slash = false
136 if c == 'n' then
137 res.add('\n')
138 else if c == 'r' then
139 res.add('\r')
140 else if c == 't' then
141 res.add('\t')
142 else if c == '0' then
143 res.add('\0')
144 else
145 res.add(c)
146 end
147 end
148 return res.to_s
149 end
150 end