1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
use std::convert::TryFrom;
use crate::common::{
span::Spanned,
data::Data,
};
use crate::compiler::ast::ASTPattern;
#[derive(Debug, Clone, PartialEq)]
pub enum CSTPattern {
Symbol(String),
Data(Data),
Label(String, Box<Spanned<CSTPattern>>),
Tuple(Vec<Spanned<CSTPattern>>),
}
impl TryFrom<ASTPattern> for CSTPattern {
type Error = String;
fn try_from(ast_pattern: ASTPattern) -> Result<Self, Self::Error> {
Ok(
match ast_pattern {
ASTPattern::Symbol(s) => CSTPattern::Symbol(s),
ASTPattern::Data(d) => CSTPattern::Data(d),
ASTPattern::Label(k, a) => CSTPattern::Label(k, Box::new(a.map(CSTPattern::try_from)?)),
ASTPattern::Tuple(t) => CSTPattern::Tuple(t.into_iter().map(|i| i.map(CSTPattern::try_from)).collect::<Result<Vec<_>, _>>()?),
ASTPattern::Chain(_) => return Err("Unexpected chained construct inside pattern".into()),
}
)
}
}
#[derive(Debug, Clone, PartialEq)]
pub enum CST {
Symbol(String),
Data(Data),
Block(Vec<Spanned<CST>>),
Assign {
pattern: Box<Spanned<CSTPattern>>,
expression: Box<Spanned<CST>>,
},
Lambda {
pattern: Box<Spanned<CSTPattern>>,
expression: Box<Spanned<CST>>,
},
Call {
fun: Box<Spanned<CST>>,
arg: Box<Spanned<CST>>,
},
Label(String, Box<Spanned<CST>>),
Tuple(Vec<Spanned<CST>>),
FFI {
name: String,
expression: Box<Spanned<CST>>,
},
}
impl CST {
pub fn assign(
pattern: Spanned<CSTPattern>,
expression: Spanned<CST>
) -> CST {
CST::Assign {
pattern: Box::new(pattern),
expression: Box::new(expression)
}
}
pub fn lambda(
pattern: Spanned<CSTPattern>,
expression: Spanned<CST>
) -> CST {
CST::Lambda {
pattern: Box::new(pattern),
expression: Box::new(expression)
}
}
pub fn label(name: &str, expression: Spanned<CST>) -> CST {
CST::Label(name.to_string(), Box::new(expression))
}
pub fn call(fun: Spanned<CST>, arg: Spanned<CST>) -> CST {
CST::Call {
fun: Box::new(fun),
arg: Box::new(arg),
}
}
pub fn ffi(name: &str, expression: Spanned<CST>) -> CST {
CST::FFI {
name: name.to_string(),
expression: Box::new(expression),
}
}
}