diff options
| author | Rose Hogenson <rosehogenson@posteo.net> | 2025-05-16 08:24:59 -0700 |
|---|---|---|
| committer | Rose Hogenson <rosehogenson@posteo.net> | 2025-05-17 09:50:31 -0700 |
| commit | 06624f3183f4d773cf1023cabe2e370ebba5dee1 (patch) | |
| tree | 93742397b82037c81077507920096d5ac80d4e63 | |
| parent | c2bb80335b590c9118bad0da1d4407942b3765de (diff) | |
| download | sml-06624f3183f4d773cf1023cabe2e370ebba5dee1.tar.zst | |
Use code generation for printing the AST
| -rw-r--r-- | CPS.sml | 2 | ||||
| -rw-r--r-- | CodeGen.sml | 2 | ||||
| -rw-r--r-- | Compiler.sml | 10 | ||||
| -rw-r--r-- | Parser.sml | 13 | ||||
| -rw-r--r-- | ShowSyntax.sml | 190 | ||||
| -rw-r--r-- | Syntax.sml | 134 | ||||
| -rw-r--r-- | generate-show-syntax.sml | 66 | ||||
| -rw-r--r-- | main.sml | 1 | ||||
| -rw-r--r-- | program.cm | 1 |
9 files changed, 277 insertions, 142 deletions
@@ -127,7 +127,7 @@ struct , toCPS expr (fn v => go v sortedArms contFunc) ) end - | _ => raise Fail ("malformed expression " ^ Syntax.lexpToString e) + | _ => raise Fail ("malformed expression " ^ ShowSyntax.lexpToString e) fun hoist (expr : Syntax.cexp) : Syntax.cexp = let diff --git a/CodeGen.sml b/CodeGen.sml index 0bd86be..04b2774 100644 --- a/CodeGen.sml +++ b/CodeGen.sml @@ -175,7 +175,7 @@ struct Syntax.OWrite (translate ptr, translateVal off, translateVal len) :: go k | Syntax.CPrimop (Syntax.PWriteErr, [Syntax.VVar ptr, off, len], _, [k]) => Syntax.OWriteErr (translate ptr, translateVal off, translateVal len) :: go k - | _ => raise Fail ("malformed CPS:\n" ^ Syntax.cexpToString expr) + | _ => raise Fail ("malformed CPS:\n" ^ ShowSyntax.cexpToString expr) in go expr end end diff --git a/Compiler.sml b/Compiler.sml index 4c5e238..0ca0ee5 100644 --- a/Compiler.sml +++ b/Compiler.sml @@ -2,17 +2,17 @@ structure Compiler = struct fun compile (prog : Syntax.expr) : Word8Vector.vector = let - val _ = print ("ast:\n" ^ Syntax.exprToString prog ^ "\n") + val _ = print ("ast:\n" ^ ShowSyntax.exprToString prog ^ "\n") val elab = Elab.elaborate prog - val _ = print ("lambda lang:\n" ^ Syntax.lexpToString elab ^ "\n") + val _ = print ("lambda lang:\n" ^ ShowSyntax.lexpToString elab ^ "\n") val cps = CPS.toCPS elab (fn _ => Syntax.CPrimop (Syntax.PExit, [Syntax.VInt 0], [], [])) - val _ = print ("cps1:\n" ^ Syntax.cexpToString cps ^ "\n") + val _ = print ("cps1:\n" ^ ShowSyntax.cexpToString cps ^ "\n") val cps' = CPS.convertClosures cps - val _ = print ("cps:\n" ^ Syntax.cexpToString cps' ^ "\n") + val _ = print ("cps:\n" ^ ShowSyntax.cexpToString cps' ^ "\n") val asm = CodeGen.toASM cps' - val _ = print ("bytecode:\n" ^ String.concatWith "\n" (map Syntax.opcodeToString asm) ^ "\n") + val _ = print ("bytecode:\n" ^ String.concatWith "\n" (map ShowSyntax.opcodeToString asm) ^ "\n") in Linker.link asm end @@ -426,6 +426,9 @@ struct [i] => Syntax.PVar i | _ => Syntax.PCon (ident, Syntax.PTuple []))) <|> atpat) st + and typedPat : Syntax.pat parser = fn st => + (bind appPat (fn pat => + pat <$ (reserved ":" >> parseType) <|> const pat)) st and pat : Syntax.pat parser = fn st => foldl (fn (i, patLower) => @@ -445,7 +448,7 @@ struct bind patLower (fn pat1 => patLeft pat1 <|> patRight pat1 <|> const pat1) end) - appPat + typedPat (List.tabulate (10, fn i => 9 - i)) st val rec atom : Syntax.expr parser = @@ -546,7 +549,7 @@ struct else {infixTable = Vector.update (infixTable, level, (ops @ leftOps, rightOps))} end) >> const NONE))) - <|> (reserved "datatype" >> + <|> ((reserved "datatype" <|> reserved "and") >> (between (symbol "(") (symbol ")") (sepBy1 tyvar (symbol ",")) <|> (fn x => [x]) <$> tyvar <|> const []) >> @@ -561,6 +564,11 @@ struct <|> const (con, NONE))) (reserved "|")) (fn cons => const (SOME (Syntax.DDatatype (name, cons)))))) + <|> (reserved "type" >> + bind identifier (fn name => + reserved "=" >> + bind parseType (fn ty => + const (SOME (Syntax.DType (name, ty)))))) <|> (reserved "val" >> bind (true <$ reserved "rec" <|> const false) (fn isRec => bind pat (fn p => @@ -628,6 +636,7 @@ struct | fixDecConstructors constructors (Syntax.DFun (f, arms)) = Syntax.DFun (f, map (fn (args, body) => (map (fixPatConstructors constructors) args, fixConstructors constructors body)) arms) | fixDecConstructors _ (decl as Syntax.DDatatype _) = decl + | fixDecConstructors _ (decl as Syntax.DType _) = decl | fixDecConstructors constructors (Syntax.DStruct (name, decs)) = let val constructors = ref constructors diff --git a/ShowSyntax.sml b/ShowSyntax.sml new file mode 100644 index 0000000..645ef84 --- /dev/null +++ b/ShowSyntax.sml @@ -0,0 +1,190 @@ +(* + This file was generated by generate-show-syntax.sml. Do not edit manually. + To regenerate, use + + sml generate-show-syntax.sml -o ShowSyntax.sml Syntax.sml +*) + +structure ShowSyntax = struct +fun intToStringI (_ : string) (i : int) : string = Int.toString i + +fun varToStringI (_ : string) (v : Syntax.var) : string = "Var " ^ Int.toString v + +fun stringToStringI (_ : string) (s : string) : string = "\"" ^ String.toString s ^ "\"" + +fun optionToString (_ : string -> 'a -> string) (_ : string) NONE : string = "NONE" + | optionToString show indent (SOME x) = "SOME (" ^ show indent x ^ ")" + +fun listToString (_ : string -> 'a -> string) (_ : string) ([] : 'a list) : string = "[]" + | listToString show indent [x] = "[" ^ show indent x ^ "]" + | listToString show indent xs = + let val indent' = indent ^ " " in + "[\n" ^ indent' ^ String.concatWith (",\n" ^ indent') (map (show indent') xs) ^ "\n" ^ indent ^ "]" + end + +fun etypeToStringI (indent : string) (Syntax.Tyvar x : Syntax.etype) : string = + "Tyvar " ^ stringToStringI indent x + | etypeToStringI (indent : string) (Syntax.Tycon x : Syntax.etype) : string = + "Tycon " ^ (fn indent => fn (x0, x1) => let val indent' = indent ^ " " in "(\n" ^ indent' ^ listToString (etypeToStringI) indent' x0 ^ ",\n" ^ indent' ^ stringToStringI indent' x1 ^ "\n" ^ indent ^ ")" end) indent x + | etypeToStringI (indent : string) (Syntax.TyTuple x : Syntax.etype) : string = + "TyTuple " ^ listToString (etypeToStringI) indent x + | etypeToStringI (indent : string) (Syntax.Tyfun x : Syntax.etype) : string = + "Tyfun " ^ (fn indent => fn (x0, x1) => let val indent' = indent ^ " " in "(\n" ^ indent' ^ etypeToStringI indent' x0 ^ ",\n" ^ indent' ^ etypeToStringI indent' x1 ^ "\n" ^ indent ^ ")" end) indent x +and etypeToString (x : Syntax.etype) : string = etypeToStringI "" x + +and patToStringI (indent : string) (Syntax.PWild : Syntax.pat) : string = + "PWild" + | patToStringI (indent : string) (Syntax.PVar x : Syntax.pat) : string = + "PVar " ^ stringToStringI indent x + | patToStringI (indent : string) (Syntax.PInt x : Syntax.pat) : string = + "PInt " ^ intToStringI indent x + | patToStringI (indent : string) (Syntax.PTuple x : Syntax.pat) : string = + "PTuple " ^ listToString (patToStringI) indent x + | patToStringI (indent : string) (Syntax.PCon x : Syntax.pat) : string = + "PCon " ^ (fn indent => fn (x0, x1) => let val indent' = indent ^ " " in "(\n" ^ indent' ^ listToString (stringToStringI) indent' x0 ^ ",\n" ^ indent' ^ patToStringI indent' x1 ^ "\n" ^ indent ^ ")" end) indent x +and patToString (x : Syntax.pat) : string = patToStringI "" x + +and exprToStringI (indent : string) (Syntax.EIdent x : Syntax.expr) : string = + "EIdent " ^ listToString (stringToStringI) indent x + | exprToStringI (indent : string) (Syntax.EBuiltin x : Syntax.expr) : string = + "EBuiltin " ^ stringToStringI indent x + | exprToStringI (indent : string) (Syntax.EInt x : Syntax.expr) : string = + "EInt " ^ intToStringI indent x + | exprToStringI (indent : string) (Syntax.EStr x : Syntax.expr) : string = + "EStr " ^ stringToStringI indent x + | exprToStringI (indent : string) (Syntax.ETuple x : Syntax.expr) : string = + "ETuple " ^ listToString (exprToStringI) indent x + | exprToStringI (indent : string) (Syntax.EList x : Syntax.expr) : string = + "EList " ^ listToString (exprToStringI) indent x + | exprToStringI (indent : string) (Syntax.EApp x : Syntax.expr) : string = + "EApp " ^ (fn indent => fn (x0, x1) => let val indent' = indent ^ " " in "(\n" ^ indent' ^ exprToStringI indent' x0 ^ ",\n" ^ indent' ^ exprToStringI indent' x1 ^ "\n" ^ indent ^ ")" end) indent x + | exprToStringI (indent : string) (Syntax.ETyped x : Syntax.expr) : string = + "ETyped " ^ (fn indent => fn (x0, x1) => let val indent' = indent ^ " " in "(\n" ^ indent' ^ exprToStringI indent' x0 ^ ",\n" ^ indent' ^ etypeToStringI indent' x1 ^ "\n" ^ indent ^ ")" end) indent x + | exprToStringI (indent : string) (Syntax.EAndAlso x : Syntax.expr) : string = + "EAndAlso " ^ (fn indent => fn (x0, x1) => let val indent' = indent ^ " " in "(\n" ^ indent' ^ exprToStringI indent' x0 ^ ",\n" ^ indent' ^ exprToStringI indent' x1 ^ "\n" ^ indent ^ ")" end) indent x + | exprToStringI (indent : string) (Syntax.EOrElse x : Syntax.expr) : string = + "EOrElse " ^ (fn indent => fn (x0, x1) => let val indent' = indent ^ " " in "(\n" ^ indent' ^ exprToStringI indent' x0 ^ ",\n" ^ indent' ^ exprToStringI indent' x1 ^ "\n" ^ indent ^ ")" end) indent x + | exprToStringI (indent : string) (Syntax.ELet x : Syntax.expr) : string = + "ELet " ^ (fn indent => fn (x0, x1) => let val indent' = indent ^ " " in "(\n" ^ indent' ^ listToString (decToStringI) indent' x0 ^ ",\n" ^ indent' ^ exprToStringI indent' x1 ^ "\n" ^ indent ^ ")" end) indent x + | exprToStringI (indent : string) (Syntax.ELambda x : Syntax.expr) : string = + "ELambda " ^ (fn indent => fn (x0, x1) => let val indent' = indent ^ " " in "(\n" ^ indent' ^ patToStringI indent' x0 ^ ",\n" ^ indent' ^ exprToStringI indent' x1 ^ "\n" ^ indent ^ ")" end) indent x + | exprToStringI (indent : string) (Syntax.ECase x : Syntax.expr) : string = + "ECase " ^ (fn indent => fn (x0, x1) => let val indent' = indent ^ " " in "(\n" ^ indent' ^ exprToStringI indent' x0 ^ ",\n" ^ indent' ^ listToString ((fn indent => fn (x0, x1) => let val indent' = indent ^ " " in "(\n" ^ indent' ^ patToStringI indent' x0 ^ ",\n" ^ indent' ^ exprToStringI indent' x1 ^ "\n" ^ indent ^ ")" end)) indent' x1 ^ "\n" ^ indent ^ ")" end) indent x +and exprToString (x : Syntax.expr) : string = exprToStringI "" x + +and decToStringI (indent : string) (Syntax.DVal x : Syntax.dec) : string = + "DVal " ^ (fn indent => fn (x0, x1) => let val indent' = indent ^ " " in "(\n" ^ indent' ^ patToStringI indent' x0 ^ ",\n" ^ indent' ^ exprToStringI indent' x1 ^ "\n" ^ indent ^ ")" end) indent x + | decToStringI (indent : string) (Syntax.DValRec x : Syntax.dec) : string = + "DValRec " ^ (fn indent => fn (x0, x1) => let val indent' = indent ^ " " in "(\n" ^ indent' ^ patToStringI indent' x0 ^ ",\n" ^ indent' ^ exprToStringI indent' x1 ^ "\n" ^ indent ^ ")" end) indent x + | decToStringI (indent : string) (Syntax.DFun x : Syntax.dec) : string = + "DFun " ^ (fn indent => fn (x0, x1) => let val indent' = indent ^ " " in "(\n" ^ indent' ^ stringToStringI indent' x0 ^ ",\n" ^ indent' ^ listToString ((fn indent => fn (x0, x1) => let val indent' = indent ^ " " in "(\n" ^ indent' ^ listToString (patToStringI) indent' x0 ^ ",\n" ^ indent' ^ exprToStringI indent' x1 ^ "\n" ^ indent ^ ")" end)) indent' x1 ^ "\n" ^ indent ^ ")" end) indent x + | decToStringI (indent : string) (Syntax.DDatatype x : Syntax.dec) : string = + "DDatatype " ^ (fn indent => fn (x0, x1) => let val indent' = indent ^ " " in "(\n" ^ indent' ^ stringToStringI indent' x0 ^ ",\n" ^ indent' ^ listToString ((fn indent => fn (x0, x1) => let val indent' = indent ^ " " in "(\n" ^ indent' ^ stringToStringI indent' x0 ^ ",\n" ^ indent' ^ optionToString (etypeToStringI) indent' x1 ^ "\n" ^ indent ^ ")" end)) indent' x1 ^ "\n" ^ indent ^ ")" end) indent x + | decToStringI (indent : string) (Syntax.DType x : Syntax.dec) : string = + "DType " ^ (fn indent => fn (x0, x1) => let val indent' = indent ^ " " in "(\n" ^ indent' ^ stringToStringI indent' x0 ^ ",\n" ^ indent' ^ etypeToStringI indent' x1 ^ "\n" ^ indent ^ ")" end) indent x + | decToStringI (indent : string) (Syntax.DStruct x : Syntax.dec) : string = + "DStruct " ^ (fn indent => fn (x0, x1) => let val indent' = indent ^ " " in "(\n" ^ indent' ^ stringToStringI indent' x0 ^ ",\n" ^ indent' ^ listToString (decToStringI) indent' x1 ^ "\n" ^ indent ^ ")" end) indent x +and decToString (x : Syntax.dec) : string = decToStringI "" x + +and primopToStringI (indent : string) (Syntax.PExit : Syntax.primop) : string = + "PExit" + | primopToStringI (indent : string) (Syntax.PAdd : Syntax.primop) : string = + "PAdd" + | primopToStringI (indent : string) (Syntax.PSub : Syntax.primop) : string = + "PSub" + | primopToStringI (indent : string) (Syntax.PMul : Syntax.primop) : string = + "PMul" + | primopToStringI (indent : string) (Syntax.PDiv : Syntax.primop) : string = + "PDiv" + | primopToStringI (indent : string) (Syntax.PLess : Syntax.primop) : string = + "PLess" + | primopToStringI (indent : string) (Syntax.PEq : Syntax.primop) : string = + "PEq" + | primopToStringI (indent : string) (Syntax.PIf : Syntax.primop) : string = + "PIf" + | primopToStringI (indent : string) (Syntax.PRead : Syntax.primop) : string = + "PRead" + | primopToStringI (indent : string) (Syntax.PWrite : Syntax.primop) : string = + "PWrite" + | primopToStringI (indent : string) (Syntax.PWriteErr : Syntax.primop) : string = + "PWriteErr" +and primopToString (x : Syntax.primop) : string = primopToStringI "" x + +and lexpToStringI (indent : string) (Syntax.LVar x : Syntax.lexp) : string = + "LVar " ^ varToStringI indent x + | lexpToStringI (indent : string) (Syntax.LFn x : Syntax.lexp) : string = + "LFn " ^ (fn indent => fn (x0, x1) => let val indent' = indent ^ " " in "(\n" ^ indent' ^ varToStringI indent' x0 ^ ",\n" ^ indent' ^ lexpToStringI indent' x1 ^ "\n" ^ indent ^ ")" end) indent x + | lexpToStringI (indent : string) (Syntax.LFix x : Syntax.lexp) : string = + "LFix " ^ (fn indent => fn (x0, x1) => let val indent' = indent ^ " " in "(\n" ^ indent' ^ listToString ((fn indent => fn (x0, x1, x2) => let val indent' = indent ^ " " in "(\n" ^ indent' ^ varToStringI indent' x0 ^ ",\n" ^ indent' ^ varToStringI indent' x1 ^ ",\n" ^ indent' ^ lexpToStringI indent' x2 ^ "\n" ^ indent ^ ")" end)) indent' x0 ^ ",\n" ^ indent' ^ lexpToStringI indent' x1 ^ "\n" ^ indent ^ ")" end) indent x + | lexpToStringI (indent : string) (Syntax.LApp x : Syntax.lexp) : string = + "LApp " ^ (fn indent => fn (x0, x1) => let val indent' = indent ^ " " in "(\n" ^ indent' ^ lexpToStringI indent' x0 ^ ",\n" ^ indent' ^ lexpToStringI indent' x1 ^ "\n" ^ indent ^ ")" end) indent x + | lexpToStringI (indent : string) (Syntax.LInt x : Syntax.lexp) : string = + "LInt " ^ intToStringI indent x + | lexpToStringI (indent : string) (Syntax.LString x : Syntax.lexp) : string = + "LString " ^ stringToStringI indent x + | lexpToStringI (indent : string) (Syntax.LRecord x : Syntax.lexp) : string = + "LRecord " ^ listToString (lexpToStringI) indent x + | lexpToStringI (indent : string) (Syntax.LSelect x : Syntax.lexp) : string = + "LSelect " ^ (fn indent => fn (x0, x1) => let val indent' = indent ^ " " in "(\n" ^ indent' ^ intToStringI indent' x0 ^ ",\n" ^ indent' ^ lexpToStringI indent' x1 ^ "\n" ^ indent ^ ")" end) indent x + | lexpToStringI (indent : string) (Syntax.LPrim x : Syntax.lexp) : string = + "LPrim " ^ primopToStringI indent x + | lexpToStringI (indent : string) (Syntax.LSwitch x : Syntax.lexp) : string = + "LSwitch " ^ (fn indent => fn (x0, x1, x2) => let val indent' = indent ^ " " in "(\n" ^ indent' ^ lexpToStringI indent' x0 ^ ",\n" ^ indent' ^ listToString ((fn indent => fn (x0, x1) => let val indent' = indent ^ " " in "(\n" ^ indent' ^ intToStringI indent' x0 ^ ",\n" ^ indent' ^ lexpToStringI indent' x1 ^ "\n" ^ indent ^ ")" end)) indent' x1 ^ ",\n" ^ indent' ^ optionToString (lexpToStringI) indent' x2 ^ "\n" ^ indent ^ ")" end) indent x +and lexpToString (x : Syntax.lexp) : string = lexpToStringI "" x + +and valueToStringI (indent : string) (Syntax.VVar x : Syntax.value) : string = + "VVar " ^ varToStringI indent x + | valueToStringI (indent : string) (Syntax.VLabel x : Syntax.value) : string = + "VLabel " ^ varToStringI indent x + | valueToStringI (indent : string) (Syntax.VInt x : Syntax.value) : string = + "VInt " ^ intToStringI indent x +and valueToString (x : Syntax.value) : string = valueToStringI "" x + +and cexpToStringI (indent : string) (Syntax.CRecord x : Syntax.cexp) : string = + "CRecord " ^ (fn indent => fn (x0, x1) => let val indent' = indent ^ " " in "(\n" ^ indent' ^ listToString ((fn indent => fn (x0, x1) => let val indent' = indent ^ " " in "(\n" ^ indent' ^ listToString ((fn indent => fn (x0, x1) => let val indent' = indent ^ " " in "(\n" ^ indent' ^ valueToStringI indent' x0 ^ ",\n" ^ indent' ^ listToString (intToStringI) indent' x1 ^ "\n" ^ indent ^ ")" end)) indent' x0 ^ ",\n" ^ indent' ^ varToStringI indent' x1 ^ "\n" ^ indent ^ ")" end)) indent' x0 ^ ",\n" ^ indent' ^ cexpToStringI indent' x1 ^ "\n" ^ indent ^ ")" end) indent x + | cexpToStringI (indent : string) (Syntax.CSelect x : Syntax.cexp) : string = + "CSelect " ^ (fn indent => fn (x0, x1, x2, x3) => let val indent' = indent ^ " " in "(\n" ^ indent' ^ intToStringI indent' x0 ^ ",\n" ^ indent' ^ valueToStringI indent' x1 ^ ",\n" ^ indent' ^ varToStringI indent' x2 ^ ",\n" ^ indent' ^ cexpToStringI indent' x3 ^ "\n" ^ indent ^ ")" end) indent x + | cexpToStringI (indent : string) (Syntax.CApp x : Syntax.cexp) : string = + "CApp " ^ (fn indent => fn (x0, x1) => let val indent' = indent ^ " " in "(\n" ^ indent' ^ valueToStringI indent' x0 ^ ",\n" ^ indent' ^ listToString (valueToStringI) indent' x1 ^ "\n" ^ indent ^ ")" end) indent x + | cexpToStringI (indent : string) (Syntax.CFix x : Syntax.cexp) : string = + "CFix " ^ (fn indent => fn (x0, x1) => let val indent' = indent ^ " " in "(\n" ^ indent' ^ listToString ((fn indent => fn (x0, x1, x2) => let val indent' = indent ^ " " in "(\n" ^ indent' ^ varToStringI indent' x0 ^ ",\n" ^ indent' ^ listToString (varToStringI) indent' x1 ^ ",\n" ^ indent' ^ cexpToStringI indent' x2 ^ "\n" ^ indent ^ ")" end)) indent' x0 ^ ",\n" ^ indent' ^ cexpToStringI indent' x1 ^ "\n" ^ indent ^ ")" end) indent x + | cexpToStringI (indent : string) (Syntax.CPrimop x : Syntax.cexp) : string = + "CPrimop " ^ (fn indent => fn (x0, x1, x2, x3) => let val indent' = indent ^ " " in "(\n" ^ indent' ^ primopToStringI indent' x0 ^ ",\n" ^ indent' ^ listToString (valueToStringI) indent' x1 ^ ",\n" ^ indent' ^ listToString (varToStringI) indent' x2 ^ ",\n" ^ indent' ^ listToString (cexpToStringI) indent' x3 ^ "\n" ^ indent ^ ")" end) indent x +and cexpToString (x : Syntax.cexp) : string = cexpToStringI "" x + +and opcodeToStringI (indent : string) (Syntax.OAlloc x : Syntax.opcode) : string = + "OAlloc " ^ (fn indent => fn (x0, x1) => let val indent' = indent ^ " " in "(\n" ^ indent' ^ varToStringI indent' x0 ^ ",\n" ^ indent' ^ valueToStringI indent' x1 ^ "\n" ^ indent ^ ")" end) indent x + | opcodeToStringI (indent : string) (Syntax.OCall : Syntax.opcode) : string = + "OCall" + | opcodeToStringI (indent : string) (Syntax.OPoke x : Syntax.opcode) : string = + "OPoke " ^ (fn indent => fn (x0, x1, x2) => let val indent' = indent ^ " " in "(\n" ^ indent' ^ intToStringI indent' x0 ^ ",\n" ^ indent' ^ varToStringI indent' x1 ^ ",\n" ^ indent' ^ valueToStringI indent' x2 ^ "\n" ^ indent ^ ")" end) indent x + | opcodeToStringI (indent : string) (Syntax.OPeek x : Syntax.opcode) : string = + "OPeek " ^ (fn indent => fn (x0, x1, x2) => let val indent' = indent ^ " " in "(\n" ^ indent' ^ varToStringI indent' x0 ^ ",\n" ^ indent' ^ intToStringI indent' x1 ^ ",\n" ^ indent' ^ valueToStringI indent' x2 ^ "\n" ^ indent ^ ")" end) indent x + | opcodeToStringI (indent : string) (Syntax.OShuf x : Syntax.opcode) : string = + "OShuf " ^ (fn indent => fn (x0, x1) => let val indent' = indent ^ " " in "(\n" ^ indent' ^ varToStringI indent' x0 ^ ",\n" ^ indent' ^ valueToStringI indent' x1 ^ "\n" ^ indent ^ ")" end) indent x + | opcodeToStringI (indent : string) (Syntax.OExit x : Syntax.opcode) : string = + "OExit " ^ valueToStringI indent x + | opcodeToStringI (indent : string) (Syntax.OAdd x : Syntax.opcode) : string = + "OAdd " ^ (fn indent => fn (x0, x1, x2) => let val indent' = indent ^ " " in "(\n" ^ indent' ^ varToStringI indent' x0 ^ ",\n" ^ indent' ^ valueToStringI indent' x1 ^ ",\n" ^ indent' ^ valueToStringI indent' x2 ^ "\n" ^ indent ^ ")" end) indent x + | opcodeToStringI (indent : string) (Syntax.OSub x : Syntax.opcode) : string = + "OSub " ^ (fn indent => fn (x0, x1, x2) => let val indent' = indent ^ " " in "(\n" ^ indent' ^ varToStringI indent' x0 ^ ",\n" ^ indent' ^ valueToStringI indent' x1 ^ ",\n" ^ indent' ^ valueToStringI indent' x2 ^ "\n" ^ indent ^ ")" end) indent x + | opcodeToStringI (indent : string) (Syntax.OMul x : Syntax.opcode) : string = + "OMul " ^ (fn indent => fn (x0, x1, x2) => let val indent' = indent ^ " " in "(\n" ^ indent' ^ varToStringI indent' x0 ^ ",\n" ^ indent' ^ valueToStringI indent' x1 ^ ",\n" ^ indent' ^ valueToStringI indent' x2 ^ "\n" ^ indent ^ ")" end) indent x + | opcodeToStringI (indent : string) (Syntax.ODiv x : Syntax.opcode) : string = + "ODiv " ^ (fn indent => fn (x0, x1, x2) => let val indent' = indent ^ " " in "(\n" ^ indent' ^ varToStringI indent' x0 ^ ",\n" ^ indent' ^ valueToStringI indent' x1 ^ ",\n" ^ indent' ^ valueToStringI indent' x2 ^ "\n" ^ indent ^ ")" end) indent x + | opcodeToStringI (indent : string) (Syntax.OLess x : Syntax.opcode) : string = + "OLess " ^ (fn indent => fn (x0, x1, x2) => let val indent' = indent ^ " " in "(\n" ^ indent' ^ varToStringI indent' x0 ^ ",\n" ^ indent' ^ valueToStringI indent' x1 ^ ",\n" ^ indent' ^ valueToStringI indent' x2 ^ "\n" ^ indent ^ ")" end) indent x + | opcodeToStringI (indent : string) (Syntax.OEq x : Syntax.opcode) : string = + "OEq " ^ (fn indent => fn (x0, x1, x2) => let val indent' = indent ^ " " in "(\n" ^ indent' ^ varToStringI indent' x0 ^ ",\n" ^ indent' ^ valueToStringI indent' x1 ^ ",\n" ^ indent' ^ valueToStringI indent' x2 ^ "\n" ^ indent ^ ")" end) indent x + | opcodeToStringI (indent : string) (Syntax.OIf x : Syntax.opcode) : string = + "OIf " ^ (fn indent => fn (x0, x1) => let val indent' = indent ^ " " in "(\n" ^ indent' ^ valueToStringI indent' x0 ^ ",\n" ^ indent' ^ varToStringI indent' x1 ^ "\n" ^ indent ^ ")" end) indent x + | opcodeToStringI (indent : string) (Syntax.OLabel x : Syntax.opcode) : string = + "OLabel " ^ varToStringI indent x + | opcodeToStringI (indent : string) (Syntax.ORead x : Syntax.opcode) : string = + "ORead " ^ (fn indent => fn (x0, x1, x2, x3) => let val indent' = indent ^ " " in "(\n" ^ indent' ^ varToStringI indent' x0 ^ ",\n" ^ indent' ^ varToStringI indent' x1 ^ ",\n" ^ indent' ^ valueToStringI indent' x2 ^ ",\n" ^ indent' ^ valueToStringI indent' x3 ^ "\n" ^ indent ^ ")" end) indent x + | opcodeToStringI (indent : string) (Syntax.OWrite x : Syntax.opcode) : string = + "OWrite " ^ (fn indent => fn (x0, x1, x2) => let val indent' = indent ^ " " in "(\n" ^ indent' ^ varToStringI indent' x0 ^ ",\n" ^ indent' ^ valueToStringI indent' x1 ^ ",\n" ^ indent' ^ valueToStringI indent' x2 ^ "\n" ^ indent ^ ")" end) indent x + | opcodeToStringI (indent : string) (Syntax.OWriteErr x : Syntax.opcode) : string = + "OWriteErr " ^ (fn indent => fn (x0, x1, x2) => let val indent' = indent ^ " " in "(\n" ^ indent' ^ varToStringI indent' x0 ^ ",\n" ^ indent' ^ valueToStringI indent' x1 ^ ",\n" ^ indent' ^ valueToStringI indent' x2 ^ "\n" ^ indent ^ ")" end) indent x +and opcodeToString (x : Syntax.opcode) : string = opcodeToStringI "" x +end @@ -34,6 +34,7 @@ struct | DValRec of pat * expr | DFun of string * (pat list * expr) list | DDatatype of string * (string * etype option) list + | DType of string * etype | DStruct of string * dec list (* Lambda language *) @@ -95,137 +96,4 @@ struct | ORead of var * var * value * value | OWrite of var * value * value | OWriteErr of var * value * value - - fun listToString (show : 'a -> string) (l : 'a list) = - "[" ^ String.concatWith ", " (map show l) ^ "]" - - fun multilineListToString (show : string -> 'a -> string) (indent : string) (l : 'a list) = - case l of - [] => "[]" - | [x] => "[ " ^ show (indent ^ " ") x ^ " ]" - | (x :: xs) => - let val indent' = indent ^ " " - in "[ " ^ show indent' x ^ concat (map (fn x => "\n" ^ indent ^ ", " ^ show indent' x) xs) ^ "\n" ^ indent ^ "]" - end - - fun quote (s : string) : string = "\"" ^ String.toString s ^ "\"" - - fun optionToString (show : 'a -> string) (x : 'a option) = - case x of - NONE => "NONE" - | SOME x => "SOME " ^ show x - - fun etypeToString (x : etype) : string = - case x of - Tyvar s => "Tyvar " ^ quote s - | Tycon (args, con) => "Tycon (" ^ listToString etypeToString args ^ ", " ^ quote con ^ ")" - | TyTuple args => "TyTuple " ^ listToString etypeToString args - | Tyfun (a, b) => "Tyfun (" ^ etypeToString a ^ ", " ^ etypeToString b ^ ")" - - fun patToString (p : pat) : string = - case p of - PWild => "PWild" - | PVar v => "PVar " ^ quote v - | PInt i => "PInt " ^ Int.toString i - | PTuple pats => "PTuple " ^ listToString patToString pats - | PCon (con, v) => "PCon " ^ "(" ^ listToString quote con ^ ", " ^ patToString v ^ ")" - - fun exprToStringI (indent : string) (x : expr) : string = - let val self = exprToStringI indent - in case x of - EIdent i => "EIdent " ^ listToString quote i - | EBuiltin b => "EBuiltin " ^ quote b - | EInt i => "EInt " ^ Int.toString i - | EStr s => "EStr " ^ quote s - | ETuple xs => "ETuple " ^ listToString self xs - | EList l => "EList " ^ listToString self l - | EApp (f, x) => "EApp (" ^ self f ^ ", " ^ self x ^ ")" - | ETyped (e, t) => "ETyped (" ^ self e ^ ", " ^ etypeToString t ^ ")" - | EAndAlso (a, b) => "EAndAlso (" ^ self a ^ ", " ^ self b ^ ")" - | EOrElse (a, b) => "EOrElse (" ^ self a ^ ", " ^ self b ^ ")" - | ELet (decs, e) => "ELet (" ^ multilineListToString decToStringI indent decs ^ ", " ^ self e ^ ")" - | ELambda (pat, e) => "ELambda (" ^ patToString pat ^ ", " ^ exprToStringI indent e ^ ")" - | ECase (e, branches) => "ECase (" ^ self e ^ ", " ^ multilineListToString (fn indent => fn (pat, body) => "(" ^ patToString pat ^ ", " ^ exprToStringI indent body ^ ")") indent branches ^ ")" - end - - and decToStringI (indent : string) (x : dec) : string = - case x of - DVal (p, e) => "DVal (" ^ patToString p ^ ", " ^ exprToStringI indent e ^ ")" - | DValRec (p, e) => "DValRec (" ^ patToString p ^ ", " ^ exprToStringI indent e ^ ")" - | DFun (name, cases) => "DFun (" ^ quote name ^ ", " ^ multilineListToString (fn indent => fn (ps, b) => "(" ^ listToString patToString ps ^ ", " ^ exprToStringI indent b ^ ")") indent cases ^ ")" - | DDatatype (name, arms) => "DDatatype (" ^ quote name ^ ", " ^ listToString (fn (con, v) => "(" ^ quote con ^ ", " ^ optionToString etypeToString v ^ ")") arms ^ ")" - | DStruct (name, decls) => "DStruct (" ^ quote name ^ ",\n" ^ indent ^ "\t" ^ multilineListToString decToStringI (indent ^ "\t") decls ^ ")" - - val exprToString : expr -> string = exprToStringI "" - - val decToString : dec -> string = decToStringI "" - - fun primopToString (x : primop) : string = - case x of - PExit => "PExit" - | PAdd => "PAdd" - | PSub => "PSub" - | PMul => "PMul" - | PDiv => "PDiv" - | PLess => "PLess" - | PEq => "PEq" - | PIf => "PIf" - | PRead => "PRead" - | PWrite => "PWrite" - | PWriteErr => "PWriteErr" - - fun lexpToStringI (indent : string) (x : lexp) : string = - case x of - LVar v => "LVar " ^ Int.toString v - | LFn (arg, expr) => "LFun (" ^ Int.toString arg ^ ",\n" ^ indent ^ "\t" ^ lexpToStringI (indent ^ "\t") expr ^ ")" - | LFix (decls, body) => "LFix (" ^ multilineListToString (fn indent => fn (arg, var, expr) => "(" ^ Int.toString arg ^ ", " ^ Int.toString var ^ ", " ^ lexpToStringI indent expr ^ ")") indent decls ^ ",\n" ^ indent ^ lexpToStringI indent body ^ ")" - | LApp (a, b) => "LApp (" ^ lexpToStringI indent a ^ ",\n" ^ indent ^ "\t" ^ lexpToStringI (indent ^ "\t") b ^ ")" - | LInt i => "LInt " ^ Int.toString i - | LString s => "LString " ^ quote s - | LRecord l => "LRecord " ^ listToString (lexpToStringI indent) l - | LSelect (i, r) => "LSelect (" ^ Int.toString i ^ ", " ^ lexpToStringI indent r ^ ")" - | LPrim p => "LPrim " ^ primopToString p - | LSwitch (e, arms, otherwise) => "LSwitch (" ^ lexpToStringI indent e ^ ",\n" ^ indent ^ "\t" ^ multilineListToString (fn indent => fn (x, e) => "(" ^ Int.toString x ^ ", " ^ lexpToStringI indent e ^ ")") (indent ^ "\t") arms ^ ",\n" ^ indent ^ "\t" ^ optionToString (lexpToStringI (indent ^ "\t")) otherwise ^ ")" - - fun lexpToString (x : lexp) : string = lexpToStringI "" x - - fun valueToString (x : value) : string = - case x of - VVar v => "VVar " ^ Int.toString v - | VLabel l => "VLabel " ^ Int.toString l - | VInt i => "VInt " ^ Int.toString i - - fun cexpToStringI (indent : string) (x : cexp) : string = - let - val self = cexpToStringI indent - val newIndent = indent ^ "\t" - in case x of - CRecord (records, c) => "CRecord (" ^ listToString (fn (a, b) => listToString (fn (x, y) => "(" ^ valueToString x ^ ", " ^ listToString Int.toString y ^ ")") a ^ ", " ^ Int.toString b ^ ")") records ^ ",\n" ^ indent ^ self c ^ ")" - | CSelect (a, b, c, d) => "CSelect (" ^ Int.toString a ^ ", " ^ valueToString b ^ ", " ^ Int.toString c ^ ",\n" ^ indent ^ self d ^ ")" - | CApp (a, b) => "CApp (" ^ valueToString a ^ ", " ^ listToString valueToString b ^ ")" - | CFix (a, b) => "CFix (" ^ multilineListToString (fn indent' => fn (x, y, z) => "(" ^ Int.toString x ^ ", " ^ listToString Int.toString y ^ ",\n" ^ indent' ^ "\t" ^ cexpToStringI (indent' ^ "\t") z) newIndent a ^ ",\n" ^ newIndent ^ cexpToStringI newIndent b ^ ")" - | CPrimop (a, b, c, d) => "CPrimop (" ^ primopToString a ^ ", " ^ listToString valueToString b ^ ", " ^ listToString Int.toString c ^ ",\n" ^ indent ^ multilineListToString cexpToStringI indent d ^ ")" - end - - val cexpToString : cexp -> string = cexpToStringI "" - - fun opcodeToString (oper : opcode) : string = - case oper of - OAlloc (r, s) => "Var " ^ Int.toString r ^ " = OAlloc (" ^ valueToString s ^ ")" - | OCall => "OCall" - | OPoke (i, p, v) => "Var " ^ Int.toString p ^ "[" ^ Int.toString i ^ "] = " ^ valueToString v - | OPeek (r, i, p) => "Var " ^ Int.toString r ^ " = " ^ valueToString p ^ "[" ^ Int.toString i ^ "]" - | OShuf (d, s) => "Var " ^ Int.toString d ^ " = " ^ valueToString s - | OExit v => "OExit (" ^ valueToString v ^ ")" - | OAdd (r, v1, v2) => "Var " ^ Int.toString r ^ " = OAdd (" ^ valueToString v1 ^ ", " ^ valueToString v2 ^ ")" - | OSub (r, v1, v2) => "Var " ^ Int.toString r ^ " = OSub (" ^ valueToString v1 ^ ", " ^ valueToString v2 ^ ")" - | OMul (r, v1, v2) => "Var " ^ Int.toString r ^ " = OMul (" ^ valueToString v1 ^ ", " ^ valueToString v2 ^ ")" - | ODiv (r, v1, v2) => "Var " ^ Int.toString r ^ " = ODiv (" ^ valueToString v1 ^ ", " ^ valueToString v2 ^ ")" - | OLess (r, v1, v2) => "Var " ^ Int.toString r ^ " = OLess (" ^ valueToString v1 ^ ", " ^ valueToString v2 ^ ")" - | OEq (r, v1, v2) => "Var " ^ Int.toString r ^ " = OEq (" ^ valueToString v1 ^ ", " ^ valueToString v2 ^ ")" - | OIf (condition, target) => "OIf (" ^ valueToString condition ^ ") goto " ^ Int.toString target - | OLabel l => "OLabel " ^ Int.toString l - | ORead (r, ptr, off, len) => "Var " ^ Int.toString r ^ " = ORead (Var " ^ Int.toString ptr ^ ", " ^ valueToString off ^ ", " ^ valueToString len ^ ")" - | OWrite (ptr, off, len) => "OWrite (Var " ^ Int.toString ptr ^ ", " ^ valueToString off ^ ", " ^ valueToString len ^ ")" - | OWriteErr (ptr, off, len) => "OWriteErr (Var " ^ Int.toString ptr ^ ", " ^ valueToString off ^ ", " ^ valueToString len ^ ")" end diff --git a/generate-show-syntax.sml b/generate-show-syntax.sml new file mode 100644 index 0000000..7e7e38a --- /dev/null +++ b/generate-show-syntax.sml @@ -0,0 +1,66 @@ +use "Result.sml"; +use "Map.sml"; +use "Syntax.sml"; +use "Parser.sml"; +use "Opts.sml"; + +val header = + "fun intToStringI (_ : string) (i : int) : string = Int.toString i\n" + ^ "\n" + ^ "fun varToStringI (_ : string) (v : Syntax.var) : string = \"Var \" ^ Int.toString v\n" + ^ "\n" + ^ "fun stringToStringI (_ : string) (s : string) : string = \"\\\"\" ^ String.toString s ^ \"\\\"\"\n" + ^ "\n" + ^ "fun optionToString (_ : string -> 'a -> string) (_ : string) NONE : string = \"NONE\"\n" + ^ " | optionToString show indent (SOME x) = \"SOME (\" ^ show indent x ^ \")\"\n" + ^ "\n" + ^ "fun listToString (_ : string -> 'a -> string) (_ : string) ([] : 'a list) : string = \"[]\"\n" + ^ " | listToString show indent [x] = \"[\" ^ show indent x ^ \"]\"\n" + ^ " | listToString show indent xs =\n" + ^ " let val indent' = indent ^ \" \" in\n" + ^ " \"[\\n\" ^ indent' ^ String.concatWith (\",\\n\" ^ indent') (map (show indent') xs) ^ \"\\n\" ^ indent ^ \"]\"\n" + ^ " end\n" + +fun showTy (Syntax.Tyvar var) : string = var ^ "ToStringI" + | showTy (Syntax.Tycon ([ty], con)) = con ^ "ToString (" ^ showTy ty ^ ")" + | showTy (Syntax.TyTuple tys) = + let val vars = List.tabulate (length tys, fn i => "x" ^ Int.toString i) + in + "(fn indent => fn (" ^ String.concatWith ", " vars ^ ") => let val indent' = indent ^ \" \" in \"(\\n\" ^ indent' ^ " ^ String.concatWith " ^ \",\\n\" ^ indent' ^ " (map (fn (var, ty) => showTy ty ^ " indent' " ^ var) (ListPair.zip (vars, tys))) ^ " ^ \"\\n\" ^ indent ^ \")\" end)" + end + | showTy _ = "(fn _ => fn _ => \"UNHANDLED\")" + +val opts = { o = ref "/dev/stdout" } +val flags = + [ ("o", Opts.StringOpt (fn arg => #o opts := arg)) ] +val filename = + case Opts.getOpt flags (CommandLine.arguments ()) of + [arg] => arg + | _ => raise Fail "usage: showsyntax <filename>" +val ast = + case Parser.parse filename of + Result.Left e => raise Fail e + | Result.Right x => x +val (structName, decls) = + case ast of + Syntax.ELet (Syntax.DStruct str :: _, _) => str + | _ => raise Fail "ast has unexpected format (I can't print it sorry)" +val out = TextIO.openOut (!(#o opts)) +val _ = TextIO.output (out, "(*\n This file was generated by generate-show-syntax.sml. Do not edit manually.\n To regenerate, use\n\n sml generate-show-syntax.sml -o " ^ !(#o opts) ^ " " ^ filename ^ "\n*)\n\n") +val _ = TextIO.output (out, "structure Show" ^ structName ^ " = struct\n") +val _ = TextIO.output (out, header) +val _ = map + (fn (i, Syntax.DDatatype (typeName, cases)) => ( + TextIO.output (out, + "\n" ^ (if i = 0 then "fun" else "and") ^ " " + ^ String.concatWith "\n | " (map + (fn (caseName, NONE) => typeName ^ "ToStringI (indent : string) (" ^ structName ^ "." ^ caseName ^ " : " ^ structName ^ "." ^ typeName ^ ") : string =\n \"" ^ caseName ^ "\"" + | (caseName, SOME ty) => typeName ^ "ToStringI (indent : string) (" ^ structName ^ "." ^ caseName ^ " x : " ^ structName ^ "." ^ typeName ^ ") : string =\n \"" ^ caseName ^ " \" ^ " ^ showTy ty ^ " indent x") + cases) + ^ "\n"); + TextIO.output (out, "and " ^ typeName ^ "ToString (x : " ^ structName ^ "." ^ typeName ^ ") : string = " ^ typeName ^ "ToStringI \"\" x\n") + ) + | _ => ()) + (ListPair.zip (List.tabulate (length decls, fn i => i), decls)) +val _ = TextIO.output(out, "end\n") +val _ = OS.Process.exit OS.Process.success @@ -4,6 +4,7 @@ use "Buffer.sml"; use "GenSym.sml"; use "Map.sml"; use "Syntax.sml"; +use "ShowSyntax.sml"; use "CodeGen.sml"; use "CPS.sml"; use "Elab.sml"; @@ -11,6 +11,7 @@ Map.sml Opts.sml Parser.sml Result.sml +ShowSyntax.sml Syntax.sml $/basis.cm |
