rpl 0.4.0 → 0.7.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.
@@ -1,8 +1,10 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module RplLang
4
- module Core
4
+ module Words
5
5
  module Store
6
+ include Types
7
+
6
8
  def populate_dictionary
7
9
  super
8
10
 
@@ -10,9 +12,9 @@ module RplLang
10
12
  'Store',
11
13
  '( content name -- ) store to variable',
12
14
  proc do
13
- args = stack_extract( [%i[name], :any] )
15
+ args = stack_extract( [[RplName], :any] )
14
16
 
15
- @dictionary.add_var( args[0][:value],
17
+ @dictionary.add_var( args[0].value,
16
18
  args[1] )
17
19
  end )
18
20
 
@@ -20,9 +22,9 @@ module RplLang
20
22
  'Store',
21
23
  '( name -- … ) push content of variable name onto stack',
22
24
  proc do
23
- args = stack_extract( [%i[name]] )
25
+ args = stack_extract( [[RplName]] )
24
26
 
25
- content = @dictionary.lookup( args[0][:value] )
27
+ content = @dictionary.lookup( args[0].value )
26
28
 
27
29
  @stack << content unless content.nil?
28
30
  end )
@@ -31,17 +33,16 @@ module RplLang
31
33
  'Store',
32
34
  '( name -- ) delete variable',
33
35
  proc do
34
- args = stack_extract( [%i[name]] )
36
+ args = stack_extract( [[RplName]] )
35
37
 
36
- @dictionary.remove_var( args[0][:value] )
38
+ @dictionary.remove_var( args[0].value )
37
39
  end )
38
40
 
39
41
  @dictionary.add_word( ['vars'],
40
42
  'Store',
41
43
  '( -- […] ) list variables',
42
44
  proc do
43
- @stack << { type: :list,
44
- value: (@dictionary.vars.keys + @dictionary.local_vars_layers.reduce([]) { |memo, layer| memo + layer.keys }).map { |name| { type: :name, value: name } } }
45
+ @stack << Types.new_object( RplList, (@dictionary.vars.keys + @dictionary.local_vars_layers.reduce([]) { |memo, layer| memo + layer.keys }).map { |name| Types.new_object( RplName, name ) } )
45
46
  end )
46
47
 
47
48
  @dictionary.add_word( ['clusr'],
@@ -54,68 +55,40 @@ module RplLang
54
55
  @dictionary.add_word( ['sto+'],
55
56
  'Store',
56
57
  '( a n -- ) add content to variable\'s value',
57
- proc do
58
- run( '
59
- dup type "name" ==
60
- « swap »
61
- ift
62
- over rcl + swap sto' )
63
- end )
58
+ Types.new_object( RplProgram, '« swap over rcl + swap sto »' ) )
64
59
 
65
60
  @dictionary.add_word( ['sto-'],
66
61
  'Store',
67
62
  '( a n -- ) subtract content to variable\'s value',
68
- proc do
69
- run( '
70
- dup type "name" ==
71
- « swap »
72
- ift
73
- over rcl swap - swap sto' )
74
- end )
63
+ Types.new_object( RplProgram, '« swap over rcl swap - swap sto »' ) )
75
64
 
76
65
  @dictionary.add_word( ['sto×', 'sto*'],
77
66
  'Store',
78
67
  '( a n -- ) multiply content of variable\'s value',
79
- proc do
80
- run( '
81
- dup type "name" ==
82
- « swap »
83
- ift
84
- over rcl * swap sto' )
85
- end )
68
+ Types.new_object( RplProgram, '« swap over rcl * swap sto »' ) )
86
69
 
87
70
  @dictionary.add_word( ['sto÷', 'sto/'],
88
71
  'Store',
89
72
  '( a n -- ) divide content of variable\'s value',
90
- proc do
91
- run( '
92
- dup type "name" ==
93
- « swap »
94
- ift
95
- over rcl swap / swap sto' )
96
- end )
73
+ Types.new_object( RplProgram, '« swap over rcl swap / swap sto »' ) )
97
74
 
98
75
  @dictionary.add_word( ['sneg'],
99
76
  'Store',
100
77
  '( a n -- ) negate content of variable\'s value',
101
- proc do
102
- run( 'dup rcl chs swap sto' )
103
- end )
78
+ Types.new_object( RplProgram, '« dup rcl chs swap sto »' ) )
104
79
 
