Commit 3dfbfdab authored by Austin Clements's avatar Austin Clements

Clean up the statement and expression public interfaces. The

only visible change is that evaluating an expression returns a
interface{} instead of a Value.

R=rsc
APPROVED=rsc
DELTA=60  (15 added, 26 deleted, 19 changed)
OCL=34206
CL=34208
parent 27c4e7e7
...@@ -131,7 +131,7 @@ func (a *expr) asMulti() (func(f *Frame) []Value) { ...@@ -131,7 +131,7 @@ func (a *expr) asMulti() (func(f *Frame) []Value) {
return a.eval.(func(*Frame)[]Value) return a.eval.(func(*Frame)[]Value)
} }
func (a *expr) asInterface() (func(f *Frame) interface{}) { func (a *expr) asInterface() (func(f *Frame) interface {}) {
switch sf := a.eval.(type) { switch sf := a.eval.(type) {
case func(*Frame)bool: case func(*Frame)bool:
return func(f *Frame) interface{} { return sf(f) }; return func(f *Frame) interface{} { return sf(f) };
...@@ -139,19 +139,30 @@ func (a *expr) asInterface() (func(f *Frame) interface{}) { ...@@ -139,19 +139,30 @@ func (a *expr) asInterface() (func(f *Frame) interface{}) {
return func(f *Frame) interface{} { return sf(f) }; return func(f *Frame) interface{} { return sf(f) };
case func(*Frame)int64: case func(*Frame)int64:
return func(f *Frame) interface{} { return sf(f) }; return func(f *Frame) interface{} { return sf(f) };
case func()*bignum.Integer:
return func(f *Frame) interface{} { return sf() };
case func(*Frame)float64: case func(*Frame)float64:
return func(f *Frame) interface{} { return sf(f) }; return func(f *Frame) interface{} { return sf(f) };
case func()*bignum.Rational:
return func(f *Frame) interface{} { return sf() };
case func(*Frame)string: case func(*Frame)string:
return func(f *Frame) interface{} { return sf(f) }; return func(f *Frame) interface{} { return sf(f) };
case func(*Frame)ArrayValue:
return func(f *Frame) interface{} { return sf(f) };
case func(*Frame)StructValue:
return func(f *Frame) interface{} { return sf(f) };
case func(*Frame)Value: case func(*Frame)Value:
return func(f *Frame) interface{} { return sf(f) }; return func(f *Frame) interface{} { return sf(f) };
case func(*Frame)Func: case func(*Frame)Func:
return func(f *Frame) interface{} { return sf(f) }; return func(f *Frame) interface{} { return sf(f) };
case func(*Frame)Slice:
return func(f *Frame) interface{} { return sf(f) };
case func(*Frame)Map: case func(*Frame)Map:
return func(f *Frame) interface{} { return sf(f) }; return func(f *Frame) interface{} { return sf(f) };
default: case func(*Frame)[]Value:
log.Crashf("unexpected expression node type %v at %v", a.t, a.pos); return func(f *Frame) interface{} { return sf(f) };
} }
log.Crashf("unexpected expression node type %v at %v", a.t, a.pos);
panic(); panic();
} }
...@@ -1918,18 +1929,22 @@ func (a *expr) extractEffect(b *block, errOp string) (func(f *Frame), *expr) { ...@@ -1918,18 +1929,22 @@ func (a *expr) extractEffect(b *block, errOp string) (func(f *Frame), *expr) {
} }
/* /*
* Testing interface * Public interface
*/ */
type Expr struct { type Expr struct {
t Type; t Type;
f func(f *Frame, out Value); f func(f *Frame) interface{};
}
func (expr *Expr) Type() Type {
return expr.t;
} }
func (expr *Expr) Eval(f *Frame) (Value, os.Error) { func (expr *Expr) Eval(f *Frame) (interface{}, os.Error) {
v := expr.t.Zero(); var res interface{};
err := Try(func() {expr.f(f, v)}); err := Try(func() {res = expr.f(f)});
return v, err; return res, err;
} }
func CompileExpr(scope *Scope, expr ast.Expr) (*Expr, os.Error) { func CompileExpr(scope *Scope, expr ast.Expr) (*Expr, os.Error) {
...@@ -1940,31 +1955,5 @@ func CompileExpr(scope *Scope, expr ast.Expr) (*Expr, os.Error) { ...@@ -1940,31 +1955,5 @@ func CompileExpr(scope *Scope, expr ast.Expr) (*Expr, os.Error) {
if ec == nil { if ec == nil {
return nil, errors.GetError(scanner.Sorted); return nil, errors.GetError(scanner.Sorted);
} }
t := ec.t; return &Expr{ec.t, ec.asInterface()}, nil;
switch e := ec.eval.(type) {
case func(*Frame)bool:
return &Expr{t, func(f *Frame, out Value) { out.(BoolValue).Set(e(f)) }}, nil;
case func(*Frame)uint64:
return &Expr{t, func(f *Frame, out Value) { out.(UintValue).Set(e(f)) }}, nil;
case func(*Frame)int64:
return &Expr{t, func(f *Frame, out Value) { out.(IntValue).Set(e(f)) }}, nil;
case func()*bignum.Integer:
return &Expr{t, func(f *Frame, out Value) { out.(*idealIntV).V = e() }}, nil;
case func(*Frame)float64:
return &Expr{t, func(f *Frame, out Value) { out.(FloatValue).Set(e(f)) }}, nil;
case func()*bignum.Rational:
return &Expr{t, func(f *Frame, out Value) { out.(*idealFloatV).V = e() }}, nil;
case func(*Frame)string:
return &Expr{t, func(f *Frame, out Value) { out.(StringValue).Set(e(f)) }}, nil;
case func(*Frame)ArrayValue:
return &Expr{t, func(f *Frame, out Value) { out.(ArrayValue).Assign(e(f)) }}, nil;
case func(*Frame)Value:
return &Expr{t, func(f *Frame, out Value) { out.(PtrValue).Set(e(f)) }}, nil;
case func(*Frame)Func:
return &Expr{t, func(f *Frame, out Value) { out.(FuncValue).Set(e(f)) }}, nil;
case func(*Frame)Slice:
return &Expr{t, func(f *Frame, out Value) { out.(SliceValue).Set(e(f)) }}, nil;
}
log.Crashf("unexpected type %v", ec.t);
panic();
} }
...@@ -1274,15 +1274,15 @@ func (a *funcCompiler) checkLabels() { ...@@ -1274,15 +1274,15 @@ func (a *funcCompiler) checkLabels() {
} }
/* /*
* Testing interface * Public interface
*/ */
type Stmt struct { type Stmt struct {
f func (f *Frame); code code;
} }
func (s *Stmt) Exec(f *Frame) os.Error { func (s *Stmt) Exec(f *Frame) os.Error {
return Try(func() {s.f(f)}); return Try(func() {s.code.exec(f)});
} }
func CompileStmts(scope *Scope, stmts []ast.Stmt) (*Stmt, os.Error) { func CompileStmts(scope *Scope, stmts []ast.Stmt) (*Stmt, os.Error) {
...@@ -1311,5 +1311,5 @@ func CompileStmts(scope *Scope, stmts []ast.Stmt) (*Stmt, os.Error) { ...@@ -1311,5 +1311,5 @@ func CompileStmts(scope *Scope, stmts []ast.Stmt) (*Stmt, os.Error) {
return nil, errors.GetError(scanner.Sorted); return nil, errors.GetError(scanner.Sorted);
} }
code := fc.get(); code := fc.get();
return &Stmt{func(f *Frame) { code.exec(f); }}, nil; return &Stmt{code}, 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