浏览代码

fixed iterators.

Nicolas Cannasse 20 年之前
父节点
当前提交
211689b723
共有 1 个文件被更改,包括 30 次插入11 次删除
  1. 30 11
      typer.ml

+ 30 - 11
typer.ml

@@ -163,6 +163,7 @@ let set_heritance ctx c herits p =
 			(match t with
 			| TInst (cl,params) ->
 				if is_parent c cl then error "Recursive class" p; 
+				if c.cl_interface then error "Cannot extend an interface" p;
 				c.cl_super <- Some (cl,params)
 			| _ -> error "Should extend a class" p)
 		| HImplements t ->
@@ -242,6 +243,15 @@ let t_array ctx =
 	| _ ->
 		assert false
 
+let t_iterator ctx =
+	match load_type_def ctx null_pos ([],"Iterator") with
+	| TClassDecl c ->
+		if List.length c.cl_types <> 1 then assert false;
+		let pt = mk_mono() in
+		TInst (c,[pt]) , pt
+	| _ ->
+		assert false
+
 let rec return_flow e =
 	let error() = error "A return is missing here" e.epos in
 	match e.eexpr with
@@ -509,9 +519,10 @@ let rec type_binop ctx op e1 e2 p =
 		mk_op b
 	| OpInterval ->
 		let i = t_int ctx in
-		unify ctx e1.etype i p;
-		unify ctx e2.etype i p;
-		mk_op (TFun ([],i))
+		let t = load_normal_type ctx { tpackage = []; tname = "IntIter"; tparams = [] } p false in
+		unify ctx e1.etype i e1.epos;
+		unify ctx e2.etype i e2.epos;
+		mk (TNew ((match t with TInst (c,[]) -> c | _ -> assert false),[],[e1;e2])) t p
 	| OpAssign ->
 		unify ctx e2.etype e1.etype p;
 		check_assign ctx e1;
@@ -682,20 +693,28 @@ and type_expr ctx ?(need_val=true) (e,p) =
 		mk (TVars vl) (t_void ctx) p
 	| EFor (i,e1,e2) ->
 		let e1 = type_expr ctx e1 in
-		let pt = mk_mono() in
-		let t = TFun ([],pt) in
-		(match follow e1.etype with
+		let t, pt = t_iterator ctx in
+		let e1 = (match follow e1.etype with
 		| TAnon _
 		| TInst _ ->
-			let ft = type_field ctx e1.etype "iterator" e1.epos in
-			unify ctx ft t e1.epos 
+			(try
+				unify ctx e1.etype t e1.epos;
+				e1
+			with _ ->
+				match follow (type_field ctx e1.etype "iterator" e1.epos) with
+				| TFun ([],it) as ft ->
+					unify ctx it t e1.epos;
+					let fe = mk (TField (e1,"iterator")) ft e1.epos in
+					mk (TCall (fe,[])) t e1.epos
+				| _ ->
+					error "The field iterator is not a method" e1.epos
+			)
 		| _ ->
 			unify ctx e1.etype t e1.epos;
-		);
-		let locals = ctx.locals in
+			e1
+		) in
 		ctx.locals <- PMap.add i pt ctx.locals;
 		let e2 = type_expr ctx e2 in
-		ctx.locals <- locals;
 		mk (TFor (i,e1,e2)) (t_void ctx) p
 	| EIf (e,e1,e2) ->
 		let e = type_expr ctx e in