~thon/thon

e39f9a85082827d18a4e0dc2edacc1efa18b22c8 — Evan Bergeron 2 months ago 813056c
consumeNewlines and fixup
4 files changed, 76 insertions(+), 47 deletions(-)

M examples/parse00.thon
A examples/parse01.thon
M parse.sml
M thon.sml
M examples/parse00.thon => examples/parse00.thon +1 -1
@@ 1,2 1,2 @@
fun zero(a nat):
fun zero(a nat) nat:
    z

A examples/parse01.thon => examples/parse01.thon +4 -0
@@ 0,0 1,4 @@
fun ident(a nat) nat:
    a

ident(z)

M parse.sml => parse.sml +62 -45
@@ 6,6 6,14 @@ exception Unimplemented

fun parse s = A.Zero

fun incr i = (i := !i + 1)

fun println s = print (s  ^ "\n")

fun debugPrint s =
    if true then println s
    else ()

fun errMsg (expectedToken, actualToken) =
    ("Expected " ^ (Lex.tokenToString expectedToken) ^
     ", got " ^ (Lex.tokenToString actualToken) ^ "\n")


@@ 16,6 24,11 @@ fun expect tokens (token : Lex.Token) i =
         raise UnexpectedToken(errMsg(token,  List.nth (tokens, !i))))
    else (i := !i + 1)

fun lookahead tokens i =
    if ((!i)+1) > ((List.length tokens) - 1)
    then NONE
    else SOME (List.nth (tokens, ((!i)+1)))

fun consumeName tokens i =
    let val res  =
            (case List.nth (tokens, !i) of


@@ 27,58 40,62 @@ fun consumeName tokens i =
    in i := (!i) + 1;
       res end

fun consumeNewlines tokens i =
    if (!i) >= (List.length tokens) then () else
    case List.nth (tokens, !i) of
        Lex.NEWLINE => (incr(i); consumeNewlines tokens i)
      | _ => ()

fun parseType tokens i =
    case List.nth (tokens, !i) of
        Lex.NAT => (i := (!i) + 1; A.Nat)
      | _ => raise Unimplemented

fun lookahead tokens i =
    if ((!i)+1) > ((List.length tokens) - 1)
    then NONE
    else SOME (List.nth (tokens, ((!i)+1)))

fun parseExpr tokens i =
    (
      (case List.nth (tokens, !i) of
           Lex.FUN =>
           let
               val () = expect tokens Lex.FUN i
               val funcName = consumeName tokens i
               val () = expect tokens Lex.LPAREN i
               (* TODO multiple params *)
               val argName = consumeName tokens i
               val argType = parseType tokens i
               val () = expect tokens Lex.RPAREN i
               val retType = parseType tokens i
               val funcType = A.Arr(argType, retType)
               val () = expect tokens Lex.NEWLINE i
               val () = expect tokens Lex.INDENT i
               val body = parseExpr tokens i
               val () = expect tokens Lex.NEWLINE i
           in
               A.Let(funcName, funcType, A.Fix(funcName, funcType, A.Fn(argName, argType, body)), A.Zero)
           end
         | Lex.ZERO => A.Zero
         | Lex.NAME name =>
           (case lookahead tokens i of
                SOME Lex.LPAREN => (
                 (* Function application *)
                 let val funcName = consumeName tokens i
                     val () = expect tokens Lex.LPAREN i
                     (* TODO multiple params *)
                     val arg = parseExpr tokens i
                     val () = expect tokens Lex.RPAREN i
                 in
                     A.App(A.Var(funcName, ~1), arg)
                 end
             )
              | _ => let val () = expect tokens (Lex.NAME name) i
                     in
                         A.Var (name, ~1)
                     end
           )
    (if (!i) >= (List.length tokens) then A.TmUnit else
     (case List.nth (tokens, !i) of
          Lex.FUN =>
          let
              val () = expect tokens Lex.FUN i
              val funcName = consumeName tokens i
              val () = expect tokens Lex.LPAREN i
              (* TODO multiple params *)
              val argName = consumeName tokens i
              val argType = parseType tokens i
              val () = expect tokens Lex.RPAREN i
              val retType = parseType tokens i
              val funcType = A.Arr(argType, retType)
              val () = consumeNewlines tokens i
              val () = expect tokens Lex.INDENT i
                                       val () = debugPrint "func ident"
              val body = parseExpr tokens i
              val () = consumeNewlines tokens i
              val rest = parseExpr tokens i
          in
              A.Let(funcName, funcType,
                    A.Fix(funcName, funcType, A.Fn(argName, argType, body)), rest)
          end
        | Lex.ZERO => (incr(i); A.Zero)
        | Lex.NAME name =>
          (case lookahead tokens i of
               SOME Lex.LPAREN => (
                (* Function application *)
                let val funcName = consumeName tokens i
                    val () = expect tokens Lex.LPAREN i
                    (* TODO multiple params *)
                    val arg = parseExpr tokens i
                    val () = expect tokens Lex.RPAREN i
                in
                    A.App(A.Var(funcName, ~1), arg)
                end
            )
             | _ => let val () = expect tokens (Lex.NAME name) i
                    in
                        A.Var (name, ~1)
                    end
          )

         | _ => raise Unimplemented)
        | tok => (println (Lex.tokenToString tok); raise Unimplemented))
    )

fun parseFile filename =

M thon.sml => thon.sml +9 -1
@@ 1281,7 1281,15 @@ val

val true = (Lex.lexFileNoPrintErrMsg "/home/evan/thon/examples/lex03.thon"; false) handle UnexpectedToken => true;

val Fn ("a",Nat,Zero) : Ast.exp = newRunFile "/home/evan/thon/examples/parse00.thon";
val Let ("zero",Arr (Nat,Nat),Fix ("zero",Arr (Nat,Nat),Fn ("a",Nat,Zero)),TmUnit)
    : Ast.exp =
    newParseFile "/home/evan/thon/examples/parse00.thon";

val Let
    ("ident",Arr (Nat,Nat),
     Fix ("ident",Arr (Nat,Nat),Fn ("a",Nat,Var ("a",0))),
     App (Var ("ident",0),Zero)) : Ast.exp =
    newParseFile "/home/evan/thon/examples/parse01.thon";

in
()