rpl 0.3.0 → 0.6.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 Operations
6
+ include Types
7
+
6
8
  def populate_dictionary
7
9
  super
8
10
 
@@ -11,69 +13,70 @@ module RplLang
11
13
  'Usual operations on reals and complexes',
12
14
  '( a b -- c ) addition',
13
15
  proc do
14
- addable = %i[numeric string name list]
16
+ addable = [RplNumeric, RplString, RplName, RplList]
15
17
  args = stack_extract( [addable, addable] )
16
- # | + | 1 numeric | 1 string | 1 name | 1 list |
18
+ # | + | 1 numeric | 1 string | 1 name |v1 list |
17
19
  # |-----------+-----------+----------+--------+--------|
18
- # | 0 numeric | numeric | string | name | list |
19
- # | 0 string | string | string | string | list |
20
- # | 0 name | string | string | name | list |
21
- # | 0 list | list | list | list | list |
22
-
23
- result = { type: case args[0][:type]
24
- when :numeric
25
- args[1][:type]
26
-
27
- when :string
28
- case args[1][:type]
29
- when :list
30
- :list
31
- else
32
- :string
33
- end
34
-
35
- when :name
36
- case args[1][:type]
37
- when :name
38
- :name
39
- when :list
40
- :list
41
- else
42
- :string
43
- end
44
-
45
- when :list
46
- :list
47
-
48
- else
49
- args[0][:type]
50
- end }
51
-
52
- if result[:type] == :list
53
- args.each do |elt|
54
- next unless elt[:type] != :list
55
-
56
- elt_copy = Marshal.load(Marshal.dump( elt ))
57
- elt[:type] = :list
58
- elt[:value] = [elt_copy]
59
- end
60
- end
61
-
62
- value_to_string = lambda do |e|
63
- if e[:type] == :numeric
64
- stringify( e )
65
- else
66
- e[:value].to_s
67
- end
68
- end
69
-
70
- result[:value] = if %i[name string].include?( result[:type] )
71
- "#{value_to_string.call( args[1] )}#{value_to_string.call( args[0] )}"
72
- else
73
- args[1][:value] + args[0][:value]
74
- end
75
-
76
- result[:base] = args[0][:base] if result[:type] == :numeric
20
+ # | 0 numeric | numeric | string | name |vlist |
21
+ # |v0 string |vstring |vstring |vstring |vlist |
22
+ # |v0 name |vstring |vstring |vname |vlist |
23
+ # |v0 list |vlist |vlist |vlist |vlist |
24
+
25
+ args.reverse!
26
+
27
+ result = if args[0].instance_of?( RplList )
28
+ if args[1].instance_of?( RplList )
29
+ args[0].value.concat( args[1].value )
30
+ else
31
+ args[0].value << args[1]
32
+ end
33
+ args[0]
34
+
35
+ elsif args[1].instance_of?( RplList )
36
+ if args[0].instance_of?( RplList )
37
+ args[0].value.concat( args[1].value )
38
+ args[0]
39
+ else
40
+ args[1].value.unshift( args[0] )
41
+ args[1]
42
+ end
43
+
44
+ elsif args[0].instance_of?( RplString )
45
+ args[0].value = if args[1].instance_of?( RplString ) ||
46
+ args[1].instance_of?( RplName )
47
+ "#{args[0].value}#{args[1].value}"
48
+ else
49
+ "#{args[0].value}#{args[1]}"
50
+ end
51
+ args[0]
52
+
53
+ elsif args[0].instance_of?( RplName )
54
+
55
+ if args[1].instance_of?( RplName )
56
+ args[0].value = "#{args[0].value}#{args[1].value}"
57
+ args[0]
58
+ else
59
+ if args[1].instance_of?( RplString )
60
+ RplString.new( "\"#{args[0].value}#{args[1].value}\"" )
61
+ elsif args[1].instance_of?( RplNumeric )
62
+ args[0].value = "#{args[0].value}#{args[1]}"
63
+ args[0]
64
+ else
65
+ RplString.new( "\"#{args[0]}#{args[1]}\"" )
66
+ end
67
+ end
68
+
69
+ elsif args[0].instance_of?( RplNumeric )
70
+ if args[1].instance_of?( RplNumeric )
71
+ args[0].value += args[1].value
72
+ args[0]
73
+
74
+ elsif args[1].instance_of?( RplString ) ||
75
+ args[1].instance_of?( RplName )
76
+ args[1].value = "#{args[0]}#{args[1].value}"
77
+ args[1]
78
+ end
79
+ end
77
80
 
