successful.
R=rsc
APPROVED=rsc
DELTA=43 (31 added, 0 deleted, 12 changed)
OCL=34375
CL=34397
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 {
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;
}
// 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;
package eval
import (
+ "fmt";
"go/ast";
"go/parser";
"go/scanner";
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;
}