ast.ml 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774
  1. (*
  2. * Haxe Compiler
  3. * Copyright (c)2005 Nicolas Cannasse
  4. *
  5. * This program is free software; you can redistribute it and/or modify
  6. * it under the terms of the GNU General Public License as published by
  7. * the Free Software Foundation; either version 2 of the License, or
  8. * (at your option) any later version.
  9. *
  10. * This program is distributed in the hope that it will be useful,
  11. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. * GNU General Public License for more details.
  14. *
  15. * You should have received a copy of the GNU General Public License
  16. * along with this program; if not, write to the Free Software
  17. * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  18. *)
  19. type pos = {
  20. pfile : string;
  21. pmin : int;
  22. pmax : int;
  23. }
  24. type keyword =
  25. | Function
  26. | Class
  27. | Var
  28. | If
  29. | Else
  30. | While
  31. | Do
  32. | For
  33. | Break
  34. | Continue
  35. | Return
  36. | Extends
  37. | Implements
  38. | Import
  39. | Switch
  40. | Case
  41. | Default
  42. | Static
  43. | Public
  44. | Private
  45. | Try
  46. | Catch
  47. | New
  48. | This
  49. | Throw
  50. | Extern
  51. | Enum
  52. | In
  53. | Interface
  54. | Untyped
  55. | Cast
  56. | Override
  57. | Typedef
  58. | Dynamic
  59. | Package
  60. | Callback
  61. | Inline
  62. | Using
  63. | Null
  64. | True
  65. | False
  66. type binop =
  67. | OpAdd
  68. | OpMult
  69. | OpDiv
  70. | OpSub
  71. | OpAssign
  72. | OpEq
  73. | OpNotEq
  74. | OpGt
  75. | OpGte
  76. | OpLt
  77. | OpLte
  78. | OpAnd
  79. | OpOr
  80. | OpXor
  81. | OpBoolAnd
  82. | OpBoolOr
  83. | OpShl
  84. | OpShr
  85. | OpUShr
  86. | OpMod
  87. | OpAssignOp of binop
  88. | OpInterval
  89. type unop =
  90. | Increment
  91. | Decrement
  92. | Not
  93. | Neg
  94. | NegBits
  95. type constant =
  96. | Int of string
  97. | Float of string
  98. | String of string
  99. | Ident of string
  100. | Regexp of string * string
  101. type token =
  102. | Eof
  103. | Const of constant
  104. | Kwd of keyword
  105. | Comment of string
  106. | CommentLine of string
  107. | Binop of binop
  108. | Unop of unop
  109. | Semicolon
  110. | Comma
  111. | BrOpen
  112. | BrClose
  113. | BkOpen
  114. | BkClose
  115. | POpen
  116. | PClose
  117. | Dot
  118. | DblDot
  119. | Arrow
  120. | IntInterval of string
  121. | Macro of string
  122. | Question
  123. | At
  124. | Dollar of string
  125. type unop_flag =
  126. | Prefix
  127. | Postfix
  128. type while_flag =
  129. | NormalWhile
  130. | DoWhile
  131. type type_path = {
  132. tpackage : string list;
  133. tname : string;
  134. tparams : type_param_or_const list;
  135. tsub : string option;
  136. }
  137. and type_param_or_const =
  138. | TPType of complex_type
  139. | TPExpr of expr
  140. and complex_type =
  141. | CTPath of type_path
  142. | CTFunction of complex_type list * complex_type
  143. | CTAnonymous of class_field list
  144. | CTParent of complex_type
  145. | CTExtend of type_path * class_field list
  146. | CTOptional of complex_type
  147. and func = {
  148. f_params : type_param list;
  149. f_args : (string * bool * complex_type option * expr option) list;
  150. f_type : complex_type option;
  151. f_expr : expr option;
  152. }
  153. and expr_def =
  154. | EConst of constant
  155. | EArray of expr * expr
  156. | EBinop of binop * expr * expr
  157. | EField of expr * string
  158. | EParenthesis of expr
  159. | EObjectDecl of (string * expr) list
  160. | EArrayDecl of expr list
  161. | ECall of expr * expr list
  162. | ENew of type_path * expr list
  163. | EUnop of unop * unop_flag * expr
  164. | EVars of (string * complex_type option * expr option) list
  165. | EFunction of string option * func
  166. | EBlock of expr list
  167. | EFor of expr * expr
  168. | EIn of expr * expr
  169. | EIf of expr * expr * expr option
  170. | EWhile of expr * expr * while_flag
  171. | ESwitch of expr * (expr list * expr) list * expr option
  172. | ETry of expr * (string * complex_type * expr) list
  173. | EReturn of expr option
  174. | EBreak
  175. | EContinue
  176. | EUntyped of expr
  177. | EThrow of expr
  178. | ECast of expr * complex_type option
  179. | EDisplay of expr * bool
  180. | EDisplayNew of type_path
  181. | ETernary of expr * expr * expr
  182. | ECheckType of expr * complex_type
  183. and expr = expr_def * pos
  184. and type_param = string * complex_type list
  185. and documentation = string option
  186. and metadata = (string * expr list * pos) list
  187. and access =
  188. | APublic
  189. | APrivate
  190. | AStatic
  191. | AOverride
  192. | ADynamic
  193. | AInline
  194. and class_field_kind =
  195. | FVar of complex_type option * expr option
  196. | FFun of func
  197. | FProp of string * string * complex_type * expr option
  198. and class_field = {
  199. cff_name : string;
  200. cff_doc : documentation;
  201. cff_pos : pos;
  202. mutable cff_meta : metadata;
  203. mutable cff_access : access list;
  204. mutable cff_kind : class_field_kind;
  205. }
  206. type enum_flag =
  207. | EPrivate
  208. | EExtern
  209. type class_flag =
  210. | HInterface
  211. | HExtern
  212. | HPrivate
  213. | HExtends of type_path
  214. | HImplements of type_path
  215. type enum_constructor = string * documentation * metadata * (string * bool * complex_type) list * pos
  216. type ('a,'b) definition = {
  217. d_name : string;
  218. d_doc : documentation;
  219. d_params : type_param list;
  220. d_meta : metadata;
  221. d_flags : 'a list;
  222. d_data : 'b;
  223. }
  224. type type_def =
  225. | EClass of (class_flag, class_field list) definition
  226. | EEnum of (enum_flag, enum_constructor list) definition
  227. | ETypedef of (enum_flag, complex_type) definition
  228. | EImport of type_path
  229. | EUsing of type_path
  230. type type_decl = type_def * pos
  231. type package = string list * type_decl list
  232. let is_lower_ident i =
  233. let rec loop p =
  234. match String.unsafe_get i p with
  235. | 'a'..'z' -> true
  236. | '_' -> if p + 1 < String.length i then loop (p + 1) else true
  237. | _ -> false
  238. in
  239. loop 0
  240. let pos = snd
  241. let is_postfix (e,_) = function
  242. | Increment | Decrement -> (match e with EConst _ | EField _ | EArray _ -> true | _ -> false)
  243. | Not | Neg | NegBits -> false
  244. let is_prefix = function
  245. | Increment | Decrement -> true
  246. | Not | Neg | NegBits -> true
  247. let base_class_name = snd
  248. let null_pos = { pfile = "?"; pmin = -1; pmax = -1 }
  249. let punion p p2 =
  250. {
  251. pfile = p.pfile;
  252. pmin = min p.pmin p2.pmin;
  253. pmax = max p.pmax p2.pmax;
  254. }
  255. let s_type_path (p,s) = match p with [] -> s | _ -> String.concat "." p ^ "." ^ s
  256. let parse_path s =
  257. match List.rev (ExtString.String.nsplit s ".") with
  258. | [] -> failwith "Invalid empty path"
  259. | x :: l -> List.rev l, x
  260. let s_escape s =
  261. let b = Buffer.create (String.length s) in
  262. for i = 0 to (String.length s) - 1 do
  263. match s.[i] with
  264. | '\n' -> Buffer.add_string b "\\n"
  265. | '\t' -> Buffer.add_string b "\\t"
  266. | '\r' -> Buffer.add_string b "\\r"
  267. | '"' -> Buffer.add_string b "\\\""
  268. | '\\' -> Buffer.add_string b "\\\\"
  269. | c -> Buffer.add_char b c
  270. done;
  271. Buffer.contents b
  272. let s_constant = function
  273. | Int s -> s
  274. | Float s -> s
  275. | String s -> "\"" ^ s_escape s ^ "\""
  276. | Ident s -> s
  277. | Regexp (r,o) -> "~/" ^ r ^ "/"
  278. let s_access = function
  279. | APublic -> "public"
  280. | APrivate -> "private"
  281. | AStatic -> "static"
  282. | AOverride -> "override"
  283. | ADynamic -> "dynamic"
  284. | AInline -> "inline"
  285. let s_keyword = function
  286. | Function -> "function"
  287. | Class -> "class"
  288. | Static -> "static"
  289. | Var -> "var"
  290. | If -> "if"
  291. | Else -> "else"
  292. | While -> "while"
  293. | Do -> "do"
  294. | For -> "for"
  295. | Break -> "break"
  296. | Return -> "return"
  297. | Continue -> "continue"
  298. | Extends -> "extends"
  299. | Implements -> "implements"
  300. | Import -> "import"
  301. | Switch -> "switch"
  302. | Case -> "case"
  303. | Default -> "default"
  304. | Private -> "private"
  305. | Public -> "public"
  306. | Try -> "try"
  307. | Catch -> "catch"
  308. | New -> "new"
  309. | This -> "this"
  310. | Throw -> "throw"
  311. | Extern -> "extern"
  312. | Enum -> "enum"
  313. | In -> "in"
  314. | Interface -> "interface"
  315. | Untyped -> "untyped"
  316. | Cast -> "cast"
  317. | Override -> "override"
  318. | Typedef -> "typedef"
  319. | Dynamic -> "dynamic"
  320. | Package -> "package"
  321. | Callback -> "callback"
  322. | Inline -> "inline"
  323. | Using -> "using"
  324. | Null -> "null"
  325. | True -> "true"
  326. | False -> "false"
  327. let rec s_binop = function
  328. | OpAdd -> "+"
  329. | OpMult -> "*"
  330. | OpDiv -> "/"
  331. | OpSub -> "-"
  332. | OpAssign -> "="
  333. | OpEq -> "=="
  334. | OpNotEq -> "!="
  335. | OpGte -> ">="
  336. | OpLte -> "<="
  337. | OpGt -> ">"
  338. | OpLt -> "<"
  339. | OpAnd -> "&"
  340. | OpOr -> "|"
  341. | OpXor -> "^"
  342. | OpBoolAnd -> "&&"
  343. | OpBoolOr -> "||"
  344. | OpShr -> ">>"
  345. | OpUShr -> ">>>"
  346. | OpShl -> "<<"
  347. | OpMod -> "%"
  348. | OpAssignOp op -> s_binop op ^ "="
  349. | OpInterval -> "..."
  350. let s_unop = function
  351. | Increment -> "++"
  352. | Decrement -> "--"
  353. | Not -> "!"
  354. | Neg -> "-"
  355. | NegBits -> "~"
  356. let s_token = function
  357. | Eof -> "<end of file>"
  358. | Const c -> s_constant c
  359. | Kwd k -> s_keyword k
  360. | Comment s -> "/*"^s^"*/"
  361. | CommentLine s -> "//"^s
  362. | Binop o -> s_binop o
  363. | Unop o -> s_unop o
  364. | Semicolon -> ";"
  365. | Comma -> ","
  366. | BkOpen -> "["
  367. | BkClose -> "]"
  368. | BrOpen -> "{"
  369. | BrClose -> "}"
  370. | POpen -> "("
  371. | PClose -> ")"
  372. | Dot -> "."
  373. | DblDot -> ":"
  374. | Arrow -> "->"
  375. | IntInterval s -> s ^ "..."
  376. | Macro s -> "#" ^ s
  377. | Question -> "?"
  378. | At -> "@"
  379. | Dollar v -> "$" ^ v
  380. let unescape s =
  381. let b = Buffer.create 0 in
  382. let rec loop esc i =
  383. if i = String.length s then
  384. ()
  385. else
  386. let c = s.[i] in
  387. if esc then begin
  388. let inext = ref (i + 1) in
  389. (match c with
  390. | 'n' -> Buffer.add_char b '\n'
  391. | 'r' -> Buffer.add_char b '\r'
  392. | 't' -> Buffer.add_char b '\t'
  393. | '"' | '\'' | '\\' -> Buffer.add_char b c
  394. | '0'..'3' ->
  395. let c = (try char_of_int (int_of_string ("0o" ^ String.sub s i 3)) with _ -> raise Exit) in
  396. Buffer.add_char b c;
  397. inext := !inext + 2;
  398. | 'x' ->
  399. let c = (try char_of_int (int_of_string ("0x" ^ String.sub s (i+1) 2)) with _ -> raise Exit) in
  400. Buffer.add_char b c;
  401. inext := !inext + 2;
  402. | _ ->
  403. raise Exit);
  404. loop false !inext;
  405. end else
  406. match c with
  407. | '\\' -> loop true (i + 1)
  408. | c ->
  409. Buffer.add_char b c;
  410. loop false (i + 1)
  411. in
  412. loop false 0;
  413. Buffer.contents b
  414. let map_expr loop (e,p) =
  415. let opt f o =
  416. match o with None -> None | Some v -> Some (f v)
  417. in
  418. let rec tparam = function
  419. | TPType t -> TPType (ctype t)
  420. | TPExpr e -> TPExpr (loop e)
  421. and cfield f =
  422. { f with cff_kind = (match f.cff_kind with
  423. | FVar (t,e) -> FVar (opt ctype t, opt loop e)
  424. | FFun f -> FFun (func f)
  425. | FProp (get,set,t,e) -> FProp (get,set,ctype t,opt loop e))
  426. }
  427. and ctype = function
  428. | CTPath t -> CTPath (tpath t)
  429. | CTFunction (cl,c) -> CTFunction (List.map ctype cl, ctype c)
  430. | CTAnonymous fl -> CTAnonymous (List.map cfield fl)
  431. | CTParent t -> CTParent (ctype t)
  432. | CTExtend (t,fl) -> CTExtend (tpath t, List.map cfield fl)
  433. | CTOptional t -> CTOptional (ctype t)
  434. and func f =
  435. {
  436. f_params = List.map (fun (n,tl) -> n,List.map ctype tl) f.f_params;
  437. f_args = List.map (fun (n,o,t,e) -> n,o,opt ctype t,opt loop e) f.f_args;
  438. f_type = opt ctype f.f_type;
  439. f_expr = opt loop f.f_expr;
  440. }
  441. and tpath t = { t with tparams = List.map tparam t.tparams }
  442. in
  443. let e = (match e with
  444. | EConst _ -> e
  445. | EArray (e1,e2) -> EArray (loop e1, loop e2)
  446. | EBinop (op,e1,e2) -> EBinop (op,loop e1, loop e2)
  447. | EField (e,f) -> EField (loop e, f)
  448. | EParenthesis e -> EParenthesis (loop e)
  449. | EObjectDecl fl -> EObjectDecl (List.map (fun (f,e) -> f,loop e) fl)
  450. | EArrayDecl el -> EArrayDecl (List.map loop el)
  451. | ECall (e,el) -> ECall (loop e, List.map loop el)
  452. | ENew (t,el) -> ENew (tpath t,List.map loop el)
  453. | EUnop (op,f,e) -> EUnop (op,f,loop e)
  454. | EVars vl -> EVars (List.map (fun (n,t,eo) -> n,opt ctype t,opt loop eo) vl)
  455. | EFunction (n,f) -> EFunction (n,func f)
  456. | EBlock el -> EBlock (List.map loop el)
  457. | EFor (e1,e2) -> EFor (loop e1, loop e2)
  458. | EIn (e1,e2) -> EIn (loop e1, loop e2)
  459. | EIf (e,e1,e2) -> EIf (loop e, loop e1, opt loop e2)
  460. | EWhile (econd,e,f) -> EWhile (loop econd, loop e, f)
  461. | ESwitch (e,cases,def) -> ESwitch (loop e, List.map (fun (el,e) -> List.map loop el, loop e) cases, opt loop def)
  462. | ETry (e, catches) -> ETry (loop e, List.map (fun (n,t,e) -> n,ctype t,loop e) catches)
  463. | EReturn e -> EReturn (opt loop e)
  464. | EBreak -> EBreak
  465. | EContinue -> EContinue
  466. | EUntyped e -> EUntyped (loop e)
  467. | EThrow e -> EThrow (loop e)
  468. | ECast (e,t) -> ECast (loop e,opt ctype t)
  469. | EDisplay (e,f) -> EDisplay (loop e,f)
  470. | EDisplayNew t -> EDisplayNew (tpath t)
  471. | ETernary (e1,e2,e3) -> ETernary (loop e1,loop e2,loop e3)
  472. | ECheckType (e,t) -> ECheckType (loop e, ctype t)
  473. ) in
  474. (e,p)
  475. let reify in_macro =
  476. let mk_enum ename n vl p =
  477. let constr = (EConst (Ident n),p) in
  478. match vl with
  479. | [] -> constr
  480. | _ -> (ECall (constr,vl),p)
  481. in
  482. let to_const c p =
  483. let cst n v = mk_enum "Constant" n [EConst (String v),p] p in
  484. match c with
  485. | Int i -> cst "CInt" i
  486. | String s -> cst "CString" s
  487. | Float s -> cst "CFloat" s
  488. | Ident s -> cst "CIdent" s
  489. | Regexp (r,o) -> mk_enum "Constant" "CRegexp" [(EConst (String r),p);(EConst (String o),p)] p
  490. in
  491. let rec to_binop o p =
  492. let op n = mk_enum "Binop" n [] p in
  493. match o with
  494. | OpAdd -> op "OpAdd"
  495. | OpMult -> op "OpMult"
  496. | OpDiv -> op "OpDiv"
  497. | OpSub -> op "OpSub"
  498. | OpAssign -> op "OpAssign"
  499. | OpEq -> op "OpEq"
  500. | OpNotEq -> op "OpNotEq"
  501. | OpGt -> op "OpGt"
  502. | OpGte -> op "OpGte"
  503. | OpLt -> op "OpLt"
  504. | OpLte -> op "OpLte"
  505. | OpAnd -> op "OpAnd"
  506. | OpOr -> op "OpOr"
  507. | OpXor -> op "OpXor"
  508. | OpBoolAnd -> op "OpBoolAnd"
  509. | OpBoolOr -> op "OpBoolOr"
  510. | OpShl -> op "OpShl"
  511. | OpShr -> op "OpShr"
  512. | OpUShr -> op "OpUShr"
  513. | OpMod -> op "OpMod"
  514. | OpAssignOp o -> mk_enum "Binop" "OpAssignOp" [to_binop o p] p
  515. | OpInterval -> op "OpInterval"
  516. in
  517. let to_string s p =
  518. let len = String.length s in
  519. if len > 0 && s.[0] = '$' then
  520. (EConst (Ident (String.sub s 1 (len - 1))),p)
  521. else
  522. (EConst (String s),p)
  523. in
  524. let to_array f a p =
  525. (EArrayDecl (List.map (fun s -> f s p) a),p)
  526. in
  527. let to_null p =
  528. (EConst (Ident "null"),p)
  529. in
  530. let to_opt f v p =
  531. match v with
  532. | None -> to_null p
  533. | Some v -> f v p
  534. in
  535. let to_bool o p =
  536. (EConst (Ident (if o then "true" else "false")),p)
  537. in
  538. let to_obj fields p =
  539. (EObjectDecl fields,p)
  540. in
  541. let rec to_tparam t p =
  542. let n, v = (match t with
  543. | TPType t -> "TPType", to_ctype t p
  544. | TPExpr e -> "TPExpr", to_expr e p
  545. ) in
  546. mk_enum "TypeParam" n [v] p
  547. and to_tpath t p =
  548. let fields = [
  549. ("pack", to_array to_string t.tpackage p);
  550. ("name", to_string t.tname p);
  551. ("params", to_array to_tparam t.tparams p);
  552. ] in
  553. to_obj (match t.tsub with None -> fields | Some s -> fields @ ["sub",to_string s p]) p
  554. and to_ctype t p =
  555. let ct n vl = mk_enum "ComplexType" n vl p in
  556. match t with
  557. | CTPath { tpackage = []; tparams = []; tsub = None; tname = n } when n.[0] = '$' ->
  558. to_string n p
  559. | CTPath t -> ct "TPath" [to_tpath t p]
  560. | CTFunction (args,ret) -> ct "TFunction" [to_array to_ctype args p; to_ctype ret p]
  561. | CTAnonymous fields -> ct "TAnonymous" [to_array to_cfield fields p]
  562. | CTParent t -> ct "TParent" [to_ctype t p]
  563. | CTExtend (t,fields) -> ct "TExtend" [to_tpath t p; to_array to_cfield fields p]
  564. | CTOptional t -> ct "TOptional" [to_ctype t p]
  565. and to_fun f p =
  566. let farg (n,o,t,e) p =
  567. let fields = [
  568. "name", to_string n p;
  569. "opt", to_bool o p;
  570. "type", to_opt to_ctype t p;
  571. ] in
  572. to_obj (match e with None -> fields | Some e -> fields @ ["value",to_expr e p]) p
  573. in
  574. let fparam (n,tl) p =
  575. let fields = [
  576. "name", to_string n p;
  577. "constraints", to_array to_ctype tl p;
  578. ] in
  579. to_obj fields p
  580. in
  581. let fields = [
  582. ("args",to_array farg f.f_args p);
  583. ("ret",to_opt to_ctype f.f_type p);
  584. ("expr",to_opt to_expr f.f_expr p);
  585. ("params",to_array fparam f.f_params p);
  586. ] in
  587. to_obj fields p
  588. and to_cfield f p =
  589. let p = f.cff_pos in
  590. let to_access a p =
  591. let n = (match a with
  592. | APublic -> "APublic"
  593. | APrivate -> "APrivate"
  594. | AStatic -> "AStatic"
  595. | AOverride -> "AOverride"
  596. | ADynamic -> "ADynamic"
  597. | AInline -> "AInline"
  598. ) in
  599. mk_enum "Access" n [] p
  600. in
  601. let to_kind k =
  602. let n, vl = (match k with
  603. | FVar (ct,e) -> "FVar", [to_opt to_ctype ct p;to_opt to_expr e p]
  604. | FFun f -> "FFun", [to_fun f p]
  605. | FProp (get,set,t,e) -> "FProp", [to_string get p; to_string set p; to_ctype t p; to_opt to_expr e p]
  606. ) in
  607. mk_enum "FieldType" n vl p
  608. in
  609. let fields = [
  610. Some ("name", to_string f.cff_name p);
  611. (match f.cff_doc with None -> None | Some s -> Some ("doc", to_string s p));
  612. (match f.cff_access with [] -> None | l -> Some ("access", to_array to_access l p));
  613. Some ("kind", to_kind f.cff_kind);
  614. Some ("pos", to_pos f.cff_pos);
  615. (match f.cff_meta with [] -> None | l -> Some ("meta", to_meta f.cff_meta p));
  616. ] in
  617. let fields = List.rev (List.fold_left (fun acc v -> match v with None -> acc | Some e -> e :: acc) [] fields) in
  618. to_obj fields p
  619. and to_meta m p =
  620. to_array (fun (m,el,p) _ ->
  621. let fields = [
  622. "name", to_string m p;
  623. "params", to_array to_expr el p;
  624. "pos", to_pos p;
  625. ] in
  626. to_obj fields p
  627. ) m p
  628. and to_pos p =
  629. let file = (EConst (String p.pfile),p) in
  630. let pmin = (EConst (Int (string_of_int p.pmin)),p) in
  631. let pmax = (EConst (Int (string_of_int p.pmax)),p) in
  632. if in_macro then
  633. (EUntyped (ECall ((EConst (Ident "$mk_pos"),p),[file;pmin;pmax]),p),p)
  634. else
  635. to_obj [("file",file);("min",pmin);("max",pmax)] p
  636. and to_expr e _ =
  637. let p = snd e in
  638. let expr n vl =
  639. let e = mk_enum "ExprDef" n vl p in
  640. to_obj [("expr",e);("pos",to_pos p)] p
  641. in
  642. let loop e = to_expr e (snd e) in
  643. match fst e with
  644. | EConst (Ident n) when n.[0] = '$' ->
  645. to_string n p
  646. | EConst c ->
  647. expr "EConst" [to_const c p]
  648. | EArray (e1,e2) ->
  649. expr "EArray" [loop e1;loop e2]
  650. | EBinop (op,e1,e2) ->
  651. expr "EBinop" [to_binop op p; loop e1; loop e2]
  652. | EField (e,s) ->
  653. expr "EField" [loop e; to_string s p]
  654. | EParenthesis e ->
  655. expr "EParenthesis" [loop e]
  656. | EObjectDecl fl ->
  657. expr "EObjectDecl" [to_array (fun (f,e) -> to_obj [("field",to_string f p);("expr",loop e)]) fl p]
  658. | EArrayDecl el ->
  659. expr "EArrayDecl" [to_array to_expr el p]
  660. | ECall ((EConst(Ident("$")),_),[e]) ->
  661. (ECall ((EField ((EField ((EField ((EConst (Ident "haxe"),p),"macro"),p),"Context"),p),"makeExpr"),p),[e; to_pos (pos e)]),p)
  662. | ECall (e,el) ->
  663. expr "ECall" [loop e;to_array to_expr el p]
  664. | ENew (t,el) ->
  665. expr "ENew" [to_tpath t p;to_array to_expr el p]
  666. | EUnop (op,flag,e) ->
  667. let op = mk_enum "Unop" (match op with
  668. | Increment -> "OpIncrement"
  669. | Decrement -> "OpDecrement"
  670. | Not -> "OpNot"
  671. | Neg -> "OpNeg"
  672. | NegBits -> "OpNegBits"
  673. ) [] p in
  674. expr "EUnop" [op;to_bool (flag = Postfix) p;loop e]
  675. | EVars vl ->
  676. expr "EVars" [to_array (fun (v,t,e) p ->
  677. let fields = [
  678. "name", to_string v p;
  679. "type", to_opt to_ctype t p;
  680. "expr", to_opt to_expr e p;
  681. ] in
  682. to_obj fields p
  683. ) vl p]
  684. | EFunction (name,f) ->
  685. expr "EFunction" [to_opt to_string name p; to_fun f p]
  686. | EBlock el ->
  687. expr "EBlock" [to_array to_expr el p]
  688. | EFor (e1,e2) ->
  689. expr "EFor" [loop e1;loop e2]
  690. | EIn (e1,e2) ->
  691. expr "EIn" [loop e1;loop e2]
  692. | EIf (e1,e2,eelse) ->
  693. expr "EIf" [loop e1;loop e2;to_opt to_expr eelse p]
  694. | EWhile (e1,e2,flag) ->
  695. expr "EWhile" [loop e1;loop e2;to_bool (flag = NormalWhile) p]
  696. | ESwitch (e1,cases,def) ->
  697. let scase (el,e) p =
  698. to_obj [("values",to_array to_expr el p);"expr",loop e] p
  699. in
  700. expr "ESwitch" [loop e1;to_array scase cases p;to_opt to_expr def p]
  701. | ETry (e1,catches) ->
  702. let scatch (n,t,e) p =
  703. to_obj [("name",to_string n p);("type",to_ctype t p);("expr",loop e)] p
  704. in
  705. expr "ETry" [loop e1;to_array scatch catches p]
  706. | EReturn eo ->
  707. expr "EReturn" [to_opt to_expr eo p]
  708. | EBreak ->
  709. expr "EBreak" []
  710. | EContinue ->
  711. expr "EContinue" []
  712. | EUntyped e ->
  713. expr "EUntyped" [loop e]
  714. | EThrow e ->
  715. expr "EThrow" [loop e]
  716. | ECast (e,ct) ->
  717. expr "ECast" [loop e; to_opt to_ctype ct p]
  718. | EDisplay (e,flag) ->
  719. expr "EDisplay" [loop e; to_bool flag p]
  720. | EDisplayNew t ->
  721. expr "EDisplayNew" [to_tpath t p]
  722. | ETernary (e1,e2,e3) ->
  723. expr "ETernary" [loop e1;loop e2;loop e3]
  724. | ECheckType (e1,ct) ->
  725. expr "ECheckType" [loop e1; to_ctype ct p]
  726. in
  727. (fun e -> to_expr e (snd e)), to_ctype