xrpn 1.1

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 (289) hide show
  1. checksums.yaml +7 -0
  2. data/bin/xrpn +110 -0
  3. data/cmd/abs +7 -0
  4. data/cmd/acos +10 -0
  5. data/cmd/adate +12 -0
  6. data/cmd/adateiso +13 -0
  7. data/cmd/add +9 -0
  8. data/cmd/adv +7 -0
  9. data/cmd/agsub +8 -0
  10. data/cmd/aleng +8 -0
  11. data/cmd/almcat +7 -0
  12. data/cmd/almnow +7 -0
  13. data/cmd/anum +10 -0
  14. data/cmd/aoff +7 -0
  15. data/cmd/aon +7 -0
  16. data/cmd/appchr +13 -0
  17. data/cmd/apprec +13 -0
  18. data/cmd/arcl +22 -0
  19. data/cmd/arcli +7 -0
  20. data/cmd/arclrec +30 -0
  21. data/cmd/arot +13 -0
  22. data/cmd/ashf +7 -0
  23. data/cmd/asin +10 -0
  24. data/cmd/asroom +7 -0
  25. data/cmd/asto +21 -0
  26. data/cmd/asub +8 -0
  27. data/cmd/atan +10 -0
  28. data/cmd/atime +26 -0
  29. data/cmd/atime24 +21 -0
  30. data/cmd/atox +9 -0
  31. data/cmd/aview +7 -0
  32. data/cmd/aviewc +7 -0
  33. data/cmd/beep +7 -0
  34. data/cmd/bindec +8 -0
  35. data/cmd/cat +26 -0
  36. data/cmd/cf +7 -0
  37. data/cmd/chs +7 -0
  38. data/cmd/cla +7 -0
  39. data/cmd/clalma +7 -0
  40. data/cmd/clalmx +7 -0
  41. data/cmd/cld +6 -0
  42. data/cmd/clear +7 -0
  43. data/cmd/clfl +13 -0
  44. data/cmd/clk12 +7 -0
  45. data/cmd/clk24 +7 -0
  46. data/cmd/clkeys +7 -0
  47. data/cmd/clock +7 -0
  48. data/cmd/clp +8 -0
  49. data/cmd/clralms +7 -0
  50. data/cmd/clrg +7 -0
  51. data/cmd/clrgx +12 -0
  52. data/cmd/cls +12 -0
  53. data/cmd/clst +10 -0
  54. data/cmd/clx +8 -0
  55. data/cmd/cmdadd +7 -0
  56. data/cmd/cmddel +7 -0
  57. data/cmd/correct +7 -0
  58. data/cmd/cos +10 -0
  59. data/cmd/crflas +9 -0
  60. data/cmd/crfld +9 -0
  61. data/cmd/cube +8 -0
  62. data/cmd/d_r +8 -0
  63. data/cmd/date +8 -0
  64. data/cmd/dateplus +12 -0
  65. data/cmd/ddate +11 -0
  66. data/cmd/dec +7 -0
  67. data/cmd/decbin +8 -0
  68. data/cmd/dechex +8 -0
  69. data/cmd/decoct +8 -0
  70. data/cmd/deg +7 -0
  71. data/cmd/degq +7 -0
  72. data/cmd/delchr +14 -0
  73. data/cmd/delrec +12 -0
  74. data/cmd/divide +9 -0
  75. data/cmd/dmy +7 -0
  76. data/cmd/dot +7 -0
  77. data/cmd/dow +9 -0
  78. data/cmd/drop +7 -0
  79. data/cmd/dropy +7 -0
  80. data/cmd/dse +40 -0
  81. data/cmd/ed +7 -0
  82. data/cmd/emdir +7 -0
  83. data/cmd/emdirx +14 -0
  84. data/cmd/emroom +7 -0
  85. data/cmd/end +9 -0
  86. data/cmd/eng +9 -0
  87. data/cmd/enter +8 -0
  88. data/cmd/exp +9 -0
  89. data/cmd/expx1 +9 -0
  90. data/cmd/fact +9 -0
  91. data/cmd/fc +7 -0
  92. data/cmd/fcc +8 -0
  93. data/cmd/fcs +8 -0
  94. data/cmd/fix +9 -0
  95. data/cmd/fixq +7 -0
  96. data/cmd/flsize +7 -0
  97. data/cmd/frc +8 -0
  98. data/cmd/fs +7 -0
  99. data/cmd/fsc +8 -0
  100. data/cmd/fss +8 -0
  101. data/cmd/geir +11 -0
  102. data/cmd/getas +7 -0
  103. data/cmd/getfile +12 -0
  104. data/cmd/getfilea +11 -0
  105. data/cmd/getkey +9 -0
  106. data/cmd/getkeyx +10 -0
  107. data/cmd/getp +13 -0
  108. data/cmd/getr +13 -0
  109. data/cmd/getrec +8 -0
  110. data/cmd/getrx +17 -0
  111. data/cmd/getsub +7 -0
  112. data/cmd/getweb +12 -0
  113. data/cmd/getx +12 -0
  114. data/cmd/grad +7 -0
  115. data/cmd/gsb +7 -0
  116. data/cmd/gto +23 -0
  117. data/cmd/help +14 -0
  118. data/cmd/hexdec +8 -0
  119. data/cmd/hms +12 -0
  120. data/cmd/hmsminus +14 -0
  121. data/cmd/hmsplus +13 -0
  122. data/cmd/hr +11 -0
  123. data/cmd/inschr +14 -0
  124. data/cmd/insrec +12 -0
  125. data/cmd/int +8 -0
  126. data/cmd/invf +7 -0
  127. data/cmd/isg +40 -0
  128. data/cmd/lastx +8 -0
  129. data/cmd/lbl +6 -0
  130. data/cmd/lift +8 -0
  131. data/cmd/ln +8 -0
  132. data/cmd/ln1x +8 -0
  133. data/cmd/log +8 -0
  134. data/cmd/mdy +7 -0
  135. data/cmd/mean +11 -0
  136. data/cmd/mod +13 -0
  137. data/cmd/multiply +9 -0
  138. data/cmd/oct +7 -0
  139. data/cmd/octdec +8 -0
  140. data/cmd/off +8 -0
  141. data/cmd/on +7 -0
  142. data/cmd/p_r +13 -0
  143. data/cmd/pack +7 -0
  144. data/cmd/page +13 -0
  145. data/cmd/pagedel +8 -0
  146. data/cmd/pageq +7 -0
  147. data/cmd/pageswap +8 -0
  148. data/cmd/pasn +7 -0
  149. data/cmd/pcat +14 -0
  150. data/cmd/pclps +12 -0
  151. data/cmd/percent +9 -0
  152. data/cmd/percentch +9 -0
  153. data/cmd/pi +8 -0
  154. data/cmd/posa +23 -0
  155. data/cmd/posfl +26 -0
  156. data/cmd/pow +9 -0
  157. data/cmd/pprg +27 -0
  158. data/cmd/pprgx +33 -0
  159. data/cmd/pra +7 -0
  160. data/cmd/prflags +8 -0
  161. data/cmd/prompt +8 -0
  162. data/cmd/prp +7 -0
  163. data/cmd/prregs +8 -0
  164. data/cmd/prstk +10 -0
  165. data/cmd/prx +7 -0
  166. data/cmd/prxm +21 -0
  167. data/cmd/pse +7 -0
  168. data/cmd/psize +7 -0
  169. data/cmd/purfl +14 -0
  170. data/cmd/r_d +8 -0
  171. data/cmd/r_p +18 -0
  172. data/cmd/rad +7 -0
  173. data/cmd/rand +10 -0
  174. data/cmd/rcl +23 -0
  175. data/cmd/rclaf +7 -0
  176. data/cmd/rclflag +16 -0
  177. data/cmd/rclpt +8 -0
  178. data/cmd/rclpta +16 -0
  179. data/cmd/rclsw +7 -0
  180. data/cmd/rdn +7 -0
  181. data/cmd/recip +8 -0
  182. data/cmd/regmove +18 -0
  183. data/cmd/regswap +19 -0
  184. data/cmd/reload +7 -0
  185. data/cmd/reszfl +7 -0
  186. data/cmd/rnd +8 -0
  187. data/cmd/root +9 -0
  188. data/cmd/rtn +12 -0
  189. data/cmd/rubycmd +7 -0
  190. data/cmd/runsw +7 -0
  191. data/cmd/rup +7 -0
  192. data/cmd/saveas +7 -0
  193. data/cmd/savep +7 -0
  194. data/cmd/saver +24 -0
  195. data/cmd/saverx +31 -0
  196. data/cmd/savex +10 -0
  197. data/cmd/savexm +7 -0
  198. data/cmd/sci +9 -0
  199. data/cmd/sdev +11 -0
  200. data/cmd/seekpt +10 -0
  201. data/cmd/seekpta +7 -0
  202. data/cmd/sep +7 -0
  203. data/cmd/setaf +7 -0
  204. data/cmd/setsw +7 -0
  205. data/cmd/sf +7 -0
  206. data/cmd/shellcmd +7 -0
  207. data/cmd/sign +19 -0
  208. data/cmd/sin +10 -0
  209. data/cmd/size +7 -0
  210. data/cmd/sizeq +7 -0
  211. data/cmd/sminus +20 -0
  212. data/cmd/splus +20 -0
  213. data/cmd/sqr +8 -0
  214. data/cmd/sqrt +8 -0
  215. data/cmd/sreg +7 -0
  216. data/cmd/sregq +7 -0
  217. data/cmd/stdivide +22 -0
  218. data/cmd/stmultiply +22 -0
  219. data/cmd/sto +21 -0
  220. data/cmd/stoflag +13 -0
  221. data/cmd/stop +7 -0
  222. data/cmd/stopsw +7 -0
  223. data/cmd/stplus +22 -0
  224. data/cmd/stsubtract +22 -0
  225. data/cmd/subtract +9 -0
  226. data/cmd/sw +7 -0
  227. data/cmd/swap +7 -0
  228. data/cmd/swpt +7 -0
  229. data/cmd/tan +10 -0
  230. data/cmd/tenx +8 -0
  231. data/cmd/time +8 -0
  232. data/cmd/tx +7 -0
  233. data/cmd/version +7 -0
  234. data/cmd/view +7 -0
  235. data/cmd/writefile +12 -0
  236. data/cmd/xeq +21 -0
  237. data/cmd/xeq0 +7 -0
  238. data/cmd/xeqnn +9 -0
  239. data/cmd/xeqy +7 -0
  240. data/cmd/xf +20 -0
  241. data/cmd/xgt0 +7 -0
  242. data/cmd/xgteq0 +7 -0
  243. data/cmd/xgteqnn +9 -0
  244. data/cmd/xgteqy +7 -0
  245. data/cmd/xgtnn +9 -0
  246. data/cmd/xgty +7 -0
  247. data/cmd/xlt0 +7 -0
  248. data/cmd/xlteq0 +7 -0
  249. data/cmd/xlteqnn +9 -0
  250. data/cmd/xlteqy +7 -0
  251. data/cmd/xltnn +9 -0
  252. data/cmd/xlty +7 -0
  253. data/cmd/xmexistq +15 -0
  254. data/cmd/xmfileq +7 -0
  255. data/cmd/xneq0 +7 -0
  256. data/cmd/xneqnn +9 -0
  257. data/cmd/xneqy +7 -0
  258. data/cmd/xnn +21 -0
  259. data/cmd/xtoa +7 -0
  260. data/cmd/xy +7 -0
  261. data/cmd/xyzalm +7 -0
  262. data/lib/_xrpn_version +5 -0
  263. data/lib/bei +18 -0
  264. data/lib/check +26 -0
  265. data/lib/conditional +10 -0
  266. data/lib/convert_base +8 -0
  267. data/lib/debug_mode +124 -0
  268. data/lib/dtparse +10 -0
  269. data/lib/error +10 -0
  270. data/lib/fact +7 -0
  271. data/lib/getpt +7 -0
  272. data/lib/help +12 -0
  273. data/lib/hp_41 +83 -0
  274. data/lib/ind +21 -0
  275. data/lib/load_xm +28 -0
  276. data/lib/locate_prg +32 -0
  277. data/lib/numeric +62 -0
  278. data/lib/numformat +12 -0
  279. data/lib/optparse +23 -0
  280. data/lib/read_cmd +12 -0
  281. data/lib/read_state +6 -0
  282. data/lib/save_state +18 -0
  283. data/lib/save_xm +5 -0
  284. data/lib/setpt +5 -0
  285. data/lib/string +28 -0
  286. data/lib/theme_dark +10 -0
  287. data/lib/theme_light +10 -0
  288. data/lib/xrpn_class +34 -0
  289. metadata +348 -0
