From 6398f0e31e2dd374451e644c2beddc0f428f726a Mon Sep 17 00:00:00 2001 From: Devyn Cairns Date: Thu, 4 Jul 2024 00:48:23 -0700 Subject: [PATCH] literal ValueWithUnit (filesize, duration) --- crates/nu-engine/src/compile/builder.rs | 2 ++ crates/nu-engine/src/compile/expression.rs | 33 +++++++++++++++++-- crates/nu-engine/src/eval_ir.rs | 2 ++ .../nu-protocol/src/errors/compile_error.rs | 7 ++++ crates/nu-protocol/src/ir/display.rs | 2 ++ crates/nu-protocol/src/ir/mod.rs | 2 ++ 6 files changed, 45 insertions(+), 3 deletions(-) diff --git a/crates/nu-engine/src/compile/builder.rs b/crates/nu-engine/src/compile/builder.rs index beff2bba2d..49721094c5 100644 --- a/crates/nu-engine/src/compile/builder.rs +++ b/crates/nu-engine/src/compile/builder.rs @@ -112,6 +112,8 @@ impl BlockBuilder { Literal::Bool(_) | Literal::Int(_) | Literal::Float(_) + | Literal::Filesize(_) + | Literal::Duration(_) | Literal::Binary(_) | Literal::Block(_) | Literal::Closure(_) diff --git a/crates/nu-engine/src/compile/expression.rs b/crates/nu-engine/src/compile/expression.rs index bf62a459d4..4978cb9a15 100644 --- a/crates/nu-engine/src/compile/expression.rs +++ b/crates/nu-engine/src/compile/expression.rs @@ -4,10 +4,10 @@ use super::{ }; use nu_protocol::{ - ast::{CellPath, Expr, Expression, ListItem, RecordItem}, + ast::{CellPath, Expr, Expression, ListItem, RecordItem, ValueWithUnit}, engine::StateWorkingSet, ir::{DataSlice, Instruction, Literal}, - IntoSpanned, RegId, ENV_VARIABLE_ID, + IntoSpanned, RegId, Span, Value, ENV_VARIABLE_ID, }; pub(crate) fn compile_expression( @@ -372,7 +372,9 @@ pub(crate) fn compile_expression( Ok(()) } Expr::Keyword(_) => Err(unexpected("Keyword")), - Expr::ValueWithUnit(_) => Err(todo("ValueWithUnit")), + Expr::ValueWithUnit(value_with_unit) => { + lit(builder, literal_from_value_with_unit(value_with_unit)?) + } Expr::DateTime(_) => Err(todo("DateTime")), Expr::Filepath(path, no_expand) => { let val = builder.data(path)?; @@ -506,3 +508,28 @@ pub(crate) fn compile_expression( Expr::Garbage => Err(CompileError::Garbage { span: expr.span }), } } + +fn literal_from_value_with_unit(value_with_unit: &ValueWithUnit) -> Result { + let Expr::Int(int_value) = value_with_unit.expr.expr else { + return Err(CompileError::UnexpectedExpression { + expr_name: format!("{:?}", value_with_unit.expr), + span: value_with_unit.expr.span, + }); + }; + + match value_with_unit + .unit + .item + .build_value(int_value, Span::unknown()) + .map_err(|err| CompileError::InvalidLiteral { + msg: err.to_string(), + span: value_with_unit.expr.span, + })? { + Value::Filesize { val, .. } => Ok(Literal::Filesize(val)), + Value::Duration { val, .. } => Ok(Literal::Duration(val)), + other => Err(CompileError::InvalidLiteral { + msg: format!("bad value returned by Unit::build_value(): {other:?}"), + span: value_with_unit.unit.span, + }), + } +} diff --git a/crates/nu-engine/src/eval_ir.rs b/crates/nu-engine/src/eval_ir.rs index 932099b560..9bb579c47b 100644 --- a/crates/nu-engine/src/eval_ir.rs +++ b/crates/nu-engine/src/eval_ir.rs @@ -633,6 +633,8 @@ fn literal_value( Literal::Bool(b) => Value::bool(*b, span), Literal::Int(i) => Value::int(*i, span), Literal::Float(f) => Value::float(*f, span), + Literal::Filesize(q) => Value::filesize(*q, span), + Literal::Duration(q) => Value::duration(*q, span), Literal::Binary(bin) => Value::binary(&ctx.data[*bin], span), Literal::Block(block_id) | Literal::RowCondition(block_id) => Value::closure( Closure { diff --git a/crates/nu-protocol/src/errors/compile_error.rs b/crates/nu-protocol/src/errors/compile_error.rs index 9885c92a3a..4810f9f38f 100644 --- a/crates/nu-protocol/src/errors/compile_error.rs +++ b/crates/nu-protocol/src/errors/compile_error.rs @@ -122,6 +122,13 @@ pub enum CompileError { span: Span, }, + #[error("Invalid literal")] + InvalidLiteral { + msg: String, + #[label("{msg}")] + span: Span, + }, + #[error("TODO: {msg}")] #[diagnostic(code(nu::compile::todo), help("IR compilation is a work in progress"))] Todo { diff --git a/crates/nu-protocol/src/ir/display.rs b/crates/nu-protocol/src/ir/display.rs index 8aa7e4ffaf..55b886939b 100644 --- a/crates/nu-protocol/src/ir/display.rs +++ b/crates/nu-protocol/src/ir/display.rs @@ -291,6 +291,8 @@ impl<'a> fmt::Display for FmtLiteral<'a> { Literal::Bool(b) => write!(f, "bool({b:?})"), Literal::Int(i) => write!(f, "int({i:?})"), Literal::Float(fl) => write!(f, "float({fl:?})"), + Literal::Filesize(q) => write!(f, "filesize({q}b)"), + Literal::Duration(q) => write!(f, "duration({q}ns)"), Literal::Binary(b) => write!(f, "binary({})", FmtData(self.data, *b)), Literal::Block(id) => write!(f, "block({id})"), Literal::Closure(id) => write!(f, "closure({id})"), diff --git a/crates/nu-protocol/src/ir/mod.rs b/crates/nu-protocol/src/ir/mod.rs index 0571142e73..ff79eac2f8 100644 --- a/crates/nu-protocol/src/ir/mod.rs +++ b/crates/nu-protocol/src/ir/mod.rs @@ -209,6 +209,8 @@ pub enum Literal { Bool(bool), Int(i64), Float(f64), + Filesize(i64), + Duration(i64), Binary(DataSlice), Block(BlockId), Closure(BlockId),