int i, etype, sameas;
Type *t;
Sym *s;
-
+
if(widthptr == 0)
fatal("typeinit before betypeinit");
redeclare("constant", s);
s->oconst = e;
- s->lexical = LNAME;
+ s->lexical = LACONST;
d = dcl();
d->dsym = s;
Node *n;
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;
if(n == N) {
n = nod(ONONAME, N, N);
for(l=&na; (n=*l)->op == OLIST; l=&n->left)
n->right = nametoanondcl(n->right);
- t = n->sym->otype;
- if(t == T) {
+ if(n->sym->lexical != LATYPE && n->sym->lexical != LBASETYPE) {
yyerror("%s is not a type", n->sym->name);
t = typ(TINT32);
- }
+ } else
+ t = oldtype(n->sym);
n = nod(ODCLFIELD, N, N);
n->type = t;
*l = n;
yyerror("package export symbol: %S", s);
break;
case LATYPE:
+ case LBASETYPE:
// TODO(rsc): sort methods by name
for(f=s->otype->method; f!=T; f=f->down)
dumpprereq(f);
f->type->type->type, f->sym, f->type);
break;
case LNAME:
- if(s->oconst)
- dumpexportconst(s);
- else
- dumpexportvar(s);
+ dumpexportvar(s);
+ break;
+ case LACONST:
+ dumpexportconst(s);
break;
}
}
return;
convlit(n, t);
- s = importsym(ss, LNAME);
+ s = importsym(ss, LACONST);
if(s->oconst != N) {
// TODO: check if already the same.
return;
}
%token <val> LLITERAL
%token <lint> LASOP
-%token <sym> LNAME LATYPE LPACK
+%token <sym> LNAME LBASETYPE LATYPE LPACK LACONST
%token <sym> LPACKAGE LIMPORT LDEFER LCLOSE LCLOSED
%token <sym> LMAP LCHAN LINTERFACE LFUNC LSTRUCT
%token <sym> LCOLAS LFALL LRETURN LDDD
* names like Bstmt, Bvardcl, etc. can't.
*/
-%type <sym> sym sym1 sym2 sym3 keyword lname latype lpackatype
+%type <sym> sym sym1 sym2 sym3 keyword laconst lname latype lpackatype
%type <node> xdcl xdcl_list_r oxdcl_list
%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
{
$$ = nodbool(0);
}
+| laconst
+ {
+ $$ = nod(OLITERAL, N, N);
+ $$->sym = $1;
+ $$->val = $1->oconst->val;
+ $$->type = $1->oconst->type;
+ }
| LIOTA
{
$$ = nodintconst(iota);
}
*/
+laconst:
+ LACONST
+| lpack '.' LACONST
+ {
+ $$ = $3;
+ context = nil;
+ }
+
lname:
LNAME
| lpack '.' LNAME
sym:
LATYPE
| LNAME
+| LACONST
| LPACK
sym1:
| LPRINTN
| LNEW
| LMAKE
+| LBASETYPE
/*
* keywords that we can
YYERROR;
}
+laconst:
+ LATYPE
+ {
+ yyerror("%s is type, not var", $1->name);
+ YYERROR;
+ }
+
latype:
- LPACK
+ LACONST
+ {
+ yyerror("%s is const, not type", $1->name);
+ YYERROR;
+ }
+| LPACK
{
yyerror("%s is package, not type", $1->name);
YYERROR;
fatal("betypeinit failed");
lexinit();
- typeinit(LATYPE);
+ typeinit(LBASETYPE);
lineno = 1;
block = 1;
DBG("lex: %S %s\n", s, lexname(s->lexical));
yylval.sym = s;
+ if(s->lexical == LBASETYPE)
+ return LATYPE;
return s->lexical;
tnum:
/* name lexical etype
*/
/* basic types */
- "int8", LATYPE, TINT8,
- "int16", LATYPE, TINT16,
- "int32", LATYPE, TINT32,
- "int64", LATYPE, TINT64,
+ "int8", LBASETYPE, TINT8,
+ "int16", LBASETYPE, TINT16,
+ "int32", LBASETYPE, TINT32,
+ "int64", LBASETYPE, TINT64,
- "uint8", LATYPE, TUINT8,
- "uint16", LATYPE, TUINT16,
- "uint32", LATYPE, TUINT32,
- "uint64", LATYPE, TUINT64,
+ "uint8", LBASETYPE, TUINT8,
+ "uint16", LBASETYPE, TUINT16,
+ "uint32", LBASETYPE, TUINT32,
+ "uint64", LBASETYPE, TUINT64,
- "float32", LATYPE, TFLOAT32,
- "float64", LATYPE, TFLOAT64,
- "float80", LATYPE, TFLOAT80,
+ "float32", LBASETYPE, TFLOAT32,
+ "float64", LBASETYPE, TFLOAT64,
+ "float80", LBASETYPE, TFLOAT80,
- "bool", LATYPE, TBOOL,
- "byte", LATYPE, TUINT8,
- "string", LATYPE, TSTRING,
+ "bool", LBASETYPE, TBOOL,
+ "byte", LBASETYPE, TUINT8,
+ "string", LBASETYPE, TSTRING,
- "any", LATYPE, TANY,
+ "any", LBASETYPE, TANY,
"break", LBREAK, Txxx,
"case", LCASE, Txxx,
s->lexical = lex;
s->package = package;
- etype = syms[i].etype;
- if(etype == Txxx)
+ if(lex != LBASETYPE)
continue;
+ etype = syms[i].etype;
if(etype < 0 || etype >= nelem(types))
fatal("lexinit: %s bad etype", s->name);
{
LANDAND, "ANDAND",
LASOP, "ASOP",
+ LACONST, "ACONST",
+ LATYPE, "ATYPE",
+ LBASETYPE, "BASETYPE",
LBREAK, "BREAK",
LCASE, "CASE",
LCHAN, "CHAN",
flag.install: fmt.install os.install strconv.install
fmt.install: io.install os.install reflect.install strconv.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 template.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/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/token.install: strconv.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
testing.install: flag.install fmt.install os.install runtime.install
-testing/iotest.install: io.install log.install os.install
+testing/iotest.install: io.install os.install
time.install: io.install once.install os.install syscall.install
unicode.install:
utf8.install:
return nil
}
-// Read reads data into p, returning the number of bytes read.
-// Read reads as much data as possible into p.
-// If nn < len(p), Read also returns an error explaining
+// Read reads data into p.
+// It returns the number of bytes read into p.
+// If nn < len(p), also returns an error explaining
// why the read is short. At EOF, the count will be
-// zero and err will be io.ErrUnexpectedEOF.
+// zero and err will be io.ErrEOF.
func (b *Reader) Read(p []byte) (nn int, err os.Error) {
nn = 0;
for len(p) > 0 {
Closer;
}
-// 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.
+// Convert a string to an array of bytes for easy marshaling.
func StringBytes(s string) []byte {
b := make([]byte, len(s));
for i := 0; i < len(s); i++ {
// Shared pipe structure.
type pipe struct {
rclosed bool; // Read end closed?
- rerr os.Error; // Error supplied to CloseReader
wclosed bool; // Write end closed?
- werr os.Error; // Error supplied to CloseWriter
wpend []byte; // Written data waiting to be read.
wtot int; // Bytes consumed so far in current write.
cr chan []byte; // Write sends data here...
p.wpend = <-p.cr;
}
if p.wpend == nil {
- return 0, p.werr;
+ return 0, nil;
}
p.wtot = 0;
}
return 0, os.EINVAL;
}
if p.rclosed {
- return 0, p.rerr;
+ return 0, os.EPIPE;
}
// Send data to reader.
return res.n, res.err;
}
-func (p *pipe) CloseReader(rerr os.Error) os.Error {
+func (p *pipe) CloseReader() os.Error {
if p == nil || p.rclosed {
return os.EINVAL;
}
// Stop any future writes.
p.rclosed = true;
- if rerr == nil {
- rerr = os.EPIPE;
- }
- p.rerr = rerr;
// Stop the current write.
if !p.wclosed {
- p.cw <- pipeReturn{p.wtot, rerr};
+ p.cw <- pipeReturn{p.wtot, os.EPIPE};
}
return nil;
}
-func (p *pipe) CloseWriter(werr os.Error) os.Error {
+func (p *pipe) CloseWriter() os.Error {
if p == nil || p.wclosed {
return os.EINVAL;
}
// Stop any future reads.
p.wclosed = true;
- p.werr = werr;
// Stop the current read.
if !p.rclosed {
// 2. Clients cannot use interface conversions on the
// read end to find the Write method, and vice versa.
-// A PipeReader is the read half of a pipe.
-type PipeReader struct {
+// Read half of pipe.
+type pipeRead struct {
lock sync.Mutex;
p *pipe;
}
-// 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) {
+func (r *pipeRead) Read(data []byte) (n int, err os.Error) {
r.lock.Lock();
defer r.lock.Unlock();
return r.p.Read(data);
}
-// 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();
- defer r.lock.Unlock();
-
- return r.p.CloseReader(nil);
-}
-
-// 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 {
+func (r *pipeRead) Close() os.Error {
r.lock.Lock();
defer r.lock.Unlock();
- return r.p.CloseReader(rerr);
+ return r.p.CloseReader();
}
-func (r *PipeReader) finish() {
+func (r *pipeRead) finish() {
r.Close();
}
// Write half of pipe.
-type PipeWriter struct {
+type pipeWrite struct {
lock sync.Mutex;
p *pipe;
}
-// 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) {
+func (w *pipeWrite) Write(data []byte) (n int, err os.Error) {
w.lock.Lock();
defer w.lock.Unlock();
return w.p.Write(data);
}
-// 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();
- defer w.lock.Unlock();
-
- return w.p.CloseWriter(nil);
-}
-
-// 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 {
+func (w *pipeWrite) Close() os.Error {
w.lock.Lock();
defer w.lock.Unlock();
- return w.p.CloseWriter(werr);
+ return w.p.CloseWriter();
}
-func (w *PipeWriter) finish() {
+func (w *pipeWrite) finish() {
w.Close();
}
// Pipe creates a synchronous in-memory pipe.
-// It can be used to connect code expecting an io.Reader
+// Used to connect code expecting an io.Reader
// with code expecting an io.Writer.
-// Reads on one end are matched with writes on the other.
-func Pipe() (*PipeReader, *PipeWriter) {
+//
+// Reads on one end are matched by writes on the other.
+// 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.cr = make(chan []byte, 1);
p.cw = make(chan pipeReturn, 1);
- r := new(PipeReader);
+ r := new(pipeRead);
r.p = p;
- w := new(PipeWriter);
+ w := new(pipeWrite);
w.p = p;
return r, w;
}
+++ /dev/null
-// 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;
-}
-
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
-/*
- The sync /* package * / provides basic sync primitives.
- // Such as mutual exclusion locks.
-*/
+// The sync package provides basic synchronization primitives
+// such as mutual exclusion locks. These are intended for use
+// by low-level library routines. Higher-level synchronization
+// is better done via channels and communication.
package sync
func cas(val *int32, old, new int32) bool
func semacquire(*int32)
func semrelease(*int32)
- // A Mutex is a mutual exclusion lock.
- // Mutexes can be created as part of other structures;
- // the zero value for a Mutex is an unlocked mutex.
+// A Mutex is a mutual exclusion lock.
+// Mutexes can be created as part of other structures;
+// the zero value for a Mutex is an unlocked mutex.
type Mutex struct {
key int32;
sema int32;
panic("unreached")
}
-/*
- * Lock locks m.
- * If the lock is already in use, the calling goroutine
- * blocks until the mutex is available.
- */
+// Lock locks m.
+// If the lock is already in use, the calling goroutine
+// blocks until the mutex is available.
func (m *Mutex) Lock() {
if xadd(&m.key, 1) == 1 {
// changed from 0 to 1; we hold lock