diff --git a/core/src/ast.rs b/core/src/ast.rs index 72872922..7bbbd8fd 100644 --- a/core/src/ast.rs +++ b/core/src/ast.rs @@ -544,6 +544,20 @@ fn evaluate_as( } return Err(FendError::ExpectedAString); } + "char" | "character" => { + let a = evaluate(a, scope, attrs, context, int)?; + if let Value::Num(v) = a { + let n = v.try_as_usize(int)?; + let ch = n + .try_into() + .ok() + .and_then(std::char::from_u32) + .ok_or(FendError::InvalidCodepoint(n))?; + + return Ok(Value::String(ch.to_string().into())); + } + return Err(FendError::ExpectedANumber); + } _ => (), } } diff --git a/core/src/error.rs b/core/src/error.rs index 2041279e..95050f46 100644 --- a/core/src/error.rs +++ b/core/src/error.rs @@ -51,6 +51,7 @@ pub(crate) enum FendError { ExpectedACharacter, StringCannotBeLonger, StringCannotBeEmpty, + InvalidCodepoint(usize), ExpectedADigit(char), ExpectedChar(char, char), ExpectedDigitSeparator(char), @@ -160,6 +161,9 @@ impl fmt::Display for FendError { Self::ExpectedARealNumber => write!(f, "expected a real number"), Self::StringCannotBeLonger => write!(f, "string cannot be longer than one codepoint"), Self::StringCannotBeEmpty => write!(f, "string cannot be empty"), + Self::InvalidCodepoint(codepoint) => { + write!(f, "invalid codepoint: U+{codepoint:04x}") + } Self::UnableToGetCurrentDate => write!(f, "unable to get the current date"), Self::NegativeNumbersNotAllowed => write!(f, "negative numbers are not allowed"), Self::ProbabilityDistributionsNotAllowed => {