1use log::error;
2use pest::iterators::Pair;
3
4use super::{Block, Param, Position, Rule, TypeAnnotation};
5
6#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord)]
7pub struct FnDef<T> {
8 pub params: Vec<Param<T>>,
9 pub type_annotation: TypeAnnotation,
10 pub block: Block<T>,
11 pub position: Position,
12 pub info: T,
13}
14
15impl FnDef<()> {
16 pub fn from_pair(pair: Pair<Rule>, file: &str) -> FnDef<()> {
17 assert_eq!(pair.as_rule(), Rule::fnDef);
18
19 let (line, col) = pair.line_col();
20
21 let mut inner = pair.into_inner();
22
23 let Some(param_list) = inner.next() else {
24 error!("Expected param list in function definition at {}:{}", line, col);
25 std::process::exit(-1);
26 };
27 let param_list = Self::from_param_list(param_list, file);
28
29 let Some(type_annotation) = inner.next() else {
30 error!("Expected return type annotation in function definition at {}:{}", line, col);
31 std::process::exit(-1);
32 };
33 let type_annotation = TypeAnnotation::from_pair(type_annotation, file);
34
35 let Some(block) = inner.next() else {
36 error!("Expected block in function definition at {}:{}", line, col);
37 std::process::exit(-1);
38 };
39 let block = Block::from_pair(block, file);
40
41 FnDef {
42 params: param_list,
43 type_annotation,
44 block,
45 position: (file.to_owned(), line, col),
46 info: (),
47 }
48 }
49
50 fn from_param_list(pair: Pair<Rule>, file: &str) -> Vec<Param<()>> {
51 assert_eq!(pair.as_rule(), Rule::paramList);
52
53 let param_pairs = pair.into_inner();
54
55 let mut params = vec![];
56
57 for param in param_pairs {
58 params.push(Param::from_pair(param, file));
59 }
60
61 params
62 }
63}