fOOrth 0.6.10 → 0.6.11

Sign up to get free protection for your applications and to get access to all the features.
Files changed (42) hide show
  1. checksums.yaml +5 -5
  2. data/README.md +13 -2
  3. data/fOOrth.gemspec +2 -2
  4. data/integration/array_lib_tests.rb +10 -0
  5. data/integration/exception_lib_tests.rb +4 -0
  6. data/integration/hash_lib_tests.rb +9 -0
  7. data/integration/numeric_lib_tests.rb +326 -321
  8. data/integration/procedure_lib_tests.rb +16 -0
  9. data/integration/queue_lib_tests.rb +2 -1
  10. data/integration/stack_lib_tests.rb +2 -1
  11. data/integration/string_lib_tests.rb +11 -0
  12. data/integration/thread_lib_tests.rb +11 -8
  13. data/lib/fOOrth/compiler/context.rb +64 -64
  14. data/lib/fOOrth/compiler/context/locals.rb +34 -34
  15. data/lib/fOOrth/compiler/context/map_name.rb +85 -85
  16. data/lib/fOOrth/compiler/context/tags.rb +60 -48
  17. data/lib/fOOrth/compiler/process/procedure.rb +40 -0
  18. data/lib/fOOrth/library.rb +1 -0
  19. data/lib/fOOrth/library/array_library.rb +41 -21
  20. data/lib/fOOrth/library/command_library.rb +1 -1
  21. data/lib/fOOrth/library/compile_library.rb +266 -266
  22. data/lib/fOOrth/library/complex_library.rb +82 -80
  23. data/lib/fOOrth/library/float_library.rb +37 -0
  24. data/lib/fOOrth/library/hash_library.rb +14 -6
  25. data/lib/fOOrth/library/mutex_library.rb +4 -2
  26. data/lib/fOOrth/library/numeric_library.rb +359 -380
  27. data/lib/fOOrth/library/procedure_library.rb +69 -65
  28. data/lib/fOOrth/library/queue_library.rb +6 -1
  29. data/lib/fOOrth/library/rational_library.rb +89 -89
  30. data/lib/fOOrth/library/stack_library.rb +6 -1
  31. data/lib/fOOrth/library/string_library.rb +18 -6
  32. data/lib/fOOrth/monkey_patch/exceptions.rb +2 -6
  33. data/lib/fOOrth/version.rb +1 -1
  34. data/tests/compiler/context_tests.rb +188 -177
  35. data/tests/compiler/file_source_tests.rb +130 -130
  36. data/tests/compiler/parser_tests.rb +4 -4
  37. data/tests/compiler/string_source_tests.rb +4 -4
  38. data/tests/core_tests.rb +138 -138
  39. data/tests/monkey_patch/complex_test.rb +24 -24
  40. data/tests/monkey_patch/object_test.rb +49 -49
  41. data/tests/monkey_patch/string_test.rb +61 -61
  42. 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
- code = ': test_mutex_one ' +
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 }} "" = while again $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('""* val$: $tmtx_str test_mutex_one', ["@"*10])
83
+ foorth_equal('test_mutex_one', ["@"*10])
83
84
  end
84
85
 
85
- code = '{{ Mutex .do{{ 0 10 do $tmtx_str "@" << loop }} }} .start drop ' +
86
- 'begin Mutex .do{{ $tmtx_str }} "" = while again $tmtx_str'
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
- foorth_run('""* val$: $tmtx_str')
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