1
0
mirror of https://github.com/golang/go synced 2024-11-26 08:38:01 -07:00

- no column info in error messages for Rob

- fixed parsing of function literals
- added first round of scope handling

SVN=127124
This commit is contained in:
Robert Griesemer 2008-07-14 18:06:41 -07:00
parent 2d9ff40774
commit 230230c880
4 changed files with 104 additions and 9 deletions

View File

@ -182,7 +182,7 @@ func (scope *Scope) Lookup(ident string) *Object {
func (scope *Scope) Insert(obj *Object) { func (scope *Scope) Insert(obj *Object) {
if scope.Lookup(obj.ident) != nil { if scope.Lookup(obj.ident) != nil {
panic; panic "obj already inserted";
} }
scope.entries.AddObj(obj); scope.entries.AddObj(obj);
} }

View File

@ -5,6 +5,8 @@
package Parser package Parser
import Scanner "scanner" import Scanner "scanner"
import Globals "globals"
import Universe "universe"
export Parser export Parser
@ -14,6 +16,7 @@ type Parser struct {
tok int; // one token look-ahead tok int; // one token look-ahead
beg, end int; // token position beg, end int; // token position
ident string; // last ident seen ident string; // last ident seen
top_scope *Globals.Scope;
} }
@ -59,6 +62,7 @@ func (P *Parser) Open(S *Scanner.Scanner, verbose int) {
P.indent = 0; P.indent = 0;
P.S = S; P.S = S;
P.Next(); P.Next();
P.top_scope = Universe.scope;
} }
@ -84,6 +88,46 @@ func (P *Parser) Optional(tok int) {
} }
// ----------------------------------------------------------------------------
func (P *Parser) OpenScope() {
P.top_scope = Globals.NewScope(P.top_scope);
}
func (P *Parser) CloseScope() {
P.top_scope = P.top_scope.parent;
}
func (P *Parser) Lookup(ident string) *Globals.Object {
for scope := P.top_scope; scope != nil; scope = scope.parent {
obj := scope.Lookup(ident);
if obj != nil {
return obj;
}
}
return nil;
}
func (P *Parser) DeclareInScope(scope *Globals.Scope, obj *Globals.Object) {
if scope.Lookup(obj.ident) != nil {
// TODO is this the correct error position?
P.Error(P.beg, `"` + obj.ident + `" is declared already`);
return; // don't insert it into the scope
}
scope.Insert(obj);
}
func (P *Parser) Declare(obj *Globals.Object) {
P.DeclareInScope(P.top_scope, obj);
}
// ----------------------------------------------------------------------------
func (P *Parser) TryType() bool; func (P *Parser) TryType() bool;
func (P *Parser) ParseExpression(); func (P *Parser) ParseExpression();
@ -178,9 +222,11 @@ func (P *Parser) ParseInterfaceType() {
P.Trace("InterfaceType"); P.Trace("InterfaceType");
P.Expect(Scanner.INTERFACE); P.Expect(Scanner.INTERFACE);
P.Expect(Scanner.LBRACE); P.Expect(Scanner.LBRACE);
P.OpenScope();
for P.tok != Scanner.RBRACE { for P.tok != Scanner.RBRACE {
P.ParseMethodDecl(); P.ParseMethodDecl();
} }
P.CloseScope();
P.Next(); P.Next();
P.Ecart(); P.Ecart();
} }
@ -220,6 +266,7 @@ func (P *Parser) ParseStructType() {
P.Trace("StructType"); P.Trace("StructType");
P.Expect(Scanner.STRUCT); P.Expect(Scanner.STRUCT);
P.Expect(Scanner.LBRACE); P.Expect(Scanner.LBRACE);
P.OpenScope();
for P.tok != Scanner.RBRACE { for P.tok != Scanner.RBRACE {
P.ParseFieldDecl(); P.ParseFieldDecl();
if P.tok != Scanner.RBRACE { if P.tok != Scanner.RBRACE {
@ -227,6 +274,7 @@ func (P *Parser) ParseStructType() {
} }
} }
P.Optional(Scanner.SEMICOLON); P.Optional(Scanner.SEMICOLON);
P.CloseScope();
P.Expect(Scanner.RBRACE); P.Expect(Scanner.RBRACE);
P.Ecart(); P.Ecart();
} }
@ -458,12 +506,14 @@ func (P *Parser) TryResult() bool {
func (P *Parser) ParseAnonymousSignature() { func (P *Parser) ParseAnonymousSignature() {
P.Trace("AnonymousSignature"); P.Trace("AnonymousSignature");
P.OpenScope();
P.ParseParameters(); P.ParseParameters();
if P.tok == Scanner.PERIOD { if P.tok == Scanner.PERIOD {
P.Next(); P.Next();
P.ParseParameters(); P.ParseParameters();
} }
P.TryResult(); P.TryResult();
P.CloseScope();
P.Ecart(); P.Ecart();
} }
@ -479,12 +529,14 @@ func (P *Parser) ParseAnonymousSignature() {
func (P *Parser) ParseNamedSignature() { func (P *Parser) ParseNamedSignature() {
P.Trace("NamedSignature"); P.Trace("NamedSignature");
P.OpenScope();
if P.tok == Scanner.LPAREN { if P.tok == Scanner.LPAREN {
P.ParseParameters(); P.ParseParameters();
} }
P.ParseIdent(); // function name P.ParseIdent(); // function name
P.ParseParameters(); P.ParseParameters();
P.TryResult(); P.TryResult();
P.CloseScope();
P.Ecart(); P.Ecart();
} }
@ -591,6 +643,7 @@ func (P *Parser) ParseStatement() {
func (P *Parser) ParseIfStat() { func (P *Parser) ParseIfStat() {
P.Trace("IfStat"); P.Trace("IfStat");
P.Expect(Scanner.IF); P.Expect(Scanner.IF);
P.OpenScope();
if P.tok != Scanner.LBRACE { if P.tok != Scanner.LBRACE {
if P.tok != Scanner.SEMICOLON { if P.tok != Scanner.SEMICOLON {
P.ParseSimpleStat(); P.ParseSimpleStat();
@ -612,6 +665,7 @@ func (P *Parser) ParseIfStat() {
P.ParseStatement(); P.ParseStatement();
} }
} }
P.CloseScope();
P.Ecart(); P.Ecart();
} }
@ -619,6 +673,7 @@ func (P *Parser) ParseIfStat() {
func (P *Parser) ParseForStat() { func (P *Parser) ParseForStat() {
P.Trace("ForStat"); P.Trace("ForStat");
P.Expect(Scanner.FOR); P.Expect(Scanner.FOR);
P.OpenScope();
if P.tok != Scanner.LBRACE { if P.tok != Scanner.LBRACE {
if P.tok != Scanner.SEMICOLON { if P.tok != Scanner.SEMICOLON {
P.ParseSimpleStat(); P.ParseSimpleStat();
@ -635,6 +690,7 @@ func (P *Parser) ParseForStat() {
} }
} }
P.ParseBlock(); P.ParseBlock();
P.CloseScope();
P.Ecart(); P.Ecart();
} }
@ -680,6 +736,7 @@ func (P *Parser) ParseCaseClause() {
func (P *Parser) ParseSwitchStat() { func (P *Parser) ParseSwitchStat() {
P.Trace("SwitchStat"); P.Trace("SwitchStat");
P.Expect(Scanner.SWITCH); P.Expect(Scanner.SWITCH);
P.OpenScope();
if P.tok != Scanner.LBRACE { if P.tok != Scanner.LBRACE {
if P.tok != Scanner.SEMICOLON { if P.tok != Scanner.SEMICOLON {
P.ParseSimpleStat(); P.ParseSimpleStat();
@ -696,6 +753,7 @@ func (P *Parser) ParseSwitchStat() {
P.ParseCaseClause(); P.ParseCaseClause();
} }
P.Expect(Scanner.RBRACE); P.Expect(Scanner.RBRACE);
P.CloseScope();
P.Ecart(); P.Ecart();
} }
@ -822,10 +880,12 @@ func (P *Parser) ParseStatementList() {
func (P *Parser) ParseBlock() { func (P *Parser) ParseBlock() {
P.Trace("Block"); P.Trace("Block");
P.Expect(Scanner.LBRACE); P.Expect(Scanner.LBRACE);
P.OpenScope();
if P.tok != Scanner.RBRACE && P.tok != Scanner.SEMICOLON { if P.tok != Scanner.RBRACE && P.tok != Scanner.SEMICOLON {
P.ParseStatementList(); P.ParseStatementList();
} }
P.Optional(Scanner.SEMICOLON); P.Optional(Scanner.SEMICOLON);
P.CloseScope();
P.Expect(Scanner.RBRACE); P.Expect(Scanner.RBRACE);
P.Ecart(); P.Ecart();
} }
@ -904,6 +964,14 @@ func (P *Parser) ParseNew() {
} }
func (P *Parser) ParseFunctionLit() {
P.Trace("FunctionLit");
P.ParseFunctionType();
P.ParseBlock();
P.Ecart();
}
func (P *Parser) ParseOperand() { func (P *Parser) ParseOperand() {
P.Trace("Operand"); P.Trace("Operand");
switch P.tok { switch P.tok {
@ -920,6 +988,8 @@ func (P *Parser) ParseOperand() {
case Scanner.TRUE: fallthrough; case Scanner.TRUE: fallthrough;
case Scanner.FALSE: case Scanner.FALSE:
P.Next(); P.Next();
case Scanner.FUNC:
P.ParseFunctionLit();
case Scanner.NEW: case Scanner.NEW:
P.ParseNew(); P.ParseNew();
default: default:
@ -1052,10 +1122,12 @@ func (P *Parser) ParseExpression() {
func (P *Parser) ParseProgram() { func (P *Parser) ParseProgram() {
P.Trace("Program"); P.Trace("Program");
P.OpenScope();
P.Expect(Scanner.PACKAGE); P.Expect(Scanner.PACKAGE);
P.ParseIdent(); P.ParseIdent();
P.Optional(Scanner.SEMICOLON); P.Optional(Scanner.SEMICOLON);
{ P.OpenScope();
for P.tok == Scanner.IMPORT { for P.tok == Scanner.IMPORT {
P.ParseImportDecl(); P.ParseImportDecl();
P.Optional(Scanner.SEMICOLON); P.Optional(Scanner.SEMICOLON);
@ -1065,5 +1137,9 @@ func (P *Parser) ParseProgram() {
P.ParseDeclaration(); P.ParseDeclaration();
P.Optional(Scanner.SEMICOLON); P.Optional(Scanner.SEMICOLON);
} }
P.CloseScope();
}
P.CloseScope();
P.Ecart(); P.Ecart();
} }

View File

@ -121,6 +121,7 @@ const (
var Keywords *map [string] int; var Keywords *map [string] int;
var VerboseMsgs bool; // error message customization
export TokenName export TokenName
@ -362,12 +363,25 @@ bad:
} }
func IsUser(username string) bool {
for i := 0; i < sys.envc(); i++ {
if sys.envv(i) == "USER=" + username {
return true;
}
}
return false;
}
func Init () { func Init () {
Keywords = new(map [string] int); Keywords = new(map [string] int);
for i := KEYWORDS_BEG; i <= KEYWORDS_END; i++ { for i := KEYWORDS_BEG; i <= KEYWORDS_END; i++ {
Keywords[TokenName(i)] = i; Keywords[TokenName(i)] = i;
} }
// r doesn't want column information in error messages...
VerboseMsgs = !IsUser("r");
} }
@ -396,7 +410,11 @@ func (S *Scanner) Error(pos int, msg string) {
const errdist = 10; const errdist = 10;
if pos > S.errpos + errdist || S.nerrors == 0 { if pos > S.errpos + errdist || S.nerrors == 0 {
line, col := S.LineCol(pos); line, col := S.LineCol(pos);
if VerboseMsgs {
print S.filename, ":", line, ":", col, ": ", msg, "\n"; print S.filename, ":", line, ":", col, ": ", msg, "\n";
} else {
print S.filename, ":", line, ": ", msg, "\n";
}
S.nerrors++; S.nerrors++;
S.errpos = pos; S.errpos = pos;
} }

View File

@ -4,6 +4,7 @@
package main package main
import Globals "globals" // to get rid od 6g warning only
import Scanner "scanner" import Scanner "scanner"
import Parser "parser" import Parser "parser"