misc/vim: inform the user when no results are found
[nit.git] / examples / draw_operation.nit
1 # This file is part of NIT ( http://www.nitlanguage.org ).
2 #
3 # Copyright 2012-2013 Alexis Laferrière <alexis.laf@xymus.net>
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 # Draws an arithmetic operation to the terminal
18 module draw_operation
19
20 redef enum Int
21 fun n_chars: Int `{
22 int c;
23 if ( abs(recv) >= 10 )
24 c = 1+(int)log10f( (float)abs(recv) );
25 else
26 c = 1;
27 if ( recv < 0 ) c ++;
28 return c;
29 `}
30 end
31
32 redef enum Char
33 fun as_operator(a, b: Int): Int
34 do
35 if self == '+' then return a + b
36 if self == '-' then return a - b
37 if self == '*' then return a * b
38 if self == '/' then return a / b
39 if self == '%' then return a % b
40 abort
41 end
42
43 fun override_dispc: Bool
44 do
45 return self == '+' or self == '-' or self == '*' or self == '/' or self == '%'
46 end
47
48 fun lines(s: Int): Array[Line]
49 do
50 if self == '+' then
51 return [new Line(new P(0,s/2),1,0,s), new Line(new P(s/2,1),0,1,s-2)]
52 else if self == '-' then
53 return [new Line(new P(0,s/2),1,0,s)]
54 else if self == '*' then
55 var lines = new Array[Line]
56 for y in [1..s-1[ do
57 lines.add( new Line(new P(1,y), 1,0,s-2) )
58 end
59 return lines
60 else if self == '/' then
61 return [new Line(new P(s-1,0), -1,1, s )]
62 else if self == '%' then
63 var q4 = s/4
64 var lines = [new Line(new P(s-1,0),-1,1,s)]
65 for l in [0..q4[ do
66 lines.append([ new Line( new P(0,l), 1,0,q4), new Line( new P(s-1,s-1-l), -1,0,q4) ])
67 end
68 return lines
69 else if self == '1' then
70 return [new Line(new P(s/2,0), 0,1,s),new Line(new P(0,s-1),1,0,s),
71 new Line( new P(s/2,0),-1,1,s/2)]
72 else if self == '2' then
73 return [new Line(new P(0,0), 1,0,s),new Line(new P(s-1,0),0,1,s/2),
74 new Line( new P(0,s-1),1,0,s), new Line( new P(0,s/2), 0,1,s/2),
75 new Line( new P(0,s/2), 1,0,s)]
76 else if self == '3' then
77 return [new Line(new P(0,0), 1,0,s),new Line(new P(s-1,0),0,1,s),
78 new Line( new P(0,s-1),1,0,s), new Line( new P(0,s/2), 1,0,s)]
79 else if self == '4' then
80 return [new Line(new P(s-1,0),0,1,s), new Line( new P(0,0), 0,1,s/2),
81 new Line( new P(0,s/2), 1,0,s)]
82 else if self == '5' then
83 return [new Line(new P(0,0), 1,0,s),new Line(new P(s-1,s/2),0,1,s/2),
84 new Line( new P(0,s-1),1,0,s), new Line( new P(0,0), 0,1,s/2),
85 new Line( new P(0,s/2), 1,0,s)]
86 else if self == '6' then
87 return [new Line(new P(0,0), 1,0,s),new Line(new P(s-1,s/2),0,1,s/2),
88 new Line( new P(0,s-1),1,0,s), new Line( new P(0,0), 0,1,s),
89 new Line( new P(0,s/2), 1,0,s)]
90 else if self == '7' then
91 var tl = new P(0,0)
92 var tr = new P(s-1,0)
93 return [new Line(tl, 1,0,s), new Line(tr,-1,1,s)]
94 else if self == '8' then
95 return [new Line(new P(0,0), 1,0,s),new Line(new P(s-1,0),0,1,s),
96 new Line( new P(0,s-1),1,0,s), new Line( new P(0,0), 0,1,s),
97 new Line( new P(0,s/2), 1,0,s)]
98 else if self == '9' then
99 return [new Line(new P(0,0), 1,0,s),new Line(new P(s-1,0),0,1,s),
100 new Line( new P(0,s-1),1,0,s), new Line( new P(0,0), 0,1,s/2),
101 new Line( new P(0,s/2), 1,0,s)]
102 else if self == '0' then
103 return [new Line(new P(0,0), 1,0,s),new Line(new P(s-1,0),0,1,s),
104 new Line( new P(0,s-1),1,0,s), new Line( new P(0,0), 0,1,s)]
105 end
106 return new Array[Line]
107 end
108 end
109
110 class P
111 var x : Int
112 var y : Int
113 end
114
115 redef class String
116 # hack is to support a bug in the evaluation software
117 fun draw(dispc: Char, size, gap: Int, hack: Bool)
118 do
119 var w = size * length +(length-1)*gap
120 var h = size
121 var map = new Array[Array[Char]]
122 for x in [0..w[ do
123 map[x] = new Array[Char].filled_with( ' ', h )
124 end
125
126 var ci = 0
127 for c in self.chars do
128 var local_dispc
129 if c.override_dispc then
130 local_dispc = c
131 else
132 local_dispc = dispc
133 end
134
135 var lines = c.lines( size )
136 for line in lines do
137 var x = line.o.x+ci*size
138 x += ci*gap
139 var y = line.o.y
140 for s in [0..line.len[ do
141 assert map.length > x and map[x].length > y else print "setting {x},{y} as {local_dispc}"
142 map[x][y] = local_dispc
143 x += line.step_x
144 y += line.step_y
145 end
146 end
147
148 ci += 1
149 end
150
151 if hack then
152 for c in [0..size[ do
153 map[c][0] = map[map.length-size+c][0]
154 map[map.length-size+c][0] = ' '
155 end
156 end
157
158 for y in [0..h[ do
159 for x in [0..w[ do
160 printn map[x][y]
161 end
162 print ""
163 end
164 end
165 end
166
167 class Line
168 var o : P
169 var step_x : Int
170 var step_y : Int
171 var len : Int
172 end
173
174 var a
175 var b
176 var op_char
177 var disp_char
178 var disp_size
179 var disp_gap
180
181 if "NIT_TESTING".environ == "true" then
182 a = 567
183 b = 13
184 op_char = '*'
185 disp_char = 'O'
186 disp_size = 8
187 disp_gap = 1
188 else
189 printn "Left operand: "
190 a = gets.to_i
191
192 printn "Right operand: "
193 b = gets.to_i
194
195 printn "Operator (+, -, *, /, %): "
196 op_char = gets.chars[0]
197
198 printn "Char to display: "
199 disp_char = gets.chars[0]
200
201 printn "Size of text: "
202 disp_size = gets.to_i
203
204 printn "Space between digits: "
205 disp_gap = gets.to_i
206 end
207
208 var result = op_char.as_operator( a, b )
209
210 var len_a = a.n_chars
211 var len_b = b.n_chars
212 var len_res = result.n_chars
213 var max_len = len_a.max( len_b.max( len_res ) ) + 1
214
215 # draw first line
216 var d = max_len - len_a
217 var line_a = ""
218 for i in [0..d[ do line_a += " "
219 line_a += a.to_s
220 line_a.draw( disp_char, disp_size, disp_gap, false )
221
222 print ""
223 # draw second line
224 d = max_len - len_b-1
225 var line_b = op_char.to_s
226 for i in [0..d[ do line_b += " "
227 line_b += b.to_s
228 line_b.draw( disp_char, disp_size, disp_gap, false )
229
230 # draw -----
231 print ""
232 for i in [0..disp_size*max_len+(max_len-1)*disp_gap] do
233 printn "_"
234 end
235 print ""
236 print ""
237
238 # draw result
239 d = max_len - len_res
240 var line_res = ""
241 for i in [0..d[ do line_res += " "
242 line_res += result.to_s
243 line_res.draw( disp_char, disp_size, disp_gap, false )