Skip to content

Commit 97db37d

Browse files
committed
Implement script tokenizer
0 parents  commit 97db37d

File tree

7 files changed

+611
-0
lines changed

7 files changed

+611
-0
lines changed

design/scripting.md

Lines changed: 177 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,177 @@
1+
# Scripting in Ballduck
2+
3+
Ballduck offers a simple scripting language optimized for prototyping and
4+
overall development speed. It is useful as a "glue" between components that
5+
would be too tedious to implement in Rust.
6+
7+
To attach scripts to a Node, it needs a `ScriptComponent`. This Component can
8+
hold any number of scripts.
9+
10+
11+
## Syntax
12+
13+
Ballscript resembles a very simplified form of `Python`.
14+
15+
The convention for intendation is to use **tabs**.
16+
17+
### Functions
18+
19+
A function can be declared with:
20+
21+
```ballscript
22+
fn foo(bar, baz)
23+
pass
24+
fn bar(qux,)
25+
pass
26+
```
27+
28+
A function can be called with:
29+
30+
```ballscript
31+
foo(13, "thirty-seven")
32+
a = bar("quux")
33+
```
34+
35+
Function names may **not** conflict with variable names.
36+
37+
### Variables
38+
39+
A variable can be declared with:
40+
41+
```ballscript
42+
var qux
43+
var quux = 42
44+
```
45+
46+
A variable can be assigned to with:
47+
48+
```ballscript
49+
qux = "( ^-^)"
50+
```
51+
52+
Variable names may **not** conflict with function names.
53+
54+
### Comments
55+
56+
```ballscript
57+
# This is a comment
58+
```
59+
60+
61+
## Types
62+
63+
All types implement the `ScriptType` component. To use your own types you
64+
must implement `ScriptType` for said type.
65+
66+
### Built-in types
67+
68+
There are a few built-in types with a custom syntax
69+
70+
### Integers
71+
72+
Integers can be defined as
73+
74+
```ballscript
75+
232
76+
16_777_216
77+
80u8
78+
443_i16
79+
0xdeadbeef
80+
0b101010101_i32
81+
```
82+
83+
By default, integers are `isize`s, but this can be overriden as shown above
84+
85+
86+
### Floating point numbers
87+
88+
Floating point numbers can be defined as
89+
90+
```ballscript
91+
23.2
92+
16_777.216
93+
80f32
94+
443_f64
95+
0xdeadb.eef
96+
0b10101.0101_f32
97+
```
98+
99+
100+
### Arrays
101+
102+
Arrays are internally defined as `Vec<Box<dyn ScriptType>>`, which means
103+
they can hold any type.
104+
105+
Arrays can be created using:
106+
107+
```ballscript
108+
[]
109+
[1, 2, 3, "Chicken!"]
110+
["blep", 0.0,]
111+
```
112+
113+
114+
### Dictionaries
115+
116+
Dictionaries are internally defined as `HashMap<Box<dyn ScriptType + Hash + Eq>, Box<dyn ScriptType>>`.
117+
Again, this means that they can hold any type. The keys mush implement `Hash`
118+
and `Eq` though.
119+
120+
Dictionaries can be created using:
121+
122+
```ballscript
123+
{}
124+
{"a": 0, 5: 3.14}
125+
{a: b,}
126+
```
127+
128+
Note that floating point numbers do not implement `Eq` and hence cannot be
129+
used as keys.
130+
131+
132+
### Boolean
133+
134+
This type can be either `true` or `false`
135+
136+
137+
## Control structures
138+
139+
### `if`
140+
141+
If the expression following the `if` statement evaluates to a boolean `true`,
142+
the code block follwing it will be executed. If it is `false` it will skip
143+
the code block. If it evaluates to a non-boolean type it will throw an error.
144+
145+
### `else`
146+
147+
This statement can be put behind an `if` block. If the expression in the `if`
148+
evaluates to `false`, the block following the `else` will be executed.
149+
Otherwise, it will be skipped.
150+
151+
### `elif`
152+
153+
This is a combination of `if` and `else`: if the previous `if` or `elif`
154+
statement evaluates to `false`, the expression in the current `elif`
155+
block will be evaluates as if it were an `if`. Otherwise, it is skipped.
156+
157+
### `while`
158+
159+
This is a variant of the `if` instruction that will repeatedly execute
160+
a code block until the expression evaluates to `false`.
161+
162+
### `for`
163+
164+
This structure will iterate types that implement `ScriptIter`. If the type
165+
does not implement `ScriptIter`, an error will be thrown.
166+
167+
```ballscript
168+
for i in 10:
169+
...
170+
for v in [42, "foo"]:
171+
...
172+
for k in {"bar": "qux", 13: 37}:
173+
...
174+
```
175+
176+
## Creating custom types in Rust
177+

script/.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
/target

script/Cargo.toml

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
[package]
2+
name = "ballduck_script"
3+
version = "0.1.0"
4+
authors = ["David Hoppenbrouwers <david@salt-inc.org>"]
5+
edition = "2018"
6+
7+
[dependencies]
8+
9+
10+
[lib]
11+
name = "ballscript"
12+
path = "src/lib.rs"
13+
14+
[[bin]]
15+
name = "ballscript"
16+
path = "src/bin.rs"

script/src/ast.rs

Whitespace-only changes.

script/src/bin.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
use ballscript::*;
2+
3+
pub fn main() {
4+
test();
5+
}

script/src/lib.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
mod tokenizer;
2+
3+
pub fn test() {
4+
println!("Test");
5+
}

0 commit comments

Comments
 (0)