Skip to content

Commit

Permalink
Remove support for curly braces in foreach, while, if and function (#89)
Browse files Browse the repository at this point in the history
* Remove support for curly braces in foreach, while, if and function

Signed-off-by: Flipez <code@brauser.io>

* Update docs

Signed-off-by: Flipez <code@brauser.io>

* Update docs

Signed-off-by: Flipez <code@brauser.io>
  • Loading branch information
Flipez authored Jun 27, 2022
1 parent 6461ba9 commit d6c32a4
Show file tree
Hide file tree
Showing 32 changed files with 142 additions and 147 deletions.
10 changes: 5 additions & 5 deletions ast/ast_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,8 @@ func TestString(t *testing.T) {
`true ? puts(true) : puts(false)`,
},
{
"foreach i, e in [1, 2, 3] {\n puts(i)\n}",
"foreach i, e in [1, 2, 3] {\n puts(i)\n}",
"foreach i, e in [1, 2, 3] \n puts(i)\nend",
"foreach i, e in [1, 2, 3] \n puts(i)\nend",
},
{
"if (true)\n return (true)\nelse\n puts(false)\nend",
Expand All @@ -41,12 +41,12 @@ func TestString(t *testing.T) {
"while (true)\n puts(true)\nend",
},
{
"while (true) {\n puts(true)\n}",
"while (true)\n puts(true)\nend",
"while (true)\n puts(true)\nend",
},
{
"while {\n puts(true)\n}",
"",
"while\n puts(true)\n",
"puts(true)",
},
}

Expand Down
4 changes: 2 additions & 2 deletions ast/foreach.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,8 @@ func (fes *Foreach) String() string {
out.WriteString(fes.Ident)
out.WriteString(" in ")
out.WriteString(fes.Value.String())
out.WriteString(" {\n ")
out.WriteString(" \n ")
out.WriteString(fes.Body.String())
out.WriteString("\n}")
out.WriteString("\nend")
return out.String()
}
12 changes: 6 additions & 6 deletions docs/content/_index.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,28 +25,28 @@ input = open("examples/aoc/2021/day-1/input").lines()


a = []
foreach i, number in input {
foreach i, number in input
a.yoink(number.strip().plz_i())
}
end
input = a

increase = 0
foreach i, number in input {
foreach i, number in input
if (number > input[i-1])
increase = increase + 1
end
}
end
puts(increase + 1)

increase = 0
foreach i, number in input {
foreach i, number in input
sum = number + input[i+1] + input[i+2]
sum_two = input[i+1] + input[i+2] + input[i+3]

if (sum_two > sum)
increase = increase + 1
end
}
end
puts(increase + 1)
```

Expand Down
14 changes: 10 additions & 4 deletions docs/content/docs/control_expressions/foreach.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,10 @@ input = open("examples/aoc/2021/day-1/input").lines()
// define temporary array
a = []

foreach i, number in input {
foreach i, number in input
// read each line into temporary array and cast it into an integer
a.yoink(number.strip().plz_i())
}
end

// assign temporary array to input array
input = a
Expand All @@ -28,7 +28,10 @@ input = a
Count form zero to a given number (excluding):

```js
🚀 > foreach i in 5 { puts(i) }
🚀 > foreach i in 5
puts(i)
end

0
1
2
Expand All @@ -40,7 +43,10 @@ Count form zero to a given number (excluding):
Iterate over a string:

```js
🚀 > foreach i in "test" { puts(i) }
🚀 > foreach i in "test"
puts(i)
end

"t"
"e"
"s"
Expand Down
13 changes: 0 additions & 13 deletions docs/content/docs/control_expressions/if.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,19 +7,6 @@ menu:
# If
With `if` and `else` keywords the flow of a program can be controlled.

```js
🚀 > if (a.type() == "STRING") {
puts("is a string")
} else {
puts("is not a string")
}

// which prints
is a string
```

> 👉 Since `0.13` curly braces are completely optional (closing brace needs to be replaced with `end`)
```js
🚀 > if (a.type() == "STRING")
puts("is a string")
Expand Down
4 changes: 2 additions & 2 deletions docs/content/docs/literals/file.md
Original file line number Diff line number Diff line change
Expand Up @@ -58,9 +58,9 @@ Seek sets the offset for the next Read or Write on file to offset, interpreted a


### write(STRING)
> Returns `BOOLEAN|ERROR`
> Returns `INTEGER|ERROR`
Writes the given string to the file. Returns `true` on success.
Writes the given string to the file. Returns number of written bytes on success.



Expand Down
4 changes: 2 additions & 2 deletions docs/content/docs/literals/http.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,10 @@ menu:


```js
def test() {
def test()
puts(request["body"])
return("test")
}
end

HTTP.handle("/", test)

Expand Down
8 changes: 5 additions & 3 deletions docs/content/docs/specification/closures.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,11 @@ toc: true
---
# Closures
```js
newGreeter = def (greeting) {
return def (name) { puts(greeting + " " + name); }
};
newGreeter = def (greeting)
return def (name)
puts(greeting + " " + name)
end
end

hello = newGreeter("Hello");

Expand Down
4 changes: 2 additions & 2 deletions docs/content/docs/specification/comments.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@ All following content up to the end of the line is part of the comment.

```js
// This is a comment
def (a) {
def (a)
// This is also a comment
a + a // And this
}
end
```
15 changes: 9 additions & 6 deletions docs/content/docs/specification/functions.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ toc: true
Implicit and explicit return statements are supported.

```js
fibonacci = def (x) {
fibonacci = def (x)
if (x == 0)
0
else
Expand All @@ -19,18 +19,21 @@ fibonacci = def (x) {
fibonacci(x - 1) + fibonacci(x - 2);
end
end
};
end
```

> New in `0.11`:
Functions can now also be created as named functions:

```js
🚀 > def test() { puts("test")}
=> def () {
puts(test)
}
🚀 > def test()
puts("test")
end

=> def ()
puts(test)
end

🚀 > test()
"test"
Expand Down
6 changes: 2 additions & 4 deletions docs/content/docs/specification/modules.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,9 @@ For example take this module:
a = 1
A = 5

Sum = def (a, b) {
Sum = def (a, b)
return a + b
}


end
```

You can import it with:
Expand Down
4 changes: 2 additions & 2 deletions docs/generate.go
Original file line number Diff line number Diff line change
Expand Up @@ -166,10 +166,10 @@ To cast a negative integer a digit can be prefixed with a - eg. -456.`,

tempData = templateData{
Title: "HTTP",
Example: `def test() {
Example: `def test()
puts(request["body"])
return("test")
}
end
HTTP.handle("/", test)
Expand Down
71 changes: 34 additions & 37 deletions evaluator/evaluator_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -117,17 +117,13 @@ func TestIfElseExpressions(t *testing.T) {
input string
expected interface{}
}{
{"if (true) { 10 }", 10},
{"if (false) { 10 }", nil},
{"if (true)\n 10 end", 10},
{"if (false) \n 10 end", nil},
{"if (1) { 10 }", 10},
{"if (1) \n 10 end", 10},
{"if (1 < 2) { 10 }", 10},
{"if (1 > 2) { 10 }", nil},
{"if (1 > 2) { 10 } else { 20 }", 20},
{"if (1 < 2) { 10 } else { 20 }", 10},
{"if (1 < 2) \n 10 \n else \n 20 end", 10},
{"if (true) \n 10 \nend", 10},
{"if (false) \n 10 \nend", nil},
{"if (1) \n 10 \nend", 10},
{"if (1 < 2) \n 10 \nend", 10},
{"if (1 > 2) \n 10 \nend", nil},
{"if (1 > 2) \n 10 \n else \n 20 \nend", 20},
{"if (1 < 2) \n 10 \n else \n 20 \nend", 10},
}

for _, tt := range tests {
Expand All @@ -151,12 +147,12 @@ func TestReturnStatements(t *testing.T) {
{"return 2 * 5; 9;", 10},
{"9; return 2 * 5; 9;", 10},
{`
if (10 > 1) {
if (10 > 1) {
if (10 > 1)
if (10 > 1)
return 10;
}
end
return 1;
}
end
`, 10},
}

Expand All @@ -176,17 +172,16 @@ func TestErrorHandling(t *testing.T) {
{"-true", "unknown operator: -BOOLEAN"},
{"true + false", "unknown operator: BOOLEAN + BOOLEAN"},
{"5; true + false; 5", "unknown operator: BOOLEAN + BOOLEAN"},
{"if (10 > 1) { true + false }", "unknown operator: BOOLEAN + BOOLEAN"},
{"if (10 > 1) \n true + false \n", "unknown operator: BOOLEAN + BOOLEAN"},
{"foobar", "identifier not found: foobar"},
{
`
if (10 > 1) {
if (10 > 1) {
if (10 > 1)
if (10 > 1)
return true + false
}
end
return 1
}
end
`, "unknown operator: BOOLEAN + BOOLEAN",
},
{`"Hello" - "World"`, "unknown operator: STRING - STRING"},
Expand All @@ -198,15 +193,15 @@ func TestErrorHandling(t *testing.T) {
{"if (5 % 0)\n puts(true)\nend", "division by zero not allowed"},
{"a = {(5%0): true}", "division by zero not allowed"},
{"a = {true: (5%0)}", "division by zero not allowed"},
{"def test() { puts(true) }; a = {test: true}", "unusable as hash key: FUNCTION"},
{"def test() \n puts(true) \nend; a = {test: true}", "unusable as hash key: FUNCTION"},
{"import(true)", "Import Error: invalid import path '&{%!s(bool=true)}'"},
{"import(5%0)", "division by zero not allowed"},
{`import("fixtures/nope")`, "Import Error: no module named 'fixtures/nope' found"},
{
`import("../fixtures/parser_error")`,
"Parse Error: [0:10: expected next token to be EOF, got EOF instead 0:10: expected next token to be EOF, got EOF instead]",
"Parse Error: [0:10: expected next token to be EOF, got EOF instead]",
},
{"def test() { puts(true) }; test[1]", "index operator not supported: FUNCTION"},
{"def test() \n puts(true) \nend; test[1]", "index operator not supported: FUNCTION"},
{"[1] - [1]", "unknown operator: ARRAY - ARRAY"},
}

Expand Down Expand Up @@ -242,7 +237,7 @@ func TestAssignStatements(t *testing.T) {
}

func TestFunctionObject(t *testing.T) {
input := "def(x) { x + 2; };"
input := "def(x) \n x + 2; \nend;"

evaluated := testEval(input)
def, ok := evaluated.(*object.Function)
Expand Down Expand Up @@ -270,12 +265,12 @@ func TestFunctionApplication(t *testing.T) {
input string
expected int64
}{
{"identity = def(x) { x; }; identity(5);", 5},
{"identity = def(x) { return x; }; identity(5);", 5},
{"double = def(x) { x * 2; }; double(5);", 10},
{"add = def(x, y) { x + y; }; add(5, 5);", 10},
{"add = def(x, y) { x + y; }; add(5 + 5, add(5, 5));", 20},
{"def(x) { x; }(5)", 5},
{"identity = def(x) \n x; \nend; identity(5);", 5},
{"identity = def(x) \n return x; \nend; identity(5);", 5},
{"double = def(x) \n x * 2; \nend; double(5);", 10},
{"add = def(x, y) \n x + y; \nend; add(5, 5);", 10},
{"add = def(x, y) \n x + y; \nend; add(5 + 5, add(5, 5));", 20},
{"def(x) \n x; \nend(5)", 5},
}

for _, tt := range tests {
Expand All @@ -285,9 +280,11 @@ func TestFunctionApplication(t *testing.T) {

func TestClosures(t *testing.T) {
input := `
newAdder = def(x) {
def(y) { x + y };
};
newAdder = def(x)
def(y)
x + y
end
end;
addTwo = newAdder(2);
addTwo(2);`
Expand Down Expand Up @@ -570,9 +567,9 @@ func TestNamedFunctionStatements(t *testing.T) {
input string
expected int64
}{
{"def five() { return 5 } five()", 5},
{"def ten() { return 10 } ten()", 10},
{"def fifteen() { return 15 } fifteen()", 15},
{"def five() \n return 5 \nend five()", 5},
{"def ten() \n return 10 \nend ten()", 10},
{"def fifteen() \n return 15 \nend fifteen()", 15},
}

for _, tt := range tests {
Expand Down
Loading

0 comments on commit d6c32a4

Please sign in to comment.