//
// A client may parse the entire program (ParseProgram), only the package
// clause (ParsePackageClause), or the package clause and the import
-// declarations (ParseImportDecls). The resulting AST represents the part
-// of the program that is parsed.
+// declarations (ParseImportDecls).
//
package Parser
// ----------------------------------------------------------------------------
// Helper functions
-func unimplemented() {
- panic("unimplemented");
-}
-
-
func unreachable() {
panic("unreachable");
}
-func assert(pred bool) {
- if !pred {
- panic("assertion failed");
- }
-}
-
-
// ----------------------------------------------------------------------------
// Parsing support
}
-func (P *Parser) OptSemicolon() {
- if P.tok == token.SEMICOLON {
- P.next();
- }
-}
-
-
// ----------------------------------------------------------------------------
// Common productions
func (P *Parser) parseDeclaration() ast.Decl;
-// If scope != nil, lookup identifier in scope. Otherwise create one.
func (P *Parser) parseIdent() *ast.Ident {
if P.trace {
defer un(trace(P, "Ident"));
break;
}
}
- P.OptSemicolon();
+ if P.tok == token.SEMICOLON {
+ P.next();
+ }
end = P.pos;
P.expect(token.RBRACE);
defer un(trace(P, "StringLit"));
}
- assert(P.tok == token.STRING);
var x ast.Expr = &ast.BasicLit{P.pos, P.tok, P.val};
- P.next();
+ P.expect(token.STRING); // always satisfied
for P.tok == token.STRING {
y := &ast.BasicLit{P.pos, P.tok, P.val};
list := vector.New(0);
for P.tok == token.IMPORT {
list.Push(P.parseDecl(token.IMPORT));
- P.OptSemicolon();
+ if P.tok == token.SEMICOLON {
+ P.next();
+ }
}
return list;
list := P.parseImportDecls();
for P.tok != token.EOF {
list.Push(P.parseDeclaration());
- P.OptSemicolon();
+ if P.tok == token.SEMICOLON {
+ P.next();
+ }
}
// convert list
"token";
"ast";
"template";
+ "utf8";
+ "unicode";
SymbolTable "symboltable";
)
func (P *Printer) funcDecl(d *ast.FuncDecl, with_body bool) {
- P.Token(d.Pos_, token.FUNC);
+ P.Token(d.Pos, token.FUNC);
P.separator = blank;
if recv := d.Recv; recv != nil {
// method: print receiver
// ----------------------------------------------------------------------------
-// Interface
+// Package interface
+
+// TODO this should be an AST method
+func isExported(name *ast.Ident) bool {
+ ch, len := utf8.DecodeRuneInString(name.Str, 0);
+ return unicode.IsUpper(ch);
+}
+
func (P *Printer) Interface(p *ast.Program) {
for i := 0; i < len(p.Decls); i++ {
- decl := p.Decls[i];
- // TODO use type switch
- if fun, is_fun := decl.(*ast.FuncDecl); is_fun {
- P.funcDecl(fun, false);
+ switch d := p.Decls[i].(type) {
+ case *ast.FuncDecl:
+ if isExported(d.Ident) {
+ P.Printf("<h2>%s</h2>\n", d.Ident.Str);
+ /*
+ P.Printf("<p><code>");
+ P.funcDecl(d, false);
+ P.String(0, "");
+ P.Printf("</code></p>");
+ */
+ }
}
}
}