| 1 | (******************************************************************************* |
|---|
| 2 | Copyright 2008 Sun Microsystems, Inc., |
|---|
| 3 | 4150 Network Circle, Santa Clara, California 95054, U.S.A. |
|---|
| 4 | All rights reserved. |
|---|
| 5 | |
|---|
| 6 | U.S. Government Rights - Commercial software. |
|---|
| 7 | Government users are subject to the Sun Microsystems, Inc. standard |
|---|
| 8 | license agreement and applicable provisions of the FAR and its supplements. |
|---|
| 9 | |
|---|
| 10 | Use is subject to license terms. |
|---|
| 11 | |
|---|
| 12 | This distribution may include materials developed by third parties. |
|---|
| 13 | |
|---|
| 14 | Sun, Sun Microsystems, the Sun logo and Java are trademarks or registered |
|---|
| 15 | trademarks of Sun Microsystems, Inc. in the U.S. and other countries. |
|---|
| 16 | ******************************************************************************) |
|---|
| 17 | |
|---|
| 18 | component NatReflect |
|---|
| 19 | export NatReflect |
|---|
| 20 | |
|---|
| 21 | (** Reflection for run-time integers into compile-time nat parameters. |
|---|
| 22 | * |
|---|
| 23 | * Basically you can call the function reflect(n) and it will return |
|---|
| 24 | * an instance of NatParam. But every instance of NatParam is an |
|---|
| 25 | * object N[\n\], so we can write a function which takes N[\n\] and |
|---|
| 26 | * pass it a NatParam; within that function n becomes a static nat |
|---|
| 27 | * parameter. |
|---|
| 28 | *) |
|---|
| 29 | trait NatParam |
|---|
| 30 | (* comprises { N[\n\] } where [\ nat n \] *) |
|---|
| 31 | getter toZZ() : ZZ32 |
|---|
| 32 | end |
|---|
| 33 | |
|---|
| 34 | value object N[\nat n\] extends { NatParam } |
|---|
| 35 | getter toZZ() = n |
|---|
| 36 | getter asString() = n.asString |
|---|
| 37 | end |
|---|
| 38 | |
|---|
| 39 | (* Inner loop of reflect, hoisted to top level because of incomplete |
|---|
| 40 | * implementation of generic local functions. This basically |
|---|
| 41 | * decomposes the argument x into binary digits, and does the same |
|---|
| 42 | * operations on the static parameter r as it does so. |
|---|
| 43 | * |
|---|
| 44 | * Really this just proves that it can be done without extending the |
|---|
| 45 | * language. Having proven that, we ought to build it in and document |
|---|
| 46 | * it in the spec for clarity and sanity's sake. |
|---|
| 47 | *) |
|---|
| 48 | __refl'[\nat r, nat b\](x:ZZ32):NatParam = |
|---|
| 49 | if x=0 then N[\r\] |
|---|
| 50 | elif (x REM (b+b)) = 0 then |
|---|
| 51 | __refl'[\r, b+b\](x) |
|---|
| 52 | else |
|---|
| 53 | __refl'[\r+b, b+b\](x-b) |
|---|
| 54 | end |
|---|
| 55 | |
|---|
| 56 | (* Actually convert a ZZ32 into a NatParam. *) |
|---|
| 57 | reflect(z:ZZ32):NatParam = do |
|---|
| 58 | if z < 0 then |
|---|
| 59 | fail("reflect(" z "): negative argument") |
|---|
| 60 | else |
|---|
| 61 | __refl'[\0,1\](z) |
|---|
| 62 | end |
|---|
| 63 | end |
|---|
| 64 | |
|---|
| 65 | end |
|---|