1# Copyright 2001, 2002 Dave Abrahams 2# Copyright 2002, 2003 Vladimir Prus 3# Distributed under the Boost Software License, Version 1.0. 4# (See accompanying file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt) 5 6import errors ; 7 8 9rule trim-leading-zeroes ( value ) 10{ 11 return [ CALC $(value) + 0 ] ; 12} 13 14 15rule check ( numbers * ) 16{ 17 for local n in $(numbers) 18 { 19 switch $(n) 20 { 21 case *[^0-9]* : 22 errors.error $(n) "in" $(numbers) : is not a number ; 23 } 24 } 25} 26 27 28rule increment ( number ) 29{ 30 return [ CALC $(number) + 1 ] ; 31} 32 33 34rule decrement ( number ) 35{ 36 return [ CALC $(number) - 1 ] ; 37} 38 39 40rule range ( start finish ? : step ? ) 41{ 42 if ! $(finish) 43 { 44 finish = $(start) ; 45 start = 1 ; 46 } 47 step ?= 1 ; 48 49 check $(start) $(finish) $(step) ; 50 51 if $(finish) != 0 52 { 53 local result ; 54 while [ less $(start) $(finish) ] || $(start) = $(finish) 55 { 56 result += $(start) ; 57 start = [ CALC $(start) + $(step) ] ; 58 } 59 return $(result) ; 60 } 61} 62 63 64rule less ( n1 n2 ) 65{ 66 switch [ CALC $(n2) - $(n1) ] 67 { 68 case [1-9]* : return true ; 69 } 70} 71 72 73rule log10 ( number ) 74{ 75 switch $(number) 76 { 77 case *[^0-9]* : errors.error $(number) is not a number ; 78 case 0 : errors.error can't take log of zero ; 79 case [1-9] : return 0 ; 80 case [1-9]? : return 1 ; 81 case [1-9]?? : return 2 ; 82 case [1-9]??? : return 3 ; 83 case [1-9]???? : return 4 ; 84 case [1-9]????? : return 5 ; 85 case [1-9]?????? : return 6 ; 86 case [1-9]??????? : return 7 ; 87 case [1-9]???????? : return 8 ; 88 case [1-9]????????? : return 9 ; 89 case * : 90 { 91 import sequence ; 92 import string ; 93 local chars = [ string.chars $(number) ] ; 94 while $(chars[1]) = 0 95 { 96 chars = $(chars[2-]) ; 97 } 98 if ! $(chars) 99 { 100 errors.error can't take log of zero ; 101 } 102 else 103 { 104 return [ decrement [ sequence.length $(chars) ] ] ; 105 } 106 } 107 } 108} 109 110 111rule __test__ ( ) 112{ 113 import assert ; 114 115 assert.result 1 : increment 0 ; 116 assert.result 2 : increment 1 ; 117 assert.result 1 : decrement 2 ; 118 assert.result 0 : decrement 1 ; 119 assert.result 50 : increment 49 ; 120 assert.result 49 : decrement 50 ; 121 assert.result 99 : increment 98 ; 122 assert.result 99 : decrement 100 ; 123 assert.result 100 : increment 99 ; 124 assert.result 999 : decrement 1000 ; 125 assert.result 1000 : increment 999 ; 126 127 assert.result 1 2 3 : range 3 ; 128 assert.result 1 2 3 4 5 6 7 8 9 10 11 12 : range 12 ; 129 assert.result 3 4 5 6 7 8 9 10 11 : range 3 11 ; 130 assert.result : range 0 ; 131 assert.result 1 4 7 10 : range 10 : 3 ; 132 assert.result 2 4 6 8 10 : range 2 10 : 2 ; 133 assert.result 25 50 75 100 : range 25 100 : 25 ; 134 135 assert.result 0 : trim-leading-zeroes 0 ; 136 assert.result 1234 : trim-leading-zeroes 1234 ; 137 assert.result 123456 : trim-leading-zeroes 0000123456 ; 138 assert.result 1000123456 : trim-leading-zeroes 1000123456 ; 139 assert.result 10000 : trim-leading-zeroes 10000 ; 140 assert.result 10000 : trim-leading-zeroes 00010000 ; 141 142 assert.true less 1 2 ; 143 assert.true less 1 12 ; 144 assert.true less 1 21 ; 145 assert.true less 005 217 ; 146 assert.false less 0 0 ; 147 assert.false less 03 3 ; 148 assert.false less 3 03 ; 149 assert.true less 005 217 ; 150 assert.true less 0005 217 ; 151 assert.true less 5 00217 ; 152 153 # TEMPORARY disabled, because nested "try"/"catch" do not work and I do no 154 # have the time to fix that right now. 155 if $(0) 156 { 157 try ; 158 { 159 decrement 0 ; 160 } 161 catch can't decrement zero! ; 162 163 try ; 164 { 165 check foo ; 166 } 167 catch : not a number ; 168 169 try ; 170 { 171 increment foo ; 172 } 173 catch : not a number ; 174 175 try ; 176 { 177 log10 0 ; 178 } 179 catch can't take log of zero ; 180 181 try ; 182 { 183 log10 000 ; 184 } 185 catch can't take log of zero ; 186 187 } 188 189 assert.result 0 : log10 1 ; 190 assert.result 0 : log10 9 ; 191 assert.result 1 : log10 10 ; 192 assert.result 1 : log10 99 ; 193 assert.result 2 : log10 100 ; 194 assert.result 2 : log10 101 ; 195 assert.result 2 : log10 125 ; 196 assert.result 2 : log10 999 ; 197 assert.result 3 : log10 1000 ; 198 assert.result 10 : log10 12345678901 ; 199 200 for local x in [ range 75 110 : 5 ] 201 { 202 for local y in [ range $(x) 111 : 3 ] 203 { 204 if $(x) != $(y) 205 { 206 assert.true less $(x) $(y) ; 207 } 208 } 209 } 210 211 for local x in [ range 90 110 : 2 ] 212 { 213 for local y in [ range 80 $(x) : 4 ] 214 { 215 assert.false less $(x) $(y) ; 216 } 217 } 218} 219