Commit 5fc79191 authored by Robert Griesemer's avatar Robert Griesemer

Experiments with "export":

Allow "export" keyword in front of a declaration. Semantics:
export *top-level* identifiers declared (but not the fields
of a struct type for instance).

R=r
OCL=13464
CL=13464
parent cf4c37ca
...@@ -971,8 +971,9 @@ func (P *Parser) ParseBinaryExpr(pos int, ident string, prec1 int) AST.Expr { ...@@ -971,8 +971,9 @@ func (P *Parser) ParseBinaryExpr(pos int, ident string, prec1 int) AST.Expr {
} }
// Expressions where the first token may be an // Expressions where the first token may be an identifier which has already
// identifier that has already been consumed. // been consumed. If the identifier is present, pos is the identifier position,
// otherwise pos must be < 0 (and ident is ignored).
func (P *Parser) ParseIdentExpression(pos int, ident string) { func (P *Parser) ParseIdentExpression(pos int, ident string) {
P.Trace("IdentExpression"); P.Trace("IdentExpression");
indent := P.indent; indent := P.indent;
...@@ -1456,13 +1457,14 @@ func (P *Parser) ParseImportDecl() { ...@@ -1456,13 +1457,14 @@ func (P *Parser) ParseImportDecl() {
} }
func (P *Parser) ParseConstSpec() { func (P *Parser) ParseConstSpec(exported bool) {
P.Trace("ConstSpec"); P.Trace("ConstSpec");
list := P.ParseIdentDeclList(Object.CONST); list := P.ParseIdentDeclList(Object.CONST);
typ := P.TryType(); typ := P.TryType();
if typ != nil { if typ != nil {
for p := list.first; p != nil; p = p.next { for p := list.first; p != nil; p = p.next {
p.obj.mark = exported;
p.obj.typ = typ; // TODO should use/have set_type()! p.obj.typ = typ; // TODO should use/have set_type()!
} }
} }
...@@ -1475,28 +1477,28 @@ func (P *Parser) ParseConstSpec() { ...@@ -1475,28 +1477,28 @@ func (P *Parser) ParseConstSpec() {
} }
func (P *Parser) ParseConstDecl() { func (P *Parser) ParseConstDecl(exported bool) {
P.Trace("ConstDecl"); P.Trace("ConstDecl");
P.Expect(Scanner.CONST); P.Expect(Scanner.CONST);
if P.tok == Scanner.LPAREN { if P.tok == Scanner.LPAREN {
P.Next(); P.Next();
for P.tok == Scanner.IDENT { for P.tok == Scanner.IDENT {
P.ParseConstSpec(); P.ParseConstSpec(exported);
if P.tok != Scanner.RPAREN { if P.tok != Scanner.RPAREN {
P.Expect(Scanner.SEMICOLON); P.Expect(Scanner.SEMICOLON);
} }
} }
P.Next(); P.Next();
} else { } else {
P.ParseConstSpec(); P.ParseConstSpec(exported);
} }
P.Ecart(); P.Ecart();
} }
func (P *Parser) ParseTypeSpec() { func (P *Parser) ParseTypeSpec(exported bool) {
P.Trace("TypeSpec"); P.Trace("TypeSpec");
pos := P.pos; pos := P.pos;
...@@ -1510,6 +1512,7 @@ func (P *Parser) ParseTypeSpec() { ...@@ -1510,6 +1512,7 @@ func (P *Parser) ParseTypeSpec() {
} }
} else { } else {
obj = Globals.NewObject(pos, Object.TYPE, ident); obj = Globals.NewObject(pos, Object.TYPE, ident);
obj.mark = exported;
obj.typ = Universe.undef_t; // TODO fix this obj.typ = Universe.undef_t; // TODO fix this
P.top_scope.Insert(obj); P.top_scope.Insert(obj);
} }
...@@ -1527,28 +1530,28 @@ func (P *Parser) ParseTypeSpec() { ...@@ -1527,28 +1530,28 @@ func (P *Parser) ParseTypeSpec() {
} }
func (P *Parser) ParseTypeDecl() { func (P *Parser) ParseTypeDecl(exported bool) {
P.Trace("TypeDecl"); P.Trace("TypeDecl");
P.Expect(Scanner.TYPE); P.Expect(Scanner.TYPE);
if P.tok == Scanner.LPAREN { if P.tok == Scanner.LPAREN {
P.Next(); P.Next();
for P.tok == Scanner.IDENT { for P.tok == Scanner.IDENT {
P.ParseTypeSpec(); P.ParseTypeSpec(exported);
if P.tok != Scanner.RPAREN { if P.tok != Scanner.RPAREN {
P.Expect(Scanner.SEMICOLON); P.Expect(Scanner.SEMICOLON);
} }
} }
P.Next(); P.Next();
} else { } else {
P.ParseTypeSpec(); P.ParseTypeSpec(exported);
} }
P.Ecart(); P.Ecart();
} }
func (P *Parser) ParseVarSpec() { func (P *Parser) ParseVarSpec(exported bool) {
P.Trace("VarSpec"); P.Trace("VarSpec");
list := P.ParseIdentDeclList(Object.VAR); list := P.ParseIdentDeclList(Object.VAR);
...@@ -1570,28 +1573,28 @@ func (P *Parser) ParseVarSpec() { ...@@ -1570,28 +1573,28 @@ func (P *Parser) ParseVarSpec() {
} }
func (P *Parser) ParseVarDecl() { func (P *Parser) ParseVarDecl(exported bool) {
P.Trace("VarDecl"); P.Trace("VarDecl");
P.Expect(Scanner.VAR); P.Expect(Scanner.VAR);
if P.tok == Scanner.LPAREN { if P.tok == Scanner.LPAREN {
P.Next(); P.Next();
for P.tok == Scanner.IDENT { for P.tok == Scanner.IDENT {
P.ParseVarSpec(); P.ParseVarSpec(exported);
if P.tok != Scanner.RPAREN { if P.tok != Scanner.RPAREN {
P.Expect(Scanner.SEMICOLON); P.Expect(Scanner.SEMICOLON);
} }
} }
P.Next(); P.Next();
} else { } else {
P.ParseVarSpec(); P.ParseVarSpec(exported);
} }
P.Ecart(); P.Ecart();
} }
func (P *Parser) ParseFuncDecl() { func (P *Parser) ParseFuncDecl(exported bool) {
P.Trace("FuncDecl"); P.Trace("FuncDecl");
P.Expect(Scanner.FUNC); P.Expect(Scanner.FUNC);
...@@ -1612,7 +1615,7 @@ func (P *Parser) ParseExportDecl() { ...@@ -1612,7 +1615,7 @@ func (P *Parser) ParseExportDecl() {
// TODO this needs to be clarified - the current syntax is // TODO this needs to be clarified - the current syntax is
// "everything goes" - sigh... // "everything goes" - sigh...
P.Expect(Scanner.EXPORT); //P.Expect(Scanner.EXPORT);
has_paren := false; has_paren := false;
if P.tok == Scanner.LPAREN { if P.tok == Scanner.LPAREN {
P.Next(); P.Next();
...@@ -1632,27 +1635,40 @@ func (P *Parser) ParseExportDecl() { ...@@ -1632,27 +1635,40 @@ func (P *Parser) ParseExportDecl() {
func (P *Parser) ParseDeclaration() { func (P *Parser) ParseDeclaration() {
P.Trace("Declaration"); P.Trace("Declaration");
indent := P.indent; indent := P.indent;
exported := false;
if P.tok == Scanner.EXPORT {
P.Next();
exported = true;
}
switch P.tok { switch P.tok {
case Scanner.CONST: case Scanner.CONST:
P.ParseConstDecl(); P.ParseConstDecl(exported);
case Scanner.TYPE: case Scanner.TYPE:
P.ParseTypeDecl(); P.ParseTypeDecl(exported);
case Scanner.VAR: case Scanner.VAR:
P.ParseVarDecl(); P.ParseVarDecl(exported);
case Scanner.FUNC: case Scanner.FUNC:
P.ParseFuncDecl(); P.ParseFuncDecl(exported);
case Scanner.EXPORT: case Scanner.EXPORT:
if exported {
P.Error(P.pos, "cannot mark export declaration for export");
}
P.Next();
P.ParseExportDecl(); P.ParseExportDecl();
default: default:
if exported && (P.tok == Scanner.IDENT || P.tok == Scanner.LPAREN) {
P.ParseExportDecl();
} else {
P.Error(P.pos, "declaration expected"); P.Error(P.pos, "declaration expected");
P.Next(); // make progress P.Next(); // make progress
} }
}
if indent != P.indent { if indent != P.indent {
panic "imbalanced tracing code (Declaration)" panic "imbalanced tracing code (Declaration)"
} }
P.Ecart(); P.Ecart();
} }
......
...@@ -387,8 +387,8 @@ func Init() { ...@@ -387,8 +387,8 @@ func Init() {
Keywords[TokenName(i)] = i; Keywords[TokenName(i)] = i;
} }
// r doesn't want column information in error messages... // Provide column information in error messages for gri only...
VerboseMsgs = !IsUser("r"); VerboseMsgs = IsUser("gri");
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment