AST: Allow KCL fn params to have defaults and labels (#4676)

Pure refactor, should not change any behaviour.

Previously, optional parameters in KCL function calls always set the parameter to KclNone. 

As of this PR, they can be set to KCL literals in addition to KCL none. However the parser does not actually ever use this (that'll be in a follow-up PR).

Also adds a `labeled: bool` to all parameters, which is always true. But it lays the groundwork for the unlabeled first parameter in a follow-up PR.
This commit is contained in:
Adam Chalmers
2024-12-05 21:04:40 -06:00
committed by GitHub
parent eb96d6539c
commit 9e57034873
35 changed files with 240 additions and 200 deletions

View File

@ -25,9 +25,7 @@ use crate::{
engine::{EngineManager, ExecutionKind},
errors::{KclError, KclErrorDetails},
fs::{FileManager, FileSystem},
parsing::ast::types::{
BodyItem, Expr, FunctionExpression, ItemVisibility, KclNone, Node, NodeRef, TagDeclarator, TagNode,
},
parsing::ast::types::{BodyItem, Expr, FunctionExpression, ItemVisibility, Node, NodeRef, TagDeclarator, TagNode},
settings::types::UnitLength,
source_range::{ModuleId, SourceRange},
std::{args::Arg, StdLib},
@ -2172,18 +2170,12 @@ fn assign_args_to_params(
fn_memory.add(&param.identifier.name, arg.value.clone(), (&param.identifier).into())?;
} else {
// Argument was not provided.
if param.optional {
if let Some(ref default_val) = param.default_value {
// If the corresponding parameter is optional,
// then it's fine, the user doesn't need to supply it.
let none = Node {
inner: KclNone::new(),
start: param.identifier.start,
end: param.identifier.end,
module_id: param.identifier.module_id,
};
fn_memory.add(
&param.identifier.name,
KclValue::from(&none),
default_val.clone().into(),
(&param.identifier).into(),
)?;
} else {
@ -2238,7 +2230,7 @@ mod tests {
use pretty_assertions::assert_eq;
use super::*;
use crate::parsing::ast::types::{Identifier, Node, Parameter};
use crate::parsing::ast::types::{DefaultParamVal, Identifier, Node, Parameter};
pub async fn parse_execute(code: &str) -> Result<ProgramMemory> {
let program = Program::parse_no_errs(code)?;
@ -2998,7 +2990,8 @@ let w = f() + f()
Parameter {
identifier: ident(s),
type_: None,
optional: true,
default_value: Some(DefaultParamVal::none()),
labeled: true,
digest: None,
}
}
@ -3006,7 +2999,8 @@ let w = f() + f()
Parameter {
identifier: ident(s),
type_: None,
optional: false,
default_value: None,
labeled: true,
digest: None,
}
}
@ -3041,10 +3035,7 @@ let w = f() + f()
"all params optional, none given, should be OK",
vec![opt_param("x")],
vec![],
Ok(additional_program_memory(&[(
"x".to_owned(),
KclValue::from(&KclNone::default()),
)])),
Ok(additional_program_memory(&[("x".to_owned(), KclValue::none())])),
),
(
"mixed params, too few given",
@ -3061,7 +3052,7 @@ let w = f() + f()
vec![mem(1)],
Ok(additional_program_memory(&[
("x".to_owned(), mem(1)),
("y".to_owned(), KclValue::from(&KclNone::default())),
("y".to_owned(), KclValue::none()),
])),
),
(

View File

@ -8,7 +8,7 @@ use crate::{
errors::KclErrorDetails,
exec::{ProgramMemory, Sketch},
executor::{Face, ImportedGeometry, MemoryFunction, Metadata, Plane, SketchSet, Solid, SolidSet, TagIdentifier},
parsing::ast::types::{FunctionExpression, KclNone, TagDeclarator, TagNode},
parsing::ast::types::{FunctionExpression, KclNone, LiteralValue, TagDeclarator, TagNode},
std::{args::Arg, FnAsArg},
ExecState, ExecutorContext, KclError, SourceRange,
};
@ -221,6 +221,14 @@ impl KclValue {
}
}
#[allow(unused)]
pub(crate) fn none() -> Self {
Self::KclNone {
value: Default::default(),
meta: Default::default(),
}
}
/// Human readable type name used in error messages. Should not be relied
/// on for program logic.
pub(crate) fn human_friendly_type(&self) -> &'static str {
@ -246,6 +254,14 @@ impl KclValue {
}
}
pub(crate) fn from_literal(literal: LiteralValue, meta: Vec<Metadata>) -> Self {
match literal {
LiteralValue::Number(value) => KclValue::Number { value, meta },
LiteralValue::String(value) => KclValue::String { value, meta },
LiteralValue::Bool(value) => KclValue::Bool { value, meta },
}
}
pub(crate) fn is_function(&self) -> bool {
matches!(self, KclValue::Function { .. })
}

View File

@ -1,6 +1,6 @@
use sha2::{Digest as DigestTrait, Sha256};
use super::types::{ItemVisibility, VariableKind};
use super::types::{DefaultParamVal, ItemVisibility, VariableKind};
use crate::parsing::ast::types::{
ArrayExpression, ArrayRangeExpression, BinaryExpression, BinaryPart, BodyItem, CallExpression, CallExpressionKw,
CommentStyle, ElseIf, Expr, ExpressionStatement, FnArgType, FunctionExpression, Identifier, IfExpression,
@ -169,6 +169,7 @@ impl FnArgType {
hasher.finalize().into()
}
}
impl Parameter {
compute_digest!(|slf, hasher| {
hasher.update(slf.identifier.compute_digest());
@ -181,7 +182,11 @@ impl Parameter {
hasher.update(b"Parameter::type_::None");
}
}
hasher.update(if slf.optional { [1] } else { [0] })
match slf.default_value {
None => hasher.update(vec![0]),
Some(DefaultParamVal::KclNone(ref _kcl_none)) => hasher.update(vec![1]),
Some(DefaultParamVal::Literal(ref mut literal)) => hasher.update(literal.compute_digest()),
}
});
}

View File

@ -2707,7 +2707,7 @@ impl FnArgPrimitive {
}
}
#[derive(Debug, Clone, Deserialize, Serialize, PartialEq, Eq, JsonSchema)]
#[derive(Debug, Clone, Deserialize, Serialize, PartialEq, JsonSchema)]
#[serde(tag = "type")]
pub enum FnArgType {
/// A primitive type.
@ -2720,8 +2720,38 @@ pub enum FnArgType {
},
}
/// Default value for a parameter of a KCL function.
#[derive(Debug, Clone, Deserialize, Serialize, PartialEq, ts_rs::TS, JsonSchema)]
#[ts(export)]
#[serde(tag = "type")]
#[allow(clippy::large_enum_variant)]
pub enum DefaultParamVal {
KclNone(KclNone),
Literal(Literal),
}
// TODO: This should actually take metadata.
impl From<DefaultParamVal> for KclValue {
fn from(v: DefaultParamVal) -> Self {
match v {
DefaultParamVal::KclNone(kcl_none) => Self::KclNone {
value: kcl_none,
meta: Default::default(),
},
DefaultParamVal::Literal(literal) => Self::from_literal(literal.value, Vec::new()),
}
}
}
impl DefaultParamVal {
/// KCL none.
pub(crate) fn none() -> Self {
Self::KclNone(KclNone::default())
}
}
/// Parameter of a KCL function.
#[derive(Debug, Clone, Deserialize, Serialize, PartialEq, Eq, ts_rs::TS, JsonSchema)]
#[derive(Debug, Clone, Deserialize, Serialize, PartialEq, ts_rs::TS, JsonSchema)]
#[ts(export)]
#[serde(tag = "type")]
pub struct Parameter {
@ -2732,13 +2762,35 @@ pub struct Parameter {
#[serde(skip)]
pub type_: Option<FnArgType>,
/// Is the parameter optional?
pub optional: bool,
/// If so, what is its default value?
/// If this is None, then the parameter is required.
/// Defaults to None.
#[serde(default, skip_serializing_if = "Option::is_none")]
pub default_value: Option<DefaultParamVal>,
/// Functions may declare at most one parameter without label, prefixed by '@', and it must be the first parameter.
#[serde(default = "return_true", skip_serializing_if = "is_true")]
pub labeled: bool,
#[serde(default, skip_serializing_if = "Option::is_none")]
#[ts(optional)]
pub digest: Option<Digest>,
}
impl Parameter {
/// Is the parameter optional?
pub fn optional(&self) -> bool {
self.default_value.is_some()
}
}
fn is_true(b: &bool) -> bool {
*b
}
fn return_true() -> bool {
true
}
#[derive(Debug, Clone, Deserialize, Serialize, PartialEq, ts_rs::TS, JsonSchema)]
#[ts(export)]
#[serde(tag = "type")]
@ -2783,13 +2835,13 @@ impl FunctionExpression {
} = self;
let mut found_optional = false;
for param in params {
if param.optional {
if param.optional() {
found_optional = true;
} else if found_optional {
return Err(RequiredParamAfterOptionalParam(Box::new(param.clone())));
}
}
let boundary = self.params.partition_point(|param| !param.optional);
let boundary = self.params.partition_point(|param| !param.optional());
// SAFETY: split_at panics if the boundary is greater than the length.
Ok(self.params.split_at(boundary))
}
@ -2800,7 +2852,7 @@ impl FunctionExpression {
let end_of_required_params = self
.params
.iter()
.position(|param| param.optional)
.position(|param| param.optional())
// If there's no optional params, then all the params are required params.
.unwrap_or(self.params.len());
&self.params[..end_of_required_params]
@ -3257,8 +3309,9 @@ const cylinder = startSketchOn('-XZ')
module_id,
),
type_: Some(FnArgType::Primitive(FnArgPrimitive::Number)),
optional: false,
digest: None
default_value: None,
labeled: true,
digest: None,
},
Parameter {
identifier: Node::new(
@ -3271,7 +3324,8 @@ const cylinder = startSketchOn('-XZ')
module_id,
),
type_: Some(FnArgType::Array(FnArgPrimitive::String)),
optional: false,
default_value: None,
labeled: true,
digest: None
},
Parameter {
@ -3285,7 +3339,8 @@ const cylinder = startSketchOn('-XZ')
module_id,
),
type_: Some(FnArgType::Primitive(FnArgPrimitive::String)),
optional: true,
labeled: true,
default_value: Some(DefaultParamVal::none()),
digest: None
}
]
@ -3327,7 +3382,8 @@ const cylinder = startSketchOn('-XZ')
module_id,
),
type_: Some(FnArgType::Primitive(FnArgPrimitive::Number)),
optional: false,
default_value: None,
labeled: true,
digest: None
},
Parameter {
@ -3341,7 +3397,8 @@ const cylinder = startSketchOn('-XZ')
module_id,
),
type_: Some(FnArgType::Array(FnArgPrimitive::String)),
optional: false,
default_value: None,
labeled: true,
digest: None
},
Parameter {
@ -3355,7 +3412,8 @@ const cylinder = startSketchOn('-XZ')
module_id,
),
type_: Some(FnArgType::Primitive(FnArgPrimitive::String)),
optional: true,
labeled: true,
default_value: Some(DefaultParamVal::none()),
digest: None
}
]
@ -3391,7 +3449,8 @@ const cylinder = startSketchOn('-XZ')
digest: None,
}),
type_: None,
optional: false,
default_value: None,
labeled: true,
digest: None,
}],
body: Node {
@ -3419,7 +3478,8 @@ const cylinder = startSketchOn('-XZ')
digest: None,
}),
type_: None,
optional: true,
default_value: Some(DefaultParamVal::none()),
labeled: true,
digest: None,
}],
body: Node {
@ -3448,7 +3508,8 @@ const cylinder = startSketchOn('-XZ')
digest: None,
}),
type_: None,
optional: false,
default_value: None,
labeled: true,
digest: None,
},
Parameter {
@ -3457,7 +3518,8 @@ const cylinder = startSketchOn('-XZ')
digest: None,
}),
type_: None,
optional: true,
default_value: Some(DefaultParamVal::none()),
labeled: true,
digest: None,
},
],

