Ast fixes (#650)

* allow using member expressions for memory items

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

* fixes pi in binary expressions

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

* add fix

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

* updates

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-19 16:05:53 -07:00
committed by GitHub
parent c767c1c3a6
commit e34501cc5a
6 changed files with 97 additions and 15 deletions

View File

@ -1820,10 +1820,11 @@ impl MemberExpression {
let value = memory.get(&identifier.name, identifier.into())?;
value.clone()
}
}
.get_json_value()?;
};
if let serde_json::Value::Array(array) = array {
let array_json = array.get_json_value()?;
if let serde_json::Value::Array(array) = array_json {
if let Some(value) = array.get(index) {
Ok(MemoryItem::UserVal(UserVal {
value: value.clone(),
@ -1871,10 +1872,11 @@ impl MemberExpression {
let value = memory.get(&identifier.name, identifier.into())?;
value.clone()
}
}
.get_json_value()?;
};
if let serde_json::Value::Object(map) = object {
let object_json = object.get_json_value()?;
if let serde_json::Value::Object(map) = object_json {
if let Some(value) = map.get(&property_name) {
Ok(MemoryItem::UserVal(UserVal {
value: value.clone(),

View File

@ -159,10 +159,12 @@ impl MemoryItem {
if let MemoryItem::UserVal(user_val) = self {
Ok(user_val.value.clone())
} else {
Err(KclError::Semantic(KclErrorDetails {
message: format!("Not a user value: {:?}", self),
source_ranges: self.clone().into(),
}))
serde_json::to_value(self).map_err(|err| {
KclError::Semantic(KclErrorDetails {
message: format!("Cannot convert memory item to json value: {:?}", err),
source_ranges: self.clone().into(),
})
})
}
}
@ -1177,6 +1179,16 @@ show(thisBox)
);
}
#[tokio::test(flavor = "multi_thread")]
async fn test_math_execute_with_pi() {
let ast = r#"const myVar = pi() * 2"#;
let memory = parse_execute(ast).await.unwrap();
assert_eq!(
serde_json::json!(std::f64::consts::TAU),
memory.root.get("myVar").unwrap().get_json_value().unwrap()
);
}
#[tokio::test(flavor = "multi_thread")]
async fn test_math_define_decimal_without_leading_zero() {
let ast = r#"let thing = .4 + 7"#;

View File

@ -422,9 +422,8 @@ impl ReversePolishNotation {
{
let closing_brace = self.parser.find_closing_brace(1, 0, "")?;
let mut new_stack = stack;
new_stack.push(MathExpression::CallExpression(Box::new(
self.parser.make_call_expression(0)?.expression,
)));
let call_expression = self.parser.make_call_expression(0)?;
new_stack.push(MathExpression::CallExpression(Box::new(call_expression.expression)));
return self.build_tree(&reverse_polish_notation_tokens[closing_brace + 1..], new_stack);
}
if reverse_polish_notation_tokens[1].token_type == TokenType::Period

View File

@ -777,6 +777,7 @@ impl Parser {
});
}
}
if current_token.token_type == TokenType::Word
|| current_token.token_type == TokenType::Number
|| current_token.token_type == TokenType::String
@ -1249,7 +1250,15 @@ impl Parser {
})
})?;
let closing_brace_token = self.get_token(closing_brace_index)?;
let args = self.make_arguments(brace_token.index, vec![])?;
// Account for if we have no args.
let args = if brace_token.index + 1 == closing_brace_index {
ArgumentsReturn {
arguments: vec![],
last_index: closing_brace_index,
}
} else {
self.make_arguments(brace_token.index, vec![])?
};
let function = if let Some(stdlib_fn) = self.stdlib.get(&callee.name) {
crate::ast::types::Function::StdLib { func: stdlib_fn }
} else {
@ -3409,11 +3418,43 @@ thing(false)
);
}
#[test]
fn test_member_expression_sketch_group() {
let some_program_string = r#"fn cube = (pos, scale) => {
const sg = startSketchAt(pos)
|> line([0, scale], %)
|> line([scale, 0], %)
|> line([0, -scale], %)
return sg
}
const b1 = cube([0,0], 10)
const b2 = cube([3,3], 4)
const pt1 = b1[0]
const pt2 = b2[0]
show(b1)
show(b2)"#;
let tokens = crate::tokeniser::lexer(some_program_string);
let parser = crate::parser::Parser::new(tokens);
parser.ast().unwrap();
}
#[test]
fn test_math_with_stdlib() {
let some_program_string = r#"const d2r = pi() / 2
let other_thing = 2 * cos(3)"#;
let tokens = crate::tokeniser::lexer(some_program_string);
let parser = crate::parser::Parser::new(tokens);
parser.ast().unwrap();
}
#[test]
#[ignore] // ignore until more stack fixes
fn test_parse_pipes_on_pipes() {
let code = include_str!("../../tests/executor/inputs/pipes_on_pipes.kcl");
println!("code: {}", code);
let tokens = crate::tokeniser::lexer(code);
let parser = crate::parser::Parser::new(tokens);

View File

@ -173,3 +173,31 @@ async fn serial_test_execute_pipes_on_pipes() {
let result = execute_and_snapshot(code).await.unwrap();
twenty_twenty::assert_image("tests/executor/outputs/pipes_on_pipes.png", &result, 1.0);
}
#[tokio::test(flavor = "multi_thread")]
async fn test_member_expression_sketch_group() {
let code = r#"fn cube = (pos, scale) => {
const sg = startSketchAt(pos)
|> line([0, scale], %)
|> line([scale, 0], %)
|> line([0, -scale], %)
return sg
}
const b1 = cube([0,0], 10)
const b2 = cube([3,3], 4)
const pt1 = b1.value[0]
const pt2 = b2.value[0]
show(b1)
show(b2)"#;
let result = execute_and_snapshot(code).await.unwrap();
twenty_twenty::assert_image(
"tests/executor/outputs/member_expression_sketch_group.png",
&result,
1.0,
);
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 69 KiB