• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

TyRoXx / NonlocalityOS / 14776241932

01 May 2025 01:31PM UTC coverage: 77.046% (-0.6%) from 77.611%
14776241932

Pull #227

github

web-flow
Merge 005650a70 into 3008f5ee2
Pull Request #227: Remove obsolete code

287 of 351 new or added lines in 9 files covered. (81.77%)

4 existing lines in 3 files now uncovered.

3954 of 5132 relevant lines covered (77.05%)

1837.21 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

65.05
/lambda_compiler/src/parsing.rs
1
use crate::{
2
    compilation::{CompilerError, CompilerOutput, SourceLocation},
3
    tokenization::{Token, TokenContent},
4
};
5
use astraea::tree::{HashedValue, Value};
6
use lambda::expressions::{DeepExpression, Expression};
7
use lambda::name::{Name, NamespaceId};
8
use std::sync::Arc;
9

10
#[derive(Debug)]
11
pub struct ParserError {
12
    pub message: String,
13
}
14

15
impl ParserError {
16
    pub fn new(message: String) -> Self {
1✔
17
        Self { message }
18
    }
19
}
20

21
impl std::fmt::Display for ParserError {
22
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1✔
23
        write!(f, "{}", &self.message)
1✔
24
    }
25
}
26

27
pub type ParserResult<T> = std::result::Result<T, ParserError>;
28

29
pub fn pop_next_non_whitespace_token<'t>(
48✔
30
    tokens: &mut std::iter::Peekable<std::slice::Iter<'t, Token>>,
31
) -> Option<&'t Token> {
32
    let token = peek_next_non_whitespace_token(tokens);
48✔
33
    if token.is_some() {
91✔
34
        tokens.next();
43✔
35
    }
36

37
    return token;
48✔
38
}
39

40
pub fn peek_next_non_whitespace_token<'t>(
66✔
41
    tokens: &mut std::iter::Peekable<std::slice::Iter<'t, Token>>,
42
) -> Option<&'t Token> {
43
    loop {
×
44
        let next = tokens.peek();
80✔
45
        match next {
80✔
46
            Some(token) => match token.content {
65✔
47
                TokenContent::Whitespace => {
×
48
                    tokens.next();
14✔
49
                    continue;
14✔
50
                }
51
                TokenContent::Identifier(_)
×
52
                | TokenContent::Assign
×
53
                | TokenContent::LeftParenthesis
×
54
                | TokenContent::RightParenthesis
×
55
                | TokenContent::Dot
×
56
                | TokenContent::Quotes(_)
×
57
                | TokenContent::FatArrow => return Some(token),
51✔
58
            },
59
            None => return None,
15✔
60
        }
61
    }
62
}
63

64
fn expect_right_parenthesis(tokens: &mut std::iter::Peekable<std::slice::Iter<'_, Token>>) {
11✔
65
    match pop_next_non_whitespace_token(tokens) {
11✔
66
        Some(non_whitespace) => match &non_whitespace.content {
11✔
67
            TokenContent::Whitespace => todo!(),
68
            TokenContent::Identifier(_) => todo!(),
69
            TokenContent::Assign => todo!(),
70
            TokenContent::LeftParenthesis => todo!(),
71
            TokenContent::RightParenthesis => {}
11✔
72
            TokenContent::Dot => todo!(),
73
            TokenContent::Quotes(_) => todo!(),
74
            TokenContent::FatArrow => todo!(),
75
        },
76
        None => todo!(),
77
    }
78
}
79

80
fn expect_fat_arrow(tokens: &mut std::iter::Peekable<std::slice::Iter<'_, Token>>) {
7✔
81
    match pop_next_non_whitespace_token(tokens) {
7✔
82
        Some(non_whitespace) => match &non_whitespace.content {
7✔
83
            TokenContent::Whitespace => todo!(),
84
            TokenContent::Identifier(_) => todo!(),
85
            TokenContent::Assign => todo!(),
86
            TokenContent::LeftParenthesis => todo!(),
87
            TokenContent::RightParenthesis => todo!(),
88
            TokenContent::Dot => todo!(),
89
            TokenContent::Quotes(_) => todo!(),
90
            TokenContent::FatArrow => {}
7✔
91
        },
92
        None => todo!(),
93
    }
94
}
95

96
async fn parse_expression_start<'t>(
19✔
97
    tokens: &mut std::iter::Peekable<std::slice::Iter<'t, Token>>,
98
    local_namespace: &NamespaceId,
