Continue implementing as expression

This commit is contained in:
Jeff 2024-05-21 19:27:33 -04:00
parent 8ea6b4be81
commit 7b78250eca
4 changed files with 59 additions and 12 deletions

View File

@ -1,12 +1,38 @@
use super::{Expression, Type}; use super::{AbstractNode, Expression, Type, WithPosition};
#[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Ord)]
pub struct As { pub struct As {
expression: Expression, expression: Expression,
r#type: Type, r#type: WithPosition<Type>,
} }
impl As { impl As {
pub fn new(expression: Expression, r#type: Type) -> Self { pub fn new(expression: Expression, r#type: WithPosition<Type>) -> Self {
Self { expression, r#type } Self { expression, r#type }
} }
} }
impl AbstractNode for As {
fn expected_type(
&self,
context: &mut crate::context::Context,
) -> Result<Type, crate::error::ValidationError> {
todo!()
}
fn validate(
&self,
context: &mut crate::context::Context,
manage_memory: bool,
) -> Result<(), crate::error::ValidationError> {
todo!()
}
fn run(
self,
context: &mut crate::context::Context,
manage_memory: bool,
) -> Result<super::Action, crate::error::RuntimeError> {
todo!()
}
}

View File

@ -41,6 +41,7 @@ impl Expression {
impl AbstractNode for Expression { impl AbstractNode for Expression {
fn expected_type(&self, _context: &mut Context) -> Result<Type, ValidationError> { fn expected_type(&self, _context: &mut Context) -> Result<Type, ValidationError> {
match self { match self {
Expression::As(r#as) => r#as.item.expected_type(_context),
Expression::FunctionCall(function_call) => function_call.item.expected_type(_context), Expression::FunctionCall(function_call) => function_call.item.expected_type(_context),
Expression::Identifier(identifier) => { Expression::Identifier(identifier) => {
if let Some(r#type) = _context.get_type(&identifier.item)? { if let Some(r#type) = _context.get_type(&identifier.item)? {
@ -60,12 +61,12 @@ impl AbstractNode for Expression {
Expression::BuiltInFunctionCall(built_in_function_call) => { Expression::BuiltInFunctionCall(built_in_function_call) => {
built_in_function_call.item.expected_type(_context) built_in_function_call.item.expected_type(_context)
} }
Expression::As(_) => todo!(),
} }
} }
fn validate(&self, context: &mut Context, manage_memory: bool) -> Result<(), ValidationError> { fn validate(&self, context: &mut Context, manage_memory: bool) -> Result<(), ValidationError> {
match self { match self {
Expression::As(r#as) => r#as.item.validate(context, manage_memory),
Expression::FunctionCall(function_call) => { Expression::FunctionCall(function_call) => {
function_call.item.validate(context, manage_memory) function_call.item.validate(context, manage_memory)
} }
@ -98,6 +99,7 @@ impl AbstractNode for Expression {
fn run(self, context: &mut Context, manage_memory: bool) -> Result<Action, RuntimeError> { fn run(self, context: &mut Context, manage_memory: bool) -> Result<Action, RuntimeError> {
match self { match self {
Expression::As(r#as) => r#as.item.run(context, manage_memory),
Expression::FunctionCall(function_call) => { Expression::FunctionCall(function_call) => {
function_call.item.run(context, manage_memory) function_call.item.run(context, manage_memory)
} }

View File

@ -258,8 +258,8 @@ pub fn lexer<'src>() -> impl Parser<
let identifier_and_keyword = text::ident().map(|text: &str| match text { let identifier_and_keyword = text::ident().map(|text: &str| match text {
"any" => Token::Keyword(Keyword::Any), "any" => Token::Keyword(Keyword::Any),
"as" => Token::Keyword(Keyword::As),
"async" => Token::Keyword(Keyword::Async), "async" => Token::Keyword(Keyword::Async),
"as" => Token::Keyword(Keyword::As),
"bool" => Token::Keyword(Keyword::Bool), "bool" => Token::Keyword(Keyword::Bool),
"break" => Token::Keyword(Keyword::Break), "break" => Token::Keyword(Keyword::Break),
"else" => Token::Keyword(Keyword::Else), "else" => Token::Keyword(Keyword::Else),

View File

@ -335,12 +335,6 @@ pub fn parser<'src>(
just(Token::Control(Control::DoubleColon)), just(Token::Control(Control::DoubleColon)),
); );
let r#as = expression
.clone()
.then_ignore(just(Token::Keyword(Keyword::As)))
.then(r#type.clone())
.map_with(|(expression, r#type), state| todo!());
let atom = choice(( let atom = choice((
range.clone(), range.clone(),
parsed_function.clone(), parsed_function.clone(),
@ -511,9 +505,20 @@ pub fn parser<'src>(
), ),
)); ));
let r#as = choice((
basic_value.clone(),
identifier_expression.clone(),
logic_math_indexes_and_function_calls.clone(),
))
.then_ignore(just(Token::Keyword(Keyword::As)))
.then(r#type.clone())
.map_with(|(expression, r#type), state| {
Expression::As(Box::new(As::new(expression, r#type)).with_position(state.span()))
});
choice(( choice((
logic_math_indexes_and_function_calls,
r#as, r#as,
logic_math_indexes_and_function_calls,
built_in_function_call, built_in_function_call,
range, range,
structure_instance, structure_instance,
@ -630,6 +635,20 @@ mod tests {
use super::*; use super::*;
#[test]
fn r#as() {
assert_eq!(
parse(&lex("1 as str").unwrap()).unwrap()[0],
Statement::Expression(Expression::As(
Box::new(As::new(
Expression::Value(ValueNode::Integer(1).with_position((0, 1))),
Type::String.with_position((5, 8))
))
.with_position((0, 8))
))
)
}
#[test] #[test]
fn built_in_function() { fn built_in_function() {
let tokens = lex("READ_LINE").unwrap(); let tokens = lex("READ_LINE").unwrap();