Nicolas Cannasse vor 20 Jahren
Ursprung
Commit
263d8d971f
2 geänderte Dateien mit 40 neuen und 9 gelöschten Zeilen
  1. 14 8
      main.ml
  2. 26 1
      typer.ml

+ 14 - 8
main.ml

@@ -35,7 +35,7 @@ let report msg p =
 	warn msg p;
 	exit 1
 
-let compile ctx f =
+let make_path f =
 	let cl = ExtString.String.nsplit f "." in
 	let error() = failwith ("Invalid class name " ^ f) in
 	let invalid_char x =
@@ -54,16 +54,16 @@ let compile ctx f =
 				let path , name = loop l in
 				x :: path , name
 	in
-	let cpath = loop cl in
-	ignore(Typer.load ctx cpath Ast.null_pos)
+	loop cl
 
 ;;
 try	
 	let usage = "Haxe Compiler Alpha - (c)2005 Motion-Twin\n Usage : haxe.exe [options] <class names...>\n Options :" in
 	let base_path = normalize_path (try Extc.executable_path() with _ -> "./") in
-	let classes = ref ["Std"] in
+	let classes = ref [([],"Std")] in
 	let swf_out = ref None in
 	let neko_out = ref None in
+	let main_class = ref None in
 	let swf_version = ref 8 in
 	let time = Sys.time() in
 	Plugin.class_path := [base_path ^ "std/";"";"/"];
@@ -82,6 +82,12 @@ try
 			check_targets();
 			neko_out := Some file
 		),"<file> : compile code to Neko Binary");
+		("-main",Arg.String (fun cl ->
+			if !main_class <> None then raise (Arg.Bad "Multiple -main");
+			let cpath = make_path cl in
+			main_class := Some cpath;
+			classes := cpath :: !classes
+		),"<class> : select startup class");
 		("-D",Arg.String (fun def ->
 			Hashtbl.add Parser.defines def ();
 		),"<var> : define the macro variable");
@@ -90,7 +96,7 @@ try
 		),"<version> : flash player version (8 by default)");
 		("-v",Arg.Unit (fun () -> Plugin.verbose := true),": turn on verbose mode");
 	] @ !Plugin.options in
-	Arg.parse args_spec (fun cl -> classes := cl :: !classes) usage;
+	Arg.parse args_spec (fun cl -> classes := make_path cl :: !classes) usage;
 	(match !swf_out with
 	| None -> ()
 	| Some _ ->
@@ -102,14 +108,14 @@ try
 	| Some _ ->
 		Hashtbl.add Parser.defines "neko" ();
 		Plugin.class_path := (base_path ^ "neko/") :: !Plugin.class_path);
-	if !classes = ["Std"] then begin
+	if !classes = [([],"Std")] then begin
 		Arg.usage args_spec usage
 	end else begin
 		if !Plugin.verbose then print_endline ("Classpath : " ^ (String.concat ";" !Plugin.class_path));
 		let ctx = Typer.context warn in
-		List.iter (compile ctx) (List.rev !classes);
+		List.iter (fun cpath -> ignore(Typer.load ctx cpath Ast.null_pos)) (List.rev !classes);
 		Typer.finalize ctx;
-		let types = Typer.types ctx in
+		let types = Typer.types ctx (!main_class) in
 		(match !swf_out with
 		| None -> ()
 		| Some file ->

+ 26 - 1
typer.ml

@@ -1199,7 +1199,7 @@ type state =
 	| Done
 	| NotYet
 
-let types ctx =
+let types ctx main =
 	let types = ref [] in
 	let states = Hashtbl.create 0 in
 	let state p = try Hashtbl.find states p with Not_found -> NotYet in
@@ -1281,6 +1281,31 @@ let types ctx =
 
 	in
 	Hashtbl.iter (fun _ m -> List.iter loop m.mtypes) ctx.modules;
+	(match main with
+	| None -> ()
+	| Some cl ->
+		let t = load_type_def ctx null_pos cl in
+		(match t with
+		| TEnumDecl _ -> error ("Invalid -main : " ^ s_type_path cl ^ " is not a class") null_pos
+		| TClassDecl c ->
+			try
+				let f = PMap.find "main" c.cl_statics in
+				match follow f.cf_type with
+				| TFun ([],_) -> ()
+				| _ -> error ("Invalid -main : " ^ s_type_path cl ^ " has invalid main function") null_pos
+			with
+				Not_found -> error ("Invalid -main : " ^ s_type_path cl ^ " does not have static function main") null_pos
+		);
+		let path = ([],"@Main") in
+		let c = mk_class path in
+		c.cl_statics <- PMap.add "init" {
+			cf_name = "init";
+			cf_type = mk_mono();
+			cf_public = false;
+			cf_expr = Some (mk (TCall (mk (TField (mk (TType t) (mk_mono()) null_pos,"main")) (mk_mono()) null_pos,[])) (mk_mono()) null_pos);
+		} c.cl_statics;
+		types := (path,TClassDecl c) :: !types
+	);
 	List.rev !types
 
 ;;