View File

@ -18,12 +18,12 @@ use crate::{
parsing::{
ast::types::{
ArrayExpression, ArrayRangeExpression, BinaryExpression, BinaryOperator, BinaryPart, BodyItem, BoxNode,
CallExpression, CallExpressionKw, CommentStyle, ElseIf, Expr, ExpressionStatement, FnArgPrimitive,
FnArgType, FunctionExpression, Identifier, IfExpression, ImportItem, ImportStatement, ItemVisibility,
LabeledArg, Literal, LiteralIdentifier, LiteralValue, MemberExpression, MemberObject, Node, NonCodeMeta,
NonCodeNode, NonCodeValue, ObjectExpression, ObjectProperty, Parameter, PipeExpression, PipeSubstitution,
Program, ReturnStatement, Shebang, TagDeclarator, UnaryExpression, UnaryOperator, VariableDeclaration,
VariableDeclarator, VariableKind,
CallExpression, CallExpressionKw, CommentStyle, DefaultParamVal, ElseIf, Expr, ExpressionStatement,
FnArgPrimitive, FnArgType, FunctionExpression, Identifier, IfExpression, ImportItem, ImportStatement,
ItemVisibility, LabeledArg, Literal, LiteralIdentifier, LiteralValue, MemberExpression, MemberObject, Node,
NonCodeMeta, NonCodeNode, NonCodeValue, ObjectExpression, ObjectProperty, Parameter, PipeExpression,
PipeSubstitution, Program, ReturnStatement, Shebang, TagDeclarator, UnaryExpression, UnaryOperator,
VariableDeclaration, VariableDeclarator, VariableKind,
},
math::BinaryExpressionToken,
token::{Token, TokenType},
@ -2145,7 +2145,13 @@ fn argument_type(i: TokenSlice) -> PResult<FnArgType> {
Ok(type_)
}
fn parameter(i: TokenSlice) -> PResult<(Token, std::option::Option<FnArgType>, bool)> {
struct ParamDescription {
arg_name: Token,
type_: std::option::Option<FnArgType>,
is_optional: bool,
}
fn parameter(i: TokenSlice) -> PResult<ParamDescription> {
let (arg_name, optional, _, type_) = (
any.verify(|token: &Token| !matches!(token.token_type, TokenType::Brace) || token.value != ")"),
opt(question_mark),
@ -2153,7 +2159,11 @@ fn parameter(i: TokenSlice) -> PResult<(Token, std::option::Option<FnArgType>, b
opt((colon, opt(whitespace), argument_type).map(|tup| tup.2)),
)
.parse_next(i)?;
Ok((arg_name, type_, optional.is_some()))
Ok(ParamDescription {
arg_name,
type_,
is_optional: optional.is_some(),
})
}
/// Parameters are declared in a function signature, and used within a function.
@ -2166,17 +2176,28 @@ fn parameters(i: TokenSlice) -> PResult<Vec<Parameter>> {
// Make sure all those tokens are valid parameters.
let params: Vec<Parameter> = candidates
.into_iter()
.map(|(arg_name, type_, optional)| {
let identifier =
Node::<Identifier>::try_from(arg_name).and_then(Node::<Identifier>::into_valid_binding_name)?;
.map(
|ParamDescription {
arg_name,
type_,
is_optional,
}| {
let identifier =
Node::<Identifier>::try_from(arg_name).and_then(Node::<Identifier>::into_valid_binding_name)?;
Ok(Parameter {
identifier,
type_,
optional,
digest: None,
})
})
Ok(Parameter {
identifier,
type_,
default_value: if is_optional {
Some(DefaultParamVal::none())
} else {
None
},
labeled: true,
digest: None,
})
},
)
.collect::<Result<_, _>>()
.map_err(|e: CompilationError| ErrMode::Backtrack(ContextError::from(e)))?;
@ -2190,10 +2211,10 @@ fn parameters(i: TokenSlice) -> PResult<Vec<Parameter>> {
fn optional_after_required(params: &[Parameter]) -> Result<(), CompilationError> {
let mut found_optional = false;
for p in params {
if p.optional {
if p.optional() {
found_optional = true;
}
if !p.optional && found_optional {
if !p.optional() && found_optional {
let e = CompilationError::fatal(
(&p.identifier).into(),
"mandatory parameters must be declared before optional parameters",
@ -3547,7 +3568,8 @@ e
digest: None,
}),
type_: None,
optional: true,
default_value: Some(DefaultParamVal::none()),
labeled: true,
digest: None,
}],
true,
@ -3559,7 +3581,8 @@ e
digest: None,
}),
type_: None,
optional: false,
default_value: None,
labeled: true,
digest: None,
}],
true,
@ -3572,7 +3595,8 @@ e
digest: None,
}),
type_: None,
optional: false,
default_value: None,
labeled: true,
digest: None,
},
Parameter {
@ -3581,7 +3605,8 @@ e
digest: None,
}),
type_: None,
optional: true,
default_value: Some(DefaultParamVal::none()),
labeled: true,
digest: None,
},
],
@ -3595,7 +3620,8 @@ e
digest: None,
}),
type_: None,
optional: true,
default_value: Some(DefaultParamVal::none()),
labeled: true,
digest: None,
},
Parameter {
@ -3604,7 +3630,8 @@ e
digest: None,
}),
type_: None,
optional: false,
default_value: None,
labeled: true,
digest: None,
},
],

