fOOrth 0.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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