~repos /plum

#treesitter#compiler#wasm

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

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


6a5b4e28 pyrossh

1 year ago
increment spec
example/fn.mi ADDED
@@ -0,0 +1,306 @@
1
+ module lambda
2
+
3
+ Sample syntax
4
+ ```
5
+ fun sum(a: int, b: int): int = a + b
6
+
7
+ fn sum_list(series: list[int]): int =
8
+ series.reduce(0, |v| v + 1)
9
+
10
+ fn fib(n: int): int =
11
+ match n
12
+ 0 | 1 -> n
13
+ else -> fib(n - 1) + fib(n - 2)
14
+
15
+ fn fib(n: int): int =
16
+ if n == 0 || n == 1 then
17
+ n
18
+ else
19
+ fib(n - 1) + fib(n - 2)
20
+ end
21
+
22
+ fn factorial(n: int): int =
23
+ match n
24
+ 1 -> 1
25
+ _ -> n * factorial(n - 1)
26
+
27
+ fn to-celsius(f: float) =
28
+ (f - 32) * (5 / 9)
29
+
30
+ record Cat(
31
+ name: str
32
+ age: int
33
+ )
34
+
35
+ fn (c: Cat) fullname(): str =
36
+ c.name + c.age.to_str()
37
+
38
+ fn (c: Cat) to_str(): str =
39
+ "Cat<{c.fullname()}>"
40
+
41
+ test("Cat", |v|
42
+ c := Cat(name = "123", age = 1)
43
+ c.talk()
44
+ Cat("rabby", 21).fullname() == "rabby21"
45
+ c2 := Cat(...c, age: c.age + 1)
46
+
47
+ [Cat("Molly", 9), Cat("Fenton", 6)]
48
+ .retain(|p| p.name.size > 5)
49
+ .map(|p| describe(p))
50
+ .each(|d| println(d))
51
+ // → cat Fenton is 6 years of age
52
+ )
53
+
54
+ type MapCallback = fn(v: a): v
55
+
56
+ trait Comparable[A](
57
+ fn compare(left: A, right: A): bool
58
+ )
59
+
60
+ trait ToStr(
61
+ fn to_str(): str
62
+ )
63
+
64
+ struct Cat(name: str, age: int) =
65
+ fn fullname() =
66
+ name + age.str()
67
+
68
+ fn talk() =
69
+ println("cat ${name} says meow")
70
+
71
+ #[ToStr]
72
+ fn to_str(self): str =
73
+ "Cat<{self.fullname()}>"
74
+
75
+
76
+ enum Temperature =
77
+ | celsius(float)
78
+ | fahrenheit(float)
79
+
80
+ fn (s Temperature) to_str() =
81
+ match s
82
+ celsius(t) && t > 30 -> "${t}C is above 30 celsius"
83
+ celsius(t) -> "${t}C is below 30 celsius"
84
+ fahrenheit(t) && t > 86 -> "${t}F is above 86 fahrenheit"
85
+ fahrenheit(t) -> "${t}F is below 86 fahrenheit"
86
+
87
+ test "enum ordinal value" {
88
+ expect(Value.zero).to_equal(0);
89
+ expect(Value.one).to_equal(1);
90
+ expect(Value.two).to_equal(2);
91
+ }
92
+
93
+ test("enum ordinal value") |t| {
94
+ expect(Value.zero).to_equal(0);
95
+ expect(Value.one).to_equal(1);
96
+ expect(Value.two).to_equal(2);
97
+ }
98
+
99
+ group("Group 1") |g| {
100
+ }
101
+
102
+ bench("1231") |t, n| {
103
+ }
104
+ ```
105
+
106
+ ## Language Reference
107
+
108
+ **Keywords**
109
+ unreachable
110
+
111
+ **Types**
112
+ bool, byte, int, float, dec, str, time, duration
113
+ [] for lists list[int], list[list[int]]
114
+ [] for maps map[int], map[map[int]]
115
+ ? for optional int? str?
116
+ ! for return error types int!, str!
117
+ nil for optional assignment and pointers
118
+
119
+ ## Types
120
+
121
+ **nil**
122
+ A nil type is used to represent types that are nilable.
123
+
124
+ **bool**
125
+ A bool can be either `true` or `false`. It is used in logical operations and conditional statements.
126
+
127
+ ```
128
+ assert true != false
129
+
130
+ if true || false:
131
+ print("works")
132
+ ```
133
+
134
+ **byte**
135
+ A byte represents an unsigned 8 bit number. It is mainly used to represent strings and binary data.
136
+ ```
137
+ let data: []byte?
138
+ data = [104, 101, 197, 130, 197, 130, 111, 0]
139
+ ```
140
+
141
+ **int**
142
+ An int is a signed 64 bit number. It can be represented in various ways,
143
+ 0b - Binary (Base 2)
144
+ 0x - Hexadecimal (Base 16)
145
+ 13 - Standard (Base 10)
146
+
147
+ ```
148
+ 0b00101010
149
+ 0b1_1111_1
150
+ 0xff00ff
151
+ 0xFF00FF
152
+ 0xFF80_0000_0000_0000
153
+ 98762
154
+ 1_000_000
155
+ ```
156
+
157
+ **float**
158
+ A float represents a 64-bit floating point (52-bit mantissa) IEEE-754-2008 binary64
159
+
160
+ **str**
161
+ A str represents a slice of runes or unicode code points. It is encoded to UTF-8 by default.
162
+ It supports interpolation of variables/values that implement the ToStr interface.
163
+
164
+ ```
165
+ "Hello World"
166
+ name := "Pacos"
167
+ age := 1
168
+ println("Name ${name} age ${age}")
169
+ ```
170
+ "\u0061" == "a"
171
+
172
+
173
+ **list**
174
+
175
+ ```
176
+ a := [1, 2, 3]
177
+ ```
178
+
179
+ **map**
180
+
181
+ ```
182
+ tree = [
183
+ value: "Fred",
184
+ left: [
185
+ value: "Jim",
186
+ ],
187
+ right: [
188
+ value: "Shiela",
189
+ left: [
190
+ value: "Alice",
191
+ },
192
+ right: [
193
+ value: "Bob"
194
+ ],
195
+ ],
196
+ ]
197
+ ```
198
+
199
+
200
+ **Assignment operator**
201
+ low, mid, high := 0, 0, n.numItems
202
+ x := 10
203
+ y := 20
204
+ xy_list := [x, y]
205
+ xy_map := [x: x, y: y]
206
+ assoc_list = [a: 1, b: 2]
207
+ assoc_list[:a]
208
+ assoc_list["b"]
209
+
210
+ **While statement**
211
+ while low < high
212
+ mid = (low + high) / 2
213
+ low = cmp > 0 > mid + 1 : low
214
+ high = cmp < 0 ? mid : high
215
+ if cmp == 0
216
+ return mid, true
217
+
218
+ while (i < 10) : (i += 1) {}
219
+
220
+ while (eventuallyErrorSequence()) |value| {
221
+ sum1 += value;
222
+ else |err|
223
+ try expect(err == error.ReachedZero);
224
+
225
+ **For statement**
226
+ for players_list |value|
227
+ if value == 0
228
+ continue
229
+ sum += value
230
+
231
+ for items[0..1] |v|
232
+ sum += v
233
+
234
+ for 0..5 |v|
235
+ sum3 += v
236
+
237
+ let list = for filter(players_list) |v|
238
+
239
+ items
240
+ .map(|v| v + 1)
241
+ .each(|v| println("v", v))
242
+
243
+ items
244
+ .each(v =>
245
+ if v == 2
246
+ break
247
+ if v == 0
248
+ continue
249
+ println(v)
250
+ )
251
+ .map {v => v * 2}
252
+ .reduce(0, |v| => v + 1)
253
+
254
+ fn range(start: int, end: int, cb: (v: T) -> IterateResult) =
255
+
256
+ range(0, 5, |v| =>
257
+ sum3 += v
258
+ )
259
+
260
+ // Iterate over multiple objects.
261
+ // All lengths must be equal at the start of the loop, otherwise detectable
262
+ // illegal behavior occurs.
263
+ for items, items2 |i, j|
264
+ count += i + j
265
+
266
+ **When expression/statement**
267
+ when
268
+ cmp > 0 -> low = mid + 1
269
+ cmp < 0 -> high = mid
270
+ cmp == 0 -> return mid, true
271
+
272
+ Arithmetic (+, -, /, *, @divFloor, @sqrt, @ceil, @log, etc.)
273
+ Bitwise operators (>>, <<, &, |, ~, etc.)
274
+ Comparison operators (<, >, ==, etc.)
275
+
276
+ **if expression/statement**
277
+ if (a) |value| {
278
+ try expect(value == 0);
279
+ } else |err| {
280
+ _ = err;
281
+ unreachable;
282
+ }
283
+
284
+ ### 5. Conditional operators
285
+
286
+ **not operator**
287
+ !a
288
+ !true
289
+
290
+ **ternary operator**
291
+ x ? x : y
292
+
293
+ **safe navigation operator**
294
+ a?.b?.c?.d
295
+
296
+ **elvis operator**
297
+ x ?: y
298
+
299
+ **elvis assignment operator**
300
+ atomicNumber ?= 2
301
+
302
+ **Range operator**
303
+ for 5..10 |i|:
304
+
305
+ **Safe index operator**
306
+ array?[1]
example/fn.palm DELETED
@@ -1,300 +0,0 @@
1
- module lambda
2
-
3
- // binary, bool, int, float, str, decimal, time
4
- // [] for slices []int []str
5
- // {} for maps [int]int [str]str
6
- // ? for optional int? str?
7
- // ! for error types int!, str!
8
- // nil for optional assignment
9
-
10
- // 2.0
11
- // |> math.sqrt()
12
- // |> math.log()
13
- // |> math.round()
14
-
15
- alias MapCallback = fn(v: a): v
16
-
17
- trait Comparable<a> =
18
- fn compare(left: a, right: a): bool
19
-
20
- enum Temperature(celsius(float) | fahrenheit(float)) =
21
- fn str(self) =
22
- match self
23
- Temperature::celsius(t) && t > 30 -> "${t}C is above 30 celsius"
24
- Temperature::celsius(t) -> "${t}C is below 30 celsius"
25
- Temperature::fahrenheit(t) && t > 86 -> "${t}F is above 86 fahrenheit"
26
- Temperature::fahrenheit(t) -> "${t}F is below 86 fahrenheit"
27
-
28
- struct Cat(name: str, age: int) =
29
- fn fullname() =
30
- name + age.str()
31
-
32
- fn talk() =
33
- println("cat ${name} says meow")
34
-
35
- test "Cat" =
36
- c = Cat(name = "123", age = 1)
37
- c.talk()
38
- Cat("rabby", 21).fullname() == "rabby21"
39
-
40
- fn fib(n: int): int =
41
- match n
42
- 0 | 1 -> n
43
- else -> fib(n - 1) + fib(n - 2)
44
-
45
- fn factorial(n: int): int =
46
- match n
47
- 1 -> 1
48
- _ -> n * factorial(n - 1)
49
-
50
- fn to-celsius(f: float) =
51
- (f - 32) * (5 / 9)
52
-
53
- fn repeat(n: int, cb: fn(int)) =
54
- if n != 0:
55
- cb(n)
56
- repeat(n-1, cb)
57
-
58
- fn range(start: int, e: int, cb: fn(int)) =
59
- if (start < end):
60
- cb(start)
61
- range(start + 1, end, cb)
62
- elif (start > end):
63
- cb(start)
64
- range(start - 1, end, cb)
65
-
66
- fn main() =
67
- repeat(10) |i|
68
- println(i)
69
- range(10, 20) |i|
70
- println(i)
71
-
72
- /// Http similar to rocket
73
- /// GET,DELETE Request -> fn params are got from query
74
- /// POST,PUT,PATCH Request -> fn params got from multi part form body
75
- /// DI at compiler level
76
- /// Controller similar to IHP
77
-
78
- #[path("/counters")]
79
- @path("/counters")
80
- struct CounterController(db: DB)
81
- static path = "/counters"
82
-
83
- fn all(): HttpResponse =
84
- counters := db.query(Counter).fetchAll()
85
- render(CounterList(counters))
86
-
87
- fn view() =
88
- counter := fetchOne(Counter) ?? createOne(Counter)
89
- if counter := fetchOne(Counter)
90
- render CounterView(counter)
91
- else
92
- counter <- newRecord @Counter |> set #count 0 |> createRecord
93
- render CounterView(counter)
94
-
95
- fn increment(id: str) =
96
- counter <- fetch counterId
97
- updatedCounter <- counter |> incrementField #count |> updateRecord
98
- respondHtml $ counterView updatedCounter
99
-
100
- fn decrement(id: str) =
101
- counter <- fetch counterId
102
- updatedCounter <- counter |> decrementField #count |> updateRecord
103
- respondHtml $ counterView updatedCounter
104
-
105
- module palm
106
-
107
- primitive int is Stringable {
108
- fn add(y: int) {
109
- @"llvm.uadd.with.overflow.i32"(this, y)
110
- }
111
- fn sub() {
112
- }
113
-
114
- fn minus() {
115
- }
116
-
117
- fn str() {
118
- if (this == 0) {
119
- return "0";
120
- }
121
- let result = str(31)
122
- let i = 0
123
- let num = this
124
- while (num != 0) {
125
- const rem = num % 10
126
- result.push((rem > 9) ? (rem - 10) + 'a' : rem + '0')
127
- num = num / 10
128
- }
129
- if (this < 0) {
130
- result.push("-")
131
- }
132
- return result.reverse()
133
- }
134
-
135
-
136
- // fn str() {
137
- // ipart = (int)n
138
- // fpart = n - (float)ipart
139
- // // convert integer part to string
140
- // int i = intToStr(ipart, res, 0)
141
-
142
- // // check for display option after point
143
- // if (afterpoint != 0) {
144
- // res[i] = '.'; // add dot
145
-
146
- // // Get the value of fraction part upto given no.
147
- // // of points after dot. The third parameter
148
- // // is needed to handle cases like 233.007
149
- // fpart = fpart * pow(10, afterpoint);
150
-
151
- // intToStr((int)fpart, res + i + 1, afterpoint);
152
- // }
153
- // }
154
- }
155
-
156
- entity decimal {
157
- mantissa: int
158
- exponent: float
159
- }
160
-
161
- enum List
162
- | first
163
- | link(first: a, rest: List<a>)
164
-
165
- fn sum():
166
- case this:
167
- | first => 0
168
- | link(a, res) => a + sum(res)
169
- end
170
- end
171
- end
172
-
173
- enitity List<a> {
174
- data: Pointer
175
- length: int
176
-
177
- fn construct(items ...a) {
178
- repeat(items) |item| {
179
- data.alloc(item)
180
- }
181
- }
182
- }
183
-
184
- enum List<a> {
185
- first
186
- link(first: a, rest: List<a>)
187
-
188
- fn op_brackets(items ...a) {
189
- l = link(items[0])
190
- range(items.length-2) |i| {
191
- l.rest = link(items[i+1])
192
- }
193
- return l
194
- }
195
-
196
- fn sum() {
197
- match this {
198
- first => 0
199
- link(a, res) => a + sum(res)
200
- }
201
- }
202
- }
203
-
204
- test("List") |t| {
205
- fn sum(l: List<int>) int {
206
- return l.reduce(|it| it.value, 0)
207
- }
208
-
209
- sum(empty) is 0
210
- sum(link(1, link(2, link(3, empty)))) is 6
211
- sum([1, 2, 3]) is 6
212
- }
213
-
214
- enum Tree<a> {
215
- leaf
216
- node(value: a, left: Tree<a>, right: Tree<a>)
217
- }
218
-
219
- fn main() int {
220
- repeat(10) |i| {
221
- println(i)
222
- }
223
- range(10, 20) |i| {
224
- println(i)
225
- }
226
- }
227
-
228
-
229
-
230
-
231
-
232
- // fn decrement() {
233
- // println("decrementing")
234
- // Cat(...c, age: c.age + 1)
235
- // }
236
-
237
- // fn add(x: Int, y: Int) -> Int {
238
- // x + y
239
- // }
240
-
241
- // list
242
- // .map(|it| it + 1)
243
- // .each(|_| println("it", it))
244
-
245
- // test "enum ordinal value" {
246
- // expect(Value.zero).to_equal(0);
247
- // expect(Value.one).to_equal(1);
248
- // expect(Value.two).to_equal(2);
249
- // }
250
-
251
- // test("enum ordinal value") |t| {
252
- // expect(Value.zero).to_equal(0);
253
- // expect(Value.one).to_equal(1);
254
- // expect(Value.two).to_equal(2);
255
- // }
256
-
257
- // group("Group 1") |g| {
258
- // test("Test 1") |t| {
259
-
260
- // }
261
- // }
262
-
263
- // bench("1231") |t, n| {
264
- // }
265
-
266
- // tree = {
267
- // value: "Fred",
268
- // left: {
269
- // value: "Jim",
270
- // },
271
- // right: {
272
- // value: "Shiela",
273
- // left: {
274
- // value: "Alice",
275
- // },
276
- // right: {
277
- // value: "Bob"
278
- // },
279
- // },
280
- // }
281
-
282
- // Node "Fred" (Node "Jim" Leaf Leaf)
283
- // (Node "Sheila" (Node "Alice" Leaf Leaf)
284
- // (Node "Bob" Leaf Leaf))
285
-
286
-
287
-
288
-
289
-
290
- fun sum(a: Int64, b: Int64): Int64 = a + b
291
-
292
- fun describe(pet: Pet): String = if pet
293
- ... is Cat(let name, let lives) { "cat $name has $lives lives" }
294
- ... is Dog(let name, let years) { "dog $name is $years of age" }
295
-
296
- List(Cat("Molly", 9), Dog("Fenton", 6))
297
- .retain(|p| p.name.size > 5)
298
- .map (|p| describe(p))
299
- .each (|d| println(d))
300
- // → dog Fenton is 6 years of age
example/std/bool.mi CHANGED
@@ -1,10 +1,11 @@
1
1
  module std
2
2
 
3
- enum bool is (true | false) =
3
+ type bool = true | false
4
4
  fn op_eq(x: bool, y: bool) = x == y
5
5
  fn op_ne(x: bool, y: bool) = x != y
6
- fn op_and(x: bool, y: bool) = x && y
6
+ fn op_and(x: bool, y: bool) = x == false || y == false ? false : true
7
- fn op_or(x: bool, y: bool) = x || y
7
+ fn op_or(x: bool, y: bool) = x == true || y == true ? true : false
8
- fn op_xor(x: bool, y: bool) = x <> y
8
+ fn op_not(x: bool): bool = x == true ? false : true
9
+
9
- fn op_not(x: bool,): bool = !x
10
+ #[ToStr]
10
- fn str(x: bool) = x ? "true" : "false"
11
+ fn to_str(x: bool) = x ? "true" : "false"
example/std/buffer.mi DELETED
File without changes
example/std/http.mi ADDED
@@ -0,0 +1,83 @@
1
+ import std/path
2
+ import std/os
3
+ import http/content_type
4
+
5
+ fn file_response(file: str) =
6
+ ext := path::ext(file)
7
+ content := content_type::from_ext(ext)
8
+ data := try os.read_file(file)
9
+ Response(
10
+ header("Content-Type", content)
11
+ header("Content-Length", "2")
12
+ body(data)
13
+ status(200)
14
+ )
15
+
16
+ Response(
17
+ status = 200
18
+ header = [
19
+ Content-Type: content,
20
+ Content-Length: "2"
21
+ ]
22
+ body = data
23
+ )
24
+
25
+ Response::build()
26
+ .header("Content-Type", content)
27
+ .header("Content-Length", "2")
28
+ .body(data)
29
+ .status(200)
30
+
31
+ response.new(200)
32
+ |> response.header("Content-Type", content)
33
+ |> response.body(data)
34
+
35
+ #[get("/")]
36
+ fn index(): Response! =
37
+ file_response("index.html")
38
+
39
+ #[get("/public/<...>")]
40
+ fn public(file: str): Response! =
41
+ ext := path::ext(file)
42
+ content := content_type::from_ext(ext)
43
+ data := try os.read_file(file)
44
+ Response(
45
+ status: 200,
46
+ headers: [
47
+ ContentType: content,
48
+ ],
49
+ body: data,
50
+ )
51
+
52
+
53
+ /// Http similar to rocket
54
+ /// GET,DELETE Request -> fn params are got from query
55
+ /// POST,PUT,PATCH Request -> fn params got from multi part form body
56
+ /// DI at compiler level
57
+ /// Controller similar to IHP
58
+
59
+ #[path("/counters")]
60
+ record CounterController(db: DB)
61
+ static path = "/counters"
62
+
63
+ fn all(): HttpResponse =
64
+ counters := db.query(Counter).fetchAll()
65
+ render(CounterList(counters))
66
+
67
+ fn view() =
68
+ counter := fetchOne(Counter) ?? createOne(Counter)
69
+ if counter := fetchOne(Counter)
70
+ render CounterView(counter)
71
+ else
72
+ counter <- newRecord @Counter |> set #count 0 |> createRecord
73
+ render CounterView(counter)
74
+
75
+ fn increment(id: str) =
76
+ counter <- fetch counterId
77
+ updatedCounter <- counter |> incrementField #count |> updateRecord
78
+ respondHtml $ counterView updatedCounter
79
+
80
+ fn decrement(id: str) =
81
+ counter <- fetch counterId
82
+ updatedCounter <- counter |> decrementField #count |> updateRecord
83
+ respondHtml $ counterView updatedCounter
example/std/int.mi DELETED
@@ -1,28 +0,0 @@
1
- module std
2
-
3
- primitive int =
4
- MIN_VALUE = 0
5
- MAX_VALUE = 0xFFFF_FFFF_FFFF_FFFF_FFFF_FFFF_FFFF_FFFF
6
-
7
- fn random(): int =
8
- 0
9
-
10
- fn min_value() => -0x8000_0000_0000_0000
11
- fn max_value() => 0x7FFF_FFFF_FFFF_FFFF
12
- fn abs(a: int): int => a < 0 ? -a : a
13
- fn to_str(v: int): str = ""
14
-
15
- fn op_add(x: int, y: int): int =
16
- @"i64.add"(x, y)
17
-
18
-
19
- sub
20
- mul
21
- div
22
- rem
23
-
24
- min
25
- max
26
-
27
- to_float()
28
-
example/std/list.mi CHANGED
@@ -1,35 +1,39 @@
1
1
  module std
2
2
 
3
+ // A list is a data structure describing a contiguous section of an array stored separately from the slice variable itself.
4
+ // A list is not an array. A list describes a piece of an array. A list is immutable.
3
- enum List is (first | link(v: a, rest: List)) =
5
+ record list<V>(_ptr: *V): ToStr
4
- // where a : Number & Stringable
5
6
 
6
- fn each(self, cb: fn(v: a)) =
7
+ new create<V>(ptr: *V)
7
- match self
8
+ _ptr = ptr
8
- List::first -> List::first
9
- List::link(v, rest) ->
10
- cb(v)
11
- each(rest, cb)
12
9
 
13
- fn map(self, cb: fn(v: a): v) =
10
+ fn concat(): slice<V> =
14
- match self
11
+ pass
15
- List::first -> first
16
- List::link(v, rest) -> List::link(cb(v), map(rest, cb))
17
12
 
18
- fn get(i: int): a? =
13
+ fn length(): int =
14
+ len := 0
15
+ while *_ptr != 0x00
16
+ len += 1
19
- match self
17
+ _ptr += 1
20
- List::first -> List::first
21
- List::link(v, rest) ->
22
- each(rest, cb)
18
+ len
23
19
 
24
- fun get<a>(lst :: List<a>, n :: Number) -> a:
20
+ fn each(cb: fn(v: V): void): void =
25
- doc: "Returns the nth element of the given list, or raises an error if n is out of range"
26
- fun help(l, cur):
27
- if is-empty(l): raise("get: n too large " + tostring(n))
28
- else if cur == 0: l.first
21
+ while *_ptr != 0x00
29
- else: help(l.rest, cur - 1)
30
- end
31
- end
32
- if n < 0: raise("get: invalid argument: " + tostring(n))
33
- else: help(lst, n)
22
+ cb(@CastTo(_ptr, V))
23
+ _ptr += @SizeOf(V)
24
+
25
+ fn map<A>(cb: fn(v: V): A): []A =
26
+ res := []V
27
+ while *_ptr != 0x00
28
+ res.append(cb(@CastTo(_ptr, V)))
29
+ _ptr += @SizeOf(V)
30
+ res
31
+
32
+ fn to_str() =
33
+ res := ""
34
+ each<str>(|v| =
35
+ if @HasTrait(V, ToStr)
36
+ res.write(v.to_str())
34
- end
37
+ else
38
+ res.write(@TypeToString(v))
35
- end
39
+ )
example/std/map.mi CHANGED
@@ -1,14 +1,9 @@
1
+ module std
2
+
3
+ record map<V>(data: Pointer, length: int)
4
+ """
5
+ A slice is a data structure describing a contiguous section of an array stored separately from the slice variable itself.
6
+ A slice is not an array. A slice describes a piece of an array.
7
+ """
8
+ new init(): Slice
1
- map
9
+ pass
2
-
3
- entity Map()
4
-
5
- fn new() =
6
- alloc Map
7
-
8
- fn get()
9
-
10
- fn set()
11
-
12
- fn
13
-
14
-
example/std/math.mi CHANGED
@@ -97,4 +97,25 @@ fun sqrt(): F64 =>
97
97
  else
98
98
  @"llvm.sqrt.f64"(this)
99
99
  end
100
+
100
-
101
+ MIN_INT_VALUE = 0
102
+ MAX_INT_VALUE = 0xFFFF_FFFF_FFFF_FFFF_FFFF_FFFF_FFFF_FFFF
103
+
104
+ fn min_value() => -0x8000_0000_0000_0000
105
+ fn max_value() => 0x7FFF_FFFF_FFFF_FFFF
106
+ fn abs(a: int): int => a < 0 ? -a : a
107
+ fn to_str(v: int): str = ""
108
+
109
+ fn op_add(x: int, y: int): int =
110
+ @"i64.add"(x, y)
111
+
112
+
113
+ sub
114
+ mul
115
+ div
116
+ rem
117
+
118
+ min
119
+ max
120
+
121
+ to_float()
example/std/ranges.mi ADDED
@@ -0,0 +1,18 @@
1
+ fn range(start: int, e: int, cb: fn(int)) =
2
+ if (start < end):
3
+ cb(start)
4
+ range(start + 1, end, cb)
5
+ elif (start > end):
6
+ cb(start)
7
+ range(start - 1, end, cb)
8
+
9
+ fn repeat(n: int, cb: fn(int)) =
10
+ if n != 0:
11
+ cb(n)
12
+ repeat(n-1, cb)
13
+
14
+ fn main() =
15
+ repeat(10) |i|
16
+ println(i)
17
+ range(10, 20) |i|
18
+ println(i)
example/std/str.mi CHANGED
@@ -1,34 +1,87 @@
1
1
  module std
2
2
 
3
+ // Trait ToStr defines any data that can be converted to a str
3
- trait Stringable =
4
+ trait ToStr
4
5
  fn to_str(): str
5
6
 
7
+ // A str is an array of contiguous data stored in memory with a null termination using hex 0x00 or ASCII 0x00.
8
+ // It is immutable and cannot be modified. It is copied for any changes and saved to a new memory location.
9
+ // The previous str is freed if its reference count is 0 within the block.
6
- struct str(data: Pointer<u16>, length: int) is Comparable, Stringable =
10
+ struct str(_ptr: *u8) : Comparable, ToStr
7
- fn get(i: int) = data[i]
8
11
 
9
- fn concat(other: str): str =
12
+ new (s str) create(ptr: *u8) =
13
+ // TODO: have a check in dev builds to throw an error if not null terminated
14
+ // to prevent undefined behavior
10
- pass
15
+ _ptr = ptr
11
16
 
12
- fn starts_with(search: str): bool =
17
+ fn (s str) get(i: int) =
13
- pass
18
+ data[i]
14
19
 
15
- fn ends_with(search: str): bool =
20
+ fn (s str) contains(search: str): bool =
16
- pass
21
+ pass
17
22
 
18
- fn contains(search: str): bool =
23
+ fn (s str) index_of(sub: str): int =
19
- pass
24
+ pass
20
25
 
21
- fn index_of(sub: str): int =
26
+ fn (s str) test(pattern: Regex): []str =
22
- pass
27
+ pass
23
28
 
24
- fn match(pattern: Regex): []str =
29
+ fn (s str) search(key str): int, bool =
30
+ low, mid, high := 0, 0, n.numItems
31
+ while low < high
32
+ mid = (low + high) / 2
33
+ cmp := key > n.items[mid].key
34
+ low = cmp > 0 ? mid + 1 : low
35
+ high = cmp < 0 ? mid : high
36
+ if cmp == 0
37
+ return mid, true
25
- pass
38
+ low, false
26
39
 
27
- fn match_all(pattern: Regex): []str =
40
+ fn (t BTree) delete(key str): bool =
41
+ if t.root == nil
42
+ return false
43
+ deletedItem := t.root.delete(key, false)
44
+ if t.root.numItems == 0
45
+ if t.root.isLeaf()
46
+ t.root = nil
28
- pass
47
+ else
48
+ t.root = t.root.children[0]
49
+ if deletedItem != nil
50
+ return true
51
+ return false
29
52
 
30
- fn pad_start(sub: str, count: int): str =
53
+ fn (s str) Comparable::starts_with(search: str): bool =
31
- pass
54
+ pass
55
+
56
+
57
+ fn (s str) concat(other: str): str =
58
+ s + other
59
+
60
+ fn (s str) to_str(): str = s
61
+
62
+ fn (s str) concat(other: str): str =
63
+ s + s
64
+
65
+ fn (s str) starts_with(search: str): bool =
66
+ pass
67
+
68
+ fn (s str) ends_with(search: str): bool =
69
+ pass
70
+
71
+ fn (s str) contains(search: str): bool =
72
+ pass
73
+
74
+ fn (s str) index_of(sub: str): int =
75
+ pass
76
+
77
+ fn (s str) match(pattern: Regex): []str =
78
+ pass
79
+
80
+ fn (s str) match_all(pattern: Regex): []str =
81
+ pass
82
+
83
+ fn (s str) pad_start(sub: str, count: int): str =
84
+ pass
32
85
 
33
86
  fn pad_end(sub: str, count: int): str =
34
87
  pass
@@ -60,9 +113,6 @@ struct str(data: Pointer<u16>, length: int) is Comparable, Stringable =
60
113
  fn to_upper(): str =
61
114
  pass
62
115
 
63
- fn to_str(self): str =
64
- self
65
-
66
116
  fn trim(): str =
67
117
  pass
68
118
 
@@ -72,7 +122,8 @@ struct str(data: Pointer<u16>, length: int) is Comparable, Stringable =
72
122
  fn trim_end(): str =
73
123
  pass
74
124
 
75
- fn reverse(): str =
125
+ fn reverse(): str
126
+ """reverses a str
76
127
  start := 0
77
128
  end := length - 1
78
129
  result := []
@@ -88,4 +139,10 @@ struct str(data: Pointer<u16>, length: int) is Comparable, Stringable =
88
139
  0
89
140
 
90
141
  fn parse_float(): float! =
91
- 0.0
142
+ 0.0
143
+
144
+ fn parse_bool(): bool! =
145
+ match to_lower()
146
+ "true" -> bool::true
147
+ "false" -> bool::false
148
+ _ -> error("could not parse bool '${this}'")
public/index.html ADDED
@@ -0,0 +1,47 @@
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <link rel="stylesheet" type="text/css" href="public/main.css" />
5
+ <script src="public/main.js"></script>
6
+ <style>
7
+ body {
8
+ color: #000000;
9
+ font-family: sans-serif;
10
+ font-size: small;
11
+ font-style: italic;
12
+ font-weight: bold;
13
+ }
14
+
15
+ table.hh {
16
+ border: 1px solid gray;
17
+ }
18
+
19
+ bor {
20
+ border: 1px;
21
+ }
22
+ </style>
23
+ </head>
24
+ <body>
25
+ <div class="bor">
26
+ <table bgcolor="#f0f0f0" cellspacing="0" class="hh">
27
+ <tr>
28
+ <td><img src="/llama.png" align="left" /></td>
29
+ <td>
30
+ <table cellspacing="0">
31
+ <tr>
32
+ <td><b>pyros2097</b></td>
33
+ </tr>
34
+ <tr>
35
+ <td>Gdx Developer</td>
36
+ </tr>
37
+ <tr>
38
+ <td>"Awesomeness we can has"</td>
39
+ </tr>
40
+ </table>
41
+ </td>
42
+ </tr>
43
+ <tr></tr>
44
+ </table>
45
+ </div>
46
+ </body>
47
+ </html>
public/llama.png ADDED
Binary file