1
0
mirror of https://github.com/golang/go synced 2024-10-01 01:38:33 -06:00

simplifying grammar: delete LBASETYPE and LACONST

R=ken
OCL=29300
CL=29302
This commit is contained in:
Russ Cox 2009-05-22 22:42:12 -07:00
parent b112d42ad6
commit 2a4dcfffc9
11 changed files with 251 additions and 109 deletions

View File

@ -213,7 +213,7 @@ typeinit(int lex)
int i, etype, sameas; int i, etype, sameas;
Type *t; Type *t;
Sym *s; Sym *s;
if(widthptr == 0) if(widthptr == 0)
fatal("typeinit before betypeinit"); fatal("typeinit before betypeinit");

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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",

View File

@ -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:

View File

@ -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 {

View File

@ -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++ {

View File

@ -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
View 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;
}

View File

@ -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