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.
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,125 @@
1
+ # coding: utf-8
2
+
3
+ require 'getoptlong'
4
+
5
+ #* main.rb - The entry point for a stand-alone foorth session.
6
+ module XfOOrth
7
+
8
+ #The user facing format used for date/time display.
9
+ TimeFormat = '%Y-%m-%d at %I:%M%P'
10
+
11
+ #The starting point for an interactive fOOrth programming session.
12
+ #This method only returns when the session is closed.
13
+ #<br>Returns:
14
+ #* The virtual machine used to run the session.
15
+ #<br>To launch a fOOrth interactive session, simply use:
16
+ # XfOOrth::main
17
+ #<br>Endemic Code Smells
18
+ #* :reek:TooManyStatements
19
+ def self.main
20
+ vm = VirtualMachine.vm('Console')
21
+ running = false
22
+
23
+ loop do
24
+ begin
25
+ running ||= start_up(vm)
26
+ vm.process_console
27
+
28
+ rescue Interrupt, ForceExit, SilentExit, MiniReadlineEOI => err
29
+ puts "\n#{err.foorth_message}"
30
+ break
31
+
32
+ rescue StandardError => err
33
+ vm.display_abort(err)
34
+
35
+ rescue Exception => err
36
+ puts "\n#{err.class.to_s.gsub(/.*::/, '')} detected: #{err}"
37
+ puts err.backtrace
38
+ break
39
+ end
40
+
41
+ break unless running
42
+ end
43
+
44
+ vm
45
+ end
46
+
47
+ #Perform one time start-up actions.
48
+ def self.start_up(vm)
49
+ announcements
50
+ vm.debug = false
51
+ vm.show_stack = false
52
+ vm.process_string(process_command_line_options)
53
+ true
54
+ end
55
+
56
+ #Display the start-up messages for the interactive session.
57
+ def self.announcements
58
+ puts "Welcome to fOOrth: fO(bject)O(riented)rth."
59
+ puts "\nfOOrth Reference Implementation Version: #{XfOOrth.version}"
60
+ puts "\nSession began on: #{Time.now.strftime(TimeFormat)}"
61
+ end
62
+
63
+ #Process the command line arguments. A string is returned containing
64
+ #fOOrth commands to be executed after the dictionary is loaded.
65
+ #<br>Returns
66
+ #* A string of fOOrth commands to be executed after the dictionary is loaded.
67
+ #<br>Endemic Code Smells
68
+ #* :reek:TooManyStatements
69
+ def self.process_command_line_options
70
+ begin
71
+
72
+ defer, found = "", false
73
+
74
+ opts = GetoptLong.new(
75
+ [ "--help", "-h", "-?", GetoptLong::NO_ARGUMENT ],
76
+ [ "--load", "-l", GetoptLong::REQUIRED_ARGUMENT ],
77
+ [ "--debug", "-d", GetoptLong::NO_ARGUMENT ],
78
+ [ "--show", "-s", GetoptLong::NO_ARGUMENT ],
79
+ [ "--quit", "-q", GetoptLong::NO_ARGUMENT ],
80
+ [ "--words", "-w", GetoptLong::NO_ARGUMENT ])
81
+
82
+ # Translate the parsed options into fOOrth.
83
+ opts.each do |opt, arg|
84
+
85
+ unless found
86
+ puts
87
+ found = true
88
+ end
89
+
90
+ case opt
91
+ when "--debug"
92
+ defer << ")debug "
93
+ when "--show"
94
+ defer << ")show "
95
+ when "--load"
96
+ defer << "\"#{arg}\" .load "
97
+ when "--quit"
98
+ defer << ")quit "
99
+ when "--words"
100
+ defer << ")words "
101
+ else
102
+ fail SilentExit
103
+ end
104
+ end
105
+
106
+ puts if found
107
+
108
+ rescue Exception
109
+ puts
110
+ puts "fOOrth available options:"
111
+ puts
112
+ puts "--help -h -? Display this message and exit."
113
+ puts "--load -l <filename> Load the specified fOOrth source file."
114
+ puts "--debug -d Default to debug ON."
115
+ puts "--quit -q Quit after processing the command line."
116
+ puts "--show -s Default to show results ON."
117
+ puts "--words -w List the current vocabulary."
118
+ puts
119
+ raise SilentExit
120
+ end
121
+
122
+ defer
123
+ end
124
+
125
+ end
@@ -0,0 +1,14 @@
1
+ # coding: utf-8
2
+
3
+ #A collection of standard library monkey patches required by foorth.
4
+
5
+ require_relative 'monkey_patch/exceptions'
6
+ require_relative 'monkey_patch/object'
7
+ require_relative 'monkey_patch/false'
8
+ require_relative 'monkey_patch/nil'
9
+ require_relative 'monkey_patch/numeric'
10
+ require_relative 'monkey_patch/integer'
11
+ require_relative 'monkey_patch/float'
12
+ require_relative 'monkey_patch/rational'
13
+ require_relative 'monkey_patch/complex'
14
+ require_relative 'monkey_patch/string'
@@ -0,0 +1,30 @@
1
+ # coding: utf-8
2
+
3
+ #Extensions to the \Complex class required by the fOOrth language system.
4
+ class Complex
5
+ #Convert this complex number to a form suitable for embedding in a source string.
6
+ #<br>Returns
7
+ #* An embeddable form of this complex number as a string.
8
+ def foorth_embed
9
+ "Complex(#{self.real.foorth_embed},#{self.imaginary.foorth_embed})"
10
+ end
11
+
12
+ #Argument coercion methods.
13
+
14
+ #Coerce the argument to match my type.
15
+ def foorth_coerce(arg)
16
+ Complex(arg)
17
+ rescue
18
+ error "F40: Cannot coerce a #{arg.foorth_name} to a Complex"
19
+ end
20
+
21
+ #Cannot convert this number to a single character string.
22
+ def to_foorth_c
23
+ error "F40: Cannot convert a Complex instance to a character"
24
+ end
25
+
26
+ #Cannot convert this number to a Rational.
27
+ def to_foorth_r
28
+ nil
29
+ end
30
+ end
@@ -0,0 +1,154 @@
1
+ # coding: utf-8
2
+
3
+ # Extensions to Exception to support fOOrth.
4
+ class Exception
5
+
6
+ #A hash of exception classes and their fOOrth codes.
7
+ FOORTH_EXCEPTION_CODE = {
8
+ SignalException => "E30:",
9
+ Interrupt => "E30,01:",
10
+ MiniReadlineEOI => "E30,02:",
11
+ StandardError => "E:",
12
+ ArgumentError => "E01:",
13
+ Gem::Requirement::BadRequirementError => "E01,01:",
14
+ EncodingError => "E02:",
15
+ Encoding::CompatibilityError => "E02,01:",
16
+ Encoding::ConverterNotFoundError => "E02,02:",
17
+ Encoding::InvalidByteSequenceError => "E02,03:",
18
+ Encoding::UndefinedConversionError => "E02,04:",
19
+ FiberError => "E03:",
20
+ IOError => "E04:",
21
+ EOFError => "E04,01:",
22
+ IndexError => "E05:",
23
+ KeyError => "E05,01:",
24
+ StopIteration => "E05,02:",
25
+ LocalJumpError => "E06:",
26
+ Math::DomainError => "E07:",
27
+ NameError => "E08:",
28
+ NoMethodError => "E08,01:",
29
+ RangeError => "E09:",
30
+ FloatDomainError => "E09,01:",
31
+ RegexpError => "E10:",
32
+ RuntimeError => "E11:",
33
+ Gem::Exception => "E11,01:",
34
+ Gem::CommandLineError => "E11,01,01:",
35
+ Gem::DependencyError => "E11,01,02:",
36
+ Gem::DependencyRemovalException => "E11,01,03:",
37
+ Gem::DependencyResolutionError => "E11,01,04:",
38
+ Gem::DocumentError => "E11,01,05:",
39
+ Gem::EndOfYAMLException => "E11,01,06:",
40
+ Gem::FilePermissionError => "E11,01,07:",
41
+ Gem::FormatException => "E11,01,08:",
42
+ Gem::GemNotFoundException => "E11,01,09:",
43
+ Gem::SpecificGemNotFoundException => "E11,01,09,01:",
44
+ Gem::GemNotInHomeException => "E11,01,10:",
45
+ Gem::ImpossibleDependenciesError => "E11,01,11:",
46
+ Gem::InstallError => "E11,01,12:",
47
+ Gem::InvalidSpecificationException => "E11,01,13:",
48
+ Gem::OperationNotSupportedError => "E11,01,14:",
49
+ Gem::RemoteError => "E11,01,15:",
50
+ Gem::RemoteInstallationCancelled => "E11,01,16:",
51
+ Gem::RemoteInstallationSkipped => "E11,01,17:",
52
+ Gem::RemoteSourceException => "E11,01,18:",
53
+ #Gem::RubyVersionMismatch => "E11,01,19:",
54
+ Gem::UnsatisfiableDependencyError => "E11,01,20:",
55
+ Gem::VerificationError => "E11,01,21:",
56
+ #SystemCallError => "E12,<error_name>:",
57
+ ThreadError => "E13:",
58
+ TypeError => "E14:",
59
+ ZeroDivisionError => "E15:"}
60
+
61
+ if Object.const_defined?('RubyVersionMismatch')
62
+ FOORTH_EXCEPTION_CODE[Gem::RubyVersionMismatch] = "E11,01,19:"
63
+ end
64
+
65
+ #Retrieve the fOOrth exception code of this exception.
66
+ def foorth_code
67
+ if /^[A-Z]\d\d(,\d\d)*:/ =~ self.message
68
+ result = $MATCH
69
+ else
70
+ klass = self.class
71
+
72
+ while (klass)
73
+ break if (result = FOORTH_EXCEPTION_CODE[klass])
74
+ klass = klass.superclass
75
+ end
76
+ end
77
+
78
+ result ||= "E??:"
79
+ end
80
+
81
+ #Is this exception covered by target?
82
+ def foorth_match(target)
83
+ self.foorth_code[0, target.length] == target
84
+ end
85
+
86
+ #Get the error message for this exception.
87
+ def foorth_message
88
+ "#{self.foorth_code} #{self.message}"
89
+ end
90
+ end
91
+
92
+ # Extensions to SystemCallError to support fOOrth.
93
+ class SystemCallError
94
+
95
+ #Get the fOOrth error code for a system call error.
96
+ def foorth_code
97
+ result = "E12"
98
+
99
+ if /::/ =~ self.class.to_s
100
+ result += ",#{$POSTMATCH}"
101
+ end
102
+
103
+ result + ':'
104
+ end
105
+
106
+ end
107
+
108
+ # Extensions to Interrupt to support fOOrth.
109
+ class Interrupt
110
+
111
+ #The message text for the interrupt. Needed as Ruby provides none.
112
+ def message
113
+ "Interrupt detected. Exiting fOOrth."
114
+ end
115
+
116
+ end
117
+
118
+ #Shut up already!
119
+ module Exception::Gem #:nodoc: don't document this!
120
+ end
121
+
122
+ #* exceptions.rb - Exception classes for the fOOrth language interpreter.
123
+ module XfOOrth
124
+ #The generalize exception used by all fOOrth specific exceptions.
125
+ class XfOOrthError < StandardError
126
+
127
+ #Get the error message for this exception.
128
+ def foorth_message
129
+ self.message
130
+ end
131
+
132
+ end
133
+
134
+ #The exception raised to force the fOOrth language system to exit.
135
+ class ForceExit < StandardError
136
+
137
+ #Get the error message for this exception.
138
+ def foorth_message
139
+ "F00: Quit command received. Exiting fOOrth."
140
+ end
141
+
142
+ end
143
+
144
+ #The exception raised to silently force the fOOrth language system to exit.
145
+ class SilentExit < StandardError
146
+
147
+ #Get the error message for this exception. Nothing... It's silent!
148
+ def foorth_message
149
+ ""
150
+ end
151
+
152
+ end
153
+
154
+ end
@@ -0,0 +1,11 @@
1
+ # coding: utf-8
2
+
3
+ #Extensions to the \FalseClass class required by the fOOrth language system.
4
+ class FalseClass
5
+
6
+ #Convert this object to a fOOrth boolean.
7
+ def to_foorth_b
8
+ self
9
+ end
10
+
11
+ end
@@ -0,0 +1,22 @@
1
+ # coding: utf-8
2
+
3
+ #Extensions to the \Float class required by the fOOrth language system.
4
+ class Float
5
+
6
+ #Argument coercion methods.
7
+
8
+ #Coerce the argument to match my type.
9
+ def self.foorth_coerce(arg)
10
+ Float(arg)
11
+ rescue
12
+ error "F40: Cannot coerce a #{arg.foorth_name} to a Float instance"
13
+ end
14
+
15
+ #Coerce the argument to match my type.
16
+ def foorth_coerce(arg)
17
+ Float(arg)
18
+ rescue
19
+ error "F40: Cannot coerce a #{arg.foorth_name} to a Float instance"
20
+ end
21
+
22
+ end
@@ -0,0 +1,22 @@
1
+ # coding: utf-8
2
+
3
+ #Extensions to the \Integer class required by the fOOrth language system.
4
+ class Integer
5
+
6
+ #Argument coercion methods.
7
+
8
+ #Coerce the argument to match my type.
9
+ def self.foorth_coerce(arg)
10
+ Integer(arg)
11
+ rescue
12
+ error "F40: Cannot coerce a #{arg.foorth_name} to an Integer instance"
13
+ end
14
+
15
+ #Coerce the argument to match my type.
16
+ def foorth_coerce(arg)
17
+ Integer(arg)
18
+ rescue
19
+ error "F40: Cannot coerce a #{arg.foorth_name} to an Integer instance"
20
+ end
21
+
22
+ end
@@ -0,0 +1,11 @@
1
+ # coding: utf-8
2
+
3
+ #Extensions to the \NilClass class required by the fOOrth language system.
4
+ class NilClass
5
+
6
+ #Convert this object to a fOOrth boolean.
7
+ def to_foorth_b
8
+ false
9
+ end
10
+
11
+ end
@@ -0,0 +1,33 @@
1
+ # coding: utf-8
2
+
3
+ #Extensions to the \Numeric class required by the fOOrth language system.
4
+ class Numeric
5
+ #Convert this number to a form suitable for embedding in a source string.
6
+ #<br>Returns
7
+ #* An embeddable form of this number as a string.
8
+ def foorth_embed
9
+ self.to_s
10
+ end
11
+
12
+ #Convert this number to a single character string.
13
+ def to_foorth_c
14
+ as_int = Integer.foorth_coerce(self)
15
+
16
+ if as_int < 0 || as_int > 1114111
17
+ error "F40: Can't convert #{self} to a character."
18
+ else
19
+ [as_int].pack('U')
20
+ end
21
+ end
22
+
23
+ #Convert this numeric to a numeric. Return self.
24
+ def to_foorth_n
25
+ self
26
+ end
27
+
28
+ #Convert this numeric to a rational.
29
+ def to_foorth_r
30
+ self.rationalize
31
+ end
32
+
33
+ end
@@ -0,0 +1,43 @@
1
+ # coding: utf-8
2
+
3
+ #Extensions to the \Object class required by the fOOrth language system.
4
+ class Object
5
+
6
+ #Raise a fOOrth language internal exception as this operation is not allowed.
7
+ def foorth_embed
8
+ error "F40: Can't embed class #{self.class.to_s}"
9
+ end
10
+
11
+ #Convert this object to a fOOrth boolean.
12
+ def to_foorth_b
13
+ true
14
+ end
15
+
16
+ #Convert this object to a single character string.
17
+ def to_foorth_c
18
+ "\x00"
19
+ end
20
+
21
+ #Convert this object to a numeric. Returns nil for fail.
22
+ def to_foorth_n
23
+ nil
24
+ end
25
+
26
+ #Convert this object to a rational. Returns nil for fail.
27
+ def to_foorth_r
28
+ nil
29
+ end
30
+
31
+ #Fail with XfOOrthError argument error.
32
+ def error(msg)
33
+ fail XfOOrth::XfOOrthError, msg, caller
34
+ end
35
+
36
+ #Argument coercion methods. These are stubs.
37
+
38
+ #Coerce the argument to match my type. Stub
39
+ def foorth_coerce(_arg)
40
+ error "F40: Cannot coerce to a #{self.foorth_name}"
41
+ end
42
+
43
+ end