~repos /plum
git clone
https://pyrossh.dev/repos/plum.git
Discussions:
https://groups.google.com/g/rust-embed-devs
A statically typed, imperative programming language inspired by rust, python
c3ac9baf
—
pyrossh 1 year ago
improve readme
readme.md
CHANGED
|
@@ -3,23 +3,14 @@
|
|
|
3
3
|
- A statically typed, imperative programming language inspired by rust, koka.
|
|
4
4
|
- The compiler users the tree-sitter parser so has out of the box syntax highlighting support for helix and zed editor.
|
|
5
5
|
|
|
6
|
-
**Rules**
|
|
7
|
-
|
|
8
|
-
- Function parameters are passed by value only. You cannot modify a parameter. The compiler will throw an error if you try to.
|
|
9
|
-
- Strict naming convention
|
|
10
|
-
- Only one way of doing things ex: loops, condition
|
|
11
|
-
|
|
12
|
-
**Todo**
|
|
13
|
-
linter, formatter, test runner, language server, package manager
|
|
14
|
-
|
|
15
6
|
Here is some sample code, please enjoy.
|
|
16
7
|
|
|
17
8
|
```go
|
|
18
9
|
module lambda
|
|
19
10
|
|
|
20
|
-
import
|
|
11
|
+
import std/list
|
|
21
|
-
import
|
|
12
|
+
import std/math
|
|
22
|
-
import
|
|
13
|
+
import std/http
|
|
23
14
|
|
|
24
15
|
const START_YEAR = 2101
|
|
25
16
|
const END_YEAR = 2111
|
|
@@ -154,17 +145,13 @@ for,while,if,else if,else,record,enum,fn,assert,match,type
|
|
|
154
145
|
|
|
155
146
|
### Types
|
|
156
147
|
|
|
157
|
-
**nil**
|
|
158
|
-
|
|
159
|
-
The nil type is used to represent types that are nilable
|
|
160
|
-
|
|
161
148
|
**any**
|
|
162
149
|
|
|
163
150
|
The any type is an empty trait and is used to represent all types
|
|
164
151
|
|
|
165
152
|
**error**
|
|
166
153
|
|
|
167
|
-
The error type is
|
|
154
|
+
The error type is a trait that represents all Error types
|
|
168
155
|
|
|
169
156
|
**bool**
|
|
170
157
|
|
|
@@ -242,7 +229,7 @@ age := 1
|
|
|
242
229
|
printLn("Name ${name} age ${age}")
|
|
243
230
|
```
|
|
244
231
|
|
|
245
|
-
|
|
232
|
+
##list
|
|
246
233
|
|
|
247
234
|
```py
|
|
248
235
|
import pacos/list
|
|
@@ -268,7 +255,7 @@ items
|
|
|
268
255
|
.reduce(0, |v| v + 1)
|
|
269
256
|
```
|
|
270
257
|
|
|
271
|
-
|
|
258
|
+
## map
|
|
272
259
|
|
|
273
260
|
```rs
|
|
274
261
|
import pacos/map
|
|
@@ -298,9 +285,9 @@ friends_tree
|
|
|
298
285
|
.reduce(0, |k, v| v + 1)
|
|
299
286
|
```
|
|
300
287
|
|
|
301
|
-
|
|
288
|
+
## option
|
|
302
289
|
|
|
303
|
-
An option is a type that represents either value present
|
|
290
|
+
An option is a type that represents either value present `some` or nothing present `none`
|
|
304
291
|
|
|
305
292
|
```go
|
|
306
293
|
import std/option
|
|
@@ -314,9 +301,9 @@ match c
|
|
|
314
301
|
some(car) -> car.wheels
|
|
315
302
|
```
|
|
316
303
|
|
|
317
|
-
|
|
304
|
+
## result
|
|
318
305
|
|
|
319
|
-
A result is a type that represents either success ok or failure err
|
|
306
|
+
A result is a type that represents either success `ok` or failure `err`
|
|
320
307
|
|
|
321
308
|
```rs
|
|
322
309
|
import std/str
|
|
@@ -379,7 +366,7 @@ const PI = 3.14159
|
|
|
379
366
|
const NAME = "pacos"
|
|
380
367
|
const DEBUG_ENABLED = true
|
|
381
368
|
const COUNT = count(10)
|
|
382
|
-
const COUNTRIES_LIST =
|
|
369
|
+
const COUNTRIES_LIST = list.of("US", "INDIA", "CANADA")
|
|
383
370
|
const COUNTRY_CODES = map.of(
|
|
384
371
|
"in" => "INDIA",
|
|
385
372
|
"us" => "United States",
|
|
@@ -434,32 +421,6 @@ for v := range list
|
|
|
434
421
|
sum += k + v
|
|
435
422
|
```
|
|
436
423
|
|
|
437
|
-
**Range Over Function**
|
|
438
|
-
|
|
439
|
-
```rb
|
|
440
|
-
type Seq0 = fn(yield: fn(): bool): bool
|
|
441
|
-
type Seq1[V] = fn(yield: fn(V): bool): bool
|
|
442
|
-
type Seq2[K, V] = fn(yield: fn(K, V): bool): bool
|
|
443
|
-
|
|
444
|
-
record Tree[E](
|
|
445
|
-
value E,
|
|
446
|
-
left: optional[Tree[E]],
|
|
447
|
-
right: optional[Tree[E]],
|
|
448
|
-
)
|
|
449
|
-
|
|
450
|
-
fn (t Tree[E]) op_range(yld: fn(E): bool): bool =
|
|
451
|
-
t ? true : t.left?.in_order(yld) && yld(t.val) && t.right?.in_order(yld)
|
|
452
|
-
|
|
453
|
-
tree := Tree(
|
|
454
|
-
value: 10,
|
|
455
|
-
left: Tree(20, Tree(30), Tree(39)),
|
|
456
|
-
right: Tree(40),
|
|
457
|
-
)
|
|
458
|
-
|
|
459
|
-
for t := range tree
|
|
460
|
-
printLn(v)
|
|
461
|
-
```
|
|
462
|
-
|
|
463
424
|
**if expression/statement**
|
|
464
425
|
|
|
465
426
|
```py
|
|
@@ -473,33 +434,33 @@ else
|
|
|
473
434
|
printLn("Boring name...")
|
|
474
435
|
```
|
|
475
436
|
|
|
476
|
-
|
|
437
|
+
## Match expression/statement
|
|
477
438
|
|
|
478
|
-
```
|
|
439
|
+
```rs
|
|
440
|
+
fn getPerimeter(shape: Shape): Result[float] =
|
|
479
|
-
|
|
441
|
+
match shape
|
|
442
|
+
Rectangle(r) -> Ok(2 * r.length() + 2 * r.width())
|
|
480
|
-
|
|
443
|
+
Circle(c) -> Ok(2 * c.radius() * PI)
|
|
481
|
-
cmp < 0 -> high = mid
|
|
482
|
-
|
|
444
|
+
c -> err(RuntimeError("expected shape but found ${@TypeName(c)}"))
|
|
483
445
|
|
|
484
|
-
|
|
446
|
+
match x, y
|
|
485
447
|
1, 1 -> "both are 1"
|
|
486
448
|
1, _ -> "x is 1"
|
|
487
449
|
_, 1 -> "y is 1"
|
|
488
450
|
_, _ -> "neither is 1"
|
|
489
451
|
|
|
490
|
-
|
|
452
|
+
match n
|
|
491
453
|
2 | 4 | 6 | 8 -> "This is an even number"
|
|
492
454
|
1 | 3 | 5 | 7 -> "This is an odd number"
|
|
493
455
|
_ -> "I'm not sure"
|
|
494
456
|
|
|
495
|
-
|
|
457
|
+
match
|
|
496
|
-
|
|
458
|
+
cmp > 0 -> low = mid + 1
|
|
497
|
-
|
|
459
|
+
cmp < 0 -> high = mid
|
|
498
|
-
|
|
460
|
+
cmp == 0 -> return mid, true
|
|
499
|
-
_ -> "This list has more than 2 elements"
|
|
500
461
|
```
|
|
501
462
|
|
|
502
|
-
##
|
|
463
|
+
## Operators
|
|
503
464
|
|
|
504
465
|
**not operator**
|
|
505
466
|
|
|
@@ -586,13 +547,45 @@ fn add(items ...str) =
|
|
|
586
547
|
x >>= y // 3
|
|
587
548
|
```
|
|
588
549
|
|
|
550
|
+
**range operator**
|
|
551
|
+
|
|
552
|
+
```go
|
|
553
|
+
type Seq0 = fn(yield: fn(): bool): bool
|
|
554
|
+
type Seq1[V] = fn(yield: fn(V): bool): bool
|
|
555
|
+
type Seq2[K, V] = fn(yield: fn(K, V): bool): bool
|
|
556
|
+
|
|
557
|
+
record Tree[E](
|
|
558
|
+
value E,
|
|
559
|
+
left: option[Tree[E]],
|
|
560
|
+
right: option[Tree[E]],
|
|
561
|
+
)
|
|
562
|
+
|
|
563
|
+
fn (t Tree[E]) op_range(yld: fn(E): bool): bool =
|
|
564
|
+
t ? true : t.left?.in_order(yld) && yld(t.val) && t.right?.in_order(yld)
|
|
565
|
+
|
|
566
|
+
tree := Tree(
|
|
567
|
+
value: 10,
|
|
568
|
+
left: Tree(20, Tree(30), Tree(39)),
|
|
569
|
+
right: Tree(40),
|
|
570
|
+
)
|
|
571
|
+
|
|
572
|
+
for t := range tree
|
|
573
|
+
printLn(v)
|
|
574
|
+
```
|
|
575
|
+
|
|
589
|
-
|
|
576
|
+
## Generics
|
|
590
577
|
|
|
591
578
|
```
|
|
592
579
|
fn add[T: int | float](a: List[T], b: List[T]): List[T] =
|
|
593
580
|
pass
|
|
594
581
|
```
|
|
595
582
|
|
|
583
|
+
## Rules
|
|
584
|
+
|
|
585
|
+
- Function parameters are passed by value only. You cannot modify a parameter. The compiler will throw an error if you try to.
|
|
586
|
+
- Strict naming convention
|
|
587
|
+
- Only one way of doing things ex: loops, condition
|
|
588
|
+
|
|
596
589
|
### General naming convention
|
|
597
590
|
|
|
598
591
|
| Item | Convention |
|
|
@@ -603,3 +596,7 @@ fn add[T: int | float](a: List[T], b: List[T]): List[T] =
|
|
|
603
596
|
| Local variables | snake_case |
|
|
604
597
|
| Constants | SCREAMING_SNAKE_CASE |
|
|
605
598
|
| Generics | single uppercase letter |
|
|
599
|
+
|
|
600
|
+
## Todo
|
|
601
|
+
|
|
602
|
+
linter, formatter, test runner, language server, package manager
|