staload "error.sats"
staload "stamp.sats"
staload "PARCOMB/posloc.sats"
typedef loc = location_t
staload "symbol.sats"
typedef sym = symbol_t
staload "types.sats"
staload "absyn.sats"
staload "tychecker.sats"
staload _ = "symbol.dats"
val ty_INT = TYbase (symbol_INT)
val ty_STRING = TYbase (symbol_STRING)
val ty_NIL = TYnil () and ty_UNIT = TYunit ()
fun tyleq_solve
(loc: loc, ty1: ty, ty2: ty): void = case+ (ty1, ty2) of
| (TYname (sym1, r_ty1), _) => let
val ty1 = ty_lnkrmv r_ty1 in tyleq_solve (loc, ty1, ty2)
end | (_, TYname (sym2, r_ty2)) => let
val ty2 = ty_lnkrmv r_ty2 in tyleq_solve (loc, ty1, ty2)
end | (TYbase sym1, TYbase sym2) when sym1 = sym2 => ()
| (TYnil _, TYnil _) => () | (TYnil _, TYrec _) => ()
| (TYrec (stamp1, _), TYrec (stamp2, _)) when stamp1 = stamp2 => ()
| (TYarr (stamp1, _), TYarr (stamp2, _)) when stamp1 = stamp2 => ()
| (TYunit _, TYunit _) => ()
| (_, _) => begin
prerr_location loc;
prerr ": exit(TIGER): type mismatch";
prerr ": the needed type is [";
prerr_ty ty2;
prerr "] but the actual type is [";
prerr_ty ty1;
prerr "]";
prerr_newline ();
abort {void} (1)
end
implement vfty_var_make (level, rb, ty) = '{
vfty_level=level, vfty_node= VFTYvar (rb, ty)
}
implement vfty_fun_make (level, tys, ty) = '{
vfty_level=level, vfty_node= VFTYfun (tys, ty)
}
local
val the_funlevel = ref_make_elt<int> (0)
in
fun the_funlevel_get (): int = !the_funlevel
fun the_funlevel_inc (): void = let
val n = !the_funlevel in !the_funlevel := n + 1
end
fun the_funlevel_dec (): void = let
val n = !the_funlevel in !the_funlevel := n - 1
end
end
local
val the_looplevel = ref_make_elt<int> (0)
in
fun the_looplevel_get (): int = !the_looplevel
fun the_looplevel_inc (): void = let
val n = !the_looplevel in !the_looplevel := n + 1
end
fun the_looplevel_dec (): void = let
val n = !the_looplevel in !the_looplevel := n - 1
end
end
staload M = "LIB/funmap_avltree.dats"
typedef tymap = $M.map_t (sym, ty)
typedef vftymap = $M.map_t (sym, vfty)
local
val _cmp =
lam (x1: sym, x2: sym): Sgn =<cloref> compare (x1, x2)
in
fn tymap_empty () = $M.funmap_empty<> ()
fn vftymap_empty () = $M.funmap_empty<> ()
fn tymap_search
(loc0: loc, tmap: tymap, sym: sym): ty = let
val ans =
$M.funmap_search<sym,ty> (tmap, sym, _cmp) in
case+ ans of
| ~Some_vt ty => ty | ~None_vt () => begin
prerr_location loc0;
prerr ": exit(TIGER)";
prerr ": unrecognized type symbol ["; prerr_symbol sym;
prerr "]"; prerr_newline ();
abort {ty} (1)
end end
fn vftymap_search
(loc0: loc, vmap: vftymap, sym: sym): vfty = let
val ans =
$M.funmap_search<sym,vfty> (vmap, sym, _cmp) in
case+ ans of
| ~Some_vt (vfty) => vfty | ~None_vt () => begin
prerr_location loc0;
prerr ": exit(TIGER)";
prerr ": unrecognized var/fun symbol ["; prerr_symbol sym;
prerr "]"; prerr_newline ();
abort {vfty} (1)
end end
fn tymap_insert
(tmap: tymap, sym: sym, ty: ty): tymap =
$M.funmap_insert<sym,ty> (tmap, sym, ty, _cmp)
fn vftymap_insert
(vmap: vftymap, sym: sym, vfty: vfty): vftymap =
$M.funmap_insert<sym,vfty> (vmap, sym, vfty, _cmp)
end
fun ty_make_typ
(tmap: tymap, typ: typ): ty = let
val ty0 = case+ typ.typ_node of
| NameTyp sym => let
val loc0 = typ.typ_loc in tymap_search (loc0, tmap, sym)
end | RecordTyp fts => let
val stamp = stamp_make ()
val lts = aux (tmap, fts) where {
fun aux (tmap: tymap, fts: fieldtyplst): labtylst =
case+ fts of
| list_cons (ft, fts) => let
val loc = ft.fieldtyp_loc
val lab = ft.fieldtyp_lab
val sym = ft.fieldtyp_typ
val ty = tymap_search (loc, tmap, sym)
in
LABTYLSTcons (lab, ty, aux (tmap, fts))
end | list_nil () => LABTYLSTnil ()
} in
TYrec (stamp, lts)
end | ArrayTyp sym => let
val loc0 = typ.typ_loc
val stamp = stamp_make ()
val ty = tymap_search (loc0, tmap, sym)
in
TYarr (stamp, ty)
end in
typ_ty_set (typ, ty0); ty0
end
extern fun transVar (tmap: tymap, vmap: vftymap, x: v1ar): ty
extern fun transExpUp (tmap: tymap, vmap: vftymap, e: exp): ty
extern fun transExpDn (tmap: tymap, vmap: vftymap, e: exp, t: ty): void
extern fun transDec
(tmap: &tymap, vmap: &vftymap, d: dec): void
extern fun transDeclst
(tmap: &tymap, vmap: &vftymap, ds: declst): void
implement transVar (tmap, vmap, x0) = let
val ty0 = case+ x0.v1ar_node of
| SimpleVar sym => let
val vfty = vftymap_search (x0.v1ar_loc, vmap, sym)
in
case+ vfty.vfty_node of
| VFTYvar (rb, ty) => ty where {
val level = the_funlevel_get ()
val isEscaped = level > vfty.vfty_level
val () = if isEscaped then !rb := true } | VFTYfun _ => begin
prerr ": exit(TIGER)";
prerr ": the variable [";
prerr_symbol sym;
prerr "] is not a recognized variable";
prerr_newline ();
abort {ty} (1)
end end | FieldVar (x, lab) => let
val ty_rec = transVar (tmap, vmap, x)
val ty_rec = ty_normalize (ty_rec)
val fts = (case+ ty_rec of
| TYrec (_, fts) => fts | _ => begin
prerr x.v1ar_loc;
prerr ": exit(TIGER)";
prerr ": the type of the variable is expected to be a record type";
prerr ", but it is not.";
prerr_newline ();
abort {labtylst} (1)
end ) : labtylst val ty = loop (lab, fts) where {
fun loop (lab0: sym, fts: labtylst):<cloref1> ty =
case+ fts of
| LABTYLSTcons (lab, ty, fts) =>
if lab = lab0 then ty else loop (lab0, fts)
| LABTYLSTnil () => begin
prerr x.v1ar_loc;
prerr ": exit(TIGER)";
prerr ": the label ["; prerr_symbol lab0;
prerr "] is not found in the recorded type assigned to the variable.";
prerr_newline ();
abort {ty} (1)
end } in
ty
end | SubscriptVar (x, e_ind) => let
val ty_arr = transVar (tmap, vmap, x)
val ty_arr = ty_normalize ty_arr
val ty_elt = case+ ty_arr of
| TYarr (_, ty_elt) => ty_elt
| _ => begin
prerr x.v1ar_loc;
prerr ": exit(TIGER)";
prerr ": the variable should be assigned an array type";
prerr ", but it is not";
prerr_newline ();
abort {ty} (1)
end val () = transExpDn (tmap, vmap, e_ind, ty_INT)
in
ty_elt
end val ty0 = ty_normalize ty0
in
v1ar_ty_set (x0, ty0); ty0
end
#define nil list_nil
#define cons list_cons
#define :: list_cons
fn transExpUp_callexp (
tmap: tymap, vmap: vftymap
, e0: exp, f: sym, es: explst
) : ty = let
val vfty = vftymap_search (e0.exp_loc, vmap, f)
in
case+ vfty.vfty_node of
| VFTYfun (tys, ty) => ty where {
fun loop (
tmap: tymap
, vmap: vftymap
, e0: exp
, es: explst
, tys: tylst
) : void = begin case+ (es, tys) of
| (e :: es, ty :: tys) => let
val () =
transExpDn (tmap, vmap, e, ty) in
loop (tmap, vmap, e0, es, tys)
end | (nil (), nil ()) => ()
| (cons _, nil _) => begin
prerr_location e0.exp_loc;
prerr ": exit(TIGER)";
prerr ": arith mismatch: less arguments are needed";
prerr_newline ();
abort {void} (1)
end | (nil _, cons _) => begin
prerr_location e0.exp_loc;
prerr ": exit(TIGER)";
prerr ": arith mismatch: more arguments are needed";
prerr_newline ();
abort {void} (1)
end end val () = loop (tmap, vmap, e0, es, tys)
} | VFTYvar _ => begin
prerr_location e0.exp_loc;
prerr ": exit(TIGER)";
prerr ": ["; prerr_symbol f;
prerr "] should be assigned a function type but it is not.";
prerr_newline ();
abort {ty} (1)
end end
fn transExpUp_opexp_eqop (
tmap: tymap, vmap: vftymap, e0: exp, e1: exp, e2: exp
) : void = () where {
val ty1 = transExpUp (tmap, vmap, e1)
val ty2 = transExpUp (tmap, vmap, e2)
val ty12 = join_ty_ty (ty1, ty2); val () = case+ ty12 of
| TYtop () => begin
prerr_location e0.exp_loc;
prerr ": exit(TIGER)";
prerr ": type mismatch: the arguments need to be assigned the same type";
prerr ", but they are not";
prerr_newline ();
abort {void} (1)
end | _ => ()
}
fn transExpUp_opexp (
tmap: tymap, vmap: vftymap
, e0: exp, e1: exp, oper: oper, e2: exp
) : ty = let
macdef transExpUp_opexp_arith () = let
val () = transExpDn (tmap, vmap, e1, ty_INT)
val () = transExpDn (tmap, vmap, e2, ty_INT) in
ty_INT
end macdef transExpUp_opexp_logic () = let
val () = transExpDn (tmap, vmap, e1, ty_INT)
val () = transExpDn (tmap, vmap, e2, ty_INT) in
ty_INT
end in
case+ oper of
| PlusOp _ => transExpUp_opexp_arith ()
| MinusOp _ => transExpUp_opexp_arith ()
| TimesOp _ => transExpUp_opexp_arith ()
| DivideOp _ => transExpUp_opexp_arith ()
| GtOp _ => transExpUp_opexp_logic ()
| GeOp _ => transExpUp_opexp_logic ()
| LtOp _ => transExpUp_opexp_logic ()
| LeOp _ => transExpUp_opexp_logic ()
| EqOp _ => let
val () = transExpUp_opexp_eqop (tmap, vmap, e0, e1, e2)
in
ty_INT
end | NeqOp _ => let
val () = transExpUp_opexp_eqop (tmap, vmap, e0, e1, e2)
in
ty_INT
end | AndOp _ => let
val () = transExpDn (tmap, vmap, e1, ty_INT)
val () = transExpDn (tmap, vmap, e2, ty_INT)
in
ty_INT
end | OrOp _ => let
val () = transExpDn (tmap, vmap, e1, ty_INT)
val () = transExpDn (tmap, vmap, e2, ty_INT)
in
ty_INT
end end
fn transExpUp_recordexp (
tmap: tymap, vmap: vftymap
, e0: exp, fes: fieldexplst, ty_rec: ty
) : void = () where {
val ty_rec = ty_normalize (ty_rec)
val lts = (case+ ty_rec of
| TYrec (_, fts) => fts | _ => begin
prerr e0.exp_loc;
prerr ": exit(TIGER)";
prerr ": the type for the record is not a record type.";
prerr_newline ();
abort {labtylst} (1)
end ) : labtylst val () = loop (fes, lts) where {
fun loop
(fes: fieldexplst, lts: labtylst):<cloref1> void = begin
case+ fes of
| list_cons (fe, fes) => let
val fe_lab = fe.fieldexp_lab in case+ lts of
| LABTYLSTcons (lab, ty, lts) when fe_lab = lab => let
val () = transExpDn (tmap, vmap, fe.fieldexp_exp, ty) in
loop (fes, lts)
end | _ => begin
prerr e0.exp_loc;
prerr ": exit(TIGER)";
prerr ": the lable ["; prerr_symbol fe_lab;
prerr "] is skipped.";
prerr_newline ();
abort {void} (1)
end
end | list_nil () => begin case+ lts of
| LABTYLSTcons (lab, _, _) => begin
prerr e0.exp_loc;
prerr ": exit(TIGER)";
prerr ": the lable ["; prerr_symbol lab;
prerr "] is extra.";
prerr_newline ();
abort {void} (1)
end | LABTYLSTnil () => ()
end end } }
implement transExpUp (tmap, vmap, e0) = let
val ty0 = case+ e0.exp_node of
| VarExp x => transVar (tmap, vmap, x)
| NilExp _ => ty_NIL
| IntExp _ => ty_INT
| StringExp _ => ty_STRING
| CallExp (f, es) => let
val loc0 = e0.exp_loc in
transExpUp_callexp (tmap, vmap, e0, f, es)
end | OpExp (e1, oper, e2) =>
transExpUp_opexp (tmap, vmap, e0, e1, oper, e2)
| RecordExp (fes, typ) => let
val ty_rec = ty_make_typ (tmap, typ); val () =
transExpUp_recordexp (tmap, vmap, e0, fes, ty_rec) in
ty_rec
end | ArrayExp (typ, e_size, e_init) => let
val ty_arr = ty_make_typ (tmap, typ)
val ty_arr = ty_normalize ty_arr
val ty_elt = (case+ ty_arr of
| TYarr (_, ty_elt) => ty_elt
| _ => begin
prerr e0.exp_loc;
prerr ": exit(TIGER)";
prerr ": the type assigned to the array expression is not an array type";
prerr_newline ();
abort {ty} (1)
end ) : ty val () = transExpDn (tmap, vmap, e_size, ty_INT)
val () = transExpDn (tmap, vmap, e_init, ty_elt)
in
ty_arr
end | AssignExp (x, e) => let
val ty = transVar (tmap, vmap, x)
val () = transExpDn (tmap, vmap, e, ty)
in
ty_UNIT
end | SeqExp es => begin case+ es of
| list_cons _ => loop (tmap, vmap, es) where {
fun loop {n:pos} .<n>. (
tmap: tymap, vmap: vftymap, es: list (exp, n)
) : ty = let
val+ list_cons (e, es) = es
in
case+ es of
| list_cons _ => let
val _ =
transExpUp (tmap, vmap, e) in loop (tmap, vmap, es)
end | list_nil () => transExpUp (tmap, vmap, e)
end } | list_nil () => ty_UNIT
end | IfExp (e1, e2, oe3) => ty where {
val () = transExpDn (tmap, vmap, e1, ty_INT)
val ty = (case+ oe3 of
| Some e3 => ty where {
val ty2 = transExpUp (tmap, vmap, e2)
val ty3 = transExpUp (tmap, vmap, e3)
val ty = join_ty_ty (ty2, ty3)
val () = case+ ty of
| TYtop () => begin
prerr_location e0.exp_loc;
prerr ": exit(TIGER): type mismatch";
prerr ": the type for the then-branch is [";
prerr_ty ty2;
prerr "] but the type for the else-branch is [";
prerr_ty ty3;
prerr "]";
prerr_newline ();
abort {void} (1)
end | _ => ()
} | None () => let
val () = transExpDn (tmap, vmap, e2, ty_UNIT) in ty_UNIT
end ) : ty } | WhileExp (e_test, e_body) => let
val () = transExpDn (tmap, vmap, e_test, ty_INT)
val () = the_looplevel_inc ()
val () = transExpDn (tmap, vmap, e_body, ty_UNIT)
val () = the_looplevel_dec ()
in
ty_UNIT
end | ForExp (ind, rb, e_lo, e_hi, e_body) => let
val () = transExpDn (tmap, vmap, e_lo, ty_INT)
val () = transExpDn (tmap, vmap, e_hi, ty_INT)
val vmap = let
val level = the_funlevel_get ()
val vfty_ind = vfty_var_make (level, rb, ty_INT)
in
vftymap_insert (vmap, ind, vfty_ind)
end val () = the_looplevel_inc ()
val () = transExpDn (tmap, vmap, e_body, ty_UNIT)
val () = the_looplevel_dec ()
in
ty_UNIT
end | BreakExp () => let
val level = the_looplevel_get ()
in
case+ 0 of
| _ when level > 0 => ty_UNIT | _ => begin
prerr_location e0.exp_loc;
prerr ": exit(TIGER): [break] can only occur inside a loop";
prerr_newline ();
abort {ty} (1)
end end | ContinueExp () => let
val level = the_looplevel_get ()
in
case+ 0 of
| _ when level > 0 => ty_UNIT | _ => begin
prerr_location e0.exp_loc;
prerr ": exit(TIGER): [continue] can only occur inside a loop";
prerr_newline ();
abort {ty} (1)
end end | LetExp (ds, e_body) => let
var tmap = tmap and vmap = vmap
val () = transDeclst (tmap, vmap, ds) in
transExpUp (tmap, vmap, e_body)
end
in
exp_ty_set (e0, ty0); ty0
end
implement transExpDn
(tmap, vmap, e0, ty0) = () where {
val ty = transExpUp (tmap, vmap, e0)
val () = tyleq_solve (e0.exp_loc, ty, ty0)
val () = exp_ty_set (e0, ty0)
}
staload _ = "prelude/DATS/list.dats"
fun transTypdeclst
(tmap: &tymap, tds: typdeclst): void = () where {
val n = list_length (tds)
val rtyfds = aux (tmap, tds) where {
fun aux (tmap: &tymap, tds: typdeclst)
: List_vt @(tyref, typdec) = begin case+ tds of
| list_cons (td, tds) => let
val r_ty = ref_make_elt<ty> (TYtop ())
val sym = td.typdec_name
val () = tmap := tymap_insert (tmap, sym, TYname (sym, r_ty))
in
list_vt_cons (@(r_ty, td), aux (tmap, tds))
end | list_nil () => list_vt_nil ()
end } val () = loop (tmap, rtyfds) where {
fun loop (
tmap: tymap
, xs: !List_vt @(tyref, typdec)
) : void =
case+ xs of
| list_vt_cons (x, !p_xs1) => let
val r_ty = x.0 and td = x.1
val () = !r_ty := ty_make_typ (tmap, td.typdec_typ)
val () = loop (tmap, !p_xs1)
in
fold@ xs
end | list_vt_nil () => fold@ xs
} var err: int = 0
val () = loop (rtyfds, n - 1, err) where {
fun loop (
xs: List_vt @(tyref, typdec), max: int, err: &int
) : void = case+ xs of
| ~list_vt_cons (x, xs) => let
val r_ty = x.0; val ty = ty_normalize_max (!r_ty, max)
val () = case+ ty of
| TYname (sym, _) => let
val () = err := err + 1
in
prerr "The type ["; prerr_symbol sym;
prerr "] is involved in a circular type definition.";
prerr_newline ()
end | _ => ()
in
loop (xs, max, err)
end | ~list_vt_nil () => ()
} val () = if err > 0 then abort {void} (1)
}
typedef labrbtylst = List @(sym, refb, ty)
fn transFundec (
tmap: tymap, vmap: &vftymap, fd: fundec
) : @(labrbtylst, ty) = let
val labrbtys = aux (tmap, vmap, fd.fundec_arglst) where {
fun aux (
tmap: tymap
, vmap: &vftymap
, fts: fieldtyplst
) : labrbtylst = begin case+ fts of
| list_cons (ft, fts) => let
val loc = ft.fieldtyp_loc
val lab = ft.fieldtyp_lab
val typ = ft.fieldtyp_typ
val ty = tymap_search (loc, tmap, typ)
val rb = ft.fieldtyp_escape
val x = @(lab, rb, ty)
in
list_cons (x, aux (tmap, vmap, fts))
end | list_nil () => list_nil ()
end }
val tys_arg = aux (labrbtys) where {
fun aux (xs: labrbtylst): tylst = case+ xs of
| list_cons (x, xs) => list_cons (x.2, aux xs)
| list_nil () => list_nil ()
} val ty_res = (case+ fd.fundec_result of
| Some typ => ty_make_typ (tmap, typ)
| None () => ty_UNIT
) : ty val level = the_funlevel_get ()
val vfty_fun = vfty_fun_make (level, tys_arg, ty_res)
val () = vmap := vftymap_insert (vmap, fd.fundec_name, vfty_fun)
in
@(labrbtys, ty_res)
end
fn transFundeclst (
tmap: tymap
, vmap: &vftymap
, fds: fundeclst
) : void = let
val lrtsets = aux (tmap, vmap, fds) where {
fun aux {n:nat} (
tmap: tymap
, vmap: &vftymap
, fds: list (fundec, n)
) : list_vt (@(labrbtylst, exp, ty), n) = begin
case+ fds of
| list_cons (fd, fds) => let
val lrtst = transFundec (tmap, vmap, fd)
val lrtset = @(lrtst.0, fd.fundec_body, lrtst.1)
in
list_vt_cons (lrtset, aux (tmap, vmap, fds))
end | list_nil () => list_vt_nil ()
end } val () = loop (tmap, vmap, lrtsets) where {
fun loop (
tmap: tymap, vmap: vftymap
, lrtsets: List_vt @(labrbtylst, exp, ty)
) : void = begin case+ lrtsets of
| ~list_vt_cons (lrtset, lrtsets) => let
val vmap_new = loop1 (vmap, lrtset.0) where {
fun loop1
(vmap: vftymap, lrts: labrbtylst): vftymap = begin
case+ lrts of
| list_cons (lrt, lrts) => let
val level = the_funlevel_get ()
val vfty = vfty_var_make (level, lrt.1, lrt.2)
val vmap = vftymap_insert (vmap, lrt.0, vfty)
in
loop1 (vmap, lrts)
end
| list_nil () => vmap
end } val () = transExpDn (tmap, vmap_new, lrtset.1, lrtset.2)
in
loop (tmap, vmap, lrtsets)
end | ~list_vt_nil () => ()
end } in
end
implement transDec (tmap, vmap, d) = begin
case+ d.dec_node of
| FunctionDec fds => () where {
val () = the_funlevel_inc ()
val () = transFundeclst (tmap, vmap, fds)
val () = the_funlevel_dec ()
} | VarDec (sym, rb, oty, e_init) => let
val ty = (case+ oty of
| Some typ => let
val ty = ty_make_typ (tmap, typ) in
transExpDn (tmap, vmap, e_init, ty); ty
end | None () => transExpUp (tmap, vmap, e_init)
) : ty
val level = the_funlevel_get ()
val vfty = vfty_var_make (level, rb, ty)
in
vmap := vftymap_insert (vmap, sym, vfty)
end | TypeDec tds => transTypdeclst (tmap, tds)
end
implement transDeclst (tmap, vmap, ds) = case+ ds of
| list_cons (d, ds) => begin
transDec (tmap, vmap, d); transDeclst (tmap, vmap, ds)
end | list_nil () => ()
val vfty_PRINT =
vfty_fun_make (0, $lst (ty_STRING), ty_UNIT)
val vfty_PRINT_INT =
vfty_fun_make (0, $lst (ty_INT), ty_UNIT)
val vfty_FLUSH =
vfty_fun_make (0, $lst (), ty_UNIT)
val vfty_GETCHAR =
vfty_fun_make (0, $lst (), ty_STRING)
val vfty_ORD =
vfty_fun_make (0, $lst (ty_STRING), ty_INT)
val vfty_CHR =
vfty_fun_make (0, $lst (ty_INT), ty_STRING)
val vfty_SIZE =
vfty_fun_make (0, $lst (ty_STRING), ty_INT)
val vfty_SUBSTRING = vfty_fun_make
(0, $lst (ty_STRING, ty_INT, ty_INT), ty_STRING)
val vfty_CONCAT = vfty_fun_make
(0, $lst (ty_STRING, ty_STRING), ty_STRING)
val vfty_NOT =
vfty_fun_make (0, $lst (ty_INT), ty_INT)
val vfty_EXIT =
vfty_fun_make (0, $lst (ty_INT), ty_UNIT)
implement transProg (e) = let
val tmap = tmap where {
val tmap = tymap_empty ()
val tmap = tymap_insert (tmap, symbol_INT, ty_INT)
val tmap = tymap_insert (tmap, symbol_STRING, ty_STRING)
val tmap = tymap_insert (tmap, symbol_UNIT, ty_UNIT)
} val vmap = vmap where {
val vmap = vftymap_empty ()
val vmap = vftymap_insert (vmap, symbol_CHR, vfty_CHR)
val vmap = vftymap_insert (vmap, symbol_FLUSH, vfty_FLUSH)
val vmap = vftymap_insert (vmap, symbol_GETCHAR, vfty_GETCHAR)
val vmap = vftymap_insert (vmap, symbol_ORD, vfty_ORD)
val vmap = vftymap_insert (vmap, symbol_PRINT, vfty_PRINT)
val vmap = vftymap_insert (vmap, symbol_PRINT_INT, vfty_PRINT_INT)
val vmap = vftymap_insert (vmap, symbol_SIZE, vfty_SIZE)
val vmap = vftymap_insert (vmap, symbol_SUBSTRING, vfty_SUBSTRING)
val vmap = vftymap_insert (vmap, symbol_CONCAT, vfty_CONCAT)
val vmap = vftymap_insert (vmap, symbol_NOT, vfty_NOT)
val vmap = vftymap_insert (vmap, symbol_EXIT, vfty_EXIT)
} in
transExpUp (tmap, vmap, e)
end