~repos /plum
git clone https://pyrossh.dev/repos/plum.git
A statically typed, imperative programming language inspired by rust, python
58ce2893
—
pyrossh 1 year ago
docs
readme.md
CHANGED
|
@@ -5,7 +5,7 @@ A simple statically typed imperative programming language. Its main aim to be si
|
|
|
5
5
|
The compiler users the tree-sitter parser so has out of the box syntax highlighting support for helix and zed editor.
|
|
6
6
|
|
|
7
7
|
Here is some sample code, please enjoy.
|
|
8
|
-
```
|
|
8
|
+
```rb
|
|
9
9
|
module lambda
|
|
10
10
|
|
|
11
11
|
import ca/list
|
|
@@ -55,28 +55,12 @@ fn first_item(l: list[int]): int? =
|
|
|
55
55
|
fn to-celsius(f: float): float =
|
|
56
56
|
(f - 32) * (5 / 9)
|
|
57
57
|
|
|
58
|
-
class Cat[A: Comparable & Stringable] is Stringable:
|
|
59
|
-
name: str
|
|
60
|
-
age: int
|
|
61
|
-
|
|
62
|
-
fn Cat.with_name(name: str):
|
|
63
|
-
Cat(name: name, age: 0)
|
|
64
|
-
|
|
65
|
-
fn fullname() -> str:
|
|
66
|
-
name + age.to_str()
|
|
67
|
-
|
|
68
|
-
fn talk():
|
|
69
|
-
println("cat ${name} says meow")
|
|
70
|
-
|
|
71
|
-
fn to_str() -> str:
|
|
72
|
-
"Cat<{fullname()}, ${age}>"
|
|
73
|
-
|
|
74
58
|
record Cat[A: Comparable & Stringable](
|
|
75
59
|
name: str
|
|
76
60
|
age: int
|
|
77
|
-
)
|
|
61
|
+
)
|
|
78
62
|
|
|
79
|
-
fn Cat.with_name(name: str) =
|
|
63
|
+
fn Cat.with_name(name: str): Cat =
|
|
80
64
|
Cat(name: name, age: 0)
|
|
81
65
|
|
|
82
66
|
fn (c: Cat) fullname(): str =
|
|
@@ -88,7 +72,6 @@ fn (c: Cat) talk() =
|
|
|
88
72
|
fn (c: Cat) to_str(): str =
|
|
89
73
|
"Cat<{c.fullname()}, ${c.age}>"
|
|
90
74
|
|
|
91
|
-
|
|
92
75
|
type MapCallback = fn(v: a): v
|
|
93
76
|
|
|
94
77
|
trait Comparable(
|
|
@@ -103,7 +86,7 @@ enum Temperature =
|
|
|
103
86
|
| celsius(float)
|
|
104
87
|
| fahrenheit(float)
|
|
105
88
|
|
|
106
|
-
fn (s Temperature) to_str() =
|
|
89
|
+
fn (s Temperature) to_str(): str =
|
|
107
90
|
match s
|
|
108
91
|
celsius(t) && t > 30 -> "${t}C is above 30 celsius"
|
|
109
92
|
celsius(t) -> "${t}C is below 30 celsius"
|
|
@@ -148,8 +131,8 @@ for,while,if,else,record,enum,fn,assert,when,match,type
|
|
|
148
131
|
### Types
|
|
149
132
|
```
|
|
150
133
|
nil, any, bool, byte, int, float, dec, str, time, duration, regex, uuid
|
|
151
|
-
[] for lists list[int], list[list[int]]
|
|
134
|
+
[1, 2, 3] for lists list[int], list[list[int]]
|
|
152
|
-
[] for maps map[int], map[map[int]]
|
|
135
|
+
[:a => 1, :b => 2] for maps map[int], map[map[int]]
|
|
153
136
|
? for optional int? str?
|
|
154
137
|
! for return error types int!, str!
|
|
155
138
|
```
|
|
@@ -169,15 +152,14 @@ A bool can be either `true` or `false`. It is used in logical operations and con
|
|
|
169
152
|
```rb
|
|
170
153
|
assert true != false
|
|
171
154
|
|
|
172
|
-
if true || false
|
|
155
|
+
if true || false
|
|
173
156
|
print("works")
|
|
174
|
-
end
|
|
175
157
|
```
|
|
176
158
|
|
|
177
159
|
**byte**
|
|
178
160
|
|
|
179
161
|
A byte represents an unsigned 8 bit number. It is mainly used to represent strings and binary data.
|
|
180
|
-
```
|
|
162
|
+
```rb
|
|
181
163
|
let data: []byte?
|
|
182
164
|
data = [104, 101, 197, 130, 197, 130, 111, 0]
|
|
183
165
|
```
|
|
@@ -189,7 +171,7 @@ An int is a signed 64 bit number. It can be represented in various ways,
|
|
|
189
171
|
0x - Hexadecimal (Base 16)
|
|
190
172
|
13 - Standard (Base 10)
|
|
191
173
|
|
|
192
|
-
```
|
|
174
|
+
```rb
|
|
193
175
|
0b00101010
|
|
194
176
|
0b1_1111_1
|
|
195
177
|
0xff00ff
|
|
@@ -208,18 +190,17 @@ A float represents a 64-bit floating point (52-bit mantissa) IEEE-754-2008 binar
|
|
|
208
190
|
A str represents a slice of runes or unicode code points. It is encoded to UTF-8 by default.
|
|
209
191
|
It supports interpolation of variables/values that implement the ToStr interface.
|
|
210
192
|
|
|
211
|
-
```
|
|
193
|
+
```go
|
|
212
194
|
"Hello World"
|
|
213
195
|
name := "Pacos"
|
|
214
196
|
age := 1
|
|
215
197
|
println("Name ${name} age ${age}")
|
|
216
198
|
```
|
|
217
|
-
"\u0061" == "a"
|
|
218
199
|
|
|
219
200
|
|
|
220
201
|
**list**
|
|
221
202
|
|
|
222
|
-
```
|
|
203
|
+
```py
|
|
223
204
|
import pacos/list
|
|
224
205
|
|
|
225
206
|
a := [1, 2, 3] // list[int]
|
|
@@ -235,7 +216,7 @@ actors.get(5) // => nil
|
|
|
235
216
|
|
|
236
217
|
**map**
|
|
237
218
|
|
|
238
|
-
```
|
|
219
|
+
```rb
|
|
239
220
|
import pacos/map
|
|
240
221
|
|
|
241
222
|
nums := Map.new(:one => 1, :two => 2)
|
|
@@ -259,13 +240,13 @@ friends_tree := [
|
|
|
259
240
|
]
|
|
260
241
|
```
|
|
261
242
|
|
|
262
|
-
**
|
|
243
|
+
**Constants**
|
|
263
244
|
|
|
264
245
|
Constants can be declared at the top level of a program. They cannot be reassigned.
|
|
265
246
|
* Primitive values like`int, float, str` are directly replaced in code.
|
|
266
247
|
* Reference values like `list, map, records` are initialized at program start and passed by reference when used. Their data can be modified.
|
|
267
248
|
|
|
268
|
-
```
|
|
249
|
+
```rb
|
|
269
250
|
PI = 3.14159f
|
|
270
251
|
ERR_MESSAGE = "An unknown error occured"
|
|
271
252
|
COUNT = count(10)
|
|
@@ -282,7 +263,7 @@ fn count(n: int): int = n * 1
|
|
|
282
263
|
|
|
283
264
|
**Assignment statement**
|
|
284
265
|
|
|
285
|
-
```
|
|
266
|
+
```rb
|
|
286
267
|
low, mid, high := 0, 0, n.numItems
|
|
287
268
|
x := 10
|
|
288
269
|
y := 20
|
|
@@ -295,7 +276,7 @@ assoc_list["b"]
|
|
|
295
276
|
|
|
296
277
|
**While statement**
|
|
297
278
|
|
|
298
|
-
```
|
|
279
|
+
```rb
|
|
299
280
|
while low < high
|
|
300
281
|
mid = (low + high) / 2
|
|
301
282
|
low = cmp > 0 > mid + 1 : low
|
|
@@ -306,7 +287,7 @@ while low < high
|
|
|
306
287
|
|
|
307
288
|
**For statement**
|
|
308
289
|
|
|
309
|
-
```
|
|
290
|
+
```rb
|
|
310
291
|
for players_list |value|
|
|
311
292
|
if value == 0
|
|
312
293
|
continue
|
|
@@ -325,7 +306,7 @@ items
|
|
|
325
306
|
.each(|v| println("v", v))
|
|
326
307
|
.reduce(0, |v| v + 1)
|
|
327
308
|
|
|
328
|
-
fn range(start: int, end: int, cb: (v: T)
|
|
309
|
+
fn range(start: int, end: int, cb: fn(v: T): IterateResult) =
|
|
329
310
|
|
|
330
311
|
range(0, 5, |v| =>
|
|
331
312
|
sum3 += v
|
|
@@ -337,7 +318,7 @@ for items, items2 |i, j|
|
|
|
337
318
|
|
|
338
319
|
**When expression/statement**
|
|
339
320
|
|
|
340
|
-
```
|
|
321
|
+
```rb
|
|
341
322
|
when
|
|
342
323
|
cmp > 0 -> low = mid + 1
|
|
343
324
|
cmp < 0 -> high = mid
|
|
@@ -367,55 +348,64 @@ Comparison operators (<, >, ==, etc.)
|
|
|
367
348
|
|
|
368
349
|
**if expression/statement**
|
|
369
350
|
|
|
370
|
-
```
|
|
351
|
+
```rb
|
|
371
|
-
if (
|
|
352
|
+
if post.valid()
|
|
372
|
-
try expect(value == 0);
|
|
373
|
-
} else |err| {
|
|
374
|
-
_ = err;
|
|
375
|
-
|
|
353
|
+
RenderNewView()
|
|
376
|
-
|
|
354
|
+
else
|
|
355
|
+
RenderPostView(post: post)
|
|
377
356
|
```
|
|
378
357
|
|
|
379
358
|
### Conditional operators
|
|
380
359
|
|
|
381
360
|
**not operator**
|
|
382
361
|
|
|
383
|
-
```
|
|
362
|
+
```rb
|
|
384
363
|
!a
|
|
385
364
|
!true
|
|
386
365
|
```
|
|
387
366
|
|
|
388
367
|
**ternary operator**
|
|
389
368
|
|
|
390
|
-
```
|
|
369
|
+
```rb
|
|
391
370
|
x ? x : y
|
|
392
371
|
```
|
|
393
372
|
|
|
394
373
|
**safe navigation operator**
|
|
395
374
|
|
|
396
|
-
```
|
|
375
|
+
```rb
|
|
397
376
|
a?.b?.c?.d
|
|
398
377
|
```
|
|
399
378
|
|
|
400
379
|
**Safe index operator**
|
|
401
|
-
```
|
|
380
|
+
```rb
|
|
402
381
|
array?[1]
|
|
403
382
|
```
|
|
404
383
|
|
|
405
384
|
**elvis operator**
|
|
406
385
|
|
|
407
|
-
```
|
|
386
|
+
```rb
|
|
408
387
|
x ?: y
|
|
409
388
|
```
|
|
410
389
|
|
|
411
390
|
**elvis assignment operator**
|
|
412
391
|
|
|
413
|
-
```
|
|
392
|
+
```rb
|
|
414
393
|
atomic_number ?= 2
|
|
415
394
|
```
|
|
416
395
|
|
|
417
396
|
**Range operator**
|
|
418
|
-
```
|
|
397
|
+
```rb
|
|
419
398
|
for 5..10 |i|
|
|
420
399
|
println(i)
|
|
421
400
|
```
|
|
401
|
+
|
|
402
|
+
```rb
|
|
403
|
+
fn create_post_action(req: Request): Response =
|
|
404
|
+
post := Post(title = req.params.title, body = req.params.body)
|
|
405
|
+
if post.valid()
|
|
406
|
+
RenderNewView()
|
|
407
|
+
else
|
|
408
|
+
post := createRecord(post)
|
|
409
|
+
setSuccessMessage("Post created")
|
|
410
|
+
redirectTo("/posts")
|
|
411
|
+
```
|