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
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
# coding: utf-8
|
|
2
|
+
|
|
3
|
+
#* library/bundle_library.rb - The fOOrth Bundle class library.
|
|
4
|
+
module XfOOrth
|
|
5
|
+
|
|
6
|
+
#Define the Bundle class.
|
|
7
|
+
Object.create_foorth_subclass('Bundle').new_class
|
|
8
|
+
|
|
9
|
+
#The fOOrth Bundle class. A bundle contains multiple fibers.
|
|
10
|
+
class XfOOrth_Bundle
|
|
11
|
+
|
|
12
|
+
#Build up the bundle instance
|
|
13
|
+
def initialize(fibers=[])
|
|
14
|
+
@fibers = fibers.in_array.map {|f| f.to_foorth_fiber}
|
|
15
|
+
@current = 0
|
|
16
|
+
rescue NoMethodError
|
|
17
|
+
error "F70: A bundle may only contain procedures, fibers, or bundles."
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
#Add the fibers to this bundle.
|
|
21
|
+
def add_fibers(fibers)
|
|
22
|
+
fibers.in_array.each {|f| @fibers << f.to_foorth_fiber}
|
|
23
|
+
rescue NoMethodError
|
|
24
|
+
error "F70: A bundle may only contain procedures, fibers, or bundles."
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
#Return this bundle as a fiber.
|
|
28
|
+
def to_foorth_fiber
|
|
29
|
+
self
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
#What is the status of this bundle?
|
|
33
|
+
def status
|
|
34
|
+
@fibers.empty? ? "dead" : "alive"
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
#how many fibers in this bundle?
|
|
38
|
+
def length
|
|
39
|
+
@fibers.length
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
#Let the fiber run for one step
|
|
43
|
+
def step(vm)
|
|
44
|
+
if @current < @fibers.length
|
|
45
|
+
if @fibers[@current].step(vm)
|
|
46
|
+
@current += 1
|
|
47
|
+
else
|
|
48
|
+
@fibers.delete_at(@current)
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
@current = 0 unless @current < @fibers.length
|
|
53
|
+
!@fibers.empty?
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
#Run the fiber bundle constantly until done.
|
|
57
|
+
def run(vm)
|
|
58
|
+
while step(vm); end
|
|
59
|
+
end
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
# [a_bundle] .to_fiber [a_bundle] ; Bundles are compatible with fibers!
|
|
63
|
+
XfOOrth_Bundle.create_shared_method('.to_fiber', TosSpec, [], &lambda {|vm|
|
|
64
|
+
vm.push(self)
|
|
65
|
+
})
|
|
66
|
+
|
|
67
|
+
#[a_bundle] .to_bundle [a_bundle]; Bundles are compatible with bundles too!
|
|
68
|
+
XfOOrth_Bundle.create_shared_method('.to_bundle', TosSpec, [], &lambda{|vm|
|
|
69
|
+
vm.push(self)
|
|
70
|
+
})
|
|
71
|
+
|
|
72
|
+
#[an_array_of_procs_fibers_or_bundles] .to_bundle [a_bundle]
|
|
73
|
+
Array.create_shared_method('.to_bundle', TosSpec, [], &lambda{|vm|
|
|
74
|
+
vm.push(XfOOrth_Bundle.new(self))
|
|
75
|
+
})
|
|
76
|
+
|
|
77
|
+
#[a_proc] .to_bundle [a_bundle]
|
|
78
|
+
Proc.create_shared_method('.to_bundle', TosSpec, [], &lambda{|vm|
|
|
79
|
+
vm.push(XfOOrth_Bundle.new(self))
|
|
80
|
+
})
|
|
81
|
+
|
|
82
|
+
# [a_proc_fiber_or_bundle a_bundle] .add [] ; Add to the bundle.
|
|
83
|
+
XfOOrth_Bundle.create_shared_method('.add', TosSpec, [], &lambda {|vm|
|
|
84
|
+
self.add_fibers(vm.pop)
|
|
85
|
+
})
|
|
86
|
+
|
|
87
|
+
#[a_bundle] .step []; Do a single step on the bundle.
|
|
88
|
+
XfOOrth_Bundle.create_shared_method('.step', TosSpec, [], &lambda{|vm|
|
|
89
|
+
step(vm)
|
|
90
|
+
})
|
|
91
|
+
|
|
92
|
+
#[a_bundle] .run []; Run the bundle until all of its fibers are done.
|
|
93
|
+
XfOOrth_Bundle.create_shared_method('.run', TosSpec, [], &lambda{|vm|
|
|
94
|
+
run(vm)
|
|
95
|
+
})
|
|
96
|
+
|
|
97
|
+
# [a_bundle] .alive? [a_boolean]; Does the bundle still have fibers in it?
|
|
98
|
+
XfOOrth_Bundle.create_shared_method('.alive?', TosSpec, [], &lambda {|vm|
|
|
99
|
+
vm.push(!@fibers.empty?)
|
|
100
|
+
})
|
|
101
|
+
|
|
102
|
+
# [a_bundle] .status [a_string]; Does the bundle still have fibers in it?
|
|
103
|
+
XfOOrth_Bundle.create_shared_method('.status', TosSpec, [], &lambda {|vm|
|
|
104
|
+
vm.push(status)
|
|
105
|
+
})
|
|
106
|
+
|
|
107
|
+
# [a_bundle] .length [a_count]; How many fibers does the bundle have?
|
|
108
|
+
XfOOrth_Bundle.create_shared_method('.length', TosSpec, [], &lambda {|vm|
|
|
109
|
+
vm.push(self.length)
|
|
110
|
+
})
|
|
111
|
+
|
|
112
|
+
end
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
# coding: utf-8
|
|
2
|
+
|
|
3
|
+
#* library/class_library.rb - The fOOrth Class class library.
|
|
4
|
+
module XfOOrth
|
|
5
|
+
|
|
6
|
+
#Create a new instance of this class of objects.
|
|
7
|
+
# [{optional args for .init} a_class] .new [an_instance]
|
|
8
|
+
Class.create_shared_method('.new', TosSpec, [],
|
|
9
|
+
&lambda {|vm| vm.push(self.create_foorth_instance(vm)); })
|
|
10
|
+
|
|
11
|
+
#Get the class as a string.
|
|
12
|
+
# [cls] .to_s ["cls as a string"]
|
|
13
|
+
Class.create_shared_method('.to_s', TosSpec, [], &lambda {|vm|
|
|
14
|
+
vm.push(self.foorth_name || "AnonymousClass<#{self.object_id}>")
|
|
15
|
+
})
|
|
16
|
+
|
|
17
|
+
#The .parent_class method. Retrieves the parent class of a class.
|
|
18
|
+
# [a_class] .parent_class [parent_class or nil]
|
|
19
|
+
Class.create_shared_method('.parent_class', TosSpec, [], &lambda {|vm|
|
|
20
|
+
#Ugly hack. Sorry :-(
|
|
21
|
+
if self == Object
|
|
22
|
+
vm.push(nil)
|
|
23
|
+
elsif (self == Class) || self < Exception
|
|
24
|
+
vm.push(Object)
|
|
25
|
+
else
|
|
26
|
+
vm.push(self.superclass)
|
|
27
|
+
end
|
|
28
|
+
})
|
|
29
|
+
|
|
30
|
+
#The .is_class? method. Is the object a class object?
|
|
31
|
+
# [obj] .is_class? [boolean]
|
|
32
|
+
Object.create_shared_method('.is_class?', TosSpec, [],
|
|
33
|
+
&lambda {|vm| vm.push(false)})
|
|
34
|
+
|
|
35
|
+
Class.create_shared_method('.is_class?', TosSpec, [],
|
|
36
|
+
&lambda {|vm| vm.push(true)})
|
|
37
|
+
|
|
38
|
+
#Create a new subclass of an existing class.
|
|
39
|
+
# [a_class] .subclass: <ClassName> []; Create subclass of a_class <ClassName>
|
|
40
|
+
VirtualMachine.create_shared_method('.subclass:', VmSpec, [:immediate], &lambda {|vm|
|
|
41
|
+
name = vm.parser.get_word()
|
|
42
|
+
|
|
43
|
+
if execute_mode?
|
|
44
|
+
target = vm.pop
|
|
45
|
+
error "F13: The target of .subclass: must be a class" unless target.is_a?(Class)
|
|
46
|
+
target.create_foorth_subclass(name)
|
|
47
|
+
else
|
|
48
|
+
buffer = "vm.process_string(#{".subclass: #{name} ".inspect}); "
|
|
49
|
+
dbg_puts " Append=#{buffer}"
|
|
50
|
+
@buffer << buffer
|
|
51
|
+
end
|
|
52
|
+
})
|
|
53
|
+
|
|
54
|
+
#Create a new subclass of the Object class.
|
|
55
|
+
# [] class: <ClassName> []; Create subclass of Object <ClassName>
|
|
56
|
+
VirtualMachine.create_shared_method('class:', VmSpec, [:immediate], &lambda {|vm|
|
|
57
|
+
name = vm.parser.get_word()
|
|
58
|
+
|
|
59
|
+
if execute_mode?
|
|
60
|
+
Object.create_foorth_subclass(name)
|
|
61
|
+
else
|
|
62
|
+
buffer = "vm.process_string(#{"class: #{name} ".inspect}); "
|
|
63
|
+
dbg_puts " Append=#{buffer}"
|
|
64
|
+
@buffer << buffer
|
|
65
|
+
end
|
|
66
|
+
})
|
|
67
|
+
|
|
68
|
+
#Check that an object is of the correct class.
|
|
69
|
+
#[an_object a_class] .check [an_object or nil]
|
|
70
|
+
Class.create_shared_method('.check', TosSpec, [], &lambda {|vm|
|
|
71
|
+
object = vm.pop
|
|
72
|
+
vm.push(object.class <= self ? object : nil)
|
|
73
|
+
})
|
|
74
|
+
|
|
75
|
+
#Check that an object is of the correct class.
|
|
76
|
+
#[an_object a_class] .check! [an_object or error]
|
|
77
|
+
Class.create_shared_method('.check!', TosSpec, [], &lambda {|vm|
|
|
78
|
+
object = vm.pop
|
|
79
|
+
|
|
80
|
+
unless object.class <= self
|
|
81
|
+
error "F42: A #{object.foorth_name} is not compatible with a #{self.foorth_name}. "
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
vm.push(object)
|
|
85
|
+
})
|
|
86
|
+
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
|
|
90
|
+
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
# coding: utf-8
|
|
2
|
+
|
|
3
|
+
#* library/clone_library.rb - The fOOrth data cloning library.
|
|
4
|
+
module XfOOrth
|
|
5
|
+
|
|
6
|
+
#Add an explicit mapping for .clone_exclude so that it is accessible to Ruby.
|
|
7
|
+
SymbolMap.add_entry('.clone_exclude', :foorth_exclude)
|
|
8
|
+
|
|
9
|
+
# [a] copy [a, a']
|
|
10
|
+
VirtualMachine.create_shared_method('copy', MacroSpec,
|
|
11
|
+
[:macro, "vm.push(vm.peek.safe_clone); "])
|
|
12
|
+
|
|
13
|
+
# [a] .copy [a']
|
|
14
|
+
Object.create_shared_method('.copy', TosSpec, [],
|
|
15
|
+
&lambda {|vm| vm.push(self.safe_clone); })
|
|
16
|
+
|
|
17
|
+
# [a] clone [a, a']
|
|
18
|
+
VirtualMachine.create_shared_method('clone', MacroSpec,
|
|
19
|
+
[:macro, "vm.push(vm.peek.full_clone); "])
|
|
20
|
+
|
|
21
|
+
# [a] .clone [a']
|
|
22
|
+
Object.create_shared_method('.clone', TosSpec, [],
|
|
23
|
+
&lambda {|vm| vm.push(self.full_clone); })
|
|
24
|
+
|
|
25
|
+
# [] .clone_exclude [[exclusion_list]]
|
|
26
|
+
Object.create_shared_method('.clone_exclude', TosSpec, [],
|
|
27
|
+
&lambda {|vm| vm.push([]); })
|
|
28
|
+
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
#* Runtime clone library support in Object.
|
|
32
|
+
class Object
|
|
33
|
+
|
|
34
|
+
# The full clone data member clone exclusion control
|
|
35
|
+
def full_clone_exclude
|
|
36
|
+
vm = Thread.current[:vm]
|
|
37
|
+
self.foorth_exclude(vm)
|
|
38
|
+
|
|
39
|
+
vm.pop.map do |entry|
|
|
40
|
+
if (sym = XfOOrth::SymbolMap.map(entry))
|
|
41
|
+
("@" + sym.to_s).to_sym
|
|
42
|
+
else
|
|
43
|
+
entry
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
#* Runtime clone library support in Array.
|
|
51
|
+
class Array
|
|
52
|
+
|
|
53
|
+
# The full clone data member clone exclusion control
|
|
54
|
+
def full_clone_exclude
|
|
55
|
+
vm = Thread.current[:vm]
|
|
56
|
+
self.foorth_exclude(vm)
|
|
57
|
+
vm.pop
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
#* Runtime clone library support in Hash.
|
|
63
|
+
class Hash
|
|
64
|
+
|
|
65
|
+
# The full clone data member clone exclusion control
|
|
66
|
+
def full_clone_exclude
|
|
67
|
+
vm = Thread.current[:vm]
|
|
68
|
+
self.foorth_exclude(vm)
|
|
69
|
+
vm.pop
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
end
|
|
@@ -0,0 +1,205 @@
|
|
|
1
|
+
# coding: utf-8
|
|
2
|
+
|
|
3
|
+
#* library/command_library.rb - The utility command fOOrth library.
|
|
4
|
+
module XfOOrth
|
|
5
|
+
|
|
6
|
+
#The quit out of fOOrth method.
|
|
7
|
+
VirtualMachine.create_shared_method(')quit', MacroSpec,
|
|
8
|
+
[:macro, "raise ForceExit; "])
|
|
9
|
+
|
|
10
|
+
#Execute a command to the shell.
|
|
11
|
+
VirtualMachine.create_shared_method(')"', MacroSpec,
|
|
12
|
+
[:macro, "system(vm.pop()); "])
|
|
13
|
+
|
|
14
|
+
#Enter debug mode. Warning! This is really verbose!
|
|
15
|
+
VirtualMachine.create_shared_method(')debug', MacroSpec,
|
|
16
|
+
[:macro, "vm.debug = true; "])
|
|
17
|
+
|
|
18
|
+
#Leave debug mode.
|
|
19
|
+
VirtualMachine.create_shared_method(')nodebug', MacroSpec,
|
|
20
|
+
[:macro, "vm.debug = false; "])
|
|
21
|
+
|
|
22
|
+
#Enter show stack mode.
|
|
23
|
+
VirtualMachine.create_shared_method(')show', MacroSpec,
|
|
24
|
+
[:macro, "vm.show_stack = true; "])
|
|
25
|
+
|
|
26
|
+
#Leave show stack mode.
|
|
27
|
+
VirtualMachine.create_shared_method(')noshow', MacroSpec,
|
|
28
|
+
[:macro, "vm.show_stack = false; "])
|
|
29
|
+
|
|
30
|
+
#Dump the context.
|
|
31
|
+
VirtualMachine.create_shared_method(')context', VmSpec, [],
|
|
32
|
+
&lambda {|vm| vm.context.debug_dump(vm) })
|
|
33
|
+
|
|
34
|
+
#Dump the context right NOW!.
|
|
35
|
+
VirtualMachine.create_shared_method(')context!', VmSpec, [:immediate],
|
|
36
|
+
&lambda {|vm| vm.context.debug_dump(vm) })
|
|
37
|
+
|
|
38
|
+
#Dump the virtual machine.
|
|
39
|
+
VirtualMachine.create_shared_method(')vm', VmSpec, [],
|
|
40
|
+
&lambda {|vm| vm.debug_dump })
|
|
41
|
+
|
|
42
|
+
#Dump the virtual machine right NOW!
|
|
43
|
+
VirtualMachine.create_shared_method(')vm!', VmSpec, [:immediate],
|
|
44
|
+
&lambda {|vm| vm.debug_dump })
|
|
45
|
+
|
|
46
|
+
#Map a symbol entry
|
|
47
|
+
VirtualMachine.create_shared_method(')map"', VmSpec, [], &lambda {|vm|
|
|
48
|
+
str = vm.pop.to_s
|
|
49
|
+
puts "#{str} => #{(SymbolMap.map(str).to_s)}"
|
|
50
|
+
})
|
|
51
|
+
|
|
52
|
+
#Unmap a symbol entry
|
|
53
|
+
VirtualMachine.create_shared_method(')unmap"', VmSpec, [], &lambda {|vm|
|
|
54
|
+
str = vm.pop.to_s
|
|
55
|
+
puts "#{str} <= #{(SymbolMap.unmap(str.to_sym).to_s)}"
|
|
56
|
+
})
|
|
57
|
+
|
|
58
|
+
#Start an Interactive RuBy session (IRB)
|
|
59
|
+
VirtualMachine.create_shared_method(')irb', VmSpec, [], &lambda {|vm|
|
|
60
|
+
require 'irb'
|
|
61
|
+
require 'irb/completion'
|
|
62
|
+
|
|
63
|
+
puts
|
|
64
|
+
puts "Starting an IRB console for fOOrth."
|
|
65
|
+
puts "Enter quit to return to fOOrth."
|
|
66
|
+
puts
|
|
67
|
+
|
|
68
|
+
ARGV.clear
|
|
69
|
+
IRB.start
|
|
70
|
+
})
|
|
71
|
+
|
|
72
|
+
#Start a Pry session (IRB)
|
|
73
|
+
VirtualMachine.create_shared_method(')pry', VmSpec, [], &lambda {|vm|
|
|
74
|
+
require 'pry'
|
|
75
|
+
|
|
76
|
+
puts
|
|
77
|
+
puts "Starting an PRY console for fOOrth."
|
|
78
|
+
puts "Enter quit to return to fOOrth."
|
|
79
|
+
puts
|
|
80
|
+
|
|
81
|
+
ARGV.clear
|
|
82
|
+
Pry.start
|
|
83
|
+
})
|
|
84
|
+
|
|
85
|
+
#Get the VM timer start time.
|
|
86
|
+
VirtualMachine.create_shared_method(')start', VmSpec, [], &lambda {|vm|
|
|
87
|
+
puts "Start time is #{vm.start_time}"
|
|
88
|
+
})
|
|
89
|
+
|
|
90
|
+
#Reset the VM timer start time.
|
|
91
|
+
VirtualMachine.create_shared_method(')restart', VmSpec, [], &lambda {|vm|
|
|
92
|
+
puts "Start time reset to #{(vm.start_time = Time.now)}"
|
|
93
|
+
})
|
|
94
|
+
|
|
95
|
+
#Display the elapsed time.
|
|
96
|
+
VirtualMachine.create_shared_method(')elapsed', VmSpec, [], &lambda {|vm|
|
|
97
|
+
puts "Elapsed time is #{Time.now - vm.start_time} seconds"
|
|
98
|
+
})
|
|
99
|
+
|
|
100
|
+
#What time is it now?
|
|
101
|
+
VirtualMachine.create_shared_method(')time', VmSpec, [], &lambda {|vm|
|
|
102
|
+
puts "It is now: #{Time.now.strftime(TimeFormat)}"
|
|
103
|
+
})
|
|
104
|
+
|
|
105
|
+
#Load the file as source code.
|
|
106
|
+
VirtualMachine.create_shared_method(')load"', VmSpec, [], &lambda {|vm|
|
|
107
|
+
start_time = Time.now
|
|
108
|
+
file_name = vm.pop.to_s
|
|
109
|
+
|
|
110
|
+
if File.extname(file_name) == ''
|
|
111
|
+
file_name = file_name + '.foorth'
|
|
112
|
+
end
|
|
113
|
+
|
|
114
|
+
if File.exists?(file_name)
|
|
115
|
+
puts "Loading file: #{file_name}"
|
|
116
|
+
else
|
|
117
|
+
error "F50: Unable to locate file #{file_name}"
|
|
118
|
+
end
|
|
119
|
+
|
|
120
|
+
vm.process_file(file_name)
|
|
121
|
+
|
|
122
|
+
puts "Completed in #{Time.now - start_time} seconds"
|
|
123
|
+
})
|
|
124
|
+
|
|
125
|
+
#Display the current fOOrth language version.
|
|
126
|
+
VirtualMachine.create_shared_method(')version', MacroSpec,
|
|
127
|
+
[:macro, 'puts "fOOrth language system version = #{XfOOrth::VERSION}"; '])
|
|
128
|
+
|
|
129
|
+
#Dump the SymbolMap entries.
|
|
130
|
+
VirtualMachine.create_shared_method(')entries', VmSpec, [], &lambda {|vm|
|
|
131
|
+
entries = SymbolMap.forward_map.keys.sort
|
|
132
|
+
puts 'Symbol Map Entries = '
|
|
133
|
+
entries.foorth_pretty(vm)
|
|
134
|
+
puts
|
|
135
|
+
})
|
|
136
|
+
|
|
137
|
+
#List the methods defined for this object.
|
|
138
|
+
Object.create_shared_method(')methods', TosSpec, [], &lambda {|vm|
|
|
139
|
+
if self.foorth_has_exclusive?
|
|
140
|
+
puts 'Exclusive Methods = '
|
|
141
|
+
self.foorth_exclusive.extract_method_names.sort.foorth_pretty(vm)
|
|
142
|
+
end
|
|
143
|
+
|
|
144
|
+
puts "#{self.class.foorth_name} Shared Methods = "
|
|
145
|
+
self.class.foorth_shared.extract_method_names.sort.foorth_pretty(vm)
|
|
146
|
+
})
|
|
147
|
+
|
|
148
|
+
#List the methods defined for this class.
|
|
149
|
+
Class.create_shared_method(')methods', TosSpec, [], &lambda {|vm|
|
|
150
|
+
if self.foorth_has_exclusive?
|
|
151
|
+
puts "#{self.foorth_name} Class Methods = "
|
|
152
|
+
self.foorth_exclusive.extract_method_names.sort.foorth_pretty(vm)
|
|
153
|
+
end
|
|
154
|
+
|
|
155
|
+
puts "#{self.foorth_name} Shared Methods = "
|
|
156
|
+
self.foorth_shared.extract_method_names.sort.foorth_pretty(vm)
|
|
157
|
+
})
|
|
158
|
+
|
|
159
|
+
#List the stubs defined for this class.
|
|
160
|
+
Class.create_shared_method(')stubs', TosSpec, [], &lambda {|vm|
|
|
161
|
+
if self.foorth_has_exclusive?
|
|
162
|
+
puts "#{self.foorth_name} Class Stubs = "
|
|
163
|
+
self.foorth_exclusive.extract_method_names(:stubs).sort.foorth_pretty(vm)
|
|
164
|
+
end
|
|
165
|
+
|
|
166
|
+
puts "#{self.foorth_name} Shared Stubs = "
|
|
167
|
+
self.foorth_shared.extract_method_names(:stubs).sort.foorth_pretty(vm)
|
|
168
|
+
})
|
|
169
|
+
|
|
170
|
+
|
|
171
|
+
#List the classes defined in fOOrth.
|
|
172
|
+
VirtualMachine.create_shared_method(')classes', VmSpec, [], &lambda {|vm|
|
|
173
|
+
$FOORTH_GLOBALS.values.
|
|
174
|
+
select {|entry| entry.has_tag?(:class)}.
|
|
175
|
+
collect {|spec| spec.new_class.foorth_name}.
|
|
176
|
+
sort.
|
|
177
|
+
foorth_pretty(vm)
|
|
178
|
+
})
|
|
179
|
+
|
|
180
|
+
#List the globals defined in fOOrth.
|
|
181
|
+
VirtualMachine.create_shared_method(')globals', VmSpec, [], &lambda {|vm|
|
|
182
|
+
$FOORTH_GLOBALS.keys.
|
|
183
|
+
select {|key| !($FOORTH_GLOBALS[key].has_tag?(:class))}.
|
|
184
|
+
collect {|key| "#{XfOOrth::SymbolMap.unmap(key)} (#{key.to_s})"}.
|
|
185
|
+
foorth_pretty(vm)
|
|
186
|
+
})
|
|
187
|
+
|
|
188
|
+
#List the virtual machine methods
|
|
189
|
+
#List the methods defined for this object.
|
|
190
|
+
VirtualMachine.create_shared_method(')words', VmSpec, [], &lambda {|vm|
|
|
191
|
+
if vm.foorth_has_exclusive?
|
|
192
|
+
puts 'Exclusive Methods = '
|
|
193
|
+
vm.foorth_exclusive.extract_method_names.sort.foorth_pretty(vm)
|
|
194
|
+
end
|
|
195
|
+
|
|
196
|
+
puts "#{vm.class.foorth_name} Shared Methods = "
|
|
197
|
+
vm.class.foorth_shared.extract_method_names.sort.foorth_pretty(vm)
|
|
198
|
+
})
|
|
199
|
+
|
|
200
|
+
VirtualMachine.create_shared_method(')threads', VmSpec, [], &lambda {|vm|
|
|
201
|
+
Thread.list.
|
|
202
|
+
collect {|thrd| "#{thrd} vm = <#{thrd[:vm].name}>" }.
|
|
203
|
+
foorth_pretty(vm)
|
|
204
|
+
})
|
|
205
|
+
end
|