linmeric 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/bin/linmeric +547 -0
- data/doc/Instructions_en.html +231 -0
- data/doc/Instructions_en.txt +208 -0
- data/doc/Instructions_it.html +231 -0
- data/doc/Instructions_it.txt +214 -0
- data/doc/README_en.html +177 -0
- data/doc/README_en.txt +30 -0
- data/doc/README_it.html +187 -0
- data/doc/README_it.txt +32 -0
- data/lib/linmeric/Archive.rb +50 -0
- data/lib/linmeric/CnGal_Matrix_class.rb +358 -0
- data/lib/linmeric/CnGal_new_classes.rb +231 -0
- data/lib/linmeric/CnGal_tools.rb +80 -0
- data/lib/linmeric/Error_print.rb +66 -0
- data/lib/linmeric/Function_class.rb +249 -0
- data/lib/linmeric/Integrators.rb +76 -0
- data/lib/linmeric/LU.rb +84 -0
- data/lib/linmeric/Lexer.rb +54 -0
- data/lib/linmeric/Listener.rb +191 -0
- data/lib/linmeric/Parser.rb +118 -0
- data/lib/linmeric/Scopify.rb +206 -0
- data/lib/linmeric/Sizer.rb +328 -0
- data/lib/linmeric/Token.rb +53 -0
- data/lib/linmeric.rb +10 -0
- metadata +76 -0
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
#! /usr/bin/env ruby
|
|
2
|
+
|
|
3
|
+
module PrintError
|
|
4
|
+
def self.print(message,expression,pos)
|
|
5
|
+
puts message
|
|
6
|
+
puts expression
|
|
7
|
+
puts " " * pos + "^"
|
|
8
|
+
#puts
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def self.default(token,expression)
|
|
12
|
+
message = " Sintax Error: unexpected #{token.attribute} token '#{token.me}' found"
|
|
13
|
+
self.print(message,expression,token.position)
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def self.reduced(token,expression)
|
|
17
|
+
message = " Sintax Error: unexpected #{token.attribute} '#{token.me}' found"
|
|
18
|
+
self.print(message,expression,token.position)
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def self.unknown(token,expression)
|
|
22
|
+
message = " Sintax Error: unknown #{token.attribute} '#{token.me}' found"
|
|
23
|
+
self.print(message,expression,token.position)
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def self.missmatch(token,expression,expectation)
|
|
27
|
+
message = " Sintax Error: expecting #{expectation} but #{token.attribute} token '#{token.me}' found"
|
|
28
|
+
self.print(message,expression,token.position)
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def self.missing(token,expression)
|
|
32
|
+
message = " Sintax Error: missing argument for '#{token.me}' #{token.attribute}"
|
|
33
|
+
self.print(message,expression,token.position)
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def self.no_final_quotes(expression,position)
|
|
37
|
+
message = " Sintax Error: missing quotes for block"
|
|
38
|
+
self.print(message,expression,position)
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
def self.missing_general_string(position,expression)
|
|
42
|
+
message = " Sintax Error: missing agument block"
|
|
43
|
+
self.print(message,expression,position)
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
def self.numPoint_missing(position,expression)
|
|
47
|
+
message = " Sintax Error: number of points is missing"
|
|
48
|
+
self.print(message,expression,position)
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
def self.missing_expression_after_equal(pos,expression)
|
|
52
|
+
message = " Sintax Error: missing expression after EQUAL operator"
|
|
53
|
+
self.print(message,expression,pos)
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
def self.unexpected_token_in_solve(token,expression)
|
|
57
|
+
message = " Sintax Error: unexpected #{token.attribute} token '#{token.me}' in 'solve:' args"
|
|
58
|
+
self.print(message,expression,token.position)
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
def self.missing_integ_range(pos,expression)
|
|
62
|
+
message = " Sintax Error: missing integration range for 'integ:' method"
|
|
63
|
+
self.print(message,expression,pos)
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
end
|
|
@@ -0,0 +1,249 @@
|
|
|
1
|
+
#! /usr/bin/env ruby
|
|
2
|
+
|
|
3
|
+
require_relative 'CnGal_new_classes.rb'
|
|
4
|
+
require_relative 'Integrators.rb'
|
|
5
|
+
|
|
6
|
+
class Function
|
|
7
|
+
def initialize(str)
|
|
8
|
+
@inp = str
|
|
9
|
+
@vars = []
|
|
10
|
+
@i = 0
|
|
11
|
+
@funct = convert(str)
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def ok?
|
|
15
|
+
@funct == nil ? (return false) : (return true)
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def to_block(n = 0)
|
|
19
|
+
n = @vars.size if n == 0
|
|
20
|
+
return nil if not self.ok?
|
|
21
|
+
return nil if n < @vars.size
|
|
22
|
+
b_v = "|#{vars(n)}|" if @vars.size > 0
|
|
23
|
+
return "{ #{b_v} #{@funct} }"
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def vars(n = 0)
|
|
27
|
+
n = @vars.size if n == 0
|
|
28
|
+
return nil if not self.ok?
|
|
29
|
+
return nil if n < @vars.size
|
|
30
|
+
var = @vars[0]
|
|
31
|
+
for i in 1...@vars.length do
|
|
32
|
+
var += ',' + @vars[i]
|
|
33
|
+
end
|
|
34
|
+
if n != @vars.size then
|
|
35
|
+
i = 0
|
|
36
|
+
('a'..'z').each do |ch|
|
|
37
|
+
unless @vars.include? ch
|
|
38
|
+
i +=1
|
|
39
|
+
var += ',' + ch
|
|
40
|
+
break if i == (n - @vars.size)
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
return var
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
def show()
|
|
48
|
+
puts @inp
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
def integrate(r,n,m = 'simpson')
|
|
52
|
+
return nil unless self.ok?
|
|
53
|
+
block = self.to_block(1)
|
|
54
|
+
unless block == nil
|
|
55
|
+
m = (m - '"').downcase
|
|
56
|
+
case m
|
|
57
|
+
when "trapezes"
|
|
58
|
+
return eval("Integrators.trapezi(r.sx,r.dx,n)#{block}")
|
|
59
|
+
when "midpoint"
|
|
60
|
+
return eval("Integrators.simpson(r.sx,r.dx,n)#{block}")
|
|
61
|
+
when "simpson"
|
|
62
|
+
return eval("Integrators.simpson(r.sx,r.dx,n)#{block}")
|
|
63
|
+
when "rectl"
|
|
64
|
+
return eval("Integrators.rettsx(r.sx,r.dx,n)#{block}")
|
|
65
|
+
when "rectr"
|
|
66
|
+
return eval("Integrators.rettdx(r.sx,r.dx,n)#{block}")
|
|
67
|
+
when "boole"
|
|
68
|
+
return eval("Integrators.boole(r.sx,r.dx,n)#{block}")
|
|
69
|
+
else
|
|
70
|
+
puts "Argument Error: Invalid integration method"; #puts
|
|
71
|
+
return nil
|
|
72
|
+
end
|
|
73
|
+
end
|
|
74
|
+
puts "Argument Error: bad function for integration"; #puts
|
|
75
|
+
return nil
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
private
|
|
79
|
+
|
|
80
|
+
def tokenize(str)
|
|
81
|
+
tokens = Array.new
|
|
82
|
+
x = ''
|
|
83
|
+
str.each_char do |ch|
|
|
84
|
+
case ch
|
|
85
|
+
when /[\+\-\*\/\^\(\)]/
|
|
86
|
+
tokens.push ch
|
|
87
|
+
when /[a-zA-Z\0-9\.]/
|
|
88
|
+
x = tokens.pop if not '+-*/^()'.include? tokens[tokens.size - 1].to_s
|
|
89
|
+
tokens.push (x + ch)
|
|
90
|
+
x = ""
|
|
91
|
+
else
|
|
92
|
+
return nil
|
|
93
|
+
end
|
|
94
|
+
end
|
|
95
|
+
return tokens
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
def convert(str)
|
|
99
|
+
return nil unless str.is_a? String
|
|
100
|
+
str = tokenize(str)
|
|
101
|
+
return nil if str == ""
|
|
102
|
+
return nil unless balanced_brackets? str
|
|
103
|
+
return translate(str)
|
|
104
|
+
end
|
|
105
|
+
|
|
106
|
+
def balanced_brackets?(expr)
|
|
107
|
+
return nil unless expr.is_a? Array
|
|
108
|
+
brakets = 0
|
|
109
|
+
expr.each do |el|
|
|
110
|
+
case el
|
|
111
|
+
when '('
|
|
112
|
+
brakets += 1
|
|
113
|
+
when ')'
|
|
114
|
+
brakets -= 1
|
|
115
|
+
end
|
|
116
|
+
end
|
|
117
|
+
brakets == 0 ? (return true) : (return false)
|
|
118
|
+
end
|
|
119
|
+
|
|
120
|
+
def translate(str,open_b = false)
|
|
121
|
+
return nil unless str.is_a? Array
|
|
122
|
+
funct = ""
|
|
123
|
+
state = 0
|
|
124
|
+
while @i < str.size
|
|
125
|
+
case state
|
|
126
|
+
when 0
|
|
127
|
+
case str[@i]
|
|
128
|
+
when /[\+\-]/
|
|
129
|
+
funct += str[@i]
|
|
130
|
+
state = 1
|
|
131
|
+
when /\p{Alpha}/
|
|
132
|
+
if Tool.f.include? str[@i] then
|
|
133
|
+
funct += "Math::#{str[@i]}"
|
|
134
|
+
state = 4 unless str[@i] == "PI"
|
|
135
|
+
state = 2 if str[@i] == "PI"
|
|
136
|
+
elsif str[@i].size == 1
|
|
137
|
+
ch = str[@i].downcase
|
|
138
|
+
funct += ch
|
|
139
|
+
@vars << ch unless @vars.include? ch
|
|
140
|
+
state = 2
|
|
141
|
+
else
|
|
142
|
+
return nil
|
|
143
|
+
end
|
|
144
|
+
when /[0-9]+/
|
|
145
|
+
if str[@i].integer? or str[@i].float? then
|
|
146
|
+
funct += str[@i]
|
|
147
|
+
state = 2
|
|
148
|
+
else
|
|
149
|
+
return nil
|
|
150
|
+
end
|
|
151
|
+
when "("
|
|
152
|
+
funct += "("
|
|
153
|
+
@i += 1
|
|
154
|
+
part = translate(str,true)
|
|
155
|
+
state = 2
|
|
156
|
+
if part != nil then
|
|
157
|
+
funct += part
|
|
158
|
+
else
|
|
159
|
+
return nil
|
|
160
|
+
end
|
|
161
|
+
else
|
|
162
|
+
return nil
|
|
163
|
+
end
|
|
164
|
+
|
|
165
|
+
# state 1 expects or a variable (single char) or a number or a function or (
|
|
166
|
+
when 1
|
|
167
|
+
case str[@i]
|
|
168
|
+
when /\p{Alpha}/
|
|
169
|
+
if Tool.f.include? str[@i] then
|
|
170
|
+
funct += "Math::#{str[@i]}"
|
|
171
|
+
state = 4 unless str[@i] == "PI"
|
|
172
|
+
state = 2 if str[@i] == "PI"
|
|
173
|
+
elsif str[@i].size == 1
|
|
174
|
+
ch = str[@i].downcase
|
|
175
|
+
funct += ch
|
|
176
|
+
@vars << ch unless @vars.include? ch
|
|
177
|
+
state = 2
|
|
178
|
+
else
|
|
179
|
+
return nil
|
|
180
|
+
end
|
|
181
|
+
when /[0-9]+/
|
|
182
|
+
if str[@i].integer? or str[@i].float? then
|
|
183
|
+
funct += str[@i]
|
|
184
|
+
state = 2
|
|
185
|
+
else
|
|
186
|
+
return nil
|
|
187
|
+
end
|
|
188
|
+
when "("
|
|
189
|
+
funct += "("
|
|
190
|
+
state = 3
|
|
191
|
+
else
|
|
192
|
+
return nil
|
|
193
|
+
|
|
194
|
+
end
|
|
195
|
+
|
|
196
|
+
# state 2 expects an operator or )
|
|
197
|
+
when 2
|
|
198
|
+
if /[\+\-\*\/\^]{1}/ =~ str[@i] then
|
|
199
|
+
funct += str[@i] if str[@i] != "^"
|
|
200
|
+
funct += "**" if str[@i] == "^"
|
|
201
|
+
state = 1
|
|
202
|
+
elsif str[@i] == ")"
|
|
203
|
+
if open_b then
|
|
204
|
+
return funct + ")"
|
|
205
|
+
else
|
|
206
|
+
return nil
|
|
207
|
+
end
|
|
208
|
+
else
|
|
209
|
+
return nil
|
|
210
|
+
end
|
|
211
|
+
|
|
212
|
+
# state 3 expects a sub_expression not beginnin with (
|
|
213
|
+
when 3
|
|
214
|
+
part = translate(str,true)
|
|
215
|
+
state = 2
|
|
216
|
+
if part != nil then
|
|
217
|
+
funct += part
|
|
218
|
+
else
|
|
219
|
+
return nil
|
|
220
|
+
end
|
|
221
|
+
|
|
222
|
+
# state 4 expects a sub_expression beginning with (
|
|
223
|
+
when 4
|
|
224
|
+
if str[@i] == '(' then
|
|
225
|
+
@i += 1
|
|
226
|
+
part = translate(str,true)
|
|
227
|
+
state = 2
|
|
228
|
+
if part != nil then
|
|
229
|
+
funct += '(' + part
|
|
230
|
+
else
|
|
231
|
+
return nil
|
|
232
|
+
end
|
|
233
|
+
else
|
|
234
|
+
return nil
|
|
235
|
+
end
|
|
236
|
+
|
|
237
|
+
else
|
|
238
|
+
return nil
|
|
239
|
+
end
|
|
240
|
+
@i += 1
|
|
241
|
+
end
|
|
242
|
+
return nil if state == 1
|
|
243
|
+
return funct
|
|
244
|
+
end
|
|
245
|
+
|
|
246
|
+
end
|
|
247
|
+
|
|
248
|
+
|
|
249
|
+
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
#! /usr/bin/env ruby
|
|
2
|
+
|
|
3
|
+
module Integrators
|
|
4
|
+
def self.trapezi(a,b,n)
|
|
5
|
+
#Implementazione
|
|
6
|
+
h=(b-a)/n.to_f
|
|
7
|
+
int_parz=0
|
|
8
|
+
for i in 0...n
|
|
9
|
+
#calcolo primo addendo =f(x_i)
|
|
10
|
+
f1=yield(a+i*h) #chiama il blocco definito sotto
|
|
11
|
+
#calcolo secondo addendo = f(X_{i+1})
|
|
12
|
+
f2=yield(a+(i+1)*h)
|
|
13
|
+
#calcolo area trapezio
|
|
14
|
+
trap=0.5*h*(f1+f2)
|
|
15
|
+
int_parz+=trap
|
|
16
|
+
end
|
|
17
|
+
return int_parz
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def self.midpoint(a,b,n)
|
|
21
|
+
parz=0
|
|
22
|
+
h=(b-a)/n.to_f
|
|
23
|
+
for i in 0...n
|
|
24
|
+
f1 = yield(a+(i+0.5)*h)
|
|
25
|
+
parz+=f1
|
|
26
|
+
end
|
|
27
|
+
return h*parz
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def self.simpson(a,b,n)
|
|
31
|
+
hs=(b-a)/(n*2.0)
|
|
32
|
+
intSA =0
|
|
33
|
+
intSB =0
|
|
34
|
+
for i in 1..n-1
|
|
35
|
+
xa = a+ (2*i)*hs
|
|
36
|
+
intSA+=yield(xa)
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
for i in 0..n-1
|
|
40
|
+
xb=a+ (2*i+1)*hs
|
|
41
|
+
intSB+=yield(xb)
|
|
42
|
+
end
|
|
43
|
+
fa=yield(a)
|
|
44
|
+
fb=yield(b)
|
|
45
|
+
intS=hs/3.0*(fa+fb+2*intSA+4*intSB)
|
|
46
|
+
return intS
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
def self.rettsx(a,b,n)
|
|
50
|
+
h=(b-a)/n.to_f
|
|
51
|
+
area=0
|
|
52
|
+
for i in 0..n-1
|
|
53
|
+
area+=yield(a+(h*i))*h
|
|
54
|
+
end
|
|
55
|
+
return area
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
def self.rettdx(a,b,n)
|
|
59
|
+
h=(b-a)/n.to_f
|
|
60
|
+
area=0
|
|
61
|
+
for i in 1..n
|
|
62
|
+
area+=yield(a+(h*i))*h
|
|
63
|
+
end
|
|
64
|
+
return area
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
def self.boole(a,b,n)
|
|
68
|
+
h=(b-a)/(4*n.to_f)
|
|
69
|
+
parz=0
|
|
70
|
+
for i in 0..n-1
|
|
71
|
+
parz+=7*yield(a+(h*4*i)) +32*yield(a+(h*(4*i+1))) +12*yield(a+(h*(4*i+2))) +32*yield(a+(h*(4*i+3)))+7*yield(a+(h*(4*i+4)))
|
|
72
|
+
end
|
|
73
|
+
return (2*h)/45.0*parz
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
end
|
data/lib/linmeric/LU.rb
ADDED
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
#! /usr/bin/env ruby
|
|
2
|
+
require_relative 'CnGal_Matrix_class'
|
|
3
|
+
|
|
4
|
+
module LU
|
|
5
|
+
|
|
6
|
+
# swapping two rows (pivoting)
|
|
7
|
+
def self.swap(mx,r1,r2)
|
|
8
|
+
for i in 0...mx.getCls do
|
|
9
|
+
mx[r1,i],mx[r2,i] = mx[r2,i],mx[r1,i]
|
|
10
|
+
end
|
|
11
|
+
return mx
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def self.L()
|
|
15
|
+
return @L
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def self.U()
|
|
19
|
+
return @U
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def self.reset
|
|
23
|
+
@L = nil
|
|
24
|
+
@U = nil
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def self.factorize(mx,sol)
|
|
28
|
+
[mx,sol].each do |vec|
|
|
29
|
+
return nil unless vec.is_a? Matrix
|
|
30
|
+
end
|
|
31
|
+
sol = sol.tr if sol.getCls > 1
|
|
32
|
+
return nil unless sol.getCls == 1
|
|
33
|
+
return nil unless mx.is_squared?
|
|
34
|
+
return nil unless mx.getRws == sol.getRws
|
|
35
|
+
rows = mx.getRws
|
|
36
|
+
#sol.show;gets
|
|
37
|
+
for k in 0...rows do
|
|
38
|
+
column = mx[k...mx.getRws,k].export.map! { |val| val.abs}
|
|
39
|
+
max_index = column.index(column.max)
|
|
40
|
+
mx = self.swap(mx,k,k + max_index) unless k == max_index + k
|
|
41
|
+
sol = self.swap(sol,0,k + max_index) unless k == max_index + k
|
|
42
|
+
#mx.show;gets
|
|
43
|
+
for i in (k+1)...mx.getRws do
|
|
44
|
+
alpha = (mx[k,k] != 0) ? (mx[i,k] / mx[k,k].to_f) : 0
|
|
45
|
+
mx[i,k] = alpha
|
|
46
|
+
for j in (k+1)...mx.getCls do
|
|
47
|
+
mx[i,j] -= alpha * mx[k,j]
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
#return mx
|
|
52
|
+
@L = Matrix.identity(mx.getRws) + Matrix.new(mx.getRws,mx.getCls){ |i,j| (i > j) ? mx[i,j] : 0} #
|
|
53
|
+
@U = Matrix.new(mx.getRws,mx.getCls){ |i,j| (i <= j) ? mx[i,j] : 0}
|
|
54
|
+
return solve(sol)
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
def self.solve(sol)
|
|
58
|
+
z = Matrix.new(sol.getRws,1) {0}
|
|
59
|
+
x = Matrix.new(sol.getRws,1) {0}
|
|
60
|
+
for i in 0...sol.getRws do
|
|
61
|
+
z[i,0] = sol[i,0]
|
|
62
|
+
for j in 0...i do
|
|
63
|
+
z[i,0] -= @L[i,j] * (z[j,0] || 1)
|
|
64
|
+
end
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
(sol.getRws - 1).downto(0) do |i|
|
|
68
|
+
x[i,0] = z[i,0]
|
|
69
|
+
for j in i...sol.getRws
|
|
70
|
+
x[i,0] -= (@U[i,j+1] || 0) * (x[j+1,0] || 0)
|
|
71
|
+
end
|
|
72
|
+
x[i,0] = x[i,0] / @U[i,i].to_f
|
|
73
|
+
end
|
|
74
|
+
return x
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
|
|
81
|
+
|
|
82
|
+
|
|
83
|
+
|
|
84
|
+
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
#! /usr/bin/env ruby
|
|
2
|
+
|
|
3
|
+
require_relative 'CnGal_tools.rb'
|
|
4
|
+
require_relative 'CnGal_new_classes.rb'
|
|
5
|
+
require_relative 'Token.rb'
|
|
6
|
+
|
|
7
|
+
class Lexer
|
|
8
|
+
|
|
9
|
+
def tokenize(expr)
|
|
10
|
+
token = []
|
|
11
|
+
temp = ""
|
|
12
|
+
ignore = false
|
|
13
|
+
pos = 0
|
|
14
|
+
i = 0
|
|
15
|
+
gen_exp = []
|
|
16
|
+
tokenizers = Tool.operators + [" ","(",")",":",'"',"~"]
|
|
17
|
+
while i < expr.size
|
|
18
|
+
# puts expr[i];gets
|
|
19
|
+
if (tokenizers.include? expr[i]) then
|
|
20
|
+
temp += ':' if expr[i] == ':'
|
|
21
|
+
token << Token.new(temp, pos) unless temp == ""
|
|
22
|
+
temp = ""
|
|
23
|
+
token << Token.new(expr[i],i) unless " :".include? expr[i]
|
|
24
|
+
gen_exp = extract_gen_exp(expr[(i+1)...expr.size]) if expr[i] == '"'
|
|
25
|
+
token << Token.new(gen_exp[0],pos+1,"GENERAL_STRING") unless gen_exp == []
|
|
26
|
+
i += gen_exp[1] unless gen_exp == []
|
|
27
|
+
pos = i + ((gen_exp == []) ? 1 : 0)
|
|
28
|
+
token << Token.new('"',pos) && pos += 1 if gen_exp[2]
|
|
29
|
+
gen_exp = []
|
|
30
|
+
else
|
|
31
|
+
temp += expr[i]
|
|
32
|
+
end
|
|
33
|
+
i += 1
|
|
34
|
+
end
|
|
35
|
+
token << Token.new(temp,pos) unless temp == ""
|
|
36
|
+
return token
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
private
|
|
40
|
+
|
|
41
|
+
def extract_gen_exp(string)
|
|
42
|
+
i = 0
|
|
43
|
+
gen_exp = ""
|
|
44
|
+
while i < string.size and string[i] != '"'
|
|
45
|
+
gen_exp += string[i]
|
|
46
|
+
i += 1
|
|
47
|
+
end
|
|
48
|
+
quotes = (string[i] == '"') ? true : false
|
|
49
|
+
i += 1 if string[i] == '"'
|
|
50
|
+
return [gen_exp,i,quotes]
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
end
|
|
@@ -0,0 +1,191 @@
|
|
|
1
|
+
#! /usr/bin/env ruby
|
|
2
|
+
|
|
3
|
+
require 'io/console'
|
|
4
|
+
require_relative 'CnGal_new_classes.rb'
|
|
5
|
+
require_relative 'Archive.rb'
|
|
6
|
+
require_relative 'CnGal_tools.rb'
|
|
7
|
+
|
|
8
|
+
class Listener
|
|
9
|
+
CSI = "\e["
|
|
10
|
+
LETTERS = Tool.letters
|
|
11
|
+
NUMBERS = "0123456789"
|
|
12
|
+
SPECIAL_CHARS = "|!$%&/()=?'^~+-*<>-_,:;. " + '"'
|
|
13
|
+
CHARS = LETTERS + LETTERS.upcase + SPECIAL_CHARS + NUMBERS
|
|
14
|
+
|
|
15
|
+
def initialize
|
|
16
|
+
@final_string = ""
|
|
17
|
+
@i = 0
|
|
18
|
+
@s = 0
|
|
19
|
+
@exit = false
|
|
20
|
+
@list = Archive.new
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def reset
|
|
24
|
+
@final_string = ""
|
|
25
|
+
@i = 0
|
|
26
|
+
@exit = false
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def read_char
|
|
30
|
+
STDIN.echo = false
|
|
31
|
+
STDIN.raw!
|
|
32
|
+
|
|
33
|
+
input = STDIN.getc.chr
|
|
34
|
+
if input == "\e" then
|
|
35
|
+
input << STDIN.read_nonblock(3) rescue nil
|
|
36
|
+
input << STDIN.read_nonblock(2) rescue nil
|
|
37
|
+
end
|
|
38
|
+
ensure
|
|
39
|
+
STDIN.echo = true
|
|
40
|
+
STDIN.cooked!
|
|
41
|
+
|
|
42
|
+
return input
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
def show_single_key()
|
|
46
|
+
c = read_char
|
|
47
|
+
case c
|
|
48
|
+
|
|
49
|
+
when "\t"
|
|
50
|
+
# "TAB"
|
|
51
|
+
|
|
52
|
+
# "RETURN"
|
|
53
|
+
when "\r"
|
|
54
|
+
puts c
|
|
55
|
+
@exit = true
|
|
56
|
+
when "\n"
|
|
57
|
+
# "LINE FEED"
|
|
58
|
+
when "\e"
|
|
59
|
+
# "ESCAPE"
|
|
60
|
+
|
|
61
|
+
# "UP ARROW"
|
|
62
|
+
when "\e[A"
|
|
63
|
+
temp = @list.previous
|
|
64
|
+
unless temp == ""
|
|
65
|
+
clear_line
|
|
66
|
+
@final_string = temp
|
|
67
|
+
@i = @final_string.size
|
|
68
|
+
print @final_string
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
# "DOWN ARROW"
|
|
72
|
+
when "\e[B"
|
|
73
|
+
clear_line
|
|
74
|
+
@final_string = @list.next_
|
|
75
|
+
@i = @final_string.size
|
|
76
|
+
print @final_string
|
|
77
|
+
|
|
78
|
+
# "RIGHT ARROW"
|
|
79
|
+
when "\e[C"
|
|
80
|
+
@list.top
|
|
81
|
+
unless @i == @final_string.size
|
|
82
|
+
$stdout.write "#{CSI}1C"
|
|
83
|
+
@i += 1
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
# "LEFT ARROW"
|
|
87
|
+
when "\e[D"
|
|
88
|
+
@list.top
|
|
89
|
+
unless @i == 0
|
|
90
|
+
$stdout.write "#{CSI}1D"
|
|
91
|
+
@i -= 1
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
# Delete char
|
|
95
|
+
when "\177"
|
|
96
|
+
@list.top
|
|
97
|
+
unless @i == 0
|
|
98
|
+
$stdout.write "#{CSI}1D"
|
|
99
|
+
for i in (@i)...@final_string.size do
|
|
100
|
+
$stdout.write "#{@final_string[i]}"
|
|
101
|
+
end
|
|
102
|
+
$stdout.write " "
|
|
103
|
+
@final_string = @final_string.remove(@i-1)
|
|
104
|
+
for i in (@i-2)...@final_string.size do
|
|
105
|
+
$stdout.write "#{CSI}1D"
|
|
106
|
+
end
|
|
107
|
+
@i -= 1
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
when "\004"
|
|
111
|
+
# "DELETE"
|
|
112
|
+
when "\e[3~"
|
|
113
|
+
# "ALTERNATE DELETE"
|
|
114
|
+
|
|
115
|
+
# "Ctrl + C"
|
|
116
|
+
when "\u0003"
|
|
117
|
+
# puts
|
|
118
|
+
# exit 0
|
|
119
|
+
when /^.$/
|
|
120
|
+
@list.top
|
|
121
|
+
if CHARS.include? c
|
|
122
|
+
if @i < @final_string.size then
|
|
123
|
+
last_i = @i + 2
|
|
124
|
+
@final_string.insert @i, c
|
|
125
|
+
clear_line
|
|
126
|
+
$stdout.write "#{@final_string}"
|
|
127
|
+
cursor_to(last_i)
|
|
128
|
+
@i = last_i - 1
|
|
129
|
+
else
|
|
130
|
+
print c
|
|
131
|
+
@final_string += c
|
|
132
|
+
@i += 1
|
|
133
|
+
end
|
|
134
|
+
elsif c == "\f" then
|
|
135
|
+
@i = 0
|
|
136
|
+
print "\e[H\e[2J"
|
|
137
|
+
print "Linmeric-main> "
|
|
138
|
+
end
|
|
139
|
+
end
|
|
140
|
+
end
|
|
141
|
+
|
|
142
|
+
def gets()
|
|
143
|
+
show_single_key while(!@exit)
|
|
144
|
+
@list.store(@final_string)
|
|
145
|
+
return @final_string.clone
|
|
146
|
+
end
|
|
147
|
+
|
|
148
|
+
private
|
|
149
|
+
|
|
150
|
+
def clear_line
|
|
151
|
+
if @i < @final_string.size
|
|
152
|
+
for i in @i...@final_string.size do
|
|
153
|
+
$stdout.write "#{CSI}1C"
|
|
154
|
+
end
|
|
155
|
+
end
|
|
156
|
+
@i = (@final_string == nil or @final_string == "") ? 0 : @final_string.size
|
|
157
|
+
for i in 0...@i do
|
|
158
|
+
$stdout.write "#{CSI}1D"
|
|
159
|
+
$stdout.write " "
|
|
160
|
+
$stdout.write "#{CSI}1D"
|
|
161
|
+
end
|
|
162
|
+
@i = 0
|
|
163
|
+
end
|
|
164
|
+
|
|
165
|
+
def cursor_to(pos)
|
|
166
|
+
return nil if pos < 0
|
|
167
|
+
for i in pos..@final_string.size
|
|
168
|
+
$stdout.write "#{CSI}1D"
|
|
169
|
+
end
|
|
170
|
+
end
|
|
171
|
+
|
|
172
|
+
end
|
|
173
|
+
|
|
174
|
+
|
|
175
|
+
|
|
176
|
+
########################################
|
|
177
|
+
# TESTS #
|
|
178
|
+
########################################
|
|
179
|
+
=begin
|
|
180
|
+
listener = Listener.new
|
|
181
|
+
while true
|
|
182
|
+
print '> '
|
|
183
|
+
listener.gets
|
|
184
|
+
listener.reset
|
|
185
|
+
end
|
|
186
|
+
=end
|
|
187
|
+
|
|
188
|
+
|
|
189
|
+
|
|
190
|
+
|
|
191
|
+
|