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

View File

@ -58,10 +58,12 @@ where
} }
match self.current().token_type { match self.current().token_type {
TokenType::Fn => self.parse_function(), TokenType::Fn => self.parse_function(),
TokenType::Return => self.parse_function(), TokenType::Return => self.parse_return(),
TokenType::While => self.parse_function(), TokenType::For => self.parse_for(),
TokenType::Break => self.parse_function(), TokenType::While => self.parse_while(),
TokenType::Continue => self.parse_function(), TokenType::Break => self.parse_break(),
TokenType::Continue => self.parse_continue(),
TokenType::Let => self.parse_let(),
_ => self.parse_assign(), _ => self.parse_assign(),
} }
} }
@ -73,10 +75,39 @@ where
} }
let name = self.token_string(self.current()); let name = self.token_string(self.current());
self.step(); 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) { if self.done() || !self.current_is(TokenType::LParen) {
return self.error("expected '('"); return Err(self.error("expected '('"));
} }
self.step(); 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(); let mut parameters = Vec::<Node<Parameter>>::new();
if !self.done() && !self.current_is(TokenType::RParen) { if !self.done() && !self.current_is(TokenType::RParen) {
if self.current_is(TokenType::DotDotDot) { if self.current_is(TokenType::DotDotDot) {
@ -100,19 +131,7 @@ where
} }
} }
} }
if self.done() || !self.current_is(TokenType::RParen) { parameters
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),
})
} }
fn parse_parameter(&mut self) -> Node<Parameter> { 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> { fn parse_while(&mut self) -> Node<Expr> {
self.step(); self.step();
let condition = self.parse_expr(); let condition = self.parse_expr();
@ -357,6 +395,18 @@ where
left: Box::new(left), left: Box::new(left),
right: Box::new(right), 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 { } else {
break; break;
} }
@ -585,9 +635,10 @@ where
TokenType::True => self.step_and_node(Expr::Bool(true)), TokenType::True => self.step_and_node(Expr::Bool(true)),
TokenType::LParen => self.parse_unit_group_or_tuple(), TokenType::LParen => self.parse_unit_group_or_tuple(),
TokenType::LBrace => self.parse_block(), TokenType::LBrace => self.parse_block(),
TokenType::Underscore => todo!(), TokenType::Underscore => self.parse_object(),
TokenType::LBracket => self.parse_array(), TokenType::LBracket => self.parse_array(),
TokenType::If => self.parse_if(), TokenType::If => self.parse_if(),
TokenType::Fn => self.parse_function_value(),
TokenType::MalformedString => self.error("malformed string"), TokenType::MalformedString => self.error("malformed string"),
other => self.node(Expr::Error(format!("expected value, got {:?}", other))), other => self.node(Expr::Error(format!("expected value, got {:?}", other))),
} }
@ -605,8 +656,19 @@ where
self.step(); self.step();
if !self.done() && !self.current_is(TokenType::LParen) { if !self.done() && !self.current_is(TokenType::LParen) {
let first_value = self.parse_expr(); let first_value = self.parse_expr();
if !self.done() && !self.current_is(TokenType::LParen) { if !self.done() && !self.current_is(TokenType::RParen) {
todo!() 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 { } else {
self.step_and(first_value) self.step_and(first_value)
} }
@ -616,6 +678,10 @@ where
} }
fn parse_object(&mut self) -> Node<Expr> { 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(); self.step();
let mut values = Vec::<Node<ObjectEntry>>::new(); let mut values = Vec::<Node<ObjectEntry>>::new();
if !self.done() && !self.current_is(TokenType::RBracket) { if !self.done() && !self.current_is(TokenType::RBracket) {
@ -709,11 +775,23 @@ where
} }
falsy = Some(self.parse_block()); falsy = Some(self.parse_block());
} }
return self.node(Expr::If { self.node(Expr::If {
condition: Box::new(condition), condition: Box::new(condition),
truthy: Box::new(truthy), truthy: Box::new(truthy),
falsy: falsy.map(Box::new), 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 { 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
*/