rpl 0.5.0 → 0.6.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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 << RplList.new( (@dictionary.vars.keys + @dictionary.local_vars_layers.reduce([]) { |memo, layer| memo + layer.keys }).map { |name| RplName.new( name ) } )
45
46
  end )
46
47
 
47
48
  @dictionary.add_word( ['clusr'],
@@ -54,68 +55,52 @@ 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" ==
58
+ RplProgram.new( '« dup type "Name" ==
60
59
  « swap »
61
60
  ift
62
- over rcl + swap sto' )
63
- end )
61
+ over rcl + swap sto »' ) )
64
62
 
65
63
  @dictionary.add_word( ['sto-'],
66
64
  'Store',
67
65
  '( a n -- ) subtract content to variable\'s value',
68
- proc do
69
- run( '
70
- dup type "name" ==
66
+ RplProgram.new( '« dup type "Name" ==
71
67
  « swap »
72
68
  ift
73
- over rcl swap - swap sto' )
74
- end )
69
+ over rcl swap - swap sto »' ) )
75
70
 
76
71
  @dictionary.add_word( ['sto×', 'sto*'],
77
72
  'Store',
78
73
  '( a n -- ) multiply content of variable\'s value',
79
- proc do
80
- run( '
81
- dup type "name" ==
74
+ RplProgram.new( '« dup type "Name" ==
82
75
  « swap »
83
76
  ift
84
- over rcl * swap sto' )
85
- end )
77
+ over rcl * swap sto »' ) )
86
78
 
87
79
  @dictionary.add_word( ['sto÷', 'sto/'],
88
80
  'Store',
89
81
  '( a n -- ) divide content of variable\'s value',
90
- proc do
91
- run( '
92
- dup type "name" ==
82
+ RplProgram.new( '« dup type "Name" ==
93
83
  « swap »
94
84
  ift
95
- over rcl swap / swap sto' )
96
- end )
85
+ over rcl swap / swap sto »' ) )
97
86
 
98
87
  @dictionary.add_word( ['sneg'],
99
88
  'Store',
100
89
  '( a n -- ) negate content of variable\'s value',
101
- proc do
102
- run( 'dup rcl chs swap sto' )
103
- end )
90
+ RplProgram.new( '« dup rcl chs swap sto »' ) )
104
91
 
105
92
  @dictionary.add_word( ['sinv'],
106
93
  'Store',
107
94
  '( a n -- ) invert content of variable\'s value',
108
- proc do
109
- run( 'dup rcl inv swap sto' )
110
- end )
95
+ RplProgram.new( '« dup rcl inv swap sto »' ) )
111
96
 
112
97
  @dictionary.add_word( ['↴', 'lsto'],
113
98
  'Program',
114
99
  '( content name -- ) store to local variable',
115
100
  proc do
116
- args = stack_extract( [%i[name], :any] )
101
+ args = stack_extract( [[RplName], :any] )
117
102
 
118
- @dictionary.add_local_var( args[0][:value],
103
+ @dictionary.add_local_var( args[0].value,
119
104
  args[1] )
120
105
  end )
121
106
  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 << RplString.new( "\"#{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 << RplList.new( 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 << RplString.new( "\"#{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 << RplNumeric.new( 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 << RplNumeric.new( 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 << RplNumeric.new( 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 << RplString.new( "\"#{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 << RplString.new( "\"#{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 << RplBoolean.new( 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 << RplBoolean.new( 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 << RplBoolean.new( 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 << RplBoolean.new( 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 << RplBoolean.new( 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 << RplBoolean.new( 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 << RplBoolean.new( 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 << RplBoolean.new( 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 << RplBoolean.new( 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 << RplBoolean.new(!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 << RplBoolean.new( 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 << RplBoolean.new( 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 << RplString.new( "\"#{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 << RplString.new( "\"#{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 << RplNumeric.new( 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 << RplNumeric.new( 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 << RplNumeric.new( 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
+ RplProgram.new( '« 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 << RplNumeric.new( 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
+ RplProgram.new( '« 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
+ RplProgram.new( '« 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 << RplNumeric.new( 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
+ RplProgram.new( '« 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
+ RplProgram.new( '« 𝛑 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