add function value

This commit is contained in:
SimonFJ20 2023-03-16 15:37:21 +01:00
parent a29bc95f3b
commit 76cf35e72e
3 changed files with 111 additions and 35 deletions

View File

@ -24,6 +24,10 @@ pub enum Expr {
truthy: Box<Node<Expr>>,
falsy: Option<Box<Node<Expr>>>,
},
FunctionValue {
parameters: Vec<Node<Parameter>>,
body: Box<Node<Expr>>,
},
Member {
subject: Box<Node<Expr>>,
@ -70,6 +74,11 @@ pub enum Expr {
condition: Box<Node<Expr>>,
body: Box<Node<Expr>>,
},
For {
subject: Node<Parameter>,
value: Box<Node<Expr>>,
body: Box<Node<Expr>>,
},
Return(Option<Box<Node<Expr>>>),
Function {
name: String,
@ -116,6 +125,7 @@ pub enum BinaryType {
GT,
GTE,
In,
NotIn,
Equal,
Inequal,
And,

View File

@ -58,10 +58,12 @@ where
}
match self.current().token_type {
TokenType::Fn => self.parse_function(),
TokenType::Return => self.parse_function(),
TokenType::While => self.parse_function(),
TokenType::Break => self.parse_function(),
TokenType::Continue => self.parse_function(),
TokenType::Return => self.parse_return(),
TokenType::For => self.parse_for(),
TokenType::While => self.parse_while(),
TokenType::Break => self.parse_break(),
TokenType::Continue => self.parse_continue(),
TokenType::Let => self.parse_let(),
_ => self.parse_assign(),
}
}
@ -73,10 +75,39 @@ where
}
let name = self.token_string(self.current());
self.step();
let (parameters, body) = match self.parse_function_details() {
Ok(v) => v,
Err(e) => return e,
};
self.node(Expr::Function {
name,
parameters,
body: Box::new(body),
})
}
fn parse_function_details(&mut self) -> Result<(Vec<Node<Parameter>>, Node<Expr>), Node<Expr>> {
if self.done() || !self.current_is(TokenType::LParen) {
return self.error("expected '('");
return Err(self.error("expected '('"));
}
self.step();
let mut parameters = self.parse_function_parameters();
if self.done() || !self.current_is(TokenType::RParen) {
return Err(self.error("expected ')'"));
}
self.step();
let body = if !self.done() && self.current_is(TokenType::LBrace) {
self.parse_block()
} else if !self.done() && self.current_is(TokenType::EqualLessThan) {
self.step();
self.parse_expr()
} else {
return Err(self.error("expected '{'"));
};
Ok((parameters, body))
}
fn parse_function_parameters(&mut self) -> Vec<Node<Parameter>> {
let mut parameters = Vec::<Node<Parameter>>::new();
if !self.done() && !self.current_is(TokenType::RParen) {
if self.current_is(TokenType::DotDotDot) {
@ -100,19 +131,7 @@ where
}
}
}
if self.done() || !self.current_is(TokenType::RParen) {
return self.error("expected ')'");
}
self.step();
if self.done() || !self.current_is(TokenType::LBrace) {
return self.error("expected '{'");
}
let body = self.parse_block();
self.node(Expr::Function {
name,
parameters,
body: Box::new(body),
})
parameters
}
fn parse_parameter(&mut self) -> Node<Parameter> {
@ -139,6 +158,25 @@ where
}
}
fn parse_for(&mut self) -> Node<Expr> {
self.step();
let subject = self.parse_parameter();
if self.done() || !self.current_is(TokenType::In) {
return self.error("expected 'in'");
}
self.step();
let value = self.parse_expr();
if self.done() || !self.current_is(TokenType::LBrace) {
return self.error("expected '{'");
}
let body = self.parse_block();
self.node(Expr::For {
subject,
value: Box::new(value),
body: Box::new(body),
})
}
fn parse_while(&mut self) -> Node<Expr> {
self.step();
let condition = self.parse_expr();
@ -357,6 +395,18 @@ where
left: Box::new(left),
right: Box::new(right),
});
} else if self.current_is(TokenType::Not) {
self.step();
if self.done() || !self.current_is(TokenType::In) {
return self.error("expected 'in'");
}
self.step();
let right = self.parse_prec_range();
left = self.node(Expr::Binary {
binary_type: BinaryType::NotIn,
left: Box::new(left),
right: Box::new(right),
});
} else {
break;
}
@ -585,9 +635,10 @@ where
TokenType::True => self.step_and_node(Expr::Bool(true)),
TokenType::LParen => self.parse_unit_group_or_tuple(),
TokenType::LBrace => self.parse_block(),
TokenType::Underscore => todo!(),
TokenType::Underscore => self.parse_object(),
TokenType::LBracket => self.parse_array(),
TokenType::If => self.parse_if(),
TokenType::Fn => self.parse_function_value(),
TokenType::MalformedString => self.error("malformed string"),
other => self.node(Expr::Error(format!("expected value, got {:?}", other))),
}
@ -605,8 +656,19 @@ where
self.step();
if !self.done() && !self.current_is(TokenType::LParen) {
let first_value = self.parse_expr();
if !self.done() && !self.current_is(TokenType::LParen) {
todo!()
if !self.done() && !self.current_is(TokenType::RParen) {
let mut values = vec![first_value];
while !self.done() && self.current_is(TokenType::Comma) {
self.step();
if self.done() || self.current_is(TokenType::RParen) {
break;
}
values.push(self.parse_expr());
}
if self.done() || !self.current_is(TokenType::RParen) {
return self.error("expected ')'");
}
self.step_and_node(Expr::Tuple(values))
} else {
self.step_and(first_value)
}
@ -616,6 +678,10 @@ where
}
fn parse_object(&mut self) -> Node<Expr> {
self.step();
if self.done() || !self.current_is(TokenType::LBrace) {
return self.error("expected '{' of object literal");
}
self.step();
let mut values = Vec::<Node<ObjectEntry>>::new();
if !self.done() && !self.current_is(TokenType::RBracket) {
@ -709,11 +775,23 @@ where
}
falsy = Some(self.parse_block());
}
return self.node(Expr::If {
self.node(Expr::If {
condition: Box::new(condition),
truthy: Box::new(truthy),
falsy: falsy.map(Box::new),
});
})
}
fn parse_function_value(&mut self) -> Node<Expr> {
self.step();
let (parameters, body) = match self.parse_function_details() {
Ok(v) => v,
Err(e) => return e,
};
self.node(Expr::FunctionValue {
parameters,
body: Box::new(body),
})
}
fn token_string(&self, token: &Token) -> String {

View File

@ -1,12 +0,0 @@
let a = 5;
if 1 == 0 and true {
return true;
}
// safadkjasda
/*
sdasd
*/