105
80
  @dictionary.add_word( ['sinv'],
106
81
  'Store',
107
82
  '( a n -- ) invert content of variable\'s value',
108
- proc do
109
- run( 'dup rcl inv swap sto' )
110
- end )
83
+ Types.new_object( RplProgram, '« dup rcl inv swap sto »' ) )
111
84
 
112
85
  @dictionary.add_word( ['↴', 'lsto'],
113
86
  'Program',
114
87
  '( content name -- ) store to local variable',
115
88
  proc do
116
- args = stack_extract( [%i[name], :any] )
89
+ args = stack_extract( [[RplName], :any] )
117
90
 
118
- @dictionary.add_local_var( args[0][:value],
91
+ @dictionary.add_local_var( args[0].value,
119
92
  args[1] )
120
93
  end )
121
94
  end
@@ -0,0 +1,133 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RplLang
4
+ module Words
5
+ module StringAndList
6
+ include Types
7
+
8
+ def populate_dictionary
9
+ super
10
+
11
+ @dictionary.add_word( ['→str', '->str'],
12
+ 'String',
13
+ '( a -- s ) convert element to string',
14
+ proc do
15
+ args = stack_extract( [:any] )
16
+
17
+ @stack << Types.new_object( RplString, "\"#{args[0]}\"" )
18
+ end )
19
+
20
+ @dictionary.add_word( ['str→', 'str->'],
21
+ 'String',
22
+ '( s -- a ) convert string to element',
23
+ proc do
24
+ args = stack_extract( [[RplString]] )
25
+
26
+ @stack += Parser.parse( args[0].value )
27
+ end )
28
+
29
+ @dictionary.add_word( ['→list', '->list'],
30
+ 'Lists',
31
+ '( … x -- […] ) pack x stacks levels into a list',
32
+ proc do
33
+ args = stack_extract( [[RplNumeric]] )
34
+ args = stack_extract( %i[any] * args[0].value )
35
+
36
+ @stack << Types.new_object( RplList, args.reverse )
37
+ end )
38
+
39
+ @dictionary.add_word( ['list→', 'list->'],
40
+ 'Lists',
41
+ '( […] -- … ) unpack list on stack',
42
+ proc do
43
+ args = stack_extract( [[RplList]] )
44
+
45
+ args[0].value.each do |elt|
46
+ @stack << elt
47
+ end
48
+ end )
49
+
50
+ @dictionary.add_word( ['chr'],
51
+ 'String',
52
+ '( n -- c ) convert ASCII character code in stack level 1 into a string',
53
+ proc do
54
+ args = stack_extract( [[RplNumeric]] )
55
+
56
+ @stack << Types.new_object( RplString, "\"#{args[0].value.to_i.chr}\"" )
57
+ end )
58
+
59
+ @dictionary.add_word( ['num'],
60
+ 'String',
61
+ '( s -- n ) return ASCII code of the first character of the string in stack level 1 as a real number',
62
+ proc do
63
+ args = stack_extract( [[RplString]] )
64
+
65
+ @stack << Types.new_object( RplNumeric, args[0].value.ord )
66
+ end )
67
+
68
+ @dictionary.add_word( ['size'],
69
+ 'String',
70
+ '( s -- n ) return the length of the string or list',
71
+ proc do
72
+ args = stack_extract( [[RplString, RplList]] )
73
+
74
+ @stack << Types.new_object( RplNumeric, args[0].value.length )
75
+ end )
76
+
77
+ @dictionary.add_word( ['pos'],
78
+ 'String',
79
+ '( s s -- n ) search for the string in level 1 within the string in level 2',
80
+ proc do
81
+ args = stack_extract( [[RplString], [RplString]] )
82
+
83
+ @stack << Types.new_object( RplNumeric, args[1].value.index( args[0].value ) )
84
+ end )
85
+
86
+ @dictionary.add_word( ['sub'],
87
+ 'String',
88
+ '( s n n -- s ) return a substring of the string in level 3',
89
+ proc do
90
+ args = stack_extract( [[RplNumeric], [RplNumeric], [RplString]] )
91
+
92
+ @stack << Types.new_object( RplString, "\"#{args[2].value[ (args[1].value - 1)..(args[0].value - 1) ]}\"" )
93
+ end )
94
+
95
+ @dictionary.add_word( ['rev'],
96
+ 'String',
97
+ '( s -- s ) reverse string or list',
98
+ proc do
99
+ args = stack_extract( [[RplString, RplList]] )
100
+
101
+ args[0].value.reverse!
102
+
103
+ @stack << args[0]
104
+ end )
105
+
106
+ @dictionary.add_word( ['split'],
107
+ 'String',
108
+ '( s c -- … ) split string s on character c',
109
+ proc do
110
+ args = stack_extract( [[RplString], [RplString]] )
111
+
112
+ args[1].value.split( args[0].value ).each do |elt|
113
+ @stack << Types.new_object( RplString, "\"#{elt}\"" )
114
+ end
115
+ end )
116
+
117
+ @dictionary.add_word( ['dolist'],
118
+ 'Lists',
119
+ '( […] prg -- … ) run prg on each element of a list',
120
+ proc do
121
+ args = stack_extract( [[RplProgram], [RplList]] )
122
+
123
+ args[1].value.each do |elt|
124
+ @stack << elt
125
+ run( args[0].value )
126
+ end
127
+
128
+ run( "#{args[1].value.length} →list" )
129
+ end )
130
+ end
131
+ end
132
+ end
133
+ end
@@ -1,8 +1,10 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module RplLang
4
- module Core
4
+ module Words
5
5
  module Test
6
+ include Types
7
+
6
8
  def populate_dictionary
7
9
  super
8
10
 
@@ -12,8 +14,7 @@ module RplLang
12
14
  proc do
13
15
  args = stack_extract( %i[any any] )
14
16
 
15
- @stack << { type: :boolean,
16
- value: args[1][:value] > args[0][:value] }
17
+ @stack << Types.new_object( RplBoolean, args[1].value > args[0].value )
17
18
  end )
