Skip to content
Projects
Groups
Snippets
Help
Loading...
Sign in
Toggle navigation
G
golang
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Commits
Issue Boards
Open sidebar
go
golang
Commits
9e48df68
Commit
9e48df68
authored
Nov 05, 2009
by
Robert Griesemer
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
gofmt-ify eval
R=rsc
http://go/go-review/1016054
parent
d2af7313
Expand all
Show whitespace changes
Inline
Side-by-side
Showing
17 changed files
with
209 additions
and
235 deletions
+209
-235
abort.go
src/pkg/exp/eval/abort.go
+3
-3
bridge.go
src/pkg/exp/eval/bridge.go
+6
-6
compiler.go
src/pkg/exp/eval/compiler.go
+4
-3
eval_test.go
src/pkg/exp/eval/eval_test.go
+24
-25
expr.go
src/pkg/exp/eval/expr.go
+32
-52
expr1.go
src/pkg/exp/eval/expr1.go
+0
-0
expr_test.go
src/pkg/exp/eval/expr_test.go
+21
-21
func.go
src/pkg/exp/eval/func.go
+1
-1
gen.go
src/pkg/exp/eval/gen.go
+39
-39
main.go
src/pkg/exp/eval/main.go
+1
-2
scope.go
src/pkg/exp/eval/scope.go
+6
-6
stmt.go
src/pkg/exp/eval/stmt.go
+25
-29
stmt_test.go
src/pkg/exp/eval/stmt_test.go
+5
-5
type.go
src/pkg/exp/eval/type.go
+29
-29
typec.go
src/pkg/exp/eval/typec.go
+3
-3
value.go
src/pkg/exp/eval/value.go
+6
-6
world.go
src/pkg/exp/eval/world.go
+4
-5
No files found.
src/pkg/exp/eval/abort.go
View file @
9e48df68
...
...
@@ -35,13 +35,13 @@ func (t *Thread) Try(f func(t *Thread)) os.Error {
return
err
;
}
type
DivByZeroError
struct
{}
type
DivByZeroError
struct
{}
func
(
DivByZeroError
)
String
()
string
{
return
"divide by zero"
;
}
type
NilPointerError
struct
{}
type
NilPointerError
struct
{}
func
(
NilPointerError
)
String
()
string
{
return
"nil pointer dereference"
;
...
...
@@ -67,7 +67,7 @@ func (e SliceError) String() string {
}
type
KeyError
struct
{
Key
interface
{};
Key
interface
{};
}
func
(
e
KeyError
)
String
()
string
{
...
...
src/pkg/exp/eval/bridge.go
View file @
9e48df68
...
...
@@ -15,8 +15,8 @@ import (
*/
var
(
evalTypes
=
make
(
map
[
reflect
.
Type
]
Type
);
nativeTypes
=
make
(
map
[
Type
]
reflect
.
Type
);
evalTypes
=
make
(
map
[
reflect
.
Type
]
Type
);
nativeTypes
=
make
(
map
[
Type
]
reflect
.
Type
);
)
// TypeFromNative converts a regular Go type into a the corresponding
...
...
@@ -29,7 +29,7 @@ func TypeFromNative(t reflect.Type) Type {
var
nt
*
NamedType
;
if
t
.
Name
()
!=
""
{
name
:=
t
.
PkgPath
()
+
"·"
+
t
.
Name
();
nt
=
&
NamedType
{
token
.
Position
{},
name
,
nil
,
true
,
make
(
map
[
string
]
Method
)};
nt
=
&
NamedType
{
token
.
Position
{},
name
,
nil
,
true
,
make
(
map
[
string
]
Method
)};
evalTypes
[
t
]
=
nt
;
}
...
...
@@ -77,7 +77,7 @@ func TypeFromNative(t reflect.Type) Type {
// Variadic functions have DotDotDotType at the end
varidic
:=
false
;
if
nin
>
0
{
if
_
,
ok
:=
t
.
In
(
nin
-
1
)
.
(
*
reflect
.
DotDotDotType
);
ok
{
if
_
,
ok
:=
t
.
In
(
nin
-
1
)
.
(
*
reflect
.
DotDotDotType
);
ok
{
varidic
=
true
;
nin
--
;
}
...
...
@@ -130,7 +130,7 @@ func TypeFromNative(t reflect.Type) Type {
}
// TypeOfNative returns the interpreter Type of a regular Go value.
func
TypeOfNative
(
v
interface
{})
Type
{
func
TypeOfNative
(
v
interface
{})
Type
{
return
TypeFromNative
(
reflect
.
Typeof
(
v
));
}
...
...
@@ -149,7 +149,7 @@ func (f *nativeFunc) NewFrame() *Frame {
}
func
(
f
*
nativeFunc
)
Call
(
t
*
Thread
)
{
f
.
fn
(
t
,
t
.
f
.
Vars
[
0
:
f
.
in
],
t
.
f
.
Vars
[
f
.
in
:
f
.
in
+
f
.
out
]);
f
.
fn
(
t
,
t
.
f
.
Vars
[
0
:
f
.
in
],
t
.
f
.
Vars
[
f
.
in
:
f
.
in
+
f
.
out
]);
}
// FuncFromNative creates an interpreter function from a native
...
...
src/pkg/exp/eval/compiler.go
View file @
9e48df68
...
...
@@ -43,11 +43,12 @@ func newUniverse() *Scope {
offset
:
0
,
scope
:
sc
,
global
:
true
,
defs
:
make
(
map
[
string
]
Def
)
defs
:
make
(
map
[
string
]
Def
),
};
return
sc
;
}
var
universe
*
Scope
=
newUniverse
();
var
universe
*
Scope
=
newUniverse
()
// TODO(austin) These can all go in stmt.go now
...
...
@@ -80,7 +81,7 @@ type funcCompiler struct {
outVarsNamed
bool
;
*
codeBuf
;
flow
*
flowBuf
;
labels
map
[
string
]
*
label
;
labels
map
[
string
]
*
label
;
}
// A blockCompiler captures information used throughout the compilation
...
...
src/pkg/exp/eval/eval_test.go
View file @
9e48df68
...
...
@@ -16,6 +16,7 @@ import (
// Print each statement or expression before parsing it
var
noisy
=
false
func
init
()
{
flag
.
BoolVar
(
&
noisy
,
"noisy"
,
false
,
"chatter during eval tests"
);
}
...
...
@@ -104,37 +105,37 @@ func match(t *testing.T, err os.Error, pat string) bool {
// Expression compile error
func
CErr
(
expr
string
,
cerr
string
)
test
{
return
test
([]
job
{
job
{
code
:
expr
,
cerr
:
cerr
}})
return
test
([]
job
{
job
{
code
:
expr
,
cerr
:
cerr
}})
;
}
// Expression runtime error
func
RErr
(
expr
string
,
rterr
string
)
test
{
return
test
([]
job
{
job
{
code
:
expr
,
rterr
:
rterr
}})
return
test
([]
job
{
job
{
code
:
expr
,
rterr
:
rterr
}})
;
}
// Expression value
func
Val
(
expr
string
,
val
interface
{})
test
{
return
test
([]
job
{
job
{
code
:
expr
,
val
:
toValue
(
val
)}})
return
test
([]
job
{
job
{
code
:
expr
,
val
:
toValue
(
val
)}})
;
}
// Statement runs without error
func
Run
(
stmts
string
)
test
{
return
test
([]
job
{
job
{
code
:
stmts
,
noval
:
true
}})
return
test
([]
job
{
job
{
code
:
stmts
,
noval
:
true
}})
;
}
// Two statements without error.
// TODO(rsc): Should be possible with Run but the parser
// won't let us do both top-level and non-top-level statements.
func
Run2
(
stmt1
,
stmt2
string
)
test
{
return
test
([]
job
{
job
{
code
:
stmt1
,
noval
:
true
},
job
{
code
:
stmt2
,
noval
:
true
}})
return
test
([]
job
{
job
{
code
:
stmt1
,
noval
:
true
},
job
{
code
:
stmt2
,
noval
:
true
}})
;
}
// Statement runs and test one expression's value
func
Val1
(
stmts
string
,
expr1
string
,
val1
interface
{})
test
{
return
test
([]
job
{
job
{
code
:
stmts
,
noval
:
true
},
job
{
code
:
expr1
,
val
:
toValue
(
val1
)}
})
job
{
code
:
expr1
,
val
:
toValue
(
val1
)}
,
})
;
}
// Statement runs and test two expressions' values
...
...
@@ -142,8 +143,8 @@ func Val2(stmts string, expr1 string, val1 interface{}, expr2 string, val2 inter
return
test
([]
job
{
job
{
code
:
stmts
,
noval
:
true
},
job
{
code
:
expr1
,
val
:
toValue
(
val1
)},
job
{
code
:
expr2
,
val
:
toValue
(
val2
)}
})
job
{
code
:
expr2
,
val
:
toValue
(
val2
)}
,
})
;
}
/*
...
...
@@ -210,24 +211,24 @@ func toValue(val interface{}) Value {
* Default test scope
*/
type
testFunc
struct
{};
type
testFunc
struct
{}
func
(
*
testFunc
)
NewFrame
()
*
Frame
{
return
&
Frame
{
nil
,
&
[
2
]
Value
{}};
return
&
Frame
{
nil
,
&
[
2
]
Value
{}};
}
func
(
*
testFunc
)
Call
(
t
*
Thread
)
{
n
:=
t
.
f
.
Vars
[
0
]
.
(
IntValue
)
.
Get
(
t
);
res
:=
n
+
1
;
res
:=
n
+
1
;
t
.
f
.
Vars
[
1
]
.
(
IntValue
)
.
Set
(
t
,
res
);
}
type
oneTwoFunc
struct
{};
type
oneTwoFunc
struct
{}
func
(
*
oneTwoFunc
)
NewFrame
()
*
Frame
{
return
&
Frame
{
nil
,
&
[
2
]
Value
{}};
return
&
Frame
{
nil
,
&
[
2
]
Value
{}};
}
func
(
*
oneTwoFunc
)
Call
(
t
*
Thread
)
{
...
...
@@ -235,10 +236,10 @@ func (*oneTwoFunc) Call(t *Thread) {
t
.
f
.
Vars
[
1
]
.
(
IntValue
)
.
Set
(
t
,
2
);
}
type
voidFunc
struct
{};
type
voidFunc
struct
{}
func
(
*
voidFunc
)
NewFrame
()
*
Frame
{
return
&
Frame
{
nil
,
[]
Value
{}};
return
&
Frame
{
nil
,
[]
Value
{}};
}
func
(
*
voidFunc
)
Call
(
t
*
Thread
)
{
...
...
@@ -247,9 +248,7 @@ func (*voidFunc) Call(t *Thread) {
func
newTestWorld
()
*
World
{
w
:=
NewWorld
();
def
:=
func
(
name
string
,
t
Type
,
val
interface
{})
{
w
.
DefineVar
(
name
,
t
,
toValue
(
val
));
};
def
:=
func
(
name
string
,
t
Type
,
val
interface
{})
{
w
.
DefineVar
(
name
,
t
,
toValue
(
val
))
};
w
.
DefineConst
(
"c"
,
IdealIntType
,
toValue
(
bignum
.
Int
(
1
)));
def
(
"i"
,
IntType
,
1
);
...
...
@@ -257,13 +256,13 @@ func newTestWorld() *World {
def
(
"u"
,
UintType
,
uint
(
1
));
def
(
"f"
,
FloatType
,
1.0
);
def
(
"s"
,
StringType
,
"abc"
);
def
(
"t"
,
NewStructType
([]
StructField
{
StructField
{
"a"
,
IntType
,
false
}}),
vstruct
{
1
});
def
(
"t"
,
NewStructType
([]
StructField
{
StructField
{
"a"
,
IntType
,
false
}}),
vstruct
{
1
});
def
(
"ai"
,
NewArrayType
(
2
,
IntType
),
varray
{
1
,
2
});
def
(
"aai"
,
NewArrayType
(
2
,
NewArrayType
(
2
,
IntType
)),
varray
{
varray
{
1
,
2
},
varray
{
3
,
4
}});
def
(
"aai2"
,
NewArrayType
(
2
,
NewArrayType
(
2
,
IntType
)),
varray
{
varray
{
5
,
6
},
varray
{
7
,
8
}});
def
(
"fn"
,
NewFuncType
([]
Type
{
IntType
},
false
,
[]
Type
{
IntType
}),
&
testFunc
{});
def
(
"oneTwo"
,
NewFuncType
([]
Type
{},
false
,
[]
Type
{
IntType
,
IntType
}),
&
oneTwoFunc
{});
def
(
"void"
,
NewFuncType
([]
Type
{},
false
,
[]
Type
{}),
&
voidFunc
{});
def
(
"aai"
,
NewArrayType
(
2
,
NewArrayType
(
2
,
IntType
)),
varray
{
varray
{
1
,
2
},
varray
{
3
,
4
}});
def
(
"aai2"
,
NewArrayType
(
2
,
NewArrayType
(
2
,
IntType
)),
varray
{
varray
{
5
,
6
},
varray
{
7
,
8
}});
def
(
"fn"
,
NewFuncType
([]
Type
{
IntType
},
false
,
[]
Type
{
IntType
}),
&
testFunc
{});
def
(
"oneTwo"
,
NewFuncType
([]
Type
{},
false
,
[]
Type
{
IntType
,
IntType
}),
&
oneTwoFunc
{});
def
(
"void"
,
NewFuncType
([]
Type
{},
false
,
[]
Type
{}),
&
voidFunc
{});
def
(
"sli"
,
NewSliceType
(
IntType
),
vslice
{
varray
{
1
,
2
,
3
},
2
,
3
});
return
w
;
...
...
src/pkg/exp/eval/expr.go
View file @
9e48df68
...
...
@@ -175,9 +175,7 @@ func (a *expr) convertToInt(max int64, negErr string, errOp string) *expr {
// Convert to int
na
:=
a
.
newExpr
(
IntType
,
a
.
desc
);
af
:=
a
.
asUint
();
na
.
eval
=
func
(
t
*
Thread
)
int64
{
return
int64
(
af
(
t
));
};
na
.
eval
=
func
(
t
*
Thread
)
int64
{
return
int64
(
af
(
t
))
};
return
na
;
case
*
intType
:
...
...
@@ -296,7 +294,7 @@ func (a *assignCompiler) allowMapForms(nls int) {
// Update unpacking info if this is r, ok = a[x]
if
nls
==
2
&&
len
(
a
.
rs
)
==
1
&&
a
.
rs
[
0
]
!=
nil
&&
a
.
rs
[
0
]
.
evalMapValue
!=
nil
{
a
.
isUnpack
=
true
;
a
.
rmt
=
NewMultiType
([]
Type
{
a
.
rs
[
0
]
.
t
,
BoolType
});
a
.
rmt
=
NewMultiType
([]
Type
{
a
.
rs
[
0
]
.
t
,
BoolType
});
a
.
isMapUnpack
=
true
;
}
}
...
...
@@ -355,13 +353,11 @@ func (a *assignCompiler) compile(b *block, lt Type) (func(Value, *Thread)) {
found
=
boolV
(
false
);
v
=
vt
.
Zero
();
}
t
.
f
.
Vars
[
tempIdx
]
=
multiV
([]
Value
{
v
,
&
found
});
t
.
f
.
Vars
[
tempIdx
]
=
multiV
([]
Value
{
v
,
&
found
});
};
}
else
{
rf
:=
a
.
rs
[
0
]
.
asMulti
();
effect
=
func
(
t
*
Thread
)
{
t
.
f
.
Vars
[
tempIdx
]
=
multiV
(
rf
(
t
));
};
effect
=
func
(
t
*
Thread
)
{
t
.
f
.
Vars
[
tempIdx
]
=
multiV
(
rf
(
t
))
};
}
orig
:=
a
.
rs
[
0
];
a
.
rs
=
make
([]
*
expr
,
len
(
a
.
rmt
.
Elems
));
...
...
@@ -836,10 +832,10 @@ func (a *exprInfo) compileSelectorExpr(v *expr, name string) *expr {
default
:
log
.
Crashf
(
"Marked field at depth %d, but already found one at depth %d"
,
depth
,
bestDepth
);
}
amberr
+=
"
\n\t
"
+
pathName
[
1
:
len
(
pathName
)];
amberr
+=
"
\n\t
"
+
pathName
[
1
:
len
(
pathName
)];
};
visited
:=
make
(
map
[
Type
]
bool
);
visited
:=
make
(
map
[
Type
]
bool
);
// find recursively searches for the named field, starting at
// type t. If it finds the named field, it returns a function
...
...
@@ -851,8 +847,8 @@ func (a *exprInfo) compileSelectorExpr(v *expr, name string) *expr {
// TODO(austin) Now that the expression compiler works on
// semantic values instead of AST's, there should be a much
// better way of doing this.
var
find
func
(
Type
,
int
,
string
)
(
func
(
*
expr
)
*
expr
);
find
=
func
(
t
Type
,
depth
int
,
pathName
string
)
(
func
(
*
expr
)
*
expr
)
{
var
find
func
(
Type
,
int
,
string
)
(
func
(
*
expr
)
*
expr
);
find
=
func
(
t
Type
,
depth
int
,
pathName
string
)
(
func
(
*
expr
)
*
expr
)
{
// Don't bother looking if we've found something shallower
if
bestDepth
!=
-
1
&&
bestDepth
<
depth
{
return
nil
;
...
...
@@ -875,7 +871,7 @@ func (a *exprInfo) compileSelectorExpr(v *expr, name string) *expr {
if
ti
,
ok
:=
t
.
(
*
NamedType
);
ok
{
_
,
ok
:=
ti
.
methods
[
name
];
if
ok
{
mark
(
depth
,
pathName
+
"."
+
name
);
mark
(
depth
,
pathName
+
"."
+
name
);
log
.
Crash
(
"Methods not implemented"
);
}
t
=
ti
.
Def
;
...
...
@@ -888,7 +884,7 @@ func (a *exprInfo) compileSelectorExpr(v *expr, name string) *expr {
var
sub
func
(
*
expr
)
*
expr
;
switch
{
case
f
.
Name
==
name
:
mark
(
depth
,
pathName
+
"."
+
name
);
mark
(
depth
,
pathName
+
"."
+
name
);
sub
=
func
(
e
*
expr
)
*
expr
{
return
e
};
case
f
.
Anonymous
:
...
...
@@ -911,9 +907,7 @@ func (a *exprInfo) compileSelectorExpr(v *expr, name string) *expr {
}
expr
:=
a
.
newExpr
(
ft
,
"selector expression"
);
pf
:=
parent
.
asStruct
();
evalAddr
:=
func
(
t
*
Thread
)
Value
{
return
pf
(
t
)
.
Field
(
t
,
index
);
};
evalAddr
:=
func
(
t
*
Thread
)
Value
{
return
pf
(
t
)
.
Field
(
t
,
index
)
};
expr
.
genValue
(
evalAddr
);
return
sub
(
expr
);
};
...
...
@@ -983,7 +977,7 @@ func (a *exprInfo) compileSliceExpr(arr, lo, hi *expr) *expr {
if
lo
>
hi
||
hi
>
bound
||
lo
<
0
{
t
.
Abort
(
SliceError
{
lo
,
hi
,
bound
});
}
return
Slice
{
arr
.
Sub
(
lo
,
bound
-
lo
),
hi
-
lo
,
bound
-
lo
}
return
Slice
{
arr
.
Sub
(
lo
,
bound
-
lo
),
hi
-
lo
,
bound
-
lo
};
};
case
*
SliceType
:
...
...
@@ -993,7 +987,7 @@ func (a *exprInfo) compileSliceExpr(arr, lo, hi *expr) *expr {
if
lo
>
hi
||
hi
>
arr
.
Cap
||
lo
<
0
{
t
.
Abort
(
SliceError
{
lo
,
hi
,
arr
.
Cap
});
}
return
Slice
{
arr
.
Base
.
Sub
(
lo
,
arr
.
Cap
-
lo
),
hi
-
lo
,
arr
.
Cap
-
lo
}
return
Slice
{
arr
.
Base
.
Sub
(
lo
,
arr
.
Cap
-
lo
),
hi
-
lo
,
arr
.
Cap
-
lo
};
};
case
*
stringType
:
...
...
@@ -1007,7 +1001,7 @@ func (a *exprInfo) compileSliceExpr(arr, lo, hi *expr) *expr {
t
.
Abort
(
SliceError
{
lo
,
hi
,
int64
(
len
(
arr
))});
}
return
arr
[
lo
:
hi
];
}
}
;
default
:
log
.
Crashf
(
"unexpected left operand type %T"
,
arr
.
t
.
lit
());
...
...
@@ -1108,7 +1102,7 @@ func (a *exprInfo) compileIndexExpr(l, r *expr) *expr {
t
.
Abort
(
IndexError
{
r
,
int64
(
len
(
l
))});
}
return
uint64
(
l
[
r
]);
}
}
;
case
*
MapType
:
lf
:=
l
.
asMap
();
...
...
@@ -1181,7 +1175,7 @@ func (a *exprInfo) compileCallExpr(b *block, l *expr, as []*expr) *expr {
expr
:=
a
.
newExpr
(
t
,
"function call"
);
// Gather argument and out types to initialize frame variables
vts
:=
make
([]
Type
,
nin
+
nout
);
vts
:=
make
([]
Type
,
nin
+
nout
);
for
i
,
t
:=
range
lt
.
In
{
vts
[
i
]
=
t
;
}
...
...
@@ -1202,7 +1196,7 @@ func (a *exprInfo) compileCallExpr(b *block, l *expr, as []*expr) *expr {
t
.
f
=
fr
;
fun
.
Call
(
t
);
t
.
f
=
oldf
;
return
fr
.
Vars
[
nin
:
nin
+
nout
];
return
fr
.
Vars
[
nin
:
nin
+
nout
];
};
expr
.
genFuncCall
(
call
);
...
...
@@ -1233,15 +1227,11 @@ func (a *exprInfo) compileBuiltinCallExpr(b *block, ft *FuncType, as []*expr) *e
// TODO(austin) It would be nice if this could
// be a constant int.
v
:=
t
.
Len
;
expr
.
eval
=
func
(
t
*
Thread
)
int64
{
return
v
;
};
expr
.
eval
=
func
(
t
*
Thread
)
int64
{
return
v
};
case
*
SliceType
:
vf
:=
arg
.
asSlice
();
expr
.
eval
=
func
(
t
*
Thread
)
int64
{
return
vf
(
t
)
.
Cap
;
};
expr
.
eval
=
func
(
t
*
Thread
)
int64
{
return
vf
(
t
)
.
Cap
};
//case *ChanType:
...
...
@@ -1260,23 +1250,17 @@ func (a *exprInfo) compileBuiltinCallExpr(b *block, ft *FuncType, as []*expr) *e
switch
t
:=
arg
.
t
.
lit
()
.
(
type
)
{
case
*
stringType
:
vf
:=
arg
.
asString
();
expr
.
eval
=
func
(
t
*
Thread
)
int64
{
return
int64
(
len
(
vf
(
t
)));
};
expr
.
eval
=
func
(
t
*
Thread
)
int64
{
return
int64
(
len
(
vf
(
t
)))
};
case
*
ArrayType
:
// TODO(austin) It would be nice if this could
// be a constant int.
v
:=
t
.
Len
;
expr
.
eval
=
func
(
t
*
Thread
)
int64
{
return
v
;
};
expr
.
eval
=
func
(
t
*
Thread
)
int64
{
return
v
};
case
*
SliceType
:
vf
:=
arg
.
asSlice
();
expr
.
eval
=
func
(
t
*
Thread
)
int64
{
return
vf
(
t
)
.
Len
;
};
expr
.
eval
=
func
(
t
*
Thread
)
int64
{
return
vf
(
t
)
.
Len
};
case
*
MapType
:
vf
:=
arg
.
asMap
();
...
...
@@ -1398,13 +1382,11 @@ func (a *exprInfo) compileBuiltinCallExpr(b *block, ft *FuncType, as []*expr) *e
t
:=
as
[
0
]
.
valType
;
expr
:=
a
.
newExpr
(
NewPtrType
(
t
),
"new"
);
expr
.
eval
=
func
(
*
Thread
)
Value
{
return
t
.
Zero
();
};
expr
.
eval
=
func
(
*
Thread
)
Value
{
return
t
.
Zero
()
};
return
expr
;
case
panicType
,
paniclnType
,
printType
,
printlnType
:
evals
:=
make
([]
func
(
*
Thread
)
interface
{},
len
(
as
));
evals
:=
make
([]
func
(
*
Thread
)
interface
{},
len
(
as
));
for
i
,
x
:=
range
as
{
evals
[
i
]
=
x
.
asInterface
();
}
...
...
@@ -1416,7 +1398,9 @@ func (a *exprInfo) compileBuiltinCallExpr(b *block, ft *FuncType, as []*expr) *e
print
(
" "
);
}
v
:=
eval
(
t
);
type
stringer
interface
{
String
()
string
}
type
stringer
interface
{
String
()
string
;
}
switch
v1
:=
v
.
(
type
)
{
case
bool
:
print
(
v1
);
...
...
@@ -1444,7 +1428,7 @@ func (a *exprInfo) compileBuiltinCallExpr(b *block, ft *FuncType, as []*expr) *e
expr
.
exec
=
func
(
t
*
Thread
)
{
printer
(
t
);
t
.
Abort
(
os
.
NewError
(
"panic"
));
}
}
;
}
return
expr
;
}
...
...
@@ -1472,7 +1456,7 @@ func (a *exprInfo) compileStarExpr(v *expr) *expr {
return
nil
;
}
var
unaryOpDescs
=
make
(
map
[
token
.
Token
]
string
)
var
unaryOpDescs
=
make
(
map
[
token
.
Token
]
string
)
func
(
a
*
exprInfo
)
compileUnaryExpr
(
op
token
.
Token
,
v
*
expr
)
*
expr
{
// Type check
...
...
@@ -1556,7 +1540,7 @@ func (a *exprInfo) compileUnaryExpr(op token.Token, v *expr) *expr {
return
expr
;
}
var
binOpDescs
=
make
(
map
[
token
.
Token
]
string
)
var
binOpDescs
=
make
(
map
[
token
.
Token
]
string
)
func
(
a
*
exprInfo
)
compileBinaryExpr
(
op
token
.
Token
,
l
,
r
*
expr
)
*
expr
{
// Save the original types of l.t and r.t for error messages.
...
...
@@ -1607,15 +1591,11 @@ func (a *exprInfo) compileBinaryExpr(op token.Token, l, r *expr) *expr {
// Useful type predicates
// TODO(austin) CL 33668 mandates identical types except for comparisons.
compat
:=
func
()
bool
{
return
l
.
t
.
compat
(
r
.
t
,
false
);
};
compat
:=
func
()
bool
{
return
l
.
t
.
compat
(
r
.
t
,
false
)
};
integers
:=
func
()
bool
{
return
l
.
t
.
isInteger
()
&&
r
.
t
.
isInteger
();
};
floats
:=
func
()
bool
{
return
l
.
t
.
isFloat
()
&&
r
.
t
.
isFloat
();
};
floats
:=
func
()
bool
{
return
l
.
t
.
isFloat
()
&&
r
.
t
.
isFloat
()
};
strings
:=
func
()
bool
{
// TODO(austin) Deal with named types
return
l
.
t
==
StringType
&&
r
.
t
==
StringType
;
...
...
src/pkg/exp/eval/expr1.go
View file @
9e48df68
This diff is collapsed.
Click to expand it.
src/pkg/exp/eval/expr_test.go
View file @
9e48df68
...
...
@@ -22,9 +22,9 @@ var implLimit = "implementation limit"
var
mustBeUnsigned
=
"must be unsigned"
var
divByZero
=
"divide by zero"
var
hugeInteger
=
bignum
.
Int
(
1
)
.
Shl
(
64
)
;
var
hugeInteger
=
bignum
.
Int
(
1
)
.
Shl
(
64
)
var
exprTests
=
[]
test
{
var
exprTests
=
[]
test
{
Val
(
"i"
,
1
),
CErr
(
"zzz"
,
undefined
),
// TODO(austin) Test variable in constant context
...
...
@@ -230,13 +230,13 @@ var exprTests = []test {
Val
(
"2<<u"
,
2
<<
1
),
CErr
(
"2<<f"
,
opTypes
),
Val
(
"-2<<2"
,
bignum
.
Int
(
-
2
<<
2
)),
Val
(
"-2<<2"
,
bignum
.
Int
(
-
2
<<
2
)),
CErr
(
"-2<<(-1)"
,
constantUnderflows
),
CErr
(
"-2<<0x10000000000000000"
,
constantOverflows
),
CErr
(
"-2<<2.5"
,
constantTruncated
),
Val
(
"-2<<2.0"
,
bignum
.
Int
(
-
2
<<
2.0
)),
Val
(
"-2<<2.0"
,
bignum
.
Int
(
-
2
<<
2.0
)),
CErr
(
"-2<<i"
,
mustBeUnsigned
),
Val
(
"-2<<u"
,
-
2
<<
1
),
Val
(
"-2<<u"
,
-
2
<<
1
),
CErr
(
"-2<<f"
,
opTypes
),
Val
(
"0x10000000000000000<<2"
,
hugeInteger
.
Shl
(
2
)),
...
...
@@ -274,22 +274,22 @@ var exprTests = []test {
CErr
(
"f<<2"
,
opTypes
),
// <, <=, >, >=
Val
(
"1<2"
,
1
<
2
),
Val
(
"1<=2"
,
1
<=
2
),
Val
(
"2<=2"
,
2
<=
2
),
Val
(
"1>2"
,
1
>
2
),
Val
(
"1>=2"
,
1
>=
2
),
Val
(
"2>=2"
,
2
>=
2
),
Val
(
"i<2"
,
1
<
2
),
Val
(
"i<=2"
,
1
<=
2
),
Val
(
"i+1<=2"
,
2
<=
2
),
Val
(
"i>2"
,
1
>
2
),
Val
(
"i>=2"
,
1
>=
2
),
Val
(
"i+1>=2"
,
2
>=
2
),
Val
(
"u<2"
,
1
<
2
),
Val
(
"f<2"
,
1
<
2
),
Val
(
"1<2"
,
1
<
2
),
Val
(
"1<=2"
,
1
<=
2
),
Val
(
"2<=2"
,
2
<=
2
),
Val
(
"1>2"
,
1
>
2
),
Val
(
"1>=2"
,
1
>=
2
),
Val
(
"2>=2"
,
2
>=
2
),
Val
(
"i<2"
,
1
<
2
),
Val
(
"i<=2"
,
1
<=
2
),
Val
(
"i+1<=2"
,
2
<=
2
),
Val
(
"i>2"
,
1
>
2
),
Val
(
"i>=2"
,
1
>=
2
),
Val
(
"i+1>=2"
,
2
>=
2
),
Val
(
"u<2"
,
1
<
2
),
Val
(
"f<2"
,
1
<
2
),
Val
(
"s<
\"
b
\"
"
,
true
),
Val
(
"s<
\"
a
\"
"
,
false
),
...
...
src/pkg/exp/eval/func.go
View file @
9e48df68
...
...
@@ -53,7 +53,7 @@ func (b *codeBuf) push(instr func(*Thread)) {
}
b
.
instrs
=
a
;
}
b
.
instrs
=
b
.
instrs
[
0
:
n
+
1
];
b
.
instrs
=
b
.
instrs
[
0
:
n
+
1
];
b
.
instrs
[
n
]
=
instr
;
}
...
...
src/pkg/exp/eval/gen.go
View file @
9e48df68
...
...
@@ -38,25 +38,25 @@ type Type struct {
}
var
(
boolType
=
&
Type
{
Repr
:
"*boolType"
,
Value
:
"BoolValue"
,
Native
:
"bool"
,
As
:
"asBool"
};
uintType
=
&
Type
{
Repr
:
"*uintType"
,
Value
:
"UintValue"
,
Native
:
"uint64"
,
As
:
"asUint"
,
Sizes
:
[]
Size
{
Size
{
8
,
"uint8"
},
Size
{
16
,
"uint16"
},
Size
{
32
,
"uint32"
},
Size
{
64
,
"uint64"
},
Size
{
0
,
"uint"
}}
boolType
=
&
Type
{
Repr
:
"*boolType"
,
Value
:
"BoolValue"
,
Native
:
"bool"
,
As
:
"asBool"
};
uintType
=
&
Type
{
Repr
:
"*uintType"
,
Value
:
"UintValue"
,
Native
:
"uint64"
,
As
:
"asUint"
,
Sizes
:
[]
Size
{
Size
{
8
,
"uint8"
},
Size
{
16
,
"uint16"
},
Size
{
32
,
"uint32"
},
Size
{
64
,
"uint64"
},
Size
{
0
,
"uint"
}},
};
intType
=
&
Type
{
Repr
:
"*intType"
,
Value
:
"IntValue"
,
Native
:
"int64"
,
As
:
"asInt"
,
Sizes
:
[]
Size
{
Size
{
8
,
"int8"
},
Size
{
16
,
"int16"
},
Size
{
32
,
"int32"
},
Size
{
64
,
"int64"
},
Size
{
0
,
"int"
}}
intType
=
&
Type
{
Repr
:
"*intType"
,
Value
:
"IntValue"
,
Native
:
"int64"
,
As
:
"asInt"
,
Sizes
:
[]
Size
{
Size
{
8
,
"int8"
},
Size
{
16
,
"int16"
},
Size
{
32
,
"int32"
},
Size
{
64
,
"int64"
},
Size
{
0
,
"int"
}}
,
};
idealIntType
=
&
Type
{
Repr
:
"*idealIntType"
,
Value
:
"IdealIntValue"
,
Native
:
"*bignum.Integer"
,
As
:
"asIdealInt"
,
IsIdeal
:
true
};
floatType
=
&
Type
{
Repr
:
"*floatType"
,
Value
:
"FloatValue"
,
Native
:
"float64"
,
As
:
"asFloat"
,
Sizes
:
[]
Size
{
Size
{
32
,
"float32"
},
Size
{
64
,
"float64"
},
Size
{
0
,
"float"
}}
idealIntType
=
&
Type
{
Repr
:
"*idealIntType"
,
Value
:
"IdealIntValue"
,
Native
:
"*bignum.Integer"
,
As
:
"asIdealInt"
,
IsIdeal
:
true
};
floatType
=
&
Type
{
Repr
:
"*floatType"
,
Value
:
"FloatValue"
,
Native
:
"float64"
,
As
:
"asFloat"
,
Sizes
:
[]
Size
{
Size
{
32
,
"float32"
},
Size
{
64
,
"float64"
},
Size
{
0
,
"float"
}}
,
};
idealFloatType
=
&
Type
{
Repr
:
"*idealFloatType"
,
Value
:
"IdealFloatValue"
,
Native
:
"*bignum.Rational"
,
As
:
"asIdealFloat"
,
IsIdeal
:
true
};
stringType
=
&
Type
{
Repr
:
"*stringType"
,
Value
:
"StringValue"
,
Native
:
"string"
,
As
:
"asString"
};
arrayType
=
&
Type
{
Repr
:
"*ArrayType"
,
Value
:
"ArrayValue"
,
Native
:
"ArrayValue"
,
As
:
"asArray"
,
HasAssign
:
true
};
structType
=
&
Type
{
Repr
:
"*StructType"
,
Value
:
"StructValue"
,
Native
:
"StructValue"
,
As
:
"asStruct"
,
HasAssign
:
true
};
ptrType
=
&
Type
{
Repr
:
"*PtrType"
,
Value
:
"PtrValue"
,
Native
:
"Value"
,
As
:
"asPtr"
};
funcType
=
&
Type
{
Repr
:
"*FuncType"
,
Value
:
"FuncValue"
,
Native
:
"Func"
,
As
:
"asFunc"
};
sliceType
=
&
Type
{
Repr
:
"*SliceType"
,
Value
:
"SliceValue"
,
Native
:
"Slice"
,
As
:
"asSlice"
};
mapType
=
&
Type
{
Repr
:
"*MapType"
,
Value
:
"MapValue"
,
Native
:
"Map"
,
As
:
"asMap"
};
idealFloatType
=
&
Type
{
Repr
:
"*idealFloatType"
,
Value
:
"IdealFloatValue"
,
Native
:
"*bignum.Rational"
,
As
:
"asIdealFloat"
,
IsIdeal
:
true
};
stringType
=
&
Type
{
Repr
:
"*stringType"
,
Value
:
"StringValue"
,
Native
:
"string"
,
As
:
"asString"
};
arrayType
=
&
Type
{
Repr
:
"*ArrayType"
,
Value
:
"ArrayValue"
,
Native
:
"ArrayValue"
,
As
:
"asArray"
,
HasAssign
:
true
};
structType
=
&
Type
{
Repr
:
"*StructType"
,
Value
:
"StructValue"
,
Native
:
"StructValue"
,
As
:
"asStruct"
,
HasAssign
:
true
};
ptrType
=
&
Type
{
Repr
:
"*PtrType"
,
Value
:
"PtrValue"
,
Native
:
"Value"
,
As
:
"asPtr"
};
funcType
=
&
Type
{
Repr
:
"*FuncType"
,
Value
:
"FuncValue"
,
Native
:
"Func"
,
As
:
"asFunc"
};
sliceType
=
&
Type
{
Repr
:
"*SliceType"
,
Value
:
"SliceValue"
,
Native
:
"Slice"
,
As
:
"asSlice"
};
mapType
=
&
Type
{
Repr
:
"*MapType"
,
Value
:
"MapValue"
,
Native
:
"Map"
,
As
:
"asMap"
};
all
=
[]
*
Type
{
boolType
,
...
...
@@ -93,41 +93,41 @@ var (
)
var
unOps
=
[]
Op
{
Op
{
Name
:
"Neg"
,
Expr
:
"-v"
,
ConstExpr
:
"v.Neg()"
,
Types
:
numbers
},
Op
{
Name
:
"Not"
,
Expr
:
"!v"
,
Types
:
bools
},
Op
{
Name
:
"Xor"
,
Expr
:
"^v"
,
ConstExpr
:
"v.Neg().Sub(bignum.Int(1))"
,
Types
:
integers
},
Op
{
Name
:
"Neg"
,
Expr
:
"-v"
,
ConstExpr
:
"v.Neg()"
,
Types
:
numbers
},
Op
{
Name
:
"Not"
,
Expr
:
"!v"
,
Types
:
bools
},
Op
{
Name
:
"Xor"
,
Expr
:
"^v"
,
ConstExpr
:
"v.Neg().Sub(bignum.Int(1))"
,
Types
:
integers
},
}
var
binOps
=
[]
Op
{
Op
{
Name
:
"Add"
,
Expr
:
"l + r"
,
ConstExpr
:
"l.Add(r)"
,
Types
:
addable
},
Op
{
Name
:
"Sub"
,
Expr
:
"l - r"
,
ConstExpr
:
"l.Sub(r)"
,
Types
:
numbers
},
Op
{
Name
:
"Mul"
,
Expr
:
"l * r"
,
ConstExpr
:
"l.Mul(r)"
,
Types
:
numbers
},
Op
{
Name
:
"Quo"
,
Op
{
Name
:
"Add"
,
Expr
:
"l + r"
,
ConstExpr
:
"l.Add(r)"
,
Types
:
addable
},
Op
{
Name
:
"Sub"
,
Expr
:
"l - r"
,
ConstExpr
:
"l.Sub(r)"
,
Types
:
numbers
},
Op
{
Name
:
"Mul"
,
Expr
:
"l * r"
,
ConstExpr
:
"l.Mul(r)"
,
Types
:
numbers
},
Op
{
Name
:
"Quo"
,
Body
:
"if r == 0 { t.Abort(DivByZeroError{}) } ret = l / r"
,
ConstExpr
:
"l.Quo(r)"
,
Types
:
numbers
,
},
Op
{
Name
:
"Rem"
,
Op
{
Name
:
"Rem"
,
Body
:
"if r == 0 { t.Abort(DivByZeroError{}) } ret = l % r"
,
ConstExpr
:
"l.Rem(r)"
,
Types
:
integers
,
},
Op
{
Name
:
"And"
,
Expr
:
"l & r"
,
ConstExpr
:
"l.And(r)"
,
Types
:
integers
},
Op
{
Name
:
"Or"
,
Expr
:
"l | r"
,
ConstExpr
:
"l.Or(r)"
,
Types
:
integers
},
Op
{
Name
:
"Xor"
,
Expr
:
"l ^ r"
,
ConstExpr
:
"l.Xor(r)"
,
Types
:
integers
},
Op
{
Name
:
"AndNot"
,
Expr
:
"l &^ r"
,
ConstExpr
:
"l.AndNot(r)"
,
Types
:
integers
},
Op
{
Name
:
"Shl"
,
Expr
:
"l << r"
,
ConstExpr
:
"l.Shl(uint(r.Value()))"
,
AsRightName
:
"asUint"
,
Types
:
shiftable
Op
{
Name
:
"And"
,
Expr
:
"l & r"
,
ConstExpr
:
"l.And(r)"
,
Types
:
integers
},
Op
{
Name
:
"Or"
,
Expr
:
"l | r"
,
ConstExpr
:
"l.Or(r)"
,
Types
:
integers
},
Op
{
Name
:
"Xor"
,
Expr
:
"l ^ r"
,
ConstExpr
:
"l.Xor(r)"
,
Types
:
integers
},
Op
{
Name
:
"AndNot"
,
Expr
:
"l &^ r"
,
ConstExpr
:
"l.AndNot(r)"
,
Types
:
integers
},
Op
{
Name
:
"Shl"
,
Expr
:
"l << r"
,
ConstExpr
:
"l.Shl(uint(r.Value()))"
,
AsRightName
:
"asUint"
,
Types
:
shiftable
,
},
Op
{
Name
:
"Shr"
,
Expr
:
"l >> r"
,
ConstExpr
:
"l.Shr(uint(r.Value()))"
,
AsRightName
:
"asUint"
,
Types
:
shiftable
Op
{
Name
:
"Shr"
,
Expr
:
"l >> r"
,
ConstExpr
:
"l.Shr(uint(r.Value()))"
,
AsRightName
:
"asUint"
,
Types
:
shiftable
,
},
Op
{
Name
:
"Lss"
,
Expr
:
"l < r"
,
ConstExpr
:
"l.Cmp(r) < 0"
,
ReturnType
:
"bool"
,
Types
:
addable
},
Op
{
Name
:
"Gtr"
,
Expr
:
"l > r"
,
ConstExpr
:
"l.Cmp(r) > 0"
,
ReturnType
:
"bool"
,
Types
:
addable
},
Op
{
Name
:
"Leq"
,
Expr
:
"l <= r"
,
ConstExpr
:
"l.Cmp(r) <= 0"
,
ReturnType
:
"bool"
,
Types
:
addable
},
Op
{
Name
:
"Geq"
,
Expr
:
"l >= r"
,
ConstExpr
:
"l.Cmp(r) >= 0"
,
ReturnType
:
"bool"
,
Types
:
addable
},
Op
{
Name
:
"Eql"
,
Expr
:
"l == r"
,
ConstExpr
:
"l.Cmp(r) == 0"
,
ReturnType
:
"bool"
,
Types
:
cmpable
},
Op
{
Name
:
"Neq"
,
Expr
:
"l != r"
,
ConstExpr
:
"l.Cmp(r) != 0"
,
ReturnType
:
"bool"
,
Types
:
cmpable
},
Op
{
Name
:
"Lss"
,
Expr
:
"l < r"
,
ConstExpr
:
"l.Cmp(r) < 0"
,
ReturnType
:
"bool"
,
Types
:
addable
},
Op
{
Name
:
"Gtr"
,
Expr
:
"l > r"
,
ConstExpr
:
"l.Cmp(r) > 0"
,
ReturnType
:
"bool"
,
Types
:
addable
},
Op
{
Name
:
"Leq"
,
Expr
:
"l <= r"
,
ConstExpr
:
"l.Cmp(r) <= 0"
,
ReturnType
:
"bool"
,
Types
:
addable
},
Op
{
Name
:
"Geq"
,
Expr
:
"l >= r"
,
ConstExpr
:
"l.Cmp(r) >= 0"
,
ReturnType
:
"bool"
,
Types
:
addable
},
Op
{
Name
:
"Eql"
,
Expr
:
"l == r"
,
ConstExpr
:
"l.Cmp(r) == 0"
,
ReturnType
:
"bool"
,
Types
:
cmpable
},
Op
{
Name
:
"Neq"
,
Expr
:
"l != r"
,
ConstExpr
:
"l.Cmp(r) != 0"
,
ReturnType
:
"bool"
,
Types
:
cmpable
},
}
type
Data
struct
{
...
...
@@ -136,7 +136,7 @@ type Data struct {
Types
[]
*
Type
;
}
var
data
=
Data
{
var
data
=
Data
{
unOps
,
binOps
,
all
,
...
...
src/pkg/exp/eval/main.go
View file @
9e48df68
...
...
@@ -14,7 +14,7 @@ import (
"os"
;
)
var
filename
=
flag
.
String
(
"f"
,
""
,
"file to run"
)
;
var
filename
=
flag
.
String
(
"f"
,
""
,
"file to run"
)
func
main
()
{
flag
.
Parse
();
...
...
@@ -89,4 +89,3 @@ func main() {
}
}
}
src/pkg/exp/eval/scope.go
View file @
9e48df68
...
...
@@ -47,7 +47,7 @@ type block struct {
// The Scope containing this block.
scope
*
Scope
;
// The Variables, Constants, and Types defined in this block.
defs
map
[
string
]
Def
;
defs
map
[
string
]
Def
;
// The index of the first variable defined in this block.
// This must be greater than the index of any variable defined
// in any parent of this block within the same Scope at the
...
...
@@ -79,8 +79,8 @@ func (b *block) enterChild() *block {
sub
:=
&
block
{
outer
:
b
,
scope
:
b
.
scope
,
defs
:
make
(
map
[
string
]
Def
),
offset
:
b
.
offset
+
b
.
numVars
,
defs
:
make
(
map
[
string
]
Def
),
offset
:
b
.
offset
+
b
.
numVars
,
};
b
.
inner
=
sub
;
return
sub
;
...
...
@@ -122,7 +122,7 @@ func (b *block) DefineVar(name string, pos token.Position, t Type) (*Variable, D
}
func
(
b
*
block
)
DefineTemp
(
t
Type
)
*
Variable
{
return
b
.
defineSlot
(
t
,
true
)
return
b
.
defineSlot
(
t
,
true
)
;
}
func
(
b
*
block
)
defineSlot
(
t
Type
,
temp
bool
)
*
Variable
{
...
...
@@ -131,7 +131,7 @@ func (b *block) defineSlot(t Type, temp bool) *Variable {
}
index
:=
-
1
;
if
!
b
.
global
||
temp
{
index
=
b
.
offset
+
b
.
numVars
;
index
=
b
.
offset
+
b
.
numVars
;
b
.
numVars
++
;
if
index
>=
b
.
scope
.
maxVars
{
b
.
scope
.
maxVars
=
index
+
1
;
...
...
@@ -154,7 +154,7 @@ func (b *block) DefineType(name string, pos token.Position, t Type) Type {
if
_
,
ok
:=
b
.
defs
[
name
];
ok
{
return
nil
;
}
nt
:=
&
NamedType
{
pos
,
name
,
nil
,
true
,
make
(
map
[
string
]
Method
)};
nt
:=
&
NamedType
{
pos
,
name
,
nil
,
true
,
make
(
map
[
string
]
Method
)};
if
t
!=
nil
{
nt
.
Complete
(
t
);
}
...
...
src/pkg/exp/eval/stmt.go
View file @
9e48df68
...
...
@@ -62,19 +62,19 @@ type flowBuf struct {
cb
*
codeBuf
;
// ents is a map from PC's to flow entries. Any PC missing
// from this map is assumed to reach only PC+1.
ents
map
[
uint
]
*
flowEnt
;
ents
map
[
uint
]
*
flowEnt
;
// gotos is a map from goto positions to information on the
// block at the point of the goto.
gotos
map
[
*
token
.
Position
]
*
flowBlock
;
gotos
map
[
*
token
.
Position
]
*
flowBlock
;
// labels is a map from label name to information on the block
// at the point of the label. labels are tracked by name,
// since mutliple labels at the same PC can have different
// blocks.
labels
map
[
string
]
*
flowBlock
;
labels
map
[
string
]
*
flowBlock
;
}
func
newFlowBuf
(
cb
*
codeBuf
)
*
flowBuf
{
return
&
flowBuf
{
cb
,
make
(
map
[
uint
]
*
flowEnt
),
make
(
map
[
*
token
.
Position
]
*
flowBlock
),
make
(
map
[
string
]
*
flowBlock
)};
return
&
flowBuf
{
cb
,
make
(
map
[
uint
]
*
flowEnt
),
make
(
map
[
*
token
.
Position
]
*
flowBlock
),
make
(
map
[
string
]
*
flowBlock
)};
}
// put creates a flow control point for the next PC in the code buffer.
...
...
@@ -97,7 +97,7 @@ func (f *flowBuf) putTerm() {
// PC and, if cond is true, can also continue to the PC following the
// next PC.
func
(
f
*
flowBuf
)
put1
(
cond
bool
,
jumpPC
*
uint
)
{
f
.
put
(
cond
,
false
,
[]
*
uint
{
jumpPC
});
f
.
put
(
cond
,
false
,
[]
*
uint
{
jumpPC
});
}
func
newFlowBlock
(
target
string
,
b
*
block
)
*
flowBlock
{
...
...
@@ -228,9 +228,7 @@ func (a *stmtCompiler) defineVar(ident *ast.Ident, t Type) *Variable {
// Initialize the variable
index
:=
v
.
Index
;
if
v
.
Index
>=
0
{
a
.
push
(
func
(
v
*
Thread
)
{
v
.
f
.
Vars
[
index
]
=
t
.
Zero
();
});
a
.
push
(
func
(
v
*
Thread
)
{
v
.
f
.
Vars
[
index
]
=
t
.
Zero
()
});
}
return
v
;
}
...
...
@@ -730,7 +728,7 @@ func (a *stmtCompiler) doAssign(lhs []ast.Expr, rhs []ast.Expr, tok token.Token,
temp
:=
lmt
.
Zero
()
.
(
multiV
);
assign
(
temp
,
t
);
// Copy to destination
for
i
:=
0
;
i
<
n
;
i
++
{
for
i
:=
0
;
i
<
n
;
i
++
{
// TODO(austin) Need to evaluate LHS
// before RHS
lfs
[
i
](
t
)
.
Assign
(
t
,
temp
[
i
]);
...
...
@@ -739,19 +737,19 @@ func (a *stmtCompiler) doAssign(lhs []ast.Expr, rhs []ast.Expr, tok token.Token,
}
}
var
assignOpToOp
=
map
[
token
.
Token
]
token
.
Token
{
token
.
ADD_ASSIGN
:
token
.
ADD
,
token
.
SUB_ASSIGN
:
token
.
SUB
,
token
.
MUL_ASSIGN
:
token
.
MUL
,
token
.
QUO_ASSIGN
:
token
.
QUO
,
token
.
REM_ASSIGN
:
token
.
REM
,
token
.
AND_ASSIGN
:
token
.
AND
,
token
.
OR_ASSIGN
:
token
.
OR
,
token
.
XOR_ASSIGN
:
token
.
XOR
,
token
.
SHL_ASSIGN
:
token
.
SHL
,
token
.
SHR_ASSIGN
:
token
.
SHR
,
token
.
AND_NOT_ASSIGN
:
token
.
AND_NOT
,
var
assignOpToOp
=
map
[
token
.
Token
]
token
.
Token
{
token
.
ADD_ASSIGN
:
token
.
ADD
,
token
.
SUB_ASSIGN
:
token
.
SUB
,
token
.
MUL_ASSIGN
:
token
.
MUL
,
token
.
QUO_ASSIGN
:
token
.
QUO
,
token
.
REM_ASSIGN
:
token
.
REM
,
token
.
AND_ASSIGN
:
token
.
AND
,
token
.
OR_ASSIGN
:
token
.
OR
,
token
.
XOR_ASSIGN
:
token
.
XOR
,
token
.
SHL_ASSIGN
:
token
.
SHL
,
token
.
SHR_ASSIGN
:
token
.
SHR
,
token
.
AND_NOT_ASSIGN
:
token
.
AND_NOT
,
}
func
(
a
*
stmtCompiler
)
doAssignOp
(
s
*
ast
.
AssignStmt
)
{
...
...
@@ -850,7 +848,7 @@ func (a *stmtCompiler) compileReturnStmt(s *ast.ReturnStmt) {
nout
:=
len
(
a
.
fnType
.
Out
);
a
.
flow
.
putTerm
();
a
.
push
(
func
(
t
*
Thread
)
{
assign
(
multiV
(
t
.
f
.
Vars
[
start
:
start
+
nout
]),
t
);
assign
(
multiV
(
t
.
f
.
Vars
[
start
:
start
+
nout
]),
t
);
t
.
pc
=
returnPC
;
});
}
...
...
@@ -979,9 +977,7 @@ func (a *stmtCompiler) compileIfStmt(s *ast.IfStmt) {
if
s
.
Else
!=
nil
{
// Skip over else if we executed the body
a
.
flow
.
put1
(
false
,
&
endPC
);
a
.
push
(
func
(
v
*
Thread
)
{
v
.
pc
=
endPC
;
});
a
.
push
(
func
(
v
*
Thread
)
{
v
.
pc
=
endPC
});
elsePC
=
a
.
nextPC
();
bc
.
compileStmt
(
s
.
Else
);
}
else
{
...
...
@@ -1105,7 +1101,7 @@ func (a *stmtCompiler) compileSwitchStmt(s *ast.SwitchStmt) {
// non-empty statement in a case or
// default clause in an expression
// "switch" statement.
for
_
,
s2
:=
range
clause
.
Body
[
j
+
1
:
len
(
clause
.
Body
)]
{
for
_
,
s2
:=
range
clause
.
Body
[
j
+
1
:
len
(
clause
.
Body
)]
{
// XXX(Spec) 6g also considers
// empty blocks to be empty
// statements.
...
...
@@ -1234,7 +1230,7 @@ func (a *blockCompiler) exit() {
* Function compiler
*/
func
(
a
*
compiler
)
compileFunc
(
b
*
block
,
decl
*
FuncDecl
,
body
*
ast
.
BlockStmt
)
(
func
(
*
Thread
)
Func
)
{
func
(
a
*
compiler
)
compileFunc
(
b
*
block
,
decl
*
FuncDecl
,
body
*
ast
.
BlockStmt
)
(
func
(
*
Thread
)
Func
)
{
// Create body scope
//
// The scope of a parameter or result is the body of the
...
...
@@ -1264,7 +1260,7 @@ func (a *compiler) compileFunc(b *block, decl *FuncDecl, body *ast.BlockStmt) (f
outVarsNamed
:
len
(
decl
.
OutNames
)
>
0
&&
decl
.
OutNames
[
0
]
!=
nil
,
codeBuf
:
cb
,
flow
:
newFlowBuf
(
cb
),
labels
:
make
(
map
[
string
]
*
label
),
labels
:
make
(
map
[
string
]
*
label
),
};
bc
:=
&
blockCompiler
{
funcCompiler
:
fc
,
...
...
src/pkg/exp/eval/stmt_test.go
View file @
9e48df68
...
...
@@ -6,9 +6,9 @@ package eval
import
"testing"
var
atLeastOneDecl
=
"at least one new variable must be declared"
;
var
atLeastOneDecl
=
"at least one new variable must be declared"
var
stmtTests
=
[]
test
{
var
stmtTests
=
[]
test
{
// Short declarations
Val1
(
"x := i"
,
"x"
,
1
),
Val1
(
"x := f"
,
"x"
,
1.0
),
...
...
@@ -60,9 +60,9 @@ var stmtTests = []test {
Val1
(
"x := &i; *x = 2"
,
"i"
,
2
),
Val1
(
"ai[0] = 42"
,
"ai"
,
varray
{
42
,
2
}),
Val1
(
"aai[1] = ai; ai[0] = 42"
,
"aai"
,
varray
{
varray
{
1
,
2
},
varray
{
1
,
2
}
}),
Val1
(
"aai = aai2"
,
"aai"
,
varray
{
varray
{
5
,
6
},
varray
{
7
,
8
}
}),
Val1
(
"ai[0] = 42"
,
"ai"
,
varray
{
42
,
2
}),
Val1
(
"aai[1] = ai; ai[0] = 42"
,
"aai"
,
varray
{
varray
{
1
,
2
},
varray
{
1
,
2
}
}),
Val1
(
"aai = aai2"
,
"aai"
,
varray
{
varray
{
5
,
6
},
varray
{
7
,
8
}
}),
// Assignment conversions
Run
(
"var sl []int; sl = &ai"
),
...
...
src/pkg/exp/eval/type.go
View file @
9e48df68
...
...
@@ -65,7 +65,7 @@ type BoundedType interface {
maxVal
()
*
bignum
.
Rational
;
}
var
universePos
=
token
.
Position
{
"<universe>"
,
0
,
0
,
0
}
;
var
universePos
=
token
.
Position
{
"<universe>"
,
0
,
0
,
0
}
/*
* Type array maps. These are used to memoize composite types.
...
...
@@ -73,16 +73,16 @@ var universePos = token.Position{"<universe>", 0, 0, 0};
type
typeArrayMapEntry
struct
{
key
[]
Type
;
v
interface
{};
v
interface
{};
next
*
typeArrayMapEntry
;
}
type
typeArrayMap
map
[
uintptr
]
*
typeArrayMapEntry
type
typeArrayMap
map
[
uintptr
]
*
typeArrayMapEntry
func
hashTypeArray
(
key
[]
Type
)
uintptr
{
hash
:=
uintptr
(
0
);
for
_
,
t
:=
range
key
{
hash
=
hash
*
33
;
hash
=
hash
*
33
;
if
t
==
nil
{
continue
;
}
...
...
@@ -93,10 +93,10 @@ func hashTypeArray(key []Type) uintptr {
}
func
newTypeArrayMap
()
typeArrayMap
{
return
make
(
map
[
uintptr
]
*
typeArrayMapEntry
);
return
make
(
map
[
uintptr
]
*
typeArrayMapEntry
);
}
func
(
m
typeArrayMap
)
Get
(
key
[]
Type
)
(
interface
{})
{
func
(
m
typeArrayMap
)
Get
(
key
[]
Type
)
interface
{}
{
ent
,
ok
:=
m
[
hashTypeArray
(
key
)];
if
!
ok
{
return
nil
;
...
...
@@ -132,8 +132,7 @@ func (m typeArrayMap) Put(key []Type, v interface{}) interface{} {
* Common type
*/
type
commonType
struct
{
}
type
commonType
struct
{}
func
(
commonType
)
isBoolean
()
bool
{
return
false
;
...
...
@@ -216,7 +215,8 @@ var (
func
(
t
*
uintType
)
compat
(
o
Type
,
conv
bool
)
bool
{
t2
,
ok
:=
o
.
lit
()
.
(
*
uintType
);
return
ok
&&
t
==
t2
;;
return
ok
&&
t
==
t2
;
;
}
func
(
t
*
uintType
)
lit
()
Type
{
...
...
@@ -343,7 +343,7 @@ func (t *intType) minVal() *bignum.Rational {
if
bits
==
0
{
bits
=
uint
(
8
*
unsafe
.
Sizeof
(
int
(
0
)));
}
return
bignum
.
MakeRat
(
bignum
.
Int
(
-
1
)
.
Shl
(
bits
-
1
),
bignum
.
Nat
(
1
));
return
bignum
.
MakeRat
(
bignum
.
Int
(
-
1
)
.
Shl
(
bits
-
1
),
bignum
.
Nat
(
1
));
}
func
(
t
*
intType
)
maxVal
()
*
bignum
.
Rational
{
...
...
@@ -351,7 +351,7 @@ func (t *intType) maxVal() *bignum.Rational {
if
bits
==
0
{
bits
=
uint
(
8
*
unsafe
.
Sizeof
(
int
(
0
)));
}
return
bignum
.
MakeRat
(
bignum
.
Int
(
1
)
.
Shl
(
bits
-
1
)
.
Add
(
bignum
.
Int
(
-
1
)),
bignum
.
Nat
(
1
));
return
bignum
.
MakeRat
(
bignum
.
Int
(
1
)
.
Shl
(
bits
-
1
)
.
Add
(
bignum
.
Int
(
-
1
)),
bignum
.
Nat
(
1
));
}
/*
...
...
@@ -483,7 +483,7 @@ type idealFloatType struct {
commonType
;
}
var
IdealFloatType
Type
=
&
idealFloatType
{}
;
var
IdealFloatType
Type
=
&
idealFloatType
{}
func
(
t
*
idealFloatType
)
compat
(
o
Type
,
conv
bool
)
bool
{
_
,
ok
:=
o
.
lit
()
.
(
*
idealFloatType
);
...
...
@@ -548,7 +548,7 @@ type ArrayType struct {
Elem
Type
;
}
var
arrayTypes
=
make
(
map
[
int64
]
map
[
Type
]
*
ArrayType
)
var
arrayTypes
=
make
(
map
[
int64
]
map
[
Type
]
*
ArrayType
)
// Two array types are identical if they have identical element types
// and the same array length.
...
...
@@ -556,7 +556,7 @@ var arrayTypes = make(map[int64] map[Type] *ArrayType)
func
NewArrayType
(
len
int64
,
elem
Type
)
*
ArrayType
{
ts
,
ok
:=
arrayTypes
[
len
];
if
!
ok
{
ts
=
make
(
map
[
Type
]
*
ArrayType
);
ts
=
make
(
map
[
Type
]
*
ArrayType
);
arrayTypes
[
len
]
=
ts
;
}
t
,
ok
:=
ts
[
elem
];
...
...
@@ -626,9 +626,9 @@ func NewStructType(fields []StructField) *StructType {
}
tMapI
:=
structTypes
.
Get
(
fts
);
if
tMapI
==
nil
{
tMapI
=
structTypes
.
Put
(
fts
,
make
(
map
[
string
]
*
StructType
));
tMapI
=
structTypes
.
Put
(
fts
,
make
(
map
[
string
]
*
StructType
));
}
tMap
:=
tMapI
.
(
map
[
string
]
*
StructType
);
tMap
:=
tMapI
.
(
map
[
string
]
*
StructType
);
// Construct key for field names
key
:=
""
;
...
...
@@ -673,9 +673,9 @@ func (t *StructType) compat(o Type, conv bool) bool {
e2
:=
t2
.
Elems
[
i
];
// XXX(Spec) An anonymous and a non-anonymous field
// are neither identical nor compatible.
if
(
e
.
Anonymous
!=
e2
.
Anonymous
||
if
e
.
Anonymous
!=
e2
.
Anonymous
||
(
!
e
.
Anonymous
&&
e
.
Name
!=
e2
.
Name
)
||
!
e
.
Type
.
compat
(
e2
.
Type
,
conv
)
)
{
!
e
.
Type
.
compat
(
e2
.
Type
,
conv
)
{
return
false
;
}
}
...
...
@@ -697,7 +697,7 @@ func (t *StructType) String() string {
}
s
+=
f
.
Type
.
String
();
}
return
s
+
"}"
;
return
s
+
"}"
;
}
func
(
t
*
StructType
)
Zero
()
Value
{
...
...
@@ -717,7 +717,7 @@ type PtrType struct {
Elem
Type
;
}
var
ptrTypes
=
make
(
map
[
Type
]
*
PtrType
)
var
ptrTypes
=
make
(
map
[
Type
]
*
PtrType
)
// Two pointer types are identical if they have identical base types.
...
...
@@ -862,7 +862,7 @@ func (t *FuncType) String() string {
}
args
+=
"..."
;
}
s
:=
"func("
+
args
+
")"
;
s
:=
"func("
+
args
+
")"
;
if
len
(
t
.
Out
)
>
0
{
s
+=
" ("
+
typeListString
(
t
.
Out
,
nil
)
+
")"
;
}
...
...
@@ -959,9 +959,9 @@ func NewInterfaceType(methods []IMethod, embeds []*InterfaceType) *InterfaceType
}
tMapI
:=
interfaceTypes
.
Get
(
mts
);
if
tMapI
==
nil
{
tMapI
=
interfaceTypes
.
Put
(
mts
,
make
(
map
[
string
]
*
InterfaceType
));
tMapI
=
interfaceTypes
.
Put
(
mts
,
make
(
map
[
string
]
*
InterfaceType
));
}
tMap
:=
tMapI
.
(
map
[
string
]
*
InterfaceType
);
tMap
:=
tMapI
.
(
map
[
string
]
*
InterfaceType
);
key
:=
""
;
for
_
,
m
:=
range
allMethods
{
...
...
@@ -1021,7 +1021,7 @@ func (t *InterfaceType) String() string {
}
s
+=
m
.
Name
+
funcTypeString
(
m
.
Type
,
nil
,
nil
);
}
return
s
+
"}"
;
return
s
+
"}"
;
}
// implementedBy tests if o implements t, returning nil, true if it does.
...
...
@@ -1091,7 +1091,7 @@ type SliceType struct {
Elem
Type
;
}
var
sliceTypes
=
make
(
map
[
Type
]
*
SliceType
)
var
sliceTypes
=
make
(
map
[
Type
]
*
SliceType
)
// Two slice types are identical if they have identical element types.
...
...
@@ -1136,12 +1136,12 @@ type MapType struct {
Elem
Type
;
}
var
mapTypes
=
make
(
map
[
Type
]
map
[
Type
]
*
MapType
)
var
mapTypes
=
make
(
map
[
Type
]
map
[
Type
]
*
MapType
)
func
NewMapType
(
key
Type
,
elem
Type
)
*
MapType
{
ts
,
ok
:=
mapTypes
[
key
];
if
!
ok
{
ts
=
make
(
map
[
Type
]
*
MapType
);
ts
=
make
(
map
[
Type
]
*
MapType
);
mapTypes
[
key
]
=
ts
;
}
t
,
ok
:=
ts
[
elem
];
...
...
@@ -1197,13 +1197,13 @@ type NamedType struct {
Def
Type
;
// True while this type is being defined.
incomplete
bool
;
methods
map
[
string
]
Method
;
methods
map
[
string
]
Method
;
}
// TODO(austin) This is temporarily needed by the debugger's remote
// type parser. This should only be possible with block.DefineType.
func
NewNamedType
(
name
string
)
*
NamedType
{
return
&
NamedType
{
token
.
Position
{},
name
,
nil
,
true
,
make
(
map
[
string
]
Method
)};
return
&
NamedType
{
token
.
Position
{},
name
,
nil
,
true
,
make
(
map
[
string
]
Method
)};
}
func
(
t
*
NamedType
)
Complete
(
def
Type
)
{
...
...
src/pkg/exp/eval/typec.go
View file @
9e48df68
...
...
@@ -22,7 +22,7 @@ type typeCompiler struct {
//
// TODO(austin) This will probably have to change after we
// eliminate forward declarations.
lateCheck
func
()
bool
lateCheck
func
()
bool
;
}
func
(
a
*
typeCompiler
)
compileIdent
(
x
*
ast
.
Ident
,
allowRec
bool
)
Type
{
...
...
@@ -142,7 +142,7 @@ func (a *typeCompiler) compileStructType(x *ast.StructType, allowRec bool) Type
// uniqueness of field names inherited from anonymous fields
// at use time.
fields
:=
make
([]
StructField
,
len
(
ts
));
nameSet
:=
make
(
map
[
string
]
token
.
Position
,
len
(
ts
));
nameSet
:=
make
(
map
[
string
]
token
.
Position
,
len
(
ts
));
for
i
:=
range
fields
{
// Compute field name and check anonymous fields
var
name
string
;
...
...
@@ -237,7 +237,7 @@ func (a *typeCompiler) compileInterfaceType(x *ast.InterfaceType, allowRec bool)
ts
,
names
,
poss
,
bad
:=
a
.
compileFields
(
x
.
Methods
,
allowRec
);
methods
:=
make
([]
IMethod
,
len
(
ts
));
nameSet
:=
make
(
map
[
string
]
token
.
Position
,
len
(
ts
));
nameSet
:=
make
(
map
[
string
]
token
.
Position
,
len
(
ts
));
embeds
:=
make
([]
*
InterfaceType
,
len
(
ts
));
var
nm
,
ne
int
;
...
...
src/pkg/exp/eval/value.go
View file @
9e48df68
...
...
@@ -497,7 +497,7 @@ func (v *arrayV) String() string {
}
res
+=
e
.
String
();
}
return
res
+
"}"
;
return
res
+
"}"
;
}
func
(
v
*
arrayV
)
Assign
(
t
*
Thread
,
o
Value
)
{
...
...
@@ -517,7 +517,7 @@ func (v *arrayV) Elem(t *Thread, i int64) Value {
}
func
(
v
*
arrayV
)
Sub
(
i
int64
,
len
int64
)
ArrayValue
{
res
:=
(
*
v
)[
i
:
i
+
len
];
res
:=
(
*
v
)[
i
:
i
+
len
];
return
&
res
;
}
...
...
@@ -537,7 +537,7 @@ func (v *structV) String() string {
}
res
+=
v
.
String
();
}
return
res
+
"}"
;
return
res
+
"}"
;
}
func
(
v
*
structV
)
Assign
(
t
*
Thread
,
o
Value
)
{
...
...
@@ -685,7 +685,7 @@ func (v *mapV) String() string {
res
+=
fmt
.
Sprint
(
key
)
+
":"
+
val
.
String
();
return
true
;
});
return
res
+
"]"
;
return
res
+
"]"
;
}
func
(
v
*
mapV
)
Assign
(
t
*
Thread
,
o
Value
)
{
...
...
@@ -700,7 +700,7 @@ func (v *mapV) Set(t *Thread, x Map) {
v
.
target
=
x
;
}
type
evalMap
map
[
interface
{}]
Value
type
evalMap
map
[
interface
{}]
Value
func
(
m
evalMap
)
Len
(
t
*
Thread
)
int64
{
return
int64
(
len
(
m
));
...
...
@@ -743,7 +743,7 @@ func (v multiV) String() string {
}
res
+=
v
.
String
();
}
return
res
+
")"
;
return
res
+
")"
;
}
func
(
v
multiV
)
Assign
(
t
*
Thread
,
o
Value
)
{
...
...
src/pkg/exp/eval/world.go
View file @
9e48df68
...
...
@@ -20,7 +20,7 @@ type World struct {
frame
*
Frame
;
}
func
NewWorld
()
(
*
World
)
{
func
NewWorld
()
*
World
{
w
:=
new
(
World
);
w
.
scope
=
universe
.
ChildScope
();
w
.
scope
.
global
=
true
;
// this block's vars allocate directly
...
...
@@ -56,7 +56,7 @@ func (w *World) CompileStmtList(stmts []ast.Stmt) (Code, os.Error) {
outVarsNamed
:
false
,
codeBuf
:
cb
,
flow
:
newFlowBuf
(
cb
),
labels
:
make
(
map
[
string
]
*
label
),
labels
:
make
(
map
[
string
]
*
label
),
};
bc
:=
&
blockCompiler
{
funcCompiler
:
fc
,
...
...
@@ -88,7 +88,7 @@ func (s *stmtCode) Type() Type {
func
(
s
*
stmtCode
)
Run
()
(
Value
,
os
.
Error
)
{
t
:=
new
(
Thread
);
t
.
f
=
s
.
w
.
scope
.
NewFrame
(
nil
);
return
nil
,
t
.
Try
(
func
(
t
*
Thread
)
{
s
.
code
.
exec
(
t
)
});
return
nil
,
t
.
Try
(
func
(
t
*
Thread
)
{
s
.
code
.
exec
(
t
)
});
}
type
exprCode
struct
{
...
...
@@ -135,7 +135,7 @@ func (e *exprCode) Run() (Value, os.Error) {
}
v
:=
e
.
e
.
t
.
Zero
();
eval
:=
e
.
eval
;
err
:=
t
.
Try
(
func
(
t
*
Thread
)
{
eval
(
v
,
t
)
});
err
:=
t
.
Try
(
func
(
t
*
Thread
)
{
eval
(
v
,
t
)
});
return
v
,
err
;
}
...
...
@@ -187,4 +187,3 @@ func (w *World) DefineVar(name string, t Type, val Value) os.Error {
v
.
Init
=
val
;
return
nil
;
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment