fOOrth 0.5.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (155) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +21 -0
  3. data/.rdoc_options +17 -0
  4. data/Gemfile +4 -0
  5. data/README.md +67 -0
  6. data/bin/fOOrth +8 -0
  7. data/demo.rb +24 -0
  8. data/fOOrth.gemspec +40 -0
  9. data/fOOrth.reek +109 -0
  10. data/integration/README.md +12 -0
  11. data/integration/_FILE_test.foorth +5 -0
  12. data/integration/array_lib_tests.rb +360 -0
  13. data/integration/class_lib_tests.rb +116 -0
  14. data/integration/clone_lib_tests.rb +108 -0
  15. data/integration/comparison_tests.rb +132 -0
  16. data/integration/compile_lib_tests.rb +190 -0
  17. data/integration/ctrl_struct_lib_tests.rb +80 -0
  18. data/integration/data_ref_lib_tests.rb +43 -0
  19. data/integration/exception_lib_tests.rb +86 -0
  20. data/integration/fiber_bundle_tests.rb +380 -0
  21. data/integration/hash_lib_tests.rb +120 -0
  22. data/integration/in_stream_test_1.txt +4 -0
  23. data/integration/load_test_one.foorth +6 -0
  24. data/integration/load_test_two.foorth +4 -0
  25. data/integration/numeric_lib_tests.rb +321 -0
  26. data/integration/object_lib_tests.rb +38 -0
  27. data/integration/procedure_lib_tests.rb +40 -0
  28. data/integration/queue_lib_tests.rb +66 -0
  29. data/integration/stack_lib_tests.rb +70 -0
  30. data/integration/standard_lib_tests.rb +208 -0
  31. data/integration/stdio_lib_tests.rb +52 -0
  32. data/integration/stream_lib_tests.rb +196 -0
  33. data/integration/string_lib_tests.rb +217 -0
  34. data/integration/support/foorth_testing.rb +135 -0
  35. data/integration/thread_lib_tests.rb +83 -0
  36. data/integration/time_lib_tests.rb +791 -0
  37. data/integration/vm_lib_tests.rb +38 -0
  38. data/lib/fOOrth.rb +57 -0
  39. data/lib/fOOrth/compiler.rb +78 -0
  40. data/lib/fOOrth/compiler/context.rb +49 -0
  41. data/lib/fOOrth/compiler/context/locals.rb +34 -0
  42. data/lib/fOOrth/compiler/context/map_name.rb +92 -0
  43. data/lib/fOOrth/compiler/context/tags.rb +48 -0
  44. data/lib/fOOrth/compiler/modes.rb +32 -0
  45. data/lib/fOOrth/compiler/modes/compiled.rb +41 -0
  46. data/lib/fOOrth/compiler/modes/deferred.rb +57 -0
  47. data/lib/fOOrth/compiler/modes/delayed.rb +40 -0
  48. data/lib/fOOrth/compiler/modes/nested.rb +34 -0
  49. data/lib/fOOrth/compiler/modes/suspend.rb +32 -0
  50. data/lib/fOOrth/compiler/parser.rb +26 -0
  51. data/lib/fOOrth/compiler/parser/get_string.rb +71 -0
  52. data/lib/fOOrth/compiler/parser/normal.rb +53 -0
  53. data/lib/fOOrth/compiler/parser/skip.rb +50 -0
  54. data/lib/fOOrth/compiler/parser/special.rb +42 -0
  55. data/lib/fOOrth/compiler/process.rb +47 -0
  56. data/lib/fOOrth/compiler/process/generate.rb +24 -0
  57. data/lib/fOOrth/compiler/process/get_token.rb +23 -0
  58. data/lib/fOOrth/compiler/process/procedure.rb +55 -0
  59. data/lib/fOOrth/compiler/process/string.rb +20 -0
  60. data/lib/fOOrth/compiler/source.rb +51 -0
  61. data/lib/fOOrth/compiler/source/console.rb +70 -0
  62. data/lib/fOOrth/compiler/source/file_source.rb +37 -0
  63. data/lib/fOOrth/compiler/source/read_point.rb +46 -0
  64. data/lib/fOOrth/compiler/source/string_source.rb +28 -0
  65. data/lib/fOOrth/compiler/token.rb +37 -0
  66. data/lib/fOOrth/compiler/word_specs.rb +178 -0
  67. data/lib/fOOrth/core.rb +27 -0
  68. data/lib/fOOrth/core/class.rb +116 -0
  69. data/lib/fOOrth/core/object.rb +78 -0
  70. data/lib/fOOrth/core/virtual_machine.rb +28 -0
  71. data/lib/fOOrth/debug.rb +13 -0
  72. data/lib/fOOrth/debug/context_dump.rb +31 -0
  73. data/lib/fOOrth/debug/dbg_puts.rb +17 -0
  74. data/lib/fOOrth/debug/display_abort.rb +37 -0
  75. data/lib/fOOrth/debug/vm_dump.rb +27 -0
  76. data/lib/fOOrth/initialize.rb +83 -0
  77. data/lib/fOOrth/interpreter.rb +24 -0
  78. data/lib/fOOrth/interpreter/add_to_hash.rb +17 -0
  79. data/lib/fOOrth/interpreter/data_stack.rb +125 -0
  80. data/lib/fOOrth/interpreter/do_loop.rb +55 -0
  81. data/lib/fOOrth/interpreter/squash.rb +25 -0
  82. data/lib/fOOrth/library.rb +38 -0
  83. data/lib/fOOrth/library/array_library.rb +577 -0
  84. data/lib/fOOrth/library/bundle_library.rb +112 -0
  85. data/lib/fOOrth/library/class_library.rb +90 -0
  86. data/lib/fOOrth/library/clone_library.rb +72 -0
  87. data/lib/fOOrth/library/command_library.rb +205 -0
  88. data/lib/fOOrth/library/compile_library.rb +181 -0
  89. data/lib/fOOrth/library/complex_library.rb +81 -0
  90. data/lib/fOOrth/library/ctrl_struct_library.rb +116 -0
  91. data/lib/fOOrth/library/data_ref_library.rb +100 -0
  92. data/lib/fOOrth/library/duration/arithmetic.rb +114 -0
  93. data/lib/fOOrth/library/duration/formatter.rb +152 -0
  94. data/lib/fOOrth/library/duration/intervals.rb +233 -0
  95. data/lib/fOOrth/library/duration/make.rb +75 -0
  96. data/lib/fOOrth/library/duration_library.rb +52 -0
  97. data/lib/fOOrth/library/fiber_library.rb +120 -0
  98. data/lib/fOOrth/library/hash_library.rb +203 -0
  99. data/lib/fOOrth/library/in_stream_library.rb +81 -0
  100. data/lib/fOOrth/library/integer_library.rb +104 -0
  101. data/lib/fOOrth/library/mutex_library.rb +31 -0
  102. data/lib/fOOrth/library/numeric_library.rb +380 -0
  103. data/lib/fOOrth/library/object_library.rb +80 -0
  104. data/lib/fOOrth/library/other_value_types_library.rb +96 -0
  105. data/lib/fOOrth/library/out_stream_library.rb +146 -0
  106. data/lib/fOOrth/library/procedure_library.rb +65 -0
  107. data/lib/fOOrth/library/queue_library.rb +47 -0
  108. data/lib/fOOrth/library/rational_library.rb +90 -0
  109. data/lib/fOOrth/library/stack_library.rb +56 -0
  110. data/lib/fOOrth/library/stdio_library.rb +56 -0
  111. data/lib/fOOrth/library/string_library.rb +285 -0
  112. data/lib/fOOrth/library/stubs.rb +76 -0
  113. data/lib/fOOrth/library/sync_bundle_library.rb +50 -0
  114. data/lib/fOOrth/library/thread_library.rb +73 -0
  115. data/lib/fOOrth/library/time_library.rb +302 -0
  116. data/lib/fOOrth/library/vm_library.rb +105 -0
  117. data/lib/fOOrth/main.rb +125 -0
  118. data/lib/fOOrth/monkey_patch.rb +14 -0
  119. data/lib/fOOrth/monkey_patch/complex.rb +30 -0
  120. data/lib/fOOrth/monkey_patch/exceptions.rb +154 -0
  121. data/lib/fOOrth/monkey_patch/false.rb +11 -0
  122. data/lib/fOOrth/monkey_patch/float.rb +22 -0
  123. data/lib/fOOrth/monkey_patch/integer.rb +22 -0
  124. data/lib/fOOrth/monkey_patch/nil.rb +11 -0
  125. data/lib/fOOrth/monkey_patch/numeric.rb +33 -0
  126. data/lib/fOOrth/monkey_patch/object.rb +43 -0
  127. data/lib/fOOrth/monkey_patch/rational.rb +31 -0
  128. data/lib/fOOrth/monkey_patch/string.rb +51 -0
  129. data/lib/fOOrth/symbol_map.rb +82 -0
  130. data/lib/fOOrth/version.rb +7 -0
  131. data/license.txt +21 -0
  132. data/rakefile.rb +65 -0
  133. data/reek.txt +1 -0
  134. data/sire.rb +132 -0
  135. data/t.txt +3 -0
  136. data/test.foorth +5 -0
  137. data/tests/compiler/context_tests.rb +180 -0
  138. data/tests/compiler/file_source_test_one.txt +1 -0
  139. data/tests/compiler/file_source_test_three.txt +3 -0
  140. data/tests/compiler/file_source_test_two.txt +3 -0
  141. data/tests/compiler/file_source_tests.rb +130 -0
  142. data/tests/compiler/mode_tests.rb +45 -0
  143. data/tests/compiler/parser_tests.rb +116 -0
  144. data/tests/compiler/spec_tests.rb +113 -0
  145. data/tests/compiler/string_source_tests.rb +128 -0
  146. data/tests/core_tests.rb +138 -0
  147. data/tests/interpreter/data_stack_tests.rb +119 -0
  148. data/tests/monkey_patch/coerce_test.rb +131 -0
  149. data/tests/monkey_patch/complex_test.rb +25 -0
  150. data/tests/monkey_patch/numeric_test.rb +62 -0
  151. data/tests/monkey_patch/object_test.rb +49 -0
  152. data/tests/monkey_patch/rational_test.rb +57 -0
  153. data/tests/monkey_patch/string_test.rb +53 -0
  154. data/tests/symbol_map_tests.rb +53 -0
  155. metadata +366 -0
@@ -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
@@ -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