<commit_before>(*
 *  Haxe Compiler
 *  Copyright (c)2005 <NAME>
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 *)
open Ast
open Type
open Nast
open Nxml
open Common

type context = {
	com : Common.context;
	packages : (string list, unit) Hashtbl.t;
	globals : (string list * string, string) Hashtbl.t;
	mutable curglobal : int;
	mutable macros : bool;
	mutable curclass : string;
	mutable curmethod : string;
	mutable inits : (tclass * texpr) list;
}

let files = Hashtbl.create 0

let pos ctx p =
	if ctx.macros then
		{
			psource = p.pfile;
			pline = p.pmin lor (p.pmax lsl 16);
		}
	else let file = (match ctx.com.debug with
		| true -> ctx.curclass ^ "::" ^ ctx.curmethod
		| false ->
			try
				Hashtbl.find files p.pfile
			with Not_found -> try
				(* lookup relative path *)
				let len = String.length p.pfile in
				let base = List.find (fun path ->
					let l = String.length path in
					len > l && String.sub p.pfile 0 l = path
				) ctx.com.Common.class_path in
				let l = String.length base in
				let path = String.sub p.pfile l (len - l) in
				Hashtbl.add files p.pfile path;
				path
			with Not_found ->
				Hashtbl.add files p.pfile p.pfile;
				p.pfile
	) in
	{
		psource = file;
		pline = Lexer.get_error_line p;
	}

let gen_global_name ctx path =
	match path with
	| [], name -> name
	| _ ->
	try
		Hashtbl.find ctx.globals path
	with Not_found ->
		let name = "@G" ^ string_of_int ctx.curglobal in
		ctx.curglobal <- ctx.curglobal + 1;
		Hashtbl.add ctx.globals path name;
		name

let null p =
	(EConst Null,p)

let this p =
	(EConst This,p)

let int p n =
	(EConst (Int n),p)

let str p s =
	(EConst (String s),p)

let ident p s =
	let l = String.length s in
	if l > 10 && String.sub s 0 10 = "__dollar__" then
		(EConst (Builtin (String.sub s 10 (l - 10))),p)
	else
		(EConst (Ident s),p)

let field p e f =
	(EField (e,f),p)

let builtin p n =
	(EConst (Builtin n),p)

let call p e el =
	(ECall (e,el),p)

let array p el =
	call p (builtin p "array") el

let pmap_list f p =
	PMap.fold (fun v acc -> f v :: acc) p []

let rec needs_return e =
	match e with
	| (EBlock l,_) ->
		let rec loop = function
			| [] -> true
			| [x] -> needs_return x
			| _ :: l -> loop l
		in
		loop l
	| (EReturn _,_) ->
		false
	| _ ->
		true

let with_return e =
	if needs_return e then
		let p = snd e in
		let ret = EReturn (Some (null p)),p in
		match e with
		| (EBlock l,_) ->
			(EBlock (l @ [ret]),p)
		| _ ->
			(EBlock [e;ret] , p)
	else
		e

let gen_type_path p (path,t) =
	match path with
	| [] ->
		ident p t
	| path :: l ->
		let epath = List.fold_left (fun e path -> field p e path) (ident p path) l in
		field p epath t

let rec gen_big_string ctx p s =
	let max = 1 lsl 16 - 1 in
	if String.length s > max then
		(EBinop ("+",str p (String.sub s 0 max),gen_big_string ctx p (String.sub s max (String.length s - max))),p)
	else
		str p s

let gen_constant ctx pe c =
	let p = pos ctx pe in
	match c with
	| TInt i -> (try int p (Int32.to_int i) with _ -> error "This integer is too big to be compiled to a Neko 31-bit integer. Please use a Float instead" pe)
	| TFloat f -> (EConst (Float f),p)
	| TString s -> call p (field p (ident p "String") "new") [gen_big_string ctx p s]
	| TBool b -> (EConst (if b then True else False),p)
	| TNull -> null p
	| TThis -> this p
	| TSuper -> assert false

let rec gen_binop ctx p op e1 e2 =
	(EBinop (Ast.s_binop op,gen_expr ctx e1,gen_expr ctx e2),p)

