123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269 |
- (*
- * Neko Binary AST for OCaml
- * Copyright (c)2005-2007 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
- *)
- open Nast
- type context = {
- ch : unit IO.output;
- mutable curfile : string;
- mutable curline : int;
- mutable scount : int;
- strings : (string,int) Hashtbl.t;
- }
- let b ctx n =
- IO.write_byte ctx.ch n
- let write_ui24 ctx n =
- IO.write_byte ctx.ch n;
- IO.write_byte ctx.ch (n lsr 8);
- IO.write_byte ctx.ch (n lsr 16)
- let write_string ctx s =
- try
- let x = ctx.scount - Hashtbl.find ctx.strings s in
- if x > 0xFF then raise Not_found;
- b ctx x;
- with
- Not_found ->
- Hashtbl.replace ctx.strings s ctx.scount;
- ctx.scount <- ctx.scount + 1;
- b ctx 0;
- IO.write_ui16 ctx.ch (String.length s);
- IO.nwrite_string ctx.ch s
- let write_constant ctx = function
- | True -> b ctx 0
- | False -> b ctx 1
- | Null -> b ctx 2
- | This -> b ctx 3
- | Int n ->
- if n >= 0 && n <= 0xFF then begin
- b ctx 4;
- b ctx n;
- end else begin
- b ctx 5;
- IO.write_i32 ctx.ch n;
- end
- | Float s ->
- b ctx 6;
- write_string ctx s
- | String s ->
- b ctx 7;
- write_string ctx s
- | Builtin s ->
- b ctx 8;
- write_string ctx s
- | Ident s ->
- b ctx 9;
- write_string ctx s
- | Int32 n ->
- b ctx 5; (* same as Int *)
- IO.write_real_i32 ctx.ch n
- let write_op ctx op =
- b ctx (match op with
- | "+" -> 0
- | "-" -> 1
- | "/" -> 2
- | "*" -> 3
- | "%" -> 4
- | "<<" -> 5
- | ">>" -> 6
- | ">>>" -> 7
- | "|" -> 8
- | "&" -> 9
- | "^" -> 10
- | "==" -> 11
- | "!=" -> 12
- | ">" -> 13
- | ">=" -> 14
- | "<" -> 15
- | "<=" -> 16
- | "=" -> 17
- | "&&" -> 18
- | "||" -> 19
- | "++=" -> 20
- | "--=" -> 21
- | "+=" -> 22
- | "-=" -> 23
- | "/=" -> 24
- | "*=" -> 25
- | "%=" -> 26
- | "<<=" -> 27
- | ">>=" -> 28
- | ">>>=" -> 29
- | "|=" -> 30
- | "&=" -> 31
- | "^=" -> 32
- | op -> failwith ("Invalid neko ast op " ^ op))
- let rec write_expr_opt ctx = function
- | None ->
- b ctx 0;
- | Some e ->
- b ctx 1;
- write_expr ctx e
- and write_expr ctx (e,p) =
- if p.psource <> ctx.curfile then begin
- b ctx 0;
- write_string ctx p.psource;
- write_ui24 ctx p.pline;
- ctx.curfile <- p.psource;
- ctx.curline <- p.pline;
- end else if p.pline <> ctx.curline then begin
- b ctx 1;
- write_ui24 ctx p.pline;
- ctx.curline <- p.pline;
- end;
- match e with
- | EConst c ->
- b ctx 2;
- write_constant ctx c
- | EBlock el ->
- let n = List.length el in
- if n <= 0xFF then begin
- b ctx 3;
- b ctx n;
- end else begin
- b ctx 4;
- write_ui24 ctx n;
- end;
- List.iter (write_expr ctx) el
- | EParenthesis e ->
- b ctx 5;
- write_expr ctx e;
- | EField (e,f) ->
- b ctx 6;
- write_expr ctx e;
- write_string ctx f;
- | ECall (e,el) ->
- let n = List.length el in
- if n <= 0xFF then begin
- b ctx 7;
- write_expr ctx e;
- b ctx n;
- end else begin
- b ctx 28;
- write_expr ctx e;
- write_ui24 ctx n;
- end;
- List.iter (write_expr ctx) el;
- | EArray (e1,e2) ->
- b ctx 8;
- write_expr ctx e1;
- write_expr ctx e2;
- | EVars vl ->
- b ctx 9;
- b ctx (List.length vl);
- List.iter (fun (v,e) ->
- write_string ctx v;
- write_expr_opt ctx e;
- ) vl;
- | EWhile (e1,e2,NormalWhile) ->
- b ctx 10;
- write_expr ctx e1;
- write_expr ctx e2;
- | EWhile (e1,e2,DoWhile) ->
- b ctx 11;
- write_expr ctx e1;
- write_expr ctx e2;
- | EIf (e1,e2,eo) ->
- b ctx 12;
- write_expr ctx e1;
- write_expr ctx e2;
- write_expr_opt ctx eo;
- | ETry (e1,v,e2) ->
- b ctx 13;
- write_expr ctx e1;
- write_string ctx v;
- write_expr ctx e2;
- | EFunction (pl,e) ->
- b ctx 14;
- b ctx (List.length pl);
- List.iter (write_string ctx) pl;
- write_expr ctx e;
- | EBinop (op,e1,e2) ->
- b ctx 15;
- write_op ctx op;
- write_expr ctx e1;
- write_expr ctx e2;
- | EReturn None ->
- b ctx 16;
- | EReturn (Some e) ->
- b ctx 17;
- write_expr ctx e;
- | EBreak None ->
- b ctx 18;
- | EBreak (Some e) ->
- b ctx 19;
- write_expr ctx e;
- | EContinue ->
- b ctx 20;
- | ENext (e1,e2) ->
- b ctx 21;
- write_expr ctx e1;
- write_expr ctx e2;
- | EObject fl ->
- let n = List.length fl in
- if n <= 0xFF then begin
- b ctx 22;
- b ctx n;
- end else begin
- b ctx 23;
- write_ui24 ctx n;
- end;
- List.iter (fun (f,e) ->
- write_string ctx f;
- write_expr ctx e;
- ) fl;
- | ELabel l ->
- b ctx 24;
- write_string ctx l;
- | ESwitch (e,cases,eo) ->
- let n = List.length cases in
- if n <= 0xFF then begin
- b ctx 25;
- b ctx n;
- end else begin
- b ctx 26;
- write_ui24 ctx n;
- end;
- write_expr ctx e;
- List.iter (fun (e1,e2) ->
- write_expr ctx e1;
- write_expr ctx e2;
- ) cases;
- write_expr_opt ctx eo;
- | ENeko s ->
- b ctx 27;
- write_ui24 ctx (String.length s);
- IO.nwrite_string ctx.ch s
- let write ch e =
- let ctx = {
- ch = ch;
- curfile = "";
- curline = -1;
- scount = 0;
- strings = Hashtbl.create 0;
- } in
- IO.nwrite_string ctx.ch "NBA\001";
- write_expr ctx e
|