View File

@ -1,6 +1,5 @@
---
source: kcl/src/parsing/parser.rs
assertion_line: 3974
expression: actual
snapshot_kind: text
---
@ -46,8 +45,7 @@ snapshot_kind: text
"name": "param",
"start": 12,
"type": "Identifier"
},
"optional": false
}
}
],
"start": 11,

View File

@ -1,6 +1,5 @@
---
source: kcl/src/parsing/parser.rs
assertion_line: 4006
expression: actual
snapshot_kind: text
---
@ -68,7 +67,11 @@ snapshot_kind: text
"start": 8,
"type": "Identifier"
},
"optional": true
"default_value": {
"type": "KclNone",
"type": "KclNone",
"__private": "KCL_NONE_ID"
}
}
],
"start": 7,

View File

@ -60,8 +60,7 @@ snapshot_kind: text
"name": "i",
"start": 5,
"type": "Identifier"
},
"optional": false
}
}
],
"start": 4,

View File

@ -1,6 +1,7 @@
---
source: kcl/src/simulation_tests.rs
description: Program memory after executing add_lots.kcl
snapshot_kind: text
---
{
"environments": [
@ -72,8 +73,7 @@ description: Program memory after executing add_lots.kcl
"name": "i",
"start": 5,
"type": "Identifier"
},
"optional": false
}
}
],
"start": 4,