18
19
 
19
20
  @dictionary.add_word( ['≥', '>='],
@@ -22,8 +23,7 @@ module RplLang
22
23
  proc do
23
24
  args = stack_extract( %i[any any] )
24
25
 
25
- @stack << { type: :boolean,
26
- value: args[1][:value] >= args[0][:value] }
26
+ @stack << Types.new_object( RplBoolean, args[1].value >= args[0].value )
27
27
  end )
28
28
 
29
29
  @dictionary.add_word( ['<'],
@@ -32,8 +32,7 @@ module RplLang
32
32
  proc do
33
33
  args = stack_extract( %i[any any] )
34
34
 
35
- @stack << { type: :boolean,
36
- value: args[1][:value] < args[0][:value] }
35
+ @stack << Types.new_object( RplBoolean, args[1].value < args[0].value )
37
36
  end )
38
37
 
39
38
  @dictionary.add_word( ['≤', '<='],
@@ -42,8 +41,7 @@ module RplLang
42
41
  proc do
43
42
  args = stack_extract( %i[any any] )
44
43
 
45
- @stack << { type: :boolean,
46
- value: args[1][:value] <= args[0][:value] }
44
+ @stack << Types.new_object( RplBoolean, args[1].value <= args[0].value )
47
45
  end )
48
46
 
49
47
  @dictionary.add_word( ['≠', '!='],
@@ -52,8 +50,7 @@ module RplLang
52
50
  proc do
53
51
  args = stack_extract( %i[any any] )
54
52
 
55
- @stack << { type: :boolean,
56
- value: args[1][:value] != args[0][:value] }
53
+ @stack << Types.new_object( RplBoolean, args[1].value != args[0].value )
57
54
  end )
58
55
 
59
56
  @dictionary.add_word( ['==', 'same'],
@@ -62,64 +59,57 @@ module RplLang
62
59
  proc do
63
60
  args = stack_extract( %i[any any] )
64
61
 
65
- @stack << { type: :boolean,
66
- value: args[1][:value] == args[0][:value] }
62
+ @stack << Types.new_object( RplBoolean, args[1].value == args[0].value )
67
63
  end )
