use super::ParseNode;
use crate::ast_node::{ASTContext, Node, TokenSlice};
use crate::operations::Operation;
use crate::tokens::Token;
use crate::types::IJType;
use anyhow::Result;
use std::rc::Rc;
pub struct NumberNode;
impl ParseNode for NumberNode {
fn next_node(
op: Token,
slice: TokenSlice,
context: &mut ASTContext,
) -> Result<(Rc<Node>, TokenSlice)> {
let node_op = match op {
Token::Number(n) => Operation::Number(n),
_ => unreachable!(),
};
match context.get_token_at_index(slice.start) {
Ok(Token::NumberType(n)) => {
let slice = slice.move_start(1)?;
Ok((
Rc::new(Node::new(
node_op,
vec![],
IJType::Number(Some(n.clone())),
vec![],
context,
)?),
slice,
))
}
_ => Ok((
Rc::new(Node::new(
node_op,
vec![],
IJType::Number(None),
vec![],
context,
)?),
slice,
)),
}
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::parser::parse_str_no_context;
use crate::tokens::Number;
#[test]
fn test_number_node() -> Result<()> {
let (node, _) = parse_str_no_context("1.0")?;
assert_eq!(
node.op,
Operation::Number(Number {
value: "1.0".to_string()
})
);
assert_eq!(node.output_type, IJType::Number(None));
let (node, _) = parse_str_no_context("1")?;
assert_eq!(
node.op,
Operation::Number(Number {
value: "1".to_string()
})
);
assert_eq!(node.output_type, IJType::Number(None));
Ok(())
}
#[test]
fn test_number_node_type() -> Result<()> {
let (node, _) = parse_str_no_context("1.0<_>")?;
assert_eq!(
node.op,
Operation::Number(Number {
value: "1.0".to_string()
})
);
assert_eq!(node.output_type, IJType::Number(Some("_".to_string())));
let (node, _) = parse_str_no_context("1.0<f64>")?;
assert_eq!(
node.op,
Operation::Number(Number {
value: "1.0".to_string()
})
);
assert_eq!(node.output_type, IJType::Number(Some("f64".to_string())));
let (node, _) = parse_str_no_context("1<i32>")?;
assert_eq!(
node.op,
Operation::Number(Number {
value: "1".to_string()
})
);
assert_eq!(node.output_type, IJType::Number(Some("i32".to_string())));
Ok(())
}
}