rpl 0.5.0 → 0.7.1

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.
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 Core
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
- proc do
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, %i[boolean]] )
20
+ args = stack_extract( [:any, :any, [RplBoolean]] )
21
21
 
22
- run( args[ args[2][:value] ? 1 : 0 ][:value] )
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( [%i[numeric], :any] )
29
+ args = stack_extract( [[RplNumeric], :any] )
30
30
 
31
- args[0][:value].to_i.times do |i|
32
- counter = { value: BigDecimal( i, @precision ), type: :numeric, base: 10 }
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][:value] )
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( [%i[numeric], %i[numeric], :any] )
42
+ args = stack_extract( [[RplNumeric], [RplNumeric], :any] )
44
43
 
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
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][:value] )
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 Core
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( [%i[string]] )
15
+ args = stack_extract( [[RplString]] )
14
16
 
15
- path = File.absolute_path( args[0][:value] )
17
+ path = File.absolute_path( args[0].value )
16
18
 
17
- @stack << { type: :string,
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
- proc do
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( [%i[string], :any] )
31
+ args = stack_extract( [[RplString], :any] )
33
32
 
34
- File.write( File.absolute_path( args[0][:value] ),
35
- args[1][:value] )
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 Core
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 << { type: :numeric,
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 Core
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( [%i[numeric]] )
15
+ args = stack_extract( [[RplNumeric]] )
14
16
 
15
- @precision = args[0][:value]
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
- @precision = default_precision
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 << { type: :string,
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'],