parser.ml 48 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488
  1. (*
  2. * Copyright (C)2005-2013 Haxe Foundation
  3. *
  4. * Permission is hereby granted, free of charge, to any person obtaining a
  5. * copy of this software and associated documentation files (the "Software"),
  6. * to deal in the Software without restriction, including without limitation
  7. * the rights to use, copy, modify, merge, publish, distribute, sublicense,
  8. * and/or sell copies of the Software, and to permit persons to whom the
  9. * Software is furnished to do so, subject to the following conditions:
  10. *
  11. * The above copyright notice and this permission notice shall be included in
  12. * all copies or substantial portions of the Software.
  13. *
  14. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  15. * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  16. * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  17. * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  18. * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
  19. * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
  20. * DEALINGS IN THE SOFTWARE.
  21. *)
  22. open Ast
  23. type error_msg =
  24. | Unexpected of token
  25. | Duplicate_default
  26. | Missing_semicolon
  27. | Unclosed_macro
  28. | Unimplemented
  29. | Missing_type
  30. | Custom of string
  31. exception Error of error_msg * pos
  32. exception TypePath of string list * (string * bool) option
  33. exception Display of expr
  34. let error_msg = function
  35. | Unexpected t -> "Unexpected "^(s_token t)
  36. | Duplicate_default -> "Duplicate default"
  37. | Missing_semicolon -> "Missing ;"
  38. | Unclosed_macro -> "Unclosed macro"
  39. | Unimplemented -> "Not implemented for current platform"
  40. | Missing_type -> "Missing type declaration"
  41. | Custom s -> s
  42. let error m p = raise (Error (m,p))
  43. let display_error : (error_msg -> pos -> unit) ref = ref (fun _ _ -> assert false)
  44. let quoted_ident_prefix = "@$__hx__"
  45. let quote_ident s =
  46. try
  47. for i = 0 to String.length s - 1 do
  48. match String.unsafe_get s i with
  49. | 'a'..'z' | 'A'..'Z' | '_' -> ()
  50. | '0'..'9' when i > 0 -> ()
  51. | _ -> raise Exit
  52. done;
  53. if Hashtbl.mem Lexer.keywords s then raise Exit;
  54. s
  55. with Exit ->
  56. quoted_ident_prefix ^ s
  57. let cache = ref (DynArray.create())
  58. let last_doc = ref None
  59. let use_doc = ref false
  60. let resume_display = ref null_pos
  61. let in_macro = ref false
  62. let last_token s =
  63. let n = Stream.count s in
  64. DynArray.get (!cache) (if n = 0 then 0 else n - 1)
  65. let serror() = raise (Stream.Error "")
  66. let do_resume() = !resume_display <> null_pos
  67. let display e = raise (Display e)
  68. let is_resuming p =
  69. let p2 = !resume_display in
  70. p.pmax = p2.pmin && Common.unique_full_path p.pfile = p2.pfile
  71. let is_dollar_ident e = match fst e with
  72. | EConst (Ident n) when n.[0] = '$' ->
  73. true
  74. | _ ->
  75. false
  76. let precedence op =
  77. let left = true and right = false in
  78. match op with
  79. | OpMod -> 0, left
  80. | OpMult | OpDiv -> 1, left
  81. | OpAdd | OpSub -> 2, left
  82. | OpShl | OpShr | OpUShr -> 3, left
  83. | OpOr | OpAnd | OpXor -> 4, left
  84. | OpEq | OpNotEq | OpGt | OpLt | OpGte | OpLte -> 5, left
  85. | OpInterval -> 6, left
  86. | OpBoolAnd -> 7, left
  87. | OpBoolOr -> 8, left
  88. | OpArrow -> 9, right
  89. | OpAssign | OpAssignOp _ -> 10, right
  90. let is_not_assign = function
  91. | OpAssign | OpAssignOp _ -> false
  92. | _ -> true
  93. let swap op1 op2 =
  94. let p1, left1 = precedence op1 in
  95. let p2, _ = precedence op2 in
  96. left1 && p1 <= p2
  97. let rec make_binop op e ((v,p2) as e2) =
  98. match v with
  99. | EBinop (_op,_e,_e2) when swap op _op ->
  100. let _e = make_binop op e _e in
  101. EBinop (_op,_e,_e2) , punion (pos _e) (pos _e2)
  102. | ETernary (e1,e2,e3) when is_not_assign op ->
  103. let e = make_binop op e e1 in
  104. ETernary (e,e2,e3) , punion (pos e) (pos e3)
  105. | _ ->
  106. EBinop (op,e,e2) , punion (pos e) (pos e2)
  107. let rec make_unop op ((v,p2) as e) p1 =
  108. match v with
  109. | EBinop (bop,e,e2) -> EBinop (bop, make_unop op e p1 , e2) , (punion p1 p2)
  110. | ETernary (e1,e2,e3) -> ETernary (make_unop op e1 p1 , e2, e3), punion p1 p2
  111. | _ ->
  112. EUnop (op,Prefix,e), punion p1 p2
  113. let rec make_meta name params ((v,p2) as e) p1 =
  114. match v with
  115. | EBinop (bop,e,e2) -> EBinop (bop, make_meta name params e p1 , e2) , (punion p1 p2)
  116. | ETernary (e1,e2,e3) -> ETernary (make_meta name params e1 p1 , e2, e3), punion p1 p2
  117. | _ ->
  118. EMeta((name,params,p1),e),punion p1 p2
  119. let reify in_macro =
  120. let cur_pos = ref None in
  121. let mk_enum ename n vl p =
  122. let constr = (EConst (Ident n),p) in
  123. match vl with
  124. | [] -> constr
  125. | _ -> (ECall (constr,vl),p)
  126. in
  127. let to_const c p =
  128. let cst n v = mk_enum "Constant" n [EConst (String v),p] p in
  129. match c with
  130. | Int i -> cst "CInt" i
  131. | String s -> cst "CString" s
  132. | Float s -> cst "CFloat" s
  133. | Ident s -> cst "CIdent" s
  134. | Regexp (r,o) -> mk_enum "Constant" "CRegexp" [(EConst (String r),p);(EConst (String o),p)] p
  135. in
  136. let rec to_binop o p =
  137. let op n = mk_enum "Binop" n [] p in
  138. match o with
  139. | OpAdd -> op "OpAdd"
  140. | OpMult -> op "OpMult"
  141. | OpDiv -> op "OpDiv"
  142. | OpSub -> op "OpSub"
  143. | OpAssign -> op "OpAssign"
  144. | OpEq -> op "OpEq"
  145. | OpNotEq -> op "OpNotEq"
  146. | OpGt -> op "OpGt"
  147. | OpGte -> op "OpGte"
  148. | OpLt -> op "OpLt"
  149. | OpLte -> op "OpLte"
  150. | OpAnd -> op "OpAnd"
  151. | OpOr -> op "OpOr"
  152. | OpXor -> op "OpXor"
  153. | OpBoolAnd -> op "OpBoolAnd"
  154. | OpBoolOr -> op "OpBoolOr"
  155. | OpShl -> op "OpShl"
  156. | OpShr -> op "OpShr"
  157. | OpUShr -> op "OpUShr"
  158. | OpMod -> op "OpMod"
  159. | OpAssignOp o -> mk_enum "Binop" "OpAssignOp" [to_binop o p] p
  160. | OpInterval -> op "OpInterval"
  161. | OpArrow -> op "OpArrow"
  162. in
  163. let to_string s p =
  164. let len = String.length s in
  165. if len > 1 && s.[0] = '$' then
  166. (EConst (Ident (String.sub s 1 (len - 1))),p)
  167. else
  168. (EConst (String s),p)
  169. in
  170. let to_array f a p =
  171. (EArrayDecl (List.map (fun s -> f s p) a),p)
  172. in
  173. let to_null p =
  174. (EConst (Ident "null"),p)
  175. in
  176. let to_opt f v p =
  177. match v with
  178. | None -> to_null p
  179. | Some v -> f v p
  180. in
  181. let to_bool o p =
  182. (EConst (Ident (if o then "true" else "false")),p)
  183. in
  184. let to_obj fields p =
  185. (EObjectDecl fields,p)
  186. in
  187. let rec to_tparam t p =
  188. let n, v = (match t with
  189. | TPType t -> "TPType", to_ctype t p
  190. | TPExpr e -> "TPExpr", to_expr e p
  191. ) in
  192. mk_enum "TypeParam" n [v] p
  193. and to_tpath t p =
  194. let fields = [
  195. ("pack", to_array to_string t.tpackage p);
  196. ("name", to_string t.tname p);
  197. ("params", to_array to_tparam t.tparams p);
  198. ] in
  199. to_obj (match t.tsub with None -> fields | Some s -> fields @ ["sub",to_string s p]) p
  200. and to_ctype t p =
  201. let ct n vl = mk_enum "ComplexType" n vl p in
  202. match t with
  203. | CTPath { tpackage = []; tparams = []; tsub = None; tname = n } when n.[0] = '$' ->
  204. to_string n p
  205. | CTPath t -> ct "TPath" [to_tpath t p]
  206. | CTFunction (args,ret) -> ct "TFunction" [to_array to_ctype args p; to_ctype ret p]
  207. | CTAnonymous fields -> ct "TAnonymous" [to_array to_cfield fields p]
  208. | CTParent t -> ct "TParent" [to_ctype t p]
  209. | CTExtend (t,fields) -> ct "TExtend" [to_tpath t p; to_array to_cfield fields p]
  210. | CTOptional t -> ct "TOptional" [to_ctype t p]
  211. and to_fun f p =
  212. let farg (n,o,t,e) p =
  213. let fields = [
  214. "name", to_string n p;
  215. "opt", to_bool o p;
  216. "type", to_opt to_ctype t p;
  217. ] in
  218. to_obj (match e with None -> fields | Some e -> fields @ ["value",to_expr e p]) p
  219. in
  220. let rec fparam t p =
  221. let fields = [
  222. "name", to_string t.tp_name p;
  223. "constraints", to_array to_ctype t.tp_constraints p;
  224. "params", to_array fparam t.tp_params p;
  225. ] in
  226. to_obj fields p
  227. in
  228. let fields = [
  229. ("args",to_array farg f.f_args p);
  230. ("ret",to_opt to_ctype f.f_type p);
  231. ("expr",to_opt to_expr f.f_expr p);
  232. ("params",to_array fparam f.f_params p);
  233. ] in
  234. to_obj fields p
  235. and to_cfield f p =
  236. let p = f.cff_pos in
  237. let to_access a p =
  238. let n = (match a with
  239. | APublic -> "APublic"
  240. | APrivate -> "APrivate"
  241. | AStatic -> "AStatic"
  242. | AOverride -> "AOverride"
  243. | ADynamic -> "ADynamic"
  244. | AInline -> "AInline"
  245. | AMacro -> "AMacro"
  246. ) in
  247. mk_enum "Access" n [] p
  248. in
  249. let to_kind k =
  250. let n, vl = (match k with
  251. | FVar (ct,e) -> "FVar", [to_opt to_ctype ct p;to_opt to_expr e p]
  252. | FFun f -> "FFun", [to_fun f p]
  253. | FProp (get,set,t,e) -> "FProp", [to_string get p; to_string set p; to_opt to_ctype t p; to_opt to_expr e p]
  254. ) in
  255. mk_enum "FieldType" n vl p
  256. in
  257. let fields = [
  258. Some ("name", to_string f.cff_name p);
  259. (match f.cff_doc with None -> None | Some s -> Some ("doc", to_string s p));
  260. (match f.cff_access with [] -> None | l -> Some ("access", to_array to_access l p));
  261. Some ("kind", to_kind f.cff_kind);
  262. Some ("pos", to_pos f.cff_pos);
  263. (match f.cff_meta with [] -> None | l -> Some ("meta", to_meta f.cff_meta p));
  264. ] in
  265. let fields = List.rev (List.fold_left (fun acc v -> match v with None -> acc | Some e -> e :: acc) [] fields) in
  266. to_obj fields p
  267. and to_meta m p =
  268. to_array (fun (m,el,p) _ ->
  269. let fields = [
  270. "name", to_string (fst (Common.MetaInfo.to_string m)) p;
  271. "params", to_expr_array el p;
  272. "pos", to_pos p;
  273. ] in
  274. to_obj fields p
  275. ) m p
  276. and to_pos p =
  277. match !cur_pos with
  278. | Some p ->
  279. p
  280. | None ->
  281. let file = (EConst (String p.pfile),p) in
  282. let pmin = (EConst (Int (string_of_int p.pmin)),p) in
  283. let pmax = (EConst (Int (string_of_int p.pmax)),p) in
  284. if in_macro then
  285. (EUntyped (ECall ((EConst (Ident "$mk_pos"),p),[file;pmin;pmax]),p),p)
  286. else
  287. to_obj [("file",file);("min",pmin);("max",pmax)] p
  288. and to_expr_array a p = match a with
  289. | [EMeta ((Meta.Dollar "a",[],_),e1),_] -> (match fst e1 with EArrayDecl el -> to_expr_array el p | _ -> e1)
  290. | _ -> to_array to_expr a p
  291. and to_expr e _ =
  292. let p = snd e in
  293. let expr n vl =
  294. let e = mk_enum "ExprDef" n vl p in
  295. to_obj [("expr",e);("pos",to_pos p)] p
  296. in
  297. let loop e = to_expr e (snd e) in
  298. match fst e with
  299. | EConst (Ident n) when n.[0] = '$' && String.length n > 1 ->
  300. to_string n p
  301. | EConst c ->
  302. expr "EConst" [to_const c p]
  303. | EArray (e1,e2) ->
  304. expr "EArray" [loop e1;loop e2]
  305. | EBinop (op,e1,e2) ->
  306. expr "EBinop" [to_binop op p; loop e1; loop e2]
  307. | EField (e,s) ->
  308. expr "EField" [loop e; to_string s p]
  309. | EParenthesis e ->
  310. expr "EParenthesis" [loop e]
  311. | EObjectDecl fl ->
  312. expr "EObjectDecl" [to_array (fun (f,e) -> to_obj [("field",to_string f p);("expr",loop e)]) fl p]
  313. | EArrayDecl el ->
  314. expr "EArrayDecl" [to_expr_array el p]
  315. | ECall (e,el) ->
  316. expr "ECall" [loop e;to_expr_array el p]
  317. | ENew (t,el) ->
  318. expr "ENew" [to_tpath t p;to_expr_array el p]
  319. | EUnop (op,flag,e) ->
  320. let op = mk_enum "Unop" (match op with
  321. | Increment -> "OpIncrement"
  322. | Decrement -> "OpDecrement"
  323. | Not -> "OpNot"
  324. | Neg -> "OpNeg"
  325. | NegBits -> "OpNegBits"
  326. ) [] p in
  327. expr "EUnop" [op;to_bool (flag = Postfix) p;loop e]
  328. | EVars vl ->
  329. expr "EVars" [to_array (fun (v,t,e) p ->
  330. let fields = [
  331. "name", to_string v p;
  332. "type", to_opt to_ctype t p;
  333. "expr", to_opt to_expr e p;
  334. ] in
  335. to_obj fields p
  336. ) vl p]
  337. | EFunction (name,f) ->
  338. expr "EFunction" [to_opt to_string name p; to_fun f p]
  339. | EBlock el ->
  340. expr "EBlock" [to_expr_array el p]
  341. | EFor (e1,e2) ->
  342. expr "EFor" [loop e1;loop e2]
  343. | EIn (e1,e2) ->
  344. expr "EIn" [loop e1;loop e2]
  345. | EIf (e1,e2,eelse) ->
  346. expr "EIf" [loop e1;loop e2;to_opt to_expr eelse p]
  347. | EWhile (e1,e2,flag) ->
  348. expr "EWhile" [loop e1;loop e2;to_bool (flag = NormalWhile) p]
  349. | ESwitch (e1,cases,def) ->
  350. let scase (el,eg,e) p =
  351. to_obj [("values",to_expr_array el p);"guard",to_opt to_expr eg p;"expr",to_opt to_expr e p] p
  352. in
  353. expr "ESwitch" [loop e1;to_array scase cases p;to_opt (to_opt to_expr) def p]
  354. | ETry (e1,catches) ->
  355. let scatch (n,t,e) p =
  356. to_obj [("name",to_string n p);("type",to_ctype t p);("expr",loop e)] p
  357. in
  358. expr "ETry" [loop e1;to_array scatch catches p]
  359. | EReturn eo ->
  360. expr "EReturn" [to_opt to_expr eo p]
  361. | EBreak ->
  362. expr "EBreak" []
  363. | EContinue ->
  364. expr "EContinue" []
  365. | EUntyped e ->
  366. expr "EUntyped" [loop e]
  367. | EThrow e ->
  368. expr "EThrow" [loop e]
  369. | ECast (e,ct) ->
  370. expr "ECast" [loop e; to_opt to_ctype ct p]
  371. | EDisplay (e,flag) ->
  372. expr "EDisplay" [loop e; to_bool flag p]
  373. | EDisplayNew t ->
  374. expr "EDisplayNew" [to_tpath t p]
  375. | ETernary (e1,e2,e3) ->
  376. expr "ETernary" [loop e1;loop e2;loop e3]
  377. | ECheckType (e1,ct) ->
  378. expr "ECheckType" [loop e1; to_ctype ct p]
  379. | EMeta ((m,ml,p),e1) ->
  380. match m, ml with
  381. | Meta.Dollar ("" | "e"), _ ->
  382. e1
  383. | Meta.Dollar "a", _ ->
  384. expr "EArrayDecl" (match fst e1 with EArrayDecl el -> [to_expr_array el p] | _ -> [e1])
  385. | Meta.Dollar "b", _ ->
  386. expr "EBlock" [e1]
  387. (* TODO: can $v and $i be implemented better? *)
  388. | Meta.Dollar "v", _ ->
  389. (ECall ((EField ((EField ((EField ((EConst (Ident "haxe"),p),"macro"),p),"Context"),p),"makeExpr"),p),[e; to_pos (pos e)]),p)
  390. | Meta.Dollar "i", _ ->
  391. expr "EConst" [mk_enum "Constant" "CIdent" [e1] (pos e1)]
  392. | Meta.Dollar "p", _ ->
  393. (ECall ((EField ((EField ((EField ((EConst (Ident "haxe"),p),"macro"),p),"ExprTools"),p),"toFieldExpr"),p),[e]),p)
  394. | Meta.Custom ":pos", [pexpr] ->
  395. let old = !cur_pos in
  396. cur_pos := Some pexpr;
  397. let e = loop e1 in
  398. cur_pos := old;
  399. e
  400. | _ ->
  401. expr "EMeta" [to_obj [("name",to_string (fst (Common.MetaInfo.to_string m)) p);("params",to_expr_array ml p);("pos",to_pos p)] p;loop e1]
  402. and to_tparam_decl p t =
  403. to_obj [
  404. "name", to_string t.tp_name p;
  405. "params", (EArrayDecl (List.map (to_tparam_decl p) t.tp_params),p);
  406. "constraints", (EArrayDecl (List.map (fun t -> to_ctype t p) t.tp_constraints),p)
  407. ] p
  408. and to_type_def (t,p) =
  409. match t with
  410. | EClass d ->
  411. let ext = ref None and impl = ref [] and interf = ref false in
  412. List.iter (function
  413. | HExtern | HPrivate -> ()
  414. | HInterface -> interf := true;
  415. | HExtends t -> ext := Some (to_tpath t p)
  416. | HImplements i -> impl := (to_tpath i p) :: !impl
  417. ) d.d_flags;
  418. to_obj [
  419. "pack", (EArrayDecl [],p);
  420. "name", to_string d.d_name p;
  421. "pos", to_pos p;
  422. "meta", to_meta d.d_meta p;
  423. "params", (EArrayDecl (List.map (to_tparam_decl p) d.d_params),p);
  424. "isExtern", to_bool (List.mem HExtern d.d_flags) p;
  425. "kind", mk_enum "TypeDefKind" "TDClass" [(match !ext with None -> (EConst (Ident "null"),p) | Some t -> t);(EArrayDecl (List.rev !impl),p);to_bool !interf p] p;
  426. "fields", (EArrayDecl (List.map (fun f -> to_cfield f p) d.d_data),p)
  427. ] p
  428. | _ -> assert false
  429. in
  430. (fun e -> to_expr e (snd e)), to_ctype, to_type_def
  431. let popt f = parser
  432. | [< v = f >] -> Some v
  433. | [< >] -> None
  434. let rec plist f = parser
  435. | [< v = f; l = plist f >] -> v :: l
  436. | [< >] -> []
  437. let rec psep sep f = parser
  438. | [< v = f; s >] ->
  439. let rec loop = parser
  440. | [< '(sep2,_) when sep2 = sep; v = f; l = loop >] -> v :: l
  441. | [< >] -> []
  442. in
  443. v :: loop s
  444. | [< >] -> []
  445. let ident = parser
  446. | [< '(Const (Ident i),p) >] -> i,p
  447. let dollar_ident = parser
  448. | [< '(Const (Ident i),p) >] -> i,p
  449. | [< '(Dollar i,p) >] -> ("$" ^ i),p
  450. let dollar_ident_macro pack = parser
  451. | [< '(Const (Ident i),p) >] -> i,p
  452. | [< '(Dollar i,p) >] -> ("$" ^ i),p
  453. | [< '(Kwd Macro,p) when pack <> [] >] -> "macro", p
  454. let lower_ident_or_macro = parser
  455. | [< '(Const (Ident i),p) when is_lower_ident i >] -> i
  456. | [< '(Kwd Macro,_) >] -> "macro"
  457. let any_enum_ident = parser
  458. | [< i = ident >] -> i
  459. | [< '(Kwd k,p) when Filename.basename p.pfile = "StdTypes.hx" >] -> s_keyword k, p
  460. let property_ident = parser
  461. | [< i, _ = ident >] -> i
  462. | [< '(Kwd Dynamic,_) >] -> "dynamic"
  463. | [< '(Kwd Default,_) >] -> "default"
  464. | [< '(Kwd Null,_) >] -> "null"
  465. let get_doc s =
  466. (* do the peek first to make sure we fetch the doc *)
  467. match Stream.peek s with
  468. | None -> None
  469. | Some (tk,p) ->
  470. match !last_doc with
  471. | None -> None
  472. | Some (d,pos) ->
  473. last_doc := None;
  474. if pos = p.pmin then Some d else None
  475. let comma = parser
  476. | [< '(Comma,_) >] -> ()
  477. let semicolon s =
  478. if fst (last_token s) = BrClose then
  479. match s with parser
  480. | [< '(Semicolon,p) >] -> p
  481. | [< >] -> snd (last_token s)
  482. else
  483. match s with parser
  484. | [< '(Semicolon,p) >] -> p
  485. | [< s >] ->
  486. let pos = snd (last_token s) in
  487. if do_resume() then pos else error Missing_semicolon pos
  488. let rec parse_file s =
  489. last_doc := None;
  490. match s with parser
  491. | [< '(Kwd Package,_); p = parse_package; _ = semicolon; l = parse_type_decls p []; '(Eof,_) >] -> p , l
  492. | [< l = parse_type_decls [] []; '(Eof,_) >] -> [] , l
  493. and parse_type_decls pack acc s =
  494. try
  495. match s with parser
  496. | [< v = parse_type_decl; l = parse_type_decls pack (v :: acc) >] -> l
  497. | [< >] -> List.rev acc
  498. with TypePath ([],Some (name,false)) ->
  499. (* resolve imports *)
  500. List.iter (fun d ->
  501. match fst d with
  502. | EImport (t,_) ->
  503. (match List.rev t with
  504. | (n,_) :: path when n = name && List.for_all (fun (i,_) -> is_lower_ident i) path -> raise (TypePath (List.map fst (List.rev path),Some (name,false)))
  505. | _ -> ())
  506. | _ -> ()
  507. ) acc;
  508. raise (TypePath (pack,Some(name,true)))
  509. and parse_type_decl s =
  510. match s with parser
  511. | [< '(Kwd Import,p1) >] -> parse_import s p1
  512. | [< '(Kwd Using,p1); t = parse_type_path; p2 = semicolon >] -> EUsing t, punion p1 p2
  513. | [< doc = get_doc; meta = parse_meta; c = parse_common_flags; s >] ->
  514. match s with parser
  515. | [< n , p1 = parse_enum_flags; name = type_name; tl = parse_constraint_params; '(BrOpen,_); l = plist parse_enum; '(BrClose,p2) >] ->
  516. (EEnum {
  517. d_name = name;
  518. d_doc = doc;
  519. d_meta = meta;
  520. d_params = tl;
  521. d_flags = List.map snd c @ n;
  522. d_data = l
  523. }, punion p1 p2)
  524. | [< n , p1 = parse_class_flags; name = type_name; tl = parse_constraint_params; hl = plist parse_class_herit; '(BrOpen,_); fl, p2 = parse_class_fields false p1 >] ->
  525. (EClass {
  526. d_name = name;
  527. d_doc = doc;
  528. d_meta = meta;
  529. d_params = tl;
  530. d_flags = List.map fst c @ n @ hl;
  531. d_data = fl;
  532. }, punion p1 p2)
  533. | [< '(Kwd Typedef,p1); name = type_name; tl = parse_constraint_params; '(Binop OpAssign,p2); t = parse_complex_type; s >] ->
  534. (match s with parser
  535. | [< '(Semicolon,_) >] -> ()
  536. | [< >] -> ());
  537. (ETypedef {
  538. d_name = name;
  539. d_doc = doc;
  540. d_meta = meta;
  541. d_params = tl;
  542. d_flags = List.map snd c;
  543. d_data = t;
  544. }, punion p1 p2)
  545. | [< '(Kwd Abstract,p1); name = type_name; tl = parse_constraint_params; st = parse_abstract_subtype; sl = plist parse_abstract_relations; '(BrOpen,_); fl, p2 = parse_class_fields false p1 >] ->
  546. let flags = List.map (fun (_,c) -> match c with EPrivate -> APrivAbstract | EExtern -> error (Custom "extern abstract not allowed") p1) c in
  547. let flags = (match st with None -> flags | Some t -> AIsType t :: flags) in
  548. (EAbstract {
  549. d_name = name;
  550. d_doc = doc;
  551. d_meta = meta;
  552. d_params = tl;
  553. d_flags = flags @ sl;
  554. d_data = fl;
  555. },punion p1 p2)
  556. and parse_class doc meta cflags need_name s =
  557. let opt_name = if need_name then type_name else (fun s -> match popt type_name s with None -> "" | Some n -> n) in
  558. match s with parser
  559. | [< n , p1 = parse_class_flags; name = opt_name; tl = parse_constraint_params; hl = psep Comma parse_class_herit; '(BrOpen,_); fl, p2 = parse_class_fields false p1 >] ->
  560. (EClass {
  561. d_name = name;
  562. d_doc = doc;
  563. d_meta = meta;
  564. d_params = tl;
  565. d_flags = List.map fst cflags @ n @ hl;
  566. d_data = fl;
  567. }, punion p1 p2)
  568. and parse_import s p1 =
  569. let rec loop acc =
  570. match s with parser
  571. | [< '(Dot,p) >] ->
  572. if is_resuming p then raise (TypePath (List.rev (List.map fst acc),None));
  573. (match s with parser
  574. | [< '(Const (Ident k),p) >] ->
  575. loop ((k,p) :: acc)
  576. | [< '(Kwd Macro,p) >] ->
  577. loop (("macro",p) :: acc)
  578. | [< '(Binop OpMult,_); '(Semicolon,p2) >] ->
  579. p2, List.rev acc, IAll
  580. | [< '(Binop OpOr,_) when do_resume() >] ->
  581. raise (TypePath (List.rev (List.map fst acc),None))
  582. | [< >] ->
  583. serror());
  584. | [< '(Semicolon,p2) >] ->
  585. p2, List.rev acc, INormal
  586. | [< '(Kwd In,_); '(Const (Ident name),_); '(Semicolon,p2) >] ->
  587. p2, List.rev acc, IAsName name
  588. | [< >] ->
  589. serror()
  590. in
  591. let p2, path, mode = (match s with parser
  592. | [< '(Const (Ident name),p) >] -> loop [name,p]
  593. | [< >] -> serror()
  594. ) in
  595. (EImport (path,mode),punion p1 p2)
  596. and parse_abstract_relations s =
  597. match s with parser
  598. | [< '(Const (Ident "to"),_); t = parse_complex_type >] -> AToType t
  599. | [< '(Const (Ident "from"),_); t = parse_complex_type >] -> AFromType t
  600. and parse_abstract_subtype s =
  601. match s with parser
  602. | [< '(POpen, _); t = parse_complex_type; '(PClose,_) >] -> Some t
  603. | [< >] -> None
  604. and parse_package s = psep Dot lower_ident_or_macro s
  605. and parse_class_fields tdecl p1 s =
  606. let l = parse_class_field_resume tdecl s in
  607. let p2 = (match s with parser
  608. | [< '(BrClose,p2) >] -> p2
  609. | [< >] -> if do_resume() then p1 else serror()
  610. ) in
  611. l, p2
  612. and parse_class_field_resume tdecl s =
  613. if not (do_resume()) then
  614. plist parse_class_field s
  615. else try
  616. let c = parse_class_field s in
  617. c :: parse_class_field_resume tdecl s
  618. with Stream.Error _ | Stream.Failure ->
  619. (* look for next variable/function or next type declaration *)
  620. let rec junk k =
  621. if k <= 0 then () else begin
  622. Stream.junk s;
  623. junk (k - 1);
  624. end
  625. in
  626. (*
  627. walk back tokens which are prefixing a type/field declaration
  628. *)
  629. let rec junk_tokens k =
  630. if k = 0 then
  631. ()
  632. else match List.rev_map fst (Stream.npeek k s) with
  633. | Kwd Private :: _ -> junk_tokens (k - 1)
  634. | (Const (Ident _) | Kwd _) :: DblDot :: At :: l
  635. | (Const (Ident _) | Kwd _) :: At :: l ->
  636. junk_tokens (List.length l)
  637. | PClose :: l ->
  638. (* count matching parenthesises for metadata call *)
  639. let rec loop n = function
  640. | [] -> []
  641. | POpen :: l -> if n = 0 then l else loop (n - 1) l
  642. | PClose :: l -> loop (n + 1) l
  643. | _ :: l -> loop n l
  644. in
  645. (match loop 0 l with
  646. | (Const (Ident _) | Kwd _) :: At :: l
  647. | (Const (Ident _) | Kwd _) :: DblDot :: At :: l -> junk_tokens (List.length l)
  648. | _ ->
  649. junk k)
  650. | _ ->
  651. junk k
  652. in
  653. let rec loop k =
  654. match List.rev_map fst (Stream.npeek k s) with
  655. (* field declaration *)
  656. | Const _ :: Kwd Function :: _
  657. | Kwd New :: Kwd Function :: _ ->
  658. junk_tokens (k - 2);
  659. parse_class_field_resume tdecl s
  660. | Kwd Macro :: _ | Kwd Public :: _ | Kwd Static :: _ | Kwd Var :: _ | Kwd Override :: _ | Kwd Dynamic :: _ | Kwd Inline :: _ ->
  661. junk_tokens (k - 1);
  662. parse_class_field_resume tdecl s
  663. | BrClose :: _ when tdecl ->
  664. junk_tokens (k - 1);
  665. []
  666. (* type declaration *)
  667. | Eof :: _ | Kwd Import :: _ | Kwd Using :: _ | Kwd Extern :: _ | Kwd Class :: _ | Kwd Interface :: _ | Kwd Enum :: _ | Kwd Typedef :: _ | Kwd Abstract :: _->
  668. junk_tokens (k - 1);
  669. []
  670. | [] ->
  671. []
  672. | _ ->
  673. loop (k + 1)
  674. in
  675. loop 1
  676. and parse_common_flags = parser
  677. | [< '(Kwd Private,_); l = parse_common_flags >] -> (HPrivate, EPrivate) :: l
  678. | [< '(Kwd Extern,_); l = parse_common_flags >] -> (HExtern, EExtern) :: l
  679. | [< >] -> []
  680. and parse_meta_params pname s = match s with parser
  681. | [< '(POpen,p) when p.pmin = pname.pmax; params = psep Comma expr; '(PClose,_); >] -> params
  682. | [< >] -> []
  683. and parse_meta_entry = parser
  684. [< '(At,_); name,p = meta_name; params = parse_meta_params p; s >] -> (name,params,p)
  685. and parse_meta = parser
  686. | [< entry = parse_meta_entry; s >] ->
  687. entry :: parse_meta s
  688. | [< >] -> []
  689. and meta_name = parser
  690. | [< '(Const (Ident i),p) >] -> (Meta.Custom i), p
  691. | [< '(Kwd k,p) >] -> (Meta.Custom (s_keyword k)),p
  692. | [< '(DblDot,_); s >] -> match s with parser
  693. | [< '(Const (Ident i),p) >] -> (Common.MetaInfo.parse i), p
  694. | [< '(Kwd k,p) >] -> (Common.MetaInfo.parse (s_keyword k)),p
  695. and parse_enum_flags = parser
  696. | [< '(Kwd Enum,p) >] -> [] , p
  697. and parse_class_flags = parser
  698. | [< '(Kwd Class,p) >] -> [] , p
  699. | [< '(Kwd Interface,p) >] -> [HInterface] , p
  700. and parse_type_opt = parser
  701. | [< '(DblDot,_); t = parse_complex_type >] -> Some t
  702. | [< >] -> None
  703. and parse_complex_type s =
  704. let t = parse_complex_type_inner s in
  705. parse_complex_type_next t s
  706. and parse_complex_type_inner = parser
  707. | [< '(POpen,_); t = parse_complex_type; '(PClose,_) >] -> CTParent t
  708. | [< '(BrOpen,p1); s >] ->
  709. (match s with parser
  710. | [< l = parse_type_anonymous false >] -> CTAnonymous l
  711. | [< '(Binop OpGt,_); t = parse_type_path; '(Comma,_); s >] ->
  712. (match s with parser
  713. | [< l = parse_type_anonymous false >] -> CTExtend (t,l)
  714. | [< l, _ = parse_class_fields true p1 >] -> CTExtend (t,l)
  715. | [< >] -> serror())
  716. | [< l, _ = parse_class_fields true p1 >] -> CTAnonymous l
  717. | [< >] -> serror())
  718. | [< '(Question,_); t = parse_complex_type_inner >] ->
  719. CTOptional t
  720. | [< t = parse_type_path >] ->
  721. CTPath t
  722. and parse_type_path s = parse_type_path1 [] s
  723. and parse_type_path1 pack = parser
  724. | [< name, p = dollar_ident_macro pack; s >] ->
  725. if is_lower_ident name then
  726. (match s with parser
  727. | [< '(Dot,p) >] ->
  728. if is_resuming p then
  729. raise (TypePath (List.rev (name :: pack),None))
  730. else
  731. parse_type_path1 (name :: pack) s
  732. | [< '(Semicolon,_) >] ->
  733. error (Custom "Type name should start with an uppercase letter") p
  734. | [< >] -> serror())
  735. else
  736. let sub = (match s with parser
  737. | [< '(Dot,p); s >] ->
  738. (if is_resuming p then
  739. raise (TypePath (List.rev pack,Some (name,false)))
  740. else match s with parser
  741. | [< '(Const (Ident name),_) when not (is_lower_ident name) >] -> Some name
  742. | [< '(Binop OpOr,_) when do_resume() >] ->
  743. raise (TypePath (List.rev pack,Some (name,false)))
  744. | [< >] -> serror())
  745. | [< >] -> None
  746. ) in
  747. let params = (match s with parser
  748. | [< '(Binop OpLt,_); l = psep Comma parse_type_path_or_const; '(Binop OpGt,_) >] -> l
  749. | [< >] -> []
  750. ) in
  751. {
  752. tpackage = List.rev pack;
  753. tname = name;
  754. tparams = params;
  755. tsub = sub;
  756. }
  757. | [< '(Binop OpOr,_) when do_resume() >] ->
  758. raise (TypePath (List.rev pack,None))
  759. and type_name = parser
  760. | [< '(Const (Ident name),p) >] ->
  761. if is_lower_ident name then
  762. error (Custom "Type name should start with an uppercase letter") p
  763. else
  764. name
  765. and parse_type_path_or_const = parser
  766. (* we can't allow (expr) here *)
  767. | [< '(BkOpen,p1); l = parse_array_decl; '(BkClose,p2); s >] -> TPExpr (EArrayDecl l, punion p1 p2)
  768. | [< t = parse_complex_type >] -> TPType t
  769. | [< '(Const c,p) >] -> TPExpr (EConst c,p)
  770. | [< e = expr >] -> TPExpr e
  771. | [< >] -> serror()
  772. and parse_complex_type_next t = parser
  773. | [< '(Arrow,_); t2 = parse_complex_type >] ->
  774. (match t2 with
  775. | CTFunction (args,r) ->
  776. CTFunction (t :: args,r)
  777. | _ ->
  778. CTFunction ([t] , t2))
  779. | [< >] -> t
  780. and parse_type_anonymous opt = parser
  781. | [< '(Question,_) when not opt; s >] -> parse_type_anonymous true s
  782. | [< name, p1 = ident; '(DblDot,_); t = parse_complex_type; s >] ->
  783. let next p2 acc =
  784. let t = if not opt then t else (match t with
  785. | CTPath { tpackage = []; tname = "Null" } -> t
  786. | _ -> CTPath { tpackage = []; tname = "Null"; tsub = None; tparams = [TPType t] }
  787. ) in
  788. {
  789. cff_name = name;
  790. cff_meta = if opt then [Meta.Optional,[],p1] else [];
  791. cff_access = [];
  792. cff_doc = None;
  793. cff_kind = FVar (Some t,None);
  794. cff_pos = punion p1 p2;
  795. } :: acc
  796. in
  797. match s with parser
  798. | [< '(BrClose,p2) >] -> next p2 []
  799. | [< '(Comma,p2) >] ->
  800. (match s with parser
  801. | [< '(BrClose,_) >] -> next p2 []
  802. | [< l = parse_type_anonymous false >] -> next p2 l
  803. | [< >] -> serror());
  804. | [< >] -> serror()
  805. and parse_enum s =
  806. let doc = get_doc s in
  807. let meta = parse_meta s in
  808. match s with parser
  809. | [< name, p1 = any_enum_ident; params = parse_constraint_params; s >] ->
  810. let args = (match s with parser
  811. | [< '(POpen,_); l = psep Comma parse_enum_param; '(PClose,_) >] -> l
  812. | [< >] -> []
  813. ) in
  814. let t = (match s with parser
  815. | [< '(DblDot,_); t = parse_complex_type >] -> Some t
  816. | [< >] -> None
  817. ) in
  818. let p2 = (match s with parser
  819. | [< p = semicolon >] -> p
  820. | [< >] -> serror()
  821. ) in
  822. {
  823. ec_name = name;
  824. ec_doc = doc;
  825. ec_meta = meta;
  826. ec_args = args;
  827. ec_params = params;
  828. ec_type = t;
  829. ec_pos = punion p1 p2;
  830. }
  831. and parse_enum_param = parser
  832. | [< '(Question,_); name, _ = ident; '(DblDot,_); t = parse_complex_type >] -> (name,true,t)
  833. | [< name, _ = ident; '(DblDot,_); t = parse_complex_type >] -> (name,false,t)
  834. and parse_class_field s =
  835. let doc = get_doc s in
  836. match s with parser
  837. | [< meta = parse_meta; al = parse_cf_rights true []; s >] ->
  838. let name, pos, k = (match s with parser
  839. | [< '(Kwd Var,p1); name, _ = ident; s >] ->
  840. (match s with parser
  841. | [< '(POpen,_); i1 = property_ident; '(Comma,_); i2 = property_ident; '(PClose,_) >] ->
  842. let t = (match s with parser
  843. | [< '(DblDot,_); t = parse_complex_type >] -> Some t
  844. | [< >] -> None
  845. ) in
  846. let e , p2 = (match s with parser
  847. | [< '(Binop OpAssign,_); e = toplevel_expr; p2 = semicolon >] -> Some e , p2
  848. | [< '(Semicolon,p2) >] -> None , p2
  849. | [< >] -> serror()
  850. ) in
  851. name, punion p1 p2, FProp (i1,i2,t, e)
  852. | [< t = parse_type_opt; s >] ->
  853. let e , p2 = (match s with parser
  854. | [< '(Binop OpAssign,_); e = toplevel_expr; p2 = semicolon >] -> Some e , p2
  855. | [< '(Semicolon,p2) >] -> None , p2
  856. | [< >] -> serror()
  857. ) in
  858. name, punion p1 p2, FVar (t,e))
  859. | [< '(Kwd Function,p1); name = parse_fun_name; pl = parse_constraint_params; '(POpen,_); al = psep Comma parse_fun_param; '(PClose,_); t = parse_type_opt; s >] ->
  860. let e, p2 = (match s with parser
  861. | [< e = toplevel_expr; s >] ->
  862. (try ignore(semicolon s) with Error (Missing_semicolon,p) -> !display_error Missing_semicolon p);
  863. Some e, pos e
  864. | [< '(Semicolon,p) >] -> None, p
  865. | [< >] -> serror()
  866. ) in
  867. let f = {
  868. f_params = pl;
  869. f_args = al;
  870. f_type = t;
  871. f_expr = e;
  872. } in
  873. name, punion p1 p2, FFun f
  874. | [< >] ->
  875. if al = [] then raise Stream.Failure else serror()
  876. ) in
  877. {
  878. cff_name = name;
  879. cff_doc = doc;
  880. cff_meta = meta;
  881. cff_access = al;
  882. cff_pos = pos;
  883. cff_kind = k;
  884. }
  885. and parse_cf_rights allow_static l = parser
  886. | [< '(Kwd Static,_) when allow_static; l = parse_cf_rights false (AStatic :: l) >] -> l
  887. | [< '(Kwd Macro,_) when not(List.mem AMacro l); l = parse_cf_rights allow_static (AMacro :: l) >] -> l
  888. | [< '(Kwd Public,_) when not(List.mem APublic l || List.mem APrivate l); l = parse_cf_rights allow_static (APublic :: l) >] -> l
  889. | [< '(Kwd Private,_) when not(List.mem APublic l || List.mem APrivate l); l = parse_cf_rights allow_static (APrivate :: l) >] -> l
  890. | [< '(Kwd Override,_) when not (List.mem AOverride l); l = parse_cf_rights false (AOverride :: l) >] -> l
  891. | [< '(Kwd Dynamic,_) when not (List.mem ADynamic l); l = parse_cf_rights allow_static (ADynamic :: l) >] -> l
  892. | [< '(Kwd Inline,_); l = parse_cf_rights allow_static (AInline :: l) >] -> l
  893. | [< >] -> l
  894. and parse_fun_name = parser
  895. | [< '(Const (Ident name),_) >] -> name
  896. | [< '(Kwd New,_) >] -> "new"
  897. and parse_fun_param = parser
  898. | [< '(Question,_); name, _ = ident; t = parse_type_opt; c = parse_fun_param_value >] -> (name,true,t,c)
  899. | [< name, _ = ident; t = parse_type_opt; c = parse_fun_param_value >] -> (name,false,t,c)
  900. and parse_fun_param_value = parser
  901. | [< '(Binop OpAssign,_); e = toplevel_expr >] -> Some e
  902. | [< >] -> None
  903. and parse_fun_param_type = parser
  904. | [< '(Question,_); name = ident; '(DblDot,_); t = parse_complex_type >] -> (name,true,t)
  905. | [< name = ident; '(DblDot,_); t = parse_complex_type >] -> (name,false,t)
  906. and parse_constraint_params = parser
  907. | [< '(Binop OpLt,_); l = psep Comma parse_constraint_param; '(Binop OpGt,_) >] -> l
  908. | [< >] -> []
  909. and parse_constraint_param = parser
  910. | [< name = type_name; s >] ->
  911. let params = (match s with parser
  912. | [< >] -> []
  913. ) in
  914. let ctl = (match s with parser
  915. | [< '(DblDot,_); s >] ->
  916. (match s with parser
  917. | [< '(POpen,_); l = psep Comma parse_complex_type; '(PClose,_) >] -> l
  918. | [< t = parse_complex_type >] -> [t]
  919. | [< >] -> serror())
  920. | [< >] -> []
  921. ) in
  922. {
  923. tp_name = name;
  924. tp_params = params;
  925. tp_constraints = ctl;
  926. }
  927. and parse_class_herit = parser
  928. | [< '(Kwd Extends,_); t = parse_type_path >] -> HExtends t
  929. | [< '(Kwd Implements,_); t = parse_type_path >] -> HImplements t
  930. and block1 = parser
  931. | [< '(Const (Ident name),p); s >] -> block2 name (Ident name) p s
  932. | [< '(Const (String name),p); s >] -> block2 (quote_ident name) (String name) p s
  933. | [< b = block [] >] -> EBlock b
  934. and block2 name ident p s =
  935. match s with parser
  936. | [< '(DblDot,_); e = expr; l = parse_obj_decl >] -> EObjectDecl ((name,e) :: l)
  937. | [< >] ->
  938. let e = expr_next (EConst ident,p) s in
  939. try
  940. let _ = semicolon s in
  941. let b = block [e] s in
  942. EBlock b
  943. with
  944. | Error (err,p) ->
  945. (!display_error) err p;
  946. EBlock (block [e] s)
  947. and block acc s =
  948. try
  949. (* because of inner recursion, we can't put Display handling in errors below *)
  950. let e = try parse_block_elt s with Display e -> display (EBlock (List.rev (e :: acc)),snd e) in
  951. block (e :: acc) s
  952. with
  953. | Stream.Failure ->
  954. List.rev acc
  955. | Stream.Error _ ->
  956. let tk , pos = (match Stream.peek s with None -> last_token s | Some t -> t) in
  957. (!display_error) (Unexpected tk) pos;
  958. block acc s
  959. | Error (e,p) ->
  960. (!display_error) e p;
  961. block acc s
  962. and parse_block_elt = parser
  963. | [< '(Kwd Var,p1); vl = psep Comma parse_var_decl; p2 = semicolon >] -> (EVars vl,punion p1 p2)
  964. | [< e = expr; _ = semicolon >] -> e
  965. and parse_obj_decl = parser
  966. | [< '(Comma,_); s >] ->
  967. (match s with parser
  968. | [< name, _ = ident; '(DblDot,_); e = expr; l = parse_obj_decl >] -> (name,e) :: l
  969. | [< '(Const (String name),_); '(DblDot,_); e = expr; l = parse_obj_decl >] -> (quote_ident name,e) :: l
  970. | [< >] -> [])
  971. | [< >] -> []
  972. and parse_array_decl = parser
  973. | [< e = expr; s >] ->
  974. (match s with parser
  975. | [< '(Comma,_); l = parse_array_decl >] -> e :: l
  976. | [< >] -> [e])
  977. | [< >] ->
  978. []
  979. and parse_var_decl = parser
  980. | [< name, _ = dollar_ident; t = parse_type_opt; s >] ->
  981. match s with parser
  982. | [< '(Binop OpAssign,_); e = expr >] -> (name,t,Some e)
  983. | [< >] -> (name,t,None)
  984. and inline_function = parser
  985. | [< '(Kwd Inline,_); '(Kwd Function,p1) >] -> true, p1
  986. | [< '(Kwd Function,p1) >] -> false, p1
  987. and reify_expr e =
  988. let to_expr,_,_ = reify !in_macro in
  989. let e = to_expr e in
  990. (ECheckType (e,(CTPath { tpackage = ["haxe";"macro"]; tname = "Expr"; tsub = None; tparams = [] })),pos e)
  991. and parse_macro_expr p = parser
  992. | [< '(DblDot,_); t = parse_complex_type >] ->
  993. let _, to_type, _ = reify !in_macro in
  994. let t = to_type t p in
  995. (ECheckType (t,(CTPath { tpackage = ["haxe";"macro"]; tname = "Expr"; tsub = Some "ComplexType"; tparams = [] })),p)
  996. | [< '(Kwd Var,p1); vl = psep Comma parse_var_decl >] ->
  997. reify_expr (EVars vl,p1)
  998. | [< d = parse_class None [] [] false >] ->
  999. let _,_,to_type = reify !in_macro in
  1000. (ECheckType (to_type d,(CTPath { tpackage = ["haxe";"macro"]; tname = "Expr"; tsub = Some "TypeDefinition"; tparams = [] })),p)
  1001. | [< e = secure_expr >] ->
  1002. reify_expr e
  1003. and expr = parser
  1004. | [< (name,params,p) = parse_meta_entry; s >] ->
  1005. (try
  1006. make_meta name params (secure_expr s) p
  1007. with Display e ->
  1008. display (make_meta name params e p))
  1009. | [< '(BrOpen,p1); b = block1; '(BrClose,p2); s >] ->
  1010. let e = (b,punion p1 p2) in
  1011. (match b with
  1012. | EObjectDecl _ -> expr_next e s
  1013. | _ -> e)
  1014. | [< '(Kwd Macro,p); s >] ->
  1015. parse_macro_expr p s
  1016. | [< '(Kwd Var,p1); v = parse_var_decl >] -> (EVars [v],p1)
  1017. | [< '(Const c,p); s >] -> expr_next (EConst c,p) s
  1018. | [< '(Kwd This,p); s >] -> expr_next (EConst (Ident "this"),p) s
  1019. | [< '(Kwd True,p); s >] -> expr_next (EConst (Ident "true"),p) s
  1020. | [< '(Kwd False,p); s >] -> expr_next (EConst (Ident "false"),p) s
  1021. | [< '(Kwd Null,p); s >] -> expr_next (EConst (Ident "null"),p) s
  1022. | [< '(Kwd Cast,p1); s >] ->
  1023. (match s with parser
  1024. | [< '(POpen,_); e = expr; s >] ->
  1025. (match s with parser
  1026. | [< '(Comma,_); t = parse_complex_type; '(PClose,p2); s >] -> expr_next (ECast (e,Some t),punion p1 p2) s
  1027. | [< '(PClose,p2); s >] -> expr_next (ECast (e,None),punion p1 (pos e)) s
  1028. | [< >] -> serror())
  1029. | [< e = secure_expr >] -> expr_next (ECast (e,None),punion p1 (pos e)) s)
  1030. | [< '(Kwd Throw,p); e = expr >] -> (EThrow e,p)
  1031. | [< '(Kwd New,p1); t = parse_type_path; '(POpen,p); s >] ->
  1032. if is_resuming p then display (EDisplayNew t,punion p1 p);
  1033. (match s with parser
  1034. | [< al = psep Comma expr; '(PClose,p2); s >] -> expr_next (ENew (t,al),punion p1 p2) s
  1035. | [< >] -> serror())
  1036. | [< '(POpen,p1); e = expr; '(PClose,p2); s >] -> expr_next (EParenthesis e, punion p1 p2) s
  1037. | [< '(BkOpen,p1); l = parse_array_decl; '(BkClose,p2); s >] -> expr_next (EArrayDecl l, punion p1 p2) s
  1038. | [< inl, p1 = inline_function; name = popt dollar_ident; pl = parse_constraint_params; '(POpen,_); al = psep Comma parse_fun_param; '(PClose,_); t = parse_type_opt; s >] ->
  1039. let make e =
  1040. let f = {
  1041. f_params = pl;
  1042. f_type = t;
  1043. f_args = al;
  1044. f_expr = Some e;
  1045. } in
  1046. EFunction ((match name with None -> None | Some (name,_) -> Some (if inl then "inline_" ^ name else name)),f), punion p1 (pos e)
  1047. in
  1048. (try
  1049. expr_next (make (secure_expr s)) s
  1050. with
  1051. Display e -> display (make e))
  1052. | [< '(Unop op,p1) when is_prefix op; e = expr >] -> make_unop op e p1
  1053. | [< '(Binop OpSub,p1); e = expr >] ->
  1054. let neg s =
  1055. if s.[0] = '-' then String.sub s 1 (String.length s - 1) else "-" ^ s
  1056. in
  1057. (match make_unop Neg e p1 with
  1058. | EUnop (Neg,Prefix,(EConst (Int i),pc)),p -> EConst (Int (neg i)),p
  1059. | EUnop (Neg,Prefix,(EConst (Float j),pc)),p -> EConst (Float (neg j)),p
  1060. | e -> e)
  1061. (*/* removed unary + : this cause too much syntax errors go unnoticed, such as "a + + 1" (missing 'b')
  1062. without adding anything to the language
  1063. | [< '(Binop OpAdd,p1); s >] ->
  1064. (match s with parser
  1065. | [< '(Const (Int i),p); e = expr_next (EConst (Int i),p) >] -> e
  1066. | [< '(Const (Float f),p); e = expr_next (EConst (Float f),p) >] -> e
  1067. | [< >] -> serror()) */*)
  1068. | [< '(Kwd For,p); '(POpen,_); it = expr; '(PClose,_); s >] ->
  1069. (try
  1070. let e = secure_expr s in
  1071. (EFor (it,e),punion p (pos e))
  1072. with
  1073. Display e -> display (EFor (it,e),punion p (pos e)))
  1074. | [< '(Kwd If,p); '(POpen,_); cond = expr; '(PClose,_); e1 = expr; s >] ->
  1075. let e2 = (match s with parser
  1076. | [< '(Kwd Else,_); e2 = expr; s >] -> Some e2
  1077. | [< >] ->
  1078. match Stream.npeek 2 s with
  1079. | [(Semicolon,_); (Kwd Else,_)] ->
  1080. Stream.junk s;
  1081. Stream.junk s;
  1082. Some (secure_expr s)
  1083. | _ ->
  1084. None
  1085. ) in
  1086. (EIf (cond,e1,e2), punion p (match e2 with None -> pos e1 | Some e -> pos e))
  1087. | [< '(Kwd Return,p); e = popt expr >] -> (EReturn e, match e with None -> p | Some e -> punion p (pos e))
  1088. | [< '(Kwd Break,p) >] -> (EBreak,p)
  1089. | [< '(Kwd Continue,p) >] -> (EContinue,p)
  1090. | [< '(Kwd While,p1); '(POpen,_); cond = expr; '(PClose,_); s >] ->
  1091. (try
  1092. let e = secure_expr s in
  1093. (EWhile (cond,e,NormalWhile),punion p1 (pos e))
  1094. with
  1095. Display e -> display (EWhile (cond,e,NormalWhile),punion p1 (pos e)))
  1096. | [< '(Kwd Do,p1); e = expr; '(Kwd While,_); '(POpen,_); cond = expr; '(PClose,_); s >] -> (EWhile (cond,e,DoWhile),punion p1 (pos e))
  1097. | [< '(Kwd Switch,p1); e = expr; '(BrOpen,_); cases , def = parse_switch_cases e []; '(BrClose,p2); s >] -> (ESwitch (e,cases,def),punion p1 p2)
  1098. | [< '(Kwd Try,p1); e = expr; cl = plist (parse_catch e); s >] -> (ETry (e,cl),p1)
  1099. | [< '(IntInterval i,p1); e2 = expr >] -> make_binop OpInterval (EConst (Int i),p1) e2
  1100. | [< '(Kwd Untyped,p1); e = expr >] -> (EUntyped e,punion p1 (pos e))
  1101. | [< '(Dollar v,p); s >] -> expr_next (EConst (Ident ("$"^v)),p) s
  1102. and expr_next e1 = parser
  1103. | [< '(BrOpen,p1) when is_dollar_ident e1; eparam = expr; '(BrClose,p2); s >] ->
  1104. (match fst e1 with
  1105. | EConst(Ident n) -> expr_next (EMeta((Common.MetaInfo.from_string n,[],snd e1),eparam), punion p1 p2) s
  1106. | _ -> assert false)
  1107. | [< '(Dot,p); s >] ->
  1108. if is_resuming p then display (EDisplay (e1,false),p);
  1109. (match s with parser
  1110. | [< '(Kwd Macro,p2) when p.pmax = p2.pmin; s >] -> expr_next (EField (e1,"macro") , punion (pos e1) p2) s
  1111. | [< '(Const (Ident f),p2) when p.pmax = p2.pmin; s >] -> expr_next (EField (e1,f) , punion (pos e1) p2) s
  1112. | [< '(Dollar v,p2); s >] -> expr_next (EField (e1,"$"^v) , punion (pos e1) p2) s
  1113. | [< '(Binop OpOr,p2) when do_resume() >] -> display (EDisplay (e1,false),p) (* help for debug display mode *)
  1114. | [< >] ->
  1115. (* turn an integer followed by a dot into a float *)
  1116. match e1 with
  1117. | (EConst (Int v),p2) when p2.pmax = p.pmin -> expr_next (EConst (Float (v ^ ".")),punion p p2) s
  1118. | _ -> serror())
  1119. | [< '(POpen,p1); s >] ->
  1120. if is_resuming p1 then display (EDisplay (e1,true),p1);
  1121. (match s with parser
  1122. | [< '(Binop OpOr,p2) when do_resume() >] -> display (EDisplay (e1,true),p1) (* help for debug display mode *)
  1123. | [< params = parse_call_params e1; '(PClose,p2); s >] -> expr_next (ECall (e1,params) , punion (pos e1) p2) s
  1124. | [< >] -> serror())
  1125. | [< '(BkOpen,_); e2 = expr; '(BkClose,p2); s >] ->
  1126. expr_next (EArray (e1,e2), punion (pos e1) p2) s
  1127. | [< '(Binop OpGt,_); s >] ->
  1128. (match s with parser
  1129. | [< '(Binop OpGt,_); s >] ->
  1130. (match s with parser
  1131. | [< '(Binop OpGt,_) >] ->
  1132. (match s with parser
  1133. | [< '(Binop OpAssign,_); e2 = expr >] -> make_binop (OpAssignOp OpUShr) e1 e2
  1134. | [< e2 = secure_expr >] -> make_binop OpUShr e1 e2)
  1135. | [< '(Binop OpAssign,_); e2 = expr >] -> make_binop (OpAssignOp OpShr) e1 e2
  1136. | [< e2 = secure_expr >] -> make_binop OpShr e1 e2)
  1137. | [< '(Binop OpAssign,_); s >] ->
  1138. make_binop OpGte e1 (secure_expr s)
  1139. | [< e2 = secure_expr >] ->
  1140. make_binop OpGt e1 e2)
  1141. | [< '(Binop op,_); e2 = expr >] ->
  1142. make_binop op e1 e2
  1143. | [< '(Unop op,p) when is_postfix e1 op; s >] ->
  1144. expr_next (EUnop (op,Postfix,e1), punion (pos e1) p) s
  1145. | [< '(Question,_); e2 = expr; '(DblDot,_); e3 = expr >] ->
  1146. (ETernary (e1,e2,e3),punion (pos e1) (pos e3))
  1147. | [< '(Kwd In,_); e2 = expr >] ->
  1148. (EIn (e1,e2), punion (pos e1) (pos e2))
  1149. | [< >] -> e1
  1150. and parse_guard = parser
  1151. | [< '(Kwd If,p1); '(POpen,_); e = expr; '(PClose,_); >] ->
  1152. e
  1153. and parse_switch_cases eswitch cases = parser
  1154. | [< '(Kwd Default,p1); '(DblDot,_); s >] ->
  1155. let b = (try block [] s with Display e -> display (ESwitch (eswitch,cases,Some (Some e)),punion (pos eswitch) (pos e))) in
  1156. let b = match b with
  1157. | [] -> None
  1158. | _ -> Some ((EBlock b,p1))
  1159. in
  1160. let l , def = parse_switch_cases eswitch cases s in
  1161. (match def with None -> () | Some _ -> error Duplicate_default p1);
  1162. l , Some b
  1163. | [< '(Kwd Case,p1); el = psep Comma expr; eg = popt parse_guard; '(DblDot,_); s >] ->
  1164. let b = (try block [] s with Display e -> display (ESwitch (eswitch,List.rev ((el,eg,Some e) :: cases),None),punion (pos eswitch) (pos e))) in
  1165. let b = match b with
  1166. | [] -> None
  1167. | _ -> Some ((EBlock b,p1))
  1168. in
  1169. parse_switch_cases eswitch ((el,eg,b) :: cases) s
  1170. | [< >] ->
  1171. List.rev cases , None
  1172. and parse_catch etry = parser
  1173. | [< '(Kwd Catch,p); '(POpen,_); name, _ = ident; s >] ->
  1174. match s with parser
  1175. | [< '(DblDot,_); t = parse_complex_type; '(PClose,_); s >] ->
  1176. (try
  1177. (name,t,secure_expr s)
  1178. with
  1179. Display e -> display (ETry (etry,[name,t,e]),punion (pos etry) (pos e)))
  1180. | [< '(_,p) >] -> error Missing_type p
  1181. and parse_call_params ec s =
  1182. let e = (try
  1183. match s with parser
  1184. | [< e = expr >] -> Some e
  1185. | [< >] -> None
  1186. with Display e ->
  1187. display (ECall (ec,[e]),punion (pos ec) (pos e))
  1188. ) in
  1189. let rec loop acc =
  1190. try
  1191. match s with parser
  1192. | [< '(Comma,_); e = expr >] -> loop (e::acc)
  1193. | [< >] -> List.rev acc
  1194. with Display e ->
  1195. display (ECall (ec,List.rev (e::acc)),punion (pos ec) (pos e))
  1196. in
  1197. match e with
  1198. | None -> []
  1199. | Some e -> loop [e]
  1200. and parse_macro_cond allow_op s =
  1201. match s with parser
  1202. | [< '(Const (Ident t),p) >] ->
  1203. parse_macro_ident allow_op t p s
  1204. | [< '(Const (String s),p) >] ->
  1205. None, (EConst (String s),p)
  1206. | [< '(Const (Int i),p) >] ->
  1207. None, (EConst (Int i),p)
  1208. | [< '(Const (Float f),p) >] ->
  1209. None, (EConst (Float f),p)
  1210. | [< '(Kwd k,p) >] ->
  1211. parse_macro_ident allow_op (s_keyword k) p s
  1212. | [< '(POpen, p1); _,e = parse_macro_cond true; '(PClose, p2) >] ->
  1213. let e = (EParenthesis e,punion p1 p2) in
  1214. if allow_op then parse_macro_op e s else None, e
  1215. | [< '(Unop op,p); tk, e = parse_macro_cond allow_op >] ->
  1216. tk, make_unop op e p
  1217. and parse_macro_ident allow_op t p s =
  1218. let e = (EConst (Ident t),p) in
  1219. if not allow_op then
  1220. None, e
  1221. else
  1222. parse_macro_op e s
  1223. and parse_macro_op e s =
  1224. match Stream.peek s with
  1225. | Some (Binop op,_) ->
  1226. Stream.junk s;
  1227. let op = match Stream.peek s with
  1228. | Some (Binop OpAssign,_) when op = OpGt ->
  1229. Stream.junk s;
  1230. OpGte
  1231. | _ -> op
  1232. in
  1233. let tk, e2 = (try parse_macro_cond true s with Stream.Failure -> serror()) in
  1234. tk, make_binop op e e2
  1235. | tk ->
  1236. tk, e
  1237. and toplevel_expr s =
  1238. try
  1239. expr s
  1240. with
  1241. Display e -> e
  1242. and secure_expr s =
  1243. match s with parser
  1244. | [< e = expr >] -> e
  1245. | [< >] -> serror()
  1246. type small_type =
  1247. | TNull
  1248. | TBool of bool
  1249. | TFloat of float
  1250. | TString of string
  1251. let parse ctx code =
  1252. let old = Lexer.save() in
  1253. let old_cache = !cache in
  1254. let mstack = ref [] in
  1255. cache := DynArray.create();
  1256. last_doc := None;
  1257. in_macro := Common.defined ctx Common.Define.Macro;
  1258. Lexer.skip_header code;
  1259. let sraw = Stream.from (fun _ -> Some (Lexer.token code)) in
  1260. let rec next_token() = process_token (Lexer.token code)
  1261. and process_token tk =
  1262. match fst tk with
  1263. | Comment s ->
  1264. let tk = next_token() in
  1265. if !use_doc then begin
  1266. let l = String.length s in
  1267. if l > 0 && s.[0] = '*' then last_doc := Some (String.sub s 1 (l - (if l > 1 && s.[l-1] = '*' then 2 else 1)), (snd tk).pmin);
  1268. end;
  1269. tk
  1270. | CommentLine s ->
  1271. next_token()
  1272. | Sharp "end" ->
  1273. (match !mstack with
  1274. | [] -> tk
  1275. | _ :: l ->
  1276. mstack := l;
  1277. next_token())
  1278. | Sharp "else" | Sharp "elseif" ->
  1279. (match !mstack with
  1280. | [] -> tk
  1281. | _ :: l ->
  1282. mstack := l;
  1283. process_token (skip_tokens (snd tk) false))
  1284. | Sharp "if" ->
  1285. process_token (enter_macro (snd tk))
  1286. | Sharp "error" ->
  1287. (match Lexer.token code with
  1288. | (Const (String s),p) -> error (Custom s) p
  1289. | _ -> error Unimplemented (snd tk))
  1290. | Sharp "line" ->
  1291. let line = (match next_token() with
  1292. | (Const (Int s),_) -> int_of_string s
  1293. | (t,p) -> error (Unexpected t) p
  1294. ) in
  1295. !(Lexer.cur).Lexer.lline <- line - 1;
  1296. next_token();
  1297. | _ ->
  1298. tk
  1299. and enter_macro p =
  1300. let is_true = function
  1301. | TBool false | TNull | TFloat 0. | TString "" -> false
  1302. | _ -> true
  1303. in
  1304. let cmp v1 v2 =
  1305. match v1, v2 with
  1306. | TNull, TNull -> 0
  1307. | TFloat a, TFloat b -> compare a b
  1308. | TString a, TString b -> compare a b
  1309. | TBool a, TBool b -> compare a b
  1310. | TString a, TFloat b -> compare (float_of_string a) b
  1311. | TFloat a, TString b -> compare a (float_of_string b)
  1312. | _ -> raise Exit (* always false *)
  1313. in
  1314. let rec loop (e,p) =
  1315. match e with
  1316. | EConst (Ident i) ->
  1317. (try TString (Common.raw_defined_value ctx i) with Not_found -> TNull)
  1318. | EConst (String s) -> TString s
  1319. | EConst (Int i) -> TFloat (float_of_string i)
  1320. | EConst (Float f) -> TFloat (float_of_string f)
  1321. | EBinop (OpBoolAnd, e1, e2) -> TBool (is_true (loop e1) && is_true (loop e2))
  1322. | EBinop (OpBoolOr, e1, e2) -> TBool (is_true (loop e1) || is_true(loop e2))
  1323. | EUnop (Not, _, e) -> TBool (not (is_true (loop e)))
  1324. | EParenthesis e -> loop e
  1325. | EBinop (op, e1, e2) ->
  1326. let v1 = loop e1 in
  1327. let v2 = loop e2 in
  1328. let compare op =
  1329. TBool (try op (cmp v1 v2) 0 with _ -> false)
  1330. in
  1331. (match op with
  1332. | OpEq -> compare (=)
  1333. | OpNotEq -> compare (<>)
  1334. | OpGt -> compare (>)
  1335. | OpGte -> compare (>=)
  1336. | OpLt -> compare (<)
  1337. | OpLte -> compare (<=)
  1338. | _ -> error (Custom "Unsupported operation") p)
  1339. | _ ->
  1340. error Unclosed_macro p
  1341. in
  1342. let tk, e = parse_macro_cond false sraw in
  1343. let tk = (match tk with None -> Lexer.token code | Some tk -> tk) in
  1344. if is_true (loop e) || (match fst e with EConst (Ident "macro") when Common.unique_full_path p.pfile = (!resume_display).pfile -> true | _ -> false) then begin
  1345. mstack := p :: !mstack;
  1346. tk
  1347. end else
  1348. skip_tokens_loop p true tk
  1349. and skip_tokens_loop p test tk =
  1350. match fst tk with
  1351. | Sharp "end" ->
  1352. Lexer.token code
  1353. | Sharp "elseif" | Sharp "else" when not test ->
  1354. skip_tokens p test
  1355. | Sharp "else" ->
  1356. mstack := snd tk :: !mstack;
  1357. Lexer.token code
  1358. | Sharp "elseif" ->
  1359. enter_macro (snd tk)
  1360. | Sharp "if" ->
  1361. skip_tokens_loop p test (skip_tokens p false)
  1362. | Eof ->
  1363. if do_resume() then tk else error Unclosed_macro p
  1364. | _ ->
  1365. skip_tokens p test
  1366. and skip_tokens p test = skip_tokens_loop p test (Lexer.token code)
  1367. in
  1368. let s = Stream.from (fun _ ->
  1369. let t = next_token() in
  1370. DynArray.add (!cache) t;
  1371. Some t
  1372. ) in
  1373. try
  1374. let l = parse_file s in
  1375. (match !mstack with p :: _ when not (do_resume()) -> error Unclosed_macro p | _ -> ());
  1376. cache := old_cache;
  1377. Lexer.restore old;
  1378. l
  1379. with
  1380. | Stream.Error _
  1381. | Stream.Failure ->
  1382. let last = (match Stream.peek s with None -> last_token s | Some t -> t) in
  1383. Lexer.restore old;
  1384. cache := old_cache;
  1385. error (Unexpected (fst last)) (pos last)
  1386. | e ->
  1387. Lexer.restore old;
  1388. cache := old_cache;
  1389. raise e