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