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
@@ -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
|