]> git.lizzy.rs Git - plan9front.git/blobdiff - sys/src/cmd/pc.y
upas/fs: fix more locking bugs, remove debugging clutter, remove planb mbox code
[plan9front.git] / sys / src / cmd / pc.y
index 0f456a6eb5a12cc23e75b1a2af93ab482d7b152a..73eb301100893ed424e764357aee0b73623ff155 100644 (file)
@@ -7,7 +7,7 @@
 #include <thread.h>
 #include <libsec.h>
 
-int inbase = 10, outbase, divmode, sep, fail, prompt;
+int inbase = 10, outbase, divmode, sep, heads, fail, prompt;
 enum { MAXARGS = 16 };
 
 typedef struct Num Num;
@@ -228,11 +228,38 @@ getsym(char *n, int mk)
        return *p;
 }
 
+static void
+printhead(int n, int s, int sp, char *t)
+{
+       char *q;
+       int i, j, k;
+       
+       for(i = 1; i < n; i *= 10)
+               ;
+       while(i /= 10, i != 0){
+               q = t;
+               *--q = 0;
+               for(j = 0, k = 0; j < n; j += s, k++){
+                       if(k == sep && sep != 0){
+                               *--q = ' ';
+                               k = 0;
+                       }
+                       if(j >= i || j == 0 && i == 1)
+                               *--q = '0' + j / i % 10;
+                       else
+                               *--q = ' ';
+               }
+               for(j = 0; j < sp; j++)
+                       *--q = ' ';
+               print("%s\n", q);
+       }
+}
+
 void
 numprint(Num *n)
 {
        int b;
-       int l, i;
+       int l, i, st, sp;
        char *s, *t, *p, *q;
 
        if(n == nil) return;
@@ -246,6 +273,18 @@ numprint(Num *n)
        l = strlen(s);
        t = emalloc(l * 2 + 4);
        q = t + l * 2 + 4;
+       if(heads){
+               switch(b){
+               case 16: st = 4; sp = 2; break;
+               case 8: st = 3; sp = 1; break;
+               case 2: st = 1; sp = 2; break;
+               default: st = 0; sp = 0;
+               }
+               if(n->sign < 0)
+                       sp++;
+               if(st != 0)
+                       printhead(mpsignif(n), st, sp, q);
+       }
        *--q = 0;
        for(p = s + l - 1, i = 0; p >= s && *p != '-'; p--, i++){
                if(sep != 0 && i == sep){
@@ -260,7 +299,7 @@ numprint(Num *n)
        if(mpcmp(n, mpzero) != 0)
                switch(b){
                case 16: *--q = 'x'; *--q = '0'; break;
-               case 10: if(outbase != 0 && outbase != 10) {*--q = 'd'; *--q = '0';} break;
+               case 10: if(outbase != 0 && outbase != 10 || inbase != 10) {*--q = 'd'; *--q = '0';} break;
                case 8: *--q = '0'; break;
                case 2: *--q = 'b'; *--q = '0'; break;
                }
@@ -388,7 +427,7 @@ stat: { last = nil; }
                save = outbase;
                if(!fail) 
                        outbase = mptoi($3);
-               if(outbase != 2 && outbase != 8 && outbase != 10 && outbase != 16){
+               if(outbase != 0 && outbase != 2 && outbase != 8 && outbase != 10 && outbase != 16){
                        error("no.");
                        outbase = save;
                }
@@ -409,6 +448,19 @@ stat: { last = nil; }
                numdecref(last);
                last = nil;
        }
+       | '\'' { save = inbase; inbase = 10; } expr {
+               inbase = save;
+               save = heads;
+               if(!fail) 
+                       heads = mptoi($3);
+               if(heads != 0 && heads != 1){
+                       error("no.");
+                       heads = save;
+               }
+               numdecref($3);
+               numdecref(last);
+               last = nil;
+       }
        | error
 
 expr: LNUM
@@ -527,7 +579,7 @@ yylex(void)
        if(c == '\n') prompted = 0;
        if(isdigit(c)){
                for(p = buf, *p++ = c; c = Bgetc(in), isalnum(c) || c == '_'; )
-                       if(p < buf + sizeof(buf) - 1)
+                       if(p < buf + sizeof(buf) - 1 && c != '_')
                                *p++ = c;
                *p = 0;
                Bungetc(in);
@@ -638,6 +690,30 @@ fnbin(int, Num **a)
        return r;
 }
 
+Num *
+fnpb(int, Num **a)
+{
+       Num *r;
+       int b;
+       
+       if(toint(a[1], &b, 1)){
+       out:
+               numdecref(a[0]);
+               numdecref(a[1]);
+               return nil;
+       }
+       if(b != 0 && b != 2 && b != 8 && b != 10 && b != 16){
+               error("unsupported base");
+               goto out;
+       }
+       r = nummod(a[0]);
+       if(b == 0)
+               r->b = 0;
+       else
+               r->b = STRONG | b;
+       return r;
+}
+
 Num *
 fnabs(int, Num **a)
 {
@@ -766,6 +842,28 @@ fnsbits(int, Num **a)
        return a[0];
 }
 
+Num *
+fnnsa(int, Num **a)
+{
+       int n, i;
+       mpdigit d;
+
+       a[0] = nummod(a[0]);
+       if(a[0]->sign < 0){
+               numdecref(a[0]);
+               return error("invalid argument");
+       }
+       n = 0;
+       for(i = 0; i < a[0]->top; i++){
+               d = a[0]->p[i];
+               for(; d != 0; d &= d-1)
+                       n++;
+       }
+       itomp(n, a[0]);
+       a[0]->b = 0;
+       return a[0];
+}
+
 Num *
 fngcd(int, Num **a)
 {
@@ -836,6 +934,36 @@ fnrev(int, Num **a)
        return a[0];
 }
 
+Num *
+fncat(int n, Num **a)
+{
+       int i, w;
+       Num *r;
+
+       if(n % 2 != 0){
+               error("cat: odd number of arguments");
+               i = 0;
+       fail:
+               for(; i < n; i++)
+                       numdecref(a[i]);
+               return nil;
+       }
+       r = numalloc();
+       for(i = 0; i < n; i += 2){
+               if(toint(a[i+1], &w, 1)) goto fail;
+               mpleft(r, w, r);
+               if(a[i]->sign < 0 || mpsignif(a[i]) > w){
+                       a[i] = nummod(a[i]);
+                       mptrunc(a[i], w, a[i]);
+               }
+               r->b = basemax(r->b, a[i]->b);
+               mpor(r, a[i], r);
+               numdecref(a[i]);
+               numdecref(a[i+1]);
+       }
+       return r;
+}
+
 void
 main(int argc, char **argv)
 {
@@ -851,6 +979,7 @@ main(int argc, char **argv)
        regfunc("dec", fndec, 1);
        regfunc("oct", fnoct, 1);
        regfunc("bin", fnbin, 1);
+       regfunc("pb", fnpb, 2);
        regfunc("abs", fnabs, 1);
        regfunc("round", fnround, 2);
        regfunc("floor", fnfloor, 2);
@@ -859,10 +988,12 @@ main(int argc, char **argv)
        regfunc("xtend", fnxtend, 2);
        regfunc("ubits", fnubits, 1);
        regfunc("sbits", fnsbits, 1);
+       regfunc("nsa", fnnsa, 1);
        regfunc("gcd", fngcd, 2);
        regfunc("minv", fnminv, 2);
        regfunc("rand", fnrand, 1);
        regfunc("rev", fnrev, 2);
+       regfunc("cat", fncat, -1);
 
        prompt = 1;
        ARGBEGIN{