shithub: mc

Download patch

ref: c75921a96eb005b11144df5169064721e64d640b
parent: df0b6010f2506030d6674dedede207d19434f662
author: Ori Bernstein <[email protected]>
date: Tue Jul 17 10:05:33 EDT 2012

Parse and set builtin constraints. First cut.

    We only support one constraint, it must be builtin, and the current
    test case fails to compile in the backend.

--- a/parse/gram.y
+++ b/parse/gram.y
@@ -20,6 +20,7 @@
 static Node *mkpseudodecl(Type *t);
 static void installucons(Stab *st, Type *t);
 Stab *curscope;
+static void constrainwith(Type *t, char *str);
 
 %}
 
@@ -120,6 +121,7 @@
 %type <ty> type structdef uniondef tupledef compoundtype functype funcsig
 %type <ty> generictype
 %type <tylist> tuptybody
+%type <node> typaramlist
 
 %type <tok> asnop cmpop addop mulop shiftop
 
@@ -274,10 +276,18 @@
         ;
 
 generictype
-        : Ttyparam {$$ = mktyparam($1->line, $1->str);}
-        /* FIXME: allow constrained typarmas */
+        : Ttyparam typaramlist 
+            {$$ = mktyparam($1->line, $1->str);
+            /* FIXME: this will only work for builtin cstrs */
+             if ($2)
+                constrainwith($$, $2->name.name);}
         ;
 
+typaramlist
+        : /* empty */ {$$ = NULL;}
+        | Ttrait name {$$ = $2;}
+        ;
+
 compoundtype
         : functype   {$$ = $1;}
         | type Tosqbrac Tcomma Tcsqbrac {$$ = mktyslice($2->line, $1);}
@@ -313,7 +323,7 @@
         ;
 
 tuptybody
-        : type 
+        : type
             {$$.types = NULL; $$.ntypes = 0;
              lappend(&$$.types, &$$.ntypes, $1);}
         | tuptybody Tcomma type
@@ -355,10 +365,10 @@
         ;
 
 unionelt /* nb: the ucon union type gets filled in when we have context */
-        : Ttick Tident type Tendln
-            {$$ = mkucon($2->line, mkname($2->line, $2->str), NULL, $3);}
-        | Ttick Tident Tendln
-            {$$ = mkucon($2->line, mkname($2->line, $2->str), NULL, NULL);}
+        : Ttick name type Tendln
+            {$$ = mkucon($2->line, $2, NULL, $3);}
+        | Ttick name Tendln
+            {$$ = mkucon($2->line, $2, NULL, NULL);}
         | visdef Tendln
             {$$ = NULL;}
         | Tendln
@@ -421,10 +431,10 @@
 cmpop   : Teq | Tgt | Tlt | Tge | Tle | Tne ;
 
 unionexpr
-        : Ttick Tident borexpr
-            {$$ = mkexpr($1->line, Ocons, mkname($2->line, $2->str), $3, NULL);}
-        | Ttick Tident
-            {$$ = mkexpr($1->line, Ocons, mkname($2->line, $2->str), NULL);}
+        : Ttick name borexpr
+            {$$ = mkexpr($1->line, Ocons, $2, $3, NULL);}
+        | Ttick name
+            {$$ = mkexpr($1->line, Ocons, $2, NULL);}
         | borexpr
         ;
 
@@ -665,6 +675,19 @@
         ;
 
 %%
+
+static void constrainwith(Type *t, char *str)
+{
+    size_t i;
+
+    for (i = 0; i < ncstrs; i++) {
+        if (!strcmp(cstrtab[i]->name, str)) {
+            setcstr(t, cstrtab[i]);
+            return;
+        }
+    }
+    fatal(t->line, "Constraint %s does not exist", str);
+}
 
 static Node *mkpseudodecl(Type *t)
 {
--- a/parse/parse.h
+++ b/parse/parse.h
@@ -94,6 +94,8 @@
     int line;
     int resolved;     /* Have we resolved the subtypes? Idempotent, but slow to repeat. */
     Bitset *cstrs;    /* the type constraints matched on this type */
+    Node **cstrlist;  /* The names of the constraints on the type. Used to resolve/fill the bitset */
+    size_t ncstrlist; /* The length of the constraint list above */
     size_t nsub;      /* For compound types */
     size_t nmemb;     /* for aggregate types (struct, union) */
     Type **sub;       /* sub-types; shared by all composite types */
@@ -244,9 +246,9 @@
 extern int line;        /* the last line number we tokenized */
 extern Node *file;      /* the current file we're compiling */
 extern Type **tytab;    /* type -> type map used by inference. size maintained by type creation code */
-extern int ntypes;
+extern size_t ntypes;
 extern Cstr **cstrtab;  /* int -> cstr map */
-extern int ncstrs;
+extern size_t ncstrs;
 extern int maxnid;      /* the maximum node id generated so far */
 extern int maxdid;      /* the maximum decl id generated so far */
 
--- a/parse/type.c
+++ b/parse/type.c
@@ -18,9 +18,9 @@
 };
 
 Type **tytab = NULL;
-int ntypes;
+size_t ntypes;
 Cstr **cstrtab;
-int ncstrs;
+size_t ncstrs;
 
 static Cstr *tycstrs[Ntypes + 1][4];
 
@@ -271,10 +271,10 @@
 
 static int cstrfmt(char *buf, size_t len, Type *t)
 {
+    size_t i;
     char *p;
     char *end;
     char *sep;
-    int i;
 
     if (!t->cstrs || !bscount(t->cstrs))
         return 0;
--- a/test/cstr-builtin.myr
+++ b/test/cstr-builtin.myr
@@ -1,4 +1,4 @@
-const max = {a:@a::tcnum, b:@a::tcnum
+generic max = {a:@a::tcnum, b:@a::tcnum
 	if a > b
 		-> a
 	else