and gen_unop ctx p op flag e =
	match op with
	| Increment -> (EBinop ((if flag = Prefix then "+=" else "++="), gen_expr ctx e , int p 1),p)
	| Decrement -> (EBinop ((if flag = Prefix then "-=" else "--="), gen_expr ctx e , int p 1),p)
	| Not -> call p (builtin p "not") [gen_expr ctx e]
	| Neg -> (EBinop ("-",int p 0, gen_expr ctx e),p)
	| NegBits -> error "Operation not available" e.epos

and gen_call ctx p e el =
	match e.eexpr , el with
	| TConst TSuper , _ ->
		let c = (match follow e.etype with TInst (c,_) -> c | _ -> assert false) in
		call p (builtin p "call") [
			field p (gen_type_path p c.cl_path) "__construct__";
			this p;
			array p (List.map (gen_expr ctx) el)
		]
	| TLocal { v_name = "__resources__" }, [] ->
		call p (builtin p "array") (Hashtbl.fold (fun name data acc ->
			(EObject [("name",gen_constant ctx e.epos (TString name));("data",gen_big_string ctx p data)],p) :: acc
		) ctx.com.resources [])
	| TField ({ eexpr = TConst TSuper; etype = t },f) , _ ->
		let c = (match follow t with TInst (c,_) -> c | _ -> assert false) in
		call p (builtin p "call") [
			field p (gen_type_path p (fst c.cl_path,"@" ^ snd c.cl_path)) f;
			this p;
			array p (List.map (gen_expr ctx) el)
		]
	| _ , _ ->
		let e = (match gen_expr ctx e with EFunction _, _ as e -> (EBlock [e],p) | e -> e) in
		call p e (List.map (gen_expr ctx) el)

