plum

#treesitter#compiler#wasm

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

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


141b67a — Peter John 2026-11-01T17:36:38+05:30
T3: record migration
plum-checker/tests/error_union_tests.rs CHANGED
@@ -341,8 +341,7 @@ fun d(n: Int) -> !Str =
341
341
  #[test]
342
342
  fn safe_nav_on_error_union() {
343
343
  let src = "\
344
- enum User =
345
- | User(name: Str)
344
+ record User(name: Str)
346
345
 
347
346
  fun load(n: Int) -> !User =
348
347
  return error.NoUser
@@ -353,8 +352,7 @@ fun name(n: Int) -> !Str =
353
352
  // Same set; `?.` flattens.
354
353
  assert!(check(src).is_ok(), "{:?}", check(src));
355
354
  let src2 = "\
356
- enum User =
357
- | User(name: Str)
355
+ record User(name: Str)
358
356
 
359
357
  fun load(n: Int) -> !User =
360
358
  return error.NoUser
@@ -369,8 +367,7 @@ fun name(n: Int) -> Str =
369
367
  fn pinned_set_vs_generic_unambiguous() {
370
368
  // Generics next to a pinned set: the set comes first, in front of the `!`.
371
369
  let src = "\
372
- enum Box[T] =
373
- | Box(item: T)
370
+ record Box[T](item: T)
374
371
 
375
372
  fun unbox(b: Box[Int]) -> error{Empty}!Box[Int] =
376
373
  return error.Empty
@@ -412,8 +409,7 @@ fn null_is_absent_anywhere() {
412
409
  // Constructor argument of type `Int?`: not an early return, and legal in a
413
410
  // fn that returns a plain value.
414
411
  let src = "\
415
- enum Cfg =
416
- | Cfg(port: Int?)
412
+ record Cfg(port: Int?)
417
413
 
418
414
  fun mk() -> Cfg =
419
415
  Cfg(port: null)
plum-cli/tests/assert_once_test.rs CHANGED
@@ -24,8 +24,7 @@ fn assert_operands_evaluated_once() {
24
24
  import std/Int
25
25
  import std/Float
26
26
 
27
- enum Counter =
28
- | Counter(n: Int)
27
+ record Counter(n: Int) =
29
28
 
30
29
  fun bump(self) -> Int =
31
30
  self.n = self.n + 1
plum-core/tests/loader_test.rs CHANGED
@@ -213,8 +213,7 @@ fn sameMethodNameOnDifferentReceiversAcrossFilesIsNotACollision() {
213
213
  "\
214
214
  module fixtures
215
215
 
216
- enum Cat =
217
- | Cat(age: Unit)
216
+ record Cat(age: Unit) =
218
217
 
219
218
  fun length(self) -> Unit =
220
219
  self.age
@@ -228,8 +227,7 @@ module fixtures
228
227
 
229
228
  import cat
230
229
 
231
- enum Box =
232
- | Box(items: Unit)
230
+ record Box(items: Unit) =
233
231
 
234
232
  fun length(self) -> Unit =
235
233
  self.items
plum-examples/chains.plum CHANGED
@@ -24,8 +24,7 @@ import std/Seq
24
24
  # No closure is allocated and there is no call_indirect: the wasm is the loop you
25
25
  # would have written by hand. See plum-std/Seq.plum.
26
26
 
27
- enum Soldier =
28
- | Soldier(name: Str, team: Int, hp: Float, x: Float, y: Float)
27
+ record Soldier(name: Str, team: Int, hp: Float, x: Float, y: Float)
29
28
 
30
29
  fun dist2(ax: Float, ay: Float, bx: Float, by: Float) -> Float =
31
30
  dx := ax - bx
plum-examples/closures.plum CHANGED
@@ -32,8 +32,7 @@ fun useFloatClosure() -> Float =
32
32
  offset + v
33
33
  eachF(floatCb)
34
34
 
35
- enum ClosureCat =
36
- | ClosureCat(age: Int)
35
+ record ClosureCat(age: Int)
37
36
 
38
37
  fun eachCat(cb: fn(ClosureCat) -> Int) -> Int =
39
38
  cb(ClosureCat(age: 7))
plum-examples/forms.plum CHANGED
@@ -12,8 +12,7 @@ import std/Seq
12
12
  # thing is expanded at the call site, so there are no closures. See
13
13
  # plum-std/Seq.plum and plum-core/src/forms.rs.
14
14
 
15
- enum Fighter =
16
- | Fighter(name: Str, hp: Int, dead: Bool)
15
+ record Fighter(name: Str, hp: Int, dead: Bool)
17
16
 
18
17
  fun sampleFighters() -> List[Fighter] =
19
18
  List(Fighter(name: "a", hp: 10, dead: false), Fighter(name: "b", hp: 0, dead: true), Fighter(name: "c", hp: 7, dead: false))
@@ -57,8 +56,7 @@ fun tailForm(xs: List[Int]) -> Int =
57
56
 
58
57
 
59
58
  # A type with a fun* method: `self` is bound to the receiver at the use site.
60
- enum Countdown =
61
- | Countdown(from: Int)
59
+ record Countdown(from: Int) =
62
60
 
63
61
  fun* ticks(self) *Int =
64
62
  i := self.from
plum-examples/functions.plum CHANGED
@@ -45,8 +45,7 @@ fun factorial(x: Int) -> Int =
45
45
  fun double(n: Int) -> Int =
46
46
  n * 2
47
47
 
48
- enum GenericBox[T] =
49
- | GenericBox(value: T)
48
+ record GenericBox[T](value: T) =
50
49
 
51
50
  fun getIntValue() -> T =
52
51
  self.value
@@ -58,8 +57,7 @@ fun useGenericBox() -> Int =
58
57
  fun identity(value: T) -> T =
59
58
  value
60
59
 
61
- enum GenericBox2[T] =
62
- | GenericBox2(value: T)
60
+ record GenericBox2[T](value: T) =
63
61
 
64
62
  fun getValue() -> T =
65
63
  self.value
@@ -89,8 +87,7 @@ fun strContentsOr(p: Parcel[Str], default: Int) -> Int =
89
87
  Delivered(v) => 4
90
88
  Lost => default
91
89
 
92
- enum GenericBox3[T] =
93
- | GenericBox3(value: T)
90
+ record GenericBox3[T](value: T) =
94
91
 
95
92
  fun getBoxValue() -> T =
96
93
  self.value
plum-examples/generics.plum CHANGED
@@ -45,8 +45,7 @@ fun readDeep(outer: List[List[Map[Str, Int]]], r: Int, c: Int, key: Str) -> erro
45
45
  v := try m.get(key)
46
46
  return v
47
47
 
48
- enum Circle =
49
- | Circle(r: Float)
48
+ record Circle(r: Float) =
50
49
 
51
50
  fun area(self) -> Float =
52
51
  self.r * self.r * 3.0
@@ -54,8 +53,7 @@ enum Circle =
54
53
  fun name(self) -> Str =
55
54
  "circle"
56
55
 
57
- enum Square =
58
- | Square(s: Float)
56
+ record Square(s: Float) =
59
57
 
60
58
  fun area(self) -> Float =
61
59
  self.s * self.s
@@ -72,8 +70,7 @@ fun nameOf(s: T) -> Str =
72
70
  # "Trait values": there are no traits, so the behavior a generic needs is passed
73
71
  # explicitly as a record of functions (a "Num dictionary"). `num.add(a, b)` calls
74
72
  # the closure stored in the `add` field (a method named `add` would win).
75
- enum Num[T] =
76
- | Num(add: fn(T, T) -> T, zero: T)
73
+ record Num[T](add: fn(T, T) -> T, zero: T)
77
74
 
78
75
  fun sumWith(xs: List[T], num: Num[T]) -> T =
79
76
  acc := num.zero
plum-examples/match.plum CHANGED
@@ -131,8 +131,7 @@ fun bothOptions(a: Reading[Int], b: Reading[Int]) -> Int =
131
131
  Sample(x), Sample(y) => x + y
132
132
  _, _ => 0
133
133
 
134
- enum Point =
135
- | Point(x: Int, y: Int)
134
+ record Point(x: Int, y: Int) =
136
135
 
137
136
  fun sum(self) -> Int =
138
137
  match self
plum-examples/methods.plum CHANGED
@@ -4,8 +4,7 @@ import std/Str
4
4
  import std/Int
5
5
  import std/Float
6
6
 
7
- enum Cat =
8
- | Cat(name: Str, age: Int)
7
+ record Cat(name: Str, age: Int) =
9
8
 
10
9
  fun getAge(self) -> Int =
11
10
  self.age
@@ -13,8 +12,7 @@ enum Cat =
13
12
  fun birthday(self) -> Int =
14
13
  self.age + 1
15
14
 
16
- enum Wrapper =
17
- | Wrapper(inner: Cat, tag: Int)
15
+ record Wrapper(inner: Cat, tag: Int) =
18
16
 
19
17
  fun innerAge(self) -> Int =
20
18
  self.inner.age
plum-examples/oop_visitor.plum CHANGED
@@ -37,8 +37,7 @@ enum Rating =
37
37
  | Good(name: Str)
38
38
  | Bad(name: Str)
39
39
 
40
- enum FantasyBook =
41
- | FantasyBook(title: Str, pages: Int, hasMythicalCreatures: Bool)
40
+ record FantasyBook(title: Str, pages: Int, hasMythicalCreatures: Bool) =
42
41
 
43
42
  fun collectInterestingInfo(self) -> Str =
44
43
  if self.hasMythicalCreatures
@@ -46,8 +45,7 @@ enum FantasyBook =
46
45
  else
47
46
  "Fantasy book \"{self.title}\" has no mythical creatures"
48
47
 
49
- enum ScifiBook =
50
- | ScifiBook(title: Str, pages: Int, theme: Str)
48
+ record ScifiBook(title: Str, pages: Int, theme: Str) =
51
49
 
52
50
  fun collectInterestingInfo(self) -> Str =
53
51
  if self.theme == "space exploration"
@@ -55,8 +53,7 @@ enum ScifiBook =
55
53
  else
56
54
  "Scifi book \"{self.title}\" has theme {self.theme}"
57
55
 
58
- enum ChildrensTaleBook =
59
- | ChildrensTaleBook(title: Str, pages: Int, moralLesson: Str)
56
+ record ChildrensTaleBook(title: Str, pages: Int, moralLesson: Str) =
60
57
 
61
58
  fun collectInterestingInfo(self) -> Str =
62
59
  if self.pages == 0
@@ -64,8 +61,7 @@ enum ChildrensTaleBook =
64
61
  else
65
62
  "Childrens book \"{self.title}\" teaches: {self.moralLesson}"
66
63
 
67
- enum NonFictionBook =
68
- | NonFictionBook(title: Str, pages: Int, rating1: Rating, rating2: Rating)
64
+ record NonFictionBook(title: Str, pages: Int, rating1: Rating, rating2: Rating) =
69
65
 
70
66
  fun collectInterestingInfo(self) -> Str =
71
67
  match self.rating1, self.rating2
plum-examples/operators.plum CHANGED
@@ -5,8 +5,7 @@ import std/Float
5
5
 
6
6
  # Operators on non-primitive operands call methods: `a + b` is `a.add(b)`,
7
7
  # `-a` is `a.neg()`, `a == b` is `a.eq(b)`, `a < b` is `a.lt(b)`.
8
- enum Vec2 =
9
- | Vec2(x: Float, y: Float)
8
+ record Vec2(x: Float, y: Float) =
10
9
 
11
10
  fun toStr(self) -> Str =
12
11
  "Vec2({self.x}, {self.y})"
@@ -29,8 +28,7 @@ enum Vec2 =
29
28
  fun le(self, o: Vec2) -> Bool =
30
29
  self.x <= o.x
31
30
 
32
- enum Plain =
33
- | Plain(v: Int)
31
+ record Plain(v: Int)
34
32
 
35
33
  fun double(a: T) -> T =
36
34
  a + a
plum-examples/optionals.plum CHANGED
@@ -6,11 +6,9 @@ import std/List
6
6
  # `while x := opt`, `opt!` (crashes on null) and `opt == null`; `catch` and `try`
7
7
  # are for errors only. `!T?` is an error union whose success value is an optional.
8
8
 
9
- enum Box =
10
- | Box(label: Str)
9
+ record Box(label: Str)
11
10
 
12
- enum Holder =
13
- | Holder(item: Box?, count: Int?)
11
+ record Holder(item: Box?, count: Int?)
14
12
 
15
13
  fun maybeBox(c: Bool) -> Box? =
16
14
  if c
plum-examples/safe_navigation.plum CHANGED
@@ -18,17 +18,14 @@ import std/List
18
18
  # Pure sugar for `obj.andThen(|v| v.field)`, desugared entirely in the parser
19
19
  # (see `plum-core`'s `parseSafeAttribute`).
20
20
 
21
- enum Person =
22
- | Person(name: Str, age: Int)
21
+ record Person(name: Str, age: Int) =
23
22
 
24
23
  fun birthday(self) -> Int =
25
24
  self.age + 1
26
25
 
27
- enum Target =
28
- | Target(name: Str)
26
+ record Target(name: Str)
29
27
 
30
- enum User =
31
- | User(name: Str, target: Target?)
28
+ record User(name: Str, target: Target?)
32
29
 
33
30
  fun personName(p: Person?) -> Str? =
34
31
  p?.name
plum-examples/types.plum CHANGED
@@ -5,17 +5,14 @@ import std/Int
5
5
  import std/Float
6
6
  import std/Seq
7
7
 
8
- enum Point =
9
- | Point(x: Int, y: Int)
8
+ record Point(x: Int, y: Int)
10
9
 
11
- enum Named =
12
- | Named(name: Str)
10
+ record Named(name: Str) =
13
11
 
14
12
  fun toStr(self) -> Str =
15
13
  self.name
16
14
 
17
- enum Box[T] =
18
- | Box(value: T)
15
+ record Box[T](value: T)
19
16
 
20
17
  enum Color =
21
18
  | Red
@@ -35,26 +32,21 @@ fun makeStrBox() -> Box[Str] =
35
32
 
36
33
  # ---- record-shaped and sum-type enum regression tests ----
37
34
 
38
- enum Cat =
39
- | Cat(name: Str, age: Int)
35
+ record Cat(name: Str, age: Int) =
40
36
 
41
37
  fun getAge() -> Int =
42
38
  self.age
43
39
 
44
- enum Dog =
45
- | Dog(name: Str, age: Int)
40
+ record Dog(name: Str, age: Int) =
46
41
 
47
42
  fun getAge(self) -> Int =
48
43
  self.age
49
44
 
50
- enum IntPair =
51
- | IntPair(a: Int, b: Int)
45
+ record IntPair(a: Int, b: Int)
52
46
 
53
- enum Wrapper =
54
- | Wrapper(inner: IntPair, tag: Int)
47
+ record Wrapper(inner: IntPair, tag: Int)
55
48
 
56
- enum LoopBox =
57
- | LoopBox(v: Int)
49
+ record LoopBox(v: Int)
58
50
 
59
51
  fun sumLoopBoxes() -> Int =
60
52
  total := 0
@@ -89,15 +81,13 @@ fun area(s: ShapeKind) -> Int =
89
81
  Circle(r) =>
90
82
  return r * r
91
83
 
92
- enum Vec2 =
93
- | Vec2(x: Int, y: Int)
84
+ record Vec2(x: Int, y: Int)
94
85
 
95
86
  enum ShapeWithFields =
96
87
  | CircleField(radius: Int)
97
88
  | SquareField(side: Int)
98
89
 
99
- enum MaybeBox =
100
- | MaybeBox(value: Int?)
90
+ record MaybeBox(value: Int?) =
101
91
 
102
92
  fun unwrap(default: Int) -> Int =
103
93
  self.value ?: default
plum-std/Buffer.plum CHANGED
@@ -14,8 +14,7 @@ import std/Float
14
14
  # `bytes.Buffer`'s asymptotic behavior — unlike the previous `Str`-backed
15
15
  # version of this type, which recopied everything written so far on every
16
16
  # write.
17
- enum Buffer =
18
- | Buffer(data: []Byte, len: Int)
17
+ record Buffer(data: []Byte, len: Int) =
19
18
 
20
19
  # A no-param `init` nested in the type is `Buffer()`'s constructor — a
21
20
  # zero-arg `Buffer()` call desugars to `Buffer.init()` (see `plum-checker`'s
plum-std/Deque.plum CHANGED
@@ -9,8 +9,7 @@ import std/Float
9
9
  # element `i` (0 = front) lives at `(head + i) % capacity`. Pushes at either end
10
10
  # are O(1) amortized — when full, capacity doubles and the elements are copied
11
11
  # out in front-to-back order (so the ring unwraps).
12
- enum Deque[T] =
13
- | Deque(buf: Array[T], head: Int, size: Int)
12
+ record Deque[T](buf: Array[T], head: Int, size: Int) =
14
13
 
15
14
  fun init() -> Deque[T] =
16
15
  b := Array[T]().resize(8)
plum-std/Grid.plum CHANGED
@@ -9,8 +9,7 @@ import std/Float
9
9
  # `y` the row in `[0, h)`. `get`/`set` do no bounds check of their own beyond
10
10
  # the underlying array's trap — use `inBounds` first when coordinates may stray
11
11
  # off the map (neighbour scans, pathfinding).
12
- enum Grid[T] =
13
- | Grid(w: Int, h: Int, data: Array[T])
12
+ record Grid[T](w: Int, h: Int, data: Array[T]) =
14
13
 
15
14
  # `Grid.filled(w, h, v)` — a `w` x `h` grid with every cell set to `v`
16
15
  # (`T` is inferred from `v`).
plum-std/Heap.plum CHANGED
@@ -11,8 +11,7 @@ import std/Float
11
11
  # comparison, so keep it cheap and don't mutate an element's key while it is in
12
12
  # the heap. `push`/`pop` are O(log n); `peek`/`length` are O(1). Equal keys pop in
13
13
  # no guaranteed order.
14
- enum Heap[T] =
15
- | Heap(items: List[T], key: fn(T) -> Float)
14
+ record Heap[T](items: List[T], key: fn(T) -> Float) =
16
15
 
17
16
  fun length(self) -> Int =
18
17
  return self.items.length()
plum-std/Http.plum CHANGED
@@ -13,8 +13,7 @@ error HttpError = HttpFailed | BadResponse
13
13
 
14
14
  # An HTTP response: status code, response headers, and the raw response
15
15
  # body as a `Str` (a byte array, so binary bodies round-trip intact).
16
- enum Response =
17
- | Response(status: Int, headers: Map[Str, Str], body: Str)
16
+ record Response(status: Int, headers: Map[Str, Str], body: Str) =
18
17
 
19
18
  # 2xx status codes are success; everything else (redirects, 4xx, 5xx) is
20
19
  # surfaced here rather than as an error from `request` — a non-2xx
plum-std/Json.plum CHANGED
@@ -85,8 +85,7 @@ enum JsonParse =
85
85
  # A recursive-descent parser over a `Str` source, tracking its read position
86
86
  # in `pos`. It reads directly from a `Str`, the same way every other stdlib
87
87
  # parser (e.g. `Int.parse`) does.
88
- enum JsonParser =
89
- | JsonParser(src: Str, pos: Int, text: Str)
88
+ record JsonParser(src: Str, pos: Int, text: Str) =
90
89
 
91
90
  # Records why parsing is about to fail at the current position; the caller
92
91
  # then fails with `InvalidJson`.
plum-std/List.plum CHANGED
@@ -12,8 +12,7 @@ import std/Str
12
12
  # `get`/`set` are O(1). The core operations (`init`, `length`, `get`, `set`,
13
13
  # `push`, `pop`, `clear`) sit directly on the `Array` intrinsics; everything
14
14
  # else (`map`, `retain`, `reduce`, `chunk`, ...) is ordinary Plum on top of them.
15
- enum List[T] =
16
- | List(data: Array[T], size: Int)
15
+ record List[T](data: Array[T], size: Int) =
17
16
 
18
17
  # `List[T](1, 2, 3)` (or, for an empty list, `List[T]()` — explicit
19
18
  # generics required either way, since nothing else in a call this shape
plum-std/Map.plum CHANGED
@@ -9,8 +9,7 @@ import std/Str
9
9
  #
10
10
  # `toStr` exists because `List[T]` calls `toStr` on its elements (duck-typed)
11
11
  # and `Map` stores `List[Pair[K, V]]` buckets.
12
- enum Pair[K, V] =
13
- | Pair(key: K, val: V)
12
+ record Pair[K, V](key: K, val: V) =
14
13
 
15
14
  fun toStr(self) -> Str =
16
15
  return "{self.key.toStr()}: {self.val.toStr()}"
@@ -21,8 +20,7 @@ enum Pair[K, V] =
21
20
  # association list costs), degrading to O(n) only if many keys collide into
22
21
  # the same bucket.
23
22
  # `K` must have a `hash() -> Int` method (duck-typed, checked per instantiation).
24
- enum Map[K, V] =
25
- | Map(buckets: Array[List[Pair[K, V]]], size: Int)
23
+ record Map[K, V](buckets: Array[List[Pair[K, V]]], size: Int) =
26
24
 
27
25
  # Number of buckets every `Map` allocates at construction — fixed for the
28
26
  # map's whole lifetime, no rehashing/resizing as it grows. A real hash table
plum-std/Random.plum CHANGED
@@ -16,8 +16,7 @@ import std/Float
16
16
  # One raw 32-bit half of the host's pseudo-random generator.
17
17
  extern fun rawRandomHalf() -> Int
18
18
 
19
- enum Random =
20
- | Random(seed: Int)
19
+ record Random(seed: Int) =
21
20
 
22
21
  # A raw, host-provided pseudo-random 64-bit Int (xorshift64*, seeded from the
23
22
  # wall clock — not cryptographically secure). Every other wall-clock random
plum-std/Set.plum CHANGED
@@ -7,8 +7,7 @@ import std/Float
7
7
  # A set of unique `T`s, a thin layer over `Map[T, Bool]` (so `T` needs the same
8
8
  # duck-typed `hash() -> Int` and `==` that `Map`'s keys do). `Set[Int]()`
9
9
  # builds an empty one.
10
- enum Set[T] =
11
- | Set(map: Map[T, Bool])
10
+ record Set[T](map: Map[T, Bool]) =
12
11
 
13
12
  fun init() -> Set[T] =
14
13
  return Set(map: Map[T, Bool]())
plum-std/Str.plum CHANGED
@@ -22,8 +22,7 @@ import std/Float
22
22
  # means constructing a brand new `Str`/`Buffer` pair (`Buffer.write`'s own
23
23
  # callers are always building up a FRESH buffer before wrapping it, never
24
24
  # mutating an already-published `Str`'s backing storage).
25
- enum Str =
26
- | Str(data: Buffer)
25
+ record Str(data: Buffer) =
27
26
 
28
27
  # Number of bytes in the string — `self.data` (a `Buffer`) already tracks
29
28
  # this, so unlike `byteAt`/`byteToStr` this needs no compiler intrinsic of
plum-std/Time.plum CHANGED
@@ -8,8 +8,7 @@ import std/Str
8
8
  extern fun rawNowMillis() -> Float
9
9
 
10
10
  # A single point in time, stored as milliseconds since the Unix epoch.
11
- enum Time =
12
- | Time(value: Int)
11
+ record Time(value: Int) =
13
12
 
14
13
  MILLIS_PER_DAY = 86400000
15
14
 
@@ -82,8 +81,7 @@ enum Time =
82
81
  + "." + self.millisecond().toStr().padStart("0", 3) + "Z"
83
82
 
84
83
  # A Gregorian calendar date, decomposed from a day count by `civilFromDays`.
85
- enum Civil =
86
- | Civil(year: Int, month: Int, day: Int)
84
+ record Civil(year: Int, month: Int, day: Int)
87
85
 
88
86
  # Days-since-epoch to proleptic Gregorian year/month/day, via Howard
89
87
  # Hinnant's `civil_from_days` (http://howardhinnant.github.io/date_algorithms.html) —
@@ -116,8 +114,7 @@ fun floorMod(a: Int, b: Int) -> Int =
116
114
 
117
115
  # A span of time, stored as milliseconds. Negative values are meaningful
118
116
  # (e.g. the result of `Time.since` when `self` is earlier than `other`).
119
- enum Duration =
120
- | Duration(value: Int)
117
+ record Duration(value: Int) =
121
118
 
122
119
  fun millis(n: Int) -> Duration =
123
120
  return Duration(value: n)
plum-std/Uuid.plum CHANGED
@@ -6,8 +6,7 @@ import std/Random
6
6
 
7
7
  # A UUID, stored as its canonical 36-character
8
8
  # `xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx` text form.
9
- enum Uuid =
10
- | Uuid(value: Str)
9
+ record Uuid(value: Str) =
11
10
 
12
11
  fun toStr(self) -> Str =
13
12
  return self.value
plum-tooling/tree-sitter-plum/test/aa.plum CHANGED
@@ -14,8 +14,7 @@ primitive Defaults =
14
14
  error CatError = Hungry | Asleep
15
15
 
16
16
  # Cat is an animal that meows always
17
- enum Cat =
18
- | Cat(name: Str, age: Int)
17
+ record Cat(name: Str, age: Int) =
19
18
 
20
19
  fun withName(self, name: Str) -> Cat =
21
20
  Cat(name: name, age: self.age)
plum-tooling/tree-sitter-plum/test/corpus/const.txt CHANGED
@@ -121,8 +121,7 @@ primitive Consts =
121
121
  associated consts in an enum body and Type.NAME access
122
122
  ================================================================================
123
123
 
124
- enum Vec2 =
125
- | Vec2(x: Float, y: Float)
124
+ record Vec2(x: Float, y: Float) =
126
125
 
127
126
  ZERO = Vec2(x: 0.0, y: 0.0)
128
127
 
@@ -134,18 +133,16 @@ fun main() =
134
133
  --------------------------------------------------------------------------------
135
134
 
136
135
  (source
137
- (enum
136
+ (record
138
137
  (type_identifier)
139
- (field
140
- (type_identifier)
141
- (enum_named_field
138
+ (enum_named_field
142
- (var_identifier)
139
+ (var_identifier)
143
- (type
140
+ (type
144
- (type_identifier)))
141
+ (type_identifier)))
145
- (enum_named_field
142
+ (enum_named_field
146
- (var_identifier)
143
+ (var_identifier)
147
- (type
144
+ (type
148
- (type_identifier))))
145
+ (type_identifier)))
149
146
  (const
150
147
  (const_identifier)
151
148
  (expression
plum-tooling/tree-sitter-plum/test/corpus/type.txt CHANGED
@@ -2,11 +2,9 @@
2
2
  type
3
3
  ================================================================================
4
4
 
5
- enum Dog =
6
- | Dog(name: Str, age: B)
5
+ record Dog(name: Str, age: B)
7
6
 
8
- enum Cat =
9
- | Cat(name: Str, age: Int)
7
+ record Cat(name: Str, age: Int) =
10
8
 
11
9
  fun init(name: Str) -> Cat =
12
10
  Cat(name: name, age: 0)
@@ -23,30 +21,26 @@ enum Cat =
23
21
  --------------------------------------------------------------------------------
24
22
 
25
23
  (source
26
- (enum
24
+ (record
27
25
  (type_identifier)
28
- (field
29
- (type_identifier)
30
- (enum_named_field
26
+ (enum_named_field
31
- (var_identifier)
27
+ (var_identifier)
32
- (type
28
+ (type
33
- (type_identifier)))
29
+ (type_identifier)))
34
- (enum_named_field
30
+ (enum_named_field
35
- (var_identifier)
31
+ (var_identifier)
36
- (type
32
+ (type
37
- (generic)))))
33
+ (generic))))
38
- (enum
34
+ (record
39
35
  (type_identifier)
40
- (field
41
- (type_identifier)
42
- (enum_named_field
36
+ (enum_named_field
43
- (var_identifier)
37
+ (var_identifier)
44
- (type
38
+ (type
45
- (type_identifier)))
39
+ (type_identifier)))
46
- (enum_named_field
40
+ (enum_named_field
47
- (var_identifier)
41
+ (var_identifier)
48
- (type
42
+ (type
49
- (type_identifier))))
43
+ (type_identifier)))
50
44
  (fn
51
45
  (fn_identifier)
52
46
  (param
@@ -153,8 +147,7 @@ enum Cat =
153
147
  type - nested method declaration
154
148
  ================================================================================
155
149
 
156
- enum Cat =
157
- | Cat(name: Str)
150
+ record Cat(name: Str) =
158
151
 
159
152
  fun getName(self) -> Str =
160
153
  self.name
@@ -162,14 +155,12 @@ enum Cat =
162
155
  --------------------------------------------------------------------------------
163
156
 
164
157
  (source
165
- (enum
158
+ (record
166
159
  (type_identifier)
167
- (field
168
- (type_identifier)
169
- (enum_named_field
160
+ (enum_named_field
170
- (var_identifier)
161
+ (var_identifier)
171
- (type
162
+ (type
172
- (type_identifier))))
163
+ (type_identifier)))
173
164
  (fn
174
165
  (fn_identifier)
175
166
  (self)
plum-tooling/tree-sitter-plum/test/highlight/sample.plum CHANGED
@@ -1,7 +1,6 @@
1
1
  module std
2
2
 
3
- enum Cat =
4
- | Cat(name: Str, age: Int)
3
+ record Cat(name: Str, age: Int) =
5
4
 
6
5
  fun withName(self, name: Str) -> Cat =
7
6
  Cat(name: name, age: self.age)