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.
- checksums.yaml +4 -4
- data/bin/rpl +11 -9
- data/lib/rpl/interpreter.rb +25 -204
- data/lib/rpl/parser.rb +87 -0
- data/lib/rpl/types/boolean.rb +32 -0
- data/lib/rpl/types/list.rb +34 -0
- data/lib/rpl/types/name.rb +36 -0
- data/lib/rpl/types/numeric.rb +113 -0
- data/lib/rpl/types/program.rb +27 -0
- data/lib/rpl/types/string.rb +27 -0
- data/lib/rpl/types.rb +19 -0
- data/lib/rpl/{core → words}/branch.rb +14 -16
- data/lib/rpl/{core → words}/filesystem.rb +10 -11
- data/lib/rpl/words/general.rb +112 -0
- data/lib/rpl/{core → words}/logarithm.rb +4 -4
- data/lib/rpl/{core → words}/mode.rb +7 -6
- data/lib/rpl/{core → words}/operations.rb +144 -134
- data/lib/rpl/{core → words}/program.rb +5 -3
- data/lib/rpl/{core → words}/stack.rb +22 -28
- data/lib/rpl/{core → words}/store.rb +18 -45
- data/lib/rpl/words/string-list.rb +133 -0
- data/lib/rpl/{core → words}/test.rb +19 -29
- data/lib/rpl/{core → words}/time-date.rb +6 -8
- data/lib/rpl/{core → words}/trig.rb +20 -36
- data/lib/rpl/words.rb +15 -0
- data/lib/rpl.rb +17 -29
- metadata +24 -16
- data/lib/rpl/core/general.rb +0 -57
- data/lib/rpl/core/list.rb +0 -33
- data/lib/rpl/core/string.rb +0 -114
data/lib/rpl/types.rb
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'rpl/types/boolean'
|
4
|
+
require 'rpl/types/name'
|
5
|
+
require 'rpl/types/list'
|
6
|
+
require 'rpl/types/string'
|
7
|
+
require 'rpl/types/program'
|
8
|
+
require 'rpl/types/numeric'
|
9
|
+
|
10
|
+
module Types
|
11
|
+
module_function
|
12
|
+
def new_object( type_class, value )
|
13
|
+
if type_class.can_parse?( value )
|
14
|
+
type_class.new( value )
|
15
|
+
else
|
16
|
+
RplString.new( "\"Error: cannot create #{type_class} with value #{value}\"" )
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -1,38 +1,37 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
module RplLang
|
4
|
-
module
|
4
|
+
module Words
|
5
5
|
module Branch
|
6
|
+
include Types
|
7
|
+
|
6
8
|
def populate_dictionary
|
7
9
|
super
|
8
10
|
|
9
11
|
@dictionary.add_word( ['ift'],
|
10
12
|
'Branch',
|
11
13
|
'( t pt -- … ) eval pt or not based on the value of boolean t',
|
12
|
-
|
13
|
-
run( '« nop » ifte' )
|
14
|
-
end )
|
14
|
+
Types.new_object( RplProgram, '« « nop » ifte »' ) )
|
15
15
|
|
16
16
|
@dictionary.add_word( ['ifte'],
|
17
17
|
'Branch',
|
18
18
|
'( t pt pf -- … ) eval pt or pf based on the value of boolean t',
|
19
19
|
proc do
|
20
|
-
args = stack_extract( [:any, :any,
|
20
|
+
args = stack_extract( [:any, :any, [RplBoolean]] )
|
21
21
|
|
22
|
-
run( args[ args[2]
|
22
|
+
run( args[ args[2].value ? 1 : 0 ].value )
|
23
23
|
end )
|
24
24
|
|
25
25
|
@dictionary.add_word( ['times'],
|
26
26
|
'Branch',
|
27
27
|
'( p n -- … ) eval p n times while pushing counter on stack before',
|
28
28
|
proc do
|
29
|
-
args = stack_extract( [
|
29
|
+
args = stack_extract( [[RplNumeric], :any] )
|
30
30
|
|
31
|
-
args[0]
|
32
|
-
|
33
|
-
@stack << counter
|
31
|
+
args[0].value.to_i.times do |counter|
|
32
|
+
@stack << Types.new_object( RplNumeric, counter )
|
34
33
|
|
35
|
-
run( args[1]
|
34
|
+
run( args[1].value )
|
36
35
|
end
|
37
36
|
end )
|
38
37
|
|
@@ -40,13 +39,12 @@ module RplLang
|
|
40
39
|
'Branch',
|
41
40
|
'( p n1 n2 -- … ) eval p looping from n1 to n2 while pushing counter on stack before',
|
42
41
|
proc do
|
43
|
-
args = stack_extract( [
|
42
|
+
args = stack_extract( [[RplNumeric], [RplNumeric], :any] )
|
44
43
|
|
45
|
-
((args[1]
|
46
|
-
|
47
|
-
@stack << counter
|
44
|
+
((args[1].value.to_i)..(args[0].value.to_i)).each do |counter|
|
45
|
+
@stack << Types.new_object( RplNumeric, counter )
|
48
46
|
|
49
|
-
run( args[2]
|
47
|
+
run( args[2].value )
|
50
48
|
end
|
51
49
|
end )
|
52
50
|
end
|
@@ -1,8 +1,10 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
module RplLang
|
4
|
-
module
|
4
|
+
module Words
|
5
5
|
module FileSystem
|
6
|
+
include Types
|
7
|
+
|
6
8
|
def populate_dictionary
|
7
9
|
super
|
8
10
|
|
@@ -10,29 +12,26 @@ module RplLang
|
|
10
12
|
'Filesystem',
|
11
13
|
'( filename -- content ) read file and put content on stack as string',
|
12
14
|
proc do
|
13
|
-
args = stack_extract( [
|
15
|
+
args = stack_extract( [[RplString]] )
|
14
16
|
|
15
|
-
path = File.absolute_path( args[0]
|
17
|
+
path = File.absolute_path( args[0].value )
|
16
18
|
|
17
|
-
@stack << {
|
18
|
-
value: File.read( path ) }
|
19
|
+
@stack << Types.new_object( RplString, "\"#{File.read( path )}\"" )
|
19
20
|
end )
|
20
21
|
|
21
22
|
@dictionary.add_word( ['feval'],
|
22
23
|
'Filesystem',
|
23
24
|
'( filename -- … ) read and run file',
|
24
|
-
|
25
|
-
run( 'fread eval' )
|
26
|
-
end )
|
25
|
+
Types.new_object( RplProgram, '« fread eval »' ) )
|
27
26
|
|
28
27
|
@dictionary.add_word( ['fwrite'],
|
29
28
|
'Filesystem',
|
30
29
|
'( content filename -- ) write content into filename',
|
31
30
|
proc do
|
32
|
-
args = stack_extract( [
|
31
|
+
args = stack_extract( [[RplString], :any] )
|
33
32
|
|
34
|
-
File.write( File.absolute_path( args[0]
|
35
|
-
args[1]
|
33
|
+
File.write( File.absolute_path( args[0].value ),
|
34
|
+
args[1].value )
|
36
35
|
end )
|
37
36
|
end
|
38
37
|
end
|
@@ -0,0 +1,112 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'tempfile'
|
4
|
+
|
5
|
+
module RplLang
|
6
|
+
module Words
|
7
|
+
module General
|
8
|
+
include Types
|
9
|
+
|
10
|
+
def populate_dictionary
|
11
|
+
super
|
12
|
+
|
13
|
+
@dictionary.add_word( ['nop'],
|
14
|
+
'General',
|
15
|
+
'( -- ) no operation',
|
16
|
+
proc {} )
|
17
|
+
|
18
|
+
@dictionary.add_word( ['help'],
|
19
|
+
'General',
|
20
|
+
'( w -- s ) pop help string of the given word',
|
21
|
+
proc do
|
22
|
+
args = stack_extract( [[RplName]] )
|
23
|
+
|
24
|
+
word = @dictionary.words[ args[0].value ]
|
25
|
+
|
26
|
+
@stack << Types.new_object( RplString, "\"#{args[0].value}: #{word.nil? ? 'not a core word' : word[:help]}\"" )
|
27
|
+
end )
|
28
|
+
|
29
|
+
@dictionary.add_word( ['words'],
|
30
|
+
'REPL',
|
31
|
+
'DEBUG',
|
32
|
+
proc do
|
33
|
+
@dictionary.words
|
34
|
+
.to_a
|
35
|
+
.group_by { |word| word.last[:category] }
|
36
|
+
.each do |cat, words|
|
37
|
+
puts cat
|
38
|
+
puts " #{words.map(&:first).join(', ')}"
|
39
|
+
end
|
40
|
+
end )
|
41
|
+
|
42
|
+
@dictionary.add_word( ['quit'],
|
43
|
+
'General',
|
44
|
+
'( -- ) Stop and quit interpreter',
|
45
|
+
proc {} )
|
46
|
+
|
47
|
+
@dictionary.add_word( ['version'],
|
48
|
+
'General',
|
49
|
+
'( -- n ) Pop the interpreter\'s version number',
|
50
|
+
proc do
|
51
|
+
@stack << Types.new_object( RplString, "\"#{@version}\"" )
|
52
|
+
end )
|
53
|
+
|
54
|
+
@dictionary.add_word( ['uname'],
|
55
|
+
'General',
|
56
|
+
'( -- s ) Pop the interpreter\'s complete indentification string',
|
57
|
+
proc do
|
58
|
+
@stack << Types.new_object( RplString, "\"Rpl Interpreter version #{@version}\"" )
|
59
|
+
end )
|
60
|
+
|
61
|
+
@dictionary.add_word( ['history'],
|
62
|
+
'REPL',
|
63
|
+
'',
|
64
|
+
proc {} )
|
65
|
+
|
66
|
+
@dictionary.add_word( ['edit'],
|
67
|
+
'General',
|
68
|
+
'( -- s ) Pop the interpreter\'s complete indentification string',
|
69
|
+
proc do
|
70
|
+
args = stack_extract( [:any] )
|
71
|
+
|
72
|
+
value = args[0].to_s
|
73
|
+
tempfile = Tempfile.new('rpl')
|
74
|
+
|
75
|
+
begin
|
76
|
+
tempfile.write( value )
|
77
|
+
tempfile.rewind
|
78
|
+
|
79
|
+
`$EDITOR #{tempfile.path}`
|
80
|
+
|
81
|
+
edited_value = tempfile.read
|
82
|
+
ensure
|
83
|
+
tempfile.close
|
84
|
+
tempfile.unlink
|
85
|
+
end
|
86
|
+
|
87
|
+
@stack << Types.new_object( args[0].class, edited_value )
|
88
|
+
end )
|
89
|
+
|
90
|
+
@dictionary.add_word( ['.s'],
|
91
|
+
'REPL',
|
92
|
+
'DEBUG',
|
93
|
+
proc { pp @stack } )
|
94
|
+
|
95
|
+
@dictionary.add_word( ['.d'],
|
96
|
+
'REPL',
|
97
|
+
'DEBUG',
|
98
|
+
proc { pp @dictionary } )
|
99
|
+
|
100
|
+
@dictionary.add_word( ['.v'],
|
101
|
+
'REPL',
|
102
|
+
'DEBUG',
|
103
|
+
proc { pp @dictionary.vars } )
|
104
|
+
|
105
|
+
@dictionary.add_word( ['.lv'],
|
106
|
+
'REPL',
|
107
|
+
'DEBUG',
|
108
|
+
proc { pp @dictionary.local_vars_layers } )
|
109
|
+
end
|
110
|
+
end
|
111
|
+
end
|
112
|
+
end
|
@@ -1,8 +1,10 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
module RplLang
|
4
|
-
module
|
4
|
+
module Words
|
5
5
|
module Logarithm
|
6
|
+
include Types
|
7
|
+
|
6
8
|
def populate_dictionary
|
7
9
|
super
|
8
10
|
|
@@ -10,9 +12,7 @@ module RplLang
|
|
10
12
|
'Logs on reals and complexes',
|
11
13
|
'( … -- ℇ ) push ℇ',
|
12
14
|
proc do
|
13
|
-
@stack <<
|
14
|
-
base: 10,
|
15
|
-
value: BigMath.E( @precision ) }
|
15
|
+
@stack << Types.new_object( RplNumeric, BigMath.E( RplNumeric.precision ) )
|
16
16
|
end )
|
17
17
|
|
18
18
|
# @dictionary.add_word( ['ln'],
|
@@ -1,8 +1,10 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
module RplLang
|
4
|
-
module
|
4
|
+
module Words
|
5
5
|
module Mode
|
6
|
+
include Types
|
7
|
+
|
6
8
|
def populate_dictionary
|
7
9
|
super
|
8
10
|
|
@@ -10,15 +12,15 @@ module RplLang
|
|
10
12
|
'Mode',
|
11
13
|
'( a -- ) set precision to a',
|
12
14
|
proc do
|
13
|
-
args = stack_extract( [
|
15
|
+
args = stack_extract( [[RplNumeric]] )
|
14
16
|
|
15
|
-
|
17
|
+
RplNumeric.precision = args[0].value
|
16
18
|
end )
|
17
19
|
@dictionary.add_word( ['default'],
|
18
20
|
'Mode',
|
19
21
|
'( -- ) set default precision',
|
20
22
|
proc do
|
21
|
-
|
23
|
+
RplNumeric.default_precision
|
22
24
|
end )
|
23
25
|
@dictionary.add_word( ['type'],
|
24
26
|
'Mode',
|
@@ -26,8 +28,7 @@ module RplLang
|
|
26
28
|
proc do
|
27
29
|
args = stack_extract( [:any] )
|
28
30
|
|
29
|
-
@stack << {
|
30
|
-
value: args[0][:type].to_s }
|
31
|
+
@stack << Types.new_object( RplString, "\"#{args[0].class.to_s[10..-1]}\"" )
|
31
32
|
end )
|
32
33
|
|
33
34
|
# @dictionary.add_word( ['std'],
|