fix bugs left over from *[] to [] conversion.
TBR=r
OCL=21576
CL=21581
set -e
# They all compile; now generate the code to call them.
-#trap "rm -f _testmain.go _testmain.6" 0 1 2 3 14 15
+trap "rm -f _testmain.go _testmain.6" 0 1 2 3 14 15
{
# package spec
echo 'package main'
if n < m {
return y.Add(x);
}
-
+
c := Digit(0);
- z := new(Natural, n + 1);
+ z := new(*Natural, n + 1);
i := 0;
for i < m {
t := c + x[i] + y[i];
if n < m {
panic("underflow")
}
-
+
c := Digit(0);
- z := new(Natural, n);
+ z := new(*Natural, n);
i := 0;
for i < m {
t := c + x[i] - y[i];
n := len(x);
m := len(y);
- z := new(Natural, n + m);
+ z := new(*Natural, n + m);
for j := 0; j < m; j++ {
d := y[j];
if d != 0 {
func Pack(x []Digit2) *Natural {
n := (len(x) + 1) / 2;
- z := new(Natural, n);
+ z := new(*Natural, n);
if len(x) & 1 == 1 {
// handle odd len(x)
n--;
} else {
// general case
assert(2 <= m && m <= n);
-
+
// normalize x and y
// TODO Instead of multiplying, it would be sufficient to
// shift y such that the normalization condition is
func (x *Natural) Shl(s uint) *Natural {
n := uint(len(x));
m := n + s/W;
- z := new(Natural, m+1);
+ z := new(*Natural, m+1);
z[m] = Shl(z[m-n : m], x, s%W);
if m > n { // check for underflow
m = 0;
}
- z := new(Natural, m);
+ z := new(*Natural, m);
Shr(z, x[n-m : n], s%W);
return y.And(x);
}
- z := new(Natural, m);
+ z := new(*Natural, m);
for i := 0; i < m; i++ {
z[i] = x[i] & y[i];
}
return y.Or(x);
}
- z := new(Natural, n);
+ z := new(*Natural, n);
for i := 0; i < m; i++ {
z[i] = x[i] | y[i];
}
return y.Xor(x);
}
- z := new(Natural, n);
+ z := new(*Natural, n);
for i := 0; i < m; i++ {
z[i] = x[i] ^ y[i];
}
s := new([]byte, n);
// don't destroy x
- t := new(Natural, len(x));
+ t := new(*Natural, len(x));
Copy(t, x);
// convert
func MulAdd1(x *Natural, d, c Digit) *Natural {
assert(IsSmall(d-1) && IsSmall(c));
n := len(x);
- z := new(Natural, n + 1);
+ z := new(*Natural, n + 1);
for i := 0; i < n; i++ {
t := c + x[i]*d;
return s + x.mant.ToString(base);
}
-
+
func (x *Integer) String() string {
return x.ToString(10);
}
if size <= 0 {
return nil, BadBufSize
}
- b = new(BufRead);
+ b = new(*BufRead);
b.buf = new([]byte, size);
b.rd = rd;
return b, nil
// For internal (or advanced) use only.
// Use ReadLineString or ReadLineBytes instead.
-var NIL []byte // TODO(rsc): should be able to use nil
-
func (b *BufRead) ReadLineSlice(delim byte) (line []byte, err *os.Error) {
if b.err != nil {
- return NIL, b.err
+ return nil, b.err
}
// Look in buffer.
n := b.Buffered();
b.Fill();
if b.err != nil {
- return NIL, b.err
+ return nil, b.err
}
if b.Buffered() == n { // no data added; end of file
line := b.buf[b.r:b.w];
// Buffer is full?
if b.Buffered() >= len(b.buf) {
- return NIL, BufferFull
+ return nil, BufferFull
}
}
// BUG 6g bug100
- return NIL, nil
+ return nil, nil
}
// Read until the first occurrence of delim in the input,
// we might have read more than the buffer size.)
func (b *BufRead) ReadLineBytes(delim byte) (line []byte, err *os.Error) {
if b.err != nil {
- return NIL, b.err
+ return nil, b.err
}
// Use ReadLineSlice to look for array,
}
// Grow list if needed.
- if len(full) == 0 {
+ if full == nil {
full = new([][]byte, 16);
} else if nfull >= len(full) {
newfull := new([][]byte, len(full)*2);
return buf, err
}
-// BUG(bugs/bug102.go): string(empty bytes array) throws error
-func ToString(p []byte) string {
- if len(p) == 0 {
- return ""
- }
- return string(p)
-}
-
// Read until the first occurrence of delim in the input,
// returning a new string containing the line.
// If savedelim, keep delim in the result; otherwise chop it off.
func (b *BufRead) ReadLineString(delim byte, savedelim bool) (line string, err *os.Error) {
bytes, e := b.ReadLineBytes(delim);
if e != nil {
- return ToString(bytes), e
+ return string(bytes), e
}
if !savedelim {
bytes = bytes[0:len(bytes)-1]
}
- return ToString(bytes), nil
+ return string(bytes), nil
}
if size <= 0 {
return nil, BadBufSize
}
- b = new(BufWrite);
+ b = new(*BufWrite);
b.buf = new([]byte, size);
b.wr = wr;
return b, nil
}
func NewByteReader(p []byte) io.Read {
- b := new(ByteReader);
+ b := new(*ByteReader);
b.p = p;
return b
}
}
func NewHalfByteReader(p []byte) io.Read {
- b := new(HalfByteReader);
+ b := new(*HalfByteReader);
b.p = p;
return b
}
}
func NewRot13Reader(r io.Read) *Rot13Reader {
- r13 := new(Rot13Reader);
+ r13 := new(*Rot13Reader);
r13.r = r;
return r13
}
}
func NewByteWriter() WriteBuffer {
- return new(ByteWriter)
+ return new(*ByteWriter)
}
func (w *ByteWriter) Write(p []byte) (int, *os.Error) {
}
func NewHalfByteWriter() WriteBuffer {
- w := new(HalfByteWriter);
+ w := new(*HalfByteWriter);
w.bw = NewByteWriter();
return w
}
export func New(len int) *Array {
- return new(Array).Init(len)
+ return new(*Array).Init(len)
}
export func NewIntArray(len int) *IntArray {
- return new(IntArray).Init(len)
+ return new(*IntArray).Init(len)
}
}
type Flags struct {
- actual *map[string] *Flag;
- formal *map[string] *Flag;
+ actual map[string] *Flag;
+ formal map[string] *Flag;
first_arg int;
flag_list *Flag; // BUG: remove when we can iterate over maps
}
}
func New() *Flags {
- f := new(Flags);
+ f := new(*Flags);
f.first_arg = 1; // 0 is the program name, 1 is first arg
f.actual = new(map[string] *Flag);
f.formal = new(map[string] *Flag);
}
func Add(name string, value Value, usage string) *Flag {
- f := new(Flag);
+ f := new(*Flag);
f.name = name;
f.usage = usage;
f.value = value;
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
-// Adler-32 checksum.
+// Adler-32 checksum.
// Defined in RFC 1950:
// Adler-32 is composed of two sums accumulated per byte: s1 is
// the sum of all bytes, s2 is the sum of all s1 values. Both sums
Koopman = 0xeb31d82e;
)
-// TODO(rsc): Change to [256]uint32
+// TODO(rsc): Change to [256]uint32 once 6g can handle it.
export type Table []uint32
export func MakeTable(poly uint32) Table {
}
export func NewDigest() *Digest {
- d := new(Digest);
+ d := new(*Digest);
d.s[0] = A;
d.s[1] = B;
d.s[2] = C;
}
export func NewDigest() *Digest {
- d := new(Digest);
+ d := new(*Digest);
d.h[0] = H0;
d.h[1] = H1;
d.h[2] = H2;
// Create new connection from rwc.
export func NewConn(rwc io.ReadWriteClose) (c *Conn, err *os.Error) {
- c = new(Conn);
+ c = new(*Conn);
c.rwc = rwc;
if c.br, err = bufio.NewBufRead(rwc); err != nil {
return nil, err
pmajor int; // 1
pminor int; // 0
- header *map[string] string;
+ header map[string] string;
close bool;
host string;
useragent string;
}
-var NIL []byte // TODO(rsc)
-
// Read a line of bytes (up to \n) from b.
// Give up if the line exceeds MaxLineLength.
// The returned bytes are a pointer into storage in
// the bufio, so they are only valid until the next bufio read.
func ReadLineBytes(b *bufio.BufRead) (p []byte, err *os.Error) {
if p, err = b.ReadLineSlice('\n'); err != nil {
- return NIL, err
+ return nil, err
}
if len(p) >= MaxLineLength {
- return NIL, LineTooLong
+ return nil, LineTooLong
}
// Chop off trailing white space.
// Read and parse a request from b.
export func ReadRequest(b *bufio.BufRead) (req *Request, err *os.Error) {
- req = new(Request);
+ req = new(*Request);
// First line: GET /index.html HTTP/1.0
var s string;
if rawurl == "" {
return nil, BadURL
}
- url = new(URL);
+ url = new(*URL);
url.raw = rawurl;
// Split off possible leading "http:", "mailto:", etc.
export func NewByteBufferFromArray(buf []byte) *ByteBuffer {
- b := new(ByteBuffer);
+ b := new(*ByteBuffer);
b.buf = buf;
b.off = 0;
b.len = len(buf);
return "false"
}
-type Map struct { m *map[string]Json; Null }
+type Map struct { m map[string]Json; Null }
func (j *Map) Kind() int { return MapKind }
func (j *Map) Get(s string) Json {
if j.m == nil {
i int;
// or to m[k] (can't set ptr = &m[k])
- m *map[string] Json;
+ m map[string] Json;
k string;
}
}
func (b *JsonBuilder) Elem(i int) Builder {
- bb := new(JsonBuilder);
+ bb := new(*JsonBuilder);
bb.a = b.Get().(*Array).a;
bb.i = i;
for i >= bb.a.Len() {
}
func (b *JsonBuilder) Key(k string) Builder {
- bb := new(JsonBuilder);
+ bb := new(*JsonBuilder);
bb.m = b.Get().(*Map).m;
bb.k = k;
bb.m[k] = null;
export func StringToJson(s string) (json Json, ok bool, errtok string) {
var errindx int;
var j Json;
- b := new(JsonBuilder);
+ b := new(*JsonBuilder);
b.ptr = &j;
ok, errindx, errtok = Parse(s, b);
if !ok {
export func Quote(s string) string {
chr := new([]byte, utf8.UTFMax);
chr0 := chr[0:1];
- b := new(io.ByteBuffer);
+ b := new(*io.ByteBuffer);
chr[0] = '"';
b.Write(chr0);
for i := 0; i < len(s); i++ {
}
export func Parse(s string, build Builder) (ok bool, errindx int, errtok string) {
- lex := new(Lexer);
+ lex := new(*Lexer);
lex.s = s;
lex.Next();
if ParseValue(lex, build) {
fl float;
fl32 float32;
fl64 float64;
- a []string;
+ a *[]string; // TODO(rsc): Should be able to use []string.
my *MyStruct;
};
Check(t, m.fl==11.5, "fl", m.fl);
Check(t, m.fl32==12.25, "fl32", m.fl32);
Check(t, m.fl64==13.75, "fl64", m.fl64);
-// Check(t, m.a!=nil, "a", m.a); // TODO(rsc): uncomment once []string as interface works
+ Check(t, m.a!=nil, "a", m.a);
if m.a != nil {
Check(t, m.a[0]=="x", "a[0]", m.a[0]);
Check(t, m.a[1]=="y", "a[1]", m.a[1]);
req := io.StringBytes("GET / HTTP/1.0\r\nHost: www.google.com\r\n\r\n");
n, errno := fd.Write(req);
- buf := new([1000]byte);
+ buf := new([]byte, 1000);
n, errno = io.Readn(fd, buf);
if n < 1000 {
if len(name) >= 256 {
return nil, DNS_NameTooLong
}
- out := new(DNS_Msg);
+ out := new(*DNS_Msg);
out.id = 0x1234;
out.question = []DNS_Question{
DNS_Question{ name, DNS_TypeA, DNS_ClassINET }
continue
}
buf = buf[0:n];
- in := new(DNS_Msg);
+ in := new(*DNS_Msg);
if !in.Unpack(buf) || in.id != out.id {
continue
}
return nil, DNS_NoAnswer
}
-var NIL []string // TODO(rsc)
-
// Find answer for name in dns message.
// On return, if err == nil, addrs != nil.
// TODO(rsc): Maybe return [][]byte (==[]IPAddr) instead?
func Answer(name string, dns *DNS_Msg) (addrs []string, err *os.Error) {
- addrs = new([]string, len(dns.answer))[0:0];
+ addrs = new([]string, 0, len(dns.answer));
if dns.rcode == DNS_RcodeNameError && dns.authoritative {
- return NIL, DNS_NameNotFound // authoritative "no such host"
+ return nil, DNS_NameNotFound // authoritative "no such host"
}
if dns.rcode != DNS_RcodeSuccess {
// None of the error codes make sense
// for the query we sent. If we didn't get
// a name error and we didn't get success,
// the server is behaving incorrectly.
- return NIL, DNS_ServerFailure
+ return nil, DNS_ServerFailure
}
// Look for the name.
}
}
if len(addrs) == 0 {
- return NIL, DNS_NameNotFound
+ return nil, DNS_NameNotFound
}
return addrs, nil
}
// Too many redirects
- return NIL, DNS_RedirectLoop
+ return nil, DNS_RedirectLoop
}
// Do a lookup for a single name, which must be rooted
if file == nil {
return nil
}
- conf := new(DNS_Config);
+ conf := new(*DNS_Config);
conf.servers = new([]string, 3)[0:0]; // small, but the standard limit
conf.search = new([]string, 0);
conf.ndots = 1;
// Map of constructors for each RR wire type.
var rr_mk = map[int]*()DNS_RR {
- DNS_TypeCNAME: func() DNS_RR { return new(DNS_RR_CNAME) },
- DNS_TypeHINFO: func() DNS_RR { return new(DNS_RR_HINFO) },
- DNS_TypeMB: func() DNS_RR { return new(DNS_RR_MB) },
- DNS_TypeMG: func() DNS_RR { return new(DNS_RR_MG) },
- DNS_TypeMINFO: func() DNS_RR { return new(DNS_RR_MINFO) },
- DNS_TypeMR: func() DNS_RR { return new(DNS_RR_MR) },
- DNS_TypeMX: func() DNS_RR { return new(DNS_RR_MX) },
- DNS_TypeNS: func() DNS_RR { return new(DNS_RR_NS) },
- DNS_TypePTR: func() DNS_RR { return new(DNS_RR_PTR) },
- DNS_TypeSOA: func() DNS_RR { return new(DNS_RR_SOA) },
- DNS_TypeTXT: func() DNS_RR { return new(DNS_RR_TXT) },
- DNS_TypeA: func() DNS_RR { return new(DNS_RR_A) },
+ DNS_TypeCNAME: func() DNS_RR { return new(*DNS_RR_CNAME) },
+ DNS_TypeHINFO: func() DNS_RR { return new(*DNS_RR_HINFO) },
+ DNS_TypeMB: func() DNS_RR { return new(*DNS_RR_MB) },
+ DNS_TypeMG: func() DNS_RR { return new(*DNS_RR_MG) },
+ DNS_TypeMINFO: func() DNS_RR { return new(*DNS_RR_MINFO) },
+ DNS_TypeMR: func() DNS_RR { return new(*DNS_RR_MR) },
+ DNS_TypeMX: func() DNS_RR { return new(*DNS_RR_MX) },
+ DNS_TypeNS: func() DNS_RR { return new(*DNS_RR_NS) },
+ DNS_TypePTR: func() DNS_RR { return new(*DNS_RR_PTR) },
+ DNS_TypeSOA: func() DNS_RR { return new(*DNS_RR_SOA) },
+ DNS_TypeTXT: func() DNS_RR { return new(*DNS_RR_TXT) },
+ DNS_TypeA: func() DNS_RR { return new(*DNS_RR_A) },
}
// Pack a domain name s into msg[off:].
extra []DNS_RR;
}
-var NIL []byte // TODO(rsc): remove
func (dns *DNS_Msg) Pack() (msg []byte, ok bool) {
var dh DNS_Header;
dh.bits |= QR;
}
- // Prepare variable sized arrays; paper over nils.
- var question []DNS_Question;
- var answer, ns, extra []DNS_RR;
+ // Prepare variable sized arrays.
+ question := dns.question;
+ answer := dns.answer;
+ ns := dns.ns;
+ extra := dns.extra;
dh.qdcount = uint16(len(question));
dh.ancount = uint16(len(answer));
off, ok = PackStruct(extra[i], msg, off);
}
if !ok {
- return NIL, false
+ return nil, false
}
return msg[0:off], true
}
// immutable until Close
fd int64;
osfd *os.FD;
- cr *chan *FD;
- cw *chan *FD;
+ cr chan *FD;
+ cw chan *FD;
// owned by fd wait server
ncr, ncw int;
// might help batch requests.
type PollServer struct {
- cr, cw *chan *FD; // buffered >= 1
+ cr, cw chan *FD; // buffered >= 1
pr, pw *os.FD;
- pending *map[int64] *FD;
+ pending map[int64] *FD;
poll *Pollster; // low-level OS hooks
}
func (s *PollServer) Run();
func NewPollServer() (s *PollServer, err *os.Error) {
- s = new(PollServer);
+ s = new(*PollServer);
s.cr = new(chan *FD, 1);
s.cw = new(chan *FD, 1);
if s.pr, s.pw, err = os.Pipe(); err != nil {
if err = SetNonblock(fd); err != nil {
return nil, err
}
- f = new(FD);
+ f = new(*FD);
f.fd = fd;
f.osfd = os.NewFD(fd);
f.cr = new(chan *FD, 1);
events []syscall.Kevent;
}
-var NIL []syscall.Kevent; // TODO(rsc): remove
-
export func NewPollster() (p *Pollster, err *os.Error) {
- p = new(Pollster);
+ p = new(*Pollster);
var e int64;
if p.kq, e = syscall.kqueue(); e != 0 {
return nil, os.ErrnoToError(e)
func (p *Pollster) WaitFD() (fd int64, mode int, err *os.Error) {
for len(p.events) == 0 {
- nn, e := syscall.kevent(p.kq, NIL, p.eventbuf, nil);
+ nn, e := syscall.kevent(p.kq, nil, p.eventbuf, nil);
if e != 0 {
if e == syscall.EAGAIN || e == syscall.EINTR {
continue
epfd int64;
// Events we're already waiting for
- events *map[int64] uint32;
+ events map[int64] uint32;
}
export func NewPollster() (p *Pollster, err *os.Error) {
- p = new(Pollster);
+ p = new(*Pollster);
var e int64;
// The arg to epoll_create is a hint to the kernel
// Get an event.
var evarray [1]syscall.EpollEvent;
ev := &evarray[0];
- n, e := syscall.epoll_wait(p.epfd, &evarray, -1);
+ n, e := syscall.epoll_wait(p.epfd, evarray, -1);
for e == syscall.EAGAIN || e == syscall.EINTR {
- n, e = syscall.epoll_wait(p.epfd, &evarray, -1)
+ n, e = syscall.epoll_wait(p.epfd, evarray, -1)
}
if e != 0 {
return -1, 0, os.ErrnoToError(e)
// Well-known IP addresses
export var IPv4bcast, IPv4allsys, IPv4allrouter, IPv4prefix, IPallbits, IPnoaddr []byte
-var NIL []byte // TODO(rsc)
-
func init() {
IPv4bcast = MakeIPv4(0xff, 0xff, 0xff, 0xff);
IPv4allsys = MakeIPv4(0xe0, 0x00, 0x00, 0x01);
&& p[11] == 0xff {
return p[12:16]
}
- return NIL
+ return nil
}
// Convert p to IPv6 form.
if len(p) == IPv6len {
return p
}
- return NIL
+ return nil
}
// Default route masks for IPv4.
)
export func DefaultMask(p []byte) []byte {
- if p = ToIPv4(p); len(p) == 0 {
- return NIL
+ if p = ToIPv4(p); p == nil {
+ return nil
}
switch true {
case p[0] < 0x80:
default:
return ClassCMask;
}
- return NIL; // not reached
+ return nil; // not reached
}
// Apply mask to ip, returning new address.
export func Mask(ip []byte, mask []byte) []byte {
n := len(ip);
if n != len(mask) {
- return NIL
+ return nil
}
out := new([]byte, n);
for i := 0; i < n; i++ {
for j := 0; j < IPv4len; j++ {
if j > 0 {
if s[i] != '.' {
- return NIL
+ return nil
}
i++;
}
)
n, i, ok = Dtoi(s, i);
if !ok || n > 0xFF {
- return NIL
+ return nil
}
p[j] = byte(n)
}
if i != len(s) {
- return NIL
+ return nil
}
return MakeIPv4(p[0], p[1], p[2], p[3])
}
// Hex number.
n, i1, ok := Xtoi(s, i);
if !ok || n > 0xFFFF {
- return NIL
+ return nil
}
// If followed by dot, might be in trailing IPv4.
if i1 < len(s) && s[i1] == '.' {
if ellipsis < 0 && j != IPv6len - IPv4len {
// Not the right place.
- return NIL
+ return nil
}
if j+IPv4len > IPv6len {
// Not enough room.
- return NIL
+ return nil
}
p4 := ParseIPv4(s[i:len(s)]);
- if len(p4) == 0 {
- return NIL
+ if p4 == nil {
+ return nil
}
// BUG: p[j:j+4] = p4
p[j] = p4[12];
// Otherwise must be followed by colon and more.
if s[i] != ':' && i+1 == len(s) {
- return NIL
+ return nil
}
i++;
// Look for ellipsis.
if s[i] == ':' {
if ellipsis >= 0 { // already have one
- return NIL
+ return nil
}
ellipsis = j;
if i++; i == len(s) { // can be at end
// Must have used entire string.
if i != len(s) {
- return NIL
+ return nil
}
// If didn't parse enough, expand ellipsis.
if j < IPv6len {
if ellipsis < 0 {
- return NIL
+ return nil
}
n := IPv6len - j;
for k := j-1; k >= ellipsis; k-- {
export func ParseIP(s string) []byte {
p := ParseIPv4(s);
- if len(p) != 0 {
+ if p != nil {
return p
}
return ParseIPv6(s)
return host + ":" + port
}
-var NIL []byte
-
// Convert "host:port" into IP address and port.
// For now, host and port must be numeric literals.
// Eventually, we'll have name resolution.
var host, port string;
host, port, err = SplitHostPort(hostport);
if err != nil {
- return NIL, 0, err
+ return nil, 0, err
}
// Try as an IP address.
addr := ParseIP(host);
- if len(addr) == 0 {
+ if addr == nil {
// Not an IP address. Try as a DNS name.
hostname, addrs, err := LookupHost(host);
if err != nil {
- return NIL, 0, err
+ return nil, 0, err
}
if len(addrs) == 0 {
- return NIL, 0, UnknownHost
+ return nil, 0, UnknownHost
}
addr = ParseIP(addrs[0]);
- if len(addr) == 0 {
+ if addr == nil {
// should not happen
- return NIL, 0, BadAddress
+ return nil, 0, BadAddress
}
}
if !ok || i != len(port) {
p, ok = LookupPort(net, port);
if !ok {
- return NIL, 0, UnknownPort
+ return nil, 0, UnknownPort
}
}
if p < 0 || p > 0xFFFF {
- return NIL, 0, BadAddress
+ return nil, 0, BadAddress
}
return addr, p, nil
default:
// Otherwise, guess.
// If the addresses are IPv4 and we prefer IPv4, use 4; else 6.
- if PreferIPv4 && len(ToIPv4(lip)) != 0 && len(ToIPv4(rip)) != 0 {
+ if PreferIPv4 && ToIPv4(lip) != nil && ToIPv4(rip) != nil {
vers = 4
} else {
vers = 6
}
var la, ra *syscall.Sockaddr;
- if len(lip) != 0 {
+ if lip != nil {
la, lerr = cvt(lip, lport);
if lerr != nil {
return nil, lerr
}
}
- if len(rip) != 0 {
+ if rip != nil {
ra, rerr = cvt(rip, rport);
if rerr != nil {
return nil, rerr
}
func NewConnTCP(fd *FD, raddr string) *ConnTCP {
- c := new(ConnTCP);
+ c := new(*ConnTCP);
c.fd = fd;
c.raddr = raddr;
c.SetNoDelay(true);
}
func NewConnUDP(fd *FD, raddr string) *ConnUDP {
- c := new(ConnUDP);
+ c := new(*ConnUDP);
c.fd = fd;
c.raddr = raddr;
return c
syscall.close(fd.fd);
return nil, os.ErrnoToError(e1)
}
- l = new(ListenerTCP);
+ l = new(*ListenerTCP);
l.fd = fd;
return l, nil
}
export func IPv4ToSockaddr(p []byte, port int) (sa1 *syscall.Sockaddr, err *os.Error) {
p = ToIPv4(p);
- if len(p) == 0 || port < 0 || port > 0xFFFF {
+ if p == nil || port < 0 || port > 0xFFFF {
return nil, os.EINVAL
}
- sa := new(syscall.SockaddrInet4);
+ sa := new(*syscall.SockaddrInet4);
sa.len = syscall.SizeofSockaddrInet4;
sa.family = syscall.AF_INET;
sa.port[0] = byte(port>>8);
export func IPv6ToSockaddr(p []byte, port int) (sa1 *syscall.Sockaddr, err *os.Error) {
p = ToIPv6(p);
- if len(p) == 0 || port < 0 || port > 0xFFFF {
+ if p == nil || port < 0 || port > 0xFFFF {
return nil, os.EINVAL
}
- sa := new(syscall.SockaddrInet6);
+ sa := new(*syscall.SockaddrInet6);
sa.len = syscall.SizeofSockaddrInet6;
sa.family = syscall.AF_INET6;
sa.port[0] = byte(port>>8);
return unsafe.pointer(sa).(*syscall.Sockaddr), nil
}
-var NIL []byte // TODO(rsc)
export func SockaddrToIP(sa1 *syscall.Sockaddr) (p []byte, port int, err *os.Error) {
switch sa1.family {
case syscall.AF_INET:
sa := unsafe.pointer(sa1).(*syscall.SockaddrInet4);
a := ToIPv6(sa.addr);
- if len(a) == 0 {
- return NIL, 0, os.EINVAL
+ if a == nil {
+ return nil, 0, os.EINVAL
}
return a, int(sa.port[0])<<8 + int(sa.port[1]), nil;
case syscall.AF_INET6:
sa := unsafe.pointer(sa1).(*syscall.SockaddrInet6);
a := ToIPv6(sa.addr);
- if len(a) == 0 {
- return NIL, 0, os.EINVAL
+ if a == nil {
+ return nil, 0, os.EINVAL
}
- return NIL, int(sa.port[0])<<8 + int(sa.port[1]), nil;
+ return nil, int(sa.port[0])<<8 + int(sa.port[1]), nil;
default:
- return NIL, 0, os.EINVAL
+ return nil, 0, os.EINVAL
}
- return NIL, 0, nil // not reached
+ return nil, 0, nil // not reached
}
export func ListenBacklog() int64 {
if p == nil || port < 0 || port > 0xFFFF {
return nil, os.EINVAL
}
- sa := new(syscall.SockaddrInet4);
+ sa := new(*syscall.SockaddrInet4);
sa.family = syscall.AF_INET;
sa.port[0] = byte(port>>8);
sa.port[1] = byte(port);
// In IPv6 mode, Linux treats that as meaning "announce on 0.0.0.0",
// which it refuses to do. Rewrite to the IPv6 all zeros.
if p4 := ToIPv4(p); p4 != nil && p4[0] == 0 && p4[1] == 0 && p4[2] == 0 && p4[3] == 0 {
- p = &IPv6zero;
+ p = IPv6zero;
}
- sa := new(syscall.SockaddrInet6);
+ sa := new(*syscall.SockaddrInet6);
sa.family = syscall.AF_INET6;
sa.port[0] = byte(port>>8);
sa.port[1] = byte(port);
switch sa1.family {
case syscall.AF_INET:
sa := unsafe.pointer(sa1).(*syscall.SockaddrInet4);
- a := ToIPv6(&sa.addr);
+ a := ToIPv6(sa.addr);
if a == nil {
return nil, 0, os.EINVAL
}
return a, int(sa.port[0])<<8 + int(sa.port[1]), nil;
case syscall.AF_INET6:
sa := unsafe.pointer(sa1).(*syscall.SockaddrInet6);
- a := ToIPv6(&sa.addr);
+ a := ToIPv6(sa.addr);
if a == nil {
return nil, 0, os.EINVAL
}
"strconv";
)
-var services *map[string] *map[string] int
+var services map[string] map[string] int
func ReadServices() {
- services = new(map[string] *map[string] int);
+ services = new(map[string] map[string] int);
file := Open("/etc/services");
for line, ok := file.ReadLine(); ok; line, ok = file.ReadLine() {
// "http 80/tcp www www-http # World Wide Web HTTP"
"testing";
)
-func Echo(fd io.ReadWrite, done *chan<- int) {
+func Echo(fd io.ReadWrite, done chan<- int) {
var buf [1024]byte;
for {
done <- 1
}
-func Serve(t *testing.T, network, addr string, listening, done *chan<- int) {
+func Serve(t *testing.T, network, addr string, listening, done chan<- int) {
l, err := net.Listen(network, addr);
if err != nil {
t.Fatalf("net.Listen(%q, %q) = _, %v", network, addr, err);
}
export func TestTcpServer(t *testing.T) {
- DoTest(t, "tcp", "0.0.0.0:9999", "127.0.0.1:9999");
- DoTest(t, "tcp", "[::]:9999", "[::ffff:127.0.0.1]:9999");
- DoTest(t, "tcp", "[::]:9999", "127.0.0.1:9999");
- DoTest(t, "tcp", "0.0.0.0:9999", "[::ffff:127.0.0.1]:9999");
+ DoTest(t, "tcp", "0.0.0.0:9997", "127.0.0.1:9997");
+ DoTest(t, "tcp", "[::]:9997", "[::ffff:127.0.0.1]:9997");
+ DoTest(t, "tcp", "[::]:9997", "127.0.0.1:9997");
+ DoTest(t, "tcp", "0.0.0.0:9997", "[::ffff:127.0.0.1]:9997");
}
type Job struct {
done bool;
- doit *chan bool; // buffer of 1
+ doit chan bool; // buffer of 1
}
type Request struct {
f *();
- reply *chan *Job
+ reply chan *Job
}
// TODO: Would like to use chan Request but 6g rejects it.
req := <-service;
job, present := jobmap[req.f];
if !present {
- job = new(Job);
+ job = new(*Job);
job.doit = new(chan bool, 1);
job.doit <- true;
jobmap[req.f] = job
type RE struct {
expr string; // the original expression
- ch *chan<- *RE; // reply channel when we're done
+ ch chan<- *RE; // reply channel when we're done
error *os.Error; // compile- or run-time error; nil if OK
inst *array.Array;
start Inst;
func (char *Char) Print() { print("char ", string(char.char)) }
func NewChar(char int) *Char {
- c := new(Char);
+ c := new(*Char);
c.char = char;
return c;
}
}
func NewCharClass() *CharClass {
- c := new(CharClass);
+ c := new(*CharClass);
c.ranges = array.NewIntArray(0);
return c;
}
}
func NewParser(re *RE) *Parser {
- parser := new(Parser);
+ parser := new(*Parser);
parser.re = re;
parser.nextc(); // load p.ch
return parser;
p.re.Error(ErrUnmatchedRbkt);
case '^':
p.nextc();
- start = p.re.Add(new(Bot));
+ start = p.re.Add(new(*Bot));
return start, start;
case '$':
p.nextc();
- start = p.re.Add(new(Eot));
+ start = p.re.Add(new(*Eot));
return start, start;
case '.':
p.nextc();
- start = p.re.Add(new(Any));
+ start = p.re.Add(new(*Any));
return start, start;
case '[':
p.nextc();
}
p.nlpar--;
p.nextc();
- bra := new(Bra);
+ bra := new(*Bra);
p.re.Add(bra);
- ebra := new(Ebra);
+ ebra := new(*Ebra);
p.re.Add(ebra);
bra.n = nbra;
ebra.n = nbra;
switch p.c() {
case '*':
// (start,end)*:
- alt := new(Alt);
+ alt := new(*Alt);
p.re.Add(alt);
end.SetNext(alt); // after end, do alt
alt.left = start; // alternate brach: return to start
end = alt;
case '+':
// (start,end)+:
- alt := new(Alt);
+ alt := new(*Alt);
p.re.Add(alt);
end.SetNext(alt); // after end, do alt
alt.left = start; // alternate brach: return to start
end = alt; // start is unchanged; end is alt
case '?':
// (start,end)?:
- alt := new(Alt);
+ alt := new(*Alt);
p.re.Add(alt);
- nop := new(Nop);
+ nop := new(*Nop);
p.re.Add(nop);
alt.left = start; // alternate branch is start
alt.next = nop; // follow on to nop
switch {
case nstart == NULL: // end of this concatenation
if start == NULL { // this is the empty string
- nop := p.re.Add(new(Nop));
+ nop := p.re.Add(new(*Nop));
return nop, nop;
}
return;
case '|':
p.nextc();
nstart, nend := p.Concatenation();
- alt := new(Alt);
+ alt := new(*Alt);
p.re.Add(alt);
alt.left = start;
alt.next = nstart;
- nop := new(Nop);
+ nop := new(*Nop);
p.re.Add(nop);
end.SetNext(nop);
nend.SetNext(nop);
func (re *RE) DoParse() {
parser := NewParser(re);
- start := new(Start);
+ start := new(*Start);
re.Add(start);
s, e := parser.Regexp();
start.next = s;
re.start = start;
- e.SetNext(re.Add(new(End)));
+ e.SetNext(re.Add(new(*End)));
if debug {
re.Dump();
}
-func Compiler(str string, ch *chan *RE) {
- re := new(RE);
+func Compiler(str string, ch chan *RE) {
+ re := new(*RE);
re.expr = str;
re.inst = array.New(0);
re.ch = ch;
}
// digits
- b := new(Decimal);
+ b := new(*Decimal);
sawdot := false;
sawdigits := false;
for ; i < len(s); i++ {
}
package func NewDecimal(i uint64) *Decimal {
- a := new(Decimal);
+ a := new(*Decimal);
a.Assign(i);
return a;
}
"testing"
)
-func HammerSemaphore(s *int32, cdone *chan bool) {
+func HammerSemaphore(s *int32, cdone chan bool) {
for i := 0; i < 1000; i++ {
sys.semacquire(s);
sys.semrelease(s);
}
export func TestSemaphore(t *testing.T) {
- s := new(int32);
+ s := new(*int32);
*s = 1;
c := new(chan bool);
for i := 0; i < 10; i++ {
}
-func HammerMutex(m *Mutex, cdone *chan bool) {
+func HammerMutex(m *Mutex, cdone chan bool) {
for i := 0; i < 1000; i++ {
m.Lock();
m.Unlock();
}
export func TestMutex(t *testing.T) {
- m := new(Mutex);
+ m := new(*Mutex);
c := new(chan bool);
for i := 0; i < 10; i++ {
go HammerMutex(m, c);
export func open(name string, mode int64, perm int64) (ret int64, errno int64) {
var namebuf [NameBufsize]byte;
- if !StringToBytes(&namebuf, name) {
+ if !StringToBytes(namebuf, name) {
return -1, ENAMETOOLONG
}
r1, r2, err := Syscall(SYS_OPEN, int64(uintptr(unsafe.pointer(&namebuf[0]))), mode, perm);
export func creat(name string, perm int64) (ret int64, errno int64) {
var namebuf [NameBufsize]byte;
- if !StringToBytes(&namebuf, name) {
+ if !StringToBytes(namebuf, name) {
return -1, ENAMETOOLONG
}
r1, r2, err := Syscall(SYS_OPEN, int64(uintptr(unsafe.pointer(&namebuf[0]))), O_CREAT|O_WRONLY|O_TRUNC, perm);
export func stat(name string, buf *Stat) (ret int64, errno int64) {
var namebuf [NameBufsize]byte;
- if !StringToBytes(&namebuf, name) {
+ if !StringToBytes(namebuf, name) {
return -1, ENAMETOOLONG
}
r1, r2, err := Syscall(SYS_STAT, int64(uintptr(unsafe.pointer(&namebuf[0]))), int64(uintptr(unsafe.pointer(buf))), 0);
export func unlink(name string) (ret int64, errno int64) {
var namebuf [NameBufsize]byte;
- if !StringToBytes(&namebuf, name) {
+ if !StringToBytes(namebuf, name) {
return -1, ENAMETOOLONG
}
r1, r2, err := Syscall(SYS_UNLINK, int64(uintptr(unsafe.pointer(&namebuf[0]))), 0, 0);
export func mkdir(name string, perm int64) (ret int64, errno int64) {
var namebuf [NameBufsize]byte;
- if !StringToBytes(&namebuf, name) {
+ if !StringToBytes(namebuf, name) {
return -1, ENAMETOOLONG
}
r1, r2, err := Syscall(SYS_MKDIR, int64(uintptr(unsafe.pointer(&namebuf[0]))), perm, 0);
b.lines_width.Init(0);
b.widths.Init(0);
b.AddLine(); // the very first line
-
+
return b;
}
if b.padbytes[0] == '\t' {
n = (n + b.cellwidth - 1) / b.cellwidth;
}
-
+
for n > len(b.padbytes) {
err = b.Write0(b.padbytes);
if err != nil {
pos += s;
}
}
-
+
if i+1 == b.lines_size.Len() {
// last buffered line - we don't have a newline, so just write
// any outstanding buffered data
func (b *Writer) Format(pos0 int, line0, line1 int) (pos int, err *os.Error) {
pos = pos0;
- column := b.widths.Len();
+ column := b.widths.Len();
last := line0;
for this := line0; this < line1; this++ {
line_size, line_width := b.Line(this);
-
+
if column < line_size.Len() - 1 {
// cell exists in this column
// (note that the last cell per line is ignored)
-
+
// print unprinted lines until beginning of block
pos, err = b.WriteLines(pos, last, this);
if err != nil {
goto exit;
}
last = this;
-
+
// column block begin
width := b.cellwidth; // minimal width
for ; this < line1; this++ {
// print unprinted lines until end
pos, err = b.WriteLines(pos, last, line1);
-
+
exit:
return pos, err;
}
}
return l;
}
-
+
func (b *Writer) Append(buf []byte) {
b.buf.Append(buf);
}
}
}
-
+
// append leftover text
b.Append(buf[i0 : n]);
return n, nil;
export func New(writer io.Write, cellwidth, padding int, padchar byte, align_left, filter_html bool) *Writer {
- return new(Writer).Init(writer, cellwidth, padding, padchar, align_left, filter_html)
+ return new(*Writer).Init(writer, cellwidth, padding, padchar, align_left, filter_html)
}
export type T struct {
errors string;
failed bool;
- ch *chan *T;
+ ch chan *T;
}
func (t *T) Fail() {
if chatty {
println("=== RUN ", tests[i].name);
}
- t := new(T);
+ t := new(*T);
t.ch = new(chan *T);
go TRunner(t, &tests[i]);
<-t.ch;
// Also, if timeouts become part of the select statement,
// perhaps the Ticker is just:
//
-// func Ticker(ns int64, c *chan int64) {
+// func Ticker(ns int64, c chan int64) {
// for {
// select { timeout ns: }
// nsec, err := time.Nanoseconds();
// c <- nsec;
// }
-func Ticker(ns int64, c *chan int64) {
+func Ticker(ns int64, c chan int64) {
var tv syscall.Timeval;
now := time.Nanoseconds();
when := now;
}
}
-export func Tick(ns int64) *chan int64 {
+export func Tick(ns int64) chan int64 {
if ns <= 0 {
return nil
}
)
export func SecondsToUTC(sec int64) *Time {
- t := new(Time);
+ t := new(*Time);
// Split into time and day.
day := sec/SecondsPerDay;
error bool;
}
-var NIL []byte // TODO(rsc)
func (d *Data) Read(n int) []byte {
if len(d.p) < n {
- d.p = NIL;
+ d.p = nil;
d.error = true;
- return NIL;
+ return nil;
}
p := d.p[0:n];
d.p = d.p[n:len(d.p)];
}
func ParseZoneinfo(bytes []byte) (zt []Zonetime, err *os.Error) {
- var NIL []Zonetime; // TODO(rsc)
data1 := Data{bytes, false};
data := &data1;
// 4-byte magic "TZif"
if magic := data.Read(4); string(magic) != "TZif" {
- return NIL, BadZoneinfo
+ return nil, BadZoneinfo
}
// 1-byte version, then 15 bytes of padding
var p []byte;
if p = data.Read(16); len(p) != 16 || p[0] != 0 && p[0] != '2' {
- return NIL, BadZoneinfo
+ return nil, BadZoneinfo
}
vers := p[0];
for i := 0; i < 6; i++ {
nn, ok := data.Big4();
if !ok {
- return NIL, BadZoneinfo
+ return nil, BadZoneinfo
}
n[i] = int(nn);
}
isutc := data.Read(n[NUTCLocal]);
if data.error { // ran out of data
- return NIL, BadZoneinfo
+ return nil, BadZoneinfo
}
// If version == 2, the entire file repeats, this time using
var ok bool;
var n uint32;
if n, ok = zonedata.Big4(); !ok {
- return NIL, BadZoneinfo
+ return nil, BadZoneinfo
}
zone[i].utcoff = int(n);
var b byte;
if b, ok = zonedata.Byte(); !ok {
- return NIL, BadZoneinfo
+ return nil, BadZoneinfo
}
zone[i].isdst = b != 0;
if b, ok = zonedata.Byte(); !ok || int(b) >= len(abbrev) {
- return NIL, BadZoneinfo
+ return nil, BadZoneinfo
}
zone[i].name = ByteString(abbrev[b:len(abbrev)])
}
var ok bool;
var n uint32;
if n, ok = txtimes.Big4(); !ok {
- return NIL, BadZoneinfo
+ return nil, BadZoneinfo
}
zt[i].time = int32(n);
if int(txzones[i]) >= len(zone) {
- return NIL, BadZoneinfo
+ return nil, BadZoneinfo
}
zt[i].zone = &zone[txzones[i]];
if i < len(isstd) {
}
func ReadFile(name string, max int) (p []byte, err *os.Error) {
- var NIL []byte; // TODO(rsc)
fd, e := os.Open(name, os.O_RDONLY, 0);
if e != nil {
- return NIL, e
+ return nil, e
}
p = new([]byte, max+1)[0:0];
n := 0;
nn, e := fd.Read(p[n:cap(p)]);
if e != nil {
fd.Close();
- return NIL, e
+ return nil, e
}
if nn == 0 {
fd.Close();
p = p[0:n+nn]
}
fd.Close();
- return NIL, BadZoneinfo // too long
+ return nil, BadZoneinfo // too long
}
func ReadZoneinfoFile(name string) (tx []Zonetime, err *os.Error) {
- var NIL []Zonetime; // TODO(rsc)
data, e := ReadFile(name, MaxFileSize);
if e != nil {
- return NIL, e
+ return nil, e
}
tx, err = ParseZoneinfo(data);
return tx, err
maketest \
lib/fmt\
lib/hash\
+ lib/json\
lib/math\
+ lib/net\
lib/reflect\
lib/regexp\
lib/strconv\
lib/tabwriter\
lib/time\
-# lib/json\
-# lib/net\
-
# all of these are subtly different
# from what maketest does.
type T chan uint64;
-func M(f uint64) (in, out *T) {
+func M(f uint64) (in, out T) {
in = new(T, 100);
out = new(T, 100);
- go func(in, out *T, f uint64) {
+ go func(in, out T, f uint64) {
for {
out <- f * <-in;
}
1250, 1280, 1296, 1350, 1440, 1458, 1500, 1536, 1600 };
x := uint64(1);
- ins := new([]*T, n);
- outs := new([]*T, n);
+ ins := new([]T, n);
+ outs := new([]T, n);
xs := new([]uint64, n);
for i := 0; i < n; i++ {
ins[i], outs[i] = M(F[i]);
for i := 0; i < n; i++ {
if xs[i] == x { xs[i] = <- outs[i]; }
}
-
+
x = min(xs);
if x != OUT[i] { panic("bad: ", x, " should be ", OUT[i]); }
}
func (s *S) h() {} // here we can't write (s *S) T either
func main() {
- var i I = new(S);
+ var i I = new(*S);
}
}
}
-func Chain(ch *<-chan int, val int, in *<-chan int, out *chan<- int) {
+func Chain(ch <-chan int, val int, in <-chan int, out chan<- int) {
<-in;
if <-ch != val {
panic(val)
"strconv";
)
-func f(left, right *chan int) {
+func f(left, right chan int) {
left <- <-right;
}
go f(left, right);
left = right;
}
- go func(c *chan int) { c <- 1 }(right);
+ go func(c chan int) { c <- 1 }(right);
<-leftmost;
}
for i:=0; i<100; i++ { sys.gosched() }
}
-func i32receiver(c *chan int32) {
+func i32receiver(c chan int32) {
if <-c != 123 { panic("i32 value") }
}
-func i32sender(c *chan int32) {
+func i32sender(c chan int32) {
c <- 234
}
-func i64receiver(c *chan int64) {
+func i64receiver(c chan int64) {
if <-c != 123456 { panic("i64 value") }
}
-func i64sender(c *chan int64) {
+func i64sender(c chan int64) {
c <- 234567
}
-func breceiver(c *chan bool) {
+func breceiver(c chan bool) {
if ! <-c { panic("b value") }
}
-func bsender(c *chan bool) {
+func bsender(c chan bool) {
c <- true
}
-func sreceiver(c *chan string) {
+func sreceiver(c chan string) {
if <-c != "hello" { panic("s value") }
}
-func ssender(c *chan string) {
+func ssender(c chan string) {
c <- "hello again"
}
c64 := new(chan int64, buffer);
cb := new(chan bool, buffer);
cs := new(chan string, buffer);
-
+
i32, ok = <-c32;
if ok { panic("blocked i32sender") }
-
+
i64, ok = <-c64;
if ok { panic("blocked i64sender") }
-
+
b, ok = <-cb;
if ok { panic("blocked bsender") }
-
+
s, ok = <-cs;
if ok { panic("blocked ssender") }
-
+
go i32receiver(c32);
pause();
ok = c32 <- 123;
i32, ok = <-c32;
if !ok { panic("i32sender") }
if i32 != 234 { panic("i32sender value") }
-
+
go i64receiver(c64);
pause();
ok = c64 <- 123456;
i64, ok = <-c64;
if !ok { panic("i64sender") }
if i64 != 234567 { panic("i64sender value") }
-
+
go breceiver(cb);
pause();
ok = cb <- true;
b, ok = <-cb;
if !ok { panic("bsender") }
if !b{ panic("bsender value") }
-
+
go sreceiver(cs);
pause();
ok = cs <- "hello";
}
type dch struct {
- req *chan int;
- dat *chan item;
+ req chan int;
+ dat chan item;
nam int;
}
func mkdch() *dch {
c := chnameserial % len(chnames);
chnameserial++;
- d := new(dch);
+ d := new(*dch);
d.req = new(chan int);
d.dat = new(chan item);
d.nam = c;
}
func mkdch2() *dch2 {
- d2 := new(dch2);
+ d2 := new(*dch2);
d2[0] = mkdch();
d2[1] = mkdch();
return d2;
// a signal on the release-wait channel tells the next newer
// generation to begin servicing out[1].
-func dosplit(in *dch, out *dch2, wait *chan int ){
+func dosplit(in *dch, out *dch2, wait chan int ){
var t *dch;
both := false; // do not service both channels
func getn(in []*dch, n int) []item {
// BUG n:=len(in);
if n != 2 { panic("bad n in getn") };
- req := new([2] *chan int);
- dat := new([2] *chan item);
- out := new([2] item);
+ req := new(*[2] chan int);
+ dat := new(*[2] chan item);
+ out := new([]item, 2);
var i int;
var it item;
for i=0; i<n; i++ {
// Get one item from each of 2 demand channels
-func get2(in0 *dch, in1 *dch) []item {
- x := new([2] *dch);
- x[0] = in0;
- x[1] = in1;
- return getn(x, 2);
+func get2(in0 *dch, in1 *dch) []item {
+ return getn([]*dch{in0, in1}, 2);
}
func copy(in *dch, out *dch){
func i2tor(u, v int64) *rat{
g := gcd(u,v);
- r := new(rat);
+ r := new(*rat);
if v > 0 {
r.num = u/g;
r.den = v/g;
func mul(u, v *rat) *rat{
g1 := gcd(u.num,v.den);
g2 := gcd(u.den,v.num);
- r := new(rat);
+ r := new(*rat);
r.num =(u.num/g1)*(v.num/g2);
r.den = (u.den/g2)*(v.den/g1);
return r;
check(Ones, one, 5, "Ones");
check(Add(Ones, Ones), itor(2), 0, "Add Ones Ones"); // 1 1 1 1 1
check(Add(Ones, Twos), itor(3), 0, "Add Ones Twos"); // 3 3 3 3 3
- a := new([N] *rat);
+ a := new([] *rat, N);
d := Diff(Ones);
// BUG: want array initializer
for i:=0; i < N; i++ {
}
type dch struct {
- req *chan int;
- dat *chan item;
+ req chan int;
+ dat chan item;
nam int;
}
func mkdch() *dch {
c := chnameserial % len(chnames);
chnameserial++;
- d := new(dch);
+ d := new(*dch);
d.req = new(chan int);
d.dat = new(chan item);
d.nam = c;
}
func mkdch2() *dch2 {
- d2 := new(dch2);
+ d2 := new(*dch2);
d2[0] = mkdch();
d2[1] = mkdch();
return d2;
// a signal on the release-wait channel tells the next newer
// generation to begin servicing out[1].
-func dosplit(in *dch, out *dch2, wait *chan int ){
+func dosplit(in *dch, out *dch2, wait chan int ){
var t *dch;
both := false; // do not service both channels
func getn(in []*dch, n int) []item {
// BUG n:=len(in);
if n != 2 { panic("bad n in getn") };
- req := new([2] *chan int);
- dat := new([2] *chan item);
- out := new([2] item);
+ req := new([] chan int, 2);
+ dat := new([] chan item, 2);
+ out := new([]item, 2);
var i int;
var it item;
for i=0; i<n; i++ {
// Get one item from each of 2 demand channels
func get2(in0 *dch, in1 *dch) []item {
- x := new([2] *dch);
- x[0] = in0;
- x[1] = in1;
- return getn(x, 2);
+ return getn([]*dch{in0, in1}, 2);
}
func copy(in *dch, out *dch){
func i2tor(u, v int64) *rat{
g := gcd(u,v);
- r := new(rat);
+ r := new(*rat);
if v > 0 {
r.num = u/g;
r.den = v/g;
func mul(u, v *rat) *rat{
g1 := gcd(u.num,v.den);
g2 := gcd(u.den,v.num);
- r := new(rat);
+ r := new(*rat);
r.num =(u.num/g1)*(v.num/g2);
r.den = (u.den/g2)*(v.den/g1);
return r;
check(Ones, one, 5, "Ones");
check(Add(Ones, Ones), itor(2), 0, "Add Ones Ones"); // 1 1 1 1 1
check(Add(Ones, Twos), itor(3), 0, "Add Ones Twos"); // 3 3 3 3 3
- a := new([N] *rat);
+ a := new([]*rat, N);
d := Diff(Ones);
// BUG: want array initializer
for i:=0; i < N; i++ {
return 1 << shift
}
-func Send(a, b *chan uint) int {
+func Send(a, b chan uint) int {
var i int;
LOOP:
for {
package main
// Send the sequence 2, 3, 4, ... to channel 'ch'.
-func Generate(ch *chan<- int) {
+func Generate(ch chan<- int) {
for i := 2; ; i++ {
ch <- i // Send 'i' to channel 'ch'.
}
// Copy the values from channel 'in' to channel 'out',
// removing those divisible by 'prime'.
-func Filter(in *<-chan int, out *chan<- int, prime int) {
+func Filter(in <-chan int, out chan<- int, prime int) {
for {
i := <-in; // Receive value of new variable 'i' from 'in'.
if i % prime != 0 {
}
// The prime sieve: Daisy-chain Filter processes together.
-func Sieve(primes *chan<- int) {
+func Sieve(primes chan<- int) {
ch := new(chan int); // Create a new channel.
go Generate(ch); // Start Generate() as a subprocess.
for {
type R struct { num int }
func itor(a int) *R {
- r := new(R);
+ r := new(*R);
r.num = a;
return r;
}
if len(at) != 3 { panic("at") }
c := new(chan int);
- ac := []*chan int{c, c, c};
+ ac := []chan int{c, c, c};
if len(ac) != 3 { panic("ac") }
aat := [][len(at)]*T{at, at};
if len(aat) != 2 || len(aat[1]) != 3 { panic("at") }
-
+
s := string([]byte{'h', 'e', 'l', 'l', 'o'});
if s != "hello" { panic("s") }
if len(m) != 3 { panic("m") }
eq(&[]*R{itor(0), itor(1), itor(2), itor(3), itor(4), itor(5)});
-
+
p1 := NewP(1, 2);
p2 := NewP(1, 2);
if p1 == p2 { panic("NewP") }
}
func main() {
- var t *T = new(T);
+ var t *T = new(*T);
t.x = 1;
t.y = 2;
r10 := t.m(1, 3.0);
func main() {
type I struct { val int; }; // BUG: can't be local; works if global
- v := new(Vector);
- v.Insert(0, new(I));
+ v := new(*Vector);
+ v.Insert(0, new(*I));
}
/*
check: main_sigs_I: not defined
}
func New() *Vector {
- v := new(Vector);
+ v := new(*Vector);
v.nelem = 0;
- v.elem = new([10]Element);
+ v.elem = new(*[10]Element);
return v;
}
type I struct { val int; }; // BUG: can't be local;
func main() {
- i0 := new(I); i0.val = 0;
- i1 := new(I); i1.val = 11;
- i2 := new(I); i2.val = 222;
- i3 := new(I); i3.val = 3333;
- i4 := new(I); i4.val = 44444;
+ i0 := new(*I); i0.val = 0;
+ i1 := new(*I); i1.val = 11;
+ i2 := new(*I); i2.val = 222;
+ i3 := new(*I); i3.val = 3333;
+ i4 := new(*I); i4.val = 44444;
v := New();
print("hi\n");
v.Insert(i4);
func main() {
var z [3]byte;
- z := new([3]byte); // BUG redeclaration
+ z := new(*[3]byte); // BUG redeclaration
}
func main() {
var ta []*T;
- ta = new([1]*T);
+ ta = new(*[1]*T);
ta[0] = nil;
}
/*
}
func main() {
- v := new(Vector);
- v.elem = new([10]Element);
- t := new(TStruct);
+ v := new(*Vector);
+ v.elem = new(*[10]Element);
+ t := new(*TStruct);
t.name = "hi";
v.elem[0] = t;
- s := new(TStruct);
+ s := new(*TStruct);
s.name = "foo";
s.fields = v;
if s.field(0).name != "hi" {
package main
type Box struct {};
-var m *map[string] *Box;
-
+var m map[string] *Box;
+
func main() {
m := new(map[string] *Box);
s := "foo";
func main() {
m := new(map[string] []string);
- as := new([2]string);
+ as := new(*[2]string);
as[0] = "0";
as[1] = "1";
m["0"] = as;
)
type Scope struct {
- entries *map[string] *Object;
+ entries map[string] *Object;
}
package main
-var c *chan int
+var c chan int
func main() {
c = new(chan int);
i, ok = <-c; // works
- ca := new([2]*chan int);
+ ca := new(*[2]chan int);
i, ok = <-(ca[0]); // fails: c.go:11: bad shape across assignment - cr=1 cl=2
}
}
type dch struct {
- dat *chan *rat;
+ dat chan *rat;
}
func dosplit(in *dch){
package main
-type T struct { m *map[int]int }
+type T struct { m map[int]int }
func main() {
- t := new(T);
+ t := new(*T);
t.m = new(map[int]int);
var x int;
var ok bool;
package main
-func dosplit(wait *chan int ){
+func dosplit(wait chan int ){
select {
case <-wait:
}
func main() {
c := new(chan string);
- a := new(Service);
+ a := new(*Service);
go a.Serve(1234);
}
// if you take it out (and the 0s below)
// then the bug goes away.
func NewI(i int) I {
- return new(S)
+ return new(*S)
}
// Uses interface method.
}
func main() {
- s := new(Stucky);
+ s := new(*Stucky);
i := s.Me();
j := i.Me();
j.Me();
package main
-export func Send(c *chan int) int {
+export func Send(c chan int) int {
select {
default:
return 1;
r9, s9 := f9(1);
assertequal(r9, 9, "r9");
assertequal(int(s9), 9, "s9");
- var t *T = new(T);
+ var t *T = new(*T);
t.x = 1;
t.y = 2;
r10 := t.m10(1, 3.0);
func (m *HashMap) Initialize (initial_log2_capacity uint32) {
m.log2_capacity_ = initial_log2_capacity;
- m.map_ = new([1024] Entry);
+ m.map_ = new(*[1024] Entry);
m.Clear();
}
var i uint32 = key.Hash() % m.capacity();
ASSERT(0 <= i && i < m.capacity());
-
+
ASSERT(m.occupancy_ < m.capacity()); // guarantees loop termination
for m.map_[i].key != nil && !m.map_[i].key.Match(key) {
i++;
i = 0;
}
}
-
+
return &m.map_[i];
}
p.key = key;
p.value = nil;
m.occupancy_++;
-
+
// Grow the map if we reached >= 80% occupancy.
if m.occupancy_ + m.occupancy_/4 >= m.capacity() {
m.Resize();
p = m.Probe(key);
}
-
+
return p;
}
func (m *HashMap) Resize() {
var hmap *[1024] Entry = m.map_;
var n uint32 = m.occupancy_;
-
+
// Allocate a new map of twice the current size.
m.Initialize(m.log2_capacity_ << 1);
-
+
// Rehash all current entries.
var i uint32 = 0;
for n > 0 {
func MakeNumber (x uint32) *Number {
- var n *Number = new(Number);
+ var n *Number = new(*Number);
n.x = x;
return n;
}
//f unc (n int) int { return n + 1; }(1);
//print "HashMap - gri 2/8/2008\n";
-
- var hmap *HashMap = new(HashMap);
+
+ var hmap *HashMap = new(*HashMap);
hmap.Initialize(0);
-
+
var x1 *Number = MakeNumber(1001);
var x2 *Number = MakeNumber(2002);
var x3 *Number = MakeNumber(3003);
-
+
// this doesn't work I think...
//hmap.Lookup(x1, true);
//hmap.Lookup(x2, true);
//hmap.Lookup(x3, true);
-
+
//print "done\n";
}
func NewMatrix(n, m int) *Matrix {
assert(0 <= n && 0 <= m);
- a := new(Matrix);
+ a := new(*Matrix);
a.n = n;
a.m = m;
a.a = new([]*Big.Rational, n*m);
package main
var a = []int { 1, 2, }
-var b = [5]int { }
+var b = []int { }
var c = []int { 1 }
func main() {
}
func main() {
- re := new(Regexp);
+ re := new(*Regexp);
print("call addinst\n");
- var x Inst = AddInst(new(Start)); // ERROR "illegal|incompatible"
+ var x Inst = AddInst(new(*Start)); // ERROR "illegal|incompatible"
print("return from addinst\n");
}
func
testpdpf1()
{
- a := new([40]int);
+ a := new(*[40]int);
setpd(a);
res(sumpd(a), 0, 40);
type Chan
struct
{
- sc,rc *chan int; // send and recv chan
+ sc,rc chan int; // send and recv chan
sv,rv int; // send and recv seq
}
func
init()
{
- nc = new(Chan);
+ nc = new(*Chan);
}
func
ca := new([]*Chan, n);
for i:=0; i<n; i++ {
cval = cval+100;
- ch := new(Chan);
+ ch := new(*Chan);
ch.sc = new(chan int, c);
ch.rc = ch.sc;
ch.sv = cval;
var s *S;
// allocate
- s = new(S);
- s.Subp = new(Subp);
- s.Sub.SubSubp = new(SubSubp);
- s.Subp.SubpSubp = new(SubpSubp);
+ s = new(*S);
+ s.Subp = new(*Subp);
+ s.Sub.SubSubp = new(*SubSubp);
+ s.Subp.SubpSubp = new(*SubpSubp);
// explicit assignment
s.a = 1;
var i2 I2;
var g *S;
- s := new(S);
+ s := new(*S);
s.a = 5;
s.b = 6;
func
main()
{
- p := new(Print);
- b := new(Bio);
- f := new(File);
+ p := new(*Print);
+ b := new(*Bio);
+ f := new(*File);
p.whoami = 1;
p.put = b;
var v int;
var c *C;
- c = new(C);
+ c = new(*C);
c.a = 6;
c.x = &g;
var a [size]byte;
var p []byte;
-var m *map[int]byte;
+var m map[int]byte;
func
f(k int) byte
func (list *List)
Insert(i Item)
{
- item := new(ListItem);
+ item := new(*ListItem);
item.item = i;
item.next = list.head;
list.head = item;
func
main()
{
- list := new(List);
+ list := new(*List);
list.Init();
for i := 0; i < 10; i = i + 1 {
- integer := new(Integer);
+ integer := new(*Integer);
integer.Init(i);
list.Insert(integer);
}
{
var slist, retval *Slist;
- slist = new(Slist);
+ slist = new(*Slist);
slist.list.car = nil;
slist.list.cdr = nil;
slist.isatom = false;
if token == ')' || token == EOF { // empty cdr
break;
}
- slist.list.cdr = new(Slist);
+ slist.list.cdr = new(*Slist);
slist = slist.list.cdr;
}
return retval;
var h, length int;
var slist, tail *Slist;
- slist = new(Slist);
+ slist = new(*Slist);
if token == '0' {
slist.atom.integer = i;
slist.isstring = false;
r9, s9 = f9(1);
assertequal(r9, 9, "r9");
assertequal(int(s9), 9, "s9");
- var t *T = new(T);
+ var t *T = new(*T);
t.x = 1;
t.y = 2;
r10 := t.m10(1, 3.0);
if s2 != 35 { panic(s2); }
- b := new([100]int);
+ b := new(*[100]int);
for i:=0; i<100; i=i+1 {
b[i] = i;
}
if !!!a { panic(6); }
var x *s;
- x = new(s);
+ x = new(*s);
x.a = true;
x.b = false;
}
/* create string with byte array pointer */
- z2 := new([3]byte);
+ z2 := new(*[3]byte);
z2[0] = 'a';
z2[1] = 'b';
z2[2] = 'c';
//mit := new(map[int] T); // should be able to do a value but: fatal error: algtype: cant find type <T>{}
//mti := new(map[T] int); // should be able to do a value but: fatal error: algtype: cant find type <T>{}
- type M map[int] int;
- mipM := new(map[int] *M);
+ type M map[int] int;
+ mipM := new(map[int] M);
const count = 100; // BUG: should be bigger but maps do linear lookup
var apT [2*count]*T;
for i := 0; i < count; i++ {
s := F.d(i).str();
f := float(i);
- apT[i] = new(T);
+ apT[i] = new(*T);
apT[i].s = s;
apT[i].f = f;
- apT[2*i] = new(T); // need twice as many entries as we use, for the nonexistence check
+ apT[2*i] = new(*T); // need twice as many entries as we use, for the nonexistence check
apT[2*i].s = s;
apT[2*i].f = f;
// BUG t := T(s, f);
- t := new(T); t.s = s; t.f = f;
+ t := new(*T); t.s = s; t.f = f;
// BUG m := M(i, i+1);
m := new(M); m[i] = i+1;
mib[i] = (i != 0);
msi[F.d(i).str()] = i;
mss[F.d(i).str()] = F.d(10*i).str();
mss[F.d(i).str()] = F.d(10*i).str();
- as := new([arraylen]string);
+ as := new([]string, arraylen);
as[0] = F.d(10*i).str();
as[1] = F.d(10*i).str();
mspa[F.d(i).str()] = as;
if len(mipM) != count {
F.s("len(mipM) = ").d(len(mipM)).putnl();
}
-
+
// test construction directly
for i := 0; i < count; i++ {
s := F.d(i).str();
}
}
}
-
+
// tests for structured map element updates
for i := 0; i < count; i++ {
var i *int;
var f *float;
var s *string;
- var m *map[float] *int;
- var c *chan int;
+ var m map[float] *int;
+ var c chan int;
var t *T;
var in IN;
var ta []IN;
c = nil;
t = nil;
i = nil;
- ta = new([1]IN);
+ ta = new([]IN, 1);
ta[0] = nil;
}
func add1(x *Number) *Number {
- e := new(Number);
+ e := new(*Number);
e.next = x;
return e;
}
func main() {
-
+
verify();
for i := 0; i <= 10; i++ {
print(i, "! = ", count(fact(gen(i))), "\n");
package main
// Send the sequence 2, 3, 4, ... to channel 'ch'.
-func Generate(ch *chan<- int) {
+func Generate(ch chan<- int) {
for i := 2; ; i++ {
ch <- i // Send 'i' to channel 'ch'.
}
// Copy the values from channel 'in' to channel 'out',
// removing those divisible by 'prime'.
-func Filter(in *<-chan int, out *chan<- int, prime int) {
+func Filter(in <-chan int, out chan<- int, prime int) {
for {
i := <-in; // Receive value of new variable 'i' from 'in'.
if i % prime != 0 {
const
a_const = 0
-
+
const (
pi = /* the usual */ 3.14159265358979323;
e = 2.718281828;
}
func control_structs() {
- var p *Point = new(Point).Initialize(2, 3);
+ var p *Point = new(*Point).Initialize(2, 3);
i := p.Distance();
var f float = 0.3;
for {}
// encoded as bytes: 'a' 'b' 'c' e6 97 a5 e6 9c ac e8 aa 9e
const L = 12;
if L != l { panic("wrong length constructing array") }
- a := new([L]byte);
+ a := new(*[L]byte);
a[0] = 'a';
a[1] = 'b';
a[2] = 'c';
func test1() {
var a [1000] *S;
for i := 0; i < len(a); i++ {
- a[i] = new(S).Init(i);
+ a[i] = new(*S).Init(i);
}
v := array.New(0);
panic("expected ", i, ", found ", x.val, "\n");
}
}
-
+
for v.Len() > 10 {
v.Remove(10);
}
export func NewLiteral(pos int, typ *Globals.Type) *Literal {
- x := new(Literal);
+ x := new(*Literal);
x.pos_ = pos;
x.typ_ = typ;
return x;
export func NewObject(pos int, obj* Globals.Object) *Object {
- x := new(Object);
+ x := new(*Object);
x.pos_ = pos;
x.obj = obj;
return x;
export func NewSelector(pos int, typ *Globals.Type) *Selector {
- x := new(Selector);
+ x := new(*Selector);
x.pos_ = pos;
x.typ_ = typ;
return x;
print(src_file, "\n");
}
- scanner := new(Scanner.Scanner);
+ scanner := new(*Scanner.Scanner);
scanner.Open(src_file, src);
- var tstream *chan *Scanner.Token;
+ var tstream chan *Scanner.Token;
if comp.flags.token_chan {
tstream = new(chan *Scanner.Token, 100);
go scanner.Server(tstream);
}
- parser := new(Parser.Parser);
+ parser := new(*Parser.Parser);
parser.Open(comp, scanner, tstream);
parser.ParseProgram();
type T9 struct {
p *T9;
- q [] *map [int] *T9;
+ q [] map [int] *T9;
f *(x, y *T9) *T9;
}
export type Scope struct {
parent *Scope;
entries *List;
- // entries *map[string] *Object; // doesn't work properly
+ // entries map[string] *Object; // doesn't work properly
}
export var Universe_void_t *Type // initialized by Universe to Universe.void_t
export func NewObject(pos, kind int, ident string) *Object {
- obj := new(Object);
+ obj := new(*Object);
obj.exported = false;
obj.pos = pos;
obj.kind = kind;
export func NewType(form int) *Type {
- typ := new(Type);
+ typ := new(*Type);
typ.ref = -1; // not yet exported
typ.form = form;
return typ;
export func NewPackage(file_name string, obj *Object, scope *Scope) *Package {
- pkg := new(Package);
+ pkg := new(*Package);
pkg.ref = -1; // not yet exported
pkg.file_name = file_name;
pkg.key = "<the package key>"; // empty key means package forward declaration
export func NewList() *List {
- return new(List);
+ return new(*List);
}
export func NewScope(parent *Scope) *Scope {
- scope := new(Scope);
+ scope := new(*Scope);
scope.parent = parent;
scope.entries = NewList();
return scope;
// Object methods
func (obj *Object) Copy() *Object {
- copy := new(Object);
+ copy := new(*Object);
copy.exported = obj.exported;
copy.pos = obj.pos;
copy.kind = obj.kind;
func (L *List) Add() *Elem {
L.len_++;
- e := new(Elem);
+ e := new(*Elem);
if L.first == nil {
L.first = e;
} else {
func main() {
arg := Next();
-
+
if arg == "" {
PrintHelp();
return;
}
// collect flags and files
- flags := new(Globals.Flags);
+ flags := new(*Globals.Flags);
files := Globals.NewList();
for arg != "" {
switch arg {
}
arg = Next();
}
-
+
// setup environment
- env := new(Globals.Environment);
+ env := new(*Globals.Environment);
env.Import = &Compilation.Import;
env.Export = &Compilation.Export;
env.Compile = &Compilation.Compile;
-
+
// compile files
for p := files.first; p != nil; p = p.next {
// setup compilation
- comp := new(Globals.Compilation);
+ comp := new(*Globals.Compilation);
comp.flags = flags;
comp.env = env;
-
+
// compile
Compilation.Compile(comp, p.str);
}
verbose bool;
indent uint;
S *Scanner.Scanner;
- C *chan *Scanner.Token;
-
+ C chan *Scanner.Token;
+
// Token
tok int; // one token look-ahead
pos int; // token source position
}
-func (P *Parser) Open(comp *Globals.Compilation, S *Scanner.Scanner, C *chan *Scanner.Token) {
+func (P *Parser) Open(comp *Globals.Compilation, S *Scanner.Scanner, C chan *Scanner.Token) {
P.comp = comp;
P.semantic_checks = comp.flags.ast;
P.verbose = comp.flags.verbosity > 2;
obj = Globals.NewObject(-1, Object.FUNC, ident);
obj.typ = typ;
// TODO do we need to set the primary type? probably...
- return obj;
+ return obj;
}
// We have a matching forward declaration. Use it.
} else {
P.Expect(Scanner.IDENT); // use Expect() error handling
}
-
+
P.Ecart();
return pos, ident;
}
func (P *Parser) ParseIdentDecl(kind int) *Globals.Object {
P.Trace("IdentDecl");
-
+
pos, ident := P.ParseIdent(kind == Object.FIELD);
obj := Globals.NewObject(pos, kind, ident);
P.Declare(obj);
-
+
P.Ecart();
return obj;
}
func (P *Parser) ParseIdentDeclList(kind int) *Globals.List {
P.Trace("IdentDeclList");
-
+
list := Globals.NewList();
list.AddObj(P.ParseIdentDecl(kind));
for P.tok == Scanner.COMMA {
P.Next();
list.AddObj(P.ParseIdentDecl(kind));
}
-
+
P.Ecart();
return list;
}
if pos < 0 {
pos, ident = P.ParseIdent(false);
}
-
+
if P.semantic_checks {
obj := P.Lookup(ident);
if obj == nil {
obj = Globals.NewObject(pos, Object.BAD, ident);
}
}
-
+
P.Ecart();
return obj;
-
+
} else {
if P.tok == Scanner.PERIOD {
P.Next();
P.Ecart();
return nil;
}
-
+
panic("UNREACHABLE");
}
func (P *Parser) ParseType() *Globals.Type {
P.Trace("Type");
-
+
typ := P.TryType();
if typ == nil {
P.Error(P.pos, "type expected");
typ = Universe.bad_t;
}
-
+
P.Ecart();
return typ;
}
func (P *Parser) ParseVarType() *Globals.Type {
P.Trace("VarType");
-
+
pos := P.pos;
typ := P.ParseType();
-
+
if P.semantic_checks {
switch typ.form {
case Type.ARRAY:
}
// open arrays must be pointers
fallthrough;
-
+
case Type.MAP, Type.CHANNEL, Type.FUNCTION:
P.Error(pos, "must be pointer to this type");
typ = Universe.bad_t;
}
}
-
+
P.Ecart();
return typ;
}
func (P *Parser) ParseTypeName() *Globals.Type {
P.Trace("TypeName");
-
+
if P.semantic_checks {
pos := P.pos;
obj := P.ParseQualifiedIdent(-1, "");
P.Ecart();
return Universe.bad_t;
}
-
+
panic("UNREACHABLE");
}
func (P *Parser) ParseArrayType() *Globals.Type {
P.Trace("ArrayType");
-
+
P.Expect(Scanner.LBRACK);
typ := Globals.NewType(Type.ARRAY);
if P.tok != Scanner.RBRACK {
P.Expect(Scanner.RBRACK);
typ.elt = P.ParseVarType();
- P.Ecart();
+ P.Ecart();
return typ;
}
func (P *Parser) ParseChannelType() *Globals.Type {
P.Trace("ChannelType");
-
+
typ := Globals.NewType(Type.CHANNEL);
if P.tok == Scanner.CHAN {
P.Next();
}
typ.elt = P.ParseVarType();
- P.Ecart();
+ P.Ecart();
return typ;
}
func (P *Parser) ParseVarDeclList(kind int) {
P.Trace("VarDeclList");
-
+
list := P.ParseIdentDeclList(kind);
typ := P.ParseVarType();
for p := list.first; p != nil; p = p.next {
p.obj.typ = typ; // TODO should use/have set_type()
}
-
+
P.Ecart();
}
func (P *Parser) ParseParameterList() {
P.Trace("ParameterList");
-
+
P.ParseVarDeclList(Object.VAR);
for P.tok == Scanner.COMMA {
P.Next();
P.ParseVarDeclList(Object.VAR);
}
-
+
P.Ecart();
}
func (P *Parser) ParseParameters() {
P.Trace("Parameters");
-
+
P.Expect(Scanner.LPAREN);
if P.tok != Scanner.RPAREN {
P.ParseParameterList();
}
P.Expect(Scanner.RPAREN);
-
+
P.Ecart();
}
func (P *Parser) TryResult() bool {
P.Trace("Result (try)");
-
+
res := false;
if P.tok == Scanner.LPAREN {
// TODO: here we allow empty returns - should proably fix this
res = P.TryType() != nil;
}
P.Ecart();
-
+
return res;
}
func (P *Parser) ParseAnonymousSignature() *Globals.Type {
P.Trace("AnonymousSignature");
-
+
P.OpenScope();
P.level--;
sig := P.top_scope;
p0 := 0;
-
+
recv_pos := P.pos;
P.ParseParameters();
-
+
if P.tok == Scanner.PERIOD {
p0 = sig.entries.len_;
if P.semantic_checks && p0 != 1 {
P.Next();
P.ParseParameters();
}
-
+
r0 := sig.entries.len_;
P.TryResult();
P.level++;
P.CloseScope();
-
+
P.Ecart();
return MakeFunctionType(sig, p0, r0, true);
}
func (P *Parser) ParseNamedSignature() (pos int, ident string, typ *Globals.Type) {
P.Trace("NamedSignature");
-
+
P.OpenScope();
P.level--;
sig := P.top_scope;
// TODO do something useful here
}
}
-
+
pos, ident = P.ParseIdent(true);
P.ParseParameters();
-
+
r0 := sig.entries.len_;
P.TryResult();
P.level++;
P.CloseScope();
-
+
P.Ecart();
return pos, ident, MakeFunctionType(sig, p0, r0, true);
}
func (P *Parser) ParseFunctionType() *Globals.Type {
P.Trace("FunctionType");
-
+
typ := P.ParseAnonymousSignature();
-
+
P.Ecart();
return typ;
}
func (P *Parser) ParseMethodDecl(recv_typ *Globals.Type) {
P.Trace("MethodDecl");
-
+
pos, ident := P.ParseIdent(true);
P.OpenScope();
P.level--;
sig := P.top_scope;
-
+
// dummy receiver (give it a name so it won't conflict with unnamed result)
recv := Globals.NewObject(pos, Object.VAR, ".recv");
recv.typ = recv_typ;
sig.Insert(recv);
-
+
P.ParseParameters();
-
+
r0 := sig.entries.len_;
P.TryResult();
P.level++;
P.CloseScope();
P.Optional(Scanner.SEMICOLON);
-
+
obj := Globals.NewObject(pos, Object.FUNC, ident);
obj.typ = MakeFunctionType(sig, 1, r0, true);
P.Declare(obj);
-
+
P.Ecart();
}
func (P *Parser) ParseInterfaceType() *Globals.Type {
P.Trace("InterfaceType");
-
+
P.Expect(Scanner.INTERFACE);
P.Expect(Scanner.LBRACE);
P.OpenScope();
P.level++;
P.CloseScope();
P.Expect(Scanner.RBRACE);
-
+
P.Ecart();
return typ;
}
func (P *Parser) ParseMapType() *Globals.Type {
P.Trace("MapType");
-
+
P.Expect(Scanner.MAP);
P.Expect(Scanner.LBRACK);
typ := Globals.NewType(Type.MAP);
P.Expect(Scanner.RBRACK);
typ.elt = P.ParseVarType();
P.Ecart();
-
+
return typ;
}
func (P *Parser) ParseStructType() *Globals.Type {
P.Trace("StructType");
-
+
P.Expect(Scanner.STRUCT);
P.Expect(Scanner.LBRACE);
P.OpenScope();
P.level++;
P.CloseScope();
P.Expect(Scanner.RBRACE);
-
+
P.Ecart();
return typ;
}
func (P *Parser) ParsePointerType() *Globals.Type {
P.Trace("PointerType");
-
+
P.Expect(Scanner.MUL);
typ := Globals.NewType(Type.POINTER);
-
+
var elt *Globals.Type;
if P.semantic_checks {
if P.tok == Scanner.STRING && !P.comp.flags.sixg {
// TODO introduce dummy package so we can continue safely
}
}
-
+
P.Next(); // consume package name
P.Expect(Scanner.PERIOD);
pos, ident := P.ParseIdent(false);
}
elt = obj.typ;
}
-
+
} else if P.tok == Scanner.IDENT {
if P.Lookup(P.val) == nil {
// implicit type forward declaration
- // create a named forward type
+ // create a named forward type
pos, ident := P.ParseIdent(false);
obj := Globals.NewObject(pos, Object.TYPE, ident);
elt = Globals.NewType(Type.FORWARD);
// remember the current scope - resolving the forward
// type must find a matching declaration in this or a less nested scope
elt.scope = P.top_scope;
-
+
} else {
// type name
// (ParseType() (via TryType()) checks for forward types and complains,
if elt.form == Type.FORWARD {
P.forward_types.AddTyp(typ);
}
-
+
} else {
elt = P.ParseType();
}
-
+
} else {
elt = P.ParseType();
}
typ.elt = elt;
-
+
P.Ecart();
return typ;
}
// Returns nil if no type was found.
func (P *Parser) TryType() *Globals.Type {
P.Trace("Type (try)");
-
+
pos := P.pos;
var typ *Globals.Type = nil;
switch P.tok {
func (P *Parser) ParseBlock(sig *Globals.Scope) {
P.Trace("Block");
-
+
P.Expect(Scanner.LBRACE);
P.OpenScope();
if sig != nil {
}
P.CloseScope();
P.Expect(Scanner.RBRACE);
-
+
P.Ecart();
}
func (P *Parser) ParseExpressionList(list *Globals.List) {
P.Trace("ExpressionList");
-
+
list.AddExpr(P.ParseExpression());
for P.tok == Scanner.COMMA {
P.Next();
list.AddExpr(P.ParseExpression());
}
-
+
P.Ecart();
}
func (P *Parser) ParseNewExpressionList() *Globals.List {
P.Trace("NewExpressionList");
-
+
list := Globals.NewList();
P.ParseExpressionList(list);
-
+
P.Ecart();
return list;
}
func (P *Parser) ParseNew() Globals.Expr {
P.Trace("New");
-
+
P.Expect(Scanner.NEW);
P.Expect(Scanner.LPAREN);
P.ParseType();
P.ParseExpressionList(args)
}
P.Expect(Scanner.RPAREN);
-
+
P.Ecart();
return nil;
}
func (P *Parser) ParseFunctionLit() Globals.Expr {
P.Trace("FunctionLit");
-
+
P.Expect(Scanner.FUNC);
typ := P.ParseFunctionType();
P.ParseBlock(typ.scope);
-
+
P.Ecart();
return nil;
}
list.AddExpr(P.ParseExpression());
P.Expect(Scanner.COLON);
list.AddExpr(P.ParseExpression());
-
+
P.Ecart();
}
for (P.tok == Scanner.COMMA) {
P.ParseExpressionPair(list);
}
-
+
P.Ecart();
}
func (P *Parser) ParseCompositeLit(typ *Globals.Type) Globals.Expr {
P.Trace("CompositeLit");
-
+
P.Expect(Scanner.LBRACE);
// TODO: should allow trailing ','
list := Globals.NewList();
}
} else {
-
+
switch P.tok {
case Scanner.IDENT:
panic("UNREACHABLE");
-
+
case Scanner.LPAREN:
P.Next();
res = P.ParseExpression();
P.Expect(Scanner.RPAREN);
-
+
case Scanner.INT:
x := AST.NewLiteral(P.pos, Universe.int_t);
x.i = 42; // TODO set the right value
case Scanner.NIL:
P.Next();
res = AST.Nil;
-
+
case Scanner.IOTA:
x := AST.NewLiteral(P.pos, Universe.int_t);
x.i = 42; // TODO set the right value
case Scanner.FALSE:
P.Next();
res = AST.False;
-
+
case Scanner.FUNC:
res = P.ParseFunctionLit();
-
+
case Scanner.NEW:
res = P.ParseNew();
-
+
default:
typ := P.TryType();
if typ != nil {
P.Next(); // make progress
}
}
-
+
}
P.Ecart();
period_pos := P.pos;
P.Expect(Scanner.PERIOD);
-
+
if P.tok >= Scanner.IDENT {
ident_pos, ident := P.ParseIdent(true);
-
+
if P.semantic_checks {
switch typ := x.typ(); typ.form {
case Type.BAD:
obj := typ.scope.Lookup(ident);
if obj != nil {
x = AST.NewSelector(x.pos(), obj.typ);
-
+
} else {
P.Error(ident_pos, `no field/method "` + ident + `"`);
x = AST.Bad;
x = AST.Bad;
}
}
-
+
} else {
P.Expect(Scanner.LPAREN);
P.ParseType();
P.Expect(Scanner.RPAREN);
-
+
if P.semantic_checks {
panic("UNIMPLEMENTED");
}
}
-
+
P.Ecart();
return x;
}
func (P *Parser) ParseIndexOrSlice(x Globals.Expr) Globals.Expr {
P.Trace("IndexOrSlice");
-
+
pos := P.pos;
P.Expect(Scanner.LBRACK);
i1 := P.ParseExpression();
i2 := P.ParseExpression();
}
P.Expect(Scanner.RBRACK);
-
+
if P.semantic_checks {
switch typ := x.typ(); typ.form {
case Type.BAD:
break;
case Type.STRING, Type.ARRAY:
panic("UNIMPLEMENTED");
-
+
case Type.MAP:
if Type.Equal(typ.aux, i1.typ()) {
// x = AST.NewSubscript(x, i1);
panic("UNIMPLEMENTED");
-
+
} else {
P.Error(x.pos(), "map key type mismatch");
x = AST.Bad;
}
-
+
default:
P.Error(pos, `"[]" not applicable`);
x = AST.Bad;
}
-
+
}
-
+
P.Ecart();
return x;
}
if P.semantic_checks {
panic("UNIMPLEMENTED");
}
-
+
P.Ecart();
return x;
}
func (P *Parser) ParsePrimaryExpr(pos int, ident string) Globals.Expr {
P.Trace("PrimaryExpr");
-
+
x := P.ParseOperand(pos, ident);
for {
switch P.tok {
P.Next();
list.AddExpr(P.ParsePrimaryExpr(-1, ""));
}
-
+
P.Ecart();
return list;
}
func (P *Parser) ParseUnaryExpr() Globals.Expr {
P.Trace("UnaryExpr");
-
+
switch P.tok {
case Scanner.ADD: fallthrough;
case Scanner.SUB: fallthrough;
return nil; // TODO fix this
}
P.ParsePrimaryExpr(-1, "");
-
+
P.Ecart();
return nil; // TODO fix this
}
func (P *Parser) ParseBinaryExpr(pos int, ident string, prec1 int) Globals.Expr {
P.Trace("BinaryExpr");
-
+
var x Globals.Expr;
if pos >= 0 {
x = P.ParsePrimaryExpr(pos, ident);
}
for prec := Precedence(P.tok); prec >= prec1; prec-- {
for Precedence(P.tok) == prec {
- e := new(AST.BinaryExpr);
+ e := new(*AST.BinaryExpr);
e.typ_ = Universe.bad_t; // TODO fix this
e.op = P.tok; // TODO should we use tokens or separate operator constants?
e.x = x;
x = e;
}
}
-
+
P.Ecart();
return x;
}
func (P *Parser) ParseIdentExpression(pos int, ident string) Globals.Expr {
P.Trace("IdentExpression");
indent := P.indent;
-
+
x := P.ParseBinaryExpr(pos, ident, 1);
-
+
if indent != P.indent {
panic("imbalanced tracing code (Expression)");
}
func (P *Parser) ParseExpression() Globals.Expr {
P.Trace("Expression");
-
+
x := P.ParseIdentExpression(-1, "");
P.Ecart();
func (P *Parser) ParseIdentOrExpr(pos_list, ident_list, expr_list *Globals.List) {
P.Trace("IdentOrExpr");
-
+
pos_list.AddInt(P.pos);
pos, ident := -1, "";
just_ident := false;
P.ParseIdentExpression(pos, ident);
expr_list.AddInt(0); // TODO fix this - add correct expression
}
-
+
P.Ecart();
}
func (P *Parser) ParseIdentOrExprList() (pos_list, ident_list, expr_list *Globals.List) {
P.Trace("IdentOrExprList");
-
+
pos_list, ident_list, expr_list = Globals.NewList(), Globals.NewList(), Globals.NewList();
P.ParseIdentOrExpr(pos_list, ident_list, expr_list);
for P.tok == Scanner.COMMA {
P.Next();
P.ParseIdentOrExpr(pos_list, ident_list, expr_list);
}
-
+
P.Ecart();
return pos_list, ident_list, expr_list;
}
func (P *Parser) ParseSimpleStat() {
P.Trace("SimpleStat");
-
+
// If we see an identifier, we don't know if it's part of a
// label declaration, (multiple) variable declaration, assignment,
// or simply an expression, without looking ahead.
// a non-empty list of identifiers or a non-empty list of expressions
// (but not both).
pos_list, ident_list, expr_list := P.ParseIdentOrExprList();
-
+
switch P.tok {
case Scanner.COLON:
// label declaration
P.Error(P.pos, "illegal label declaration");
}
P.Next();
-
+
case Scanner.DEFINE:
// variable declaration
if P.semantic_checks && ident_list.len_ == 0 {
// TODO set correct types
}
}
-
+
case Scanner.ASSIGN: fallthrough;
case Scanner.ADD_ASSIGN: fallthrough;
case Scanner.SUB_ASSIGN: fallthrough;
if P.semantic_checks && val_list.len_ != expr_list.len_ {
P.Error(pos, "number of expressions does not match number of variables");
}
-
+
default:
P.ConvertToExprList(pos_list, ident_list, expr_list);
if P.semantic_checks && expr_list.len_ != 1 {
P.Next();
}
}
-
+
P.Ecart();
}
func (P *Parser) ParseGoStat() {
P.Trace("GoStat");
-
+
P.Expect(Scanner.GO);
P.ParseExpression();
-
+
P.Ecart();
}
func (P *Parser) ParseReturnStat() {
P.Trace("ReturnStat");
-
+
P.Expect(Scanner.RETURN);
res := Globals.NewList();
if P.tok != Scanner.SEMICOLON && P.tok != Scanner.RBRACE {
P.ParseExpressionList(res);
}
-
+
P.Ecart();
}
func (P *Parser) ParseControlFlowStat(tok int) {
P.Trace("ControlFlowStat");
-
+
P.Expect(tok);
if P.tok == Scanner.IDENT {
P.ParseIdent(false);
}
-
+
P.Ecart();
}
func (P *Parser) ParseIfStat() *AST.IfStat {
P.Trace("IfStat");
-
+
P.Expect(Scanner.IF);
P.OpenScope();
if P.tok != Scanner.LBRACE {
}
}
P.CloseScope();
-
+
P.Ecart();
return nil;
}
func (P *Parser) ParseForStat() {
P.Trace("ForStat");
-
+
P.Expect(Scanner.FOR);
P.OpenScope();
if P.tok != Scanner.LBRACE {
}
P.ParseBlock(nil);
P.CloseScope();
-
+
P.Ecart();
}
func (P *Parser) ParseCase() {
P.Trace("Case");
-
+
if P.tok == Scanner.CASE {
P.Next();
list := Globals.NewList();
P.Expect(Scanner.DEFAULT);
}
P.Expect(Scanner.COLON);
-
+
P.Ecart();
}
func (P *Parser) ParseCaseClause() {
P.Trace("CaseClause");
-
+
P.ParseCase();
if P.tok != Scanner.FALLTHROUGH && P.tok != Scanner.RBRACE {
P.ParseStatementList();
P.Next();
P.Optional(Scanner.SEMICOLON);
}
-
+
P.Ecart();
}
func (P *Parser) ParseSwitchStat() {
P.Trace("SwitchStat");
-
+
P.Expect(Scanner.SWITCH);
P.OpenScope();
if P.tok != Scanner.LBRACE {
}
P.Expect(Scanner.RBRACE);
P.CloseScope();
-
+
P.Ecart();
}
func (P *Parser) ParseCommCase() {
P.Trace("CommCase");
-
+
if P.tok == Scanner.CASE {
P.Next();
if P.tok == Scanner.GTR {
P.Expect(Scanner.DEFAULT);
}
P.Expect(Scanner.COLON);
-
+
P.Ecart();
}
func (P *Parser) ParseCommClause() {
P.Trace("CommClause");
-
+
P.ParseCommCase();
if P.tok != Scanner.CASE && P.tok != Scanner.DEFAULT && P.tok != Scanner.RBRACE {
P.ParseStatementList();
P.Optional(Scanner.SEMICOLON);
}
-
+
P.Ecart();
}
func (P *Parser) ParseRangeStat() {
P.Trace("RangeStat");
-
+
P.Expect(Scanner.RANGE);
P.ParseIdentList();
P.Expect(Scanner.DEFINE);
P.ParseExpression();
P.ParseBlock(nil);
-
+
P.Ecart();
}
func (P *Parser) ParseSelectStat() {
P.Trace("SelectStat");
-
+
P.Expect(Scanner.SELECT);
P.Expect(Scanner.LBRACE);
for P.tok != Scanner.RBRACE && P.tok != Scanner.EOF {
P.ParseCommClause();
}
P.Next();
-
+
P.Ecart();
}
func (P *Parser) ParseImportSpec() {
P.Trace("ImportSpec");
-
+
var obj *Globals.Object = nil;
if P.tok == Scanner.PERIOD {
P.Error(P.pos, `"import ." not yet handled properly`);
} else if P.tok == Scanner.IDENT {
obj = P.ParseIdentDecl(Object.PACKAGE);
}
-
+
if P.semantic_checks && P.tok == Scanner.STRING {
// TODO eventually the scanner should strip the quotes
pkg_name := P.val[1 : len(P.val) - 1]; // strip quotes
} else {
P.Expect(Scanner.STRING); // use Expect() error handling
}
-
+
P.Ecart();
}
func (P *Parser) ParseConstSpec(exported bool) {
P.Trace("ConstSpec");
-
+
list := P.ParseIdentDeclList(Object.CONST);
typ := P.TryType();
if typ != nil {
p.obj.typ = typ;
}
}
-
+
if P.tok == Scanner.ASSIGN {
P.Next();
P.ParseNewExpressionList();
}
-
+
if exported {
for p := list.first; p != nil; p = p.next {
p.obj.exported = true;
}
}
-
+
P.Ecart();
}
P.Trace("TypeSpec");
var typ *Globals.Type;
-
+
pos, ident := P.ParseIdent(false);
obj := P.Lookup(ident);
-
+
if !P.comp.flags.sixg && obj != nil {
if obj.typ.form == Type.FORWARD {
// imported forward-declared type
} else {
panic("bar");
}
-
+
} else {
// Immediately after declaration of the type name, the type is
// considered forward-declared. It may be referred to from inside
if typ.obj == nil {
typ.obj = obj; // primary type object
}
-
+
// if the type is exported, for now we export all fields
// of structs and interfaces by default
// TODO this needs to change eventually
p.obj.exported = true;
}
}
-
+
P.Ecart();
}
func (P *Parser) ParseVarSpec(exported bool) {
P.Trace("VarSpec");
-
+
list := P.ParseIdentDeclList(Object.VAR);
if P.tok == Scanner.ASSIGN {
P.Next();
P.ParseNewExpressionList();
}
}
-
+
if exported {
for p := list.first; p != nil; p = p.next {
p.obj.exported = true;
}
}
-
+
P.Ecart();
}
func (P *Parser) ParseDecl(exported bool, keyword int) {
P.Trace("Decl");
-
+
P.Expect(keyword);
if P.tok == Scanner.LPAREN {
P.Next();
} else {
P.ParseSpec(exported, keyword);
}
-
+
P.Ecart();
}
func (P *Parser) ParseFuncDecl(exported bool) {
P.Trace("FuncDecl");
-
+
P.Expect(Scanner.FUNC);
pos, ident, typ := P.ParseNamedSignature();
obj := P.DeclareFunc(pos, ident, typ); // need obj later for statements
} else {
P.ParseBlock(typ.scope);
}
-
+
P.Ecart();
}
func (P *Parser) ParseExportDecl() {
P.Trace("ExportDecl");
-
+
// TODO This is deprecated syntax and should go away eventually.
// (Also at the moment the syntax is everything goes...)
//P.Expect(Scanner.EXPORT);
if !P.comp.flags.sixg {
P.Error(P.pos, "deprecated export syntax (use -6g to enable)");
}
-
+
has_paren := false;
if P.tok == Scanner.LPAREN {
P.Next();
if has_paren {
P.Expect(Scanner.RPAREN)
}
-
+
P.Ecart();
}
func (P *Parser) ParseDeclaration() {
P.Trace("Declaration");
indent := P.indent;
-
+
exported := false;
if P.tok == Scanner.EXPORT {
if P.level == 0 {
}
P.Next();
}
-
+
switch P.tok {
case Scanner.CONST, Scanner.TYPE, Scanner.VAR:
P.ParseDecl(exported, P.tok);
P.Next(); // make progress
}
}
-
+
if indent != P.indent {
panic("imbalanced tracing code (Declaration)");
}
if !P.semantic_checks {
return;
}
-
+
for p := P.forward_types.first; p != nil; p = p.next {
typ := p.typ;
if typ.form != Type.POINTER {
panic("unresolved types should be pointers only");
}
-
+
elt := typ.elt;
if typ.elt.form != Type.FORWARD {
panic("unresolved pointer should point to forward type");
}
-
+
obj := elt.obj;
if obj.typ == elt {
// actual forward declaration (as opposed to forward types introduced
// update the pointer type
typ.elt = obj.typ;
-
+
// TODO as long as we don't *use* a forward type, we are ok
// => consider not reporting this as an error
// (in a real forward declaration, the corresponding objects are not in a scope
if !P.semantic_checks {
return;
}
-
+
scope := P.top_scope;
for p := P.exports.first; p != nil; p = p.next {
obj := scope.Lookup(p.str);
func (P *Parser) ParseProgram() {
P.Trace("Program");
-
+
P.OpenScope();
P.Expect(Scanner.PACKAGE);
obj := P.ParseIdentDecl(Object.PACKAGE);
P.Optional(Scanner.SEMICOLON);
-
+
{ P.OpenScope();
if P.level != 0 {
panic("incorrect scope level");
}
-
+
P.comp.Insert(Globals.NewPackage(P.S.filename, obj, P.top_scope));
if P.comp.pkg_ref != 1 {
panic("should have exactly one package now");
P.ParseDecl(false, Scanner.IMPORT);
P.Optional(Scanner.SEMICOLON);
}
-
+
for P.tok != Scanner.EOF {
P.ParseDeclaration();
P.Optional(Scanner.SEMICOLON);
}
-
+
P.ResolveForwardTypes();
P.MarkExports();
-
+
if P.level != 0 {
panic("incorrect scope level");
}
P.CloseScope();
}
-
+
P.CloseScope();
P.Ecart();
}
RBRACK;
LBRACE;
RBRACE;
-
+
ASSIGN;
DEFINE;
-
+
INC;
DEC;
NOT;
-
+
AND;
OR;
XOR;
-
+
ADD;
SUB;
MUL;
QUO;
REM;
-
+
EQL;
NEQ;
LSS;
SHL;
SHR;
-
+
ARROW;
ADD_ASSIGN;
AND_ASSIGN;
OR_ASSIGN;
XOR_ASSIGN;
-
+
SHL_ASSIGN;
SHR_ASSIGN;
LAND;
LOR;
-
+
// IDENT must be immediately before keywords
IDENT;
)
-var Keywords *map [string] int;
+var Keywords map [string] int;
var VerboseMsgs bool; // error message customization
case ASSIGN: return "=";
case DEFINE: return ":=";
-
+
case INC: return "++";
case DEC: return "--";
case NOT: return "!";
case AND: return "&";
case OR: return "|";
case XOR: return "^";
-
+
case ADD: return "+";
case SUB: return "-";
case MUL: return "*";
case QUO: return "/";
case REM: return "%";
-
+
case EQL: return "==";
case NEQ: return "!=";
case LSS: return "<";
case SHL: return "<<";
case SHR: return ">>";
-
+
case ARROW: return "<-";
case ADD_ASSIGN: return "+=";
case TYPE: return "type";
case VAR: return "var";
}
-
+
return "???";
}
func init() {
Keywords = new(map [string] int);
-
+
for i := KEYWORDS_BEG; i <= KEYWORDS_END; i++ {
Keywords[TokenName(i)] = i;
}
-
+
// Provide column information in error messages for gri only...
VerboseMsgs = Platform.USER == "gri";
}
filename string; // error reporting only
nerrors int; // number of errors
errpos int; // last error position
-
+
src string; // scanned source
pos int; // current reading position
ch int; // one char look-ahead
src := S.src;
lim := len(src);
pos := S.pos;
-
+
// 1-byte sequence
// 0000-007F => T1
if pos >= lim {
func (S *Scanner) LineCol(pos int) (line, col int) {
line = 1;
lpos := 0;
-
+
src := S.src;
if pos > len(src) {
pos = len(src);
lpos = i;
}
}
-
+
return line, pos - lpos;
}
S.nerrors++;
S.errpos = pos;
}
-
+
if S.nerrors >= 10 {
sys.exit(1);
}
S.filename = filename;
S.nerrors = 0;
S.errpos = 0;
-
+
S.src = src;
S.pos = 0;
S.Next();
for S.ch != '\n' && S.ch >= 0 {
S.Next();
}
-
+
} else {
/* comment */
pos := S.chpos - 1;
S.Next();
}
val = S.src[pos : S.chpos];
-
+
var present bool;
tok, present = Keywords[val];
if !present {
tok = IDENT;
}
-
+
return tok, val;
}
func (S *Scanner) ScanNumber(seen_decimal_point bool) (tok int, val string) {
pos := S.chpos;
tok = INT;
-
+
if seen_decimal_point {
tok = FLOAT;
pos--; // '.' is one byte
S.ScanMantissa(10);
goto exponent;
}
-
+
if S.ch == '0' {
// int or float
S.Next();
}
goto exit;
}
-
+
mantissa:
// decimal int or float
S.ScanMantissa(10);
-
+
if S.ch == '.' {
// float
tok = FLOAT;
S.Next();
S.ScanMantissa(10)
}
-
+
exponent:
if S.ch == 'e' || S.ch == 'E' {
// float
}
S.ScanMantissa(10);
}
-
+
exit:
return tok, S.src[pos : S.chpos];
}
func (S *Scanner) ScanEscape() string {
// TODO: fix this routine
-
+
ch := S.ch;
pos := S.chpos;
S.Next();
switch (ch) {
case 'a', 'b', 'f', 'n', 'r', 't', 'v', '\\', '\'', '"':
return string(ch);
-
+
case '0', '1', '2', '3', '4', '5', '6', '7':
S.ScanDigits(3 - 1, 8); // 1 char already read
return ""; // TODO fix this
-
+
case 'x':
S.ScanDigits(2, 16);
return ""; // TODO fix this
-
+
case 'u':
S.ScanDigits(4, 16);
return ""; // TODO fix this
S.ScanEscape();
}
}
-
+
S.Next();
return S.src[pos : S.chpos];
}
func (S *Scanner) Scan() (tok, pos int, val string) {
S.SkipWhitespace();
-
+
ch := S.ch;
tok = ILLEGAL;
pos = S.chpos;
-
+
switch {
case is_letter(ch): tok, val = S.ScanIdentifier();
case digit_val(ch) < 10: tok, val = S.ScanNumber(false);
tok = ILLEGAL;
}
}
-
+
return tok, pos, val;
}
}
-func (S *Scanner) Server(c *chan *Token) {
+func (S *Scanner) Server(c chan *Token) {
for {
- t := new(Token);
+ t := new(*Token);
t.tok, t.pos, t.val = S.Scan();
c <- t;
if t.tok == EOF {
func Scan1(filename, src string) {
- S := new(Scanner.Scanner);
+ S := new(*Scanner.Scanner);
S.Open(filename, src);
for {
tok, pos, val := S.Scan();
func Scan2(filename, src string) {
- S := new(Scanner.Scanner);
+ S := new(*Scanner.Scanner);
S.Open(filename, src);
c := new(chan *Scanner.Token, 32);
go S.Server(c);
type Verifier struct {
comp *Globals.Compilation;
-
+
// various sets for marking the graph (and thus avoid cycles)
- objs *map[*Globals.Object] bool;
- typs *map[*Globals.Type] bool;
- pkgs *map[*Globals.Package] bool;
+ objs map[*Globals.Object] bool;
+ typs map[*Globals.Type] bool;
+ pkgs map[*Globals.Package] bool;
}
return; // already verified
}
V.typs[typ] = true;
-
+
if typ.obj != nil {
V.VerifyObject(typ.obj, 0);
}
-
+
switch typ.form {
case Type.VOID:
break; // TODO for now - remove eventually
return; // already verified
}
V.objs[obj] = true;
-
+
// all objects have a non-nil type
V.VerifyType(obj.typ);
-
+
switch obj.kind {
case Object.CONST:
break;
return; // already verified
}
V.pkgs[pkg] = true;
-
+
V.VerifyObject(pkg.obj, pno);
V.VerifyScope(pkg.scope);
}
export func Verify(comp *Globals.Compilation) {
- V := new(Verifier);
+ V := new(*Verifier);
V.Verify(comp);
}
if x != nil && x.tok == Scanner.TYPE || y != nil && y.tok == Scanner.TYPE {
panic("no type expression allowed");
}
- e := new(Expr);
+ e := new(*Expr);
e.pos, e.tok, e.x, e.y = pos, tok, x, y;
return e;
}
export func NewLit(pos, tok int, s string) *Expr {
- e := new(Expr);
+ e := new(*Expr);
e.pos, e.tok, e.s = pos, tok, s;
return e;
}
export func NewType(pos, tok int) *Type {
- t := new(Type);
+ t := new(*Type);
t.pos, t.tok = pos, tok;
return t;
}
// requires complete Type type
export func NewTypeExpr(t *Type) *Expr {
- e := new(Expr);
+ e := new(*Expr);
e.pos, e.tok, e.t = t.pos, Scanner.TYPE, t;
return e;
}
export func NewStat(pos, tok int) *Stat {
- s := new(Stat);
+ s := new(*Stat);
s.pos, s.tok = pos, tok;
return s;
}
export func NewDecl(pos, tok int, exported bool) *Decl {
- d := new(Decl);
+ d := new(*Decl);
d.pos, d.tok, d.exported = pos, tok, exported;
return d;
}
export func NewComment(pos int, text string) *Comment {
- c := new(Comment);
+ c := new(*Comment);
c.pos, c.text = pos, text;
return c;
}
export func NewProgram(pos int) *Program {
- p := new(Program);
+ p := new(*Program);
p.pos = pos;
return p;
}
func (h *ErrorHandler) LineCol(pos int) (line, col int) {
line = 1;
lpos := 0;
-
+
src := h.src;
if pos > len(src) {
pos = len(src);
lpos = i;
}
}
-
+
return line, pos - lpos;
}
}
}
print(" ", msg, "\n");
-
+
h.nerrors++;
h.errpos = pos;
if delta < 0 {
delta = -delta;
}
-
+
if delta > errdist || h.nerrors == 0 /* always report first error */ {
h.ErrorMsg(pos, msg);
- }
+ }
}
print("cannot open ", src_file, "\n");
return nil, 1;
}
-
+
var err ErrorHandler;
err.Init(src_file, src, flags.columns);
var scanner Scanner.Scanner;
scanner.Init(&err, src, true, flags.testmode);
- var tstream *<-chan *Scanner.Token;
+ var tstream <-chan *Scanner.Token;
if flags.tokenchan {
tstream = scanner.TokenStream();
}
parser.Open(flags.verbose, flags.sixg, flags.deps, &scanner, tstream);
prog := parser.ParseProgram();
-
+
if err.nerrors == 0 {
TypeChecker.CheckProgram(prog);
}
-
+
return prog, err.nerrors;
}
}
-func AddDeps(globalset *map [string] bool, wset *array.Array, src_file string, flags *Flags) {
+func AddDeps(globalset map [string] bool, wset *array.Array, src_file string, flags *Flags) {
dummy, found := globalset[src_file];
if !found {
globalset[src_file] = true;
-
+
prog, nerrors := Compile(src_file, flags);
if nerrors > 0 {
return;
}
-
+
nimports := prog.decls.Len();
if nimports > 0 {
print(src_file, ".6:\t");
-
+
localset := new(map [string] bool);
for i := 0; i < nimports; i++ {
decl := prog.decls.At(i).(*AST.Decl);
assert(decl.tok == Scanner.IMPORT && decl.val.tok == Scanner.STRING);
src := decl.val.s;
src = src[1 : len(src) - 1]; // strip "'s
-
+
// ignore files when they are seen a 2nd time
dummy, found := localset[src];
if !found {
} else if
FileExists(Platform.GOROOT + "/pkg/" + src + ".6") ||
FileExists(Platform.GOROOT + "/pkg/" + src + ".a") {
-
+
} else {
// TODO should collect these and print later
//print("missing file: ", src, "\n");
export type Scope struct {
parent *Scope;
- entries *map[string] *Object;
+ entries map[string] *Object;
}
export type OldCompilation struct {
// environment
env *Environment;
-
+
// TODO rethink the need for this here
src_file string;
src string;
-
+
// Error handling
nerrors int; // number of errors reported
errpos int; // last error position
-
+
// TODO use open arrays eventually
pkg_list [256] *Package; // pkg_list[0] is the current package
pkg_ref int;
export var Universe_void_typ *Type // initialized by Universe to Universe.void_typ
export func NewObject(pos, kind int, ident string) *Object {
- obj := new(Object);
+ obj := new(*Object);
obj.exported = false;
obj.pos = pos;
obj.kind = kind;
export func NewType(form int) *Type {
- typ := new(Type);
+ typ := new(*Type);
typ.ref = -1; // not yet exported
typ.form = form;
return typ;
export func NewPackage(file_name string, obj *Object, scope *Scope) *Package {
- pkg := new(Package);
+ pkg := new(*Package);
pkg.ref = -1; // not yet exported
pkg.file_name = file_name;
pkg.key = "<the package key>"; // empty key means package forward declaration
export func NewScope(parent *Scope) *Scope {
- scope := new(Scope);
+ scope := new(*Scope);
scope.parent = parent;
scope.entries = new(map[string]*Object, 8);
return scope;
// Object methods
func (obj *Object) Copy() *Object {
- copy := new(Object);
+ copy := new(*Object);
copy.exported = obj.exported;
copy.pos = obj.pos;
copy.kind = obj.kind;
// Tracing/debugging
verbose, sixg, deps bool;
indent uint;
-
+
// Scanner
scanner *Scanner.Scanner;
- tokchan *<-chan *Scanner.Token;
+ tokchan <-chan *Scanner.Token;
comments *array.Array;
-
+
// Scanner.Token
pos int; // token source position
tok int; // one token look-ahead
val string; // token value (for IDENT, NUMBER, STRING only)
-
+
// Non-syntactic parser control
opt_semi bool; // true if semicolon is optional
P.tok, P.pos, P.val = t.tok, t.pos, t.val;
}
P.opt_semi = false;
-
+
if P.verbose {
P.PrintIndent();
print("[", P.pos, "] ", Scanner.TokenString(P.tok), "\n");
}
-func (P *Parser) Open(verbose, sixg, deps bool, scanner *Scanner.Scanner, tokchan *<-chan *Scanner.Token) {
+func (P *Parser) Open(verbose, sixg, deps bool, scanner *Scanner.Scanner, tokchan <-chan *Scanner.Token) {
P.verbose = verbose;
P.sixg = sixg;
P.deps = deps;
P.indent = 0;
-
+
P.scanner = scanner;
P.tokchan = tokchan;
P.comments = array.New(0);
-
+
P.Next();
P.expr_lev = 0;
P.scope_lev = 0;
} else {
P.Expect(Scanner.IDENT); // use Expect() error handling
}
-
+
P.Ecart();
return x;
}
func (P *Parser) ParseType() *AST.Type {
P.Trace("Type");
-
+
t := P.TryType();
if t == nil {
P.Error(P.pos, "type expected");
t = AST.BadType;
}
-
+
P.Ecart();
return t;
}
func (P *Parser) ParseVarType() *AST.Type {
P.Trace("VarType");
-
+
typ := P.ParseType();
-
+
P.Ecart();
return typ;
}
y := P.ParseIdent();
x = P.NewExpr(pos, Scanner.PERIOD, x, y);
}
-
+
P.Ecart();
return x;
}
func (P *Parser) ParseTypeName() *AST.Type {
P.Trace("TypeName");
-
+
t := AST.NewType(P.pos, P.tok);
t.expr = P.ParseQualifiedIdent();
func (P *Parser) ParseArrayType() *AST.Type {
P.Trace("ArrayType");
-
+
t := AST.NewType(P.pos, Scanner.LBRACK);
P.Expect(Scanner.LBRACK);
if P.tok != Scanner.RBRACK {
func (P *Parser) ParseChannelType() *AST.Type {
P.Trace("ChannelType");
-
+
t := AST.NewType(P.pos, Scanner.CHAN);
t.mode = AST.FULL;
if P.tok == Scanner.CHAN {
typ = AST.NewType(P.pos, Scanner.ELLIPSIS);
P.Next();
}
-
+
if ellipsis_ok /* param list */ && i0 > 0 && typ == nil {
// not the first parameter section; we must have a type
P.Error(P.pos, "type expected");
typ = AST.BadType;
}
-
+
// convert the list into a list of (type) expressions
if typ != nil {
// all list entries must be identifiers
list.Set(i, AST.NewTypeExpr(t));
}
}
-
+
P.Ecart();
}
func (P *Parser) ParseParameterList(ellipsis_ok bool) *array.Array {
P.Trace("ParameterList");
-
+
list := array.New(0);
P.ParseVarDeclList(list, ellipsis_ok);
for P.tok == Scanner.COMMA {
P.Next();
P.ParseVarDeclList(list, ellipsis_ok);
}
-
+
P.Ecart();
return list;
}
func (P *Parser) ParseParameters(ellipsis_ok bool) *AST.Type {
P.Trace("Parameters");
-
+
t := AST.NewType(P.pos, Scanner.STRUCT);
P.Expect(Scanner.LPAREN);
if P.tok != Scanner.RPAREN {
}
t.end = P.pos;
P.Expect(Scanner.RPAREN);
-
+
P.Ecart();
return t;
}
func (P *Parser) ParseResult() *AST.Type {
P.Trace("Result");
-
+
var t *AST.Type;
if P.tok == Scanner.LPAREN {
t = P.ParseParameters(false);
func (P *Parser) ParseFunctionType() *AST.Type {
P.Trace("FunctionType");
-
+
t := AST.NewType(P.pos, Scanner.LPAREN);
t.list = P.ParseParameters(true).list; // TODO find better solution
t.end = P.pos;
t.elt = P.ParseResult();
-
+
P.Ecart();
return t;
}
func (P *Parser) ParseMethodSpec(list *array.Array) {
P.Trace("MethodDecl");
-
+
list.Push(P.ParseIdentList());
t := AST.BadType;
if P.sixg {
t = P.ParseFunctionType();
}
list.Push(AST.NewTypeExpr(t));
-
+
P.Ecart();
}
func (P *Parser) ParseInterfaceType() *AST.Type {
P.Trace("InterfaceType");
-
+
t := AST.NewType(P.pos, Scanner.INTERFACE);
P.Expect(Scanner.INTERFACE);
if P.tok == Scanner.LBRACE {
func (P *Parser) ParseMapType() *AST.Type {
P.Trace("MapType");
-
+
t := AST.NewType(P.pos, Scanner.MAP);
P.Expect(Scanner.MAP);
P.Expect(Scanner.LBRACK);
t.key = P.ParseVarType();
P.Expect(Scanner.RBRACK);
t.elt = P.ParseVarType();
-
+
P.Ecart();
return t;
}
func (P *Parser) ParsePointerType() *AST.Type {
P.Trace("PointerType");
-
+
t := AST.NewType(P.pos, Scanner.MUL);
P.Expect(Scanner.MUL);
t.elt = P.ParseType();
-
+
P.Ecart();
return t;
}
func (P *Parser) TryType() *AST.Type {
P.Trace("Type (try)");
-
+
t := AST.BadType;
switch P.tok {
case Scanner.IDENT: t = P.ParseTypeName();
func (P *Parser) ParseStatementList() *array.Array {
P.Trace("StatementList");
-
+
list := array.New(0);
for P.tok != Scanner.CASE && P.tok != Scanner.DEFAULT && P.tok != Scanner.RBRACE && P.tok != Scanner.EOF {
s := P.ParseStatement();
break;
}
}
-
+
// Try to provide a good error message
if P.tok != Scanner.CASE && P.tok != Scanner.DEFAULT && P.tok != Scanner.RBRACE && P.tok != Scanner.EOF {
P.Error(P.pos, "expected end of statement list (semicolon missing?)");
func (P *Parser) ParseBlock() (slist *array.Array, end int) {
P.Trace("Block");
-
+
P.Expect(Scanner.LBRACE);
slist = P.ParseStatementList();
end = P.pos;
P.Expect(Scanner.RBRACE);
P.opt_semi = true;
-
+
P.Ecart();
return slist, end;
}
func (P *Parser) ParseFunctionLit() *AST.Expr {
P.Trace("FunctionLit");
-
+
x := AST.NewLit(P.pos, Scanner.FUNC, "");
P.Expect(Scanner.FUNC);
x.t = P.ParseFunctionType();
x.block, x.end = P.ParseBlock();
P.scope_lev--;
P.expr_lev--;
-
+
P.Ecart();
return x;
}
/*
func (P *Parser) ParseNewCall() *AST.Expr {
P.Trace("NewCall");
-
+
x := AST.NewExpr(P.pos, Scanner.NEW, nil, nil);
P.Next();
P.Expect(Scanner.LPAREN);
}
P.expr_lev--;
P.Expect(Scanner.RPAREN);
-
+
P.Ecart();
return x;
}
switch P.tok {
case Scanner.IDENT:
x = P.ParseIdent();
-
+
case Scanner.LPAREN:
- // TODO we could have a function type here as in: new(*())
+ // TODO we could have a function type here as in: new(**())
// (currently not working)
P.Next();
P.expr_lev++;
x = P.NewExpr(P.pos, Scanner.PERIOD, x, nil);
P.Expect(Scanner.PERIOD);
-
+
if P.tok == Scanner.IDENT {
x.y = P.ParseIdent();
-
+
} else {
P.Expect(Scanner.LPAREN);
x.t = P.ParseType();
P.Expect(Scanner.RPAREN);
}
-
+
P.Ecart();
return x;
}
func (P *Parser) ParseIndex(x *AST.Expr) *AST.Expr {
P.Trace("IndexOrSlice");
-
+
pos := P.pos;
P.Expect(Scanner.LBRACK);
P.expr_lev++;
i := P.ParseExpression(0);
P.expr_lev--;
P.Expect(Scanner.RBRACK);
-
+
P.Ecart();
return P.NewExpr(pos, Scanner.LBRACK, x, i);
}
P.expr_lev++;
var t *AST.Type;
if x0.tok == Scanner.IDENT && x0.s == "new" {
- // heuristic: assume it's a new(T, ...) call, try to parse a type
+ // heuristic: assume it's a new(*T, ...) call, try to parse a type
t = P.TryType();
}
if t != nil {
P.expr_lev--;
}
P.Expect(Scanner.RPAREN);
-
+
P.Ecart();
return x;
}
if P.tok == Scanner.COMMA {
pos := P.pos;
P.Next();
-
+
// first element determines mode
singles := true;
if x.tok == Scanner.COLON {
singles = false;
}
-
+
for first := true; P.tok != Scanner.RBRACE && P.tok != Scanner.EOF; {
y := P.ParseExpression(0);
P.Error(y.pos, "key:value pair expected; found single value");
}
}
-
+
if first {
x = P.NewExpr(pos, Scanner.COMMA, x, y);
} else {
x.y = P.NewExpr(pos, Scanner.COMMA, x.y, y);
}
-
+
if P.tok == Scanner.COMMA {
pos = P.pos;
P.Next();
func (P *Parser) ParseCompositeLit(t *AST.Type) *AST.Expr {
P.Trace("CompositeLit");
-
+
x := P.NewExpr(P.pos, Scanner.LBRACE, nil, nil);
x.t = t;
P.Expect(Scanner.LBRACE);
x.y = P.ParseCompositeElements();
}
P.Expect(Scanner.RBRACE);
-
+
P.Ecart();
return x;
}
func (P *Parser) ParsePrimaryExpr() *AST.Expr {
P.Trace("PrimaryExpr");
-
+
x := P.ParseOperand();
for {
switch P.tok {
default: goto exit;
}
}
-
+
exit:
P.Ecart();
return x;
func (P *Parser) ParseUnaryExpr() *AST.Expr {
P.Trace("UnaryExpr");
-
+
x := AST.BadExpr;
switch P.tok {
case Scanner.ADD, Scanner.SUB, Scanner.MUL, Scanner.NOT, Scanner.XOR, Scanner.ARROW, Scanner.AND:
} else {
x = P.NewExpr(pos, tok, nil, y);
}
-
+
default:
x = P.ParsePrimaryExpr();
}
-
+
P.Ecart();
return x;
}
func (P *Parser) ParseBinaryExpr(prec1 int) *AST.Expr {
P.Trace("BinaryExpr");
-
+
x := P.ParseUnaryExpr();
for prec := Scanner.Precedence(P.tok); prec >= prec1; prec-- {
for Scanner.Precedence(P.tok) == prec {
x = P.NewExpr(pos, tok, x, y);
}
}
-
+
P.Ecart();
return x;
}
func (P *Parser) ParseSimpleStat(range_ok bool) *AST.Stat {
P.Trace("SimpleStat");
-
+
s := AST.BadStat;
x := P.ParseExpressionList();
-
+
is_range := false;
if range_ok && P.tok == Scanner.COLON {
pos := P.pos;
P.Error(pos, "expected initialization, found ':'");
}
}
-
+
switch P.tok {
case Scanner.COLON:
// label declaration
P.Error(x.pos, "only one expression allowed");
}
}
-
+
P.Ecart();
return s;
}
func (P *Parser) ParseGoStat() *AST.Stat {
P.Trace("GoStat");
-
+
s := AST.NewStat(P.pos, Scanner.GO);
P.Expect(Scanner.GO);
s.expr = P.ParseExpression(1);
-
+
P.Ecart();
return s;
}
func (P *Parser) ParseReturnStat() *AST.Stat {
P.Trace("ReturnStat");
-
+
s := AST.NewStat(P.pos, Scanner.RETURN);
P.Expect(Scanner.RETURN);
if P.tok != Scanner.SEMICOLON && P.tok != Scanner.RBRACE {
s.expr = P.ParseExpressionList();
}
-
+
P.Ecart();
return s;
}
func (P *Parser) ParseControlFlowStat(tok int) *AST.Stat {
P.Trace("ControlFlowStat");
-
+
s := AST.NewStat(P.pos, tok);
P.Expect(tok);
if tok != Scanner.FALLTHROUGH && P.tok == Scanner.IDENT {
s.expr = P.ParseIdent();
}
-
+
P.Ecart();
return s;
}
func (P *Parser) ParseControlClause(keyword int) *AST.Stat {
P.Trace("ControlClause");
-
+
s := AST.NewStat(P.pos, keyword);
P.Expect(keyword);
if P.tok != Scanner.LBRACE {
}
s.post = s1;
}
-
+
P.Ecart();
return s;
}
func (P *Parser) ParseForStat() *AST.Stat {
P.Trace("ForStat");
-
+
s := P.ParseControlClause(Scanner.FOR);
s.block, s.end = P.ParseBlock();
-
+
P.Ecart();
return s;
}
func (P *Parser) ParseCase() *AST.Stat {
P.Trace("Case");
-
+
s := AST.NewStat(P.pos, P.tok);
if P.tok == Scanner.CASE {
P.Next();
P.Expect(Scanner.DEFAULT);
}
P.Expect(Scanner.COLON);
-
+
P.Ecart();
return s;
}
if P.tok != Scanner.CASE && P.tok != Scanner.DEFAULT && P.tok != Scanner.RBRACE {
s.block = P.ParseStatementList();
}
-
+
P.Ecart();
return s;
}
func (P *Parser) ParseSwitchStat() *AST.Stat {
P.Trace("SwitchStat");
-
+
s := P.ParseControlClause(Scanner.SWITCH);
s.block = array.New(0);
P.Expect(Scanner.LBRACE);
func (P *Parser) ParseCommClause() *AST.Stat {
P.Trace("CommClause");
-
+
s := P.ParseCommCase();
if P.tok != Scanner.CASE && P.tok != Scanner.DEFAULT && P.tok != Scanner.RBRACE {
s.block = P.ParseStatementList();
}
-
+
P.Ecart();
return s;
}
func (P *Parser) ParseSelectStat() *AST.Stat {
P.Trace("SelectStat");
-
+
s := AST.NewStat(P.pos, Scanner.SELECT);
s.block = array.New(0);
P.Expect(Scanner.SELECT);
}
P.Expect(Scanner.RBRACE);
P.opt_semi = true;
-
+
P.Ecart();
return s;
}
func (P *Parser) ParseRangeStat() *AST.Stat {
P.Trace("RangeStat");
-
+
s := AST.NewStat(P.pos, Scanner.RANGE);
P.Expect(Scanner.RANGE);
P.ParseIdentList();
P.Expect(Scanner.DEFINE);
s.expr = P.ParseExpression(1);
s.block, s.end = P.ParseBlock();
-
+
P.Ecart();
return s;
}
func (P *Parser) ParseImportSpec(pos int) *AST.Decl {
P.Trace("ImportSpec");
-
+
d := AST.NewDecl(pos, Scanner.IMPORT, false);
if P.tok == Scanner.PERIOD {
P.Error(P.pos, `"import ." not yet handled properly`);
} else if P.tok == Scanner.IDENT {
d.ident = P.ParseIdent();
}
-
+
if P.tok == Scanner.STRING {
// TODO eventually the scanner should strip the quotes
d.val = AST.NewLit(P.pos, Scanner.STRING, P.val);
} else {
P.Expect(Scanner.STRING); // use Expect() error handling
}
-
+
P.Ecart();
return d;
}
func (P *Parser) ParseConstSpec(exported bool, pos int) *AST.Decl {
P.Trace("ConstSpec");
-
+
d := AST.NewDecl(pos, Scanner.CONST, exported);
d.ident = P.ParseIdentList();
d.typ = P.TryType();
P.Next();
d.val = P.ParseExpressionList();
}
-
+
P.Ecart();
return d;
}
d.ident = P.ParseIdent();
d.typ = P.ParseType();
P.opt_semi = true;
-
+
P.Ecart();
return d;
}
func (P *Parser) ParseVarSpec(exported bool, pos int) *AST.Decl {
P.Trace("VarSpec");
-
+
d := AST.NewDecl(pos, Scanner.VAR, exported);
d.ident = P.ParseIdentList();
if P.tok == Scanner.ASSIGN {
d.val = P.ParseExpressionList();
}
}
-
+
P.Ecart();
return d;
}
func (P *Parser) ParseDecl(exported bool, keyword int) *AST.Decl {
P.Trace("Decl");
-
+
d := AST.BadDecl;
pos := P.pos;
P.Expect(keyword);
d.end = P.pos;
P.Expect(Scanner.RPAREN);
P.opt_semi = true;
-
+
} else {
d = P.ParseSpec(exported, pos, keyword);
}
-
+
P.Ecart();
return d;
}
func (P *Parser) ParseFunctionDecl(exported bool) *AST.Decl {
P.Trace("FunctionDecl");
-
+
d := AST.NewDecl(P.pos, Scanner.FUNC, exported);
P.Expect(Scanner.FUNC);
-
+
var recv *AST.Type;
if P.tok == Scanner.LPAREN {
pos := P.pos;
P.Error(pos, "must have exactly one receiver");
}
}
-
+
d.ident = P.ParseIdent();
d.typ = P.ParseFunctionType();
d.typ.key = recv;
d.list, d.end = P.ParseBlock();
P.scope_lev--;
}
-
+
P.Ecart();
return d;
}
func (P *Parser) ParseExportDecl() *AST.Decl {
P.Trace("ExportDecl");
-
+
d := AST.NewDecl(P.pos, Scanner.EXPORT, false);
d.ident = P.ParseIdentList();
func (P *Parser) ParseDeclaration() *AST.Decl {
P.Trace("Declaration");
indent := P.indent;
-
+
d := AST.BadDecl;
exported := false;
// TODO don't use bool flag for export
}
P.Next();
}
-
+
switch P.tok {
case Scanner.CONST, Scanner.TYPE, Scanner.VAR:
d = P.ParseDecl(exported, P.tok);
func (P *Parser) ParseProgram() *AST.Program {
P.Trace("Program");
-
+
p := AST.NewProgram(P.pos);
P.Expect(Scanner.PACKAGE);
p.ident = P.ParseIdent();
-
+
p.decls = array.New(0);
for P.tok == Scanner.IMPORT {
p.decls.Push(P.ParseDecl(false, Scanner.IMPORT));
P.OptSemicolon();
}
-
+
if !P.deps {
for P.tok != Scanner.EOF {
p.decls.Push(P.ParseDeclaration());
P.OptSemicolon();
}
}
-
+
p.comments = P.comments;
-
+
P.Ecart();
return p;
}
MUL;
QUO;
REM;
-
+
AND;
OR;
XOR;
SHL;
SHR;
-
+
ADD_ASSIGN;
SUB_ASSIGN;
MUL_ASSIGN;
ARROW;
INC;
DEC;
-
+
EQL;
NEQ;
LSS;
DEFINE;
NOT;
ELLIPSIS;
-
+
LPAREN;
RPAREN;
LBRACK;
RBRACK;
LBRACE;
RBRACE;
-
+
COMMA;
SEMICOLON;
COLON;
CHAN;
CONST;
CONTINUE;
-
+
DEFAULT;
ELSE;
EXPORT;
FALLTHROUGH;
FOR;
-
+
FUNC;
GO;
GOTO;
IF;
IMPORT;
-
+
INTERFACE;
MAP;
PACKAGE;
RANGE;
RETURN;
-
+
SELECT;
STRUCT;
SWITCH;
TYPE;
VAR;
KEYWORDS_END;
-
+
// AST use only
EXPRSTAT;
)
export func TokenString(tok int) string {
switch tok {
case ILLEGAL: return "ILLEGAL";
-
+
case IDENT: return "IDENT";
case INT: return "INT";
case FLOAT: return "FLOAT";
case MUL: return "*";
case QUO: return "/";
case REM: return "%";
-
+
case AND: return "&";
case OR: return "|";
case XOR: return "^";
case SHL: return "<<";
case SHR: return ">>";
-
+
case ADD_ASSIGN: return "+=";
case SUB_ASSIGN: return "-=";
case MUL_ASSIGN: return "+=";
case SWITCH: return "switch";
case TYPE: return "type";
case VAR: return "var";
-
+
case EXPRSTAT: return "EXPRSTAT";
}
-
+
return "token(" + Utils.IntToString(tok, 10) + ")";
}
}
-var Keywords *map [string] int;
+var Keywords map [string] int;
func init() {
S.testpos = -1;
return;
}
-
+
S.err.Error(pos, msg);
}
func (S *Scanner) ScanComment() string {
// first '/' already consumed
pos := S.chpos - 1;
-
+
if S.ch == '/' {
//-style comment
S.Next();
goto exit;
}
}
-
+
} else {
/*-style comment */
S.Expect('*');
}
}
}
-
+
S.Error(pos, "comment not terminated");
exit:
oldpos = S.testpos;
S.ExpectNoErrors();
}
-
+
if 0 <= oldpos && oldpos <= len(S.src) {
// the previous error was not found
S.Error(oldpos, "ERROR not found"); // TODO this should call ErrorMsg
S.Next();
}
val = S.src[pos : S.chpos];
-
+
var present bool;
tok, present = Keywords[val];
if !present {
tok = IDENT;
}
-
+
return tok, val;
}
func (S *Scanner) ScanNumber(seen_decimal_point bool) (tok int, val string) {
pos := S.chpos;
tok = INT;
-
+
if seen_decimal_point {
tok = FLOAT;
pos--; // '.' is one byte
S.ScanMantissa(10);
goto exponent;
}
-
+
if S.ch == '0' {
// int or float
S.Next();
}
goto exit;
}
-
+
mantissa:
// decimal int or float
S.ScanMantissa(10);
-
+
if S.ch == '.' {
// float
tok = FLOAT;
S.Next();
S.ScanMantissa(10)
}
-
+
exponent:
if S.ch == 'e' || S.ch == 'E' {
// float
}
S.ScanMantissa(10);
}
-
+
exit:
return tok, S.src[pos : S.chpos];
}
func (S *Scanner) ScanEscape(quote int) string {
// TODO: fix this routine
-
+
ch := S.ch;
pos := S.chpos;
S.Next();
switch ch {
case 'a', 'b', 'f', 'n', 'r', 't', 'v', '\\':
return string(ch);
-
+
case '0', '1', '2', '3', '4', '5', '6', '7':
S.ScanDigits(3 - 1, 8); // 1 char already read
return ""; // TODO fix this
-
+
case 'x':
S.ScanDigits(2, 16);
return ""; // TODO fix this
-
+
case 'u':
S.ScanDigits(4, 16);
return ""; // TODO fix this
}
S.Error(pos, "illegal char escape");
}
-
+
return ""; // TODO fix this
}
S.ScanEscape('"');
}
}
-
+
S.Next();
return S.src[pos : S.chpos];
}
func (S *Scanner) Scan() (pos, tok int, val string) {
L: S.SkipWhitespace();
-
+
pos, tok = S.chpos, ILLEGAL;
-
+
switch ch := S.ch; {
case is_letter(ch): tok, val = S.ScanIdentifier();
case digit_val(ch) < 10: tok, val = S.ScanNumber(false);
tok = ILLEGAL;
}
}
-
+
return pos, tok, val;
}
}
-func (S *Scanner) TokenStream() *<-chan *Token {
+func (S *Scanner) TokenStream() <-chan *Token {
ch := new(chan *Token, 100);
- go func(S *Scanner, ch *chan <- *Token) {
+ go func(S *Scanner, ch chan <- *Token) {
for {
- t := new(Token);
+ t := new(*Token);
t.pos, t.tok, t.val = S.Scan();
ch <- t;
if t.tok == EOF {
}
-func f3(a *[]int, m *map[string] int) {
+func f3(a *[]int, m map[string] int) {
println("A1");
for i := range a {
println(i);