vector and assign

This commit is contained in:
me 2025-12-16 17:27:12 +02:00
parent 8836f95149
commit 8b544edba5
7 changed files with 166 additions and 20 deletions

View file

@ -25,7 +25,7 @@ pub fn record_expr(rec: Vec<(&str, Expr)>) -> Expr {
} }
pub fn assign(name: &str, expr: Expr) -> Statement { 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 { pub fn stmt_expr(expr: Expr) -> Statement {

View file

@ -5,6 +5,11 @@ use std::collections::BTreeMap;
/// An expression. /// An expression.
#[derive(PartialEq, PartialOrd, Debug, Clone)] #[derive(PartialEq, PartialOrd, Debug, Clone)]
pub enum Expr { pub enum Expr {
Op {
lhs: Box<Expr>,
op: Op,
rhs: Box<Expr>,
},
Value(Value), Value(Value),
Var(Name), Var(Name),
Func(Box<Fn>), Func(Box<Fn>),
@ -32,11 +37,17 @@ pub enum Expr {
*/ */
} }
#[derive(PartialEq, PartialOrd, Debug, Clone)]
pub enum Op {
Assign,
// Equals,
}
/// A statement. /// A statement.
#[derive(PartialEq, PartialOrd, Debug, Clone)] #[derive(PartialEq, PartialOrd, Debug, Clone)]
pub enum Statement { pub enum Statement {
Expr(Expr), Expr(Expr),
Assign(Definition), Let(Definition),
} }
#[derive(PartialEq, PartialOrd, Debug, Clone)] #[derive(PartialEq, PartialOrd, Debug, Clone)]

View file

@ -34,7 +34,7 @@ fn eval_statement(
) -> Result<ast::Value, Error> { ) -> Result<ast::Value, Error> {
match statement { match statement {
ast::Statement::Expr(expr) => eval_expr(expr_env, state, expr), 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)?; let result = eval_expr(expr_env, state, expr)?;
expr_env.insert(name.clone(), result.clone()); expr_env.insert(name.clone(), result.clone());
Ok(result) Ok(result)
@ -115,6 +115,7 @@ fn eval_expr(expr_env: &Env, state: &mut State, expr: &ast::Expr) -> Result<ast:
} }
_ => Ok(v.clone()), _ => Ok(v.clone()),
}, },
ast::Expr::Op { .. } => todo!("Implement bin op"),
} }
} }

View file

@ -18,13 +18,11 @@ fn parse_definitions(tokens: &mut Tokens) -> ParseResult<Vec<ast::Definition>> {
tokens.many(parse_definition) tokens.many(parse_definition)
} }
fn parse_definition(tokens: &mut Tokens) -> ParseResult<ast::Definition> { fn parse_set(tokens: &mut Tokens) -> ParseResult<ast::Expr> {
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(_eq) = tokens.next_if(&Token::Equals) {
if let Some(expr) = parse_expr(tokens)? { if let Some(expr) = parse_expr(tokens)? {
if let Some(_) = tokens.next_if(&Token::Semicolon) { if let Some(_) = tokens.next_if(&Token::Semicolon) {
Ok(Some(ast::Definition { name, expr })) Ok(Some(expr))
} else { } else {
Err(Error::UnexpectedToken { Err(Error::UnexpectedToken {
expected: Token::Semicolon, expected: Token::Semicolon,
@ -37,6 +35,16 @@ fn parse_definition(tokens: &mut Tokens) -> ParseResult<ast::Definition> {
tokens.next(), 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(expr) = parse_set(tokens)? {
Ok(Some(ast::Definition { name, expr }))
} else { } else {
Err(Error::UnexpectedToken { Err(Error::UnexpectedToken {
expected: Token::Equals, expected: Token::Equals,
@ -64,7 +72,13 @@ fn parse_expr(tokens: &mut Tokens) -> ParseResult<ast::Expr> {
args: args, args: args,
})) }))
} else { } 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 { } else {
Ok(None) Ok(None)
@ -79,6 +93,7 @@ fn parse_simple_expr(tokens: &mut Tokens) -> ParseResult<ast::Expr> {
parse_bool, parse_bool,
parse_fn, parse_fn,
parse_record, parse_record,
parse_vector,
|t| t.between(&Token::OpenParen, &Token::CloseParen, parse_expr), |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)> { fn parse_record_field_expr(tokens: &mut Tokens) -> ParseResult<(ast::Label, ast::Expr)> {
if let Some(label) = parse_identifier_label(tokens)? { if let Some(label) = parse_identifier_label(tokens)? {
if let Some(_) = tokens.next_if(&Token::Colon) { if let Some(_) = tokens.next_if(&Token::Colon) {
@ -244,6 +271,24 @@ mod tests {
insta::assert_debug_snapshot!(result); insta::assert_debug_snapshot!(result);
} }
#[test] #[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() { fn fn_def() {
let program = "fn(a1, boco, c_c) { 108 }".to_string(); let program = "fn(a1, boco, c_c) { 108 }".to_string();
let result = parse(&mut scan(program), parse_expr); let result = parse(&mut scan(program), parse_expr);

View file

@ -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,
),
),
},
),
),
),
],
),
),
),
},
)

View file

@ -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,
),
),
],
),
),
),
)

View file

@ -0,0 +1,13 @@
---
source: src/parser/parser.rs
expression: result
---
Ok(
Value(
Vector(
Vector(
[],
),
),
),
)