Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
G
Geth-Modification
Project
Project
Details
Activity
Releases
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
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
张蕾
Geth-Modification
Commits
c305005d
Commit
c305005d
authored
Feb 19, 2016
by
Felix Lange
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #2227 from bas-vk/mathrandom
console: seed random number generator
parents
17649edd
6777531a
Changes
12
Show whitespace changes
Inline
Side-by-side
Showing
12 changed files
with
815 additions
and
46 deletions
+815
-46
Godeps.json
Godeps/Godeps.json
+1
-1
comments.go
...orkspace/src/github.com/robertkrimen/otto/ast/comments.go
+92
-0
node.go
...s/_workspace/src/github.com/robertkrimen/otto/ast/node.go
+8
-0
builtin_math.go
...orkspace/src/github.com/robertkrimen/otto/builtin_math.go
+7
-1
cmpl_parse.go
..._workspace/src/github.com/robertkrimen/otto/cmpl_parse.go
+3
-0
otto.go
Godeps/_workspace/src/github.com/robertkrimen/otto/otto.go
+4
-0
expression.go
...ace/src/github.com/robertkrimen/otto/parser/expression.go
+262
-23
lexer.go
...orkspace/src/github.com/robertkrimen/otto/parser/lexer.go
+47
-0
parser.go
...rkspace/src/github.com/robertkrimen/otto/parser/parser.go
+79
-8
statement.go
...pace/src/github.com/robertkrimen/otto/parser/statement.go
+293
-13
runtime.go
...ps/_workspace/src/github.com/robertkrimen/otto/runtime.go
+1
-0
jsre.go
jsre/jsre.go
+18
-0
No files found.
Godeps/Godeps.json
View file @
c305005d
...
...
@@ -84,7 +84,7 @@
},
{
"ImportPath"
:
"github.com/robertkrimen/otto"
,
"Rev"
:
"
c21072f61b64b51ea58138ccacf0a85d54b9f07c
"
"Rev"
:
"
53221230c215611a90762720c9042ac782ef74ee
"
},
{
"ImportPath"
:
"github.com/syndtr/goleveldb/leveldb"
,
...
...
Godeps/_workspace/src/github.com/robertkrimen/otto/ast/comments.go
0 → 100644
View file @
c305005d
package
ast
import
(
"fmt"
"github.com/robertkrimen/otto/file"
)
// CommentPosition determines where the comment is in a given context
type
CommentPosition
int
const
(
_
CommentPosition
=
iota
LEADING
// Before the pertinent expression
TRAILING
// After the pertinent expression
KEY
// After a key or keyword
COLON
// After a colon in a field declaration
FINAL
// Final comments in a block, not belonging to a specific expression or the comment after a trailing , in an array or object literal
TBD
)
// Comment contains the data of the comment
type
Comment
struct
{
Begin
file
.
Idx
Text
string
Position
CommentPosition
}
// String returns a stringified version of the position
func
(
cp
CommentPosition
)
String
()
string
{
switch
cp
{
case
LEADING
:
return
"Leading"
case
TRAILING
:
return
"Trailing"
case
KEY
:
return
"Key"
case
COLON
:
return
"Colon"
case
FINAL
:
return
"Final"
default
:
return
"???"
}
}
// String returns a stringified version of the comment
func
(
c
Comment
)
String
()
string
{
return
fmt
.
Sprintf
(
"Comment: %v"
,
c
.
Text
)
}
// CommentMap is the data structure where all found comments are stored
type
CommentMap
map
[
Node
][]
*
Comment
// AddComment adds a single comment to the map
func
(
cm
CommentMap
)
AddComment
(
node
Node
,
comment
*
Comment
)
{
list
:=
cm
[
node
]
list
=
append
(
list
,
comment
)
cm
[
node
]
=
list
}
// AddComments adds a slice of comments, given a node and an updated position
func
(
cm
CommentMap
)
AddComments
(
node
Node
,
comments
[]
*
Comment
,
position
CommentPosition
)
{
for
_
,
comment
:=
range
comments
{
comment
.
Position
=
position
cm
.
AddComment
(
node
,
comment
)
}
}
// Size returns the size of the map
func
(
cm
CommentMap
)
Size
()
int
{
size
:=
0
for
_
,
comments
:=
range
cm
{
size
+=
len
(
comments
)
}
return
size
}
// MoveComments moves comments with a given position from a node to another
func
(
cm
CommentMap
)
MoveComments
(
from
,
to
Node
,
position
CommentPosition
)
{
for
i
,
c
:=
range
cm
[
from
]
{
if
c
.
Position
==
position
{
cm
.
AddComment
(
to
,
c
)
// Remove the comment from the "from" slice
cm
[
from
][
i
]
=
cm
[
from
][
len
(
cm
[
from
])
-
1
]
cm
[
from
][
len
(
cm
[
from
])
-
1
]
=
nil
cm
[
from
]
=
cm
[
from
][
:
len
(
cm
[
from
])
-
1
]
}
}
}
Godeps/_workspace/src/github.com/robertkrimen/otto/ast/node.go
View file @
c305005d
...
...
@@ -86,6 +86,11 @@ type (
Identifier
Identifier
}
EmptyExpression
struct
{
Begin
file
.
Idx
End
file
.
Idx
}
FunctionLiteral
struct
{
Function
file
.
Idx
Name
*
Identifier
...
...
@@ -185,6 +190,7 @@ func (*BracketExpression) _expressionNode() {}
func
(
*
CallExpression
)
_expressionNode
()
{}
func
(
*
ConditionalExpression
)
_expressionNode
()
{}
func
(
*
DotExpression
)
_expressionNode
()
{}
func
(
*
EmptyExpression
)
_expressionNode
()
{}
func
(
*
FunctionLiteral
)
_expressionNode
()
{}
func
(
*
Identifier
)
_expressionNode
()
{}
func
(
*
NewExpression
)
_expressionNode
()
{}
...
...
@@ -399,6 +405,7 @@ func (self *BracketExpression) Idx0() file.Idx { return self.Left.Idx0() }
func
(
self
*
CallExpression
)
Idx0
()
file
.
Idx
{
return
self
.
Callee
.
Idx0
()
}
func
(
self
*
ConditionalExpression
)
Idx0
()
file
.
Idx
{
return
self
.
Test
.
Idx0
()
}
func
(
self
*
DotExpression
)
Idx0
()
file
.
Idx
{
return
self
.
Left
.
Idx0
()
}
func
(
self
*
EmptyExpression
)
Idx0
()
file
.
Idx
{
return
self
.
Begin
}
func
(
self
*
FunctionLiteral
)
Idx0
()
file
.
Idx
{
return
self
.
Function
}
func
(
self
*
Identifier
)
Idx0
()
file
.
Idx
{
return
self
.
Idx
}
func
(
self
*
NewExpression
)
Idx0
()
file
.
Idx
{
return
self
.
New
}
...
...
@@ -447,6 +454,7 @@ func (self *BracketExpression) Idx1() file.Idx { return self.RightBracket +
func
(
self
*
CallExpression
)
Idx1
()
file
.
Idx
{
return
self
.
RightParenthesis
+
1
}
func
(
self
*
ConditionalExpression
)
Idx1
()
file
.
Idx
{
return
self
.
Test
.
Idx1
()
}
func
(
self
*
DotExpression
)
Idx1
()
file
.
Idx
{
return
self
.
Identifier
.
Idx1
()
}
func
(
self
*
EmptyExpression
)
Idx1
()
file
.
Idx
{
return
self
.
End
}
func
(
self
*
FunctionLiteral
)
Idx1
()
file
.
Idx
{
return
self
.
Body
.
Idx1
()
}
func
(
self
*
Identifier
)
Idx1
()
file
.
Idx
{
return
file
.
Idx
(
int
(
self
.
Idx
)
+
len
(
self
.
Name
))
}
func
(
self
*
NewExpression
)
Idx1
()
file
.
Idx
{
return
self
.
RightParenthesis
+
1
}
...
...
Godeps/_workspace/src/github.com/robertkrimen/otto/builtin_math.go
View file @
c305005d
...
...
@@ -117,7 +117,13 @@ func builtinMath_pow(call FunctionCall) Value {
}
func
builtinMath_random
(
call
FunctionCall
)
Value
{
return
toValue_float64
(
rand
.
Float64
())
var
v
float64
if
call
.
runtime
.
random
!=
nil
{
v
=
call
.
runtime
.
random
()
}
else
{
v
=
rand
.
Float64
()
}
return
toValue_float64
(
v
)
}
func
builtinMath_round
(
call
FunctionCall
)
Value
{
...
...
Godeps/_workspace/src/github.com/robertkrimen/otto/cmpl_parse.go
View file @
c305005d
...
...
@@ -82,6 +82,9 @@ func (cmpl *_compiler) parseExpression(in ast.Expression) _nodeExpression {
identifier
:
in
.
Identifier
.
Name
,
}
case
*
ast
.
EmptyExpression
:
return
nil
case
*
ast
.
FunctionLiteral
:
name
:=
""
if
in
.
Name
!=
nil
{
...
...
Godeps/_workspace/src/github.com/robertkrimen/otto/otto.go
View file @
c305005d
...
...
@@ -363,6 +363,10 @@ func (self Otto) SetDebuggerHandler(fn func(vm *Otto)) {
self
.
runtime
.
debugger
=
fn
}
func
(
self
Otto
)
SetRandomSource
(
fn
func
()
float64
)
{
self
.
runtime
.
random
=
fn
}
// Context is a structure that contains information about the current execution
// context.
type
Context
struct
{
...
...
Godeps/_workspace/src/github.com/robertkrimen/otto/parser/expression.go
View file @
c305005d
...
...
@@ -12,10 +12,14 @@ func (self *_parser) parseIdentifier() *ast.Identifier {
literal
:=
self
.
literal
idx
:=
self
.
idx
self
.
next
()
return
&
ast
.
Identifier
{
comments
:=
self
.
findComments
(
false
)
exp
:=
&
ast
.
Identifier
{
Name
:
literal
,
Idx
:
idx
,
}
self
.
commentMap
.
AddComments
(
exp
,
comments
,
ast
.
TRAILING
)
return
exp
}
func
(
self
*
_parser
)
parsePrimaryExpression
()
ast
.
Expression
{
...
...
@@ -196,11 +200,20 @@ func (self *_parser) parseVariableDeclarationList(var_ file.Idx) []ast.Expressio
var
list
[]
ast
.
Expression
for
{
list
=
append
(
list
,
self
.
parseVariableDeclaration
(
&
declarationList
))
comments
:=
self
.
findComments
(
false
)
decl
:=
self
.
parseVariableDeclaration
(
&
declarationList
)
if
self
.
mode
&
StoreComments
!=
0
{
self
.
commentMap
.
AddComments
(
decl
,
comments
,
ast
.
LEADING
)
self
.
commentMap
.
AddComments
(
decl
,
self
.
findComments
(
false
),
ast
.
TRAILING
)
}
list
=
append
(
list
,
decl
)
if
self
.
token
!=
token
.
COMMA
{
break
}
self
.
next
()
}
self
.
scope
.
declare
(
&
ast
.
VariableDeclaration
{
...
...
@@ -211,10 +224,13 @@ func (self *_parser) parseVariableDeclarationList(var_ file.Idx) []ast.Expressio
return
list
}
func
(
self
*
_parser
)
parseObjectPropertyKey
()
(
string
,
string
)
{
func
(
self
*
_parser
)
parseObjectPropertyKey
()
(
string
,
string
,
[]
*
ast
.
Comment
)
{
idx
,
tkn
,
literal
:=
self
.
idx
,
self
.
token
,
self
.
literal
value
:=
""
self
.
next
()
comments
:=
self
.
findComments
(
false
)
switch
tkn
{
case
token
.
IDENTIFIER
:
value
=
literal
...
...
@@ -238,15 +254,14 @@ func (self *_parser) parseObjectPropertyKey() (string, string) {
value
=
literal
}
}
return
literal
,
value
return
literal
,
value
,
comments
}
func
(
self
*
_parser
)
parseObjectProperty
()
ast
.
Property
{
literal
,
value
:=
self
.
parseObjectPropertyKey
()
literal
,
value
,
comments
:=
self
.
parseObjectPropertyKey
()
if
literal
==
"get"
&&
self
.
token
!=
token
.
COLON
{
idx
:=
self
.
idx
_
,
value
:=
self
.
parseObjectPropertyKey
()
_
,
value
,
_
:=
self
.
parseObjectPropertyKey
()
parameterList
:=
self
.
parseFunctionParameterList
()
node
:=
&
ast
.
FunctionLiteral
{
...
...
@@ -261,7 +276,7 @@ func (self *_parser) parseObjectProperty() ast.Property {
}
}
else
if
literal
==
"set"
&&
self
.
token
!=
token
.
COLON
{
idx
:=
self
.
idx
_
,
value
:=
self
.
parseObjectPropertyKey
()
_
,
value
,
_
:=
self
.
parseObjectPropertyKey
()
parameterList
:=
self
.
parseFunctionParameterList
()
node
:=
&
ast
.
FunctionLiteral
{
...
...
@@ -277,63 +292,128 @@ func (self *_parser) parseObjectProperty() ast.Property {
}
self
.
expect
(
token
.
COLON
)
comments2
:=
self
.
findComments
(
false
)
return
ast
.
Property
{
exp
:=
ast
.
Property
{
Key
:
value
,
Kind
:
"value"
,
Value
:
self
.
parseAssignmentExpression
(),
}
if
self
.
mode
&
StoreComments
!=
0
{
self
.
commentMap
.
AddComments
(
exp
.
Value
,
comments
,
ast
.
KEY
)
self
.
commentMap
.
AddComments
(
exp
.
Value
,
comments2
,
ast
.
COLON
)
}
return
exp
}
func
(
self
*
_parser
)
parseObjectLiteral
()
ast
.
Expression
{
var
value
[]
ast
.
Property
idx0
:=
self
.
expect
(
token
.
LEFT_BRACE
)
var
comments2
[]
*
ast
.
Comment
for
self
.
token
!=
token
.
RIGHT_BRACE
&&
self
.
token
!=
token
.
EOF
{
// Leading comments for object literal
comments
:=
self
.
findComments
(
false
)
property
:=
self
.
parseObjectProperty
()
if
self
.
mode
&
StoreComments
!=
0
{
self
.
commentMap
.
AddComments
(
property
.
Value
,
comments
,
ast
.
LEADING
)
self
.
commentMap
.
AddComments
(
property
.
Value
,
comments2
,
ast
.
LEADING
)
}
value
=
append
(
value
,
property
)
if
self
.
token
==
token
.
COMMA
{
self
.
next
()
// Find leading comments after trailing comma
comments2
=
self
.
findComments
(
false
)
continue
}
}
idx1
:=
self
.
expect
(
token
.
RIGHT_BRACE
)
return
&
ast
.
ObjectLiteral
{
exp
:=
&
ast
.
ObjectLiteral
{
LeftBrace
:
idx0
,
RightBrace
:
idx1
,
Value
:
value
,
}
if
self
.
mode
&
StoreComments
!=
0
{
self
.
commentMap
.
AddComments
(
exp
,
comments2
,
ast
.
FINAL
)
}
self
.
consumeComments
(
exp
,
ast
.
FINAL
)
return
exp
}
func
(
self
*
_parser
)
parseArrayLiteral
()
ast
.
Expression
{
idx0
:=
self
.
expect
(
token
.
LEFT_BRACKET
)
var
comments2
[]
*
ast
.
Comment
var
comments
[]
*
ast
.
Comment
var
value
[]
ast
.
Expression
for
self
.
token
!=
token
.
RIGHT_BRACKET
&&
self
.
token
!=
token
.
EOF
{
// Find leading comments for both empty and non-empty expressions
comments
=
self
.
findComments
(
false
)
if
self
.
token
==
token
.
COMMA
{
self
.
next
()
value
=
append
(
value
,
nil
)
// This kind of comment requires a special empty expression node.
empty
:=
&
ast
.
EmptyExpression
{
self
.
idx
,
self
.
idx
}
if
self
.
mode
&
StoreComments
!=
0
{
self
.
commentMap
.
AddComments
(
empty
,
comments
,
ast
.
LEADING
)
self
.
commentMap
.
AddComments
(
empty
,
comments2
,
ast
.
LEADING
)
}
value
=
append
(
value
,
empty
)
// This comment belongs to the following expression, or trailing
comments2
=
self
.
findComments
(
false
)
continue
}
value
=
append
(
value
,
self
.
parseAssignmentExpression
())
exp
:=
self
.
parseAssignmentExpression
()
if
self
.
mode
&
StoreComments
!=
0
{
self
.
commentMap
.
AddComments
(
exp
,
comments
,
ast
.
LEADING
)
self
.
commentMap
.
AddComments
(
exp
,
comments2
,
ast
.
LEADING
)
}
value
=
append
(
value
,
exp
)
if
self
.
token
!=
token
.
RIGHT_BRACKET
{
self
.
expect
(
token
.
COMMA
)
}
// This comment belongs to the following expression, or trailing
comments2
=
self
.
findComments
(
false
)
}
idx1
:=
self
.
expect
(
token
.
RIGHT_BRACKET
)
return
&
ast
.
ArrayLiteral
{
array
:=
&
ast
.
ArrayLiteral
{
LeftBracket
:
idx0
,
RightBracket
:
idx1
,
Value
:
value
,
}
// This is where comments after a possible trailing comma are added
if
self
.
mode
&
StoreComments
!=
0
{
self
.
commentMap
.
AddComments
(
array
,
comments2
,
ast
.
FINAL
)
}
return
array
}
func
(
self
*
_parser
)
parseArgumentList
()
(
argumentList
[]
ast
.
Expression
,
idx0
,
idx1
file
.
Idx
)
{
idx0
=
self
.
expect
(
token
.
LEFT_PARENTHESIS
)
if
self
.
token
!=
token
.
RIGHT_PARENTHESIS
{
for
{
argumentList
=
append
(
argumentList
,
self
.
parseAssignmentExpression
())
comments
:=
self
.
findComments
(
false
)
exp
:=
self
.
parseAssignmentExpression
()
if
self
.
mode
&
StoreComments
!=
0
{
self
.
commentMap
.
AddComments
(
exp
,
comments
,
ast
.
LEADING
)
}
argumentList
=
append
(
argumentList
,
exp
)
if
self
.
token
!=
token
.
COMMA
{
break
}
...
...
@@ -346,12 +426,17 @@ func (self *_parser) parseArgumentList() (argumentList []ast.Expression, idx0, i
func
(
self
*
_parser
)
parseCallExpression
(
left
ast
.
Expression
)
ast
.
Expression
{
argumentList
,
idx0
,
idx1
:=
self
.
parseArgumentList
()
return
&
ast
.
CallExpression
{
exp
:=
&
ast
.
CallExpression
{
Callee
:
left
,
LeftParenthesis
:
idx0
,
ArgumentList
:
argumentList
,
RightParenthesis
:
idx1
,
}
if
self
.
mode
&
StoreComments
!=
0
{
self
.
commentMap
.
AddComments
(
exp
,
self
.
findComments
(
false
),
ast
.
TRAILING
)
}
return
exp
}
func
(
self
*
_parser
)
parseDotMember
(
left
ast
.
Expression
)
ast
.
Expression
{
...
...
@@ -402,6 +487,11 @@ func (self *_parser) parseNewExpression() ast.Expression {
node
.
LeftParenthesis
=
idx0
node
.
RightParenthesis
=
idx1
}
if
self
.
mode
&
StoreComments
!=
0
{
self
.
commentMap
.
AddComments
(
node
,
self
.
findComments
(
false
),
ast
.
TRAILING
)
}
return
node
}
...
...
@@ -414,6 +504,10 @@ func (self *_parser) parseLeftHandSideExpression() ast.Expression {
left
=
self
.
parsePrimaryExpression
()
}
if
self
.
mode
&
StoreComments
!=
0
{
self
.
commentMap
.
AddComments
(
left
,
self
.
findComments
(
false
),
ast
.
TRAILING
)
}
for
{
if
self
.
token
==
token
.
PERIOD
{
left
=
self
.
parseDotMember
(
left
)
...
...
@@ -442,6 +536,10 @@ func (self *_parser) parseLeftHandSideExpressionAllowCall() ast.Expression {
left
=
self
.
parsePrimaryExpression
()
}
if
self
.
mode
&
StoreComments
!=
0
{
self
.
commentMap
.
AddComments
(
left
,
self
.
findComments
(
false
),
ast
.
TRAILING
)
}
for
{
if
self
.
token
==
token
.
PERIOD
{
left
=
self
.
parseDotMember
(
left
)
...
...
@@ -476,12 +574,18 @@ func (self *_parser) parsePostfixExpression() ast.Expression {
self
.
nextStatement
()
return
&
ast
.
BadExpression
{
From
:
idx
,
To
:
self
.
idx
}
}
return
&
ast
.
UnaryExpression
{
exp
:=
&
ast
.
UnaryExpression
{
Operator
:
tkn
,
Idx
:
idx
,
Operand
:
operand
,
Postfix
:
true
,
}
if
self
.
mode
&
StoreComments
!=
0
{
self
.
commentMap
.
AddComments
(
exp
,
self
.
findComments
(
false
),
ast
.
TRAILING
)
}
return
exp
}
return
operand
...
...
@@ -496,16 +600,30 @@ func (self *_parser) parseUnaryExpression() ast.Expression {
tkn
:=
self
.
token
idx
:=
self
.
idx
self
.
next
()
return
&
ast
.
UnaryExpression
{
comments
:=
self
.
findComments
(
false
)
exp
:=
&
ast
.
UnaryExpression
{
Operator
:
tkn
,
Idx
:
idx
,
Operand
:
self
.
parseUnaryExpression
(),
}
if
self
.
mode
&
StoreComments
!=
0
{
self
.
commentMap
.
AddComments
(
exp
.
Operand
,
comments
,
ast
.
LEADING
)
}
return
exp
case
token
.
INCREMENT
,
token
.
DECREMENT
:
tkn
:=
self
.
token
idx
:=
self
.
idx
self
.
next
()
comments
:=
self
.
findComments
(
false
)
operand
:=
self
.
parseUnaryExpression
()
if
self
.
mode
&
StoreComments
!=
0
{
self
.
commentMap
.
AddComments
(
operand
,
comments
,
ast
.
LEADING
)
}
switch
operand
.
(
type
)
{
case
*
ast
.
Identifier
,
*
ast
.
DotExpression
,
*
ast
.
BracketExpression
:
default
:
...
...
@@ -531,11 +649,18 @@ func (self *_parser) parseMultiplicativeExpression() ast.Expression {
self
.
token
==
token
.
REMAINDER
{
tkn
:=
self
.
token
self
.
next
()
comments
:=
self
.
findComments
(
false
)
left
=
&
ast
.
BinaryExpression
{
Operator
:
tkn
,
Left
:
left
,
Right
:
next
(),
}
if
self
.
mode
&
StoreComments
!=
0
{
self
.
commentMap
.
AddComments
(
left
.
(
*
ast
.
BinaryExpression
)
.
Right
,
comments
,
ast
.
LEADING
)
}
}
return
left
...
...
@@ -548,11 +673,18 @@ func (self *_parser) parseAdditiveExpression() ast.Expression {
for
self
.
token
==
token
.
PLUS
||
self
.
token
==
token
.
MINUS
{
tkn
:=
self
.
token
self
.
next
()
comments
:=
self
.
findComments
(
false
)
left
=
&
ast
.
BinaryExpression
{
Operator
:
tkn
,
Left
:
left
,
Right
:
next
(),
}
if
self
.
mode
&
StoreComments
!=
0
{
self
.
commentMap
.
AddComments
(
left
.
(
*
ast
.
BinaryExpression
)
.
Right
,
comments
,
ast
.
LEADING
)
}
}
return
left
...
...
@@ -566,11 +698,18 @@ func (self *_parser) parseShiftExpression() ast.Expression {
self
.
token
==
token
.
UNSIGNED_SHIFT_RIGHT
{
tkn
:=
self
.
token
self
.
next
()
comments
:=
self
.
findComments
(
false
)
left
=
&
ast
.
BinaryExpression
{
Operator
:
tkn
,
Left
:
left
,
Right
:
next
(),
}
if
self
.
mode
&
StoreComments
!=
0
{
self
.
commentMap
.
AddComments
(
left
.
(
*
ast
.
BinaryExpression
)
.
Right
,
comments
,
ast
.
LEADING
)
}
}
return
left
...
...
@@ -590,31 +729,55 @@ func (self *_parser) parseRelationalExpression() ast.Expression {
case
token
.
LESS
,
token
.
LESS_OR_EQUAL
,
token
.
GREATER
,
token
.
GREATER_OR_EQUAL
:
tkn
:=
self
.
token
self
.
next
()
return
&
ast
.
BinaryExpression
{
comments
:=
self
.
findComments
(
false
)
exp
:=
&
ast
.
BinaryExpression
{
Operator
:
tkn
,
Left
:
left
,
Right
:
self
.
parseRelationalExpression
(),
Comparison
:
true
,
}
if
self
.
mode
&
StoreComments
!=
0
{
self
.
commentMap
.
AddComments
(
exp
.
Right
,
comments
,
ast
.
LEADING
)
}
return
exp
case
token
.
INSTANCEOF
:
tkn
:=
self
.
token
self
.
next
()
return
&
ast
.
BinaryExpression
{
comments
:=
self
.
findComments
(
false
)
exp
:=
&
ast
.
BinaryExpression
{
Operator
:
tkn
,
Left
:
left
,
Right
:
self
.
parseRelationalExpression
(),
}
if
self
.
mode
&
StoreComments
!=
0
{
self
.
commentMap
.
AddComments
(
exp
.
Right
,
comments
,
ast
.
LEADING
)
}
return
exp
case
token
.
IN
:
if
!
allowIn
{
return
left
}
tkn
:=
self
.
token
self
.
next
()
return
&
ast
.
BinaryExpression
{
comments
:=
self
.
findComments
(
false
)
exp
:=
&
ast
.
BinaryExpression
{
Operator
:
tkn
,
Left
:
left
,
Right
:
self
.
parseRelationalExpression
(),
}
if
self
.
mode
&
StoreComments
!=
0
{
self
.
commentMap
.
AddComments
(
exp
.
Right
,
comments
,
ast
.
LEADING
)
}
return
exp
}
return
left
...
...
@@ -628,12 +791,19 @@ func (self *_parser) parseEqualityExpression() ast.Expression {
self
.
token
==
token
.
STRICT_EQUAL
||
self
.
token
==
token
.
STRICT_NOT_EQUAL
{
tkn
:=
self
.
token
self
.
next
()
comments
:=
self
.
findComments
(
false
)
left
=
&
ast
.
BinaryExpression
{
Operator
:
tkn
,
Left
:
left
,
Right
:
next
(),
Comparison
:
true
,
}
if
self
.
mode
&
StoreComments
!=
0
{
self
.
commentMap
.
AddComments
(
left
.
(
*
ast
.
BinaryExpression
)
.
Right
,
comments
,
ast
.
LEADING
)
}
}
return
left
...
...
@@ -646,11 +816,18 @@ func (self *_parser) parseBitwiseAndExpression() ast.Expression {
for
self
.
token
==
token
.
AND
{
tkn
:=
self
.
token
self
.
next
()
comments
:=
self
.
findComments
(
false
)
left
=
&
ast
.
BinaryExpression
{
Operator
:
tkn
,
Left
:
left
,
Right
:
next
(),
}
if
self
.
mode
&
StoreComments
!=
0
{
self
.
commentMap
.
AddComments
(
left
.
(
*
ast
.
BinaryExpression
)
.
Right
,
comments
,
ast
.
LEADING
)
}
}
return
left
...
...
@@ -663,11 +840,18 @@ func (self *_parser) parseBitwiseExclusiveOrExpression() ast.Expression {
for
self
.
token
==
token
.
EXCLUSIVE_OR
{
tkn
:=
self
.
token
self
.
next
()
comments
:=
self
.
findComments
(
false
)
left
=
&
ast
.
BinaryExpression
{
Operator
:
tkn
,
Left
:
left
,
Right
:
next
(),
}
if
self
.
mode
&
StoreComments
!=
0
{
self
.
commentMap
.
AddComments
(
left
.
(
*
ast
.
BinaryExpression
)
.
Right
,
comments
,
ast
.
LEADING
)
}
}
return
left
...
...
@@ -680,11 +864,18 @@ func (self *_parser) parseBitwiseOrExpression() ast.Expression {
for
self
.
token
==
token
.
OR
{
tkn
:=
self
.
token
self
.
next
()
comments
:=
self
.
findComments
(
false
)
left
=
&
ast
.
BinaryExpression
{
Operator
:
tkn
,
Left
:
left
,
Right
:
next
(),
}
if
self
.
mode
&
StoreComments
!=
0
{
self
.
commentMap
.
AddComments
(
left
.
(
*
ast
.
BinaryExpression
)
.
Right
,
comments
,
ast
.
LEADING
)
}
}
return
left
...
...
@@ -697,11 +888,18 @@ func (self *_parser) parseLogicalAndExpression() ast.Expression {
for
self
.
token
==
token
.
LOGICAL_AND
{
tkn
:=
self
.
token
self
.
next
()
comments
:=
self
.
findComments
(
false
)
left
=
&
ast
.
BinaryExpression
{
Operator
:
tkn
,
Left
:
left
,
Right
:
next
(),
}
if
self
.
mode
&
StoreComments
!=
0
{
self
.
commentMap
.
AddComments
(
left
.
(
*
ast
.
BinaryExpression
)
.
Right
,
comments
,
ast
.
LEADING
)
}
}
return
left
...
...
@@ -714,11 +912,18 @@ func (self *_parser) parseLogicalOrExpression() ast.Expression {
for
self
.
token
==
token
.
LOGICAL_OR
{
tkn
:=
self
.
token
self
.
next
()
comments
:=
self
.
findComments
(
false
)
left
=
&
ast
.
BinaryExpression
{
Operator
:
tkn
,
Left
:
left
,
Right
:
next
(),
}
if
self
.
mode
&
StoreComments
!=
0
{
self
.
commentMap
.
AddComments
(
left
.
(
*
ast
.
BinaryExpression
)
.
Right
,
comments
,
ast
.
LEADING
)
}
}
return
left
...
...
@@ -729,13 +934,29 @@ func (self *_parser) parseConditionlExpression() ast.Expression {
if
self
.
token
==
token
.
QUESTION_MARK
{
self
.
next
()
// Comments before the consequence
comments1
:=
self
.
findComments
(
false
)
consequent
:=
self
.
parseAssignmentExpression
()
if
self
.
mode
&
StoreComments
!=
0
{
self
.
commentMap
.
AddComments
(
consequent
,
comments1
,
ast
.
LEADING
)
}
self
.
expect
(
token
.
COLON
)
return
&
ast
.
ConditionalExpression
{
// Comments before the alternate
comments2
:=
self
.
findComments
(
false
)
exp
:=
&
ast
.
ConditionalExpression
{
Test
:
left
,
Consequent
:
consequent
,
Alternate
:
self
.
parseAssignmentExpression
(),
}
if
self
.
mode
&
StoreComments
!=
0
{
self
.
commentMap
.
AddComments
(
exp
.
Alternate
,
comments2
,
ast
.
LEADING
)
}
return
exp
}
return
left
...
...
@@ -783,17 +1004,30 @@ func (self *_parser) parseAssignmentExpression() ast.Expression {
self
.
nextStatement
()
return
&
ast
.
BadExpression
{
From
:
idx
,
To
:
self
.
idx
}
}
return
&
ast
.
AssignExpression
{
comments
:=
self
.
findComments
(
false
)
exp
:=
&
ast
.
AssignExpression
{
Left
:
left
,
Operator
:
operator
,
Right
:
self
.
parseAssignmentExpression
(),
}
if
self
.
mode
&
StoreComments
!=
0
{
self
.
commentMap
.
AddComments
(
exp
.
Right
,
comments
,
ast
.
LEADING
)
}
return
exp
}
return
left
}
func
(
self
*
_parser
)
parseExpression
()
ast
.
Expression
{
comments
:=
self
.
findComments
(
false
)
statementComments
:=
self
.
fetchComments
()
next
:=
self
.
parseAssignmentExpression
left
:=
next
()
...
...
@@ -811,5 +1045,10 @@ func (self *_parser) parseExpression() ast.Expression {
}
}
if
self
.
mode
&
StoreComments
!=
0
{
self
.
commentMap
.
AddComments
(
left
,
comments
,
ast
.
LEADING
)
self
.
commentMap
.
AddComments
(
left
,
statementComments
,
ast
.
LEADING
)
}
return
left
}
Godeps/_workspace/src/github.com/robertkrimen/otto/parser/lexer.go
View file @
c305005d
...
...
@@ -120,6 +120,7 @@ func isLineTerminator(chr rune) bool {
func
(
self
*
_parser
)
scan
()
(
tkn
token
.
Token
,
literal
string
,
idx
file
.
Idx
)
{
self
.
implicitSemicolon
=
false
self
.
skippedLineBreak
=
false
for
{
self
.
skipWhiteSpace
()
...
...
@@ -238,9 +239,20 @@ func (self *_parser) scan() (tkn token.Token, literal string, idx file.Idx) {
tkn
=
self
.
switch2
(
token
.
MULTIPLY
,
token
.
MULTIPLY_ASSIGN
)
case
'/'
:
if
self
.
chr
==
'/'
{
if
self
.
mode
&
StoreComments
!=
0
{
runes
:=
self
.
readSingleLineComment
()
literal
=
string
(
runes
)
tkn
=
token
.
COMMENT
return
}
self
.
skipSingleLineComment
()
continue
}
else
if
self
.
chr
==
'*'
{
if
self
.
mode
&
StoreComments
!=
0
{
literal
=
string
(
self
.
readMultiLineComment
())
tkn
=
token
.
COMMENT
return
}
self
.
skipMultiLineComment
()
continue
}
else
{
...
...
@@ -411,6 +423,39 @@ func (self *_RegExp_parser) read() {
}
}
func
(
self
*
_parser
)
readSingleLineComment
()
(
result
[]
rune
)
{
for
self
.
chr
!=
-
1
{
self
.
read
()
if
isLineTerminator
(
self
.
chr
)
{
return
}
result
=
append
(
result
,
self
.
chr
)
}
// Get rid of the trailing -1
result
=
result
[
:
len
(
result
)
-
1
]
return
}
func
(
self
*
_parser
)
readMultiLineComment
()
(
result
[]
rune
)
{
self
.
read
()
for
self
.
chr
>=
0
{
chr
:=
self
.
chr
self
.
read
()
if
chr
==
'*'
&&
self
.
chr
==
'/'
{
self
.
read
()
return
}
result
=
append
(
result
,
chr
)
}
self
.
errorUnexpected
(
0
,
self
.
chr
)
return
}
func
(
self
*
_parser
)
skipSingleLineComment
()
{
for
self
.
chr
!=
-
1
{
self
.
read
()
...
...
@@ -442,6 +487,7 @@ func (self *_parser) skipWhiteSpace() {
continue
case
'\r'
:
if
self
.
_peek
()
==
'\n'
{
self
.
skippedLineBreak
=
true
self
.
read
()
}
fallthrough
...
...
@@ -449,6 +495,7 @@ func (self *_parser) skipWhiteSpace() {
if
self
.
insertSemicolon
{
return
}
self
.
skippedLineBreak
=
true
self
.
read
()
continue
}
...
...
Godeps/_workspace/src/github.com/robertkrimen/otto/parser/parser.go
View file @
c305005d
...
...
@@ -49,6 +49,7 @@ type Mode uint
const
(
IgnoreRegExpErrors
Mode
=
1
<<
iota
// Ignore RegExp compatibility errors (allow backtracking)
StoreComments
// Store the comments from source to the comments map
)
type
_parser
struct
{
...
...
@@ -79,6 +80,10 @@ type _parser struct {
mode
Mode
file
*
file
.
File
comments
[]
*
ast
.
Comment
commentMap
*
ast
.
CommentMap
skippedLineBreak
bool
}
func
_newParser
(
filename
,
src
string
,
base
int
)
*
_parser
{
...
...
@@ -88,6 +93,9 @@ func _newParser(filename, src string, base int) *_parser {
length
:
len
(
src
),
base
:
base
,
file
:
file
.
NewFile
(
filename
,
src
,
base
),
comments
:
make
([]
*
ast
.
Comment
,
0
),
commentMap
:
&
ast
.
CommentMap
{},
skippedLineBreak
:
false
,
}
}
...
...
@@ -184,6 +192,9 @@ func (self *_parser) parse() (*ast.Program, error) {
if
false
{
self
.
errors
.
Sort
()
}
self
.
addCommentStatements
(
program
,
ast
.
FINAL
)
return
program
,
self
.
errors
.
Err
()
}
...
...
@@ -270,3 +281,63 @@ func (self *_parser) position(idx file.Idx) file.Position {
return
position
}
// findComments finds the following comments.
// Comments on the same line will be grouped together and returned.
// After the first line break, comments will be added as statement comments.
func
(
self
*
_parser
)
findComments
(
ignoreLineBreak
bool
)
[]
*
ast
.
Comment
{
if
self
.
mode
&
StoreComments
==
0
{
return
nil
}
comments
:=
make
([]
*
ast
.
Comment
,
0
)
newline
:=
false
for
self
.
implicitSemicolon
==
false
||
ignoreLineBreak
{
if
self
.
token
!=
token
.
COMMENT
{
break
}
comment
:=
&
ast
.
Comment
{
Begin
:
self
.
idx
,
Text
:
self
.
literal
,
Position
:
ast
.
TBD
,
}
newline
=
self
.
skippedLineBreak
||
newline
if
newline
&&
!
ignoreLineBreak
{
self
.
comments
=
append
(
self
.
comments
,
comment
)
}
else
{
comments
=
append
(
comments
,
comment
)
}
self
.
next
()
}
return
comments
}
// addCommentStatements will add the previously parsed, not positioned comments to the provided node
func
(
self
*
_parser
)
addCommentStatements
(
node
ast
.
Node
,
position
ast
.
CommentPosition
)
{
if
len
(
self
.
comments
)
>
0
{
self
.
commentMap
.
AddComments
(
node
,
self
.
comments
,
position
)
// Reset comments
self
.
comments
=
make
([]
*
ast
.
Comment
,
0
)
}
}
// fetchComments fetches the current comments, resets the slice and returns the comments
func
(
self
*
_parser
)
fetchComments
()
(
comments
[]
*
ast
.
Comment
)
{
comments
=
self
.
comments
self
.
comments
=
nil
return
comments
}
// consumeComments consumes the current comments and appends them to the provided node
func
(
self
*
_parser
)
consumeComments
(
node
ast
.
Node
,
position
ast
.
CommentPosition
)
{
self
.
commentMap
.
AddComments
(
node
,
self
.
comments
,
position
)
self
.
comments
=
nil
}
Godeps/_workspace/src/github.com/robertkrimen/otto/parser/statement.go
View file @
c305005d
...
...
@@ -7,10 +7,24 @@ import (
func
(
self
*
_parser
)
parseBlockStatement
()
*
ast
.
BlockStatement
{
node
:=
&
ast
.
BlockStatement
{}
// Find comments before the leading brace
if
self
.
mode
&
StoreComments
!=
0
{
self
.
commentMap
.
AddComments
(
node
,
self
.
findComments
(
false
),
ast
.
LEADING
)
}
node
.
LeftBrace
=
self
.
expect
(
token
.
LEFT_BRACE
)
node
.
List
=
self
.
parseStatementList
()
self
.
consumeComments
(
node
,
ast
.
FINAL
)
node
.
RightBrace
=
self
.
expect
(
token
.
RIGHT_BRACE
)
// Find comments after the trailing brace
if
self
.
mode
&
StoreComments
!=
0
{
self
.
commentMap
.
AddComments
(
node
,
self
.
findComments
(
false
),
ast
.
TRAILING
)
}
return
node
}
...
...
@@ -21,7 +35,14 @@ func (self *_parser) parseEmptyStatement() ast.Statement {
func
(
self
*
_parser
)
parseStatementList
()
(
list
[]
ast
.
Statement
)
{
for
self
.
token
!=
token
.
RIGHT_BRACE
&&
self
.
token
!=
token
.
EOF
{
list
=
append
(
list
,
self
.
parseStatement
())
if
self
.
token
==
token
.
COMMENT
{
self
.
parseCommentElement
()
continue
}
statement
:=
self
.
parseStatement
()
list
=
append
(
list
,
statement
)
self
.
addCommentStatements
(
statement
,
ast
.
LEADING
)
}
return
...
...
@@ -77,6 +98,9 @@ func (self *_parser) parseStatement() ast.Statement {
// LabelledStatement
colon
:=
self
.
idx
self
.
next
()
// :
comments
:=
self
.
findComments
(
false
)
label
:=
identifier
.
Name
for
_
,
value
:=
range
self
.
scope
.
labels
{
if
label
==
value
{
...
...
@@ -86,11 +110,17 @@ func (self *_parser) parseStatement() ast.Statement {
self
.
scope
.
labels
=
append
(
self
.
scope
.
labels
,
label
)
// Push the label
statement
:=
self
.
parseStatement
()
self
.
scope
.
labels
=
self
.
scope
.
labels
[
:
len
(
self
.
scope
.
labels
)
-
1
]
// Pop the label
return
&
ast
.
LabelledStatement
{
exp
:=
&
ast
.
LabelledStatement
{
Label
:
identifier
,
Colon
:
colon
,
Statement
:
statement
,
}
if
self
.
mode
&
StoreComments
!=
0
{
self
.
commentMap
.
AddComments
(
exp
,
comments
,
ast
.
TRAILING
)
}
return
exp
}
self
.
optionalSemicolon
()
...
...
@@ -107,16 +137,26 @@ func (self *_parser) parseTryStatement() ast.Statement {
Body
:
self
.
parseBlockStatement
(),
}
if
self
.
mode
&
StoreComments
!=
0
{
self
.
commentMap
.
AddComments
(
node
.
Body
,
self
.
findComments
(
true
),
ast
.
TRAILING
)
}
if
self
.
token
==
token
.
CATCH
{
catch
:=
self
.
idx
self
.
next
()
self
.
expect
(
token
.
LEFT_PARENTHESIS
)
comments
:=
self
.
findComments
(
true
)
if
self
.
token
!=
token
.
IDENTIFIER
{
self
.
expect
(
token
.
IDENTIFIER
)
self
.
nextStatement
()
return
&
ast
.
BadStatement
{
From
:
catch
,
To
:
self
.
idx
}
}
else
{
identifier
:=
self
.
parseIdentifier
()
if
self
.
mode
&
StoreComments
!=
0
{
self
.
commentMap
.
AddComments
(
identifier
,
comments
,
ast
.
LEADING
)
}
self
.
expect
(
token
.
RIGHT_PARENTHESIS
)
node
.
Catch
=
&
ast
.
CatchStatement
{
Catch
:
catch
,
...
...
@@ -124,11 +164,22 @@ func (self *_parser) parseTryStatement() ast.Statement {
Body
:
self
.
parseBlockStatement
(),
}
}
if
self
.
mode
&
StoreComments
!=
0
{
self
.
commentMap
.
AddComments
(
node
.
Catch
,
self
.
findComments
(
true
),
ast
.
TRAILING
)
}
}
if
self
.
token
==
token
.
FINALLY
{
self
.
next
()
comments
:=
self
.
findComments
(
true
)
node
.
Finally
=
self
.
parseBlockStatement
()
if
self
.
mode
&
StoreComments
!=
0
{
self
.
commentMap
.
AddComments
(
node
.
Finally
,
comments
,
ast
.
LEADING
)
}
}
if
node
.
Catch
==
nil
&&
node
.
Finally
==
nil
{
...
...
@@ -143,10 +194,15 @@ func (self *_parser) parseFunctionParameterList() *ast.ParameterList {
opening
:=
self
.
expect
(
token
.
LEFT_PARENTHESIS
)
var
list
[]
*
ast
.
Identifier
for
self
.
token
!=
token
.
RIGHT_PARENTHESIS
&&
self
.
token
!=
token
.
EOF
{
comments
:=
self
.
findComments
(
true
)
if
self
.
token
!=
token
.
IDENTIFIER
{
self
.
expect
(
token
.
IDENTIFIER
)
}
else
{
list
=
append
(
list
,
self
.
parseIdentifier
())
identifier
:=
self
.
parseIdentifier
()
if
self
.
mode
&
StoreComments
!=
0
{
self
.
commentMap
.
AddComments
(
identifier
,
comments
,
ast
.
LEADING
)
}
list
=
append
(
list
,
identifier
)
}
if
self
.
token
!=
token
.
RIGHT_PARENTHESIS
{
self
.
expect
(
token
.
COMMA
)
...
...
@@ -218,12 +274,24 @@ func (self *_parser) parseFunctionBlock(node *ast.FunctionLiteral) {
func
(
self
*
_parser
)
parseDebuggerStatement
()
ast
.
Statement
{
idx
:=
self
.
expect
(
token
.
DEBUGGER
)
comments
:=
self
.
findComments
(
true
)
node
:=
&
ast
.
DebuggerStatement
{
Debugger
:
idx
,
}
if
self
.
mode
&
StoreComments
!=
0
{
self
.
commentMap
.
AddComments
(
node
,
comments
,
ast
.
TRAILING
)
}
self
.
semicolon
()
if
!
self
.
skippedLineBreak
{
if
self
.
mode
&
StoreComments
!=
0
{
self
.
commentMap
.
AddComments
(
node
,
self
.
findComments
(
false
),
ast
.
TRAILING
)
}
}
return
node
}
...
...
@@ -309,30 +377,77 @@ func (self *_parser) parseSwitchStatement() ast.Statement {
func
(
self
*
_parser
)
parseWithStatement
()
ast
.
Statement
{
self
.
expect
(
token
.
WITH
)
// Find the comments after with
comments
:=
self
.
findComments
(
true
)
self
.
expect
(
token
.
LEFT_PARENTHESIS
)
node
:=
&
ast
.
WithStatement
{
Object
:
self
.
parseExpression
(),
}
self
.
expect
(
token
.
RIGHT_PARENTHESIS
)
// Add the key comments
if
self
.
mode
&
StoreComments
!=
0
{
self
.
commentMap
.
AddComments
(
node
,
comments
,
ast
.
KEY
)
}
// Find the leading comments for the body
comments
=
self
.
findComments
(
true
)
node
.
Body
=
self
.
parseStatement
()
// Add the body comments
if
self
.
mode
&
StoreComments
!=
0
{
self
.
commentMap
.
AddComments
(
node
.
Body
,
comments
,
ast
.
LEADING
)
}
// Move the trailing comments to the with statement
self
.
commentMap
.
MoveComments
(
node
.
Body
,
node
,
ast
.
TRAILING
)
return
node
}
func
(
self
*
_parser
)
parseCaseStatement
()
*
ast
.
CaseStatement
{
var
comments
[]
*
ast
.
Comment
node
:=
&
ast
.
CaseStatement
{
Case
:
self
.
idx
,
}
if
self
.
mode
&
StoreComments
!=
0
{
self
.
commentMap
.
AddComments
(
node
,
self
.
findComments
(
true
),
ast
.
LEADING
)
}
// Consume current comments
self
.
consumeComments
(
node
,
ast
.
LEADING
)
if
self
.
token
==
token
.
DEFAULT
{
self
.
next
()
}
else
{
self
.
expect
(
token
.
CASE
)
comments
=
self
.
findComments
(
true
)
node
.
Test
=
self
.
parseExpression
()
if
self
.
mode
&
StoreComments
!=
0
{
self
.
commentMap
.
AddComments
(
node
.
Test
,
comments
,
ast
.
LEADING
)
}
comments
=
self
.
findComments
(
true
)
if
self
.
mode
&
StoreComments
!=
0
{
self
.
commentMap
.
AddComments
(
node
.
Test
,
comments
,
ast
.
TRAILING
)
}
}
self
.
expect
(
token
.
COLON
)
if
self
.
mode
&
StoreComments
!=
0
{
self
.
commentMap
.
AddComments
(
node
.
Test
,
self
.
findComments
(
false
),
ast
.
TRAILING
)
}
for
{
if
self
.
token
==
token
.
EOF
||
self
.
token
==
token
.
RIGHT_BRACE
||
...
...
@@ -340,8 +455,12 @@ func (self *_parser) parseCaseStatement() *ast.CaseStatement {
self
.
token
==
token
.
DEFAULT
{
break
}
node
.
Consequent
=
append
(
node
.
Consequent
,
self
.
parseStatement
())
consequent
:=
self
.
parseStatement
()
node
.
Consequent
=
append
(
node
.
Consequent
,
consequent
)
if
self
.
mode
&
StoreComments
!=
0
{
self
.
commentMap
.
AddComments
(
consequent
,
self
.
findComments
(
false
),
ast
.
TRAILING
)
}
}
return
node
...
...
@@ -360,44 +479,84 @@ func (self *_parser) parseForIn(into ast.Expression) *ast.ForInStatement {
// Already have consumed "<into> in"
// Comments after the in, before the expression
comments
:=
self
.
findComments
(
true
)
source
:=
self
.
parseExpression
()
if
self
.
mode
&
StoreComments
!=
0
{
self
.
commentMap
.
AddComments
(
source
,
comments
,
ast
.
LEADING
)
}
self
.
expect
(
token
.
RIGHT_PARENTHESIS
)
return
&
ast
.
ForInStatement
{
comments
=
self
.
findComments
(
true
)
body
:=
self
.
parseIterationStatement
()
if
self
.
mode
&
StoreComments
!=
0
{
self
.
commentMap
.
AddComments
(
body
,
comments
,
ast
.
LEADING
)
}
forin
:=
&
ast
.
ForInStatement
{
Into
:
into
,
Source
:
source
,
Body
:
self
.
parseIterationStatement
()
,
Body
:
body
,
}
self
.
commentMap
.
MoveComments
(
body
,
forin
,
ast
.
TRAILING
)
return
forin
}
func
(
self
*
_parser
)
parseFor
(
initializer
ast
.
Expression
)
*
ast
.
ForStatement
{
// Already have consumed "<initializer> ;"
comments
:=
self
.
findComments
(
true
)
var
test
,
update
ast
.
Expression
if
self
.
token
!=
token
.
SEMICOLON
{
test
=
self
.
parseExpression
()
if
self
.
mode
&
StoreComments
!=
0
{
self
.
commentMap
.
AddComments
(
test
,
comments
,
ast
.
LEADING
)
}
}
self
.
expect
(
token
.
SEMICOLON
)
comments
=
self
.
findComments
(
true
)
if
self
.
token
!=
token
.
RIGHT_PARENTHESIS
{
update
=
self
.
parseExpression
()
if
self
.
mode
&
StoreComments
!=
0
{
self
.
commentMap
.
AddComments
(
update
,
comments
,
ast
.
LEADING
)
}
}
self
.
expect
(
token
.
RIGHT_PARENTHESIS
)
return
&
ast
.
ForStatement
{
comments
=
self
.
findComments
(
true
)
body
:=
self
.
parseIterationStatement
()
if
self
.
mode
&
StoreComments
!=
0
{
self
.
commentMap
.
AddComments
(
body
,
comments
,
ast
.
LEADING
)
}
forstatement
:=
&
ast
.
ForStatement
{
Initializer
:
initializer
,
Test
:
test
,
Update
:
update
,
Body
:
self
.
parseIterationStatement
()
,
Body
:
body
,
}
self
.
commentMap
.
MoveComments
(
body
,
forstatement
,
ast
.
TRAILING
)
return
forstatement
}
func
(
self
*
_parser
)
parseForOrForInStatement
()
ast
.
Statement
{
idx
:=
self
.
expect
(
token
.
FOR
)
self
.
expect
(
token
.
LEFT_PARENTHESIS
)
comments
:=
self
.
findComments
(
true
)
var
left
[]
ast
.
Expression
forIn
:=
false
...
...
@@ -435,11 +594,19 @@ func (self *_parser) parseForOrForInStatement() ast.Statement {
self
.
nextStatement
()
return
&
ast
.
BadStatement
{
From
:
idx
,
To
:
self
.
idx
}
}
if
self
.
mode
&
StoreComments
!=
0
{
self
.
commentMap
.
AddComments
(
left
[
0
],
comments
,
ast
.
LEADING
)
}
return
self
.
parseForIn
(
left
[
0
])
}
self
.
expect
(
token
.
SEMICOLON
)
return
self
.
parseFor
(
&
ast
.
SequenceExpression
{
Sequence
:
left
})
initializer
:=
&
ast
.
SequenceExpression
{
Sequence
:
left
}
if
self
.
mode
&
StoreComments
!=
0
{
self
.
commentMap
.
AddComments
(
initializer
,
comments
,
ast
.
LEADING
)
}
return
self
.
parseFor
(
initializer
)
}
func
(
self
*
_parser
)
parseVariableStatement
()
*
ast
.
VariableStatement
{
...
...
@@ -447,12 +614,27 @@ func (self *_parser) parseVariableStatement() *ast.VariableStatement {
idx
:=
self
.
expect
(
token
.
VAR
)
list
:=
self
.
parseVariableDeclarationList
(
idx
)
self
.
semicolon
()
return
&
ast
.
VariableStatement
{
statement
:=
&
ast
.
VariableStatement
{
Var
:
idx
,
List
:
list
,
}
self
.
commentMap
.
MoveComments
(
statement
.
List
[
len
(
statement
.
List
)
-
1
],
statement
,
ast
.
TRAILING
)
if
self
.
mode
&
StoreComments
!=
0
{
self
.
commentMap
.
AddComments
(
statement
,
self
.
findComments
(
true
),
ast
.
TRAILING
)
}
self
.
semicolon
()
if
self
.
skippedLineBreak
{
if
self
.
mode
&
StoreComments
!=
0
{
self
.
commentMap
.
AddComments
(
statement
,
self
.
findComments
(
false
),
ast
.
TRAILING
)
}
}
return
statement
}
func
(
self
*
_parser
)
parseDoWhileStatement
()
ast
.
Statement
{
...
...
@@ -463,7 +645,13 @@ func (self *_parser) parseDoWhileStatement() ast.Statement {
}()
self
.
expect
(
token
.
DO
)
comments
:=
self
.
findComments
(
true
)
node
:=
&
ast
.
DoWhileStatement
{}
if
self
.
mode
&
StoreComments
!=
0
{
self
.
commentMap
.
AddComments
(
node
,
comments
,
ast
.
KEY
)
}
if
self
.
token
==
token
.
LEFT_BRACE
{
node
.
Body
=
self
.
parseBlockStatement
()
}
else
{
...
...
@@ -471,49 +659,123 @@ func (self *_parser) parseDoWhileStatement() ast.Statement {
}
self
.
expect
(
token
.
WHILE
)
comments
=
self
.
findComments
(
true
)
self
.
expect
(
token
.
LEFT_PARENTHESIS
)
node
.
Test
=
self
.
parseExpression
()
if
self
.
mode
&
StoreComments
!=
0
{
self
.
commentMap
.
AddComments
(
node
.
Test
,
comments
,
ast
.
LEADING
)
}
self
.
expect
(
token
.
RIGHT_PARENTHESIS
)
if
self
.
mode
&
StoreComments
!=
0
{
self
.
commentMap
.
AddComments
(
node
.
Test
,
self
.
findComments
(
false
),
ast
.
TRAILING
)
}
return
node
}
func
(
self
*
_parser
)
parseWhileStatement
()
ast
.
Statement
{
self
.
expect
(
token
.
WHILE
)
// Comments after while keyword
comments
:=
self
.
findComments
(
true
)
self
.
expect
(
token
.
LEFT_PARENTHESIS
)
node
:=
&
ast
.
WhileStatement
{
Test
:
self
.
parseExpression
(),
}
// Add the while comments
if
self
.
mode
&
StoreComments
!=
0
{
self
.
commentMap
.
AddComments
(
node
,
comments
,
ast
.
KEY
)
}
self
.
expect
(
token
.
RIGHT_PARENTHESIS
)
// Finding comments prior to the body
comments
=
self
.
findComments
(
true
)
node
.
Body
=
self
.
parseIterationStatement
()
// Adding the comments prior to the body
if
self
.
mode
&
StoreComments
!=
0
{
self
.
commentMap
.
AddComments
(
node
.
Body
,
comments
,
ast
.
LEADING
)
}
// Move the trailing comments to the while statement
self
.
commentMap
.
MoveComments
(
node
.
Body
,
node
,
ast
.
TRAILING
)
return
node
}
func
(
self
*
_parser
)
parseIfStatement
()
ast
.
Statement
{
self
.
expect
(
token
.
IF
)
comments
:=
self
.
findComments
(
true
)
self
.
expect
(
token
.
LEFT_PARENTHESIS
)
node
:=
&
ast
.
IfStatement
{
Test
:
self
.
parseExpression
(),
}
if
self
.
mode
&
StoreComments
!=
0
{
self
.
commentMap
.
AddComments
(
node
,
comments
,
ast
.
KEY
)
}
self
.
expect
(
token
.
RIGHT_PARENTHESIS
)
comments
=
self
.
findComments
(
true
)
if
self
.
token
==
token
.
LEFT_BRACE
{
node
.
Consequent
=
self
.
parseBlockStatement
()
}
else
{
node
.
Consequent
=
self
.
parseStatement
()
}
if
self
.
mode
&
StoreComments
!=
0
{
self
.
commentMap
.
AddComments
(
node
.
Consequent
,
comments
,
ast
.
LEADING
)
self
.
commentMap
.
AddComments
(
node
.
Consequent
,
self
.
findComments
(
true
),
ast
.
TRAILING
)
}
if
self
.
token
==
token
.
ELSE
{
self
.
next
()
comments
=
self
.
findComments
(
true
)
node
.
Alternate
=
self
.
parseStatement
()
if
self
.
mode
&
StoreComments
!=
0
{
self
.
commentMap
.
AddComments
(
node
.
Alternate
,
comments
,
ast
.
LEADING
)
self
.
commentMap
.
AddComments
(
node
.
Alternate
,
self
.
findComments
(
false
),
ast
.
TRAILING
)
}
}
return
node
}
func
(
self
*
_parser
)
parseSourceElement
()
ast
.
Statement
{
return
self
.
parseStatement
()
statementComment
:=
self
.
fetchComments
()
statement
:=
self
.
parseStatement
()
if
self
.
mode
&
StoreComments
!=
0
{
self
.
commentMap
.
AddComments
(
statement
,
statementComment
,
ast
.
LEADING
)
}
return
statement
}
func
(
self
*
_parser
)
parseCommentElement
()
{
literal
:=
self
.
literal
idx
:=
self
.
expect
(
token
.
COMMENT
)
self
.
comments
=
append
(
self
.
comments
,
&
ast
.
Comment
{
Begin
:
idx
,
Text
:
literal
,
Position
:
ast
.
LEADING
,
})
}
func
(
self
*
_parser
)
parseSourceElements
()
[]
ast
.
Statement
{
...
...
@@ -524,10 +786,19 @@ func (self *_parser) parseSourceElements() []ast.Statement {
break
}
if
self
.
token
==
token
.
COMMENT
{
self
.
parseCommentElement
()
continue
}
body
=
append
(
body
,
self
.
parseSourceElement
())
}
for
self
.
token
!=
token
.
EOF
{
if
self
.
token
==
token
.
COMMENT
{
self
.
parseCommentElement
()
continue
}
body
=
append
(
body
,
self
.
parseSourceElement
())
}
...
...
@@ -546,6 +817,9 @@ func (self *_parser) parseProgram() *ast.Program {
func
(
self
*
_parser
)
parseBreakStatement
()
ast
.
Statement
{
idx
:=
self
.
expect
(
token
.
BREAK
)
breakComments
:=
self
.
findComments
(
true
)
semicolon
:=
self
.
implicitSemicolon
if
self
.
token
==
token
.
SEMICOLON
{
semicolon
=
true
...
...
@@ -557,10 +831,16 @@ func (self *_parser) parseBreakStatement() ast.Statement {
if
!
self
.
scope
.
inIteration
&&
!
self
.
scope
.
inSwitch
{
goto
illegal
}
return
&
ast
.
BranchStatement
{
breakStatement
:=
&
ast
.
BranchStatement
{
Idx
:
idx
,
Token
:
token
.
BREAK
,
}
if
self
.
mode
&
StoreComments
!=
0
{
self
.
commentMap
.
AddComments
(
breakStatement
,
breakComments
,
ast
.
TRAILING
)
}
return
breakStatement
}
if
self
.
token
==
token
.
IDENTIFIER
{
...
...
Godeps/_workspace/src/github.com/robertkrimen/otto/runtime.go
View file @
c305005d
...
...
@@ -55,6 +55,7 @@ type _runtime struct {
otto
*
Otto
eval
*
_object
// The builtin eval, for determine indirect versus direct invocation
debugger
func
(
*
Otto
)
random
func
()
float64
labels
[]
string
// FIXME
lck
sync
.
Mutex
...
...
jsre/jsre.go
View file @
c305005d
...
...
@@ -18,8 +18,11 @@
package
jsre
import
(
crand
"crypto/rand"
"encoding/binary"
"fmt"
"io/ioutil"
"math/rand"
"sync"
"time"
...
...
@@ -70,6 +73,18 @@ func New(assetPath string) *JSRE {
return
re
}
// randomSource returns a pseudo random value generator.
func
randomSource
()
*
rand
.
Rand
{
bytes
:=
make
([]
byte
,
8
)
seed
:=
time
.
Now
()
.
UnixNano
()
if
_
,
err
:=
crand
.
Read
(
bytes
);
err
==
nil
{
seed
=
int64
(
binary
.
LittleEndian
.
Uint64
(
bytes
))
}
src
:=
rand
.
NewSource
(
seed
)
return
rand
.
New
(
src
)
}
// This function runs the main event loop from a goroutine that is started
// when JSRE is created. Use Stop() before exiting to properly stop it.
// The event loop processes vm access requests from the evalQueue in a
...
...
@@ -81,6 +96,9 @@ func New(assetPath string) *JSRE {
// called from JS through an RPC call.
func
(
self
*
JSRE
)
runEventLoop
()
{
vm
:=
otto
.
New
()
r
:=
randomSource
()
vm
.
SetRandomSource
(
r
.
Float64
)
registry
:=
map
[
*
jsTimer
]
*
jsTimer
{}
ready
:=
make
(
chan
*
jsTimer
)
...
...
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