289b30715d
This commit converts the dependency management from Godeps to the vendor folder, also switching the tool from godep to trash. Since the upstream tool lacks a few features proposed via a few PRs, until those PRs are merged in (if), use github.com/karalabe/trash. You can update dependencies via trash --update. All dependencies have been updated to their latest version. Parts of the build system are reworked to drop old notions of Godeps and invocation of the go vet command so that it doesn't run against the vendor folder, as that will just blow up during vetting. The conversion drops OpenCL (and hence GPU mining support) from ethash and our codebase. The short reasoning is that there's noone to maintain and having opencl libs in our deps messes up builds as go install ./... tries to build them, failing with unsatisfied link errors for the C OpenCL deps. golang.org/x/net/context is not vendored in. We expect it to be fetched by the user (i.e. using go get). To keep ci.go builds reproducible the package is "vendored" in build/_vendor.
657 lines
15 KiB
Go
657 lines
15 KiB
Go
package otto
|
|
|
|
import (
|
|
"fmt"
|
|
"regexp"
|
|
|
|
"github.com/robertkrimen/otto/ast"
|
|
"github.com/robertkrimen/otto/file"
|
|
"github.com/robertkrimen/otto/token"
|
|
)
|
|
|
|
var trueLiteral = &_nodeLiteral{value: toValue_bool(true)}
|
|
var falseLiteral = &_nodeLiteral{value: toValue_bool(false)}
|
|
var nullLiteral = &_nodeLiteral{value: nullValue}
|
|
var emptyStatement = &_nodeEmptyStatement{}
|
|
|
|
func (cmpl *_compiler) parseExpression(in ast.Expression) _nodeExpression {
|
|
if in == nil {
|
|
return nil
|
|
}
|
|
|
|
switch in := in.(type) {
|
|
|
|
case *ast.ArrayLiteral:
|
|
out := &_nodeArrayLiteral{
|
|
value: make([]_nodeExpression, len(in.Value)),
|
|
}
|
|
for i, value := range in.Value {
|
|
out.value[i] = cmpl.parseExpression(value)
|
|
}
|
|
return out
|
|
|
|
case *ast.AssignExpression:
|
|
return &_nodeAssignExpression{
|
|
operator: in.Operator,
|
|
left: cmpl.parseExpression(in.Left),
|
|
right: cmpl.parseExpression(in.Right),
|
|
}
|
|
|
|
case *ast.BinaryExpression:
|
|
return &_nodeBinaryExpression{
|
|
operator: in.Operator,
|
|
left: cmpl.parseExpression(in.Left),
|
|
right: cmpl.parseExpression(in.Right),
|
|
comparison: in.Comparison,
|
|
}
|
|
|
|
case *ast.BooleanLiteral:
|
|
if in.Value {
|
|
return trueLiteral
|
|
}
|
|
return falseLiteral
|
|
|
|
case *ast.BracketExpression:
|
|
return &_nodeBracketExpression{
|
|
idx: in.Left.Idx0(),
|
|
left: cmpl.parseExpression(in.Left),
|
|
member: cmpl.parseExpression(in.Member),
|
|
}
|
|
|
|
case *ast.CallExpression:
|
|
out := &_nodeCallExpression{
|
|
callee: cmpl.parseExpression(in.Callee),
|
|
argumentList: make([]_nodeExpression, len(in.ArgumentList)),
|
|
}
|
|
for i, value := range in.ArgumentList {
|
|
out.argumentList[i] = cmpl.parseExpression(value)
|
|
}
|
|
return out
|
|
|
|
case *ast.ConditionalExpression:
|
|
return &_nodeConditionalExpression{
|
|
test: cmpl.parseExpression(in.Test),
|
|
consequent: cmpl.parseExpression(in.Consequent),
|
|
alternate: cmpl.parseExpression(in.Alternate),
|
|
}
|
|
|
|
case *ast.DotExpression:
|
|
return &_nodeDotExpression{
|
|
idx: in.Left.Idx0(),
|
|
left: cmpl.parseExpression(in.Left),
|
|
identifier: in.Identifier.Name,
|
|
}
|
|
|
|
case *ast.EmptyExpression:
|
|
return nil
|
|
|
|
case *ast.FunctionLiteral:
|
|
name := ""
|
|
if in.Name != nil {
|
|
name = in.Name.Name
|
|
}
|
|
out := &_nodeFunctionLiteral{
|
|
name: name,
|
|
body: cmpl.parseStatement(in.Body),
|
|
source: in.Source,
|
|
file: cmpl.file,
|
|
}
|
|
if in.ParameterList != nil {
|
|
list := in.ParameterList.List
|
|
out.parameterList = make([]string, len(list))
|
|
for i, value := range list {
|
|
out.parameterList[i] = value.Name
|
|
}
|
|
}
|
|
for _, value := range in.DeclarationList {
|
|
switch value := value.(type) {
|
|
case *ast.FunctionDeclaration:
|
|
out.functionList = append(out.functionList, cmpl.parseExpression(value.Function).(*_nodeFunctionLiteral))
|
|
case *ast.VariableDeclaration:
|
|
for _, value := range value.List {
|
|
out.varList = append(out.varList, value.Name)
|
|
}
|
|
default:
|
|
panic(fmt.Errorf("Here be dragons: parseProgram.declaration(%T)", value))
|
|
}
|
|
}
|
|
return out
|
|
|
|
case *ast.Identifier:
|
|
return &_nodeIdentifier{
|
|
idx: in.Idx,
|
|
name: in.Name,
|
|
}
|
|
|
|
case *ast.NewExpression:
|
|
out := &_nodeNewExpression{
|
|
callee: cmpl.parseExpression(in.Callee),
|
|
argumentList: make([]_nodeExpression, len(in.ArgumentList)),
|
|
}
|
|
for i, value := range in.ArgumentList {
|
|
out.argumentList[i] = cmpl.parseExpression(value)
|
|
}
|
|
return out
|
|
|
|
case *ast.NullLiteral:
|
|
return nullLiteral
|
|
|
|
case *ast.NumberLiteral:
|
|
return &_nodeLiteral{
|
|
value: toValue(in.Value),
|
|
}
|
|
|
|
case *ast.ObjectLiteral:
|
|
out := &_nodeObjectLiteral{
|
|
value: make([]_nodeProperty, len(in.Value)),
|
|
}
|
|
for i, value := range in.Value {
|
|
out.value[i] = _nodeProperty{
|
|
key: value.Key,
|
|
kind: value.Kind,
|
|
value: cmpl.parseExpression(value.Value),
|
|
}
|
|
}
|
|
return out
|
|
|
|
case *ast.RegExpLiteral:
|
|
return &_nodeRegExpLiteral{
|
|
flags: in.Flags,
|
|
pattern: in.Pattern,
|
|
}
|
|
|
|
case *ast.SequenceExpression:
|
|
out := &_nodeSequenceExpression{
|
|
sequence: make([]_nodeExpression, len(in.Sequence)),
|
|
}
|
|
for i, value := range in.Sequence {
|
|
out.sequence[i] = cmpl.parseExpression(value)
|
|
}
|
|
return out
|
|
|
|
case *ast.StringLiteral:
|
|
return &_nodeLiteral{
|
|
value: toValue_string(in.Value),
|
|
}
|
|
|
|
case *ast.ThisExpression:
|
|
return &_nodeThisExpression{}
|
|
|
|
case *ast.UnaryExpression:
|
|
return &_nodeUnaryExpression{
|
|
operator: in.Operator,
|
|
operand: cmpl.parseExpression(in.Operand),
|
|
postfix: in.Postfix,
|
|
}
|
|
|
|
case *ast.VariableExpression:
|
|
return &_nodeVariableExpression{
|
|
idx: in.Idx0(),
|
|
name: in.Name,
|
|
initializer: cmpl.parseExpression(in.Initializer),
|
|
}
|
|
|
|
}
|
|
|
|
panic(fmt.Errorf("Here be dragons: cmpl.parseExpression(%T)", in))
|
|
}
|
|
|
|
func (cmpl *_compiler) parseStatement(in ast.Statement) _nodeStatement {
|
|
if in == nil {
|
|
return nil
|
|
}
|
|
|
|
switch in := in.(type) {
|
|
|
|
case *ast.BlockStatement:
|
|
out := &_nodeBlockStatement{
|
|
list: make([]_nodeStatement, len(in.List)),
|
|
}
|
|
for i, value := range in.List {
|
|
out.list[i] = cmpl.parseStatement(value)
|
|
}
|
|
return out
|
|
|
|
case *ast.BranchStatement:
|
|
out := &_nodeBranchStatement{
|
|
branch: in.Token,
|
|
}
|
|
if in.Label != nil {
|
|
out.label = in.Label.Name
|
|
}
|
|
return out
|
|
|
|
case *ast.DebuggerStatement:
|
|
return &_nodeDebuggerStatement{}
|
|
|
|
case *ast.DoWhileStatement:
|
|
out := &_nodeDoWhileStatement{
|
|
test: cmpl.parseExpression(in.Test),
|
|
}
|
|
body := cmpl.parseStatement(in.Body)
|
|
if block, ok := body.(*_nodeBlockStatement); ok {
|
|
out.body = block.list
|
|
} else {
|
|
out.body = append(out.body, body)
|
|
}
|
|
return out
|
|
|
|
case *ast.EmptyStatement:
|
|
return emptyStatement
|
|
|
|
case *ast.ExpressionStatement:
|
|
return &_nodeExpressionStatement{
|
|
expression: cmpl.parseExpression(in.Expression),
|
|
}
|
|
|
|
case *ast.ForInStatement:
|
|
out := &_nodeForInStatement{
|
|
into: cmpl.parseExpression(in.Into),
|
|
source: cmpl.parseExpression(in.Source),
|
|
}
|
|
body := cmpl.parseStatement(in.Body)
|
|
if block, ok := body.(*_nodeBlockStatement); ok {
|
|
out.body = block.list
|
|
} else {
|
|
out.body = append(out.body, body)
|
|
}
|
|
return out
|
|
|
|
case *ast.ForStatement:
|
|
out := &_nodeForStatement{
|
|
initializer: cmpl.parseExpression(in.Initializer),
|
|
update: cmpl.parseExpression(in.Update),
|
|
test: cmpl.parseExpression(in.Test),
|
|
}
|
|
body := cmpl.parseStatement(in.Body)
|
|
if block, ok := body.(*_nodeBlockStatement); ok {
|
|
out.body = block.list
|
|
} else {
|
|
out.body = append(out.body, body)
|
|
}
|
|
return out
|
|
|
|
case *ast.FunctionStatement:
|
|
return emptyStatement
|
|
|
|
case *ast.IfStatement:
|
|
return &_nodeIfStatement{
|
|
test: cmpl.parseExpression(in.Test),
|
|
consequent: cmpl.parseStatement(in.Consequent),
|
|
alternate: cmpl.parseStatement(in.Alternate),
|
|
}
|
|
|
|
case *ast.LabelledStatement:
|
|
return &_nodeLabelledStatement{
|
|
label: in.Label.Name,
|
|
statement: cmpl.parseStatement(in.Statement),
|
|
}
|
|
|
|
case *ast.ReturnStatement:
|
|
return &_nodeReturnStatement{
|
|
argument: cmpl.parseExpression(in.Argument),
|
|
}
|
|
|
|
case *ast.SwitchStatement:
|
|
out := &_nodeSwitchStatement{
|
|
discriminant: cmpl.parseExpression(in.Discriminant),
|
|
default_: in.Default,
|
|
body: make([]*_nodeCaseStatement, len(in.Body)),
|
|
}
|
|
for i, clause := range in.Body {
|
|
out.body[i] = &_nodeCaseStatement{
|
|
test: cmpl.parseExpression(clause.Test),
|
|
consequent: make([]_nodeStatement, len(clause.Consequent)),
|
|
}
|
|
for j, value := range clause.Consequent {
|
|
out.body[i].consequent[j] = cmpl.parseStatement(value)
|
|
}
|
|
}
|
|
return out
|
|
|
|
case *ast.ThrowStatement:
|
|
return &_nodeThrowStatement{
|
|
argument: cmpl.parseExpression(in.Argument),
|
|
}
|
|
|
|
case *ast.TryStatement:
|
|
out := &_nodeTryStatement{
|
|
body: cmpl.parseStatement(in.Body),
|
|
finally: cmpl.parseStatement(in.Finally),
|
|
}
|
|
if in.Catch != nil {
|
|
out.catch = &_nodeCatchStatement{
|
|
parameter: in.Catch.Parameter.Name,
|
|
body: cmpl.parseStatement(in.Catch.Body),
|
|
}
|
|
}
|
|
return out
|
|
|
|
case *ast.VariableStatement:
|
|
out := &_nodeVariableStatement{
|
|
list: make([]_nodeExpression, len(in.List)),
|
|
}
|
|
for i, value := range in.List {
|
|
out.list[i] = cmpl.parseExpression(value)
|
|
}
|
|
return out
|
|
|
|
case *ast.WhileStatement:
|
|
out := &_nodeWhileStatement{
|
|
test: cmpl.parseExpression(in.Test),
|
|
}
|
|
body := cmpl.parseStatement(in.Body)
|
|
if block, ok := body.(*_nodeBlockStatement); ok {
|
|
out.body = block.list
|
|
} else {
|
|
out.body = append(out.body, body)
|
|
}
|
|
return out
|
|
|
|
case *ast.WithStatement:
|
|
return &_nodeWithStatement{
|
|
object: cmpl.parseExpression(in.Object),
|
|
body: cmpl.parseStatement(in.Body),
|
|
}
|
|
|
|
}
|
|
|
|
panic(fmt.Errorf("Here be dragons: cmpl.parseStatement(%T)", in))
|
|
}
|
|
|
|
func cmpl_parse(in *ast.Program) *_nodeProgram {
|
|
cmpl := _compiler{
|
|
program: in,
|
|
}
|
|
return cmpl.parse()
|
|
}
|
|
|
|
func (cmpl *_compiler) _parse(in *ast.Program) *_nodeProgram {
|
|
out := &_nodeProgram{
|
|
body: make([]_nodeStatement, len(in.Body)),
|
|
file: in.File,
|
|
}
|
|
for i, value := range in.Body {
|
|
out.body[i] = cmpl.parseStatement(value)
|
|
}
|
|
for _, value := range in.DeclarationList {
|
|
switch value := value.(type) {
|
|
case *ast.FunctionDeclaration:
|
|
out.functionList = append(out.functionList, cmpl.parseExpression(value.Function).(*_nodeFunctionLiteral))
|
|
case *ast.VariableDeclaration:
|
|
for _, value := range value.List {
|
|
out.varList = append(out.varList, value.Name)
|
|
}
|
|
default:
|
|
panic(fmt.Errorf("Here be dragons: cmpl.parseProgram.DeclarationList(%T)", value))
|
|
}
|
|
}
|
|
return out
|
|
}
|
|
|
|
type _nodeProgram struct {
|
|
body []_nodeStatement
|
|
|
|
varList []string
|
|
functionList []*_nodeFunctionLiteral
|
|
|
|
variableList []_nodeDeclaration
|
|
|
|
file *file.File
|
|
}
|
|
|
|
type _nodeDeclaration struct {
|
|
name string
|
|
definition _node
|
|
}
|
|
|
|
type _node interface {
|
|
}
|
|
|
|
type (
|
|
_nodeExpression interface {
|
|
_node
|
|
_expressionNode()
|
|
}
|
|
|
|
_nodeArrayLiteral struct {
|
|
value []_nodeExpression
|
|
}
|
|
|
|
_nodeAssignExpression struct {
|
|
operator token.Token
|
|
left _nodeExpression
|
|
right _nodeExpression
|
|
}
|
|
|
|
_nodeBinaryExpression struct {
|
|
operator token.Token
|
|
left _nodeExpression
|
|
right _nodeExpression
|
|
comparison bool
|
|
}
|
|
|
|
_nodeBracketExpression struct {
|
|
idx file.Idx
|
|
left _nodeExpression
|
|
member _nodeExpression
|
|
}
|
|
|
|
_nodeCallExpression struct {
|
|
callee _nodeExpression
|
|
argumentList []_nodeExpression
|
|
}
|
|
|
|
_nodeConditionalExpression struct {
|
|
test _nodeExpression
|
|
consequent _nodeExpression
|
|
alternate _nodeExpression
|
|
}
|
|
|
|
_nodeDotExpression struct {
|
|
idx file.Idx
|
|
left _nodeExpression
|
|
identifier string
|
|
}
|
|
|
|
_nodeFunctionLiteral struct {
|
|
name string
|
|
body _nodeStatement
|
|
source string
|
|
parameterList []string
|
|
varList []string
|
|
functionList []*_nodeFunctionLiteral
|
|
file *file.File
|
|
}
|
|
|
|
_nodeIdentifier struct {
|
|
idx file.Idx
|
|
name string
|
|
}
|
|
|
|
_nodeLiteral struct {
|
|
value Value
|
|
}
|
|
|
|
_nodeNewExpression struct {
|
|
callee _nodeExpression
|
|
argumentList []_nodeExpression
|
|
}
|
|
|
|
_nodeObjectLiteral struct {
|
|
value []_nodeProperty
|
|
}
|
|
|
|
_nodeProperty struct {
|
|
key string
|
|
kind string
|
|
value _nodeExpression
|
|
}
|
|
|
|
_nodeRegExpLiteral struct {
|
|
flags string
|
|
pattern string // Value?
|
|
regexp *regexp.Regexp
|
|
}
|
|
|
|
_nodeSequenceExpression struct {
|
|
sequence []_nodeExpression
|
|
}
|
|
|
|
_nodeThisExpression struct {
|
|
}
|
|
|
|
_nodeUnaryExpression struct {
|
|
operator token.Token
|
|
operand _nodeExpression
|
|
postfix bool
|
|
}
|
|
|
|
_nodeVariableExpression struct {
|
|
idx file.Idx
|
|
name string
|
|
initializer _nodeExpression
|
|
}
|
|
)
|
|
|
|
type (
|
|
_nodeStatement interface {
|
|
_node
|
|
_statementNode()
|
|
}
|
|
|
|
_nodeBlockStatement struct {
|
|
list []_nodeStatement
|
|
}
|
|
|
|
_nodeBranchStatement struct {
|
|
branch token.Token
|
|
label string
|
|
}
|
|
|
|
_nodeCaseStatement struct {
|
|
test _nodeExpression
|
|
consequent []_nodeStatement
|
|
}
|
|
|
|
_nodeCatchStatement struct {
|
|
parameter string
|
|
body _nodeStatement
|
|
}
|
|
|
|
_nodeDebuggerStatement struct {
|
|
}
|
|
|
|
_nodeDoWhileStatement struct {
|
|
test _nodeExpression
|
|
body []_nodeStatement
|
|
}
|
|
|
|
_nodeEmptyStatement struct {
|
|
}
|
|
|
|
_nodeExpressionStatement struct {
|
|
expression _nodeExpression
|
|
}
|
|
|
|
_nodeForInStatement struct {
|
|
into _nodeExpression
|
|
source _nodeExpression
|
|
body []_nodeStatement
|
|
}
|
|
|
|
_nodeForStatement struct {
|
|
initializer _nodeExpression
|
|
update _nodeExpression
|
|
test _nodeExpression
|
|
body []_nodeStatement
|
|
}
|
|
|
|
_nodeIfStatement struct {
|
|
test _nodeExpression
|
|
consequent _nodeStatement
|
|
alternate _nodeStatement
|
|
}
|
|
|
|
_nodeLabelledStatement struct {
|
|
label string
|
|
statement _nodeStatement
|
|
}
|
|
|
|
_nodeReturnStatement struct {
|
|
argument _nodeExpression
|
|
}
|
|
|
|
_nodeSwitchStatement struct {
|
|
discriminant _nodeExpression
|
|
default_ int
|
|
body []*_nodeCaseStatement
|
|
}
|
|
|
|
_nodeThrowStatement struct {
|
|
argument _nodeExpression
|
|
}
|
|
|
|
_nodeTryStatement struct {
|
|
body _nodeStatement
|
|
catch *_nodeCatchStatement
|
|
finally _nodeStatement
|
|
}
|
|
|
|
_nodeVariableStatement struct {
|
|
list []_nodeExpression
|
|
}
|
|
|
|
_nodeWhileStatement struct {
|
|
test _nodeExpression
|
|
body []_nodeStatement
|
|
}
|
|
|
|
_nodeWithStatement struct {
|
|
object _nodeExpression
|
|
body _nodeStatement
|
|
}
|
|
)
|
|
|
|
// _expressionNode
|
|
|
|
func (*_nodeArrayLiteral) _expressionNode() {}
|
|
func (*_nodeAssignExpression) _expressionNode() {}
|
|
func (*_nodeBinaryExpression) _expressionNode() {}
|
|
func (*_nodeBracketExpression) _expressionNode() {}
|
|
func (*_nodeCallExpression) _expressionNode() {}
|
|
func (*_nodeConditionalExpression) _expressionNode() {}
|
|
func (*_nodeDotExpression) _expressionNode() {}
|
|
func (*_nodeFunctionLiteral) _expressionNode() {}
|
|
func (*_nodeIdentifier) _expressionNode() {}
|
|
func (*_nodeLiteral) _expressionNode() {}
|
|
func (*_nodeNewExpression) _expressionNode() {}
|
|
func (*_nodeObjectLiteral) _expressionNode() {}
|
|
func (*_nodeRegExpLiteral) _expressionNode() {}
|
|
func (*_nodeSequenceExpression) _expressionNode() {}
|
|
func (*_nodeThisExpression) _expressionNode() {}
|
|
func (*_nodeUnaryExpression) _expressionNode() {}
|
|
func (*_nodeVariableExpression) _expressionNode() {}
|
|
|
|
// _statementNode
|
|
|
|
func (*_nodeBlockStatement) _statementNode() {}
|
|
func (*_nodeBranchStatement) _statementNode() {}
|
|
func (*_nodeCaseStatement) _statementNode() {}
|
|
func (*_nodeCatchStatement) _statementNode() {}
|
|
func (*_nodeDebuggerStatement) _statementNode() {}
|
|
func (*_nodeDoWhileStatement) _statementNode() {}
|
|
func (*_nodeEmptyStatement) _statementNode() {}
|
|
func (*_nodeExpressionStatement) _statementNode() {}
|
|
func (*_nodeForInStatement) _statementNode() {}
|
|
func (*_nodeForStatement) _statementNode() {}
|
|
func (*_nodeIfStatement) _statementNode() {}
|
|
func (*_nodeLabelledStatement) _statementNode() {}
|
|
func (*_nodeReturnStatement) _statementNode() {}
|
|
func (*_nodeSwitchStatement) _statementNode() {}
|
|
func (*_nodeThrowStatement) _statementNode() {}
|
|
func (*_nodeTryStatement) _statementNode() {}
|
|
func (*_nodeVariableStatement) _statementNode() {}
|
|
func (*_nodeWhileStatement) _statementNode() {}
|
|
func (*_nodeWithStatement) _statementNode() {}
|