and gen_expr ctx e =
	let p = pos ctx e.epos in
	match e.eexpr with
	| TConst c ->
		gen_constant ctx e.epos c
	| TLocal v ->
		if v.v_capture then
			(EArray (ident p v.v_name,int p 0),p)
		else
			ident p v.v_name
	| TEnumField (e,f) ->
		field p (gen_type_path p e.e_path) f
	| TArray (e1,e2) ->
		(EArray (gen_expr ctx e1,gen_expr ctx e2),p)
	| TBinop (OpAssign,{ eexpr = TField (e1,f) },e2) ->
		(EBinop ("=",field p (gen_expr ctx e1) f,gen_expr ctx e2),p)
	| TBinop (op,e1,e2) ->
		gen_binop ctx p op e1 e2
	| TField (e,f) ->
		field p (gen_expr ctx e) f
	| TClosure (({ eexpr = TTypeExpr _ } as e),f) ->
		field p (gen_expr ctx e) f
	| TClosure (e2,f) ->
		(match follow e.etype with
		| TFun (args,_) ->
			let n = List.length args in
			if n > 5 then error "Cannot create closure with more than 5 arguments" e.epos;
			let tmp = ident p "@tmp" in
			EBlock [
				(EVars ["@tmp", Some (gen_expr ctx e2); "@fun", Some (field p tmp f)] , p);
				if ctx.macros then
					call p (builtin p "closure") [ident p "@fun";tmp]
				else
					call p (ident p ("@closure" ^ string_of_int n)) [tmp;ident p "@fun"]
			] , p
		| _ -> assert false)
	| TTypeExpr t ->
		gen_type_path p (t_path t)
	| TParenthesis e ->
		(EParenthesis (gen_expr ctx e),p)
	| TObjectDecl fl ->
		(EObject (List.map (fun (f,e) -> f , gen_expr ctx e) fl),p)
	| TArrayDecl el ->
		call p (field p (ident p "Array") "new1") [array p (List.map (gen_expr ctx) el); int p (List.length el)]
	| TCall (e,el) ->
		gen_call ctx p e el
	| TNew (c,_,params) ->
		call p (field p (gen_type_path p c.cl_path) "new") (List.map (gen_expr ctx) params)
	| TUnop (op,flag,e) ->
		gen_unop ctx p op flag e
	| TVars vl ->
		(EVars (List.map (fun (v,e) ->
			let e = (match e with
				| None ->
					if v.v_capture then
						Some (call p (builtin p "array") [null p])
					else
						None
				| Some e ->
					let e = gen_expr ctx e in
					if v.v_capture then
						Some (call p (builtin p "array") [e])
					else
						Some e
			) in
			v.v_name , e
		) vl),p)
	| TFunction f ->
		let inits = List.fold_left (fun acc (a,c) ->
			let acc = if a.v_capture then
				(EBinop ("=",ident p a.v_name,call p (builtin p "array") [ident p a.v_name]),p) :: acc
			else
				acc
			in
			match c with
			| None | Some TNull -> acc
			| Some c ->	gen_expr ctx (Codegen.set_default ctx.com a c e.epos) :: acc			
		) [] f.tf_args in
		let e = gen_expr ctx f.tf_expr in
		let e = (match inits with [] -> e | _ -> EBlock (List.rev (e :: inits)),p) in
		(EFunction (List.map arg_name f.tf_args, with_return e),p)
	| TBlock el ->
		(EBlock (List.map (gen_expr ctx) el), p)
	| TFor (v, it, e) ->
		let it = gen_expr ctx it in
		let e = gen_expr ctx e in
		let next = call p (field p (ident p "@tmp") "next") [] in
		let next = (if v.v_capture then call p (builtin p "array") [next] else next) in
		(EBlock
			[(EVars ["@tmp", Some it],p);
			(EWhile (call p (field p (ident p "@tmp") "hasNext") [],
				(EBlock [
					(EVars [v.v_name, Some next],p);
					e
				],p)
			,NormalWhile),p)]
		,p)
	| TIf (cond,e1,e2) ->
		(EIf (gen_expr ctx cond,gen_expr ctx e1,(match e2 with None -> None | Some e -> Some (gen_expr ctx e))),p)
	| TWhile (econd,e,flag) ->
		(EWhile (gen_expr ctx econd, gen_expr ctx e, match flag with Ast.NormalWhile -> NormalWhile | Ast.DoWhile -> DoWhile),p)
	| TTry (e,catchs) ->
		let rec loop = function
			| [] -> call p (builtin p "rethrow") [ident p "@tmp"]
			| (v,e) :: l ->
				let e2 = loop l in
				let path = (match follow v.v_type with
					| TInst (c,_) -> Some c.cl_path
					| TEnum (e,_) -> Some e.e_path
					| TDynamic _ -> None
					| _ -> assert false
				) in
				let cond = (match path with
					| None -> (EConst True,p)
					| Some path -> call p (field p (gen_type_path p (["neko"],"Boot")) "__instanceof") [ident p "@tmp"; gen_type_path p path]
				) in
				let id = ident p "@tmp" in
				let id = (if v.v_capture then call p (builtin p "array") [id] else id) in
				let e = gen_expr ctx e in
				(EIf (cond,(EBlock [
					EVars [v.v_name,Some id],p;
					e;
				],p),Some e2),p)
		in
		let catchs = loop catchs in
		let catchs = (EBlock [
			(EIf (
				(EBinop ("==",call p (builtin p "typeof") [ident p "@tmp"],builtin p "tstring"),p),
				(EBinop ("=",ident p "@tmp",call p (field p (ident p "String") "new") [ident p "@tmp"]),p),
				None
			),p);
			catchs;
		],p) in
		(ETry (gen_expr ctx e,"@tmp",catchs),p)
	| TReturn eo ->
		(EReturn (match eo with None -> Some (null p) | Some e -> Some (gen_expr ctx e)),p)
	| TBreak ->
		(EBreak None,p)
	| TContinue ->
		(EContinue,p)
	| TThrow e ->
		call p (builtin p "throw") [gen_expr ctx e]
	| TCast (e,None) ->
		gen_expr ctx e
	| TCast (e1,Some t) ->
		gen_expr ctx (Codegen.default_cast ctx.com e1 t e.etype e.epos)
	| TMatch (e,_,cases,eo) ->
		let etmp = (EVars ["@tmp",Some (gen_expr ctx e)],p) in
		let eindex = field p (ident p "@tmp") "index" in
		let gen_params params e =
			match params with
			| None ->
				gen_expr ctx e
			| Some el -><commit_msg>minor fix for switch exception position<commit_after>(*
 *  Haxe Compiler
 *  Copyright (c)2005 <NAME>
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 *)
open Ast
open Type
open Nast
open Nxml
open Common