View File

@ -46,8 +46,7 @@ snapshot_kind: text
"name": "i",
"start": 5,
"type": "Identifier"
},
"optional": false
}
}
],
"start": 4,

View File

@ -671,8 +671,7 @@ snapshot_kind: text
"name": "length",
"start": 8,
"type": "Identifier"
},
"optional": false
}
},
{
"type": "Parameter",
@ -681,8 +680,7 @@ snapshot_kind: text
"name": "center",
"start": 16,
"type": "Identifier"
},
"optional": false
}
}
],
"start": 7,

View File

@ -684,8 +684,7 @@ snapshot_kind: text
"name": "length",
"start": 8,
"type": "Identifier"
},
"optional": false
}
},
{
"type": "Parameter",
@ -694,8 +693,7 @@ snapshot_kind: text
"name": "center",
"start": 16,
"type": "Identifier"
},
"optional": false
}
}
],
"start": 7,

View File

@ -60,8 +60,7 @@ snapshot_kind: text
"name": "i",
"start": 13,
"type": "Identifier"
},
"optional": false
}
}
],
"start": 12,

View File

@ -1,6 +1,7 @@
---
source: kcl/src/simulation_tests.rs
description: Program memory after executing double_map_fn.kcl
snapshot_kind: text
---
{
"environments": [
@ -72,8 +73,7 @@ description: Program memory after executing double_map_fn.kcl
"name": "i",
"start": 13,
"type": "Identifier"
},
"optional": false
}
}
],
"start": 12,

