rpl 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/bin/rpl +51 -0
- data/lib/rpl/core/branch.rb +55 -0
- data/lib/rpl/core/filesystem.rb +40 -0
- data/lib/rpl/core/general.rb +57 -0
- data/lib/rpl/core/list.rb +33 -0
- data/lib/rpl/core/logarithm.rb +118 -0
- data/lib/rpl/core/mode.rb +44 -0
- data/lib/rpl/core/operations.rb +387 -0
- data/lib/rpl/core/program.rb +20 -0
- data/lib/rpl/core/stack.rb +155 -0
- data/lib/rpl/core/store.rb +124 -0
- data/lib/rpl/core/string.rb +114 -0
- data/lib/rpl/core/test.rb +127 -0
- data/lib/rpl/core/time-date.rb +38 -0
- data/lib/rpl/core/trig.rb +100 -0
- data/lib/rpl/dictionary.rb +75 -0
- data/lib/rpl/interpreter.rb +217 -0
- data/lib/rpl.rb +43 -0
- metadata +61 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: b8843f4b55d77c8d3ec6c92cbe565ecb883361ba8cb47628097425b4b6f73da2
|
4
|
+
data.tar.gz: 430db66a68a4eeead6b16091e75aa9022a6a734004006067a38fb5283c3ec261
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 7eff83ebc75b43ba473b913513590b82286932dd8b9628f9ae8970bb8d352ddd60a057e648d31fad7a5fefab974d2ddbcd9a03b18094c8c977e709bf1d910f56
|
7
|
+
data.tar.gz: 5fcd3aa9b3c9d918876fc5f69e3025a2f0339a4e0da8c2bc66432db11821ded06a149b3dcfe88d2d3d955c90ca42c86d0f2a4dc1257612bc5804380cf0638a4a
|
data/bin/rpl
ADDED
@@ -0,0 +1,51 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
require 'readline'
|
5
|
+
|
6
|
+
require 'rpl'
|
7
|
+
|
8
|
+
class RplRepl
|
9
|
+
def initialize
|
10
|
+
@interpreter = Rpl.new
|
11
|
+
end
|
12
|
+
|
13
|
+
def run
|
14
|
+
Readline.completion_proc = proc do |s|
|
15
|
+
( @interpreter.dictionary.words.keys + @interpreter.dictionary.vars.keys ).grep(/^#{Regexp.escape(s)}/)
|
16
|
+
end
|
17
|
+
Readline.completion_append_character = ' '
|
18
|
+
|
19
|
+
loop do
|
20
|
+
input = Readline.readline( ' ', true )
|
21
|
+
break if input.nil? || input == 'quit'
|
22
|
+
|
23
|
+
pp Readline::HISTORY if input == 'history'
|
24
|
+
|
25
|
+
# Remove blank lines from history
|
26
|
+
Readline::HISTORY.pop if input.empty?
|
27
|
+
|
28
|
+
begin
|
29
|
+
@interpreter.run( input )
|
30
|
+
rescue ArgumentError => e
|
31
|
+
p e
|
32
|
+
end
|
33
|
+
|
34
|
+
print_stack
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
def format_element( elt )
|
39
|
+
@interpreter.stringify( elt )
|
40
|
+
end
|
41
|
+
|
42
|
+
def print_stack
|
43
|
+
stack_size = @interpreter.stack.size
|
44
|
+
|
45
|
+
@interpreter.stack.each_with_index do |elt, i|
|
46
|
+
puts "#{stack_size - i}: #{format_element( elt )}"
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
RplRepl.new.run
|
@@ -0,0 +1,55 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RplLang
|
4
|
+
module Core
|
5
|
+
module Branch
|
6
|
+
def populate_dictionary
|
7
|
+
super
|
8
|
+
|
9
|
+
@dictionary.add_word( ['ift'],
|
10
|
+
'Branch',
|
11
|
+
'( t pt -- … ) eval pt or not based on the value of boolean t',
|
12
|
+
proc do
|
13
|
+
run( '« nop » ifte' )
|
14
|
+
end )
|
15
|
+
|
16
|
+
@dictionary.add_word( ['ifte'],
|
17
|
+
'Branch',
|
18
|
+
'( t pt pf -- … ) eval pt or pf based on the value of boolean t',
|
19
|
+
proc do
|
20
|
+
args = stack_extract( [:any, :any, %i[boolean]] )
|
21
|
+
|
22
|
+
run( args[ args[2][:value] ? 1 : 0 ][:value] )
|
23
|
+
end )
|
24
|
+
|
25
|
+
@dictionary.add_word( ['times'],
|
26
|
+
'Branch',
|
27
|
+
'( p n -- … ) eval p n times while pushing counter on stack before',
|
28
|
+
proc do
|
29
|
+
args = stack_extract( [%i[numeric], :any] )
|
30
|
+
|
31
|
+
args[0][:value].to_i.times do |i|
|
32
|
+
counter = { value: BigDecimal( i, @precision ), type: :numeric, base: 10 }
|
33
|
+
@stack << counter
|
34
|
+
|
35
|
+
run( args[1][:value] )
|
36
|
+
end
|
37
|
+
end )
|
38
|
+
|
39
|
+
@dictionary.add_word( ['loop'],
|
40
|
+
'Branch',
|
41
|
+
'( p n1 n2 -- … ) eval p looping from n1 to n2 while pushing counter on stack before',
|
42
|
+
proc do
|
43
|
+
args = stack_extract( [%i[numeric], %i[numeric], :any] )
|
44
|
+
|
45
|
+
((args[1][:value].to_i)..(args[0][:value].to_i)).each do |i|
|
46
|
+
counter = { value: BigDecimal( i, @precision ), type: :numeric, base: 10 }
|
47
|
+
@stack << counter
|
48
|
+
|
49
|
+
run( args[2][:value] )
|
50
|
+
end
|
51
|
+
end )
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RplLang
|
4
|
+
module Core
|
5
|
+
module FileSystem
|
6
|
+
def populate_dictionary
|
7
|
+
super
|
8
|
+
|
9
|
+
@dictionary.add_word( ['fread'],
|
10
|
+
'Filesystem',
|
11
|
+
'( filename -- content ) read file and put content on stack as string',
|
12
|
+
proc do
|
13
|
+
args = stack_extract( [%i[string]] )
|
14
|
+
|
15
|
+
path = File.absolute_path( args[0][:value] )
|
16
|
+
|
17
|
+
@stack << { type: :string,
|
18
|
+
value: File.read( path ) }
|
19
|
+
end )
|
20
|
+
|
21
|
+
@dictionary.add_word( ['feval'],
|
22
|
+
'Filesystem',
|
23
|
+
'( filename -- … ) read and run file',
|
24
|
+
proc do
|
25
|
+
run( 'fread eval' )
|
26
|
+
end )
|
27
|
+
|
28
|
+
@dictionary.add_word( ['fwrite'],
|
29
|
+
'Filesystem',
|
30
|
+
'( content filename -- ) write content into filename',
|
31
|
+
proc do
|
32
|
+
args = stack_extract( [%i[string], :any] )
|
33
|
+
|
34
|
+
File.write( File.absolute_path( args[0][:value] ),
|
35
|
+
args[1][:value] )
|
36
|
+
end )
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
@@ -0,0 +1,57 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RplLang
|
4
|
+
module Core
|
5
|
+
module General
|
6
|
+
def populate_dictionary
|
7
|
+
super
|
8
|
+
|
9
|
+
@dictionary.add_word( ['nop'],
|
10
|
+
'General',
|
11
|
+
'( -- ) no operation',
|
12
|
+
proc {} )
|
13
|
+
|
14
|
+
@dictionary.add_word( ['help'],
|
15
|
+
'General',
|
16
|
+
'( w -- s ) pop help string of the given word',
|
17
|
+
proc do
|
18
|
+
args = stack_extract( [%i[name]] )
|
19
|
+
|
20
|
+
word = @dictionary.words[ args[0][:value] ]
|
21
|
+
|
22
|
+
@stack << { type: :string,
|
23
|
+
value: "#{args[0][:value]}: #{word.nil? ? 'not a core word' : word[:help]}" }
|
24
|
+
end )
|
25
|
+
|
26
|
+
@dictionary.add_word( ['quit'],
|
27
|
+
'General',
|
28
|
+
'( -- ) Stop and quit interpreter',
|
29
|
+
proc {} )
|
30
|
+
|
31
|
+
@dictionary.add_word( ['version'],
|
32
|
+
'General',
|
33
|
+
'( -- n ) Pop the interpreter\'s version number',
|
34
|
+
proc do
|
35
|
+
@stack += parse( @version.to_s )
|
36
|
+
end )
|
37
|
+
|
38
|
+
@dictionary.add_word( ['uname'],
|
39
|
+
'General',
|
40
|
+
'( -- s ) Pop the interpreter\'s complete indentification string',
|
41
|
+
proc do
|
42
|
+
@stack += parse( "\"Rpl Interpreter version #{@version}\"" )
|
43
|
+
end )
|
44
|
+
|
45
|
+
@dictionary.add_word( ['history'],
|
46
|
+
'REPL',
|
47
|
+
'',
|
48
|
+
proc {} )
|
49
|
+
|
50
|
+
@dictionary.add_word( ['.s'],
|
51
|
+
'REPL',
|
52
|
+
'DEBUG',
|
53
|
+
proc { pp @stack } )
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RplLang
|
4
|
+
module Core
|
5
|
+
module List
|
6
|
+
def populate_dictionary
|
7
|
+
super
|
8
|
+
|
9
|
+
@dictionary.add_word( ['→list', '->list'],
|
10
|
+
'Lists',
|
11
|
+
'( … x -- […] ) pack x stacks levels into a list',
|
12
|
+
proc do
|
13
|
+
args = stack_extract( [%i[numeric]] )
|
14
|
+
args = stack_extract( %i[any] * args[0][:value] )
|
15
|
+
|
16
|
+
@stack << { type: :list,
|
17
|
+
value: args.reverse }
|
18
|
+
end )
|
19
|
+
|
20
|
+
@dictionary.add_word( ['list→', 'list->'],
|
21
|
+
'Lists',
|
22
|
+
'( […] -- … ) unpack list on stack',
|
23
|
+
proc do
|
24
|
+
args = stack_extract( [%i[list]] )
|
25
|
+
|
26
|
+
args[0][:value].each do |elt|
|
27
|
+
@stack << elt
|
28
|
+
end
|
29
|
+
end )
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,118 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RplLang
|
4
|
+
module Core
|
5
|
+
module Logarithm
|
6
|
+
def populate_dictionary
|
7
|
+
super
|
8
|
+
|
9
|
+
@dictionary.add_word( ['ℇ', 'e'],
|
10
|
+
'Logs on reals and complexes',
|
11
|
+
'( … -- ℇ ) push ℇ',
|
12
|
+
proc do
|
13
|
+
@stack << { type: :numeric,
|
14
|
+
base: 10,
|
15
|
+
value: BigMath.E( @precision ) }
|
16
|
+
end )
|
17
|
+
|
18
|
+
# @dictionary.add_word( ['ln'],
|
19
|
+
# 'Logs on reals and complexes',
|
20
|
+
# 'logarithm base e',
|
21
|
+
# proc do
|
22
|
+
|
23
|
+
# end )
|
24
|
+
|
25
|
+
# @dictionary.add_word( ['lnp1'],
|
26
|
+
# 'Logs on reals and complexes',
|
27
|
+
# 'ln(1+x) which is useful when x is close to 0',
|
28
|
+
# proc do
|
29
|
+
|
30
|
+
# end )
|
31
|
+
|
32
|
+
# @dictionary.add_word( ['exp'],
|
33
|
+
# 'Logs on reals and complexes',
|
34
|
+
# 'exponential',
|
35
|
+
# proc do
|
36
|
+
|
37
|
+
# end )
|
38
|
+
|
39
|
+
# @dictionary.add_word( ['expm'],
|
40
|
+
# 'Logs on reals and complexes',
|
41
|
+
# 'exp(x)-1 which is useful when x is close to 0',
|
42
|
+
# proc do
|
43
|
+
|
44
|
+
# end )
|
45
|
+
|
46
|
+
# @dictionary.add_word( ['log10'],
|
47
|
+
# 'Logs on reals and complexes',
|
48
|
+
# 'logarithm base 10',
|
49
|
+
# proc do
|
50
|
+
|
51
|
+
# end )
|
52
|
+
|
53
|
+
# @dictionary.add_word( ['alog10'],
|
54
|
+
# 'Logs on reals and complexes',
|
55
|
+
# 'exponential base 10',
|
56
|
+
# proc do
|
57
|
+
|
58
|
+
# end )
|
59
|
+
|
60
|
+
# @dictionary.add_word( ['log2'],
|
61
|
+
# 'Logs on reals and complexes',
|
62
|
+
# 'logarithm base 2',
|
63
|
+
# proc do
|
64
|
+
|
65
|
+
# end )
|
66
|
+
|
67
|
+
# @dictionary.add_word( ['alog2'],
|
68
|
+
# 'Logs on reals and complexes',
|
69
|
+
# 'exponential base 2',
|
70
|
+
# proc do
|
71
|
+
|
72
|
+
# end )
|
73
|
+
|
74
|
+
# @dictionary.add_word( ['sinh'],
|
75
|
+
# 'Logs on reals and complexes',
|
76
|
+
# 'hyperbolic sine',
|
77
|
+
# proc do
|
78
|
+
|
79
|
+
# end )
|
80
|
+
|
81
|
+
# @dictionary.add_word( ['asinh'],
|
82
|
+
# 'Logs on reals and complexes',
|
83
|
+
# 'inverse hyperbolic sine',
|
84
|
+
# proc do
|
85
|
+
|
86
|
+
# end )
|
87
|
+
|
88
|
+
# @dictionary.add_word( ['cosh'],
|
89
|
+
# 'Logs on reals and complexes',
|
90
|
+
# 'hyperbolic cosine',
|
91
|
+
# proc do
|
92
|
+
|
93
|
+
# end )
|
94
|
+
|
95
|
+
# @dictionary.add_word( ['acosh'],
|
96
|
+
# 'Logs on reals and complexes',
|
97
|
+
# 'inverse hyperbolic cosine',
|
98
|
+
# proc do
|
99
|
+
|
100
|
+
# end )
|
101
|
+
|
102
|
+
# @dictionary.add_word( ['tanh'],
|
103
|
+
# 'Logs on reals and complexes',
|
104
|
+
# 'hyperbolic tangent',
|
105
|
+
# proc do
|
106
|
+
|
107
|
+
# end )
|
108
|
+
|
109
|
+
# @dictionary.add_word( ['atanh'],
|
110
|
+
# 'Logs on reals and complexes',
|
111
|
+
# 'inverse hyperbolic tangent',
|
112
|
+
# proc do
|
113
|
+
|
114
|
+
# end )
|
115
|
+
end
|
116
|
+
end
|
117
|
+
end
|
118
|
+
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RplLang
|
4
|
+
module Core
|
5
|
+
module Mode
|
6
|
+
def populate_dictionary
|
7
|
+
super
|
8
|
+
|
9
|
+
@dictionary.add_word( ['prec'],
|
10
|
+
'Mode',
|
11
|
+
'( a -- ) set precision to a',
|
12
|
+
proc do
|
13
|
+
args = stack_extract( [%i[numeric]] )
|
14
|
+
|
15
|
+
@precision = args[0][:value]
|
16
|
+
end )
|
17
|
+
@dictionary.add_word( ['default'],
|
18
|
+
'Mode',
|
19
|
+
'( -- ) set default precision',
|
20
|
+
proc do
|
21
|
+
@precision = default_precision
|
22
|
+
end )
|
23
|
+
@dictionary.add_word( ['type'],
|
24
|
+
'Mode',
|
25
|
+
'( a -- s ) type of a as a string',
|
26
|
+
proc do
|
27
|
+
args = stack_extract( [:any] )
|
28
|
+
|
29
|
+
@stack << { type: :string,
|
30
|
+
value: args[0][:type].to_s }
|
31
|
+
end )
|
32
|
+
|
33
|
+
# @dictionary.add_word( ['std'],
|
34
|
+
# proc { __todo } ) # standard floating numbers representation. ex: std
|
35
|
+
# @dictionary.add_word( ['fix'],
|
36
|
+
# proc { __todo } ) # fixed point representation. ex: 6 fix
|
37
|
+
# @dictionary.add_word( ['sci'],
|
38
|
+
# proc { __todo } ) # scientific floating point representation. ex: 20 sci
|
39
|
+
# @dictionary.add_word( ['round'],
|
40
|
+
# proc { __todo } ) # set float rounding mode. ex: ["nearest", "toward zero", "toward +inf", "toward -inf", "away from zero"] round
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|