Commit 10678fc8 authored by Kim Nguyễn's avatar Kim Nguyễn
Browse files

Remove the need for mandatory spaces around ':' in function parameters.

Now functions such as
let fun f (x:Int):Int = ...
are parsed correctly (that is, its parameter is 'x' with type Int).
parent 09feaa19
......@@ -45,6 +45,24 @@ let keyword = Gram.Entry.mk "keyword"
let lop pos = Cduce_loc.loc_of_pos (tloc pos)
let exp pos e = LocatedExpr (lop pos,e)
let split_id_list loc l =
let rec loop l acc =
match l with
[] -> acc, []
| qname :: ll ->
try
let i = String.index qname ':' in
let pre = String.sub qname 0 i in
let post = String.sub qname (i+1) (String.length qname - i - 1) in
pre :: acc, post::ll
with
Not_found -> loop ll (qname :: acc)
in
let l1, l2 = loop l [] in
if l2 == [] then raise Stream.Failure else
(mk loc (PatVar(List.rev_map ident l1, [])),
mk loc (PatVar(List.map ident l2, [])))
let rec multi_prod loc = function
| [ x ] -> x
| x :: l -> mk loc (Prod (x, multi_prod loc l))
......@@ -437,6 +455,17 @@ EXTEND Gram
]
];
arg_colon_type: [
[ p1 = pat ; targ1 = OPT [ ":"; p = pat -> p ] ->
match p1.descr,targ1 with
PatVar(id1, []), None ->
split_id_list _loc (List.map Ident.U.get_str id1)
| _, Some targ1 -> p1, targ1
| _ -> raise Stream.Failure
]
];
fun_decl_after_lparen: [
(* need an hack to do this, because both productions would
match [ OPT IDENT; "("; pat ] .... *)
......@@ -444,19 +473,20 @@ EXTEND Gram
res = [ "->"; p2 = pat;
a = [ ";"; a = LIST0 arrow SEP ";" -> a | -> [] ];
")"; b = branches -> `Classic (p2,a,b)
| ":"; targ1 = pat;
args = LIST0 [ ","; arg = pat; ":"; targ = pat -> (arg,targ) ];
| targ1 = OPT [ ":"; p = pat -> p ];
args = LIST0 [ ","; arg = arg_colon_type -> arg ];
")";
others = LIST0
[ "(";
args =
LIST1
[ arg = pat; ":"; targ = pat -> (arg,targ) ]
[ arg = arg_colon_type -> arg ]
SEP ",";
")" -> args ];
":"; tres = pat ;
":" ; tres = pat ;
"="; body = expr ->
`Compact (targ1,args,others,tres,body)
] ->
match res with
| `Classic (p2,a,b) -> (p1,p2)::a,b
......@@ -476,6 +506,13 @@ EXTEND Gram
(t,e)
)
others (tres,body) in
let p1, targ1 =
match p1.descr,targ1 with
PatVar(id1, []), None ->
split_id_list _loc (List.map Ident.U.get_str id1)
| _, Some targ1 -> p1, targ1
| _ -> raise Stream.Failure
in
let (targ,arg) = mkfun ((p1,targ1) :: args) in
[(targ,tres)],[(arg,body)]
]
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment