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:
@ -179,7 +179,10 @@ describe('Testing moveValueIntoNewVariable', () => {
|
|||||||
return x
|
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 abc = 3
|
||||||
const identifierGuy = 5
|
const identifierGuy = 5
|
||||||
const yo = 5 + 6
|
const yo = 5 + 6
|
||||||
|
@ -500,15 +500,22 @@ impl BinaryPart {
|
|||||||
pipe_info: &mut PipeInfo,
|
pipe_info: &mut PipeInfo,
|
||||||
engine: &mut EngineConnection,
|
engine: &mut EngineConnection,
|
||||||
) -> Result<MemoryItem, KclError> {
|
) -> 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 {
|
match self {
|
||||||
BinaryPart::Literal(literal) => Ok(literal.into()),
|
BinaryPart::Literal(literal) => Ok(literal.into()),
|
||||||
BinaryPart::Identifier(identifier) => {
|
BinaryPart::Identifier(identifier) => {
|
||||||
let value = memory.get(&identifier.name, identifier.into())?;
|
let value = memory.get(&identifier.name, identifier.into())?;
|
||||||
Ok(value.clone())
|
Ok(value.clone())
|
||||||
}
|
}
|
||||||
BinaryPart::BinaryExpression(binary_expression) => binary_expression.get_result(memory, pipe_info, engine),
|
BinaryPart::BinaryExpression(binary_expression) => {
|
||||||
BinaryPart::CallExpression(call_expression) => call_expression.execute(memory, pipe_info, engine),
|
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) => {
|
BinaryPart::UnaryExpression(unary_expression) => {
|
||||||
// Return an error this should not happen.
|
// Return an error this should not happen.
|
||||||
Err(KclError::Semantic(KclErrorDetails {
|
Err(KclError::Semantic(KclErrorDetails {
|
||||||
@ -718,8 +725,12 @@ impl CallExpression {
|
|||||||
binary_expression.get_result(memory, pipe_info, engine)?
|
binary_expression.get_result(memory, pipe_info, engine)?
|
||||||
}
|
}
|
||||||
Value::CallExpression(call_expression) => {
|
Value::CallExpression(call_expression) => {
|
||||||
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
|
||||||
call_expression.execute(memory, pipe_info, engine)?
|
// 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::UnaryExpression(unary_expression) => unary_expression.get_result(memory, pipe_info, engine)?,
|
||||||
Value::ObjectExpression(object_expression) => object_expression.execute(memory, pipe_info, engine)?,
|
Value::ObjectExpression(object_expression) => object_expression.execute(memory, pipe_info, engine)?,
|
||||||
@ -773,7 +784,7 @@ impl CallExpression {
|
|||||||
Function::InMemory => {
|
Function::InMemory => {
|
||||||
let mem = memory.clone();
|
let mem = memory.clone();
|
||||||
let func = mem.get(&fn_name, self.into())?;
|
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 {
|
KclError::UndefinedValue(KclErrorDetails {
|
||||||
message: format!("Result of function {} is undefined", fn_name),
|
message: format!("Result of function {} is undefined", fn_name),
|
||||||
source_ranges: vec![self.into()],
|
source_ranges: vec![self.into()],
|
||||||
@ -1199,8 +1210,12 @@ impl ArrayExpression {
|
|||||||
binary_expression.get_result(memory, pipe_info, engine)?
|
binary_expression.get_result(memory, pipe_info, engine)?
|
||||||
}
|
}
|
||||||
Value::CallExpression(call_expression) => {
|
Value::CallExpression(call_expression) => {
|
||||||
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
|
||||||
call_expression.execute(memory, pipe_info, engine)?
|
// 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::UnaryExpression(unary_expression) => unary_expression.get_result(memory, pipe_info, engine)?,
|
||||||
Value::ObjectExpression(object_expression) => object_expression.execute(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)?
|
binary_expression.get_result(memory, pipe_info, engine)?
|
||||||
}
|
}
|
||||||
Value::CallExpression(call_expression) => {
|
Value::CallExpression(call_expression) => {
|
||||||
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
|
||||||
call_expression.execute(memory, pipe_info, engine)?
|
// 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::UnaryExpression(unary_expression) => unary_expression.get_result(memory, pipe_info, engine)?,
|
||||||
Value::ObjectExpression(object_expression) => object_expression.execute(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,
|
pipe_info: &mut PipeInfo,
|
||||||
engine: &mut EngineConnection,
|
engine: &mut EngineConnection,
|
||||||
) -> Result<MemoryItem, KclError> {
|
) -> 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 left_json_value = self
|
||||||
let right_json_value = self.right.get_result(memory, pipe_info, engine)?.get_json_value()?;
|
.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.
|
// First check if we are doing string concatenation.
|
||||||
if self.operator == BinaryOperator::Add {
|
if self.operator == BinaryOperator::Add {
|
||||||
@ -1803,10 +1832,17 @@ impl UnaryExpression {
|
|||||||
pipe_info: &mut PipeInfo,
|
pipe_info: &mut PipeInfo,
|
||||||
engine: &mut EngineConnection,
|
engine: &mut EngineConnection,
|
||||||
) -> Result<MemoryItem, KclError> {
|
) -> 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(
|
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(),
|
self.into(),
|
||||||
)?;
|
)?;
|
||||||
Ok(MemoryItem::UserVal {
|
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)"#
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -595,7 +595,9 @@ pub fn execute(
|
|||||||
|
|
||||||
memory.return_ = Some(ProgramReturn::Arguments(call_expr.arguments.clone()));
|
memory.return_ = Some(ProgramReturn::Arguments(call_expr.arguments.clone()));
|
||||||
} else if let Some(func) = memory.clone().root.get(&fn_name) {
|
} 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 {
|
} else {
|
||||||
return Err(KclError::Semantic(KclErrorDetails {
|
return Err(KclError::Semantic(KclErrorDetails {
|
||||||
message: format!("No such name {} defined", fn_name),
|
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)?;
|
let result = bin_expr.get_result(memory, &mut pipe_info, engine)?;
|
||||||
memory.return_ = Some(ProgramReturn::Value(result));
|
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) => {
|
Value::Identifier(identifier) => {
|
||||||
let value = memory.get(&identifier.name, identifier.into())?.clone();
|
let value = memory.get(&identifier.name, identifier.into())?.clone();
|
||||||
memory.return_ = Some(ProgramReturn::Value(value));
|
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();
|
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();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user