78
81
  @stack << result
79
82
  end )
@@ -82,10 +85,11 @@ module RplLang
82
85
  'Usual operations on reals and complexes',
83
86
  '( a b -- c ) subtraction',
84
87
  proc do
85
- args = stack_extract( [%i[numeric], %i[numeric]] )
88
+ args = stack_extract( [[RplNumeric], [RplNumeric]] )
89
+
90
+ args[1].value = args[1].value - args[0].value
86
91
 
87
- @stack << { type: :numeric, base: infer_resulting_base( args ),
88
- value: args[1][:value] - args[0][:value] }
92
+ @stack << args[1]
89
93
  end )
90
94
 
91
95
  @dictionary.add_word( ['chs'],
@@ -99,20 +103,22 @@ module RplLang
99
103
  'Usual operations on reals and complexes',
100
104
  '( a b -- c ) multiplication',
101
105
  proc do
102
- args = stack_extract( [%i[numeric], %i[numeric]] )
106
+ args = stack_extract( [[RplNumeric], [RplNumeric]] )
107
+
108
+ args[1].value = args[1].value * args[0].value
103
109
 
104
- @stack << { type: :numeric, base: infer_resulting_base( args ),
105
- value: args[1][:value] * args[0][:value] }
110
+ @stack << args[1]
106
111
  end )
107
112
 
108
113
  @dictionary.add_word( ['÷', '/'],
109
114
  'Usual operations on reals and complexes',
110
115
  '( a b -- c ) division',
111
116
  proc do
112
- args = stack_extract( [%i[numeric], %i[numeric]] )
117
+ args = stack_extract( [[RplNumeric], [RplNumeric]] )
118
+
119
+ args[1].value = args[1].value / args[0].value
113
120
 
114
- @stack << { type: :numeric, base: infer_resulting_base( args ),
115
- value: args[1][:value] / args[0][:value] }
121
+ @stack << args[1]
116
122
  end )
117
123
 
118
124
  @dictionary.add_word( ['inv'],
@@ -126,20 +132,22 @@ module RplLang
126
132
  'Usual operations on reals and complexes',
127
133
  '( a b -- c ) a to the power of b',
128
134
  proc do
129
- args = stack_extract( [%i[numeric], %i[numeric]] )
135
+ args = stack_extract( [[RplNumeric], [RplNumeric]] )
130
136
 
131
- @stack << { type: :numeric, base: infer_resulting_base( args ),
132
- value: args[1][:value]**args[0][:value] }
137
+ args[1].value = args[1].value**args[0].value
138
+
139
+ @stack << args[1]
133
140
  end )
134
141
 
135
142
  @dictionary.add_word( ['√', 'sqrt'],
136
143
  'Usual operations on reals and complexes',
137
144
  '( a -- b ) square root',
138
145
  proc do
139
- args = stack_extract( [%i[numeric]] )
146
+ args = stack_extract( [[RplNumeric]] )
140
147
 
141
- @stack << { type: :numeric, base: infer_resulting_base( args ),
142
- value: BigMath.sqrt( BigDecimal( args[0][:value], precision ), precision ) }
148
+ args[0].value = BigMath.sqrt( args[0].value, RplNumeric.precision )
149
+
150
+ @stack << args[0]
143
151
  end )
144
152
 
145
153
  @dictionary.add_word( ['²', 'sq'],
@@ -153,10 +161,11 @@ module RplLang
153
161
  'Usual operations on reals and complexes',
154
162
  '( a -- b ) absolute value',
155
163
  proc do
156
- args = stack_extract( [%i[numeric]] )
164
+ args = stack_extract( [[RplNumeric]] )
165
+
166
+ args[0].value = args[0].value.abs
157
167
 
158
- @stack << { type: :numeric, base: infer_resulting_base( args ),
159
- value: args[0][:value].abs }
168
+ @stack << args[0]
160
169
  end )
161
170
 
