diff src/lacweb.grm @ 207:cc68da3801bc

Non-star SELECT
author Adam Chlipala <adamc@hcoop.net>
date Thu, 14 Aug 2008 18:35:08 -0400
parents 241c9a0e3397
children 1487c712eb12
line wrap: on
line diff
--- a/src/lacweb.grm	Thu Aug 14 15:27:35 2008 -0400
+++ b/src/lacweb.grm	Thu Aug 14 18:35:08 2008 -0400
@@ -39,6 +39,39 @@
         TRecord c => c
       | _ => t
 
+datatype select_item =
+         Field of con * con
+
+datatype select =
+         Star
+       | Items of select_item list
+
+fun eqTnames ((c1, _), (c2, _)) =
+    case (c1, c2) of
+        (CVar (ms1, x1), CVar (ms2, x2)) => ms1 = ms2 andalso x1 = x2
+      | (CName x1, CName x2) => x1 = x2
+      | _ => false
+
+fun amend_select loc (si, tabs) =
+    let
+        val (tx, c) = case si of
+                          Field (tx, fx) => (tx, (CRecord ([(fx, (CWild (KType, loc), loc))]), loc))
+
+        val (tabs, found) = ListUtil.foldlMap (fn ((tx', c'), found) =>
+                                                  if eqTnames (tx, tx') then
+                                                      ((tx', (CConcat (c, c'), loc)), true)
+                                                  else
+                                                      ((tx', c'), found))
+                            false tabs
+    in
+        if found then
+            ()
+        else
+            ErrorMsg.errorAt loc "Select of field from unbound table";
+
+        tabs
+    end
+
 %%
 %header (functor LacwebLrValsFn(structure Token : TOKEN))
 
@@ -84,6 +117,7 @@
  | str of str
 
  | kind of kind
+ | ktuple of kind list
  | kcolon of explicitness
 
  | path of string list * string
@@ -95,6 +129,7 @@
  | capps of con
  | cterm of con
  | ctuple of con list
+ | ctuplev of con list
  | ident of con
  | idents of con list
  | rcon of (con * con) list
@@ -126,6 +161,12 @@
  | tables of (con * exp) list
  | tname of con
  | table of con * exp
+ | tident of con
+ | fident of con
+ | seli of select_item
+ | selis of select_item list
+ | select of select
+
 
 %verbose                                (* print summary of errors *)
 %pos int                                (* positions *)
@@ -270,6 +311,10 @@
        | LPAREN kind RPAREN             (#1 kind, s (LPARENleft, RPARENright))
        | KUNIT                          (KUnit, s (KUNITleft, KUNITright))
        | UNDERUNDER                     (KWild, s (UNDERUNDERleft, UNDERUNDERright))
+       | LPAREN ktuple RPAREN           (KTuple ktuple, s (LPARENleft, RPARENright))
+
+ktuple : kind STAR kind                 ([kind1, kind2])
+       | kind STAR ktuple               (kind :: ktuple)
 
 capps  : cterm                          (cterm)
        | capps cterm                    (CApp (capps, cterm), s (cappsleft, ctermright))
@@ -319,9 +364,15 @@
        | HASH INT                       (CName (Int64.toString INT), s (HASHleft, INTright))
 
        | path                           (CVar path, s (pathleft, pathright))
+       | path DOT INT                   (CProj ((CVar path, s (pathleft, pathright)), Int64.toInt INT),
+                                         s (pathleft, INTright))
        | UNDER                          (CWild (KWild, s (UNDERleft, UNDERright)), s (UNDERleft, UNDERright))
        | FOLD                           (CFold, s (FOLDleft, FOLDright))
        | UNIT                           (CUnit, s (UNITleft, UNITright))
+       | LPAREN ctuplev RPAREN          (CTuple ctuplev, s (LPARENleft, RPARENright))
+
+ctuplev: cexp COMMA cexp                ([cexp1, cexp2])
+       | cexp COMMA ctuplev             (cexp :: ctuplev)
 
 ctuple : capps STAR capps               ([capps1, capps2])
        | capps STAR ctuple              (capps :: ctuple)
@@ -503,11 +554,34 @@
        | STRING                         (EPrim (Prim.String STRING), s (STRINGleft, STRINGright))
        | LBRACE eexp RBRACE             (eexp)
                 
-query  : SELECT STAR FROM tables        (let
+query  : SELECT select FROM tables      (let
                                              val loc = s (SELECTleft, tablesright)
+
+                                             val sel =
+                                                 case select of
+                                                     Star => map (fn (nm, _) =>
+                                                                     (nm, (CTuple [(CWild (KRecord (KType, loc), loc),
+                                                                                    loc),
+                                                                                   (CRecord [], loc)],
+                                                                           loc))) tables
+                                                   | Items sis =>
+                                                     let
+                                                         val tabs = map (fn (nm, _) => (nm, (CRecord [], loc))) tables
+                                                         val tabs = foldl (amend_select loc) tabs sis
+                                                     in
+                                                         map (fn (nm, c) => (nm,
+                                                                             (CTuple [c,
+                                                                                      (CWild (KRecord (KType, loc), loc),
+                                                                                       loc)], loc))) tabs
+                                                     end
+
+                                             val sel = (CRecord sel, loc)
+
+                                             val e = (EVar (["Basis"], "sql_query"), loc)
+                                             val e = (ECApp (e, sel), loc)
+                                             val e = (EApp (e, (ERecord tables, loc)), loc)
                                          in
-                                             (EApp ((EVar (["Basis"], "sql_query"), loc),
-                                                    (ERecord tables, loc)), loc)
+                                             e
                                          end)
 
 tables : table                          ([table])
@@ -516,7 +590,22 @@
 tname  : CSYMBOL                        (CName CSYMBOL, s (CSYMBOLleft, CSYMBOLright))
        | LBRACE cexp RBRACE             (cexp)
 
-table  : SYMBOL                         ((CName (capitalize SYMBOL), s (SYMBOLleft, SYMBOLright)),
+table  : SYMBOL                         ((CName SYMBOL, s (SYMBOLleft, SYMBOLright)),
                                          (EVar ([], SYMBOL), s (SYMBOLleft, SYMBOLright)))
        | SYMBOL AS tname                (tname, (EVar ([], SYMBOL), s (SYMBOLleft, SYMBOLright)))
        | LBRACE eexp RBRACE AS tname    (tname, eexp)
+
+tident : SYMBOL                         (CName SYMBOL, s (SYMBOLleft, SYMBOLright))
+       | CSYMBOL                        (CName CSYMBOL, s (CSYMBOLleft, CSYMBOLright))
+       | LBRACE cexp RBRACE             (cexp)
+
+fident : CSYMBOL                        (CName CSYMBOL, s (CSYMBOLleft, CSYMBOLright))
+       | LBRACE cexp RBRACE             (cexp)
+
+seli   : tident DOT fident              (Field (tident, fident))
+
+selis  : seli                           ([seli])
+       | seli COMMA selis               (seli :: selis)
+
+select : STAR                           (Star)
+       | selis                          (Items selis)