summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRobert Griesemer <gri@golang.org>2009-01-06 14:54:18 -0800
committerRobert Griesemer <gri@golang.org>2009-01-06 14:54:18 -0800
commit3d178ac4ec7ccc1afb3affd2e6205d0145c1b19b (patch)
tree4debd0e916f040ed55004dbf253e1c538203e783
parentccb7be1cf2360c56280969c2c630b2722b1a6b37 (diff)
downloadgolang-3d178ac4ec7ccc1afb3affd2e6205d0145c1b19b.tar.gz
- steps towards augmenting ast with declaration info
(will help produce html output where we can click on identifiers and get to the declaration) - snapshot before changing back to old new R=r OCL=22159 CL=22159
-rw-r--r--usr/gri/pretty/compilation.go2
-rw-r--r--usr/gri/pretty/printer.go2
-rw-r--r--usr/gri/pretty/typechecker.go110
3 files changed, 106 insertions, 8 deletions
diff --git a/usr/gri/pretty/compilation.go b/usr/gri/pretty/compilation.go
index 316835487..fb7f41600 100644
--- a/usr/gri/pretty/compilation.go
+++ b/usr/gri/pretty/compilation.go
@@ -136,7 +136,7 @@ export func Compile(src_file string, flags *Flags) (*AST.Program, int) {
prog := parser.ParseProgram();
if err.nerrors == 0 {
- TypeChecker.CheckProgram(prog);
+ TypeChecker.CheckProgram(&err, prog);
}
return prog, err.nerrors;
diff --git a/usr/gri/pretty/printer.go b/usr/gri/pretty/printer.go
index f799d0f88..cbfdc5fc8 100644
--- a/usr/gri/pretty/printer.go
+++ b/usr/gri/pretty/printer.go
@@ -846,7 +846,7 @@ func (P *Printer) Program(p *AST.Program) {
P.Expr(p.ident);
P.newlines = 1;
for i := 0; i < p.decls.Len(); i++ {
- P.Declaration(p.decls.At(i), false);
+ P.Declaration(p.decls.At(i).(*AST.Decl), false);
}
P.newlines = 1;
}
diff --git a/usr/gri/pretty/typechecker.go b/usr/gri/pretty/typechecker.go
index 1f74d8025..b7d796257 100644
--- a/usr/gri/pretty/typechecker.go
+++ b/usr/gri/pretty/typechecker.go
@@ -6,6 +6,7 @@ package TypeChecker
import (
AST "ast";
+ Scanner "scanner";
Universe "universe";
Globals "globals";
Object "object";
@@ -14,16 +15,42 @@ import (
type State struct {
+ // setup
+ err Scanner.ErrorHandler;
+
+ // state
level int;
top_scope *Globals.Scope;
}
+func (s *State) Init(err Scanner.ErrorHandler) {
+ s.err = err;
+}
+
+
// ----------------------------------------------------------------------------
// Support
+func unimplemented() {
+ panic("unimplemented");
+}
+
+
+func unreachable() {
+ panic("unreachable");
+}
+
+
+func assert(pred bool) {
+ if !pred {
+ panic("assertion failed");
+ }
+}
+
+
func (s *State) Error(pos int, msg string) {
- panicln("error:" + msg);
+ s.err.Error(pos, msg);
}
@@ -72,19 +99,87 @@ func (s *State) Declare(obj *Globals.Object) {
// ----------------------------------------------------------------------------
// Common productions
-func (s *State) DeclareIdent(kind int) {
- obj := Globals.NewObject(0, kind, "");
- s.Declare(obj);
+func (s *State) DeclareIdent(ident *AST.Expr, kind int, typ *AST.Type) {
+ // ident is either a comma-separated list or a single ident
+ switch ident.tok {
+ case Scanner.IDENT:
+ obj := Globals.NewObject(ident.pos, kind, ident.s);
+ s.Declare(obj);
+ case Scanner.COMMA:
+ s.DeclareIdent(ident.x, kind, typ);
+ s.DeclareIdent(ident.y, kind, typ);
+ default:
+ unreachable();
+ }
}
// ----------------------------------------------------------------------------
+func (s *State) CheckType() {
+}
+
+
+func (s *State) CheckDeclaration(d *AST.Decl) {
+ if d.tok != Scanner.FUNC && d.list != nil {
+ // group of parenthesized declarations
+ for i := 0; i < d.list.Len(); i++ {
+ s.CheckDeclaration(d.list.At(i).(*AST.Decl))
+ }
+
+ } else {
+ // single declaration
+ switch d.tok {
+ case Scanner.IMPORT:
+ assert(d.ident == nil || d.ident.tok == Scanner.IDENT);
+ if d.ident != nil {
+ s.DeclareIdent(d.ident, d.tok, d.typ);
+ } else {
+ }
+
+ case Scanner.EXPORT:
+ // TODO
+
+ case Scanner.CONST:
+ s.DeclareIdent(d.ident, d.tok, d.typ);
+
+ case Scanner.VAR:
+ s.DeclareIdent(d.ident, d.tok, d.typ);
+
+ case Scanner.TYPE:
+ assert(d.ident.tok == Scanner.IDENT);
+ // types may be forward-declared
+ obj := s.Lookup(d.ident.s);
+ if obj != nil {
+ // TODO check if proper forward-declaration
+
+ } else {
+ s.DeclareIdent(d.ident, d.tok, d.typ);
+ }
+
+ case Scanner.FUNC:
+ assert(d.ident.tok == Scanner.IDENT);
+ if d.typ.key != nil {
+ // method
+ // TODO
+ } else {
+ s.DeclareIdent(d.ident, d.tok, d.typ);
+ }
+
+ default:
+ unreachable();
+ }
+ }
+}
+
+
func (s *State) CheckProgram(p *AST.Program) {
s.OpenScope();
{ s.OpenScope();
-
+ for i := 0; i < p.decls.Len(); i++ {
+ s.CheckDeclaration(p.decls.At(i).(*AST.Decl));
+ }
s.CloseScope();
}
@@ -94,7 +189,10 @@ func (s *State) CheckProgram(p *AST.Program) {
// ----------------------------------------------------------------------------
-export func CheckProgram(p *AST.Program) {
+export func CheckProgram(err Scanner.ErrorHandler, p *AST.Program) {
+ return; // DISABLED FOR NOW
+
var s State;
+ s.Init(err);
s.CheckProgram(p);
}