Commit 155d0e52 authored by Giuseppe Castagna's avatar Giuseppe Castagna
Browse files

Merge branch 'master' of https://git.cduce.org/cduce

parents b5cae60a 6d5a5fb7
......@@ -370,8 +370,8 @@ let rec collect_funs accu = function
| rest -> (List.rev accu,rest)
let rec collect_types accu = function
| { descr = Ast.TypeDecl ((loc,x),t) } :: rest ->
collect_types ((loc,x,t) :: accu) rest
| { descr = Ast.TypeDecl (x,pl,t) } :: rest ->
collect_types ((x,pl,t) :: accu) rest
| rest -> (accu,rest)
let rec phrases ~run ~show ~directive =
......@@ -380,7 +380,7 @@ let rec phrases ~run ~show ~directive =
| { descr = Ast.FunDecl _ } :: _ ->
let (funs,rest) = collect_funs [] phs in
loop (let_funs ~run ~show accu funs) rest
| { descr = Ast.TypeDecl (_,_) } :: _ ->
| { descr = Ast.TypeDecl (_,_,_) } :: _ ->
let (typs,rest) = collect_types [] phs in
loop (type_defs accu typs) rest
| { descr = Ast.SchemaDecl (name, uri); loc = loc } :: rest ->
......
open Cduce_loc
open Ident
exception InconsistentCrc of U.t
exception InvalidObject of string
exception CannotOpen of string
......@@ -23,13 +22,11 @@ type t = {
mutable exts: Value.t array;
mutable depends: (U.t * string) list;
mutable status: [ `Evaluating | `Unevaluated | `Evaluated ];
}
let digest c = match c.digest with None -> assert false | Some x -> x
module Tbl = Hashtbl.Make(U)
let tbl = Tbl.create 64
......@@ -117,7 +114,6 @@ let set_hash c =
Compunit.set_hash c.descr (succ max_rank) h
(* This invalidates all hash tables on types ! *)
let compile_save verbose name src out =
protect_op "Save compilation unit";
......
......@@ -5,11 +5,14 @@ open Ident
type ns_expr = [ `Uri of Ns.Uri.t | `Path of U.t list ]
(* located ident *)
type lident = (Cduce_loc.loc * U.t)
type pprog = pmodule_item list
and pmodule_item = pmodule_item' located
and pmodule_item' =
| TypeDecl of (Cduce_loc.loc * U.t) * ppat
| TypeDecl of (lident * U.t list * ppat)
| SchemaDecl of U.t * string
| LetDecl of ppat * pexpr
| FunDecl of pexpr
......@@ -86,17 +89,9 @@ and pexpr =
and label = U.t
and abstr = {
fun_name : (Cduce_loc.loc * U.t) option;
fun_name : lident option;
fun_iface : (ppat * ppat) list;
fun_body : branches
(* add deco : (sigma) symbolic representation of set type substitutions *)
(* plus a flag that is true if interesection of the free varbialbes of S that are not intruduced
* by the lambda astractions are domain of sigma.
* if oldvar(S) ^ dom(sigma) = empty then s < t else s[eval(sigma, env)] < t
* (biginter_{sigma_i \in eval} s (sigma_i) ) < t
*
* see Evaluation, section 5.3 Article part 1
* *)
}
and branches = (ppat * pexpr) list
......@@ -105,10 +100,10 @@ and branches = (ppat * pexpr) list
and ppat = ppat' located
and ppat' =
| PatVar of U.t list
| PatVar of (U.t list * ppat list)
| Cst of pexpr
| NsT of U.t
| Recurs of ppat * (Cduce_loc.loc * U.t * ppat) list
| Recurs of ppat * (lident * U.t list * ppat) list
| Internal of Types.descr
| Or of ppat * ppat
| And of ppat * ppat
......@@ -131,8 +126,7 @@ and regexp =
| Alt of regexp * regexp
| Star of regexp
| WeakStar of regexp
| SeqCapture of Cduce_loc.loc * U.t * regexp
| SeqCapture of lident * regexp
let pat_true = mknoloc (Internal Builtin_defs.true_type)
let pat_false = mknoloc (Internal Builtin_defs.false_type)
......
......@@ -12,7 +12,6 @@ let () = Grammar.error_verbose := true
let tloc (i,j) = (i,j)
let nopos = (-1,-1)
let mk loc x = Cduce_loc.mk_located (tloc loc) x
exception Error of string
......@@ -59,7 +58,6 @@ let rec tuple = function
let tuple_queue =
List.fold_right (fun x q -> Pair (x, q))
let char = mknoloc (Internal (Types.char Chars.any))
let string_regexp = Star (Elem char)
......@@ -71,7 +69,6 @@ let seq_of_string s =
in
aux (Encodings.Utf8.start_index s) (Encodings.Utf8.end_index s)
let parse_char loc s =
match seq_of_string s with
| [ c ] -> c
......@@ -109,7 +106,6 @@ let is_capture =
| _ -> raise Stream.Failure
)
let if_then_else cond e1 e2 =
Match (cond, [(mk (0,0) (Cst (Atom (ident "true")))),e1;
(mk (0,0) (Cst (Atom (ident "false")))),e2])
......@@ -144,7 +140,10 @@ EXTEND Gram
[ mk _loc (LetDecl (p,e)) ]
| (_,p,e1) = let_binding; "in"; e2 = expr LEVEL "top"->
[ mk _loc (EvalStatement (exp _loc (let_in e1 p e2))) ]
| "type"; x = located_ident; "="; t = pat -> [ mk _loc (TypeDecl (x,t)) ]
| "type"; x = PTYPE; pargs = LIST1 [ x = PVAR -> ident x ] SEP ","; ")"; "="; t = pat ->
[ mk _loc (TypeDecl ((lop _loc,ident x),pargs,t)) ]
| "type"; x = located_ident; "="; t = pat ->
[ mk _loc (TypeDecl (x,[],t)) ]
| "using"; name = IDENT; "="; cu = [ x = IDENT -> x | x = STRING -> x ] ->
[ mk _loc (Using (U.mk name, U.mk cu)) ]
| "open"; ids = LIST1 ident_or_keyword SEP "." ->
......@@ -280,44 +279,36 @@ EXTEND Gram
exp _loc (Ref (e,p))
| "not"; e = expr -> exp _loc (logical_not e)
]
|
[ e1 = expr; ":="; e2 = expr -> exp _loc (set_ref e1 e2)
]
|
[ e1 = expr; op = ["=" | "<=" | "<<" | ">>" | ">=" ]; e2 = expr ->
| [ e1 = expr; ":="; e2 = expr -> exp _loc (set_ref e1 e2) ]
| [ e1 = expr; op = ["=" | "<=" | "<<" | ">>" | ">=" ]; e2 = expr ->
let op = match op with
| "<<" -> "<"
| ">>" -> ">"
| s -> s in
| s -> s
in
apply_op2 _loc op e1 e2
]
|
[ e1 = expr; op = ["+" | "-" | "@" ]; e2 = expr -> apply_op2 _loc op e1 e2
| [ e1 = expr; op = ["+" | "-" | "@" ]; e2 = expr -> apply_op2 _loc op e1 e2
| e1 = expr; ["||" | "or"]; e2 = expr -> exp _loc (logical_or e1 e2)
| e = expr; "\\"; l = ident_or_keyword ->
exp _loc (RemoveField (e, label l))
]
|
[ e1 = expr; op = ["*"]; e2 = expr -> apply_op2 _loc op e1 e2
| [ e1 = expr; op = ["*"]; e2 = expr -> apply_op2 _loc op e1 e2
| e1 = expr; "&&"; e2 = expr -> exp _loc (logical_and e1 e2)
| e = expr; op = "/"; p = pat LEVEL "simple" ->
(* transform e with <(Atom)>[($$$::t|_)*] -> [$$$] *)
let tag = mk _loc (Internal (Types.atom Atoms.any)) in
let att = mk _loc (Internal Types.Record.any) in
let any = mk _loc (Internal Types.any) in
let re = Star(Alt(SeqCapture(noloc,id_dummy,Elem p), Elem any)) in
let re = Star(Alt(SeqCapture((noloc,id_dummy),Elem p), Elem any)) in
let ct = mk _loc (Regexp re) in
let p = mk _loc (XmlT (tag, multi_prod _loc [att;ct])) in
let p = mk _loc (XmlT (tag, multi_prod _loc [att;ct])) in
exp _loc (Transform (e,[p, Var id_dummy]))
| e = expr; "/@"; a = ident_or_keyword ->
(* transform e with <(Atom) {a=$$$}>_ -> [$$$] *)
let tag = mk _loc (Internal (Types.atom Atoms.any)) in
let any = mk _loc (Internal Types.any) in
let att = mk _loc (Record
(true, [(label a,
(mk _loc (PatVar [id_dummy]),
None))])) in
let att = mk _loc (Record (true, [(label a, (mk _loc (PatVar([id_dummy],[])), None))])) in
let p = mk _loc (XmlT (tag, multi_prod _loc [att;any])) in
let t = (p, Pair (Var id_dummy,cst_nil)) in
exp _loc (Transform (e,[t]))
......@@ -332,27 +323,27 @@ EXTEND Gram
let x = U.mk "x" in
let f = U.mk "f" in
let assign =
set_ref
(Var stk)
(concat (get_ref (Var stk)) (Pair (Var id_dummy,cst_nil))) in
let tag = mknoloc (Internal (Types.atom Atoms.any)) in
let att = mknoloc (Internal Types.Record.any) in
let any = mknoloc (Internal Types.any) in
let re = (SeqCapture(noloc,y,Star(Elem(any)))) in
let ct = mknoloc (Regexp re) in
let children = mknoloc (XmlT (tag, multi_prod _loc [att;ct])) in
let capt = mknoloc (And (mknoloc (And (mknoloc (PatVar [id_dummy]),p)),children)) in
let assign = seq assign ( (Apply(Var(f) , Var(y) ) ) ) in
let xt = Xtrans ((Var x),[capt,assign]) in
let rf = Ref (cst_nil, mknoloc (Regexp (Star(Elem p)))) in
let targ = mknoloc (Regexp(Star(Elem(any)))) in
let tres = targ in
let arg = mknoloc(PatVar [x]) in
let abst = {fun_name = Some (lop _loc,ident "f") ; fun_iface = [(targ, tres)] ;fun_body = [(arg,xt)] } in
let body =
let_in rf (mknoloc (PatVar [stk]))
(let_in ((Abstraction abst)) (mknoloc (PatVar[ident "f"]))
(let_in ((Apply(Var(f) , e) ) ) (mknoloc (Internal Types.any)) (get_ref (Var stk))))
set_ref
(Var stk)
(concat (get_ref (Var stk)) (Pair (Var id_dummy,cst_nil))) in
let tag = mknoloc (Internal (Types.atom Atoms.any)) in
let att = mknoloc (Internal Types.Record.any) in
let any = mknoloc (Internal Types.any) in
let re = (SeqCapture((noloc,y),Star(Elem(any)))) in
let ct = mknoloc (Regexp re) in
let children = mknoloc (XmlT (tag, multi_prod _loc [att;ct])) in
let capt = mknoloc (And (mknoloc (And (mknoloc (PatVar([id_dummy],[])),p)),children)) in
let assign = seq assign ((Apply(Var(f),Var(y)))) in
let xt = Xtrans ((Var x),[capt,assign]) in
let rf = Ref (cst_nil, mknoloc (Regexp (Star(Elem p)))) in
let targ = mknoloc (Regexp(Star(Elem(any)))) in
let tres = targ in
let arg = mknoloc(PatVar ([x],[])) in
let abst = {fun_name = Some (lop _loc,ident "f") ; fun_iface = [(targ, tres)] ;fun_body = [(arg,xt)] } in
let body =
let_in rf (mknoloc (PatVar ([stk],[])))
(let_in ((Abstraction abst)) (mknoloc (PatVar ([ident "f"],[])))
(let_in ((Apply(Var(f) , e) ) ) (mknoloc (Internal Types.any)) (get_ref (Var stk))))
in
exp _loc body
]
......@@ -362,9 +353,7 @@ EXTEND Gram
| e1 = SELF; e2 = expr -> exp _loc (Apply (e1,e2))
]
| "no_appl"
[ e = expr; "."; l = ident_or_keyword;
| "no_appl" [ e = expr; "."; l = ident_or_keyword;
tyargs = [ "with"; "{"; tyargs = LIST0 pat; "}" -> Some tyargs
| -> None ] ->
let e = Dot (e,label l) in
......@@ -441,11 +430,10 @@ EXTEND Gram
`Path ids ]
];
let_binding: [
[ "let"; is_fun_decl; OPT "fun"; (f,a,b) = fun_decl ->
let f = match f with Some x -> x | None -> assert false in
let p = mk _loc (PatVar [snd f]) in
let p = mk _loc (PatVar([snd f],[])) in
let abst = { fun_name = Some f; fun_iface = a; fun_body = b } in
let e = exp _loc (Abstraction abst) in
(true,p,e)
......@@ -457,7 +445,7 @@ EXTEND Gram
];
fun_decl_after_lparen: [
(* need an hack to do this, because both productions would
(* need an hack to do this, because both productions would
match [ OPT IDENT; "("; pat ] .... *)
[ p1 = pat LEVEL "no_arrow";
res = [ "->"; p2 = pat;
......@@ -476,7 +464,7 @@ EXTEND Gram
":"; tres = pat ;
"="; body = expr ->
`Compact (targ1,args,others,tres,body)
] ->
] ->
match res with
| `Classic (p2,a,b) -> (p1,p2)::a,b
| `Compact (targ1,args,others,tres,body) ->
......@@ -497,7 +485,8 @@ EXTEND Gram
others (tres,body) in
let (targ,arg) = mkfun ((p1,targ1) :: args) in
[(targ,tres)],[(arg,body)]
] ];
]
];
fun_decl: [
......@@ -518,7 +507,6 @@ EXTEND Gram
[ p = pat LEVEL "no_arrow"; "->"; e = expr -> (p,e) ]
];
regexp: [
[ x = regexp; "|"; y = regexp ->
match (x,y) with
......@@ -531,7 +519,7 @@ EXTEND Gram
| Elem x, Elem y -> Elem (mk _loc (And (x,y)))
| _ -> error _loc "Conjunction not allowed in regular expression"
]
| [ a = IDENT; "::"; x = regexp -> SeqCapture (lop _loc,ident a,x) ]
| [ a = IDENT; "::"; x = regexp -> SeqCapture ((lop _loc,ident a),x) ]
| [ x = regexp; "*" -> Star x
| x = regexp; "*?" -> WeakStar x
| x = regexp; "+" -> Seq (x, Star x)
......@@ -582,8 +570,7 @@ EXTEND Gram
Seq (Elem (mknoloc (Internal (Types.char c))), accu))
(seq_of_string s)
Epsilon ]
| [ e = pat LEVEL "simple" -> Elem e
]
| [ e = pat LEVEL "simple" -> Elem e ]
];
schema_ref: [
......@@ -595,15 +582,15 @@ EXTEND Gram
pat: [
[ x = pat; "where";
b = LIST1 [ (la,a) = located_ident; "="; y = pat -> (la,a,y) ] SEP "and" ->
b = LIST1 [ x = located_ident; "="; y = pat -> (x,[],y) ] SEP "and" ->
mk _loc (Recurs (x,b)) ]
| RIGHTA [ x = pat; "->"; y = pat -> mk _loc (Arrow (x,y))
| x = pat; "@"; y = pat -> mk _loc (Concat (x,y))
| x = pat; "+"; y = pat -> mk _loc (Merge (x,y)) ]
| "no_arrow" [ x = pat; "|"; y = pat -> mk _loc (Or (x,y)) ]
| "simple" [ x = pat; "&"; y = pat -> mk _loc (And (x,y))
| x = pat; "\\"; y = pat -> mk _loc (Diff (x,y)) ]
| "var_typ" [ x = PTYPE ->
| x = pat; "\\"; y = pat -> mk _loc (Diff (x,y)) ]
| "var" [ x = PVAR ->
mk _loc (Internal (Types.var (Var.mk (ident_aux x)))) ]
|
[ "{"; r = record_spec; "}" -> r
......@@ -618,9 +605,10 @@ EXTEND Gram
mk _loc (Constant (ident a,c))
| "!"; a = IDENT ->
mk _loc (Internal (Types.abstract (Types.Abstracts.atom a)))
| id = PTYPE; pargs = LIST1 pat SEP ","; ")" ->
mk _loc (PatVar ([ident id],pargs))
| ids = LIST1 ident_or_keyword SEP "." ->
let ids = List.map ident ids in
mk _loc (PatVar ids)
mk _loc (PatVar (List.map ident ids,[]))
| i = INT ; "--"; j = INT ->
let i = Intervals.V.mk i
and j = Intervals.V.mk j in
......@@ -641,8 +629,7 @@ EXTEND Gram
| "`"; c = tag_type -> c
| "("; l = LIST1 pat SEP ","; ")" -> multi_prod _loc l
| "["; r = [ r = regexp -> r | -> Epsilon ];
q = [ ";"; q = pat -> Some q
| -> None ];
q = [ ";"; q = pat -> Some q | -> None ];
"]" ->
let r = match q with
| Some q ->
......@@ -653,9 +640,9 @@ EXTEND Gram
mk _loc (Regexp r)
| "<"; t =
[ x = tag_type -> x
| "("; t = pat; ")" -> t ];
a = attrib_spec; ">"; c = pat ->
mk _loc (XmlT (t, multi_prod _loc [a;c]))
| "("; t = pat; ")" -> t ];
a = attrib_spec; ">"; c = pat ->
mk _loc (XmlT (t, multi_prod _loc [a;c]))
| s = STRING ->
let s =
List.map
......@@ -673,29 +660,32 @@ EXTEND Gram
or_else : [ [ OPT [ "else"; y = pat -> y ] ] ];
opt_field_pat: [ [ OPT [ "=";
o = [ "?" -> true | -> false];
x = pat; y = or_else -> (o,x,y) ] ] ];
opt_field_pat: [
[ OPT [ "=";
o = [ "?" -> true | -> false];
x = pat; y = or_else -> (o,x,y) ]
]
];
record_spec:
[ [ r = LIST0 [ l = ident_or_keyword; f = opt_field_pat; OPT ";" ->
let (o,x,y) =
match f with
| None -> (false, mknoloc (PatVar [ident l]), None)
| Some z -> z
in
let x = if o then mk _loc (Optional x) else x in
(label l, (x,y))
]; op = [ ".." -> true | -> false ] ->
mk _loc (Record (op,r))
] ];
record_spec: [
[ r = LIST0 [ l = ident_or_keyword; f = opt_field_pat; OPT ";" ->
let (o,x,y) =
match f with
| None -> (false, mknoloc (PatVar([ident l],[])), None)
| Some z -> z
in
let x = if o then mk _loc (Optional x) else x in
(label l, (x,y))
]; op = [ ".." -> true | -> false ] ->
mk _loc (Record (op,r))
]
];
char:
[
[ c = CHAR -> Chars.V.mk_int (parse_char _loc c)
| c = STRING2 -> Chars.V.mk_int (parse_char _loc c) ]
char: [
[ c = CHAR -> Chars.V.mk_int (parse_char _loc c)
| c = STRING2 -> Chars.V.mk_int (parse_char _loc c) ]
];
];
attrib_spec: [
......@@ -705,20 +695,19 @@ EXTEND Gram
opt_field_expr: [ [ OPT [ "="; x = expr LEVEL "no_appl" -> x ] ] ];
expr_record_spec:
[ [ r = LIST0
[ l = ident_or_keyword;
x = opt_field_expr; OPT ";" ->
let x = match x with Some x -> x | None -> Var (ident l) in
(label l,x) ]
->
exp _loc (RecordLitt r)
] ];
expr_record_spec: [
[ r = LIST0 [ l = ident_or_keyword;
x = opt_field_expr; OPT ";" ->
let x = match x with Some x -> x | None -> Var (ident l) in
(label l,x) ] -> exp _loc (RecordLitt r)
]
];
expr_attrib_spec: [
[ e = expr_record_spec -> e
| "("; e = expr; ")" -> e
] ];
]
];
END
module Hook = struct
......
......@@ -51,6 +51,7 @@ type token =
| CHAR of string
| STRING of string
| STRING2 of string
| PVAR of string
| PTYPE of string
| EOI
......@@ -71,6 +72,7 @@ module Token = struct
| STRING s -> sf "STRING \"%s\"" s
| STRING2 s -> sf "STRING \'%s\'" s
(* here it's not %S since the string is already escaped *)
| PVAR s -> sf "PVAR \'%S\'" s
| PTYPE s -> sf "PTYPE \'%S\'" s
| ANY_IN_NS s -> sf "ANY_IN_NS %S" s
| EOI -> sf "EOI"
......@@ -84,7 +86,7 @@ module Token = struct
let extract_string =
function
| KEYWORD s | IDENT s | INT s | CHAR s | STRING s | STRING2 s | PTYPE s |
| PTYPE s | KEYWORD s | IDENT s | INT s | CHAR s | STRING s | STRING2 s | PVAR s |
ANY_IN_NS s -> s
| tok ->
invalid_arg ("Cannot extract a string from this token: "^
......@@ -178,7 +180,6 @@ let parse_char lexbuf base i =
done;
!r
let regexp ncname_char =
xml_letter | xml_digit | [ '-' '_' ] | xml_combining_char | xml_extender | "\\."
let regexp ncname = ( xml_letter ncname_char* ) | ('_' ncname_char+)
......@@ -203,6 +204,9 @@ let return_loc i j tok = (tok, (i,j))
let rec token = lexer
| xml_blank+ -> token lexbuf
| qname "(" ->
let s = L.utf8_sub_lexeme lexbuf 0 (L.lexeme_length lexbuf - 1) in
return lexbuf (PTYPE s)
| qname ->
let s = L.utf8_lexeme lexbuf in
return lexbuf (IDENT s)
......@@ -239,7 +243,7 @@ let rec token = lexer
| "'" ncname ->
let s = L.utf8_lexeme lexbuf in
let s = String.sub s 1 (String.length s - 1) in
return lexbuf (PTYPE s)
return lexbuf (PVAR s)
| "(*" ->
in_comment := true;
comment (L.lexeme_start lexbuf) lexbuf;
......@@ -257,6 +261,9 @@ let rec token = lexer
and token2 = lexer
| xml_blank+ -> token2 lexbuf
| qname "(" ->
let s = L.utf8_sub_lexeme lexbuf 0 (L.lexeme_length lexbuf - 1) in
return lexbuf (PTYPE s)
| qname ->
let s = L.utf8_lexeme lexbuf in
return lexbuf (IDENT s)
......@@ -300,11 +307,11 @@ and token2 = lexer
(try String.index s '\t' with _ -> len))
(try String.index s ')' with _ -> len) in
let s = String.sub s 0 idend in
return lexbuf (PTYPE s)
return lexbuf (PVAR s)
| "'" ncname ->
let s = L.utf8_lexeme lexbuf in
let s = String.sub s 1 (String.length s - 1) in
return lexbuf (PTYPE s)
return lexbuf (PVAR s)
| "(*" ->
in_comment := true;
comment (L.lexeme_start lexbuf) lexbuf;
......@@ -322,6 +329,9 @@ and token2 = lexer
and token2toplevel = lexer
| xml_blank+ -> token2toplevel lexbuf
| qname "(" ->
let s = L.utf8_sub_lexeme lexbuf 0 (L.lexeme_length lexbuf - 1) in
return lexbuf (PTYPE s)
| qname ->
let s = L.utf8_lexeme lexbuf in
return lexbuf (IDENT s)
......@@ -365,11 +375,11 @@ and token2toplevel = lexer
(try String.index s '\t' with _ -> len))
(try String.index s ')' with _ -> len) in
let s = String.sub s 0 idend in
return lexbuf (PTYPE s)
return lexbuf (PVAR s)
| "'" ncname ->
let s = L.utf8_lexeme lexbuf in
let s = String.sub s 1 (String.length s - 1) in
return lexbuf (PTYPE s)
return lexbuf (PVAR s)
| "(*" ->
in_comment := true;
comment (L.lexeme_start lexbuf) lexbuf;
......
......@@ -8,6 +8,7 @@ type token =
| CHAR of string
| STRING of string
| STRING2 of string
| PVAR of string
| PTYPE of string
| EOI
......
......@@ -171,7 +171,7 @@ let load_schema schema_name uri =
let schema_name = schema_name ^ "." in
let log_schema_component kind name cd_type =
if not (Schema_builtin.is name) then begin
Types.Print.register_global schema_name name cd_type;
Types.Print.register_global (schema_name,name,[||]) cd_type;
(* Format.fprintf Format.std_formatter "Registering schema %s: %a@." kind
Ns.QName.print name; *)
......
type t( 'a ) = [ 'a* ]
let length (l : t( 'a ) ) : Int =
let aux (l : ['a*])(res : Int) : Int = match l with
| [] -> res
| [_; rest] -> aux rest (res + 1) in
aux l 0
let hd (['a+] -> 'a) [el _*] -> el
let tl (t( 'a ) -> ['a*])
| [] -> []
| [_; rest] -> rest
let nth (l : t( 'a ))(n : Int) : 'a =
let aux (l : ['a*])(n : Int) : 'a = match l with