mirror of
https://github.com/golang/go
synced 2024-11-26 01:37:58 -07:00
- renamed scanner.Location to token.Position
- by moving Position into token, scanner dependencies are removed from several files - clearer field names in token.Position, now possible to have a Pos() accessor w/o naming conflicts - added Pos() accessor - use anonymous token.Position field in AST nodes R=r DELTA=244 (28 added, 55 deleted, 161 changed) OCL=26786 CL=26793
This commit is contained in:
parent
b923b01665
commit
5a72ca45fb
@ -16,28 +16,20 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
// Source locations are represented by a Location value.
|
|
||||||
type Location struct {
|
|
||||||
Pos int; // byte position in source
|
|
||||||
Line int; // line count, starting at 1
|
|
||||||
Col int; // column, starting at 1 (character count)
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// An implementation of an ErrorHandler must be provided to the Scanner.
|
// An implementation of an ErrorHandler must be provided to the Scanner.
|
||||||
// If a syntax error is encountered, Error is called with a location and
|
// If a syntax error is encountered, Error is called with a position and
|
||||||
// an error message. The location points at the beginning of the offending
|
// an error message. The position points to the beginning of the offending
|
||||||
// token.
|
// token.
|
||||||
//
|
//
|
||||||
type ErrorHandler interface {
|
type ErrorHandler interface {
|
||||||
Error(loc Location, msg string);
|
Error(pos token.Position, msg string);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// A Scanner holds the scanner's internal state while processing
|
// A Scanner holds the scanner's internal state while processing
|
||||||
// a given text. It can be allocated as part of another data
|
// a given text. It can be allocated as part of another data
|
||||||
// structure but must be initialized via Init before use.
|
// structure but must be initialized via Init before use. For
|
||||||
// See also the package comment for a sample use.
|
// a sample use, see the implementation of Tokenize.
|
||||||
//
|
//
|
||||||
type Scanner struct {
|
type Scanner struct {
|
||||||
// immutable state
|
// immutable state
|
||||||
@ -46,31 +38,32 @@ type Scanner struct {
|
|||||||
scan_comments bool; // if set, comments are reported as tokens
|
scan_comments bool; // if set, comments are reported as tokens
|
||||||
|
|
||||||
// scanning state
|
// scanning state
|
||||||
loc Location; // location before ch (src[loc.Pos] == ch)
|
pos token.Position; // previous reading position (position before ch)
|
||||||
pos int; // current reading position (position after ch)
|
offset int; // current reading offset (position after ch)
|
||||||
ch int; // one char look-ahead
|
ch int; // one char look-ahead
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Read the next Unicode char into S.ch.
|
// Read the next Unicode char into S.ch.
|
||||||
// S.ch < 0 means end-of-file.
|
// S.ch < 0 means end-of-file.
|
||||||
|
//
|
||||||
func (S *Scanner) next() {
|
func (S *Scanner) next() {
|
||||||
if S.pos < len(S.src) {
|
if S.offset < len(S.src) {
|
||||||
S.loc.Pos = S.pos;
|
S.pos.Offset = S.offset;
|
||||||
S.loc.Col++;
|
S.pos.Column++;
|
||||||
r, w := int(S.src[S.pos]), 1;
|
r, w := int(S.src[S.offset]), 1;
|
||||||
switch {
|
switch {
|
||||||
case r == '\n':
|
case r == '\n':
|
||||||
S.loc.Line++;
|
S.pos.Line++;
|
||||||
S.loc.Col = 0;
|
S.pos.Column = 0;
|
||||||
case r >= 0x80:
|
case r >= 0x80:
|
||||||
// not ASCII
|
// not ASCII
|
||||||
r, w = utf8.DecodeRune(S.src[S.pos : len(S.src)]);
|
r, w = utf8.DecodeRune(S.src[S.offset : len(S.src)]);
|
||||||
}
|
}
|
||||||
S.pos += w;
|
S.offset += w;
|
||||||
S.ch = r;
|
S.ch = r;
|
||||||
} else {
|
} else {
|
||||||
S.loc.Pos = len(S.src);
|
S.pos.Offset = len(S.src);
|
||||||
S.ch = -1; // eof
|
S.ch = -1; // eof
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -86,13 +79,13 @@ func (S *Scanner) Init(src []byte, err ErrorHandler, scan_comments bool) {
|
|||||||
S.src = src;
|
S.src = src;
|
||||||
S.err = err;
|
S.err = err;
|
||||||
S.scan_comments = scan_comments;
|
S.scan_comments = scan_comments;
|
||||||
S.loc.Line = 1;
|
S.pos.Line = 1;
|
||||||
S.next();
|
S.next();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
func charString(ch int) string {
|
func charString(ch int) string {
|
||||||
s := string(ch);
|
var s string;
|
||||||
switch ch {
|
switch ch {
|
||||||
case '\a': s = `\a`;
|
case '\a': s = `\a`;
|
||||||
case '\b': s = `\b`;
|
case '\b': s = `\b`;
|
||||||
@ -103,25 +96,26 @@ func charString(ch int) string {
|
|||||||
case '\v': s = `\v`;
|
case '\v': s = `\v`;
|
||||||
case '\\': s = `\\`;
|
case '\\': s = `\\`;
|
||||||
case '\'': s = `\'`;
|
case '\'': s = `\'`;
|
||||||
|
default : s = utf8.EncodeRuneToString(ch);
|
||||||
}
|
}
|
||||||
return "'" + s + "' (U+" + strconv.Itob(ch, 16) + ")";
|
return "'" + s + "' (U+" + strconv.Itob(ch, 16) + ")";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
func (S *Scanner) error(loc Location, msg string) {
|
func (S *Scanner) error(pos token.Position, msg string) {
|
||||||
S.err.Error(loc, msg);
|
S.err.Error(pos, msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
func (S *Scanner) expect(ch int) {
|
func (S *Scanner) expect(ch int) {
|
||||||
if S.ch != ch {
|
if S.ch != ch {
|
||||||
S.error(S.loc, "expected " + charString(ch) + ", found " + charString(S.ch));
|
S.error(S.pos, "expected " + charString(ch) + ", found " + charString(S.ch));
|
||||||
}
|
}
|
||||||
S.next(); // always make progress
|
S.next(); // always make progress
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
func (S *Scanner) scanComment(loc Location) {
|
func (S *Scanner) scanComment(pos token.Position) {
|
||||||
// first '/' already consumed
|
// first '/' already consumed
|
||||||
|
|
||||||
if S.ch == '/' {
|
if S.ch == '/' {
|
||||||
@ -147,7 +141,7 @@ func (S *Scanner) scanComment(loc Location) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
S.error(loc, "comment not terminated");
|
S.error(pos, "comment not terminated");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -168,11 +162,11 @@ func isDigit(ch int) bool {
|
|||||||
|
|
||||||
|
|
||||||
func (S *Scanner) scanIdentifier() token.Token {
|
func (S *Scanner) scanIdentifier() token.Token {
|
||||||
pos := S.loc.Pos;
|
pos := S.pos.Offset;
|
||||||
for isLetter(S.ch) || isDigit(S.ch) {
|
for isLetter(S.ch) || isDigit(S.ch) {
|
||||||
S.next();
|
S.next();
|
||||||
}
|
}
|
||||||
return token.Lookup(S.src[pos : S.loc.Pos]);
|
return token.Lookup(S.src[pos : S.pos.Offset]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -255,13 +249,13 @@ func (S *Scanner) scanDigits(base, length int) {
|
|||||||
length--;
|
length--;
|
||||||
}
|
}
|
||||||
if length > 0 {
|
if length > 0 {
|
||||||
S.error(S.loc, "illegal char escape");
|
S.error(S.pos, "illegal char escape");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
func (S *Scanner) scanEscape(quote int) {
|
func (S *Scanner) scanEscape(quote int) {
|
||||||
loc := S.loc;
|
pos := S.pos;
|
||||||
ch := S.ch;
|
ch := S.ch;
|
||||||
S.next();
|
S.next();
|
||||||
switch ch {
|
switch ch {
|
||||||
@ -276,7 +270,7 @@ func (S *Scanner) scanEscape(quote int) {
|
|||||||
case 'U':
|
case 'U':
|
||||||
S.scanDigits(16, 8);
|
S.scanDigits(16, 8);
|
||||||
default:
|
default:
|
||||||
S.error(loc, "illegal char escape");
|
S.error(pos, "illegal char escape");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -294,14 +288,14 @@ func (S *Scanner) scanChar() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
func (S *Scanner) scanString(loc Location) {
|
func (S *Scanner) scanString(pos token.Position) {
|
||||||
// '"' already consumed
|
// '"' already consumed
|
||||||
|
|
||||||
for S.ch != '"' {
|
for S.ch != '"' {
|
||||||
ch := S.ch;
|
ch := S.ch;
|
||||||
S.next();
|
S.next();
|
||||||
if ch == '\n' || ch < 0 {
|
if ch == '\n' || ch < 0 {
|
||||||
S.error(loc, "string not terminated");
|
S.error(pos, "string not terminated");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if ch == '\\' {
|
if ch == '\\' {
|
||||||
@ -313,14 +307,14 @@ func (S *Scanner) scanString(loc Location) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
func (S *Scanner) scanRawString(loc Location) {
|
func (S *Scanner) scanRawString(pos token.Position) {
|
||||||
// '`' already consumed
|
// '`' already consumed
|
||||||
|
|
||||||
for S.ch != '`' {
|
for S.ch != '`' {
|
||||||
ch := S.ch;
|
ch := S.ch;
|
||||||
S.next();
|
S.next();
|
||||||
if ch == '\n' || ch < 0 {
|
if ch == '\n' || ch < 0 {
|
||||||
S.error(loc, "string not terminated");
|
S.error(pos, "string not terminated");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -374,11 +368,11 @@ func (S *Scanner) switch4(tok0, tok1 token.Token, ch2 int, tok2, tok3 token.Toke
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Scan scans the next token and returns the token location loc,
|
// Scan scans the next token and returns the token position pos,
|
||||||
// the token tok, and the literal text lit corresponding to the
|
// the token tok, and the literal text lit corresponding to the
|
||||||
// token. The source end is indicated by token.EOF.
|
// token. The source end is indicated by token.EOF.
|
||||||
//
|
//
|
||||||
func (S *Scanner) Scan() (loc Location, tok token.Token, lit []byte) {
|
func (S *Scanner) Scan() (pos token.Position, tok token.Token, lit []byte) {
|
||||||
scan_again:
|
scan_again:
|
||||||
// skip white space
|
// skip white space
|
||||||
for S.ch == ' ' || S.ch == '\t' || S.ch == '\n' || S.ch == '\r' {
|
for S.ch == ' ' || S.ch == '\t' || S.ch == '\n' || S.ch == '\r' {
|
||||||
@ -386,7 +380,7 @@ scan_again:
|
|||||||
}
|
}
|
||||||
|
|
||||||
// current token start
|
// current token start
|
||||||
loc, tok = S.loc, token.ILLEGAL;
|
pos, tok = S.pos, token.ILLEGAL;
|
||||||
|
|
||||||
// determine token value
|
// determine token value
|
||||||
switch ch := S.ch; {
|
switch ch := S.ch; {
|
||||||
@ -398,9 +392,9 @@ scan_again:
|
|||||||
S.next(); // always make progress
|
S.next(); // always make progress
|
||||||
switch ch {
|
switch ch {
|
||||||
case -1 : tok = token.EOF;
|
case -1 : tok = token.EOF;
|
||||||
case '"' : tok = token.STRING; S.scanString(loc);
|
case '"' : tok = token.STRING; S.scanString(pos);
|
||||||
case '\'': tok = token.CHAR; S.scanChar();
|
case '\'': tok = token.CHAR; S.scanChar();
|
||||||
case '`' : tok = token.STRING; S.scanRawString(loc);
|
case '`' : tok = token.STRING; S.scanRawString(pos);
|
||||||
case ':' : tok = S.switch2(token.COLON, token.DEFINE);
|
case ':' : tok = S.switch2(token.COLON, token.DEFINE);
|
||||||
case '.' :
|
case '.' :
|
||||||
if digitVal(S.ch) < 10 {
|
if digitVal(S.ch) < 10 {
|
||||||
@ -427,7 +421,7 @@ scan_again:
|
|||||||
case '*': tok = S.switch2(token.MUL, token.MUL_ASSIGN);
|
case '*': tok = S.switch2(token.MUL, token.MUL_ASSIGN);
|
||||||
case '/':
|
case '/':
|
||||||
if S.ch == '/' || S.ch == '*' {
|
if S.ch == '/' || S.ch == '*' {
|
||||||
S.scanComment(loc);
|
S.scanComment(pos);
|
||||||
tok = token.COMMENT;
|
tok = token.COMMENT;
|
||||||
if !S.scan_comments {
|
if !S.scan_comments {
|
||||||
goto scan_again;
|
goto scan_again;
|
||||||
@ -455,20 +449,20 @@ scan_again:
|
|||||||
tok = S.switch3(token.AND, token.AND_ASSIGN, '&', token.LAND);
|
tok = S.switch3(token.AND, token.AND_ASSIGN, '&', token.LAND);
|
||||||
}
|
}
|
||||||
case '|': tok = S.switch3(token.OR, token.OR_ASSIGN, '|', token.LOR);
|
case '|': tok = S.switch3(token.OR, token.OR_ASSIGN, '|', token.LOR);
|
||||||
default: S.error(loc, "illegal character " + charString(ch));
|
default: S.error(pos, "illegal character " + charString(ch));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return loc, tok, S.src[loc.Pos : S.loc.Pos];
|
return pos, tok, S.src[pos.Offset : S.pos.Offset];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Tokenize calls a function f with the token location, token value, and token
|
// Tokenize calls a function f with the token position, token value, and token
|
||||||
// text for each token in the source src. The other parameters have the same
|
// text for each token in the source src. The other parameters have the same
|
||||||
// meaning as for the Init function. Tokenize keeps scanning until f returns
|
// meaning as for the Init function. Tokenize keeps scanning until f returns
|
||||||
// false (usually when the token value is token.EOF).
|
// false (usually when the token value is token.EOF).
|
||||||
//
|
//
|
||||||
func Tokenize(src []byte, err ErrorHandler, scan_comments bool, f func (loc Location, tok token.Token, lit []byte) bool) {
|
func Tokenize(src []byte, err ErrorHandler, scan_comments bool, f func (pos token.Position, tok token.Token, lit []byte) bool) {
|
||||||
var s Scanner;
|
var s Scanner;
|
||||||
s.Init(src, err, scan_comments);
|
s.Init(src, err, scan_comments);
|
||||||
for f(s.Scan()) {
|
for f(s.Scan()) {
|
||||||
|
@ -160,7 +160,7 @@ type TestErrorHandler struct {
|
|||||||
t *testing.T
|
t *testing.T
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *TestErrorHandler) Error(loc scanner.Location, msg string) {
|
func (h *TestErrorHandler) Error(pos token.Position, msg string) {
|
||||||
h.t.Errorf("Error() called (msg = %s)", msg);
|
h.t.Errorf("Error() called (msg = %s)", msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -186,9 +186,9 @@ func Test(t *testing.T) {
|
|||||||
|
|
||||||
// verify scan
|
// verify scan
|
||||||
index := 0;
|
index := 0;
|
||||||
eloc := scanner.Location{0, 1, 1};
|
eloc := token.Position{0, 1, 1};
|
||||||
scanner.Tokenize(io.StringBytes(src), &TestErrorHandler{t}, true,
|
scanner.Tokenize(io.StringBytes(src), &TestErrorHandler{t}, true,
|
||||||
func (loc Location, tok token.Token, litb []byte) bool {
|
func (pos token.Position, tok token.Token, litb []byte) bool {
|
||||||
e := elt{token.EOF, "", special};
|
e := elt{token.EOF, "", special};
|
||||||
if index < len(tokens) {
|
if index < len(tokens) {
|
||||||
e = tokens[index];
|
e = tokens[index];
|
||||||
@ -196,16 +196,16 @@ func Test(t *testing.T) {
|
|||||||
lit := string(litb);
|
lit := string(litb);
|
||||||
if tok == token.EOF {
|
if tok == token.EOF {
|
||||||
lit = "<EOF>";
|
lit = "<EOF>";
|
||||||
eloc.Col = 0;
|
eloc.Column = 0;
|
||||||
}
|
}
|
||||||
if loc.Pos != eloc.Pos {
|
if pos.Offset != eloc.Offset {
|
||||||
t.Errorf("bad position for %s: got %d, expected %d", lit, loc.Pos, eloc.Pos);
|
t.Errorf("bad position for %s: got %d, expected %d", lit, pos.Offset, eloc.Offset);
|
||||||
}
|
}
|
||||||
if loc.Line != eloc.Line {
|
if pos.Line != eloc.Line {
|
||||||
t.Errorf("bad line for %s: got %d, expected %d", lit, loc.Line, eloc.Line);
|
t.Errorf("bad line for %s: got %d, expected %d", lit, pos.Line, eloc.Line);
|
||||||
}
|
}
|
||||||
if loc.Col != eloc.Col {
|
if pos.Column!= eloc.Column {
|
||||||
t.Errorf("bad column for %s: got %d, expected %d", lit, loc.Col, eloc.Col);
|
t.Errorf("bad column for %s: got %d, expected %d", lit, pos.Column, eloc.Column);
|
||||||
}
|
}
|
||||||
if tok != e.tok {
|
if tok != e.tok {
|
||||||
t.Errorf("bad token for %s: got %s, expected %s", lit, tok.String(), e.tok.String());
|
t.Errorf("bad token for %s: got %s, expected %s", lit, tok.String(), e.tok.String());
|
||||||
@ -216,7 +216,7 @@ func Test(t *testing.T) {
|
|||||||
if tokenclass(tok) != e.class {
|
if tokenclass(tok) != e.class {
|
||||||
t.Errorf("bad class for %s: got %d, expected %d", lit, tokenclass(tok), e.class);
|
t.Errorf("bad class for %s: got %d, expected %d", lit, tokenclass(tok), e.class);
|
||||||
}
|
}
|
||||||
eloc.Pos += len(lit) + len(whitespace);
|
eloc.Offset += len(lit) + len(whitespace);
|
||||||
eloc.Line += NewlineCount(lit) + whitespace_linecount;
|
eloc.Line += NewlineCount(lit) + whitespace_linecount;
|
||||||
index++;
|
index++;
|
||||||
return tok != token.EOF;
|
return tok != token.EOF;
|
||||||
|
@ -255,10 +255,10 @@ const (
|
|||||||
|
|
||||||
|
|
||||||
// Precedence returns the syntax precedence of the operator
|
// Precedence returns the syntax precedence of the operator
|
||||||
// token tok or LowestPrecedence if tok is not an operator.
|
// token op or LowestPrecedence if op is not an operator.
|
||||||
//
|
//
|
||||||
func (tok Token) Precedence() int {
|
func (op Token) Precedence() int {
|
||||||
switch tok {
|
switch op {
|
||||||
case COLON:
|
case COLON:
|
||||||
return 0;
|
return 0;
|
||||||
case LOR:
|
case LOR:
|
||||||
@ -322,3 +322,19 @@ func (tok Token) IsOperator() bool {
|
|||||||
func (tok Token) IsKeyword() bool {
|
func (tok Token) IsKeyword() bool {
|
||||||
return keyword_beg < tok && tok < keyword_end;
|
return keyword_beg < tok && tok < keyword_end;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Token source positions are represented by a Position value.
|
||||||
|
type Position struct {
|
||||||
|
Offset int; // byte offset, starting at 0
|
||||||
|
Line int; // line number, starting at 1
|
||||||
|
Column int; // column number, starting at 1 (character count)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Pos is an accessor method for anonymous Position fields.
|
||||||
|
// It returns its receiver.
|
||||||
|
//
|
||||||
|
func (pos *Position) Pos() Position {
|
||||||
|
return *pos;
|
||||||
|
}
|
||||||
|
@ -7,14 +7,7 @@
|
|||||||
//
|
//
|
||||||
package ast
|
package ast
|
||||||
|
|
||||||
import (
|
import "token"
|
||||||
"token";
|
|
||||||
"scanner";
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
// TODO rename Position to scanner.Position, possibly factor out
|
|
||||||
type Position scanner.Location
|
|
||||||
|
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
@ -26,18 +19,17 @@ type Position scanner.Location
|
|||||||
// correspond. The node fields correspond to the individual parts
|
// correspond. The node fields correspond to the individual parts
|
||||||
// of the respective productions.
|
// of the respective productions.
|
||||||
//
|
//
|
||||||
// Nodes contain selective position information: a position field
|
// All nodes contain position information marking the beginning of
|
||||||
// marking the beginning of the corresponding source text segment
|
// the corresponding source text segment; it is accessible via the
|
||||||
// if necessary; and specific position information for language
|
// Pos accessor method. Nodes may contain additional position info
|
||||||
// constructs where comments may be found between parts of the
|
// for language constructs where comments may be found between parts
|
||||||
// construct (typically any larger, parenthesized subpart). The
|
// of the construct (typically any larger, parenthesized subpart).
|
||||||
// position information is needed to properly position comments
|
// That position information is needed to properly position comments
|
||||||
// when printing the construct.
|
// when printing the construct.
|
||||||
|
|
||||||
// TODO: For comment positioning only the byte position and not
|
// TODO: For comment positioning only the byte position and not
|
||||||
// a complete Position field is needed. May be able to trim node
|
// a complete token.Position field is needed. May be able to trim
|
||||||
// sizes a bit. Then, embed Position field so we can get rid of
|
// node sizes a bit.
|
||||||
// most of the Pos() methods.
|
|
||||||
|
|
||||||
|
|
||||||
type (
|
type (
|
||||||
@ -55,7 +47,7 @@ type Expr interface {
|
|||||||
Visit(v ExprVisitor);
|
Visit(v ExprVisitor);
|
||||||
|
|
||||||
// Pos returns the (beginning) position of the expression.
|
// Pos returns the (beginning) position of the expression.
|
||||||
Pos() Position;
|
Pos() token.Position;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -67,7 +59,7 @@ type Stmt interface {
|
|||||||
Visit(v StmtVisitor);
|
Visit(v StmtVisitor);
|
||||||
|
|
||||||
// Pos returns the (beginning) position of the statement.
|
// Pos returns the (beginning) position of the statement.
|
||||||
Pos() Position;
|
Pos() token.Position;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -79,7 +71,7 @@ type Decl interface {
|
|||||||
Visit(v DeclVisitor);
|
Visit(v DeclVisitor);
|
||||||
|
|
||||||
// Pos returns the (beginning) position of the declaration.
|
// Pos returns the (beginning) position of the declaration.
|
||||||
Pos() Position;
|
Pos() token.Position;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -88,7 +80,7 @@ type Decl interface {
|
|||||||
|
|
||||||
// A Comment node represents a single //-style or /*-style comment.
|
// A Comment node represents a single //-style or /*-style comment.
|
||||||
type Comment struct {
|
type Comment struct {
|
||||||
Pos_ Position; // beginning position of the comment
|
token.Position; // beginning position of the comment
|
||||||
Text []byte; // the comment text (without '\n' for //-style comments)
|
Text []byte; // the comment text (without '\n' for //-style comments)
|
||||||
EndLine int; // the line where the comment ends
|
EndLine int; // the line where the comment ends
|
||||||
}
|
}
|
||||||
@ -131,12 +123,12 @@ type (
|
|||||||
// created.
|
// created.
|
||||||
//
|
//
|
||||||
BadExpr struct {
|
BadExpr struct {
|
||||||
Pos_ Position; // beginning position of bad expression
|
token.Position; // beginning position of bad expression
|
||||||
};
|
};
|
||||||
|
|
||||||
// An Ident node represents an identifier.
|
// An Ident node represents an identifier.
|
||||||
Ident struct {
|
Ident struct {
|
||||||
Pos_ Position; // identifier position
|
token.Position; // identifier position
|
||||||
Lit []byte; // identifier string (e.g. foobar)
|
Lit []byte; // identifier string (e.g. foobar)
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -144,30 +136,30 @@ type (
|
|||||||
// parameter list or the "..." length in an array type.
|
// parameter list or the "..." length in an array type.
|
||||||
//
|
//
|
||||||
Ellipsis struct {
|
Ellipsis struct {
|
||||||
Pos_ Position; // position of "..."
|
token.Position; // position of "..."
|
||||||
};
|
};
|
||||||
|
|
||||||
// An IntLit node represents an integer literal.
|
// An IntLit node represents an integer literal.
|
||||||
IntLit struct {
|
IntLit struct {
|
||||||
Pos_ Position; // literal string position
|
token.Position; // int literal position
|
||||||
Lit []byte; // literal string; e.g. 42 or 0x7f
|
Lit []byte; // literal string; e.g. 42 or 0x7f
|
||||||
};
|
};
|
||||||
|
|
||||||
// A FloatLit node represents a floating-point literal.
|
// A FloatLit node represents a floating-point literal.
|
||||||
FloatLit struct {
|
FloatLit struct {
|
||||||
Pos_ Position; // literal string position
|
token.Position; // float literal position
|
||||||
Lit []byte; // literal string; e.g. 3.14 or 1e-9
|
Lit []byte; // literal string; e.g. 3.14 or 1e-9
|
||||||
};
|
};
|
||||||
|
|
||||||
// A CharLit node represents a character literal.
|
// A CharLit node represents a character literal.
|
||||||
CharLit struct {
|
CharLit struct {
|
||||||
Pos_ Position; // literal string position
|
token.Position; // char literal position
|
||||||
Lit []byte; // literal string, including quotes; e.g. 'a' or '\x7f'
|
Lit []byte; // literal string, including quotes; e.g. 'a' or '\x7f'
|
||||||
};
|
};
|
||||||
|
|
||||||
// A StringLit node represents a string literal.
|
// A StringLit node represents a string literal.
|
||||||
StringLit struct {
|
StringLit struct {
|
||||||
Pos_ Position; // literal string position
|
token.Position; // string literal position
|
||||||
Lit []byte; // literal string, including quotes; e.g. "foo" or `\m\n\o`
|
Lit []byte; // literal string, including quotes; e.g. "foo" or `\m\n\o`
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -187,18 +179,22 @@ type (
|
|||||||
};
|
};
|
||||||
|
|
||||||
// A CompositeLit node represents a composite literal.
|
// A CompositeLit node represents a composite literal.
|
||||||
|
// A pair (x : y) in a CompositeLit is represented by
|
||||||
|
// a binary expression with the Colon operator.
|
||||||
|
// TODO decide if better to use a Pair node instead.
|
||||||
|
//
|
||||||
CompositeLit struct {
|
CompositeLit struct {
|
||||||
Type Expr; // literal type
|
Type Expr; // literal type
|
||||||
Lbrace Position; // position of "{"
|
Lbrace token.Position; // position of "{"
|
||||||
Elts []Expr; // list of composite elements
|
Elts []Expr; // list of composite elements
|
||||||
Rbrace Position; // position of "}"
|
Rbrace token.Position; // position of "}"
|
||||||
};
|
};
|
||||||
|
|
||||||
// A ParenExpr node represents a parenthesized expression.
|
// A ParenExpr node represents a parenthesized expression.
|
||||||
ParenExpr struct {
|
ParenExpr struct {
|
||||||
Lparen Position; // position of "("
|
token.Position; // position of "("
|
||||||
X Expr; // parenthesized expression
|
X Expr; // parenthesized expression
|
||||||
Rparen Position; // position of ")"
|
Rparen token.Position; // position of ")"
|
||||||
};
|
};
|
||||||
|
|
||||||
// A SelectorExpr node represents an expression followed by a selector.
|
// A SelectorExpr node represents an expression followed by a selector.
|
||||||
@ -230,15 +226,15 @@ type (
|
|||||||
// A CallExpr node represents an expression followed by an argument list.
|
// A CallExpr node represents an expression followed by an argument list.
|
||||||
CallExpr struct {
|
CallExpr struct {
|
||||||
Fun Expr; // function expression
|
Fun Expr; // function expression
|
||||||
Lparen Position; // position of "("
|
Lparen token.Position; // position of "("
|
||||||
Args []Expr; // function arguments
|
Args []Expr; // function arguments
|
||||||
Rparen Position; // positions of ")"
|
Rparen token.Position; // positions of ")"
|
||||||
};
|
};
|
||||||
|
|
||||||
// A StarExpr node represents an expression of the form "*" Expression.
|
// A StarExpr node represents an expression of the form "*" Expression.
|
||||||
// Semantically it could be a unary "*" expression, or a pointer type.
|
// Semantically it could be a unary "*" expression, or a pointer type.
|
||||||
StarExpr struct {
|
StarExpr struct {
|
||||||
Star Position; // position of "*"
|
token.Position; // position of "*"
|
||||||
X Expr; // operand
|
X Expr; // operand
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -246,16 +242,20 @@ type (
|
|||||||
// Unary "*" expressions are represented via DerefExpr nodes.
|
// Unary "*" expressions are represented via DerefExpr nodes.
|
||||||
//
|
//
|
||||||
UnaryExpr struct {
|
UnaryExpr struct {
|
||||||
Pos_ Position; // token position
|
token.Position; // position of Op
|
||||||
Tok token.Token; // operator
|
Op token.Token; // operator
|
||||||
X Expr; // operand
|
X Expr; // operand
|
||||||
};
|
};
|
||||||
|
|
||||||
// A BinaryExpr node represents a binary expression.
|
// A BinaryExpr node represents a binary expression.
|
||||||
|
// A pair (x : y) in a CompositeLit is represented by
|
||||||
|
// a binary expression with the Colon operator.
|
||||||
|
// TODO decide if better to use a Pair node instead.
|
||||||
|
//
|
||||||
BinaryExpr struct {
|
BinaryExpr struct {
|
||||||
X Expr; // left operand
|
X Expr; // left operand
|
||||||
Pos_ Position; // token position
|
OpPos token.Position; // position of Op
|
||||||
Tok token.Token; // operator
|
Op token.Token; // operator
|
||||||
Y Expr; // right operand
|
Y Expr; // right operand
|
||||||
};
|
};
|
||||||
)
|
)
|
||||||
@ -278,85 +278,70 @@ const (
|
|||||||
type (
|
type (
|
||||||
// An ArrayType node represents an array type.
|
// An ArrayType node represents an array type.
|
||||||
ArrayType struct {
|
ArrayType struct {
|
||||||
Lbrack Position; // position of "["
|
token.Position; // position of "["
|
||||||
Len Expr; // possibly an Ellipsis node for [...]T array types
|
Len Expr; // possibly an Ellipsis node for [...]T array types
|
||||||
Elt Expr; // element type
|
Elt Expr; // element type
|
||||||
};
|
};
|
||||||
|
|
||||||
// A SliceType node represents a slice type.
|
// A SliceType node represents a slice type.
|
||||||
SliceType struct {
|
SliceType struct {
|
||||||
Lbrack Position; // position of "["
|
token.Position; // position of "["
|
||||||
Elt Expr; // element type
|
Elt Expr; // element type
|
||||||
};
|
};
|
||||||
|
|
||||||
// A StructType node represents a struct type.
|
// A StructType node represents a struct type.
|
||||||
StructType struct {
|
StructType struct {
|
||||||
Struct, Lbrace Position; // positions of "struct" keyword, "{"
|
token.Position; // position of "struct" keyword
|
||||||
|
Lbrace token.Position; // position of "{"
|
||||||
Fields []*Field; // list of field declarations; nil if forward declaration
|
Fields []*Field; // list of field declarations; nil if forward declaration
|
||||||
Rbrace Position; // position of "}"
|
Rbrace token.Position; // position of "}"
|
||||||
};
|
};
|
||||||
|
|
||||||
// Pointer types are represented via StarExpr nodes.
|
// Pointer types are represented via StarExpr nodes.
|
||||||
|
|
||||||
// A FunctionType node represents a function type.
|
// A FunctionType node represents a function type.
|
||||||
FunctionType struct {
|
FunctionType struct {
|
||||||
Func Position; // position of "func" keyword
|
token.Position; // position of "func" keyword
|
||||||
Params []*Field; // (incoming) parameters
|
Params []*Field; // (incoming) parameters
|
||||||
Results []*Field; // (outgoing) results
|
Results []*Field; // (outgoing) results
|
||||||
};
|
};
|
||||||
|
|
||||||
// An InterfaceType node represents an interface type.
|
// An InterfaceType node represents an interface type.
|
||||||
InterfaceType struct {
|
InterfaceType struct {
|
||||||
Interface, Lbrace Position; // positions of "interface" keyword, "{"
|
token.Position; // position of "interface" keyword
|
||||||
|
Lbrace token.Position; // position of "{"
|
||||||
Methods []*Field; // list of methods; nil if forward declaration
|
Methods []*Field; // list of methods; nil if forward declaration
|
||||||
Rbrace Position; // position of "}"
|
Rbrace token.Position; // position of "}"
|
||||||
};
|
};
|
||||||
|
|
||||||
// A MapType node represents a map type.
|
// A MapType node represents a map type.
|
||||||
MapType struct {
|
MapType struct {
|
||||||
Map Position; // position of "map" keyword
|
token.Position; // position of "map" keyword
|
||||||
Key Expr;
|
Key Expr;
|
||||||
Value Expr;
|
Value Expr;
|
||||||
};
|
};
|
||||||
|
|
||||||
// A ChannelType node represents a channel type.
|
// A ChannelType node represents a channel type.
|
||||||
ChannelType struct {
|
ChannelType struct {
|
||||||
Pos_ Position; // position of "chan" keyword or "<-" (whichever comes first)
|
token.Position; // position of "chan" keyword or "<-" (whichever comes first)
|
||||||
Dir ChanDir; // channel direction
|
Dir ChanDir; // channel direction
|
||||||
Value Expr; // value type
|
Value Expr; // value type
|
||||||
};
|
};
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
// Pos() implementations for all expression/type nodes.
|
// Pos() implementations for expression/type where the position
|
||||||
|
// corresponds to the position of a sub-node.
|
||||||
//
|
//
|
||||||
func (x *BadExpr) Pos() Position { return x.Pos_; }
|
func (x *StringList) Pos() token.Position { return x.Strings[0].Pos(); }
|
||||||
func (x *Ident) Pos() Position { return x.Pos_; }
|
func (x *FunctionLit) Pos() token.Position { return x.Type.Pos(); }
|
||||||
func (x *IntLit) Pos() Position { return x.Pos_; }
|
func (x *CompositeLit) Pos() token.Position { return x.Type.Pos(); }
|
||||||
func (x *FloatLit) Pos() Position { return x.Pos_; }
|
func (x *SelectorExpr) Pos() token.Position { return x.X.Pos(); }
|
||||||
func (x *CharLit) Pos() Position { return x.Pos_; }
|
func (x *IndexExpr) Pos() token.Position { return x.X.Pos(); }
|
||||||
func (x *StringLit) Pos() Position { return x.Pos_; }
|
func (x *SliceExpr) Pos() token.Position { return x.X.Pos(); }
|
||||||
func (x *StringList) Pos() Position { return x.Strings[0].Pos(); }
|
func (x *TypeAssertExpr) Pos() token.Position { return x.X.Pos(); }
|
||||||
func (x *FunctionLit) Pos() Position { return x.Type.Func; }
|
func (x *CallExpr) Pos() token.Position { return x.Fun.Pos(); }
|
||||||
func (x *CompositeLit) Pos() Position { return x.Type.Pos(); }
|
func (x *BinaryExpr) Pos() token.Position { return x.X.Pos(); }
|
||||||
func (x *ParenExpr) Pos() Position { return x.Lparen; }
|
|
||||||
func (x *SelectorExpr) Pos() Position { return x.X.Pos(); }
|
|
||||||
func (x *IndexExpr) Pos() Position { return x.X.Pos(); }
|
|
||||||
func (x *SliceExpr) Pos() Position { return x.X.Pos(); }
|
|
||||||
func (x *TypeAssertExpr) Pos() Position { return x.X.Pos(); }
|
|
||||||
func (x *CallExpr) Pos() Position { return x.Fun.Pos(); }
|
|
||||||
func (x *StarExpr) Pos() Position { return x.Star; }
|
|
||||||
func (x *UnaryExpr) Pos() Position { return x.Pos_; }
|
|
||||||
func (x *BinaryExpr) Pos() Position { return x.X.Pos(); }
|
|
||||||
|
|
||||||
func (x *Ellipsis) Pos() Position { return x.Pos_; }
|
|
||||||
func (x *ArrayType) Pos() Position { return x.Lbrack; }
|
|
||||||
func (x *SliceType) Pos() Position { return x.Lbrack; }
|
|
||||||
func (x *StructType) Pos() Position { return x.Struct; }
|
|
||||||
func (x *FunctionType) Pos() Position { return x.Func; }
|
|
||||||
func (x *InterfaceType) Pos() Position { return x.Interface; }
|
|
||||||
func (x *MapType) Pos() Position { return x.Map; }
|
|
||||||
func (x *ChannelType) Pos() Position { return x.Pos_; }
|
|
||||||
|
|
||||||
|
|
||||||
// All expression/type nodes implement a Visit method which takes
|
// All expression/type nodes implement a Visit method which takes
|
||||||
@ -440,7 +425,7 @@ type (
|
|||||||
// created.
|
// created.
|
||||||
//
|
//
|
||||||
BadStmt struct {
|
BadStmt struct {
|
||||||
Pos_ Position; // beginning position of bad statement
|
token.Position; // beginning position of bad statement
|
||||||
};
|
};
|
||||||
|
|
||||||
// A DeclStmt node represents a declaration in a statement list.
|
// A DeclStmt node represents a declaration in a statement list.
|
||||||
@ -453,7 +438,7 @@ type (
|
|||||||
// of the immediately preceeding semicolon.
|
// of the immediately preceeding semicolon.
|
||||||
//
|
//
|
||||||
EmptyStmt struct {
|
EmptyStmt struct {
|
||||||
Semicolon Position; // position of preceeding ";"
|
token.Position; // position of preceeding ";"
|
||||||
};
|
};
|
||||||
|
|
||||||
// A LabeledStmt node represents a labeled statement.
|
// A LabeledStmt node represents a labeled statement.
|
||||||
@ -479,26 +464,26 @@ type (
|
|||||||
// a short variable declaration.
|
// a short variable declaration.
|
||||||
AssignStmt struct {
|
AssignStmt struct {
|
||||||
Lhs []Expr;
|
Lhs []Expr;
|
||||||
Pos_ Position; // token position
|
TokPos token.Position; // position of Tok
|
||||||
Tok token.Token; // assignment token, DEFINE
|
Tok token.Token; // assignment token, DEFINE
|
||||||
Rhs []Expr;
|
Rhs []Expr;
|
||||||
};
|
};
|
||||||
|
|
||||||
// A GoStmt node represents a go statement.
|
// A GoStmt node represents a go statement.
|
||||||
GoStmt struct {
|
GoStmt struct {
|
||||||
Go Position; // position of "go" keyword
|
token.Position; // position of "go" keyword
|
||||||
Call *CallExpr;
|
Call *CallExpr;
|
||||||
};
|
};
|
||||||
|
|
||||||
// A DeferStmt node represents a defer statement.
|
// A DeferStmt node represents a defer statement.
|
||||||
DeferStmt struct {
|
DeferStmt struct {
|
||||||
Defer Position; // position of "defer" keyword
|
token.Position; // position of "defer" keyword
|
||||||
Call *CallExpr;
|
Call *CallExpr;
|
||||||
};
|
};
|
||||||
|
|
||||||
// A ReturnStmt node represents a return statement.
|
// A ReturnStmt node represents a return statement.
|
||||||
ReturnStmt struct {
|
ReturnStmt struct {
|
||||||
Return Position; // position of "return" keyword
|
token.Position; // position of "return" keyword
|
||||||
Results []Expr;
|
Results []Expr;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -506,21 +491,21 @@ type (
|
|||||||
// or fallthrough statement.
|
// or fallthrough statement.
|
||||||
//
|
//
|
||||||
BranchStmt struct {
|
BranchStmt struct {
|
||||||
Pos_ Position; // position of keyword
|
token.Position; // position of Tok
|
||||||
Tok token.Token; // keyword token (BREAK, CONTINUE, GOTO, FALLTHROUGH)
|
Tok token.Token; // keyword token (BREAK, CONTINUE, GOTO, FALLTHROUGH)
|
||||||
Label *Ident;
|
Label *Ident;
|
||||||
};
|
};
|
||||||
|
|
||||||
// A BlockStmt node represents a braced statement list.
|
// A BlockStmt node represents a braced statement list.
|
||||||
BlockStmt struct {
|
BlockStmt struct {
|
||||||
Lbrace Position;
|
token.Position; // position of "{"
|
||||||
List []Stmt;
|
List []Stmt;
|
||||||
Rbrace Position;
|
Rbrace token.Position; // position of "}"
|
||||||
};
|
};
|
||||||
|
|
||||||
// An IfStmt node represents an if statement.
|
// An IfStmt node represents an if statement.
|
||||||
IfStmt struct {
|
IfStmt struct {
|
||||||
If Position; // position of "if" keyword
|
token.Position; // position of "if" keyword
|
||||||
Init Stmt;
|
Init Stmt;
|
||||||
Cond Expr;
|
Cond Expr;
|
||||||
Body *BlockStmt;
|
Body *BlockStmt;
|
||||||
@ -529,15 +514,15 @@ type (
|
|||||||
|
|
||||||
// A CaseClause represents a case of an expression switch statement.
|
// A CaseClause represents a case of an expression switch statement.
|
||||||
CaseClause struct {
|
CaseClause struct {
|
||||||
Case Position; // position of "case" or "default" keyword
|
token.Position; // position of "case" or "default" keyword
|
||||||
Values []Expr; // nil means default case
|
Values []Expr; // nil means default case
|
||||||
Colon Position; // position of ":"
|
Colon token.Position; // position of ":"
|
||||||
Body []Stmt; // statement list; or nil
|
Body []Stmt; // statement list; or nil
|
||||||
};
|
};
|
||||||
|
|
||||||
// A SwitchStmt node represents an expression switch statement.
|
// A SwitchStmt node represents an expression switch statement.
|
||||||
SwitchStmt struct {
|
SwitchStmt struct {
|
||||||
Switch Position; // position of "switch" keyword
|
token.Position; // position of "switch" keyword
|
||||||
Init Stmt;
|
Init Stmt;
|
||||||
Tag Expr;
|
Tag Expr;
|
||||||
Body *BlockStmt; // CaseClauses only
|
Body *BlockStmt; // CaseClauses only
|
||||||
@ -545,15 +530,15 @@ type (
|
|||||||
|
|
||||||
// A TypeCaseClause represents a case of a type switch statement.
|
// A TypeCaseClause represents a case of a type switch statement.
|
||||||
TypeCaseClause struct {
|
TypeCaseClause struct {
|
||||||
Case Position; // position of "case" or "default" keyword
|
token.Position; // position of "case" or "default" keyword
|
||||||
Type Expr; // nil means default case
|
Type Expr; // nil means default case
|
||||||
Colon Position; // position of ":"
|
Colon token.Position; // position of ":"
|
||||||
Body []Stmt; // statement list; or nil
|
Body []Stmt; // statement list; or nil
|
||||||
};
|
};
|
||||||
|
|
||||||
// An TypeSwitchStmt node represents a type switch statement.
|
// An TypeSwitchStmt node represents a type switch statement.
|
||||||
TypeSwitchStmt struct {
|
TypeSwitchStmt struct {
|
||||||
Switch Position; // position of "switch" keyword
|
token.Position; // position of "switch" keyword
|
||||||
Init Stmt;
|
Init Stmt;
|
||||||
Assign Stmt; // x := y.(type)
|
Assign Stmt; // x := y.(type)
|
||||||
Body *BlockStmt; // TypeCaseClauses only
|
Body *BlockStmt; // TypeCaseClauses only
|
||||||
@ -561,22 +546,22 @@ type (
|
|||||||
|
|
||||||
// A CommClause node represents a case of a select statement.
|
// A CommClause node represents a case of a select statement.
|
||||||
CommClause struct {
|
CommClause struct {
|
||||||
Case Position; // position of "case" or "default" keyword
|
token.Position; // position of "case" or "default" keyword
|
||||||
Tok token.Token; // ASSIGN or DEFINE (valid only if Lhs != nil)
|
Tok token.Token; // ASSIGN or DEFINE (valid only if Lhs != nil)
|
||||||
Lhs, Rhs Expr; // Rhs == nil means default case
|
Lhs, Rhs Expr; // Rhs == nil means default case
|
||||||
Colon Position; // position of ":"
|
Colon token.Position; // position of ":"
|
||||||
Body []Stmt; // statement list; or nil
|
Body []Stmt; // statement list; or nil
|
||||||
};
|
};
|
||||||
|
|
||||||
// An SelectStmt node represents a select statement.
|
// An SelectStmt node represents a select statement.
|
||||||
SelectStmt struct {
|
SelectStmt struct {
|
||||||
Select Position; // position of "select" keyword
|
token.Position; // position of "select" keyword
|
||||||
Body *BlockStmt; // CommClauses only
|
Body *BlockStmt; // CommClauses only
|
||||||
};
|
};
|
||||||
|
|
||||||
// A ForStmt represents a for statement.
|
// A ForStmt represents a for statement.
|
||||||
ForStmt struct {
|
ForStmt struct {
|
||||||
For Position; // position of "for" keyword
|
token.Position; // position of "for" keyword
|
||||||
Init Stmt;
|
Init Stmt;
|
||||||
Cond Expr;
|
Cond Expr;
|
||||||
Post Stmt;
|
Post Stmt;
|
||||||
@ -585,39 +570,24 @@ type (
|
|||||||
|
|
||||||
// A RangeStmt represents a for statement with a range clause.
|
// A RangeStmt represents a for statement with a range clause.
|
||||||
RangeStmt struct {
|
RangeStmt struct {
|
||||||
For Position; // position of "for" keyword
|
token.Position; // position of "for" keyword
|
||||||
Key, Value Expr; // Value may be nil
|
Key, Value Expr; // Value may be nil
|
||||||
Pos_ Position; // token position
|
TokPos token.Position; // position of Tok
|
||||||
Tok token.Token; // ASSIGN or DEFINE
|
Tok token.Token; // ASSIGN, DEFINE
|
||||||
X Expr; // value to range over
|
X Expr; // value to range over
|
||||||
Body *BlockStmt;
|
Body *BlockStmt;
|
||||||
};
|
};
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
// Pos() implementations for all statement nodes.
|
// Pos() implementations for statement nodes where the position
|
||||||
|
// corresponds to the position of a sub-node.
|
||||||
//
|
//
|
||||||
func (s *BadStmt) Pos() Position { return s.Pos_; }
|
func (s *DeclStmt) Pos() token.Position { return s.Decl.Pos(); }
|
||||||
func (s *DeclStmt) Pos() Position { return s.Decl.Pos(); }
|
func (s *LabeledStmt) Pos() token.Position { return s.Label.Pos(); }
|
||||||
func (s *EmptyStmt) Pos() Position { return s.Semicolon; }
|
func (s *ExprStmt) Pos() token.Position { return s.X.Pos(); }
|
||||||
func (s *LabeledStmt) Pos() Position { return s.Label.Pos(); }
|
func (s *IncDecStmt) Pos() token.Position { return s.X.Pos(); }
|
||||||
func (s *ExprStmt) Pos() Position { return s.X.Pos(); }
|
func (s *AssignStmt) Pos() token.Position { return s.Lhs[0].Pos(); }
|
||||||
func (s *IncDecStmt) Pos() Position { return s.X.Pos(); }
|
|
||||||
func (s *AssignStmt) Pos() Position { return s.Lhs[0].Pos(); }
|
|
||||||
func (s *GoStmt) Pos() Position { return s.Go; }
|
|
||||||
func (s *DeferStmt) Pos() Position { return s.Defer; }
|
|
||||||
func (s *ReturnStmt) Pos() Position { return s.Return; }
|
|
||||||
func (s *BranchStmt) Pos() Position { return s.Pos_; }
|
|
||||||
func (s *BlockStmt) Pos() Position { return s.Lbrace; }
|
|
||||||
func (s *IfStmt) Pos() Position { return s.If; }
|
|
||||||
func (s *CaseClause) Pos() Position { return s.Case; }
|
|
||||||
func (s *SwitchStmt) Pos() Position { return s.Switch; }
|
|
||||||
func (s *TypeCaseClause) Pos() Position { return s.Case; }
|
|
||||||
func (s *TypeSwitchStmt) Pos() Position { return s.Switch; }
|
|
||||||
func (s *CommClause) Pos() Position { return s.Case; }
|
|
||||||
func (s *SelectStmt) Pos() Position { return s.Select; }
|
|
||||||
func (s *ForStmt) Pos() Position { return s.For; }
|
|
||||||
func (s *RangeStmt) Pos() Position { return s.For; }
|
|
||||||
|
|
||||||
|
|
||||||
// All statement nodes implement a Visit method which takes
|
// All statement nodes implement a Visit method which takes
|
||||||
@ -686,19 +656,19 @@ type (
|
|||||||
// created.
|
// created.
|
||||||
//
|
//
|
||||||
BadDecl struct {
|
BadDecl struct {
|
||||||
Pos_ Position; // beginning position of bad declaration
|
token.Position; // beginning position of bad declaration
|
||||||
};
|
};
|
||||||
|
|
||||||
ImportDecl struct {
|
ImportDecl struct {
|
||||||
Doc Comments; // associated documentation; or nil
|
Doc Comments; // associated documentation; or nil
|
||||||
Import Position; // position of "import" keyword
|
token.Position; // position of "import" keyword
|
||||||
Name *Ident; // local package name or nil
|
Name *Ident; // local package name or nil
|
||||||
Path []*StringLit; // package path
|
Path []*StringLit; // package path
|
||||||
};
|
};
|
||||||
|
|
||||||
ConstDecl struct {
|
ConstDecl struct {
|
||||||
Doc Comments; // associated documentation; or nil
|
Doc Comments; // associated documentation; or nil
|
||||||
Const Position; // position of "const" keyword
|
token.Position; // position of "const" keyword
|
||||||
Names []*Ident;
|
Names []*Ident;
|
||||||
Type Expr; // constant type or nil
|
Type Expr; // constant type or nil
|
||||||
Values []Expr;
|
Values []Expr;
|
||||||
@ -706,14 +676,14 @@ type (
|
|||||||
|
|
||||||
TypeDecl struct {
|
TypeDecl struct {
|
||||||
Doc Comments; // associated documentation; or nil
|
Doc Comments; // associated documentation; or nil
|
||||||
Pos_ Position; // position of "type" keyword
|
token.Position; // position of "type" keyword
|
||||||
Name *Ident;
|
Name *Ident;
|
||||||
Type Expr;
|
Type Expr;
|
||||||
};
|
};
|
||||||
|
|
||||||
VarDecl struct {
|
VarDecl struct {
|
||||||
Doc Comments; // associated documentation; or nil
|
Doc Comments; // associated documentation; or nil
|
||||||
Var Position; // position of "var" keyword
|
token.Position; // position of "var" keyword
|
||||||
Names []*Ident;
|
Names []*Ident;
|
||||||
Type Expr; // variable type or nil
|
Type Expr; // variable type or nil
|
||||||
Values []Expr;
|
Values []Expr;
|
||||||
@ -729,24 +699,17 @@ type (
|
|||||||
|
|
||||||
DeclList struct {
|
DeclList struct {
|
||||||
Doc Comments; // associated documentation; or nil
|
Doc Comments; // associated documentation; or nil
|
||||||
Pos_ Position; // position of token
|
token.Position; // position of Tok
|
||||||
Tok token.Token; // IMPORT, CONST, VAR, TYPE
|
Tok token.Token; // IMPORT, CONST, VAR, TYPE
|
||||||
Lparen Position; // position of '('
|
Lparen token.Position; // position of '('
|
||||||
List []Decl; // the list of parenthesized declarations
|
List []Decl; // the list of parenthesized declarations
|
||||||
Rparen Position; // position of ')'
|
Rparen token.Position; // position of ')'
|
||||||
};
|
};
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
// Pos() implementations for all declaration nodes.
|
// The position of a FuncDecl node is the position of its function type.
|
||||||
//
|
func (d *FuncDecl) Pos() token.Position { return d.Type.Pos(); }
|
||||||
func (d *BadDecl) Pos() Position { return d.Pos_; }
|
|
||||||
func (d *ImportDecl) Pos() Position { return d.Import; }
|
|
||||||
func (d *ConstDecl) Pos() Position { return d.Const; }
|
|
||||||
func (d *TypeDecl) Pos() Position { return d.Pos_; }
|
|
||||||
func (d *VarDecl) Pos() Position { return d.Var; }
|
|
||||||
func (d *FuncDecl) Pos() Position { return d.Type.Func; }
|
|
||||||
func (d *DeclList) Pos() Position { return d.Lparen; }
|
|
||||||
|
|
||||||
|
|
||||||
// All declaration nodes implement a Visit method which takes
|
// All declaration nodes implement a Visit method which takes
|
||||||
@ -782,7 +745,7 @@ func (d *DeclList) Visit(v DeclVisitor) { v.DoDeclList(d); }
|
|||||||
// A Package node represents the root node of an AST.
|
// A Package node represents the root node of an AST.
|
||||||
type Package struct {
|
type Package struct {
|
||||||
Doc Comments; // associated documentation; or nil
|
Doc Comments; // associated documentation; or nil
|
||||||
Package Position; // position of "package" keyword
|
token.Position; // position of "package" keyword
|
||||||
Name *Ident; // package name
|
Name *Ident; // package name
|
||||||
Decls []Decl; // top-level declarations
|
Decls []Decl; // top-level declarations
|
||||||
Comments []*Comment; // list of unassociated comments
|
Comments []*Comment; // list of unassociated comments
|
||||||
|
Loading…
Reference in New Issue
Block a user