Skip to content

Commit

Permalink
Merge pull request #300 from mlcui-corp/push-wuqtusywnyvz
Browse files Browse the repository at this point in the history
Resolve fully-uppercase builtin identifiers
  • Loading branch information
printfn authored Jul 10, 2024
2 parents cac1cde + 3cb990d commit 3c29a6d
Show file tree
Hide file tree
Showing 2 changed files with 56 additions and 9 deletions.
54 changes: 45 additions & 9 deletions core/src/ast.rs
Original file line number Diff line number Diff line change
Expand Up @@ -678,6 +678,50 @@ pub(crate) fn resolve_identifier<I: Interrupt>(
attrs: Attrs,
context: &mut crate::Context,
int: &I,
) -> FResult<Value> {
let cloned_scope = scope.clone();
if let Some(ref scope) = cloned_scope {
if let Some(val) = scope.get(ident, attrs, context, int)? {
return Ok(val);
}
}
if let Some(val) = context.variables.get(ident.as_str()) {
return Ok(val.clone());
}

let builtin_result = resolve_builtin_identifier(ident, cloned_scope, attrs, context, int);
if !matches!(builtin_result, Err(FendError::IdentifierNotFound(_))) {
return builtin_result;
}
let unit_result = crate::units::query_unit(ident.as_str(), attrs, context, int);
if !matches!(unit_result, Err(FendError::IdentifierNotFound(_))) {
return unit_result;
}

if !ident
.as_str()
.bytes()
.all(|b| b.is_ascii_digit() || b.is_ascii_uppercase())
{
return unit_result;
}
let lowercase_builtin_result = resolve_builtin_identifier(
&ident.as_str().to_ascii_lowercase().into(),
scope,
attrs,
context,
int,
);
// "Unknown identifier" errors should use the uppercase ident.
lowercase_builtin_result.or(unit_result)
}

fn resolve_builtin_identifier<I: Interrupt>(
ident: &Ident,
scope: Option<Arc<Scope>>,
attrs: Attrs,
context: &mut crate::Context,
int: &I,
) -> FResult<Value> {
macro_rules! eval_box {
($input:expr) => {
Expand All @@ -690,14 +734,6 @@ pub(crate) fn resolve_identifier<I: Interrupt>(
)?)
};
}
if let Some(scope) = scope.clone() {
if let Some(val) = scope.get(ident, attrs, context, int)? {
return Ok(val);
}
}
if let Some(val) = context.variables.get(ident.as_str()) {
return Ok(val.clone());
}
Ok(match ident.as_str() {
"pi" | "\u{3c0}" => Value::Num(Box::new(Number::pi())),
"tau" | "\u{3c4}" => Value::Num(Box::new(Number::pi().mul(2.into(), int)?)),
Expand Down Expand Up @@ -774,7 +810,7 @@ pub(crate) fn resolve_identifier<I: Interrupt>(
"tomorrow" => Value::Date(crate::date::Date::today(context)?.next()),
"yesterday" => Value::Date(crate::date::Date::today(context)?.prev()),
"trans" => Value::String(Cow::Borrowed("🏳️‍⚧️")),
_ => return crate::units::query_unit(ident.as_str(), attrs, context, int),
_ => return Err(FendError::IdentifierNotFound(ident.clone())),
})
}

Expand Down
11 changes: 11 additions & 0 deletions core/tests/integration_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5994,3 +5994,14 @@ fn fibonacci() {
test_eval("fib 10", "55");
test_eval("fib 11", "89");
}

#[test]
fn uppercase_identifiers() {
test_eval("SIN PI", "0");
test_eval("COS TAU", "1");
test_eval("LOG 1", "approx. 0");
test_eval("LOG10 1", "approx. 0");
test_eval("EXP 0", "approx. 1");

expect_error("foo = 1; FOO", Some("unknown identifier 'FOO'"));
}

0 comments on commit 3c29a6d

Please sign in to comment.