Skip to content

Commit

Permalink
stream 3
Browse files Browse the repository at this point in the history
  • Loading branch information
ilyas-taouaou committed Mar 14, 2024
1 parent 6386d6a commit 9b60503
Show file tree
Hide file tree
Showing 2 changed files with 146 additions and 85 deletions.
21 changes: 20 additions & 1 deletion sample.cdtk
Original file line number Diff line number Diff line change
@@ -1 +1,20 @@
let numbers = (0..10).for(|x| (x + 1) * 2);
{
let list = [1, 2, 3 + 3];
let x = (0..10).123.map(|x| {
let w = 10;
w
});
let y = 20;
let z = {
let w = 10;
w;
};
for i in (0..10) {
i = 10;
print(i);
};

if 10 == 20 {

}
}
210 changes: 126 additions & 84 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ type Bound<'src> = Option<Box<Expression<'src>>>;
enum Expression<'src> {
Number(f64),
Identifier(&'src str),
Let(&'src str, Box<Expression<'src>>, Box<Expression<'src>>),
Let(&'src str, Box<Expression<'src>>),
Mul(Box<Expression<'src>>, Box<Expression<'src>>),
Div(Box<Expression<'src>>, Box<Expression<'src>>),
Add(Box<Expression<'src>>, Box<Expression<'src>>),
Expand All @@ -23,9 +23,14 @@ enum Expression<'src> {
Tuple(Args<'src>),
Closure(Parameters<'src>, Box<Expression<'src>>),
Range(Bound<'src>, Bound<'src>),
// Dot(Vec<&'src str>),
Dot(Box<Expression<'src>>, Box<Expression<'src>>),
Block((Vec<Expression<'src>>, bool)),
For(&'src str, Box<Expression<'src>>, Box<Expression<'src>>),
End,
Assign(Box<Expression<'src>>, Box<Expression<'src>>),
Equal(Box<Expression<'src>>, Box<Expression<'src>>),
If(Box<Expression<'src>>, Box<Expression<'src>>),
Array(Vec<Expression<'src>>),
}

type BinaryOperator<'src> = fn(Box<Expression<'src>>, Box<Expression<'src>>) -> Expression<'src>;
Expand Down Expand Up @@ -57,94 +62,131 @@ fn parser<'src>() -> impl Parser<'src, &'src str, Expression<'src>, extra::Err<S
.map(Expression::Number);
let identifier = text::ident().map(Expression::Identifier);

let expression = recursive(|expression| {
let tuple = expression
.clone()
.separated_by(just(','))
.allow_trailing()
.collect::<Vec<_>>()
.delimited_by(just('('), just(')'));

let range = expression
.clone()
.or_not()
.separated_by(just(".."))
.exactly(2)
.collect_exactly::<[_; 2]>()
.delimited_by(just('('), just(')'))
.map(|[min, max]| Expression::Range(min.map(Box::new), max.map(Box::new)));

let call = text::ident()
.then(tuple.clone())
.map(|(name, arguments)| Expression::Call(name, arguments));

let closure = text::ident()
let block = recursive(|block| {
let expression = recursive(|expression| {
let tuple = expression
.clone()
.separated_by(just(','))
.allow_trailing()
.collect::<Vec<_>>()
.delimited_by(just('('), just(')'));

let array = expression
.clone()
.separated_by(just(','))
.allow_trailing()
.collect::<Vec<_>>()
.delimited_by(just('['), just(']'))
.map(Expression::Array);

let range = expression
.clone()
.or_not()
.separated_by(just(".."))
.exactly(2)
.collect_exactly::<[_; 2]>()
.delimited_by(just('('), just(')'))
.map(|[min, max]| Expression::Range(min.map(Box::new), max.map(Box::new)));

let call = text::ident()
.then(tuple.clone())
.map(|(name, arguments)| Expression::Call(name, arguments));

let closure = text::ident()
.padded()
.separated_by(just(','))
.allow_trailing()
.collect::<Vec<_>>()
.delimited_by(just('|'), just('|'))
.then(expression.clone())
.map(|(parameters, expression)| {
Expression::Closure(parameters, Box::new(expression))
});

let value = choice((
block.clone(),
array,
range,
closure,
call,
number,
identifier,
expression.delimited_by(just('('), just(')')),
tuple.map(Expression::Tuple),
))
.padded();

let dot_operator = value
.clone()
.foldl(just('.').ignore_then(value.clone()).repeated(), |a, b| {
Expression::Dot(Box::new(a), Box::new(b))
});

let unary_operator = choice((just('-').to(-1.0f64), just('+').to(1.0f64)))
.repeated()
.foldr(dot_operator, |a, b| {
Expression::Mul(Box::new(Expression::Number(a)), Box::new(b))
});

let product = binary_parser(
unary_operator,
('*', Expression::Mul),
('/', Expression::Div),
);
let sum = binary_parser(
product.clone(),
('+', Expression::Add),
('-', Expression::Sub),
);
let equal = sum
.clone()
.foldl(just("==").ignore_then(sum.clone()).repeated(), |a, b| {
Expression::Equal(Box::new(a), Box::new(b))
});
let assign = equal
.clone()
.foldl(just('=').ignore_then(equal.clone()).repeated(), |a, b| {
Expression::Assign(Box::new(a), Box::new(b))
});
assign
});

let r#let = text::keyword("let")
.padded()
.separated_by(just(','))
.allow_trailing()
.collect::<Vec<_>>()
.delimited_by(just('|'), just('|'))
.ignore_then(text::ident())
.then_ignore(just('=').padded())
.then(expression.clone())
.map(|(parameters, expression)| Expression::Closure(parameters, Box::new(expression)));

let value = choice((
range,
closure,
call,
number,
identifier,
expression.delimited_by(just('('), just(')')),
tuple.map(Expression::Tuple),
))
.padded();

let dot_operator = value
.clone()
.foldl(just('.').ignore_then(value.clone()).repeated(), |a, b| {
Expression::Dot(Box::new(a), Box::new(b))
});

// let dot_operator = text::ident()
// .separated_by(just('.'))
// .collect::<Vec<_>>()
// .map(Expression::Dot);
.map(|(identifier, expression)| Expression::Let(identifier, Box::new(expression)));

let unary_operator = choice((just('-').to(-1.0f64), just('+').to(1.0f64)))
.repeated()
.foldr(dot_operator, |a, b| {
Expression::Mul(Box::new(Expression::Number(a)), Box::new(b))
let r#for = text::keyword("for")
.padded()
.ignore_then(text::ident().padded())
.then_ignore(text::keyword("in").padded())
.then(expression.clone().padded())
.then(block.clone().padded())
.map(|((name, iterator), block)| {
Expression::For(name, Box::new(iterator), Box::new(block))
});

let product = binary_parser(
unary_operator,
('*', Expression::Mul),
('/', Expression::Div),
);
let sum = binary_parser(
product.clone(),
('+', Expression::Add),
('-', Expression::Sub),
);
sum
});

let r#let = recursive(|r#let| {
text::keyword("let")
let r#if = text::keyword("if")
.padded()
.ignore_then(text::ident())
.then_ignore(just('=').padded())
.then(expression.clone())
.then_ignore(just(';'))
.then(r#let.or(expression).or_not())
.map(|((identifier, expression), then)| {
Expression::Let(
identifier,
Box::new(expression),
Box::new(then.unwrap_or(Expression::End)),
)
})
.ignore_then(expression.clone().padded())
.then(block.clone().padded())
.map(|(condition, block)| Expression::If(Box::new(condition), Box::new(block)));

r#let
.or(r#if)
.or(r#for)
.or(expression)
.separated_by(just(';'))
.collect::<Vec<_>>()
.then(just(';').or_not().map(|x| x.is_some()))
.padded()
.delimited_by(just('{'), just('}'))
.map(Expression::Block)
});
r#let

block
}

fn main() {
Expand All @@ -154,7 +196,7 @@ fn main() {
Err(errors) => errors.into_iter().for_each(|error| {
Report::build(ReportKind::Error, (), error.span().start)
.with_message("Parse error")
.with_label(Label::new(error.span().into_range()).with_message(error.to_string()))
.with_label(Label::new(error.span().into_range()).with_message("Unexpected token"))
.finish()
.print(Source::from(source.clone()))
.unwrap();
Expand Down

0 comments on commit 9b60503

Please sign in to comment.