Basic conditionals working
This commit is contained in:
parent
856e74cb5e
commit
77cdfc229f
@ -108,7 +108,7 @@ impl<'a> Reducer<'a> {
|
||||
let symbol = self.symbol_table.lookup_symbol(item_id).unwrap();
|
||||
let def_id = symbol.def_id().unwrap();
|
||||
let function_def = FunctionDefinition {
|
||||
body: self.function(statements)
|
||||
body: self.function_internal_block(statements)
|
||||
};
|
||||
self.functions.insert(def_id, function_def);
|
||||
}
|
||||
@ -136,7 +136,7 @@ impl<'a> Reducer<'a> {
|
||||
Lambda { params, body, .. } => {
|
||||
Expression::Callable(Callable::Lambda {
|
||||
arity: params.len() as u8,
|
||||
body: self.function(body),
|
||||
body: self.function_internal_block(body),
|
||||
})
|
||||
},
|
||||
NamedStruct { .. } => Expression::ReductionError("NamedStruct not implemented".to_string()), //self.reduce_named_struct(name, fields),
|
||||
@ -147,8 +147,29 @@ impl<'a> Reducer<'a> {
|
||||
}
|
||||
}
|
||||
|
||||
fn reduce_if_expression(&mut self, _discriminator: Option<&ast::Expression>, _body: &ast::IfExpressionBody) -> Expression {
|
||||
Expression::ReductionError("if expr".to_string())
|
||||
fn reduce_if_expression(&mut self, discriminator: Option<&ast::Expression>, body: &ast::IfExpressionBody) -> Expression {
|
||||
let cond = Box::new(match discriminator {
|
||||
Some(expr) => self.expression(expr),
|
||||
None => return Expression::ReductionError("blank cond if-expr not supported".to_string()),
|
||||
});
|
||||
match body {
|
||||
ast::IfExpressionBody::SimpleConditional {
|
||||
then_case,
|
||||
else_case,
|
||||
} => {
|
||||
let then_clause = self.function_internal_block(then_case);
|
||||
let else_clause = match else_case.as_ref() {
|
||||
None => vec![],
|
||||
Some(stmts) => self.function_internal_block(stmts),
|
||||
};
|
||||
Expression::Conditional {
|
||||
cond,
|
||||
then_clause,
|
||||
else_clause,
|
||||
}
|
||||
},
|
||||
_ => Expression::ReductionError("if expr".to_string())
|
||||
}
|
||||
}
|
||||
|
||||
fn invocation_argument(&mut self, invoc: &ast::InvocationArgument) -> Expression {
|
||||
@ -160,7 +181,7 @@ impl<'a> Reducer<'a> {
|
||||
}
|
||||
}
|
||||
|
||||
fn function(&mut self, statements: &ast::Block) -> Vec<Statement> {
|
||||
fn function_internal_block(&mut self, statements: &ast::Block) -> Vec<Statement> {
|
||||
statements.iter().filter_map(|stmt| self.function_internal_statement(stmt)).collect()
|
||||
}
|
||||
|
||||
|
@ -61,6 +61,11 @@ pub enum Expression {
|
||||
f: Box<Expression>,
|
||||
args: Vec<Expression>
|
||||
},
|
||||
Conditional {
|
||||
cond: Box<Expression>,
|
||||
then_clause: Vec<Statement>,
|
||||
else_clause: Vec<Statement>,
|
||||
},
|
||||
ReductionError(String),
|
||||
}
|
||||
|
||||
|
@ -262,6 +262,14 @@ impl<'a> State<'a> {
|
||||
type_id, tag, items: vec![]
|
||||
},
|
||||
Expression::Callable(func) => Primitive::Callable(func),
|
||||
Expression::Conditional { box cond, then_clause, else_clause } => {
|
||||
let cond = self.expression(cond)?;
|
||||
match cond {
|
||||
Primitive::Literal(Literal::Bool(true)) => self.block(then_clause)?,
|
||||
Primitive::Literal(Literal::Bool(false)) => self.block(else_clause)?,
|
||||
v => return Err(format!("Non-boolean value {:?} in if-statement", v).into())
|
||||
}
|
||||
},
|
||||
Expression::ReductionError(e) => return Err(e.into()),
|
||||
})
|
||||
}
|
||||
|
@ -75,9 +75,19 @@ let b = Option::Some(10)
|
||||
eval_assert(source, "(Some(10), None)");
|
||||
}
|
||||
|
||||
/*
|
||||
#[test]
|
||||
fn basic_if_statement() {
|
||||
let source = r#"
|
||||
let a = 10
|
||||
let b = 10
|
||||
if a == b then { 69 } else { 420 }
|
||||
"#;
|
||||
eval_assert(source, "69");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn if_is_patterns() {
|
||||
/*
|
||||
let source = r#"
|
||||
type Option<T> = Some(T) | None
|
||||
let x = Option::Some(9); if x is Option::Some(q) then { q } else { 0 }"#;
|
||||
@ -88,8 +98,8 @@ let x = Option::Some(9); if x is Option::Some(q) then { q } else { 0 }"#;
|
||||
type Option<T> = Some(T) | None
|
||||
let x = Option::None; if x is Option::Some(q) then { q } else { 0 }"#;
|
||||
eval_assert(source, "0");
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
|
||||
#[test]
|
||||
|
Loading…
Reference in New Issue
Block a user