type context = {
	com : Common.context;
	packages : (string list, unit) Hashtbl.t;
	globals : (string list * string, string) Hashtbl.t;
	mutable curglobal : int;
	mutable macros : bool;
	mutable curclass : string;
	mutable curmethod : string;
	mutable inits : (tclass * texpr) list;
}

let files = Hashtbl.create 0

let pos ctx p =
	if ctx.macros then
		{
			psource = p.pfile;
			pline = p.pmin lor (p.pmax lsl 16);
		}
	else let file = (match ctx.com.debug with
		| true -> ctx.curclass ^ "::" ^ ctx.curmethod
		| false ->
			try
				Hashtbl.find files p.pfile
			with Not_found -> try
				(* lookup relative path *)
				let len = String.length p.pfile in
				let base = List.find (fun path ->
					let l = String.length path in
					len > l && String.sub p.pfile 0 l = path
				) ctx.com.Common.class_path in
				let l = String.length base in
				let path = String.sub p.pfile l (len - l) in
				Hashtbl.add files p.pfile path;
				path
			with Not_found ->
				Hashtbl.add files p.pfile p.pfile;
				p.pfile
	) in
	{
		psource = file;
		pline = Lexer.get_error_line p;
	}

let gen_global_name ctx path =
	match path with
	| [], name -> name
	| _ ->
	try
		Hashtbl.find ctx.globals path
	with Not_found ->
		let name = "@G" ^ string_of_int ctx.curglobal in
		ctx.curglobal <- ctx.curglobal + 1;
		Hashtbl.add ctx.globals path name;
		name

let null p =
	(EConst Null,p)

let this p =
	(EConst This,p)

let int p n =
	(EConst (Int n),p)

let str p s =
	(EConst (String s),p)

let ident p s =
	let l = String.length s in
	if l > 10 && String.sub s 0 10 = "__dollar__" then
		(EConst (Builtin (String.sub s 10 (l - 10))),p)
	else
		(EConst (Ident s),p)

let field p e f =
	(EField (e,f),p)

let builtin p n =
	(EConst (Builtin n),p)

let call p e el =
	(ECall (e,el),p)

let array p el =
	call p (builtin p "array") el

let pmap_list f p =
	PMap.fold (fun v acc -> f v :: acc) p []

let rec needs_return e =
	match e with
	| (EBlock l,_) ->
		let rec loop = function
			| [] -> true
			| [x] -> needs_return x
			| _ :: l -> loop l
		in
		loop l
	| (EReturn _,_) ->
		false
	| _ ->
		true

let with_return e =
	if needs_return e then
		let p = snd e in
		let ret = EReturn (Some (null p)),p in
		match e with
		| (EBlock l,_) ->
			(EBlock (l @ [ret]),p)
		| _ ->
			(EBlock [e;ret] , p)
	else
		e

let gen_type_path p (path,t) =
	match path with
	| [] ->
		ident p t
	| path :: l ->
		let epath = List.fold_left (fun e path -> field p e path) (ident p path) l in
		field p epath t

let rec gen_big_string ctx p s =
	let max = 1 lsl 16 - 1 in
	if String.length s > max then
		(EBinop ("+",str p (String.sub s 0 max),gen_big_string ctx p (String.sub s max (String.length s - max))),p)
	else
		str p s

let gen_constant ctx pe c =
	let p = pos ctx pe in
	match c with
	| TInt i -> (try int p (Int32.to_int i) with _ -> error "This integer is too big to be compiled to a Neko 31-bit integer. Please use a Float instead" pe)
	| TFloat f -> (EConst (Float f),p)
	| TString s -> call p (field p (ident p "String") "new") [gen_big_string ctx p s]
	| TBool b -> (EConst (if b then True else False),p)
	| TNull -> null p
	| TThis -> this p
	| TSuper -> assert false

let rec gen_binop ctx p op e1 e2 =
	(EBinop (Ast.s_binop op,gen_expr ctx e1,gen_expr ctx e2),p)

and gen_unop ctx p op flag e =
	match op with
	| Increment -> (EBinop ((if flag = Prefix then "+=" else "++="), gen_expr ctx e , int p 1),p)
	| Decrement -> (EBinop ((if flag = Prefix then "-=" else "--="), gen_expr ctx e , int p 1),p)
	| Not -> call p (builtin p "not") [gen_expr ctx e]
	| Neg -> (EBinop ("-",int p 0, gen_expr ctx e),p)
	| NegBits -> error "Operation not available" e.epos

