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)
case TPTR32:
case TPTR64:
if(isptrto(tl, TSTRING)) {
nr->val.sval = mal(8);
nr->val.ctype = CTSTR;
break;
}
nr->val.ctype = CTNIL;
nr->val.vval = 0;
break;
......
......@@ -20,9 +20,13 @@ convlit(Node *n, Type *t)
goto bad1;
case Wlitnil:
if(isptr[et] || et == TINTER)
break;
goto bad1;
if(!isptr[et] && et != TINTER)
goto bad1;
if(isptrto(t, TSTRING)) {
n->val.sval = mal(8);
n->val.ctype = CTSTR;
}
break;
case Wlitstr:
if(isptrto(t, TSTRING))
......
......@@ -219,7 +219,7 @@ enum
OLIST, OCMP,
OPTR, OARRAY,
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,
OOROR,
......
......@@ -18,7 +18,7 @@
%token LMAP LCHAN LINTERFACE LFUNC LSTRUCT
%token LCOLAS LFALL LRETURN
%token LNEW LLEN
%token LVAR LTYPE LCONST LCONVERT
%token LVAR LTYPE LCONST LCONVERT LSELECT
%token LFOR LIF LELSE LSWITCH LCASE LDEFAULT
%token LBREAK LCONTINUE LGO LGOTO LRANGE
%token LOROR LANDAND LEQ LNE LLE LLT LGE LGT
......@@ -37,7 +37,7 @@
%type <node> Astmt Bstmt Cstmt Dstmt
%type <node> for_stmt for_body for_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> expr uexpr pexpr expr_list oexpr oexpr_list expr_list_r
%type <node> name name_name new_name new_name_list_r conexpr
......@@ -360,6 +360,11 @@ complex_stmt:
//if($$->ninit != N && $$->ntest == N)
// yyerror("if conditional should not be missing");
}
| LSELECT select_stmt
{
popdcl();
$$ = $2;
}
| LRANGE range_stmt
{
popdcl();
......@@ -529,6 +534,15 @@ range_stmt:
$$ = $2;
}
select_stmt:
{
markdcl();
}
compound_stmt
{
$$ = nod(OSELECT, $2, N);
}
/*
* expressions
*/
......
......@@ -962,20 +962,20 @@ static struct
"string", LBASETYPE, TSTRING,
"any", LBASETYPE, TANY,
"sys", LPACK, Txxx,
/* keywords */
// "any", LANY, Txxx,
"break", LBREAK, Txxx,
"case", LCASE, Txxx,
"chan", LCHAN, Txxx,
"const", LCONST, Txxx,
"continue", LCONTINUE, Txxx,
"convert", LCONVERT, Txxx,
"convert", LCONVERT, Txxx, // should be a var
"default", LDEFAULT, Txxx,
"else", LELSE, Txxx,
"export", LEXPORT, Txxx,
"fallthrough", LFALL, Txxx,
"false", LFALSE, Txxx,
"false", LFALSE, Txxx, // should be a var
"for", LFOR, Txxx,
"func", LFUNC, Txxx,
"go", LGO, Txxx,
......@@ -985,20 +985,20 @@ static struct
"interface", LINTERFACE, Txxx,
"iota", LIOTA, Txxx,
"map", LMAP, Txxx,
"new", LNEW, Txxx,
"len", LLEN, Txxx,
"nil", LNIL, Txxx,
"new", LNEW, Txxx, // should be a var
"len", LLEN, Txxx, // should be a var
"nil", LNIL, Txxx, // should be a var
"package", LPACKAGE, Txxx,
"panic", LPANIC, Txxx,
"print", LPRINT, Txxx,
"panic", LPANIC, Txxx, // temp
"print", LPRINT, Txxx, // temp
"range", LRANGE, Txxx,
"return", LRETURN, Txxx,
"select", LSELECT, Txxx,
"struct", LSTRUCT, Txxx,
"switch", LSWITCH, Txxx,
"true", LTRUE, Txxx,
"true", LTRUE, Txxx, // should be a var
"type", LTYPE, Txxx,
"var", LVAR, Txxx,
"sys", LPACK, Txxx,
"notwithstanding", LIGNORE, Txxx,
"thetruthofthematter", LIGNORE, Txxx,
......
......@@ -659,6 +659,7 @@ opnames[] =
[OI2I] = "I2I",
[OSLICE] = "SLICE",
[OSUB] = "SUB",
[OSELECT] = "SELECT",
[OSWITCH] = "SWITCH",
[OTYPE] = "TYPE",
[OVAR] = "VAR",
......
......@@ -8,6 +8,21 @@ static int32 debug = 0;
typedef struct Hchan Hchan;
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
{
......@@ -21,6 +36,7 @@ struct Hchan
Link* recvdataq; // pointer for receiver
WaitQ recvq; // list of recv waiters
WaitQ sendq; // list of send waiters
SudoG* free; // freelist
};
struct Link
......@@ -29,6 +45,11 @@ struct Link
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);
void
sys·newchan(uint32 elemsize, uint32 elemalg, uint32 hint,
......@@ -97,7 +118,8 @@ void
sys·chansend1(Hchan* c, ...)
{
byte *ae;
G *gr;
SudoG *sgr;
G* gr;
ae = (byte*)&c + c->eo;
if(debug) {
......@@ -110,30 +132,39 @@ sys·chansend1(Hchan* c, ...)
if(c->dataqsiz > 0)
goto asynch;
gr = dequeue(&c->recvq);
if(gr != nil) {
sgr = dequeue(&c->recvq, c);
if(sgr != nil) {
gr = sgr->g;
freesg(c, sgr);
c->elemalg->copy(c->elemsize, gr->elem, ae);
gr->status = Grunnable;
return;
}
c->elemalg->copy(c->elemsize, g->elem, ae);
sgr = allocsg(c);
g->status = Gwaiting;
enqueue(&c->sendq, g);
enqueue(&c->sendq, sgr);
sys·gosched();
return;
asynch:
while(c->qcount >= c->dataqsiz) {
sgr = allocsg(c);
g->status = Gwaiting;
enqueue(&c->sendq, g);
enqueue(&c->sendq, sgr);
sys·gosched();
}
c->elemalg->copy(c->elemsize, c->senddataq->elem, ae);
c->senddataq = c->senddataq->link;
c->qcount++;
gr = dequeue(&c->recvq);
if(gr != nil)
sgr = dequeue(&c->recvq, c);
if(sgr != nil) {
gr = sgr->g;
freesg(c, sgr);
gr->status = Grunnable;
}
}
// chansend2(hchan *chan any, elem any) (pres bool);
......@@ -141,6 +172,7 @@ void
sys·chansend2(Hchan* c, ...)
{
byte *ae, *ap;
SudoG *sgr;
G *gr;
ae = (byte*)&c + c->eo;
......@@ -156,8 +188,11 @@ sys·chansend2(Hchan* c, ...)
if(c->dataqsiz > 0)
goto asynch;
gr = dequeue(&c->recvq);
if(gr != nil) {
sgr = dequeue(&c->recvq, c);
if(sgr != nil) {
gr = sgr->g;
freesg(c, sgr);
c->elemalg->copy(c->elemsize, gr->elem, ae);
gr->status = Grunnable;
*ap = true;
......@@ -174,9 +209,12 @@ asynch:
c->elemalg->copy(c->elemsize, c->senddataq->elem, ae);
c->senddataq = c->senddataq->link;
c->qcount++;
gr = dequeue(&c->recvq);
if(gr != nil)
sgr = dequeue(&c->recvq, c);
if(gr != nil) {
gr = sgr->g;
freesg(c, sgr);
gr->status = Grunnable;
}
*ap = true;
}
......@@ -185,6 +223,7 @@ void
sys·chanrecv1(Hchan* c, ...)
{
byte *ae;
SudoG *sgs;
G *gs;
ae = (byte*)&c + c->eo;
......@@ -196,30 +235,39 @@ sys·chanrecv1(Hchan* c, ...)
if(c->dataqsiz > 0)
goto asynch;
gs = dequeue(&c->sendq);
if(gs != nil) {
sgs = dequeue(&c->sendq, c);
if(sgs != nil) {
gs = sgs->g;
freesg(c, sgs);
c->elemalg->copy(c->elemsize, ae, gs->elem);
gs->status = Grunnable;
return;
}
sgs = allocsg(c);
g->status = Gwaiting;
enqueue(&c->recvq, g);
enqueue(&c->recvq, sgs);
sys·gosched();
c->elemalg->copy(c->elemsize, ae, g->elem);
return;
asynch:
while(c->qcount <= 0) {
sgs = allocsg(c);
g->status = Gwaiting;
enqueue(&c->recvq, g);
enqueue(&c->recvq, sgs);
sys·gosched();
}
c->elemalg->copy(c->elemsize, ae, c->recvdataq->elem);
c->recvdataq = c->recvdataq->link;
c->qcount--;
gs = dequeue(&c->sendq);
if(gs != nil)
sgs = dequeue(&c->sendq, c);
if(gs != nil) {
gs = sgs->g;
freesg(c, sgs);
gs->status = Grunnable;
}
}
// chanrecv2(hchan *chan any) (elem any, pres bool);
......@@ -227,6 +275,7 @@ void
sys·chanrecv2(Hchan* c, ...)
{
byte *ae, *ap;
SudoG *sgs;
G *gs;
ae = (byte*)&c + c->eo;
......@@ -240,8 +289,11 @@ sys·chanrecv2(Hchan* c, ...)
if(c->dataqsiz > 0)
goto asynch;
gs = dequeue(&c->sendq);
if(gs != nil) {
sgs = dequeue(&c->sendq, c);
if(sgs != nil) {
gs = sgs->g;
freesg(c, sgs);
c->elemalg->copy(c->elemsize, ae, gs->elem);
gs->status = Grunnable;
*ap = true;
......@@ -258,8 +310,70 @@ asynch:
c->elemalg->copy(c->elemsize, ae, c->recvdataq->elem);
c->recvdataq = c->recvdataq->link;
c->qcount--;
gs = dequeue(&c->sendq);
if(gs != nil)
sgs = dequeue(&c->sendq, c);
if(sgs != nil) {
gs = sgs->g;
freesg(c, sgs);
gs->status = Grunnable;
}
*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)
*(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;
typedef struct M M;
typedef struct Stktop Stktop;
typedef struct Alg Alg;
typedef struct WaitQ WaitQ;
/*
* per cpu declaration
......@@ -108,9 +107,9 @@ struct G
byte* stack0; // first stack segment
Gobuf sched;
G* alllink; // on allq
G* qlink; // on wait q
int32 status;
int32 goid;
int64 selgen; // valid sudog pointer
byte elem[8]; // transfer element for chan
};
struct M
......@@ -126,11 +125,6 @@ struct M
int32 siz1;
int32 siz2;
};
struct WaitQ
{
G* first;
G* last;
};
struct Stktop
{
uint8* oldbase;
......@@ -176,8 +170,6 @@ int32 findnull(int8*);
void dump(byte*, int32);
int32 runetochar(byte*, int32);
int32 chartorune(uint32*, byte*);
G* dequeue(WaitQ*);
void enqueue(WaitQ*, G*);
/*
* very low level c-called
......
......@@ -233,24 +233,6 @@ type PS2 *[2] PS; // pair of power series
var Ones 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 {
return mkdch()
}
......@@ -335,8 +317,25 @@ func inv(u *rat) *rat{ // invert a rat
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){
done := false;
for ; !done && n>0; n-- {
......@@ -352,7 +351,6 @@ func Print(U PS){
}
// Evaluate n terms of power series U at x=c
func eval(c *rat, U PS, n int) *rat{
if n==0 { return zero }
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