2
0
Nicolas Cannasse 19 жил өмнө
parent
commit
eaa38ca974
6 өөрчлөгдсөн 98 нэмэгдсэн , 29 устгасан
  1. 4 2
      genjs.ml
  2. 29 13
      genneko.ml
  3. 24 13
      genswf8.ml
  4. 13 1
      std/flash/Boot.hx
  5. 13 0
      std/js/Boot.hx
  6. 15 0
      std/neko/Boot.hx

+ 4 - 2
genjs.ml

@@ -524,9 +524,11 @@ let generate_enum ctx e =
 		(match f.ef_type with
 		| TFun (args,_) ->
 			let sargs = String.concat "," (List.map fst args) in
-			print ctx "function(%s) { return [\"%s\",%s]; }" sargs f.ef_name sargs;
+			print ctx "function(%s) { var $x = [\"%s\",%s]; $x.__enum__ = %s; return $x; }" sargs f.ef_name sargs p;
 		| _ ->
-			print ctx "[\"%s\"]" f.ef_name
+			print ctx "[\"%s\"]" f.ef_name;
+			newline ctx;
+			print ctx "%s%s.__enum__ = %s" p (field f.ef_name) p;
 		);
 		newline ctx
 	) e.e_constrs

+ 29 - 13
genneko.ml

