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,57 @@
|
|
|
1
|
+
# coding: utf-8
|
|
2
|
+
|
|
3
|
+
#* compiler/modes/deferred.rb - The control of the deferred compiler mode.
|
|
4
|
+
module XfOOrth
|
|
5
|
+
#* compiler/modes/deferred.rb - The control of the deferred compiler mode.
|
|
6
|
+
class VirtualMachine
|
|
7
|
+
|
|
8
|
+
#Enter a mode where execution is deferred. If currently in :execute mode,
|
|
9
|
+
#enter :deferred mode else the mode is unchanged. This is used by words
|
|
10
|
+
#that need to group words together to work like if, do, and begin.
|
|
11
|
+
#<br>Parameters:
|
|
12
|
+
#* text - Some text to append to the buffer before proceeding.
|
|
13
|
+
#* ctrl - The control symbol that started the deferral.
|
|
14
|
+
#<br>Note:
|
|
15
|
+
#* Adds a nested context level to be un-nested at a later point.
|
|
16
|
+
def suspend_execute_mode(text, ctrl)
|
|
17
|
+
dbg_puts " suspend_execute_mode"
|
|
18
|
+
@context = Context.new(@context, ctrl: ctrl)
|
|
19
|
+
|
|
20
|
+
if execute_mode?
|
|
21
|
+
@context[:mode] = :deferred
|
|
22
|
+
@buffer = ''
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
self << text
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
#Verify the deferred execution state. This are used by words that work
|
|
29
|
+
#within a word grouping like else or while.
|
|
30
|
+
#<br>Parameters:
|
|
31
|
+
#* text - Some text to append to the buffer before bundling it up.
|
|
32
|
+
#* ctrls - An array of control symbols that could have started the deferral.
|
|
33
|
+
def check_deferred_mode(text, ctrls)
|
|
34
|
+
@context.check_set(:ctrl, ctrls)
|
|
35
|
+
self << text
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
#If execution was previously deferred, resume the previous mode. This is
|
|
39
|
+
#used in words that close off a block action like then, loop, or repeat.
|
|
40
|
+
#<br>Parameters:
|
|
41
|
+
#* text - Some text to append to the buffer before bundling it up.
|
|
42
|
+
#* ctrls - An array of control symbols that could have started the deferral.
|
|
43
|
+
#<br>Note:
|
|
44
|
+
#* Un-nests a context level.
|
|
45
|
+
def resume_execute_mode(text, ctrls)
|
|
46
|
+
dbg_puts " resume_execute_mode"
|
|
47
|
+
check_deferred_mode(text, ctrls)
|
|
48
|
+
@context = @context.previous
|
|
49
|
+
|
|
50
|
+
if @context[:mode] == :execute
|
|
51
|
+
source, @buffer = "lambda {|vm| #{@buffer} }", nil
|
|
52
|
+
instance_exec(self, &eval(source))
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
end
|
|
57
|
+
end
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
# coding: utf-8
|
|
2
|
+
|
|
3
|
+
#* compiler/modes/delayed.rb - The delayed compile system mode.
|
|
4
|
+
module XfOOrth
|
|
5
|
+
#* compiler/modes/delayed.rb - The delayed compile system mode.
|
|
6
|
+
class VirtualMachine
|
|
7
|
+
|
|
8
|
+
#Enter a delayed compile mode in which compilation is delayed till a
|
|
9
|
+
#later time.
|
|
10
|
+
def delayed_compile_mode(start)
|
|
11
|
+
dbg_puts " begin_delayed_compile_mode"
|
|
12
|
+
|
|
13
|
+
buffer = do_delayed_compile_mode(start)
|
|
14
|
+
|
|
15
|
+
dbg_puts " Append=#{buffer}"
|
|
16
|
+
@buffer << buffer
|
|
17
|
+
dbg_puts " end_delayed_compile_mode"
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
#The worker bee for delayed_compile_mode.
|
|
21
|
+
#<br>Endemic Code Smells
|
|
22
|
+
#* :reek:FeatureEnvy -- false positive
|
|
23
|
+
def do_delayed_compile_mode(start)
|
|
24
|
+
buffer, depth = start + ' ', 1
|
|
25
|
+
|
|
26
|
+
while depth > 0
|
|
27
|
+
if (word = parser.get_word_or_string)
|
|
28
|
+
buffer << word + ' '
|
|
29
|
+
depth += 1 if [':', '!:', '.:', '.::'].include?(word)
|
|
30
|
+
depth -= 1 if word == ';'
|
|
31
|
+
else
|
|
32
|
+
error "F12: Error, Invalid compile nesting."
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
"vm.process_string(#{buffer.foorth_embed}); "
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
end
|
|
40
|
+
end
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
# coding: utf-8
|
|
2
|
+
|
|
3
|
+
#* compiler/modes/nested.rb - The control of the nested compiler modes.
|
|
4
|
+
module XfOOrth
|
|
5
|
+
#* compiler/modes/nested.rb - The control of the nested compiler modes.
|
|
6
|
+
class VirtualMachine
|
|
7
|
+
|
|
8
|
+
#Enter a nested context without altering the current mode.
|
|
9
|
+
#<br>Parameters:
|
|
10
|
+
#* text - Some text to append associated with the nested state.
|
|
11
|
+
#* ctrl - The control symbol that started the nested context.
|
|
12
|
+
#<br>Note:
|
|
13
|
+
#* Adds a nested context level to be un-nested at a later point.
|
|
14
|
+
def nest_mode(text, ctrl)
|
|
15
|
+
dbg_puts " nest_context"
|
|
16
|
+
@context = Context.new(@context, ctrl: ctrl)
|
|
17
|
+
process_text(text)
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
#Leave a nested context without altering the current mode.
|
|
21
|
+
#<br>Parameters:
|
|
22
|
+
#* text - Some text to append associated with the nested state.
|
|
23
|
+
#* ctrls - An array of control symbols that could have started the nest.
|
|
24
|
+
#<br>Note:
|
|
25
|
+
#* Removes a nested context level.
|
|
26
|
+
def unnest_mode(text, ctrls)
|
|
27
|
+
dbg_puts " unnest_context"
|
|
28
|
+
@context.check_set(:ctrl, ctrls)
|
|
29
|
+
@context = @context.previous
|
|
30
|
+
process_text(text) if text
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
end
|
|
34
|
+
end
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
# coding: utf-8
|
|
2
|
+
|
|
3
|
+
#* compiler/modes/suspend.rb - The ability to suspend compile mode.
|
|
4
|
+
module XfOOrth
|
|
5
|
+
#* compiler/modes/suspend.rb - The ability to suspend compile mode.
|
|
6
|
+
class VirtualMachine
|
|
7
|
+
|
|
8
|
+
#While compiling, suspend compiling so that some code may be executed.
|
|
9
|
+
#<br>Parameters:
|
|
10
|
+
#* ctrl - The control symbol that suspended the compilation.
|
|
11
|
+
#<br>Note:
|
|
12
|
+
#* Adds a nested context level to be un-nested at a later point.
|
|
13
|
+
def suspend_compile_mode(ctrl)
|
|
14
|
+
dbg_puts " suspend_compile_mode"
|
|
15
|
+
@context.check_set(:mode, [:compile])
|
|
16
|
+
@context = Context.new(@context, mode: :execute, ctrl: ctrl)
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
#While compiling and compiling is suspended, resume normal compiling.
|
|
20
|
+
#<br>Parameters:
|
|
21
|
+
#* ctrls - An array of control symbols that could have
|
|
22
|
+
# suspended the compilation.
|
|
23
|
+
#<br>Note:
|
|
24
|
+
#* Un-nests a context level.
|
|
25
|
+
def resume_compile_mode(ctrls)
|
|
26
|
+
dbg_puts " resume_compile_mode"
|
|
27
|
+
@context.check_set(:ctrl, ctrls)
|
|
28
|
+
@context = @context.previous
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
end
|
|
32
|
+
end
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
# coding: utf-8
|
|
2
|
+
|
|
3
|
+
require_relative 'parser/get_string'
|
|
4
|
+
require_relative 'parser/skip'
|
|
5
|
+
require_relative 'parser/normal'
|
|
6
|
+
require_relative 'parser/special'
|
|
7
|
+
|
|
8
|
+
#* compiler/parser.rb - Parse source code from a code source.
|
|
9
|
+
module XfOOrth
|
|
10
|
+
|
|
11
|
+
#* parser.rb - Parse source code from a code source.
|
|
12
|
+
class Parser
|
|
13
|
+
|
|
14
|
+
#The source of the text to be parsed.
|
|
15
|
+
attr_reader :source
|
|
16
|
+
|
|
17
|
+
#Initialize this parser.
|
|
18
|
+
#<br>Parameters
|
|
19
|
+
#* source - The source of the text to be parsed.
|
|
20
|
+
def initialize(source)
|
|
21
|
+
@source = source
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
end
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
# coding: utf-8
|
|
2
|
+
|
|
3
|
+
#* compiler/parser/get_string.rb - Extract string literals from code source.
|
|
4
|
+
module XfOOrth
|
|
5
|
+
|
|
6
|
+
#* compiler/parser/get_string.rb - Extract string literals from code source.
|
|
7
|
+
class Parser
|
|
8
|
+
|
|
9
|
+
#Get the balance of a string from the source code source.
|
|
10
|
+
def get_string
|
|
11
|
+
vm = Thread.current[:vm]
|
|
12
|
+
vm.quotes, done, result = 1, false, ''
|
|
13
|
+
|
|
14
|
+
begin
|
|
15
|
+
next_char = @source.get
|
|
16
|
+
|
|
17
|
+
if next_char == "\\"
|
|
18
|
+
break if process_backslash(result)
|
|
19
|
+
elsif next_char == '"' || @source.eoln?
|
|
20
|
+
vm.quotes, done = 0, true
|
|
21
|
+
elsif next_char >= ' '
|
|
22
|
+
result << next_char
|
|
23
|
+
end
|
|
24
|
+
end until done
|
|
25
|
+
|
|
26
|
+
result
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
#Process a backlash character found with a string in the source text.
|
|
30
|
+
def process_backslash(buffer)
|
|
31
|
+
next_char = @source.get
|
|
32
|
+
|
|
33
|
+
if next_char == ' ' && @source.eoln?
|
|
34
|
+
next_char = skip_white_space_or_to_eoln
|
|
35
|
+
return true if ['"', ' '].include?(next_char)
|
|
36
|
+
elsif next_char == 'n'
|
|
37
|
+
next_char = "\n"
|
|
38
|
+
elsif next_char == 'x'
|
|
39
|
+
next_char = process_8_bit
|
|
40
|
+
elsif next_char == 'u'
|
|
41
|
+
next_char = process_16_bit
|
|
42
|
+
elsif next_char != "\\" && next_char != '"'
|
|
43
|
+
error "F10: Invalid string literal value: '\\#{next_char}'"
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
buffer << next_char
|
|
47
|
+
false
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
#Process an 8 bit hex character constant.
|
|
51
|
+
def process_8_bit
|
|
52
|
+
hex = process_hex_character + process_hex_character
|
|
53
|
+
eval("\"\\x#{hex}\"")
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
#Process a 16 bit hex character constant.
|
|
57
|
+
def process_16_bit
|
|
58
|
+
hex = process_hex_character + process_hex_character +
|
|
59
|
+
process_hex_character + process_hex_character
|
|
60
|
+
eval("\"\\u#{hex}\"")
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
#Get a hex character from the input stream.
|
|
64
|
+
def process_hex_character
|
|
65
|
+
next_char = @source.get
|
|
66
|
+
error "F10: Invalid hex character: '#{next_char}'" unless /\h/ =~ next_char
|
|
67
|
+
|
|
68
|
+
next_char
|
|
69
|
+
end
|
|
70
|
+
end
|
|
71
|
+
end
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
# coding: utf-8
|
|
2
|
+
|
|
3
|
+
#* compiler/parser/normal.rb - Parse source code when not in quote mode.
|
|
4
|
+
module XfOOrth
|
|
5
|
+
|
|
6
|
+
#* compiler/parser/normal.rb - Parse source code when not in quote mode.
|
|
7
|
+
class Parser
|
|
8
|
+
|
|
9
|
+
#Get the next forth word from the source code source. This method
|
|
10
|
+
#recognizes and skips over comments in the source code.
|
|
11
|
+
#<br>Returns:
|
|
12
|
+
#* A string with the next non-comment language element or nil if none
|
|
13
|
+
# could be found.
|
|
14
|
+
def get_word
|
|
15
|
+
loop do
|
|
16
|
+
return nil unless (word = get_word_raw)
|
|
17
|
+
|
|
18
|
+
if word == '('
|
|
19
|
+
skip_over_comment
|
|
20
|
+
elsif word == '//'
|
|
21
|
+
skip_to_eoln
|
|
22
|
+
else
|
|
23
|
+
return word
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
#Get the next forth word from the source code source. Recognizes, but
|
|
29
|
+
#does not process comments in the source code.
|
|
30
|
+
#<br>Returns:
|
|
31
|
+
#* A string with the next language element or nil if none could be found.
|
|
32
|
+
def get_word_raw
|
|
33
|
+
#Skip white space.
|
|
34
|
+
return nil unless (next_char = skip_white_space)
|
|
35
|
+
|
|
36
|
+
#Gather the word token.
|
|
37
|
+
word = ''
|
|
38
|
+
|
|
39
|
+
begin
|
|
40
|
+
word << next_char
|
|
41
|
+
|
|
42
|
+
#Check for the three special cases.
|
|
43
|
+
break if ['(', '//'].include?(word) || (next_char == '"')
|
|
44
|
+
|
|
45
|
+
next_char = @source.get
|
|
46
|
+
end while next_char && next_char > ' '
|
|
47
|
+
|
|
48
|
+
word
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
end
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
# coding: utf-8
|
|
2
|
+
|
|
3
|
+
#* compiler/parser/skip.rb - Skip over stuff in the source code.
|
|
4
|
+
module XfOOrth
|
|
5
|
+
|
|
6
|
+
#* compiler/parser/skip.rb - Skip over stuff in the source code.
|
|
7
|
+
class Parser
|
|
8
|
+
|
|
9
|
+
#Skip over any white space.
|
|
10
|
+
#<br>Returns:
|
|
11
|
+
#* The first non-white space character or nil if none were found.
|
|
12
|
+
def skip_white_space
|
|
13
|
+
begin
|
|
14
|
+
return nil unless (next_char = @source.get)
|
|
15
|
+
end while next_char <= ' '
|
|
16
|
+
|
|
17
|
+
next_char
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
#Skip over a portion of the source text until end of line detected.
|
|
21
|
+
#<br>Returns:
|
|
22
|
+
#* true
|
|
23
|
+
def skip_to_eoln
|
|
24
|
+
@source.get until @source.eoln?
|
|
25
|
+
true
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
#Skip over a portion of the source text until a ')' detected.
|
|
29
|
+
#<br>Returns:
|
|
30
|
+
#* true
|
|
31
|
+
#<br>Note:
|
|
32
|
+
#* Raises an XfOOrthError exception on an unterminated comment.
|
|
33
|
+
def skip_over_comment
|
|
34
|
+
until @source.eoln?
|
|
35
|
+
return true if @source.get == ')'
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
error "F10: Unbalanced comment detected."
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
#Skip till a non-white space or an end of line
|
|
42
|
+
def skip_white_space_or_to_eoln
|
|
43
|
+
while (next_char = @source.get)
|
|
44
|
+
return next_char if (next_char > ' ') || @source.eoln?
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
end
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
# coding: utf-8
|
|
2
|
+
|
|
3
|
+
#* compiler/parser/special.rb - Parse source code in special quoted mode.
|
|
4
|
+
module XfOOrth
|
|
5
|
+
|
|
6
|
+
#* compiler/parser/special.rb - Parse source code in special quoted mode.
|
|
7
|
+
class Parser
|
|
8
|
+
|
|
9
|
+
#Get the next forth word and any embedded string data. This is used to
|
|
10
|
+
#support the quoted compiler mode.
|
|
11
|
+
#<br>Returns:
|
|
12
|
+
#* A string with the next non-comment language element or nil if none
|
|
13
|
+
# could be found.
|
|
14
|
+
#<br>Endemic Code Smells
|
|
15
|
+
#* :reek:TooManyStatements
|
|
16
|
+
def get_word_or_string
|
|
17
|
+
return nil unless (word = get_word)
|
|
18
|
+
|
|
19
|
+
if word[-1] == '"'
|
|
20
|
+
vm = Thread.current[:vm]
|
|
21
|
+
vm.quotes, skip, done = 1, false, false
|
|
22
|
+
|
|
23
|
+
until done
|
|
24
|
+
return nil unless (next_char = @source.get)
|
|
25
|
+
word << next_char
|
|
26
|
+
|
|
27
|
+
if skip
|
|
28
|
+
skip = false
|
|
29
|
+
elsif next_char == '"'
|
|
30
|
+
vm.quotes, done = 0, true
|
|
31
|
+
else
|
|
32
|
+
skip = (next_char == '\\')
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
word
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
end
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
# coding: utf-8
|
|
2
|
+
|
|
3
|
+
require_relative 'process/get_token'
|
|
4
|
+
require_relative 'process/string'
|
|
5
|
+
require_relative 'process/procedure'
|
|
6
|
+
require_relative 'process/generate'
|
|
7
|
+
|
|
8
|
+
#* compiler/process.rb - Process source code from a code source.
|
|
9
|
+
module XfOOrth
|
|
10
|
+
|
|
11
|
+
#* compiler/process.rb - Process source code from a code source.
|
|
12
|
+
class VirtualMachine
|
|
13
|
+
|
|
14
|
+
private
|
|
15
|
+
|
|
16
|
+
#Process the source code provided by the source parameter.
|
|
17
|
+
#<br>Parameters:
|
|
18
|
+
#* source - A source object. Typically a Console, StringSource or FileSource.
|
|
19
|
+
def process(source)
|
|
20
|
+
save, @parser, start_depth = @parser, Parser.new(source), @context.depth
|
|
21
|
+
due_process
|
|
22
|
+
@context.check_depth(start_depth)
|
|
23
|
+
@parser = save
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
#The actual work of processing source code.
|
|
27
|
+
def due_process
|
|
28
|
+
while (token = get_token)
|
|
29
|
+
due_token(token)
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
#Finally, process the taken.
|
|
34
|
+
def due_token(token)
|
|
35
|
+
dbg_puts token.to_s
|
|
36
|
+
code = token.code
|
|
37
|
+
|
|
38
|
+
if execute_mode? || ((token.has_tag?(:immediate)) && (!@force))
|
|
39
|
+
@context.recvr.instance_exec(self, &eval("lambda {|vm| #{code} }"))
|
|
40
|
+
else
|
|
41
|
+
@buffer << code
|
|
42
|
+
@force = false
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
end
|
|
47
|
+
end
|