~repos /plum

#treesitter#compiler#wasm

git clone https://pyrossh.dev/repos/plum.git

A statically typed, imperative programming language inspired by rust, python


c772e73b pyrossh

1 year ago
improve syn
Files changed (4) hide show
  1. example/aa.kk +84 -0
  2. example/fn.palm +83 -0
  3. example/sample.palm +261 -26
  4. src/language/palm.langium +3 -3
example/aa.kk ADDED
@@ -0,0 +1,84 @@
1
+ fun print10()
2
+ for(1,10) fn(i)
3
+ println(i)
4
+
5
+ fun encode2( s : string, shift : int )
6
+ s.map( fn(c)
7
+ if c < 'a' || c > 'z' then return c
8
+ val base = (c - 'a').int
9
+ val rot = (base + shift) % 26
10
+ (rot.char + 'a')
11
+ )
12
+
13
+ fun printhi10()
14
+ repeat(10)
15
+ println("hi")
16
+
17
+ fun sublist( xs : list<a>, start : int, len : int = xs.length ) : list<a>
18
+ if start <= 0 return xs.take(len)
19
+ match xs
20
+ Nil -> Nil
21
+ Cons(_,xx) -> xx.sublist(start - 1, len)
22
+
23
+ fun chisqr( xs : list<float64>, ys : list<float64> ) : float64
24
+ zipwith(xs,ys, fn(x,y) ((x - y)^2.0)/y ).foldr(0.0,(+))
25
+
26
+
27
+ fun fib(n : int) : div int
28
+ if n <= 0 then 0
29
+ elif n == 1 then 1
30
+ else fib(n - 1) + fib(n - 2)
31
+
32
+ fun fib2(n)
33
+ var x := 0
34
+ var y := 1
35
+ repeat(n)
36
+ val y0 = y
37
+ y := x+y
38
+ x := y0
39
+ x
40
+
41
+ fun wrong() : (() -> console ())
42
+ var x := 1
43
+ (fn(){ x := x + 1; println(x) })
44
+
45
+
46
+ struct person
47
+ age : int
48
+ name : string
49
+ realname : string = name
50
+
51
+ type person
52
+ Person
53
+ age : int
54
+ name : string
55
+ realname : string = name
56
+
57
+ val brian = Person( 29, "Brian" )
58
+
59
+
60
+ type color
61
+ Red
62
+ Green
63
+ Blue
64
+
65
+ type number
66
+ Infinity
67
+ Integer( i : int )
68
+
69
+ type bool
70
+ False
71
+ True
72
+
73
+ type list<a>
74
+ Nil
75
+ Cons{ head : a; tail : list<a> }
76
+
77
+ type tree
78
+ Tip
79
+ Bin( left: tree, value : int, right: tree )
80
+
81
+ fun tmap-inorder( t : tree, f : int -> int ) : tree
82
+ match t
83
+ Bin(l,x,r) -> Bin( l.tmap-inorder(f), f(x), r.tmap-inorder(f) )
84
+ Tip -> Tip
example/fn.palm ADDED
@@ -0,0 +1,83 @@
1
+ bool = (true | false)
2
+ op_eq(x: bool, y: bool) = x == y
3
+ op_ne(x: bool, y: bool) = x != y
4
+ op_and(x: bool, y: bool) = x && y
5
+ op_or(x: bool, y: bool) = x || y
6
+ op_xor(x: bool, y: bool) = x <> y
7
+ op_not(x: bool,): bool = !x
8
+ str(x: bool) = x.str()
9
+
10
+ list = (first | link(v: a, rest: list))
11
+ each(l: list, cb: (v: a)) =
12
+ match l
13
+ first => first
14
+ link(v, rest) =>
15
+ cb(v)
16
+ each(rest, cb)
17
+
18
+ map(l: list, cb: (v: a): v) =
19
+ match l
20
+ first => first
21
+ link(v, rest) => link(cb(v), map(rest, cb))
22
+
23
+ enum List<a>
24
+ first
25
+ link(v: a, rest: List)
26
+
27
+ fn each(l: list, cb: fn(v: a)) =
28
+ match l
29
+ first => first
30
+ link(v, rest) =>
31
+ cb(v)
32
+ each(rest, cb)
33
+
34
+ fn map(l: list, cb: fn(v: a): v) =
35
+ match l
36
+ first => first
37
+ link(v, rest) => link(cb(v), map(rest, cb))
38
+
39
+ Cat = (name: str, age: int)
40
+ fullname(c: Cat) =
41
+ c.name + c.age.str()
42
+ talk(c: Cat) =
43
+ println("cat ${c.name} says meow")
44
+
45
+ struct Cat(a, b)
46
+ name: str
47
+ age: int
48
+ fullname(c: Cat) =
49
+ c.name + c.age.str()
50
+ talk(c: Cat) =
51
+ println("cat ${c.name} says meow")
52
+
53
+ c = Cat(name = "123", age = 1)
54
+ c |> Cat.talk()
55
+ [1, 2, 3] |> list.each(println)
56
+
57
+ fib(n: int = 0) = 0
58
+ fib(n: int = 1) = 1
59
+ fib(n: int) = fib(n - 1) + fib(n - 2)
60
+
61
+ factorial(n: int) = 1
62
+ factorial(n: int) = n * factorial(n - 1)
63
+
64
+ to-celsius(f: float) = (f - 32) * (5 / 9)
65
+
66
+ repeat(n: int, cb: fn(int)) =
67
+ if n != 0:
68
+ cb(n)
69
+ repeat(n-1, cb)
70
+
71
+ range(start: int, e: int, cb: fn(int)) =
72
+ if (start < end):
73
+ cb(start)
74
+ range(start + 1, end, cb)
75
+ elif (start > end):
76
+ cb(start)
77
+ range(start - 1, end, cb)
78
+
79
+ main() =
80
+ repeat(10) |i|:
81
+ println(i)
82
+ range(10, 20) |i|:
83
+ println(i)
example/sample.palm CHANGED
@@ -1,9 +1,10 @@
1
1
  module palm
