Browse Source

fixed some closure code.

Nicolas Cannasse 19 years ago
parent
commit
78b79276c8
4 changed files with 47 additions and 10 deletions
  1. 22 3
      genjs.ml
  2. 10 5
      genneko.ml
  3. 4 1
      std/flash/Boot.hx
  4. 11 1
      std/js/Boot.hx

+ 22 - 3
genjs.ml

@@ -107,6 +107,12 @@ let rec gen_call ctx e el =
 			concat ctx "," (gen_value ctx) params;
 			concat ctx "," (gen_value ctx) params;
 			spr ctx "])";
 			spr ctx "])";
 		);
 		);
+	| TField (e,s) , el ->
+		gen_value ctx e;
+		spr ctx (field s);
+		spr ctx "(";
+		concat ctx "," (gen_value ctx) el;
+		spr ctx ")"		
 	| TLocal "__new__" , { eexpr = TConst (TString cl) } :: params ->
 	| TLocal "__new__" , { eexpr = TConst (TString cl) } :: params ->
 		print ctx "new %s(" cl;
 		print ctx "new %s(" cl;
 		concat ctx "," (gen_value ctx) params;
 		concat ctx "," (gen_value ctx) params;
@@ -137,13 +143,26 @@ and gen_expr ctx e =
 		spr ctx "[";
 		spr ctx "[";
 		gen_value ctx e2;
 		gen_value ctx e2;
 		spr ctx "]";
 		spr ctx "]";
+	| TBinop (op,{ eexpr = TField (e1,s) },e2) ->
+		gen_value ctx e1;
+		spr ctx (field s);
+		print ctx " %s " (Ast.s_binop op);
+		gen_value ctx e2;
 	| TBinop (op,e1,e2) ->
 	| TBinop (op,e1,e2) ->
 		gen_value ctx e1;
 		gen_value ctx e1;
 		print ctx " %s " (Ast.s_binop op);
 		print ctx " %s " (Ast.s_binop op);
 		gen_value ctx e2;
 		gen_value ctx e2;
-	| TField (e,s) ->
-		gen_value ctx e;
-		spr ctx (field s)
+	| TField (x,s) ->
+		(match follow e.etype with
+		| TFun _ -> 
+			spr ctx "$closure(";
+			gen_value ctx x;
+			spr ctx ",";
+			gen_constant ctx (TString s);
+			spr ctx ")";
+		| _ -> 
+			gen_value ctx x;
+			spr ctx (field s))
 	| TType t ->
 	| TType t ->
 		spr ctx (s_path (t_path t))
 		spr ctx (s_path (t_path t))
 	| TParenthesis e ->
 	| TParenthesis e ->

+ 10 - 5
genneko.ml

@@ -182,12 +182,17 @@ and gen_closure p t e f =
 	| TFun (args,_) ->
 	| TFun (args,_) ->
 		let n = ref 0 in
 		let n = ref 0 in
 		let args = List.map (fun _ -> incr n; "p" ^ string_of_int (!n)) args in
 		let args = List.map (fun _ -> incr n; "p" ^ string_of_int (!n)) args in
+		let tmp = ident p "@tmp" in
+		let ifun = ident p "@fun" in
 		EBlock [
 		EBlock [
-			(EVars ["@tmp", Some e; "@fun", Some (field p (ident p "@tmp") f)] , p);
-			(EFunction (args,(EBlock [
-				(EBinop ("=",this p,ident p "@tmp"),p);
-				(EReturn (Some (call p (ident p "@fun") (List.map (ident p) args))),p)
-			],p)),p)
+			(EVars ["@tmp", Some e; "@fun", Some (field p tmp f)] , p);
+			(EIf ((EBinop ("==",ifun,null p),p),
+				null p,
+				Some (EFunction (args,(EBlock [
+					(EBinop ("=",this p,tmp),p);
+					(EReturn (Some (call p ifun (List.map (ident p) args))),p)
+				],p)),p)
+			),p)
 		] , p
 		] , p
 	| _ -> 
 	| _ -> 
 		field p e f
 		field p e f

+ 4 - 1
std/flash/Boot.hx

@@ -95,11 +95,14 @@ class Boot {
 
 
 	private static function __closure(f,o) {
 	private static function __closure(f,o) {
 		untyped {
 		untyped {
+			var m = o[f];
+			if( m == null )
+				return null;
 			var f2 = function() {
 			var f2 = function() {
 				var me = __arguments__.callee;
 				var me = __arguments__.callee;
 				return me.f.apply(me.o,__arguments__);
 				return me.f.apply(me.o,__arguments__);
 			};
 			};
-			f2.f = o[f];
+			f2.f = m;
 			f2.o = o;
 			f2.o = o;
 			return f2;
 			return f2;
 		}
 		}

+ 11 - 1
std/js/Boot.hx

@@ -58,6 +58,15 @@ class Boot {
 		}
 		}
 	}
 	}
 
 
+	private static function __closure(o,f) {
+		untyped {
+			var m = o[f];
+			if( m == null )
+				return null;
+			return function() { return m.apply(o,arguments); };
+		}
+	}
+
 	private static function __string_rec(o,s) {
 	private static function __string_rec(o,s) {
 		untyped {
 		untyped {
 			if( o == null )
 			if( o == null )
@@ -95,7 +104,7 @@ class Boot {
 				}
 				}
 				var tostr;
 				var tostr;
 				try {
 				try {
-					tostr = o.toString;
+					tostr = untyped o.toString;
 				} catch( e : Dynamic ) {
 				} catch( e : Dynamic ) {
 					// strange error on IE
 					// strange error on IE
 					return "???";
 					return "???";
@@ -266,6 +275,7 @@ class Boot {
 			Float = __js__("Number");
 			Float = __js__("Number");
 			Bool["true"] = true;
 			Bool["true"] = true;
 			Bool["false"] = false;
 			Bool["false"] = false;
+			__js__("$closure = js.Boot.__closure");
 		}
 		}
 	}
 	}