--- /dev/null
+# Copyright 2009 The Go Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style
+# license that can be found in the LICENSE file.
+
+include $(GOROOT)/src/Make.$(GOARCH)
+
+TARG=eval
+GOFILES=\
+ compiler.go\
+ decls.go\
+ expr.go\
+ func.go\
+ scope.go\
+ stmt.go\
+ type.go\
+ typec.go\
+ util.go\
+ value.go\
+
+include $(GOROOT)/src/Make.pkg
package eval
import (
- "eval";
"fmt";
"go/ast";
"go/scanner";
a.errors.Error(pos.Pos(), fmt.Sprintf(format, args));
}
-type FuncDecl struct
-func (a *compiler) compileFunc(b *block, decl *FuncDecl, body *ast.BlockStmt) (func (f *Frame) Func)
-type exprCompiler struct
-func (a *compiler) compileExpr(b *block, expr ast.Expr, constant bool) *exprCompiler
-type assignCompiler struct
-func (a *compiler) checkAssign(pos token.Position, rs []*exprCompiler, errOp, errPosName string) (*assignCompiler, bool)
-func (a *compiler) compileAssign(pos token.Position, lt Type, rs []*exprCompiler, errOp, errPosName string) (func(lv Value, f *Frame))
-func (a *compiler) compileType(b *block, typ ast.Expr) Type
-func (a *compiler) compileTypeDecl(b *block, decl *ast.GenDecl) bool
-func (a *compiler) compileFuncType(b *block, typ *ast.FuncType) *FuncDecl
-
-func (a *compiler) compileArrayLen(b *block, expr ast.Expr) (int64, bool)
-
type label struct {
name string;
used token.Position;
}
-type codeBuf struct
-type flowBuf struct
-type FuncType struct
// A funcCompiler captures information used throughout the compilation
// of a single function body.
type funcCompiler struct {
err bool;
}
-func (a *funcCompiler) checkLabels()
-
// A blockCompiler captures information used throughout the compilation
// of a single block within a function.
type blockCompiler struct {
parent *blockCompiler;
}
-func (a *blockCompiler) compileStmt(s ast.Stmt)
-func (a *blockCompiler) compileStmts(body *ast.BlockStmt)
-func (a *blockCompiler) enterChild() *blockCompiler
-func (a *blockCompiler) exit()
-
// An exprContext stores information used throughout the compilation
// of a single expression. It does not embed funcCompiler because
// expressions can appear at top level.
* Types
*/
-type Value interface
-
type Type interface {
// compat returns whether this type is compatible with another
// type. If conv is false, this is normal compatibility,
Set(Value);
}
-type Func interface
type FuncValue interface {
Value;
Get() Func;
Value Value;
}
-type Scope struct
-
// A block represents a definition block in which a name may not be
// defined more than once.
type block struct {
maxVars int;
}
-func (b *block) enterChild() *block
-func (b *block) exit()
-func (b *block) ChildScope() *Scope
-func (b *block) DefineVar(name string, pos token.Position, t Type) (*Variable, Def)
-func (b *block) DefineSlot(t Type) *Variable
-func (b *block) DefineConst(name string, pos token.Position, t Type, v Value) *Constant
-func (b *block) DefineType(name string, pos token.Position, t Type) Type
-func (b *block) Lookup(name string) (level int, def Def)
-
// The universal scope
func newUniverse() *Scope {
sc := &Scope{nil, 0};
Vars []Value;
}
-func (f *Frame) Get(level int, index int) Value
-func (f *Frame) child(numVars int) *Frame
-
-func (s *Scope) NewFrame(outer *Frame) *Frame
-
/*
* Functions
*/
import (
"bignum";
- "eval";
"go/ast";
"go/scanner";
"go/token";
};
}
-// Operator generators
-// TODO(austin) Remove these forward declarations
-func (a *exprCompiler) genConstant(v Value)
-func (a *exprCompiler) genIdentOp(level int, index int)
-func (a *exprCompiler) genIndexArray(l *exprCompiler, r *exprCompiler)
-func (a *exprCompiler) genFuncCall(call func(f *Frame) []Value)
-func (a *exprCompiler) genValue(vf func(*Frame) Value)
-func (a *exprCompiler) genUnaryOpNeg(v *exprCompiler)
-func (a *exprCompiler) genUnaryOpNot(v *exprCompiler)
-func (a *exprCompiler) genUnaryOpXor(v *exprCompiler)
-func (a *exprCompiler) genBinOpAdd(l *exprCompiler, r *exprCompiler)
-func (a *exprCompiler) genBinOpSub(l *exprCompiler, r *exprCompiler)
-func (a *exprCompiler) genBinOpMul(l *exprCompiler, r *exprCompiler)
-func (a *exprCompiler) genBinOpQuo(l *exprCompiler, r *exprCompiler)
-func (a *exprCompiler) genBinOpRem(l *exprCompiler, r *exprCompiler)
-func (a *exprCompiler) genBinOpAnd(l *exprCompiler, r *exprCompiler)
-func (a *exprCompiler) genBinOpOr(l *exprCompiler, r *exprCompiler)
-func (a *exprCompiler) genBinOpXor(l *exprCompiler, r *exprCompiler)
-func (a *exprCompiler) genBinOpAndNot(l *exprCompiler, r *exprCompiler)
-func (a *exprCompiler) genBinOpShl(l *exprCompiler, r *exprCompiler)
-func (a *exprCompiler) genBinOpShr(l *exprCompiler, r *exprCompiler)
-func (a *exprCompiler) genBinOpLss(l *exprCompiler, r *exprCompiler)
-func (a *exprCompiler) genBinOpGtr(l *exprCompiler, r *exprCompiler)
-func (a *exprCompiler) genBinOpLeq(l *exprCompiler, r *exprCompiler)
-func (a *exprCompiler) genBinOpGeq(l *exprCompiler, r *exprCompiler)
-func (a *exprCompiler) genBinOpEql(l *exprCompiler, r *exprCompiler)
-func (a *exprCompiler) genBinOpNeq(l *exprCompiler, r *exprCompiler)
-func genAssign(lt Type, r *exprCompiler) (func(lv Value, f *Frame))
-
func (a *exprCompiler) copy() *exprCompiler {
ec := newExprCompiler(a.exprContext, a.pos);
ec.desc = a.desc;
package eval
-import (
- "container/vector";
- "eval";
-)
-
/*
* Virtual machine
*/
package eval
import (
- "eval";
"fmt";
"go/token";
"log";
import (
"bignum";
- "eval";
"log";
"os";
"go/ast";
return v;
}
-// TODO(austin) Move the real definition
-func (a *stmtCompiler) doAssign(lhs []ast.Expr, rhs []ast.Expr, tok token.Token, declTypeExpr ast.Expr)
+// TODO(austin) Move doAssign to here
/*
* Statement visitors
import (
"bignum";
- "eval";
"go/ast";
"go/token";
"log";
return "<bool>";
}
-func (t *boolType) Zero() Value
+func (t *boolType) Zero() Value {
+ res := boolV(false);
+ return &res;
+}
/*
* Uint
return "<" + t.name + ">";
}
-func (t *uintType) Zero() Value
+func (t *uintType) Zero() Value {
+ switch t.Bits {
+ case 0:
+ if t.Ptr {
+ res := uintptrV(0);
+ return &res;
+ } else {
+ res := uintV(0);
+ return &res;
+ }
+ case 8:
+ res := uint8V(0);
+ return &res;
+ case 16:
+ res := uint16V(0);
+ return &res;
+ case 32:
+ res := uint32V(0);
+ return &res;
+ case 64:
+ res := uint64V(0);
+ return &res;
+ }
+ panic("unexpected uint bit count: ", t.Bits);
+}
func (t *uintType) minVal() *bignum.Rational {
return bignum.Rat(0, 1);
return "<" + t.name + ">";
}
-func (t *intType) Zero() Value
+func (t *intType) Zero() Value {
+ switch t.Bits {
+ case 8:
+ res := int8V(0);
+ return &res;
+ case 16:
+ res := int16V(0);
+ return &res;
+ case 32:
+ res := int32V(0);
+ return &res;
+ case 64:
+ res := int64V(0);
+ return &res;
+
+ case 0:
+ res := intV(0);
+ return &res;
+ }
+ panic("unexpected int bit count: ", t.Bits);
+}
func (t *intType) minVal() *bignum.Rational {
bits := t.Bits;
return "ideal integer";
}
-func (t *idealIntType) Zero() Value
+func (t *idealIntType) Zero() Value {
+ return &idealIntV{bignum.Int(0)};
+}
/*
* Float
return "<" + t.name + ">";
}
-func (t *floatType) Zero() Value
+func (t *floatType) Zero() Value {
+ switch t.Bits {
+ case 32:
+ res := float32V(0);
+ return &res;
+ case 64:
+ res := float64V(0);
+ return &res;
+ case 0:
+ res := floatV(0);
+ return &res;
+ }
+ panic("unexpected float bit count: ", t.Bits);
+}
var maxFloat32Val = bignum.MakeRat(bignum.Int(0xffffff).Shl(127-23), bignum.Nat(1));
var maxFloat64Val = bignum.MakeRat(bignum.Int(0x1fffffffffffff).Shl(1023-52), bignum.Nat(1));
return "ideal float";
}
-func (t *idealFloatType) Zero() Value
+func (t *idealFloatType) Zero() Value {
+ return &idealFloatV{bignum.Rat(1, 0)};
+}
/*
* String
return "<string>";
}
-func (t *stringType) Zero() Value
+func (t *stringType) Zero() Value {
+ res := stringV("");
+ return &res;
+}
/*
* Array
return "[]" + t.Elem.String();
}
-func (t *ArrayType) Zero() Value
+func (t *ArrayType) Zero() Value {
+ res := arrayV(make([]Value, t.Len));
+ // TODO(austin) It's unfortunate that each element is
+ // separately heap allocated. We could add ZeroArray to
+ // everything, though that doesn't help with multidimensional
+ // arrays. Or we could do something unsafe. We'll have this
+ // same problem with structs.
+ for i := int64(0); i < t.Len; i++ {
+ res[i] = t.Elem.Zero();
+ }
+ return &res;
+}
/*
* Struct
return s + "}";
}
-func (t *StructType) Zero() Value
+func (t *StructType) Zero() Value {
+ res := structV(make([]Value, len(t.Elems)));
+ for i, f := range t.Elems {
+ res[i] = f.Type.Zero();
+ }
+ return &res;
+}
/*
* Pointer
return "*" + t.Elem.String();
}
-func (t *PtrType) Zero() Value
+func (t *PtrType) Zero() Value {
+ return &ptrV{nil};
+}
/*
* Function
return s;
}
-func (t *FuncType) Zero() Value
+func (t *FuncType) Zero() Value {
+ return &funcV{nil};
+}
type FuncDecl struct {
Type *FuncType;
return typeListString(t.Elems, nil);
}
-func (t *MultiType) Zero() Value
+func (t *MultiType) Zero() Value {
+ res := make([]Value, len(t.Elems));
+ for i, t := range t.Elems {
+ res[i] = t.Zero();
+ }
+ return multiV(res);
+}
package eval
import (
- "eval";
"go/ast";
"go/token";
"log";
* Type compiler
*/
-// TODO(austin) Without this, I get a "conflicting definitions for
-// eval.compiler" when gopack'ing typec.6 from gobuild.
-// Interestingly, if I create the Makefile with this line, then
-// comment it out and use the Makefile, things work.
-type exprCompiler struct
-
type typeCompiler struct {
*compiler;
block *block;
lateCheck func() bool
}
-func (a *typeCompiler) compileType(x ast.Expr, allowRec bool) Type
-
func (a *typeCompiler) compileIdent(x *ast.Ident, allowRec bool) Type {
_, def := a.block.Lookup(x.Value);
if def == nil {
import (
"bignum";
- "eval";
"fmt";
"go/token";
)
import (
"bignum";
- "eval";
"fmt";
)
*v = boolV(x);
}
-func (t *boolType) Zero() Value {
- res := boolV(false);
- return &res;
-}
-
/*
* Uint
*/
*v = uintptrV(x);
}
-func (t *uintType) Zero() Value {
- switch t.Bits {
- case 0:
- if t.Ptr {
- res := uintptrV(0);
- return &res;
- } else {
- res := uintV(0);
- return &res;
- }
- case 8:
- res := uint8V(0);
- return &res;
- case 16:
- res := uint16V(0);
- return &res;
- case 32:
- res := uint32V(0);
- return &res;
- case 64:
- res := uint64V(0);
- return &res;
- }
- panic("unexpected uint bit count: ", t.Bits);
-}
-
/*
* Int
*/
*v = intV(x);
}
-func (t *intType) Zero() Value {
- switch t.Bits {
- case 8:
- res := int8V(0);
- return &res;
- case 16:
- res := int16V(0);
- return &res;
- case 32:
- res := int32V(0);
- return &res;
- case 64:
- res := int64V(0);
- return &res;
-
- case 0:
- res := intV(0);
- return &res;
- }
- panic("unexpected int bit count: ", t.Bits);
-}
-
/*
* Ideal int
*/
return v.V;
}
-func (t *idealIntType) Zero() Value {
- return &idealIntV{bignum.Int(0)};
-}
-
/*
* Float
*/
*v = floatV(x);
}
-func (t *floatType) Zero() Value {
- switch t.Bits {
- case 32:
- res := float32V(0);
- return &res;
- case 64:
- res := float64V(0);
- return &res;
- case 0:
- res := floatV(0);
- return &res;
- }
- panic("unexpected float bit count: ", t.Bits);
-}
-
/*
* Ideal float
*/
return v.V;
}
-func (t *idealFloatType) Zero() Value {
- return &idealFloatV{bignum.Rat(1, 0)};
-}
-
/*
* String
*/
*v = stringV(x);
}
-func (t *stringType) Zero() Value {
- res := stringV("");
- return &res;
-}
-
/*
* Array
*/
return (*v)[i];
}
-func (t *ArrayType) Zero() Value {
- res := arrayV(make([]Value, t.Len));
- // TODO(austin) It's unfortunate that each element is
- // separately heap allocated. We could add ZeroArray to
- // everything, though that doesn't help with multidimensional
- // arrays. Or we could do something unsafe. We'll have this
- // same problem with structs.
- for i := int64(0); i < t.Len; i++ {
- res[i] = t.Elem.Zero();
- }
- return &res;
-}
-
/*
* Struct
*/
return (*v)[i];
}
-func (t *StructType) Zero() Value {
- res := structV(make([]Value, len(t.Elems)));
- for i, f := range t.Elems {
- res[i] = f.Type.Zero();
- }
- return &res;
-}
-
/*
* Pointer
*/
v.target = x;
}
-func (t *PtrType) Zero() Value {
- return &ptrV{nil};
-}
-
/*
* Functions
*/
v.target = x;
}
-func (t *FuncType) Zero() Value {
- return &funcV{nil};
-}
-
/*
* Multi-values
*/
}
}
-func (t *MultiType) Zero() Value {
- res := make([]Value, len(t.Elems));
- for i, t := range t.Elems {
- res[i] = t.Zero();
- }
- return multiV(res);
-}
-
/*
* Universal constants
*/