2
2
 
3
+ // byte, *byte, bool, int, float, str, decimal, time
3
- // [] for arrays []int []string
4
+ // [] for slices []int []str
4
- // {} for maps {int}int {string}string
5
+ // {} for maps [int]int [str]str
5
- // ? for optional int? string?
6
+ // ? for optional int? str?
6
- // ! for error types int!, string!
7
+ // ! for error types int!, str!
7
8
  // nil
8
9
 
9
10
  // match a {
@@ -13,25 +14,151 @@ module palm
13
14
  // _ => 10
14
15
  // }
15
16
 
17
+ trait Comparable<a>:
18
+ fn compare(left: a, right: a): bool
19
+
20
+ trait Stringable:
16
- primitive str {
21
+ fn str() str
22
+
23
+ entity arr<A>:
24
+ val data: *A
25
+ val length: int
26
+
27
+ fn map(cb: fn(v: A) A):
28
+ return cb(a)
29
+
30
+ fn each():
31
+ pass
32
+
33
+ entity number is Comparable, Stringable {
34
+ fn sqrt() {
35
+ }
36
+ fn abs() {
37
+ }
38
+ fn acos() {
39
+ }
40
+ fn acosh() {
41
+ }
42
+ fn asin() {
43
+ }
44
+ fn asinh() {
45
+ }
17
46
  }
18
47
 
48
+ alias list<a, n : int> = {
49
+ data : a[n],
50
+ length : uint32
51
+ }
52
+
53
+
19
- primitive int {
54
+ primitive math {
55
+ fn sqrt() {
56
+ }
57
+
20
- fn add() {
58
+ fn log() {
59
+ }
60
+
61
+ fn round() {
62
+ }
63
+ }
64
+
65
+ 2.0
66
+ |> math.sqrt()
67
+ |> math.log()
68
+ |> math.round()
69
+
70
+ var nn = 2.0
71
+
72
+ entity str is Comparable, Stringable {
73
+ val data: *u16
74
+ val length: int
75
+
76
+ // fn reverse() {
77
+ // let start = 0
78
+ // let end = this.length - 1
79
+ // let result = []
80
+ // while (start < end) {
81
+ // const temp = this[start]
82
+ // this[start] = this[end]
83
+ // this[end] = temp
84
+ // end = end - 1
85
+ // start = start + 1
86
+ // }
87
+ // }
88
+
89
+ fn to_int() int! {
90
+ if (fail) {
91
+ throw errors.int_parse;
92
+ }
93
+ return 0
94
+ }
95
+
96
+ fn to_float() float! {
97
+ if (fail) {
98
+ throw errors.float_parse;
99
+ }
100
+ return 0.0
101
+ }
102
+ }
103
+
104
+ primitive int is Stringable {
105
+ fn add(y: int) {
106
+ @"llvm.uadd.with.overflow.i32"(this, y)
21
107
  }
22
108
  fn sub() {
23
109
  }
110
+
24
111
  fn minus() {
25
112
  }
113
+
114
+ fn str() {
115
+ if (this == 0) {
116
+ return "0";
117
+ }
118
+ let result = str(31)
119
+ let i = 0
120
+ let num = this
121
+ while (num != 0) {
122
+ const rem = num % 10
123
+ result.push((rem > 9) ? (rem - 10) + 'a' : rem + '0')
124
+ num = num / 10
125
+ }
126
+ if (this < 0) {
127
+ result.push("-")
128
+ }
129
+ return result.reverse()
130
+ }
131
+
132
+ fn str() {
133
+ }
26
134
  }
27
135
 
28
- primitive float {
136
+ primitive float is Stringable {
29
137
  fn add() {
30
138
  }
31
139
  fn sub() {
32
140
  }
33
141
  fn minus() {
34
142
  }
143
+
144
+ // fn str() {
145
+ // ipart = (int)n
146
+ // fpart = n - (float)ipart
147
+ // // convert integer part to string
148
+ // int i = intToStr(ipart, res, 0)
149
+
150
+ // // check for display option after point
151
+ // if (afterpoint != 0) {
152
+ // res[i] = '.'; // add dot
153
+
154
+ // // Get the value of fraction part upto given no.
155
+ // // of points after dot. The third parameter
156
+ // // is needed to handle cases like 233.007
157
+ // fpart = fpart * pow(10, afterpoint);
158
+
159
+ // intToStr((int)fpart, res + i + 1, afterpoint);
160
+ // }
161
+ // }
35
162
  }
36
163
 
37
164
  entity decimal {
@@ -39,7 +166,7 @@ entity decimal {
39
166
  exponent: float
40
167
  }
41
168
 
42
- fn println() -> bool? {
169
+ fn println() bool? {
43
170
  }
44
171
 
45
172
  // value Email(str) {
@@ -80,20 +207,35 @@ trait IO {
80
207
 
81
208
  // // static fn only(top: double = 0, left: double = 0, bottom: double = 0, right: double = 0) {
82
209
  // // return EdgeInsets(top, left, bottom, right)
83
- // // }
210
+ // // }
84
211
  // }
85
212
 
86
213
  enum bool {
87
214
  false
88
215
  true
89
-
90
- fn is_equal(other: bool) -> bool {
91
- // return this == other
92
- }
93
216
 
217
+ fn op_eq(y: bool) bool {
218
+ this == y;
219
+ }
220
+ fn op_ne(y: bool) bool {
221
+ this != y
222
+ }
223
+ fn op_and(y: bool) bool {
224
+ this and y
225
+ }
226
+ fn op_or(y: bool) bool {
227
+ this or y
228
+ }
229
+ fn op_xor(y: bool) bool {
230
+ this xor y
231
+ }
232
+ fn op_not() bool {
233
+ !this
234
+ }
235
+
94
- fn to_string() -> str {
236
+ fn str() str {
95
237
  println("123")
96
- println(1 + 2 + 4 + 5.33 + 7.8km)
238
+ // println(1 + 2 + 4 + 5.33 + 7.8km)
97
239
  }
98
240
  }
99
241
 
@@ -106,11 +248,11 @@ enum Color {
106
248
  println("log")
107
249
  }
108
250
 
109
- fn to_string() -> str {
251
+ fn str() str {
110
- println("ToString")
252
+ println("Str")
111
253
  }
112
254
 
113
- fn where_is() -> int {
255
+ fn where_is() int {
114
256
  // match a {
115
257
  // 1, 2, 3 => 0,
116
258
  // 5...100 => 1,
@@ -120,14 +262,76 @@ enum Color {
120
262
  }
121
263
  }
122
264
 
265
+ enum List
266
+ | first
267
+ | link(first: a, rest: List<a>)
268
+
269
+ fn sum():
270
+ case this:
271
+ | first => 0
272
+ | link(a, res) => a + sum(res)
273
+ end
274
+ end
275
+ end
276
+
277
+ enitity List<a> {
278
+ data: Pointer
279
+ length: int
280
+
281
+ fn construct(items ...a) {
282
+ repeat(items) |item| {
283
+ data.alloc(item)
284
+ }
285
+ }
286
+ }
287
+
288
+ enum List<a> {
289
+ first
290
+ link(first: a, rest: List<a>)
291
+
292
+ fn op_brackets(items ...a) {
293
+ l = link(items[0])
294
+ range(items.length-2) |i| {
295
+ l.rest = link(items[i+1])
296
+ }
297
+ return l
298
+ }
299
+
300
+ fn sum() {
301
+ match this {
302
+ first => 0
303
+ link(a, res) => a + sum(res)
304
+ }
305
+ }
306
+ }
307
+
308
+ test("List") |t| {
309
+ fn sum(l: List<int>) int {
310
+ return l.reduce(|it| it.value, 0)
311
+ }
312
+
313
+ sum(empty) is 0
314
+ sum(link(1, link(2, link(3, empty)))) is 6
315
+ sum([1, 2, 3]) is 6
316
+ }
317
+
318
+ enum Tree<a> {
319
+ leaf
320
+ node(value: a, left: Tree<a>, right: Tree<a>)
321
+ }
322
+
323
+ fn main() int {
324
+ repeat(10) |i| {
325
+ println(i)
326
+ }
327
+ range(10, 20) |i| {
328
+ println(i)
329
+ }
330
+ }
331
+
332
+
123
333
 
124
- // repeat(10) |i| {
125
- // println(i)
126
- // }
127
334
 
128
- // range(10, 20) |i| {
129
- // println(i)
130
- // }
131
335
 
132
336
  // fn decrement() {
133
337
  // println("decrementing")
@@ -181,4 +385,35 @@ enum Color {
181
385
 
182
386
  // Node "Fred" (Node "Jim" Leaf Leaf)
183
387
  // (Node "Sheila" (Node "Alice" Leaf Leaf)
184
- // (Node "Bob" Leaf Leaf))
388
+ // (Node "Bob" Leaf Leaf))
389
+
390
+
391
+
392
+
393
+
394
+ class Cat(let name: String, let lives: Int64)
395
+ class Dog(let name: String, let years: Int64)
396
+ union Pet of Cat, Dog
397
+
398
+
399
+ class Person(
400
+ let firstName: String,
401
+ let lastName: String,
402
+ var age: Int64
403
+ ) {
404
+ fun fullName(): String = "${self.firstName} ${self.lastName}"
405
+ }
406
+
407
+ fun sum(a: Int64, b: Int64): Int64 = a + b
408
+
409
+ 2.0.sqrt()
410
+
411
+ fun describe(pet: Pet): String = if pet
412
+ ... is Cat(let name, let lives) { "cat $name has $lives lives" }
413
+ ... is Dog(let name, let years) { "dog $name is $years of age" }
414
+
415
+ List(Cat("Molly", 9), Dog("Fenton", 6))
416
+ .retain(|p| p.name.size > 5)
417
+ .map (|p| describe(p))
418
+ .each (|d| println(d))
419
+ // → dog Fenton is 6 years of age
src/language/palm.langium CHANGED
@@ -21,7 +21,7 @@ Enum:
21
21
  '}';
22
22
 
23
23
  EnumField:
24
- name=ID;
24
+ name=ID ('(' (params+=Param (',' params+=Param)*)? ')')?;
25
25
 
26
26
  Trait:
27
27
  'trait' name=ID Generics '{'
@@ -51,8 +51,8 @@ QualifiedName returns string:
51
51
  type AbstractDefinition = FunctionDefinition | Param;
52
52
 
53
53
  FunctionDefinition<isMethod, isTrait>:
54
- (<isMethod> static?='static')?
54
+ (<isMethod> static?='static')?
55
- 'fn' name=ID '(' (params+=Param (',' params+=Param)*)? ')' ('->' returns+=ReturnType (',' returns+=ReturnType)*)? (<!isTrait> Block);
55
+ 'fn' name=ID '(' (params+=Param (',' params+=Param)*)? ')' (returns+=ReturnType (',' returns+=ReturnType)*)? (<!isTrait> Block);
56
56
 
57
57
  ParamType:
58
58
  type=[Type] (nilable?='?')?;