]> Cypherpunks repositories - gostls13.git/commitdiff
- no column info in error messages for Rob
authorRobert Griesemer <gri@golang.org>
Tue, 15 Jul 2008 01:06:41 +0000 (18:06 -0700)
committerRobert Griesemer <gri@golang.org>
Tue, 15 Jul 2008 01:06:41 +0000 (18:06 -0700)
- fixed parsing of function literals
- added first round of scope handling

SVN=127124

usr/gri/gosrc/globals.go
usr/gri/gosrc/parser.go
usr/gri/gosrc/scanner.go
usr/gri/gosrc/test_parser.go

index f0f5711a31dd82be96bac57409f2403baed6e506..a689eaa945bbade29bede4a906e60194211bd0da 100644 (file)
@@ -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);
 }
index ecf7699ae06d065e402915c308e667a232ea99a9..beb74205f9fe34a98b90c6fd6233fbb16b26c5b7 100644 (file)
@@ -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();
 }
index 94d8f1915187d5ebc649b862297fb09c69c7c795..2ae3031d57a9afdd745c451145450e882c64b8e2 100644 (file)
@@ -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;
        }
index 78d8d87119cdb36f439b1f1104712f389d8e2fc8..cab01608aaca28629f52628c702419579f71302b 100644 (file)
@@ -4,6 +4,7 @@
 
 package main
 
+import Globals "globals"  // to get rid od 6g warning only
 import Scanner "scanner"
 import Parser "parser"