123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154 |
- (*
- * Neko AST for OCaml
- * Copyright (c)2005 Nicolas Cannasse
- *
- * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
- *)
- type pos = {
- psource : string;
- pline : int;
- }
- type constant =
- | True
- | False
- | Null
- | This
- | Int of int
- | Float of string
- | String of string
- | Builtin of string
- | Ident of string
- | Int32 of int32
- type while_flag =
- | NormalWhile
- | DoWhile
- type expr_decl =
- | EConst of constant
- | EBlock of expr list
- | EParenthesis of expr
- | EField of expr * string
- | ECall of expr * expr list
- | EArray of expr * expr
- | EVars of (string * expr option) list
- | EWhile of expr * expr * while_flag
- | EIf of expr * expr * expr option
- | ETry of expr * string * expr
- | EFunction of string list * expr
- | EBinop of string * expr * expr
- | EReturn of expr option
- | EBreak of expr option
- | EContinue
- | ENext of expr * expr
- | EObject of (string * expr) list
- | ELabel of string
- | ESwitch of expr * (expr * expr) list * expr option
- | ENeko of string
- and expr = expr_decl * pos
- let pos = snd
- let null_pos = { pline = 0; psource = "<null pos>" }
- let mk_call v args p = ECall (v,args) , p
- let mk_call0 v p = ECall (v,[]) , p
- let mk_call1 v a p = ECall (v,[a]) , p
- let mk_ident i p = EConst (Ident i) , p
- let mk_builtin b p = EConst (Builtin b) , p
- let mk_int i p = EConst (Int i) , p
- let mk_string s p = EConst (String s) , p
- let mk_binop op e1 e2 p = EBinop (op,e1,e2) , p
- let map f (e,p) =
- (match e with
- | EBlock el -> EBlock (List.map f el)
- | EParenthesis e -> EParenthesis (f e)
- | EField (e,s) -> EField (f e, s)
- | ECall (e,el) -> ECall (f e, List.map f el)
- | EArray (e1,e2) -> EArray (f e1, f e2)
- | EVars vl -> EVars (List.map (fun (v,e) -> v , match e with None -> None | Some e -> Some (f e)) vl)
- | EWhile (e1,e2,flag) -> EWhile (f e1, f e2, flag)
- | EIf (e,e1,e2) -> EIf (f e, f e1, match e2 with None -> None | Some e -> Some (f e))
- | ETry (e,ident,e2) -> ETry (f e, ident, f e2)
- | EFunction (params,e) -> EFunction (params, f e)
- | EBinop (op,e1,e2) -> EBinop (op, f e1, f e2)
- | EReturn (Some e) -> EReturn (Some (f e))
- | EBreak (Some e) -> EBreak (Some (f e))
- | ENext (e1,e2) -> ENext (f e1,f e2)
- | EObject fl -> EObject (List.map (fun (s,e) -> s , f e) fl)
- | ESwitch (e,cases,def) -> ESwitch (f e,List.map (fun(e1,e2) -> f e1, f e2) cases,match def with None -> None | Some e -> Some (f e))
- | EReturn None
- | EBreak None
- | EContinue
- | ENeko _
- | ELabel _
- | EConst _ as x -> x) , p
- let iter f (e,p) =
- match e with
- | EBlock el -> List.iter f el
- | EParenthesis e -> f e
- | EField (e,s) -> f e
- | ECall (e,el) -> f e; List.iter f el
- | EArray (e1,e2) -> f e1; f e2
- | EVars vl -> List.iter (fun (_,e) -> match e with None -> () | Some e -> f e) vl
- | EWhile (e1,e2,_) -> f e1; f e2
- | EIf (e,e1,e2) -> f e; f e1; (match e2 with None -> () | Some e -> f e)
- | ETry (e1,_,e2) -> f e1; f e2
- | EFunction (_,e) -> f e
- | EBinop (_,e1,e2) -> f e1; f e2
- | EReturn (Some e) -> f e
- | EBreak (Some e) -> f e
- | ENext (e1,e2) -> f e1; f e2
- | EObject fl -> List.iter (fun (_,e) -> f e) fl
- | ESwitch (e,cases,def) -> f e; List.iter (fun(e1,e2) -> f e1; f e2) cases; (match def with None -> () | Some e -> f e)
- | EReturn None
- | EBreak None
- | EContinue
- | ENeko _
- | ELabel _
- | EConst _ -> ()
- let is_printable c = c >= '\032' && c <= '\126'
- let escape s =
- let b = Buffer.create (String.length s) in
- for i = 0 to (String.length s) - 1 do
- match s.[i] with
- | '\n' -> Buffer.add_string b "\\n"
- | '\t' -> Buffer.add_string b "\\t"
- | '\r' -> Buffer.add_string b "\\r"
- | '\\' -> Buffer.add_string b "\\\\"
- | c when c == '"' || not (is_printable c) -> Buffer.add_string b (Printf.sprintf "\\%.3d" (int_of_char c))
- | c -> Buffer.add_char b c
- done;
- Buffer.contents b
- let s_constant = function
- | True -> "true"
- | False -> "false"
- | Null -> "null"
- | This -> "this"
- | Int i -> string_of_int i
- | Float s -> s
- | String s -> "\"" ^ escape s ^ "\""
- | Builtin s -> "$" ^ s
- | Ident s -> s
- | Int32 i -> Int32.to_string i
|