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.rb DELETED
@@ -1,880 +0,0 @@
1
- #!/usr/bin/env ruby
2
- # encoding: utf-8
3
-
4
- require 'io/console'
5
- require 'curses'
6
- include Curses
7
-
8
- # CLASSES
9
- class Curses::Window # CLASS EXTENSION
10
- # General extensions (see https://github.com/isene/Ruby-Curses-Class-Extension)
11
- attr_accessor :color, :fg, :bg, :attr
12
- # Set self.color for an already defined color pair such as: init_pair(1, 255, 3)
13
- # The color pair is defined like this: init_pair(index, foreground, background)
14
- # self.fg is set for the foreground color (and is used if self.color is not set)
15
- # self.bg is set for the background color (and is used if self.color is not set)
16
- # self.attr is set for text attributes like Curses::A_BOLD
17
- def clr # Clears the whole window
18
- self.setpos(0, 0)
19
- self.maxy.times {self.deleteln()}
20
- self.refresh
21
- self.setpos(0, 0)
22
- end
23
- def fill # Fill window with color as set by self.color (or self.bg if not set)
24
- self.setpos(0, 0)
25
- self.fill_from_cur_pos
26
- end
27
- def fill_from_cur_pos # Fills the rest of the window from current line
28
- x = curx
29
- y = cury
30
- self.setpos(y, 0)
31
- blank = " " * self.maxx
32
- if self.color == nil
33
- self.bg = 0 if self.bg == nil
34
- self.fg = 255 if self.fg == nil
35
- init_pair(self.fg, self.fg, self.bg)
36
- self.maxy.times {self.attron(color_pair(self.fg)) {self << blank}}
37
- else
38
- self.maxy.times {self.attron(color_pair(self.color)) {self << blank}}
39
- end
40
- self.refresh
41
- self.setpos(y, x)
42
- end
43
- def fill_to_cur_pos # Fills the window up to current line
44
- x = curx
45
- y = cury
46
- self.setpos(0, 0)
47
- blank = " " * self.maxx
48
- if self.color == nil
49
- self.bg = 0 if self.bg == nil
50
- self.fg = 255 if self.fg == nil
51
- init_pair(self.fg, self.fg, self.bg)
52
- y.times {self.attron(color_pair(self.fg)) {self << blank}}
53
- else
54
- y.times {self.attron(color_pair(self.color)) {self << blank}}
55
- end
56
- self.refresh
57
- self.setpos(y, x)
58
- end
59
- def p(text) # Puts text to window
60
- self.attr = 0 if self.attr == nil
61
- if self.color == nil
62
- self.bg = 0 if self.bg == nil
63
- self.fg = 255 if self.fg == nil
64
- init_pair(self.fg, self.fg, self.bg)
65
- self.attron(color_pair(self.fg) | self.attr) { self << text }
66
- else
67
- self.attron(color_pair(self.color) | self.attr) { self << text }
68
- end
69
- self.refresh
70
- end
71
- end
72
- class Stack
73
- attr_accessor :x, :y, :z, :t, :l, :deg
74
-
75
- def initialize(x, y, z, t, l)
76
- self.x = x.to_f
77
- self.y = y.to_f
78
- self.z = z.to_f
79
- self.t = t.to_f
80
- self.l = l.to_f
81
- end
82
- def lift
83
- self.y, self.z, self.t = self.x, self.y, self.z
84
- end
85
- def drop
86
- self.y, self.z = self.z, self.t
87
- end
88
- def rdn
89
- self.x, self.y, self.z, self.t = self.y, self.z, self.t, self.x
90
- end
91
- def rup
92
- self.x, self.y, self.z, self.t = self.t, self.x, self.y, self.z
93
- end
94
- def xy
95
- self.x, self.y = self.y, self.x
96
- end
97
- def add
98
- self.l = self.x
99
- self.x = self.y + self.x
100
- self.drop
101
- end
102
- def subtract
103
- self.l = self.x
104
- self.x = self.y - self.x
105
- self.drop
106
- end
107
- def multiply
108
- self.l = self.x
109
- self.x = self.y * self.x
110
- self.drop
111
- end
112
- def divide
113
- begin
114
- throw if self.x == 0
115
- self.l = self.x
116
- self.x = self.y / self.x
117
- self.drop
118
- rescue
119
- return "Error"
120
- end
121
- end
122
- def mod
123
- begin
124
- throw if self.x == 0
125
- self.l = self.x
126
- self.x = self.y % self.x
127
- self.drop
128
- rescue
129
- return "Error"
130
- end
131
- end
132
- def percent
133
- begin
134
- throw if self.y == 0
135
- self.l = self.x
136
- self.x = 100*(self.x / self.y)
137
- self.drop
138
- rescue
139
- return "Error"
140
- end
141
- end
142
- def chs
143
- self.x = -self.x
144
- end
145
- def pi
146
- self.l = self.x
147
- self.lift
148
- self.x = Math::PI
149
- end
150
- def pow
151
- self.l = self.x
152
- self.x = self.y ** self.x
153
- self.drop
154
- end
155
- def root
156
- begin
157
- self.l = self.x
158
- self.x = self.y ** (1 / self.x)
159
- self.drop
160
- rescue
161
- return "Error"
162
- end
163
- end
164
- def recip
165
- begin
166
- throw if self.x == 0
167
- self.l = self.x
168
- self.x = 1 / self.x
169
- rescue
170
- return "Error"
171
- end
172
- end
173
- def sqr
174
- self.l = self.x
175
- self.x = self.x ** 2
176
- end
177
- def sqrt
178
- self.l = self.x
179
- begin
180
- self.x = Math::sqrt(self.x)
181
- rescue
182
- return "Error"
183
- end
184
- end
185
- def cube
186
- self.l = self.x
187
- self.x = self.x ** 3
188
- end
189
- def ln
190
- self.l = self.x
191
- begin
192
- self.x = Math::log(self.x)
193
- rescue
194
- return "Error"
195
- end
196
- end
197
- def ex
198
- self.l = self.x
199
- self.x = Math::exp(self.x)
200
- end
201
- def log
202
- self.l = self.x
203
- begin
204
- self.x = Math::log10(self.x)
205
- rescue
206
- return "Error"
207
- end
208
- end
209
- def tenx
210
- self.l = self.x
211
- self.x = 10 ** self.x
212
- end
213
- def sin
214
- self.l = self.x
215
- self.x = self.x * Math::PI / 180 if self.deg
216
- self.x = Math::sin(self.x)
217
- end
218
- def cos
219
- self.l = self.x
220
- self.x = self.x * Math::PI / 180 if self.deg
221
- self.x = Math::cos(self.x)
222
- end
223
- def tan
224
- self.l = self.x
225
- self.x = self.x * Math::PI / 180 if self.deg
226
- self.x = Math::tan(self.x)
227
- end
228
- def asin
229
- self.l = self.x
230
- self.x = Math::asin(self.x)
231
- self.x = self.x * 180 / Math::PI if self.deg
232
- end
233
- def acos
234
- self.l = self.x
235
- self.x = Math::acos(self.x)
236
- self.x = self.x * 180 / Math::PI if self.deg
237
- end
238
- def atan
239
- self.l = self.x
240
- self.x = Math::atan(self.x)
241
- self.x = self.x * 180 / Math::PI if self.deg
242
- end
243
- def rp
244
- begin
245
- throw if self.x == 0
246
- self.l = self.x
247
- x = self.x
248
- y = self.y
249
- self.x = Math::sqrt(x*x + y*y)
250
- self.y = Math::atan(y/x)
251
- if x < 0 # Q2 & Q3
252
- self.y += Math::PI
253
- elsif x >= 0 and y < 0 # Q4
254
- self.y += 2 * Math::PI
255
- end
256
- self.y = self.y * 180 / Math::PI if self.deg
257
- rescue
258
- return "Error"
259
- end
260
- end
261
- def pr
262
- self.l = self.x
263
- r = self.x
264
- t = self.y
265
- t = t * Math::PI / 180 if self.deg
266
- self.x = r * Math::cos(t)
267
- self.y = r * Math::sin(t)
268
- end
269
- end
270
-
271
- begin # BASIC SETUP
272
- @stk = Stack.new(0, 0, 0, 0, 0)
273
- @reg = %w[0 0 0 0 0 0 0 0 0 0]
274
- @fix = 4
275
- @sci = 6
276
- @dot = true
277
- @mod = "Deg"
278
- @hlp = true
279
-
280
- load(Dir.home+'/.t-rex.conf') if File.exist?(Dir.home+'/.t-rex.conf')
281
- @mod == "Deg" ? @stk.deg = true : @stk.deg = false
282
-
283
- @history = [""]
284
-
285
- Curses.init_screen
286
- Curses.start_color
287
- Curses.curs_set(0)
288
- Curses.noecho
289
- Curses.cbreak
290
- Curses.stdscr.keypad = true
291
- end
292
-
293
- # FUNCTIONS
294
- def getchr # PROCESS KEY PRESSES
295
- c = STDIN.getch(min: 0, time: 1)
296
- case c
297
- when "\e" # ANSI escape sequences
298
- case $stdin.getc
299
- when '[' # CSI
300
- case $stdin.getc
301
- when 'A' then chr = "UP"
302
- when 'B' then chr = "DOWN"
303
- when 'C' then chr = "RIGHT"
304
- when 'D' then chr = "LEFT"
305
- when 'Z' then chr = "S-TAB"
306
- when '2' then chr = "INS" ; STDIN.getc
307
- when '3' then chr = "DEL" ; STDIN.getc
308
- when '5' then chr = "PgUP" ; STDIN.getc
309
- when '6' then chr = "PgDOWN" ; STDIN.getc
310
- when '7' then chr = "HOME" ; STDIN.getc
311
- when '8' then chr = "END" ; STDIN.getc
312
- end
313
- end
314
- when "", "" then chr = "BACK"
315
- when "" then chr = "WBACK"
316
- when "" then chr = "LDEL"
317
- when "" then chr = "C-X"
318
- when "" then chr = "C-Q"
319
- when "" then chr = "C-N"
320
- when "" then chr = "C-G"
321
- when " " then chr = "C-L"
322
- when " " then chr = "C-I"
323
- when "" then chr = "C-O"
324
- when "" then chr = "C-A"
325
- when "" then chr = "C-R"
326
- when "" then chr = "C-D"
327
- when "" then chr = "C-C"
328
- when "" then chr = "C-T"
329
- when "" then chr = "C-^"
330
- when "\r" then chr = "ENTER"
331
- when "\t" then chr = "TAB"
332
- when /./ then chr = c
333
- end
334
- return chr
335
- end
336
- def main_getkey(c) # GET KEY FROM USER
337
- c == "" ? chr = getchr : chr = c
338
- case chr
339
- when 'ENTER'
340
- @stk.l = @stk.x
341
- @stk.y, @stk.z, @stk.t = @stk.x, @stk.y, @stk.z
342
- when "'"
343
- @dot = !@dot
344
- when 'UP' # Roll stack up
345
- @stk.rup
346
- when 'DOWN' # Roll stack down
347
- @stk.rdn
348
- when '<', 'LEFT', 'RIGHT' # x<>y
349
- @stk.xy
350
- when '+'
351
- @stk.add
352
- when '-'
353
- @stk.subtract
354
- when '*'
355
- @stk.multiply
356
- when '/'
357
- e = @stk.divide
358
- error ("Error: Divide by zero") if e == "Error"
359
- when '\\' # \ (modulo)
360
- @stk.mod
361
- when '%' # 100*x/y
362
- e = @stk.percent
363
- error ("Error: Divide by zero") if e == "Error"
364
- when 'h' # Change sign
365
- @stk.chs
366
- when 'p' # pi
367
- @stk.l = @stk.x
368
- @stk.pi
369
- when '^' # y^x
370
- @stk.pow
371
- when 'C-^' # y^(1/x)
372
- e = @stk.root
373
- error ("Error: Divide by zero") if e == "Error"
374
- when 'x' # 1/x
375
- e = @stk.recip
376
- error ("Error: Divide by zero") if e == "Error"
377
- when 'C-X' # x^2
378
- @stk.sqr
379
- when 'q' # Square root
380
- e = @stk.sqrt
381
- error ("Error: Imaginary number") if e == "Error"
382
- when 'C-Q' # x^3
383
- @stk.cube
384
- when 'n' # ln(x)
385
- e = @stk.ln
386
- error ("Error: Negative x") if e == "Error"
387
- when 'C-N' # e^x
388
- @stk.ex
389
- when 'g' # log(x)
390
- e = @stk.log
391
- error ("Error: Negative x") if e == "Error"
392
- when 'C-G' # 10^x
393
- @stk.tenx
394
- when 'l' # Recall Lastx (l) to x
395
- @stk.lift
396
- @stk.x = @stk.l
397
- when 'C-L' # Break/redraw
398
- @break = true
399
- when 'i'
400
- @stk.sin
401
- when 'C-I'
402
- @stk.asin
403
- when 'o'
404
- @stk.cos
405
- when 'C-O'
406
- @stk.acos
407
- when 'a'
408
- @stk.tan
409
- when 'C-A'
410
- @stk.atan
411
- when 'r' # Rad mode
412
- @mod = "Rad"
413
- @stk.deg = false
414
- when 'C-R' # R->P
415
- e = @stk.rp
416
- error ("Error: Divide by zero") if e == "Error"
417
- when 'd' # Deg mode
418
- @mod = "Deg"
419
- @stk.deg = true
420
- when 'C-D' # P->R
421
- @stk.pr
422
- when 'c', 'BACK'
423
- @stk.x = 0
424
- when 'C-C' # Clear stack
425
- @stk.x = 0
426
- @stk.y = 0
427
- @stk.z = 0
428
- @stk.t = 0
429
- @stk.l = 0
430
- when 'M'
431
- @reg = %w[0 0 0 0 0 0 0 0 0 0]
432
- when 'S' # Store to Reg
433
- @w_x.clr
434
- @w_x.p(" Store x in Reg #(0-9)")
435
- r = getchr
436
- if r =~ /[0-9]/
437
- @reg[r.to_i] = @stk.x
438
- end
439
- when 'R' # Recall from Reg
440
- @w_x.clr
441
- @w_x.p(" Recall from Reg #(0-9)")
442
- r = getchr
443
- if r =~ /[0-9]/
444
- @stk.lift
445
- @stk.x = @reg[r.to_i].to_f
446
- end
447
- when 's' # Set Sci size/limit
448
- @w_x.clr
449
- @w_x.p(" Sci notation limit (2-9)")
450
- r = getchr
451
- if r =~ /[2-9]/
452
- @sci = r.to_i
453
- end
454
- when 'f' # Set Fix size
455
- @w_x.clr
456
- @w_x.p(" Fixed decimals (0-9)")
457
- r = getchr
458
- if r =~ /[0-9]/
459
- @fix = r.to_i
460
- end
461
- when 'u' # Undo
462
- unless @u.empty?
463
- @stk = @u.last.dup
464
- @u.pop
465
- @undo = true
466
- end
467
- when 'y'
468
- begin
469
- @w_x.color = 7
470
- @w_x.fill
471
- system("echo '#{@stk.x}' | xclip")
472
- sleep(0.1)
473
- @w_x.color = 6
474
- rescue
475
- @w_x.clr
476
- @w_x.p(" Install xclip to yank")
477
- getchr
478
- end
479
- when 'Y'
480
- begin
481
- @w_x.color = 5
482
- @w_x.fill
483
- mem = ""
484
- 10.times do |i|
485
- reg = @reg[i]
486
- mem += "#{reg}\n"
487
- end
488
- system("echo '#{mem}' | xclip")
489
- sleep(0.1)
490
- @w_x.color = 6
491
- rescue
492
- @w_x.clr
493
- @w_x.p(" Install xclip to yank")
494
- getchr
495
- end
496
- when 'H'
497
- @hlp = !@hlp
498
- @w_hlp.fill
499
- help if @hlp
500
- when '@' # Ruby console
501
- @w_hlp.fill
502
- console(" Ruby: ")
503
- @w_hlp.fill
504
- help if @hlp
505
- when 'Q' # Exit
506
- exit 0
507
- when /[0-9.,-]/ # Go to entry mode for x
508
- number, c = entry(chr)
509
- if number != ""
510
- @stk.l = @stk.x
511
- @stk.lift unless @stk.x == 0
512
- @stk.x = number
513
- end
514
- main_getkey(c) 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)
515
- end
516
- end
517
- def console(pretext) # A SIMPLE READLINE-LIKE ROUTINE
518
- Curses.curs_set(1)
519
- Curses.echo
520
- @w_hlp.color = 9
521
- stk = 0
522
- pos = @history[stk].length
523
- @w_hlp.setpos(0,0)
524
- chr = ""
525
- while chr != "C-C"
526
- @w_hlp.setpos(@w_hlp.cury,0)
527
- text = pretext + @history[stk]
528
- text += " " * (@w_hlp.maxx - text.length) if text.length < @w_hlp.maxx
529
- @w_hlp.p(text)
530
- @w_hlp.setpos(0,pretext.length + pos)
531
- @w_hlp.refresh
532
- chr = getchr
533
- case chr
534
- when 'UP'
535
- unless stk == @history.length - 1
536
- stk += 1
537
- pos = @history[stk].length
538
- end
539
- when 'DOWN'
540
- unless stk == 0
541
- stk -= 1
542
- pos = @history[stk].length
543
- end
544
- when 'RIGHT'
545
- pos += 1 unless pos > @history[stk].length
546
- when 'LEFT'
547
- pos -= 1 unless pos == 0
548
- when 'HOME'
549
- pos = 0
550
- when 'END'
551
- pos = @history[stk].length
552
- when 'DEL'
553
- @history[stk][pos] = ""
554
- when 'BACK'
555
- unless pos == 0
556
- pos -= 1
557
- @history[stk][pos] = ""
558
- end
559
- when 'WBACK'
560
- unless pos == 0
561
- until @history[stk][pos - 1] == " " or pos == 0
562
- pos -= 1
563
- @history[stk][pos] = ""
564
- end
565
- if @history[stk][pos - 1] == " "
566
- pos -= 1
567
- @history[stk][pos] = ""
568
- end
569
- end
570
- when 'LDEL'
571
- @history[stk] = ""
572
- pos = 0
573
- when /^.$/
574
- @history[stk].insert(pos,chr)
575
- pos += 1
576
- when 'ENTER'
577
- @w_hlp.fill
578
- @w_hlp.p(text)
579
- @w_hlp.setpos(0,pretext.length + pos)
580
- @w_hlp.refresh
581
- @w_hlp.p("\n ")
582
- curstr = @history[stk]
583
- @history.uniq!
584
- @history.compact!
585
- @history.delete("")
586
- begin
587
- x = @stk.x
588
- y = @stk.y
589
- z = @stk.z
590
- t = @stk.t
591
- l = @stk.l
592
- eval(curstr)
593
- @stk.x = x
594
- @stk.y = y
595
- @stk.z = z
596
- @stk.t = t
597
- @stk.l = l
598
- @w_hlp.p("\n\n")
599
- pstack
600
- rescue StandardError => e
601
- @w_hlp.p("\n Error: #{e.inspect}\n")
602
- end
603
- @history.unshift("")
604
- stk = 0
605
- pos = @history[stk].length
606
- chr = ""
607
- @w_hlp.setpos(0,0)
608
- end
609
- end
610
- @w_hlp.color = 11
611
- Curses.curs_set(0)
612
- Curses.noecho
613
- end
614
- def entry(chr)
615
- Curses.curs_set(1)
616
- Curses.echo
617
- num = chr
618
- pos = 1
619
- @w_x.color = 7
620
- while %w[0 1 2 3 4 5 6 7 8 9 . , h RIGHT LEFT HOME END DEL BACK WBACK LDEL].include?(chr)
621
- @w_x.clr
622
- @w_x.setpos(0,0)
623
- @w_x.p(num)
624
- @w_x.setpos(0,pos)
625
- @w_x.refresh
626
- chr = getchr
627
- case chr
628
- when 'RIGHT'
629
- pos += 1 unless pos >= num.length
630
- when 'LEFT'
631
- pos -= 1 unless pos == 0
632
- when 'HOME'
633
- pos = 0
634
- when 'END'
635
- pos = num.length
636
- when 'DEL'
637
- num[pos] = ""
638
- when 'BACK'
639
- unless pos == 0
640
- pos -= 1
641
- num[pos] = ""
642
- end
643
- when 'WBACK'
644
- unless pos == 0
645
- until num[pos - 1] == " " or pos == 0
646
- pos -= 1
647
- num[pos] = ""
648
- end
649
- if num[pos - 1] == " "
650
- pos -= 1
651
- num[pos] = ""
652
- end
653
- end
654
- when 'LDEL'
655
- num = ""
656
- pos = 0
657
- when 'h'
658
- if num[0] == "-"
659
- num[0] = ""
660
- pos -= 1
661
- else
662
- num.insert(0, "-")
663
- pos += 1
664
- end
665
- when /[0-9.,]/
666
- num.insert(pos,chr)
667
- pos += 1
668
- end
669
- end
670
- num = "" if %w[DOWN UP].include?(chr)
671
- num.gsub!(/,/, '.')
672
- num != "" ? number = num.to_f : number = ""
673
- Curses.curs_set(0)
674
- Curses.noecho
675
- @w_x.color = 6
676
- return number, chr
677
- end
678
- def num_format(n)
679
- if n.abs >= 10 ** @sci.to_i
680
- n = "%.#{@sci}g" % n
681
- elsif n.abs <= 10 ** (1 / @sci.to_i) and n > 10
682
- n = "%.#{@sci}g" % n
683
- else
684
- n = n.round(@fix)
685
- n = "%.#{@fix}f" % n
686
- m = n[/^-/]
687
- m = "" if m == nil
688
- n.sub!(/-/, '')
689
- i = n[/\d*/]
690
- i.gsub!(/(\d)(?=(\d\d\d)+(?!\d))/, "\\1,")
691
- f = n.sub(/\d*\.(\d*)/, '\1')
692
- n = m + i + "." + f
693
- if not @dot
694
- n.gsub!(/,/, ' ')
695
- n.sub!(/\./, ',')
696
- end
697
- end
698
- return n
699
- end
700
- def pstack
701
- x = num_format(@stk.x)
702
- y = num_format(@stk.y)
703
- z = num_format(@stk.z)
704
- t = num_format(@stk.t)
705
- l = num_format(@stk.l)
706
- @w_l.setpos(0,0)
707
- @w_l.p(l.rjust(30))
708
- @w_yzt.setpos(0,0)
709
- @w_yzt.p(t.rjust(30) + z.rjust(30) + y.rjust(30))
710
- @w_x.setpos(0,0)
711
- @w_x.p(x.rjust(30))
712
- end
713
- def pregs
714
- @w_reg.setpos(1,0)
715
- 10.times do |i|
716
- r = num_format(@reg[i].to_f)
717
- @w_reg.p(" R##{i}" + "#{r}".rjust(27) + " ")
718
- end
719
- end
720
- def error(err)
721
- @w_x.clr
722
- @w_x.p(err.rjust(30))
723
- getchr
724
- end
725
- def cmd
726
- text = <<CMDTEXT
727
-
728
- r|↓| r|↑| x|<|>y |+| |-| |*| |/| |\\| |%| c|h|s |p|i
729
- y√x x^2 x^3 e^x 10^x redrw
730
- y|^|x 1/|x| s|q|rt l|n| lo|g| |l|astx
731
- asin acos atan R→P P→R cstk
732
- s|i|n c|o|s t|a|n |r|ad |d|eg |c|lx
733
-
734
- |S|to |R|cl |s|ci |f|ix |u|ndo |H|lp |Q|uit
735
- CMDTEXT
736
- text = text.split("\n")
737
- text.each_with_index do |t,i|
738
- if i.even?
739
- @w_cmd.color = 8
740
- @w_cmd.p(t)
741
- else
742
- t = t.split("|")
743
- t.each_with_index do |c,j|
744
- if j.even?
745
- @w_cmd.color = 9
746
- @w_cmd.p(c)
747
- else
748
- @w_cmd.color = 10
749
- @w_cmd.p(c)
750
- end
751
- end
752
- @w_cmd.p("\n")
753
- end
754
- @w_cmd.p("\n")
755
- end
756
- end
757
- def help
758
- help = <<HELPTEXT
759
-
760
- T-REX - Terminal Rpn calculator EXperiment. GitHub: https://github.com/isene/T-REX
761
-
762
- This is a Reverse Polish Notation calculator similar to the traditional Hewlett
763
- Packard calculators. See https://www.hpmuseum.org/rpn.htm for info on RPN.
764
-
765
- The stack is shown to the top left. The X, Y, Z and T registers comprise the
766
- operating stack. L is the "Last X" register showing the previous value in X.
767
- Toggle US and European number formats by pressing '.
768
-
769
- Functions available are shown under the stack registers. The orange symbol
770
- corresponds to the key to be pressed. For functions above each label (grey
771
- functions), press the Control key (Ctrl) and the orange key (asin = Ctrl+i).
772
-
773
- For Rectangular to Polar conversions:
774
- R-P: X value in x, Y in y - yields "θ" in y and "r" in x.
775
- P-R: "θ" in y and "r" in x - yeilds X in x and Y in y.
776
-
777
- Use the "f" key to set the fixed number of decimal places. Use the "s" key to set
778
- the limit for viewing numbers in the "scientific" notation (e.g. 5e+06 for 5000000).
779
-
780
- Content of registers #0-#9 are shown below the functions.
781
- Store/recall using capital "S"/"R". "M" clears the regs.
782
-
783
- Copy/yank the X register to clipboard with "y". Use "Y" to yank all the memory regs.
784
-
785
- You can undo all the way to the beginning of the session.
786
-
787
- The 'H' key toggles the help text in the right pane.
788
-
789
- The stack, register contents, modes and help text settings are saved on Quit.
790
-
791
- Additionally, for a world of possibilities, you can access the "Ruby mode" via '@'.
792
- Here you can address the stack directly, e.g. x = y + (z / t). Quit Ruby mode with Ctrl-C.
793
-
794
- HELPTEXT
795
- @w_hlp.p(help)
796
- end
797
- def conf_write # WRITE TO .t-rex.conf
798
- conf = "@fix = #{@fix}\n"
799
- conf += "@sci = #{@sci}\n"
800
- @dot ? d = "true" : d = "false"
801
- conf += "@dot = #{d}\n"
802
- conf += "@mod = \"#{@mod}\"\n"
803
- conf += "@stk = Stack.new(#{@stk.x}, #{@stk.y}, #{@stk.z}, #{@stk.t}, #{@stk.l})\n"
804
- conf += "@reg = %w[#{@reg[0]} #{@reg[1]} #{@reg[2]} #{@reg[3]} #{@reg[4]} #{@reg[5]} #{@reg[6]} #{@reg[7]} #{@reg[8]} #{@reg[9]}]\n"
805
- @hlp ? h = "true" : h = "false"
806
- conf += "@hlp = #{h}\n"
807
- File.write(Dir.home+'/.t-rex.conf', conf)
808
- end
809
-
810
- # MAIN PROGRAM
811
- loop do # OUTER LOOP - (catching refreshes via 'b')
812
- @break = false # Initialize @break variable (set if user hits 'b')
813
- begin # Create the windows/panels
814
- maxx = Curses.cols
815
- maxy = Curses.lines
816
- init_pair( 1, 235, 235) # stdscr
817
- Curses.stdscr.color = 1
818
- Curses.stdscr.fill
819
- # Curses::Window.new(h,w,y,x)
820
- @w_inf = Curses::Window.new( 1, 32, 1, 1)
821
- @w_lbl = Curses::Window.new( 5, 2, 2, 1)
822
- @w_l = Curses::Window.new( 1, 30, 2, 3)
823
- @w_yzt = Curses::Window.new( 3, 30, 3, 3)
824
- @w_x = Curses::Window.new( 1, 30, 6, 3)
825
- @w_cmd = Curses::Window.new(12, 32, 8, 1)
826
- @w_reg = Curses::Window.new(maxy - 22, 32, 21, 1)
827
- @w_hlp = Curses::Window.new(maxy - 2, maxx - 35, 1, 34)
828
-
829
- init_pair( 2, 88, 238) # @w_inf
830
- init_pair( 3, 60, 238) # @w_lbl
831
- init_pair( 4, 246, 236) # @w_l
832
- init_pair( 5, 250, 234) # @w_yzt
833
- init_pair( 6, 7, 0) # @w_x
834
- init_pair( 7, 0, 250) # @w_xi
835
- init_pair( 8, 242, 0) # @w_cmd ctrl- & @w_reg
836
- init_pair( 9, 111, 0) # @w_cmd
837
- init_pair(10, 214, 0) # @w_cmd key
838
- init_pair(11, 238, 0) # @w_hlp
839
-
840
- @w_inf.color = 2
841
- @w_lbl.color = 3
842
- @w_l.color = 4
843
- @w_yzt.color = 5
844
- @w_x.color = 6
845
- @w_x.attr = Curses::A_BOLD
846
- @w_cmd.color = 8
847
- @w_cmd.attr = Curses::A_BOLD
848
- @w_reg.color = 8
849
- @w_hlp.color = 11
850
-
851
- @w_lbl.p(" L T Z Y X")
852
- @w_cmd.fill; cmd
853
- @w_reg.fill
854
- @w_hlp.fill
855
- help if @hlp
856
-
857
- @u = []
858
- @undo = false
859
-
860
- loop do # INNER, CORE LOOP
861
-
862
- @w_inf.clr
863
- @w_inf.p(" #{@mod} Sci=#{@sci} Fix=#{@fix}".ljust(32))
864
- pstack
865
- pregs
866
- @t = @stk.dup
867
- main_getkey("") # Get key from user
868
- @u.push(@t.dup) if @t != @stk and @undo == false
869
- @undo = false
870
-
871
- break if @break # Break to outer loop, redrawing windows, if user hit 'r'
872
- break if Curses.cols != maxx or Curses.lines != maxy # break on terminal resize
873
- end
874
- ensure # On exit: close curses, clear terminal
875
- conf_write
876
- close_screen
877
- end
878
- end
879
-
880
- # vim: set sw=2 sts=2 et fdm=syntax fdn=2 fcs=fold\:\ :