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