Is mock mode to fix errors when cap end or ids dont exist. (#1913)
* add is_mock Signed-off-by: Jess Frazelle <github@jessfraz.com> * js side Signed-off-by: Jess Frazelle <github@jessfraz.com> * is mock mode Signed-off-by: Jess Frazelle <github@jessfraz.com> * fix cargo tests Signed-off-by: Jess Frazelle <github@jessfraz.com> --------- Signed-off-by: Jess Frazelle <github@jessfraz.com>
This commit is contained in:
@ -127,13 +127,15 @@ export interface ProgramMemory {
|
||||
export const executor = async (
|
||||
node: Program,
|
||||
programMemory: ProgramMemory = { root: {}, return: null },
|
||||
engineCommandManager: EngineCommandManager
|
||||
engineCommandManager: EngineCommandManager,
|
||||
isMock: boolean = false
|
||||
): Promise<ProgramMemory> => {
|
||||
engineCommandManager.startNewSession()
|
||||
const _programMemory = await _executor(
|
||||
node,
|
||||
programMemory,
|
||||
engineCommandManager
|
||||
engineCommandManager,
|
||||
isMock
|
||||
)
|
||||
await engineCommandManager.waitForAllCommands()
|
||||
|
||||
@ -148,7 +150,8 @@ const getSettingsState = import('components/SettingsAuthProvider').then(
|
||||
export const _executor = async (
|
||||
node: Program,
|
||||
programMemory: ProgramMemory = { root: {}, return: null },
|
||||
engineCommandManager: EngineCommandManager
|
||||
engineCommandManager: EngineCommandManager,
|
||||
isMock: boolean
|
||||
): Promise<ProgramMemory> => {
|
||||
try {
|
||||
const baseUnit = (await getSettingsState)()?.baseUnit || 'mm'
|
||||
@ -157,7 +160,8 @@ export const _executor = async (
|
||||
JSON.stringify(programMemory),
|
||||
baseUnit,
|
||||
engineCommandManager,
|
||||
fileSystemManager
|
||||
fileSystemManager,
|
||||
isMock
|
||||
)
|
||||
return memory
|
||||
} catch (e: any) {
|
||||
|
@ -66,7 +66,7 @@ export async function enginelessExecutor(
|
||||
}) as any as EngineCommandManager
|
||||
await mockEngineCommandManager.waitForReady
|
||||
mockEngineCommandManager.startNewSession()
|
||||
const programMemory = await _executor(ast, pm, mockEngineCommandManager)
|
||||
const programMemory = await _executor(ast, pm, mockEngineCommandManager, true)
|
||||
await mockEngineCommandManager.waitForAllCommands()
|
||||
return programMemory
|
||||
}
|
||||
@ -86,7 +86,7 @@ export async function executor(
|
||||
})
|
||||
await engineCommandManager.waitForReady
|
||||
engineCommandManager.startNewSession()
|
||||
const programMemory = await _executor(ast, pm, engineCommandManager)
|
||||
const programMemory = await _executor(ast, pm, engineCommandManager, false)
|
||||
await engineCommandManager.waitForAllCommands()
|
||||
return programMemory
|
||||
}
|
||||
|
@ -263,7 +263,7 @@ export async function executeAst({
|
||||
}
|
||||
const programMemory = await (useFakeExecutor
|
||||
? enginelessExecutor(ast, programMemoryOverride || programMemoryInit())
|
||||
: _executor(ast, programMemoryInit(), engineCommandManager))
|
||||
: _executor(ast, programMemoryInit(), engineCommandManager, false))
|
||||
|
||||
await engineCommandManager.waitForAllCommands()
|
||||
return {
|
||||
|
@ -778,12 +778,7 @@ fn generate_code_block_test(fn_name: &str, code_block: &str, index: usize) -> pr
|
||||
let parser = crate::parser::Parser::new(tokens);
|
||||
let program = parser.ast().unwrap();
|
||||
let mut mem: crate::executor::ProgramMemory = Default::default();
|
||||
let ctx = crate::executor::ExecutorContext {
|
||||
engine: std::sync::Arc::new(Box::new(crate::engine::conn::EngineConnection::new(ws).await.unwrap())),
|
||||
fs: crate::fs::FileManager::new(),
|
||||
stdlib: std::sync::Arc::new(crate::std::StdLib::new()),
|
||||
units: kittycad::types::UnitLength::Mm,
|
||||
};
|
||||
let ctx = crate::executor::ExecutorContext::new(ws,kittycad::types::UnitLength::Mm).await.unwrap();
|
||||
|
||||
crate::executor::execute(program, &mut mem, crate::executor::BodyType::Root, &ctx).await.unwrap();
|
||||
}
|
||||
|
@ -29,16 +29,9 @@ mod test_examples_show {
|
||||
let parser = crate::parser::Parser::new(tokens);
|
||||
let program = parser.ast().unwrap();
|
||||
let mut mem: crate::executor::ProgramMemory = Default::default();
|
||||
let ctx = crate::executor::ExecutorContext {
|
||||
engine: std::sync::Arc::new(Box::new(
|
||||
crate::engine::conn::EngineConnection::new(ws)
|
||||
.await
|
||||
.unwrap(),
|
||||
)),
|
||||
fs: crate::fs::FileManager::new(),
|
||||
stdlib: std::sync::Arc::new(crate::std::StdLib::new()),
|
||||
units: kittycad::types::UnitLength::Mm,
|
||||
};
|
||||
let ctx = crate::executor::ExecutorContext::new(ws, kittycad::types::UnitLength::Mm)
|
||||
.await
|
||||
.unwrap();
|
||||
crate::executor::execute(program, &mut mem, crate::executor::BodyType::Root, &ctx)
|
||||
.await
|
||||
.unwrap();
|
||||
@ -73,16 +66,9 @@ mod test_examples_show {
|
||||
let parser = crate::parser::Parser::new(tokens);
|
||||
let program = parser.ast().unwrap();
|
||||
let mut mem: crate::executor::ProgramMemory = Default::default();
|
||||
let ctx = crate::executor::ExecutorContext {
|
||||
engine: std::sync::Arc::new(Box::new(
|
||||
crate::engine::conn::EngineConnection::new(ws)
|
||||
.await
|
||||
.unwrap(),
|
||||
)),
|
||||
fs: crate::fs::FileManager::new(),
|
||||
stdlib: std::sync::Arc::new(crate::std::StdLib::new()),
|
||||
units: kittycad::types::UnitLength::Mm,
|
||||
};
|
||||
let ctx = crate::executor::ExecutorContext::new(ws, kittycad::types::UnitLength::Mm)
|
||||
.await
|
||||
.unwrap();
|
||||
crate::executor::execute(program, &mut mem, crate::executor::BodyType::Root, &ctx)
|
||||
.await
|
||||
.unwrap();
|
||||
|
@ -29,16 +29,9 @@ mod test_examples_show {
|
||||
let parser = crate::parser::Parser::new(tokens);
|
||||
let program = parser.ast().unwrap();
|
||||
let mut mem: crate::executor::ProgramMemory = Default::default();
|
||||
let ctx = crate::executor::ExecutorContext {
|
||||
engine: std::sync::Arc::new(Box::new(
|
||||
crate::engine::conn::EngineConnection::new(ws)
|
||||
.await
|
||||
.unwrap(),
|
||||
)),
|
||||
fs: crate::fs::FileManager::new(),
|
||||
stdlib: std::sync::Arc::new(crate::std::StdLib::new()),
|
||||
units: kittycad::types::UnitLength::Mm,
|
||||
};
|
||||
let ctx = crate::executor::ExecutorContext::new(ws, kittycad::types::UnitLength::Mm)
|
||||
.await
|
||||
.unwrap();
|
||||
crate::executor::execute(program, &mut mem, crate::executor::BodyType::Root, &ctx)
|
||||
.await
|
||||
.unwrap();
|
||||
|
@ -29,16 +29,9 @@ mod test_examples_my_func {
|
||||
let parser = crate::parser::Parser::new(tokens);
|
||||
let program = parser.ast().unwrap();
|
||||
let mut mem: crate::executor::ProgramMemory = Default::default();
|
||||
let ctx = crate::executor::ExecutorContext {
|
||||
engine: std::sync::Arc::new(Box::new(
|
||||
crate::engine::conn::EngineConnection::new(ws)
|
||||
.await
|
||||
.unwrap(),
|
||||
)),
|
||||
fs: crate::fs::FileManager::new(),
|
||||
stdlib: std::sync::Arc::new(crate::std::StdLib::new()),
|
||||
units: kittycad::types::UnitLength::Mm,
|
||||
};
|
||||
let ctx = crate::executor::ExecutorContext::new(ws, kittycad::types::UnitLength::Mm)
|
||||
.await
|
||||
.unwrap();
|
||||
crate::executor::execute(program, &mut mem, crate::executor::BodyType::Root, &ctx)
|
||||
.await
|
||||
.unwrap();
|
||||
@ -73,16 +66,9 @@ mod test_examples_my_func {
|
||||
let parser = crate::parser::Parser::new(tokens);
|
||||
let program = parser.ast().unwrap();
|
||||
let mut mem: crate::executor::ProgramMemory = Default::default();
|
||||
let ctx = crate::executor::ExecutorContext {
|
||||
engine: std::sync::Arc::new(Box::new(
|
||||
crate::engine::conn::EngineConnection::new(ws)
|
||||
.await
|
||||
.unwrap(),
|
||||
)),
|
||||
fs: crate::fs::FileManager::new(),
|
||||
stdlib: std::sync::Arc::new(crate::std::StdLib::new()),
|
||||
units: kittycad::types::UnitLength::Mm,
|
||||
};
|
||||
let ctx = crate::executor::ExecutorContext::new(ws, kittycad::types::UnitLength::Mm)
|
||||
.await
|
||||
.unwrap();
|
||||
crate::executor::execute(program, &mut mem, crate::executor::BodyType::Root, &ctx)
|
||||
.await
|
||||
.unwrap();
|
||||
|
@ -30,16 +30,9 @@ mod test_examples_import {
|
||||
let parser = crate::parser::Parser::new(tokens);
|
||||
let program = parser.ast().unwrap();
|
||||
let mut mem: crate::executor::ProgramMemory = Default::default();
|
||||
let ctx = crate::executor::ExecutorContext {
|
||||
engine: std::sync::Arc::new(Box::new(
|
||||
crate::engine::conn::EngineConnection::new(ws)
|
||||
.await
|
||||
.unwrap(),
|
||||
)),
|
||||
fs: crate::fs::FileManager::new(),
|
||||
stdlib: std::sync::Arc::new(crate::std::StdLib::new()),
|
||||
units: kittycad::types::UnitLength::Mm,
|
||||
};
|
||||
let ctx = crate::executor::ExecutorContext::new(ws, kittycad::types::UnitLength::Mm)
|
||||
.await
|
||||
.unwrap();
|
||||
crate::executor::execute(program, &mut mem, crate::executor::BodyType::Root, &ctx)
|
||||
.await
|
||||
.unwrap();
|
||||
@ -75,16 +68,9 @@ mod test_examples_import {
|
||||
let parser = crate::parser::Parser::new(tokens);
|
||||
let program = parser.ast().unwrap();
|
||||
let mut mem: crate::executor::ProgramMemory = Default::default();
|
||||
let ctx = crate::executor::ExecutorContext {
|
||||
engine: std::sync::Arc::new(Box::new(
|
||||
crate::engine::conn::EngineConnection::new(ws)
|
||||
.await
|
||||
.unwrap(),
|
||||
)),
|
||||
fs: crate::fs::FileManager::new(),
|
||||
stdlib: std::sync::Arc::new(crate::std::StdLib::new()),
|
||||
units: kittycad::types::UnitLength::Mm,
|
||||
};
|
||||
let ctx = crate::executor::ExecutorContext::new(ws, kittycad::types::UnitLength::Mm)
|
||||
.await
|
||||
.unwrap();
|
||||
crate::executor::execute(program, &mut mem, crate::executor::BodyType::Root, &ctx)
|
||||
.await
|
||||
.unwrap();
|
||||
|
@ -29,16 +29,9 @@ mod test_examples_line_to {
|
||||
let parser = crate::parser::Parser::new(tokens);
|
||||
let program = parser.ast().unwrap();
|
||||
let mut mem: crate::executor::ProgramMemory = Default::default();
|
||||
let ctx = crate::executor::ExecutorContext {
|
||||
engine: std::sync::Arc::new(Box::new(
|
||||
crate::engine::conn::EngineConnection::new(ws)
|
||||
.await
|
||||
.unwrap(),
|
||||
)),
|
||||
fs: crate::fs::FileManager::new(),
|
||||
stdlib: std::sync::Arc::new(crate::std::StdLib::new()),
|
||||
units: kittycad::types::UnitLength::Mm,
|
||||
};
|
||||
let ctx = crate::executor::ExecutorContext::new(ws, kittycad::types::UnitLength::Mm)
|
||||
.await
|
||||
.unwrap();
|
||||
crate::executor::execute(program, &mut mem, crate::executor::BodyType::Root, &ctx)
|
||||
.await
|
||||
.unwrap();
|
||||
@ -73,16 +66,9 @@ mod test_examples_line_to {
|
||||
let parser = crate::parser::Parser::new(tokens);
|
||||
let program = parser.ast().unwrap();
|
||||
let mut mem: crate::executor::ProgramMemory = Default::default();
|
||||
let ctx = crate::executor::ExecutorContext {
|
||||
engine: std::sync::Arc::new(Box::new(
|
||||
crate::engine::conn::EngineConnection::new(ws)
|
||||
.await
|
||||
.unwrap(),
|
||||
)),
|
||||
fs: crate::fs::FileManager::new(),
|
||||
stdlib: std::sync::Arc::new(crate::std::StdLib::new()),
|
||||
units: kittycad::types::UnitLength::Mm,
|
||||
};
|
||||
let ctx = crate::executor::ExecutorContext::new(ws, kittycad::types::UnitLength::Mm)
|
||||
.await
|
||||
.unwrap();
|
||||
crate::executor::execute(program, &mut mem, crate::executor::BodyType::Root, &ctx)
|
||||
.await
|
||||
.unwrap();
|
||||
|
@ -29,16 +29,9 @@ mod test_examples_min {
|
||||
let parser = crate::parser::Parser::new(tokens);
|
||||
let program = parser.ast().unwrap();
|
||||
let mut mem: crate::executor::ProgramMemory = Default::default();
|
||||
let ctx = crate::executor::ExecutorContext {
|
||||
engine: std::sync::Arc::new(Box::new(
|
||||
crate::engine::conn::EngineConnection::new(ws)
|
||||
.await
|
||||
.unwrap(),
|
||||
)),
|
||||
fs: crate::fs::FileManager::new(),
|
||||
stdlib: std::sync::Arc::new(crate::std::StdLib::new()),
|
||||
units: kittycad::types::UnitLength::Mm,
|
||||
};
|
||||
let ctx = crate::executor::ExecutorContext::new(ws, kittycad::types::UnitLength::Mm)
|
||||
.await
|
||||
.unwrap();
|
||||
crate::executor::execute(program, &mut mem, crate::executor::BodyType::Root, &ctx)
|
||||
.await
|
||||
.unwrap();
|
||||
@ -73,16 +66,9 @@ mod test_examples_min {
|
||||
let parser = crate::parser::Parser::new(tokens);
|
||||
let program = parser.ast().unwrap();
|
||||
let mut mem: crate::executor::ProgramMemory = Default::default();
|
||||
let ctx = crate::executor::ExecutorContext {
|
||||
engine: std::sync::Arc::new(Box::new(
|
||||
crate::engine::conn::EngineConnection::new(ws)
|
||||
.await
|
||||
.unwrap(),
|
||||
)),
|
||||
fs: crate::fs::FileManager::new(),
|
||||
stdlib: std::sync::Arc::new(crate::std::StdLib::new()),
|
||||
units: kittycad::types::UnitLength::Mm,
|
||||
};
|
||||
let ctx = crate::executor::ExecutorContext::new(ws, kittycad::types::UnitLength::Mm)
|
||||
.await
|
||||
.unwrap();
|
||||
crate::executor::execute(program, &mut mem, crate::executor::BodyType::Root, &ctx)
|
||||
.await
|
||||
.unwrap();
|
||||
|
@ -29,16 +29,9 @@ mod test_examples_show {
|
||||
let parser = crate::parser::Parser::new(tokens);
|
||||
let program = parser.ast().unwrap();
|
||||
let mut mem: crate::executor::ProgramMemory = Default::default();
|
||||
let ctx = crate::executor::ExecutorContext {
|
||||
engine: std::sync::Arc::new(Box::new(
|
||||
crate::engine::conn::EngineConnection::new(ws)
|
||||
.await
|
||||
.unwrap(),
|
||||
)),
|
||||
fs: crate::fs::FileManager::new(),
|
||||
stdlib: std::sync::Arc::new(crate::std::StdLib::new()),
|
||||
units: kittycad::types::UnitLength::Mm,
|
||||
};
|
||||
let ctx = crate::executor::ExecutorContext::new(ws, kittycad::types::UnitLength::Mm)
|
||||
.await
|
||||
.unwrap();
|
||||
crate::executor::execute(program, &mut mem, crate::executor::BodyType::Root, &ctx)
|
||||
.await
|
||||
.unwrap();
|
||||
|
@ -30,16 +30,9 @@ mod test_examples_import {
|
||||
let parser = crate::parser::Parser::new(tokens);
|
||||
let program = parser.ast().unwrap();
|
||||
let mut mem: crate::executor::ProgramMemory = Default::default();
|
||||
let ctx = crate::executor::ExecutorContext {
|
||||
engine: std::sync::Arc::new(Box::new(
|
||||
crate::engine::conn::EngineConnection::new(ws)
|
||||
.await
|
||||
.unwrap(),
|
||||
)),
|
||||
fs: crate::fs::FileManager::new(),
|
||||
stdlib: std::sync::Arc::new(crate::std::StdLib::new()),
|
||||
units: kittycad::types::UnitLength::Mm,
|
||||
};
|
||||
let ctx = crate::executor::ExecutorContext::new(ws, kittycad::types::UnitLength::Mm)
|
||||
.await
|
||||
.unwrap();
|
||||
crate::executor::execute(program, &mut mem, crate::executor::BodyType::Root, &ctx)
|
||||
.await
|
||||
.unwrap();
|
||||
|
@ -30,16 +30,9 @@ mod test_examples_import {
|
||||
let parser = crate::parser::Parser::new(tokens);
|
||||
let program = parser.ast().unwrap();
|
||||
let mut mem: crate::executor::ProgramMemory = Default::default();
|
||||
let ctx = crate::executor::ExecutorContext {
|
||||
engine: std::sync::Arc::new(Box::new(
|
||||
crate::engine::conn::EngineConnection::new(ws)
|
||||
.await
|
||||
.unwrap(),
|
||||
)),
|
||||
fs: crate::fs::FileManager::new(),
|
||||
stdlib: std::sync::Arc::new(crate::std::StdLib::new()),
|
||||
units: kittycad::types::UnitLength::Mm,
|
||||
};
|
||||
let ctx = crate::executor::ExecutorContext::new(ws, kittycad::types::UnitLength::Mm)
|
||||
.await
|
||||
.unwrap();
|
||||
crate::executor::execute(program, &mut mem, crate::executor::BodyType::Root, &ctx)
|
||||
.await
|
||||
.unwrap();
|
||||
|
@ -30,16 +30,9 @@ mod test_examples_import {
|
||||
let parser = crate::parser::Parser::new(tokens);
|
||||
let program = parser.ast().unwrap();
|
||||
let mut mem: crate::executor::ProgramMemory = Default::default();
|
||||
let ctx = crate::executor::ExecutorContext {
|
||||
engine: std::sync::Arc::new(Box::new(
|
||||
crate::engine::conn::EngineConnection::new(ws)
|
||||
.await
|
||||
.unwrap(),
|
||||
)),
|
||||
fs: crate::fs::FileManager::new(),
|
||||
stdlib: std::sync::Arc::new(crate::std::StdLib::new()),
|
||||
units: kittycad::types::UnitLength::Mm,
|
||||
};
|
||||
let ctx = crate::executor::ExecutorContext::new(ws, kittycad::types::UnitLength::Mm)
|
||||
.await
|
||||
.unwrap();
|
||||
crate::executor::execute(program, &mut mem, crate::executor::BodyType::Root, &ctx)
|
||||
.await
|
||||
.unwrap();
|
||||
|
@ -29,16 +29,9 @@ mod test_examples_show {
|
||||
let parser = crate::parser::Parser::new(tokens);
|
||||
let program = parser.ast().unwrap();
|
||||
let mut mem: crate::executor::ProgramMemory = Default::default();
|
||||
let ctx = crate::executor::ExecutorContext {
|
||||
engine: std::sync::Arc::new(Box::new(
|
||||
crate::engine::conn::EngineConnection::new(ws)
|
||||
.await
|
||||
.unwrap(),
|
||||
)),
|
||||
fs: crate::fs::FileManager::new(),
|
||||
stdlib: std::sync::Arc::new(crate::std::StdLib::new()),
|
||||
units: kittycad::types::UnitLength::Mm,
|
||||
};
|
||||
let ctx = crate::executor::ExecutorContext::new(ws, kittycad::types::UnitLength::Mm)
|
||||
.await
|
||||
.unwrap();
|
||||
crate::executor::execute(program, &mut mem, crate::executor::BodyType::Root, &ctx)
|
||||
.await
|
||||
.unwrap();
|
||||
|
@ -983,11 +983,13 @@ pub struct ExecutorContext {
|
||||
pub fs: FileManager,
|
||||
pub stdlib: Arc<StdLib>,
|
||||
pub units: kittycad::types::UnitLength,
|
||||
/// Mock mode is only for the modeling app when they just want to mock engine calls and not
|
||||
/// actually make them.
|
||||
pub is_mock: bool,
|
||||
}
|
||||
|
||||
impl ExecutorContext {
|
||||
/// Create a new default executor context.
|
||||
#[cfg(not(test))]
|
||||
#[cfg(not(target_arch = "wasm32"))]
|
||||
pub async fn new(ws: reqwest::Upgraded, units: kittycad::types::UnitLength) -> Result<Self> {
|
||||
Ok(Self {
|
||||
@ -995,6 +997,7 @@ impl ExecutorContext {
|
||||
fs: FileManager::new(),
|
||||
stdlib: Arc::new(StdLib::new()),
|
||||
units,
|
||||
is_mock: false,
|
||||
})
|
||||
}
|
||||
}
|
||||
@ -1302,6 +1305,7 @@ mod tests {
|
||||
fs: crate::fs::FileManager::new(),
|
||||
stdlib: Arc::new(crate::std::StdLib::new()),
|
||||
units: kittycad::types::UnitLength::Mm,
|
||||
is_mock: false,
|
||||
};
|
||||
let memory = execute(program, &mut mem, BodyType::Root, &ctx).await?;
|
||||
|
||||
|
@ -125,8 +125,8 @@ pub(crate) async fn do_post_extrude(
|
||||
// Create a hashmap for quick id lookup
|
||||
let mut face_id_map = std::collections::HashMap::new();
|
||||
// creating fake ids for start and end caps is to make extrudes mock-execute safe
|
||||
let mut start_cap_id = Some(Uuid::new_v4());
|
||||
let mut end_cap_id = Some(Uuid::new_v4());
|
||||
let mut start_cap_id = if args.ctx.is_mock { Some(Uuid::new_v4()) } else { None };
|
||||
let mut end_cap_id = if args.ctx.is_mock { Some(Uuid::new_v4()) } else { None };
|
||||
|
||||
for face_info in face_infos {
|
||||
match face_info.cap {
|
||||
@ -172,7 +172,8 @@ pub(crate) async fn do_post_extrude(
|
||||
new_value.push(extrude_surface);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
} else if args.ctx.is_mock {
|
||||
// Only pre-populate the extrude surface if we are in mock mode.
|
||||
new_value.push(ExtrudeSurface::ExtrudePlane(crate::executor::ExtrudePlane {
|
||||
position: sketch_group.position, // TODO should be for the extrude surface
|
||||
rotation: sketch_group.rotation, // TODO should be for the extrude surface
|
||||
|
@ -19,6 +19,7 @@ pub async fn execute_wasm(
|
||||
units: &str,
|
||||
engine_manager: kcl_lib::engine::conn_wasm::EngineCommandManager,
|
||||
fs_manager: kcl_lib::fs::wasm::FileSystemManager,
|
||||
is_mock: bool,
|
||||
) -> Result<JsValue, String> {
|
||||
console_error_panic_hook::set_once();
|
||||
// deserialize the ast from a stringified json
|
||||
@ -37,6 +38,7 @@ pub async fn execute_wasm(
|
||||
fs,
|
||||
stdlib: std::sync::Arc::new(kcl_lib::std::StdLib::new()),
|
||||
units,
|
||||
is_mock,
|
||||
};
|
||||
|
||||
let memory = kcl_lib::executor::execute(program, &mut mem, kcl_lib::executor::BodyType::Root, &ctx)
|
||||
|
Reference in New Issue
Block a user