luna_lib/lang/
ast.rs

1use crate::luna_impl::position::Located;
2
3use super::{code::BinaryOperation, tokens::Token};
4
5#[derive(Debug, Clone, PartialEq)]
6pub struct Chunk(pub Vec<Located<Statement>>);
7#[derive(Debug, Clone, PartialEq)]
8pub struct Block(pub Vec<Located<Statement>>);
9#[derive(Debug, Clone, PartialEq)]
10pub enum Statement {
11    Block(Block),
12    LetBinding {
13        params: Vec<Located<Parameter>>,
14        exprs: Vec<Located<Expression>>,
15    },
16    LetElse {
17        param: Located<Parameter>,
18        expr: Located<Expression>,
19        else_case: Located<Block>,
20    },
21    Assign {
22        paths: Vec<Located<Path>>,
23        exprs: Vec<Located<Expression>>,
24    },
25    AssignOperation {
26        op: AssignOperator,
27        path: Located<Path>,
28        expr: Located<Expression>,
29    },
30    Call {
31        path: Located<Path>,
32        args: Vec<Located<Expression>>,
33    },
34    SelfCall {
35        head: Located<Path>,
36        field: Located<String>,
37        args: Vec<Located<Expression>>,
38    },
39    Fn {
40        path: Located<Path>,
41        params: Vec<Located<Parameter>>,
42        var_args: Option<Located<String>>,
43        body: Located<Block>,
44    },
45    LetFn {
46        ident: Located<String>,
47        params: Vec<Located<Parameter>>,
48        var_args: Option<Located<String>>,
49        body: Located<Block>,
50    },
51    If {
52        cond: Located<Expression>,
53        case: Located<Block>,
54        else_case: Option<Located<Block>>,
55    },
56    IfLet {
57        param: Located<Parameter>,
58        expr: Located<Expression>,
59        case: Located<Block>,
60        else_case: Option<Located<Block>>,
61    },
62    Match {
63        expr: Located<Expression>,
64        cases: Vec<(Located<Pattern>, Located<Block>)>
65    },
66    While {
67        cond: Located<Expression>,
68        body: Located<Block>,
69    },
70    WhileLet {
71        param: Located<Parameter>,
72        expr: Located<Expression>,
73        body: Located<Block>,
74    },
75    For {
76        ident: Located<String>,
77        iter: Located<Expression>,
78        body: Located<Block>,
79    },
80    Return(Option<Located<Expression>>),
81    Break,
82    Continue,
83}
84#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
85pub enum AssignOperator {
86    Plus,
87    Minus,
88    Star,
89    Slash,
90    Exponent,
91    Percent,
92    // Ampersand,
93    // Pipe,
94}
95#[derive(Debug, Clone, PartialEq)]
96pub enum Pattern {
97    Ident(String),
98    Atom(Atom),
99    Guard {
100        pattern: Box<Located<Self>>,
101        cond: Located<Expression>
102    }
103}
104#[derive(Debug, Clone, PartialEq)]
105pub enum Expression {
106    Atom(Atom),
107    Binary {
108        op: BinaryOperator,
109        left: Box<Located<Self>>,
110        right: Box<Located<Self>>,
111    },
112    Unary {
113        op: UnaryOperator,
114        right: Box<Located<Self>>,
115    },
116    Call {
117        head: Box<Located<Self>>,
118        args: Vec<Located<Expression>>,
119    },
120    SelfCall {
121        head: Box<Located<Self>>,
122        field: Located<String>,
123        args: Vec<Located<Expression>>,
124    },
125    Field {
126        head: Box<Located<Self>>,
127        field: Located<String>,
128    },
129    Index {
130        head: Box<Located<Self>>,
131        index: Box<Located<Expression>>,
132    },
133}
134#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
135pub enum BinaryOperator {
136    Plus,
137    Minus,
138    Star,
139    Slash,
140    Exponent,
141    Percent,
142    EqualEqual,
143    ExclamationEqual,
144    Less,
145    Greater,
146    LessEqual,
147    GreaterEqual,
148    Ampersand,
149    Pipe,
150}
151#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
152pub enum UnaryOperator {
153    Minus,
154    Exclamation,
155}
156#[derive(Debug, Clone, PartialEq)]
157pub enum Atom {
158    Path(Path),
159    Null,
160    Int(i64),
161    Float(f64),
162    Bool(bool),
163    Char(char),
164    String(String),
165    Expression(Box<Located<Expression>>),
166    Vector(Vec<Located<Expression>>),
167    Object(Vec<(Located<String>, Located<Expression>)>),
168    If {
169        cond: Box<Located<Expression>>,
170        case: Box<Located<Expression>>,
171        else_case: Box<Located<Expression>>,
172    },
173    Fn {
174        params: Vec<Located<Parameter>>,
175        var_args: Option<Located<String>>,
176        body: Located<Block>,
177    },
178}
179#[derive(Debug, Clone, PartialEq)]
180pub enum Path {
181    Ident(String),
182    Field {
183        head: Box<Located<Self>>,
184        field: Located<String>,
185    },
186    Index {
187        head: Box<Located<Self>>,
188        index: Box<Located<Expression>>,
189    },
190}
191#[derive(Debug, Clone, PartialEq)]
192pub enum Parameter {
193    Ident(String),
194    Object(Vec<Located<String>>),
195    Vector(Vec<Located<String>>),
196}
197
198impl TryFrom<&Token> for AssignOperator {
199    type Error = ();
200    fn try_from(value: &Token) -> Result<Self, Self::Error> {
201        match value {
202            Token::PlusEqual => Ok(Self::Plus),
203            Token::MinusEqual => Ok(Self::Minus),
204            Token::StarEqual => Ok(Self::Star),
205            Token::SlashEqual => Ok(Self::Slash),
206            Token::PercentEqual => Ok(Self::Percent),
207            Token::ExponentEqual => Ok(Self::Exponent),
208            _ => Err(()),
209        }
210    }
211}
212impl From<AssignOperator> for BinaryOperation {
213    fn from(value: AssignOperator) -> Self {
214        match value {
215            AssignOperator::Plus => Self::Add,
216            AssignOperator::Minus => Self::Sub,
217            AssignOperator::Star => Self::Mul,
218            AssignOperator::Slash => Self::Div,
219            AssignOperator::Exponent => Self::Pow,
220            AssignOperator::Percent => Self::Mod,
221        }
222    }
223}
224impl BinaryOperator {
225    pub const LAYERS: &'static [&'static [Self]] = &[
226        &[Self::Ampersand, Self::Pipe],
227        &[
228            Self::EqualEqual,
229            Self::ExclamationEqual,
230            Self::Less,
231            Self::Greater,
232            Self::LessEqual,
233            Self::GreaterEqual,
234        ],
235        &[Self::Plus, Self::Minus],
236        &[Self::Star, Self::Slash, Self::Percent],
237        &[Self::Exponent],
238    ];
239    pub fn layer(layer: usize) -> Option<&'static [Self]> {
240        Self::LAYERS.get(layer).cloned()
241    }
242}
243impl TryFrom<&Token> for BinaryOperator {
244    type Error = ();
245    fn try_from(value: &Token) -> Result<Self, Self::Error> {
246        match value {
247            Token::Ampersand => Ok(Self::Ampersand),
248            Token::Pipe => Ok(Self::Pipe),
249            Token::Plus => Ok(Self::Plus),
250            Token::Minus => Ok(Self::Minus),
251            Token::Star => Ok(Self::Star),
252            Token::Slash => Ok(Self::Slash),
253            Token::Percent => Ok(Self::Percent),
254            Token::Exponent => Ok(Self::Exponent),
255            Token::EqualEqual => Ok(Self::EqualEqual),
256            Token::ExclamationEqual => Ok(Self::ExclamationEqual),
257            Token::Less => Ok(Self::Less),
258            Token::Greater => Ok(Self::Greater),
259            Token::LessEqual => Ok(Self::LessEqual),
260            Token::GreaterEqual => Ok(Self::GreaterEqual),
261            _ => Err(()),
262        }
263    }
264}
265impl UnaryOperator {
266    pub const LAYERS: &'static [&'static [Self]] = &[&[Self::Exclamation], &[Self::Minus]];
267    pub fn layer(layer: usize) -> Option<&'static [Self]> {
268        Self::LAYERS.get(layer).cloned()
269    }
270}
271impl TryFrom<&Token> for UnaryOperator {
272    type Error = ();
273    fn try_from(value: &Token) -> Result<Self, Self::Error> {
274        match value {
275            Token::Exclamation => Ok(Self::Exclamation),
276            Token::Minus => Ok(Self::Minus),
277            _ => Err(()),
278        }
279    }
280}