Skip to content

Commit d502e42

Browse files
committed
added continue keyword
1 parent f3ef0d2 commit d502e42

File tree

8 files changed

+73
-37
lines changed

8 files changed

+73
-37
lines changed

README.md

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -539,14 +539,26 @@ while x < 5 {
539539
```
540540

541541
### Break
542-
In order to break out of a loop early, you can use the break keyword
542+
In order to break out of a loop early, you can use the `break` keyword
543543
```js
544544
while true {
545545
println("I am not an endless loop")
546546
break
547547
}
548548
```
549549

550+
### Continue
551+
In order to stop the current iteration of a loop and skip right to the loop condition, you can use the `continue` keyword
552+
```js
553+
a = 10
554+
while a > 0 {
555+
a = a -1
556+
if a % 2 == 0 then continue
557+
println(a)
558+
}
559+
```
560+
561+
550562
## Data Types
551563

552564
### Number

ast.go

Lines changed: 20 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -3,25 +3,26 @@ package runevm
33
type ExprType string
44

55
const (
6-
Num ExprType = "num"
7-
Str ExprType = "str"
8-
Bool ExprType = "bool"
9-
Var ExprType = "var"
10-
Assign ExprType = "assign"
11-
Binary ExprType = "binary"
12-
Unary ExprType = "unary"
13-
Fun ExprType = "fun"
14-
If ExprType = "if"
15-
Block ExprType = "block"
16-
Call ExprType = "call"
17-
Return ExprType = "return"
18-
While ExprType = "while"
19-
Break ExprType = "break"
20-
Array ExprType = "array"
21-
Table ExprType = "table"
22-
Pair ExprType = "pair"
23-
Index ExprType = "Index"
24-
Import ExprType = "import"
6+
Num ExprType = "num"
7+
Str ExprType = "str"
8+
Bool ExprType = "bool"
9+
Var ExprType = "var"
10+
Assign ExprType = "assign"
11+
Binary ExprType = "binary"
12+
Unary ExprType = "unary"
13+
Fun ExprType = "fun"
14+
If ExprType = "if"
15+
Block ExprType = "block"
16+
Call ExprType = "call"
17+
Return ExprType = "return"
18+
While ExprType = "while"
19+
Break ExprType = "break"
20+
Continue ExprType = "continue"
21+
Array ExprType = "array"
22+
Table ExprType = "table"
23+
Pair ExprType = "pair"
24+
Index ExprType = "Index"
25+
Import ExprType = "import"
2526
)
2627

2728
type Expr struct {

editor/vscode/rune/rune-1.0.0.vsix

-7 Bytes
Binary file not shown.

editor/vscode/rune/syntaxes/rune.tmLanguage.json

Lines changed: 4 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,6 @@
1414
{
1515
"include": "#numbers"
1616
},
17-
{
18-
"include": "#functions"
19-
},
2017
{
2118
"include": "#user-defined-functions"
2219
},
@@ -41,11 +38,11 @@
4138
"patterns": [
4239
{
4340
"name": "keyword.control.rune",
44-
"match": "\\b(import|if|then|elif|else|while|break|return)\\b"
41+
"match": "\\b(import|if|then|elif|else|while|break|continue|return)\\b"
4542
},
4643
{
4744
"name": "constant.language.rune",
48-
"match": "\\b(fun|true|false|not|array|table)\\b"
45+
"match": "\\b(true|false|not|array|table|fun)\\b"
4946
}
5047
]
5148
},
@@ -72,22 +69,15 @@
7269
}
7370
]
7471
},
75-
"functions": {
76-
"patterns": [
77-
{
78-
"name": "entity.name.function.rune",
79-
"match": "\\b(fun)\\s+([a-zA-Z_][a-zA-Z0-9_]*)\\b"
80-
}
81-
]
82-
},
72+
8373
"user-defined-functions": {
8474
"patterns": [
8575
{
8676
"name": "entity.name.function.user-defined.rune",
8777
"begin": "\\b([a-zA-Z_][a-zA-Z0-9_]*)\\b\\s*=\\s*\\b(fun)\\b",
8878
"beginCaptures": {
8979
"1": { "name": "entity.name.function.rune" },
90-
"2": { "name": "keyword.control.rune" }
80+
"2": { "name": "constant.language.rune" }
9181
},
9282
"end": "(?={|;)",
9383
"patterns": [

evaluator.go

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,10 @@ type BreakValue struct {
2525
Value bool
2626
}
2727

28+
type ContinueValue struct {
29+
Value bool
30+
}
31+
2832
func (e *Evaluator) evaluate(exp *Expr, env *Environment) interface{} {
2933
if exp == nil {
3034
Error(exp, "Null expression error, this is a bug and should never happen!. Please file a bug!")
@@ -160,12 +164,20 @@ func (e *Evaluator) evaluate(exp *Expr, env *Environment) interface{} {
160164
if !cond.(bool) {
161165
break
162166
}
167+
shouldContinue := false
163168
for _, exp := range exp.Body.Block {
164169
result := e.evaluate(exp, env)
165170
if _, ok := result.(BreakValue); ok {
166171
return false
172+
} else if _, ok := result.(ContinueValue); ok {
173+
shouldContinue = true
174+
break
167175
}
168176
}
177+
if shouldContinue {
178+
shouldContinue = false
179+
continue
180+
}
169181
}
170182
return false
171183

@@ -229,6 +241,9 @@ func (e *Evaluator) evaluate(exp *Expr, env *Environment) interface{} {
229241
case Break:
230242
return BreakValue{Value: false}
231243

244+
case Continue:
245+
return ContinueValue{Value: false}
246+
232247
case Import:
233248
path := e.evaluate(exp.Left, env).(string) + ".rune"
234249
if _, alreadyImported := e.importedPaths[path]; alreadyImported {

example/test.rune

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,22 @@
11

2-
a = 1
2+
a = 10
33

44
while true {
5-
if a <= 0 then break
65
a = a -1
6+
if a <= 0 then break
7+
if a % 2 == 0 then continue
78
println(a)
89
}
910

11+
println("Loop finished")
12+
1013
main = fun() {
1114
println("Hello, World!")
1215
return = 42
1316
println("After return")
1417

1518
}
19+
1620
val = main()
1721
println(val)
1822

parser.go

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -436,6 +436,18 @@ func (p *Parser) parseBreakExpr() *Expr {
436436
}
437437
}
438438

439+
func (p *Parser) parseContinueExpr() *Expr {
440+
tok := p.input.Peek()
441+
p.skipKw("continue")
442+
return &Expr{
443+
Type: Continue,
444+
Right: FALSE,
445+
File: tok.File,
446+
Line: tok.Line,
447+
Col: tok.Col,
448+
}
449+
}
450+
439451
func (p *Parser) parseAtom() *Expr {
440452
var expr *Expr
441453
if p.isPunc("(") != nil {
@@ -465,6 +477,8 @@ func (p *Parser) parseAtom() *Expr {
465477
expr = p.parseReturnExpr()
466478
} else if p.isKw("break") != nil {
467479
expr = p.parseBreakExpr()
480+
} else if p.isKw("continue") != nil {
481+
expr = p.parseContinueExpr()
468482

469483
} else {
470484
tok := p.input.Next()

tokenstream.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ type TokenStream struct {
2424

2525
func NewTokenStream(input *InputStream) *TokenStream {
2626
keywords := map[string]bool{
27-
"if": true, "then": true, "elif": true, "else": true, "while": true, "break": true, "fun": true, "return": true,
27+
"if": true, "then": true, "elif": true, "else": true, "while": true, "break": true, "continue": true, "fun": true, "return": true,
2828
"true": true, "false": true, "array": true, "table": true, "import": true, "not": true,
2929
}
3030
return &TokenStream{input: input, keywords: keywords}

0 commit comments

Comments
 (0)