View File

@ -1698,8 +1698,7 @@ snapshot_kind: text
"name": "x",
"start": 1207,
"type": "Identifier"
},
"optional": false
}
},
{
"type": "Parameter",
@ -1708,8 +1707,7 @@ snapshot_kind: text
"name": "y",
"start": 1210,
"type": "Identifier"
},
"optional": false
}
},
{
"type": "Parameter",
@ -1718,8 +1716,7 @@ snapshot_kind: text
"name": "height",
"start": 1213,
"type": "Identifier"
},
"optional": false
}
}
],
"start": 1206,

View File

@ -1236,8 +1236,7 @@ snapshot_kind: text
"name": "x",
"start": 1207,
"type": "Identifier"
},
"optional": false
}
},
{
"type": "Parameter",
@ -1246,8 +1245,7 @@ snapshot_kind: text
"name": "y",
"start": 1210,
"type": "Identifier"
},
"optional": false
}
},
{
"type": "Parameter",
@ -1256,8 +1254,7 @@ snapshot_kind: text
"name": "height",
"start": 1213,
"type": "Identifier"
},
"optional": false
}
}
],
"start": 1206,

View File

@ -337,8 +337,7 @@ snapshot_kind: text
"name": "h",
"start": 7,
"type": "Identifier"
},
"optional": false
}
},
{
"type": "Parameter",
@ -347,8 +346,7 @@ snapshot_kind: text
"name": "l",
"start": 10,
"type": "Identifier"
},
"optional": false
}
},
{
"type": "Parameter",
@ -357,8 +355,7 @@ snapshot_kind: text
"name": "w",
"start": 13,
"type": "Identifier"
},
"optional": false
}
}
],
"start": 6,

