t-rex 1.0.5 → 2.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.
Files changed (4) hide show
  1. checksums.yaml +4 -4
  2. data/bin/t-rex +760 -0
  3. metadata +15 -14
  4. data/bin/t-rex.rb +0 -880
data/bin/t-rex ADDED
@@ -0,0 +1,760 @@
1
+ #!/usr/bin/env ruby
2
+ # encoding: utf-8
3
+ #
4
+ # Title: T-REX (Terminal - Rpn EXperiment)
5
+ # Language: Pure Ruby, best viewed in VIM
6
+ # Author: Geir Isene <g@isene.com> http://isene.com/
7
+ # Github: https://github.com/isene/t-rex/
8
+ # License: I release all copyright claims. This code is in the public domain.
9
+ # Permission is granted to use, copy modify, distribute, and sell
10
+ # this software for any purpose. I make no guarantee about the
11
+ # suitability of this software for any purpose and I am not liable
12
+ # for any damages resulting from its use. Further, I am under no
13
+ # obligation to maintain or extend this software. It is provided
14
+ # on an 'as is' basis without any expressed or implied warranty.
15
+ @version = "2.0" # Full rewrite with rcurses, face lift, new functionality, bug fixes
16
+
17
+ require 'rcurses'
18
+ include Rcurses::Input
19
+
20
+ def help # HELP text
21
+ help = <<HELPTEXT
22
+
23
+ T-REX - Terminal Rpn calculator EXperiment. GitHub: https://github.com/isene/T-REX
24
+ This is a Reverse Polish Notation calculator similar to the traditional Hewlett
25
+ Packard calculators. See https://www.hpmuseum.org/rpn.htm for info on RPN.
26
+
27
+ The stack is shown to the top left. The X, Y, Z and T registers comprise the
28
+ operating stack. L is the "Last X" register showing the previous value in X.
29
+ Toggle US and European number formats by pressing '.
30
+
31
+ Functions available are shown under the stack registers. The orange symbol
32
+ corresponds to the key to be pressed. For functions above each label (grey
33
+ functions), press the Control key (Ctrl) and the orange key (asin = Ctrl+i).
34
+
35
+ For Rectangular to Polar conversions:
36
+ R-P: X value in x, Y in y - yields "θ" in y and "r" in x.
37
+ P-R: "θ" in y and "r" in x - yeilds X in x and Y in y.
38
+
39
+ Use the "f" key to set the fixed number of decimal places. Use the "s" key to set
40
+ the limit for viewing numbers in the "scientific" notation (e.g. 5e+06 for 5000000).
41
+
42
+ Content of registers #0-#9 are shown below the functions.
43
+ Store/recall using capital "S"/"R". "M" clears the regs.
44
+
45
+ Copy/yank the X register to clipboard with "y". Use "Y" to yank all the memory regs.
46
+
47
+ You can undo (with "u") all the way to the beginning of the session.
48
+
49
+ The 'H' key toggles between the help text in the right pane or a continuous printout.
50
+ Save the full printout to ~/t-rex.txt with "Ctrl-P".
51
+
52
+ The stack, register contents, modes and help text settings are saved on Quit.
53
+
54
+ Additionally, you can access the "Ruby mode" via '@'. Here you can address the stack
55
+ directly, e.g. 'x = y + (z / t); puts x'. Quit Ruby mode with ESC.
56
+
57
+ Alternative keys: Left/Right keys (in addition to "<") exchanges X and Y registers.
58
+ Backspace clears the x register.
59
+ HELPTEXT
60
+ if @hlp
61
+ @p_hlp.fg = 239
62
+ @p_hlp.ix = 0
63
+ @p_hlp.puts(help)
64
+ else
65
+ @p_hlp.ix = @history.length - @h + 3
66
+ histprint
67
+ end
68
+ end
69
+
70
+ class Stack # STACK class
71
+ attr_accessor :x, :y, :z, :t, :l, :deg
72
+
73
+ def initialize(x, y, z, t, l)
74
+ self.x = x.to_f
75
+ self.y = y.to_f
76
+ self.z = z.to_f
77
+ self.t = t.to_f
78
+ self.l = l.to_f
79
+ end
80
+ def lift
81
+ self.y, self.z, self.t = self.x, self.y, self.z
82
+ end
83
+ def drop
84
+ self.y, self.z = self.z, self.t
85
+ end
86
+ def rdn
87
+ self.x, self.y, self.z, self.t = self.y, self.z, self.t, self.x
88
+ end
89
+ def rup
90
+ self.x, self.y, self.z, self.t = self.t, self.x, self.y, self.z
91
+ end
92
+ def xy
93
+ self.x, self.y = self.y, self.x
94
+ end
95
+ def add
96
+ self.l = self.x
97
+ self.x = self.y + self.x
98
+ self.drop
99
+ end
100
+ def subtract
101
+ self.l = self.x
102
+ self.x = self.y - self.x
103
+ self.drop
104
+ end
105
+ def multiply
106
+ self.l = self.x
107
+ self.x = self.y * self.x
108
+ self.drop
109
+ end
110
+ def divide
111
+ begin
112
+ throw if self.x == 0
113
+ self.l = self.x
114
+ self.x = self.y / self.x
115
+ self.drop
116
+ rescue
117
+ return "Error"
118
+ end
119
+ end
120
+ def mod
121
+ begin
122
+ throw if self.x == 0
123
+ self.l = self.x
124
+ self.x = self.y % self.x
125
+ self.drop
126
+ rescue
127
+ return "Error"
128
+ end
129
+ end
130
+ def percent
131
+ begin
132
+ throw if self.y == 0
133
+ self.l = self.x
134
+ self.x = 100*(self.x / self.y)
135
+ self.drop
136
+ rescue
137
+ return "Error"
138
+ end
139
+ end
140
+ def chs
141
+ self.x = -self.x
142
+ end
143
+ def pi
144
+ self.l = self.x
145
+ self.lift
146
+ self.x = Math::PI
147
+ end
148
+ def pow
149
+ self.l = self.x
150
+ self.x = self.y ** self.x
151
+ self.drop
152
+ end
153
+ def root
154
+ begin
155
+ self.l = self.x
156
+ self.x = self.y ** (1 / self.x)
157
+ self.drop
158
+ rescue
159
+ return "Error"
160
+ end
161
+ end
162
+ def recip
163
+ begin
164
+ throw if self.x == 0
165
+ self.l = self.x
166
+ self.x = 1 / self.x
167
+ rescue
168
+ return "Error"
169
+ end
170
+ end
171
+ def sqr
172
+ self.l = self.x
173
+ self.x = self.x ** 2
174
+ end
175
+ def sqrt
176
+ self.l = self.x
177
+ begin
178
+ self.x = Math::sqrt(self.x)
179
+ rescue
180
+ return "Error"
181
+ end
182
+ end
183
+ def cube
184
+ self.l = self.x
185
+ self.x = self.x ** 3
186
+ end
187
+ def ln
188
+ self.l = self.x
189
+ begin
190
+ self.x = Math::log(self.x)
191
+ rescue
192
+ return "Error"
193
+ end
194
+ end
195
+ def ex
196
+ self.l = self.x
197
+ self.x = Math::exp(self.x)
198
+ end
199
+ def log
200
+ self.l = self.x
201
+ begin
202
+ self.x = Math::log10(self.x)
203
+ rescue
204
+ return "Error"
205
+ end
206
+ end
207
+ def tenx
208
+ self.l = self.x
209
+ self.x = 10 ** self.x
210
+ end
211
+ def sin
212
+ self.l = self.x
213
+ self.x = self.x * Math::PI / 180 if self.deg
214
+ self.x = Math::sin(self.x)
215
+ end
216
+ def cos
217
+ self.l = self.x
218
+ self.x = self.x * Math::PI / 180 if self.deg
219
+ self.x = Math::cos(self.x)
220
+ end
221
+ def tan
222
+ self.l = self.x
223
+ self.x = self.x * Math::PI / 180 if self.deg
224
+ self.x = Math::tan(self.x)
225
+ end
226
+ def asin
227
+ self.l = self.x
228
+ begin
229
+ self.x = Math::asin(self.x)
230
+ self.x = self.x * 180 / Math::PI if self.deg
231
+ rescue
232
+ return "Error"
233
+ end
234
+ end
235
+ def acos
236
+ self.l = self.x
237
+ begin
238
+ self.x = Math::acos(self.x)
239
+ self.x = self.x * 180 / Math::PI if self.deg
240
+ rescue
241
+ return "Error"
242
+ end
243
+ end
244
+ def atan
245
+ self.l = self.x
246
+ self.x = Math::atan(self.x)
247
+ self.x = self.x * 180 / Math::PI if self.deg
248
+ end
249
+ def rp
250
+ begin
251
+ throw if self.x == 0
252
+ self.l = self.x
253
+ x = self.x
254
+ y = self.y
255
+ self.x = Math::sqrt(x*x + y*y)
256
+ self.y = Math::atan(y/x)
257
+ if x < 0 # Q2 & Q3
258
+ self.y += Math::PI
259
+ elsif x >= 0 and y < 0 # Q4
260
+ self.y += 2 * Math::PI
261
+ end
262
+ self.y = self.y * 180 / Math::PI if self.deg
263
+ rescue
264
+ return "Error"
265
+ end
266
+ end
267
+ def pr
268
+ self.l = self.x
269
+ r = self.x
270
+ t = self.y
271
+ t = t * Math::PI / 180 if self.deg
272
+ self.x = r * Math::cos(t)
273
+ self.y = r * Math::sin(t)
274
+ end
275
+ end
276
+
277
+ begin # BASIC setup
278
+ @stk = Stack.new(0, 0, 0, 0, 0)
279
+ @reg = %w[0 0 0 0 0 0 0 0 0 0]
280
+ @fix = 4
281
+ @sci = 6
282
+ @dot = true
283
+ @mod = "Deg"
284
+ @hlp = true
285
+
286
+ load(Dir.home+'/.t-rex.conf') if File.exist?(Dir.home+'/.t-rex.conf')
287
+ @mod == "Deg" ? @stk.deg = true : @stk.deg = false
288
+
289
+ @history = [" "]
290
+ @u = []
291
+ @undo = false
292
+ end
293
+
294
+ begin # PANE setup
295
+ @h, @w = IO.console.winsize
296
+
297
+ # pane = Rcurses::Pane.new( x, y, width, height, fg, bg)
298
+ @p_bck = Rcurses::Pane.new( 1, 1, @w, @h, 235, 235) # Back
299
+ @p_inf = Rcurses::Pane.new( 2, 2, 32, 1, 168, 238) # Info-line
300
+ @p_lbl = Rcurses::Pane.new( 2, 3, 1, 5, 250, 238) # LTZYX lables
301
+ @p_key = Rcurses::Pane.new( 2, 9, 32, 11, 0, 0) # Key panel
302
+ @p_reg = Rcurses::Pane.new( 2, 21, 32, @h - 21, 242, 0) # Regs
303
+ @p_hlp = Rcurses::Pane.new( 35, 2, @w - 35, @h - 2, 239, 0) # Help
304
+ @p_l = Rcurses::Pane.new( 4, 3, 30, 1, 60, 235) # L
305
+ @p_t = Rcurses::Pane.new( 4, 4, 30, 1, 68, 233) # T
306
+ @p_z = Rcurses::Pane.new( 4, 5, 30, 1, 75, 233) # Z
307
+ @p_y = Rcurses::Pane.new( 4, 6, 30, 1, 117, 233) # Y
308
+ @p_x = Rcurses::Pane.new( 4, 7, 30, 1, 7, 0) # X
309
+
310
+ @p_lbl.align = "r"
311
+ @p_l.align = "r"
312
+ @p_t.align = "r"
313
+ @p_z.align = "r"
314
+ @p_y.align = "r"
315
+ @p_x.align = "r"
316
+
317
+ @p_lbl.text = "ltzyx".i
318
+
319
+ class String
320
+ def t ; self.fg(111) ; end
321
+ def k ; self.fg(214) ; end
322
+ def s ; self.fg(242) ; end
323
+ end
324
+
325
+ keys = "\n"
326
+ keys += " r".t + "↓".k + " r".t + "↑".k + " x".t + "<".k + ">y".t
327
+ keys += " + - * / \\ %".k + " c".t + "h".k + "s".t + " p".k + "i".t
328
+ keys += "\n\n"
329
+ keys += " y√x x^2 x^3 e^x 10^x redrw".s
330
+ keys += "\n"
331
+ keys += " y".t + "^".k + "x".t + " 1/".t + "x".k + " s".t + "q".k + "rt".t
332
+ keys += " l".t + "n".k + " lo".t + "g".k + " l".k + "astx".t
333
+ keys += "\n\n"
334
+ keys += " asin acos atan R→P P→R cstk".s
335
+ keys += "\n"
336
+ keys += " s".t + "i".k + "n".t + " c".t + "o".k + "s".t + " t".t + "a".k + "n".t
337
+ keys += " r".k + "ad".t + " d".k + "eg".t + " c".k + "lx".t
338
+ keys += "\n\n"
339
+ keys += " S".k + "to".t + " R".k + "cl".t + " s".k + "ci".t + " f".k + "ix".t
340
+ keys += " u".k + "ndo".t + " H".k + "lp".t + " Q".k + "uit".t
341
+ @p_key.text = keys
342
+ end
343
+
344
+ # FUNCTIONS
345
+ def history(entry)
346
+ @history.push(entry.b, " #{@stk.t}".i, " #{@stk.z}".i, " #{@stk.y}".i, " #{@stk.x}".i.b, " ")
347
+ end
348
+ def histprint
349
+ print = @history.join("\n ")
350
+ @p_hlp.ix = 0 if @p_hlp.ix < 0
351
+ @p_hlp.fg = 145
352
+ @p_hlp.puts(print)
353
+ return print
354
+ end
355
+ def num_format(n) # THE NUMBER FORMAT FUNCTION
356
+ if n.abs >= 10 ** @sci.to_i
357
+ n = "%.#{@sci}g" % n
358
+ elsif n.abs <= 10 ** (1 / @sci.to_i) and n > 10
359
+ n = "%.#{@sci}g" % n
360
+ else
361
+ n = n.round(@fix)
362
+ n = "%.#{@fix}f" % n
363
+ m = n[/^-/]
364
+ m = "" if m == nil
365
+ n.sub!(/-/, '')
366
+ i = n[/\d*/]
367
+ i.gsub!(/(\d)(?=(\d\d\d)+(?!\d))/, "\\1,")
368
+ f = n.sub(/\d*\.(\d*)/, '\1')
369
+ n = m + i + "." + f
370
+ if not @dot
371
+ n.gsub!(/,/, ' ')
372
+ n.sub!(/\./, ',')
373
+ end
374
+ end
375
+ return n
376
+ end
377
+ def main_getkey(c) # GET KEY FROM USER
378
+ c == "" ? chr = getchr : chr = c
379
+ case chr
380
+ when 'ENTER'
381
+ @stk.l = @stk.x
382
+ @stk.y, @stk.z, @stk.t = @stk.x, @stk.y, @stk.z
383
+ history("ENTER")
384
+ when "'"
385
+ @dot = !@dot
386
+ when 'UP' # Roll stack up
387
+ @stk.rup
388
+ history("↑")
389
+ when 'DOWN' # Roll stack down
390
+ @stk.rdn
391
+ history("↓")
392
+ when '<', 'LEFT', 'RIGHT' # x<>y
393
+ @stk.xy
394
+ history("x<>y")
395
+ when '+'
396
+ @stk.add
397
+ history("+")
398
+ when '-'
399
+ @stk.subtract
400
+ history("-")
401
+ when '*'
402
+ @stk.multiply
403
+ history("*")
404
+ when '/'
405
+ e = @stk.divide
406
+ history("/")
407
+ error ("Error: Divide by zero") if e == "Error"
408
+ when '\\' # \ (modulo)
409
+ @stk.mod
410
+ history("MOD")
411
+ when '%' # 100*x/y
412
+ e = @stk.percent
413
+ history("%")
414
+ error ("Error: Divide by zero") if e == "Error"
415
+ when 'h' # Change sign
416
+ @stk.chs
417
+ history("chs")
418
+ when 'p' # pi
419
+ @stk.l = @stk.x
420
+ @stk.pi
421
+ history("pi")
422
+ when '^' # y^x
423
+ @stk.pow
424
+ history("y^x")
425
+ when 'C-^' # y^(1/x)
426
+ e = @stk.root
427
+ history("y^(1/x)")
428
+ error ("Error: Divide by zero") if e == "Error"
429
+ when 'x' # 1/x
430
+ e = @stk.recip
431
+ history("1/x")
432
+ error ("Error: Divide by zero") if e == "Error"
433
+ when 'C-X' # x^2
434
+ @stk.sqr
435
+ history("x^2")
436
+ when 'q' # Square root
437
+ e = @stk.sqrt
438
+ history("sqrt")
439
+ error ("Error: Imaginary number") if e == "Error"
440
+ when 'C-Q' # x^3
441
+ @stk.cube
442
+ history("x^3")
443
+ when 'n' # ln(x)
444
+ e = @stk.ln
445
+ history("ln")
446
+ error ("Error: Negative x") if e == "Error"
447
+ when 'C-N' # e^x
448
+ @stk.ex
449
+ history("e^x")
450
+ when 'g' # log(x)
451
+ e = @stk.log
452
+ history("log")
453
+ error ("Error: Negative x") if e == "Error"
454
+ when 'C-G' # 10^x
455
+ @stk.tenx
456
+ history("10^x")
457
+ when 'l' # Recall Lastx (l) to x
458
+ @stk.lift
459
+ @stk.x = @stk.l
460
+ history("lastx")
461
+ when 'C-L' # Redraw
462
+ refresh
463
+ when 'i'
464
+ @stk.sin
465
+ history("sin")
466
+ when 'TAB' # Same as 'C-I'
467
+ e = @stk.asin
468
+ history("asin")
469
+ error ("Error: Number out of domain") if e == "Error"
470
+ when 'o'
471
+ @stk.cos
472
+ history("cos")
473
+ when 'C-O'
474
+ e = @stk.acos
475
+ history("acos")
476
+ error ("Error: Number out of domain") if e == "Error"
477
+ when 'a'
478
+ @stk.tan
479
+ history("tan")
480
+ when 'C-A'
481
+ @stk.atan
482
+ history("atan")
483
+ when 'r' # Rad mode
484
+ @mod = "Rad"
485
+ @stk.deg = false
486
+ history("Rad")
487
+ when 'C-R' # R->P
488
+ e = @stk.rp
489
+ history("R->P")
490
+ error ("Error: Divide by zero") if e == "Error"
491
+ when 'd' # Deg mode
492
+ @mod = "Deg"
493
+ @stk.deg = true
494
+ history("Deg")
495
+ when 'C-D' # P->R
496
+ @stk.pr
497
+ history("P->R")
498
+ when 'c', 'BACK'
499
+ @stk.x = 0
500
+ when 'C-C' # Clear stack
501
+ @stk.x = 0
502
+ @stk.y = 0
503
+ @stk.z = 0
504
+ @stk.t = 0
505
+ @stk.l = 0
506
+ history("CLR")
507
+ when 'M'
508
+ @reg = %w[0 0 0 0 0 0 0 0 0 0]
509
+ when 'S' # Store to Reg
510
+ @p_x.puts(" Store x in Reg #(0-9)")
511
+ r = getchr
512
+ if r =~ /[0-9]/
513
+ @reg[r.to_i] = @stk.x
514
+ end
515
+ history("STO #{r}")
516
+ when 'R' # Recall from Reg
517
+ @p_x.puts(" Recall from Reg #(0-9)")
518
+ r = getchr
519
+ if r =~ /[0-9]/
520
+ @stk.lift
521
+ @stk.x = @reg[r.to_i].to_f
522
+ end
523
+ history("RCL #{r}")
524
+ when 's' # Set Sci size/limit
525
+ @p_x.puts(" Sci notation limit (2-9)")
526
+ s = getchr
527
+ if s =~ /[2-9]/
528
+ @sci = s.to_i
529
+ end
530
+ history("Sci #{s}")
531
+ when 'f' # Set Fix size
532
+ @p_x.puts(" Fixed decimals (0-9)")
533
+ f = getchr
534
+ if f =~ /[0-9]/
535
+ @fix = f.to_i
536
+ end
537
+ history("Fix #{f}")
538
+ when 'u' # Undo
539
+ unless @u.empty?
540
+ @stk = @u.last.dup
541
+ @u.pop
542
+ @undo = true
543
+ end
544
+ history("UNDO")
545
+ when 'y'
546
+ begin
547
+ @p_x.bg = 250
548
+ @p_x.refresh
549
+ system("echo '#{@stk.x}' | xclip")
550
+ sleep(0.1)
551
+ @p_x.bg = 0
552
+ @p_x.refresh
553
+ rescue
554
+ @p_x.text = " Install xclip to yank"
555
+ @p_x.refresh
556
+ getchr
557
+ end
558
+ when 'Y'
559
+ begin
560
+ @p_x.bg = 244
561
+ @p_x.refresh
562
+ mem = ""
563
+ 10.times do |i|
564
+ reg = @reg[i]
565
+ mem += "#{reg}\n"
566
+ end
567
+ system("echo '#{mem}' | xclip")
568
+ sleep(0.1)
569
+ @p_x.bg = 0
570
+ @p_x.refresh
571
+ rescue
572
+ @p_x.text = " Install xclip to yank"
573
+ @p_x.refresh
574
+ getchr
575
+ end
576
+ when 'H' # Toggle help/histprint
577
+ @hlp = !@hlp
578
+ when 'C-B'
579
+ if !@hlp
580
+ loop do
581
+ @p_hlp.ix -= @h + 3
582
+ histprint
583
+ break if getchr != 'C-B'
584
+ end
585
+ end
586
+ when 'C-P'
587
+ cont = histprint.pure
588
+ File.write(Dir.home+'/t-rex.txt', cont)
589
+ error ("History written to t-rex.txt")
590
+ when '@' # Ruby console
591
+ @p_hlp.fg = 168
592
+ loop do
593
+ @p_hlp.puts("")
594
+ @p_hlp.prompt = " Ruby: "
595
+ @p_hlp.editline
596
+ Rcurses::Cursor.set(4,36)
597
+ x = @stk.x
598
+ y = @stk.y
599
+ z = @stk.z
600
+ t = @stk.t
601
+ l = @stk.l
602
+ begin
603
+ eval(@p_hlp.text)
604
+ rescue
605
+ end
606
+ break if getchr == "ESC"
607
+ end
608
+ @p_hlp.fg = 239
609
+ getchr
610
+ @hlp ? help : @p_hlp.puts("")
611
+ when 'Q' # QUIT
612
+ exit 0
613
+ when /[0-9.,]/ # Go to entry mode for x
614
+ @stk.lift
615
+ pstack
616
+ number, c = entry(chr)
617
+ if number != ""
618
+ @stk.l = @stk.x
619
+ @stk.lift unless @stk.x == 0
620
+ @stk.x = number
621
+ end
622
+ history(number.to_s)
623
+ @stk.drop if c == "ENTER"
624
+ if %w[< + - * / \ % ^ x C-X q C-Q n C-N g C-G i C-I o C-O a C-A c C-C].include?(c)
625
+ @stk.drop
626
+ main_getkey(c)
627
+ end
628
+ end
629
+ end
630
+ def entry(chr) # X REGISTER ENTRY
631
+ num = chr
632
+ pos = 1
633
+ Rcurses::Cursor.set(7,33)
634
+ Rcurses::Cursor.show
635
+ while %w[0 1 2 3 4 5 6 7 8 9 . , h RIGHT LEFT HOME END DEL BACK WBACK LDEL].include?(chr)
636
+ @p_x.puts(num)
637
+ chr = getchr
638
+ case chr
639
+ when 'RIGHT'
640
+ pos += 1 unless pos >= num.length
641
+ when 'LEFT'
642
+ pos -= 1 unless pos == 0
643
+ when 'HOME'
644
+ pos = 0
645
+ when 'END'
646
+ pos = num.length
647
+ when 'DEL'
648
+ unless pos == 0
649
+ pos -= 1
650
+ num[pos] = ""
651
+ end
652
+ when 'BACK'
653
+ unless pos == 0
654
+ pos -= 1
655
+ num[pos - 1] = ""
656
+ end
657
+ when 'WBACK'
658
+ unless pos == 0
659
+ until num[pos - 1] == " " or pos == 0
660
+ pos -= 1
661
+ num[pos] = ""
662
+ end
663
+ if num[pos - 1] == " "
664
+ pos -= 1
665
+ num[pos] = ""
666
+ end
667
+ end
668
+ when 'LDEL'
669
+ num = ""
670
+ pos = 0
671
+ when 'h'
672
+ if num[0] == "-"
673
+ num[0] = ""
674
+ pos -= 1
675
+ else
676
+ num.insert(0, "-")
677
+ pos += 1
678
+ end
679
+ when /[0-9.,]/
680
+ num.insert(pos,chr)
681
+ pos += 1
682
+ end
683
+ Rcurses::Cursor.col(33 - num.length + pos)
684
+ end
685
+ num = "" if %w[DOWN UP].include?(chr)
686
+ num.gsub!(/,/, '.')
687
+ num != "" ? number = num.to_f : number = ""
688
+ Rcurses::Cursor.hide
689
+ return number, chr
690
+ end
691
+ def refresh # REFRESH ALL PANES
692
+ @p_bck.refresh
693
+ @p_inf.refresh
694
+ @p_lbl.refresh
695
+ @p_key.refresh
696
+ @p_reg.refresh
697
+ help
698
+ @p_l.refresh
699
+ @p_t.refresh
700
+ @p_z.refresh
701
+ @p_y.refresh
702
+ @p_x.refresh
703
+ end
704
+ def pstack # PRINT STACK (XYZTL)
705
+ @p_l.puts(num_format(@stk.l))
706
+ @p_t.puts(num_format(@stk.t))
707
+ @p_z.puts(num_format(@stk.z))
708
+ @p_y.puts(num_format(@stk.y))
709
+ @p_x.puts(num_format(@stk.x).b)
710
+ end
711
+ def pregs # PRINT CONTENT OF REGS (0-9)
712
+ @p_reg.text = "\n"
713
+ 10.times do |i|
714
+ r = num_format(@reg[i].to_f)
715
+ @p_reg.text += " R##{i}".i + "#{r}".rjust(27) + "\n"
716
+ end
717
+ @p_reg.refresh
718
+ end
719
+ def error(err) # PRINT ERRORS TO X
720
+ @p_x.puts(err)
721
+ @history.insert(-2, err)
722
+ getchr
723
+ end
724
+ def conf_write # WRITE TO .t-rex.conf
725
+ conf = "@fix = #{@fix}\n"
726
+ conf += "@sci = #{@sci}\n"
727
+ @dot ? d = "true" : d = "false"
728
+ conf += "@dot = #{d}\n"
729
+ conf += "@mod = \"#{@mod}\"\n"
730
+ conf += "@stk = Stack.new(#{@stk.x}, #{@stk.y}, #{@stk.z}, #{@stk.t}, #{@stk.l})\n"
731
+ conf += "@reg = %w[#{@reg[0]} #{@reg[1]} #{@reg[2]} #{@reg[3]} #{@reg[4]} #{@reg[5]} #{@reg[6]} #{@reg[7]} #{@reg[8]} #{@reg[9]}]\n"
732
+ @hlp ? h = "true" : h = "false"
733
+ conf += "@hlp = #{h}\n"
734
+ File.write(Dir.home+'/.t-rex.conf', conf)
735
+ end
736
+
737
+ # MAIN PROGRAM
738
+ refresh
739
+ Rcurses::Cursor.hide
740
+ begin # Capture main loop
741
+ loop do # Main loop
742
+ @p_inf.puts(" #{@mod} Sci=#{@sci} Fix=#{@fix}".i)
743
+ pstack
744
+ pregs
745
+ @t = @stk.dup
746
+ main_getkey("") # Get key input from user
747
+ help
748
+ @u.push(@t.dup) if @t != @stk and @undo == false
749
+ @undo = false
750
+ h1, w1 = IO.console.winsize
751
+ if h1 != @h or w1 != @w # Refresh on terminal resize
752
+ @h, @w = IO.console.winsize
753
+ refresh
754
+ end
755
+ end
756
+ ensure # Write to .t-rex.conf on exit
757
+ conf_write
758
+ end
759
+
760
+ # vim: set sw=2 sts=2 et fdm=syntax fdn=2 fcs=fold\:\ :