@@ -221,13 +221,14 @@ and gen_expr e =
 		(ENext (
 			(EVars ["@tmp",Some (gen_expr e)],p),
 			(ESwitch (
-				(EArray (ident p "@tmp",int p 0),p),
+				field p (ident p "@tmp") "tag",
 				List.map (fun (s,el,e2) ->
-					let count = ref 0 in
+					let count = ref (-1) in
 					let e = match el with
 						| None -> gen_expr e2
 						| Some el ->
 							(EBlock [
+								(EVars ["@tmp",Some (field p (ident p "@tmp") "args")],p);
 								(EVars (List.map (fun (v,_) -> incr count; v , Some (EArray (ident p "@tmp",int p (!count)),p)) el),p);
 								(gen_expr e2)
 							],p)
@@ -302,22 +303,34 @@ let gen_class c =
 	),p) in
 	(EBlock [eclass; estat; call p (builtin p "objsetproto") [clpath; esuper]; (EBinop ("=",field p clpath "__class__",stpath),p)],p)	
 
-let gen_enum_constr c =
+let gen_enum_constr path c =
 	let p = pos c.ef_pos in
-	c.ef_name , (match follow c.ef_type with
-		| TFun (params,_) -> 
+	(EBinop ("=",field p path c.ef_name, match follow c.ef_type with
+		| TFun (params,_) ->
 			let params = List.map fst params in
-			(EFunction (params,array p (str p c.ef_name :: List.map (ident p) params)),p)
+			(EFunction (params,
+				(EObject [
+					"tag" , str p c.ef_name;
+					"__enum__" , path;
+					"args" , array p (List.map (ident p) params);
+					"__string" , ident p "@enum_to_string"
+				],p)
+			),p)
 		| _ ->
-			array p [str p c.ef_name]
-	)
+			(EObject [
+				"tag" , str p c.ef_name;
+				"__enum__" , path;
+				"__string" , ident p "@enum_to_string"
+			],p)
+	),p)
 
 let gen_enum e =
 	let p = pos e.e_pos in
-	(EBinop ("=",
-		gen_type_path p e.e_path,
-		(EObject (pmap_list gen_enum_constr e.e_constrs),p)
-	),null_pos)
+	let path = gen_type_path p e.e_path in
+	(EBlock (
+		(EBinop ("=",path, call p (builtin p "new") [null p]),p) ::		
+		pmap_list (gen_enum_constr path) e.e_constrs
+	),p)
 
 let gen_type t =
 	match t with
@@ -379,11 +392,14 @@ let gen_boot hres =
 
 let generate file types hres =
 	let h = Hashtbl.create 0 in
+	let enum_str = (EBinop ("=",ident null_pos "@enum_to_string",(EFunction ([],
+		call null_pos (field null_pos (gen_type_path null_pos (["neko"],"Boot")) "__enum_str") [this null_pos]
+	),null_pos)),null_pos) in
 	let packs = List.concat (List.map (gen_packages h) types) in
 	let methods = List.map gen_type types in
 	let boot = gen_boot hres in
 	let vars = List.concat (List.map gen_static_vars types) in
-	let e = (EBlock (packs @ methods @ boot :: vars), null_pos) in
+	let e = (EBlock (enum_str :: packs @ methods @ boot :: vars), null_pos) in
 	let neko_file = Filename.chop_extension file ^ ".neko" in
 	let ch = IO.output_channel (open_out neko_file) in
 	(if !Plugin.verbose then Nxml.write_fmt else Nxml.write) ch (Nxml.to_xml e);

+ 24 - 13
genswf8.ml

@@ -1029,22 +1029,33 @@ let gen_class_field ctx f =
 	| Some e ->	gen_expr ctx true e);
 	setvar ctx VarObj
 
-let gen_enum_field ctx f =
-	let ename = mk (TConst (TString f.ef_name)) f.ef_type Ast.null_pos in
+let gen_enum_field ctx id f =
 	push ctx [VReg 0; VStr f.ef_name];
 	(match follow f.ef_type with
 	| TFun (args,r) ->
-		let e = mk (TReturn (Some (mk (TArrayDecl (ename :: 
-			List.map (fun (n,t) -> mk (TLocal n) t Ast.null_pos) args
-		)) r Ast.null_pos))) (mk_mono()) Ast.null_pos in
-		let fdat = {
-			tf_args = args;
-			tf_type = r;
-			tf_expr = e;
-		} in
-		gen_expr ctx true (mk (TFunction fdat) (mk_mono()) Ast.null_pos);
+		ctx.regs <- PMap.empty;
+		ctx.reg_count <- 1;
+		let rargs = List.map (fun _ -> alloc_reg ctx , "") args in
+		let nregs = List.length rargs + 1 in
+		let tf = func ctx false false rargs in
+		push ctx (List.map (fun (r,_) -> VReg r) (List.rev rargs));		
+		push ctx [VStr f.ef_name; VInt nregs];
+		write ctx AInitArray;
+		write ctx ADup;
+		push ctx [VStr "__enum__"; VStr id];
+		write ctx AEval;
+		write ctx AObjSet;
+		ctx.stack_size <- ctx.stack_size - nregs;
+		write ctx AReturn;
+		tf();
 	| t ->
-		gen_expr ctx true (mk (TArrayDecl [ename]) t Ast.null_pos));
+		push ctx [VStr f.ef_name; VInt 1];
+		write ctx AInitArray;
+		ctx.stack_size <- ctx.stack_size - 1;
+		write ctx ADup;
+		push ctx [VStr "__enum__"; VReg 0];
+		write ctx AObjSet;
+	);
 	write ctx AObjSet
 
 let gen_path ctx (p,t) is_extern =
@@ -1134,7 +1145,7 @@ let gen_type_def ctx t =
 		write ctx ANew;
 		write ctx (ASetReg 0);
 		setvar ctx VarStr;
-		PMap.iter (fun _ f -> gen_enum_field ctx f) e.e_constrs
+		PMap.iter (fun _ f -> gen_enum_field ctx id f) e.e_constrs
 
 let gen_boot ctx hres =
 	let id = gen_type ctx (["flash"],"Boot") false in

+ 13 - 1
std/flash/Boot.hx

@@ -40,13 +40,25 @@ class Boot {
 			switch( t ) {
 			case "object":
 				if( __instanceof__(o,Array) ) {
+					if( o.__enum__ != null ) {
+						if( o.length == 1 )
+							return o[0];
+						var str = o[0]+"(";
+						s += "    ";
+						for( i in 1...o.length ) {
+							if( i != 1 )
+								str += "," + __string_rec(o[i],s);
+							else
+								str += __string_rec(o[i],s);
+						}
+						return str + ")";
+					}
 					var l = o.length;
 					var i;
 					var str = "[";
 					s += "    ";
 					for( i in 0...l )
 						str += (if (i > 0) "," else "")+__string_rec(o[i],s);
-					s = s.substring(4);
 					str += "]";
 					return str;
 				}

+ 13 - 0
std/js/Boot.hx

@@ -70,6 +70,19 @@ class Boot {
 			switch( t ) {
 			case "object":
 				if( __js__("o instanceof Array") ) {
+					if( o.__enum__ != null ) {
+						if( o.length == 1 )
+							return o[0];
+						var str = o[0]+"(";
+						s += "    ";
+						for( i in 1...o.length ) {
+							if( i != 1 )
+								str += "," + __string_rec(o[i],s);
+							else
+								str += __string_rec(o[i],s);
+						}
+						return str + ")";
+					}
 					var l = o.length;
 					var i;
 					var str = "[";

+ 15 - 0
std/neko/Boot.hx

@@ -26,6 +26,21 @@ package neko;
 
 class Boot {
 
+	private static function __enum_str(e : Dynamic) {
+		if( e.args == null )
+			return e.tag;
+		var s = e.tag + untyped "(".__s;
+		var i = 0;
+		var l = untyped __dollar__asize(e.args);
+		while( i < l ) {
+			if( i == 0 )
+				s += e.args[i];
+			else
+				s += untyped ",".__s + e.args[i];
+			i += 1;
+		}
+		return s + untyped ")".__s;
+	}
 
 	private static function __instanceof(o,cl) {
 		untyped {