changeset 149:7420fa18d657

Record cut
author Adam Chlipala <adamc@hcoop.net>
date Thu, 24 Jul 2008 10:09:21 -0400
parents 15e8b9775539
children cc0bc756f66f
files src/core.sml src/core_print.sml src/core_util.sml src/corify.sml src/elab.sml src/elab_print.sml src/elab_util.sml src/elaborate.sml src/expl.sml src/expl_print.sml src/expl_util.sml src/explify.sml src/lacweb.grm src/lacweb.lex src/monoize.sml src/reduce.sml src/source.sml src/source_print.sml tests/cut.lac
diffstat 19 files changed, 148 insertions(+), 2 deletions(-) [+]
line wrap: on
line diff
--- a/src/core.sml	Tue Jul 22 19:12:25 2008 -0400
+++ b/src/core.sml	Thu Jul 24 10:09:21 2008 -0400
@@ -72,6 +72,7 @@
 
        | ERecord of (con * exp * con) list
        | EField of exp * con * { field : con, rest : con }
+       | ECut of exp * con * { field : con, rest : con }
        | EFold of kind
 
        | EWrite of exp
--- a/src/core_print.sml	Tue Jul 22 19:12:25 2008 -0400
+++ b/src/core_print.sml	Thu Jul 24 10:09:21 2008 -0400
@@ -226,6 +226,27 @@
             box [p_exp' true env e,
                  string ".",
                  p_con' true env c]
+      | ECut (e, c, {field, rest}) =>
+        parenIf par (if !debug then
+                         box [p_exp' true env e,
+                              space,
+                              string "--",
+                              space,
+                              p_con' true env c,
+                              space,
+                              string "[",
+                              p_con env field,
+                              space,
+                              string " in ",
+                              space,
+                              p_con env rest,
+                              string "]"]
+                     else
+                         box [p_exp' true env e,
+                              space,
+                              string "--",
+                              space,
+                              p_con' true env c])
       | EFold _ => string "fold"
 
       | EWrite e => box [string "write(",
--- a/src/core_util.sml	Tue Jul 22 19:12:25 2008 -0400
+++ b/src/core_util.sml	Thu Jul 24 10:09:21 2008 -0400
@@ -282,6 +282,16 @@
                                              S.map2 (mfc ctx rest,
                                                   fn rest' =>
                                                      (EField (e', c', {field = field', rest = rest'}), loc)))))
+              | ECut (e, c, {field, rest}) =>
+                S.bind2 (mfe ctx e,
+                      fn e' =>
+                         S.bind2 (mfc ctx c,
+                              fn c' =>
+                                 S.bind2 (mfc ctx field,
+                                          fn field' =>
+                                             S.map2 (mfc ctx rest,
+                                                  fn rest' =>
+                                                     (ECut (e', c', {field = field', rest = rest'}), loc)))))
               | EFold k =>
                 S.map2 (mfk k,
                          fn k' =>
--- a/src/corify.sml	Tue Jul 22 19:12:25 2008 -0400
+++ b/src/corify.sml	Thu Jul 24 10:09:21 2008 -0400
@@ -371,6 +371,8 @@
                                               (corifyCon st c, corifyExp st e, corifyCon st t)) xes), loc)
       | L.EField (e1, c, {field, rest}) => (L'.EField (corifyExp st e1, corifyCon st c,
                                                        {field = corifyCon st field, rest = corifyCon st rest}), loc)
