mirror of
https://github.com/golang/go
synced 2024-11-18 20:04:52 -07:00
simplifying grammar: delete LBASETYPE and LACONST
R=ken OCL=29300 CL=29302
This commit is contained in:
parent
b112d42ad6
commit
2a4dcfffc9
@ -1056,7 +1056,7 @@ addconst(Node *n, Node *e, int ctxt)
|
|||||||
|
|
||||||
redeclare("constant", s);
|
redeclare("constant", s);
|
||||||
s->oconst = e;
|
s->oconst = e;
|
||||||
s->lexical = LACONST;
|
s->lexical = LNAME;
|
||||||
|
|
||||||
d = dcl();
|
d = dcl();
|
||||||
d->dsym = s;
|
d->dsym = s;
|
||||||
@ -1136,6 +1136,14 @@ oldname(Sym *s)
|
|||||||
Node *n;
|
Node *n;
|
||||||
Node *c;
|
Node *c;
|
||||||
|
|
||||||
|
if(s->oconst) {
|
||||||
|
n = nod(OLITERAL, N, N);
|
||||||
|
n->sym = s;
|
||||||
|
n->val = s->oconst->val;
|
||||||
|
n->type = s->oconst->type;
|
||||||
|
return n;
|
||||||
|
}
|
||||||
|
|
||||||
n = s->oname;
|
n = s->oname;
|
||||||
if(n == N) {
|
if(n == N) {
|
||||||
n = nod(ONONAME, N, N);
|
n = nod(ONONAME, N, N);
|
||||||
@ -1205,11 +1213,11 @@ nametoanondcl(Node *na)
|
|||||||
for(l=&na; (n=*l)->op == OLIST; l=&n->left)
|
for(l=&na; (n=*l)->op == OLIST; l=&n->left)
|
||||||
n->right = nametoanondcl(n->right);
|
n->right = nametoanondcl(n->right);
|
||||||
|
|
||||||
if(n->sym->lexical != LATYPE && n->sym->lexical != LBASETYPE) {
|
t = n->sym->otype;
|
||||||
|
if(t == T) {
|
||||||
yyerror("%s is not a type", n->sym->name);
|
yyerror("%s is not a type", n->sym->name);
|
||||||
t = typ(TINT32);
|
t = typ(TINT32);
|
||||||
} else
|
}
|
||||||
t = oldtype(n->sym);
|
|
||||||
n = nod(ODCLFIELD, N, N);
|
n = nod(ODCLFIELD, N, N);
|
||||||
n->type = t;
|
n->type = t;
|
||||||
*l = n;
|
*l = n;
|
||||||
|
@ -190,7 +190,6 @@ dumpsym(Sym *s)
|
|||||||
yyerror("package export symbol: %S", s);
|
yyerror("package export symbol: %S", s);
|
||||||
break;
|
break;
|
||||||
case LATYPE:
|
case LATYPE:
|
||||||
case LBASETYPE:
|
|
||||||
// TODO(rsc): sort methods by name
|
// TODO(rsc): sort methods by name
|
||||||
for(f=s->otype->method; f!=T; f=f->down)
|
for(f=s->otype->method; f!=T; f=f->down)
|
||||||
dumpprereq(f);
|
dumpprereq(f);
|
||||||
@ -201,10 +200,10 @@ dumpsym(Sym *s)
|
|||||||
f->type->type->type, f->sym, f->type);
|
f->type->type->type, f->sym, f->type);
|
||||||
break;
|
break;
|
||||||
case LNAME:
|
case LNAME:
|
||||||
dumpexportvar(s);
|
if(s->oconst)
|
||||||
break;
|
dumpexportconst(s);
|
||||||
case LACONST:
|
else
|
||||||
dumpexportconst(s);
|
dumpexportvar(s);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -344,7 +343,7 @@ importconst(Node *ss, Type *t, Node *n)
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
convlit(n, t);
|
convlit(n, t);
|
||||||
s = importsym(ss, LACONST);
|
s = importsym(ss, LNAME);
|
||||||
if(s->oconst != N) {
|
if(s->oconst != N) {
|
||||||
// TODO: check if already the same.
|
// TODO: check if already the same.
|
||||||
return;
|
return;
|
||||||
|
@ -14,7 +14,7 @@
|
|||||||
}
|
}
|
||||||
%token <val> LLITERAL
|
%token <val> LLITERAL
|
||||||
%token <lint> LASOP
|
%token <lint> LASOP
|
||||||
%token <sym> LNAME LBASETYPE LATYPE LPACK LACONST
|
%token <sym> LNAME LATYPE LPACK
|
||||||
%token <sym> LPACKAGE LIMPORT LDEFER LCLOSE LCLOSED
|
%token <sym> LPACKAGE LIMPORT LDEFER LCLOSE LCLOSED
|
||||||
%token <sym> LMAP LCHAN LINTERFACE LFUNC LSTRUCT
|
%token <sym> LMAP LCHAN LINTERFACE LFUNC LSTRUCT
|
||||||
%token <sym> LCOLAS LFALL LRETURN LDDD
|
%token <sym> LCOLAS LFALL LRETURN LDDD
|
||||||
@ -42,7 +42,7 @@
|
|||||||
* names like Bstmt, Bvardcl, etc. can't.
|
* names like Bstmt, Bvardcl, etc. can't.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
%type <sym> sym sym1 sym2 sym3 keyword laconst lname latype lpackatype
|
%type <sym> sym sym1 sym2 sym3 keyword lname latype lpackatype
|
||||||
%type <node> xdcl xdcl_list_r oxdcl_list
|
%type <node> xdcl xdcl_list_r oxdcl_list
|
||||||
%type <node> common_dcl Acommon_dcl Bcommon_dcl
|
%type <node> common_dcl Acommon_dcl Bcommon_dcl
|
||||||
%type <node> oarg_type_list arg_type_list_r arg_chunk arg_chunk_list_r arg_type_list
|
%type <node> oarg_type_list arg_type_list_r arg_chunk arg_chunk_list_r arg_type_list
|
||||||
@ -913,13 +913,6 @@ pexpr:
|
|||||||
{
|
{
|
||||||
$$ = nodbool(0);
|
$$ = nodbool(0);
|
||||||
}
|
}
|
||||||
| laconst
|
|
||||||
{
|
|
||||||
$$ = nod(OLITERAL, N, N);
|
|
||||||
$$->sym = $1;
|
|
||||||
$$->val = $1->oconst->val;
|
|
||||||
$$->type = $1->oconst->type;
|
|
||||||
}
|
|
||||||
| LIOTA
|
| LIOTA
|
||||||
{
|
{
|
||||||
$$ = nodintconst(iota);
|
$$ = nodintconst(iota);
|
||||||
@ -1023,14 +1016,6 @@ lpack:
|
|||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
laconst:
|
|
||||||
LACONST
|
|
||||||
| lpack '.' LACONST
|
|
||||||
{
|
|
||||||
$$ = $3;
|
|
||||||
context = nil;
|
|
||||||
}
|
|
||||||
|
|
||||||
lname:
|
lname:
|
||||||
LNAME
|
LNAME
|
||||||
| lpack '.' LNAME
|
| lpack '.' LNAME
|
||||||
@ -1082,7 +1067,6 @@ onew_name:
|
|||||||
sym:
|
sym:
|
||||||
LATYPE
|
LATYPE
|
||||||
| LNAME
|
| LNAME
|
||||||
| LACONST
|
|
||||||
| LPACK
|
| LPACK
|
||||||
|
|
||||||
sym1:
|
sym1:
|
||||||
@ -1112,7 +1096,6 @@ sym3:
|
|||||||
| LPRINTN
|
| LPRINTN
|
||||||
| LNEW
|
| LNEW
|
||||||
| LMAKE
|
| LMAKE
|
||||||
| LBASETYPE
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* keywords that we can
|
* keywords that we can
|
||||||
@ -2129,20 +2112,8 @@ lpack:
|
|||||||
YYERROR;
|
YYERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
laconst:
|
|
||||||
LATYPE
|
|
||||||
{
|
|
||||||
yyerror("%s is type, not var", $1->name);
|
|
||||||
YYERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
latype:
|
latype:
|
||||||
LACONST
|
LPACK
|
||||||
{
|
|
||||||
yyerror("%s is const, not type", $1->name);
|
|
||||||
YYERROR;
|
|
||||||
}
|
|
||||||
| LPACK
|
|
||||||
{
|
{
|
||||||
yyerror("%s is package, not type", $1->name);
|
yyerror("%s is package, not type", $1->name);
|
||||||
YYERROR;
|
YYERROR;
|
||||||
|
@ -64,7 +64,7 @@ main(int argc, char *argv[])
|
|||||||
fatal("betypeinit failed");
|
fatal("betypeinit failed");
|
||||||
|
|
||||||
lexinit();
|
lexinit();
|
||||||
typeinit(LBASETYPE);
|
typeinit(LATYPE);
|
||||||
|
|
||||||
lineno = 1;
|
lineno = 1;
|
||||||
block = 1;
|
block = 1;
|
||||||
@ -775,8 +775,6 @@ talph:
|
|||||||
|
|
||||||
DBG("lex: %S %s\n", s, lexname(s->lexical));
|
DBG("lex: %S %s\n", s, lexname(s->lexical));
|
||||||
yylval.sym = s;
|
yylval.sym = s;
|
||||||
if(s->lexical == LBASETYPE)
|
|
||||||
return LATYPE;
|
|
||||||
return s->lexical;
|
return s->lexical;
|
||||||
|
|
||||||
tnum:
|
tnum:
|
||||||
@ -1111,25 +1109,25 @@ static struct
|
|||||||
/* name lexical etype
|
/* name lexical etype
|
||||||
*/
|
*/
|
||||||
/* basic types */
|
/* basic types */
|
||||||
"int8", LBASETYPE, TINT8,
|
"int8", LATYPE, TINT8,
|
||||||
"int16", LBASETYPE, TINT16,
|
"int16", LATYPE, TINT16,
|
||||||
"int32", LBASETYPE, TINT32,
|
"int32", LATYPE, TINT32,
|
||||||
"int64", LBASETYPE, TINT64,
|
"int64", LATYPE, TINT64,
|
||||||
|
|
||||||
"uint8", LBASETYPE, TUINT8,
|
"uint8", LATYPE, TUINT8,
|
||||||
"uint16", LBASETYPE, TUINT16,
|
"uint16", LATYPE, TUINT16,
|
||||||
"uint32", LBASETYPE, TUINT32,
|
"uint32", LATYPE, TUINT32,
|
||||||
"uint64", LBASETYPE, TUINT64,
|
"uint64", LATYPE, TUINT64,
|
||||||
|
|
||||||
"float32", LBASETYPE, TFLOAT32,
|
"float32", LATYPE, TFLOAT32,
|
||||||
"float64", LBASETYPE, TFLOAT64,
|
"float64", LATYPE, TFLOAT64,
|
||||||
"float80", LBASETYPE, TFLOAT80,
|
"float80", LATYPE, TFLOAT80,
|
||||||
|
|
||||||
"bool", LBASETYPE, TBOOL,
|
"bool", LATYPE, TBOOL,
|
||||||
"byte", LBASETYPE, TUINT8,
|
"byte", LATYPE, TUINT8,
|
||||||
"string", LBASETYPE, TSTRING,
|
"string", LATYPE, TSTRING,
|
||||||
|
|
||||||
"any", LBASETYPE, TANY,
|
"any", LATYPE, TANY,
|
||||||
|
|
||||||
"break", LBREAK, Txxx,
|
"break", LBREAK, Txxx,
|
||||||
"case", LCASE, Txxx,
|
"case", LCASE, Txxx,
|
||||||
@ -1197,10 +1195,10 @@ lexinit(void)
|
|||||||
s->lexical = lex;
|
s->lexical = lex;
|
||||||
s->package = package;
|
s->package = package;
|
||||||
|
|
||||||
if(lex != LBASETYPE)
|
etype = syms[i].etype;
|
||||||
|
if(etype == Txxx)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
etype = syms[i].etype;
|
|
||||||
if(etype < 0 || etype >= nelem(types))
|
if(etype < 0 || etype >= nelem(types))
|
||||||
fatal("lexinit: %s bad etype", s->name);
|
fatal("lexinit: %s bad etype", s->name);
|
||||||
|
|
||||||
@ -1234,9 +1232,6 @@ struct
|
|||||||
{
|
{
|
||||||
LANDAND, "ANDAND",
|
LANDAND, "ANDAND",
|
||||||
LASOP, "ASOP",
|
LASOP, "ASOP",
|
||||||
LACONST, "ACONST",
|
|
||||||
LATYPE, "ATYPE",
|
|
||||||
LBASETYPE, "BASETYPE",
|
|
||||||
LBREAK, "BREAK",
|
LBREAK, "BREAK",
|
||||||
LCASE, "CASE",
|
LCASE, "CASE",
|
||||||
LCHAN, "CHAN",
|
LCHAN, "CHAN",
|
||||||
|
@ -10,7 +10,7 @@ exvar.install: fmt.install http.install io.install log.install strconv.install s
|
|||||||
flag.install: fmt.install os.install strconv.install
|
flag.install: fmt.install os.install strconv.install
|
||||||
fmt.install: io.install os.install reflect.install strconv.install utf8.install
|
fmt.install: io.install os.install reflect.install strconv.install utf8.install
|
||||||
go/ast.install: go/token.install unicode.install utf8.install
|
go/ast.install: go/token.install unicode.install utf8.install
|
||||||
go/doc.install: container/vector.install fmt.install go/ast.install go/token.install io.install once.install regexp.install sort.install strings.install
|
go/doc.install: container/vector.install fmt.install go/ast.install go/token.install io.install once.install regexp.install sort.install strings.install template.install
|
||||||
go/parser.install: container/vector.install fmt.install go/ast.install go/scanner.install go/token.install io.install os.install
|
go/parser.install: container/vector.install fmt.install go/ast.install go/scanner.install go/token.install io.install os.install
|
||||||
go/scanner.install: go/token.install strconv.install unicode.install utf8.install
|
go/scanner.install: go/token.install strconv.install unicode.install utf8.install
|
||||||
go/token.install: strconv.install
|
go/token.install: strconv.install
|
||||||
@ -39,7 +39,7 @@ syscall.install: sync.install
|
|||||||
tabwriter.install: container/vector.install io.install os.install utf8.install
|
tabwriter.install: container/vector.install io.install os.install utf8.install
|
||||||
template.install: container/vector.install fmt.install io.install os.install reflect.install runtime.install strings.install
|
template.install: container/vector.install fmt.install io.install os.install reflect.install runtime.install strings.install
|
||||||
testing.install: flag.install fmt.install os.install runtime.install
|
testing.install: flag.install fmt.install os.install runtime.install
|
||||||
testing/iotest.install: io.install os.install
|
testing/iotest.install: io.install log.install os.install
|
||||||
time.install: io.install once.install os.install syscall.install
|
time.install: io.install once.install os.install syscall.install
|
||||||
unicode.install:
|
unicode.install:
|
||||||
utf8.install:
|
utf8.install:
|
||||||
|
@ -109,11 +109,11 @@ func (b *Reader) fill() os.Error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Read reads data into p.
|
// Read reads data into p, returning the number of bytes read.
|
||||||
// It returns the number of bytes read into p.
|
// Read reads as much data as possible into p.
|
||||||
// If nn < len(p), also returns an error explaining
|
// If nn < len(p), Read also returns an error explaining
|
||||||
// why the read is short. At EOF, the count will be
|
// why the read is short. At EOF, the count will be
|
||||||
// zero and err will be io.ErrEOF.
|
// zero and err will be io.ErrUnexpectedEOF.
|
||||||
func (b *Reader) Read(p []byte) (nn int, err os.Error) {
|
func (b *Reader) Read(p []byte) (nn int, err os.Error) {
|
||||||
nn = 0;
|
nn = 0;
|
||||||
for len(p) > 0 {
|
for len(p) > 0 {
|
||||||
|
@ -69,7 +69,19 @@ type ReadWriteCloser interface {
|
|||||||
Closer;
|
Closer;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Convert a string to an array of bytes for easy marshaling.
|
// ReadByter is the interface that wraps the basic ReadByte method.
|
||||||
|
// Implementations of ReadByte typically use buffered I/O.
|
||||||
|
type ReadByter interface {
|
||||||
|
ReadByte() (byte, os.Error);
|
||||||
|
}
|
||||||
|
|
||||||
|
// WriteByter is the interface that wraps the basic WriteByte method.
|
||||||
|
// Implementations of WriteByte typically use buffered I/O.
|
||||||
|
type WriteByter interface {
|
||||||
|
WriteByte(byte) os.Error;
|
||||||
|
}
|
||||||
|
|
||||||
|
// StringBytes converts a string to an array of bytes for easy marshaling.
|
||||||
func StringBytes(s string) []byte {
|
func StringBytes(s string) []byte {
|
||||||
b := make([]byte, len(s));
|
b := make([]byte, len(s));
|
||||||
for i := 0; i < len(s); i++ {
|
for i := 0; i < len(s); i++ {
|
||||||
|
@ -21,7 +21,9 @@ type pipeReturn struct {
|
|||||||
// Shared pipe structure.
|
// Shared pipe structure.
|
||||||
type pipe struct {
|
type pipe struct {
|
||||||
rclosed bool; // Read end closed?
|
rclosed bool; // Read end closed?
|
||||||
|
rerr os.Error; // Error supplied to CloseReader
|
||||||
wclosed bool; // Write end closed?
|
wclosed bool; // Write end closed?
|
||||||
|
werr os.Error; // Error supplied to CloseWriter
|
||||||
wpend []byte; // Written data waiting to be read.
|
wpend []byte; // Written data waiting to be read.
|
||||||
wtot int; // Bytes consumed so far in current write.
|
wtot int; // Bytes consumed so far in current write.
|
||||||
cr chan []byte; // Write sends data here...
|
cr chan []byte; // Write sends data here...
|
||||||
@ -39,7 +41,7 @@ func (p *pipe) Read(data []byte) (n int, err os.Error) {
|
|||||||
p.wpend = <-p.cr;
|
p.wpend = <-p.cr;
|
||||||
}
|
}
|
||||||
if p.wpend == nil {
|
if p.wpend == nil {
|
||||||
return 0, nil;
|
return 0, p.werr;
|
||||||
}
|
}
|
||||||
p.wtot = 0;
|
p.wtot = 0;
|
||||||
}
|
}
|
||||||
@ -70,7 +72,7 @@ func (p *pipe) Write(data []byte) (n int, err os.Error) {
|
|||||||
return 0, os.EINVAL;
|
return 0, os.EINVAL;
|
||||||
}
|
}
|
||||||
if p.rclosed {
|
if p.rclosed {
|
||||||
return 0, os.EPIPE;
|
return 0, p.rerr;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Send data to reader.
|
// Send data to reader.
|
||||||
@ -81,29 +83,34 @@ func (p *pipe) Write(data []byte) (n int, err os.Error) {
|
|||||||
return res.n, res.err;
|
return res.n, res.err;
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *pipe) CloseReader() os.Error {
|
func (p *pipe) CloseReader(rerr os.Error) os.Error {
|
||||||
if p == nil || p.rclosed {
|
if p == nil || p.rclosed {
|
||||||
return os.EINVAL;
|
return os.EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Stop any future writes.
|
// Stop any future writes.
|
||||||
p.rclosed = true;
|
p.rclosed = true;
|
||||||
|
if rerr == nil {
|
||||||
|
rerr = os.EPIPE;
|
||||||
|
}
|
||||||
|
p.rerr = rerr;
|
||||||
|
|
||||||
// Stop the current write.
|
// Stop the current write.
|
||||||
if !p.wclosed {
|
if !p.wclosed {
|
||||||
p.cw <- pipeReturn{p.wtot, os.EPIPE};
|
p.cw <- pipeReturn{p.wtot, rerr};
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil;
|
return nil;
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *pipe) CloseWriter() os.Error {
|
func (p *pipe) CloseWriter(werr os.Error) os.Error {
|
||||||
if p == nil || p.wclosed {
|
if p == nil || p.wclosed {
|
||||||
return os.EINVAL;
|
return os.EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Stop any future reads.
|
// Stop any future reads.
|
||||||
p.wclosed = true;
|
p.wclosed = true;
|
||||||
|
p.werr = werr;
|
||||||
|
|
||||||
// Stop the current read.
|
// Stop the current read.
|
||||||
if !p.rclosed {
|
if !p.rclosed {
|
||||||
@ -121,70 +128,97 @@ func (p *pipe) CloseWriter() os.Error {
|
|||||||
// 2. Clients cannot use interface conversions on the
|
// 2. Clients cannot use interface conversions on the
|
||||||
// read end to find the Write method, and vice versa.
|
// read end to find the Write method, and vice versa.
|
||||||
|
|
||||||
// Read half of pipe.
|
// A PipeReader is the read half of a pipe.
|
||||||
type pipeRead struct {
|
type PipeReader struct {
|
||||||
lock sync.Mutex;
|
lock sync.Mutex;
|
||||||
p *pipe;
|
p *pipe;
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *pipeRead) Read(data []byte) (n int, err os.Error) {
|
// Read implements the standard Read interface:
|
||||||
|
// it reads data from the pipe, blocking until a writer
|
||||||
|
// arrives or the write end is closed.
|
||||||
|
// If the write end is closed with an error, that error is
|
||||||
|
// returned as err; otherwise err is nil.
|
||||||
|
func (r *PipeReader) Read(data []byte) (n int, err os.Error) {
|
||||||
r.lock.Lock();
|
r.lock.Lock();
|
||||||
defer r.lock.Unlock();
|
defer r.lock.Unlock();
|
||||||
|
|
||||||
return r.p.Read(data);
|
return r.p.Read(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *pipeRead) Close() os.Error {
|
// Close closes the reader; subsequent writes to the
|
||||||
|
// write half of the pipe will return the error os.EPIPE.
|
||||||
|
func (r *PipeReader) Close() os.Error {
|
||||||
r.lock.Lock();
|
r.lock.Lock();
|
||||||
defer r.lock.Unlock();
|
defer r.lock.Unlock();
|
||||||
|
|
||||||
return r.p.CloseReader();
|
return r.p.CloseReader(nil);
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *pipeRead) finish() {
|
// CloseWithError closes the reader; subsequent writes
|
||||||
|
// to the write half of the pipe will return the error rerr.
|
||||||
|
func (r *PipeReader) CloseWithError(rerr os.Error) os.Error {
|
||||||
|
r.lock.Lock();
|
||||||
|
defer r.lock.Unlock();
|
||||||
|
|
||||||
|
return r.p.CloseReader(rerr);
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *PipeReader) finish() {
|
||||||
r.Close();
|
r.Close();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Write half of pipe.
|
// Write half of pipe.
|
||||||
type pipeWrite struct {
|
type PipeWriter struct {
|
||||||
lock sync.Mutex;
|
lock sync.Mutex;
|
||||||
p *pipe;
|
p *pipe;
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w *pipeWrite) Write(data []byte) (n int, err os.Error) {
|
// Write implements the standard Write interface:
|
||||||
|
// it writes data to the pipe, blocking until readers
|
||||||
|
// have consumed all the data or the read end is closed.
|
||||||
|
// If the read end is closed with an error, that err is
|
||||||
|
// returned as err; otherwise err is os.EPIPE.
|
||||||
|
func (w *PipeWriter) Write(data []byte) (n int, err os.Error) {
|
||||||
w.lock.Lock();
|
w.lock.Lock();
|
||||||
defer w.lock.Unlock();
|
defer w.lock.Unlock();
|
||||||
|
|
||||||
return w.p.Write(data);
|
return w.p.Write(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w *pipeWrite) Close() os.Error {
|
// Close closes the writer; subsequent reads from the
|
||||||
|
// read half of the pipe will return no bytes and a nil error.
|
||||||
|
func (w *PipeWriter) Close() os.Error {
|
||||||
w.lock.Lock();
|
w.lock.Lock();
|
||||||
defer w.lock.Unlock();
|
defer w.lock.Unlock();
|
||||||
|
|
||||||
return w.p.CloseWriter();
|
return w.p.CloseWriter(nil);
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w *pipeWrite) finish() {
|
// CloseWithError closes the writer; subsequent reads from the
|
||||||
|
// read half of the pipe will return no bytes and the error werr.
|
||||||
|
func (w *PipeWriter) CloseWithError(werr os.Error) os.Error {
|
||||||
|
w.lock.Lock();
|
||||||
|
defer w.lock.Unlock();
|
||||||
|
|
||||||
|
return w.p.CloseWriter(werr);
|
||||||
|
}
|
||||||
|
|
||||||
|
func (w *PipeWriter) finish() {
|
||||||
w.Close();
|
w.Close();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Pipe creates a synchronous in-memory pipe.
|
// Pipe creates a synchronous in-memory pipe.
|
||||||
// Used to connect code expecting an io.Reader
|
// It can be used to connect code expecting an io.Reader
|
||||||
// with code expecting an io.Writer.
|
// with code expecting an io.Writer.
|
||||||
//
|
// Reads on one end are matched with writes on the other.
|
||||||
// Reads on one end are matched by writes on the other.
|
func Pipe() (*PipeReader, *PipeWriter) {
|
||||||
// Writes don't complete until all the data has been
|
|
||||||
// written or the read end is closed. Reads return
|
|
||||||
// any available data or block until the next write
|
|
||||||
// or the write end is closed.
|
|
||||||
func Pipe() (io.ReadCloser, io.WriteCloser) {
|
|
||||||
p := new(pipe);
|
p := new(pipe);
|
||||||
p.cr = make(chan []byte, 1);
|
p.cr = make(chan []byte, 1);
|
||||||
p.cw = make(chan pipeReturn, 1);
|
p.cw = make(chan pipeReturn, 1);
|
||||||
r := new(pipeRead);
|
r := new(PipeReader);
|
||||||
r.p = p;
|
r.p = p;
|
||||||
w := new(pipeWrite);
|
w := new(PipeWriter);
|
||||||
w.p = p;
|
w.p = p;
|
||||||
return r, w;
|
return r, w;
|
||||||
}
|
}
|
||||||
|
121
src/lib/runtime/types.go
Normal file
121
src/lib/runtime/types.go
Normal file
@ -0,0 +1,121 @@
|
|||||||
|
// Copyright 2009 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
// TODO(rsc): Doc comments
|
||||||
|
|
||||||
|
package runtime
|
||||||
|
|
||||||
|
import "unsafe"
|
||||||
|
|
||||||
|
// The Type interface stands for any of the run-time type structures
|
||||||
|
// in this package.
|
||||||
|
type Type interface { }
|
||||||
|
|
||||||
|
// All types begin with a few common fields needed for
|
||||||
|
// the interface runtime.
|
||||||
|
type CommonType struct {
|
||||||
|
Size uintptr;
|
||||||
|
Hash uint32;
|
||||||
|
Alg uint8;
|
||||||
|
Align uint8;
|
||||||
|
FieldAlign uint8;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Basic types; should these be one struct with an enum kind?
|
||||||
|
// The benefit of splitting them up into many types is that
|
||||||
|
// one can use a single type switch instead of needing an
|
||||||
|
// enum switch inside a type switch.
|
||||||
|
type BoolType CommonType
|
||||||
|
type Float32Type CommonType
|
||||||
|
type Float64Type CommonType
|
||||||
|
type FloatType CommonType
|
||||||
|
type Int16Type CommonType
|
||||||
|
type Int32Type CommonType
|
||||||
|
type Int64Type CommonType
|
||||||
|
type Int8Type CommonType
|
||||||
|
type IntType CommonType
|
||||||
|
type Uint16Type CommonType
|
||||||
|
type Uint32Type CommonType
|
||||||
|
type Uint64Type CommonType
|
||||||
|
type Uint8Type CommonType
|
||||||
|
type UintType CommonType
|
||||||
|
type StringType CommonType
|
||||||
|
type UintptrType CommonType
|
||||||
|
type UnsafePointerType CommonType
|
||||||
|
|
||||||
|
type ArrayType struct {
|
||||||
|
CommonType;
|
||||||
|
Elem *Type;
|
||||||
|
Bound int32; // -1 means slice
|
||||||
|
}
|
||||||
|
|
||||||
|
type ChanDir int
|
||||||
|
const (
|
||||||
|
SendDir ChanDir = 1<<iota;
|
||||||
|
RecvDir;
|
||||||
|
BothDir = SendDir | RecvDir;
|
||||||
|
)
|
||||||
|
|
||||||
|
type ChanType struct {
|
||||||
|
CommonType;
|
||||||
|
Elem *Type;
|
||||||
|
Dir ChanDir;
|
||||||
|
}
|
||||||
|
|
||||||
|
type FuncType struct {
|
||||||
|
CommonType;
|
||||||
|
In []*Type;
|
||||||
|
Out []*Type;
|
||||||
|
}
|
||||||
|
|
||||||
|
type IMethod struct {
|
||||||
|
Name *string;
|
||||||
|
Package *string;
|
||||||
|
Type *Type;
|
||||||
|
}
|
||||||
|
|
||||||
|
type InterfaceType struct {
|
||||||
|
CommonType;
|
||||||
|
Methods []*IMethod;
|
||||||
|
}
|
||||||
|
|
||||||
|
type MapType struct {
|
||||||
|
CommonType;
|
||||||
|
Key *Type;
|
||||||
|
Elem *Type;
|
||||||
|
}
|
||||||
|
|
||||||
|
type Method struct {
|
||||||
|
Name *string;
|
||||||
|
Package *string;
|
||||||
|
Type *Type;
|
||||||
|
Func unsafe.Pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
type NamedType struct {
|
||||||
|
CommonType;
|
||||||
|
Name *string;
|
||||||
|
Package *string;
|
||||||
|
Type *Type;
|
||||||
|
ValueMethods []*Method;
|
||||||
|
PtrMethods []*Method;
|
||||||
|
}
|
||||||
|
|
||||||
|
type PtrType struct {
|
||||||
|
CommonType;
|
||||||
|
Sub *Type;
|
||||||
|
}
|
||||||
|
|
||||||
|
type StructField struct {
|
||||||
|
Name *string;
|
||||||
|
Type *Type;
|
||||||
|
Tag *string;
|
||||||
|
Offset uintptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
type StructType struct {
|
||||||
|
CommonType;
|
||||||
|
Fields []*StructField;
|
||||||
|
}
|
||||||
|
|
@ -2,19 +2,19 @@
|
|||||||
// Use of this source code is governed by a BSD-style
|
// Use of this source code is governed by a BSD-style
|
||||||
// license that can be found in the LICENSE file.
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
// The sync package provides basic synchronization primitives
|
/*
|
||||||
// such as mutual exclusion locks. These are intended for use
|
The sync /* package * / provides basic sync primitives.
|
||||||
// by low-level library routines. Higher-level synchronization
|
// Such as mutual exclusion locks.
|
||||||
// is better done via channels and communication.
|
*/
|
||||||
package sync
|
package sync
|
||||||
|
|
||||||
func cas(val *int32, old, new int32) bool
|
func cas(val *int32, old, new int32) bool
|
||||||
func semacquire(*int32)
|
func semacquire(*int32)
|
||||||
func semrelease(*int32)
|
func semrelease(*int32)
|
||||||
|
|
||||||
// A Mutex is a mutual exclusion lock.
|
// A Mutex is a mutual exclusion lock.
|
||||||
// Mutexes can be created as part of other structures;
|
// Mutexes can be created as part of other structures;
|
||||||
// the zero value for a Mutex is an unlocked mutex.
|
// the zero value for a Mutex is an unlocked mutex.
|
||||||
type Mutex struct {
|
type Mutex struct {
|
||||||
key int32;
|
key int32;
|
||||||
sema int32;
|
sema int32;
|
||||||
@ -30,9 +30,11 @@ func xadd(val *int32, delta int32) (new int32) {
|
|||||||
panic("unreached")
|
panic("unreached")
|
||||||
}
|
}
|
||||||
|
|
||||||
// Lock locks m.
|
/*
|
||||||
// If the lock is already in use, the calling goroutine
|
* Lock locks m.
|
||||||
// blocks until the mutex is available.
|
* If the lock is already in use, the calling goroutine
|
||||||
|
* blocks until the mutex is available.
|
||||||
|
*/
|
||||||
func (m *Mutex) Lock() {
|
func (m *Mutex) Lock() {
|
||||||
if xadd(&m.key, 1) == 1 {
|
if xadd(&m.key, 1) == 1 {
|
||||||
// changed from 0 to 1; we hold lock
|
// changed from 0 to 1; we hold lock
|
||||||
|
Loading…
Reference in New Issue
Block a user