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