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