data/lib/debug_mode ADDED
@@ -0,0 +1,124 @@
1
+ def debug_mode
2
+ prompt = TTY::Prompt.new
3
+ loop do
4
+ if $prompt
5
+ @line = prompt.ask(":")
6
+ break
7
+ else
8
+ puts "─" * 30
9
+ @p.prstk
10
+ print "> "
11
+ @ln = STDIN.getch
12
+ while IO.select([STDIN], [], [], 0) != nil # Flush STDIN (remove control chars)
13
+ STDIN.getch
14
+ end
15
+ if ["+", "-", "*", "/", "%"].include?(@ln)
16
+ print "\e[32m" + @ln + "\e[0m\n"
17
+ @ln = [@ln]
18
+ @line = hp_41(@ln)[0]
19
+ break
20
+ elsif @ln == "\r" # A simple ENTER
21
+ @line = "lift"
22
+ puts "\n"
23
+ break
24
+ end
25
+ print "\e[1G\e[K" # Clears from the beginning of line (removes getch prompt)
26
+ @line = prompt.ask(">", value: @ln)
27
+ unless @line == nil or @line.length == 1
28
+ @line = [@line]
29
+ @line = hp_41(@line)[0]
30
+ end
31
+ end
32
+ case @line
33
+ when "q" # Quit
34
+ puts "\n"
35
+ exit
36
+ when "Q" # Save and quit
37
+ save_state()
38
+ puts "\n"
39
+ exit
40
+ when /> .*/
41
+ state = @line.sub(/> /, '')
42
+ save_state(state)
43
+ when /< .*/
44
+ state = @line.sub(/< /, '')
45
+ read_state(state)
46
+ when "c"
47
+ system("clear")
48
+ when "C"
49
+ @p.x = 0.0
50
+ @p.y = 0.0
51
+ @p.z = 0.0
52
+ @p.t = 0.0
53
+ @p.l = 0.0
54
+ @p.a = ""
55
+ @p.deg = "deg"
56
+ @p.i = 4
57
+ @p.s = 6
58
+ @p.srg = 11
59
+ @p.reg = {}
60
+ @p.flg = {}
61
+ system("clear")
62
+ when "R" # Reload all commands from the cmd directory
63
+ read_cmd
64
+ puts "Commands reloaded."
65
+ when "l" # Show current line
66
+ @line = @p.prg[@p.pg][@p.pc]
67
+ puts "Line #{@p.pc + 1}: \"#{@line}\"" # Line 1 is @p.prg[@p.pg][0]
68
+ when "n" # Show next line
69
+ if @p.pc + 1 > @p.prg[@p.pg].length
70
+ puts "End of program"
71
+ else
72
+ @line = @p.prg[@p.pg][@p.pc + 1]
73
+ puts "Line #{@p.pc + 2}: \"#{@line}\"" # Line 1 is @p.prg[@p.pg][0]
74
+ end
75
+ when "p" # Show previous line
76
+ if @p.pc - 1 < 0
77
+ puts "Beginning of program"
78
+ else
79
+ @line = @p.prg[@p.pg][@p.pc - 1]
80
+ puts "Line #{@p.pc}: \"#{@line}\"" # Line 1 is @p.prg[@p.pg][0]
81
+ end
82
+ when "S" # Go to next line without executing it
83
+ @p.pc += 1
84
+ if @p.pc > @p.prg[@p.pg].length
85
+ puts "End of program"
86
+ else
87
+ @line = @p.prg[@p.pg][@p.pc + 1]
88
+ puts "Line #{@p.pc + 2}: \"#{@line}\"" # Line 1 is @p.prg[@p.pg][0]
89
+ end
90
+ when "s" # Single-step the next program line
91
+ @p.pc += 1
92
+ if @p.pc == @p.prg[@p.pg].length
93
+ @line = "END"
94
+ break
95
+ end
96
+ @line = @p.prg[@p.pg][@p.pc]
97
+ puts "Line #{@p.pc + 1}: #{@line}" # Line 1 is @p.prg[@p.pg][0]
98
+ $sst = true
99
+ break
100
+ when "b" # Back-step one line
101
+ @p.pc -= 1 unless @p.pc == 0
102
+ when /^\+\+ /
103
+ @p.prg[@p.pg].insert(@p.pc + 1, @line.sub(/^\+\+ /, ''))
104
+ when "--"
105
+ @p.prg[@p.pg].delete_at(@p.pc)
106
+ when nil # A simple ENTER
107
+ @line = "lift"
108
+ break
109
+ when "r" # End debug mode
110
+ @p.pc += 1
111
+ @line = @p.prg[@p.pg][@p.pc]
112
+ @line = "end" if @line == nil
113
+ $debug = false
114
+ $sst = false
115
+ break unless @p.flg["44"]
116
+ else
117
+ break unless @p.flg["44"]
118
+ end
119
+ end
120
+ $prompt = false
121
+ end
122
+
123
+
124
+ # vim:ft=ruby:
data/lib/dtparse ADDED
@@ -0,0 +1,10 @@
1
+ def dtparse(date)
2
+ @flg["31"] ? d = date.to_i : m = date.to_i
3
+ @flg["31"] ? m = ((date - date.to_i) * 100).to_i : d = ((date - date.to_i) * 100).to_i
4
+ y = (((date * 100) - (date * 100).to_i) * 10000).to_i
5
+ dt = "#{y.to_s}-#{m.to_s}-#{d.to_s}"
6
+ return Date.parse(dt)
7
+ end
8
+
9
+
10
+ # vim:ft=ruby:
data/lib/error ADDED
@@ -0,0 +1,10 @@
1
+ def error(msg)
2
+ if @p.flg["25"]
3
+ @p.flg["25"] = false
4
+ else
5
+ puts msg
6
+ @p.stop
7
+ end
8
+ end
9
+
10
+ # vim:ft=ruby:
data/lib/fact ADDED
@@ -0,0 +1,7 @@
1
+ class Integer
2
+ def fact
3
+ (1..self).reduce(:*) || 1
4
+ end
5
+ end
6
+
7
+ # vim:ft=ruby:
data/lib/getpt ADDED
@@ -0,0 +1,7 @@
1
+ def getpt
2
+ r = @xmcont[0][3].to_i + 1
3
+ c = (@xmcont[0][3].frc * 1000).to_i
4
+ return r, c
5
+ end
6
+
7
+ # vim:ft=ruby:
data/lib/help ADDED
@@ -0,0 +1,12 @@
1
+ def help
2
+ puts <<HELPTEXT
3
+ XRPN is a stack-based programming language. It uses Reverse Polish Notation for calculations.
4
+ The language is a superset of FOCAL, implementing the full set of HP-41CX calculator commands.
5
+ XRPN is on-the-fly extensible. Language functions can be upgraded or implemented while programs are running.
6
+ It runs programs in text files or manually in debug mode (if no text file is supplied or when a program stops)
7
+ XRPN implements indirect adressing, self-modification and features well beyond the FOCAL language.
8
+ For detailed information, visit the GitHub page: https://github.com/isene/xrpn
9
+ HELPTEXT
10
+ end
11
+
12
+ # vim:ft=ruby:
data/lib/hp_41 ADDED
@@ -0,0 +1,83 @@
1
+ def hp_41 (a)
2
+ a.map!{|x| x.sub( /^\s+/, "" )} # Remove spaces at start of line
3
+ a.map!{|x| x.sub( /^\d\d+[^0-9.]/, "" )} # Remove line numbers from program
4
+ a.map!{|x| x.sub( /\s+$/, "" )} # Remove trailing spaces
5
+ a.map!{|x| x.sub( /\s\s+/, "" )} # Remove multiple spaces
6
+ a.map!{|x| x.sub( /([a-zA-Z ]*)/, &:downcase)} # Downcase everything (use the /i below here)
7
+ a.map!{|x| x.sub( /ENTER\^/i, "enter" )}
8
+ a.map!{|x| x.sub( /R\^/i, "rup" )}
9
+ a.map!{|x| x.sub( /X\^2/i, "sqr" )}
10
+ a.map!{|x| x.sub( /X\*\*2/i, "sqr" )}
11
+ a.map!{|x| x.sub( /^E(\d+)/i, '1e\1' )}
12
+ a.map!{|x| x.sub( /1\/X/i, "recip" )}
13
+ a.map!{|x| x.sub( /HMS\+/i, "hmsplus" )}
14
+ a.map!{|x| x.sub( /HMS-/i, "hmsminus" )}
15
+ a.map!{|x| x.sub( /DATE\+/i, "dateplus" )}
16
+ a.map!{|x| x.sub( /Σ\+/i, "splus" )}
17
+ a.map!{|x| x.sub( /Σ-/i, "sminus" )}
18
+ a.map!{|x| x.sub( /S\+/i, "splus" )}
19
+ a.map!{|x| x.sub( /S-/i, "sminus" )}
20
+ a.map!{|x| x.sub( /SIGMA\+/i, "splus" )}
21
+ a.map!{|x| x.sub( /SIGMA-/i, "sminus" )}
22
+ a.map!{|x| x.sub( /SIGMAREG/, "sreg" )}
23
+ a.map!{|x| x.sub( /CLSIGMA/, "cls" )}
24
+ a.map!{|x| x.sub( /STO?\+/i, "stplus" )}
25
+ a.map!{|x| x.sub( /STO?-/i, "stsubtract" )}
26
+ a.map!{|x| x.sub( /STO?\*/i, "stmultiply" )}
27
+ a.map!{|x| x.sub( /STO?\//i, "stdivide" )}
28
+ a.map!{|x| x.sub( /%CH/i, "perch" )}
29
+ a.map!{|x| x.sub( /Y\^X/i, "pow" )}
30
+ a.map!{|x| x.sub( /Y\*\*X/i, "pow" )}
31
+ a.map!{|x| x.sub( /LN1\+X/i, "ln1x" )}
32
+ a.map!{|x| x.sub( /E\^X-1/i, "expx1" )} # Must come before next
33
+ a.map!{|x| x.sub( /E\^X/i, "exp" )}
34
+ a.map!{|x| x.sub( /E\*\*X-1/i, "expx1" )} # Must come before next
35
+ a.map!{|x| x.sub( /E\*\*X/i, "exp" )}
36
+ a.map!{|x| x.sub( /10\^X/i, "tenx" )}
37
+ a.map!{|x| x.sub( /10\*\*X/i, "tenx" )}
38
+ a.map!{|x| x.sub( /P-R/i, "p_r" )}
39
+ a.map!{|x| x.sub( /P->R/i, "p_r" )}
40
+ a.map!{|x| x.sub( /R-P/i, "r_p" )}
41
+ a.map!{|x| x.sub( /R->P/i, "r_p" )}
42
+ a.map!{|x| x.sub( /D-R/i, "d_r" )}
43
+ a.map!{|x| x.sub( /D->R/i, "d_r" )}
44
+ a.map!{|x| x.sub( /R-D/i, "r_d" )}
45
+ a.map!{|x| x.sub( /R->D/i, "r_d" )}
46
+ a.map!{|x| x.sub( /X<>Y/i, "xy" )}
47
+ a.map!{|x| x.sub( /X<>F/i, "xf" )}
48
+ a.map!{|x| x.sub( /X<>/i, "xnn" )}
49
+ a.map!{|x| x.sub( /X<>NN/i, "xnn" )}
50
+ a.map!{|x| x.sub( /FC\?C/i, "fcc?" )}
51
+ a.map!{|x| x.sub( /FS\?C/i, "fsc?" )}
52
+ a.map!{|x| x.sub( /X=Y\?/i, "xeqy?" )}
53
+ a.map!{|x| x.sub( /X#Y\?/i, "xneqy?" )}
54
+ a.map!{|x| x.sub( /X!=Y\?/i, "xneqy?" )}
55
+ a.map!{|x| x.sub( /X<>Y\?/i, "xneqy?" )}
56
+ a.map!{|x| x.sub( /X<Y\?/i, "xlty?" )}
57
+ a.map!{|x| x.sub( /X<=Y\?/i, "xlteqy?" )}
58
+ a.map!{|x| x.sub( /X>Y\?/i, "xgty?" )}
59
+ a.map!{|x| x.sub( /X>=Y\?/i, "xgteqy?" )}
60
+ a.map!{|x| x.sub( /X=0\?/i, "xeq0?" )}
61
+ a.map!{|x| x.sub( /X#0\?/i, "xneq0?" )}
62
+ a.map!{|x| x.sub( /X!=0\?/i, "xneq0?" )}
63
+ a.map!{|x| x.sub( /X<>0\?/i, "xneq0?" )}
64
+ a.map!{|x| x.sub( /X<0\?/i, "xlt0?" )}
65
+ a.map!{|x| x.sub( /X<=0\?/i, "xlteq0?" )}
66
+ a.map!{|x| x.sub( /X>0\?/i, "xgt0?" )}
67
+ a.map!{|x| x.sub( /X>=0\?/i, "xgteq0?" )}
68
+ a.map!{|x| x.sub( /X=NN\?/i, "xeqnn?" )}
69
+ a.map!{|x| x.sub( /X#NN\?/i, "xneqnn?" )}
70
+ a.map!{|x| x.sub( /X!=NN\?/i, "xneqnn?" )}
71
+ a.map!{|x| x.sub( /X<>NN\?/i, "xneqnn?" )}
72
+ a.map!{|x| x.sub( /X<NN\?/i, "xltnn?" )}
73
+ a.map!{|x| x.sub( /X<=NN\?/i, "xlteqnn?" )}
74
+ a.map!{|x| x.sub( /X>NN\?/i, "xgtnn?" )}
75
+ a.map!{|x| x.sub( /X>=NN\?/i, "xgteqnn?" )}
76
+ a.map!{|x| x.sub( /T\+X/i, "tx" )}
77
+ a.map!{|x| x.sub( /GOTO/i, "gto" )}
78
+ a.delete("")
79
+ a.compact!
80
+ return a
81
+ end
82
+
83
+ # vim:ft=ruby:
data/lib/ind ADDED
@@ -0,0 +1,21 @@
1
+ def ind(l3)
2
+ case l3
3
+ when "x"
4
+ l2 = @p.x.to_i.to_s
5
+ when "y"
6
+ l2 = @p.y.to_i.to_s
7
+ when "z"
8
+ l2 = @p.z.to_i.to_s
9
+ when "t"
10
+ l2 = @p.t.to_i.to_s
11
+ when "l"
12
+ l2 = @p.l.to_i.to_s
13
+ else
14
+ l2 = @p.reg[l3].to_i.to_s
15
+ end
16
+ l2 = "%02d" % [l2] if l2 == l2.to_i.to_s
17
+ return l2
18
+ end
19
+
20
+
21
+ # vim:ft=ruby:
data/lib/load_xm ADDED
@@ -0,0 +1,28 @@
1
+ def load_xm(f, pt=nil) # Raw file name and pointer
2
+ f = Dir.home + "/.xrpn/data/" + f
3
+ fl = [f + ".da", f + ".as"]
4
+ hit = false
5
+ fl.each do |file|
6
+ if File.exist?(file)
7
+ @xmcont = JSON.parse(File.read(file))
8
+ @xmfile = file
9
+ @xmcont[0][0] = file
10
+ unless pt == nil
11
+ @xmcont[0][3] = pt
12
+ save_xm
13
+ end
14
+ @xmcont[0][3] = 0.0 if @xmcont[0][3] < 0.0
15
+ @xmcont[0][3] = @xmcont.length.to_f - 2 if @xmcont[0][3] > @xmcont.length + 2
16
+ @xmcont[0][1] = "DA" if file.match(/da$/)
17
+ @xmcont[0][1] = "AS" if file.match(/as$/)
18
+ hit = true
19
+ end
20
+ end
21
+ if hit
22
+ puts "Loaded XM file: #{@a} (#{@xmcont[0][0]})"
23
+ else
24
+ puts "No such XM file: #{@a}"
25
+ end
26
+ end
27
+
28
+ # vim:ft=ruby:
data/lib/locate_prg ADDED
@@ -0,0 +1,32 @@
1
+ def locate_prg (l)
2
+ lbl = "lbl #{l}"
3
+ page = nil
4
+ pos = nil
5
+ prgm = []
6
+ if lbl.match(/".*"/)
7
+ @prg.each_index do |p|
8
+ pos = @prg[p].index {|e| e == lbl}
9
+ page = p unless pos == nil
10
+ break if pos != nil
11
+ end
12
+ else
13
+ @prg[@pg][@pc..-1].each_with_index do |e, i|
14
+ pos = i + @pc if e == lbl
15
+ break if pos != nil
16
+ end
17
+ pos = @prg[@pg].index {|e| e == lbl} if pos == nil
18
+ page = @pg
19
+ end
20
+ if pos != nil
21
+ l = pos
22
+ until l == @prg[page].length do
23
+ line = @prg[page][l]
24
+ prgm.push(line)
25
+ break if line == "END"
26
+ l += 1
27
+ end
28
+ end
29
+ return page, pos, prgm
30
+ end
31
+
32
+ # vim:ft=ruby:
data/lib/numeric ADDED
@@ -0,0 +1,62 @@
1
+ class Numeric
2
+
3
+ def frc
4
+ f = BigDecimal(self.to_s) - BigDecimal(self.to_s).to_i
5
+ return BigDecimal(f.to_s).to_s('F').to_f
6
+ end
7
+
8
+ def to_rad
9
+ self * Math::PI / 180
10
+ end
11
+ def to_radg
12
+ self * Math::PI / 200
13
+ end
14
+ def to_deg
15
+ self * 180 / Math::PI
16
+ end
17
+ def to_grad
18
+ self * 200 / Math::PI
19
+ end
20
+
21
+ def to_num(n=3, i=2, g=1, c=false, p=false)
22
+ # n: Threshold for when to show exponent
23
+ # i: Number og digits after the period
24
+ # g: Exponent grouping g=3 would always show exponent as a multiple of 3
25
+ # c: Use comma instead of period (European format)
26
+ # p: Separator per 3 digits (period if c=false, space when c=true)
27
+ # e: Exponent
28
+ # ge: Grouped exponent
29
+ # x: Absolute value of number less exponent
30
+ # s: String to be displayed
31
+ n = g if g > n
32
+ self != 0 ? e = Math::log10(self.abs).floor : e = 0
33
+ ge = g*(e/g).to_i
34
+ x = self.abs
35
+ x = (x / 10 ** ge) if e.abs >= n
36
+ s = x.to_i.to_s
37
+ self < 0 ? m = "-" : m = ""
38
+ s.sub!(/-/, '')
39
+ f = x.frc.to_s[0..(i + 1)].to_f
40
+ f = f.to_s.sub(/../, '')
41
+ i > 0 ? s.sub!(/(\d*\.)(\d{,#{i}}).*/, '\1\2') : s.sub!(/(\d*).*/, '\1')
42
+ if e.abs >= n # If exponent kicks in
43
+ s += "." + f.ljust(i, "0")
44
+ s += "e"
45
+ if ge < 0
46
+ s += "-"
47
+ s.sub!(/0\.(\d)/, '\1.')
48
+ end
49
+ ge = ge.abs
50
+ s += "%02d" % [ge]
51
+ else # No exponent
52
+ o = "," if p and not c
53
+ o = " " if p and c
54
+ s.gsub!(/(\d)(?=(\d\d\d)+(?!\d))/, "\\1#{o}") if p
55
+ s += "." + f.to_s.ljust(i, "0")
56
+ end
57
+ s.sub!(/\./, ',') if c
58
+ return m + s
59
+ end
60
+ end
61
+
62
+ # vim:ft=ruby:
data/lib/numformat ADDED
@@ -0,0 +1,12 @@
1
+ def numformat(n)
2
+ return n unless n.is_a? Numeric
3
+ return "Inf" if n.infinite?
4
+ if n.to_f.nan?
5
+ n = "Not a number"
6
+ return n
7
+ end
8
+ return n.to_num(@s,@i,@g,!@flg["28"],@flg["29"])
9
+ end
10
+
11
+
12
+ # vim:ft=ruby:
data/lib/optparse ADDED
@@ -0,0 +1,23 @@
1
+ # Handle the command line options
2
+ options = {}
3
+ optparse = OptionParser.new do |opts|
4
+ # Set a banner, displayed at the top of the help screen.
5
+ opts.banner = "Usage: xrpn [options]"
6
+
7
+ # Define the options, and what they do
8
+ opts.on('-f', '--file program', 'Specify the file to process') { |f| $rfile = f }
9
+ opts.on('-l', '--load program(s)', Array, 'File(s) to load, but not run') { |l| $lfile = l }
10
+ opts.on('-s', '--state STATE', 'Load a State file') { |s| $sfile = s }
11
+ opts.on('-c', '--check program', 'Program file to check for errors') { |c| check(c); exit }
12
+ opts.on('-x', '--X X-value', 'Set initial value in the X register') { |x| @x = x.to_f }
13
+ opts.on('-y', '--Y Y-value', 'Set initial value in the Y register') { |y| @y = y.to_f }
14
+ opts.on('-z', '--Z Z-value', 'Set initial value in the Z register') { |z| @z = z.to_f }
15
+ opts.on('-t', '--T T-value', 'Set initial value in the T register') { |t| @t = t.to_f }
16
+ opts.on('-a', '--Alpha Alpha-string', 'Set initial string in Alpha') { |a| @a = a.to_s }
17
+ opts.on('-h', 'Display SHORT help text') { puts opts; exit }
18
+ opts.on('--help', 'Display LONG help text') { help; puts; puts opts; exit}
19
+ opts.on('-v', '--version', 'Display the XRPN version number') { xrpn_version; exit }
20
+ end
21
+ optparse.parse!
22
+
23
+ # vim:ft=ruby:
data/lib/read_cmd ADDED
@@ -0,0 +1,12 @@
1
+ def read_cmd
2
+ $cmd = []
3
+ Dir[Dir.home+"/.xrpn/cmd/*"].each do |file|
4
+ load file
5
+ l = IO.readlines(file)[1]
6
+ c = l.sub(/\s*def (\S+).*/, '\1').chomp
7
+ $cmd.push(c)
8
+ end
9
+ $cmd.sort!
10
+ end
11
+
12
+ # vim:ft=ruby:
data/lib/read_state ADDED
@@ -0,0 +1,6 @@
1
+ def read_state (fn = "conf")
2
+ @p.flg["23"] = false
3
+ load (Dir.home + "/.xrpn/" + fn)
4
+ end
5
+
6
+ # vim:ft=ruby:
data/lib/save_state ADDED
@@ -0,0 +1,18 @@
1
+ def save_state (fn = "conf")
2
+ @p.flg["23"] = false
3
+ cont = "@p.x = #{@p.x}\n"
4
+ cont += "@p.y = #{@p.y}\n"
5
+ cont += "@p.z = #{@p.z}\n"
6
+ cont += "@p.t = #{@p.t}\n"
7
+ cont += "@p.l = #{@p.l}\n"
8
+ cont += "@p.a = \"#{@p.a}\"\n"
9
+ cont += "@p.i = #{@p.i}\n"
10
+ cont += "@p.s = #{@p.s}\n"
11
+ cont += "@p.srg = #{@p.srg}\n"
12
+ cont += "@p.reg = #{@p.reg}\n"
13
+ cont += "@p.flg = #{@p.flg}\n"
14
+ cont += "@p.prg = #{@p.prg}\n"
15
+ File.write(Dir.home + "/.xrpn/" + fn, cont)
16
+ end
17
+
18
+ # vim:ft=ruby:
data/lib/save_xm ADDED
@@ -0,0 +1,5 @@
1
+ def save_xm
2
+ File.write(@xmcont[0][0], @xmcont) if File.exist?(@xmcont[0][0])
3
+ end
4
+
5
+ # vim:ft=ruby:
data/lib/setpt ADDED
@@ -0,0 +1,5 @@
1
+ def setpt(r, c)
2
+ @xmcont[0][3] = r - 1 + (0.001 * c).round(4)
3
+ end
4
+
5
+ # vim:ft=ruby:
data/lib/string ADDED
@@ -0,0 +1,28 @@
1
+ class String
2
+
3
+ def color (color_code, bold=false)
4
+ bold ? "\e[38;5;#{color_code};1m#{self}\e[0m" : "\e[38;5;#{color_code}m#{self}\e[0m"
5
+ end
6
+
7
+ def c_x(bold=false)
8
+ color($colors["X"], bold)
9
+ end
10
+ def c_y(bold=false)
11
+ color($colors["Y"], bold)
12
+ end
13
+ def c_z(bold=false)
14
+ color($colors["Z"], bold)
15
+ end
16
+ def c_t(bold=false)
17
+ color($colors["T"], bold)
18
+ end
19
+ def c_l(bold=false)
20
+ color($colors["L"], bold)
21
+ end
22
+ def c_a(bold=false)
23
+ color($colors["A"], bold)
24
+ end
25
+
26
+ end
27
+
28
+ # vim:ft=ruby:
data/lib/theme_dark ADDED
@@ -0,0 +1,10 @@
1
+ $colors = {
2
+ "X" => 255,
3
+ "Y" => 246,
4
+ "Z" => 243,
5
+ "T" => 240,
6
+ "L" => 130,
7
+ "A" => 39
8
+ }
9
+
10
+ # vim:ft=ruby:
data/lib/theme_light ADDED
@@ -0,0 +1,10 @@
1
+ $colors = {
2
+ "X" => 232,
3
+ "Y" => 241,
4
+ "Z" => 244,
5
+ "T" => 247,
6
+ "L" => 130,
7
+ "A" => 39
8
+ }
9
+
10
+ # vim:ft=ruby:
data/lib/xrpn_class ADDED
@@ -0,0 +1,34 @@
1
+ # Define the basis for the RPN class
2
+ class XRPN
3
+ attr_accessor :nolift, :x, :y, :z, :t, :l, :a, :i, :s, :g, :deg, :srg, :reg, :flg, :clk24, :pg, :prg, :pc, :rtn, :xmfile, :xmcont
4
+ def initialize(file)
5
+ @nolift = false # Disable stacklift
6
+ @x = 0.0 # X register
7
+ @y = 0.0 # Y register
8
+ @z = 0.0 # Z register
9
+ @t = 0.0 # T register
10
+ @l = 0.0 # Last X register
11
+ @a = "" # Alpha register
12
+ @i = 4 # Fix (and Sci/Eng) nu,ber of digiet after period
13
+ @s = 9 # Threshold for when exponents kick in
14
+ @g = 1 # Exponent grouping (set to 3 when ENG mode is set)
15
+ @deg = "deg" # Degree mode (or "rad" for Radians or "grad" for 400°
16
+ @srg = 11 # Statistics registers start
17
+ @reg = {} # Registers are stored in a Hash
18
+ @flg = {} # Flags are stored in a Hash
19
+ @flg["28"] = true # Radix mark
20
+ @flg["29"] = true # Digit separator mark
21
+ @flg["31"] = false # Date format (MDY). "true" for DMY
22
+ @flg["44"] = false # Continuous ON
23
+ @clk24 = false # 24 hour time
24
+ @pg = 0 # Active Page
25
+ @prg = [] # Active Program
26
+ @prg[0] = File.read(file).split("\n") if $rfile
27
+ @pc = 0 # Active Program Counter (current step in the active program)
28
+ @rtn = [] # Return stack
29
+ @xmfile = "" # Current eXtended Memory file
30
+ @xmcont = [["", "", 0, 0.0]]
31
+ end
32
+ end
33
+
34
+ # vim:ft=ruby: