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,81 @@
1
+ # coding: utf-8
2
+
3
+ #* library/in_stream_library.rb - The fOOrth InStream class library.
4
+ module XfOOrth
5
+
6
+ in_stream = Object.create_foorth_subclass('InStream').new_class
7
+
8
+ #* The fOOrth InStream file input mini-class.
9
+ class XfOOrth_InStream
10
+
11
+ #The file used to perform the actual input operations.
12
+ attr_reader :file
13
+
14
+ #Set up the InStream for the given file name.
15
+ def initialize(file_name)
16
+ @file = File.new(file_name, 'r')
17
+ rescue
18
+ error "F50: Unable to open the file #{file_name} for reading."
19
+ end
20
+
21
+ end
22
+
23
+ #The .new method is stubbed out.
24
+ in_stream.create_exclusive_method('.new', TosSpec, [:stub])
25
+
26
+ # ["file_name", InStream] .open [an_instream]
27
+ in_stream.create_exclusive_method('.open', TosSpec, [], &lambda {|vm|
28
+ file_name = vm.pop.to_s
29
+ vm.push(XfOOrth_InStream.new(file_name))
30
+ })
31
+
32
+ in_stream.create_exclusive_method('.open{{', NosSpec, [], &lambda {|vm|
33
+ block = vm.pop
34
+ file_name = vm.pop.to_s
35
+ in_stream = XfOOrth_InStream.new(file_name)
36
+
37
+ begin
38
+ in_stream.instance_exec(vm, nil, nil, &block)
39
+ ensure
40
+ in_stream.file.close
41
+ end
42
+ })
43
+
44
+ # [an_instream] .close []
45
+ in_stream.create_shared_method('.close', TosSpec, [], &lambda {|vm|
46
+ file.close
47
+ })
48
+
49
+ # [an_instream] .gets ["a_string"]
50
+ in_stream.create_shared_method('.gets', TosSpec, [], &lambda {|vm|
51
+ vm.push(file.gets.chomp)
52
+ })
53
+
54
+ #{self = an_instream} [] ~gets ["a_string"]
55
+ in_stream.create_shared_method('~gets', SelfSpec, [], &lambda {|vm|
56
+ vm.push(file.gets.chomp)
57
+ })
58
+
59
+
60
+ # [an_instream] .getc ["a_character"]
61
+ in_stream.create_shared_method('.getc', TosSpec, [], &lambda {|vm|
62
+ vm.push(file.getc)
63
+ })
64
+
65
+ #{self = an_instream} [] ~getc ["a_character"]
66
+ in_stream.create_shared_method('~getc', SelfSpec, [], &lambda {|vm|
67
+ vm.push(file.getc)
68
+ })
69
+
70
+
71
+ # [file_name InStream] .get_all [["line 1", "line 2", ... "line n"]]
72
+ in_stream.create_exclusive_method('.get_all', TosSpec, [], &lambda {|vm|
73
+ begin
74
+ file_name = vm.pop.to_s
75
+ vm.push(IO.readlines(file_name).map{|line| line.chomp })
76
+ rescue
77
+ error "F50: Unable to open the file #{file_name} for reading all."
78
+ end
79
+ })
80
+
81
+ end
@@ -0,0 +1,104 @@
1
+ # coding: utf-8
2
+
3
+ #* library/numeric_library.rb - Numeric support for the fOOrth library.
4
+ module XfOOrth
5
+
6
+ #Connect the Numeric classes to the fOOrth class system.
7
+ Integer.create_foorth_proxy
8
+ Fixnum.create_foorth_proxy
9
+ Bignum.create_foorth_proxy
10
+
11
+ # [a] .to_i [Integer or nil]
12
+ Object.create_shared_method('.to_i', TosSpec, [], &lambda {|vm|
13
+ begin
14
+ vm.push(Integer(self))
15
+ rescue
16
+ vm.push(nil)
17
+ end
18
+ })
19
+
20
+ # [a] .to_i! [Integer]
21
+ Object.create_shared_method('.to_i!', TosSpec, [],
22
+ &lambda {|vm| vm.push(Integer.foorth_coerce(self)); })
23
+
24
+ # [a b] .gcd [gcd(a,b)]
25
+ Integer.create_shared_method('.gcd', TosSpec, [],
26
+ &lambda {|vm| vm.poke(self.gcd(Integer.foorth_coerce(vm.peek)))})
27
+
28
+ # [a b] .lcm [lcm(a,b)]
29
+ Integer.create_shared_method('.lcm', TosSpec, [],
30
+ &lambda {|vm| vm.poke(self.lcm(Integer.foorth_coerce(vm.peek)))})
31
+
32
+ # [a] .even? [flag]
33
+ Integer.create_shared_method('.even?', TosSpec, [],
34
+ &lambda {|vm| vm.push(self.even?)})
35
+
36
+ # [a] .odd? [flag]
37
+ Integer.create_shared_method('.odd?', TosSpec, [],
38
+ &lambda {|vm| vm.push(self.odd?)})
39
+
40
+ # [a] 2* [|a|]
41
+ Integer.create_shared_method('2*', TosSpec, [],
42
+ &lambda {|vm| vm.push(self << 1); })
43
+
44
+ # [a] 2/ [|a|]
45
+ Integer.create_shared_method('2/', TosSpec, [],
46
+ &lambda {|vm| vm.push(self >> 1); })
47
+
48
+ # Some bitwise operation words.
49
+ # [b,a] and [b&a]
50
+ Integer.create_shared_method('and', NosSpec, [], &lambda {|vm|
51
+ begin
52
+ vm.poke(self & Integer.foorth_coerce(vm.peek))
53
+ rescue
54
+ vm.data_stack.pop
55
+ raise
56
+ end
57
+ })
58
+
59
+ # [b,a] or [b|a]
60
+ Integer.create_shared_method('or', NosSpec, [], &lambda {|vm|
61
+ begin
62
+ vm.poke(self | Integer.foorth_coerce(vm.peek))
63
+ rescue
64
+ vm.data_stack.pop
65
+ raise
66
+ end
67
+ })
68
+
69
+ # [b,a] xor [b^a]
70
+ Integer.create_shared_method('xor', NosSpec, [], &lambda {|vm|
71
+ begin
72
+ vm.poke(self ^ Integer.foorth_coerce(vm.peek))
73
+ rescue
74
+ vm.data_stack.pop
75
+ raise
76
+ end
77
+ })
78
+
79
+ # [a] com [~a]
80
+ Integer.create_shared_method('com', TosSpec, [],
81
+ &lambda {|vm| vm.push(~(self)); })
82
+
83
+ # [b,a] << [b<<a]
84
+ Integer.create_shared_method('<<', NosSpec, [], &lambda {|vm|
85
+ begin
86
+ vm.poke(self << Integer.foorth_coerce(vm.peek))
87
+ rescue
88
+ vm.data_stack.pop
89
+ raise
90
+ end
91
+ })
92
+
93
+ # [b,a] >> [b>>a]
94
+ Integer.create_shared_method('>>', NosSpec, [], &lambda {|vm|
95
+ begin
96
+ vm.poke(self >> Integer.foorth_coerce(vm.peek))
97
+ rescue
98
+ vm.data_stack.pop
99
+ raise
100
+ end
101
+ })
102
+
103
+
104
+ end
@@ -0,0 +1,31 @@
1
+ # coding: utf-8
2
+
3
+ #* library/mutex_library.rb - The mutex support fOOrth library.
4
+ module XfOOrth
5
+
6
+ #Connect the Mutex class to the fOOrth class system
7
+ Mutex.create_foorth_proxy
8
+
9
+ # [Mutex] .do{{ ... }} [] (Releases a lock on the mutex)
10
+ Mutex.create_exclusive_method('.do{{', NosSpec, [], &lambda {|vm|
11
+ block = vm.pop
12
+ Thread.exclusive { block.call(vm, nil, nil) }
13
+ })
14
+
15
+ # [a_mutex] .lock [] (Acquires a lock on the mutex)
16
+ Mutex.create_shared_method('.lock', TosSpec, [], &lambda {|vm|
17
+ self.lock
18
+ })
19
+
20
+ # [a_mutex] .unlock [] (Releases a lock on the mutex)
21
+ Mutex.create_shared_method('.unlock', TosSpec, [], &lambda {|vm|
22
+ self.unlock
23
+ })
24
+
25
+ # [a_mutex] .do{{ ... }} [] (Releases a lock on the mutex)
26
+ Mutex.create_shared_method('.do{{', NosSpec, [], &lambda {|vm|
27
+ block = vm.pop
28
+ self.synchronize { block.call(vm, nil, nil) }
29
+ })
30
+
31
+ end
@@ -0,0 +1,380 @@
1
+ # coding: utf-8
2
+
3
+ #* This meaningless entry exists to shut up rdoc!
4
+ module Math #:nodoc: don't document this
5
+ end
6
+
7
+ #* library/numeric_library.rb - Numeric support for the fOOrth library.
8
+ module XfOOrth
9
+
10
+ #Connect the Numeric classes to the fOOrth class system.
11
+ Numeric.create_foorth_proxy
12
+ Float.create_foorth_proxy
13
+
14
+ # Some conversion words.
15
+ # [a] .to_n [Number or nil]
16
+ Object.create_shared_method('.to_n', TosSpec, [],
17
+ &lambda {|vm| vm.push(self.to_foorth_n); })
18
+
19
+ # Some conversion words.
20
+ # [a] .to_n! [Number]
21
+ Object.create_shared_method('.to_n!', TosSpec, [], &lambda {|vm|
22
+ if (result = self.to_foorth_n)
23
+ vm.push(result);
24
+ else
25
+ error "F40: Cannot convert a #{self.foorth_name} to a Numeric instance"
26
+ end
27
+ })
28
+
29
+ # [a] .to_f [Float or nil]
30
+ Object.create_shared_method('.to_f', TosSpec, [], &lambda {|vm|
31
+ begin
32
+ vm.push(Float(self))
33
+ rescue
34
+ vm.push(nil)
35
+ end
36
+ })
37
+
38
+ # [num_digits a_number] .round_to [a_float]
39
+ Numeric.create_shared_method('.round_to', TosSpec, [], &lambda {|vm|
40
+ value = Float.foorth_coerce(self)
41
+ digits = Integer.foorth_coerce(vm.pop)
42
+ vm.push(value.round(digits))
43
+ })
44
+
45
+ # [a] .to_f! [Float]
46
+ Object.create_shared_method('.to_f!', TosSpec, [],
47
+ &lambda {|vm| vm.push(Float.foorth_coerce(self)) })
48
+
49
+ # Some comparison words.
50
+ # [b,a] > if b > a then [true] else [false]
51
+ Numeric.create_shared_method('>', NosSpec, [], &lambda {|vm|
52
+ begin
53
+ vm.poke(self > self.foorth_coerce(vm.peek))
54
+ rescue
55
+ vm.data_stack.pop
56
+ raise
57
+ end
58
+ })
59
+
60
+ # [b,a] < if b < a then [true] else [false]
61
+ Numeric.create_shared_method('<', NosSpec, [], &lambda {|vm|
62
+ begin
63
+ vm.poke(self < self.foorth_coerce(vm.peek))
64
+ rescue
65
+ vm.data_stack.pop
66
+ raise
67
+ end
68
+ })
69
+
70
+ # [b,a] >= if b >= a then [true] else [false]
71
+ Numeric.create_shared_method('>=', NosSpec, [], &lambda {|vm|
72
+ begin
73
+ vm.poke(self >= self.foorth_coerce(vm.peek))
74
+ rescue
75
+ vm.data_stack.pop
76
+ raise
77
+ end
78
+ })
79
+
80
+ # [b,a] <= if b <= a then [true] else [false]
81
+ Numeric.create_shared_method('<=', NosSpec, [], &lambda {|vm|
82
+ begin
83
+ vm.poke(self <= self.foorth_coerce(vm.peek))
84
+ rescue
85
+ vm.data_stack.pop
86
+ raise
87
+ end
88
+ })
89
+
90
+ # [b,a] <=> if b <=> a then [true] else [false]
91
+ Numeric.create_shared_method('<=>', NosSpec, [], &lambda {|vm|
92
+ begin
93
+ vm.poke(self <=> self.foorth_coerce(vm.peek))
94
+ rescue
95
+ vm.data_stack.pop
96
+ raise
97
+ end
98
+ })
99
+
100
+ # Some comparison with zero words.
101
+ # [b,a] 0= if b == 0 then [true] else [false]
102
+ Numeric.create_shared_method('0=', TosSpec, [],
103
+ &lambda {|vm| vm.push(self.zero?); })
104
+
105
+ # [b,a] 0<> if b != 0 then [true] else [false]
106
+ Numeric.create_shared_method('0<>', TosSpec, [],
107
+ &lambda {|vm| vm.push(!self.zero?); })
108
+
109
+ # [b,a] 0> if b > 0 then [true] else [false]
110
+ Numeric.create_shared_method('0>', TosSpec, [],
111
+ &lambda {|vm| vm.push(self > 0); })
112
+
113
+ # [b,a] 0< if b < 0 then [true] else [false]
114
+ Numeric.create_shared_method('0<', TosSpec, [],
115
+ &lambda {|vm| vm.push(self < 0); })
116
+
117
+ # [b,a] 0>= if b >= 0 then [true] else [false]
118
+ Numeric.create_shared_method('0>=', TosSpec, [],
119
+ &lambda {|vm| vm.push(self >= 0); })
120
+
121
+ # [b,a] 0<= if b <= 0 then [true] else [false]
122
+ Numeric.create_shared_method('0<=', TosSpec, [],
123
+ &lambda {|vm| vm.push(self <= 0); })
124
+
125
+ # [b] 0<=> b < 0 [-1], b = 0 [0], b > 0 [1]
126
+ Numeric.create_shared_method('0<=>', TosSpec, [],
127
+ &lambda {|vm| vm.push(self <=> 0); })
128
+
129
+ # Some stack arithmetic words.
130
+ # [b,a] + [b+a]
131
+ Numeric.create_shared_method('+', NosSpec, [], &lambda {|vm|
132
+ begin
133
+ vm.poke(self + self.foorth_coerce(vm.peek))
134
+ rescue
135
+ vm.data_stack.pop
136
+ raise
137
+ end
138
+ })
139
+
140
+ # [b,a] - [b-a]
141
+ Numeric.create_shared_method('-', NosSpec, [], &lambda {|vm|
142
+ begin
143
+ vm.poke(self - self.foorth_coerce(vm.peek))
144
+ rescue
145
+ vm.data_stack.pop
146
+ raise
147
+ end
148
+ })
149
+
150
+ # [b,a] * [b*a]
151
+ Numeric.create_shared_method('*', NosSpec, [], &lambda {|vm|
152
+ begin
153
+ vm.poke(self * self.foorth_coerce(vm.peek))
154
+ rescue
155
+ vm.data_stack.pop
156
+ raise
157
+ end
158
+ })
159
+
160
+ # [b,a] ** [b**a]
161
+ Numeric.create_shared_method('**', NosSpec, [], &lambda {|vm|
162
+ begin
163
+ vm.poke(self ** Float.foorth_coerce(vm.peek))
164
+ rescue
165
+ vm.data_stack.pop
166
+ raise
167
+ end
168
+ })
169
+
170
+ # [b,a] / [b/a]
171
+ Numeric.create_shared_method('/', NosSpec, [], &lambda {|vm|
172
+ begin
173
+ vm.poke(self / self.foorth_coerce(vm.peek))
174
+ rescue
175
+ vm.data_stack.pop
176
+ raise
177
+ end
178
+ })
179
+
180
+ # [b,a] mod [b%a]
181
+ Numeric.create_shared_method('mod', NosSpec, [], &lambda {|vm|
182
+ begin
183
+ vm.poke(self % self.foorth_coerce(vm.peek))
184
+ rescue
185
+ vm.data_stack.pop
186
+ raise
187
+ end
188
+ })
189
+
190
+ # [a] neg [-a]
191
+ Numeric.create_shared_method('neg', TosSpec, [],
192
+ &lambda {|vm| vm.push(-self); })
193
+
194
+ # [a] .1/x [-a]
195
+ Numeric.create_shared_method('.1/x', TosSpec, [],
196
+ &lambda {|vm| vm.push(1/self); })
197
+
198
+ # [a] .abs [|a|]
199
+ Numeric.create_shared_method('.abs', TosSpec, [],
200
+ &lambda {|vm| vm.push(self.abs); })
201
+
202
+ # [a] 1+ [a+1]
203
+ Numeric.create_shared_method('1+', TosSpec, [],
204
+ &lambda {|vm| vm.push(self+1); })
205
+
206
+ # [a] 1- [a-1]
207
+ Numeric.create_shared_method('1-', TosSpec, [],
208
+ &lambda {|vm| vm.push(self-1); })
209
+
210
+ # [a] 2+ [a+2]
211
+ Numeric.create_shared_method('2+', TosSpec, [],
212
+ &lambda {|vm| vm.push(self+2); })
213
+
214
+ # [a] 2- [a-2]
215
+ Numeric.create_shared_method('2-', TosSpec, [],
216
+ &lambda {|vm| vm.push(self-2); })
217
+
218
+ # [a] 2* [a*2]
219
+ Numeric.create_shared_method('2*', TosSpec, [],
220
+ &lambda {|vm| vm.push(self*2); })
221
+
222
+ # [a] 2/ [a/2]
223
+ Numeric.create_shared_method('2/', TosSpec, [],
224
+ &lambda {|vm| vm.push(self/2); })
225
+
226
+ # [a] .ceil [a']; where a' is the closest integer >= a
227
+ Numeric.create_shared_method('.ceil', TosSpec, [],
228
+ &lambda {|vm| vm.push(self.ceil); })
229
+
230
+ # [a] .floor [a']; where a' is the closest integer <= a
231
+ Numeric.create_shared_method('.floor', TosSpec, [],
232
+ &lambda {|vm| vm.push(self.floor); })
233
+
234
+ # [a] .round [a']; where a' is the integer closest to a
235
+ Numeric.create_shared_method('.round', TosSpec, [],
236
+ &lambda {|vm| vm.push(self.round); })
237
+
238
+
239
+ #Advanced math stuff!
240
+ # [] pi [3.141592653589793]
241
+ VirtualMachine.create_shared_method('pi', MacroSpec, [:macro, "vm.push(Math::PI)"])
242
+
243
+ # [] e [2.718281828459045]
244
+ VirtualMachine.create_shared_method('e', MacroSpec, [:macro, "vm.push(Math::E)"])
245
+
246
+ #The number of degrees in one radian.
247
+ DegreesPerRadian = 180.0/Math::PI
248
+
249
+ # [] dpr [2.718281828459045]
250
+ VirtualMachine.create_shared_method('dpr', MacroSpec,
251
+ [:macro, "vm.push(DegreesPerRadian)"])
252
+
253
+ # [degrees] .d2r [radians]
254
+ Numeric.create_shared_method('.d2r', TosSpec, [],
255
+ &lambda {|vm| vm.push(Float.foorth_coerce(self)/DegreesPerRadian); })
256
+
257
+ # [radians] .r2d [degrees]
258
+ Numeric.create_shared_method('.r2d', TosSpec, [],
259
+ &lambda {|vm| vm.push(Float.foorth_coerce(self)*DegreesPerRadian); })
260
+
261
+ # [radians] .cos [cos(radians)]
262
+ Numeric.create_shared_method('.cos', TosSpec, [],
263
+ &lambda {|vm| vm.push(Math::cos(Float.foorth_coerce(self))); })
264
+
265
+ # [radians] .sin [sin(radians)]
266
+ Numeric.create_shared_method('.sin', TosSpec, [],
267
+ &lambda {|vm| vm.push(Math::sin(Float.foorth_coerce(self))); })
268
+
269
+ # [radians] .tan [tan(radians)]
270
+ Numeric.create_shared_method('.tan', TosSpec, [],
271
+ &lambda {|vm| vm.push(Math::tan(Float.foorth_coerce(self))); })
272
+
273
+ # [cos(radians)] .acos [radians]
274
+ Numeric.create_shared_method('.acos', TosSpec, [],
275
+ &lambda {|vm| vm.push(Math::acos(Float.foorth_coerce(self))); })
276
+
277
+ # [sin(radians)] .asin [radians]
278
+ Numeric.create_shared_method('.asin', TosSpec, [],
279
+ &lambda {|vm| vm.push(Math::asin(Float.foorth_coerce(self))); })
280
+
281
+ # [y/x] .atan [radians]
282
+ Numeric.create_shared_method('.atan', TosSpec, [],
283
+ &lambda {|vm| vm.push(Math::atan(Float.foorth_coerce(self))); })
284
+
285
+ # [y x] .atan2 [radians]
286
+ Numeric.create_shared_method('.atan2', TosSpec, [],
287
+ &lambda {|vm| vm.poke(Math::atan2(Float.foorth_coerce(vm.peek), Float.foorth_coerce(self))); })
288
+
289
+ # [radians] .cosh [cosh(radians)]
290
+ Numeric.create_shared_method('.cosh', TosSpec, [],
291
+ &lambda {|vm| vm.push(Math::cosh(Float.foorth_coerce(self))); })
292
+
293
+ # [radians] .sinh [sinh(radians)]
294
+ Numeric.create_shared_method('.sinh', TosSpec, [],
295
+ &lambda {|vm| vm.push(Math::sinh(Float.foorth_coerce(self))); })
296
+
297
+ # [radians] .tanh [tanh(radians)]
298
+ Numeric.create_shared_method('.tanh', TosSpec, [],
299
+ &lambda {|vm| vm.push(Math::tanh(Float.foorth_coerce(self))); })
300
+
301
+ # [cosh(radians)] .acosh [radians]
302
+ Numeric.create_shared_method('.acosh', TosSpec, [],
303
+ &lambda {|vm| vm.push(Math::acosh(Float.foorth_coerce(self))); })
304
+
305
+ # [sinh(radians)] .asinh [radians]
306
+ Numeric.create_shared_method('.asinh', TosSpec, [],
307
+ &lambda {|vm| vm.push(Math::asinh(Float.foorth_coerce(self))); })
308
+
309
+ # [y/x] .atanh [radians]
310
+ Numeric.create_shared_method('.atanh', TosSpec, [],
311
+ &lambda {|vm| vm.push(Math::atanh(Float.foorth_coerce(self))); })
312
+
313
+ # [x] .e** [e**x]
314
+ Numeric.create_shared_method('.e**', TosSpec, [],
315
+ &lambda {|vm| vm.push(Math::exp(self)); })
316
+ Complex.create_shared_method('.e**', TosSpec, [],
317
+ &lambda {|vm| vm.push(Math::E ** self); })
318
+
319
+ # [x] .ln [ln(x)]
320
+ Numeric.create_shared_method('.ln', TosSpec, [],
321
+ &lambda {|vm| vm.push(Math::log(Float.foorth_coerce(self))); })
322
+
323
+ # [x] .10** [10**x]
324
+ Numeric.create_shared_method('.10**', TosSpec, [],
325
+ &lambda {|vm| vm.push(10.0**self); })
326
+
327
+ # [x] .log10 [log10(x)]
328
+ Numeric.create_shared_method('.log10', TosSpec, [],
329
+ &lambda {|vm| vm.push(Math::log10(Float.foorth_coerce(self))); })
330
+
331
+ # [x] .2** [2**x]
332
+ Numeric.create_shared_method('.2**', TosSpec, [],
333
+ &lambda {|vm| vm.push(2.0**self); })
334
+
335
+ # [x] .log2 [log2(x)]
336
+ Numeric.create_shared_method('.log2', TosSpec, [],
337
+ &lambda {|vm| vm.push(Math::log2(Float.foorth_coerce(self))); })
338
+
339
+ # [x] .sqr [square(x)]
340
+ Numeric.create_shared_method('.sqr', TosSpec, [],
341
+ &lambda {|vm| vm.push(self*self); })
342
+
343
+ # [x] .sqrt [square root(x)]
344
+ Numeric.create_shared_method('.sqrt', TosSpec, [],
345
+ &lambda {|vm| vm.push(Math::sqrt(self)); })
346
+ Complex.create_shared_method('.sqrt', TosSpec, [],
347
+ &lambda {|vm| vm.push(self ** 0.5); })
348
+
349
+ # [x] .cube [cube(x)]
350
+ Numeric.create_shared_method('.cube', TosSpec, [],
351
+ &lambda {|vm| vm.push(self*self*self); })
352
+
353
+ # [x] .cbrt [cube root(x)]
354
+ Numeric.create_shared_method('.cbrt', TosSpec, [],
355
+ &lambda {|vm| vm.push(Math::cbrt(self)); })
356
+ Complex.create_shared_method('.cbrt', TosSpec, [],
357
+ &lambda {|vm| vm.push(self ** Rational(1,3)); })
358
+
359
+ # [x y] .hypot [sqrt(x**2 + y**2)]
360
+ Numeric.create_shared_method('.hypot', TosSpec, [], &lambda {|vm|
361
+ vm.poke(Math::hypot(Float.foorth_coerce(self), Float.foorth_coerce(vm.peek)));
362
+ })
363
+
364
+ # [r t] .p2c [x y]; Polar to Cartesian.
365
+ Numeric.create_shared_method('.p2c', TosSpec, [], &lambda {|vm|
366
+ radius = Float.foorth_coerce(vm.pop)
367
+ theta = Float.foorth_coerce(self)
368
+ vm.push(radius * Math::cos(theta))
369
+ vm.push(radius * Math::sin(theta))
370
+ })
371
+
372
+ # [x y] .c2p [r t]; Cartesian to Polar.
373
+ Numeric.create_shared_method('.c2p', TosSpec, [], &lambda {|vm|
374
+ real = Float.foorth_coerce(vm.pop)
375
+ imag = Float.foorth_coerce(self)
376
+ vm.push(Math::hypot(real,imag))
377
+ vm.push(Math::atan2(imag,real))
378
+ })
379
+
380
+ end