summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRobert Griesemer <gri@golang.org>2008-07-14 18:06:41 -0700
committerRobert Griesemer <gri@golang.org>2008-07-14 18:06:41 -0700
commit892c19c88f0a179d5c281ef4430b60dd991caa72 (patch)
tree5395025770446d17d59bbd383c61efec319cea00
parent502f90497b8cd5de576a66c8f9bd4eb5a913cbae (diff)
downloadgolang-892c19c88f0a179d5c281ef4430b60dd991caa72.tar.gz
- no column info in error messages for Rob
- fixed parsing of function literals - added first round of scope handling SVN=127124
-rw-r--r--usr/gri/gosrc/globals.go2
-rw-r--r--usr/gri/gosrc/parser.go90
-rw-r--r--usr/gri/gosrc/scanner.go20
-rw-r--r--usr/gri/gosrc/test_parser.go1
4 files changed, 104 insertions, 9 deletions
diff --git a/usr/gri/gosrc/globals.go b/usr/gri/gosrc/globals.go
index f0f5711a3..a689eaa94 100644
--- a/usr/gri/gosrc/globals.go
+++ b/usr/gri/gosrc/globals.go
@@ -182,7 +182,7 @@ func (scope *Scope) Lookup(ident string) *Object {
func (scope *Scope) Insert(obj *Object) {
if scope.Lookup(obj.ident) != nil {
- panic;
+ panic "obj already inserted";
}
scope.entries.AddObj(obj);
}
diff --git a/usr/gri/gosrc/parser.go b/usr/gri/gosrc/parser.go
index ecf7699ae..beb74205f 100644
--- a/usr/gri/gosrc/parser.go
+++ b/usr/gri/gosrc/parser.go
@@ -5,6 +5,8 @@
package Parser
import Scanner "scanner"
+import Globals "globals"
+import Universe "universe"
export Parser
@@ -14,6 +16,7 @@ type Parser struct {
tok int; // one token look-ahead
beg, end int; // token position
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.S = S;
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) ParseExpression();
@@ -178,9 +222,11 @@ func (P *Parser) ParseInterfaceType() {
P.Trace("InterfaceType");
P.Expect(Scanner.INTERFACE);
P.Expect(Scanner.LBRACE);
+ P.OpenScope();
for P.tok != Scanner.RBRACE {
P.ParseMethodDecl();
}
+ P.CloseScope();
P.Next();
P.Ecart();
}
@@ -220,6 +266,7 @@ func (P *Parser) ParseStructType() {
P.Trace("StructType");
P.Expect(Scanner.STRUCT);
P.Expect(Scanner.LBRACE);
+ P.OpenScope();
for P.tok != Scanner.RBRACE {
P.ParseFieldDecl();
if P.tok != Scanner.RBRACE {
@@ -227,6 +274,7 @@ func (P *Parser) ParseStructType() {
}
}
P.Optional(Scanner.SEMICOLON);
+ P.CloseScope();
P.Expect(Scanner.RBRACE);
P.Ecart();
}
@@ -458,12 +506,14 @@ func (P *Parser) TryResult() bool {
func (P *Parser) ParseAnonymousSignature() {
P.Trace("AnonymousSignature");
+ P.OpenScope();
P.ParseParameters();
if P.tok == Scanner.PERIOD {
P.Next();
P.ParseParameters();
}
P.TryResult();
+ P.CloseScope();
P.Ecart();
}
@@ -479,12 +529,14 @@ func (P *Parser) ParseAnonymousSignature() {
func (P *Parser) ParseNamedSignature() {
P.Trace("NamedSignature");
+ P.OpenScope();
if P.tok == Scanner.LPAREN {
P.ParseParameters();
}
P.ParseIdent(); // function name
P.ParseParameters();
P.TryResult();
+ P.CloseScope();
P.Ecart();
}
@@ -591,6 +643,7 @@ func (P *Parser) ParseStatement() {
func (P *Parser) ParseIfStat() {
P.Trace("IfStat");
P.Expect(Scanner.IF);
+ P.OpenScope();
if P.tok != Scanner.LBRACE {
if P.tok != Scanner.SEMICOLON {
P.ParseSimpleStat();
@@ -612,6 +665,7 @@ func (P *Parser) ParseIfStat() {
P.ParseStatement();
}
}
+ P.CloseScope();
P.Ecart();
}
@@ -619,6 +673,7 @@ func (P *Parser) ParseIfStat() {
func (P *Parser) ParseForStat() {
P.Trace("ForStat");
P.Expect(Scanner.FOR);
+ P.OpenScope();
if P.tok != Scanner.LBRACE {
if P.tok != Scanner.SEMICOLON {
P.ParseSimpleStat();
@@ -635,6 +690,7 @@ func (P *Parser) ParseForStat() {
}
}
P.ParseBlock();
+ P.CloseScope();
P.Ecart();
}
@@ -680,6 +736,7 @@ func (P *Parser) ParseCaseClause() {
func (P *Parser) ParseSwitchStat() {
P.Trace("SwitchStat");
P.Expect(Scanner.SWITCH);
+ P.OpenScope();
if P.tok != Scanner.LBRACE {
if P.tok != Scanner.SEMICOLON {
P.ParseSimpleStat();
@@ -696,6 +753,7 @@ func (P *Parser) ParseSwitchStat() {
P.ParseCaseClause();
}
P.Expect(Scanner.RBRACE);
+ P.CloseScope();
P.Ecart();
}
@@ -822,10 +880,12 @@ func (P *Parser) ParseStatementList() {
func (P *Parser) ParseBlock() {
P.Trace("Block");
P.Expect(Scanner.LBRACE);
+ P.OpenScope();
if P.tok != Scanner.RBRACE && P.tok != Scanner.SEMICOLON {
P.ParseStatementList();
}
P.Optional(Scanner.SEMICOLON);
+ P.CloseScope();
P.Expect(Scanner.RBRACE);
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() {
P.Trace("Operand");
switch P.tok {
@@ -920,6 +988,8 @@ func (P *Parser) ParseOperand() {
case Scanner.TRUE: fallthrough;
case Scanner.FALSE:
P.Next();
+ case Scanner.FUNC:
+ P.ParseFunctionLit();
case Scanner.NEW:
P.ParseNew();
default:
@@ -1052,18 +1122,24 @@ func (P *Parser) ParseExpression() {
func (P *Parser) ParseProgram() {
P.Trace("Program");
+ P.OpenScope();
P.Expect(Scanner.PACKAGE);
P.ParseIdent();
P.Optional(Scanner.SEMICOLON);
- for P.tok == Scanner.IMPORT {
- P.ParseImportDecl();
- P.Optional(Scanner.SEMICOLON);
+ { P.OpenScope();
+ for P.tok == Scanner.IMPORT {
+ P.ParseImportDecl();
+ P.Optional(Scanner.SEMICOLON);
+ }
+
+ for P.tok != Scanner.EOF {
+ P.ParseDeclaration();
+ P.Optional(Scanner.SEMICOLON);
+ }
+ P.CloseScope();
}
- for P.tok != Scanner.EOF {
- P.ParseDeclaration();
- P.Optional(Scanner.SEMICOLON);
- }
+ P.CloseScope();
P.Ecart();
}
diff --git a/usr/gri/gosrc/scanner.go b/usr/gri/gosrc/scanner.go
index 94d8f1915..2ae3031d5 100644
--- a/usr/gri/gosrc/scanner.go
+++ b/usr/gri/gosrc/scanner.go
@@ -121,6 +121,7 @@ const (
var Keywords *map [string] int;
+var VerboseMsgs bool; // error message customization
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 () {
Keywords = new(map [string] int);
for i := KEYWORDS_BEG; i <= KEYWORDS_END; 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;
if pos > S.errpos + errdist || S.nerrors == 0 {
line, col := S.LineCol(pos);
- print S.filename, ":", line, ":", col, ": ", msg, "\n";
+ if VerboseMsgs {
+ print S.filename, ":", line, ":", col, ": ", msg, "\n";
+ } else {
+ print S.filename, ":", line, ": ", msg, "\n";
+ }
S.nerrors++;
S.errpos = pos;
}
diff --git a/usr/gri/gosrc/test_parser.go b/usr/gri/gosrc/test_parser.go
index 78d8d8711..cab01608a 100644
--- a/usr/gri/gosrc/test_parser.go
+++ b/usr/gri/gosrc/test_parser.go
@@ -4,6 +4,7 @@
package main
+import Globals "globals" // to get rid od 6g warning only
import Scanner "scanner"
import Parser "parser"