Add to_string function; Get fizzbuzz example working

This commit is contained in:
Jeff 2024-08-11 15:12:19 -04:00
parent 28c65b0715
commit 9338d73621
6 changed files with 42 additions and 4 deletions

View File

@ -12,6 +12,9 @@ use crate::{Type, Value};
/// Integrated function that can be called from Dust code.
#[derive(Debug, Clone, Eq, PartialEq, PartialOrd, Ord, Serialize, Deserialize)]
pub enum BuiltInFunction {
// String tools
ToString,
// Integer and float tools
IsEven,
IsOdd,
@ -31,6 +34,7 @@ impl BuiltInFunction {
BuiltInFunction::IsOdd => "is_odd",
BuiltInFunction::Length => "length",
BuiltInFunction::ReadLine => "read_line",
BuiltInFunction::ToString => "to_string",
BuiltInFunction::WriteLine => "write_line",
}
}
@ -41,6 +45,17 @@ impl BuiltInFunction {
value_arguments: Option<Vec<Value>>,
) -> Result<Option<Value>, BuiltInFunctionError> {
match self {
BuiltInFunction::ToString => {
if let Some(value_arguments) = value_arguments {
if value_arguments.len() == 1 {
Ok(Some(Value::string(value_arguments[0].to_string())))
} else {
Err(BuiltInFunctionError::WrongNumberOfValueArguments)
}
} else {
Err(BuiltInFunctionError::WrongNumberOfValueArguments)
}
}
BuiltInFunction::IsEven => {
if let Some(value_arguments) = value_arguments {
if value_arguments.len() == 1 {
@ -115,6 +130,7 @@ impl BuiltInFunction {
pub fn expected_return_type(&self) -> Option<Type> {
match self {
BuiltInFunction::ToString => Some(Type::String),
BuiltInFunction::IsEven => Some(Type::Boolean),
BuiltInFunction::IsOdd => Some(Type::Boolean),
BuiltInFunction::Length => Some(Type::Integer),

View File

@ -404,6 +404,7 @@ impl Lexer {
"is_odd" => Token::IsOdd,
"length" => Token::Length,
"read_line" => Token::ReadLine,
"to_string" => Token::ToString,
"true" => Token::Boolean("true"),
"while" => Token::While,
"write_line" => Token::WriteLine,

View File

@ -476,7 +476,12 @@ impl<'src> Parser<'src> {
}
}
(
Token::IsEven | Token::IsOdd | Token::Length | Token::ReadLine | Token::WriteLine,
Token::IsEven
| Token::IsOdd
| Token::Length
| Token::ReadLine
| Token::ToString
| Token::WriteLine,
left_position,
) => {
let function = match self.current.0 {
@ -484,6 +489,7 @@ impl<'src> Parser<'src> {
Token::IsOdd => BuiltInFunction::IsOdd,
Token::Length => BuiltInFunction::Length,
Token::ReadLine => BuiltInFunction::ReadLine,
Token::ToString => BuiltInFunction::ToString,
Token::WriteLine => BuiltInFunction::WriteLine,
_ => unreachable!(),
};

View File

@ -23,6 +23,7 @@ pub enum Token<'src> {
IsOdd,
Length,
ReadLine,
ToString,
While,
WriteLine,
@ -90,6 +91,7 @@ impl<'src> Token<'src> {
Token::Star => TokenOwned::Star,
Token::Slash => TokenOwned::Slash,
Token::String(text) => TokenOwned::String(text.to_string()),
Token::ToString => TokenOwned::ToString,
Token::While => TokenOwned::While,
Token::WriteLine => TokenOwned::WriteLine,
}
@ -133,6 +135,7 @@ impl<'src> Token<'src> {
Token::Semicolon => ";",
Token::Star => "*",
Token::Slash => "/",
Token::ToString => "to_string",
Token::While => "while",
Token::WriteLine => "write_line",
}
@ -246,6 +249,7 @@ pub enum TokenOwned {
IsOdd,
Length,
ReadLine,
ToString,
While,
WriteLine,
@ -284,14 +288,14 @@ impl Display for TokenOwned {
TokenOwned::DoubleAmpersand => Token::DoubleAmpersand.fmt(f),
TokenOwned::DoubleEqual => Token::DoubleEqual.fmt(f),
TokenOwned::DoublePipe => Token::DoublePipe.fmt(f),
TokenOwned::Else => write!(f, "else"),
TokenOwned::Else => Token::Else.fmt(f),
TokenOwned::Eof => Token::Eof.fmt(f),
TokenOwned::Equal => Token::Equal.fmt(f),
TokenOwned::Float(float) => write!(f, "{float}"),
TokenOwned::Greater => Token::Greater.fmt(f),
TokenOwned::GreaterOrEqual => Token::GreaterEqual.fmt(f),
TokenOwned::Identifier(text) => write!(f, "{text}"),
TokenOwned::If => write!(f, "if"),
TokenOwned::If => Token::If.fmt(f),
TokenOwned::Integer(integer) => write!(f, "{integer}"),
TokenOwned::IsEven => Token::IsEven.fmt(f),
TokenOwned::IsOdd => Token::IsOdd.fmt(f),
@ -313,6 +317,7 @@ impl Display for TokenOwned {
TokenOwned::Star => Token::Star.fmt(f),
TokenOwned::Slash => Token::Slash.fmt(f),
TokenOwned::String(string) => write!(f, "{string}"),
TokenOwned::ToString => Token::ToString.fmt(f),
TokenOwned::While => Token::While.fmt(f),
TokenOwned::WriteLine => Token::WriteLine.fmt(f),
}

View File

@ -660,6 +660,16 @@ impl Display for VmError {
mod tests {
use super::*;
#[test]
fn to_string() {
let input = "42.to_string()";
assert_eq!(
run(input, &mut Context::new()),
Ok(Some(Value::string("42".to_string())))
);
}
#[test]
fn r#if() {
let input = "if true { 1 }";

View File

@ -11,7 +11,7 @@ while count <= 15 {
} else if divides_by_5 {
'buzz'
} else {
count as str
count.to_string()
}
write_line(output)