fOOrth 0.5.0
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.
- checksums.yaml +7 -0
- data/.gitignore +21 -0
- data/.rdoc_options +17 -0
- data/Gemfile +4 -0
- data/README.md +67 -0
- data/bin/fOOrth +8 -0
- data/demo.rb +24 -0
- data/fOOrth.gemspec +40 -0
- data/fOOrth.reek +109 -0
- data/integration/README.md +12 -0
- data/integration/_FILE_test.foorth +5 -0
- data/integration/array_lib_tests.rb +360 -0
- data/integration/class_lib_tests.rb +116 -0
- data/integration/clone_lib_tests.rb +108 -0
- data/integration/comparison_tests.rb +132 -0
- data/integration/compile_lib_tests.rb +190 -0
- data/integration/ctrl_struct_lib_tests.rb +80 -0
- data/integration/data_ref_lib_tests.rb +43 -0
- data/integration/exception_lib_tests.rb +86 -0
- data/integration/fiber_bundle_tests.rb +380 -0
- data/integration/hash_lib_tests.rb +120 -0
- data/integration/in_stream_test_1.txt +4 -0
- data/integration/load_test_one.foorth +6 -0
- data/integration/load_test_two.foorth +4 -0
- data/integration/numeric_lib_tests.rb +321 -0
- data/integration/object_lib_tests.rb +38 -0
- data/integration/procedure_lib_tests.rb +40 -0
- data/integration/queue_lib_tests.rb +66 -0
- data/integration/stack_lib_tests.rb +70 -0
- data/integration/standard_lib_tests.rb +208 -0
- data/integration/stdio_lib_tests.rb +52 -0
- data/integration/stream_lib_tests.rb +196 -0
- data/integration/string_lib_tests.rb +217 -0
- data/integration/support/foorth_testing.rb +135 -0
- data/integration/thread_lib_tests.rb +83 -0
- data/integration/time_lib_tests.rb +791 -0
- data/integration/vm_lib_tests.rb +38 -0
- data/lib/fOOrth.rb +57 -0
- data/lib/fOOrth/compiler.rb +78 -0
- data/lib/fOOrth/compiler/context.rb +49 -0
- data/lib/fOOrth/compiler/context/locals.rb +34 -0
- data/lib/fOOrth/compiler/context/map_name.rb +92 -0
- data/lib/fOOrth/compiler/context/tags.rb +48 -0
- data/lib/fOOrth/compiler/modes.rb +32 -0
- data/lib/fOOrth/compiler/modes/compiled.rb +41 -0
- data/lib/fOOrth/compiler/modes/deferred.rb +57 -0
- data/lib/fOOrth/compiler/modes/delayed.rb +40 -0
- data/lib/fOOrth/compiler/modes/nested.rb +34 -0
- data/lib/fOOrth/compiler/modes/suspend.rb +32 -0
- data/lib/fOOrth/compiler/parser.rb +26 -0
- data/lib/fOOrth/compiler/parser/get_string.rb +71 -0
- data/lib/fOOrth/compiler/parser/normal.rb +53 -0
- data/lib/fOOrth/compiler/parser/skip.rb +50 -0
- data/lib/fOOrth/compiler/parser/special.rb +42 -0
- data/lib/fOOrth/compiler/process.rb +47 -0
- data/lib/fOOrth/compiler/process/generate.rb +24 -0
- data/lib/fOOrth/compiler/process/get_token.rb +23 -0
- data/lib/fOOrth/compiler/process/procedure.rb +55 -0
- data/lib/fOOrth/compiler/process/string.rb +20 -0
- data/lib/fOOrth/compiler/source.rb +51 -0
- data/lib/fOOrth/compiler/source/console.rb +70 -0
- data/lib/fOOrth/compiler/source/file_source.rb +37 -0
- data/lib/fOOrth/compiler/source/read_point.rb +46 -0
- data/lib/fOOrth/compiler/source/string_source.rb +28 -0
- data/lib/fOOrth/compiler/token.rb +37 -0
- data/lib/fOOrth/compiler/word_specs.rb +178 -0
- data/lib/fOOrth/core.rb +27 -0
- data/lib/fOOrth/core/class.rb +116 -0
- data/lib/fOOrth/core/object.rb +78 -0
- data/lib/fOOrth/core/virtual_machine.rb +28 -0
- data/lib/fOOrth/debug.rb +13 -0
- data/lib/fOOrth/debug/context_dump.rb +31 -0
- data/lib/fOOrth/debug/dbg_puts.rb +17 -0
- data/lib/fOOrth/debug/display_abort.rb +37 -0
- data/lib/fOOrth/debug/vm_dump.rb +27 -0
- data/lib/fOOrth/initialize.rb +83 -0
- data/lib/fOOrth/interpreter.rb +24 -0
- data/lib/fOOrth/interpreter/add_to_hash.rb +17 -0
- data/lib/fOOrth/interpreter/data_stack.rb +125 -0
- data/lib/fOOrth/interpreter/do_loop.rb +55 -0
- data/lib/fOOrth/interpreter/squash.rb +25 -0
- data/lib/fOOrth/library.rb +38 -0
- data/lib/fOOrth/library/array_library.rb +577 -0
- data/lib/fOOrth/library/bundle_library.rb +112 -0
- data/lib/fOOrth/library/class_library.rb +90 -0
- data/lib/fOOrth/library/clone_library.rb +72 -0
- data/lib/fOOrth/library/command_library.rb +205 -0
- data/lib/fOOrth/library/compile_library.rb +181 -0
- data/lib/fOOrth/library/complex_library.rb +81 -0
- data/lib/fOOrth/library/ctrl_struct_library.rb +116 -0
- data/lib/fOOrth/library/data_ref_library.rb +100 -0
- data/lib/fOOrth/library/duration/arithmetic.rb +114 -0
- data/lib/fOOrth/library/duration/formatter.rb +152 -0
- data/lib/fOOrth/library/duration/intervals.rb +233 -0
- data/lib/fOOrth/library/duration/make.rb +75 -0
- data/lib/fOOrth/library/duration_library.rb +52 -0
- data/lib/fOOrth/library/fiber_library.rb +120 -0
- data/lib/fOOrth/library/hash_library.rb +203 -0
- data/lib/fOOrth/library/in_stream_library.rb +81 -0
- data/lib/fOOrth/library/integer_library.rb +104 -0
- data/lib/fOOrth/library/mutex_library.rb +31 -0
- data/lib/fOOrth/library/numeric_library.rb +380 -0
- data/lib/fOOrth/library/object_library.rb +80 -0
- data/lib/fOOrth/library/other_value_types_library.rb +96 -0
- data/lib/fOOrth/library/out_stream_library.rb +146 -0
- data/lib/fOOrth/library/procedure_library.rb +65 -0
- data/lib/fOOrth/library/queue_library.rb +47 -0
- data/lib/fOOrth/library/rational_library.rb +90 -0
- data/lib/fOOrth/library/stack_library.rb +56 -0
- data/lib/fOOrth/library/stdio_library.rb +56 -0
- data/lib/fOOrth/library/string_library.rb +285 -0
- data/lib/fOOrth/library/stubs.rb +76 -0
- data/lib/fOOrth/library/sync_bundle_library.rb +50 -0
- data/lib/fOOrth/library/thread_library.rb +73 -0
- data/lib/fOOrth/library/time_library.rb +302 -0
- data/lib/fOOrth/library/vm_library.rb +105 -0
- data/lib/fOOrth/main.rb +125 -0
- data/lib/fOOrth/monkey_patch.rb +14 -0
- data/lib/fOOrth/monkey_patch/complex.rb +30 -0
- data/lib/fOOrth/monkey_patch/exceptions.rb +154 -0
- data/lib/fOOrth/monkey_patch/false.rb +11 -0
- data/lib/fOOrth/monkey_patch/float.rb +22 -0
- data/lib/fOOrth/monkey_patch/integer.rb +22 -0
- data/lib/fOOrth/monkey_patch/nil.rb +11 -0
- data/lib/fOOrth/monkey_patch/numeric.rb +33 -0
- data/lib/fOOrth/monkey_patch/object.rb +43 -0
- data/lib/fOOrth/monkey_patch/rational.rb +31 -0
- data/lib/fOOrth/monkey_patch/string.rb +51 -0
- data/lib/fOOrth/symbol_map.rb +82 -0
- data/lib/fOOrth/version.rb +7 -0
- data/license.txt +21 -0
- data/rakefile.rb +65 -0
- data/reek.txt +1 -0
- data/sire.rb +132 -0
- data/t.txt +3 -0
- data/test.foorth +5 -0
- data/tests/compiler/context_tests.rb +180 -0
- data/tests/compiler/file_source_test_one.txt +1 -0
- data/tests/compiler/file_source_test_three.txt +3 -0
- data/tests/compiler/file_source_test_two.txt +3 -0
- data/tests/compiler/file_source_tests.rb +130 -0
- data/tests/compiler/mode_tests.rb +45 -0
- data/tests/compiler/parser_tests.rb +116 -0
- data/tests/compiler/spec_tests.rb +113 -0
- data/tests/compiler/string_source_tests.rb +128 -0
- data/tests/core_tests.rb +138 -0
- data/tests/interpreter/data_stack_tests.rb +119 -0
- data/tests/monkey_patch/coerce_test.rb +131 -0
- data/tests/monkey_patch/complex_test.rb +25 -0
- data/tests/monkey_patch/numeric_test.rb +62 -0
- data/tests/monkey_patch/object_test.rb +49 -0
- data/tests/monkey_patch/rational_test.rb +57 -0
- data/tests/monkey_patch/string_test.rb +53 -0
- data/tests/symbol_map_tests.rb +53 -0
- metadata +366 -0
data/lib/fOOrth/core.rb
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
# coding: utf-8
|
|
2
|
+
|
|
3
|
+
require_relative 'compiler/word_specs'
|
|
4
|
+
require_relative 'core/object'
|
|
5
|
+
require_relative 'core/class'
|
|
6
|
+
require_relative 'core/virtual_machine'
|
|
7
|
+
|
|
8
|
+
#* core.rb - The fOOrth language OO core.
|
|
9
|
+
module XfOOrth
|
|
10
|
+
|
|
11
|
+
$FOORTH_GLOBALS = Hash.new
|
|
12
|
+
Object.create_foorth_proxy
|
|
13
|
+
Class.create_foorth_proxy
|
|
14
|
+
VirtualMachine.create_foorth_proxy('VirtualMachine')
|
|
15
|
+
|
|
16
|
+
#Predefine the default implementation of the .init method. This method must
|
|
17
|
+
#exist at this point in order to proceed further.
|
|
18
|
+
name = '.init'
|
|
19
|
+
sym = SymbolMap.add_entry(name, :foorth_init)
|
|
20
|
+
Object.create_shared_method(name, TosSpec, [], &lambda {|vm| })
|
|
21
|
+
|
|
22
|
+
#Create a virtual machine instance for the main thread. The constructor
|
|
23
|
+
#connects the new instance to a thread variable so we don't need to do
|
|
24
|
+
#anything with it here.
|
|
25
|
+
VirtualMachine.new('Main')
|
|
26
|
+
|
|
27
|
+
end
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
# coding: utf-8
|
|
2
|
+
|
|
3
|
+
#* The additions to the Ruby Class class required to support fOOrth.
|
|
4
|
+
class Class
|
|
5
|
+
|
|
6
|
+
#Get the foorth name of this class.
|
|
7
|
+
#<br>Decree!
|
|
8
|
+
#* These are to be the only references to @_private_foorth_name!
|
|
9
|
+
def foorth_name
|
|
10
|
+
@_private_foorth_name ||= name
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
#Set the foorth name of this class.
|
|
14
|
+
#<br>Decree!
|
|
15
|
+
#* These are to be the only references to @_private_foorth_name!
|
|
16
|
+
def foorth_name=(new_name)
|
|
17
|
+
@_private_foorth_name = new_name
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
#Access/create the class's shared fOOrth dictionary.
|
|
21
|
+
#<br>Decree!
|
|
22
|
+
#* This is to be the only reference to @_private_foorth_shared!
|
|
23
|
+
def foorth_shared
|
|
24
|
+
@_private_foorth_shared ||= Hash.new
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
#Create a shared method on this fOOrth class.
|
|
28
|
+
#<br>Parameters:
|
|
29
|
+
#* name - The name of the method to create.
|
|
30
|
+
#* spec_class - The specification class to use.
|
|
31
|
+
#* options - An array of options.
|
|
32
|
+
#* block - A block to associate with the name.
|
|
33
|
+
#<br>Returns
|
|
34
|
+
#* The spec created for the shared method.
|
|
35
|
+
def create_shared_method(name, spec_class, options, &block)
|
|
36
|
+
sym = XfOOrth::SymbolMap.add_entry(name)
|
|
37
|
+
spec = spec_class.new(name, sym, options, &block)
|
|
38
|
+
|
|
39
|
+
unless self == Object && options.include?(:stub)
|
|
40
|
+
define_method(sym, &spec.does)
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
foorth_shared[sym] = spec
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
#Map the symbol to a specification or nil if there is no mapping.
|
|
47
|
+
def map_foorth_shared(symbol)
|
|
48
|
+
foorth_shared[symbol] || ((sc = superclass) && sc.map_foorth_shared(symbol))
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
#Create an instance of this fOOrth class.
|
|
52
|
+
#<br>Parameters:
|
|
53
|
+
#* vm - The current fOOrth virtual machine.
|
|
54
|
+
def create_foorth_instance(vm)
|
|
55
|
+
(obj = self.new).foorth_init(vm)
|
|
56
|
+
obj
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
#Create a new fOOrth subclass of this class.
|
|
60
|
+
#<br>Parameters:
|
|
61
|
+
#* foorth_name - The foorth_name of the new sub-class.
|
|
62
|
+
#<br>Returns:
|
|
63
|
+
#* The spec of the subclass.
|
|
64
|
+
#<br>Note:
|
|
65
|
+
#* If a sub-class with the given name already exists, an exception is raised.
|
|
66
|
+
def create_foorth_subclass(foorth_name)
|
|
67
|
+
if $FOORTH_GLOBALS[XfOOrth::SymbolMap.map(foorth_name)]
|
|
68
|
+
error "F10: The class #{foorth_name} already exists."
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
validate_class_name(foorth_name)
|
|
72
|
+
|
|
73
|
+
new_class = Class.new(self) {self.foorth_name = foorth_name}
|
|
74
|
+
|
|
75
|
+
XfOOrth.const_set('XfOOrth_' + foorth_name, new_class)
|
|
76
|
+
install_foorth_class(foorth_name, new_class)
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
#Add this class as a proxy class in the foorth class system.
|
|
80
|
+
#<br>Parameters:
|
|
81
|
+
#* proxy_name - the optional name of the proxy. Defaults to the Ruby name.
|
|
82
|
+
#<br>Returns:
|
|
83
|
+
#* The spec of the proxy class.
|
|
84
|
+
def create_foorth_proxy(proxy_name = nil)
|
|
85
|
+
if proxy_name
|
|
86
|
+
self.foorth_name = proxy_name
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
validate_class_name(foorth_name)
|
|
90
|
+
|
|
91
|
+
error "F10: The class #{foorth_name} already exists." if $FOORTH_GLOBALS[foorth_name]
|
|
92
|
+
|
|
93
|
+
install_foorth_class(foorth_name, self)
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
private
|
|
97
|
+
|
|
98
|
+
#Connect the class named foorth_name to the foorth system.
|
|
99
|
+
#<br>Returns:
|
|
100
|
+
#* The newly created spec object.
|
|
101
|
+
#<br> Endemic Code Smells
|
|
102
|
+
#* :reek:UtilityFunction
|
|
103
|
+
def install_foorth_class(new_name, new_class)
|
|
104
|
+
fail "Bad name" unless new_name
|
|
105
|
+
symbol = XfOOrth::SymbolMap.add_entry(new_name)
|
|
106
|
+
$FOORTH_GLOBALS[symbol] = XfOOrth::ClassSpec.new(new_class, nil, [:class])
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
#Is this a valid class name?
|
|
110
|
+
def validate_class_name(name)
|
|
111
|
+
unless /^[A-Z][A-Za-z0-9]+$/ =~ name
|
|
112
|
+
error "F10: Invalid class name #{name}"
|
|
113
|
+
end
|
|
114
|
+
end
|
|
115
|
+
|
|
116
|
+
end
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
# coding: utf-8
|
|
2
|
+
|
|
3
|
+
#* The additions to the Ruby Object class required to support fOOrth.
|
|
4
|
+
class Object
|
|
5
|
+
|
|
6
|
+
#Get the foorth name of this object.
|
|
7
|
+
def foorth_name
|
|
8
|
+
"#{self.class.foorth_name} instance"
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
#Access/create the object's exclusive fOOrth dictionary.
|
|
12
|
+
#<br>Decree!
|
|
13
|
+
#* These are to be the only reference to @_private_foorth_exclusive!
|
|
14
|
+
def foorth_exclusive
|
|
15
|
+
@_private_foorth_exclusive ||= Hash.new
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
#Does this object have exclusive methods defined on it?
|
|
19
|
+
#<br>Decree!
|
|
20
|
+
#* These are to be the only reference to @_private_foorth_exclusive!
|
|
21
|
+
def foorth_has_exclusive?
|
|
22
|
+
instance_variable_defined?(:@_private_foorth_exclusive)
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
#Create an exclusive method on this fOOrth object.
|
|
26
|
+
#<br>Parameters:
|
|
27
|
+
#* name - The name of the method to create.
|
|
28
|
+
#* spec_class - The specification class to use.
|
|
29
|
+
#* options - An array of options.
|
|
30
|
+
#* block - A block to associate with the name.
|
|
31
|
+
#<br>Returns
|
|
32
|
+
#* The spec created for the shared method.
|
|
33
|
+
def create_exclusive_method(name, spec_class, options, &block)
|
|
34
|
+
sym = XfOOrth::SymbolMap.add_entry(name)
|
|
35
|
+
spec = spec_class.new(name, sym, options, &block)
|
|
36
|
+
cache_exclusive_method(sym, &spec.does)
|
|
37
|
+
foorth_exclusive[sym] = spec
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
#Load the new exclusive method into the object.
|
|
41
|
+
def cache_exclusive_method(symbol, &block)
|
|
42
|
+
define_singleton_method(symbol, &block)
|
|
43
|
+
rescue TypeError
|
|
44
|
+
error "F13: Exclusive methods not allowed for type: #{self.class.foorth_name}"
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
#Map the symbol to a specification or nil if there is no mapping.
|
|
48
|
+
def map_foorth_exclusive(symbol)
|
|
49
|
+
(foorth_has_exclusive? && foorth_exclusive[symbol]) ||
|
|
50
|
+
self.class.map_foorth_shared(symbol)
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
#The default foorth_init method does nothing.
|
|
54
|
+
def foorth_init(_vm)
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
#The \method_missing hook is used to provide meaningful error messages
|
|
58
|
+
#when problems are encountered.
|
|
59
|
+
#<br>Parameters:
|
|
60
|
+
#* symbol - The symbol of the missing method.
|
|
61
|
+
#* args - Any arguments that were passed to that method.
|
|
62
|
+
#* block - Any block that might have passed to the method.
|
|
63
|
+
#<br>Note:
|
|
64
|
+
#* Since stubs for Object class do not create methods, an attempt is made
|
|
65
|
+
# to execute the stub if the symbol maps and is in the Object class.
|
|
66
|
+
def method_missing(symbol, *args, &block)
|
|
67
|
+
if (name = XfOOrth::SymbolMap.unmap(symbol))
|
|
68
|
+
if (stub_spec = Object.foorth_shared[symbol])
|
|
69
|
+
self.instance_exec(*args, &stub_spec.does)
|
|
70
|
+
else
|
|
71
|
+
error "F20: A #{self.foorth_name} does not understand #{name} (#{symbol})."
|
|
72
|
+
end
|
|
73
|
+
else
|
|
74
|
+
super
|
|
75
|
+
end
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
end
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
# coding: utf-8
|
|
2
|
+
|
|
3
|
+
#* core/virtual_machine.rb - The core connection to the virtual machine.
|
|
4
|
+
module XfOOrth
|
|
5
|
+
|
|
6
|
+
#* core/virtual_machine.rb - The core connection to the virtual machine.
|
|
7
|
+
class VirtualMachine
|
|
8
|
+
|
|
9
|
+
#The name of the virtual machine instance
|
|
10
|
+
def foorth_name
|
|
11
|
+
"#{self.class.foorth_name} instance <#{@name}>"
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
#The currently active fiber, if any.
|
|
15
|
+
attr_accessor :fiber
|
|
16
|
+
|
|
17
|
+
class << self
|
|
18
|
+
|
|
19
|
+
#Create a new fOOrth subclass of this class. This is not allowed for the
|
|
20
|
+
#VirtualMachine class so this stub merely raises an exception.
|
|
21
|
+
def create_foorth_subclass(_name)
|
|
22
|
+
error "F13: Forbidden operation: (VirtualMachine.create_foorth_subclass)."
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
end
|
|
28
|
+
end
|
data/lib/fOOrth/debug.rb
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
# coding: utf-8
|
|
2
|
+
|
|
3
|
+
require_relative 'debug/display_abort'
|
|
4
|
+
require_relative 'debug/dbg_puts'
|
|
5
|
+
require_relative 'debug/context_dump'
|
|
6
|
+
require_relative 'debug/vm_dump'
|
|
7
|
+
|
|
8
|
+
#Set up the default debug conduit.
|
|
9
|
+
$foorth_dbg = $stdout
|
|
10
|
+
|
|
11
|
+
#* debug.rb - Internal debug support.
|
|
12
|
+
module XfOOrth
|
|
13
|
+
end
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
# coding: utf-8
|
|
2
|
+
|
|
3
|
+
#* debug/context_dump.rb - Debug support for the compiler context.
|
|
4
|
+
module XfOOrth
|
|
5
|
+
|
|
6
|
+
#* debug/context_dump.rb - Debug support for the compiler context.
|
|
7
|
+
class Context
|
|
8
|
+
|
|
9
|
+
#Dump the context chain to the console for debug.
|
|
10
|
+
#<br>Parameters
|
|
11
|
+
#* vm - The current virtual machine for this thread.
|
|
12
|
+
def debug_dump(vm)
|
|
13
|
+
puts "\nContext level #{self.depth}"
|
|
14
|
+
|
|
15
|
+
@data.each do |key, value|
|
|
16
|
+
if key == :vm
|
|
17
|
+
puts "virtual machine => #{value.foorth_name}"
|
|
18
|
+
else
|
|
19
|
+
if (name = SymbolMap.unmap(key))
|
|
20
|
+
key = name.inspect
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
puts "#{key} => #{value}"
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
(prev = self.previous) && prev.debug_dump(vm)
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
end
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
# coding: utf-8
|
|
2
|
+
|
|
3
|
+
#* debug/dbg_puts.rb - Display diagnostic/debug information if enabled.
|
|
4
|
+
module XfOOrth
|
|
5
|
+
|
|
6
|
+
#* debug/dbg_puts.rb - Display diagnostic/debug information if enabled.
|
|
7
|
+
class VirtualMachine
|
|
8
|
+
|
|
9
|
+
#Send out debug info to the fOOrth debug port if debug is enabled.
|
|
10
|
+
def dbg_puts(*args)
|
|
11
|
+
$foorth_dbg.puts(*args) if debug
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
end
|
|
17
|
+
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
# coding: utf-8
|
|
2
|
+
|
|
3
|
+
#* debug/display_abort.rb - Display diagnostic information on an error.
|
|
4
|
+
module XfOOrth
|
|
5
|
+
|
|
6
|
+
#* debug/display_abort.rb - Display diagnostic information on an error.
|
|
7
|
+
class VirtualMachine
|
|
8
|
+
|
|
9
|
+
#Display the diagnostic data required for a language abort error.
|
|
10
|
+
#<br>Parameters:
|
|
11
|
+
#* exception - The exception object that required the system abort or a
|
|
12
|
+
# string describing the error that was encountered.
|
|
13
|
+
def display_abort(exception)
|
|
14
|
+
puts "\n#{exception.foorth_message}"
|
|
15
|
+
|
|
16
|
+
if debug
|
|
17
|
+
puts "Data Stack Contents: #{data_stack.inspect}"
|
|
18
|
+
|
|
19
|
+
if @context
|
|
20
|
+
@context.debug_dump(self)
|
|
21
|
+
else
|
|
22
|
+
puts "Error: No context is available!"
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
puts "\nInternal Backtrace Dump:"
|
|
26
|
+
puts
|
|
27
|
+
puts exception.backtrace
|
|
28
|
+
puts
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
reset
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
end
|
|
37
|
+
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
# coding: utf-8
|
|
2
|
+
|
|
3
|
+
#* debug/vm_dump.rb - Debug support for the virtual machine.
|
|
4
|
+
module XfOOrth
|
|
5
|
+
|
|
6
|
+
#* debug/vm_dump.rb - Debug support for the virtual machine.
|
|
7
|
+
class VirtualMachine
|
|
8
|
+
|
|
9
|
+
#Dump the virtual machine to the console for debug.
|
|
10
|
+
def debug_dump
|
|
11
|
+
source = @parser && @parser.source
|
|
12
|
+
|
|
13
|
+
puts "\n#{self.foorth_name}" \
|
|
14
|
+
"\n Ruby = #{self.to_s}" \
|
|
15
|
+
"\n Stack = #{@data_stack.inspect}" \
|
|
16
|
+
"\n Nesting = #{@context.depth}" \
|
|
17
|
+
"\n Quotes = #{@quotes}" \
|
|
18
|
+
"\n Debug = #{@debug}" \
|
|
19
|
+
"\n Show = #{@show_stack}" \
|
|
20
|
+
"\n Force = #{@force}" \
|
|
21
|
+
"\n Start = #{@start_time}" \
|
|
22
|
+
"\n Source = #{source && source.source_name}" \
|
|
23
|
+
"\n Buffer = #{source && source.read_buffer.inspect}"
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
end
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
# coding: utf-8
|
|
2
|
+
|
|
3
|
+
#* initialize.rb - The initialize method for the virtual machine
|
|
4
|
+
module XfOOrth
|
|
5
|
+
|
|
6
|
+
#* initialize.rb - The initialize method for the virtual machine
|
|
7
|
+
class VirtualMachine
|
|
8
|
+
|
|
9
|
+
#Get or create a virtual machine for this thread.
|
|
10
|
+
#<br>Paramters:
|
|
11
|
+
#* name - The name of the virtual machine, if one is created. If a virtual
|
|
12
|
+
# machine already exists for this thread, this parameter is ignored.
|
|
13
|
+
#<br>Note: Non-intuitive code.
|
|
14
|
+
#* VitualMachine.new connects to the thread, setting up
|
|
15
|
+
# \Thread.current[:vm] as a side-effect. Thus it is not done here.
|
|
16
|
+
def self.vm(name='-')
|
|
17
|
+
Thread.current[:vm] || VirtualMachine.new(name)
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
#Set true for verbose compiler play-by-plays and detailed error reports.
|
|
21
|
+
attr_accessor :debug
|
|
22
|
+
|
|
23
|
+
#Set true to print out the data stack after every interactive line is processed.
|
|
24
|
+
attr_accessor :show_stack
|
|
25
|
+
|
|
26
|
+
#The descriptive name of this virtual machine.
|
|
27
|
+
attr_reader :name
|
|
28
|
+
|
|
29
|
+
#The thread data associated with this virtual machine.
|
|
30
|
+
attr_reader :data
|
|
31
|
+
|
|
32
|
+
#Create an new instance of a fOOrth virtual machine
|
|
33
|
+
#<br>Parameters:
|
|
34
|
+
#* name - An optional string that describes this virtual machine instance.
|
|
35
|
+
#<br>Note
|
|
36
|
+
#* A XfOOrthError will be raised if an attempt is made to create more than
|
|
37
|
+
# one virtual machine on a thread.
|
|
38
|
+
def initialize(name='-')
|
|
39
|
+
@name, @debug, @show_stack, @data = name, false, false, {}
|
|
40
|
+
|
|
41
|
+
#Bring the major sub-systems to a known state.
|
|
42
|
+
self.reset.connect_vm_to_thread
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
#Create a copy of a donor vm instance.
|
|
46
|
+
#<br>Parameters:
|
|
47
|
+
#* name - An optional string that describes this virtual machine instance.
|
|
48
|
+
def foorth_copy(name)
|
|
49
|
+
copy = self.clone
|
|
50
|
+
copy.reinitialize(name)
|
|
51
|
+
copy
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
#Get the vm ready for operation
|
|
55
|
+
#<br>Parameters:
|
|
56
|
+
#* name - A string that describes this virtual machine instance.
|
|
57
|
+
def reinitialize(name)
|
|
58
|
+
@data_stack = @data_stack.clone
|
|
59
|
+
@name = name
|
|
60
|
+
@data = @data.full_clone
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
#Reset the interpreter and the compiler.
|
|
64
|
+
def reset
|
|
65
|
+
interpreter_reset
|
|
66
|
+
compiler_reset
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
#Connect the vm to a thread variable.
|
|
70
|
+
def connect_vm_to_thread
|
|
71
|
+
#Check for duplicates.
|
|
72
|
+
current = Thread.current
|
|
73
|
+
error "F91: Only one virtual machine allowed per thread" if current[:vm]
|
|
74
|
+
|
|
75
|
+
#This virtual machine is associated with this thread.
|
|
76
|
+
current[:vm] = self
|
|
77
|
+
@start_time = Time.now
|
|
78
|
+
|
|
79
|
+
self
|
|
80
|
+
end
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
end
|