+      | L.ECut (e1, c, {field, rest}) => (L'.ECut (corifyExp st e1, corifyCon st c,
+                                                   {field = corifyCon st field, rest = corifyCon st rest}), loc)
       | L.EFold k => (L'.EFold (corifyKind k), loc)
       | L.EWrite e => (L'.EWrite (corifyExp st e), loc)
 
--- a/src/elab.sml	Tue Jul 22 19:12:25 2008 -0400
+++ b/src/elab.sml	Thu Jul 24 10:09:21 2008 -0400
@@ -83,6 +83,7 @@
 
        | ERecord of (con * exp * con) list
        | EField of exp * con * { field : con, rest : con }
+       | ECut of exp * con * { field : con, rest : con }
        | EFold of kind
 
        | EError
--- a/src/elab_print.sml	Tue Jul 22 19:12:25 2008 -0400
+++ b/src/elab_print.sml	Thu Jul 24 10:09:21 2008 -0400
@@ -274,6 +274,27 @@
             box [p_exp' true env e,
                  string ".",
                  p_con' true env c]
+      | ECut (e, c, {field, rest}) =>
+        parenIf par (if !debug then
+                         box [p_exp' true env e,
+                              space,
+                              string "--",
+                              space,
+                              p_con' true env c,
+                              space,
+                              string "[",
+                              p_con env field,
+                              space,
+                              string " in ",
+                              space,
+                              p_con env rest,
+                              string "]"]
+                     else
+                         box [p_exp' true env e,
+                              space,
+                              string "--",
+                              space,
+                              p_con' true env c])
       | EFold _ => string "fold"
 
       | EError => string "<ERROR>"
--- a/src/elab_util.sml	Tue Jul 22 19:12:25 2008 -0400
+++ b/src/elab_util.sml	Thu Jul 24 10:09:21 2008 -0400
@@ -292,6 +292,16 @@
                                              S.map2 (mfc ctx rest,
                                                   fn rest' =>
                                                      (EField (e', c', {field = field', rest = rest'}), loc)))))
+              | ECut (e, c, {field, rest}) =>
+                S.bind2 (mfe ctx e,
+                      fn e' =>
+                         S.bind2 (mfc ctx c,
+                              fn c' =>
+                                 S.bind2 (mfc ctx field,
+                                          fn field' =>
+                                             S.map2 (mfc ctx rest,
+                                                  fn rest' =>
+                                                     (ECut (e', c', {field = field', rest = rest'}), loc)))))
 
               | EFold k =>
                 S.map2 (mfk k,
--- a/src/elaborate.sml	Tue Jul 22 19:12:25 2008 -0400
+++ b/src/elaborate.sml	Thu Jul 24 10:09:21 2008 -0400
@@ -895,6 +895,7 @@
 
       | L'.ERecord xes => (L'.TRecord (L'.CRecord (ktype, map (fn (x, _, t) => (x, t)) xes), loc), loc)
       | L'.EField (_, _, {field, ...}) => field
+      | L'.ECut (_, _, {rest, ...}) => (L'.TRecord rest, loc)
       | L'.EFold dom => foldType (dom, loc)
 
       | L'.EError => cerror
@@ -1108,6 +1109,23 @@
                 ((L'.EField (e', c', {field = ft, rest = rest}), loc), ft, gs1 @ gs2 @ gs3 @ gs4)
             end
 
+          | L.ECut (e, c) =>
+            let
+                val (e', et, gs1) = elabExp (env, denv) e
+                val (c', ck, gs2) = elabCon (env, denv) c
+
+                val ft = cunif (loc, ktype)
+                val rest = cunif (loc, ktype_record)
+                val first = (L'.CRecord (ktype, [(c', ft)]), loc)
+                            
+                val gs3 =
+                    checkCon (env, denv) e' et
+                             (L'.TRecord (L'.CConcat (first, rest), loc), loc)
+                val gs4 = D.prove env denv (first, rest, loc)
+            in
+                ((L'.ECut (e', c', {field = ft, rest = rest}), loc), (L'.TRecord rest, loc), gs1 @ gs2 @ gs3 @ gs4)
+            end
+
           | L.EFold =>
             let
                 val dom = kunif loc
--- a/src/expl.sml	Tue Jul 22 19:12:25 2008 -0400
+++ b/src/expl.sml	Thu Jul 24 10:09:21 2008 -0400
@@ -71,6 +71,7 @@
 
        | ERecord of (con * exp * con) list
        | EField of exp * con * { field : con, rest : con }
+       | ECut of exp * con * { field : con, rest : con }
        | EFold of kind
 
        | EWrite of exp
--- a/src/expl_print.sml	Tue Jul 22 19:12:25 2008 -0400
+++ b/src/expl_print.sml	Thu Jul 24 10:09:21 2008 -0400
@@ -237,6 +237,27 @@
             box [p_exp' true env e,
                  string ".",
                  p_con' true env c]
+      | ECut (e, c, {field, rest}) =>
+        parenIf par (if !debug then
+                         box [p_exp' true env e,
+                              space,
+                              string "--",
+                              space,
+                              p_con' true env c,
+                              space,
+                              string "[",
+                              p_con env field,
+                              space,
+                              string " in ",
+                              space,
+                              p_con env rest,
+                              string "]"]
+                     else
+                         box [p_exp' true env e,
+                              space,
+                              string "--",
+                              space,
+                              p_con' true env c])
       | EFold _ => string "fold"
 
       | EWrite e => box [string "write(",
--- a/src/expl_util.sml	Tue Jul 22 19:12:25 2008 -0400
+++ b/src/expl_util.sml	Thu Jul 24 10:09:21 2008 -0400
@@ -267,6 +267,16 @@
                                              S.map2 (mfc ctx rest,
                                                   fn rest' =>
                                                      (EField (e', c', {field = field', rest = rest'}), loc)))))
+              | ECut (e, c, {field, rest}) =>
+                S.bind2 (mfe ctx e,
+                      fn e' =>
+                         S.bind2 (mfc ctx c,
+                              fn c' =>
+                                 S.bind2 (mfc ctx field,
+                                          fn field' =>
+                                             S.map2 (mfc ctx rest,
+                                                  fn rest' =>
+                                                     (ECut (e', c', {field = field', rest = rest'}), loc)))))
               | EFold k =>
                 S.map2 (mfk k,
                          fn k' =>
--- a/src/explify.sml	Tue Jul 22 19:12:25 2008 -0400
+++ b/src/explify.sml	Thu Jul 24 10:09:21 2008 -0400
@@ -85,6 +85,8 @@
       | L.ERecord xes => (L'.ERecord (map (fn (c, e, t) => (explifyCon c, explifyExp e, explifyCon t)) xes), loc)
       | L.EField (e1, c, {field, rest}) => (L'.EField (explifyExp e1, explifyCon c,
                                                        {field = explifyCon field, rest = explifyCon rest}), loc)
+      | L.ECut (e1, c, {field, rest}) => (L'.ECut (explifyExp e1, explifyCon c,
+                                                     {field = explifyCon field, rest = explifyCon rest}), loc)
       | L.EFold k => (L'.EFold (explifyKind k), loc)
 
       | L.EError => raise Fail ("explifyExp: EError at " ^ EM.spanToString loc)
--- a/src/lacweb.grm	Tue Jul 22 19:12:25 2008 -0400
+++ b/src/lacweb.grm	Thu Jul 24 10:09:21 2008 -0400
@@ -47,7 +47,7 @@
  | CON | LTYPE | VAL | REC | AND | FOLD | UNIT | KUNIT
  | TYPE | NAME
  | ARROW | LARROW | DARROW
- | FN | PLUSPLUS | DOLLAR | TWIDDLE
+ | FN | PLUSPLUS | MINUSMINUS | DOLLAR | TWIDDLE
  | STRUCTURE | SIGNATURE | STRUCT | SIG | END | FUNCTOR | WHERE | EXTERN
  | INCLUDE | OPEN | CONSTRAINT | CONSTRAINTS | EXPORT
 
@@ -111,7 +111,7 @@
 %nonassoc DCOLON TCOLON
 %right COMMA
 %right ARROW LARROW
-%right PLUSPLUS
+%right PLUSPLUS MINUSMINUS
 %nonassoc TWIDDLE
 %nonassoc DOLLAR
 %left DOT
@@ -285,6 +285,7 @@
                                          end)
 
        | LPAREN eexp RPAREN DCOLON cexp (EAnnot (eexp, cexp), s (LPARENleft, cexpright))
+       | eexp MINUSMINUS cexp           (ECut (eexp, cexp), s (eexpleft, cexpright))
 
 eterm  : LPAREN eexp RPAREN             (#1 eexp, s (LPARENleft, RPARENright))
 
--- a/src/lacweb.lex	Tue Jul 22 19:12:25 2008 -0400
+++ b/src/lacweb.lex	Thu Jul 24 10:09:21 2008 -0400
@@ -235,6 +235,7 @@
 <INITIAL> "->"        => (Tokens.ARROW (pos yypos, pos yypos + size yytext));
 <INITIAL> "=>"        => (Tokens.DARROW (pos yypos, pos yypos + size yytext));
 <INITIAL> "++"        => (Tokens.PLUSPLUS (pos yypos, pos yypos + size yytext));
+<INITIAL> "--"        => (Tokens.MINUSMINUS (pos yypos, pos yypos + size yytext));
 
 <INITIAL> "="         => (Tokens.EQ (pos yypos, pos yypos + size yytext));
 <INITIAL> ","         => (Tokens.COMMA (pos yypos, pos yypos + size yytext));
--- a/src/monoize.sml	Tue Jul 22 19:12:25 2008 -0400
+++ b/src/monoize.sml	Thu Jul 24 10:09:21 2008 -0400
@@ -370,6 +370,7 @@
 
           | L.ERecord xes => (L'.ERecord (map (fn (x, e, t) => (monoName env x, monoExp env e, monoType env t)) xes), loc)
           | L.EField (e, x, _) => (L'.EField (monoExp env e, monoName env x), loc)
+          | L.ECut _ => poly ()
           | L.EFold _ => poly ()
           | L.EWrite e => (L'.EWrite (monoExp env e), loc)
 
--- a/src/reduce.sml	Tue Jul 22 19:12:25 2008 -0400
+++ b/src/reduce.sml	Thu Jul 24 10:09:21 2008 -0400
@@ -164,6 +164,19 @@
                           | _ => false) xes of
              SOME (_, e, _) => #1 e
            | NONE => e)
+      | ECut (r as (_, loc), _, {rest = (CRecord (k, xts), _), ...}) =>
+        let
+            fun fields (remaining, passed) =
+                case remaining of
+                    [] => []
+                  | (x, t) :: rest =>
+                    (x,
+                     (EField (r, x, {field = t,
+                                     rest = (CRecord (k, List.revAppend (passed, rest)), loc)}), loc),
+                     t) :: fields (rest, (x, t) :: passed)
+        in
+            #1 (reduceExp env (ERecord (fields (xts, [])), loc))
+        end
 
       | _ => e
 
--- a/src/source.sml	Tue Jul 22 19:12:25 2008 -0400
+++ b/src/source.sml	Thu Jul 24 10:09:21 2008 -0400
@@ -100,6 +100,7 @@
 
        | ERecord of (con * exp) list
        | EField of exp * con
+       | ECut of exp * con
        | EFold
 
 withtype exp = exp' located
--- a/src/source_print.sml	Tue Jul 22 19:12:25 2008 -0400
+++ b/src/source_print.sml	Thu Jul 24 10:09:21 2008 -0400
@@ -232,6 +232,11 @@
       | EField (e, c) => box [p_exp' true e,
                               string ".",
                               p_con' true c]
+      | ECut (e, c) => parenIf par (box [p_exp' true e,
+                                         space,
+                                         string "--",
+                                         space,
+                                         p_con' true c])
       | EFold => string "fold"
 
 and p_exp e = p_exp' false e
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/cut.lac	Thu Jul 24 10:09:21 2008 -0400
@@ -0,0 +1,6 @@
+val r = {A = 1, B = "Hi", C = 0.0}
+val rA = r -- #A
+
+val main : unit -> page = fn () => <html><body>
+        {cdata rA.B}
+</body></html>