plum

#treesitter#compiler#wasm

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

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


03e5a61Peter John 2026-07-19T19:11:09+05:30
feat(plum-checker): add type definitions
plum-checker/src/types.rs CHANGED
@@ -1 +1,78 @@
1
+ use std::collections::BTreeMap;
2
+
3
+ #[derive(Debug, Clone, PartialEq)]
4
+ pub enum PlumType {
5
+ TInt,
6
+ TFloat,
7
+ TBool,
8
+ TStr,
9
+ TUnit,
10
+ TVar(String),
11
+ TFun(Vec<PlumType>, Box<PlumType>),
12
+ TNamed(String),
13
+ }
14
+
15
+ impl std::fmt::Display for PlumType {
16
+ fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
17
+ match self {
18
+ PlumType::TInt => write!(f, "Int"),
19
+ PlumType::TFloat => write!(f, "Float"),
20
+ PlumType::TBool => write!(f, "Bool"),
21
+ PlumType::TStr => write!(f, "Str"),
22
+ PlumType::TUnit => write!(f, "Unit"),
23
+ PlumType::TVar(n) => write!(f, "{}", n),
24
+ PlumType::TFun(ps, r) => {
25
+ let ps_str: Vec<_> = ps.iter().map(|p| p.to_string()).collect();
26
+ write!(f, "({}) -> {}", ps_str.join(", "), r)
27
+ }
28
+ PlumType::TNamed(n) => write!(f, "{}", n),
29
+ }
30
+ }
31
+ }
32
+
33
+ #[derive(Debug, Clone, PartialEq)]
1
- // placeholder
34
+ pub struct TypeScheme {
35
+ pub vars: Vec<String>,
36
+ pub body: Box<PlumType>,
37
+ }
38
+
39
+ impl TypeScheme {
40
+ pub fn mono(t: PlumType) -> Self {
41
+ TypeScheme { vars: vec![], body: Box::new(t) }
42
+ }
43
+ }
44
+
45
+ pub type TypeEnv = BTreeMap<String, TypeScheme>;
46
+
47
+ pub struct InferState {
48
+ pub counter: u64,
49
+ }
50
+
51
+ impl InferState {
52
+ pub fn new() -> Self {
53
+ InferState { counter: 0 }
54
+ }
55
+
56
+ pub fn fresh_var(&mut self) -> String {
57
+ let name = format!("a{}", self.counter);
58
+ self.counter += 1;
59
+ name
60
+ }
61
+
62
+ pub fn fresh_type(&mut self) -> PlumType {
63
+ PlumType::TVar(self.fresh_var())
64
+ }
65
+ }
66
+
67
+ #[derive(Debug, Clone)]
68
+ pub struct CheckError {
69
+ pub message: String,
70
+ }
71
+
72
+ impl std::fmt::Display for CheckError {
73
+ fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
74
+ write!(f, "{}", self.message)
75
+ }
76
+ }
77
+
78
+ pub type CheckResult<T> = Result<T, Vec<CheckError>>;
plum-checker/tests/checker_tests.rs ADDED
@@ -0,0 +1,18 @@
1
+ use plum_checker::types::*;
2
+
3
+ #[test]
4
+ fn fresh_vars_are_unique() {
5
+ let mut state = InferState::new();
6
+ let a = state.fresh_var();
7
+ let b = state.fresh_var();
8
+ assert_ne!(a, b);
9
+ assert_eq!(a, "a0");
10
+ assert_eq!(b, "a1");
11
+ }
12
+
13
+ #[test]
14
+ fn mono_scheme() {
15
+ let scheme = TypeScheme::mono(PlumType::TInt);
16
+ assert!(scheme.vars.is_empty());
17
+ assert_eq!(*scheme.body, PlumType::TInt);
18
+ }