Compare commits
2 Commits
jtran/plus
...
jtran/fix-
Author | SHA1 | Date | |
---|---|---|---|
538f3a322f | |||
ab4ebbe78a |
@ -1086,32 +1086,6 @@ impl Node<MemberExpression> {
|
||||
}
|
||||
}
|
||||
|
||||
fn concat(left: &[KclValue], left_el_ty: &RuntimeType, right: &[KclValue], right_el_ty: &RuntimeType) -> KclValue {
|
||||
if left.is_empty() {
|
||||
return KclValue::HomArray {
|
||||
value: right.to_vec(),
|
||||
ty: right_el_ty.clone(),
|
||||
};
|
||||
}
|
||||
if right.is_empty() {
|
||||
return KclValue::HomArray {
|
||||
value: left.to_vec(),
|
||||
ty: left_el_ty.clone(),
|
||||
};
|
||||
}
|
||||
let mut new = left.to_vec();
|
||||
new.extend_from_slice(right);
|
||||
// Propagate the element type if we can.
|
||||
let ty = if right_el_ty.subtype(left_el_ty) {
|
||||
left_el_ty.clone()
|
||||
} else if left_el_ty.subtype(right_el_ty) {
|
||||
right_el_ty.clone()
|
||||
} else {
|
||||
RuntimeType::any()
|
||||
};
|
||||
KclValue::HomArray { value: new, ty }
|
||||
}
|
||||
|
||||
impl Node<BinaryExpression> {
|
||||
#[async_recursion]
|
||||
pub async fn get_result(&self, exec_state: &mut ExecState, ctx: &ExecutorContext) -> Result<KclValue, KclError> {
|
||||
@ -1130,50 +1104,6 @@ impl Node<BinaryExpression> {
|
||||
meta,
|
||||
});
|
||||
}
|
||||
// Array plus is concatenation.
|
||||
match (&left_value, &right_value) {
|
||||
(
|
||||
KclValue::HomArray {
|
||||
value: left,
|
||||
ty: left_el_ty,
|
||||
..
|
||||
},
|
||||
KclValue::HomArray {
|
||||
value: right,
|
||||
ty: right_el_ty,
|
||||
..
|
||||
},
|
||||
) => {
|
||||
return Ok(concat(left, left_el_ty, right, right_el_ty));
|
||||
}
|
||||
(
|
||||
KclValue::HomArray {
|
||||
value: left,
|
||||
ty: left_el_ty,
|
||||
..
|
||||
},
|
||||
_,
|
||||
) => {
|
||||
// Any single value can be coerced to an array.
|
||||
let right = vec![right_value.clone()];
|
||||
let right_el_ty = RuntimeType::any();
|
||||
return Ok(concat(left, left_el_ty, &right, &right_el_ty));
|
||||
}
|
||||
(
|
||||
_,
|
||||
KclValue::HomArray {
|
||||
value: right,
|
||||
ty: right_el_ty,
|
||||
..
|
||||
},
|
||||
) => {
|
||||
// Any single value can be coerced to an array.
|
||||
let left = vec![left_value.clone()];
|
||||
let left_el_ty = RuntimeType::any();
|
||||
return Ok(concat(&left, &left_el_ty, right, right_el_ty));
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
|
||||
// Then check if we have solids.
|
||||
|
@ -246,7 +246,7 @@ impl RuntimeType {
|
||||
}
|
||||
|
||||
// Subtype with no coercion, including refining numeric types.
|
||||
pub(super) fn subtype(&self, sup: &RuntimeType) -> bool {
|
||||
fn subtype(&self, sup: &RuntimeType) -> bool {
|
||||
use RuntimeType::*;
|
||||
|
||||
match (self, sup) {
|
||||
|
@ -14,7 +14,7 @@ description: Result of parsing add_arrays.kcl
|
||||
"commentStart": 0,
|
||||
"end": 0,
|
||||
"moduleId": 0,
|
||||
"name": "a",
|
||||
"name": "answer",
|
||||
"start": 0,
|
||||
"type": "Identifier"
|
||||
},
|
||||
@ -96,170 +96,6 @@ description: Result of parsing add_arrays.kcl
|
||||
"start": 0,
|
||||
"type": "VariableDeclaration",
|
||||
"type": "VariableDeclaration"
|
||||
},
|
||||
{
|
||||
"commentStart": 0,
|
||||
"declaration": {
|
||||
"commentStart": 0,
|
||||
"end": 0,
|
||||
"id": {
|
||||
"commentStart": 0,
|
||||
"end": 0,
|
||||
"moduleId": 0,
|
||||
"name": "b",
|
||||
"start": 0,
|
||||
"type": "Identifier"
|
||||
},
|
||||
"init": {
|
||||
"commentStart": 0,
|
||||
"end": 0,
|
||||
"left": {
|
||||
"commentStart": 0,
|
||||
"elements": [
|
||||
{
|
||||
"commentStart": 0,
|
||||
"end": 0,
|
||||
"moduleId": 0,
|
||||
"raw": "0",
|
||||
"start": 0,
|
||||
"type": "Literal",
|
||||
"type": "Literal",
|
||||
"value": {
|
||||
"value": 0.0,
|
||||
"suffix": "None"
|
||||
}
|
||||
},
|
||||
{
|
||||
"commentStart": 0,
|
||||
"end": 0,
|
||||
"moduleId": 0,
|
||||
"raw": "1",
|
||||
"start": 0,
|
||||
"type": "Literal",
|
||||
"type": "Literal",
|
||||
"value": {
|
||||
"value": 1.0,
|
||||
"suffix": "None"
|
||||
}
|
||||
}
|
||||
],
|
||||
"end": 0,
|
||||
"moduleId": 0,
|
||||
"start": 0,
|
||||
"type": "ArrayExpression",
|
||||
"type": "ArrayExpression"
|
||||
},
|
||||
"moduleId": 0,
|
||||
"operator": "+",
|
||||
"right": {
|
||||
"commentStart": 0,
|
||||
"end": 0,
|
||||
"moduleId": 0,
|
||||
"raw": "2",
|
||||
"start": 0,
|
||||
"type": "Literal",
|
||||
"type": "Literal",
|
||||
"value": {
|
||||
"value": 2.0,
|
||||
"suffix": "None"
|
||||
}
|
||||
},
|
||||
"start": 0,
|
||||
"type": "BinaryExpression",
|
||||
"type": "BinaryExpression"
|
||||
},
|
||||
"moduleId": 0,
|
||||
"start": 0,
|
||||
"type": "VariableDeclarator"
|
||||
},
|
||||
"end": 0,
|
||||
"kind": "const",
|
||||
"moduleId": 0,
|
||||
"start": 0,
|
||||
"type": "VariableDeclaration",
|
||||
"type": "VariableDeclaration"
|
||||
},
|
||||
{
|
||||
"commentStart": 0,
|
||||
"declaration": {
|
||||
"commentStart": 0,
|
||||
"end": 0,
|
||||
"id": {
|
||||
"commentStart": 0,
|
||||
"end": 0,
|
||||
"moduleId": 0,
|
||||
"name": "c",
|
||||
"start": 0,
|
||||
"type": "Identifier"
|
||||
},
|
||||
"init": {
|
||||
"commentStart": 0,
|
||||
"end": 0,
|
||||
"left": {
|
||||
"commentStart": 0,
|
||||
"end": 0,
|
||||
"moduleId": 0,
|
||||
"raw": "0",
|
||||
"start": 0,
|
||||
"type": "Literal",
|
||||
"type": "Literal",
|
||||
"value": {
|
||||
"value": 0.0,
|
||||
"suffix": "None"
|
||||
}
|
||||
},
|
||||
"moduleId": 0,
|
||||
"operator": "+",
|
||||
"right": {
|
||||
"commentStart": 0,
|
||||
"elements": [
|
||||
{
|
||||
"commentStart": 0,
|
||||
"end": 0,
|
||||
"moduleId": 0,
|
||||
"raw": "1",
|
||||
"start": 0,
|
||||
"type": "Literal",
|
||||
"type": "Literal",
|
||||
"value": {
|
||||
"value": 1.0,
|
||||
"suffix": "None"
|
||||
}
|
||||
},
|
||||
{
|
||||
"commentStart": 0,
|
||||
"end": 0,
|
||||
"moduleId": 0,
|
||||
"raw": "2",
|
||||
"start": 0,
|
||||
"type": "Literal",
|
||||
"type": "Literal",
|
||||
"value": {
|
||||
"value": 2.0,
|
||||
"suffix": "None"
|
||||
}
|
||||
}
|
||||
],
|
||||
"end": 0,
|
||||
"moduleId": 0,
|
||||
"start": 0,
|
||||
"type": "ArrayExpression",
|
||||
"type": "ArrayExpression"
|
||||
},
|
||||
"start": 0,
|
||||
"type": "BinaryExpression",
|
||||
"type": "BinaryExpression"
|
||||
},
|
||||
"moduleId": 0,
|
||||
"start": 0,
|
||||
"type": "VariableDeclarator"
|
||||
},
|
||||
"end": 0,
|
||||
"kind": "const",
|
||||
"moduleId": 0,
|
||||
"start": 0,
|
||||
"type": "VariableDeclaration",
|
||||
"type": "VariableDeclaration"
|
||||
}
|
||||
],
|
||||
"commentStart": 0,
|
||||
|
12
rust/kcl-lib/tests/add_arrays/execution_error.snap
Normal file
12
rust/kcl-lib/tests/add_arrays/execution_error.snap
Normal file
@ -0,0 +1,12 @@
|
||||
---
|
||||
source: kcl-lib/src/simulation_tests.rs
|
||||
description: Error from executing add_arrays.kcl
|
||||
---
|
||||
KCL Semantic error
|
||||
|
||||
× semantic: Expected a number, but found an array of `number`, `number`
|
||||
╭────
|
||||
1 │ answer = [0, 1] + [2]
|
||||
· ───┬──
|
||||
· ╰── tests/add_arrays/input.kcl
|
||||
╰────
|
@ -1,3 +1 @@
|
||||
a = [0, 1] + [2]
|
||||
b = [0, 1] + 2
|
||||
c = 0 + [1, 2]
|
||||
answer = [0, 1] + [2]
|
||||
|
@ -1,138 +0,0 @@
|
||||
---
|
||||
source: kcl-lib/src/simulation_tests.rs
|
||||
description: Variables in memory after executing add_arrays.kcl
|
||||
---
|
||||
{
|
||||
"a": {
|
||||
"type": "HomArray",
|
||||
"value": [
|
||||
{
|
||||
"type": "Number",
|
||||
"value": 0.0,
|
||||
"ty": {
|
||||
"type": "Default",
|
||||
"len": {
|
||||
"type": "Mm"
|
||||
},
|
||||
"angle": {
|
||||
"type": "Degrees"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "Number",
|
||||
"value": 1.0,
|
||||
"ty": {
|
||||
"type": "Default",
|
||||
"len": {
|
||||
"type": "Mm"
|
||||
},
|
||||
"angle": {
|
||||
"type": "Degrees"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "Number",
|
||||
"value": 2.0,
|
||||
"ty": {
|
||||
"type": "Default",
|
||||
"len": {
|
||||
"type": "Mm"
|
||||
},
|
||||
"angle": {
|
||||
"type": "Degrees"
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
"b": {
|
||||
"type": "HomArray",
|
||||
"value": [
|
||||
{
|
||||
"type": "Number",
|
||||
"value": 0.0,
|
||||
"ty": {
|
||||
"type": "Default",
|
||||
"len": {
|
||||
"type": "Mm"
|
||||
},
|
||||
"angle": {
|
||||
"type": "Degrees"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "Number",
|
||||
"value": 1.0,
|
||||
"ty": {
|
||||
"type": "Default",
|
||||
"len": {
|
||||
"type": "Mm"
|
||||
},
|
||||
"angle": {
|
||||
"type": "Degrees"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "Number",
|
||||
"value": 2.0,
|
||||
"ty": {
|
||||
"type": "Default",
|
||||
"len": {
|
||||
"type": "Mm"
|
||||
},
|
||||
"angle": {
|
||||
"type": "Degrees"
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
"c": {
|
||||
"type": "HomArray",
|
||||
"value": [
|
||||
{
|
||||
"type": "Number",
|
||||
"value": 0.0,
|
||||
"ty": {
|
||||
"type": "Default",
|
||||
"len": {
|
||||
"type": "Mm"
|
||||
},
|
||||
"angle": {
|
||||
"type": "Degrees"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "Number",
|
||||
"value": 1.0,
|
||||
"ty": {
|
||||
"type": "Default",
|
||||
"len": {
|
||||
"type": "Mm"
|
||||
},
|
||||
"angle": {
|
||||
"type": "Degrees"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "Number",
|
||||
"value": 2.0,
|
||||
"ty": {
|
||||
"type": "Default",
|
||||
"len": {
|
||||
"type": "Mm"
|
||||
},
|
||||
"angle": {
|
||||
"type": "Degrees"
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
@ -2,6 +2,4 @@
|
||||
source: kcl-lib/src/simulation_tests.rs
|
||||
description: Result of unparsing add_arrays.kcl
|
||||
---
|
||||
a = [0, 1] + [2]
|
||||
b = [0, 1] + 2
|
||||
c = 0 + [1, 2]
|
||||
answer = [0, 1] + [2]
|
||||
|
@ -371,53 +371,53 @@ export function kclErrorsToDiagnostics(
|
||||
sourceCode: string
|
||||
): CodeMirrorDiagnostic[] {
|
||||
let nonFatal: CodeMirrorDiagnostic[] = []
|
||||
const errs = errors
|
||||
?.filter((err) => isTopLevelModule(err.sourceRange))
|
||||
.flatMap((err) => {
|
||||
const diagnostics: CodeMirrorDiagnostic[] = []
|
||||
let message = err.msg
|
||||
if (err.kclBacktrace.length > 0) {
|
||||
// Show the backtrace in the error message.
|
||||
const backtraceLines: Array<string> = []
|
||||
for (let i = 0; i < err.kclBacktrace.length; i++) {
|
||||
const item = err.kclBacktrace[i]
|
||||
if (
|
||||
i > 0 &&
|
||||
isTopLevelModule(item.sourceRange) &&
|
||||
!sourceRangeContains(item.sourceRange, err.sourceRange)
|
||||
) {
|
||||
diagnostics.push({
|
||||
from: toUtf16(item.sourceRange[0], sourceCode),
|
||||
to: toUtf16(item.sourceRange[1], sourceCode),
|
||||
message: 'Part of the error backtrace',
|
||||
severity: 'hint',
|
||||
})
|
||||
}
|
||||
if (i === err.kclBacktrace.length - 1 && !item.fnName) {
|
||||
// The top-level doesn't have a name.
|
||||
break
|
||||
}
|
||||
const name = item.fnName ? `${item.fnName}()` : '(anonymous)'
|
||||
backtraceLines.push(name)
|
||||
const errs = errors.flatMap((err) => {
|
||||
const diagnostics: CodeMirrorDiagnostic[] = []
|
||||
let message = err.msg
|
||||
if (err.kclBacktrace.length > 0) {
|
||||
// Show the backtrace in the error message.
|
||||
const backtraceLines: Array<string> = []
|
||||
for (let i = 0; i < err.kclBacktrace.length; i++) {
|
||||
const item = err.kclBacktrace[i]
|
||||
if (
|
||||
i > 0 &&
|
||||
isTopLevelModule(item.sourceRange) &&
|
||||
!sourceRangeContains(item.sourceRange, err.sourceRange)
|
||||
) {
|
||||
diagnostics.push({
|
||||
from: toUtf16(item.sourceRange[0], sourceCode),
|
||||
to: toUtf16(item.sourceRange[1], sourceCode),
|
||||
message: 'Part of the error backtrace',
|
||||
severity: 'hint',
|
||||
})
|
||||
}
|
||||
// If the backtrace is only one line, it's not helpful to show.
|
||||
if (backtraceLines.length > 1) {
|
||||
message += `\n\nBacktrace:\n${backtraceLines.join('\n')}`
|
||||
if (i === err.kclBacktrace.length - 1 && !item.fnName) {
|
||||
// The top-level doesn't have a name.
|
||||
break
|
||||
}
|
||||
const name = item.fnName ? `${item.fnName}()` : '(anonymous)'
|
||||
backtraceLines.push(name)
|
||||
}
|
||||
if (err.nonFatal.length > 0) {
|
||||
nonFatal = nonFatal.concat(
|
||||
compilationErrorsToDiagnostics(err.nonFatal, sourceCode)
|
||||
)
|
||||
// If the backtrace is only one line, it's not helpful to show.
|
||||
if (backtraceLines.length > 1) {
|
||||
message += `\n\nBacktrace:\n${backtraceLines.join('\n')}`
|
||||
}
|
||||
}
|
||||
if (err.nonFatal.length > 0) {
|
||||
nonFatal = nonFatal.concat(
|
||||
compilationErrorsToDiagnostics(err.nonFatal, sourceCode)
|
||||
)
|
||||
}
|
||||
if (isTopLevelModule(err.sourceRange)) {
|
||||
diagnostics.push({
|
||||
from: toUtf16(err.sourceRange[0], sourceCode),
|
||||
to: toUtf16(err.sourceRange[1], sourceCode),
|
||||
message,
|
||||
severity: 'error',
|
||||
})
|
||||
return diagnostics
|
||||
})
|
||||
}
|
||||
return diagnostics
|
||||
})
|
||||
return errs.concat(nonFatal)
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user