xrpn 2.4 → 2.5
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 +4 -4
- data/README.md +19 -0
- data/bin/xrpn +5 -3
- data/tests/final_test.xrpn +44 -0
- data/tests/test_bugs.xrpn +148 -0
- data/tests/test_bugs_simple.xrpn +121 -0
- data/tests/test_final.xrpn +4 -0
- data/tests/test_simple.xrpn +35 -0
- data/xcmd/divide +6 -2
- data/xcmd/getfile +1 -1
- data/xcmd/mean +12 -2
- data/xlib/_xrpn_version +1 -1
- data/xlib/debug_mode +2 -1
- data/xlib/ind +2 -1
- data/xlib/numeric +6 -5
- data/xrpn.gemspec +3 -3
- metadata +10 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 1e981e45788657aed96a731cda1c95efc19b3fd91b5e95e5106b116ca3436da8
|
4
|
+
data.tar.gz: fa62628fef13340908bf22a858fb2f7ba12249cf870d89ee48c7e294aca85c25
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 2c0579af23c5ff05cf697a4e2600be32e3e3256f3c9bef8958866d21c312460092317e2a361d736514cfb458162732c17da909582d2f822bbf0a83e5e38c4fd4
|
7
|
+
data.tar.gz: 888fe711b5e116382e8964bed62a3d15db60da609abf83b9b7f0b9a8242a6ea817f690774af230a392c59a1c27ae39ca3ac9e3ae49bc5728ac587bb36f8e497f
|
data/README.md
CHANGED
@@ -79,6 +79,25 @@ AVIEW
|
|
79
79
|
END
|
80
80
|
```
|
81
81
|
|
82
|
+
## Changelog
|
83
|
+
|
84
|
+
### Version 2.5 (Latest)
|
85
|
+
**Critical Bug Fixes and Performance Enhancements**
|
86
|
+
|
87
|
+
- **Fixed division by zero crashes** - Now properly handles division by zero with error messages instead of crashing
|
88
|
+
- **Fixed nil reference errors in statistics** - Statistics commands (like `mean`) now handle empty or uninitialized registers gracefully
|
89
|
+
- **Fixed variable name error in file operations** - Corrected undefined variable reference in `getfile` command
|
90
|
+
- **Fixed indirect addressing nil references** - Indirect addressing now handles nil register values safely
|
91
|
+
- **Optimized file system operations** - Improved startup performance by using `FileUtils.mkdir_p` for directory creation
|
92
|
+
- **Fixed memory leak** - TTY::Prompt is now lazily initialized only when debug mode is actually used
|
93
|
+
- **Optimized numeric formatting** - Eliminated redundant string conversions in rounding overflow calculations
|
94
|
+
- **Added comprehensive test suite** - New test programs in `/tests/` directory to verify bug fixes and prevent regressions
|
95
|
+
|
96
|
+
This release significantly improves the stability and performance of XRPN while maintaining full backward compatibility.
|
97
|
+
|
98
|
+
### Version 2.4
|
99
|
+
- Fixed loading of files via the -f switch
|
100
|
+
|
82
101
|
## Documentation
|
83
102
|
|
84
103
|
...is all in [the wiki page in this repo](https://github.com/isene/xrpn/wiki/XRPN-Documentation).
|
data/bin/xrpn
CHANGED
@@ -27,9 +27,11 @@ require 'timeout'
|
|
27
27
|
|
28
28
|
|
29
29
|
# ENSURE DIRs
|
30
|
-
|
30
|
+
require 'fileutils'
|
31
|
+
home_xrpn = File.join(Dir.home, ".xrpn")
|
32
|
+
FileUtils.mkdir_p(home_xrpn)
|
31
33
|
["data", "extra", "print", "xcmd", "xlib"].each do |d|
|
32
|
-
|
34
|
+
FileUtils.mkdir_p(File.join(home_xrpn, d))
|
33
35
|
end
|
34
36
|
|
35
37
|
# READ LIBRARY AND COMMANDS
|
@@ -102,7 +104,7 @@ load(Dir.home+'/.xrpn/theme') if File.exist?(Dir.home+'/.xrpn/theme') # Override
|
|
102
104
|
# THE CORE OF THE RPN PROGRAM
|
103
105
|
@nl = false # Nolift set to false
|
104
106
|
@i = 0 # Counter to prevent infinite loops
|
105
|
-
@debugprompt =
|
107
|
+
@debugprompt = nil
|
106
108
|
until @p.pc == @p.prg[@p.pg].length do
|
107
109
|
# Enter debug mode if $debug or $prompt is set, else read next program line
|
108
110
|
($debug or $prompt) ? debug_mode : @line = @p.prg[@p.pg][@p.pc]
|
@@ -0,0 +1,44 @@
|
|
1
|
+
LBL "FINAL"
|
2
|
+
"Final bug test"
|
3
|
+
aview
|
4
|
+
PSE
|
5
|
+
|
6
|
+
"Testing division..."
|
7
|
+
aview
|
8
|
+
10
|
9
|
+
2
|
10
|
+
/
|
11
|
+
"10/2 = "
|
12
|
+
arcl x
|
13
|
+
aview
|
14
|
+
PSE
|
15
|
+
|
16
|
+
"Testing stats..."
|
17
|
+
aview
|
18
|
+
clrg
|
19
|
+
1
|
20
|
+
2
|
21
|
+
Σ+
|
22
|
+
3
|
23
|
+
4
|
24
|
+
Σ+
|
25
|
+
mean
|
26
|
+
"Mean: "
|
27
|
+
arcl x
|
28
|
+
aview
|
29
|
+
PSE
|
30
|
+
|
31
|
+
"Testing file error..."
|
32
|
+
aview
|
33
|
+
"nothere.txt"
|
34
|
+
asto 01
|
35
|
+
rcl 01
|
36
|
+
getfile
|
37
|
+
"File result: "
|
38
|
+
arcl x
|
39
|
+
aview
|
40
|
+
PSE
|
41
|
+
|
42
|
+
"All tests passed!"
|
43
|
+
aview
|
44
|
+
end
|
@@ -0,0 +1,148 @@
|
|
1
|
+
# XRPN Test Program for Bug Fixes and Performance
|
2
|
+
# Tests critical bugs and performance issues
|
3
|
+
|
4
|
+
LBL "TESTALL"
|
5
|
+
"=== XRPN Bug Test ==="
|
6
|
+
aview
|
7
|
+
PSE
|
8
|
+
|
9
|
+
# Test 1: Division by zero
|
10
|
+
LBL "TEST1"
|
11
|
+
"Test 1: Division/0"
|
12
|
+
aview
|
13
|
+
PSE
|
14
|
+
5
|
15
|
+
0
|
16
|
+
/
|
17
|
+
"DIV/0 Failed"
|
18
|
+
aview
|
19
|
+
stop
|
20
|
+
LBL 01
|
21
|
+
"DIV/0 Caught OK"
|
22
|
+
aview
|
23
|
+
PSE
|
24
|
+
|
25
|
+
# Test 2: Statistics with empty registers
|
26
|
+
LBL "TEST2"
|
27
|
+
"Test 2: Stats/empty"
|
28
|
+
aview
|
29
|
+
PSE
|
30
|
+
clrg
|
31
|
+
mean
|
32
|
+
"Stats Failed"
|
33
|
+
aview
|
34
|
+
stop
|
35
|
+
LBL 02
|
36
|
+
"Stats Caught OK"
|
37
|
+
aview
|
38
|
+
PSE
|
39
|
+
|
40
|
+
# Test 3: File operations with non-existent file
|
41
|
+
LBL "TEST3"
|
42
|
+
"Test 3: Bad file"
|
43
|
+
aview
|
44
|
+
PSE
|
45
|
+
"nonexistent_file_12345.txt"
|
46
|
+
asto 01
|
47
|
+
rcl 01
|
48
|
+
getfile
|
49
|
+
"File err Failed"
|
50
|
+
aview
|
51
|
+
stop
|
52
|
+
LBL 03
|
53
|
+
"File err OK"
|
54
|
+
aview
|
55
|
+
PSE
|
56
|
+
|
57
|
+
# Test 4: Indirect addressing with nil register
|
58
|
+
LBL "TEST4"
|
59
|
+
"Test 4: IND nil"
|
60
|
+
aview
|
61
|
+
PSE
|
62
|
+
clrg
|
63
|
+
100
|
64
|
+
sto 50
|
65
|
+
# Register 51 is nil/empty
|
66
|
+
51
|
67
|
+
sto ind x
|
68
|
+
"IND nil Failed"
|
69
|
+
aview
|
70
|
+
stop
|
71
|
+
LBL 04
|
72
|
+
"IND nil OK"
|
73
|
+
aview
|
74
|
+
PSE
|
75
|
+
|
76
|
+
# Test 5: Numeric rounding overflow
|
77
|
+
LBL "TEST5"
|
78
|
+
"Test 5: Round ovfl"
|
79
|
+
aview
|
80
|
+
PSE
|
81
|
+
9.9999999999
|
82
|
+
fix 2
|
83
|
+
# This should round to 10.00
|
84
|
+
"Rounding: "
|
85
|
+
arcl x
|
86
|
+
aview
|
87
|
+
PSE
|
88
|
+
10
|
89
|
+
x!=y?
|
90
|
+
gto 05
|
91
|
+
"Round OK"
|
92
|
+
aview
|
93
|
+
PSE
|
94
|
+
gto "TEST6"
|
95
|
+
LBL 05
|
96
|
+
"Round Failed"
|
97
|
+
aview
|
98
|
+
stop
|
99
|
+
|
100
|
+
# Test 6: Statistics with data
|
101
|
+
LBL "TEST6"
|
102
|
+
"Test 6: Stats calc"
|
103
|
+
aview
|
104
|
+
PSE
|
105
|
+
clrg
|
106
|
+
1
|
107
|
+
enter
|
108
|
+
2
|
109
|
+
Σ+
|
110
|
+
3
|
111
|
+
enter
|
112
|
+
4
|
113
|
+
Σ+
|
114
|
+
5
|
115
|
+
enter
|
116
|
+
6
|
117
|
+
Σ+
|
118
|
+
mean
|
119
|
+
"Mean Y="
|
120
|
+
arcl y
|
121
|
+
" X="
|
122
|
+
arcl x
|
123
|
+
aview
|
124
|
+
PSE
|
125
|
+
# Should be Y=2, X=4
|
126
|
+
2
|
127
|
+
x!=y?
|
128
|
+
gto 06
|
129
|
+
rdwn
|
130
|
+
4
|
131
|
+
x!=y?
|
132
|
+
gto 06
|
133
|
+
"Stats calc OK"
|
134
|
+
aview
|
135
|
+
PSE
|
136
|
+
gto "DONE"
|
137
|
+
LBL 06
|
138
|
+
"Stats calc Failed"
|
139
|
+
aview
|
140
|
+
stop
|
141
|
+
|
142
|
+
LBL "DONE"
|
143
|
+
"=== All Tests Done ==="
|
144
|
+
aview
|
145
|
+
PSE
|
146
|
+
"Check for errors"
|
147
|
+
aview
|
148
|
+
end
|
@@ -0,0 +1,121 @@
|
|
1
|
+
LBL "TESTALL"
|
2
|
+
"XRPN Bug Test"
|
3
|
+
aview
|
4
|
+
PSE
|
5
|
+
xeq "TEST1"
|
6
|
+
xeq "TEST2"
|
7
|
+
xeq "TEST3"
|
8
|
+
xeq "TEST4"
|
9
|
+
xeq "TEST5"
|
10
|
+
xeq "TEST6"
|
11
|
+
"All Tests Done"
|
12
|
+
aview
|
13
|
+
end
|
14
|
+
|
15
|
+
LBL "TEST1"
|
16
|
+
"Test 1: Division/0"
|
17
|
+
aview
|
18
|
+
PSE
|
19
|
+
5
|
20
|
+
0
|
21
|
+
/
|
22
|
+
"DIV/0 Failed"
|
23
|
+
aview
|
24
|
+
stop
|
25
|
+
|
26
|
+
LBL "TEST2"
|
27
|
+
"Test 2: Stats/empty"
|
28
|
+
aview
|
29
|
+
PSE
|
30
|
+
clrg
|
31
|
+
mean
|
32
|
+
"Stats Failed"
|
33
|
+
aview
|
34
|
+
stop
|
35
|
+
|
36
|
+
LBL "TEST3"
|
37
|
+
"Test 3: Bad file"
|
38
|
+
aview
|
39
|
+
PSE
|
40
|
+
"nonexistent_file_12345.txt"
|
41
|
+
asto 01
|
42
|
+
rcl 01
|
43
|
+
getfile
|
44
|
+
"File err Failed"
|
45
|
+
aview
|
46
|
+
stop
|
47
|
+
|
48
|
+
LBL "TEST4"
|
49
|
+
"Test 4: IND nil"
|
50
|
+
aview
|
51
|
+
PSE
|
52
|
+
clrg
|
53
|
+
100
|
54
|
+
sto 50
|
55
|
+
51
|
56
|
+
sto ind x
|
57
|
+
"IND nil Failed"
|
58
|
+
aview
|
59
|
+
stop
|
60
|
+
|
61
|
+
LBL "TEST5"
|
62
|
+
"Test 5: Round ovfl"
|
63
|
+
aview
|
64
|
+
PSE
|
65
|
+
9.9999999999
|
66
|
+
fix 2
|
67
|
+
"Rounding: "
|
68
|
+
arcl x
|
69
|
+
aview
|
70
|
+
PSE
|
71
|
+
10
|
72
|
+
x!=y?
|
73
|
+
gto 05
|
74
|
+
"Round OK"
|
75
|
+
aview
|
76
|
+
PSE
|
77
|
+
rtn
|
78
|
+
LBL 05
|
79
|
+
"Round Failed"
|
80
|
+
aview
|
81
|
+
stop
|
82
|
+
|
83
|
+
LBL "TEST6"
|
84
|
+
"Test 6: Stats calc"
|
85
|
+
aview
|
86
|
+
PSE
|
87
|
+
clrg
|
88
|
+
1
|
89
|
+
enter
|
90
|
+
2
|
91
|
+
Σ+
|
92
|
+
3
|
93
|
+
enter
|
94
|
+
4
|
95
|
+
Σ+
|
96
|
+
5
|
97
|
+
enter
|
98
|
+
6
|
99
|
+
Σ+
|
100
|
+
mean
|
101
|
+
"Mean Y="
|
102
|
+
arcl y
|
103
|
+
" X="
|
104
|
+
arcl x
|
105
|
+
aview
|
106
|
+
PSE
|
107
|
+
2
|
108
|
+
x!=y?
|
109
|
+
gto 06
|
110
|
+
rdwn
|
111
|
+
4
|
112
|
+
x!=y?
|
113
|
+
gto 06
|
114
|
+
"Stats calc OK"
|
115
|
+
aview
|
116
|
+
PSE
|
117
|
+
rtn
|
118
|
+
LBL 06
|
119
|
+
"Stats calc Failed"
|
120
|
+
aview
|
121
|
+
stop
|
@@ -0,0 +1,35 @@
|
|
1
|
+
LBL "MAIN"
|
2
|
+
"Starting tests"
|
3
|
+
aview
|
4
|
+
PSE
|
5
|
+
|
6
|
+
"Test div by zero"
|
7
|
+
aview
|
8
|
+
5
|
9
|
+
0
|
10
|
+
/
|
11
|
+
"DIV OK"
|
12
|
+
aview
|
13
|
+
PSE
|
14
|
+
|
15
|
+
"Test stats empty"
|
16
|
+
aview
|
17
|
+
clrg
|
18
|
+
mean
|
19
|
+
"STATS OK"
|
20
|
+
aview
|
21
|
+
PSE
|
22
|
+
|
23
|
+
"Test bad file"
|
24
|
+
aview
|
25
|
+
"nonexistent.txt"
|
26
|
+
asto 01
|
27
|
+
rcl 01
|
28
|
+
getfile
|
29
|
+
"FILE OK"
|
30
|
+
aview
|
31
|
+
PSE
|
32
|
+
|
33
|
+
"All tests done"
|
34
|
+
aview
|
35
|
+
end
|
data/xcmd/divide
CHANGED
data/xcmd/getfile
CHANGED
data/xcmd/mean
CHANGED
@@ -4,8 +4,18 @@ class XRPN
|
|
4
4
|
@l = @x
|
5
5
|
lift
|
6
6
|
lift
|
7
|
-
|
8
|
-
|
7
|
+
# Check for nil registers and zero divisor
|
8
|
+
sum_x = @reg[@srg] || 0
|
9
|
+
sum_y = @reg[@srg + 2] || 0
|
10
|
+
count = @reg[@srg + 5] || 0
|
11
|
+
|
12
|
+
if count == 0
|
13
|
+
@x = 0
|
14
|
+
@y = 0
|
15
|
+
else
|
16
|
+
@x = sum_x / count
|
17
|
+
@y = sum_y / count
|
18
|
+
end
|
9
19
|
end
|
10
20
|
end
|
11
21
|
|
data/xlib/_xrpn_version
CHANGED
data/xlib/debug_mode
CHANGED
data/xlib/ind
CHANGED
data/xlib/numeric
CHANGED
@@ -36,12 +36,13 @@ class Numeric
|
|
36
36
|
s = x.to_i.to_s
|
37
37
|
self < 0 ? m = "-" : m = ""
|
38
38
|
s.sub!(/-/, '')
|
39
|
-
|
40
|
-
if
|
41
|
-
s = (x + 1).
|
42
|
-
f =
|
39
|
+
f_val = (x.frc * 10 ** i).round
|
40
|
+
if f_val >= 10 ** i # Fix rounding overflow
|
41
|
+
s = (x.to_i + 1).to_s
|
42
|
+
f = "0" * i
|
43
|
+
else
|
44
|
+
f = f_val.to_s.rjust(i, '0')
|
43
45
|
end
|
44
|
-
f = f.to_s
|
45
46
|
i > 0 ? s.sub!(/(\d*\.)(\d{,#{i}}).*/, '\1\2') : s.sub!(/(\d*).*/, '\1')
|
46
47
|
if e.abs >= n # If exponent kicks in
|
47
48
|
s += "." + f.ljust(i, "0")
|
data/xrpn.gemspec
CHANGED
@@ -1,9 +1,9 @@
|
|
1
1
|
Gem::Specification.new do |s|
|
2
2
|
s.name = 'xrpn'
|
3
|
-
s.version = '2.
|
3
|
+
s.version = '2.5'
|
4
4
|
s.licenses = ['Unlicense']
|
5
5
|
s.summary = "XRPN - The eXtended RPN (Reverse Polish Notation) programming language"
|
6
|
-
s.description = "A full programming language and environment extending the features of the venerable HP calculator programmable calculators. With XRPN you can accomplish a wide range of modern programming tasks as well as running existing HP-41 FOCAL programs directly. XRPN gives modern life to tens of thousands of old HP calculator programs and opens the possibilities to many, many more. New in 2.
|
6
|
+
s.description = "A full programming language and environment extending the features of the venerable HP calculator programmable calculators. With XRPN you can accomplish a wide range of modern programming tasks as well as running existing HP-41 FOCAL programs directly. XRPN gives modern life to tens of thousands of old HP calculator programs and opens the possibilities to many, many more. New in 2.5: Critical bug fixes and performance enhancements - fixed division by zero crashes, nil reference errors, memory leaks, and optimized file system operations."
|
7
7
|
|
8
8
|
s.authors = ["Geir Isene"]
|
9
9
|
s.email = 'g@isene.com'
|
@@ -11,6 +11,6 @@ Gem::Specification.new do |s|
|
|
11
11
|
|
12
12
|
s.add_runtime_dependency 'tty-prompt', '~> 0.23'
|
13
13
|
|
14
|
-
s.files = ["bin/xrpn", "conf", "theme_example", "README.md", "xrpn.gemspec"] + Dir.glob("xcmd/*") + Dir.glob("xlib/*")
|
14
|
+
s.files = ["bin/xrpn", "conf", "theme_example", "README.md", "xrpn.gemspec"] + Dir.glob("xcmd/*") + Dir.glob("xlib/*") + Dir.glob("tests/*")
|
15
15
|
s.executables << 'xrpn'
|
16
16
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: xrpn
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: '2.
|
4
|
+
version: '2.5'
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Geir Isene
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2025-
|
11
|
+
date: 2025-07-05 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: tty-prompt
|
@@ -28,8 +28,9 @@ description: 'A full programming language and environment extending the features
|
|
28
28
|
the venerable HP calculator programmable calculators. With XRPN you can accomplish
|
29
29
|
a wide range of modern programming tasks as well as running existing HP-41 FOCAL
|
30
30
|
programs directly. XRPN gives modern life to tens of thousands of old HP calculator
|
31
|
-
programs and opens the possibilities to many, many more. New in 2.
|
32
|
-
|
31
|
+
programs and opens the possibilities to many, many more. New in 2.5: Critical bug
|
32
|
+
fixes and performance enhancements - fixed division by zero crashes, nil reference
|
33
|
+
errors, memory leaks, and optimized file system operations.'
|
33
34
|
email: g@isene.com
|
34
35
|
executables:
|
35
36
|
- xrpn
|
@@ -39,6 +40,11 @@ files:
|
|
39
40
|
- README.md
|
40
41
|
- bin/xrpn
|
41
42
|
- conf
|
43
|
+
- tests/final_test.xrpn
|
44
|
+
- tests/test_bugs.xrpn
|
45
|
+
- tests/test_bugs_simple.xrpn
|
46
|
+
- tests/test_final.xrpn
|
47
|
+
- tests/test_simple.xrpn
|
42
48
|
- theme_example
|
43
49
|
- xcmd/abs
|
44
50
|
- xcmd/acos
|