diff --git a/src/protocol/parser/pass_definitions.rs b/src/protocol/parser/pass_definitions.rs index f9f4826427962b1e0e90dbe34b7a94ea5c089dc0..e6d6204d97a66a4f9a0493382f8c15fd4887cf04 100644 --- a/src/protocol/parser/pass_definitions.rs +++ b/src/protocol/parser/pass_definitions.rs @@ -704,7 +704,7 @@ impl PassDefinitions { let poly_vars = ctx.heap[definition_id].poly_vars(); consume_parser_type( &module.source, iter, &ctx.symbols, &ctx.heap, - &poly_vars, SymbolScope::Module(module.root_id), definition_id, + poly_vars, SymbolScope::Module(module.root_id), definition_id, true, 1 )? } else { @@ -1451,13 +1451,45 @@ impl PassDefinitions { _ => unreachable!(), }; - ctx.heap.alloc_literal_expression(|this| LiteralExpression{ + ctx.heap.alloc_literal_expression(|this| LiteralExpression { this, span: ident_span, value, parent: ExpressionParent::None, unique_id_in_definition: -1, }).upcast() + } else if ident_text == KW_CAST { + // Casting expression + iter.consume(); + let to_type = if Some(TokenKind::OpenAngle) == iter.next() { + iter.consume(); + let definition_id = self.cur_definition; + let poly_vars = ctx.heap[definition_id].poly_vars(); + consume_parser_type( + &module.source, iter, &ctx.symbols, &ctx.heap, + poly_vars, SymbolScope::Module(module.root_id), definition_id, + true, 1 + )? + } else { + // Automatic casting with inferred target type + ParserType{ elements: vec![ParserTypeElement{ + full_span: ident_span, // TODO: @Span fix + variant: ParserTypeVariant::Inferred, + }]} + }; + + consume_token(&module.source, iter, TokenKind::OpenParen)?; + let subject = self.consume_expression(module, iter, ctx)?; + consume_token(&module.source, iter, TokenKind::CloseParen)?; + + ctx.heap.alloc_cast_expression(|this| CastExpression{ + this, + span: ident_span, + to_type, + subject, + parent: ExpressionParent::None, + unique_id_in_definition: -1, + }).upcast() } else { // Not a builtin literal, but also not a known type. So we // assume it is a variable expression. Although if we do,