anchor.diff:      | Const_bool(b) -> JSE_Bool(b)
       | Const_int32(n) -> JSE_Number((float)n)
       | Const_int64(n) -> JSE_Number((float)n)
  -    | Const_char(c) -> failwith "no chars..."
  +    | Const_char(c) -> JSE_String((string)c)
       | Const_float(f) -> JSE_Number(f)
       | Const_bytearray(ba,r) | Const_string(ba,r) -> JSE_String(Util.string_of_bytes ba)
   
  
positive.code:         match js_of_expr None e with JSE_Elision | JSE_Undefined -> None | e -> Some(e)
      ))])
  
  and js_of_app (e1:exp) (e2:exp) =
      let (e1,e2) = (Absyn.Util.compress_exp e1, Absyn.Util.compress_exp e2) in
      let nonstd e1 e2 = Util.print_any e1; JSE_Call(js_of_expr None e1, [js_of_expr None e2]) in
      match e1 with
      | Exp_fvar(x,b) -> (match x.v.str with
          | "Prims.op_Minus" -> JSE_Minus(js_of_expr None e2)
          | "Prims.op_Negation" -> JSE_Lnot(js_of_expr None e2)
          | _ -> nonstd e1 e2)
      | Exp_app(Exp_fvar(x,b), e3, f) ->
          (match x.v.str with
          | "Prims.op_Addition" -> JSE_Add(js_of_expr None e3, js_of_expr None e2)
          | "Prims.op_Subtraction" -> JSE_Sub(js_of_expr None e3, js_of_expr None e2)
          | "Prims.op_Multiply" -> JSE_Multiply(js_of_expr None e3, js_of_expr None e2)
          | "Prims.op_Modulus" -> JSE_Mod(js_of_expr None e3, js_of_expr None e2)
          | "Prims.op_Division" -> JSE_Divide(js_of_expr None e3, js_of_expr None e2)
          | "Prims.op_BarBar" -> JSE_Lor(js_of_expr None e3, js_of_expr None e2)
          | "Prims.op_AmpAmp" -> JSE_Land(js_of_expr None e3, js_of_expr None e2)
          | "Prims.op_GreaterThan" -> JSE_Gt(js_of_expr None e3, js_of_expr None e2)
          | "Prims.op_LessThanOrEqual" -> JSE_Le(js_of_expr None e3, js_of_expr None e2)
          | "Prims.op_LessThan" -> JSE_Lt(js_of_expr None e3, js_of_expr None e2)
          | "Prims.op_GreaterThanOrEqual" -> JSE_Ge(js_of_expr None e3, js_of_expr None e2)
          | "" -> JSE_Lor(js_of_expr None e3, js_of_expr None e2)
          | _ -> nonstd e1 e2)
      | _ -> nonstd e1 e2
  
  and js_of_binding (x:either<bvvdef,lident>, t:typ, e:exp) =
      let n = match x with Inl(x) -> x.ppname.idText | Inr(x) -> x.ident.idText in
  
negative.code:     | _ -> ([], e)
  
  and js_of_match (e:exp) (cases:list<(pat * option<exp> * exp)>) =
      let compile_pat (p:pat, cond:option<exp>, ret:exp) : source_t =
          let and_cond e1 e2 = match (e1, e2) with
              | (_, JSE_Bool(true)) -> e1 | (JSE_Bool(true), _) -> e2
              | _ -> JSE_Land(e1, e2) in
          let or_cond e1 e2 = match (e1, e2) with
              | (_, JSE_Bool(false)) -> e1 | (JSE_Bool(false), _) -> e2
              | _ -> JSE_Lor(e1, e2) in
          let pat_return props = let rs = JSS_Return(Some(js_of_expr None ret)) in
              let r = match cond with None -> rs | Some(c) -> JSS_If(js_of_expr None c, rs, None)
              in if props=[] then r else JSS_With(JSE_Object(props),r) in
          let rec aux (id:string) (p:pat) = match p with
          | Pat_cons(x, l) -> let tagcond = JSE_Equal(JSE_Identifier(id^".t"), JSE_String(x.str)) in
              let (valcond, valbinds, _) = List.fold_left (
                  fun (cur, b, i) p -> let (next, nb) = aux (sprintf "%s.v[%d]" id i) p in
                  (and_cond cur next, b @ nb, i+1)
              ) (JSE_Bool(true), [], 0) l in (and_cond tagcond valcond, valbinds)
          | Pat_var(bv) -> (JSE_Bool(true), [JSP_Property(bv.ppname.idText, JSE_Identifier(id))])
          | Pat_tvar(_) -> failwith "fail..."
          | Pat_constant(c) -> (JSE_Sequal(JSE_Identifier(id), js_of_const c), [])
          | Pat_disj(l) -> List.fold_left (fun (cur,b) p->
              let (next, nb) = aux id p in (or_cond cur next, b @ nb)) (JSE_Bool(false), []) l
          | Pat_wild -> (JSE_Bool(true), [])
          | Pat_withinfo(p,_) -> aux id p
          | _ -> failwith "fail..."
          in let (conds, binds) = (aux "$v" p) in
          let finalret = pat_return binds in
          JS_Statement(match conds with JSE_Bool(true) -> finalret | _ -> JSS_If(conds, finalret, None))
      in JSE_Call(
          JSE_Function(None, ["$v"], List.map compile_pat cases),
          [js_of_expr None e])
  
  and js_of_expr (binder:option<string>) (expr:exp) : expression_t =
      match try_compile_constructor expr with
      | Some(result) -> result
      | None -> (match expr with
          | Exp_bvar(x) -> JSE_Identifier(x.v.ppname.idText)
          | Exp_fvar(x,b) -> JSE_Identifier(x.v.str)
          | Exp_constant(c) -> js_of_const c
          | Exp_abs(x, t, e) -> js_of_fun binder x t e
          | Exp_app(e1, e2, f) -> JSE_Call(js_of_expr None e1, [js_of_expr None e2])
          | Exp_match(e, c) -> js_of_match e c
          | Exp_let((_, bnds), e) -> let (bext, ee) = compress_let expr in
              JSE_Call(JSE_Function(None, [],
                  [JS_Statement(JSS_Declaration(List.map js_of_binding bext));
                  JS_Statement(JSS_Return(Some(js_of_expr None ee)))]
              ), [])
          | _ -> Util.print_any expr; JSE_Elision)
  
  and untype_expr (e:exp) =
      let e = Absyn.Util.compress_exp e in
  