68
64
 
69
65
  @dictionary.add_word( ['and'],
70
66
  'Test',
71
67
  '( a b -- t ) boolean and',
72
68
  proc do
73
- args = stack_extract( [%i[boolean], %i[boolean]] )
69
+ args = stack_extract( [[RplBoolean], [RplBoolean]] )
74
70
 
75
- @stack << { type: :boolean,
76
- value: args[1][:value] && args[0][:value] }
71
+ @stack << Types.new_object( RplBoolean, args[1].value && args[0].value )
77
72
  end )
78
73
 
79
74
  @dictionary.add_word( ['or'],
80
75
  'Test',
81
76
  '( a b -- t ) boolean or',
82
77
  proc do
83
- args = stack_extract( [%i[boolean], %i[boolean]] )
78
+ args = stack_extract( [[RplBoolean], [RplBoolean]] )
84
79
 
85
- @stack << { type: :boolean,
86
- value: args[1][:value] || args[0][:value] }
80
+ @stack << Types.new_object( RplBoolean, args[1].value || args[0].value )
87
81
  end )
88
82
 
89
83
  @dictionary.add_word( ['xor'],
90
84
  'Test',
91
85
  '( a b -- t ) boolean xor',
92
86
  proc do
93
- args = stack_extract( [%i[boolean], %i[boolean]] )
87
+ args = stack_extract( [[RplBoolean], [RplBoolean]] )
94
88
 
95
- @stack << { type: :boolean,
96
- value: args[1][:value] ^ args[0][:value] }
89
+ @stack << Types.new_object( RplBoolean, args[1].value ^ args[0].value )
97
90
  end )
98
91
 
99
92
  @dictionary.add_word( ['not'],
100
93
  'Test',
101
94
  '( a -- t ) invert boolean value',
102
95
  proc do
103
- args = stack_extract( [%i[boolean]] )
96
+ args = stack_extract( [[RplBoolean]] )
104
97
 
105
- @stack << { type: :boolean,
106
- value: !args[0][:value] }
98
+ @stack << Types.new_object( RplBoolean,!args[0].value )
107
99
  end )
108
100
 
109
101
  @dictionary.add_word( ['true'],
110
102
  'Test',
111
103
  '( -- t ) push true onto stack',
112
104
  proc do
113
- @stack << { type: :boolean,
114
- value: true }
105
+ @stack << Types.new_object( RplBoolean, true )
115
106
  end )
116
107
 
117
108
  @dictionary.add_word( ['false'],
118
109
  'Test',
119
110
  '( -- t ) push false onto stack',
120
111
  proc do
121
- @stack << { type: :boolean,
122
- value: false }
112
+ @stack << Types.new_object( RplBoolean, false )
123
113
  end )
124
114
  end
125
115
  end
@@ -3,8 +3,10 @@
3
3
  require 'date'
4
4
 
5
5
  module RplLang
6
- module Core
6
+ module Words
7
7
  module TimeAndDate
8
+ include Types
9
+
8
10
  def populate_dictionary
9
11
  super
10
12
 
@@ -12,15 +14,13 @@ module RplLang
12
14
  'Time and date',
13
15
  '( -- t ) push current time',
14
16
  proc do
15
- @stack << { type: :string,
16
- value: Time.now.to_s }
17
+ @stack << Types.new_object( RplString, "\"#{Time.now}\"" )
17
18
  end )
18
19
  @dictionary.add_word( ['date'],
19
20
  'Time and date',
20
21
  '( -- d ) push current date',
21
22
  proc do
22
- @stack << { type: :string,
23
- value: Date.today.to_s }
23
+ @stack << Types.new_object( RplString, "\"#{Date.today}\"" )
24
24
  end )
25
25
  @dictionary.add_word( ['ticks'],
26
26
  'Time and date',
@@ -28,9 +28,7 @@ module RplLang
28
28
  proc do
29
29
  ticks_since_epoch = Time.utc( 1, 1, 1 ).to_i * 10_000_000
30
30
  now = Time.now
31
- @stack << { type: :numeric,
32
- base: 10,
33
- value: now.to_i * 10_000_000 + now.nsec / 100 - ticks_since_epoch }
31
+ @stack << Types.new_object( RplNumeric, now.to_i * 10_000_000 + now.nsec / 100 - ticks_since_epoch )
34
32
  end )
