- allow reserved words as field and method names
R=r
OCL=14102
CL=14102
diff --git a/usr/gri/gosrc/base.go b/usr/gri/gosrc/base.go
index e7a14c8..456f354 100755
--- a/usr/gri/gosrc/base.go
+++ b/usr/gri/gosrc/base.go
@@ -13,5 +13,12 @@
export type Node struct {
left, right *Node;
val bool;
- f Foo
+ f Foo;
+ const, type, var, package int;
+}
+
+export func (p *Node) case(x int) {};
+
+export type I interface {
+ func();
}
diff --git a/usr/gri/gosrc/export.go b/usr/gri/gosrc/export.go
index dced015..cfca1a9 100755
--- a/usr/gri/gosrc/export.go
+++ b/usr/gri/gosrc/export.go
@@ -231,7 +231,7 @@
case Object.CONST:
E.WriteInt(0); // should be the correct value
- case Object.VAR:
+ case Object.VAR, Object.FIELD:
E.WriteInt(0); // should be the correct address/offset
case Object.FUNC:
diff --git a/usr/gri/gosrc/import.go b/usr/gri/gosrc/import.go
index 4ce3703..2be6e06 100755
--- a/usr/gri/gosrc/import.go
+++ b/usr/gri/gosrc/import.go
@@ -260,7 +260,7 @@
case Object.CONST:
I.ReadInt(); // should set the value field
- case Object.VAR:
+ case Object.VAR, Object.FIELD:
I.ReadInt(); // should set the address/offset field
case Object.FUNC:
diff --git a/usr/gri/gosrc/object.go b/usr/gri/gosrc/object.go
index 5bd2a6b..81fab9a 100755
--- a/usr/gri/gosrc/object.go
+++ b/usr/gri/gosrc/object.go
@@ -9,7 +9,7 @@
export const /* kind */ (
BAD = iota; // error handling
- CONST; TYPE; VAR; FUNC; PACKAGE; LABEL;
+ CONST; TYPE; VAR; FIELD; FUNC; PACKAGE; LABEL;
END; // end of scope (import/export only)
)
@@ -25,6 +25,7 @@
case CONST: return "CONST";
case TYPE: return "TYPE";
case VAR: return "VAR";
+ case FIELD: return "FIELD";
case FUNC: return "FUNC";
case PACKAGE: return "PACKAGE";
case LABEL: return "LABEL";
diff --git a/usr/gri/gosrc/parser.go b/usr/gri/gosrc/parser.go
index 2ca3a0f..01bb8c7 100644
--- a/usr/gri/gosrc/parser.go
+++ b/usr/gri/gosrc/parser.go
@@ -246,12 +246,13 @@
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();
@@ -270,7 +271,7 @@
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);
@@ -296,10 +297,10 @@
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();
}
@@ -309,7 +310,7 @@
P.Trace("QualifiedIdent");
if pos < 0 {
- pos, ident = P.ParseIdent();
+ pos, ident = P.ParseIdent(false);
}
if P.semantic_checks {
@@ -328,7 +329,7 @@
// 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 + `"`);
@@ -342,7 +343,7 @@
} else {
if P.tok == Scanner.PERIOD {
P.Next();
- P.ParseIdent();
+ P.ParseIdent(false);
}
P.Ecart();
return nil;
@@ -453,10 +454,10 @@
}
-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()
@@ -466,20 +467,13 @@
}
-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();
@@ -586,7 +580,7 @@
}
}
- pos, ident = P.ParseIdent();
+ pos, ident = P.ParseIdent(true);
P.ParseParameters();
@@ -614,7 +608,7 @@
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;
@@ -649,7 +643,7 @@
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++;
@@ -676,13 +670,6 @@
}
-func (P *Parser) ParseFieldDecl() {
- P.Trace("FieldDecl");
- P.ParseVarDeclList();
- P.Ecart();
-}
-
-
func (P *Parser) ParseStructType() *Globals.Type {
P.Trace("StructType");
@@ -692,8 +679,8 @@
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);
}
@@ -738,7 +725,7 @@
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);
@@ -760,7 +747,7 @@
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;
@@ -1110,8 +1097,8 @@
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 {
@@ -1519,7 +1506,7 @@
P.Expect(tok);
if P.tok == Scanner.IDENT {
- P.ParseIdent();
+ P.ParseIdent(false);
}
P.Ecart();
@@ -1659,7 +1646,7 @@
} else {
// receive
if P.tok != Scanner.LSS {
- P.ParseIdent();
+ P.ParseIdent(false);
P.Expect(Scanner.ASSIGN);
}
P.Expect(Scanner.LSS);
@@ -1831,7 +1818,7 @@
var typ *Globals.Type;
- pos, ident := P.ParseIdent();
+ pos, ident := P.ParseIdent(false);
obj := P.Lookup(ident);
if !P.comp.flags.sixg && obj != nil {
@@ -1990,7 +1977,7 @@
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
}
diff --git a/usr/gri/gosrc/printer.go b/usr/gri/gosrc/printer.go
index 3269fe2..c053cae 100755
--- a/usr/gri/gosrc/printer.go
+++ b/usr/gri/gosrc/printer.go
@@ -149,7 +149,7 @@
print " ";
P.PrintTypeStruct(obj.typ);
- case Object.VAR:
+ case Object.VAR, Object.FIELD:
if P.level == 0 {
print "var ";
}
diff --git a/usr/gri/gosrc/scanner.go b/usr/gri/gosrc/scanner.go
index 9598180..5ff6910 100644
--- a/usr/gri/gosrc/scanner.go
+++ b/usr/gri/gosrc/scanner.go
@@ -11,7 +11,6 @@
export const (
ILLEGAL = iota;
EOF;
- IDENT;
INT;
FLOAT;
STRING;
@@ -74,6 +73,9 @@
LAND;
LOR;
+ // IDENT must be immediately before keywords
+ IDENT;
+
// keywords
KEYWORDS_BEG;
BREAK;
@@ -118,7 +120,6 @@
switch (tok) {
case ILLEGAL: return "illegal";
case EOF: return "eof";
- case IDENT: return "ident";
case INT: return "int";
case FLOAT: return "float";
case STRING: return "string";
@@ -181,6 +182,8 @@
case LAND: return "&&";
case LOR: return "||";
+ case IDENT: return "ident";
+
case BREAK: return "break";
case CASE: return "case";
case CHAN: return "chan";