Commit c7d27f88 authored by Austin Clements's avatar Austin Clements

Make world.Define{Const,Var} indicate if the definition was

successful.

R=rsc
APPROVED=rsc
DELTA=43  (31 added, 0 deleted, 12 changed)
OCL=34375
CL=34397
parent fdf5efe4
......@@ -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 {
......
......@@ -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;
......
......@@ -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;
}
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