162
171
  @dictionary.add_word( ['dec'],
@@ -184,9 +193,9 @@ module RplLang
184
193
  'Usual operations on reals and complexes',
185
194
  '( a b -- a ) set numeric\'s base to b',
186
195
  proc do
187
- args = stack_extract( [%i[numeric], %i[numeric]] )
196
+ args = stack_extract( [[RplNumeric], [RplNumeric]] )
188
197
 
189
- args[1][:base] = args[0][:value]
198
+ args[1].base = args[0].value
190
199
 
191
200
  @stack << args[1]
192
201
  end )
@@ -195,17 +204,16 @@ module RplLang
195
204
  'Usual operations on reals and complexes',
196
205
  '( a -- b ) sign of element',
197
206
  proc do
198
- args = stack_extract( [%i[numeric]] )
199
- value = if args[0][:value].positive?
200
- 1
201
- elsif args[0][:value].negative?
202
- -1
203
- else
204
- 0
205
- end
206
-
207
- @stack << { type: :numeric, base: infer_resulting_base( args ),
208
- value: value }
207
+ args = stack_extract( [[RplNumeric]] )
208
+ args[0].value = if args[0].value.positive?
209
+ 1
210
+ elsif args[0].value.negative?
211
+ -1
212
+ else
213
+ 0
214
+ end
215
+
216
+ @stack << args[0]
209
217
  end )
210
218
 
211
219
  # Operations on reals
@@ -213,102 +221,104 @@ module RplLang
213
221
  'Operations on reals',
214
222
  '( a b -- c ) b% of a',
215
223
  proc do
216
- args = stack_extract( [%i[numeric], %i[numeric]] )
224
+ args = stack_extract( [[RplNumeric], [RplNumeric]] )
217
225
 
218
- @stack << { type: :numeric,
219
- base: infer_resulting_base( args ),
220
- value: args[0][:value] * ( args[1][:value] / 100.0 ) }
226
+ args[1].value = args[0].value * ( args[1].value / 100.0 )
227
+
228
+ @stack << args[1]
221
229
  end )
222
230
 
223
231
  @dictionary.add_word( ['%CH'],
224
232
  'Operations on reals',
225
233
  '( a b -- c ) b is c% of a',
226
234
  proc do
227
- args = stack_extract( [%i[numeric], %i[numeric]] )
235
+ args = stack_extract( [[RplNumeric], [RplNumeric]] )
236
+
237
+ args[1].value = 100.0 * ( args[0].value / args[1].value )
228
238
 
229
- @stack << { type: :numeric,
230
- base: infer_resulting_base( args ),
231
- value: 100.0 * ( args[0][:value] / args[1][:value] ) }
239
+ @stack << args[1]
232
240
  end )
233
241
 
234
242
  @dictionary.add_word( ['mod'],
235
243
  'Operations on reals',
236
244
  '( a b -- c ) modulo',
237
245
  proc do
238
- args = stack_extract( [%i[numeric], %i[numeric]] )
246
+ args = stack_extract( [[RplNumeric], [RplNumeric]] )
247
+
248
+ args[1].value = args[1].value % args[0].value
239
249
 
240
- @stack << { type: :numeric,
241
- base: infer_resulting_base( args ),
242
- value: args[1][:value] % args[0][:value] }
250
+ @stack << args[1]
243
251
  end )
244
252
 
245
253
  @dictionary.add_word( ['!', 'fact'],
246
254
  'Operations on reals',
247
255
  '( a -- b ) factorial',
248
256
  proc do
249
- args = stack_extract( [%i[numeric]] )
257
+ args = stack_extract( [[RplNumeric]] )
258
+
259
+ args[0].value = Math.gamma( args[0].value )
250
260
 
251
- @stack << { type: :numeric,
252
- base: infer_resulting_base( args ),
253
- value: Math.gamma( args[0][:value] ) }
261
+ @stack << args[0]
254
262
  end )
255
263
 
256
264
  @dictionary.add_word( ['floor'],
257
265
  'Operations on reals',
258
266
  '( a -- b ) highest integer under a',
259
267
  proc do
260
- args = stack_extract( [%i[numeric]] )
268
+ args = stack_extract( [[RplNumeric]] )
261
269
 
262
- @stack << { type: :numeric,
263
- base: infer_resulting_base( args ),
264
- value: args[0][:value].floor }
270
+ args[0].value = args[0].value.floor
271
+
272
+ @stack << args[0]
265
273
  end )
266
274
 
