1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
use crate::parser::expression::{parse_expression, prefixexpr, Expression, PrefixExpr};
use crate::parser::tokens::llet;
use crate::parser::{
literals::{parse_variable, sp, Variable},
Res, Span,
};
use nom::{
character::complete::char,
error::context,
sequence::{preceded, separated_pair},
};
#[derive(Debug, PartialEq, Clone)]
pub struct Assignment<'a> {
pub variable: PrefixExpr<'a>,
pub expression: Expression<'a>,
}
#[derive(Debug, PartialEq, Clone)]
pub struct LAssignment<'a> {
pub variable: Variable<'a>,
pub expression: Expression<'a>,
}
pub(crate) fn parse_assignment(input: Span) -> Res<Assignment> {
context(
"Assignment",
preceded(
sp,
separated_pair(
preceded(sp, prefixexpr),
preceded(sp, char('=')),
parse_expression,
),
),
)(input)
.map(|(next_input, (variable, expression))| {
(
next_input,
Assignment {
variable,
expression,
},
)
})
}
pub(crate) fn parse_lassignment(input: Span) -> Res<LAssignment> {
context(
"LAssignment",
preceded(
preceded(sp, llet),
preceded(
sp,
separated_pair(
preceded(sp, parse_variable),
preceded(sp, char('=')),
parse_expression,
),
),
),
)(input)
.map(|(next_input, (variable, expression))| {
(
next_input,
LAssignment {
variable,
expression,
},
)
})
}
#[cfg(test)]
mod tests {
use super::*;
use crate::literals::Token;
use crate::parser::expression::Expression;
use crate::parser::literals::{Collection, Literal};
#[test]
fn test_assignment() {
let string = "let x = 3";
let (_, res) = parse_lassignment(Span::new(string)).unwrap();
assert_eq!(
res,
LAssignment {
variable: Token::new("x", Span::new("x")),
expression: Expression::Literal(Literal::Int(Token::new(3, Span::new("3"))))
}
);
}
#[test]
fn test_assignment_list() {
let string = "let x = [1, 2, 3]\nlet x = 1";
let (rest, res) = parse_lassignment(Span::new(string)).unwrap();
println!("{}", rest);
assert_eq!(
res,
LAssignment {
variable: Token::new("x", Span::new("x")),
expression: Expression::Collection(Collection::Array(vec![
Expression::Literal(Literal::Int(Token::new(1, Span::new("1")))),
Expression::Literal(Literal::Int(Token::new(2, Span::new("2")))),
Expression::Literal(Literal::Int(Token::new(3, Span::new("3")))),
]))
}
);
}
}