dataprop UTF8_00 (i:int, c:int) =
| {b:hb00; i == 1} UTF8_00_1(i, b) of INPUT(i, b)
dataprop UTF8_C2 (i:int, c:int) =
| {b:hbC2; i == 1} UTF8_C2_1(i, b - 0xC0) of INPUT(i, b)
| {b:tb80; i == 2} UTF8_C2_2(i, added(c, b)) of (UTF8_C2(i-1, c), INPUT(i, b))
| {b:tb80; i == 2} UTF8_C2_2(i, added(c, b)) of (UTF8_C2(i-1, c), INPUT(i, b))
dataprop UTF8_E0 (i:int, c:int) =
| {b:hbE0; i == 1} UTF8_E0_1(i, b - 0xE0) of INPUT(i, b)
| {b:tbA0; i == 2} UTF8_E0_2(i, added(c, b)) of (UTF8_E0(i-1, c), INPUT(i, b))
| {b:tb80; i == 3} UTF8_E0_3(i, added(c, b)) of (UTF8_E0(i-1, c), INPUT(i, b))
dataprop UTF8_E1 (i:int, c:int) =
| {b:hbE1; i == 1} UTF8_E1_1(i, b - 0xE0) of INPUT(i, b)
| {b:tb80; i == 2} UTF8_E1_2(i, added(c, b)) of (UTF8_E1(i-1, c), INPUT(i, b))
| {b:tb80; i == 3} UTF8_E1_3(i, added(c, b)) of (UTF8_E1(i-1, c), INPUT(i, b))
/* more of the like */
#define NEXT(UTF8_XX) (UTF8_XX(i-1, c), INPUT(i, b))
dataprop UTF8_00 (i:int, c:int) =
| {b:hb00; i == 1} UTF8_00_1(i, b) of INPUT(i, b)
dataprop UTF8_C2 (i:int, c:int) =
| {b:hbC2; i == 1} UTF8_C2_1(i, b - 0xC0) of INPUT(i, b)
| {b:tb80; i == 2} UTF8_C2_2(i, added(c, b)) of NEXT(UTF8_C2)
| {b:tb80; i == 2} UTF8_C2_2(i, added(c, b)) of NEXT(UTF8_C2)
dataprop UTF8_E0 (i:int, c:int) =
| {b:hbE0; i == 1} UTF8_E0_1(i, b - 0xE0) of INPUT(i, b)
| {b:tbA0; i == 2} UTF8_E0_2(i, added(c, b)) of NEXT(UTF8_E0)
| {b:tb80; i == 3} UTF8_E0_3(i, added(c, b)) of NEXT(UTF8_E0)
dataprop UTF8_E1 (i:int, c:int) =
| {b:hbE1; i == 1} UTF8_E1_1(i, b - 0xE0) of INPUT(i, b)
| {b:tb80; i == 2} UTF8_E1_2(i, added(c, b)) of NEXT(UTF8_E1)
| {b:tb80; i == 3} UTF8_E1_3(i, added(c, b)) of NEXT(UTF8_E1)
/* more of the like */
#undef NEXT
...
As said above, I'm not used to defines/macro and had bad experiences with C macros, thus my question for comments
val a = (1)
#define FOO (
#define BAR )
val b = FOO 1 BAR
#define FOO 1
val a = FOO
val () =
let
val b = FOO
#define BAR 1
val c = BAR
in ()
end
val d = FOO
val e = BAR // It complains! That's pretty!
dataprop UTF8_C2 (i:int, c:int) =
| {b:hb_C2; i == 1} UTF8_C2_1(i, b - 0xC0) of HEAD
| {b:tb_80; i == 2} UTF8_C2_2(i, added(c, b)) of (UTF8_C2(i-1, c), DATA(i, b))
prfn utf8_c2_lower {c:int} (pf:UTF8_C2(2, c)): [c >= 128] void =
case+ pf of
| UTF8_C2_2(pf1, pf2) =>
let (* Pending *)
in (* Pending *)
end
dataprop UTF8_C2 (i:int, c:int) =
| {b:hb_C2; i == 1} UTF8_C2_1(i, b - 0xC0) of HEAD
| {b:tb_80; i == 2} UTF8_C2_2(i, added(c, b)) of TAIL(UTF8_C2)prfn utf8_c2_lower {c:int} (pf:UTF8_C2(2, c)): [c >= 128] void =
case+ pf of
| UTF8_C2_2(pf1, pf2) =>
let (* Pending *)
in (* Pending *)
end
Yes, the behavior is expected.
If macro TAIL is used, then UTF8_C2_2 is a unary constructor
taking only one argument; the argument is a pair of proofs:
| UTF8_C2_2 (pf12) => ... // pf12.0 for pf1 and pf12.1 for pf2
Or you can write
| UTF8_C2_2 (@(pf1, pf2)) => ...
You may be able to write
| UTF8_C2_2((pf1, pf2)) => ... // I am not sure about this one.
Yes, the behavior is expected.
If macro TAIL is used, then UTF8_C2_2 is a unary constructor
taking only one argument; the argument is a pair of proofs:| UTF8_C2_2 (pf12) => ... // pf12.0 for pf1 and pf12.1 for pf2
Or you can write
|UTF8_C2_2 (@(pf1, pf2)) => ...
You may be able to write| UTF8_C2_2((pf1, pf2)) => ... // I am not sure about this one.
These additional requirements on writing, are to be balanced with the benefits of using #define.