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