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,114 @@
1
+ # coding: utf-8
2
+
3
+ #* library/duration/arithmetic.rb - Arithmetic operator support for durations.
4
+ module XfOOrth
5
+
6
+ #* library/duration/arithmetic.rb - Arithmetic operator support for durations.
7
+ class Duration
8
+
9
+ #Coerce the argument to match my type.
10
+ def foorth_coerce(arg)
11
+ @period.foorth_coerce(arg)
12
+ end
13
+
14
+ #Convert this duration to a rational number.
15
+ def to_r
16
+ @period
17
+ end
18
+
19
+ #Alias rationalize to the to_r method.
20
+ alias :rationalize :to_r
21
+
22
+ #Alias to_foorth_r to the to_r method.
23
+ alias :to_foorth_r :to_r
24
+
25
+ #Define equality for durations.
26
+ def eql?(other)
27
+ @period.eql?(other.to_foorth_r)
28
+ end
29
+
30
+ #Alias == to the eql? operator.
31
+ alias :== :eql?
32
+ end
33
+
34
+ #[a_duration numeric/duration] + [a_duration]
35
+ Duration.create_shared_method('+', NosSpec, [], &lambda {|vm|
36
+ begin
37
+ result = @period + @period.foorth_coerce(vm.peek)
38
+ vm.poke(Duration.new(result))
39
+ rescue
40
+ vm.data_stack.pop
41
+ raise
42
+ end
43
+ })
44
+
45
+ #[a_duration numeric/duration] - [a_duration]
46
+ Duration.create_shared_method('-', NosSpec, [], &lambda {|vm|
47
+ begin
48
+ result = @period - @period.foorth_coerce(vm.peek)
49
+ vm.poke(Duration.new(result))
50
+ rescue
51
+ vm.data_stack.pop
52
+ raise
53
+ end
54
+ })
55
+
56
+ #[a_duration numeric/duration] * [a_duration]
57
+ Duration.create_shared_method('*', NosSpec, [], &lambda {|vm|
58
+ begin
59
+ result = @period * @period.foorth_coerce(vm.peek)
60
+ vm.poke(Duration.new(result))
61
+ rescue
62
+ vm.data_stack.pop
63
+ raise
64
+ end
65
+ })
66
+
67
+ #[a_duration numeric/duration] / [a_duration]
68
+ Duration.create_shared_method('/', NosSpec, [], &lambda {|vm|
69
+ begin
70
+ result = @period / @period.foorth_coerce(vm.peek)
71
+ vm.poke(Duration.new(result))
72
+ rescue
73
+ vm.data_stack.pop
74
+ raise
75
+ end
76
+ })
77
+
78
+ # [a_duration] 1+ [a_duration+1]
79
+ Duration.create_shared_method('1+', TosSpec, [], &lambda {|vm|
80
+ result = @period + 1
81
+ vm.push(Duration.new(result))
82
+ })
83
+
84
+ # [a_duration] 1- [a_duration-1]
85
+ Duration.create_shared_method('1-', TosSpec, [], &lambda {|vm|
86
+ result = @period - 1
87
+ vm.push(Duration.new(result))
88
+ })
89
+
90
+ # [a_duration] 2+ [a_duration+2]
91
+ Duration.create_shared_method('2+', TosSpec, [], &lambda {|vm|
92
+ result = @period + 2
93
+ vm.push(Duration.new(result))
94
+ })
95
+
96
+ # [a_duration] 2- [a_duration-2]
97
+ Duration.create_shared_method('2-', TosSpec, [], &lambda {|vm|
98
+ result = @period - 2
99
+ vm.push(Duration.new(result))
100
+ })
101
+
102
+ # [a_duration] 2* [a_duration*2]
103
+ Duration.create_shared_method('2*', TosSpec, [], &lambda {|vm|
104
+ result = @period * 2
105
+ vm.push(Duration.new(result))
106
+ })
107
+
108
+ # [a_duration] 2/ [a_duration/2]
109
+ Duration.create_shared_method('2/', TosSpec, [], &lambda {|vm|
110
+ result = @period / 2
111
+ vm.push(Duration.new(result))
112
+ })
113
+
114
+ end
@@ -0,0 +1,152 @@
1
+ # coding: utf-8
2
+
3
+ #* library/duration/formatter.rb - Duration formatting support library.
4
+ module XfOOrth
5
+
6
+ #Formatter support for the \Duration class.
7
+ class Duration
8
+
9
+ #Extend this class with attr_formatter support.
10
+ extend FormatEngine::AttrFormatter
11
+
12
+ ##
13
+ #The specification of the formatter method of the \Duration class.
14
+ #<br>Year Formats:
15
+ #* %{?}{$}{w}y - Whole years.
16
+ #* %{?}{$}{w{.p}}Y - Total (with fractional) years.
17
+ #<br>Month Formats:
18
+ #* %{?}{$}{w}o - Whole months in the year.
19
+ #* %{?}{$}{w{.p}}O - Total (with fractional) months.
20
+ #<br>Day Formats:
21
+ #* %{?}{$}{w}d - Whole days in the month.
22
+ #* %{?}{$}{w{.p}}D - Total (with fractional) days.
23
+ #<br>Hour Formats:
24
+ #* %{?}{$}{w}h - Whole hours in the day.
25
+ #* %{?}{$}{w{.p}}H - Total (with fractional) hours.
26
+ #<br>Minute Formats:
27
+ #* %{?}{$}{w}m - Whole minutes in the hour.
28
+ #* %{?}{$}{w{.p}}M - Total (with fractional) minutes.
29
+ #<br>Second Formats:
30
+ #* %{?}{$}{w{.p}}s - Total (with fractional) seconds in the minute.
31
+ #* %{?}{$}{w{.p}}S - Total (with fractional) seconds.
32
+ #<br>Brief Summary Formats:
33
+ #* %{?}{$}{w{.p}}B - Total (with fractional) of the largest, non-zero time unit.
34
+ #<br>Raw Formats (in seconds and fractions):
35
+ #* %{w{.p}}f - Total seconds in floating point format.
36
+ #* %{w}r - Total seconds in rational format.
37
+ #<br>Where:
38
+ #* \? is an optional flag indicating that the data should be suppressed if absent.
39
+ #* \$ is an optional flag indication to retrieve the corresponding text label.
40
+ #* w is an optional field width parameter.
41
+ #* p is an optional precision parameter.
42
+
43
+ attr_formatter :strfmt,
44
+ {
45
+ :before => lambda do
46
+ tmp[:all] = arr = src.to_a
47
+ tmp[:year] = arr[0]; tmp[0] = src.as_years
48
+ tmp[:month] = arr[1]; tmp[1] = src.as_months
49
+ tmp[:day] = arr[2]; tmp[2] = src.as_days
50
+ tmp[:hour] = arr[3]; tmp[3] = src.as_hours
51
+ tmp[:min] = arr[4]; tmp[4] = src.as_minutes
52
+ tmp[:sec] = arr[5]; tmp[5] = src.as_seconds
53
+ end,
54
+
55
+ "%y" => lambda {cat "%#{fmt.parm_str}d" % tmp[:year]},
56
+ "%?y" => lambda {cat "%#{fmt.parm_str}d" % tmp[:year] if tmp[:year] >= 1},
57
+ "%Y" => lambda {cat "%#{fmt.parm_str}f" % tmp[0]},
58
+ "%?Y" => lambda {cat "%#{fmt.parm_str}f" % tmp[0] if tmp[0] > 0},
59
+
60
+ "%$y" => lambda {cat "%#{fmt.parm_str}s" % Duration.pick_label(0, tmp[:year])},
61
+ "%?$y"=> lambda {cat "%#{fmt.parm_str}s" % Duration.pick_label(0, tmp[:year]) if tmp[:year] >= 1},
62
+ "%$Y" => lambda {cat "%#{fmt.parm_str}s" % Duration.pick_label(0, tmp[0])},
63
+ "%?$Y"=> lambda {cat "%#{fmt.parm_str}s" % Duration.pick_label(0, tmp[0]) if tmp[0] > 0},
64
+
65
+ "%o" => lambda {cat "%#{fmt.parm_str}d" % tmp[:month]},
66
+ "%?o" => lambda {cat "%#{fmt.parm_str}d" % tmp[:month] if tmp[:month] >= 1},
67
+ "%O" => lambda {cat "%#{fmt.parm_str}f" % tmp[1]},
68
+ "%?O" => lambda {cat "%#{fmt.parm_str}f" % tmp[1] if tmp[1] > 0},
69
+
70
+ "%$o" => lambda {cat "%#{fmt.parm_str}s" % Duration.pick_label(1, tmp[:month])},
71
+ "%?$o"=> lambda {cat "%#{fmt.parm_str}s" % Duration.pick_label(1, tmp[:month]) if tmp[:month] >= 1},
72
+ "%$O" => lambda {cat "%#{fmt.parm_str}s" % Duration.pick_label(1, tmp[1])},
73
+ "%?$O"=> lambda {cat "%#{fmt.parm_str}s" % Duration.pick_label(1, tmp[1]) if tmp[1] > 0},
74
+
75
+ "%d" => lambda {cat "%#{fmt.parm_str}d" % tmp[:day]},
76
+ "%?d" => lambda {cat "%#{fmt.parm_str}d" % tmp[:day] if tmp[:day] >= 1},
77
+ "%D" => lambda {cat "%#{fmt.parm_str}f" % tmp[2]},
78
+ "%?D" => lambda {cat "%#{fmt.parm_str}f" % tmp[2] if tmp[2] > 0},
79
+
80
+ "%$d" => lambda {cat "%#{fmt.parm_str}s" % Duration.pick_label(2, tmp[:day])},
81
+ "%?$d"=> lambda {cat "%#{fmt.parm_str}s" % Duration.pick_label(2, tmp[:day]) if tmp[:day] >= 1},
82
+ "%$D" => lambda {cat "%#{fmt.parm_str}s" % Duration.pick_label(2, tmp[2])},
83
+ "%?$D"=> lambda {cat "%#{fmt.parm_str}s" % Duration.pick_label(2, tmp[2]) if tmp[2] > 0},
84
+
85
+ "%h" => lambda {cat "%#{fmt.parm_str}d" % tmp[:hour]},
86
+ "%?h" => lambda {cat "%#{fmt.parm_str}d" % tmp[:hour] if tmp[:hour] >= 1},
87
+ "%H" => lambda {cat "%#{fmt.parm_str}f" % tmp[3]},
88
+ "%?H" => lambda {cat "%#{fmt.parm_str}f" % tmp[3] if tmp[3] > 0},
89
+
90
+ "%$h" => lambda {cat "%#{fmt.parm_str}s" % Duration.pick_label(3, tmp[:hour])},
91
+ "%?$h"=> lambda {cat "%#{fmt.parm_str}s" % Duration.pick_label(3, tmp[:hour]) if tmp[:hour] >= 1},
92
+ "%$H" => lambda {cat "%#{fmt.parm_str}s" % Duration.pick_label(3, tmp[3])},
93
+ "%?$H"=> lambda {cat "%#{fmt.parm_str}s" % Duration.pick_label(3, tmp[3]) if tmp[3] > 0},
94
+
95
+ "%m" => lambda {cat "%#{fmt.parm_str}d" % tmp[:min]},
96
+ "%?m" => lambda {cat "%#{fmt.parm_str}d" % tmp[:min] if tmp[:min] >= 1},
97
+ "%M" => lambda {cat "%#{fmt.parm_str}f" % tmp[4]},
98
+ "%?M" => lambda {cat "%#{fmt.parm_str}f" % tmp[4] if tmp[4] > 0},
99
+
100
+ "%$m" => lambda {cat "%#{fmt.parm_str}s" % Duration.pick_label(4, tmp[:min])},
101
+ "%?$m"=> lambda {cat "%#{fmt.parm_str}s" % Duration.pick_label(4, tmp[:min]) if tmp[:min] >= 1},
102
+ "%$M" => lambda {cat "%#{fmt.parm_str}s" % Duration.pick_label(4, tmp[4])},
103
+ "%?$M"=> lambda {cat "%#{fmt.parm_str}s" % Duration.pick_label(4, tmp[4]) if tmp[4] > 0},
104
+
105
+ "%s" => lambda {cat "%#{fmt.parm_str}f" % tmp[:sec]},
106
+ "%?s" => lambda {cat "%#{fmt.parm_str}f" % tmp[:sec] if tmp[:sec] >= 1},
107
+ "%S" => lambda {cat "%#{fmt.parm_str}f" % tmp[5]},
108
+ "%?S" => lambda {cat "%#{fmt.parm_str}f" % tmp[5] if tmp[5] > 0},
109
+
110
+ "%$s" => lambda {cat "%#{fmt.parm_str}s" % Duration.pick_label(5, tmp[:sec])},
111
+ "%?$s"=> lambda {cat "%#{fmt.parm_str}s" % Duration.pick_label(5, tmp[:sec]) if tmp[:sec] >= 1},
112
+ "%$S" => lambda {cat "%#{fmt.parm_str}s" % Duration.pick_label(5, tmp[5])},
113
+ "%?$S"=> lambda {cat "%#{fmt.parm_str}s" % Duration.pick_label(5, tmp[5]) if tmp[5] > 0},
114
+
115
+ "%B" => lambda {cat "%#{fmt.parm_str}f" % tmp[src.largest_interval]},
116
+ "%?B" => lambda {cat "%#{fmt.parm_str}f" % tmp[src.largest_interval] if src.period > 0},
117
+
118
+ "%$B" => lambda do
119
+ index = src.largest_interval
120
+ cat "%#{fmt.parm_str}s" % Duration.pick_label(index, tmp[index])
121
+ end,
122
+ "%?$B" => lambda do
123
+ if src.period > 0
124
+ index = src.largest_interval
125
+ cat "%#{fmt.parm_str}s" % Duration.pick_label(index, tmp[index])
126
+ end
127
+ end,
128
+
129
+
130
+ "%f" => lambda {cat "%#{fmt.parm_str}f" % src.period.to_f},
131
+ "%r" => lambda {cat "%#{fmt.parm_str}s" % src.period.to_s}
132
+ }
133
+
134
+
135
+ end
136
+
137
+ format_action = lambda do |vm|
138
+ begin
139
+ vm.poke(self.strfmt(vm.peek))
140
+ rescue => err
141
+ vm.data_stack.pop
142
+ error "F40: Formating error: #{err.message}."
143
+ end
144
+ end
145
+
146
+ # [a_time a_string] format [a_string]
147
+ Duration.create_shared_method('format', NosSpec, [], &format_action)
148
+
149
+ # [a_time] f"string" [a_string]
150
+ Duration.create_shared_method('f"', NosSpec, [], &format_action)
151
+
152
+ end
@@ -0,0 +1,233 @@
1
+ # coding: utf-8
2
+
3
+ #* library/duration/intervals.rb - Duration intervals support library.
4
+ module XfOOrth
5
+
6
+ #Intervals support for the \Duration class.
7
+ class Duration
8
+
9
+ #Seconds in a second.
10
+ A_SECOND = Duration.new(1.to_r)
11
+
12
+ #Seconds in a minute.
13
+ A_MINUTE = Duration.new(60 * A_SECOND.to_r)
14
+
15
+ #Seconds in an hour.
16
+ AN_HOUR = Duration.new(60 * A_MINUTE.to_r)
17
+
18
+ #Seconds in a day.
19
+ A_DAY = Duration.new(24 * AN_HOUR.to_r)
20
+
21
+ #Seconds in a (average) month.
22
+ A_MONTH = Duration.new(Rational(365_2425, 120000) * A_DAY.to_r)
23
+
24
+ #Seconds in a (average) year.
25
+ A_YEAR = Duration.new(12 * A_MONTH.to_r)
26
+
27
+ #An array of interval values.
28
+ INTERVALS = [A_YEAR, A_MONTH, A_DAY, AN_HOUR, A_MINUTE, A_SECOND]
29
+
30
+ #An array of interval labels.
31
+ LABELS = ["years", "months", "days", "hours", "minutes", "seconds"]
32
+
33
+ #Pick the appropriate label
34
+ #<br>Endemic Code Smells
35
+ #* :reek:ControlParameter
36
+ def self.pick_label(index, qty=1)
37
+ result = LABELS[index]
38
+ result = result.chop if qty == 1
39
+ " " + result
40
+ end
41
+
42
+ #Find the largest interval for this duration
43
+ def largest_interval
44
+ (0..5).detect {|idx| INTERVALS[idx] <= period} || 5
45
+ end
46
+
47
+ #How many whole years in this duration?
48
+ def years
49
+ (@period/A_YEAR.to_r).to_i
50
+ end
51
+
52
+ #How many total years in this duration?
53
+ def as_years
54
+ (@period/A_YEAR.to_r).to_f
55
+ end
56
+
57
+
58
+ #How many months into the year in this duration?
59
+ def months
60
+ ((@period % A_YEAR.to_r)/A_MONTH.to_r).to_i
61
+ end
62
+
63
+ #How many total months in this duration?
64
+ def as_months
65
+ (@period/A_MONTH.to_r).to_f
66
+ end
67
+
68
+
69
+ #How many days into the month in this duration?
70
+ def days
71
+ ((@period % A_MONTH.to_r)/A_DAY.to_r).to_i
72
+ end
73
+
74
+ #How many total days in this duration?
75
+ def as_days
76
+ (@period/A_DAY.to_r).to_f
77
+ end
78
+
79
+
80
+ #How many hours into the day in this duration?
81
+ def hours
82
+ (((@period % A_MONTH.to_r) % A_DAY.to_r)/AN_HOUR.to_r).to_i
83
+ end
84
+
85
+ #How many total hours in this duration?
86
+ def as_hours
87
+ (@period/AN_HOUR.to_r).to_f
88
+ end
89
+
90
+
91
+ #How many minutes into the hour in this duration?
92
+ def minutes
93
+ (((@period % A_MONTH.to_r) % AN_HOUR.to_r)/A_MINUTE.to_r).to_i
94
+ end
95
+
96
+ #How many total minutes in this duration?
97
+ def as_minutes
98
+ (@period/A_MINUTE.to_r).to_f
99
+ end
100
+
101
+
102
+ #How many seconds into the minute in this duration?
103
+ def seconds
104
+ ((@period % A_MONTH.to_r) % A_MINUTE.to_f)
105
+ end
106
+
107
+ #How many total seconds in this duration?
108
+ def as_seconds
109
+ @period.to_f
110
+ end
111
+
112
+ end
113
+
114
+
115
+ #Methods to retrieve interval values from the Duration class.
116
+
117
+ #[Duration] .intervals [array]
118
+ Duration.create_exclusive_method('.intervals', TosSpec, [], &lambda {|vm|
119
+ vm.push(Duration::INTERVALS)
120
+ })
121
+
122
+ #[Duration] .labels [array]
123
+ Duration.create_exclusive_method('.labels', TosSpec, [], &lambda {|vm|
124
+ vm.push(Duration::LABELS)
125
+ })
126
+
127
+ #[] a_year [a_duration]
128
+ VirtualMachine.create_shared_method('a_year', VmSpec, [], &lambda {|vm|
129
+ vm.push(Duration::A_YEAR)
130
+ })
131
+
132
+ #[] a_month [a_duration]
133
+ VirtualMachine.create_shared_method('a_month', VmSpec, [], &lambda {|vm|
134
+ vm.push(Duration::A_MONTH)
135
+ })
136
+
137
+ #[] a_day [a_duration]
138
+ VirtualMachine.create_shared_method('a_day', VmSpec, [], &lambda {|vm|
139
+ vm.push(Duration::A_DAY)
140
+ })
141
+
142
+ #[] an_hour [a_duration]
143
+ VirtualMachine.create_shared_method('an_hour', VmSpec, [], &lambda {|vm|
144
+ vm.push(Duration::AN_HOUR)
145
+ })
146
+
147
+ #[] a_minute [a_duration]
148
+ VirtualMachine.create_shared_method('a_minute', VmSpec, [], &lambda {|vm|
149
+ vm.push(Duration::A_MINUTE)
150
+ })
151
+
152
+ #[] a_second [a_duration]
153
+ VirtualMachine.create_shared_method('a_second', VmSpec, [], &lambda {|vm|
154
+ vm.push(Duration::A_SECOND)
155
+ })
156
+
157
+
158
+ #Methods to deal with intervals.
159
+
160
+ #[a_duration] .largest_interval [an_index(0..5)]
161
+ Duration.create_shared_method('.largest_interval', TosSpec, [], &lambda {|vm|
162
+ vm.push(self.largest_interval)
163
+ })
164
+
165
+
166
+ #[a_duration] .years [an_integer]
167
+ Duration.create_shared_method('.years', TosSpec, [], &lambda {|vm|
168
+ vm.push(self.years)
169
+ })
170
+
171
+ #[a_duration] .as_years [a_float]
172
+ Duration.create_shared_method('.as_years', TosSpec, [], &lambda {|vm|
173
+ vm.push(self.as_years)
174
+ })
175
+
176
+
177
+ #[a_duration] .months [an_integer]
178
+ Duration.create_shared_method('.months', TosSpec, [], &lambda {|vm|
179
+ vm.push(self.months)
180
+ })
181
+
182
+ #[a_duration] .as_months [a_float]
183
+ Duration.create_shared_method('.as_months', TosSpec, [], &lambda {|vm|
184
+ vm.push(self.as_months)
185
+ })
186
+
187
+
188
+ #[a_duration] .days [an_integer]
189
+ Duration.create_shared_method('.days', TosSpec, [], &lambda {|vm|
190
+ vm.push(self.days)
191
+ })
192
+
193
+ #[a_duration] .as_days [a_float]
194
+ Duration.create_shared_method('.as_days', TosSpec, [], &lambda {|vm|
195
+ vm.push(self.as_days)
196
+ })
197
+
198
+
199
+ #[a_duration] .hours [an_integer]
200
+ Duration.create_shared_method('.hours', TosSpec, [], &lambda {|vm|
201
+ vm.push(self.hours)
202
+ })
203
+
204
+ #[a_duration] .as_hours [a_float]
205
+ Duration.create_shared_method('.as_hours', TosSpec, [], &lambda {|vm|
206
+ vm.push(self.as_hours)
207
+ })
208
+
209
+
210
+ #[a_duration] .minutes [an_integer]
211
+ Duration.create_shared_method('.minutes', TosSpec, [], &lambda {|vm|
212
+ vm.push(self.minutes)
213
+ })
214
+
215
+ #[a_duration] .as_minutes [a_float]
216
+ Duration.create_shared_method('.as_minutes', TosSpec, [], &lambda {|vm|
217
+ vm.push(self.as_minutes)
218
+ })
219
+
220
+
221
+ #[a_duration] .seconds [an_integer]
222
+ Duration.create_shared_method('.seconds', TosSpec, [], &lambda {|vm|
223
+ vm.push(self.seconds)
224
+ })
225
+
226
+ #[a_duration] .as_seconds [a_float]
227
+ Duration.create_shared_method('.as_seconds', TosSpec, [], &lambda {|vm|
228
+ vm.push(self.as_seconds)
229
+ })
230
+
231
+
232
+
233
+ end