99
) -> ParserResult<DeepExpression> {
100
    match pop_next_non_whitespace_token(tokens) {
19✔
101
        Some(non_whitespace) => match &non_whitespace.content {
18✔
102
            TokenContent::Whitespace => todo!(),
103
            TokenContent::Identifier(identifier) => Ok(DeepExpression(Expression::ReadVariable(
10✔
104
                Name::new(*local_namespace, identifier.clone()),
10✔
105
            ))),
106
            TokenContent::Assign => todo!(),
107
            TokenContent::LeftParenthesis => Box::pin(parse_lambda(tokens, local_namespace)).await,
7✔
108
            TokenContent::RightParenthesis => todo!(),
109
            TokenContent::Dot => todo!(),
110
            TokenContent::Quotes(content) => Ok(DeepExpression(Expression::Literal(
1✔
111
                HashedValue::from(Arc::new(
1✔
112
                    Value::from_string(&content).expect("It's too long. That's what she said."),
1✔
113
                ))
114
                .digest()
1✔
115
                .clone(),
1✔
116
            ))),
117
            TokenContent::FatArrow => todo!(),
118
        },
119
        None => Err(ParserError::new(
1✔
120
            "Expected expression, got EOF.".to_string(),
1✔
121
        )),
122
    }
123
}
124

125
pub async fn parse_expression<'t>(
19✔
126
    tokens: &mut std::iter::Peekable<std::slice::Iter<'t, Token>>,
127
    local_namespace: &NamespaceId,
128
) -> ParserResult<DeepExpression> {
129
    let start = parse_expression_start(tokens, local_namespace).await?;
38✔
130
    match peek_next_non_whitespace_token(tokens) {
×
131
        Some(more) => match &more.content {
8✔
132
            TokenContent::Whitespace => unreachable!(),
133
            TokenContent::Identifier(_) => Ok(start),
×
134
            TokenContent::Assign => Ok(start),
×
135
            TokenContent::LeftParenthesis => {
×
136
                tokens.next();
4✔
137
                let argument = Box::pin(parse_expression(tokens, local_namespace)).await?;
8✔
138
                expect_right_parenthesis(tokens);
×
NEW
139
                Ok(DeepExpression(Expression::make_apply(
×
NEW
140
                    Arc::new(start),
×
NEW
141
                    Arc::new(argument),
×
142
                )))
143
            }
144
            TokenContent::RightParenthesis => Ok(start),
4✔
145
            TokenContent::Dot => todo!(),
146
            TokenContent::Quotes(_) => todo!(),
147
            TokenContent::FatArrow => todo!(),
148
        },
149
        None => Ok(start),
10✔
150
    }
151
}
152

153
async fn parse_lambda<'t>(
7✔
154
    tokens: &mut std::iter::Peekable<std::slice::Iter<'t, Token>>,
155
    local_namespace: &NamespaceId,
156
) -> ParserResult<DeepExpression> {
157
    let parameter_name: Name = Name::new(
158
        *local_namespace,
7✔
159
        match pop_next_non_whitespace_token(tokens) {
7✔
160
            Some(non_whitespace) => match &non_whitespace.content {
7✔
161
                TokenContent::Whitespace => todo!(),
×
162
                TokenContent::Identifier(identifier) => identifier.clone(),
7✔
163
                TokenContent::Assign => todo!(),
×
164
                TokenContent::LeftParenthesis => todo!(),
×
165
                TokenContent::RightParenthesis => todo!(),
×
166
                TokenContent::Dot => todo!(),
×
167
                TokenContent::Quotes(_) => todo!(),
×
168
                TokenContent::FatArrow => todo!(),
×
169
            },
170
            None => todo!(),
×
171
        },
172
    );
173
    expect_right_parenthesis(tokens);
7✔
174
    expect_fat_arrow(tokens);
7✔
175
    let body = parse_expression(tokens, local_namespace).await?;
14✔
NEW
176
    Ok(DeepExpression(Expression::make_lambda(
×
UNCOV
177
        parameter_name,
×
NEW
178
        Arc::new(body),
×
179
    )))
180
}
181

182
pub async fn parse_entry_point_lambda<'t>(
5✔
183
    tokens: &mut std::iter::Peekable<std::slice::Iter<'t, Token>>,
184
    local_namespace: &NamespaceId,
185
) -> CompilerOutput {
186
    let mut errors = Vec::new();
5✔
187
    let entry_point_result = parse_expression(tokens, local_namespace).await;
10✔
188
    match entry_point_result {
5✔
189
        Ok(entry_point) => match &entry_point.0 {
4✔
NEW
190
            Expression::Literal(_)
×
NEW
191
            | Expression::Apply {
×
NEW
192
                callee: _,
×
NEW
193
                argument: _,
×
194
            }
195
            | Expression::ReadVariable(_) => {
×
196
                errors.push(CompilerError::new(
1✔
197
                    "The entry point is expected to be a lambda expression.".to_string(),
1✔
198
                    SourceLocation::new(0, 0),
1✔
199
                ));
200
                CompilerOutput::new(None, errors)
1✔
201
            }
NEW
202
            Expression::Lambda {
×
NEW
203
                parameter_name: _,
×
NEW
204
                body: _,
×
205
            } => CompilerOutput::new(Some(entry_point), errors),
3✔
NEW
206
            Expression::Construct(_arguments) => {
×
207
                todo!()
208
            }
209
        },
210
        Err(error) => {
1✔
211
            errors.push(CompilerError::new(
1✔
212
                format!("Parser error: {}", &error),
1✔
213
                SourceLocation::new(0, 0),
1✔
214
            ));
215
            CompilerOutput::new(None, errors)
1✔
216
        }
217
    }
218
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc