vector and assign
This commit is contained in:
parent
8836f95149
commit
8b544edba5
7 changed files with 166 additions and 20 deletions
|
|
@ -25,7 +25,7 @@ pub fn record_expr(rec: Vec<(&str, Expr)>) -> Expr {
|
|||
}
|
||||
|
||||
pub fn assign(name: &str, expr: Expr) -> Statement {
|
||||
Statement::Assign(define_expr(name, expr))
|
||||
Statement::Let(define_expr(name, expr))
|
||||
}
|
||||
|
||||
pub fn stmt_expr(expr: Expr) -> Statement {
|
||||
|
|
|
|||
|
|
@ -5,6 +5,11 @@ use std::collections::BTreeMap;
|
|||
/// An expression.
|
||||
#[derive(PartialEq, PartialOrd, Debug, Clone)]
|
||||
pub enum Expr {
|
||||
Op {
|
||||
lhs: Box<Expr>,
|
||||
op: Op,
|
||||
rhs: Box<Expr>,
|
||||
},
|
||||
Value(Value),
|
||||
Var(Name),
|
||||
Func(Box<Fn>),
|
||||
|
|
@ -32,11 +37,17 @@ pub enum Expr {
|
|||
*/
|
||||
}
|
||||
|
||||
#[derive(PartialEq, PartialOrd, Debug, Clone)]
|
||||
pub enum Op {
|
||||
Assign,
|
||||
// Equals,
|
||||
}
|
||||
|
||||
/// A statement.
|
||||
#[derive(PartialEq, PartialOrd, Debug, Clone)]
|
||||
pub enum Statement {
|
||||
Expr(Expr),
|
||||
Assign(Definition),
|
||||
Let(Definition),
|
||||
}
|
||||
|
||||
#[derive(PartialEq, PartialOrd, Debug, Clone)]
|
||||
|
|
|
|||
|
|
@ -34,7 +34,7 @@ fn eval_statement(
|
|||
) -> Result<ast::Value, Error> {
|
||||
match statement {
|
||||
ast::Statement::Expr(expr) => eval_expr(expr_env, state, expr),
|
||||
ast::Statement::Assign(ast::Definition { name, expr }) => {
|
||||
ast::Statement::Let(ast::Definition { name, expr }) => {
|
||||
let result = eval_expr(expr_env, state, expr)?;
|
||||
expr_env.insert(name.clone(), result.clone());
|
||||
Ok(result)
|
||||
|
|
@ -115,6 +115,7 @@ fn eval_expr(expr_env: &Env, state: &mut State, expr: &ast::Expr) -> Result<ast:
|
|||
}
|
||||
_ => Ok(v.clone()),
|
||||
},
|
||||
ast::Expr::Op { .. } => todo!("Implement bin op"),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -18,25 +18,33 @@ fn parse_definitions(tokens: &mut Tokens) -> ParseResult<Vec<ast::Definition>> {
|
|||
tokens.many(parse_definition)
|
||||
}
|
||||
|
||||
fn parse_set(tokens: &mut Tokens) -> ParseResult<ast::Expr> {
|
||||
if let Some(_eq) = tokens.next_if(&Token::Equals) {
|
||||
if let Some(expr) = parse_expr(tokens)? {
|
||||
if let Some(_) = tokens.next_if(&Token::Semicolon) {
|
||||
Ok(Some(expr))
|
||||
} else {
|
||||
Err(Error::UnexpectedToken {
|
||||
expected: Token::Semicolon,
|
||||
got: tokens.next(),
|
||||
})
|
||||
}
|
||||
} else {
|
||||
Err(Error::UnexpectedTokenForParser(
|
||||
"expr".into(),
|
||||
tokens.next(),
|
||||
))
|
||||
}
|
||||
} else {
|
||||
Ok(None)
|
||||
}
|
||||
}
|
||||
|
||||
fn parse_definition(tokens: &mut Tokens) -> ParseResult<ast::Definition> {
|
||||
if let Some(_) = tokens.next_if(&Token::Let) {
|
||||
if let Some(name) = parse_identifier_name(tokens)? {
|
||||
if let Some(_eq) = tokens.next_if(&Token::Equals) {
|
||||
if let Some(expr) = parse_expr(tokens)? {
|
||||
if let Some(_) = tokens.next_if(&Token::Semicolon) {
|
||||
Ok(Some(ast::Definition { name, expr }))
|
||||
} else {
|
||||
Err(Error::UnexpectedToken {
|
||||
expected: Token::Semicolon,
|
||||
got: tokens.next(),
|
||||
})
|
||||
}
|
||||
} else {
|
||||
Err(Error::UnexpectedTokenForParser(
|
||||
"expr".into(),
|
||||
tokens.next(),
|
||||
))
|
||||
}
|
||||
if let Some(expr) = parse_set(tokens)? {
|
||||
Ok(Some(ast::Definition { name, expr }))
|
||||
} else {
|
||||
Err(Error::UnexpectedToken {
|
||||
expected: Token::Equals,
|
||||
|
|
@ -64,7 +72,13 @@ fn parse_expr(tokens: &mut Tokens) -> ParseResult<ast::Expr> {
|
|||
args: args,
|
||||
}))
|
||||
} else {
|
||||
Ok(Some(expr1))
|
||||
Ok(parse_set(tokens)?
|
||||
.map(|expr2| ast::Expr::Op {
|
||||
op: ast::Op::Assign,
|
||||
lhs: Box::new(expr1.clone()),
|
||||
rhs: Box::new(expr2),
|
||||
})
|
||||
.or(Some(expr1)))
|
||||
}
|
||||
} else {
|
||||
Ok(None)
|
||||
|
|
@ -79,6 +93,7 @@ fn parse_simple_expr(tokens: &mut Tokens) -> ParseResult<ast::Expr> {
|
|||
parse_bool,
|
||||
parse_fn,
|
||||
parse_record,
|
||||
parse_vector,
|
||||
|t| t.between(&Token::OpenParen, &Token::CloseParen, parse_expr),
|
||||
])
|
||||
}
|
||||
|
|
@ -123,6 +138,18 @@ fn parse_record(tokens: &mut Tokens) -> ParseResult<ast::Expr> {
|
|||
}
|
||||
}
|
||||
|
||||
fn parse_vector(tokens: &mut Tokens) -> ParseResult<ast::Expr> {
|
||||
if let Some(vect) = tokens.between(&Token::OpenBracket, &Token::CloseBracket, |tokens| {
|
||||
tokens.many_sep_by(&Token::Comma, parse_expr)
|
||||
})? {
|
||||
Ok(Some(ast::Expr::Value(ast::Value::Vector(ast::Vector(
|
||||
vect,
|
||||
)))))
|
||||
} else {
|
||||
Ok(None)
|
||||
}
|
||||
}
|
||||
|
||||
fn parse_record_field_expr(tokens: &mut Tokens) -> ParseResult<(ast::Label, ast::Expr)> {
|
||||
if let Some(label) = parse_identifier_label(tokens)? {
|
||||
if let Some(_) = tokens.next_if(&Token::Colon) {
|
||||
|
|
@ -244,6 +271,24 @@ mod tests {
|
|||
insta::assert_debug_snapshot!(result);
|
||||
}
|
||||
#[test]
|
||||
fn vector_empty() {
|
||||
let program = "[]".to_string();
|
||||
let result = parse(&mut scan(program), parse_expr);
|
||||
insta::assert_debug_snapshot!(result);
|
||||
}
|
||||
#[test]
|
||||
fn vector() {
|
||||
let program = "[x, 1, 2 ,3]".to_string();
|
||||
let result = parse(&mut scan(program), parse_expr);
|
||||
insta::assert_debug_snapshot!(result);
|
||||
}
|
||||
#[test]
|
||||
fn assign() {
|
||||
let program = "x = [2, { hello: 7 }];".to_string();
|
||||
let result = parse(&mut scan(program), parse_expr);
|
||||
insta::assert_debug_snapshot!(result);
|
||||
}
|
||||
#[test]
|
||||
fn fn_def() {
|
||||
let program = "fn(a1, boco, c_c) { 108 }".to_string();
|
||||
let result = parse(&mut scan(program), parse_expr);
|
||||
|
|
|
|||
|
|
@ -0,0 +1,42 @@
|
|||
---
|
||||
source: src/parser/parser.rs
|
||||
expression: result
|
||||
---
|
||||
Ok(
|
||||
Op {
|
||||
lhs: Var(
|
||||
Name(
|
||||
"x",
|
||||
),
|
||||
),
|
||||
op: Assign,
|
||||
rhs: Value(
|
||||
Vector(
|
||||
Vector(
|
||||
[
|
||||
Value(
|
||||
Int(
|
||||
2,
|
||||
),
|
||||
),
|
||||
Value(
|
||||
Record(
|
||||
Record(
|
||||
{
|
||||
Label(
|
||||
"hello",
|
||||
): Value(
|
||||
Int(
|
||||
7,
|
||||
),
|
||||
),
|
||||
},
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
},
|
||||
)
|
||||
|
|
@ -0,0 +1,34 @@
|
|||
---
|
||||
source: src/parser/parser.rs
|
||||
expression: result
|
||||
---
|
||||
Ok(
|
||||
Value(
|
||||
Vector(
|
||||
Vector(
|
||||
[
|
||||
Var(
|
||||
Name(
|
||||
"x",
|
||||
),
|
||||
),
|
||||
Value(
|
||||
Int(
|
||||
1,
|
||||
),
|
||||
),
|
||||
Value(
|
||||
Int(
|
||||
2,
|
||||
),
|
||||
),
|
||||
Value(
|
||||
Int(
|
||||
3,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
)
|
||||
|
|
@ -0,0 +1,13 @@
|
|||
---
|
||||
source: src/parser/parser.rs
|
||||
expression: result
|
||||
---
|
||||
Ok(
|
||||
Value(
|
||||
Vector(
|
||||
Vector(
|
||||
[],
|
||||
),
|
||||
),
|
||||
),
|
||||
)
|
||||
Loading…
Add table
Reference in a new issue