35
33
  end
36
34
  end
@@ -3,8 +3,10 @@
3
3
  # https://rosettacode.org/wiki/Trigonometric_functions#Ruby
4
4
 
5
5
  module RplLang
6
- module Core
6
+ module Words
7
7
  module Trig
8
+ include Types
9
+
8
10
  def populate_dictionary
9
11
  super
10
12
 
@@ -12,49 +14,38 @@ module RplLang
12
14
  'Trig on reals and complexes',
13
15
  '( … -- 𝛑 ) push 𝛑',
14
16
  proc do
15
- @stack << { type: :numeric,
16
- base: 10,
17
- value: BigMath.PI( precision ) }
17
+ @stack << Types.new_object( RplNumeric, BigMath.PI( RplNumeric.precision ) )
18
18
  end )
19
19
 
20
20
  @dictionary.add_word( ['sin'],
21
21
  'Trig on reals and complexes',
22
22
  '( n -- m ) compute sinus of n',
23
23
  proc do
24
- args = stack_extract( [%i[numeric]] )
24
+ args = stack_extract( [[RplNumeric]] )
25
25
 
26
- @stack << { type: :numeric,
27
- base: infer_resulting_base( args ),
28
- value: BigMath.sin( BigDecimal( args[0][:value], precision ), precision ) }
26
+ @stack << Types.new_object( RplNumeric, BigMath.sin( BigDecimal( args[0].value, RplNumeric.precision ), RplNumeric.precision ) )
29
27
  end )
30
28
 
31
29
  @dictionary.add_word( ['asin'],
32
30
  'Trig on reals and complexes',
33
31
  '( n -- m ) compute arg-sinus of n',
34
- proc do
35
- run( '
36
- dup abs 1 ==
32
+ Types.new_object( RplProgram, '« dup abs 1 ==
37
33
  « 𝛑 2 / * »
38
34
  « dup sq 1 swap - sqrt / atan »
39
- ifte' )
40
- end )
35
+ ifte »' ) )
41
36
 
42
37
  @dictionary.add_word( ['cos'],
43
38
  'Trig on reals and complexes',
44
39
  '( n -- m ) compute cosinus of n',
45
40
  proc do
46
- args = stack_extract( [%i[numeric]] )
41
+ args = stack_extract( [[RplNumeric]] )
47
42
 
48
- @stack << { type: :numeric,
49
- base: infer_resulting_base( args ),
50
- value: BigMath.cos( BigDecimal( args[0][:value], precision ), precision ) }
43
+ @stack << Types.new_object( RplNumeric, BigMath.cos( BigDecimal( args[0].value, RplNumeric.precision ), RplNumeric.precision ) )
51
44
  end )
52
45
  @dictionary.add_word( ['acos'],
53
46
  'Trig on reals and complexes',
54
47
  '( n -- m ) compute arg-cosinus of n',
55
- proc do
56
- run( '
57
- dup 0 ==
48
+ Types.new_object( RplProgram, '« dup 0 ==
58
49
  « drop 𝛑 2 / »
59
50
  «
60
51
  dup sq 1 swap - sqrt / atan
@@ -62,38 +53,31 @@ module RplLang
62
53
  « 𝛑 + »
63
54
  ift
64
55
  »
65
- ifte' )
66
- end )
56
+ ifte »' ) )
67
57
 
68
58
  @dictionary.add_word( ['tan'],
69
59
  'Trig on reals and complexes',
70
60
  '( n -- m ) compute tangent of n',
71
- proc do
72
- run( 'dup sin swap cos /' )
73
- end )
61
+ Types.new_object( RplProgram, '« dup sin swap cos / »' ) )
74
62
 
75
63
  @dictionary.add_word( ['atan'],
76
64
  'Trig on reals and complexes',
77
65
  '( n -- m ) compute arc-tangent of n',
78
66
  proc do
79
- args = stack_extract( [%i[numeric]] )
67
+ args = stack_extract( [[RplNumeric]] )
68
+
69
+ @stack << Types.new_object( RplNumeric, BigMath.atan( BigDecimal( args[0].value, RplNumeric.precision ), RplNumeric.precision ) )
70
+ end )
80
71
 
81
- @stack << { type: :numeric,
82
- base: infer_resulting_base( args ),
83
- value: BigMath.atan( BigDecimal( args[0][:value], precision ), precision ) }
84
- end)
85
72
  @dictionary.add_word( ['d→r', 'd->r'],
86
73
  'Trig on reals and complexes',
87
74
  '( n -- m ) convert degree to radian',
88
- proc do
89
- run( '180 / 𝛑 *' )
90
- end )
75
+ Types.new_object( RplProgram, '« 180 / 𝛑 * »' ) )
76
+
91
77
  @dictionary.add_word( ['r→d', 'r->d'],
92
78
  'Trig on reals and complexes',
93
79
  '( n -- m ) convert radian to degree',
94
- proc do
95
- run( '𝛑 180 / /' )
96
- end)
80
+ Types.new_object( RplProgram, '« 𝛑 180 / / »' ) )
97
81
  end
