rpl 0.15.2 → 0.16.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 936af4447e39381fe59aac32c442db5f16dfeac4aa656fa2f3d60a31f5814b3d
4
- data.tar.gz: 4adf532c8185dc0083139af76243e63706a62d885fd6619c39667046bb45a53b
3
+ metadata.gz: dd44b5eda44e13d48f14e40dc350d6dbb32876da8a2362fd84aa6e1937d1c21c
4
+ data.tar.gz: b7f718fb990c70d7ae85528bb5532aacab627be27a845468126d3bf16d1d75ab
5
5
  SHA512:
6
- metadata.gz: 44ace87f98a80156f3f7567fe30b48935c550b5481f64930717fb849673d171e4b6612d17ddde8c62564964cd9ba8cc13fc3b5e4e8418b10c2da8bdec4278d9f
7
- data.tar.gz: 6493f90e472f0ed0b3afc6966b61adfe98f11116c3ecdae0e3a7606e7f27b8075a6f9e1060b9e65278aad368b3f5a6f2eff847129571f2164b45eab0daabc63b
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['XDG_DATA_HOME']
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: 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: interpreter ).run! if options[:run_REPL]
158
+ RplRepl.new( interpreter: ).run! if options[:run_REPL]
159
159
 
160
160
  interpreter.persist_state if options[:persistence]
161
161
 
@@ -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: category,
17
- help: help,
18
- implementation: 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
- parsed_input = regrouped_input.map do |element|
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
@@ -25,7 +25,7 @@ module Types
25
25
  end
26
26
 
27
27
  def ==( other )
28
- other.class == RplBoolean and
28
+ other.class == RplBoolean &&
29
29
  other.value == value
30
30
  end
31
31
  end
@@ -20,20 +20,14 @@ module Types
20
20
  end
21
21
 
22
22
  def self.can_parse?( value )
23
- # we systematicalyl trim enclosing ()
23
+ # we systematically trim enclosing ()
24
24
  value = value[1..-2] if value.is_a?( String ) && value[0] == '(' && value[-1] == ')'
25
25
 
26
- begin
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 and
30
+ other.class == RplComplex &&
37
31
  other.value == value
38
32
  end
39
33
  end
@@ -12,7 +12,7 @@ module Types
12
12
  @value = if value.instance_of?( Array )
13
13
  value
14
14
  else
15
- # we systematicalyl trim enclosing { }
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 ) or
26
- value[0..1] == '{ ' && value[-2..] == ' }'
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 and
31
+ other.class == RplList &&
31
32
  other.value == value
32
33
  end
33
34
  end
@@ -22,14 +22,14 @@ module Types
22
22
  end
23
23
 
24
24
  def self.can_parse?( value )
25
- ( value.length > 2 and value[0] == "'" and value[-1] == "'" ) or
26
- ( value != "''" and !value.match?(/^[0-9']+$/) and
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 and
32
+ other.class == RplName &&
33
33
  other.value == value
34
34
  end
35
35
  end
@@ -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 ) or
98
- ( value.is_a?( String ) and ( value.match?(/^-?[0-9]*\.?[0-9]+$/) or
99
- value.match?(/^-?∞$/) or
100
- value.match?(/^0b[0-1]+$/) or
101
- value.match?(/^0o[0-7]+$/) or
102
- value.match?(/^0x[0-9a-f]+$/) or
103
- ( value.match?(/^[0-9]+b[0-9a-z]+$/) and
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 and
109
- other.base == base and
106
+ other.class == RplNumeric &&
107
+ other.base == base &&
110
108
  other.value == value
111
109
  end
112
110
  end
@@ -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 systematicalyl trim enclosing « »
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 && value[0..1] == '« ' && value[-2..-1] == ' »' && !value[2..-3].strip.empty?
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 and
26
+ other.class == RplProgram &&
24
27
  other.value == value
25
28
  end
26
29
  end
@@ -22,7 +22,7 @@ module Types
22
22
  end
23
23
 
24
24
  def ==( other )
25
- other.class == RplString and
25
+ other.class == RplString &&
26
26
  other.value == value
27
27
  end
28
28
  end
@@ -10,7 +10,7 @@ module RplLang
10
10
 
11
11
  category = 'Logs on reals and complexes'
12
12
 
13
- @dictionary.add_word!( ['', 'e'],
13
+ @dictionary.add_word!( %w[ℇ e],
14
14
  category,
15
15
  '( … -- ℇ ) push ℇ',
16
16
  proc do
@@ -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.concat( [args[1]] )
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
- "\"#{args[0].value}#{args[1].value}\""
51
- else
52
- "\"#{args[0].value}#{args[1]}\""
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
- 1
193
- elsif args[0].value.negative?
194
- -1
195
- else
196
- 0
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( 100.0 * ( args[0].value / args[1].value ), args[1].base )
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'],
@@ -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
- Types.new_object( RplString, "\"#{args[0].value.reverse}\"" )
21
- else
22
- Types.new_object( args[0].class, "{ #{args[0].value.reverse.join(' ')} }" )
23
- end
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
@@ -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
@@ -12,7 +12,7 @@ module RplLang
12
12
 
13
13
  category = 'Trig on reals and complexes'
14
14
 
15
- @dictionary.add_word!( ['𝛑', 'pi'],
15
+ @dictionary.add_word!( %w[𝛑 pi],
16
16
  category,
17
17
  '( … -- 𝛑 ) push 𝛑',
18
18
  proc do
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.15.2'
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: stack, dictionary: dictionary )
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.open( @persistence_filename, 'w' ) do |persistence_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.15.2
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: 2022-11-15 00:00:00.000000000 Z
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.3.7
75
+ rubygems_version: 3.4.6
75
76
  signing_key:
76
77
  specification_version: 4
77
78
  summary: Functional Stack Language