dont set globally that we are not in a pipe (#432)

* dont set globally that we are not in a pipe

Signed-off-by: Jess Frazelle <github@jessfraz.com>

* updates

Signed-off-by: Jess Frazelle <github@jessfraz.com>

* fix 0-l case as well

Signed-off-by: Jess Frazelle <github@jessfraz.com>

* updates

Signed-off-by: Jess Frazelle <github@jessfraz.com>

* cleanup

Signed-off-by: Jess Frazelle <github@jessfraz.com>

* fix unary expression as well, add test

Signed-off-by: Jess Frazelle <github@jessfraz.com>

* fix array expressions in functions

Signed-off-by: Jess Frazelle <github@jessfraz.com>

* more options

Signed-off-by: Jess Frazelle <github@jessfraz.com>

* updates

Signed-off-by: Jess Frazelle <github@jessfraz.com>

* u[dates

Signed-off-by: Jess Frazelle <github@jessfraz.com>

* updates

Signed-off-by: Jess Frazelle <github@jessfraz.com>

* updates

Signed-off-by: Jess Frazelle <github@jessfraz.com>

* add a test

Signed-off-by: Jess Frazelle <github@jessfraz.com>

* updates

Signed-off-by: Jess Frazelle <github@jessfraz.com>

* Revert "updates"

This reverts commit 3cf06388db.

* fix tets

Signed-off-by: Jess Frazelle <github@jessfraz.com>

---------

Signed-off-by: Jess Frazelle <github@jessfraz.com>
This commit is contained in:
Jess Frazelle
2023-09-11 15:15:37 -07:00
committed by GitHub
parent c5cb0e2fd4
commit 3f82522fe9
3 changed files with 235 additions and 18 deletions

View File

@ -179,7 +179,10 @@ describe('Testing moveValueIntoNewVariable', () => {
return x
}
`
const code = `${fn('def')}${fn('ghi')}${fn('jkl')}${fn('hmm')}
const code = `${fn('def')}${fn('jkl')}${fn('hmm')}
fn ghi = (x) => {
return 2
}
const abc = 3
const identifierGuy = 5
const yo = 5 + 6

View File

@ -500,15 +500,22 @@ impl BinaryPart {
pipe_info: &mut PipeInfo,
engine: &mut EngineConnection,
) -> Result<MemoryItem, KclError> {
pipe_info.is_in_pipe = false;
// We DO NOT set this gloablly because if we did and this was called inside a pipe it would
// stop the execution of the pipe.
// THIS IS IMPORTANT.
let mut new_pipe_info = pipe_info.clone();
new_pipe_info.is_in_pipe = false;
match self {
BinaryPart::Literal(literal) => Ok(literal.into()),
BinaryPart::Identifier(identifier) => {
let value = memory.get(&identifier.name, identifier.into())?;
Ok(value.clone())
}
BinaryPart::BinaryExpression(binary_expression) => binary_expression.get_result(memory, pipe_info, engine),
BinaryPart::CallExpression(call_expression) => call_expression.execute(memory, pipe_info, engine),
BinaryPart::BinaryExpression(binary_expression) => {
binary_expression.get_result(memory, &mut new_pipe_info, engine)
}
BinaryPart::CallExpression(call_expression) => call_expression.execute(memory, &mut new_pipe_info, engine),
BinaryPart::UnaryExpression(unary_expression) => {
// Return an error this should not happen.
Err(KclError::Semantic(KclErrorDetails {
@ -718,8 +725,12 @@ impl CallExpression {
binary_expression.get_result(memory, pipe_info, engine)?
}
Value::CallExpression(call_expression) => {
pipe_info.is_in_pipe = false;
call_expression.execute(memory, pipe_info, engine)?
// We DO NOT set this gloablly because if we did and this was called inside a pipe it would
// stop the execution of the pipe.
// THIS IS IMPORTANT.
let mut new_pipe_info = pipe_info.clone();
new_pipe_info.is_in_pipe = false;
call_expression.execute(memory, &mut new_pipe_info, engine)?
}
Value::UnaryExpression(unary_expression) => unary_expression.get_result(memory, pipe_info, engine)?,
Value::ObjectExpression(object_expression) => object_expression.execute(memory, pipe_info, engine)?,
@ -773,7 +784,7 @@ impl CallExpression {
Function::InMemory => {
let mem = memory.clone();
let func = mem.get(&fn_name, self.into())?;
let result = func.call_fn(&fn_args, memory, engine)?.ok_or_else(|| {
let result = func.call_fn(&fn_args, &mem, engine)?.ok_or_else(|| {
KclError::UndefinedValue(KclErrorDetails {
message: format!("Result of function {} is undefined", fn_name),
source_ranges: vec![self.into()],
@ -1199,8 +1210,12 @@ impl ArrayExpression {
binary_expression.get_result(memory, pipe_info, engine)?
}
Value::CallExpression(call_expression) => {
pipe_info.is_in_pipe = false;
call_expression.execute(memory, pipe_info, engine)?
// We DO NOT set this gloablly because if we did and this was called inside a pipe it would
// stop the execution of the pipe.
// THIS IS IMPORTANT.
let mut new_pipe_info = pipe_info.clone();
new_pipe_info.is_in_pipe = false;
call_expression.execute(memory, &mut new_pipe_info, engine)?
}
Value::UnaryExpression(unary_expression) => unary_expression.get_result(memory, pipe_info, engine)?,
Value::ObjectExpression(object_expression) => object_expression.execute(memory, pipe_info, engine)?,
@ -1321,8 +1336,12 @@ impl ObjectExpression {
binary_expression.get_result(memory, pipe_info, engine)?
}
Value::CallExpression(call_expression) => {
pipe_info.is_in_pipe = false;
call_expression.execute(memory, pipe_info, engine)?
// We DO NOT set this gloablly because if we did and this was called inside a pipe it would
// stop the execution of the pipe.
// THIS IS IMPORTANT.
let mut new_pipe_info = pipe_info.clone();
new_pipe_info.is_in_pipe = false;
call_expression.execute(memory, &mut new_pipe_info, engine)?
}
Value::UnaryExpression(unary_expression) => unary_expression.get_result(memory, pipe_info, engine)?,
Value::ObjectExpression(object_expression) => object_expression.execute(memory, pipe_info, engine)?,
@ -1674,10 +1693,20 @@ impl BinaryExpression {
pipe_info: &mut PipeInfo,
engine: &mut EngineConnection,
) -> Result<MemoryItem, KclError> {
pipe_info.is_in_pipe = false;
// We DO NOT set this gloablly because if we did and this was called inside a pipe it would
// stop the execution of the pipe.
// THIS IS IMPORTANT.
let mut new_pipe_info = pipe_info.clone();
new_pipe_info.is_in_pipe = false;
let left_json_value = self.left.get_result(memory, pipe_info, engine)?.get_json_value()?;
let right_json_value = self.right.get_result(memory, pipe_info, engine)?.get_json_value()?;
let left_json_value = self
.left
.get_result(memory, &mut new_pipe_info, engine)?
.get_json_value()?;
let right_json_value = self
.right
.get_result(memory, &mut new_pipe_info, engine)?
.get_json_value()?;
// First check if we are doing string concatenation.
if self.operator == BinaryOperator::Add {
@ -1803,10 +1832,17 @@ impl UnaryExpression {
pipe_info: &mut PipeInfo,
engine: &mut EngineConnection,
) -> Result<MemoryItem, KclError> {
pipe_info.is_in_pipe = false;
// We DO NOT set this gloablly because if we did and this was called inside a pipe it would
// stop the execution of the pipe.
// THIS IS IMPORTANT.
let mut new_pipe_info = pipe_info.clone();
new_pipe_info.is_in_pipe = false;
let num = parse_json_number_as_f64(
&self.argument.get_result(memory, pipe_info, engine)?.get_json_value()?,
&self
.argument
.get_result(memory, &mut new_pipe_info, engine)?
.get_json_value()?,
self.into(),
)?;
Ok(MemoryItem::UserVal {
@ -2457,4 +2493,40 @@ show(mySuperCoolPart)"#
}"#
);
}
#[test]
fn test_recast_negative_var() {
let some_program_string = r#"const w = 20
const l = 8
const h = 10
const firstExtrude = startSketchAt([0,0])
|> line([0, l], %)
|> line([w, 0], %)
|> line([0, -l], %)
|> close(%)
|> extrude(h, %)
show(firstExtrude)"#;
let tokens = crate::tokeniser::lexer(some_program_string);
let parser = crate::parser::Parser::new(tokens);
let program = parser.ast().unwrap();
let recasted = program.recast(&Default::default(), 0);
assert_eq!(
recasted,
r#"const w = 20
const l = 8
const h = 10
const firstExtrude = startSketchAt([0, 0])
|> line([0, l], %)
|> line([w, 0], %)
|> line([0, -l], %)
|> close(%)
|> extrude(h, %)
show(firstExtrude)"#
);
}
}

View File

@ -595,7 +595,9 @@ pub fn execute(
memory.return_ = Some(ProgramReturn::Arguments(call_expr.arguments.clone()));
} else if let Some(func) = memory.clone().root.get(&fn_name) {
func.call_fn(&args, memory, engine)?;
let result = func.call_fn(&args, memory, engine)?;
memory.return_ = result;
} else {
return Err(KclError::Semantic(KclErrorDetails {
message: format!("No such name {} defined", fn_name),
@ -696,11 +698,39 @@ pub fn execute(
let result = bin_expr.get_result(memory, &mut pipe_info, engine)?;
memory.return_ = Some(ProgramReturn::Value(result));
}
Value::UnaryExpression(unary_expr) => {
let result = unary_expr.get_result(memory, &mut pipe_info, engine)?;
memory.return_ = Some(ProgramReturn::Value(result));
}
Value::Identifier(identifier) => {
let value = memory.get(&identifier.name, identifier.into())?.clone();
memory.return_ = Some(ProgramReturn::Value(value));
}
_ => (),
Value::Literal(literal) => {
memory.return_ = Some(ProgramReturn::Value(literal.into()));
}
Value::ArrayExpression(array_expr) => {
let result = array_expr.execute(memory, &mut pipe_info, engine)?;
memory.return_ = Some(ProgramReturn::Value(result));
}
Value::ObjectExpression(obj_expr) => {
let result = obj_expr.execute(memory, &mut pipe_info, engine)?;
memory.return_ = Some(ProgramReturn::Value(result));
}
Value::CallExpression(call_expr) => {
let result = call_expr.execute(memory, &mut pipe_info, engine)?;
memory.return_ = Some(ProgramReturn::Value(result));
}
Value::MemberExpression(member_expr) => {
let result = member_expr.get_result(memory)?;
memory.return_ = Some(ProgramReturn::Value(result));
}
Value::PipeExpression(pipe_expr) => {
let result = pipe_expr.get_result(memory, &mut pipe_info, engine)?;
memory.return_ = Some(ProgramReturn::Value(result));
}
Value::PipeSubstitution(_) => {}
Value::FunctionExpression(_) => {}
},
}
}
@ -856,4 +886,116 @@ show(part001)"#;
parse_execute(ast).await.unwrap();
}
#[tokio::test(flavor = "multi_thread")]
async fn test_execute_with_function_literal_in_pipe() {
let ast = r#"const w = 20
const l = 8
const h = 10
fn thing = () => {
return -8
}
const firstExtrude = startSketchAt([0,0])
|> line([0, l], %)
|> line([w, 0], %)
|> line([0, thing()], %)
|> close(%)
|> extrude(h, %)
show(firstExtrude)"#;
parse_execute(ast).await.unwrap();
}
#[tokio::test(flavor = "multi_thread")]
async fn test_execute_with_function_unary_in_pipe() {
let ast = r#"const w = 20
const l = 8
const h = 10
fn thing = (x) => {
return -x
}
const firstExtrude = startSketchAt([0,0])
|> line([0, l], %)
|> line([w, 0], %)
|> line([0, thing(8)], %)
|> close(%)
|> extrude(h, %)
show(firstExtrude)"#;
parse_execute(ast).await.unwrap();
}
#[tokio::test(flavor = "multi_thread")]
async fn test_execute_with_function_array_in_pipe() {
let ast = r#"const w = 20
const l = 8
const h = 10
fn thing = (x) => {
return [0, -x]
}
const firstExtrude = startSketchAt([0,0])
|> line([0, l], %)
|> line([w, 0], %)
|> line(thing(8), %)
|> close(%)
|> extrude(h, %)
show(firstExtrude)"#;
parse_execute(ast).await.unwrap();
}
#[tokio::test(flavor = "multi_thread")]
async fn test_execute_with_function_call_in_pipe() {
let ast = r#"const w = 20
const l = 8
const h = 10
fn other_thing = (y) => {
return -y
}
fn thing = (x) => {
return other_thing(x)
}
const firstExtrude = startSketchAt([0,0])
|> line([0, l], %)
|> line([w, 0], %)
|> line([0, thing(8)], %)
|> close(%)
|> extrude(h, %)
show(firstExtrude)"#;
parse_execute(ast).await.unwrap();
}
#[tokio::test(flavor = "multi_thread")]
async fn test_execute_with_function_sketch() {
let ast = r#"const box = (h, l, w) => {
const myBox = startSketchAt([0,0])
|> line([0, l], %)
|> line([w, 0], %)
|> line([0, -l], %)
|> close(%)
|> extrude(h, %)
return myBox
}
const fnBox = box(3, 6, 10)
show(fnBox)"#;
parse_execute(ast).await.unwrap();
}
}