diff --git a/Makefile b/Makefile index fd0b755..be2ecb7 100644 --- a/Makefile +++ b/Makefile @@ -23,7 +23,7 @@ fixme: ack -l FIXME *.go otto: - $(MAKE) -C otto + $(MAKE) -C otto run: go run -a ./otto/main.go ./otto.js diff --git a/evaluate.go b/evaluate.go index 9f53368..f6239e8 100644 --- a/evaluate.go +++ b/evaluate.go @@ -49,7 +49,7 @@ func (self *_runtime) evaluate(node _node) Value { return self.evaluateBody(node.Body) case *_blockNode: - return self.evaluateBody(node.Body) + return self.evaluateBlock(node) case *_valueNode: return self.evaluateValue(node) diff --git a/evaluate_statement.go b/evaluate_statement.go index aa3747c..2c77c0c 100644 --- a/evaluate_statement.go +++ b/evaluate_statement.go @@ -104,6 +104,16 @@ func (self *_runtime) evaluateWith(node *_withNode) Value { return self.evaluate(node.Body) } +func (self *_runtime) evaluateBlock(node *_blockNode) Value { + + body := node.Body + _labelSet := node._labelSet + + return self.breakEvaluate(_labelSet, func() Value { + return self.evaluateBody(body) + }) +} + func (self *_runtime) evaluateDoWhile(node *_doWhileNode) Value { test := node.Test diff --git a/node_statement.go b/node_statement.go index 86d7379..0372463 100644 --- a/node_statement.go +++ b/node_statement.go @@ -7,12 +7,14 @@ import ( type _blockNode struct { _nodeType _node_ - Body []_node + Body []_node + _labelSet _labelSet } func newBlockNode() *_blockNode { return &_blockNode{ _nodeType: nodeBlock, + _labelSet: _labelSet{}, } } diff --git a/parse_statement.go b/parse_statement.go index f32c047..0ed6e18 100644 --- a/parse_statement.go +++ b/parse_statement.go @@ -58,6 +58,8 @@ func (self *_parser) ParseStatement() _node { { _labelSet = nil switch node := statement.(type) { + case *_blockNode: + _labelSet = node._labelSet case *_doWhileNode: _labelSet = node._labelSet case *_whileNode: diff --git a/runtime_test.go b/runtime_test.go index f9ae903..b546c1a 100644 --- a/runtime_test.go +++ b/runtime_test.go @@ -1130,6 +1130,27 @@ func TestNewPrototype(t *testing.T) { `, "Nothing happens.") } +func TestBlock(t *testing.T) { + Terst(t) + + test := runTest() + + test(` + var abc=0; + var ghi; + def: { + do { + abc++; + if (!(abc < 10)) { + break def; + ghi = "ghi"; + } + } while (true); + } + [ abc,ghi ]; + `, "10,") +} + func TestWith(t *testing.T) { Terst(t)