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
Hide whitespace changes
Inline
Side-by-side
Showing
17 changed files
with
245 additions
and
251 deletions
+245
-251
abort.go
src/pkg/exp/eval/abort.go
+3
-3
bridge.go
src/pkg/exp/eval/bridge.go
+8
-8
compiler.go
src/pkg/exp/eval/compiler.go
+20
-19
eval_test.go
src/pkg/exp/eval/eval_test.go
+31
-32
expr.go
src/pkg/exp/eval/expr.go
+0
-0
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
+7
-7
gen.go
src/pkg/exp/eval/gen.go
+65
-65
main.go
src/pkg/exp/eval/main.go
+1
-2
scope.go
src/pkg/exp/eval/scope.go
+20
-20
stmt.go
src/pkg/exp/eval/stmt.go
+37
-41
stmt_test.go
src/pkg/exp/eval/stmt_test.go
+5
-5
type.go
src/pkg/exp/eval/type.go
+0
-0
typec.go
src/pkg/exp/eval/typec.go
+4
-4
value.go
src/pkg/exp/eval/value.go
+10
-10
world.go
src/pkg/exp/eval/world.go
+13
-14
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
));
}
...
...
@@ -139,8 +139,8 @@ func TypeOfNative(v interface {}) Type {
*/
type
nativeFunc
struct
{
fn
func
(
*
Thread
,
[]
Value
,
[]
Value
);
in
,
out
int
;
fn
func
(
*
Thread
,
[]
Value
,
[]
Value
);
in
,
out
int
;
}
func
(
f
*
nativeFunc
)
NewFrame
()
*
Frame
{
...
...
@@ -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
...
...
@@ -22,9 +22,9 @@ type positioned interface {
// TODO(austin) This might actually represent package level, in which
// case it should be package compiler.
type
compiler
struct
{
errors
scanner
.
ErrorHandler
;
numErrors
int
;
silentErrors
int
;
errors
scanner
.
ErrorHandler
;
numErrors
int
;
silentErrors
int
;
}
func
(
a
*
compiler
)
diagAt
(
pos
positioned
,
format
string
,
args
...
)
{
...
...
@@ -43,55 +43,56 @@ 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
type
label
struct
{
name
string
;
desc
string
;
name
string
;
desc
string
;
// The PC goto statements should jump to, or nil if this label
// cannot be goto'd (such as an anonymous for loop label).
gotoPC
*
uint
;
gotoPC
*
uint
;
// The PC break statements should jump to, or nil if a break
// statement is invalid.
breakPC
*
uint
;
breakPC
*
uint
;
// The PC continue statements should jump to, or nil if a
// continue statement is invalid.
continuePC
*
uint
;
continuePC
*
uint
;
// The position where this label was resolved. If it has not
// been resolved yet, an invalid position.
resolved
token
.
Position
;
resolved
token
.
Position
;
// The position where this label was first jumped to.
used
token
.
Position
;
used
token
.
Position
;
}
// A funcCompiler captures information used throughout the compilation
// of a single function body.
type
funcCompiler
struct
{
*
compiler
;
fnType
*
FuncType
;
fnType
*
FuncType
;
// Whether the out variables are named. This affects what
// kinds of return statements are legal.
outVarsNamed
bool
;
outVarsNamed
bool
;
*
codeBuf
;
flow
*
flowBuf
;
labels
map
[
string
]
*
label
;
flow
*
flowBuf
;
labels
map
[
string
]
*
label
;
}
// A blockCompiler captures information used throughout the compilation
// of a single block within a function.
type
blockCompiler
struct
{
*
funcCompiler
;
block
*
block
;
block
*
block
;
// The label of this block, used for finding break and
// continue labels.
label
*
label
;
label
*
label
;
// The blockCompiler for the block enclosing this one, or nil
// for a function-level block.
parent
*
blockCompiler
;
parent
*
blockCompiler
;
}
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"
);
}
...
...
@@ -27,11 +28,11 @@ func init() {
type
test
[]
job
type
job
struct
{
code
string
;
cerr
string
;
rterr
string
;
val
Value
;
noval
bool
;
code
string
;
cerr
string
;
rterr
string
;
val
Value
;
noval
bool
;
}
func
runTests
(
t
*
testing
.
T
,
baseName
string
,
tests
[]
test
)
{
...
...
@@ -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
)}
,
})
;
}
/*
...
...
@@ -155,8 +156,8 @@ type vstruct []interface{}
type
varray
[]
interface
{}
type
vslice
struct
{
arr
varray
;
len
,
cap
int
;
arr
varray
;
len
,
cap
int
;
}
func
toValue
(
val
interface
{})
Value
{
...
...
@@ -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
This diff is collapsed.
Click to expand it.
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
...
...
@@ -11,11 +11,11 @@ import "os"
*/
type
Thread
struct
{
abort
chan
os
.
Error
;
pc
uint
;
abort
chan
os
.
Error
;
pc
uint
;
// The execution frame of this function. This remains the
// same throughout a function invocation.
f
*
Frame
;
f
*
Frame
;
}
type
code
[]
func
(
*
Thread
)
...
...
@@ -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
;
}
...
...
@@ -75,9 +75,9 @@ func (b *codeBuf) get() code {
*/
type
evalFunc
struct
{
outer
*
Frame
;
frameSize
int
;
code
code
;
outer
*
Frame
;
frameSize
int
;
code
code
;
}
func
(
f
*
evalFunc
)
NewFrame
()
*
Frame
{
...
...
src/pkg/exp/eval/gen.go
View file @
9e48df68
...
...
@@ -13,52 +13,52 @@ import (
)
type
Op
struct
{
Name
string
;
Expr
string
;
Body
string
;
// overrides Expr
ConstExpr
string
;
AsRightName
string
;
ReturnType
string
;
Types
[]
*
Type
;
Name
string
;
Expr
string
;
Body
string
;
// overrides Expr
ConstExpr
string
;
AsRightName
string
;
ReturnType
string
;
Types
[]
*
Type
;
}
type
Size
struct
{
Bits
int
;
Sized
string
;
Bits
int
;
Sized
string
;
}
type
Type
struct
{
Repr
string
;
Value
string
;
Native
string
;
As
string
;
IsIdeal
bool
;
HasAssign
bool
;
Sizes
[]
Size
;
Repr
string
;
Value
string
;
Native
string
;
As
string
;
IsIdeal
bool
;
HasAssign
bool
;
Sizes
[]
Size
;
}
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
{
all
=
[]
*
Type
{
boolType
,
uintType
,
intType
,
...
...
@@ -73,12 +73,12 @@ var (
sliceType
,
mapType
,
};
bools
=
all
[
0
:
1
];
integers
=
all
[
1
:
4
];
shiftable
=
all
[
1
:
3
];
numbers
=
all
[
1
:
6
];
addable
=
all
[
1
:
7
];
cmpable
=
[]
*
Type
{
bools
=
all
[
0
:
1
];
integers
=
all
[
1
:
4
];
shiftable
=
all
[
1
:
3
];
numbers
=
all
[
1
:
6
];
addable
=
all
[
1
:
7
];
cmpable
=
[]
*
Type
{
boolType
,
uintType
,
intType
,
...
...
@@ -93,50 +93,50 @@ 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
{
UnaryOps
[]
Op
;
BinaryOps
[]
Op
;
Types
[]
*
Type
;
UnaryOps
[]
Op
;
BinaryOps
[]
Op
;
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
...
...
@@ -21,19 +21,19 @@ type Def interface {
type
Variable
struct
{
token
.
Position
;
// Index of this variable in the Frame structure
Index
int
;
Index
int
;
// Static type of this variable
Type
Type
;
Type
Type
;
// Value of this variable. This is only used by Scope.NewFrame;
// therefore, it is useful for global scopes but cannot be used
// in function scopes.
Init
Value
;
Init
Value
;
}
type
Constant
struct
{
token
.
Position
;
Type
Type
;
Value
Value
;
Type
Type
;
Value
Value
;
}
// A block represents a definition block in which a name may not be
...
...
@@ -41,24 +41,24 @@ type Constant struct {
type
block
struct
{
// The block enclosing this one, including blocks in other
// scopes.
outer
*
block
;
outer
*
block
;
// The nested block currently being compiled, or nil.
inner
*
block
;
inner
*
block
;
// The Scope containing this block.
scope
*
Scope
;
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
// time this block is entered.
offset
int
;
offset
int
;
// The number of Variables defined in this block.
numVars
int
;
numVars
int
;
// If global, do not allocate new vars and consts in
// the frame; assume that the refs will be compiled in
// using defs[name].Init.
global
bool
;
global
bool
;
}
// A Scope is the compile-time analogue of a Frame, which captures
...
...
@@ -69,7 +69,7 @@ type Scope struct {
// The maximum number of variables required at any point in
// this Scope. This determines the number of slots needed in
// Frame's created from this Scope at run-time.
maxVars
int
;
maxVars
int
;
}
func
(
b
*
block
)
enterChild
()
*
block
{
...
...
@@ -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
);
}
...
...
@@ -184,8 +184,8 @@ func (s *Scope) NewFrame(outer *Frame) *Frame {
*/
type
Frame
struct
{
Outer
*
Frame
;
Vars
[]
Value
;
Outer
*
Frame
;
Vars
[]
Value
;
}
func
(
f
*
Frame
)
Get
(
level
int
,
index
int
)
Value
{
...
...
src/pkg/exp/eval/stmt.go
View file @
9e48df68
...
...
@@ -12,8 +12,8 @@ import (
)
const
(
returnPC
=
^
uint
(
0
);
badPC
=
^
uint
(
1
);
returnPC
=
^
uint
(
0
);
badPC
=
^
uint
(
1
);
)
/*
...
...
@@ -22,9 +22,9 @@ const (
type
stmtCompiler
struct
{
*
blockCompiler
;
pos
token
.
Position
;
pos
token
.
Position
;
// This statement's label, or nil if it is not labeled.
stmtLabel
*
label
;
stmtLabel
*
label
;
}
func
(
a
*
stmtCompiler
)
diag
(
format
string
,
args
...
)
{
...
...
@@ -38,43 +38,43 @@ func (a *stmtCompiler) diag(format string, args ...) {
type
flowEnt
struct
{
// Whether this flow entry is conditional. If true, flow can
// continue to the next PC.
cond
bool
;
cond
bool
;
// True if this will terminate flow (e.g., a return statement).
// cond must be false and jumps must be nil if this is true.
term
bool
;
term
bool
;
// PC's that can be reached from this flow entry.
jumps
[]
*
uint
;
jumps
[]
*
uint
;
// Whether this flow entry has been visited by reachesEnd.
visited
bool
;
visited
bool
;
}
type
flowBlock
struct
{
// If this is a goto, the target label.
target
string
;
target
string
;
// The inner-most block containing definitions.
block
*
block
;
block
*
block
;
// The numVars from each block leading to the root of the
// scope, starting at block.
numVars
[]
int
;
numVars
[]
int
;
}
type
flowBuf
struct
{
cb
*
codeBuf
;
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
This diff is collapsed.
Click to expand it.
src/pkg/exp/eval/typec.go
View file @
9e48df68
...
...
@@ -17,12 +17,12 @@ import (
type
typeCompiler
struct
{
*
compiler
;
block
*
block
;
block
*
block
;
// Check to be performed after a type declaration is compiled.
//
// 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
...
...
@@ -97,8 +97,8 @@ type FuncValue interface {
}
type
Interface
struct
{
Type
Type
;
Value
Value
;
Type
Type
;
Value
Value
;
}
type
InterfaceValue
interface
{
...
...
@@ -108,8 +108,8 @@ type InterfaceValue interface {
}
type
Slice
struct
{
Base
ArrayValue
;
Len
,
Cap
int64
;
Base
ArrayValue
;
Len
,
Cap
int64
;
}
type
SliceValue
interface
{
...
...
@@ -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
...
...
@@ -16,11 +16,11 @@ import (
)
type
World
struct
{
scope
*
Scope
;
frame
*
Frame
;
scope
*
Scope
;
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
...
...
@@ -37,8 +37,8 @@ type Code interface {
}
type
stmtCode
struct
{
w
*
World
;
code
code
;
w
*
World
;
code
code
;
}
func
(
w
*
World
)
CompileStmtList
(
stmts
[]
ast
.
Stmt
)
(
Code
,
os
.
Error
)
{
...
...
@@ -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,13 +88,13 @@ 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
{
w
*
World
;
e
*
expr
;
eval
func
(
Value
,
*
Thread
);
w
*
World
;
e
*
expr
;
eval
func
(
Value
,
*
Thread
);
}
func
(
w
*
World
)
CompileExpr
(
e
ast
.
Expr
)
(
Code
,
os
.
Error
)
{
...
...
@@ -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
;
}
...
...
@@ -158,8 +158,8 @@ func (w *World) Compile(text string) (Code, os.Error) {
}
type
RedefinitionError
struct
{
Name
string
;
Prev
Def
;
Name
string
;
Prev
Def
;
}
func
(
e
*
RedefinitionError
)
String
()
string
{
...
...
@@ -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