quickscript/ast/
mod.rs

1use anyhow::{Error, Result};
2
3use crate::{
4    tokenizer::{
5        consumer::Cursor,
6        token::{operator::Operator, ttype::TokenType},
7    },
8    util::AsCharVec,
9};
10
11use self::expr::{Expression, Operation};
12
13pub mod args;
14pub mod call;
15pub mod expr;
16pub mod func;
17pub mod ifelse;
18pub mod var;
19
20pub fn or_err<T>(opt: Option<T>, err: Error) -> Result<T> {
21    opt.ok_or(err)
22}
23
24pub fn is_next_decimal(iter: &mut Cursor<TokenType>) -> bool {
25    if let Some(item) = iter.peek(1) {
26        if let Ok(op) = item.get_operator() {
27            if op == Operator::Decimal {
28                return true;
29            }
30        }
31    }
32
33    return false;
34}
35
36pub struct AstParser {
37    pub iter: Cursor<TokenType>,
38    pub tokens: Vec<TokenType>,
39    pub exprs: Vec<Expression>,
40}
41
42impl AstParser {
43    pub fn new(tokens: Vec<TokenType>) -> Self {
44        Self {
45            iter: Cursor::new(tokens.clone()),
46            tokens,
47            exprs: Vec::new(),
48        }
49    }
50
51    pub fn parse(&mut self) -> Result<()> {
52        while self.iter.has_next() {
53            let expr = self.parse_one()?;
54
55            self.exprs.push(expr);
56        }
57
58        self.exprs = self
59            .exprs
60            .iter()
61            .cloned()
62            .filter(|v| v != &Expression::None)
63            .collect();
64
65        Ok(())
66    }
67
68    pub fn parse_one(&mut self) -> Result<Expression> {
69        Ok(match self.iter.next().unwrap() {
70            TokenType::Name(name) => match String::from_iter(name).as_str() {
71                "fn" => self.parse_fn()?,
72                "if" => self.parse_if()?,
73                "let" => self.parse_let()?,
74                "return" => Expression::Return(Box::new(self.parse_one()?)),
75
76                name => {
77                    let peeked = self
78                        .iter
79                        .peek_until(TokenType::Operator(Operator::OpenParens));
80
81                    if peeked
82                        .iter()
83                        .all(|v| v == &TokenType::Operator(Operator::Decimal) || v.is_name())
84                        && peeked.contains(&TokenType::Operator(Operator::Decimal))
85                    {
86                        let mut names = self
87                            .iter
88                            .read_until(TokenType::Operator(Operator::OpenParens));
89
90                        names.insert(0, TokenType::Name(name.as_char_vec()));
91
92                        let mut names = names
93                            .iter()
94                            .cloned()
95                            .filter(|v| v != &TokenType::Operator(Operator::Decimal))
96                            .collect::<Vec<TokenType>>();
97
98                        let method = names.pop().unwrap();
99
100                        let names = names
101                            .iter()
102                            .map(|v| v.get_name().unwrap())
103                            .collect::<Vec<String>>();
104
105                        let args = self.iter.read_until_counted(
106                            TokenType::Operator(Operator::OpenParens),
107                            TokenType::Operator(Operator::CloseParens),
108                        );
109
110                        let mut parser = AstParser::new(args);
111
112                        parser.parse()?;
113
114                        let args = parser
115                            .exprs
116                            .iter()
117                            .map(|v| Box::new(v.clone()))
118                            .collect::<Vec<Box<Expression>>>();
119
120                        return Ok(Expression::MethodCall(names, method.get_name()?, args));
121                    } else if self
122                        .iter
123                        .next_is_peek(TokenType::Operator(Operator::OpenParens), 0)
124                        .is_ok()
125                    {
126                        self.iter.next();
127
128                        let args = self.iter.read_until_counted(
129                            TokenType::Operator(Operator::OpenParens),
130                            TokenType::Operator(Operator::CloseParens),
131                        );
132
133                        let mut parser = AstParser::new(args);
134
135                        parser.parse()?;
136
137                        let args = parser
138                            .exprs
139                            .iter()
140                            .map(|v| Box::new(v.clone()))
141                            .collect::<Vec<Box<Expression>>>();
142
143                        return Ok(Expression::Call(name.to_string(), args));
144                    } else if self
145                        .iter
146                        .next_is_peek(TokenType::Operator(Operator::OpenSqBracket), 0)
147                        .is_ok()
148                    {
149                        self.iter.next();
150
151                        let idx = self
152                            .iter
153                            .next_result("Cannot read index from array!")?
154                            .get_number()?;
155
156                        self.iter.next();
157
158                        return Ok(Expression::Operation(Operation::Index(
159                            name.to_string(),
160                            idx as usize,
161                        )));
162                    }
163
164                    Expression::Identifier(name.to_string())
165                }
166            },
167
168            TokenType::String(val) => Expression::String(String::from_iter(val)),
169
170            TokenType::Number(val) => {
171                let n: i32 =
172                    String::from_iter(val.iter().map(|v| v.to_string()).collect::<Vec<String>>())
173                        .parse()?;
174
175                if self
176                    .iter
177                    .next_is_peek(TokenType::Operator(Operator::Decimal), 0)
178                    .is_ok()
179                    && self.iter.peek(1).unwrap_or(TokenType::None).is_number()
180                {
181                    self.iter.next();
182
183                    let n2 = self.iter.next().unwrap().get_number()?;
184                    let flt = format!("{}.{}", n, n2).parse::<f32>()?;
185
186                    Expression::Float(flt)
187                } else {
188                    Expression::Number(n)
189                }
190            }
191
192            TokenType::Operator(op) => match op {
193                Operator::Gt => {
194                    let last = self.exprs.pop().unwrap();
195
196                    if self
197                        .iter
198                        .next_is_peek(TokenType::Operator(Operator::Equals), 0)
199                        .is_ok()
200                    {
201                        self.iter.next();
202
203                        Expression::Operation(Operation::GtEq(
204                            Box::new(last),
205                            Box::new(self.parse_one()?),
206                        ))
207                    } else {
208                        Expression::Operation(Operation::Gt(
209                            Box::new(last),
210                            Box::new(self.parse_one()?),
211                        ))
212                    }
213                }
214
215                _ => Expression::None,
216            },
217
218            TokenType::None => Expression::None,
219        })
220    }
221}