267
275
  @dictionary.add_word( ['ceil'],
268
276
  'Operations on reals',
269
277
  '( a -- b ) highest integer over a',
270
278
  proc do
271
- args = stack_extract( [%i[numeric]] )
279
+ args = stack_extract( [[RplNumeric]] )
280
+
281
+ args[0].value = args[0].value.ceil
272
282
 
273
- @stack << { type: :numeric,
274
- base: infer_resulting_base( args ),
275
- value: args[0][:value].ceil }
283
+ @stack << args[0]
276
284
  end )
277
285
 
278
286
  @dictionary.add_word( ['min'],
279
287
  'Operations on reals',
280
288
  '( a b -- a/b ) leave lowest of a or b',
281
289
  proc do
282
- args = stack_extract( [%i[numeric], %i[numeric]] )
290
+ args = stack_extract( [[RplNumeric], [RplNumeric]] )
283
291
 
284
- @stack << ( args[0][:value] < args[1][:value] ? args[0] : args[1] )
292
+ @stack << ( args[0].value < args[1].value ? args[0] : args[1] )
285
293
  end )
286
294
 
287
295
  @dictionary.add_word( ['max'],
288
296
  'Operations on reals',
289
297
  '( a b -- a/b ) leave highest of a or b',
290
298
  proc do
291
- args = stack_extract( [%i[numeric], %i[numeric]] )
299
+ args = stack_extract( [[RplNumeric], [RplNumeric]] )
292
300
 
293
- @stack << ( args[0][:value] > args[1][:value] ? args[0] : args[1] )
301
+ @stack << ( args[0].value > args[1].value ? args[0] : args[1] )
294
302
  end )
295
303
 
296
- # @dictionary.add_word( ['mant'],
297
- # 'Operations on reals',
298
- # 'mantissa of a real number',
299
- # proc do
304
+ @dictionary.add_word( ['mant'],
305
+ 'Operations on reals',
306
+ 'mantissa of a real number',
307
+ proc do
308
+ args = stack_extract( [[RplNumeric]] )
300
309
 
301
- # end )
310
+ @stack << RplNumeric.new( args[0].value.to_s.split('e').first.to_f.abs )
311
+ end )
302
312
 
303
313
  @dictionary.add_word( ['xpon'],
304
314
  'Operations on reals',
305
315
  'exponant of a real number',
306
316
  proc do
307
- args = stack_extract( [%i[numeric]] )
317
+ args = stack_extract( [[RplNumeric]] )
318
+
319
+ args[0].value = args[0].value.exponent
308
320
 
309
- @stack << { type: :numeric,
310
- base: infer_resulting_base( args ),
311
- value: args[0][:value].exponent }
321
+ @stack << args[0]
312
322
  end )
313
323
 
314
324
  @dictionary.add_word( ['ip'],
@@ -322,11 +332,11 @@ module RplLang
322
332
  'Operations on reals',
323
333
  '( n -- f ) fractional part',
324
334
  proc do
325
- args = stack_extract( [%i[numeric]] )
335
+ args = stack_extract( [[RplNumeric]] )
336
+
337
+ args[0].value = args[0].value.frac
326
338
 
327
- @stack << { type: :numeric,
328
- base: infer_resulting_base( args ),
329
- value: args[0][:value].frac }
339
+ @stack << args[0]
330
340
  end )
331
341
 
332
342
  # Operations on complexes
@@ -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 Program
6
+ include Types
7
+
6
8
  def populate_dictionary
7
9
  super
8
10
 
@@ -12,10 +14,10 @@ module RplLang
12
14
  proc do
13
15
  args = stack_extract( [:any] )
14
16
 
15
- if %i[list string numeric boolean].include?( args[0][:type] )
17
+ if [RplList, RplNumeric, RplBoolean].include?( args[0].class )
16
18
  @stack << args[0] # these types evaluate to themselves
17
19
  else
18
- run( args[0][:value].to_s )
20
+ run( args[0].value.to_s )
19
21
  end
20
22
  end )
21
23
  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 Stack
6
+ include Types
7
+
6
8
  def populate_dictionary
7
9
  super
8
10
 
@@ -18,9 +20,7 @@ module RplLang
18
20
  @dictionary.add_word( ['drop'],
19
21
  'Stack',
20
22
  '( a -- ) drop first stack element',
21
- proc do
22
- run( '1 dropn' )
23
- end )
23
+ RplProgram.new( '« 1 dropn »' ) )
24
24
 
