Add to_string function; Get fizzbuzz example working
This commit is contained in:
parent
28c65b0715
commit
9338d73621
@ -12,6 +12,9 @@ use crate::{Type, Value};
|
|||||||
/// Integrated function that can be called from Dust code.
|
/// Integrated function that can be called from Dust code.
|
||||||
#[derive(Debug, Clone, Eq, PartialEq, PartialOrd, Ord, Serialize, Deserialize)]
|
#[derive(Debug, Clone, Eq, PartialEq, PartialOrd, Ord, Serialize, Deserialize)]
|
||||||
pub enum BuiltInFunction {
|
pub enum BuiltInFunction {
|
||||||
|
// String tools
|
||||||
|
ToString,
|
||||||
|
|
||||||
// Integer and float tools
|
// Integer and float tools
|
||||||
IsEven,
|
IsEven,
|
||||||
IsOdd,
|
IsOdd,
|
||||||
@ -31,6 +34,7 @@ impl BuiltInFunction {
|
|||||||
BuiltInFunction::IsOdd => "is_odd",
|
BuiltInFunction::IsOdd => "is_odd",
|
||||||
BuiltInFunction::Length => "length",
|
BuiltInFunction::Length => "length",
|
||||||
BuiltInFunction::ReadLine => "read_line",
|
BuiltInFunction::ReadLine => "read_line",
|
||||||
|
BuiltInFunction::ToString => "to_string",
|
||||||
BuiltInFunction::WriteLine => "write_line",
|
BuiltInFunction::WriteLine => "write_line",
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -41,6 +45,17 @@ impl BuiltInFunction {
|
|||||||
value_arguments: Option<Vec<Value>>,
|
value_arguments: Option<Vec<Value>>,
|
||||||
) -> Result<Option<Value>, BuiltInFunctionError> {
|
) -> Result<Option<Value>, BuiltInFunctionError> {
|
||||||
match self {
|
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 => {
|
BuiltInFunction::IsEven => {
|
||||||
if let Some(value_arguments) = value_arguments {
|
if let Some(value_arguments) = value_arguments {
|
||||||
if value_arguments.len() == 1 {
|
if value_arguments.len() == 1 {
|
||||||
@ -115,6 +130,7 @@ impl BuiltInFunction {
|
|||||||
|
|
||||||
pub fn expected_return_type(&self) -> Option<Type> {
|
pub fn expected_return_type(&self) -> Option<Type> {
|
||||||
match self {
|
match self {
|
||||||
|
BuiltInFunction::ToString => Some(Type::String),
|
||||||
BuiltInFunction::IsEven => Some(Type::Boolean),
|
BuiltInFunction::IsEven => Some(Type::Boolean),
|
||||||
BuiltInFunction::IsOdd => Some(Type::Boolean),
|
BuiltInFunction::IsOdd => Some(Type::Boolean),
|
||||||
BuiltInFunction::Length => Some(Type::Integer),
|
BuiltInFunction::Length => Some(Type::Integer),
|
||||||
|
@ -404,6 +404,7 @@ impl Lexer {
|
|||||||
"is_odd" => Token::IsOdd,
|
"is_odd" => Token::IsOdd,
|
||||||
"length" => Token::Length,
|
"length" => Token::Length,
|
||||||
"read_line" => Token::ReadLine,
|
"read_line" => Token::ReadLine,
|
||||||
|
"to_string" => Token::ToString,
|
||||||
"true" => Token::Boolean("true"),
|
"true" => Token::Boolean("true"),
|
||||||
"while" => Token::While,
|
"while" => Token::While,
|
||||||
"write_line" => Token::WriteLine,
|
"write_line" => Token::WriteLine,
|
||||||
|
@ -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,
|
left_position,
|
||||||
) => {
|
) => {
|
||||||
let function = match self.current.0 {
|
let function = match self.current.0 {
|
||||||
@ -484,6 +489,7 @@ impl<'src> Parser<'src> {
|
|||||||
Token::IsOdd => BuiltInFunction::IsOdd,
|
Token::IsOdd => BuiltInFunction::IsOdd,
|
||||||
Token::Length => BuiltInFunction::Length,
|
Token::Length => BuiltInFunction::Length,
|
||||||
Token::ReadLine => BuiltInFunction::ReadLine,
|
Token::ReadLine => BuiltInFunction::ReadLine,
|
||||||
|
Token::ToString => BuiltInFunction::ToString,
|
||||||
Token::WriteLine => BuiltInFunction::WriteLine,
|
Token::WriteLine => BuiltInFunction::WriteLine,
|
||||||
_ => unreachable!(),
|
_ => unreachable!(),
|
||||||
};
|
};
|
||||||
|
@ -23,6 +23,7 @@ pub enum Token<'src> {
|
|||||||
IsOdd,
|
IsOdd,
|
||||||
Length,
|
Length,
|
||||||
ReadLine,
|
ReadLine,
|
||||||
|
ToString,
|
||||||
While,
|
While,
|
||||||
WriteLine,
|
WriteLine,
|
||||||
|
|
||||||
@ -90,6 +91,7 @@ impl<'src> Token<'src> {
|
|||||||
Token::Star => TokenOwned::Star,
|
Token::Star => TokenOwned::Star,
|
||||||
Token::Slash => TokenOwned::Slash,
|
Token::Slash => TokenOwned::Slash,
|
||||||
Token::String(text) => TokenOwned::String(text.to_string()),
|
Token::String(text) => TokenOwned::String(text.to_string()),
|
||||||
|
Token::ToString => TokenOwned::ToString,
|
||||||
Token::While => TokenOwned::While,
|
Token::While => TokenOwned::While,
|
||||||
Token::WriteLine => TokenOwned::WriteLine,
|
Token::WriteLine => TokenOwned::WriteLine,
|
||||||
}
|
}
|
||||||
@ -133,6 +135,7 @@ impl<'src> Token<'src> {
|
|||||||
Token::Semicolon => ";",
|
Token::Semicolon => ";",
|
||||||
Token::Star => "*",
|
Token::Star => "*",
|
||||||
Token::Slash => "/",
|
Token::Slash => "/",
|
||||||
|
Token::ToString => "to_string",
|
||||||
Token::While => "while",
|
Token::While => "while",
|
||||||
Token::WriteLine => "write_line",
|
Token::WriteLine => "write_line",
|
||||||
}
|
}
|
||||||
@ -246,6 +249,7 @@ pub enum TokenOwned {
|
|||||||
IsOdd,
|
IsOdd,
|
||||||
Length,
|
Length,
|
||||||
ReadLine,
|
ReadLine,
|
||||||
|
ToString,
|
||||||
While,
|
While,
|
||||||
WriteLine,
|
WriteLine,
|
||||||
|
|
||||||
@ -284,14 +288,14 @@ impl Display for TokenOwned {
|
|||||||
TokenOwned::DoubleAmpersand => Token::DoubleAmpersand.fmt(f),
|
TokenOwned::DoubleAmpersand => Token::DoubleAmpersand.fmt(f),
|
||||||
TokenOwned::DoubleEqual => Token::DoubleEqual.fmt(f),
|
TokenOwned::DoubleEqual => Token::DoubleEqual.fmt(f),
|
||||||
TokenOwned::DoublePipe => Token::DoublePipe.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::Eof => Token::Eof.fmt(f),
|
||||||
TokenOwned::Equal => Token::Equal.fmt(f),
|
TokenOwned::Equal => Token::Equal.fmt(f),
|
||||||
TokenOwned::Float(float) => write!(f, "{float}"),
|
TokenOwned::Float(float) => write!(f, "{float}"),
|
||||||
TokenOwned::Greater => Token::Greater.fmt(f),
|
TokenOwned::Greater => Token::Greater.fmt(f),
|
||||||
TokenOwned::GreaterOrEqual => Token::GreaterEqual.fmt(f),
|
TokenOwned::GreaterOrEqual => Token::GreaterEqual.fmt(f),
|
||||||
TokenOwned::Identifier(text) => write!(f, "{text}"),
|
TokenOwned::Identifier(text) => write!(f, "{text}"),
|
||||||
TokenOwned::If => write!(f, "if"),
|
TokenOwned::If => Token::If.fmt(f),
|
||||||
TokenOwned::Integer(integer) => write!(f, "{integer}"),
|
TokenOwned::Integer(integer) => write!(f, "{integer}"),
|
||||||
TokenOwned::IsEven => Token::IsEven.fmt(f),
|
TokenOwned::IsEven => Token::IsEven.fmt(f),
|
||||||
TokenOwned::IsOdd => Token::IsOdd.fmt(f),
|
TokenOwned::IsOdd => Token::IsOdd.fmt(f),
|
||||||
@ -313,6 +317,7 @@ impl Display for TokenOwned {
|
|||||||
TokenOwned::Star => Token::Star.fmt(f),
|
TokenOwned::Star => Token::Star.fmt(f),
|
||||||
TokenOwned::Slash => Token::Slash.fmt(f),
|
TokenOwned::Slash => Token::Slash.fmt(f),
|
||||||
TokenOwned::String(string) => write!(f, "{string}"),
|
TokenOwned::String(string) => write!(f, "{string}"),
|
||||||
|
TokenOwned::ToString => Token::ToString.fmt(f),
|
||||||
TokenOwned::While => Token::While.fmt(f),
|
TokenOwned::While => Token::While.fmt(f),
|
||||||
TokenOwned::WriteLine => Token::WriteLine.fmt(f),
|
TokenOwned::WriteLine => Token::WriteLine.fmt(f),
|
||||||
}
|
}
|
||||||
|
@ -660,6 +660,16 @@ impl Display for VmError {
|
|||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
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]
|
#[test]
|
||||||
fn r#if() {
|
fn r#if() {
|
||||||
let input = "if true { 1 }";
|
let input = "if true { 1 }";
|
||||||
|
@ -11,7 +11,7 @@ while count <= 15 {
|
|||||||
} else if divides_by_5 {
|
} else if divides_by_5 {
|
||||||
'buzz'
|
'buzz'
|
||||||
} else {
|
} else {
|
||||||
count as str
|
count.to_string()
|
||||||
}
|
}
|
||||||
|
|
||||||
write_line(output)
|
write_line(output)
|
||||||
|
Loading…
Reference in New Issue
Block a user