fn
required and can only be used for fn
not var (#483)
* fixups Signed-off-by: Jess Frazelle <github@jessfraz.com> * fix javascript tests Signed-off-by: Jess Frazelle <github@jessfraz.com> * fix clippy Signed-off-by: Jess Frazelle <github@jessfraz.com> --------- Signed-off-by: Jess Frazelle <github@jessfraz.com>
This commit is contained in:
@ -10,7 +10,7 @@ describe('processMemory', () => {
|
|||||||
// Enable rotations #152
|
// Enable rotations #152
|
||||||
const code = `
|
const code = `
|
||||||
const myVar = 5
|
const myVar = 5
|
||||||
const myFn = (a) => {
|
fn myFn = (a) => {
|
||||||
return a - 2
|
return a - 2
|
||||||
}
|
}
|
||||||
const otherVar = myFn(5)
|
const otherVar = myFn(5)
|
||||||
|
@ -176,7 +176,7 @@ show(part001)`
|
|||||||
})
|
})
|
||||||
|
|
||||||
describe('Testing moveValueIntoNewVariable', () => {
|
describe('Testing moveValueIntoNewVariable', () => {
|
||||||
const fn = (fnName: string) => `const ${fnName} = (x) => {
|
const fn = (fnName: string) => `fn ${fnName} = (x) => {
|
||||||
return x
|
return x
|
||||||
}
|
}
|
||||||
`
|
`
|
||||||
|
@ -224,7 +224,7 @@ const key = 'c'
|
|||||||
expect(recasted).toBe(code)
|
expect(recasted).toBe(code)
|
||||||
})
|
})
|
||||||
it('comments in a fn block', () => {
|
it('comments in a fn block', () => {
|
||||||
const code = `const myFn = () => {
|
const code = `fn myFn = () => {
|
||||||
// this is a comment
|
// this is a comment
|
||||||
const yo = { a: { b: { c: '123' } } }
|
const yo = { a: { b: { c: '123' } } }
|
||||||
|
|
||||||
|
@ -2283,7 +2283,7 @@ show(part001)
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_recast_comment_in_a_fn_block() {
|
fn test_recast_comment_in_a_fn_block() {
|
||||||
let some_program_string = r#"const myFn = () => {
|
let some_program_string = r#"fn myFn = () => {
|
||||||
// this is a comment
|
// this is a comment
|
||||||
const yo = { a: { b: { c: '123' } } } /* block
|
const yo = { a: { b: { c: '123' } } } /* block
|
||||||
comment */
|
comment */
|
||||||
@ -2299,7 +2299,7 @@ show(part001)
|
|||||||
let recasted = program.recast(&Default::default(), 0);
|
let recasted = program.recast(&Default::default(), 0);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
recasted,
|
recasted,
|
||||||
r#"const myFn = () => {
|
r#"fn myFn = () => {
|
||||||
// this is a comment
|
// this is a comment
|
||||||
const yo = { a: { b: { c: '123' } } }
|
const yo = { a: { b: { c: '123' } } }
|
||||||
/* block
|
/* block
|
||||||
|
@ -813,16 +813,16 @@ show(part001)"#,
|
|||||||
|
|
||||||
#[tokio::test(flavor = "multi_thread")]
|
#[tokio::test(flavor = "multi_thread")]
|
||||||
async fn test_execute_fn_definitions() {
|
async fn test_execute_fn_definitions() {
|
||||||
let ast = r#"const def = (x) => {
|
let ast = r#"fn def = (x) => {
|
||||||
return x
|
return x
|
||||||
}
|
}
|
||||||
const ghi = (x) => {
|
fn ghi = (x) => {
|
||||||
return x
|
return x
|
||||||
}
|
}
|
||||||
const jkl = (x) => {
|
fn jkl = (x) => {
|
||||||
return x
|
return x
|
||||||
}
|
}
|
||||||
const hmm = (x) => {
|
fn hmm = (x) => {
|
||||||
return x
|
return x
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -990,7 +990,7 @@ show(firstExtrude)"#;
|
|||||||
|
|
||||||
#[tokio::test(flavor = "multi_thread")]
|
#[tokio::test(flavor = "multi_thread")]
|
||||||
async fn test_execute_with_function_sketch() {
|
async fn test_execute_with_function_sketch() {
|
||||||
let ast = r#"const box = (h, l, w) => {
|
let ast = r#"fn box = (h, l, w) => {
|
||||||
const myBox = startSketchAt([0,0])
|
const myBox = startSketchAt([0,0])
|
||||||
|> line([0, l], %)
|
|> line([0, l], %)
|
||||||
|> line([w, 0], %)
|
|> line([w, 0], %)
|
||||||
@ -1010,7 +1010,7 @@ show(fnBox)"#;
|
|||||||
|
|
||||||
#[tokio::test(flavor = "multi_thread")]
|
#[tokio::test(flavor = "multi_thread")]
|
||||||
async fn test_get_member_of_object_with_function_period() {
|
async fn test_get_member_of_object_with_function_period() {
|
||||||
let ast = r#"const box = (obj) => {
|
let ast = r#"fn box = (obj) => {
|
||||||
let myBox = startSketchAt(obj.start)
|
let myBox = startSketchAt(obj.start)
|
||||||
|> line([0, obj.l], %)
|
|> line([0, obj.l], %)
|
||||||
|> line([obj.w, 0], %)
|
|> line([obj.w, 0], %)
|
||||||
@ -1030,7 +1030,7 @@ show(thisBox)
|
|||||||
|
|
||||||
#[tokio::test(flavor = "multi_thread")]
|
#[tokio::test(flavor = "multi_thread")]
|
||||||
async fn test_get_member_of_object_with_function_brace() {
|
async fn test_get_member_of_object_with_function_brace() {
|
||||||
let ast = r#"const box = (obj) => {
|
let ast = r#"fn box = (obj) => {
|
||||||
let myBox = startSketchAt(obj["start"])
|
let myBox = startSketchAt(obj["start"])
|
||||||
|> line([0, obj["l"]], %)
|
|> line([0, obj["l"]], %)
|
||||||
|> line([obj["w"], 0], %)
|
|> line([obj["w"], 0], %)
|
||||||
@ -1050,7 +1050,7 @@ show(thisBox)
|
|||||||
|
|
||||||
#[tokio::test(flavor = "multi_thread")]
|
#[tokio::test(flavor = "multi_thread")]
|
||||||
async fn test_get_member_of_object_with_function_mix_period_brace() {
|
async fn test_get_member_of_object_with_function_mix_period_brace() {
|
||||||
let ast = r#"const box = (obj) => {
|
let ast = r#"fn box = (obj) => {
|
||||||
let myBox = startSketchAt(obj["start"])
|
let myBox = startSketchAt(obj["start"])
|
||||||
|> line([0, obj["l"]], %)
|
|> line([0, obj["l"]], %)
|
||||||
|> line([obj["w"], 0], %)
|
|> line([obj["w"], 0], %)
|
||||||
@ -1071,7 +1071,7 @@ show(thisBox)
|
|||||||
#[tokio::test(flavor = "multi_thread")]
|
#[tokio::test(flavor = "multi_thread")]
|
||||||
#[ignore] // ignore til we get loops
|
#[ignore] // ignore til we get loops
|
||||||
async fn test_execute_with_function_sketch_loop_objects() {
|
async fn test_execute_with_function_sketch_loop_objects() {
|
||||||
let ast = r#"const box = (obj) => {
|
let ast = r#"fn box = (obj) => {
|
||||||
let myBox = startSketchAt(obj.start)
|
let myBox = startSketchAt(obj.start)
|
||||||
|> line([0, obj.l], %)
|
|> line([0, obj.l], %)
|
||||||
|> line([obj.w, 0], %)
|
|> line([obj.w, 0], %)
|
||||||
@ -1093,7 +1093,7 @@ for var in [{start: [0,0], l: 6, w: 10, h: 3}, {start: [-10,-10], l: 3, w: 5, h:
|
|||||||
#[tokio::test(flavor = "multi_thread")]
|
#[tokio::test(flavor = "multi_thread")]
|
||||||
#[ignore] // ignore til we get loops
|
#[ignore] // ignore til we get loops
|
||||||
async fn test_execute_with_function_sketch_loop_array() {
|
async fn test_execute_with_function_sketch_loop_array() {
|
||||||
let ast = r#"const box = (h, l, w, start) => {
|
let ast = r#"fn box = (h, l, w, start) => {
|
||||||
const myBox = startSketchAt([0,0])
|
const myBox = startSketchAt([0,0])
|
||||||
|> line([0, l], %)
|
|> line([0, l], %)
|
||||||
|> line([w, 0], %)
|
|> line([w, 0], %)
|
||||||
@ -1115,7 +1115,7 @@ for var in [[3, 6, 10, [0,0]], [1.5, 3, 5, [-10,-10]]] {
|
|||||||
|
|
||||||
#[tokio::test(flavor = "multi_thread")]
|
#[tokio::test(flavor = "multi_thread")]
|
||||||
async fn test_get_member_of_array_with_function() {
|
async fn test_get_member_of_array_with_function() {
|
||||||
let ast = r#"const box = (array) => {
|
let ast = r#"fn box = (array) => {
|
||||||
let myBox = startSketchAt(array[0])
|
let myBox = startSketchAt(array[0])
|
||||||
|> line([0, array[1]], %)
|
|> line([0, array[1]], %)
|
||||||
|> line([array[2], 0], %)
|
|> line([array[2], 0], %)
|
||||||
|
@ -1339,17 +1339,40 @@ impl Parser {
|
|||||||
fn make_variable_declaration(&self, index: usize) -> Result<VariableDeclarationResult, KclError> {
|
fn make_variable_declaration(&self, index: usize) -> Result<VariableDeclarationResult, KclError> {
|
||||||
let current_token = self.get_token(index)?;
|
let current_token = self.get_token(index)?;
|
||||||
let declaration_start_token = self.next_meaningful_token(index, None)?;
|
let declaration_start_token = self.next_meaningful_token(index, None)?;
|
||||||
let variable_declarators_result = self.make_variable_declarators(declaration_start_token.index, vec![])?;
|
let kind = VariableKind::from_str(¤t_token.value).map_err(|_| {
|
||||||
Ok(VariableDeclarationResult {
|
|
||||||
declaration: VariableDeclaration {
|
|
||||||
start: current_token.start,
|
|
||||||
end: variable_declarators_result.declarations[variable_declarators_result.declarations.len() - 1].end,
|
|
||||||
kind: VariableKind::from_str(¤t_token.value).map_err(|_| {
|
|
||||||
KclError::Syntax(KclErrorDetails {
|
KclError::Syntax(KclErrorDetails {
|
||||||
source_ranges: vec![current_token.into()],
|
source_ranges: vec![current_token.into()],
|
||||||
message: format!("Unexpected token: {}", current_token.value),
|
message: format!("Unexpected token: {}", current_token.value),
|
||||||
})
|
})
|
||||||
})?,
|
})?;
|
||||||
|
let variable_declarators_result = self.make_variable_declarators(declaration_start_token.index, vec![])?;
|
||||||
|
|
||||||
|
// Check if we have a fn variable kind but are not assigning a function.
|
||||||
|
if !variable_declarators_result.declarations.is_empty() {
|
||||||
|
if let Some(declarator) = variable_declarators_result.declarations.get(0) {
|
||||||
|
if let Value::FunctionExpression(_) = declarator.init {
|
||||||
|
if kind != VariableKind::Fn {
|
||||||
|
return Err(KclError::Syntax(KclErrorDetails {
|
||||||
|
source_ranges: vec![current_token.into()],
|
||||||
|
message: format!("Expected a `fn` variable kind, found: `{}`", current_token.value),
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// If we have anything other than a function, make sure we are not using the `fn` variable kind.
|
||||||
|
if kind == VariableKind::Fn {
|
||||||
|
return Err(KclError::Syntax(KclErrorDetails {
|
||||||
|
source_ranges: vec![current_token.into()],
|
||||||
|
message: format!("Expected a `let` variable kind, found: `{}`", current_token.value),
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Ok(VariableDeclarationResult {
|
||||||
|
declaration: VariableDeclaration {
|
||||||
|
start: current_token.start,
|
||||||
|
end: variable_declarators_result.declarations[variable_declarators_result.declarations.len() - 1].end,
|
||||||
|
kind,
|
||||||
declarations: variable_declarators_result.declarations,
|
declarations: variable_declarators_result.declarations,
|
||||||
},
|
},
|
||||||
last_index: variable_declarators_result.last_index,
|
last_index: variable_declarators_result.last_index,
|
||||||
@ -3291,4 +3314,44 @@ thing(false)
|
|||||||
let parser = crate::parser::Parser::new(tokens);
|
let parser = crate::parser::Parser::new(tokens);
|
||||||
parser.ast().unwrap();
|
parser.ast().unwrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_error_define_function_as_var() {
|
||||||
|
for name in ["var", "let", "const"] {
|
||||||
|
let some_program_string = format!(
|
||||||
|
r#"{} thing = (param) => {{
|
||||||
|
return true
|
||||||
|
}}
|
||||||
|
|
||||||
|
thing(false)
|
||||||
|
"#,
|
||||||
|
name
|
||||||
|
);
|
||||||
|
let tokens = crate::tokeniser::lexer(&some_program_string);
|
||||||
|
let parser = crate::parser::Parser::new(tokens);
|
||||||
|
let result = parser.ast();
|
||||||
|
assert!(result.is_err());
|
||||||
|
assert_eq!(
|
||||||
|
result.err().unwrap().to_string(),
|
||||||
|
format!(
|
||||||
|
r#"syntax: KclErrorDetails {{ source_ranges: [SourceRange([0, {}])], message: "Expected a `fn` variable kind, found: `{}`" }}"#,
|
||||||
|
name.len(),
|
||||||
|
name
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_error_define_var_as_function() {
|
||||||
|
let some_program_string = r#"fn thing = "thing""#;
|
||||||
|
let tokens = crate::tokeniser::lexer(some_program_string);
|
||||||
|
let parser = crate::parser::Parser::new(tokens);
|
||||||
|
let result = parser.ast();
|
||||||
|
assert!(result.is_err());
|
||||||
|
assert_eq!(
|
||||||
|
result.err().unwrap().to_string(),
|
||||||
|
r#"syntax: KclErrorDetails { source_ranges: [SourceRange([0, 2])], message: "Expected a `let` variable kind, found: `fn`" }"#
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -61,7 +61,7 @@ async fn execute_and_snapshot(code: &str) -> Result<image::DynamicImage> {
|
|||||||
|
|
||||||
#[tokio::test(flavor = "multi_thread")]
|
#[tokio::test(flavor = "multi_thread")]
|
||||||
async fn test_execute_with_function_sketch() {
|
async fn test_execute_with_function_sketch() {
|
||||||
let code = r#"const box = (h, l, w) => {
|
let code = r#"fn box = (h, l, w) => {
|
||||||
const myBox = startSketchAt([0,0])
|
const myBox = startSketchAt([0,0])
|
||||||
|> line([0, l], %)
|
|> line([0, l], %)
|
||||||
|> line([w, 0], %)
|
|> line([w, 0], %)
|
||||||
|
Reference in New Issue
Block a user