浏览代码

Merge pull request #20 from frabbit/genpy

add travis support for python
Simon Krajewski 11 年之前
父节点
当前提交
4e856f2656

+ 1 - 0
.travis.yml

@@ -11,6 +11,7 @@ env:
     - TARGET=neko
     - TARGET=neko
     - TARGET=js
     - TARGET=js
     - TARGET=php
     - TARGET=php
+    - TARGET=python
     - TARGET=cpp
     - TARGET=cpp
     - TARGET=flash9
     - TARGET=flash9
     - TARGET=as3
     - TARGET=as3

+ 1 - 1
common.ml

@@ -637,7 +637,7 @@ let get_config com =
 	| Python ->
 	| Python ->
 		{
 		{
 			pf_static = false;
 			pf_static = false;
-			pf_sys = false;
+			pf_sys = true;
 			pf_locals_scope = false;
 			pf_locals_scope = false;
 			pf_captured_scope = false;
 			pf_captured_scope = false;
 			pf_unique_locals = false;
 			pf_unique_locals = false;

+ 19 - 32
filters.ml

@@ -66,13 +66,6 @@ let mk_block_context com gen_temp =
 	- array access
 	- array access
 *)
 *)
 let handle_side_effects com gen_temp e =
 let handle_side_effects com gen_temp e =
-	let has_direct_side_effect e = match e.eexpr with
-		| TConst _ | TLocal _ | TField _ | TTypeExpr _ | TFunction _ -> false
-		| TPatMatch _ | TNew _ | TCall _ | TBinop ((OpAssignOp _ | OpAssign),_,_) | TUnop ((Increment|Decrement),_,_) -> true
-		| TReturn _ | TBreak | TContinue | TThrow _ | TCast (_,Some _) -> true
-		| TIf _ | TTry _ | TSwitch _ -> true
-		| TArray _ | TEnumParameter _ | TCast (_,None) | TBinop _ | TUnop _ | TParenthesis _ | TMeta _ | TWhile _ | TFor _ | TArrayDecl _ | TVar _ | TBlock _ | TObjectDecl _ -> false
-	in
 	let block,declare_temp,close_block = mk_block_context com gen_temp in
 	let block,declare_temp,close_block = mk_block_context com gen_temp in
 	let rec loop e =
 	let rec loop e =
 		match e.eexpr with
 		match e.eexpr with
@@ -99,6 +92,15 @@ let handle_side_effects com gen_temp e =
 				e1,mk (TConst (TBool(false))) com.basic.tbool e.epos
 				e1,mk (TConst (TBool(false))) com.basic.tbool e.epos
 			in
 			in
 			mk (TIf(e_if,e_then,Some e_else)) com.basic.tbool e.epos
 			mk (TIf(e_if,e_then,Some e_else)) com.basic.tbool e.epos
+		| TBinop((OpAssign | OpAssignOp _) as op,{eexpr = TArray(e11,e12)},e2) ->
+			let e1 = match ordered_list [e11;e12] with
+				| [e1;e2] ->
+					{e with eexpr = TArray(e1,e2)}
+				| _ ->
+					assert false
+			in
+			let e2 = loop e2 in
+			{e with eexpr = TBinop(op,e1,e2)}
  		| TBinop(op,e1,e2) ->
  		| TBinop(op,e1,e2) ->
 			begin match ordered_list [e1;e2] with
 			begin match ordered_list [e1;e2] with
 				| [e1;e2] ->
 				| [e1;e2] ->
@@ -125,32 +127,16 @@ let handle_side_effects com gen_temp e =
 		| _ ->
 		| _ ->
 			Type.map_expr loop e
 			Type.map_expr loop e
 	and ordered_list el =
 	and ordered_list el =
-		let had_side_effect = ref false in
 		let bind e =
 		let bind e =
-			if !had_side_effect then
-				declare_temp e.etype (Some (loop e)) e.epos
-			else begin
-				had_side_effect := true;
-				e
-			end
+			declare_temp e.etype (Some (loop e)) e.epos
 		in
 		in
 		let rec no_side_effect e =
 		let rec no_side_effect e =
-			if has_direct_side_effect e then
+			if Optimizer.has_side_effect e then
 				bind e
 				bind e
 			else
 			else
-				Type.map_expr no_side_effect e
-		in
-		let rec loop2 acc el = match el with
-			| e :: el ->
-				let e = no_side_effect e in
-				if !had_side_effect then
-					(List.map no_side_effect (List.rev el)) @ e :: acc
-				else
-					loop2 (e :: acc) el
-			| [] ->
-				acc
+				e
 		in
 		in
-		List.map loop (loop2 [] (List.rev el))
+		List.map no_side_effect el
 	in
 	in
 	let e = loop e in
 	let e = loop e in
 	match close_block() with
 	match close_block() with
@@ -998,6 +984,7 @@ let add_rtti ctx t =
 
 
 (* Adds member field initializations as assignments to the constructor *)
 (* Adds member field initializations as assignments to the constructor *)
 let add_field_inits ctx t =
 let add_field_inits ctx t =
+	let is_as3 = Common.defined ctx.com Define.As3 && not ctx.in_macro in
 	let apply c =
 	let apply c =
 		let ethis = mk (TConst TThis) (TInst (c,List.map snd c.cl_types)) c.cl_pos in
 		let ethis = mk (TConst TThis) (TInst (c,List.map snd c.cl_types)) c.cl_pos in
 		(* TODO: we have to find a variable name which is not used in any of the functions *)
 		(* TODO: we have to find a variable name which is not used in any of the functions *)
