mirror of
https://github.com/golang/go
synced 2024-11-12 08:40:21 -07:00
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
This commit is contained in:
parent
fdf5efe43c
commit
c7d27f88f8
@ -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;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user