View File

@ -350,8 +350,7 @@ snapshot_kind: text
"name": "h",
"start": 7,
"type": "Identifier"
},
"optional": false
}
},
{
"type": "Parameter",
@ -360,8 +359,7 @@ snapshot_kind: text
"name": "l",
"start": 10,
"type": "Identifier"
},
"optional": false
}
},
{
"type": "Parameter",
@ -370,8 +368,7 @@ snapshot_kind: text
"name": "w",
"start": 13,
"type": "Identifier"
},
"optional": false
}
}
],
"start": 6,

View File

@ -320,8 +320,7 @@ snapshot_kind: text
"name": "p",
"start": 7,
"type": "Identifier"
},
"optional": false
}
},
{
"type": "Parameter",
@ -330,8 +329,7 @@ snapshot_kind: text
"name": "h",
"start": 10,
"type": "Identifier"
},
"optional": false
}
},
{
"type": "Parameter",
@ -340,8 +338,7 @@ snapshot_kind: text
"name": "l",
"start": 13,
"type": "Identifier"
},
"optional": false
}
},
{
"type": "Parameter",
@ -350,8 +347,7 @@ snapshot_kind: text
"name": "w",
"start": 16,
"type": "Identifier"
},
"optional": false
}
}
],
"start": 6,

View File

