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
data/lib/fOOrth/main.rb
ADDED
@@ -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,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,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
|