Skip to content

Commit

Permalink
added continue keyword
Browse files Browse the repository at this point in the history
  • Loading branch information
RednibCoding committed Jun 21, 2024
1 parent f3ef0d2 commit d502e42
Show file tree
Hide file tree
Showing 8 changed files with 73 additions and 37 deletions.
14 changes: 13 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -539,14 +539,26 @@ while x < 5 {
```

### Break
In order to break out of a loop early, you can use the break keyword
In order to break out of a loop early, you can use the `break` keyword
```js
while true {
println("I am not an endless loop")
break
}
```

### Continue
In order to stop the current iteration of a loop and skip right to the loop condition, you can use the `continue` keyword
```js
a = 10
while a > 0 {
a = a -1
if a % 2 == 0 then continue
println(a)
}
```


## Data Types

### Number
Expand Down
39 changes: 20 additions & 19 deletions ast.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,25 +3,26 @@ package runevm
type ExprType string

const (
Num ExprType = "num"
Str ExprType = "str"
Bool ExprType = "bool"
Var ExprType = "var"
Assign ExprType = "assign"
Binary ExprType = "binary"
Unary ExprType = "unary"
Fun ExprType = "fun"
If ExprType = "if"
Block ExprType = "block"
Call ExprType = "call"
Return ExprType = "return"
While ExprType = "while"
Break ExprType = "break"
Array ExprType = "array"
Table ExprType = "table"
Pair ExprType = "pair"
Index ExprType = "Index"
Import ExprType = "import"
Num ExprType = "num"
Str ExprType = "str"
Bool ExprType = "bool"
Var ExprType = "var"
Assign ExprType = "assign"
Binary ExprType = "binary"
Unary ExprType = "unary"
Fun ExprType = "fun"
If ExprType = "if"
Block ExprType = "block"
Call ExprType = "call"
Return ExprType = "return"
While ExprType = "while"
Break ExprType = "break"
Continue ExprType = "continue"
Array ExprType = "array"
Table ExprType = "table"
Pair ExprType = "pair"
Index ExprType = "Index"
Import ExprType = "import"
)

type Expr struct {
Expand Down
Binary file modified editor/vscode/rune/rune-1.0.0.vsix
Binary file not shown.
18 changes: 4 additions & 14 deletions editor/vscode/rune/syntaxes/rune.tmLanguage.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,6 @@
{
"include": "#numbers"
},
{
"include": "#functions"
},
{
"include": "#user-defined-functions"
},
Expand All @@ -41,11 +38,11 @@
"patterns": [
{
"name": "keyword.control.rune",
"match": "\\b(import|if|then|elif|else|while|break|return)\\b"
"match": "\\b(import|if|then|elif|else|while|break|continue|return)\\b"
},
{
"name": "constant.language.rune",
"match": "\\b(fun|true|false|not|array|table)\\b"
"match": "\\b(true|false|not|array|table|fun)\\b"
}
]
},
Expand All @@ -72,22 +69,15 @@
}
]
},
"functions": {
"patterns": [
{
"name": "entity.name.function.rune",
"match": "\\b(fun)\\s+([a-zA-Z_][a-zA-Z0-9_]*)\\b"
}
]
},

"user-defined-functions": {
"patterns": [
{
"name": "entity.name.function.user-defined.rune",
"begin": "\\b([a-zA-Z_][a-zA-Z0-9_]*)\\b\\s*=\\s*\\b(fun)\\b",
"beginCaptures": {
"1": { "name": "entity.name.function.rune" },
"2": { "name": "keyword.control.rune" }
"2": { "name": "constant.language.rune" }
},
"end": "(?={|;)",
"patterns": [
Expand Down
15 changes: 15 additions & 0 deletions evaluator.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,10 @@ type BreakValue struct {
Value bool
}

type ContinueValue struct {
Value bool
}

func (e *Evaluator) evaluate(exp *Expr, env *Environment) interface{} {
if exp == nil {
Error(exp, "Null expression error, this is a bug and should never happen!. Please file a bug!")
Expand Down Expand Up @@ -160,12 +164,20 @@ func (e *Evaluator) evaluate(exp *Expr, env *Environment) interface{} {
if !cond.(bool) {
break
}
shouldContinue := false
for _, exp := range exp.Body.Block {
result := e.evaluate(exp, env)
if _, ok := result.(BreakValue); ok {
return false
} else if _, ok := result.(ContinueValue); ok {
shouldContinue = true
break
}
}
if shouldContinue {
shouldContinue = false
continue
}
}
return false

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

case Continue:
return ContinueValue{Value: false}

case Import:
path := e.evaluate(exp.Left, env).(string) + ".rune"
if _, alreadyImported := e.importedPaths[path]; alreadyImported {
Expand Down
8 changes: 6 additions & 2 deletions example/test.rune
Original file line number Diff line number Diff line change
@@ -1,18 +1,22 @@

a = 1
a = 10

while true {
if a <= 0 then break
a = a -1
if a <= 0 then break
if a % 2 == 0 then continue
println(a)
}

println("Loop finished")

main = fun() {
println("Hello, World!")
return = 42
println("After return")

}

val = main()
println(val)

Expand Down
14 changes: 14 additions & 0 deletions parser.go
Original file line number Diff line number Diff line change
Expand Up @@ -436,6 +436,18 @@ func (p *Parser) parseBreakExpr() *Expr {
}
}

func (p *Parser) parseContinueExpr() *Expr {
tok := p.input.Peek()
p.skipKw("continue")
return &Expr{
Type: Continue,
Right: FALSE,
File: tok.File,
Line: tok.Line,
Col: tok.Col,
}
}

func (p *Parser) parseAtom() *Expr {
var expr *Expr
if p.isPunc("(") != nil {
Expand Down Expand Up @@ -465,6 +477,8 @@ func (p *Parser) parseAtom() *Expr {
expr = p.parseReturnExpr()
} else if p.isKw("break") != nil {
expr = p.parseBreakExpr()
} else if p.isKw("continue") != nil {
expr = p.parseContinueExpr()

} else {
tok := p.input.Next()
Expand Down
2 changes: 1 addition & 1 deletion tokenstream.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ type TokenStream struct {

func NewTokenStream(input *InputStream) *TokenStream {
keywords := map[string]bool{
"if": true, "then": true, "elif": true, "else": true, "while": true, "break": true, "fun": true, "return": true,
"if": true, "then": true, "elif": true, "else": true, "while": true, "break": true, "continue": true, "fun": true, "return": true,
"true": true, "false": true, "array": true, "table": true, "import": true, "not": true,
}
return &TokenStream{input: input, keywords: keywords}
Expand Down

0 comments on commit d502e42

Please sign in to comment.