diff --git a/examples/parsing/else.an b/examples/parsing/else.an new file mode 100644 index 00000000..29902e88 --- /dev/null +++ b/examples/parsing/else.an @@ -0,0 +1,3 @@ +x = Some 10 + +y = x else 0 diff --git a/src/cache/mod.rs b/src/cache/mod.rs index 01d84529..0292247b 100644 --- a/src/cache/mod.rs +++ b/src/cache/mod.rs @@ -131,6 +131,8 @@ pub struct ModuleCache<'a> { pub error_count: usize, pub file_cache: FileCache, + + pub maybe_type: Option, } pub type FileCache = HashMap; @@ -417,6 +419,7 @@ impl<'a> ModuleCache<'a> { global_dependency_graph: DependencyGraph::default(), diagnostics: Vec::new(), error_count: 0, + maybe_type: None, file_cache, } } diff --git a/src/nameresolution/builtin.rs b/src/nameresolution/builtin.rs index b77ce384..c3c19abc 100644 --- a/src/nameresolution/builtin.rs +++ b/src/nameresolution/builtin.rs @@ -76,6 +76,8 @@ pub fn import_prelude(resolver: &mut NameResolver, cache: &mut ModuleCache<'_>) if let Some(id) = declare_module(&prelude_dir, cache, Location::builtin()) { let exports = define_module(id, cache, Location::builtin()).unwrap(); resolver.current_scope().import(exports, cache, Location::builtin(), &HashSet::new()); + let maybe_id = resolver.current_scope().types.get("Maybe").unwrap().clone(); + cache.maybe_type = Some(maybe_id); } } diff --git a/src/parser/desugar.rs b/src/parser/desugar.rs index ab8d3de8..5cbc8980 100644 --- a/src/parser/desugar.rs +++ b/src/parser/desugar.rs @@ -60,6 +60,7 @@ pub fn desugar_operators<'a>(operator: Token, lhs: Ast<'a>, rhs: Ast<'a>, locati Some(Token::ApplyRight) => prepend_argument_to_function(rhs, lhs, location), Some(Token::And) => Ast::if_expr(lhs, rhs, Some(Ast::bool_literal(false, location)), location), Some(Token::Or) => Ast::if_expr(lhs, Ast::bool_literal(true, location), Some(rhs), location), + Some(Token::Else) => create_else_match(lhs, rhs, location), Some(operator_token) => { let operator = Ast::operator(operator_token, location); Ast::function_call(operator, vec![lhs, rhs], location) @@ -72,6 +73,14 @@ pub fn desugar_operators<'a>(operator: Token, lhs: Ast<'a>, rhs: Ast<'a>, locati desugar_explicit_currying(operator_symbol, vec![lhs, rhs], call_operator_function, location) } +fn create_else_match<'a>(lhs: Ast<'a>, rhs: Ast<'a>, location: Location<'a>) -> Ast<'a> { + let x = Ast::variable(vec![], "x".to_owned(), location); + let some = Ast::type_constructor(vec!["prelude".to_owned()], "Some".to_owned(), location); + let some_x = Ast::function_call(some, vec![x.clone()], location); + let none = Ast::type_constructor(vec!["prelude".to_owned()], "None".to_owned(), location); + Ast::match_expr(lhs, vec![(some_x, x), (none, rhs)], location) +} + fn prepend_argument_to_function<'a>(f: Ast<'a>, arg: Ast<'a>, location: Location<'a>) -> Ast<'a> { match f { Ast::FunctionCall(mut call) => { diff --git a/src/parser/mod.rs b/src/parser/mod.rs index 3fd28112..1431cd0f 100644 --- a/src/parser/mod.rs +++ b/src/parser/mod.rs @@ -380,8 +380,9 @@ fn precedence(token: &Token) -> Option<(i8, bool)> { Token::In => Some((8, false)), Token::Append => Some((9, false)), Token::Range => Some((10, false)), - Token::Add | Token::Subtract => Some((11, false)), - Token::Multiply | Token::Divide | Token::Modulus => Some((12, false)), + Token::Else => Some((11, false)), + Token::Add | Token::Subtract => Some((12, false)), + Token::Multiply | Token::Divide | Token::Modulus => Some((13, false)), Token::Index => Some((14, false)), Token::As => Some((15, false)), _ => None,