fOOrth 0.6.10 → 0.6.11
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/README.md +13 -2
- data/fOOrth.gemspec +2 -2
- data/integration/array_lib_tests.rb +10 -0
- data/integration/exception_lib_tests.rb +4 -0
- data/integration/hash_lib_tests.rb +9 -0
- data/integration/numeric_lib_tests.rb +326 -321
- data/integration/procedure_lib_tests.rb +16 -0
- data/integration/queue_lib_tests.rb +2 -1
- data/integration/stack_lib_tests.rb +2 -1
- data/integration/string_lib_tests.rb +11 -0
- data/integration/thread_lib_tests.rb +11 -8
- data/lib/fOOrth/compiler/context.rb +64 -64
- data/lib/fOOrth/compiler/context/locals.rb +34 -34
- data/lib/fOOrth/compiler/context/map_name.rb +85 -85
- data/lib/fOOrth/compiler/context/tags.rb +60 -48
- data/lib/fOOrth/compiler/process/procedure.rb +40 -0
- data/lib/fOOrth/library.rb +1 -0
- data/lib/fOOrth/library/array_library.rb +41 -21
- data/lib/fOOrth/library/command_library.rb +1 -1
- data/lib/fOOrth/library/compile_library.rb +266 -266
- data/lib/fOOrth/library/complex_library.rb +82 -80
- data/lib/fOOrth/library/float_library.rb +37 -0
- data/lib/fOOrth/library/hash_library.rb +14 -6
- data/lib/fOOrth/library/mutex_library.rb +4 -2
- data/lib/fOOrth/library/numeric_library.rb +359 -380
- data/lib/fOOrth/library/procedure_library.rb +69 -65
- data/lib/fOOrth/library/queue_library.rb +6 -1
- data/lib/fOOrth/library/rational_library.rb +89 -89
- data/lib/fOOrth/library/stack_library.rb +6 -1
- data/lib/fOOrth/library/string_library.rb +18 -6
- data/lib/fOOrth/monkey_patch/exceptions.rb +2 -6
- data/lib/fOOrth/version.rb +1 -1
- data/tests/compiler/context_tests.rb +188 -177
- data/tests/compiler/file_source_tests.rb +130 -130
- data/tests/compiler/parser_tests.rb +4 -4
- data/tests/compiler/string_source_tests.rb +4 -4
- data/tests/core_tests.rb +138 -138
- data/tests/monkey_patch/complex_test.rb +24 -24
- data/tests/monkey_patch/object_test.rb +49 -49
- data/tests/monkey_patch/string_test.rb +61 -61
- metadata +10 -10
@@ -43,4 +43,20 @@ class ProcedureLibraryTester < Minitest::Test
|
|
43
43
|
foorth_equal('{{ 42 var: a a @ }} .call', [42])
|
44
44
|
end
|
45
45
|
|
46
|
+
def test_instance_data
|
47
|
+
foorth_run('42 Object .new .with{{ val@: @test self val$: $t_i_d_1 }}')
|
48
|
+
foorth_run('$t_i_d_1 .:: .mulby @test * ; ')
|
49
|
+
foorth_equal('2 $t_i_d_1 .mulby', [84])
|
50
|
+
|
51
|
+
foorth_run('99 $t_i_d_1 .with{{ var@: @boot }} ')
|
52
|
+
foorth_run('$t_i_d_1 .:: .addby @boot @ + ; ')
|
53
|
+
foorth_equal('2 $t_i_d_1 .addby', [101])
|
54
|
+
|
55
|
+
foorth_run('$t_i_d_1 .:: .set_boot @boot ! ;')
|
56
|
+
foorth_run('56 $t_i_d_1 .set_boot')
|
57
|
+
foorth_equal('2 $t_i_d_1 .addby', [58])
|
58
|
+
|
59
|
+
foorth_run('128 $t_i_d_1 .set_boot')
|
60
|
+
foorth_equal('64 $t_i_d_1 .addby', [192])
|
61
|
+
end
|
46
62
|
end
|
@@ -42,8 +42,9 @@ class QueueLibraryTester < Minitest::Test
|
|
42
42
|
|
43
43
|
foorth_equal('5 $q .push', [])
|
44
44
|
foorth_equal('$q .empty?', [false])
|
45
|
+
foorth_equal('$q .present?', [true])
|
45
46
|
foorth_equal('$q .length', [1])
|
46
|
-
foorth_equal('$q .clear', [])
|
47
|
+
foorth_equal('$q .clear!', [])
|
47
48
|
foorth_equal('$q .empty?', [true])
|
48
49
|
foorth_equal('$q .length', [0])
|
49
50
|
|
@@ -60,8 +60,9 @@ class StackLibraryTester < Minitest::Test
|
|
60
60
|
foorth_run('42 $s .push')
|
61
61
|
foorth_equal('$s .empty?', [false])
|
62
62
|
foorth_equal('$s .peek', [42])
|
63
|
+
foorth_equal('$s .present?', [true])
|
63
64
|
|
64
|
-
foorth_run('$s .clear')
|
65
|
+
foorth_run('$s .clear!')
|
65
66
|
|
66
67
|
foorth_equal('$s .empty?', [true])
|
67
68
|
foorth_raises('$s .peek')
|
@@ -523,4 +523,15 @@ class StringLibraryTester < Minitest::Test
|
|
523
523
|
foorth_equal('"Hello World" p"%s %s" .map{{ v .mutable? }}', [[false, false]])
|
524
524
|
end
|
525
525
|
|
526
|
+
def test_string_emptiness
|
527
|
+
foorth_equal('"" .empty?', [true])
|
528
|
+
foorth_equal('"1" .empty?', [false])
|
529
|
+
|
530
|
+
foorth_equal('"" .present?', [false])
|
531
|
+
foorth_equal('"1" .present?', [true])
|
532
|
+
|
533
|
+
foorth_equal('"1"* dup .clear!', [""])
|
534
|
+
end
|
535
|
+
|
536
|
+
|
526
537
|
end
|
@@ -71,23 +71,26 @@ class ThreadLibraryTester < Minitest::Test
|
|
71
71
|
foorth_run('$tmtx .lock $tmtx .unlock ')
|
72
72
|
foorth_equal('$tmtx .do{{ 3 4 + }}', [7])
|
73
73
|
|
74
|
-
|
74
|
+
foorth_run('""* val$: $tmtx_str')
|
75
|
+
|
76
|
+
code = ': test_mutex_one $tmtx_str .clear! ' +
|
75
77
|
'{{ $tmtx .do{{ 0 10 do $tmtx_str "@" << loop }} }} .start drop ' +
|
76
|
-
'begin $tmtx .do{{ $tmtx_str }}
|
78
|
+
'begin $tmtx .do{{ $tmtx_str }} .present? until $tmtx_str ;'
|
77
79
|
|
78
|
-
foorth_run('""* val$: $tmtx_str')
|
79
80
|
foorth_run(code)
|
80
81
|
|
81
82
|
10.times do
|
82
|
-
foorth_equal('
|
83
|
+
foorth_equal('test_mutex_one', ["@"*10])
|
83
84
|
end
|
84
85
|
|
85
|
-
code = '
|
86
|
-
'
|
86
|
+
code = ': test_mutex_two $tmtx_str .clear! ' +
|
87
|
+
'{{ Mutex .do{{ 0 10 do $tmtx_str "@" << loop }} }} .start drop ' +
|
88
|
+
'begin Mutex .do{{ $tmtx_str }} .present? until $tmtx_str ;'
|
89
|
+
|
90
|
+
foorth_run(code)
|
87
91
|
|
88
92
|
10.times do
|
89
|
-
|
90
|
-
foorth_equal(code, ["@"*10])
|
93
|
+
foorth_equal('test_mutex_two', ["@"*10])
|
91
94
|
end
|
92
95
|
end
|
93
96
|
|
@@ -1,64 +1,64 @@
|
|
1
|
-
# coding: utf-8
|
2
|
-
|
3
|
-
require_relative 'context/map_name'
|
4
|
-
require_relative 'context/tags'
|
5
|
-
require_relative 'context/locals'
|
6
|
-
|
7
|
-
#* compiler/context.rb - The compile progress context manager of the fOOrth
|
8
|
-
# language system.
|
9
|
-
module XfOOrth
|
10
|
-
|
11
|
-
#A class for the management of global, hierarchical, and nested compile time contexts.
|
12
|
-
#* compiler/context.rb - \Context constructor, tag support, and local defs.
|
13
|
-
class Context
|
14
|
-
|
15
|
-
#The previous context object that this one builds on. Set to nil if there
|
16
|
-
#is none.
|
17
|
-
attr_reader :previous
|
18
|
-
|
19
|
-
#Setup an instance of compiler context.
|
20
|
-
#<br>Parameters:
|
21
|
-
#* previous - The previous context object or nil if there is none.
|
22
|
-
#* data - A hash of context data.
|
23
|
-
def initialize(previous, data={})
|
24
|
-
@previous, @data = previous, data
|
25
|
-
end
|
26
|
-
|
27
|
-
#How many levels of nested context are there?
|
28
|
-
def depth
|
29
|
-
1 + (previous ? previous.depth : 0)
|
30
|
-
end
|
31
|
-
|
32
|
-
#Is the current nesting level what is expected?
|
33
|
-
#<br>Parameters
|
34
|
-
#* expected_depth - the expected nesting depth.
|
35
|
-
#<br>Notes
|
36
|
-
#* Raises an error (F12) on incorrect nesting.
|
37
|
-
def check_depth(expected_depth)
|
38
|
-
if expected_depth - self.depth != 0
|
39
|
-
error "F12: Error, Invalid control/structure nesting."
|
40
|
-
end
|
41
|
-
end
|
42
|
-
|
43
|
-
#Get the current target.
|
44
|
-
def target
|
45
|
-
self[:obj] || self[:cls] || self[:vm] || no_target_error
|
46
|
-
end
|
47
|
-
|
48
|
-
#Get the current target object.
|
49
|
-
def target_object
|
50
|
-
self[:obj] || no_target_error
|
51
|
-
end
|
52
|
-
|
53
|
-
#Get the current target class.
|
54
|
-
def target_class
|
55
|
-
self[:cls] || no_target_error
|
56
|
-
end
|
57
|
-
|
58
|
-
#Signal that no receiver was found in this context.
|
59
|
-
#This is an internal error indication.
|
60
|
-
def no_target_error
|
61
|
-
error("F90: No target found in context.")
|
62
|
-
end
|
63
|
-
end
|
64
|
-
end
|
1
|
+
# coding: utf-8
|
2
|
+
|
3
|
+
require_relative 'context/map_name'
|
4
|
+
require_relative 'context/tags'
|
5
|
+
require_relative 'context/locals'
|
6
|
+
|
7
|
+
#* compiler/context.rb - The compile progress context manager of the fOOrth
|
8
|
+
# language system.
|
9
|
+
module XfOOrth
|
10
|
+
|
11
|
+
#A class for the management of global, hierarchical, and nested compile time contexts.
|
12
|
+
#* compiler/context.rb - \Context constructor, tag support, and local defs.
|
13
|
+
class Context
|
14
|
+
|
15
|
+
#The previous context object that this one builds on. Set to nil if there
|
16
|
+
#is none.
|
17
|
+
attr_reader :previous
|
18
|
+
|
19
|
+
#Setup an instance of compiler context.
|
20
|
+
#<br>Parameters:
|
21
|
+
#* previous - The previous context object or nil if there is none.
|
22
|
+
#* data - A hash of context data.
|
23
|
+
def initialize(previous, data={})
|
24
|
+
@previous, @data = previous, data
|
25
|
+
end
|
26
|
+
|
27
|
+
#How many levels of nested context are there?
|
28
|
+
def depth
|
29
|
+
1 + (previous ? previous.depth : 0)
|
30
|
+
end
|
31
|
+
|
32
|
+
#Is the current nesting level what is expected?
|
33
|
+
#<br>Parameters
|
34
|
+
#* expected_depth - the expected nesting depth.
|
35
|
+
#<br>Notes
|
36
|
+
#* Raises an error (F12) on incorrect nesting.
|
37
|
+
def check_depth(expected_depth)
|
38
|
+
if expected_depth - self.depth != 0
|
39
|
+
error "F12: Error, Invalid control/structure nesting."
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
#Get the current target.
|
44
|
+
def target
|
45
|
+
self[:obj] || self[:cls] || self[:vm] || no_target_error
|
46
|
+
end
|
47
|
+
|
48
|
+
#Get the current target object.
|
49
|
+
def target_object
|
50
|
+
self[:obj] || no_target_error
|
51
|
+
end
|
52
|
+
|
53
|
+
#Get the current target class.
|
54
|
+
def target_class
|
55
|
+
self[:cls] || no_target_error
|
56
|
+
end
|
57
|
+
|
58
|
+
#Signal that no receiver was found in this context.
|
59
|
+
#This is an internal error indication.
|
60
|
+
def no_target_error
|
61
|
+
error("F90: No target found in context.")
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
@@ -1,34 +1,34 @@
|
|
1
|
-
# coding: utf-8
|
2
|
-
|
3
|
-
#* compiler/context/locals.rb - Support local methods in context.
|
4
|
-
module XfOOrth
|
5
|
-
|
6
|
-
#* compiler/context/locals.rb - Support local methods in context.
|
7
|
-
class Context
|
8
|
-
|
9
|
-
#Create a local method on this context.
|
10
|
-
#<br>Parameters:
|
11
|
-
#* name - The name of the method to create.
|
12
|
-
#* spec_class - The specification class to use.
|
13
|
-
#* options - An array of options.
|
14
|
-
#* block - A block to associate with the name.
|
15
|
-
#<br>Returns
|
16
|
-
#* The spec created for the shared method.
|
17
|
-
def create_local_method(name, spec_class, options, &block)
|
18
|
-
sym = SymbolMap.add_entry(name)
|
19
|
-
self[sym] = spec_class.new(name, sym, options, &block)
|
20
|
-
end
|
21
|
-
|
22
|
-
#Remove a local method on this context.
|
23
|
-
#<br>Parameters:
|
24
|
-
#* The name of the method to remove.
|
25
|
-
def remove_local_method(name)
|
26
|
-
if (sym = SymbolMap.map(name))
|
27
|
-
@data.delete(sym)
|
28
|
-
else
|
29
|
-
error "F90: Unable to remove local method #{name}"
|
30
|
-
end
|
31
|
-
end
|
32
|
-
|
33
|
-
end
|
34
|
-
end
|
1
|
+
# coding: utf-8
|
2
|
+
|
3
|
+
#* compiler/context/locals.rb - Support local methods in context.
|
4
|
+
module XfOOrth
|
5
|
+
|
6
|
+
#* compiler/context/locals.rb - Support local methods in context.
|
7
|
+
class Context
|
8
|
+
|
9
|
+
#Create a local method on this context.
|
10
|
+
#<br>Parameters:
|
11
|
+
#* name - The name of the method to create.
|
12
|
+
#* spec_class - The specification class to use.
|
13
|
+
#* options - An array of options.
|
14
|
+
#* block - A block to associate with the name.
|
15
|
+
#<br>Returns
|
16
|
+
#* The spec created for the shared method.
|
17
|
+
def create_local_method(name, spec_class, options, &block)
|
18
|
+
sym = SymbolMap.add_entry(name)
|
19
|
+
self[sym] = spec_class.new(name, sym, options, &block)
|
20
|
+
end
|
21
|
+
|
22
|
+
#Remove a local method on this context.
|
23
|
+
#<br>Parameters:
|
24
|
+
#* The name of the method to remove.
|
25
|
+
def remove_local_method(name)
|
26
|
+
if (sym = SymbolMap.map(name))
|
27
|
+
@data.delete(sym)
|
28
|
+
else
|
29
|
+
error "F90: Unable to remove local method #{name}"
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
end
|
34
|
+
end
|
@@ -1,85 +1,85 @@
|
|
1
|
-
# coding: utf-8
|
2
|
-
|
3
|
-
#* compiler/context/map_name.rb - The fOOrth language mapping of names in a context.
|
4
|
-
module XfOOrth
|
5
|
-
|
6
|
-
#* compiler/context/map_name.rb - The fOOrth language mapping of names in a context.
|
7
|
-
class Context
|
8
|
-
|
9
|
-
#Map a name to a specification.
|
10
|
-
#<br>Parameters:
|
11
|
-
#* name - The string to be mapped.
|
12
|
-
#<br>Returns:
|
13
|
-
#* The specification that corresponds to the name or nil if none found.
|
14
|
-
def map_with_defaults(name)
|
15
|
-
if (@symbol = SymbolMap.map(@name = name))
|
16
|
-
do_map_name ||
|
17
|
-
case @name[0]
|
18
|
-
when '.'
|
19
|
-
TosSpec.new(@name, @symbol, [:temp])
|
20
|
-
|
21
|
-
when '~'
|
22
|
-
SelfSpec.new(@name, @symbol, [:temp])
|
23
|
-
|
24
|
-
else
|
25
|
-
spec_error
|
26
|
-
end
|
27
|
-
end
|
28
|
-
end
|
29
|
-
|
30
|
-
#Map a name to a specification.
|
31
|
-
#<br>Parameters:
|
32
|
-
#* name - The string to be mapped.
|
33
|
-
#<br>Returns:
|
34
|
-
#* The specification that corresponds to the name or nil if none found.
|
35
|
-
def map_without_defaults(name)
|
36
|
-
if (@symbol = SymbolMap.map(@name = name))
|
37
|
-
do_map_name
|
38
|
-
end
|
39
|
-
end
|
40
|
-
|
41
|
-
#Private methods follow.
|
42
|
-
private
|
43
|
-
|
44
|
-
#Do a search of dictionaries based on the syntax of the name.
|
45
|
-
def do_map_name
|
46
|
-
self[@symbol] ||
|
47
|
-
do_target_class_map ||
|
48
|
-
do_target_object_map ||
|
49
|
-
do_target_vm_map ||
|
50
|
-
do_object_class_map ||
|
51
|
-
do_global_map
|
52
|
-
end
|
53
|
-
|
54
|
-
#Do a search of the Object class for the item.
|
55
|
-
def do_object_class_map
|
56
|
-
Object.map_foorth_shared(@symbol)
|
57
|
-
end
|
58
|
-
|
59
|
-
#Do a search of the :cls tag if it is specified.
|
60
|
-
def do_target_class_map
|
61
|
-
(tc = self[:cls]) && tc.map_foorth_shared(@symbol)
|
62
|
-
end
|
63
|
-
|
64
|
-
#Do a search of the :obj tag if it is specified.
|
65
|
-
def do_target_object_map
|
66
|
-
(to = self[:obj]) && to.map_foorth_exclusive(@symbol)
|
67
|
-
end
|
68
|
-
|
69
|
-
#Do a search of the :vm tag if it is specified.
|
70
|
-
def do_target_vm_map
|
71
|
-
(vm = self[:vm]) && vm.map_foorth_exclusive(@symbol)
|
72
|
-
end
|
73
|
-
|
74
|
-
#Do a search of the globals.
|
75
|
-
def do_global_map
|
76
|
-
$FOORTH_GLOBALS[@symbol]
|
77
|
-
end
|
78
|
-
|
79
|
-
#Error: Unable to find a specification.
|
80
|
-
def spec_error
|
81
|
-
error "F11: ?#{@name}?"
|
82
|
-
end
|
83
|
-
|
84
|
-
end
|
85
|
-
end
|
1
|
+
# coding: utf-8
|
2
|
+
|
3
|
+
#* compiler/context/map_name.rb - The fOOrth language mapping of names in a context.
|
4
|
+
module XfOOrth
|
5
|
+
|
6
|
+
#* compiler/context/map_name.rb - The fOOrth language mapping of names in a context.
|
7
|
+
class Context
|
8
|
+
|
9
|
+
#Map a name to a specification.
|
10
|
+
#<br>Parameters:
|
11
|
+
#* name - The string to be mapped.
|
12
|
+
#<br>Returns:
|
13
|
+
#* The specification that corresponds to the name or nil if none found.
|
14
|
+
def map_with_defaults(name)
|
15
|
+
if (@symbol = SymbolMap.map(@name = name))
|
16
|
+
do_map_name ||
|
17
|
+
case @name[0]
|
18
|
+
when '.'
|
19
|
+
TosSpec.new(@name, @symbol, [:temp])
|
20
|
+
|
21
|
+
when '~'
|
22
|
+
SelfSpec.new(@name, @symbol, [:temp])
|
23
|
+
|
24
|
+
else
|
25
|
+
spec_error
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
#Map a name to a specification.
|
31
|
+
#<br>Parameters:
|
32
|
+
#* name - The string to be mapped.
|
33
|
+
#<br>Returns:
|
34
|
+
#* The specification that corresponds to the name or nil if none found.
|
35
|
+
def map_without_defaults(name)
|
36
|
+
if (@symbol = SymbolMap.map(@name = name))
|
37
|
+
do_map_name
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
#Private methods follow.
|
42
|
+
private
|
43
|
+
|
44
|
+
#Do a search of dictionaries based on the syntax of the name.
|
45
|
+
def do_map_name
|
46
|
+
self[@symbol] ||
|
47
|
+
do_target_class_map ||
|
48
|
+
do_target_object_map ||
|
49
|
+
do_target_vm_map ||
|
50
|
+
do_object_class_map ||
|
51
|
+
do_global_map
|
52
|
+
end
|
53
|
+
|
54
|
+
#Do a search of the Object class for the item.
|
55
|
+
def do_object_class_map
|
56
|
+
Object.map_foorth_shared(@symbol)
|
57
|
+
end
|
58
|
+
|
59
|
+
#Do a search of the :cls tag if it is specified.
|
60
|
+
def do_target_class_map
|
61
|
+
(tc = self[:cls]) && tc.map_foorth_shared(@symbol)
|
62
|
+
end
|
63
|
+
|
64
|
+
#Do a search of the :obj tag if it is specified.
|
65
|
+
def do_target_object_map
|
66
|
+
(to = self[:obj]) && to.map_foorth_exclusive(@symbol)
|
67
|
+
end
|
68
|
+
|
69
|
+
#Do a search of the :vm tag if it is specified.
|
70
|
+
def do_target_vm_map
|
71
|
+
(vm = self[:vm]) && vm.map_foorth_exclusive(@symbol)
|
72
|
+
end
|
73
|
+
|
74
|
+
#Do a search of the globals.
|
75
|
+
def do_global_map
|
76
|
+
$FOORTH_GLOBALS[@symbol]
|
77
|
+
end
|
78
|
+
|
79
|
+
#Error: Unable to find a specification.
|
80
|
+
def spec_error
|
81
|
+
error "F11: ?#{@name}?"
|
82
|
+
end
|
83
|
+
|
84
|
+
end
|
85
|
+
end
|