Procházet zdrojové kódy

added named local functions

Nicolas Cannasse před 14 roky
rodič
revize
7d13cd18e5
6 změnil soubory, kde provedl 18 přidání a 8 odebrání
  1. 1 1
      ast.ml
  2. 1 0
      doc/CHANGES.txt
  3. 4 3
      interp.ml
  4. 2 2
      parser.ml
  5. 1 0
      std/haxe/macro/Expr.hx
  6. 9 2
      typer.ml

+ 1 - 1
ast.ml

@@ -176,7 +176,7 @@ and expr_def =
 	| ENew of type_path * expr list
 	| EUnop of unop * unop_flag * expr
 	| EVars of (string * complex_type option * expr option) list
-	| EFunction of func
+	| EFunction of string option * func
 	| EBlock of expr list
 	| EFor of string * expr * expr
 	| EIf of expr * expr * expr option

+ 1 - 0
doc/CHANGES.txt

@@ -47,6 +47,7 @@
 	all : big speedup for compiler internal completion
 	all : added --macro keepClass('classname')
 	flash9 : fixed Xml.nodeValue for comments (does not include <!--/-->)
+	all : added named local functions (allow self-recursion)
 
 2010-08-14: 2.06
 	neko : change serializer to be able to handle instances of basic classes from other modules

+ 4 - 3
interp.ml

@@ -2548,8 +2548,9 @@ let encode_expr e =
 						"expr",null loop eo;
 					]
 				) vl)]
-			| EFunction f ->
+			| EFunction (name,f) ->
 				12, [enc_obj [
+					"name", null enc_string name;
 					"args", enc_array (List.map (fun (n,opt,t,e) ->
 						enc_obj [
 							"name", enc_string n;
@@ -2778,14 +2779,14 @@ let decode_expr v =
 				(dec_string (field v "name"),opt decode_type (field v "type"),opt loop (field v "expr"))
 			) (dec_array vl))
 		| 12, [f] ->
-			let f = {
+			let ft = {
 				f_args = List.map (fun o ->
 					(dec_string (field o "name"),dec_bool (field o "opt"),opt decode_type (field o "type"),opt loop (field o "value"))
 				) (dec_array (field f "args"));
 				f_type = opt decode_type (field f "ret");
 				f_expr = loop (field f "expr");
 			} in
-			EFunction f
+			EFunction (opt dec_string (field f "name"),ft)
 		| 13, [el] ->
 			EBlock (List.map loop (dec_array el))
 		| 14, [v;e1;e2] ->

+ 2 - 2
parser.ml

@@ -538,14 +538,14 @@ and expr = parser
 		| [< >] -> serror())
 	| [< '(POpen,p1); e = expr; '(PClose,p2); s >] -> expr_next (EParenthesis e, punion p1 p2) s
 	| [< '(BkOpen,p1); l = parse_array_decl; '(BkClose,p2); s >] -> expr_next (EArrayDecl l, punion p1 p2) s
-	| [< '(Kwd Function,p1); '(POpen,_); al = psep Comma parse_fun_param; '(PClose,_); t = parse_type_opt; s >] ->
+	| [< '(Kwd Function,p1); name = popt any_ident; '(POpen,_); al = psep Comma parse_fun_param; '(PClose,_); t = parse_type_opt; s >] ->
 		let make e =
 			let f = {
 				f_type = t;
 				f_args = al;
 				f_expr = e;
 			} in
-			EFunction f, punion p1 (pos e)
+			EFunction (name,f), punion p1 (pos e)
 		in
 		(try
 			expr_next (make (expr s)) s

+ 1 - 0
std/haxe/macro/Expr.hx

@@ -127,6 +127,7 @@ enum TypeParam {
 }
 
 typedef Function = {
+	var name : Null<String>;
 	var args : Array<FunctionArg>;
 	var ret : Null<ComplexType>;
 	var expr : Expr;

+ 9 - 2
typer.ml

@@ -1456,7 +1456,7 @@ and type_expr ctx ?(need_val=true) (e,p) =
 		mk (TNew (c,params,el)) t p
 	| EUnop (op,flag,e) ->
 		type_unop ctx op flag e p
-	| EFunction f ->
+	| EFunction (name,f) ->
 		let rt = Typeload.load_type_opt ctx p f.f_type in
 		let args = List.map (fun (s,opt,t,c) ->
 			let t = Typeload.load_type_opt ctx p t in
@@ -1476,13 +1476,20 @@ and type_expr ctx ?(need_val=true) (e,p) =
 				) args args2;
 			| _ -> ());
 		let ft = TFun (fun_args args,rt) in
+		let vname = (match name with
+			| None -> None
+			| Some v -> Some (add_local ctx v ft)
+		) in
 		let e , fargs = Typeload.type_function ctx args rt true false f p in
 		let f = {
 			tf_args = fargs;
 			tf_type = rt;
 			tf_expr = e;
 		} in
-		mk (TFunction f) ft p
+		let e = mk (TFunction f) ft p in
+		(match vname with
+		| None -> e
+		| Some v -> mk (TVars [v,ft,Some e]) ctx.t.tvoid p)
 	| EUntyped e ->
 		let old = ctx.untyped in
 		ctx.untyped <- true;