fOOrth 0.5.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (155) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +21 -0
  3. data/.rdoc_options +17 -0
  4. data/Gemfile +4 -0
  5. data/README.md +67 -0
  6. data/bin/fOOrth +8 -0
  7. data/demo.rb +24 -0
  8. data/fOOrth.gemspec +40 -0
  9. data/fOOrth.reek +109 -0
  10. data/integration/README.md +12 -0
  11. data/integration/_FILE_test.foorth +5 -0
  12. data/integration/array_lib_tests.rb +360 -0
  13. data/integration/class_lib_tests.rb +116 -0
  14. data/integration/clone_lib_tests.rb +108 -0
  15. data/integration/comparison_tests.rb +132 -0
  16. data/integration/compile_lib_tests.rb +190 -0
  17. data/integration/ctrl_struct_lib_tests.rb +80 -0
  18. data/integration/data_ref_lib_tests.rb +43 -0
  19. data/integration/exception_lib_tests.rb +86 -0
  20. data/integration/fiber_bundle_tests.rb +380 -0
  21. data/integration/hash_lib_tests.rb +120 -0
  22. data/integration/in_stream_test_1.txt +4 -0
  23. data/integration/load_test_one.foorth +6 -0
  24. data/integration/load_test_two.foorth +4 -0
  25. data/integration/numeric_lib_tests.rb +321 -0
  26. data/integration/object_lib_tests.rb +38 -0
  27. data/integration/procedure_lib_tests.rb +40 -0
  28. data/integration/queue_lib_tests.rb +66 -0
  29. data/integration/stack_lib_tests.rb +70 -0
  30. data/integration/standard_lib_tests.rb +208 -0
  31. data/integration/stdio_lib_tests.rb +52 -0
  32. data/integration/stream_lib_tests.rb +196 -0
  33. data/integration/string_lib_tests.rb +217 -0
  34. data/integration/support/foorth_testing.rb +135 -0
  35. data/integration/thread_lib_tests.rb +83 -0
  36. data/integration/time_lib_tests.rb +791 -0
  37. data/integration/vm_lib_tests.rb +38 -0
  38. data/lib/fOOrth.rb +57 -0
  39. data/lib/fOOrth/compiler.rb +78 -0
  40. data/lib/fOOrth/compiler/context.rb +49 -0
  41. data/lib/fOOrth/compiler/context/locals.rb +34 -0
  42. data/lib/fOOrth/compiler/context/map_name.rb +92 -0
  43. data/lib/fOOrth/compiler/context/tags.rb +48 -0
  44. data/lib/fOOrth/compiler/modes.rb +32 -0
  45. data/lib/fOOrth/compiler/modes/compiled.rb +41 -0
  46. data/lib/fOOrth/compiler/modes/deferred.rb +57 -0
  47. data/lib/fOOrth/compiler/modes/delayed.rb +40 -0
  48. data/lib/fOOrth/compiler/modes/nested.rb +34 -0
  49. data/lib/fOOrth/compiler/modes/suspend.rb +32 -0
  50. data/lib/fOOrth/compiler/parser.rb +26 -0
  51. data/lib/fOOrth/compiler/parser/get_string.rb +71 -0
  52. data/lib/fOOrth/compiler/parser/normal.rb +53 -0
  53. data/lib/fOOrth/compiler/parser/skip.rb +50 -0
  54. data/lib/fOOrth/compiler/parser/special.rb +42 -0
  55. data/lib/fOOrth/compiler/process.rb +47 -0
  56. data/lib/fOOrth/compiler/process/generate.rb +24 -0
  57. data/lib/fOOrth/compiler/process/get_token.rb +23 -0
  58. data/lib/fOOrth/compiler/process/procedure.rb +55 -0
  59. data/lib/fOOrth/compiler/process/string.rb +20 -0
  60. data/lib/fOOrth/compiler/source.rb +51 -0
  61. data/lib/fOOrth/compiler/source/console.rb +70 -0
  62. data/lib/fOOrth/compiler/source/file_source.rb +37 -0
  63. data/lib/fOOrth/compiler/source/read_point.rb +46 -0
  64. data/lib/fOOrth/compiler/source/string_source.rb +28 -0
  65. data/lib/fOOrth/compiler/token.rb +37 -0
  66. data/lib/fOOrth/compiler/word_specs.rb +178 -0
  67. data/lib/fOOrth/core.rb +27 -0
  68. data/lib/fOOrth/core/class.rb +116 -0
  69. data/lib/fOOrth/core/object.rb +78 -0
  70. data/lib/fOOrth/core/virtual_machine.rb +28 -0
  71. data/lib/fOOrth/debug.rb +13 -0
  72. data/lib/fOOrth/debug/context_dump.rb +31 -0
  73. data/lib/fOOrth/debug/dbg_puts.rb +17 -0
  74. data/lib/fOOrth/debug/display_abort.rb +37 -0
  75. data/lib/fOOrth/debug/vm_dump.rb +27 -0
  76. data/lib/fOOrth/initialize.rb +83 -0
  77. data/lib/fOOrth/interpreter.rb +24 -0
  78. data/lib/fOOrth/interpreter/add_to_hash.rb +17 -0
  79. data/lib/fOOrth/interpreter/data_stack.rb +125 -0
  80. data/lib/fOOrth/interpreter/do_loop.rb +55 -0
  81. data/lib/fOOrth/interpreter/squash.rb +25 -0
  82. data/lib/fOOrth/library.rb +38 -0
  83. data/lib/fOOrth/library/array_library.rb +577 -0
  84. data/lib/fOOrth/library/bundle_library.rb +112 -0
  85. data/lib/fOOrth/library/class_library.rb +90 -0
  86. data/lib/fOOrth/library/clone_library.rb +72 -0
  87. data/lib/fOOrth/library/command_library.rb +205 -0
  88. data/lib/fOOrth/library/compile_library.rb +181 -0
  89. data/lib/fOOrth/library/complex_library.rb +81 -0
  90. data/lib/fOOrth/library/ctrl_struct_library.rb +116 -0
  91. data/lib/fOOrth/library/data_ref_library.rb +100 -0
  92. data/lib/fOOrth/library/duration/arithmetic.rb +114 -0
  93. data/lib/fOOrth/library/duration/formatter.rb +152 -0
  94. data/lib/fOOrth/library/duration/intervals.rb +233 -0
  95. data/lib/fOOrth/library/duration/make.rb +75 -0
  96. data/lib/fOOrth/library/duration_library.rb +52 -0
  97. data/lib/fOOrth/library/fiber_library.rb +120 -0
  98. data/lib/fOOrth/library/hash_library.rb +203 -0
  99. data/lib/fOOrth/library/in_stream_library.rb +81 -0
  100. data/lib/fOOrth/library/integer_library.rb +104 -0
  101. data/lib/fOOrth/library/mutex_library.rb +31 -0
  102. data/lib/fOOrth/library/numeric_library.rb +380 -0
  103. data/lib/fOOrth/library/object_library.rb +80 -0
  104. data/lib/fOOrth/library/other_value_types_library.rb +96 -0
  105. data/lib/fOOrth/library/out_stream_library.rb +146 -0
  106. data/lib/fOOrth/library/procedure_library.rb +65 -0
  107. data/lib/fOOrth/library/queue_library.rb +47 -0
  108. data/lib/fOOrth/library/rational_library.rb +90 -0
  109. data/lib/fOOrth/library/stack_library.rb +56 -0
  110. data/lib/fOOrth/library/stdio_library.rb +56 -0
  111. data/lib/fOOrth/library/string_library.rb +285 -0
  112. data/lib/fOOrth/library/stubs.rb +76 -0
  113. data/lib/fOOrth/library/sync_bundle_library.rb +50 -0
  114. data/lib/fOOrth/library/thread_library.rb +73 -0
  115. data/lib/fOOrth/library/time_library.rb +302 -0
  116. data/lib/fOOrth/library/vm_library.rb +105 -0
  117. data/lib/fOOrth/main.rb +125 -0
  118. data/lib/fOOrth/monkey_patch.rb +14 -0
  119. data/lib/fOOrth/monkey_patch/complex.rb +30 -0
  120. data/lib/fOOrth/monkey_patch/exceptions.rb +154 -0
  121. data/lib/fOOrth/monkey_patch/false.rb +11 -0
  122. data/lib/fOOrth/monkey_patch/float.rb +22 -0
  123. data/lib/fOOrth/monkey_patch/integer.rb +22 -0
  124. data/lib/fOOrth/monkey_patch/nil.rb +11 -0
  125. data/lib/fOOrth/monkey_patch/numeric.rb +33 -0
  126. data/lib/fOOrth/monkey_patch/object.rb +43 -0
  127. data/lib/fOOrth/monkey_patch/rational.rb +31 -0
  128. data/lib/fOOrth/monkey_patch/string.rb +51 -0
  129. data/lib/fOOrth/symbol_map.rb +82 -0
  130. data/lib/fOOrth/version.rb +7 -0
  131. data/license.txt +21 -0
  132. data/rakefile.rb +65 -0
  133. data/reek.txt +1 -0
  134. data/sire.rb +132 -0
  135. data/t.txt +3 -0
  136. data/test.foorth +5 -0
  137. data/tests/compiler/context_tests.rb +180 -0
  138. data/tests/compiler/file_source_test_one.txt +1 -0
  139. data/tests/compiler/file_source_test_three.txt +3 -0
  140. data/tests/compiler/file_source_test_two.txt +3 -0
  141. data/tests/compiler/file_source_tests.rb +130 -0
  142. data/tests/compiler/mode_tests.rb +45 -0
  143. data/tests/compiler/parser_tests.rb +116 -0
  144. data/tests/compiler/spec_tests.rb +113 -0
  145. data/tests/compiler/string_source_tests.rb +128 -0
  146. data/tests/core_tests.rb +138 -0
  147. data/tests/interpreter/data_stack_tests.rb +119 -0
  148. data/tests/monkey_patch/coerce_test.rb +131 -0
  149. data/tests/monkey_patch/complex_test.rb +25 -0
  150. data/tests/monkey_patch/numeric_test.rb +62 -0
  151. data/tests/monkey_patch/object_test.rb +49 -0
  152. data/tests/monkey_patch/rational_test.rb +57 -0
  153. data/tests/monkey_patch/string_test.rb +53 -0
  154. data/tests/symbol_map_tests.rb +53 -0
  155. metadata +366 -0
@@ -0,0 +1,24 @@
1
+ # coding: utf-8
2
+
3
+ #* compiler/process/generate.rb - Generate the Ruby object code.
4
+ module XfOOrth
5
+
6
+ #* compiler/process/generate.rb - Generate the Ruby object code.
7
+ class VirtualMachine
8
+
9
+ #Finally generate some code!
10
+ #<br>Parameters:
11
+ #* token - The token to receive the generated code.
12
+ #* word - The text of the word.
13
+ def generate_code(token, word)
14
+ if (spec = @context.map(word))
15
+ token.add(spec.builds, spec.tags)
16
+ elsif (value = word.to_foorth_n)
17
+ token.add("vm.push(#{value.foorth_embed}); ", [:numeric])
18
+ else
19
+ error "F10: ?#{word}?"
20
+ end
21
+ end
22
+
23
+ end
24
+ end
@@ -0,0 +1,23 @@
1
+ # coding: utf-8
2
+
3
+ #* compiler/process/get_token.rb - Get a complete language element.
4
+ module XfOOrth
5
+
6
+ #* compiler/process/get_token.rb - Get a complete language element.
7
+ class VirtualMachine
8
+
9
+ #Get the next token structure from the source code or nil if none
10
+ #can be found.
11
+ #<br>Returns
12
+ #* A Token structure or nil.
13
+ def get_token
14
+ return nil unless (word = parser.get_word)
15
+
16
+ token = Token.new
17
+ string_parms(token, word) || procedure_parms(token, word)
18
+ generate_code(token, word)
19
+ token
20
+ end
21
+
22
+ end
23
+ end
@@ -0,0 +1,55 @@
1
+ # coding: utf-8
2
+
3
+ #* compiler/process/procedure.rb - Get an embedded procedure literal.
4
+ module XfOOrth
5
+
6
+ #* compiler/process/procedure.rb - Get an embedded procedure literal.
7
+ class VirtualMachine
8
+
9
+ private
10
+
11
+ #Process optional string parameters.
12
+ #<br>Parameters:
13
+ #* token - The token to receive the generated code.
14
+ #* word - The text of the word.
15
+ def procedure_parms(token, word)
16
+ if word.end_with?('{{')
17
+ token.add(get_procedure_literal, [:procedure])
18
+ end
19
+ end
20
+
21
+ #Extract a procedure literal from the source code.
22
+ def get_procedure_literal
23
+ save, @buffer = @buffer, ""
24
+ open_procedure_literal
25
+
26
+ begin
27
+ token = get_procedure_token
28
+ due_token(token)
29
+ end until token.has_tag?(:end)
30
+
31
+ close_procedure_literal
32
+ (result, @buffer = @buffer, save)[0]
33
+ end
34
+
35
+ #Handle the opening of a procedure literal.
36
+ def open_procedure_literal
37
+ suspend_execute_mode("vm.push(lambda {|vm, val=nil, idx=nil| ", :procedure)
38
+ context.create_local_method('v', MacroSpec, [:macro, "vm.push(val); "])
39
+ context.create_local_method('x', MacroSpec, [:macro, "vm.push(idx); "])
40
+ context.create_local_method('}}', MacroSpec, [:macro, :end, "}); "])
41
+ end
42
+
43
+ #Handle the closing of a procedure literal.
44
+ def close_procedure_literal
45
+ unnest_mode(nil, [:procedure])
46
+ end
47
+
48
+ #Get a token for the procedure literal.
49
+ def get_procedure_token
50
+ error "F12: Error, Invalid nesting." unless (token = get_token)
51
+ token
52
+ end
53
+
54
+ end
55
+ end
@@ -0,0 +1,20 @@
1
+ # coding: utf-8
2
+
3
+ #* compiler/process/string.rb - Get an embedded string literal.
4
+ module XfOOrth
5
+
6
+ #* compiler/process/string.rb - Get an embedded string literal.
7
+ class VirtualMachine
8
+
9
+ #Process optional string parameters.
10
+ #<br>Parameters:
11
+ #* token - The token to receive the generated code.
12
+ #* word - The text of the word.
13
+ def string_parms(token, word)
14
+ if word.end_with?('"')
15
+ token.add("vm.push(#{parser.get_string.foorth_embed}); ")
16
+ end
17
+ end
18
+
19
+ end
20
+ end
@@ -0,0 +1,51 @@
1
+ # coding: utf-8
2
+
3
+ require_relative 'source/read_point'
4
+
5
+ #* compiler/source.rb - The abstract source class shared by many code sources.
6
+ module XfOOrth
7
+
8
+ #The Source class used to contain code common to most sources.
9
+ class AbstractSource
10
+ include ReadPoint
11
+
12
+ #Initialize the abstract base class.
13
+ def initialize
14
+ reset_read_point
15
+ @eof = false
16
+ end
17
+
18
+ #Close the source.
19
+ def close
20
+ @eoln = true
21
+ @eof = true
22
+ end
23
+
24
+ #Get the next character of input data
25
+ #<br>Returns:
26
+ #* The next character or nil if none are available.
27
+ def get
28
+ return nil if @eof
29
+
30
+ read do
31
+ begin
32
+ @read_step.next.rstrip
33
+ rescue StopIteration
34
+ @eof = true
35
+ nil
36
+ end
37
+ end
38
+ end
39
+
40
+ #Has the source reached the end of the available data?
41
+ #<br>Returns:
42
+ #* True if the end is reached else false.
43
+ def eof?
44
+ @eof
45
+ end
46
+ end
47
+ end
48
+
49
+ require_relative 'source/string_source'
50
+ require_relative 'source/file_source'
51
+ require_relative 'source/console'
@@ -0,0 +1,70 @@
1
+ # coding: utf-8
2
+
3
+ #* compiler/console.rb - The fOOrth console support file.
4
+ module XfOOrth
5
+
6
+ #The console class enables the use of the command line console as a source
7
+ #for fOOrth commands and source code. The readline facility is used to enable
8
+ #editing and command history and retrieval.
9
+ class Console
10
+ include ReadPoint
11
+
12
+ #Initialize a new console command source.
13
+ def initialize
14
+ reset_read_point
15
+
16
+ auto_src = lambda { SymbolMap.forward_map.keys.sort }
17
+
18
+ @edit = MiniReadline::Readline.new(history: true,
19
+ auto_complete: true,
20
+ auto_source: MiniReadline::ArraySource,
21
+ array_src: auto_src,
22
+ eoi_detect: true)
23
+ end
24
+
25
+ alias close reset_read_point
26
+ alias flush reset_read_point
27
+
28
+ #Get the next character of command text from the user.
29
+ #<br>Returns
30
+ #* The next character of user input as a string.
31
+ def get
32
+ read do
33
+ @edit.readline(prompt: prompt).rstrip
34
+ end
35
+ end
36
+
37
+ #Has the scanning of the text reached the end of input?
38
+ #<br>Returns
39
+ #* Always returns false.
40
+ def eof?
41
+ false
42
+ end
43
+
44
+ #Build the command prompt for the user based on the state
45
+ #of the virtual machine.
46
+ #<br>Returns
47
+ #* A prompt string.
48
+ #<br> Endemic Code Smells
49
+ #* :reek:FeatureEnvy
50
+ def prompt
51
+ vm = Thread.current[:vm]
52
+ puts
53
+
54
+ if vm.show_stack
55
+ vm.data_stack.to_foorth_s(vm)
56
+ puts vm.pop
57
+ end
58
+
59
+ '>' * vm.context.depth + '"' * vm.quotes
60
+ end
61
+
62
+ #What is the source of this text?
63
+ def source_name
64
+ "The console."
65
+ end
66
+
67
+ alias :file_name :source_name
68
+
69
+ end
70
+ end
@@ -0,0 +1,37 @@
1
+ # coding: utf-8
2
+
3
+ #* compiler/file_source.rb - Uses a file as a source of fOOrth source code.
4
+ module XfOOrth
5
+
6
+ #The FileSource class used to extract fOOrth source code
7
+ #from a string.
8
+ class FileSource < AbstractSource
9
+
10
+ #Initialize from a file name.
11
+ #<br>Parameters:
12
+ #* name - The name of the file with the fOOrth source code.
13
+ def initialize(name)
14
+ @name = name
15
+ @file = File.new(name, "r")
16
+ @read_step = @file.each_line
17
+ super()
18
+ end
19
+
20
+ #Close the file
21
+ def close
22
+ @file.close
23
+ super()
24
+ end
25
+
26
+ #What is the source of this text?
27
+ def source_name
28
+ "A file: #{@name}"
29
+ end
30
+
31
+ #Get the name of the file
32
+ def file_name
33
+ File.absolute_path(@name)
34
+ end
35
+ end
36
+
37
+ end
@@ -0,0 +1,46 @@
1
+ # coding: utf-8
2
+
3
+ #* compiler/read_point.rb - A module used to read source code text from a buffer.
4
+ module XfOOrth
5
+
6
+ #This module is used to facilitate the reading
7
+ #of source code text from a buffer.
8
+ module ReadPoint
9
+ #Get the current line of text being read.
10
+ attr_reader :read_buffer
11
+
12
+ #Reset the read point to the initial conditions. Namely,
13
+ #no text in the buffer and not at end of line,
14
+ def reset_read_point
15
+ @read_point = nil
16
+ @eoln = false
17
+ end
18
+
19
+ #Read the next character of data from the source. If there
20
+ #is nothing to read, call the block to get some more data to
21
+ #work with.
22
+ #<br>Parameters
23
+ #* block - A block of code that retrieves the next line of
24
+ # source code to be processed.
25
+ def read(&block)
26
+ unless @read_point
27
+ return nil unless (@read_buffer = block.call)
28
+ @read_point = @read_buffer.each_char
29
+ end
30
+
31
+ begin
32
+ result, @eoln = @read_point.next, false
33
+ rescue StopIteration
34
+ result, @read_point, @eoln = ' ', nil, true
35
+ end
36
+
37
+ result
38
+ end
39
+
40
+ #Is the read point at the end of line?
41
+ def eoln?
42
+ @eoln
43
+ end
44
+ end
45
+
46
+ end
@@ -0,0 +1,28 @@
1
+ # coding: utf-8
2
+
3
+ #* compiler/string_source.rb - Uses a string as a source of fOOrth source code.
4
+ module XfOOrth
5
+
6
+ #The StringSource class used to extract fOOrth source code
7
+ #from a string.
8
+ class StringSource < AbstractSource
9
+
10
+ #Initialize from a string.
11
+ #<br>Parameters:
12
+ #* string - A string of fOOrth source code.
13
+ def initialize(string)
14
+ @string_list = string.split("\n")
15
+ @read_step = @string_list.each
16
+ super()
17
+ end
18
+
19
+ #What is the source of this text?
20
+ def source_name
21
+ "A string."
22
+ end
23
+
24
+ alias :file_name :source_name
25
+
26
+ end
27
+
28
+ end
@@ -0,0 +1,37 @@
1
+ # coding: utf-8
2
+
3
+ #* compiler/token.rb - A little bit of object code compiled from the source.
4
+ module XfOOrth
5
+
6
+ #A class used to hold vital info extracted from the source code.
7
+ class Token
8
+
9
+ #The code fragment in this token.
10
+ attr_reader :code
11
+
12
+ #Set up an empty token
13
+ def initialize
14
+ @code = ''
15
+ @tags = []
16
+ end
17
+
18
+ #Append some text/tags to the code_fragment.
19
+ def add(text, tags=nil)
20
+ @code << text
21
+ @tags.concat(tags).uniq! if tags
22
+ self
23
+ end
24
+
25
+ #Does this token have the specified tag?
26
+ def has_tag?(value)
27
+ @tags.include?(value)
28
+ end
29
+
30
+ #As a string for debugging.
31
+ def to_s
32
+ "Tags=#{@tags.inspect} Code=#{@code.inspect}"
33
+ end
34
+
35
+ end
36
+
37
+ end
@@ -0,0 +1,178 @@
1
+ # coding: utf-8
2
+
3
+ #* compiler/word_specs.rb - The classes that support the specification of the
4
+ # compile and run-time behaviors of fOOrth definitions of all sorts.
5
+ module XfOOrth
6
+
7
+ #The abstract base class for all of the different sorts of word specs.
8
+ class AbstractWordSpec
9
+
10
+ #The compile-time text inserted into the buffer.
11
+ attr_reader :builds
12
+
13
+ #The run-time action; The block that gets linked to the method's symbol.
14
+ attr_reader :does
15
+
16
+ #The attributes tagged to this specification.
17
+ attr_reader :tags
18
+
19
+ #Set up the method spec.
20
+ #<br>Parameters:
21
+ #* name - The string that maps to the symbol.
22
+ #* symbol - The symbol that the name maps to.
23
+ #* tags - A an array of tags.
24
+ #<br>These may include:
25
+ #* :immediate - The word is executed, even in compile modes.
26
+ #* :macro - Identifies the spec as a macro spec to assist debugging.
27
+ #* :stub - The word is a place holder in the hierarchy.
28
+ #<br>Endemic Code Smells
29
+ #* :reek:ControlParameter -- false positive
30
+ def initialize(name, symbol, tags=[], &block)
31
+ @tags = tags
32
+ @does = block || get_stub_action(name, symbol)
33
+ build_builds_string(name, symbol)
34
+ end
35
+
36
+ #Get the default action if none is specified.
37
+ def get_stub_action(name, symbol)
38
+ lambda do |*_any|
39
+ error "F20: A #{self.foorth_name} does not understand #{name} (#{symbol.inspect})."
40
+ end
41
+ end
42
+
43
+ #Look up an tag of interest.
44
+ def has_tag?(tag)
45
+ @tags.include?(tag)
46
+ end
47
+
48
+ end
49
+
50
+ #A class used to specify the compile of VM words.
51
+ class VmSpec < AbstractWordSpec
52
+ #Generate the Ruby code for this method.
53
+ #<br>Parameters:
54
+ #* _name - The string that maps to the symbol. Unused
55
+ #* symbol - The symbol that the name maps to.
56
+ def build_builds_string(_name, symbol)
57
+ @builds = "vm.#{symbol}(vm); "
58
+ end
59
+ end
60
+
61
+ #A class used to specify the compile of public methods of a class or object.
62
+ class TosSpec < AbstractWordSpec
63
+ #Generate the Ruby code for this method.
64
+ #<br>Parameters:
65
+ #* _name - The string that maps to the symbol. Unused
66
+ #* symbol - The symbol that the name maps to.
67
+ def build_builds_string(_name, symbol)
68
+ @builds = "vm.pop.#{symbol}(vm); "
69
+ end
70
+ end
71
+
72
+ #A class used to specify the compile of private methods of a class or object.
73
+ class SelfSpec < AbstractWordSpec
74
+ #Generate the Ruby code for this method.
75
+ #<br>Parameters:
76
+ #* _name - The string that maps to the symbol. Unused
77
+ #* symbol - The symbol that the name maps to.
78
+ def build_builds_string(_name, symbol)
79
+ @builds = "self.#{symbol}(vm); "
80
+ end
81
+ end
82
+
83
+ #A class used to specify the compile of dyadic operators.
84
+ class NosSpec < AbstractWordSpec
85
+ #Generate the Ruby code for this dyadic operator.
86
+ #<br>Parameters:
87
+ #* _name - The string that maps to the symbol. Unused
88
+ #* symbol - The symbol that the name maps to.
89
+ def build_builds_string(_name, symbol)
90
+ @builds = "vm.swap_pop.#{symbol}(vm); "
91
+ end
92
+
93
+ #Get the default action if none is specified.
94
+ def get_stub_action(name, symbol)
95
+ lambda do |vm|
96
+ #NOS methods can leave an extra bit of mess on the stack which must
97
+ #be cleaned up at this time or it will cause further problems.
98
+ vm.data_stack.pop
99
+
100
+ error "F20: A #{self.foorth_name} does not understand #{name} (#{symbol.inspect})."
101
+ end
102
+ end
103
+
104
+ end
105
+
106
+ #A class used to specify the compile of fOOrth classes.
107
+ class ClassSpec < AbstractWordSpec
108
+ #Generate the Ruby code for this fOOrth class.
109
+ #<br>Parameters:
110
+ #* \new_class - The string that maps to the symbol.
111
+ #* _symbol - The symbol that the name maps to. Unused
112
+ def build_builds_string(new_class, _symbol)
113
+ @new_class = new_class
114
+ @builds = "vm.push(#{new_class.name}); "
115
+ end
116
+
117
+ #Give read access to the class for testing.
118
+ attr_reader :new_class
119
+ end
120
+
121
+ #A class used to specify the compile of fOOrth instances variables.
122
+ class InstanceVarSpec < AbstractWordSpec
123
+ #Generate the Ruby code for this fOOrth variable.
124
+ #<br>Parameters:
125
+ #* _name - The string that maps to the symbol. Unused
126
+ #* symbol - The symbol that the name maps to.
127
+ def build_builds_string(_name, symbol)
128
+ @builds = "vm.push(#{'@'+(symbol.to_s)}); "
129
+ end
130
+ end
131
+
132
+ #A class used to specify the compile of fOOrth thread variables.
133
+ class ThreadVarSpec < AbstractWordSpec
134
+ #Generate the Ruby code for this fOOrth variable.
135
+ #<br>Parameters:
136
+ #* _name - The string that maps to the symbol. Unused
137
+ #* symbol - The symbol that the name maps to.
138
+ def build_builds_string(_name, symbol)
139
+ @builds = "vm.push(vm.data[#{symbol.inspect}]); "
140
+ end
141
+ end
142
+
143
+ #A class used to specify the compile of fOOrth global variables.
144
+ class GlobalVarSpec < AbstractWordSpec
145
+ #Generate the Ruby code for this fOOrth variable.
146
+ #<br>Parameters:
147
+ #* _name - The string that maps to the symbol. Unused
148
+ #* symbol - The symbol that the name maps to.
149
+ def build_builds_string(_name, symbol)
150
+ @builds = "vm.push(#{'$' + symbol.to_s}); "
151
+ end
152
+ end
153
+
154
+ #A class used to specify the compile of fOOrth variable.
155
+ class LocalSpec < AbstractWordSpec
156
+ #Generate the Ruby code for this fOOrth variable.
157
+ #<br>Parameters:
158
+ #* _name - The string that maps to the symbol. Unused
159
+ #* symbol - The symbol that the name maps to.
160
+ def build_builds_string(_name, symbol)
161
+ @builds = "vm.context[#{symbol.inspect}].does.call(vm); "
162
+ end
163
+ end
164
+
165
+ #A class used to specify the compile of fOOrth macros.
166
+ class MacroSpec < AbstractWordSpec
167
+ #Generate the Ruby code for this macro.
168
+ #<br>Parameters:
169
+ #* _name - The string that maps to the symbol. Unused
170
+ #* _symbol - The symbol that the name maps to. Unused
171
+ #<br>Note:
172
+ #* The last entry in the tags array is expected to be a string
173
+ # with the text of the command macro.
174
+ def build_builds_string(_name, _symbol)
175
+ @builds = @tags.pop
176
+ end
177
+ end
178
+ end