mirror of
https://github.com/golang/go
synced 2024-11-26 06:07:57 -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:
parent
2d9ff40774
commit
230230c880
@ -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);
|
||||||
}
|
}
|
||||||
|
@ -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,18 +1122,24 @@ 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);
|
||||||
|
|
||||||
for P.tok == Scanner.IMPORT {
|
{ P.OpenScope();
|
||||||
P.ParseImportDecl();
|
for P.tok == Scanner.IMPORT {
|
||||||
P.Optional(Scanner.SEMICOLON);
|
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.CloseScope();
|
||||||
P.ParseDeclaration();
|
|
||||||
P.Optional(Scanner.SEMICOLON);
|
|
||||||
}
|
|
||||||
P.Ecart();
|
P.Ecart();
|
||||||
}
|
}
|
||||||
|
@ -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);
|
||||||
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.nerrors++;
|
||||||
S.errpos = pos;
|
S.errpos = pos;
|
||||||
}
|
}
|
||||||
|
@ -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"
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user