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,56 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
|
3
|
+
require 'thread'
|
4
|
+
|
5
|
+
#* library/queue_library.rb - The Queue support fOOrth library.
|
6
|
+
module XfOOrth
|
7
|
+
|
8
|
+
#Connect the Queue class to the fOOrth class system.
|
9
|
+
stack = Object.create_foorth_subclass('Stack').new_class
|
10
|
+
|
11
|
+
#Uses the default implementation of the .new method.
|
12
|
+
|
13
|
+
#Initialize the Stack object.
|
14
|
+
stack.create_shared_method('.init', TosSpec, [], &lambda {|vm|
|
15
|
+
@data = []
|
16
|
+
})
|
17
|
+
|
18
|
+
#Clear the Stack object.
|
19
|
+
stack.create_shared_method('.clear', TosSpec, [], &lambda {|vm|
|
20
|
+
@data.clear
|
21
|
+
})
|
22
|
+
|
23
|
+
#[v stack] .push []; pushes the v onto the stack.
|
24
|
+
stack.create_shared_method('.push', TosSpec, [], &lambda {|vm|
|
25
|
+
@data << vm.pop
|
26
|
+
})
|
27
|
+
|
28
|
+
#[stack] .pop [v]; pops the v from the stack.
|
29
|
+
stack.create_shared_method('.pop', TosSpec, [], &lambda {|vm|
|
30
|
+
if @data.length > 0
|
31
|
+
vm.push(@data.pop)
|
32
|
+
else
|
33
|
+
error "F31: Stack Underflow: .pop"
|
34
|
+
end
|
35
|
+
})
|
36
|
+
|
37
|
+
#[stack] .peek [v]; sneaks a peek at the top item of the stack.
|
38
|
+
stack.create_shared_method('.peek', TosSpec, [], &lambda {|vm|
|
39
|
+
if @data.length > 0
|
40
|
+
vm.push(@data[-1])
|
41
|
+
else
|
42
|
+
error "F31: Stack Underflow: .peek"
|
43
|
+
end
|
44
|
+
})
|
45
|
+
|
46
|
+
#[stack] .empty? [a_boolean]
|
47
|
+
stack.create_shared_method('.empty?', TosSpec, [], &lambda {|vm|
|
48
|
+
vm.push(@data.empty?)
|
49
|
+
})
|
50
|
+
|
51
|
+
#[stack] .length [an_integer]
|
52
|
+
stack.create_shared_method('.length', TosSpec, [], &lambda {|vm|
|
53
|
+
vm.push(@data.length)
|
54
|
+
})
|
55
|
+
|
56
|
+
end
|
@@ -0,0 +1,56 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
|
3
|
+
#* library/stdio_library.rb - The standard I/O fOOrth library.
|
4
|
+
module XfOOrth
|
5
|
+
|
6
|
+
# Some basic console I/O words.
|
7
|
+
#[obj] . []; print out the object as a string.
|
8
|
+
Object.create_shared_method('.', TosSpec, [], &lambda {|vm|
|
9
|
+
self.to_foorth_s(vm)
|
10
|
+
print vm.pop
|
11
|
+
})
|
12
|
+
|
13
|
+
#Print out a string.
|
14
|
+
# [] ."string" []; prints out the string.
|
15
|
+
String.create_shared_method('."', TosSpec, [], &lambda {|vm|
|
16
|
+
print self
|
17
|
+
})
|
18
|
+
|
19
|
+
#Force a new line.
|
20
|
+
# [] cr []; prints a new line.
|
21
|
+
VirtualMachine.create_shared_method('cr', MacroSpec,
|
22
|
+
[:macro, "puts; "])
|
23
|
+
|
24
|
+
#Force a space.
|
25
|
+
# [] space []; prints a space
|
26
|
+
VirtualMachine.create_shared_method('space', MacroSpec,
|
27
|
+
[:macro, "print ' '; "])
|
28
|
+
|
29
|
+
#Force multiple spaces.
|
30
|
+
# [n] spaces []; prints n spaces.
|
31
|
+
VirtualMachine.create_shared_method('spaces', MacroSpec,
|
32
|
+
[:macro, "print ' ' * Integer.foorth_coerce(vm.pop()); "])
|
33
|
+
|
34
|
+
#Print out a single character.
|
35
|
+
#[obj] .emit []; print out the object as a character.
|
36
|
+
Numeric.create_shared_method('.emit', TosSpec, [],
|
37
|
+
&lambda {|vm| print self.to_foorth_c})
|
38
|
+
String.create_shared_method('.emit', TosSpec, [],
|
39
|
+
&lambda {|vm| print self.to_foorth_c})
|
40
|
+
Complex.create_shared_method('.emit', TosSpec, [:stub])
|
41
|
+
|
42
|
+
#Get a string from the console.
|
43
|
+
# [] accept [string]; gets a string from the console.
|
44
|
+
VirtualMachine.create_shared_method('accept', VmSpec, [],
|
45
|
+
&lambda {|vm| push(MiniReadline.readline('? ', true)); })
|
46
|
+
|
47
|
+
#Get a string from the console.
|
48
|
+
# [] accept"prompt" [string]; gets a string from the console.
|
49
|
+
VirtualMachine.create_shared_method('accept"', VmSpec, [],
|
50
|
+
&lambda {|vm| poke(MiniReadline.readline(peek.to_s, true)); })
|
51
|
+
|
52
|
+
#Get a string from the console.
|
53
|
+
# "prompt" [] .accept [string]; gets a string from the console.
|
54
|
+
String.create_shared_method('.accept', TosSpec, [],
|
55
|
+
&lambda{|vm| vm.push(MiniReadline.readline(self, true))})
|
56
|
+
end
|
@@ -0,0 +1,285 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
|
3
|
+
#* library/string_library.rb - String support for the fOOrth library.
|
4
|
+
module XfOOrth
|
5
|
+
|
6
|
+
#Connect the String class to the fOOrth class system.
|
7
|
+
String.create_foorth_proxy
|
8
|
+
|
9
|
+
# A no operation place holder for string literals
|
10
|
+
VirtualMachine.create_shared_method('"', MacroSpec, [:macro, " "])
|
11
|
+
|
12
|
+
# [string] .each{{ ... }} [unspecified]
|
13
|
+
String.create_shared_method('.each{{', NosSpec, [], &lambda { |vm|
|
14
|
+
block, idx = vm.pop, 0
|
15
|
+
self.chars { |val| block.call(vm, val, idx); idx += 1 }
|
16
|
+
})
|
17
|
+
|
18
|
+
#Some comparison operators
|
19
|
+
# [b,a] > if b > a then [true] else [false]
|
20
|
+
String.create_shared_method('>', NosSpec, [],
|
21
|
+
&lambda {|vm| vm.poke(self > vm.peek.to_s); })
|
22
|
+
|
23
|
+
# [b,a] < if b < a then [true] else [false]
|
24
|
+
String.create_shared_method('<', NosSpec, [],
|
25
|
+
&lambda {|vm| vm.poke(self < vm.peek.to_s); })
|
26
|
+
|
27
|
+
# [b,a] >= if b >= a then [true] else [false]
|
28
|
+
String.create_shared_method('>=', NosSpec, [],
|
29
|
+
&lambda {|vm| vm.poke(self >= vm.peek.to_s); })
|
30
|
+
|
31
|
+
# [b,a] <= if b <= a then [true] else [false]
|
32
|
+
String.create_shared_method('<=', NosSpec, [],
|
33
|
+
&lambda {|vm| vm.poke(self <= vm.peek.to_s); })
|
34
|
+
|
35
|
+
# [b,a] <=> if b <=> a then [true] else [false]
|
36
|
+
String.create_shared_method('<=>', NosSpec, [],
|
37
|
+
&lambda {|vm| vm.poke(self <=> vm.peek.to_s); })
|
38
|
+
|
39
|
+
|
40
|
+
#Some string manipulation methods.
|
41
|
+
# [n a] .ljust ['a ']; left justify
|
42
|
+
String.create_shared_method('.ljust', TosSpec, [],
|
43
|
+
&lambda {|vm| vm.poke(self.ljust(Integer.foorth_coerce(vm.peek))); })
|
44
|
+
|
45
|
+
# [n a] .cjust [' a ']; center justify
|
46
|
+
String.create_shared_method('.cjust', TosSpec, [],
|
47
|
+
&lambda {|vm| vm.poke(self.center(Integer.foorth_coerce(vm.peek))); })
|
48
|
+
|
49
|
+
# [n a] .rjust [' a']; right justify
|
50
|
+
String.create_shared_method('.rjust', TosSpec, [],
|
51
|
+
&lambda {|vm| vm.poke(self.rjust(Integer.foorth_coerce(vm.peek))); })
|
52
|
+
|
53
|
+
# [" a "] .lstrip ["a "]; left strip
|
54
|
+
String.create_shared_method('.lstrip', TosSpec, [],
|
55
|
+
&lambda {|vm| vm.push(self.lstrip); })
|
56
|
+
|
57
|
+
# [" a "] .strip ["a"]; left and right strip
|
58
|
+
String.create_shared_method('.strip', TosSpec, [],
|
59
|
+
&lambda {|vm| vm.push(self.strip); })
|
60
|
+
|
61
|
+
# [" a "] .rstrip [" a"]; right strip
|
62
|
+
String.create_shared_method('.rstrip', TosSpec, [],
|
63
|
+
&lambda {|vm| vm.push(self.rstrip); })
|
64
|
+
|
65
|
+
format_action = lambda do |vm|
|
66
|
+
begin
|
67
|
+
vm.poke(vm.peek % self.in_array)
|
68
|
+
rescue => err
|
69
|
+
vm.data_stack.pop
|
70
|
+
error "F40: Formating error: #{err.message}."
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
# [object_or_array fmt_str] format ['a formatted string']
|
75
|
+
Object.create_shared_method('format', NosSpec, [], &format_action)
|
76
|
+
|
77
|
+
# [object_or_array] f"fmt_str" ['a formatted string']
|
78
|
+
Object.create_shared_method('f"', NosSpec, [], &format_action)
|
79
|
+
|
80
|
+
parse_action = lambda {|vm| vm.poke(self.sscanf(vm.peek))}
|
81
|
+
|
82
|
+
# [a_str fmt_str] parse [result_array]
|
83
|
+
String.create_shared_method('parse', NosSpec, [], &parse_action)
|
84
|
+
|
85
|
+
# [a_str] p"fmt_str" [result_array]
|
86
|
+
String.create_shared_method('p"', NosSpec, [], &parse_action)
|
87
|
+
|
88
|
+
|
89
|
+
#LEFT Group
|
90
|
+
|
91
|
+
# [w 'abcdefgh'] .left ['ab'] // Assumes w = 2
|
92
|
+
String.create_shared_method('.left', TosSpec, [],
|
93
|
+
&lambda {|vm| vm.poke(self[0...(Integer.foorth_coerce(vm.peek))]); })
|
94
|
+
|
95
|
+
# [w 'abcdefgh'] .-left ['cdefgh'] // Assumes w = 2
|
96
|
+
String.create_shared_method('.-left', TosSpec, [],
|
97
|
+
&lambda {|vm| vm.poke(self[(Integer.foorth_coerce(vm.peek))..-1]); })
|
98
|
+
|
99
|
+
# [w '123''abcdefgh'] .+left ['123cdefgh'] // Assumes w = 2
|
100
|
+
String.create_shared_method('.+left', TosSpec, [], &lambda {|vm|
|
101
|
+
ins = vm.pop.to_s
|
102
|
+
vm.poke(ins + self[(Integer.foorth_coerce(vm.peek))..-1])
|
103
|
+
})
|
104
|
+
|
105
|
+
# ['abc' 'abcdefgh'] .left? [boolean]
|
106
|
+
String.create_shared_method('.left?', TosSpec, [],
|
107
|
+
&lambda {|vm| vm.poke(self.start_with?(vm.peek)); })
|
108
|
+
|
109
|
+
|
110
|
+
#MID Group
|
111
|
+
|
112
|
+
# [n w 'abcdefgh'] .mid ['cdef'] // Assumes n = 2, w = 4
|
113
|
+
String.create_shared_method('.mid', TosSpec, [], &lambda {|vm|
|
114
|
+
width = Integer.foorth_coerce(vm.pop)
|
115
|
+
posn = Integer.foorth_coerce(vm.pop)
|
116
|
+
vm.push(self[posn...(posn+width)])
|
117
|
+
})
|
118
|
+
|
119
|
+
# [n w 'abcdefgh'] .-mid ['abgh'] // Assumes n = 2, w = 4
|
120
|
+
String.create_shared_method('.-mid', TosSpec, [], &lambda {|vm|
|
121
|
+
width = Integer.foorth_coerce(vm.pop)
|
122
|
+
posn = Integer.foorth_coerce(vm.pop)
|
123
|
+
vm.push(self[0...posn] + self[(posn+width)..-1])
|
124
|
+
})
|
125
|
+
|
126
|
+
# [n w "123" "abcdefgh"] .+mid ["ab123gh"] // Assumes n = 2, w = 4
|
127
|
+
String.create_shared_method('.+mid', TosSpec, [], &lambda {|vm|
|
128
|
+
ins = vm.pop.to_s
|
129
|
+
width = Integer.foorth_coerce(vm.pop)
|
130
|
+
posn = Integer.foorth_coerce(vm.pop)
|
131
|
+
vm.push(self[0...posn] + ins + self[(posn+width)..-1])
|
132
|
+
})
|
133
|
+
|
134
|
+
# [n 'cde' 'abcdefgh'] .mid? [true] // Assumes n = 2
|
135
|
+
String.create_shared_method('.mid?', TosSpec, [], &lambda {|vm|
|
136
|
+
search = vm.pop.to_s
|
137
|
+
width = search.length
|
138
|
+
posn = Integer.foorth_coerce(vm.pop)
|
139
|
+
vm.push(self[posn...(posn+width)] == search)
|
140
|
+
})
|
141
|
+
|
142
|
+
|
143
|
+
#MIDLR Group
|
144
|
+
|
145
|
+
# [l r 'abcdefgh'] .midlr ['bcdefg'] // Assumes l = 1, r = 1
|
146
|
+
String.create_shared_method('.midlr', TosSpec, [], &lambda {|vm|
|
147
|
+
right = Integer.foorth_coerce(vm.pop)
|
148
|
+
left = Integer.foorth_coerce(vm.pop)
|
149
|
+
vm.push(self[left...(0-right)])
|
150
|
+
})
|
151
|
+
|
152
|
+
# [l r 'abcdefgh'] .-midlr ['ah'] // Assumes l = 1, r = 1
|
153
|
+
String.create_shared_method('.-midlr', TosSpec, [], &lambda {|vm|
|
154
|
+
right = Integer.foorth_coerce(vm.pop)
|
155
|
+
left = Integer.foorth_coerce(vm.pop)
|
156
|
+
vm.push(self[0...left] + self[((0-right))..-1])
|
157
|
+
})
|
158
|
+
|
159
|
+
# [l r "123" 'abcdefgh'] .+midlr ['a123h'] // Assumes l = 1, r = 1
|
160
|
+
String.create_shared_method('.+midlr', TosSpec, [], &lambda {|vm|
|
161
|
+
ins = vm.pop.to_s
|
162
|
+
right = Integer.foorth_coerce(vm.pop)
|
163
|
+
left = Integer.foorth_coerce(vm.pop)
|
164
|
+
vm.push(self[0...left] + ins + self[((0-right))..-1])
|
165
|
+
})
|
166
|
+
|
167
|
+
#RIGHT Group
|
168
|
+
|
169
|
+
# [w 'abcdefgh'] .right ['gh'] // Assumes w = 2
|
170
|
+
String.create_shared_method('.right', TosSpec, [],
|
171
|
+
&lambda {|vm| vm.poke(self[(0-(Integer.foorth_coerce(vm.peek)))..-1]); })
|
172
|
+
|
173
|
+
# [w 'abcdefgh'] .-right ['abcdef'] // Assumes w = 2
|
174
|
+
String.create_shared_method('.-right', TosSpec, [],
|
175
|
+
&lambda {|vm| vm.poke(self[0...(0-(Integer.foorth_coerce(vm.peek)))]); })
|
176
|
+
|
177
|
+
# [w "123" 'abcdefgh'] .+right ['abcdef123'] // Assumes w = 2
|
178
|
+
String.create_shared_method('.+right', TosSpec, [], &lambda {|vm|
|
179
|
+
ins = vm.pop.to_s
|
180
|
+
width = Integer.foorth_coerce(vm.pop)
|
181
|
+
vm.push(self[0...(0-width)] + ins)
|
182
|
+
})
|
183
|
+
|
184
|
+
# ['fgh' 'abcdefgh'] .right? [boolean]
|
185
|
+
String.create_shared_method('.right?', TosSpec, [],
|
186
|
+
&lambda {|vm| vm.poke(self.end_with?(vm.peek)); })
|
187
|
+
|
188
|
+
#Other String Methods
|
189
|
+
|
190
|
+
# ['cde' 'abcdefgh'] .contains? [boolean]
|
191
|
+
String.create_shared_method('.contains?', TosSpec, [],
|
192
|
+
&lambda {|vm| vm.poke(self.index(vm.peek).to_foorth_b); })
|
193
|
+
|
194
|
+
# ['cde' 'abcdefgh'] .posn [position or nil]
|
195
|
+
String.create_shared_method('.posn', TosSpec, [],
|
196
|
+
&lambda {|vm| vm.poke(self.index(vm.peek)); })
|
197
|
+
|
198
|
+
# ["a"] .length [n]
|
199
|
+
String.create_shared_method('.length', TosSpec, [],
|
200
|
+
&lambda {|vm| vm.push(self.length); })
|
201
|
+
|
202
|
+
# ["b", a] + ["ba"]; "ba" is a new object, distinct from "b"
|
203
|
+
String.create_shared_method('+', NosSpec, [],
|
204
|
+
&lambda {|vm| vm.poke(self + vm.peek.to_s); })
|
205
|
+
|
206
|
+
# ["b", a] << ["ba"]; "ba" is the same object as "b"
|
207
|
+
String.create_shared_method('<<', NosSpec, [],
|
208
|
+
&lambda {|vm| vm.poke(self << vm.peek.to_s); })
|
209
|
+
|
210
|
+
# ["b", n] * ["bbb..."]
|
211
|
+
String.create_shared_method('*', NosSpec, [], &lambda {|vm|
|
212
|
+
begin
|
213
|
+
vm.poke(self * Integer.foorth_coerce(vm.peek))
|
214
|
+
rescue
|
215
|
+
vm.data_stack.pop
|
216
|
+
raise
|
217
|
+
end
|
218
|
+
})
|
219
|
+
|
220
|
+
# ["abCD"] .to_upper ["ABCD"]
|
221
|
+
String.create_shared_method('.to_upper', TosSpec, [],
|
222
|
+
&lambda {|vm| vm.push(self.upcase); })
|
223
|
+
|
224
|
+
# ["abCD"] .to_lower ["abcd"]
|
225
|
+
String.create_shared_method('.to_lower', TosSpec, [],
|
226
|
+
&lambda {|vm| vm.push(self.downcase); })
|
227
|
+
|
228
|
+
# ["stressed"] .reverse ["desserts"]
|
229
|
+
String.create_shared_method('.reverse', TosSpec, [],
|
230
|
+
&lambda {|vm| vm.push(self.reverse); })
|
231
|
+
|
232
|
+
# ["abc\\ndef\\n123"] .lines [["abc", "def", "123"]]
|
233
|
+
String.create_shared_method('.lines', TosSpec, [],
|
234
|
+
&lambda {|vm| vm.push(self.lines.to_a.collect {|line| line.chomp}) })
|
235
|
+
|
236
|
+
# ["abc def 123"] .split [["abc", "def", "123"]]
|
237
|
+
String.create_shared_method('.split', TosSpec, [],
|
238
|
+
&lambda {|vm| vm.push(self.split(' ')) })
|
239
|
+
|
240
|
+
# [file_name_string] .load [undefined]; load the file as source code.
|
241
|
+
String.create_shared_method('.load', TosSpec, [], &lambda {|vm|
|
242
|
+
if File.extname(self) == '' && !self.end_with?('.')
|
243
|
+
file_name = self + '.foorth'
|
244
|
+
else
|
245
|
+
file_name = self
|
246
|
+
end
|
247
|
+
|
248
|
+
unless File.exists?(file_name)
|
249
|
+
error "F50: Unable to locate file #{file_name}"
|
250
|
+
end
|
251
|
+
|
252
|
+
vm.process_file(file_name)
|
253
|
+
})
|
254
|
+
|
255
|
+
# [] .load"file_name_string" [undefined]; load the file as source code.
|
256
|
+
VirtualMachine.create_shared_method('load"', VmSpec, [], &lambda{|vm|
|
257
|
+
vm.pop.foorth_load_file(vm)
|
258
|
+
})
|
259
|
+
|
260
|
+
# ["a_string"] .call [unspecified]; Execute the string as source code.
|
261
|
+
String.create_shared_method('.call', TosSpec, [], &lambda {|vm|
|
262
|
+
vm.process_string(self)
|
263
|
+
})
|
264
|
+
|
265
|
+
# ["Error message"] .throw []; Raises an exception.
|
266
|
+
String.create_shared_method('.throw', TosSpec, [], &lambda {|vm|
|
267
|
+
raise XfOOrth::XfOOrthError, self, caller
|
268
|
+
})
|
269
|
+
|
270
|
+
# [] throw"Error message" []; Raises an exception.
|
271
|
+
VirtualMachine.create_shared_method('throw"', VmSpec, [], &lambda {|vm|
|
272
|
+
raise XfOOrth::XfOOrthError, vm.pop.to_s, caller
|
273
|
+
})
|
274
|
+
|
275
|
+
# [a_string] .shell []
|
276
|
+
String.create_shared_method('.shell', TosSpec, [], &lambda {|vm|
|
277
|
+
system(self)
|
278
|
+
})
|
279
|
+
|
280
|
+
# [a_string] .shell_out [a_string]
|
281
|
+
String.create_shared_method('.shell_out', TosSpec, [], &lambda {|vm|
|
282
|
+
IO.popen(self, "r") {|io| vm.push(io.read) }
|
283
|
+
})
|
284
|
+
|
285
|
+
end
|
@@ -0,0 +1,76 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
|
3
|
+
#* library/stubs.rb - The standard fOOrth library.
|
4
|
+
module XfOOrth
|
5
|
+
|
6
|
+
# Some comparison words. See numeric_library.rb and string_library.rb
|
7
|
+
Object.create_shared_method('>', NosSpec, [:stub])
|
8
|
+
Object.create_shared_method('<', NosSpec, [:stub])
|
9
|
+
Object.create_shared_method('>=', NosSpec, [:stub])
|
10
|
+
Object.create_shared_method('<=', NosSpec, [:stub])
|
11
|
+
Object.create_shared_method('<=>', NosSpec, [:stub])
|
12
|
+
|
13
|
+
# Some comparison with zero words. See numeric_library.rb
|
14
|
+
Object.create_shared_method('0=', TosSpec, [:stub])
|
15
|
+
Object.create_shared_method('0<>', TosSpec, [:stub])
|
16
|
+
Object.create_shared_method('0>', TosSpec, [:stub])
|
17
|
+
Object.create_shared_method('0<', TosSpec, [:stub])
|
18
|
+
Object.create_shared_method('0>=', TosSpec, [:stub])
|
19
|
+
Object.create_shared_method('0<=', TosSpec, [:stub])
|
20
|
+
Object.create_shared_method('0<=>', TosSpec, [:stub])
|
21
|
+
|
22
|
+
# Stubs for the stack arithmetic words. See numeric_library.rb
|
23
|
+
Object.create_shared_method('+', NosSpec, [:stub])
|
24
|
+
Object.create_shared_method('-', NosSpec, [:stub])
|
25
|
+
Object.create_shared_method('*', NosSpec, [:stub])
|
26
|
+
Object.create_shared_method('**', NosSpec, [:stub])
|
27
|
+
Object.create_shared_method('/', NosSpec, [:stub])
|
28
|
+
Object.create_shared_method('mod', NosSpec, [:stub])
|
29
|
+
Object.create_shared_method('neg', TosSpec, [:stub])
|
30
|
+
|
31
|
+
Object.create_shared_method('1+', TosSpec, [:stub])
|
32
|
+
Object.create_shared_method('1-', TosSpec, [:stub])
|
33
|
+
Object.create_shared_method('2+', TosSpec, [:stub])
|
34
|
+
Object.create_shared_method('2-', TosSpec, [:stub])
|
35
|
+
Object.create_shared_method('2*', TosSpec, [:stub])
|
36
|
+
Object.create_shared_method('2/', TosSpec, [:stub])
|
37
|
+
|
38
|
+
Object.create_shared_method(')stubs', TosSpec, [:stub])
|
39
|
+
|
40
|
+
# Some bitwise operation stubs. See numeric_library.rb
|
41
|
+
Object.create_shared_method('and', NosSpec, [:stub])
|
42
|
+
Object.create_shared_method('or', NosSpec, [:stub])
|
43
|
+
Object.create_shared_method('xor', NosSpec, [:stub])
|
44
|
+
Object.create_shared_method('com', TosSpec, [:stub])
|
45
|
+
Object.create_shared_method('<<', NosSpec, [:stub])
|
46
|
+
Object.create_shared_method('>>', NosSpec, [:stub])
|
47
|
+
|
48
|
+
Object.create_shared_method('@', TosSpec, [:stub])
|
49
|
+
Object.create_shared_method('!', TosSpec, [:stub])
|
50
|
+
|
51
|
+
Object.create_shared_method('parse', NosSpec, [:stub])
|
52
|
+
Object.create_shared_method('parse!', NosSpec, [:stub])
|
53
|
+
Object.create_shared_method('p"', NosSpec, [:stub])
|
54
|
+
Object.create_shared_method('p!"', NosSpec, [:stub])
|
55
|
+
|
56
|
+
#Procedure literal stubs.
|
57
|
+
Object.create_shared_method('.each{{', NosSpec, [:stub])
|
58
|
+
Object.create_shared_method('.new{{', NosSpec, [:stub])
|
59
|
+
Object.create_shared_method('.map{{', NosSpec, [:stub])
|
60
|
+
Object.create_shared_method('.select{{', NosSpec, [:stub])
|
61
|
+
Object.create_shared_method('.open{{', NosSpec, [:stub])
|
62
|
+
Object.create_shared_method('.create{{', NosSpec, [:stub])
|
63
|
+
Object.create_shared_method('.append{{', NosSpec, [:stub])
|
64
|
+
Object.create_shared_method('.do{{', NosSpec, [:stub])
|
65
|
+
Object.create_shared_method('.default{{', NosSpec, [:stub])
|
66
|
+
Object.create_shared_method('.new_default{{', NosSpec, [:stub])
|
67
|
+
|
68
|
+
#Define some "crossover" symbols.
|
69
|
+
SymbolMap.add_entry('.is_class?', "foorth_is_class?".to_sym)
|
70
|
+
SymbolMap.add_entry('.to_s', :to_foorth_s)
|
71
|
+
SymbolMap.add_entry('.strlen', :foorth_strlen)
|
72
|
+
SymbolMap.add_entry('.strmax', :foorth_strmax)
|
73
|
+
SymbolMap.add_entry('.strmax2', :foorth_strmax2)
|
74
|
+
SymbolMap.add_entry('.pp', :foorth_pretty)
|
75
|
+
SymbolMap.add_entry('.load', :foorth_load_file)
|
76
|
+
end
|