@ -333,8 +333,7 @@ snapshot_kind: text
"name": "p",
"start": 7,
"type": "Identifier"
},
"optional": false
}
},
{
"type": "Parameter",
@ -343,8 +342,7 @@ snapshot_kind: text
"name": "h",
"start": 10,
"type": "Identifier"
},
"optional": false
}
},
{
"type": "Parameter",
@ -353,8 +351,7 @@ snapshot_kind: text
"name": "l",
"start": 13,
"type": "Identifier"
},
"optional": false
}
},
{
"type": "Parameter",
@ -363,8 +360,7 @@ snapshot_kind: text
"name": "w",
"start": 16,
"type": "Identifier"
},
"optional": false
}
}
],
"start": 6,

View File

@ -732,8 +732,7 @@ snapshot_kind: text
"name": "x",
"start": 418,
"type": "Identifier"
},
"optional": false
}
},
{
"type": "Parameter",
@ -742,8 +741,7 @@ snapshot_kind: text
"name": "face",
"start": 421,
"type": "Identifier"
},
"optional": false
}
}
],
"start": 417,

View File

@ -1639,8 +1639,7 @@ snapshot_kind: text
"name": "x",
"start": 418,
"type": "Identifier"
},
"optional": false
}
},
{
"type": "Parameter",
@ -1649,8 +1648,7 @@ snapshot_kind: text
"name": "face",
"start": 421,
"type": "Identifier"
},
"optional": false
}
}
],
"start": 417,

View File

@ -671,8 +671,7 @@ snapshot_kind: text
"name": "length",
"start": 8,
"type": "Identifier"
},
"optional": false
}
},
{
"type": "Parameter",
@ -681,8 +680,7 @@ snapshot_kind: text
"name": "center",
"start": 16,
"type": "Identifier"
},
"optional": false
}
}
],
"start": 7,
@ -753,8 +751,7 @@ snapshot_kind: text
"name": "x",
"start": 334,
"type": "Identifier"
},
"optional": false
}
}
],
"start": 333,

View File

@ -684,8 +684,7 @@ snapshot_kind: text
"name": "length",
"start": 8,
"type": "Identifier"
},
"optional": false
}
},
{
"type": "Parameter",
@ -694,8 +693,7 @@ snapshot_kind: text
"name": "center",
"start": 16,
"type": "Identifier"
},
"optional": false
}
}
],
"start": 7,
@ -788,8 +786,7 @@ snapshot_kind: text
"name": "x",
"start": 334,
"type": "Identifier"
},
"optional": false
}
}
],
"start": 333,
@ -1476,8 +1473,7 @@ snapshot_kind: text
"name": "length",
"start": 8,
"type": "Identifier"
},
"optional": false
}
},
{
"type": "Parameter",
@ -1486,8 +1482,7 @@ snapshot_kind: text
"name": "center",
"start": 16,
"type": "Identifier"
},
"optional": false
}
}
],
"start": 7,
@ -2483,8 +2478,7 @@ snapshot_kind: text
"name": "length",
"start": 8,
"type": "Identifier"
},
"optional": false
}
},
{
"type": "Parameter",
@ -2493,8 +2487,7 @@ snapshot_kind: text
"name": "center",
"start": 16,
"type": "Identifier"
},
"optional": false
}
}
],
"start": 7,
@ -2587,8 +2580,7 @@ snapshot_kind: text
"name": "x",
"start": 334,
"type": "Identifier"
},
"optional": false
}
}
],
"start": 333,
@ -3275,8 +3267,7 @@ snapshot_kind: text
"name": "length",
"start": 8,
"type": "Identifier"
},
"optional": false
}
},
{
"type": "Parameter",
@ -3285,8 +3276,7 @@ snapshot_kind: text
"name": "center",
"start": 16,
"type": "Identifier"
},
"optional": false
}
}
],
"start": 7,