and gen_call ctx p e el =
	match e.eexpr , el with
	| TConst TSuper , _ ->
		let c = (match follow e.etype with TInst (c,_) -> c | _ -> assert false) in
		call p (builtin p "call") [
			field p (gen_type_path p c.cl_path) "__construct__";
			this p;
			array p (List.map (gen_expr ctx) el)
		]
	| TLocal { v_name = "__resources__" }, [] ->
		call p (builtin p "array") (Hashtbl.fold (fun name data acc ->
			(EObject [("name",gen_constant ctx e.epos (TString name));("data",gen_big_string ctx p data)],p) :: acc
		) ctx.com.resources [])
	| TField ({ eexpr = TConst TSuper; etype = t },f) , _ ->
		let c = (match follow t with TInst (c,_) -> c | _ -> assert false) in
		call p (builtin p "call") [
			field p (gen_type_path p (fst c.cl_path,"@" ^ snd c.cl_path)) f;
			this p;
			array p (List.map (gen_expr ctx) el)
		]
	| _ , _ ->
		let e = (match gen_expr ctx e with EFunction _, _ as e -> (EBlock [e],p) | e -> e) in
		call p e (List.map (gen_expr ctx) el)

and gen_expr ctx e =
	let p = pos ctx e.epos in
	match e.eexpr with
	| TConst c ->
		gen_constant ctx e.epos c
	| TLocal v ->
		if v.v_capture then
			(EArray (ident p v.v_name,int p 0),p)
		else
			ident p v.v_name
	| TEnumField (e,f) ->
		field p (gen_type_path p e.e_path) f
	| TArray (e1,e2) ->
		(EArray (gen_expr ctx e1,gen_expr ctx e2),p)
	| TBinop (OpAssign,{ eexpr = TField (e1,f) },e2) ->
		(EBinop ("=",field p (gen_expr ctx e1) f,gen_expr ctx e2),p)
	| TBinop (op,e1,e2) ->
		gen_binop ctx p op e1 e2
	| TField (e,f) ->
		field p (gen_expr ctx e) f
	| TClosure (({ eexpr = TTypeExpr _ } as e),f) ->
		field p (gen_expr ctx e) f
	| TClosure (e2,f) ->
		(match follow e.etype with
		| TFun (args,_) ->
			let n = List.length args in
			if n > 5 then error "Cannot create closure with more than 5 arguments" e.epos;
			let tmp = ident p "@tmp" in
			EBlock [
				(EVars ["@tmp", Some (gen_expr ctx e2); "@fun", Some (field p tmp f)] , p);
				if ctx.macros then
					call p (builtin p "closure") [ident p "@fun";tmp]
				else
					call p (ident p ("@closure" ^ string_of_int n)) [tmp;ident p "@fun"]
			] , p
		| _ -> assert false)
	| TTypeExpr t ->
		gen_type_path p (t_path t)
	| TParenthesis e ->
		(EParenthesis (gen_expr ctx e),p)
	| TObjectDecl fl ->
		(EObject (List.map (fun (f,e) -> f , gen_expr ctx e) fl),p)
	| TArrayDecl el ->
		call p (field p (ident p "Array") "new1") [array p (List.map (gen_expr ctx) el); int p (List.length el)]
	| TCall (e,el) ->
		gen_call ctx p e el
	| TNew (c,_,params) ->
		call p (field p (gen_type_path p c.cl_path) "new") (List.map (gen_expr ctx) params)
	| TUnop (op,flag,e) ->
		gen_unop ctx p op flag e
	| TVars vl ->
		(EVars (List.map (fun (v,e) ->
			let e = (match e with
				| None ->
					if v.v_capture then
						Some (call p (builtin p "array") [null p])
					else
						None
				| Some e ->
					let e = gen_expr ctx e in
					if v.v_capture then
						Some (call p (builtin p "array") [e])
					else
						Some e
			) in
			v.v_name , e
		) vl),p)
	| TFunction f ->
		let inits = List.fold_left (fun acc (a,c) ->
			let acc = if a.v_capture then
				(EBinop ("=",ident p a.v_name,call p (builtin p "array") [ident p a.v_name]),p) :: acc
			else
				acc
			in
			match c with
			| None | Some TNull -> acc
			| Some c ->	gen_expr ctx (Codegen.set_default ctx.com a c e.epos) :: acc			
		) [] f.tf_args in
		let e = gen_expr ctx f.tf_expr in
		let e = (match inits with [] -> e | _ -> EBlock (List.rev (e :: inits)),p) in
		(EFunction (List.map arg_name f.tf_args, with_return e),p)
	| TBlock el ->
		(EBlock (List.map (gen_expr ctx) el), p)
	| TFor (v, it, e) ->
		let it = gen_expr ctx it in
		let e = gen_expr ctx e in
		let next = call p (field p (ident p "@tmp") "next") [] in
		let next = (if v.v_capture then call p (builtin p "array") [next] else next) in
		(EBlock
			[(EVars ["@tmp", Some it],p);
			(EWhile (call p (field p (ident p "@tmp") "hasNext") [],
				(EBlock [
					(EVars [v.v_name, Some next],p);
					e
				],p)
			,NormalWhile),p)]
		,p)
	| TIf (cond,e1,e2) ->
		(EIf (gen_expr ctx cond,gen_expr ctx e1,(match e2 with None -> None | Some e -> Some (gen_expr ctx e))),p)
	| TWhile (econd,e,flag) ->
		(EWhile (gen_expr ctx econd, gen_expr ctx e, match flag with Ast.NormalWhile -> NormalWhile | Ast.DoWhile -> DoWhile),p)
	| TTry (e,catchs) ->
		let rec loop = function
			| [] -> call p (builtin p "rethrow") [ident p "@tmp"]
			| (v,e) :: l ->
				let e2 = loop l in
				let path = (match follow v.v_type with
					| TInst (c,_) -> Some c.cl_path
					| TEnum (e,_) -> Some e.e_path
					| TDynamic _ -> None
					| _ -> assert false
				) in
				let cond = (match path with
					| None -> (EConst True,p)
					| Some path -> call p (field p (gen_type_path p (["neko"],"Boot")) "__instanceof") [ident p "@tmp"; gen_type_path p path]
				) in
				let id = ident p "@tmp" in
				let id = (if v.v_capture then call p (builtin p "array") [id] else id) in
				let e = gen_expr ctx e in
				(EIf (cond,(EBlock [
					EVars [v.v_name,Some id],p;
					e;
				],p),Some e2),p)
		in
		let catchs = loop catchs in
		let catchs = (EBlock [
			(EIf (
				(EBinop ("==",call p (builtin p "typeof") [ident p "@tmp"],builtin p "tstring"),p),
				(EBinop ("=",ident p "@tmp",call p (field p (ident p "String") "new") [ident p "@tmp"]),p),
				None
			),p);
			catchs;
		],p) in
		(ETry (gen_expr ctx e,"@tmp",catchs),p)
	| TReturn eo ->
		(EReturn (match eo with None -> Some (null p) | Some e -> Some (gen_expr ctx e)),p)
	| TBreak ->
		(EBreak None,p)
	| TContinue ->
		(EContinue,p)
	| TThrow e ->
		call p (builtin p "throw") [gen_expr ctx e]
	| TCast (e,None) ->
		gen_expr ctx e
	| TCast (e1,Some t) ->
		gen_expr ctx (Codegen.default_cast ctx.com e1 t e.etype e.epos)
	| TMatch (e,_,cases,eo) ->
		let p = pos ctx e.epos in
		let etmp = (EVars ["@tmp",Some (gen_expr ctx e)],p) in
		let eindex = field p (ident p "@tmp") "index" in
		let gen_params params e =
			match params with
			| None ->
				gen_expr ctx e
			| Some el ->
{'fraction_non_alphanumeric': 0.14071599045346062, 'fraction_numerical': 0.007159904534606206, 'mean_word_length': 2.7147163120567375, 'pattern_counts': {'":': 2, '<': 7, '<?xml version=': 0, '>': 215, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 2}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3539050', 'n_tokens_mistral': 9006, 'n_tokens_neox': 8197, 'n_words': 2959}