25
25
  @dictionary.add_word( ['drop2'],
26
26
  'Stack',
@@ -33,9 +33,9 @@ module RplLang
33
33
  'Stack',
34
34
  '( a b … n -- ) drop first n stack elements',
35
35
  proc do
36
- args = stack_extract( [%i[numeric]] )
36
+ args = stack_extract( [[RplNumeric]] )
37
37
 
38
- _args = stack_extract( %i[any] * args[0][:value] )
38
+ _args = stack_extract( %i[any] * args[0].value )
39
39
  end )
40
40
 
41
41
  @dictionary.add_word( ['del'],
@@ -57,24 +57,20 @@ module RplLang
57
57
  @dictionary.add_word( ['dup'],
58
58
  'Stack',
59
59
  '( a -- a a ) duplicate first stack element',
60
- proc do
61
- run( '1 dupn' )
62
- end )
60
+ RplProgram.new( '« 1 dupn »' ) )
63
61
 
64
62
  @dictionary.add_word( ['dup2'],
65
63
  'Stack',
66
64
  '( a b -- a b a b ) duplicate first two stack elements',
67
- proc do
68
- run( '2 dupn' )
69
- end )
65
+ RplProgram.new( '« 2 dupn »' ) )
70
66
 
71
67
  @dictionary.add_word( ['dupn'],
72
68
  'Stack',
73
69
  '( a b … n -- a b … a b … ) duplicate first n stack elements',
74
70
  proc do
75
- args = stack_extract( [%i[numeric]] )
76
- n = args[0][:value].to_i
77
- args = stack_extract( %i[any] * args[0][:value] )
71
+ args = stack_extract( [[RplNumeric]] )
72
+ n = args[0].value.to_i
73
+ args = stack_extract( %i[any] * args[0].value )
78
74
 
79
75
  args.reverse!
80
76
 
@@ -89,9 +85,9 @@ module RplLang
89
85
  'Stack',
90
86
  '( … b … n -- … b … b ) push a copy of the given stack level onto the stack',
91
87
  proc do
92
- args = stack_extract( [%i[numeric]] )
93
- n = args[0][:value].to_i
94
- args = stack_extract( %i[any] * args[0][:value] )
88
+ args = stack_extract( [[RplNumeric]] )
89
+ n = args[0].value.to_i
90
+ args = stack_extract( %i[any] * args[0].value )
95
91
 
96
92
  args.reverse!
97
93
 
@@ -106,16 +102,16 @@ module RplLang
106
102
  'Stack',
107
103
  '( … -- … n ) push stack depth onto the stack',
108
104
  proc do
109
- @stack << { type: :numeric, base: 10, value: BigDecimal( stack.size ) }
105
+ @stack << RplNumeric.new( stack.size )
110
106
  end )
111
107
 
112
108
  @dictionary.add_word( ['roll'],
113
109
  'Stack',
114
110
  '( … a -- a … ) move a stack element to the top of the stack',
115
111
  proc do
116
- args = stack_extract( [%i[numeric]] )
117
- n = args[0][:value]
118
- args = stack_extract( %i[any] * args[0][:value] )
112
+ args = stack_extract( [[RplNumeric]] )
113
+ n = args[0].value
114
+ args = stack_extract( %i[any] * args[0].value )
119
115
 
120
116
  args.reverse!
121
117
 
@@ -130,9 +126,9 @@ module RplLang
130
126
  'Stack',
131
127
  '( a … -- … a ) move the element on top of the stack to a higher stack position',
132
128
  proc do
133
- args = stack_extract( [%i[numeric]] )
134
- n = args[0][:value]
135
- args = stack_extract( %i[any] * args[0][:value] )
129
+ args = stack_extract( [[RplNumeric]] )
130
+ n = args[0].value
131
+ args = stack_extract( %i[any] * args[0].value )
136
132
 
137
133
  args.reverse!
138
134
 
@@ -146,9 +142,7 @@ module RplLang
146
142
  @dictionary.add_word( ['over'],
147
143
  'Stack',
148
144
  '( a b -- a b a ) push a copy of the element in stack level 2 onto the stack',
149
- proc do
150
- run( '2 pick' )
151
- end )
145
+ RplProgram.new( '« 2 pick »' ) )
152
146
  end
153
147
  end
154
148
  end