1
1
function _precision (line)
2
2
m = match (r" ^precision:\s *(\d +)$" , line)
3
+ isnothing (m) && throw (ArgumentError (line))
3
4
return parse (Int, m[1 ])
4
5
end
5
6
6
7
function _rounding (line)
7
8
m = match (r" ^rounding:\s *(\w +)$" , line)
8
- return Symbol (m[1 ])
9
+ isnothing (m) && throw (ArgumentError (line))
10
+ r = m[1 ]
11
+ if r == " ceiling"
12
+ return " RoundUp"
13
+ elseif r == " down"
14
+ return " RoundToZero"
15
+ elseif r == " floor"
16
+ return " RoundDown"
17
+ elseif r == " half_even"
18
+ return " RoundNearest"
19
+ elseif r == " half_up"
20
+ return " RoundNearestTiesAway"
21
+ elseif r == " up"
22
+ return " RoundFromZero"
23
+ elseif r == " half_down"
24
+ return " RoundHalfDownUnsupported"
25
+ elseif r == " 05up"
26
+ return " Round05UpUnsupported"
27
+ else
28
+ throw (ArgumentError (r))
29
+ end
9
30
end
10
31
11
32
function _maxexponent (line)
12
- m = match (r" ^maxexponent:\s *(\d +)$" , line)
33
+ m = match (r" ^maxexponent:\s *\+ ?(\d +)$" , line)
34
+ isnothing (m) && throw (ArgumentError (line))
13
35
return parse (Int, m[1 ])
14
36
end
15
37
16
38
function _minexponent (line)
17
39
m = match (r" ^minexponent:\s *(-\d +)$" , line)
40
+ isnothing (m) && throw (ArgumentError (line))
18
41
return parse (Int, m[1 ])
19
42
end
20
43
21
44
function _test (line)
45
+ occursin (" ->" , line) || throw (ArgumentError (line))
22
46
lhs, rhs = split (line, " ->" )
23
47
id, operation, operands... = split (lhs)
24
48
result, conditions... = split (rhs)
@@ -31,47 +55,55 @@ function decimal(x)
31
55
return " dec\" $x \" "
32
56
end
33
57
34
- print_precision (io, p:: Int ) = println (io, " setprecision(Decimal, $p )" )
35
- print_maxexponent (io, e:: Int ) = println (io, " Decimals.CONTEXT.Emax = $e " )
36
- print_minexponent (io, e:: Int ) = println (io, " Decimals.CONTEXT.Emin = $e " )
37
- function print_rounding (io, r:: Symbol )
38
- modes = Dict (:ceiling => " RoundUp" ,
39
- :down => " RoundToZero" ,
40
- :floor => " RoundDown" ,
41
- :half_even => " RoundNearest" ,
42
- :half_up => " RoundNearestTiesAway" ,
43
- :up => " RoundFromZero" ,
44
- :half_down => " RoundHalfDownUnsupported" ,
45
- Symbol (" 05up" ) => " Round05UpUnsupported" )
46
- haskey (modes, r) || throw (ArgumentError (r))
47
- rmod = modes[r]
48
- println (io, " setrounding(Decimal, $rmod )" )
49
- end
50
-
51
58
function print_operation (io, operation, operands)
52
- if operation == " plus"
53
- print_plus (io, operands... )
54
- elseif operation == " minus"
55
- print_minus (io, operands... )
59
+ if operation == " abs"
60
+ print_abs (io, operands... )
61
+ elseif operation == " add"
62
+ print_add (io, operands... )
63
+ elseif operation == " apply"
64
+ print_apply (io, operands... )
56
65
elseif operation == " compare"
57
66
print_compare (io, operands... )
67
+ elseif operation == " divide"
68
+ print_divide (io, operands... )
69
+ elseif operation == " minus"
70
+ print_minus (io, operands... )
71
+ elseif operation == " multiply"
72
+ print_multiply (io, operands... )
73
+ elseif operation == " plus"
74
+ print_plus (io, operands... )
75
+ elseif operation == " reduce"
76
+ print_reduce (io, operands... )
77
+ elseif operation == " subtract"
78
+ print_subtract (io, operands... )
58
79
else
59
80
throw (ArgumentError (operation))
60
81
end
61
82
end
83
+ print_abs (io, x) = print (io, " abs(" , decimal (x), " )" )
84
+ print_add (io, x, y) = print (io, decimal (x), " + " , decimal (y))
85
+ print_apply (io, x) = print (io, decimal (x))
62
86
print_compare (io, x, y) = print (io, " cmp(" , decimal (x), " , " , decimal (y), " )" )
87
+ print_divide (io, x, y) = print (io, decimal (x), " / " , decimal (y))
63
88
print_minus (io, x) = print (io, " -(" , decimal (x), " )" )
89
+ print_multiply (io, x, y) = print (io, decimal (x), " * " , decimal (y))
64
90
print_plus (io, x) = print (io, " +(" , decimal (x), " )" )
91
+ print_reduce (io, x) = print (io, " reduce(" , decimal (x), " )" )
92
+ print_subtract (io, x, y) = print (io, decimal (x), " - " , decimal (y))
65
93
66
- function print_test (io, test)
94
+ function print_test (io, test, directives )
67
95
println (io, " # $(test. id) " )
68
96
97
+ names = sort! (collect (keys (directives)))
98
+ params = join ((" $k =$(directives[k]) " for k in names), " , " )
99
+ print (io, " @with_context ($params ) " )
100
+
69
101
if :overflow ∈ test. conditions
70
- print (io, " @test_throws OverflowError " )
102
+ print (io, " @test_throws OverflowError " )
71
103
print_operation (io, test. operation, test. operands)
72
104
println (io)
73
105
else
74
- print (io, " @test " )
106
+ print (io, " @test " )
75
107
print_operation (io, test. operation, test. operands)
76
108
print (io, " == " )
77
109
println (io, decimal (test. result))
@@ -83,34 +115,36 @@ function isspecial(value)
83
115
return occursin (r" (inf|nan|#)" , value)
84
116
end
85
117
86
- function translate (io, line)
87
- isempty (line) && return
88
- startswith (line, " --" ) && return
89
-
90
- line = lowercase (line)
91
-
92
- if startswith (line, " version:" )
93
- # ...
94
- elseif startswith (line, " extended:" )
95
- # ...
96
- elseif startswith (line, " clamp:" )
97
- # ...
98
- elseif startswith (line, " precision:" )
99
- precision = _precision (line)
100
- print_precision (io, precision)
101
- elseif startswith (line, " rounding:" )
102
- rounding = _rounding (line)
103
- print_rounding (io, rounding)
104
- elseif startswith (line, " maxexponent:" )
105
- maxexponent = _maxexponent (line)
106
- print_maxexponent (io, maxexponent)
107
- elseif startswith (line, " minexponent:" )
108
- minexponent = _minexponent (line)
109
- print_minexponent (io, minexponent)
110
- else
111
- test = _test (line)
112
- any (isspecial, test. operands) && return
113
- print_test (io, test)
118
+ function translate (io, dectest_path)
119
+ directives = Dict {String, Any} ()
120
+
121
+ for line in eachline (dectest_path)
122
+ line = strip (line)
123
+
124
+ isempty (line) && continue
125
+ startswith (line, " --" ) && continue
126
+
127
+ line = lowercase (line)
128
+
129
+ if startswith (line, " version:" )
130
+ # ...
131
+ elseif startswith (line, " extended:" )
132
+ # ...
133
+ elseif startswith (line, " clamp:" )
134
+ # ...
135
+ elseif startswith (line, " precision:" )
136
+ directives[" precision" ] = _precision (line)
137
+ elseif startswith (line, " rounding:" )
138
+ directives[" rounding" ] = _rounding (line)
139
+ elseif startswith (line, " maxexponent:" )
140
+ directives[" Emax" ] = _maxexponent (line)
141
+ elseif startswith (line, " minexponent:" )
142
+ directives[" Emin" ] = _minexponent (line)
143
+ else
144
+ test = _test (line)
145
+ any (isspecial, test. operands) && continue
146
+ print_test (io, test, directives)
147
+ end
114
148
end
115
149
end
116
150
@@ -120,13 +154,13 @@ function (@main)(args=ARGS)
120
154
open (output_path, " w" ) do io
121
155
println (io, """
122
156
using Decimals
157
+ using ScopedValues
123
158
using Test
159
+ using Decimals: @with_context
124
160
125
161
@testset \" $name \" begin""" )
126
162
127
- for line in eachline (dectest_path)
128
- translate (io, line)
129
- end
163
+ translate (io, dectest_path)
130
164
131
165
println (io, " end" )
132
166
end
0 commit comments