home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 2 / Apprentice-Release2.iso / Tools / Languages / Caml Light 0.61 / Source / src / compiler / trstream.ml < prev    next >
Encoding:
Text File  |  1993-09-24  |  5.7 KB  |  160 lines  |  [TEXT/MPS ]

  1. (* streams.ml: translation of streams *)
  2.  
  3. #open "misc";;
  4. #open "const";;
  5. #open "syntax";;
  6. #open "prim";;
  7. #open "lambda";;
  8. #open "match";;
  9. #open "tr_env";;
  10.  
  11. (* The following constants must be kept in sync with the definition
  12.    of type stream in file ../lib/stream.ml *)
  13.  
  14. let sempty_tag = ConstrRegular(0,5)
  15. and scons_tag  = ConstrRegular(1,5)
  16. and sapp_tag   = ConstrRegular(2,5)
  17. and sfunc_tag  = ConstrRegular(3,5)
  18. ;;
  19.  
  20. (* The following constant must be kept in sync with STREAM_PARSE_FAILURE
  21.    in file ../runtime/fail.h *)
  22.  
  23. let parse_failure_tag = 10
  24. ;;
  25.  
  26. (* Translation of stream expressions *)
  27.  
  28. let translate_stream translate_expr env stream_comp_list =
  29.   let rec transl_stream env = function
  30.     [] ->
  31.       Lconst(SCblock(sempty_tag, []))
  32.    | [Znonterm e] ->
  33.       Lprim(Pmakeblock sfunc_tag,
  34.             [Lfunction(translate_expr (Treserved env) e); Lconst(const_unit)])
  35.   | component :: rest ->
  36.       let tag =
  37.         match component with Zterm _ -> scons_tag | Znonterm _ -> sapp_tag in
  38.       let e =
  39.         match component with Zterm e -> e | Znonterm e -> e in
  40.       Lprim(Pmakeblock sfunc_tag,
  41.         [Lfunction(Lprim(Pmakeblock tag,
  42.                          [translate_expr (Treserved env) e;
  43.                           transl_stream (Treserved env) rest]));
  44.          Lconst(const_unit)]) in
  45.   transl_stream env stream_comp_list
  46. ;;
  47.  
  48. (* Translation of stream parsers *)
  49.  
  50. let stream_oper name =
  51.   Lprim(Pget_global {qual="stream"; id=name}, [])
  52. ;;
  53.  
  54. let stream_raise name tag =
  55.   Lprim(Praise,
  56.         [Lconst(SCblock(ConstrExtensible({qual="stream"; id=name}, tag), []))])
  57. ;;
  58.  
  59. let raise_parse_failure = stream_raise "Parse_failure" 1
  60. and raise_parse_error = stream_raise "Parse_error" 2
  61. ;;
  62.  
  63. let catch_parse_failure l =
  64.   Lhandle(l, Lifthenelse(Lprim(Ptest Peq_test,
  65.                                [Lprim(Ptag_of, [Lvar 0]);
  66.                                 Lconst(SCatom(ACint parse_failure_tag))]),
  67.                          Lstaticfail,
  68.                          Lprim(Praise, [Lvar 0])))
  69. ;;
  70.  
  71. let rec divide_term_parsing = function
  72.     (Ztermpat pat :: spatl, act) :: rest ->
  73.       let (pat_case_list, parsing) = divide_term_parsing rest in
  74.         (pat, (spatl, act)) :: pat_case_list, parsing
  75.   | parsing ->
  76.         ([], parsing)
  77. ;;
  78.  
  79. let access_stream (* env *) =
  80.   translate_access "%stream" (* env *)
  81. ;;
  82.  
  83. let translate_parser translate_expr loc init_env case_list =
  84.  
  85.   let rec transl_inner env (patl, act) =
  86.     match patl with
  87.       [] ->
  88.         translate_expr env act
  89.     | Ztermpat pat :: rest ->
  90.         let (new_env, add_lets) = add_pat_to_env env pat in
  91.           Llet([Lapply(stream_oper "stream_require", [access_stream env])],
  92.                translate_matching
  93.                  (fun tsb -> raise_parse_error) loc
  94.                  [[pat],
  95.                   add_lets(Lsequence(Lapply(stream_oper "stream_junk",
  96.                                                   [access_stream new_env]),
  97.                                      transl_inner new_env (rest,act)))])
  98.     | Znontermpat(parsexpr, pat) :: rest ->
  99.         let (new_env, add_lets) = add_pat_to_env env pat in
  100.           Llet([Lapply(stream_oper "parser_require",
  101.                        [translate_expr env parsexpr; access_stream env])],
  102.                translate_matching
  103.                  (fun tsb -> raise_parse_error) loc
  104.                  [[pat], add_lets(transl_inner new_env (rest,act))])
  105.     | Zstreampat id :: rest ->
  106.         Llet([access_stream env],
  107.              transl_inner (Tenv([id, Path_root], env)) (rest,act)) in
  108.  
  109.   let rec transl_top env parsing =
  110.     match parsing with
  111.       [] ->
  112.         raise_parse_failure
  113.     | ([], act) :: _ ->
  114.         translate_expr env act
  115.     | (Ztermpat _ :: _, _) :: _ ->
  116.         let translate_line (pat, case) =
  117.           let (new_env, add_lets) = add_pat_to_env env pat in
  118.             ([pat],
  119.              add_lets(Lsequence(Lapply(stream_oper "stream_junk",
  120.                                                   [access_stream new_env]),
  121.                                 transl_inner new_env case))) in
  122.         begin match divide_term_parsing parsing with
  123.           (pat_case_list, []) ->
  124.             Llet([Lapply(stream_oper "stream_peek", [access_stream env])],
  125.                  translate_matching
  126.                    (fun tsb -> raise_parse_failure) loc
  127.                    (map translate_line pat_case_list))
  128.         | (pat_case_list, rest) ->
  129.             Lstatichandle(
  130.               Llet(
  131.                 [catch_parse_failure(Lapply(stream_oper "stream_peek",
  132.                                         [access_stream env]))],
  133.                 translate_matching
  134.                    (fun tsb -> Lstaticfail) loc
  135.                    (map translate_line pat_case_list)),
  136.               transl_top (Treserved env) rest)
  137.         end
  138.     | (Znontermpat(parsexpr, pat) :: spatl, act) :: [] ->
  139.         let (new_env, add_lets) = add_pat_to_env env pat in
  140.           Llet([Lapply(translate_expr env parsexpr, [access_stream env])],
  141.                translate_matching
  142.                  (fun tsb -> raise_parse_failure) loc
  143.                  [[pat], add_lets(transl_inner new_env (spatl,act))])
  144.     | (Znontermpat(parsexpr, pat) :: spatl, act) :: rest ->
  145.         let (new_env, add_lets) = add_pat_to_env env pat in
  146.           Lstatichandle(
  147.             Llet(
  148.               [catch_parse_failure(Lapply(translate_expr env parsexpr,
  149.                                       [access_stream env]))],
  150.               translate_matching
  151.                 (fun tsb -> Lstaticfail) loc
  152.                 [[pat], add_lets(transl_inner new_env (spatl,act))]),
  153.             transl_top (Treserved env) rest)
  154.     | (Zstreampat id :: spatl, act) :: _ ->
  155.         Llet([access_stream env],
  156.              transl_inner (Tenv([id, Path_root], env)) (spatl, act)) in
  157.  
  158.   Lfunction(transl_top (Tenv(["%stream", Path_root], init_env)) case_list)
  159. ;;
  160.