func (P *Parser) ParseDeclaration();
-func (P *Parser) ParseIdent() (pos int, ident string) {
+func (P *Parser) ParseIdent(allow_keyword bool) (pos int, ident string) {
P.Trace("Ident");
- pos = P.pos;
- ident = "";
- if P.tok == Scanner.IDENT {
+ pos, ident = P.pos, "";
+ // NOTE Can make this faster by not doing the keyword lookup in the
+ // scanner if we don't care about keywords.
+ if P.tok == Scanner.IDENT || allow_keyword && P.tok > Scanner.IDENT {
ident = P.val;
if P.verbose {
P.PrintIndent();
func (P *Parser) ParseIdentDecl(kind int) *Globals.Object {
P.Trace("IdentDecl");
- pos, ident := P.ParseIdent();
+ pos, ident := P.ParseIdent(kind == Object.FIELD);
obj := Globals.NewObject(pos, kind, ident);
P.Declare(obj);
func (P *Parser) ParseIdentList() {
P.Trace("IdentList");
- P.ParseIdent();
+ P.ParseIdent(false);
for P.tok == Scanner.COMMA {
P.Next();
- P.ParseIdent();
+ P.ParseIdent(false);
}
P.Ecart();
}
P.Trace("QualifiedIdent");
if pos < 0 {
- pos, ident = P.ParseIdent();
+ pos, ident = P.ParseIdent(false);
}
if P.semantic_checks {
// panic "pkg.obj.ident != ident";
//}
P.Next(); // consume "."
- pos, ident = P.ParseIdent();
+ pos, ident = P.ParseIdent(false);
obj = pkg.scope.Lookup(ident);
if obj == nil {
P.Error(pos, `"` + ident + `" is not declared in package "` + pkg.obj.ident + `"`);
} else {
if P.tok == Scanner.PERIOD {
P.Next();
- P.ParseIdent();
+ P.ParseIdent(false);
}
P.Ecart();
return nil;
}
-func (P *Parser) ParseVarDeclList() {
+func (P *Parser) ParseVarDeclList(kind int) {
P.Trace("VarDeclList");
- list := P.ParseIdentDeclList(Object.VAR);
+ list := P.ParseIdentDeclList(kind);
typ := P.ParseVarType();
for p := list.first; p != nil; p = p.next {
p.obj.typ = typ; // TODO should use/have set_type()
}
-func (P *Parser) ParseParameterSection() {
- P.Trace("ParameterSection");
- P.ParseVarDeclList();
- P.Ecart();
-}
-
-
func (P *Parser) ParseParameterList() {
P.Trace("ParameterList");
- P.ParseParameterSection();
+ P.ParseVarDeclList(Object.VAR);
for P.tok == Scanner.COMMA {
P.Next();
- P.ParseParameterSection();
+ P.ParseVarDeclList(Object.VAR);
}
P.Ecart();
}
}
- pos, ident = P.ParseIdent();
+ pos, ident = P.ParseIdent(true);
P.ParseParameters();
func (P *Parser) ParseMethodDecl(recv_typ *Globals.Type) {
P.Trace("MethodDecl");
- pos, ident := P.ParseIdent();
+ pos, ident := P.ParseIdent(true);
P.OpenScope();
P.level--;
sig := P.top_scope;
P.level--;
typ := Globals.NewType(Type.INTERFACE);
typ.scope = P.top_scope;
- for P.tok == Scanner.IDENT {
+ for P.tok >= Scanner.IDENT {
P.ParseMethodDecl(typ);
}
P.level++;
}
-func (P *Parser) ParseFieldDecl() {
- P.Trace("FieldDecl");
- P.ParseVarDeclList();
- P.Ecart();
-}
-
-
func (P *Parser) ParseStructType() *Globals.Type {
P.Trace("StructType");
P.level--;
typ := Globals.NewType(Type.STRUCT);
typ.scope = P.top_scope;
- for P.tok == Scanner.IDENT {
- P.ParseFieldDecl();
+ for P.tok >= Scanner.IDENT {
+ P.ParseVarDeclList(Object.FIELD);
if P.tok != Scanner.RBRACE {
P.Expect(Scanner.SEMICOLON);
}
P.Next(); // consume package name
P.Expect(Scanner.PERIOD);
- pos, ident := P.ParseIdent();
+ pos, ident := P.ParseIdent(false);
obj := pkg.scope.Lookup(ident);
if obj == nil {
elt = Globals.NewType(Type.FORWARD);
if P.Lookup(P.val) == nil {
// implicit type forward declaration
// create a named forward type
- pos, ident := P.ParseIdent();
+ pos, ident := P.ParseIdent(false);
obj := Globals.NewObject(pos, Object.TYPE, ident);
elt = Globals.NewType(Type.FORWARD);
obj.typ = elt;
period_pos := P.pos;
P.Expect(Scanner.PERIOD);
- if P.tok == Scanner.IDENT {
- ident_pos, ident := P.ParseIdent();
+ if P.tok >= Scanner.IDENT {
+ ident_pos, ident := P.ParseIdent(true);
if P.semantic_checks {
switch typ := x.typ(); typ.form {
P.Expect(tok);
if P.tok == Scanner.IDENT {
- P.ParseIdent();
+ P.ParseIdent(false);
}
P.Ecart();
} else {
// receive
if P.tok != Scanner.LSS {
- P.ParseIdent();
+ P.ParseIdent(false);
P.Expect(Scanner.ASSIGN);
}
P.Expect(Scanner.LSS);
var typ *Globals.Type;
- pos, ident := P.ParseIdent();
+ pos, ident := P.ParseIdent(false);
obj := P.Lookup(ident);
if !P.comp.flags.sixg && obj != nil {
has_paren = true;
}
for P.tok == Scanner.IDENT {
- pos, ident := P.ParseIdent();
+ pos, ident := P.ParseIdent(false);
P.exports.AddStr(ident);
P.Optional(Scanner.COMMA); // TODO this seems wrong
}