ref: cf357b748945f161ed4a4c7ebac9e1353f3307a3
parent: 4fac3196061c75f159d37bd8e7e51dc64f0dd5df
author: Ori Bernstein <ori@eigenstate.org>
date: Sun Jul 5 07:36:46 EDT 2015
Add proper support for a 'gap' variable. '_' is now a reserved token.
--- a/6/isel.c
+++ b/6/isel.c
@@ -544,6 +544,7 @@
Loc *edx, *cl; /* x86 wants some hard-coded regs */
Node **args;
size_t al;
+ Op op;
args = n->expr.args;
edx = locphysreg(Redx);
@@ -698,8 +699,13 @@
die("Unimplemented op %s", opstr[exprop(n)]);
break;
case Oset:
- assert(exprop(args[0]) == Ovar || exprop(args[0]) == Oderef);
+ op = exprop(args[0]);
+ assert(op == Ovar || op == Oderef || op == Ogap);
assert(!stacknode(args[0]));
+
+ if (op == Ogap)
+ break;
+
b = selexpr(s, args[1]);
if (exprop(args[0]) == Oderef)
a = memloc(s, args[0]->expr.args[0], mode(n));
@@ -739,6 +745,8 @@
} else {
r = loc(s, n);
}
+ break;
+ case Ogap:
break;
case Oblit:
a = selexpr(s, args[0]);
--- a/6/simp.c
+++ b/6/simp.c
@@ -545,6 +545,9 @@
jmp(s, iftrue);
return;
}
+ } else if (exprop(pat) == Ogap) {
+ jmp(s, iftrue);
+ return;
}
switch (t->type) {
/* Never supported */
@@ -830,6 +833,7 @@
case Ostruct: r = rval(s, n, NULL); break;
case Oucon: r = rval(s, n, NULL); break;
case Oarr: r = rval(s, n, NULL); break;
+ case Ogap: r = temp(s, n); break;
default:
fatal(n, "%s cannot be an lvalue", opstr[exprop(n)]);
break;
@@ -1454,6 +1458,9 @@
break;
case Ovar:
r = n;
+ break;
+ case Ogap:
+ fatal(n, "'_' may not be an rvalue");
break;
case Oret:
if (s->isbigret) {
--- a/libregex/compile.myr
+++ b/libregex/compile.myr
@@ -798,7 +798,6 @@
const peekc = {re
var c
- var _
(c, _) = std.striter(re.pat)
-> c
--- a/libregex/test/bld.sub
+++ b/libregex/test/bld.sub
@@ -1,7 +1,7 @@
-test basic = basic.myr testmatch.myr;;
-test boundaries = boundaries.myr testmatch.myr;;
-test capture = capture.myr testmatch.myr;;
-test class = class.myr testmatch.myr;;
-test failmatch = failmatch.myr testmatch.myr;;
-test negclass = negclass.myr testmatch.myr;;
-test unicode = unicode.myr testmatch.myr;;
+test basic {inc=../libstd,inc=..} = basic.myr testmatch.myr;;
+test boundaries {inc=../libstd,inc=..} = boundaries.myr testmatch.myr;;
+test capture {inc=../libstd,inc=..} = capture.myr testmatch.myr;;
+test class {inc=../libstd,inc=..} = class.myr testmatch.myr;;
+test failmatch {inc=../libstd,inc=..} = failmatch.myr testmatch.myr;;
+test negclass {inc=../libstd,inc=..} = negclass.myr testmatch.myr;;
+test unicode {inc=../libstd,inc=..} = unicode.myr testmatch.myr;;
--- a/mbld/deps.myr
+++ b/mbld/deps.myr
@@ -234,7 +234,8 @@
| `std.None: std.fatal("library {}: could not read usefile\n", lib)
;;
match bio.getbe32(f)
- | `std.Some 2: /* nothing: version matches. */
+ | `std.Some 3: /* nothing: version matches. */
+ | `std.Some 2: std.fput(1, "library {}: warning: old usefile version\n", lib)
| `std.Some 1: std.fput(1, "library {}: warning: old usefile version\n", lib)
| `std.Some 0: std.fput(1, "library {}: warning: old usefile version\n", lib)
| `std.Some _: std.fatal("library {}: usefile version unknown\n", lib)
--- a/mi/match.c
+++ b/mi/match.c
@@ -107,7 +107,8 @@
return t->any;
t->any = mkdtree();
t->any->patexpr = pat;
- lappend(cap, ncap, pat);
+ if (cap && ncap)
+ lappend(cap, ncap, pat);
return t->any;
}
@@ -227,6 +228,9 @@
break;
case Ostruct:
ret = addstruct(t, pat, val, cap, ncap);
+ break;
+ case Ogap:
+ ret = addwild(t, pat, val, NULL, NULL);
break;
default:
ret = NULL;
--- a/parse/gram.y
+++ b/parse/gram.y
@@ -110,6 +110,7 @@
%token<tok> Texport /* export */
%token<tok> Tprotect /* protect */
+%token<tok> Tgap /* _ */
%token<tok> Tellipsis/* ... */
%token<tok> Tendln /* ; or \n */
%token<tok> Tendblk /* ;; */
@@ -708,6 +709,8 @@
atomicexpr
: Tident
{$$ = mkexpr($1->loc, Ovar, mkname($1->loc, $1->id), NULL);}
+ | Tgap
+ {$$ = mkexpr($1->loc, Ogap, NULL);}
| literal
| Toparen expr Tcparen
{$$ = $2;}
--- a/parse/infer.c
+++ b/parse/infer.c
@@ -1215,6 +1215,9 @@
settype(st, n, t);
n->expr.did = s->decl.did;
break;
+ case Ogap:
+ infernode(st, np, NULL, NULL);
+ break;
default:
fatal(n, "invalid pattern");
break;
@@ -1433,6 +1436,11 @@
if (!s)
fatal(n, "undeclared var %s", ctxstr(st, args[0]));
initvar(st, n, s);
+ break;
+ case Ogap: /* _ -> @a */
+ if (n->expr.type)
+ return;
+ n->expr.type = mktyvar(n->loc);
break;
case Oucon:
inferucon(st, n, &n->expr.isconst);
--- a/parse/ops.def
+++ b/parse/ops.def
@@ -49,6 +49,7 @@
O(Obreak, 0, OTzarg, "break")
O(Ocontinue, 0, OTzarg, "continue")
O(Ovar, 1, OTmisc, NULL)
+O(Ogap, 1, OTmisc, NULL)
O(Olit, 1, OTmisc, NULL)
O(Oucon, 1, OTmisc, "`")
O(Otup, 1, OTmisc, NULL)
--- a/parse/parse.h
+++ b/parse/parse.h
@@ -4,7 +4,7 @@
# define FATAL
#endif
-#define Abiversion 2
+#define Abiversion 3
typedef uint8_t byte;
typedef unsigned int uint;
--- a/parse/tok.c
+++ b/parse/tok.c
@@ -163,6 +163,7 @@
{
static const struct {char* kw; int tt;} kwmap[] = {
{"$noret", Tattr},
+ {"_", Tgap},
{"break", Tbreak},
{"castto", Tcast},
{"const", Tconst},