
(* Convert from linear form (lil) to tree (il) - Tom 7 *)
structure ToTree :> TOTREE =
struct
    
(****** Commenting this out to try my version - Joe
    exception BadLinear of string

    open Il



    infixr :-: 
    fun a :-: (b,c) = (a::b, c)

    (* given a token list,
       return (list of Il.exp, token list).
       Stops when it gets to a closing tag or EOL.
     *)
    fun loe (Token.Text s :: rest) = Text s :-: loe rest
      | loe (l as (Token.Closetag _ :: _)) = (nil, l)
      | loe nil = (nil, nil)
      | loe (Token.Tag t :: rest) =
        let val (exp, rest) = tot nil t rest
        in exp :-: loe rest
        end

    (* returns an expression and the rest of the list,
       as if we just entered a tag t *)
    and tot l t (Token.Closetag tt :: rest) =
        let in 
            Token.eqtag (t, tt) orelse raise BadLinear "unbalanced tags";
            (mktag ([t],mkseq l), rest)
        end
      | tot _ _ nil = raise BadLinear "unmatched tag"
      | tot l t more = 
        let
            val (exp,rest) = loe more
        in
            tot (l @ exp) t rest
        end

    fun totree m =
        case loe m of
            (l, nil) => mkseq l
          | _ => raise BadLinear "oops"

***)

    exception BadLinear of string

    structure T = Token
    open Il

    datatype item = TAG of T.tag | EXP of exp


    fun gather t ([],acc) = raise Fail "Extra end tag?"
      | gather t ((EXP e)::stack,acc) =
      gather t (stack,e::acc)
      | gather t ((TAG t')::stack,acc) =
      if t = t' then (EXP (Tag ([t],mkseq acc)))::stack
      else raise Fail "Wrong end tag?"

    fun reduce (stack,t) = gather t (stack,[])

    fun getExp (EXP e) = e
      | getExp (TAG e) = raise Fail "Unexpected tag on stack"

    fun parse (stack,[]) = mkseq (List.map getExp (rev stack)) 
      | parse (stack ,(T.Text s)::rest) = parse ((EXP (Text s))::stack,rest)
      | parse (stack ,(T.Tag t)::rest) = parse ((TAG t)::stack,rest)
      | parse (stack ,(T.Closetag t)::rest) =
      let val stack' = reduce (stack,t)
      in parse (stack',rest)
      end

    fun totree l = parse ([],l)


end
