Commit b78676a4 authored by Ken Thompson's avatar Ken Thompson

start of select

random bugs fixed

SVN=128149
parent 963753d3
...@@ -902,6 +902,11 @@ cgen_as(Node *nl, Node *nr, int op) ...@@ -902,6 +902,11 @@ cgen_as(Node *nl, Node *nr, int op)
case TPTR32: case TPTR32:
case TPTR64: case TPTR64:
if(isptrto(tl, TSTRING)) {
nr->val.sval = mal(8);
nr->val.ctype = CTSTR;
break;
}
nr->val.ctype = CTNIL; nr->val.ctype = CTNIL;
nr->val.vval = 0; nr->val.vval = 0;
break; break;
......
...@@ -20,9 +20,13 @@ convlit(Node *n, Type *t) ...@@ -20,9 +20,13 @@ convlit(Node *n, Type *t)
goto bad1; goto bad1;
case Wlitnil: case Wlitnil:
if(isptr[et] || et == TINTER) if(!isptr[et] && et != TINTER)
break; goto bad1;
goto bad1; if(isptrto(t, TSTRING)) {
n->val.sval = mal(8);
n->val.ctype = CTSTR;
}
break;
case Wlitstr: case Wlitstr:
if(isptrto(t, TSTRING)) if(isptrto(t, TSTRING))
......
...@@ -219,7 +219,7 @@ enum ...@@ -219,7 +219,7 @@ enum
OLIST, OCMP, OLIST, OCMP,
OPTR, OARRAY, OPTR, OARRAY,
ORETURN, OFOR, OIF, OSWITCH, OI2S, OS2I, OI2I, ORETURN, OFOR, OIF, OSWITCH, OI2S, OS2I, OI2I,
OAS, OASOP, OCASE, OXCASE, OFALL, OXFALL, OAS, OASOP, OCASE, OXCASE, OFALL, OXFALL, OSELECT,
OGOTO, OPROC, ONEW, OPANIC, OPRINT, OEMPTY, OGOTO, OPROC, ONEW, OPANIC, OPRINT, OEMPTY,
OOROR, OOROR,
......
...@@ -18,7 +18,7 @@ ...@@ -18,7 +18,7 @@
%token LMAP LCHAN LINTERFACE LFUNC LSTRUCT %token LMAP LCHAN LINTERFACE LFUNC LSTRUCT
%token LCOLAS LFALL LRETURN %token LCOLAS LFALL LRETURN
%token LNEW LLEN %token LNEW LLEN
%token LVAR LTYPE LCONST LCONVERT %token LVAR LTYPE LCONST LCONVERT LSELECT
%token LFOR LIF LELSE LSWITCH LCASE LDEFAULT %token LFOR LIF LELSE LSWITCH LCASE LDEFAULT
%token LBREAK LCONTINUE LGO LGOTO LRANGE %token LBREAK LCONTINUE LGO LGOTO LRANGE
%token LOROR LANDAND LEQ LNE LLE LLT LGE LGT %token LOROR LANDAND LEQ LNE LLE LLT LGE LGT
...@@ -37,7 +37,7 @@ ...@@ -37,7 +37,7 @@
%type <node> Astmt Bstmt Cstmt Dstmt %type <node> Astmt Bstmt Cstmt Dstmt
%type <node> for_stmt for_body for_header %type <node> for_stmt for_body for_header
%type <node> if_stmt if_body if_header %type <node> if_stmt if_body if_header
%type <node> range_header range_body range_stmt %type <node> range_header range_body range_stmt select_stmt
%type <node> simple_stmt osimple_stmt semi_stmt %type <node> simple_stmt osimple_stmt semi_stmt
%type <node> expr uexpr pexpr expr_list oexpr oexpr_list expr_list_r %type <node> expr uexpr pexpr expr_list oexpr oexpr_list expr_list_r
%type <node> name name_name new_name new_name_list_r conexpr %type <node> name name_name new_name new_name_list_r conexpr
...@@ -360,6 +360,11 @@ complex_stmt: ...@@ -360,6 +360,11 @@ complex_stmt:
//if($$->ninit != N && $$->ntest == N) //if($$->ninit != N && $$->ntest == N)
// yyerror("if conditional should not be missing"); // yyerror("if conditional should not be missing");
} }
| LSELECT select_stmt
{
popdcl();
$$ = $2;
}
| LRANGE range_stmt | LRANGE range_stmt
{ {
popdcl(); popdcl();
...@@ -529,6 +534,15 @@ range_stmt: ...@@ -529,6 +534,15 @@ range_stmt:
$$ = $2; $$ = $2;
} }
select_stmt:
{
markdcl();
}
compound_stmt
{
$$ = nod(OSELECT, $2, N);
}
/* /*
* expressions * expressions
*/ */
......
...@@ -962,20 +962,20 @@ static struct ...@@ -962,20 +962,20 @@ static struct
"string", LBASETYPE, TSTRING, "string", LBASETYPE, TSTRING,
"any", LBASETYPE, TANY, "any", LBASETYPE, TANY,
"sys", LPACK, Txxx,
/* keywords */ /* keywords */
// "any", LANY, Txxx,
"break", LBREAK, Txxx, "break", LBREAK, Txxx,
"case", LCASE, Txxx, "case", LCASE, Txxx,
"chan", LCHAN, Txxx, "chan", LCHAN, Txxx,
"const", LCONST, Txxx, "const", LCONST, Txxx,
"continue", LCONTINUE, Txxx, "continue", LCONTINUE, Txxx,
"convert", LCONVERT, Txxx, "convert", LCONVERT, Txxx, // should be a var
"default", LDEFAULT, Txxx, "default", LDEFAULT, Txxx,
"else", LELSE, Txxx, "else", LELSE, Txxx,
"export", LEXPORT, Txxx, "export", LEXPORT, Txxx,
"fallthrough", LFALL, Txxx, "fallthrough", LFALL, Txxx,
"false", LFALSE, Txxx, "false", LFALSE, Txxx, // should be a var
"for", LFOR, Txxx, "for", LFOR, Txxx,
"func", LFUNC, Txxx, "func", LFUNC, Txxx,
"go", LGO, Txxx, "go", LGO, Txxx,
...@@ -985,20 +985,20 @@ static struct ...@@ -985,20 +985,20 @@ static struct
"interface", LINTERFACE, Txxx, "interface", LINTERFACE, Txxx,
"iota", LIOTA, Txxx, "iota", LIOTA, Txxx,
"map", LMAP, Txxx, "map", LMAP, Txxx,
"new", LNEW, Txxx, "new", LNEW, Txxx, // should be a var
"len", LLEN, Txxx, "len", LLEN, Txxx, // should be a var
"nil", LNIL, Txxx, "nil", LNIL, Txxx, // should be a var
"package", LPACKAGE, Txxx, "package", LPACKAGE, Txxx,
"panic", LPANIC, Txxx, "panic", LPANIC, Txxx, // temp
"print", LPRINT, Txxx, "print", LPRINT, Txxx, // temp
"range", LRANGE, Txxx, "range", LRANGE, Txxx,
"return", LRETURN, Txxx, "return", LRETURN, Txxx,
"select", LSELECT, Txxx,
"struct", LSTRUCT, Txxx, "struct", LSTRUCT, Txxx,
"switch", LSWITCH, Txxx, "switch", LSWITCH, Txxx,
"true", LTRUE, Txxx, "true", LTRUE, Txxx, // should be a var
"type", LTYPE, Txxx, "type", LTYPE, Txxx,
"var", LVAR, Txxx, "var", LVAR, Txxx,
"sys", LPACK, Txxx,
"notwithstanding", LIGNORE, Txxx, "notwithstanding", LIGNORE, Txxx,
"thetruthofthematter", LIGNORE, Txxx, "thetruthofthematter", LIGNORE, Txxx,
......
...@@ -659,6 +659,7 @@ opnames[] = ...@@ -659,6 +659,7 @@ opnames[] =
[OI2I] = "I2I", [OI2I] = "I2I",
[OSLICE] = "SLICE", [OSLICE] = "SLICE",
[OSUB] = "SUB", [OSUB] = "SUB",
[OSELECT] = "SELECT",
[OSWITCH] = "SWITCH", [OSWITCH] = "SWITCH",
[OTYPE] = "TYPE", [OTYPE] = "TYPE",
[OVAR] = "VAR", [OVAR] = "VAR",
......
...@@ -8,6 +8,21 @@ static int32 debug = 0; ...@@ -8,6 +8,21 @@ static int32 debug = 0;
typedef struct Hchan Hchan; typedef struct Hchan Hchan;
typedef struct Link Link; typedef struct Link Link;
typedef struct WaitQ WaitQ;
typedef struct SudoG SudoG;
struct SudoG
{
G* g; // g and selgen constitute
int64 selgen; // a weak pointer to g
SudoG* link;
};
struct WaitQ
{
SudoG* first;
SudoG* last;
};
struct Hchan struct Hchan
{ {
...@@ -21,6 +36,7 @@ struct Hchan ...@@ -21,6 +36,7 @@ struct Hchan
Link* recvdataq; // pointer for receiver Link* recvdataq; // pointer for receiver
WaitQ recvq; // list of recv waiters WaitQ recvq; // list of recv waiters
WaitQ sendq; // list of send waiters WaitQ sendq; // list of send waiters
SudoG* free; // freelist
}; };
struct Link struct Link
...@@ -29,6 +45,11 @@ struct Link ...@@ -29,6 +45,11 @@ struct Link
byte elem[8]; byte elem[8];
}; };
static SudoG* dequeue(WaitQ*, Hchan*);
static void enqueue(WaitQ*, SudoG*);
static SudoG* allocsg(Hchan*);
static void freesg(Hchan*, SudoG*);
// newchan(elemsize uint32, elemalg uint32, hint uint32) (hchan *chan any); // newchan(elemsize uint32, elemalg uint32, hint uint32) (hchan *chan any);
void void
sys·newchan(uint32 elemsize, uint32 elemalg, uint32 hint, sys·newchan(uint32 elemsize, uint32 elemalg, uint32 hint,
...@@ -97,7 +118,8 @@ void ...@@ -97,7 +118,8 @@ void
sys·chansend1(Hchan* c, ...) sys·chansend1(Hchan* c, ...)
{ {
byte *ae; byte *ae;
G *gr; SudoG *sgr;
G* gr;
ae = (byte*)&c + c->eo; ae = (byte*)&c + c->eo;
if(debug) { if(debug) {
...@@ -110,30 +132,39 @@ sys·chansend1(Hchan* c, ...) ...@@ -110,30 +132,39 @@ sys·chansend1(Hchan* c, ...)
if(c->dataqsiz > 0) if(c->dataqsiz > 0)
goto asynch; goto asynch;
gr = dequeue(&c->recvq); sgr = dequeue(&c->recvq, c);
if(gr != nil) { if(sgr != nil) {
gr = sgr->g;
freesg(c, sgr);
c->elemalg->copy(c->elemsize, gr->elem, ae); c->elemalg->copy(c->elemsize, gr->elem, ae);
gr->status = Grunnable; gr->status = Grunnable;
return; return;
} }
c->elemalg->copy(c->elemsize, g->elem, ae); c->elemalg->copy(c->elemsize, g->elem, ae);
sgr = allocsg(c);
g->status = Gwaiting; g->status = Gwaiting;
enqueue(&c->sendq, g); enqueue(&c->sendq, sgr);
sys·gosched(); sys·gosched();
return; return;
asynch: asynch:
while(c->qcount >= c->dataqsiz) { while(c->qcount >= c->dataqsiz) {
sgr = allocsg(c);
g->status = Gwaiting; g->status = Gwaiting;
enqueue(&c->sendq, g); enqueue(&c->sendq, sgr);
sys·gosched(); sys·gosched();
} }
c->elemalg->copy(c->elemsize, c->senddataq->elem, ae); c->elemalg->copy(c->elemsize, c->senddataq->elem, ae);
c->senddataq = c->senddataq->link; c->senddataq = c->senddataq->link;
c->qcount++; c->qcount++;
gr = dequeue(&c->recvq); sgr = dequeue(&c->recvq, c);
if(gr != nil) if(sgr != nil) {
gr = sgr->g;
freesg(c, sgr);
gr->status = Grunnable; gr->status = Grunnable;
}
} }
// chansend2(hchan *chan any, elem any) (pres bool); // chansend2(hchan *chan any, elem any) (pres bool);
...@@ -141,6 +172,7 @@ void ...@@ -141,6 +172,7 @@ void
sys·chansend2(Hchan* c, ...) sys·chansend2(Hchan* c, ...)
{ {
byte *ae, *ap; byte *ae, *ap;
SudoG *sgr;
G *gr; G *gr;
ae = (byte*)&c + c->eo; ae = (byte*)&c + c->eo;
...@@ -156,8 +188,11 @@ sys·chansend2(Hchan* c, ...) ...@@ -156,8 +188,11 @@ sys·chansend2(Hchan* c, ...)
if(c->dataqsiz > 0) if(c->dataqsiz > 0)
goto asynch; goto asynch;
gr = dequeue(&c->recvq); sgr = dequeue(&c->recvq, c);
if(gr != nil) { if(sgr != nil) {
gr = sgr->g;
freesg(c, sgr);
c->elemalg->copy(c->elemsize, gr->elem, ae); c->elemalg->copy(c->elemsize, gr->elem, ae);
gr->status = Grunnable; gr->status = Grunnable;
*ap = true; *ap = true;
...@@ -174,9 +209,12 @@ asynch: ...@@ -174,9 +209,12 @@ asynch:
c->elemalg->copy(c->elemsize, c->senddataq->elem, ae); c->elemalg->copy(c->elemsize, c->senddataq->elem, ae);
c->senddataq = c->senddataq->link; c->senddataq = c->senddataq->link;
c->qcount++; c->qcount++;
gr = dequeue(&c->recvq); sgr = dequeue(&c->recvq, c);
if(gr != nil) if(gr != nil) {
gr = sgr->g;
freesg(c, sgr);
gr->status = Grunnable; gr->status = Grunnable;
}
*ap = true; *ap = true;
} }
...@@ -185,6 +223,7 @@ void ...@@ -185,6 +223,7 @@ void
sys·chanrecv1(Hchan* c, ...) sys·chanrecv1(Hchan* c, ...)
{ {
byte *ae; byte *ae;
SudoG *sgs;
G *gs; G *gs;
ae = (byte*)&c + c->eo; ae = (byte*)&c + c->eo;
...@@ -196,30 +235,39 @@ sys·chanrecv1(Hchan* c, ...) ...@@ -196,30 +235,39 @@ sys·chanrecv1(Hchan* c, ...)
if(c->dataqsiz > 0) if(c->dataqsiz > 0)
goto asynch; goto asynch;
gs = dequeue(&c->sendq); sgs = dequeue(&c->sendq, c);
if(gs != nil) { if(sgs != nil) {
gs = sgs->g;
freesg(c, sgs);
c->elemalg->copy(c->elemsize, ae, gs->elem); c->elemalg->copy(c->elemsize, ae, gs->elem);
gs->status = Grunnable; gs->status = Grunnable;
return; return;
} }
sgs = allocsg(c);
g->status = Gwaiting; g->status = Gwaiting;
enqueue(&c->recvq, g); enqueue(&c->recvq, sgs);
sys·gosched(); sys·gosched();
c->elemalg->copy(c->elemsize, ae, g->elem); c->elemalg->copy(c->elemsize, ae, g->elem);
return; return;
asynch: asynch:
while(c->qcount <= 0) { while(c->qcount <= 0) {
sgs = allocsg(c);
g->status = Gwaiting; g->status = Gwaiting;
enqueue(&c->recvq, g); enqueue(&c->recvq, sgs);
sys·gosched(); sys·gosched();
} }
c->elemalg->copy(c->elemsize, ae, c->recvdataq->elem); c->elemalg->copy(c->elemsize, ae, c->recvdataq->elem);
c->recvdataq = c->recvdataq->link; c->recvdataq = c->recvdataq->link;
c->qcount--; c->qcount--;
gs = dequeue(&c->sendq); sgs = dequeue(&c->sendq, c);
if(gs != nil) if(gs != nil) {
gs = sgs->g;
freesg(c, sgs);
gs->status = Grunnable; gs->status = Grunnable;
}
} }
// chanrecv2(hchan *chan any) (elem any, pres bool); // chanrecv2(hchan *chan any) (elem any, pres bool);
...@@ -227,6 +275,7 @@ void ...@@ -227,6 +275,7 @@ void
sys·chanrecv2(Hchan* c, ...) sys·chanrecv2(Hchan* c, ...)
{ {
byte *ae, *ap; byte *ae, *ap;
SudoG *sgs;
G *gs; G *gs;
ae = (byte*)&c + c->eo; ae = (byte*)&c + c->eo;
...@@ -240,8 +289,11 @@ sys·chanrecv2(Hchan* c, ...) ...@@ -240,8 +289,11 @@ sys·chanrecv2(Hchan* c, ...)
if(c->dataqsiz > 0) if(c->dataqsiz > 0)
goto asynch; goto asynch;
gs = dequeue(&c->sendq); sgs = dequeue(&c->sendq, c);
if(gs != nil) { if(sgs != nil) {
gs = sgs->g;
freesg(c, sgs);
c->elemalg->copy(c->elemsize, ae, gs->elem); c->elemalg->copy(c->elemsize, ae, gs->elem);
gs->status = Grunnable; gs->status = Grunnable;
*ap = true; *ap = true;
...@@ -258,8 +310,70 @@ asynch: ...@@ -258,8 +310,70 @@ asynch:
c->elemalg->copy(c->elemsize, ae, c->recvdataq->elem); c->elemalg->copy(c->elemsize, ae, c->recvdataq->elem);
c->recvdataq = c->recvdataq->link; c->recvdataq = c->recvdataq->link;
c->qcount--; c->qcount--;
gs = dequeue(&c->sendq); sgs = dequeue(&c->sendq, c);
if(gs != nil) if(sgs != nil) {
gs = sgs->g;
freesg(c, sgs);
gs->status = Grunnable; gs->status = Grunnable;
}
*ap = true; *ap = true;
} }
static SudoG*
dequeue(WaitQ *q, Hchan *c)
{
SudoG *sgp;
loop:
sgp = q->first;
if(sgp == nil)
return nil;
q->first = sgp->link;
// if sgp is stale, ignore it
if(sgp->selgen != sgp->g->selgen) {
prints("INVALID PSEUDOG POINTER\n");
freesg(c, sgp);
goto loop;
}
// invalidate any others
sgp->g->selgen++;
return sgp;
}
static void
enqueue(WaitQ *q, SudoG *sgp)
{
sgp->link = nil;
if(q->first == nil) {
q->first = sgp;
q->last = sgp;
return;
}
q->last->link = sgp;
q->last = sgp;
}
static SudoG*
allocsg(Hchan *c)
{
SudoG* sg;
sg = c->free;
if(sg != nil) {
c->free = sg->link;
} else
sg = mal(sizeof(*sg));
sg->selgen = g->selgen;
sg->g = g;
return sg;
}
static void
freesg(Hchan *c, SudoG *sg)
{
sg->link = c->free;
c->free = sg;
}
...@@ -254,28 +254,3 @@ sys·morestack(uint64 u) ...@@ -254,28 +254,3 @@ sys·morestack(uint64 u)
*(int32*)234 = 123; // never return *(int32*)234 = 123; // never return
} }
G*
dequeue(WaitQ *q)
{
G *gp;
gp = q->first;
if(gp == nil)
return nil;
q->first = gp->qlink;
return gp;
}
void
enqueue(WaitQ *q, G *gp)
{
gp->qlink = nil;
if(q->first == nil) {
q->first = gp;
q->last = gp;
return;
}
q->last->qlink = gp;
q->last = gp;
}
...@@ -42,7 +42,6 @@ typedef struct G G; ...@@ -42,7 +42,6 @@ typedef struct G G;
typedef struct M M; typedef struct M M;
typedef struct Stktop Stktop; typedef struct Stktop Stktop;
typedef struct Alg Alg; typedef struct Alg Alg;
typedef struct WaitQ WaitQ;
/* /*
* per cpu declaration * per cpu declaration
...@@ -108,9 +107,9 @@ struct G ...@@ -108,9 +107,9 @@ struct G
byte* stack0; // first stack segment byte* stack0; // first stack segment
Gobuf sched; Gobuf sched;
G* alllink; // on allq G* alllink; // on allq
G* qlink; // on wait q
int32 status; int32 status;
int32 goid; int32 goid;
int64 selgen; // valid sudog pointer
byte elem[8]; // transfer element for chan byte elem[8]; // transfer element for chan
}; };
struct M struct M
...@@ -126,11 +125,6 @@ struct M ...@@ -126,11 +125,6 @@ struct M
int32 siz1; int32 siz1;
int32 siz2; int32 siz2;
}; };
struct WaitQ
{
G* first;
G* last;
};
struct Stktop struct Stktop
{ {
uint8* oldbase; uint8* oldbase;
...@@ -176,8 +170,6 @@ int32 findnull(int8*); ...@@ -176,8 +170,6 @@ int32 findnull(int8*);
void dump(byte*, int32); void dump(byte*, int32);
int32 runetochar(byte*, int32); int32 runetochar(byte*, int32);
int32 chartorune(uint32*, byte*); int32 chartorune(uint32*, byte*);
G* dequeue(WaitQ*);
void enqueue(WaitQ*, G*);
/* /*
* very low level c-called * very low level c-called
......
...@@ -233,24 +233,6 @@ type PS2 *[2] PS; // pair of power series ...@@ -233,24 +233,6 @@ type PS2 *[2] PS; // pair of power series
var Ones PS var Ones PS
var Twos PS var Twos PS
// print eval in floating point of PS at x=c to n terms
func
Evaln(c *rat, U PS, n int)
{
xn := float64(1);
x := float64(c.num)/float64(c.den);
val := float64(0);
for i:=0; i<n; i++ {
u := get(U);
if end(u) != 0 {
break;
}
val = val + x * float64(u.num)/float64(u.den);
xn = xn*x;
}
print val, "\n";
}
func mkPS() *dch { func mkPS() *dch {
return mkdch() return mkdch()
} }
...@@ -335,8 +317,25 @@ func inv(u *rat) *rat{ // invert a rat ...@@ -335,8 +317,25 @@ func inv(u *rat) *rat{ // invert a rat
return i2tor(u.den, u.num); return i2tor(u.den, u.num);
} }
// Print n terms of a power series // print eval in floating point of PS at x=c to n terms
func
Evaln(c *rat, U PS, n int)
{
xn := float64(1);
x := float64(c.num)/float64(c.den);
val := float64(0);
for i:=0; i<n; i++ {
u := get(U);
if end(u) != 0 {
break;
}
val = val + x * float64(u.num)/float64(u.den);
xn = xn*x;
}
print val, "\n";
}
// Print n terms of a power series
func Printn(U PS, n int){ func Printn(U PS, n int){
done := false; done := false;
for ; !done && n>0; n-- { for ; !done && n>0; n-- {
...@@ -352,7 +351,6 @@ func Print(U PS){ ...@@ -352,7 +351,6 @@ func Print(U PS){
} }
// Evaluate n terms of power series U at x=c // Evaluate n terms of power series U at x=c
func eval(c *rat, U PS, n int) *rat{ func eval(c *rat, U PS, n int) *rat{
if n==0 { return zero } if n==0 { return zero }
y := get(U); y := get(U);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment