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 symbol = self.symbol_table.lookup_symbol(item_id).unwrap();
|
||||||
let def_id = symbol.def_id().unwrap();
|
let def_id = symbol.def_id().unwrap();
|
||||||
let function_def = FunctionDefinition {
|
let function_def = FunctionDefinition {
|
||||||
body: self.function(statements)
|
body: self.function_internal_block(statements)
|
||||||
};
|
};
|
||||||
self.functions.insert(def_id, function_def);
|
self.functions.insert(def_id, function_def);
|
||||||
}
|
}
|
||||||
@ -136,7 +136,7 @@ impl<'a> Reducer<'a> {
|
|||||||
Lambda { params, body, .. } => {
|
Lambda { params, body, .. } => {
|
||||||
Expression::Callable(Callable::Lambda {
|
Expression::Callable(Callable::Lambda {
|
||||||
arity: params.len() as u8,
|
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),
|
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 {
|
fn reduce_if_expression(&mut self, discriminator: Option<&ast::Expression>, body: &ast::IfExpressionBody) -> Expression {
|
||||||
Expression::ReductionError("if expr".to_string())
|
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 {
|
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()
|
statements.iter().filter_map(|stmt| self.function_internal_statement(stmt)).collect()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -61,6 +61,11 @@ pub enum Expression {
|
|||||||
f: Box<Expression>,
|
f: Box<Expression>,
|
||||||
args: Vec<Expression>
|
args: Vec<Expression>
|
||||||
},
|
},
|
||||||
|
Conditional {
|
||||||
|
cond: Box<Expression>,
|
||||||
|
then_clause: Vec<Statement>,
|
||||||
|
else_clause: Vec<Statement>,
|
||||||
|
},
|
||||||
ReductionError(String),
|
ReductionError(String),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -262,6 +262,14 @@ impl<'a> State<'a> {
|
|||||||
type_id, tag, items: vec![]
|
type_id, tag, items: vec![]
|
||||||
},
|
},
|
||||||
Expression::Callable(func) => Primitive::Callable(func),
|
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()),
|
Expression::ReductionError(e) => return Err(e.into()),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -75,9 +75,19 @@ let b = Option::Some(10)
|
|||||||
eval_assert(source, "(Some(10), None)");
|
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]
|
#[test]
|
||||||
fn if_is_patterns() {
|
fn if_is_patterns() {
|
||||||
|
/*
|
||||||
let source = r#"
|
let source = r#"
|
||||||
type Option<T> = Some(T) | None
|
type Option<T> = Some(T) | None
|
||||||
let x = Option::Some(9); if x is Option::Some(q) then { q } else { 0 }"#;
|
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
|
type Option<T> = Some(T) | None
|
||||||
let x = Option::None; if x is Option::Some(q) then { q } else { 0 }"#;
|
let x = Option::None; if x is Option::Some(q) then { q } else { 0 }"#;
|
||||||
eval_assert(source, "0");
|
eval_assert(source, "0");
|
||||||
}
|
|
||||||
*/
|
*/
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
Loading…
Reference in New Issue
Block a user