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,38 @@
|
|
|
1
|
+
# coding: utf-8
|
|
2
|
+
|
|
3
|
+
require_relative '../lib/fOOrth'
|
|
4
|
+
require_relative 'support/foorth_testing'
|
|
5
|
+
gem 'minitest'
|
|
6
|
+
require 'minitest/autorun'
|
|
7
|
+
require 'minitest_visible'
|
|
8
|
+
|
|
9
|
+
#Test the standard fOOrth library.
|
|
10
|
+
class VMLibraryTester < Minitest::Test
|
|
11
|
+
|
|
12
|
+
include XfOOrthTestExtensions
|
|
13
|
+
|
|
14
|
+
#Track mini-test progress.
|
|
15
|
+
include MinitestVisible
|
|
16
|
+
|
|
17
|
+
def test_that_the_VM_class_and_instance_are_available
|
|
18
|
+
foorth_equal("VirtualMachine", [XfOOrth::VirtualMachine])
|
|
19
|
+
|
|
20
|
+
vm = Thread.current[:vm]
|
|
21
|
+
foorth_equal("vm", [vm])
|
|
22
|
+
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def test_for_the_vm_as_string
|
|
26
|
+
foorth_equal("vm .to_s", ['VirtualMachine instance <Main>'])
|
|
27
|
+
foorth_output('vm .' , 'VirtualMachine instance <Main>')
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def test_for_the_vm_name
|
|
31
|
+
foorth_equal("vm .vm_name", ['Main'])
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def test_for_stack_clear
|
|
35
|
+
foorth_equal('3 4 5 6 clear', [])
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
end
|
data/lib/fOOrth.rb
ADDED
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
# coding: utf-8
|
|
2
|
+
|
|
3
|
+
# The fOOrth Language System implemented via a Ruby gem.
|
|
4
|
+
|
|
5
|
+
require 'safe_clone'
|
|
6
|
+
require 'full_clone'
|
|
7
|
+
require 'in_array'
|
|
8
|
+
require 'format_engine'
|
|
9
|
+
require 'ruby_sscanf'
|
|
10
|
+
require 'English'
|
|
11
|
+
|
|
12
|
+
require 'pp'
|
|
13
|
+
|
|
14
|
+
$no_alias_read_line_module = true
|
|
15
|
+
require 'mini_readline'
|
|
16
|
+
|
|
17
|
+
require_relative 'fOOrth/version'
|
|
18
|
+
require_relative 'fOOrth/debug'
|
|
19
|
+
require_relative 'fOOrth/monkey_patch'
|
|
20
|
+
require_relative 'fOOrth/symbol_map'
|
|
21
|
+
require_relative 'fOOrth/interpreter'
|
|
22
|
+
require_relative 'fOOrth/compiler'
|
|
23
|
+
require_relative 'fOOrth/initialize'
|
|
24
|
+
require_relative 'fOOrth/core'
|
|
25
|
+
|
|
26
|
+
unless $exclude_fOOrth_library
|
|
27
|
+
require_relative 'fOOrth/library'
|
|
28
|
+
require_relative 'fOOrth/main'
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
#\XfOOrth - the module name space of the fOOrth language system.
|
|
32
|
+
#* fOOrth.rb - The root file that gathers up all the system's parts.
|
|
33
|
+
module XfOOrth
|
|
34
|
+
|
|
35
|
+
#The version of this module.
|
|
36
|
+
#<br>Returns
|
|
37
|
+
#* A version string; <major>.<minor>.<step>
|
|
38
|
+
def self.version
|
|
39
|
+
VERSION
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
#The virtual machine is the heart of the fOOrth language system that is
|
|
43
|
+
#used to facilitate the stack oriented processing of data and language
|
|
44
|
+
#elements.
|
|
45
|
+
#* fOOrth.rb - Version info lives here.
|
|
46
|
+
class VirtualMachine
|
|
47
|
+
|
|
48
|
+
#Get the version string for this virtual machine.
|
|
49
|
+
#<br>Endemic Code Smells
|
|
50
|
+
#* :reek:UtilityFunction
|
|
51
|
+
def version
|
|
52
|
+
XfOOrth.version
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
end
|
|
57
|
+
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
# coding: utf-8
|
|
2
|
+
|
|
3
|
+
require_relative 'compiler/source'
|
|
4
|
+
require_relative 'compiler/parser'
|
|
5
|
+
require_relative 'compiler/token'
|
|
6
|
+
require_relative 'compiler/modes'
|
|
7
|
+
require_relative 'compiler/word_specs'
|
|
8
|
+
require_relative 'compiler/context'
|
|
9
|
+
require_relative 'compiler/process'
|
|
10
|
+
|
|
11
|
+
#* compiler.rb - The compiler portion of the fOOrth language system.
|
|
12
|
+
module XfOOrth
|
|
13
|
+
|
|
14
|
+
#* compiler.rb - The compiler service of the virtual machine.
|
|
15
|
+
class VirtualMachine
|
|
16
|
+
|
|
17
|
+
#The current system console object. Gets the current console object
|
|
18
|
+
#only creating one if somebody asks for one.
|
|
19
|
+
#<br>Note
|
|
20
|
+
#* This is to be the sole occurrence of @_private_console
|
|
21
|
+
def console
|
|
22
|
+
@_private_console ||= Console.new
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
#The current compiler parser.
|
|
26
|
+
attr_reader :parser
|
|
27
|
+
|
|
28
|
+
#The current execution/compile context.
|
|
29
|
+
attr_reader :context
|
|
30
|
+
|
|
31
|
+
#The level of quote nesting.
|
|
32
|
+
attr_accessor :quotes
|
|
33
|
+
|
|
34
|
+
#Is a force compile in effect?
|
|
35
|
+
attr_accessor :force
|
|
36
|
+
|
|
37
|
+
#Return the compiler to a known state.
|
|
38
|
+
def compiler_reset
|
|
39
|
+
@buffer = nil
|
|
40
|
+
@parser = nil
|
|
41
|
+
@quotes = 0
|
|
42
|
+
@force = false
|
|
43
|
+
@context = Context.new(nil, vm: self, mode: :execute)
|
|
44
|
+
self
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
#Append text to the compile buffer.
|
|
48
|
+
def <<(text)
|
|
49
|
+
dbg_puts " Append=#{text.inspect}"
|
|
50
|
+
@buffer << text
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
#Execute code from the interactive console.
|
|
54
|
+
def process_console
|
|
55
|
+
process(console)
|
|
56
|
+
ensure
|
|
57
|
+
console.flush
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
#Execute a string of code.
|
|
61
|
+
def process_string(str)
|
|
62
|
+
process(StringSource.new(str))
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
#Execute a file of code.
|
|
66
|
+
def process_file(name)
|
|
67
|
+
source = FileSource.new(name)
|
|
68
|
+
|
|
69
|
+
begin
|
|
70
|
+
process(source)
|
|
71
|
+
ensure
|
|
72
|
+
source.close
|
|
73
|
+
end
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
end
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
# coding: utf-8
|
|
2
|
+
|
|
3
|
+
require_relative 'context/map_name'
|
|
4
|
+
require_relative 'context/tags'
|
|
5
|
+
require_relative 'context/locals'
|
|
6
|
+
|
|
7
|
+
#* compiler/context.rb - The compile progress context manager of the fOOrth
|
|
8
|
+
# language system.
|
|
9
|
+
module XfOOrth
|
|
10
|
+
|
|
11
|
+
#A class for the management of global, hierarchical, and nested compile time contexts.
|
|
12
|
+
#* compiler/context.rb - \Context constructor, tag support, and local defs.
|
|
13
|
+
class Context
|
|
14
|
+
|
|
15
|
+
#The previous context object that this one builds on. Set to nil if there
|
|
16
|
+
#is none.
|
|
17
|
+
attr_reader :previous
|
|
18
|
+
|
|
19
|
+
#Setup an instance of compiler context.
|
|
20
|
+
#<br>Parameters:
|
|
21
|
+
#* previous - The previous context object or nil if there is none.
|
|
22
|
+
#* data - A hash of context data.
|
|
23
|
+
def initialize(previous, data={})
|
|
24
|
+
@previous, @data = previous, data
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
#How many levels of nested context are there?
|
|
28
|
+
def depth
|
|
29
|
+
1 + (previous ? previous.depth : 0)
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
#Is the current nesting level what is expected?
|
|
33
|
+
#<br>Parameters
|
|
34
|
+
#* expected_depth - the expected nesting depth.
|
|
35
|
+
#<br>Notes
|
|
36
|
+
#* Raises an error (F12) on incorrect nesting.
|
|
37
|
+
def check_depth(expected_depth)
|
|
38
|
+
if expected_depth - self.depth != 0
|
|
39
|
+
error "F12: Error, Invalid control/structure nesting."
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
#Get the currently define method receiver
|
|
44
|
+
def recvr
|
|
45
|
+
self[:obj] || self[:cls] || self[:vm] || error("F90: No message receiver.")
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
end
|
|
49
|
+
end
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
# coding: utf-8
|
|
2
|
+
|
|
3
|
+
#* compiler/context/locals.rb - Support local methods in context.
|
|
4
|
+
module XfOOrth
|
|
5
|
+
|
|
6
|
+
#* compiler/context/locals.rb - Support local methods in context.
|
|
7
|
+
class Context
|
|
8
|
+
|
|
9
|
+
#Create a local method on this context.
|
|
10
|
+
#<br>Parameters:
|
|
11
|
+
#* name - The name of the method to create.
|
|
12
|
+
#* spec_class - The specification class to use.
|
|
13
|
+
#* options - An array of options.
|
|
14
|
+
#* block - A block to associate with the name.
|
|
15
|
+
#<br>Returns
|
|
16
|
+
#* The spec created for the shared method.
|
|
17
|
+
def create_local_method(name, spec_class, options, &block)
|
|
18
|
+
sym = SymbolMap.add_entry(name)
|
|
19
|
+
self[sym] = spec_class.new(name, sym, options, &block)
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
#Remove a local method on this context.
|
|
23
|
+
#<br>Parameters:
|
|
24
|
+
#* The name of the method to remove.
|
|
25
|
+
def remove_local_method(name)
|
|
26
|
+
if (sym = SymbolMap.map(name))
|
|
27
|
+
@data.delete(sym)
|
|
28
|
+
else
|
|
29
|
+
error "F90: Unable to remove local method #{name}"
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
end
|
|
34
|
+
end
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
# coding: utf-8
|
|
2
|
+
|
|
3
|
+
#* compiler/context/map_name.rb - The fOOrth language mapping of names in a context.
|
|
4
|
+
module XfOOrth
|
|
5
|
+
|
|
6
|
+
#* compiler/context/map_name.rb - The fOOrth language mapping of names in a context.
|
|
7
|
+
class Context
|
|
8
|
+
|
|
9
|
+
#Map a name to a specification.
|
|
10
|
+
#<br>Parameters:
|
|
11
|
+
#* name - The string to be mapped.
|
|
12
|
+
#<br>Returns:
|
|
13
|
+
#* The specification that corresponds to the name or nil if none found.
|
|
14
|
+
def map(name)
|
|
15
|
+
if (@symbol = SymbolMap.map(@name = name))
|
|
16
|
+
do_map_name
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
#Private methods follow.
|
|
21
|
+
private
|
|
22
|
+
|
|
23
|
+
#Do a search of dictionaries based on the syntax of the name.
|
|
24
|
+
def do_map_name
|
|
25
|
+
self[@symbol] ||
|
|
26
|
+
case @name[0]
|
|
27
|
+
when '.'
|
|
28
|
+
do_object_class_map ||
|
|
29
|
+
do_vm_target_map ||
|
|
30
|
+
TosSpec.new(@name, @symbol, [:temp])
|
|
31
|
+
|
|
32
|
+
when '~'
|
|
33
|
+
do_class_target_map ||
|
|
34
|
+
do_object_target_map ||
|
|
35
|
+
do_vm_target_map ||
|
|
36
|
+
SelfSpec.new(@name, @symbol, [:temp])
|
|
37
|
+
|
|
38
|
+
when '@'
|
|
39
|
+
do_class_target_map ||
|
|
40
|
+
do_object_target_map ||
|
|
41
|
+
do_vm_target_map ||
|
|
42
|
+
spec_error
|
|
43
|
+
|
|
44
|
+
when '$'
|
|
45
|
+
do_global_target_map ||
|
|
46
|
+
spec_error
|
|
47
|
+
|
|
48
|
+
when '#'
|
|
49
|
+
do_vm_target_map ||
|
|
50
|
+
spec_error
|
|
51
|
+
|
|
52
|
+
else
|
|
53
|
+
do_object_class_map ||
|
|
54
|
+
do_vm_target_map ||
|
|
55
|
+
do_global_target_map ||
|
|
56
|
+
spec_error
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
#Do a search of the Object class for the item.
|
|
62
|
+
def do_object_class_map
|
|
63
|
+
Object.map_foorth_shared(@symbol)
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
#Do a search of the :cls tag if it is specified.
|
|
67
|
+
def do_class_target_map
|
|
68
|
+
(tc = self[:cls]) && tc.map_foorth_shared(@symbol)
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
#Do a search of the :obj tag if it is specified.
|
|
72
|
+
def do_object_target_map
|
|
73
|
+
(to = self[:obj]) && to.map_foorth_exclusive(@symbol)
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
#Do a search of the :vm tag if it is specified.
|
|
77
|
+
def do_vm_target_map
|
|
78
|
+
(vm = self[:vm]) && vm.map_foorth_exclusive(@symbol)
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
#Do a search of the globals.
|
|
82
|
+
def do_global_target_map
|
|
83
|
+
$FOORTH_GLOBALS[@symbol]
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
#Error: Unable to find a specification.
|
|
87
|
+
def spec_error
|
|
88
|
+
error "F11: ?#{@name}?"
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
end
|
|
92
|
+
end
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
# coding: utf-8
|
|
2
|
+
|
|
3
|
+
#* compiler/context/tags.rb - Support tags in context.
|
|
4
|
+
module XfOOrth
|
|
5
|
+
|
|
6
|
+
#* compiler/context/tags.rb - Support tags in context.
|
|
7
|
+
class Context
|
|
8
|
+
|
|
9
|
+
#Retrieve the data value currently in effect.
|
|
10
|
+
def [](index)
|
|
11
|
+
@data[index] || (previous && previous[index])
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
#Set a data value.
|
|
15
|
+
def []=(index,value)
|
|
16
|
+
@data[index] = value
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
#Get the compile tags in effect.
|
|
20
|
+
def tags
|
|
21
|
+
@data[:tags] || []
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
#Merge in a hash of tag data.
|
|
25
|
+
def merge(new_data)
|
|
26
|
+
@data.merge!(new_data)
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
#Validate a current data value.
|
|
30
|
+
#<br>Parameters:
|
|
31
|
+
#* symbol - The symbol of the value to be tested.
|
|
32
|
+
#* expect - An array of valid values.
|
|
33
|
+
#<br>Note:
|
|
34
|
+
#* Throws a XfOOrthError if the value is not valid.
|
|
35
|
+
#* To check for no value, use [nil] for expect.
|
|
36
|
+
#* Returns true to facilitate testing only.
|
|
37
|
+
def check_set(symbol, expect)
|
|
38
|
+
current = self[symbol]
|
|
39
|
+
|
|
40
|
+
unless expect.include?(current)
|
|
41
|
+
error "F10: Found a #{current.inspect}, excpected #{expect}"
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
true
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
end
|
|
48
|
+
end
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
# coding: utf-8
|
|
2
|
+
|
|
3
|
+
require_relative 'modes/compiled'
|
|
4
|
+
require_relative 'modes/suspend'
|
|
5
|
+
require_relative 'modes/delayed'
|
|
6
|
+
require_relative 'modes/deferred'
|
|
7
|
+
require_relative 'modes/nested'
|
|
8
|
+
|
|
9
|
+
#* compiler/modes.rb - The control of the various compiler modes.
|
|
10
|
+
module XfOOrth
|
|
11
|
+
#* modes.rb - The control of the various compiler modes.
|
|
12
|
+
class VirtualMachine
|
|
13
|
+
|
|
14
|
+
#Depending on the mode, process the text source code.
|
|
15
|
+
#<br>Parameters:
|
|
16
|
+
#* text - Some text to be executed or deferred.
|
|
17
|
+
def process_text(text)
|
|
18
|
+
if execute_mode?
|
|
19
|
+
dbg_puts " Code=#{text.inspect}"
|
|
20
|
+
@context.recvr.instance_exec(self, &eval("lambda {|vm| #{text} }"))
|
|
21
|
+
else
|
|
22
|
+
self << text
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
#Check to see if the virtual machine is in execute mode.
|
|
27
|
+
def execute_mode?
|
|
28
|
+
@context[:mode] == :execute
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
end
|
|
32
|
+
end
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
# coding: utf-8
|
|
2
|
+
|
|
3
|
+
#* compiler/modes/compiled.rb - The compiled system mode.
|
|
4
|
+
module XfOOrth
|
|
5
|
+
#* compiler/modes/compiled.rb - The control of the compiled system mode.
|
|
6
|
+
class VirtualMachine
|
|
7
|
+
|
|
8
|
+
#Start compiling a fOOrth definition. This is used to get things going
|
|
9
|
+
#by the various compiling words like ':', '::', ':::', etc.
|
|
10
|
+
#<br>Parameters:
|
|
11
|
+
#* ctrl - The control symbol that started the compilation.
|
|
12
|
+
#* action - A block to be executed when the compilation is done.
|
|
13
|
+
#<br>Note:
|
|
14
|
+
#* Adds a nested context level to be un-nested at a later point.
|
|
15
|
+
def begin_compile_mode(ctrl, defs={}, &action)
|
|
16
|
+
dbg_puts " begin_compile_mode"
|
|
17
|
+
@context.check_set(:mode, [:execute])
|
|
18
|
+
@context = Context.new(@context, mode: :compile, ctrl: ctrl, action: action)
|
|
19
|
+
@context.merge(defs)
|
|
20
|
+
@buffer = ''
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
#Finish compiling a fOOrth definition. This is used to wrap things up,
|
|
24
|
+
#mostly by the semi-colon ';' word.
|
|
25
|
+
#<br>Parameters:
|
|
26
|
+
#* ctrls - an array of the allowed set of control values.
|
|
27
|
+
#<br>Returns:
|
|
28
|
+
#* The value of the action block.
|
|
29
|
+
#<br>Note:
|
|
30
|
+
#* Un-nests a context level.
|
|
31
|
+
def end_compile_mode(ctrls)
|
|
32
|
+
@context.check_set(:ctrl, ctrls)
|
|
33
|
+
source, @buffer = "lambda {|vm| #{@buffer} }", nil
|
|
34
|
+
result = instance_exec(self, source, @context.tags, &@context[:action])
|
|
35
|
+
@context = @context.previous
|
|
36
|
+
dbg_puts " end_compile_mode"
|
|
37
|
+
result
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
end
|
|
41
|
+
end
|