98
82
  end
99
83
  end
data/lib/rpl/words.rb ADDED
@@ -0,0 +1,15 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'rpl/words/branch'
4
+ require 'rpl/words/general'
5
+ require 'rpl/words/mode'
6
+ require 'rpl/words/operations'
7
+ require 'rpl/words/program'
8
+ require 'rpl/words/stack'
9
+ require 'rpl/words/store'
10
+ require 'rpl/words/string-list'
11
+ require 'rpl/words/test'
12
+ require 'rpl/words/time-date'
13
+ require 'rpl/words/trig'
14
+ require 'rpl/words/logarithm'
15
+ require 'rpl/words/filesystem'
data/lib/rpl.rb CHANGED
@@ -1,43 +1,31 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require 'rpl/interpreter'
4
-
5
- require 'rpl/core/branch'
6
- require 'rpl/core/general'
7
- require 'rpl/core/mode'
8
- require 'rpl/core/operations'
9
- require 'rpl/core/program'
10
- require 'rpl/core/stack'
11
- require 'rpl/core/store'
12
- require 'rpl/core/string'
13
- require 'rpl/core/test'
14
- require 'rpl/core/time-date'
15
- require 'rpl/core/trig'
16
- require 'rpl/core/logarithm'
17
- require 'rpl/core/filesystem'
18
- require 'rpl/core/list'
4
+ require 'rpl/types'
5
+ require 'rpl/words'
19
6
 
20
7
  class Rpl < Interpreter
8
+ include Types
9
+
21
10
  def initialize( stack = [], dictionary = Dictionary.new )
22
11
  super
23
12
 
24
13
  populate_dictionary if @dictionary.words.empty?
25
14
  end
26
15
 
27
- prepend RplLang::Core::Branch
28
- prepend RplLang::Core::FileSystem
29
- prepend RplLang::Core::General
30
- prepend RplLang::Core::List
31
- prepend RplLang::Core::Logarithm
32
- prepend RplLang::Core::Mode
33
- prepend RplLang::Core::Operations
34
- prepend RplLang::Core::Program
35
- prepend RplLang::Core::Stack
36
- prepend RplLang::Core::Store
37
- prepend RplLang::Core::String
38
- prepend RplLang::Core::Test
39
- prepend RplLang::Core::TimeAndDate
40
- prepend RplLang::Core::Trig
16
+ prepend RplLang::Words::Branch
17
+ prepend RplLang::Words::FileSystem
18
+ prepend RplLang::Words::General
19
+ prepend RplLang::Words::Logarithm
20
+ prepend RplLang::Words::Mode
21
+ prepend RplLang::Words::Operations
22
+ prepend RplLang::Words::Program
23
+ prepend RplLang::Words::Stack
24
+ prepend RplLang::Words::Store
25
+ prepend RplLang::Words::StringAndList
26
+ prepend RplLang::Words::Test
27
+ prepend RplLang::Words::TimeAndDate
28
+ prepend RplLang::Words::Trig
41
29
 
42
30
  def populate_dictionary; end
43
31
  end