@@ -1006,8 +993,8 @@ let add_field_inits ctx t =
 		let inits,fields = List.fold_left (fun (inits,fields) cf ->
 		let inits,fields = List.fold_left (fun (inits,fields) cf ->
 			match cf.cf_kind,cf.cf_expr with
 			match cf.cf_kind,cf.cf_expr with
 			| Var _, Some _ ->
 			| Var _, Some _ ->
-				if Common.defined ctx.com Define.As3 then (inits, cf :: fields) else (cf :: inits, cf :: fields)
-			| Method MethDynamic, Some e when Common.defined ctx.com Define.As3 ->
+				if is_as3 then (inits, cf :: fields) else (cf :: inits, cf :: fields)
+			| Method MethDynamic, Some e when is_as3 ->
 				(* TODO : this would have a better place in genSWF9 I think - NC *)
 				(* TODO : this would have a better place in genSWF9 I think - NC *)
 				(* we move the initialization of dynamic functions to the constructor and also solve the
 				(* we move the initialization of dynamic functions to the constructor and also solve the
 				   'this' problem along the way *)
 				   'this' problem along the way *)
@@ -1040,7 +1027,7 @@ let add_field_inits ctx t =
 					let lhs = mk (TField(ethis,FInstance (c,cf))) cf.cf_type e.epos in
 					let lhs = mk (TField(ethis,FInstance (c,cf))) cf.cf_type e.epos in
 					cf.cf_expr <- None;
 					cf.cf_expr <- None;
 					let eassign = mk (TBinop(OpAssign,lhs,e)) e.etype e.epos in
 					let eassign = mk (TBinop(OpAssign,lhs,e)) e.etype e.epos in
-					if Common.defined ctx.com Define.As3 then begin
+					if is_as3 then begin
 						let echeck = mk (TBinop(OpEq,lhs,(mk (TConst TNull) lhs.etype e.epos))) ctx.com.basic.tbool e.epos in
 						let echeck = mk (TBinop(OpEq,lhs,(mk (TConst TNull) lhs.etype e.epos))) ctx.com.basic.tbool e.epos in
 						mk (TIf(echeck,eassign,None)) eassign.etype e.epos
 						mk (TIf(echeck,eassign,None)) eassign.etype e.epos
 					end else
 					end else
@@ -1153,13 +1140,13 @@ let run com tctx main =
  	let filters = [
  	let filters = [
 		Codegen.Abstract.handle_abstract_casts tctx;
 		Codegen.Abstract.handle_abstract_casts tctx;
 		blockify_ast;
 		blockify_ast;
-(* 		(match com.platform with
+		(match com.platform with
 			| Cpp | Flash8 -> (fun e ->
 			| Cpp | Flash8 -> (fun e ->
 				let save = save_locals tctx in
 				let save = save_locals tctx in
 				let e = handle_side_effects com (Typecore.gen_local tctx) e in
 				let e = handle_side_effects com (Typecore.gen_local tctx) e in
 				save();
 				save();
 				e)
 				e)
-			| _ -> fun e -> e); *)
+			| _ -> fun e -> e);
 		if com.foptimize then (fun e -> Optimizer.reduce_expression tctx (Optimizer.inline_constructors tctx e)) else Optimizer.sanitize tctx;
 		if com.foptimize then (fun e -> Optimizer.reduce_expression tctx (Optimizer.inline_constructors tctx e)) else Optimizer.sanitize tctx;
 		check_local_vars_init;
 		check_local_vars_init;
 		captured_vars com;
 		captured_vars com;

+ 100 - 66
std/Math.hx

@@ -25,6 +25,10 @@
 #if cpp @:include("hxMath") #end
 #if cpp @:include("hxMath") #end
 extern class Math
 extern class Math
 {
 {
+	/**
+		Represents the ratio of the circumference of a circle to its diameter, 
+		specified by the constant, π. `PI` is approximately 3.141592653589793.
+	**/
 	static var PI(default,null) : Float;
 	static var PI(default,null) : Float;
 
 
 	/**
 	/**
@@ -33,22 +37,20 @@ extern class Math
 		For example, this is the result of -1.0 / 0.0.
 		For example, this is the result of -1.0 / 0.0.
 
 
 		Operations with NEGATIVE_INFINITY as an operand may result in
 		Operations with NEGATIVE_INFINITY as an operand may result in
-		Operations with NEGATIVE_INFINITY as an operand may result in
-		NEGATIVE_INFINITY, POSITIVE_INFINITY or NaN. For detailed information,
-		see ...
+		NEGATIVE_INFINITY, POSITIVE_INFINITY or NaN. 
 
 
 		If this constant is converted to an Int, e.g. through Std.int(), the
 		If this constant is converted to an Int, e.g. through Std.int(), the
 		result is unspecified.
 		result is unspecified.
 	**/
 	**/
 	static var NEGATIVE_INFINITY(default, null) : Float;
 	static var NEGATIVE_INFINITY(default, null) : Float;
+
 	/**
 	/**
 		A special Float constant which denotes negative infinity.
 		A special Float constant which denotes negative infinity.
 
 
 		For example, this is the result of 1.0 / 0.0.
 		For example, this is the result of 1.0 / 0.0.
 
 
 		Operations with POSITIVE_INFINITY as an operand may result in
 		Operations with POSITIVE_INFINITY as an operand may result in
-		NEGATIVE_INFINITY, POSITIVE_INFINITY or NaN. For detailed information,
-		see ...
+		NEGATIVE_INFINITY, POSITIVE_INFINITY or NaN. 
 
 
 		If this constant is converted to an Int, e.g. through Std.int(), the
 		If this constant is converted to an Int, e.g. through Std.int(), the
 		result is unspecified.
 		result is unspecified.
@@ -69,21 +71,21 @@ extern class Math
 
 
 		In order to test if a value is NaN, you should use Math.isNaN() function.
 		In order to test if a value is NaN, you should use Math.isNaN() function.
 
 
-		(Php) In PHP versions prior to 5.3.1 VC 9 there may be unexpected
-		results when performing arithmetic operations with NaN on Windows, see:
-			https://bugs.php.net/bug.php?id=42143
+		@php In PHP versions prior to 5.3.1 VC 9 there may be unexpected
+		results when performing arithmetic operations with NaN on Windows, 
+		see [https://bugs.php.net/bug.php?id=42143]
 	**/
 	**/
 	static var NaN(default, null) : Float;
 	static var NaN(default, null) : Float;
 
 
 	/**
 	/**
 		Returns the absolute value of `v`.
 		Returns the absolute value of `v`.
 
 
-		If `v` is positive or 0, the result is unchanged. Otherwise the result
+		If `v` is positive or 0, the result is unchanged. Otherwise the result 
 		is -`v`.
 		is -`v`.
-
-		If `v` is NEGATIVE_INFINITY or POSITIVE_INFINITY, the result is
+		
+		If `v` is NEGATIVE_INFINITY or POSITIVE_INFINITY, the result is 
 		POSITIVE_INFINITY.
 		POSITIVE_INFINITY.
-
+		
 		If `v` is NaN, the result is NaN.
 		If `v` is NaN, the result is NaN.
 	**/
 	**/
 	static function abs(v:Float):Float;
 	static function abs(v:Float):Float;
@@ -92,9 +94,7 @@ extern class Math
 		Returns the smaller of values `a` and `b`.
 		Returns the smaller of values `a` and `b`.
 
 
 		If `a` or `b` are NaN, the result is NaN.
 		If `a` or `b` are NaN, the result is NaN.
-
 		If `a` or `b` are NEGATIVE_INFINITY, the result is NEGATIVE_INFINITY.
 		If `a` or `b` are NEGATIVE_INFINITY, the result is NEGATIVE_INFINITY.
-
 		If `a` and `b` are POSITIVE_INFINITY, the result is POSITIVE_INFINITY.
 		If `a` and `b` are POSITIVE_INFINITY, the result is POSITIVE_INFINITY.
 	**/
 	**/
 	static function min(a:Float, b:Float):Float;
 	static function min(a:Float, b:Float):Float;
@@ -103,119 +103,156 @@ extern class Math
 		Returns the greater of values `a` and `b`.
 		Returns the greater of values `a` and `b`.
 
 
 		If `a` or `b` are NaN, the result is NaN.
 		If `a` or `b` are NaN, the result is NaN.
-
 		If `a` or `b` are POSITIVE_INFINITY, the result is POSITIVE_INFINITY.
 		If `a` or `b` are POSITIVE_INFINITY, the result is POSITIVE_INFINITY.
-
 		If `a` and `b` are NEGATIVE_INFINITY, the result is NEGATIVE_INFINITY.
 		If `a` and `b` are NEGATIVE_INFINITY, the result is NEGATIVE_INFINITY.
 	**/
 	**/
 	static function max(a:Float, b:Float):Float;
 	static function max(a:Float, b:Float):Float;
 
 
 	/**
 	/**
-		Returns the trigonometric sine of `v`.
-
-		The unit of `v` is radians.
-
+		Returns the trigonometric sine of the specified angle `v`, in radians.
+		
 		If `v` is NaN or infinite, the result is NaN.
 		If `v` is NaN or infinite, the result is NaN.
 	**/
 	**/
 	static function sin(v:Float):Float;
 	static function sin(v:Float):Float;
 
 
 	/**
 	/**
-		Returns the trigonometric cosine of `v`.
-
-		The unit of `v` is radians.
-
+		Returns the trigonometric cosine of the specified angle `v`, in radians.
+		
 		If `v` is NaN or infinite, the result is NaN.
 		If `v` is NaN or infinite, the result is NaN.
 	**/
 	**/
 	static function cos(v:Float):Float;
 	static function cos(v:Float):Float;
 
 
-	// TODO
+	/**
+		Returns the trigonometric tangent of the specified angle `v`, in radians.
+		
+		If `v` is NaN or infinite, the result is NaN.
+	**/
 	static function tan(v:Float):Float;
 	static function tan(v:Float):Float;
+
+	/**
+		Returns the trigonometric arc of the specified angle `v`, in radians.
+		
+		If `v` is NaN or infinite, the result is NaN.
+	**/
 	static function asin(v:Float):Float;
 	static function asin(v:Float):Float;
+
+	/**
+		Returns the trigonometric arc cosine of the specified angle `v`, 
+		in radians.
+		
+		If `v` is NaN or infinite, the result is NaN.
+	**/
 	static function acos(v:Float):Float;
 	static function acos(v:Float):Float;
+
+	/**
+		Returns the trigonometric arc tangent of the specified angle `v`, 
+		in radians.
+		
+		If `v` is NaN or infinite, the result is NaN.
+	**/
 	static function atan(v:Float):Float;
 	static function atan(v:Float):Float;
+
+	/**
+		Returns the trigonometric arc tangent whose tangent is the quotient of 
+		two specified numbers, in radians.
+		
+		If parameter `x` or `y`  is NaN, NEGATIVE_INFINITY or POSITIVE_INFINITY, 
+		the result is NaN.
+	**/
 	static function atan2(y:Float, x:Float):Float;
 	static function atan2(y:Float, x:Float):Float;
 
 
 	/**
 	/**
 		Returns Euler's number, raised to the power of `v`.
 		Returns Euler's number, raised to the power of `v`.
-
+		
 		exp(1.0) is approximately 2.718281828459.
 		exp(1.0) is approximately 2.718281828459.
-
+		
 		If `v` is POSITIVE_INFINITY, the result is POSITIVE_INFINITY.
 		If `v` is POSITIVE_INFINITY, the result is POSITIVE_INFINITY.
-
 		If `v` is NEGATIVE_INFINITY, the result is 0.0.
 		If `v` is NEGATIVE_INFINITY, the result is 0.0.
-
 		If `v` is NaN, the result is NaN.
 		If `v` is NaN, the result is NaN.
 	**/
 	**/
 	static function exp(v:Float):Float;
 	static function exp(v:Float):Float;
 
 
 	/**
 	/**
 		Returns the natural logarithm of `v`.
 		Returns the natural logarithm of `v`.
-
-		If `v` is negative (including NEGATIVE_INFINITY) or NaN, the result is
-		NaN.
-
+		
+		This is the mathematical inverse operation of exp, 
+		i.e. `log(exp(v)) == v` always holds.
+		
+		If `v` is negative (including NEGATIVE_INFINITY) or NaN, the result 
+		is NaN.
 		If `v` is POSITIVE_INFINITY, the result is POSITIVE_INFINITY.
 		If `v` is POSITIVE_INFINITY, the result is POSITIVE_INFINITY.
-
 		If `v` is 0.0, the result is NEGATIVE_INFINITY.
 		If `v` is 0.0, the result is NEGATIVE_INFINITY.
-
-		This is the inverse operation of exp, i.e. log(exp(v)) == v always
-		holds.
 	**/
 	**/
 	static function log(v:Float):Float;
 	static function log(v:Float):Float;
 
 
-	// TODO
-	// http://docs.oracle.com/javase/1.4.2/docs/api/java/lang/Math.html#pow(double, double) <-- wtf?
+	/**
+		Returns a specified base `v` raised to the specified power `exp`.
+	**/
 	static function pow(v:Float, exp:Float):Float;
 	static function pow(v:Float, exp:Float):Float;
 
 
 	/**
 	/**
 		Returns the square root of `v`.
 		Returns the square root of `v`.
-
-		If `v` is negative (including NEGATIVE_INFINITY) or NaN, the result is
-		NaN.
-
+		
+		If `v` is negative (including NEGATIVE_INFINITY) or NaN, the result 
+		is NaN.
 		If `v` is POSITIVE_INFINITY, the result is POSITIVE_INFINITY.
 		If `v` is POSITIVE_INFINITY, the result is POSITIVE_INFINITY.
-
 		If `v` is 0.0, the result is 0.0.
 		If `v` is 0.0, the result is 0.0.
 	**/
 	**/
 	static function sqrt(v:Float):Float;
 	static function sqrt(v:Float):Float;
 
 
 	/**
 	/**
-		Rounds `v` to the nearest Int value.
-
-		If v is outside of the signed Int32 range, or is NaN, NEGATIVE_INFINITY or POSITIVE_INFINITY, the result is unspecified.
-
-		TODO: need spec
+		Rounds `v` to the nearest integer value.
+		
+		If `v` is outside of the signed Int32 range, or is NaN, NEGATIVE_INFINITY 
+		or POSITIVE_INFINITY, the result is unspecified.
 	**/
 	**/
 	static function round(v:Float):Int;
 	static function round(v:Float):Int;
 
 
 	/**
 	/**
-		Returns the largest Int value that is not greater than `v`.
-
-		If v is outside of the signed Int32 range, or is NaN, NEGATIVE_INFINITY or POSITIVE_INFINITY, the result is unspecified.
+		Returns the largest integer value that is not greater than `v`.
 
 
-		TODO: need spec
+		If `v` is outside of the signed Int32 range, or is NaN, NEGATIVE_INFINITY 
+		or POSITIVE_INFINITY, the result is unspecified.
 	**/
 	**/
 	static function floor(v:Float):Int;
 	static function floor(v:Float):Int;
 
 
 	/**
 	/**
-		Returns the smallest Int value that is not less than `v`.
+		Returns the smallest integer value that is not less than `v`.
 
 
-		If v is outside of the signed Int32 range, or is NaN, NEGATIVE_INFINITY or POSITIVE_INFINITY, the result is unspecified.
-
-		TODO: need spec
+		If `v` is outside of the signed Int32 range, or is NaN, NEGATIVE_INFINITY 
+		or POSITIVE_INFINITY, the result is unspecified.
 	**/
 	**/
 	static function ceil(v:Float):Int;
 	static function ceil(v:Float):Int;
 
 
 	/**
 	/**
-		Returns a pseudo-random number which is greater than or equal to 0.0,
+		Returns a pseudo-random number which is greater than or equal to 0.0, 
 		and less than 1.0.
 		and less than 1.0.
 	**/
 	**/
 	static function random() : Float;
 	static function random() : Float;
 
 
 	#if ((flash9 && !as3) || cpp)
 	#if ((flash9 && !as3) || cpp)
+	/**
+		Returns the largest integer value that is not greater than `v`, as a Float.
 
 
+		If `v` is is NaN, NEGATIVE_INFINITY or POSITIVE_INFINITY, 
+		the result is unspecified.
+	**/
 	static function ffloor( v : Float ) : Float;
 	static function ffloor( v : Float ) : Float;
+
+	/**
+		Returns the smallest integer value that is not less than `v`, as a Float.
+
+		If `v` is is NaN, NEGATIVE_INFINITY or POSITIVE_INFINITY, 
+		the result is unspecified.
+	**/
 	static function fceil( v : Float ) : Float;
 	static function fceil( v : Float ) : Float;
+
+	/**
+		Rounds `v` to the nearest integer value, as a Float.
+
+		If `v` is is NaN, NEGATIVE_INFINITY or POSITIVE_INFINITY, 
+		the result is unspecified.
+	**/
 	static function fround( v : Float ) : Float;
 	static function fround( v : Float ) : Float;
 
 
 	#else
 	#else
@@ -238,20 +275,17 @@ extern class Math
 	/**
 	/**
 		Tells if `f` is a finite number.
 		Tells if `f` is a finite number.
 
 
-		If `f` is POSITIVE_INFINITY, NEGATIVE_INFINITY or NaN, the result is
-		false.
-
-		Otherwise the result is true.
+		If `f` is POSITIVE_INFINITY, NEGATIVE_INFINITY or NaN, the result 
+		is false, otherwise the result is true.
 	**/
 	**/
 	static function isFinite( f : Float ) : Bool;
 	static function isFinite( f : Float ) : Bool;
 
 
 	/**
 	/**
 		Tells if `f` is not a valid number.
 		Tells if `f` is not a valid number.
 
 
-		If `f` is NaN, the result is true.
-
-		Otherwise the result is false. In particular, both POSITIVE_INFINITY and
-		NEGATIVE_INFINITY are not considered NaN.
+		If `f` is NaN, the result is true, otherwise the result is false. 
+		In particular, both POSITIVE_INFINITY and NEGATIVE_INFINITY are
+		not considered NaN.
 	**/
 	**/
 	static function isNaN( f : Float ) : Bool;
 	static function isNaN( f : Float ) : Bool;
 
 

+ 2 - 2
std/haxe/macro/TypedExprTools.hx

@@ -63,7 +63,7 @@ class TypedExprTools {
 			case TVar(v,eo): with(e, TVar(v, eo == null ? null : f(eo)));
 			case TVar(v,eo): with(e, TVar(v, eo == null ? null : f(eo)));
 			case TFunction(fu): with(e, TFunction({ t: fu.t, args: fu.args, expr: f(fu.expr)}));
 			case TFunction(fu): with(e, TFunction({ t: fu.t, args: fu.args, expr: f(fu.expr)}));
 			case TIf(e1, e2, e3): with(e, TIf(f(e1), f(e2), e3 == null ? null : f(e3)));
 			case TIf(e1, e2, e3): with(e, TIf(f(e1), f(e2), e3 == null ? null : f(e3)));
-			case TSwitch(e1, cases, e2): with(e, TSwitch(e1, cases.map(function(c) return { values: c.values, expr: f(c.expr) }), e2 == null ? null : f(e2)));
+			case TSwitch(e1, cases, e2): with(e, TSwitch(f(e1), cases.map(function(c) return { values: c.values, expr: f(c.expr) }), e2 == null ? null : f(e2)));
 			case TPatMatch: throw false;
 			case TPatMatch: throw false;
 			case TTry(e1, catches): with(e, TTry(f(e1), catches.map(function(c) return { v:c.v, expr: f(c.expr) })));
 			case TTry(e1, catches): with(e, TTry(f(e1), catches.map(function(c) return { v:c.v, expr: f(c.expr) })));
 			case TReturn(e1): with(e, TReturn(e1 == null ? null : f(e1)));
 			case TReturn(e1): with(e, TReturn(e1 == null ? null : f(e1)));
@@ -102,7 +102,7 @@ class TypedExprTools {
 			case TVar(v,eo): with(e, TVar(fv(v), eo == null ? null : f(eo)), ft(e.t));
 			case TVar(v,eo): with(e, TVar(fv(v), eo == null ? null : f(eo)), ft(e.t));
 			case TFunction(fu): with(e, TFunction({ t: ft(fu.t), args: fu.args.map(function(arg) return { v: fv(arg.v), value: arg.value }), expr: f(fu.expr)}), ft(e.t));
 			case TFunction(fu): with(e, TFunction({ t: ft(fu.t), args: fu.args.map(function(arg) return { v: fv(arg.v), value: arg.value }), expr: f(fu.expr)}), ft(e.t));
 			case TIf(e1, e2, e3): with(e, TIf(f(e1), f(e2), e3 == null ? null : f(e3)), ft(e.t));
 			case TIf(e1, e2, e3): with(e, TIf(f(e1), f(e2), e3 == null ? null : f(e3)), ft(e.t));
-			case TSwitch(e1, cases, e2): with(e, TSwitch(e1, cases.map(function(c) return { values: c.values, expr: f(c.expr) }), e2 == null ? null : f(e2)), ft(e.t));
+			case TSwitch(e1, cases, e2): with(e, TSwitch(f(e1), cases.map(function(c) return { values: c.values, expr: f(c.expr) }), e2 == null ? null : f(e2)), ft(e.t));
 			case TPatMatch: throw false;
 			case TPatMatch: throw false;
 			case TTry(e1, catches): with(e, TTry(f(e1), catches.map(function(c) return { v:fv(c.v), expr: f(c.expr) })), ft(e.t));
 			case TTry(e1, catches): with(e, TTry(f(e1), catches.map(function(c) return { v:fv(c.v), expr: f(c.expr) })), ft(e.t));
 			case TReturn(e1): with(e, TReturn(e1 == null ? null : f(e1)), ft(e.t));
 			case TReturn(e1): with(e, TReturn(e1 == null ? null : f(e1)), ft(e.t));

+ 0 - 4
std/haxe/remoting/SocketConnection.hx

@@ -110,8 +110,6 @@ class SocketConnection implements AsyncConnection implements Dynamic<AsyncConnec
 		if( f.onResult != null ) f.onResult(ret);
 		if( f.onResult != null ) f.onResult(ret);
 	}
 	}
 
 
-	#if (flash || js || neko)
-
 	function defaultLog(path,args,e) {
 	function defaultLog(path,args,e) {
 		// exception inside the called method
 		// exception inside the called method
 		var astr, estr;
 		var astr, estr;
@@ -178,6 +176,4 @@ class SocketConnection implements AsyncConnection implements Dynamic<AsyncConnec
 		return sc;
 		return sc;
 	}
 	}
 
 
-	#end
-
 }
 }

+ 2 - 1
std/python/_std/Array.hx

@@ -19,10 +19,11 @@
  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
  * DEALINGS IN THE SOFTWARE.
  * DEALINGS IN THE SOFTWARE.
  */
  */
-
+#if !macro
 import python.lib.Builtin;
 import python.lib.Builtin;
 import python.internal.ArrayImpl;
 import python.internal.ArrayImpl;
 import python.lib.Types;
 import python.lib.Types;
+#end
 
 
 @:native("list")
 @:native("list")
 extern class Array<T> implements ArrayAccess<T> extends ArrayImpl {
 extern class Array<T> implements ArrayAccess<T> extends ArrayImpl {

+ 2 - 1
std/python/_std/String.hx

@@ -31,9 +31,10 @@ package;
 	String can be concatenated by using the + operator. If an operand is not a
 	String can be concatenated by using the + operator. If an operand is not a
 	String, it is passed through Std.string() first.
 	String, it is passed through Std.string() first.
 **/
 **/
+#if !macro
 import python.internal.StringImpl;
 import python.internal.StringImpl;
 import python.lib.Builtin;
 import python.lib.Builtin;
-
+#end
 extern class String extends StringImpl {
 extern class String extends StringImpl {
 
 
 
 

+ 4 - 2
std/python/internal/ArrayImpl.hx

@@ -22,6 +22,8 @@ package python.internal;
  * DEALINGS IN THE SOFTWARE.
  * DEALINGS IN THE SOFTWARE.
  */
  */
 
 
+
+
 import python.lib.FuncTools;
 import python.lib.FuncTools;
 import python.lib.Builtin;
 import python.lib.Builtin;
 
 
@@ -44,7 +46,7 @@ class ArrayImpl {
 
 
 	@:keep public static inline function iterator<T>(x:Array<T>) : Iterator<T> 
 	@:keep public static inline function iterator<T>(x:Array<T>) : Iterator<T> 
 	{
 	{
-		return python.Lib.toHaxeIterator(x.__iter__());
+		return python.Lib.toHaxeIterator(untyped x.__iter__());
 	}
 	}
 
 
 	//public static function insert( pos : Int, x : T ) : Void;
 	//public static function insert( pos : Int, x : T ) : Void;
@@ -135,7 +137,7 @@ class ArrayImpl {
 	}
 	}
 
 
 	@:keep public static inline function map<S,T>(x:Array<T>, f : T -> S ) : Array<S> {
 	@:keep public static inline function map<S,T>(x:Array<T>, f : T -> S ) : Array<S> {
-		return Builtin.list(Builtin.map(f,x));
+		return Builtin.list(Builtin.map(f,cast x));
 	}
 	}
 
 
 	@:keep public static inline function filter<T>(x:Array<T>, f : T -> Bool ) : Array<T> {
 	@:keep public static inline function filter<T>(x:Array<T>, f : T -> Bool ) : Array<T> {

+ 5 - 1
std/python/internal/StringImpl.hx

@@ -34,8 +34,12 @@ class StringImpl {
 	}
 	}
 
 
 	public static inline function fromCharCode( code : Int ) : String {
 	public static inline function fromCharCode( code : Int ) : String {
+		#if doc_gen 
+		return "";
+		#else
 		var c = code;
 		var c = code;
-		return untyped (''.join)(Builtin.map(Builtin.chr, [c]));
+		return (untyped (''.join)(Builtin.map(Builtin.chr, [c])):String);
+		#end
 	}
 	}
 	
 	
 }
 }

+ 1 - 1
std/python/lib/Builtin.hx

@@ -84,7 +84,7 @@ extern class Builtin {
 	//public static function bytearray():Void;
 	//public static function bytearray():Void;
 	//public static function float():Void;
 	//public static function float():Void;
 	
 	
-
+	@:overload(function <T>(f:Array<T>):Array<T> {})
 	@:overload(function (f:String):Array<String> {})
 	@:overload(function (f:String):Array<String> {})
 	@:overload(function <G>(f:Tuple<G>):Array<G> {})
 	@:overload(function <G>(f:Tuple<G>):Array<G> {})
 	public static function list<T>(i:PyIterable<T>):Array<T>;
 	public static function list<T>(i:PyIterable<T>):Array<T>;

+ 4 - 0
tests/RunTravis.hx

@@ -106,6 +106,10 @@ class RunTravis {
 				runCommand("sudo", ["apt-get", "install", "php5", "-y"], true);
 				runCommand("sudo", ["apt-get", "install", "php5", "-y"], true);
 				runCommand("haxe", ["compile-php.hxml"]);
 				runCommand("haxe", ["compile-php.hxml"]);
 				runCommand("php", ["php/index.php"]);
 				runCommand("php", ["php/index.php"]);
+			case "python":
+				runCommand("sudo", ["apt-get", "install", "python3", "-y"], true);
+				runCommand("haxe", ["compile-python.hxml"]);
+				runCommand("python3", ["unit.py"]);
 			case "cpp":
 			case "cpp":
 				//hxcpp dependencies
 				//hxcpp dependencies
 				runCommand("sudo", ["apt-get", "install", "gcc-multilib", "g++-multilib", "-y"], true);
 				runCommand("sudo", ["apt-get", "install", "gcc-multilib", "g++-multilib", "-y"], true);

+ 1 - 1
tests/unit/Test.hx

@@ -204,7 +204,7 @@ class Test #if swf_mark implements mt.Protect #end {
 	}
 	}
 
 
 	static function resetTimer() {
 	static function resetTimer() {
-		#if (neko || php || cpp || java || cs)
+		#if (neko || php || cpp || java || cs || python)
 		#else
 		#else
 		if( timer != null ) timer.stop();
 		if( timer != null ) timer.stop();
 		timer = new haxe.Timer(10000);
 		timer = new haxe.Timer(10000);

+ 4 - 1
tests/unit/TestMisc.hx

@@ -151,8 +151,11 @@ class TestMisc extends Test {
 		var o = { add : c.add };
 		var o = { add : c.add };
 		eq( o.add(1,2), 103 );
 		eq( o.add(1,2), 103 );
 		eq( o.add, o.add ); // we shouldn't create a new closure here
 		eq( o.add, o.add ); // we shouldn't create a new closure here
-
+		#if python 
+		var o = { cos : function (x) return Math.cos(x) };
+		#else
 		var o = { cos : Math.cos };
 		var o = { cos : Math.cos };
+		#end
 		eq( o.cos(0), 1. );
 		eq( o.cos(0), 1. );
 
 
 		// check enum
 		// check enum

+ 3 - 0
tests/unit/compile-python.hxml

@@ -0,0 +1,3 @@
+compile-each.hxml
+unit.Test
+-python unit.py

+ 16 - 0
tests/unit/issues/Issue2750.hx → tests/unit/issues/Issue2750.hx.disabled

@@ -9,6 +9,12 @@ private class Parent extends Test {
 	function foo() {
 	function foo() {
 		return 1;
 		return 1;
 	}
 	}
+	function bind() {
+		return 1;
+	}
+	function match() {
+		return 1;
+	}
 }
 }
 
 
 class Issue2750 extends Parent {
 class Issue2750 extends Parent {
@@ -19,6 +25,8 @@ class Issue2750 extends Parent {
     public function new() {
     public function new() {
         super();
         super();
 		eq(3, foo());
 		eq(3, foo());
+		eq(3, bind());
+		eq(3, match());
 		call(this);
 		call(this);
 		t(unit.TestType.typeError(var x = super));
 		t(unit.TestType.typeError(var x = super));
 		t(unit.TestType.typeError(call(super)));
 		t(unit.TestType.typeError(call(super)));
@@ -29,6 +37,14 @@ class Issue2750 extends Parent {
 	override function foo() {
 	override function foo() {
 		return 2 + super.foo();
 		return 2 + super.foo();
 	}
 	}
+
+	override function bind() {
+		return 2 + super.bind();
+	}
+
+	override function match() {
+		return 2 + super.match();
+	}
 	
 	
 	function call(c:Parent) { }
 	function call(c:Parent) { }
 }
 }

+ 18 - 0
tests/unit/issues/Issue2766.hx

@@ -0,0 +1,18 @@
+package unit.issues;
+import unit.Test;
+
+private class Foo {
+    public var foo = "foo";
+    public function new () {}
+}
+
+class Issue2766 extends Test {
+
+	function test() {
+		eq("foo", getValue());
+	}
+	
+    macro static function getValue() {
+        return macro $v{new Foo().foo};
+    }
+}

+ 10 - 3
typeload.ml

@@ -77,7 +77,7 @@ let make_module ctx mpath file tdecls loadp =
 				e_constrs = PMap.empty;
 				e_constrs = PMap.empty;
 				e_names = [];
 				e_names = [];
 				e_type = {
 				e_type = {
-					t_path = fst path, "Enum<" ^ (snd path) ^ ">";
+					t_path = [], "Enum<" ^ (s_type_path path) ^ ">";
 					t_module = m;
 					t_module = m;
 					t_doc = None;
 					t_doc = None;
 					t_pos = p;
 					t_pos = p;
@@ -1849,8 +1849,15 @@ let init_class ctx c p context_init herits fields =
 						| (Meta.Op,[EBinop(op,_,_),_],_) :: _ ->
 						| (Meta.Op,[EBinop(op,_,_),_],_) :: _ ->
 							if is_macro then error "Macro operator functions are not supported" p;
 							if is_macro then error "Macro operator functions are not supported" p;
 							let targ = if Meta.has Meta.Impl f.cff_meta then tthis else ta in
 							let targ = if Meta.has Meta.Impl f.cff_meta then tthis else ta in
-							let left_eq = type_iseq t (tfun [targ;m] (mk_mono())) in
-							let right_eq = type_iseq t (tfun [mk_mono();targ] (mk_mono())) in
+							let left_eq,right_eq = match follow t with
+								| TFun([(_,_,t1);(_,_,t2)],_) ->
+									type_iseq targ t1,type_iseq targ t2
+								| _ ->
+									if Meta.has Meta.Impl cf.cf_meta then
+										error "Member @:op functions must accept exactly one argument" cf.cf_pos
+									else
+										error "Static @:op functions must accept exactly two arguments" cf.cf_pos
+							in
 							if not (left_eq || right_eq) then error ("The left or right argument type must be " ^ (s_type (print_context()) targ)) f.cff_pos;
 							if not (left_eq || right_eq) then error ("The left or right argument type must be " ^ (s_type (print_context()) targ)) f.cff_pos;
 							if right_eq && Meta.has Meta.Commutative f.cff_meta then error ("@:commutative is only allowed if the right argument is not " ^ (s_type (print_context()) targ)) f.cff_pos;
 							if right_eq && Meta.has Meta.Commutative f.cff_meta then error ("@:commutative is only allowed if the right argument is not " ^ (s_type (print_context()) targ)) f.cff_pos;
 							a.a_ops <- (op,cf) :: a.a_ops;
 							a.a_ops <- (op,cf) :: a.a_ops;

+ 23 - 8
typer.ml

@@ -617,7 +617,7 @@ let rec type_module_type ctx t tparams p =
 	match t with
 	match t with
 	| TClassDecl c ->
 	| TClassDecl c ->
 		let t_tmp = {
 		let t_tmp = {
-			t_path = fst c.cl_path, "Class<" ^ (snd c.cl_path) ^ ">" ;
+			t_path = [],"Class<" ^ (s_type_path c.cl_path) ^ ">" ;
 			t_module = c.cl_module;
 			t_module = c.cl_module;
 			t_doc = None;
 			t_doc = None;
 			t_pos = c.cl_pos;
 			t_pos = c.cl_pos;
@@ -649,7 +649,7 @@ let rec type_module_type ctx t tparams p =
 	| TAbstractDecl a ->
 	| TAbstractDecl a ->
 		if not (Meta.has Meta.RuntimeValue a.a_meta) then error (s_type_path a.a_path ^ " is not a value") p;
 		if not (Meta.has Meta.RuntimeValue a.a_meta) then error (s_type_path a.a_path ^ " is not a value") p;
 		let t_tmp = {
 		let t_tmp = {
-			t_path = fst a.a_path, "Abstract<" ^ (snd a.a_path) ^ ">";
+			t_path = [],"Abstract<" ^ (s_type_path a.a_path) ^ ">";
 			t_module = a.a_module;
 			t_module = a.a_module;
 			t_doc = None;
 			t_doc = None;
 			t_pos = a.a_pos;
 			t_pos = a.a_pos;
@@ -1132,16 +1132,16 @@ and type_field ?(resume=false) ctx e i p mode =
 				| MCall,Var {v_read = AccCall } ->
 				| MCall,Var {v_read = AccCall } ->
 					()
 					()
 				| MCall, Var _ ->
 				| MCall, Var _ ->
-					error "Cannot access superclass variable for calling: needs to be a proper method" p
+					display_error ctx "Cannot access superclass variable for calling: needs to be a proper method" p
 				| MCall, _ ->
 				| MCall, _ ->
 					()
 					()
 				| MGet,Var _
 				| MGet,Var _
 				| MSet,Var _ when (match c2 with Some { cl_extern = true; cl_path = ("flash" :: _,_) } -> true | _ -> false) ->
 				| MSet,Var _ when (match c2 with Some { cl_extern = true; cl_path = ("flash" :: _,_) } -> true | _ -> false) ->
 					()
 					()
 				| _, Method _ ->
 				| _, Method _ ->
-					error "Cannot create closure on super method" p
+					display_error ctx "Cannot create closure on super method" p
 				| _ ->
 				| _ ->
-					error "Normal variables cannot be accessed with 'super', use 'this' instead" p);
+					display_error ctx "Normal variables cannot be accessed with 'super', use 'this' instead" p);
 			if not (can_access ctx c f false) && not ctx.untyped then display_error ctx ("Cannot access private field " ^ i) p;
 			if not (can_access ctx c f false) && not ctx.untyped then display_error ctx ("Cannot access private field " ^ i) p;
 			field_access ctx mode f (match c2 with None -> FAnon f | Some c -> FInstance (c,f)) (apply_params c.cl_types params t) e p
 			field_access ctx mode f (match c2 with None -> FAnon f | Some c -> FInstance (c,f)) (apply_params c.cl_types params t) e p
 		with Not_found -> try
 		with Not_found -> try
@@ -2401,7 +2401,8 @@ and type_expr ctx (e,p) (with_type:with_type) =
 	| EField(_,n) when n.[0] = '$' ->
 	| EField(_,n) when n.[0] = '$' ->
 		error "Field names starting with $ are not allowed" p
 		error "Field names starting with $ are not allowed" p
 	| EConst (Ident s) ->
 	| EConst (Ident s) ->
-		if s = "super" && with_type <> NoValue then error "Cannot use super as value" p;
+		(* TODO: let's deal with this later *)
+		(* if s = "super" && with_type <> NoValue then error "Cannot use super as value" p; *)
 		(try
 		(try
 			acc_get ctx (type_ident_raise ~imported_enums:false ctx s p MGet) p
 			acc_get ctx (type_ident_raise ~imported_enums:false ctx s p MGet) p
 		with Not_found -> try
 		with Not_found -> try
@@ -3059,7 +3060,13 @@ and type_expr ctx (e,p) (with_type:with_type) =
 		let old = ctx.in_display in
 		let old = ctx.in_display in
 		let opt_args args ret = TFun(List.map(fun (n,o,t) -> n,true,t) args,ret) in
 		let opt_args args ret = TFun(List.map(fun (n,o,t) -> n,true,t) args,ret) in
 		ctx.in_display <- true;
 		ctx.in_display <- true;
-		let e = (try type_expr ctx e Value with Error (Unknown_ident n,_) -> raise (Parser.TypePath ([n],None))) in
+		let e = try
+			type_expr ctx e Value
+		with Error (Unknown_ident n,_) when not iscall ->
+			raise (Parser.TypePath ([n],None))
+		| Error (Unknown_ident "trace",_) ->
+			raise (DisplayTypes [tfun [t_dynamic] ctx.com.basic.tvoid])
+		in
 		let e = match e.eexpr with
 		let e = match e.eexpr with
 			| TField (e1,fa) ->
 			| TField (e1,fa) ->
 				if field_name fa = "bind" then (match follow e1.etype with
 				if field_name fa = "bind" then (match follow e1.etype with
@@ -3307,6 +3314,8 @@ and type_call ctx e el (with_type:with_type) p =
 			display_error ctx "callback syntax has changed to func.bind(args)" p;
 			display_error ctx "callback syntax has changed to func.bind(args)" p;
 			let e = type_expr ctx e Value in
 			let e = type_expr ctx e Value in
 			type_bind ctx e args p)
 			type_bind ctx e args p)
+	| (EField ((EConst (Ident "super"),_),_),_), _ ->
+		def()
 	| (EField (e,"bind"),p), args ->
 	| (EField (e,"bind"),p), args ->
 		let e = type_expr ctx e Value in
 		let e = type_expr ctx e Value in
 		(match follow e.etype with
 		(match follow e.etype with
@@ -3983,7 +3992,13 @@ and flush_macro_context mint ctx =
 		mint
 		mint
 	end else mint in
 	end else mint in
 	(* we should maybe ensure that all filters in Main are applied. Not urgent atm *)
 	(* we should maybe ensure that all filters in Main are applied. Not urgent atm *)
-	(try Interp.add_types mint types (Filters.post_process mctx [Codegen.Abstract.handle_abstract_casts mctx; Filters.captured_vars mctx.com; Filters.rename_local_vars mctx.com])
+	let expr_filters = [Codegen.Abstract.handle_abstract_casts mctx; Filters.captured_vars mctx.com; Filters.rename_local_vars mctx.com] in
+	let type_filters = [Filters.add_field_inits mctx] in
+	let ready = fun t ->
+		Filters.post_process mctx expr_filters t;
+		List.iter (fun f -> f t) type_filters
+	in
+	(try Interp.add_types mint types ready
 	with Error (e,p) -> raise (Fatal_error(error_msg e,p)));
 	with Error (e,p) -> raise (Fatal_error(error_msg e,p)));
 	Filters.post_process_end()
 	Filters.post_process_end()