home *** CD-ROM | disk | FTP | other *** search
/ Language/OS - Multiplatform Resource Library / LANGUAGE OS.iso / sml_nj / 93src.lha / src / elaborate / frontend.sml < prev    next >
Encoding:
Text File  |  1993-01-27  |  4.9 KB  |  156 lines

  1. (* Copyright 1989 by AT&T Bell Laboratories *)
  2.  
  3. functor FrontEnd(type output 
  4.          val elaborate:Ast.dec * Modules.env * Modules.env *
  5.             (int * int -> ErrorMsg.complainer) *
  6.             (int * int -> string) * (output -> output) 
  7.             -> output * Modules.env) :
  8.   sig
  9.     datatype parseResult
  10.       = EOF   (* end of file reached *)
  11.       | ERROR (* parsed successfully, but with syntactic or semantic errors *)
  12.       | ABORT (* could not even parse to end of declaration *)
  13.       | PARSE of output * Modules.env
  14.     val parse : (output -> output) -> Source.inputSource -> 
  15.         Modules.env -> parseResult
  16.   end
  17.  =
  18. struct 
  19.   structure MLLrVals = MLLrValsFun(structure Token = LrParser.Token)
  20.   structure Lex = MLLexFun(structure Tokens = MLLrVals.Tokens)
  21.   structure MLP = JoinWithArg(structure ParserData = MLLrVals.ParserData
  22.                   structure Lex=Lex
  23.                   structure LrParser = LrParser)
  24.   structure Absyn = Absyn
  25.  
  26.   open ErrorMsg
  27.  
  28.   (* the following two functions are also defined in build/computil.sml *)
  29.   fun debugmsg  (msg : string) =
  30.       let val printit = !System.Control.debugging
  31.       in  if printit then app System.Print.say[msg, "\n"]
  32.       else ();
  33.       printit
  34.       end
  35.  
  36.   fun timemsg (s : string) =
  37.       let val printit = !System.Control.timings
  38.        in if printit then (app System.Print.say[s, "\n"]; System.Print.flush()) 
  39.                  else ();
  40.       printit
  41.       end
  42.  
  43.   datatype parseResult
  44.     = EOF   (* end of file reached *)
  45.     | ERROR (* parsed successfully, but with syntactic or semantic errors *)
  46.     | ABORT (* could not even parse to end of declaration *)
  47.     | PARSE of output * Modules.env
  48.  
  49.   val dummyEOF = MLLrVals.Tokens.EOF(0,0)
  50.   val dummySEMI = MLLrVals.Tokens.SEMICOLON(0,0)
  51.  
  52.   fun parse (transform:output -> output) 
  53.             (source as {sourceStream,errConsumer,interactive,
  54.             linePos,lineNum,anyErrors,...}: Source.inputSource) =
  55.       let val lastLineNum = ref(!lineNum-1)
  56.  
  57.       val err = ErrorMsg.error source
  58.       val complainMatch = ErrorMsg.matchErrorString source
  59.  
  60.       fun parseerror(s,p1,p2) = err (p1,p2) COMPLAIN s nullErrorBody
  61.  
  62.       val lexarg = {comLevel = ref 0,
  63.             lineNum = lineNum,
  64.             linePos = linePos,
  65.             charlist = ref (nil : string list),
  66.             stringstart = ref 0,
  67.             err = err,
  68.                         brack_stack = ref (nil: int ref list)}
  69.  
  70.       val doprompt = ref true
  71.       val prompt = ref (!System.Control.primaryPrompt)
  72.  
  73.       val inputc_sourceStream = inputc sourceStream
  74.  
  75.       exception AbortLex
  76.       fun getline k =
  77.           (if !doprompt
  78.            then (if !anyErrors then raise AbortLex else ();
  79.              System.Print.say
  80.                (if !(#comLevel lexarg) > 0
  81.                orelse !(#charlist lexarg) <> nil
  82.             then !System.Control.secondaryPrompt
  83.             else !prompt);
  84.              System.Print.flush ();
  85.              doprompt := false)
  86.            else ();
  87.            let val s = inputc_sourceStream k
  88.             in doprompt := (ordof(s,size s - 1)=ord("\n") handle Ord => false);
  89.            s
  90.            end)
  91.  
  92.       val lexer = Lex.makeLexer
  93.                     (if interactive
  94.              then getline
  95.              else inputc_sourceStream)
  96.                 lexarg
  97.       val lexer' = ref(LrParser.Stream.streamify lexer)
  98.       val lookahead = if interactive then 0 else 30
  99.  
  100.       fun oneparse env =
  101.           let val _ = prompt := !System.Control.primaryPrompt
  102.           val (nextToken,rest) = LrParser.Stream.get(!lexer') 
  103.            in if interactive then linePos := [hd(!linePos)] else ();
  104.           if MLP.sameToken(nextToken,dummySEMI) 
  105.           then (lexer' := rest; oneparse env)
  106.           else if MLP.sameToken(nextToken,dummyEOF)
  107.           then EOF
  108.           else let val _ = prompt := !System.Control.secondaryPrompt;
  109.                open System.Timer
  110.                val t1 = start_timer()
  111.                val (f, lexer'') =
  112.                  MLP.parse(lookahead,!lexer',parseerror,err)
  113.                val t2 = check_timer t1
  114.                val lines = !lineNum - !lastLineNum
  115.                val _ = System.Stats.lines :=
  116.                          !System.Stats.lines + lines
  117.                val _ = timemsg("parse, " ^ 
  118.                        Integer.makestring lines
  119.                        ^ " lines, " ^ makestring t2 ^"s")
  120.                    orelse debugmsg "parse"
  121.                val _ = lexer' := lexer''
  122.                val (ast,envfix) = f env
  123.                val (absyn,envdec) =
  124.                  elaborate (ast,env,envfix,err,
  125.                     complainMatch,transform)
  126.                val result = (absyn,envdec)
  127.                val t3 = check_timer t1
  128.             in System.Stats.update(System.Stats.parse,t3);
  129.                timemsg("semantics, "^makestring(sub_time(t3,t2))
  130.                    ^"s")
  131.                    orelse debugmsg "semantics";
  132.                if !anyErrors then ERROR else PARSE result
  133.                end 
  134.           end handle LrParser.ParseError => ABORT
  135.                | AbortLex => ABORT
  136.               (* oneparse *)
  137.  
  138.        in fn env =>
  139.         (lastLineNum := !lineNum; anyErrors := false; oneparse env)
  140.       end
  141.  
  142. end; (* functor FrontEnd *)
  143.  
  144. structure Elaborate = FrontEnd(type output = Absyn.dec
  145.                    fun elaborate (ast,env,fixenv,err,errMatch,
  146.                           transform) =
  147.                  let val (decl,deltaenv) = 
  148.                        ElabStr.elaborateTop 
  149.                        (ast,env,err,errMatch,
  150.                     transform)
  151.                  in (decl,Env.atop(deltaenv,fixenv)) end)
  152.  
  153. structure Parse = FrontEnd(type output = Ast.dec 
  154.                fun elaborate (ast,env,delta,_,_,_) = (ast,delta))
  155.  
  156.