rpl 0.15.2 → 0.16.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/bin/rpl +3 -3
- data/lib/rpl/dictionary.rb +3 -3
- data/lib/rpl/parser.rb +2 -4
- data/lib/rpl/types/boolean.rb +1 -1
- data/lib/rpl/types/complex.rb +3 -9
- data/lib/rpl/types/list.rb +5 -4
- data/lib/rpl/types/name.rb +3 -3
- data/lib/rpl/types/numeric.rb +10 -12
- data/lib/rpl/types/program.rb +6 -3
- data/lib/rpl/types/string.rb +1 -1
- data/lib/rpl/words/logarithm.rb +1 -1
- data/lib/rpl/words/operations-reals-complexes.rb +9 -9
- data/lib/rpl/words/operations-reals.rb +1 -1
- data/lib/rpl/words/program.rb +9 -0
- data/lib/rpl/words/string-list.rb +4 -4
- data/lib/rpl/words/time-date.rb +1 -1
- data/lib/rpl/words/trig.rb +1 -1
- data/lib/rpl.rb +4 -6
- metadata +5 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: dd44b5eda44e13d48f14e40dc350d6dbb32876da8a2362fd84aa6e1937d1c21c
|
4
|
+
data.tar.gz: b7f718fb990c70d7ae85528bb5532aacab627be27a845468126d3bf16d1d75ab
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 88865d32234816b8a79fa1749eea4470666549fb454085f1c4bcc3457328936513ae86b48aaff4a74725923f5bd402ac030512e0400d96cf0ad41e1e4b1fe374
|
7
|
+
data.tar.gz: da6fa03c6200a4d5a9e29e19ff3791b5ad93de42575c95f551596acc2a6154ff4e57a499f24531e3748c6399b727c9df58502405315aa67eeff32c8a81bb69f0
|
data/bin/rpl
CHANGED
@@ -78,7 +78,7 @@ class RplRepl
|
|
78
78
|
end
|
79
79
|
|
80
80
|
def persistence_filename
|
81
|
-
persistence_dir = ENV
|
81
|
+
persistence_dir = ENV.fetch('XDG_DATA_HOME', nil)
|
82
82
|
persistence_dir ||= '~/.local/share'
|
83
83
|
persistence_dir += '/rpl.rb'
|
84
84
|
|
@@ -88,7 +88,7 @@ end
|
|
88
88
|
options = { run_REPL: false,
|
89
89
|
persistence: true,
|
90
90
|
live_persistence: true,
|
91
|
-
persistence_filename
|
91
|
+
persistence_filename:,
|
92
92
|
files: [],
|
93
93
|
programs: [],
|
94
94
|
verbosity: :critical }
|
@@ -155,7 +155,7 @@ options[:programs].each do |program|
|
|
155
155
|
end
|
156
156
|
|
157
157
|
# third launch REPL if (explicitely or implicitely) asked
|
158
|
-
RplRepl.new( interpreter:
|
158
|
+
RplRepl.new( interpreter: ).run! if options[:run_REPL]
|
159
159
|
|
160
160
|
interpreter.persist_state if options[:persistence]
|
161
161
|
|
data/lib/rpl/dictionary.rb
CHANGED
@@ -13,9 +13,9 @@ class Dictionary
|
|
13
13
|
|
14
14
|
def add_word!( names, category, help, implementation )
|
15
15
|
names.each do |name|
|
16
|
-
@words[ name ] = { category
|
17
|
-
help
|
18
|
-
implementation:
|
16
|
+
@words[ name ] = { category:,
|
17
|
+
help:,
|
18
|
+
implementation: }
|
19
19
|
end
|
20
20
|
end
|
21
21
|
|
data/lib/rpl/parser.rb
CHANGED
@@ -30,7 +30,7 @@ class Parser
|
|
30
30
|
.join(' ')
|
31
31
|
end
|
32
32
|
|
33
|
-
splitted_input = input.split
|
33
|
+
splitted_input = input.split
|
34
34
|
|
35
35
|
# 2-passes:
|
36
36
|
# 1. regroup strings, lists, complexes, names and programs
|
@@ -90,7 +90,7 @@ class Parser
|
|
90
90
|
end
|
91
91
|
|
92
92
|
# 2. parse
|
93
|
-
|
93
|
+
regrouped_input.map do |element|
|
94
94
|
if RplBoolean.can_parse?( element )
|
95
95
|
Types.new_object( RplBoolean, element )
|
96
96
|
elsif RplNumeric.can_parse?( element )
|
@@ -107,7 +107,5 @@ class Parser
|
|
107
107
|
Types.new_object( RplName, element )
|
108
108
|
end
|
109
109
|
end
|
110
|
-
|
111
|
-
parsed_input
|
112
110
|
end
|
113
111
|
end
|
data/lib/rpl/types/boolean.rb
CHANGED
data/lib/rpl/types/complex.rb
CHANGED
@@ -20,20 +20,14 @@ module Types
|
|
20
20
|
end
|
21
21
|
|
22
22
|
def self.can_parse?( value )
|
23
|
-
# we
|
23
|
+
# we systematically trim enclosing ()
|
24
24
|
value = value[1..-2] if value.is_a?( String ) && value[0] == '(' && value[-1] == ')'
|
25
25
|
|
26
|
-
|
27
|
-
Complex( value )
|
28
|
-
rescue ArgumentError
|
29
|
-
return false
|
30
|
-
end
|
31
|
-
|
32
|
-
true
|
26
|
+
!Complex( value, exception: false ).nil?
|
33
27
|
end
|
34
28
|
|
35
29
|
def ==( other )
|
36
|
-
other.class == RplComplex
|
30
|
+
other.class == RplComplex &&
|
37
31
|
other.value == value
|
38
32
|
end
|
39
33
|
end
|
data/lib/rpl/types/list.rb
CHANGED
@@ -12,7 +12,7 @@ module Types
|
|
12
12
|
@value = if value.instance_of?( Array )
|
13
13
|
value
|
14
14
|
else
|
15
|
-
# we
|
15
|
+
# we systematically trim enclosing { }
|
16
16
|
Parser.parse( value[2..-3] )
|
17
17
|
end
|
18
18
|
end
|
@@ -22,12 +22,13 @@ module Types
|
|
22
22
|
end
|
23
23
|
|
24
24
|
def self.can_parse?( value )
|
25
|
-
value.instance_of?( Array )
|
26
|
-
value[0..1] == '{ ' &&
|
25
|
+
value.instance_of?( Array ) ||
|
26
|
+
( value[0..1] == '{ ' &&
|
27
|
+
value[-2..] == ' }' )
|
27
28
|
end
|
28
29
|
|
29
30
|
def ==( other )
|
30
|
-
other.class == RplList
|
31
|
+
other.class == RplList &&
|
31
32
|
other.value == value
|
32
33
|
end
|
33
34
|
end
|
data/lib/rpl/types/name.rb
CHANGED
@@ -22,14 +22,14 @@ module Types
|
|
22
22
|
end
|
23
23
|
|
24
24
|
def self.can_parse?( value )
|
25
|
-
( value.length > 2
|
26
|
-
( value != "''"
|
25
|
+
( value.length > 2 && value[0] == "'" && value[-1] == "'" ) ||
|
26
|
+
( value != "''" && !value.match?(/^[0-9']+$/) &&
|
27
27
|
# it's not any other type
|
28
28
|
[RplBoolean, RplList, RplProgram, RplString, RplNumeric].reduce( true ) { |memo, type_class| memo && !type_class.can_parse?( value ) } )
|
29
29
|
end
|
30
30
|
|
31
31
|
def ==( other )
|
32
|
-
other.class == RplName
|
32
|
+
other.class == RplName &&
|
33
33
|
other.value == value
|
34
34
|
end
|
35
35
|
end
|
data/lib/rpl/types/numeric.rb
CHANGED
@@ -32,9 +32,7 @@ module Types
|
|
32
32
|
@base = value.base
|
33
33
|
when BigDecimal
|
34
34
|
@value = value
|
35
|
-
when Integer
|
36
|
-
@value = BigDecimal( value, @@precision )
|
37
|
-
when Float
|
35
|
+
when Integer, Float
|
38
36
|
@value = BigDecimal( value, @@precision )
|
39
37
|
when String
|
40
38
|
begin
|
@@ -94,19 +92,19 @@ module Types
|
|
94
92
|
end
|
95
93
|
|
96
94
|
def self.can_parse?( value )
|
97
|
-
[RplNumeric, BigDecimal, Integer, Float].include?( value.class )
|
98
|
-
( value.is_a?( String )
|
99
|
-
value.match?(/^-?∞$/)
|
100
|
-
value.match?(/^0b[0-1]+$/)
|
101
|
-
value.match?(/^0o[0-7]+$/)
|
102
|
-
value.match?(/^0x[0-9a-f]+$/)
|
103
|
-
( value.match?(/^[0-9]+b[0-9a-z]+$/)
|
95
|
+
[RplNumeric, BigDecimal, Integer, Float].include?( value.class ) ||
|
96
|
+
( value.is_a?( String ) && ( value.match?(/^-?[0-9]*\.?[0-9]+$/) ||
|
97
|
+
value.match?(/^-?∞$/) ||
|
98
|
+
value.match?(/^0b[0-1]+$/) ||
|
99
|
+
value.match?(/^0o[0-7]+$/) ||
|
100
|
+
value.match?(/^0x[0-9a-f]+$/) ||
|
101
|
+
( value.match?(/^[0-9]+b[0-9a-z]+$/) &&
|
104
102
|
value.split('_').first.to_i <= 36 ) ) )
|
105
103
|
end
|
106
104
|
|
107
105
|
def ==( other )
|
108
|
-
other.class == RplNumeric
|
109
|
-
other.base == base
|
106
|
+
other.class == RplNumeric &&
|
107
|
+
other.base == base &&
|
110
108
|
other.value == value
|
111
109
|
end
|
112
110
|
end
|
data/lib/rpl/types/program.rb
CHANGED
@@ -7,7 +7,7 @@ module Types
|
|
7
7
|
def initialize( value )
|
8
8
|
raise RplTypeError unless self.class.can_parse?( value )
|
9
9
|
|
10
|
-
# we
|
10
|
+
# we systematically trim enclosing « »
|
11
11
|
@value = value[2..-3] # TODO: parse each element ?
|
12
12
|
end
|
13
13
|
|
@@ -16,11 +16,14 @@ module Types
|
|
16
16
|
end
|
17
17
|
|
18
18
|
def self.can_parse?( value )
|
19
|
-
value.length > 4 &&
|
19
|
+
value.length > 4 &&
|
20
|
+
value[0..1] == '« ' &&
|
21
|
+
value[-2..] == ' »' &&
|
22
|
+
!value[2..-3].strip.empty?
|
20
23
|
end
|
21
24
|
|
22
25
|
def ==( other )
|
23
|
-
other.class == RplProgram
|
26
|
+
other.class == RplProgram &&
|
24
27
|
other.value == value
|
25
28
|
end
|
26
29
|
end
|
data/lib/rpl/types/string.rb
CHANGED
data/lib/rpl/words/logarithm.rb
CHANGED
@@ -30,7 +30,7 @@ module RplLang
|
|
30
30
|
new_list = if args[1].instance_of?( RplList )
|
31
31
|
RplList.new( args[0].to_s ).value.concat( args[1].value )
|
32
32
|
else
|
33
|
-
RplList.new( args[0].to_s ).value.
|
33
|
+
RplList.new( args[0].to_s ).value.push(args[1])
|
34
34
|
end
|
35
35
|
|
36
36
|
RplList.new( "{ #{new_list.join(' ')} }" )
|
@@ -47,9 +47,9 @@ module RplLang
|
|
47
47
|
elsif args[0].instance_of?( RplString )
|
48
48
|
RplString.new( if args[1].instance_of?( RplString ) ||
|
49
49
|
args[1].instance_of?( RplName )
|
50
|
-
|
51
|
-
|
52
|
-
|
50
|
+
"\"#{args[0].value}#{args[1].value}\""
|
51
|
+
else
|
52
|
+
"\"#{args[0].value}#{args[1]}\""
|
53
53
|
end )
|
54
54
|
|
55
55
|
elsif args[0].instance_of?( RplName )
|
@@ -189,11 +189,11 @@ module RplLang
|
|
189
189
|
args = stack_extract( [[RplNumeric]] )
|
190
190
|
|
191
191
|
@stack << RplNumeric.new( if args[0].value.positive?
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
192
|
+
1
|
193
|
+
elsif args[0].value.negative?
|
194
|
+
-1
|
195
|
+
else
|
196
|
+
0
|
197
197
|
end )
|
198
198
|
end )
|
199
199
|
end
|
@@ -25,7 +25,7 @@ module RplLang
|
|
25
25
|
proc do
|
26
26
|
args = stack_extract( [[RplNumeric], [RplNumeric]] )
|
27
27
|
|
28
|
-
@stack << RplNumeric.new(
|
28
|
+
@stack << RplNumeric.new( ( args[0].value / args[1].value ) * 100.0, args[1].base )
|
29
29
|
end )
|
30
30
|
|
31
31
|
@dictionary.add_word!( ['mod'],
|
data/lib/rpl/words/program.rb
CHANGED
@@ -23,6 +23,15 @@ module RplLang
|
|
23
23
|
end
|
24
24
|
end )
|
25
25
|
|
26
|
+
@dictionary.add_word!( ['sheval'],
|
27
|
+
category,
|
28
|
+
'( string -- output ) run string in OS shell and put output on stack',
|
29
|
+
proc do
|
30
|
+
args = stack_extract( [[RplString]] )
|
31
|
+
|
32
|
+
@stack << Types.new_object( RplString, "\"#{`#{args[0].value}`}\"" )
|
33
|
+
end )
|
34
|
+
|
26
35
|
@dictionary.add_word!( ['↴', 'lsto'],
|
27
36
|
category,
|
28
37
|
'( content name -- ) store to local variable',
|
@@ -17,10 +17,10 @@ module RplLang
|
|
17
17
|
args = stack_extract( [[RplString, RplList]] )
|
18
18
|
|
19
19
|
@stack << if args[0].is_a?( RplString )
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
20
|
+
Types.new_object( RplString, "\"#{args[0].value.reverse}\"" )
|
21
|
+
else
|
22
|
+
Types.new_object( args[0].class, "{ #{args[0].value.reverse.join(' ')} }" )
|
23
|
+
end
|
24
24
|
end )
|
25
25
|
end
|
26
26
|
end
|
data/lib/rpl/words/time-date.rb
CHANGED
@@ -30,7 +30,7 @@ module RplLang
|
|
30
30
|
proc do
|
31
31
|
ticks_since_epoch = Time.utc( 1, 1, 1 ).to_i * 10_000_000
|
32
32
|
now = Time.now
|
33
|
-
@stack << Types.new_object( RplNumeric, now.to_i * 10_000_000 + now.nsec / 100 - ticks_since_epoch )
|
33
|
+
@stack << Types.new_object( RplNumeric, (now.to_i * 10_000_000) + (now.nsec / 100) - ticks_since_epoch )
|
34
34
|
end )
|
35
35
|
end
|
36
36
|
end
|
data/lib/rpl/words/trig.rb
CHANGED
data/lib/rpl.rb
CHANGED
@@ -5,7 +5,7 @@ require 'rpl/types'
|
|
5
5
|
require 'rpl/words'
|
6
6
|
|
7
7
|
class Rpl < Interpreter
|
8
|
-
VERSION = '0.
|
8
|
+
VERSION = '0.16.1'
|
9
9
|
|
10
10
|
include Types
|
11
11
|
|
@@ -15,7 +15,7 @@ class Rpl < Interpreter
|
|
15
15
|
dictionary: Dictionary.new,
|
16
16
|
persistence_filename: nil,
|
17
17
|
live_persistence: true )
|
18
|
-
super( stack
|
18
|
+
super( stack:, dictionary: )
|
19
19
|
|
20
20
|
@persistence_filename = persistence_filename
|
21
21
|
@live_persistence = live_persistence
|
@@ -37,13 +37,11 @@ class Rpl < Interpreter
|
|
37
37
|
def persist_state
|
38
38
|
return if @persistence_filename.nil?
|
39
39
|
|
40
|
-
File.
|
41
|
-
persistence_file.write "#{export_vars}\n#{export_stack}"
|
42
|
-
end
|
40
|
+
File.write(@persistence_filename, "#{export_vars}\n#{export_stack}")
|
43
41
|
end
|
44
42
|
|
45
43
|
def run!( input )
|
46
|
-
stack = super
|
44
|
+
stack = super( input )
|
47
45
|
|
48
46
|
persist_state if @live_persistence
|
49
47
|
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rpl
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.16.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Gwenhael Le Moine
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2023-03-19 00:00:00.000000000 Z
|
12
12
|
dependencies: []
|
13
13
|
description: Reverse-Polish-Lisp inspired language in ruby
|
14
14
|
email: gwenhael@le-moine.org
|
@@ -55,7 +55,8 @@ files:
|
|
55
55
|
homepage: https://github.com/gwenhael-le-moine/rpl.rb
|
56
56
|
licenses:
|
57
57
|
- GPL-3.0
|
58
|
-
metadata:
|
58
|
+
metadata:
|
59
|
+
rubygems_mfa_required: 'true'
|
59
60
|
post_install_message:
|
60
61
|
rdoc_options: []
|
61
62
|
require_paths:
|
@@ -71,7 +72,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
71
72
|
- !ruby/object:Gem::Version
|
72
73
|
version: '0'
|
73
74
|
requirements: []
|
74
|
-
rubygems_version: 3.
|
75
|
+
rubygems_version: 3.4.6
|
75
76
|
signing_key:
|
76
77
|
specification_version: 4
|
77
78
|
summary: Functional Stack Language
|