Skip to main content

aver/parser/
core.rs

1use super::*;
2
3impl Parser {
4    pub fn new(tokens: Vec<Token>) -> Self {
5        Parser { tokens, pos: 0 }
6    }
7
8    pub(super) fn error(&self, msg: impl Into<String>) -> ParseError {
9        let tok = self.current();
10        ParseError::Error {
11            msg: msg.into(),
12            line: tok.line,
13            col: tok.col,
14        }
15    }
16
17    pub(super) fn current(&self) -> &Token {
18        if self.pos < self.tokens.len() {
19            &self.tokens[self.pos]
20        } else {
21            self.tokens.last().unwrap()
22        }
23    }
24
25    #[allow(dead_code)]
26    pub(super) fn peek(&self, offset: usize) -> &Token {
27        let idx = self.pos + offset;
28        if idx < self.tokens.len() {
29            &self.tokens[idx]
30        } else {
31            self.tokens.last().unwrap()
32        }
33    }
34
35    /// Peek at the nth non-formatting token (skips Newline/Indent/Dedent).
36    pub(super) fn peek_skip_formatting(&self, nth: usize) -> &Token {
37        let mut count = 0;
38        let mut idx = self.pos;
39        while idx < self.tokens.len() {
40            if !matches!(
41                self.tokens[idx].kind,
42                TokenKind::Newline | TokenKind::Indent | TokenKind::Dedent
43            ) {
44                if count == nth {
45                    return &self.tokens[idx];
46                }
47                count += 1;
48            }
49            idx += 1;
50        }
51        self.tokens.last().unwrap()
52    }
53
54    pub(super) fn advance(&mut self) -> &Token {
55        let tok = if self.pos < self.tokens.len() {
56            &self.tokens[self.pos]
57        } else {
58            self.tokens.last().unwrap()
59        };
60        if self.pos < self.tokens.len() {
61            self.pos += 1;
62        }
63        tok
64    }
65
66    pub(super) fn check_exact(&self, kind: &TokenKind) -> bool {
67        &self.current().kind == kind
68    }
69
70    pub(super) fn is_newline(&self) -> bool {
71        matches!(self.current().kind, TokenKind::Newline)
72    }
73
74    pub(super) fn is_indent(&self) -> bool {
75        matches!(self.current().kind, TokenKind::Indent)
76    }
77
78    pub(super) fn is_dedent(&self) -> bool {
79        matches!(self.current().kind, TokenKind::Dedent)
80    }
81
82    pub(super) fn is_eof(&self) -> bool {
83        matches!(self.current().kind, TokenKind::Eof)
84    }
85
86    #[allow(dead_code)]
87    pub(super) fn match_token(&mut self, kind: &TokenKind) -> Option<Token> {
88        if std::mem::discriminant(&self.current().kind) == std::mem::discriminant(kind) {
89            Some(self.advance().clone())
90        } else {
91            None
92        }
93    }
94
95    pub(super) fn expect_kind(&mut self, kind: &TokenKind, msg: &str) -> Result<Token, ParseError> {
96        if std::mem::discriminant(&self.current().kind) == std::mem::discriminant(kind) {
97            Ok(self.advance().clone())
98        } else {
99            Err(self.error(format!("{}, found {}", msg, self.current().kind)))
100        }
101    }
102
103    pub(super) fn expect_exact(&mut self, kind: &TokenKind) -> Result<Token, ParseError> {
104        if &self.current().kind == kind {
105            Ok(self.advance().clone())
106        } else {
107            Err(self.error(format!("Expected {}, found {}", kind, self.current().kind)))
108        }
109    }
110
111    pub(super) fn skip_formatting(&mut self) {
112        while matches!(
113            self.current().kind,
114            TokenKind::Newline | TokenKind::Indent | TokenKind::Dedent
115        ) {
116            self.advance();
117        }
118    }
119
120    pub(super) fn skip_newlines(&mut self) {
121        while self.is_newline() {
122            self.advance();
123        }
124    }
125
126    pub fn parse(&mut self) -> Result<Vec<TopLevel>, ParseError> {
127        let mut items = Vec::new();
128        self.skip_newlines();
129
130        while !self.is_eof() {
131            if let Some(item) = self.parse_top_level()? {
132                items.push(item);
133            }
134            self.skip_newlines();
135        }
136
137        Ok(items)
138    }
139
140    pub(super) fn parse_top_level(&mut self) -> Result<Option<TopLevel>, ParseError> {
141        match &self.current().kind {
142            TokenKind::Module => Ok(Some(TopLevel::Module(self.parse_module()?))),
143            TokenKind::Fn => Ok(Some(TopLevel::FnDef(self.parse_fn()?))),
144            TokenKind::Verify => Ok(Some(TopLevel::Verify(self.parse_verify()?))),
145            TokenKind::Decision => Ok(Some(TopLevel::Decision(self.parse_decision()?))),
146            TokenKind::Type => Ok(Some(TopLevel::TypeDef(self.parse_sum_type_def()?))),
147            TokenKind::Record => Ok(Some(TopLevel::TypeDef(self.parse_record_def()?))),
148            TokenKind::Effects => Ok(Some(self.parse_effect_set()?)),
149            TokenKind::Ident(s) if s == "val" || s == "var" => {
150                let kw = s.clone();
151                Err(self.error(format!(
152                    "Unknown keyword '{}'. Bindings are just: x = 5",
153                    kw
154                )))
155            }
156            TokenKind::Ident(_)
157                if matches!(&self.peek(1).kind, TokenKind::Assign | TokenKind::Colon) =>
158            {
159                let stmt = self.parse_binding()?;
160                Ok(Some(TopLevel::Stmt(stmt)))
161            }
162            TokenKind::Newline | TokenKind::Dedent | TokenKind::Indent => {
163                self.advance();
164                Ok(None)
165            }
166            TokenKind::Eof => Ok(None),
167            _ => {
168                let expr = self.parse_expr()?;
169                self.skip_newlines();
170                Ok(Some(TopLevel::Stmt(Stmt::Expr(expr))))
171            }
172        }
173    }
174}