View File

@ -44,8 +44,7 @@ snapshot_kind: text
"name": "ignored",
"start": 66,
"type": "Identifier"
},
"optional": false
}
}
],
"start": 65,

View File

@ -117,8 +117,7 @@ snapshot_kind: text
"name": "s",
"start": 21,
"type": "Identifier"
},
"optional": false
}
}
],
"start": 20,

View File

@ -1,6 +1,7 @@
---
source: kcl/src/simulation_tests.rs
description: Program memory after executing riddle_small.kcl
snapshot_kind: text
---
{
"environments": [
@ -413,8 +414,7 @@ description: Program memory after executing riddle_small.kcl
"name": "s",
"start": 21,
"type": "Identifier"
},
"optional": false
}
}
],
"start": 20,

View File

@ -273,8 +273,7 @@ snapshot_kind: text
"name": "pos",
"start": 8,
"type": "Identifier"
},
"optional": false
}
},
{
"type": "Parameter",
@ -283,8 +282,7 @@ snapshot_kind: text
"name": "scale",
"start": 13,
"type": "Identifier"
},
"optional": false
}
}
],
"start": 7,

View File

@ -286,8 +286,7 @@ snapshot_kind: text
"name": "pos",
"start": 8,
"type": "Identifier"
},
"optional": false
}
},
{
"type": "Parameter",
@ -296,8 +295,7 @@ snapshot_kind: text
"name": "scale",
"start": 13,
"type": "Identifier"
},
"optional": false
}
}
],
"start": 7,

View File

@ -273,8 +273,7 @@ snapshot_kind: text
"name": "pos",
"start": 8,
"type": "Identifier"
},
"optional": false
}
},
{
"type": "Parameter",
@ -283,8 +282,7 @@ snapshot_kind: text
"name": "scale",
"start": 13,
"type": "Identifier"
},
"optional": false
}
}
],
"start": 7,

View File

@ -286,8 +286,7 @@ snapshot_kind: text
"name": "pos",
"start": 8,
"type": "Identifier"
},
"optional": false
}
},
{
"type": "Parameter",
@ -296,8 +295,7 @@ snapshot_kind: text
"name": "scale",
"start": 13,
"type": "Identifier"
},
"optional": false
}
}
],
"start": 7,

View File

@ -273,8 +273,7 @@ snapshot_kind: text
"name": "pos",
"start": 8,
"type": "Identifier"
},
"optional": false
}
},
{
"type": "Parameter",
@ -283,8 +282,7 @@ snapshot_kind: text
"name": "scale",
"start": 13,
"type": "Identifier"
},
"optional": false
}
}
],
"start": 7,

View File

@ -286,8 +286,7 @@ snapshot_kind: text
"name": "pos",
"start": 8,
"type": "Identifier"
},
"optional": false
}
},
{
"type": "Parameter",
@ -296,8 +295,7 @@ snapshot_kind: text
"name": "scale",
"start": 13,
"type": "Identifier"
},
"optional": false
}
}
],
"start": 7,

View File

@ -273,8 +273,7 @@ snapshot_kind: text
"name": "pos",
"start": 8,
"type": "Identifier"
},
"optional": false
}
},
{
"type": "Parameter",
@ -283,8 +282,7 @@ snapshot_kind: text
"name": "scale",
"start": 13,
"type": "Identifier"
},
"optional": false
}
}
],
"start": 7,

View File

@ -286,8 +286,7 @@ snapshot_kind: text
"name": "pos",
"start": 8,
"type": "Identifier"
},
"optional": false
}
},
{
"type": "Parameter",
@ -296,8 +295,7 @@ snapshot_kind: text
"name": "scale",
"start": 13,
"type": "Identifier"
},
"optional": false
}
}
],
"start": 7,