rpl 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
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