shithub: mc

Download patch

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},