]> Cypherpunks repositories - gostls13.git/commitdiff
Make world.Define{Const,Var} indicate if the definition was
authorAustin Clements <aclements@csail.mit.edu>
Fri, 4 Sep 2009 19:55:25 +0000 (12:55 -0700)
committerAustin Clements <aclements@csail.mit.edu>
Fri, 4 Sep 2009 19:55:25 +0000 (12:55 -0700)
successful.

R=rsc
APPROVED=rsc
DELTA=43  (31 added, 0 deleted, 12 changed)
OCL=34375
CL=34397

usr/austin/eval/scope.go
usr/austin/eval/stmt.go
usr/austin/eval/world.go

index 3fe94e4be4c6e0f6d014a9029de373386c9082b3..7e10293d5d89301cec895cfeb513380f11ec5942 100644 (file)
@@ -142,13 +142,13 @@ func (b *block) defineSlot(t Type, temp bool) *Variable {
        return v;
 }
 
-func (b *block) DefineConst(name string, pos token.Position, t Type, v Value) *Constant {
-       if _, ok := b.defs[name]; ok {
-               return nil;
+func (b *block) DefineConst(name string, pos token.Position, t Type, v Value) (*Constant, Def) {
+       if prev, ok := b.defs[name]; ok {
+               return nil, prev;
        }
        c := &Constant{pos, t, v};
        b.defs[name] = c;
-       return c;
+       return c, nil;
 }
 
 func (b *block) DefineType(name string, pos token.Position, t Type) Type {
index 0d657c1d7f7fa44a5504961e17b298d0cbe06ecc..758157827c903d38944a4a8ae253a0da041b90d9 100644 (file)
@@ -365,7 +365,7 @@ func (a *stmtCompiler) compileVarDecl(decl *ast.GenDecl) {
                                a.defineVar(n, t);
                        }
                } else {
-                       // Decalaration with assignment
+                       // Declaration with assignment
                        lhs := make([]ast.Expr, len(spec.Names));
                        for i, n := range spec.Names {
                                lhs[i] = n;
@@ -388,9 +388,17 @@ func (a *stmtCompiler) compileDecl(decl ast.Decl) {
                }
                // Declare and initialize v before compiling func
                // so that body can refer to itself.
-               c := a.block.DefineConst(d.Name.Value, a.pos, decl.Type, decl.Type.Zero());
+               c, prev := a.block.DefineConst(d.Name.Value, a.pos, decl.Type, decl.Type.Zero());
+               if prev != nil {
+                       pos := prev.Pos();
+                       if pos.IsValid() {
+                               a.diagAt(d.Name, "identifier %s redeclared in this block\n\tprevious declaration at %s", d.Name.Value, &pos);
+                       } else {
+                               a.diagAt(d.Name, "identifier %s redeclared in this block", d.Name.Value);
+                       }
+               }
                fn := a.compileFunc(a.block, decl, d.Body);
-               if fn == nil {
+               if c == nil || fn == nil {
                        return;
                }
                var zeroThread Thread;
index e3070191352b26ec924232b57bcbbd2ddd167162..6738f6b50c80c6c6f3bdf3426552ad0ab7dde3e2 100644 (file)
@@ -5,6 +5,7 @@
 package eval
 
 import (
+       "fmt";
        "go/ast";
        "go/parser";
        "go/scanner";
@@ -154,12 +155,34 @@ func (w *World) Compile(text string) (Code, os.Error) {
        return nil, err;
 }
 
-func (w *World) DefineConst(name string, t Type, val Value) {
-       w.scope.DefineConst(name, token.Position{}, t, val);
+type RedefinitionError struct {
+       Name string;
+       Prev Def;
 }
 
-func (w *World) DefineVar(name string, t Type, val Value) {
-       v, _ := w.scope.DefineVar(name, token.Position{}, t);
+func (e *RedefinitionError) String() string {
+       res := "identifier " + e.Name + " redeclared";
+       pos := e.Prev.Pos();
+       if pos.IsValid() {
+               res += "; previous declaration at " + pos.String();
+       }
+       return res;
+}
+
+func (w *World) DefineConst(name string, t Type, val Value) os.Error {
+       _, prev := w.scope.DefineConst(name, token.Position{}, t, val);
+       if prev != nil {
+               return &RedefinitionError{name, prev};
+       }
+       return nil;
+}
+
+func (w *World) DefineVar(name string, t Type, val Value) os.Error {
+       v, prev := w.scope.DefineVar(name, token.Position{}, t);
+       if prev != nil {
+               return &RedefinitionError{name, prev};
+       }
        v.Init = val;
+       return nil;
 }