~thon/thon

813056c826ac3148afc7a78063d9f6a1f1b9515a — Evan Bergeron 3 months ago dd2129e
More parse
3 files changed, 90 insertions(+), 27 deletions(-)

M lex.sml
M parse.sml
M thon.sml
M lex.sml => lex.sml +27 -0
@@ 2,6 2,7 @@ structure Lex : sig
datatype Token = FUN | FN | NAT | COLON | LPAREN | RPAREN | NAME of string | INDENT | DEDENT | RETURN | ZERO | SUCC | LET | SARROW | EQUAL | DARROW | IF | THEN | ELSE | DATA | BAR | CASE | COMMA | NEWLINE
val lexFile : string -> Token list
val lexFileNoPrintErrMsg : string -> Token list
val tokenToString : Token -> string
end  =
struct



@@ 9,6 10,32 @@ datatype Token = FUN | FN | NAT | COLON | LPAREN | RPAREN | NAME of string | IND

exception UnexpectedIndentLevel
exception UnexpectedToken of string
exception UnimplementTokenToString

fun tokenToString FUN = "FUN"
  | tokenToString FN = "FN"
  | tokenToString NAT = "NAT"
  | tokenToString COLON = "COLON"
  | tokenToString LPAREN = "LPAREN"
  | tokenToString RPAREN = "RPAREN"
  | tokenToString (NAME name) = "NAME " ^ name
  | tokenToString INDENT = "INDENT"
  | tokenToString DEDENT = "DEDENT"
  | tokenToString RETURN = "RETURN"
  | tokenToString ZERO = "ZERO"
  | tokenToString SUCC = "SUCC"
  | tokenToString LET = "LET"
  | tokenToString SARROW = "SARROW"
  | tokenToString EQUAL = "EQUAL"
  | tokenToString DARROW = "DARROW"
  | tokenToString IF = "IF"
  | tokenToString THEN = "THEN"
  | tokenToString ELSE = "ELSE"
  | tokenToString DATA = "DATA"
  | tokenToString BAR = "BAR"
  | tokenToString CASE = "CASE"
  | tokenToString COMMA = "COMMA"
  | tokenToString NEWLINE = "NEWLINE"

fun lookaheadN s n =
    (* Can raise Size *)

M parse.sml => parse.sml +62 -27
@@ 1,52 1,87 @@
structure NewParse : PARSE =
struct 
struct

exception UnexpectedToken
exception UnexpectedToken of string
exception Unimplemented

fun parse s = A.Zero

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

fun expect tokens (token : Lex.Token) i =
    if List.nth (tokens, !i) <> token then
        raise UnexpectedToken
        (print (errMsg(token,  List.nth (tokens, !i)));
         raise UnexpectedToken(errMsg(token,  List.nth (tokens, !i))))
    else (i := !i + 1)

fun consumeName tokens i =
    let val res  = 
    let val res  =
            (case List.nth (tokens, !i) of
                 Lex.NAME n => n
               | _ => raise UnexpectedToken)
               | tok =>

                 (print(errMsg((Lex.NAME "some name"), tok));
                  raise UnexpectedToken(errMsg((Lex.NAME "some name"), tok))))
    in i := (!i) + 1;
       res end
        
fun parseType tokens i = 

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

fun parseExpr tokens i = 
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 t = parseType tokens i
              val () = expect tokens Lex.RPAREN i
              val () = expect tokens Lex.NEWLINE i
              val () = expect tokens Lex.INDENT i
              val body = parseExpr tokens i
          in 
              A.Fn(argName, t, body)
          end
        | Lex.ZERO => A.Zero
        | _ => raise Unimplemented)
      (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
           )

         | _ => raise Unimplemented)
    )

fun parseFile filename = 
fun parseFile filename =
    let val tokens = Lex.lexFile filename
        val i = ref 0;
    in

M thon.sml => thon.sml +1 -0
@@ 12,6 12,7 @@ structure Thon : sig
                   val eraseNamesInTyp : A.typ -> A.typ
                   val runFile : string -> A.exp
                   val newRunFile : string -> A.exp
                   val newParseFile : string -> A.exp
                   val findParseErrors : string -> unit
                   val elaborateDatatypes : A.exp -> A.exp
                   val shiftDeBruijinIndicesInExp : int -> A.exp -> int -> A.exp