imxc 0.6.9 → 0.6.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/emitter.js CHANGED
@@ -193,6 +193,24 @@ function emitFloat(val) {
193
193
  return trimmed;
194
194
  return trimmed.includes('.') ? `${trimmed}F` : `${trimmed}.0F`;
195
195
  }
196
+ function emitStringItemsSource(itemsExpr, dynamicItems, prefix, counter, indent, lines) {
197
+ if (!dynamicItems) {
198
+ const itemsList = itemsExpr.split(',').map(s => s.trim()).filter(s => s.length > 0);
199
+ const itemsVar = `${prefix}_${counter}`;
200
+ lines.push(`${indent}const char* ${itemsVar}[] = {${itemsList.join(', ')}};`);
201
+ return { itemsArg: itemsVar, countExpr: `${itemsList.length}` };
202
+ }
203
+ const sourceVar = `${prefix}_src_${counter}`;
204
+ const itemsVar = `${prefix}_ptrs_${counter}`;
205
+ const itemVar = `${prefix}_item_${counter}`;
206
+ lines.push(`${indent}const auto& ${sourceVar} = ${itemsExpr};`);
207
+ lines.push(`${indent}std::vector<const char*> ${itemsVar};`);
208
+ lines.push(`${indent}${itemsVar}.reserve(${sourceVar}.size());`);
209
+ lines.push(`${indent}for (const auto& ${itemVar} : ${sourceVar}) {`);
210
+ lines.push(`${indent}${INDENT}${itemsVar}.push_back(${itemVar}.c_str());`);
211
+ lines.push(`${indent}}`);
212
+ return { itemsArg: `${itemsVar}.data()`, countExpr: `static_cast<int>(${itemsVar}.size())` };
213
+ }
196
214
  function findDockLayout(nodes) {
197
215
  for (const node of nodes) {
198
216
  if (node.kind === 'dock_layout')
@@ -308,6 +326,7 @@ export function emitComponent(comp, imports, sourceFile, boundProps, boundPropsM
308
326
  // Named interface: include runtime + renderer, plus user header for the struct definition
309
327
  lines.push('#include <imx/runtime.h>');
310
328
  lines.push('#include <imx/renderer.h>');
329
+ lines.push('#include <vector>');
311
330
  lines.push(`#include "${comp.namedPropsType}.h"`);
312
331
  if (hasColorType) {
313
332
  lines.push('#include <array>');
@@ -328,6 +347,7 @@ export function emitComponent(comp, imports, sourceFile, boundProps, boundPropsM
328
347
  else {
329
348
  // Component with inline props: include its own header instead of redeclaring struct
330
349
  lines.push(`#include "${comp.name}.gen.h"`);
350
+ lines.push('#include <vector>');
331
351
  if (hasColorType) {
332
352
  lines.push('#include <array>');
333
353
  }
@@ -349,6 +369,7 @@ export function emitComponent(comp, imports, sourceFile, boundProps, boundPropsM
349
369
  // No props: standard headers
350
370
  lines.push('#include <imx/runtime.h>');
351
371
  lines.push('#include <imx/renderer.h>');
372
+ lines.push('#include <vector>');
352
373
  if (hasColorType) {
353
374
  lines.push('#include <array>');
354
375
  }
@@ -2283,18 +2304,16 @@ function emitDragInt(node, lines, indent) {
2283
2304
  function emitCombo(node, lines, indent) {
2284
2305
  emitLocComment(node.loc, 'Combo', lines, indent);
2285
2306
  const label = asCharPtr(node.label);
2286
- const itemsList = node.items.split(',').map(s => s.trim()).filter(s => s.length > 0);
2287
- const count = itemsList.length;
2288
- const varName = `combo_items_${comboCounter++}`;
2307
+ const counter = comboCounter++;
2289
2308
  if (node.stateVar) {
2290
2309
  lines.push(`${indent}{`);
2291
2310
  const innerIndent = indent + INDENT;
2292
2311
  const styleVar = buildWidgetStyleVar(node.style, node.width, innerIndent, lines);
2293
2312
  const styleArg = styleVar ? `, ${styleVar}` : '';
2294
- lines.push(`${innerIndent}const char* ${varName}[] = {${itemsList.join(', ')}};`);
2313
+ const { itemsArg, countExpr } = emitStringItemsSource(node.items, node.dynamicItems, 'combo_items', counter, innerIndent, lines);
2295
2314
  lines.push(`${innerIndent}int val = ${node.stateVar}.get();`);
2296
2315
  const changedVar = nextWidgetTemp('combo_changed');
2297
- const resultVar = emitBoolWidgetCall(`imx::renderer::combo(${label}, &val, ${varName}, ${count}${styleArg})`, node.item, lines, innerIndent, changedVar);
2316
+ const resultVar = emitBoolWidgetCall(`imx::renderer::combo(${label}, &val, ${itemsArg}, ${countExpr}${styleArg})`, node.item, lines, innerIndent, changedVar);
2298
2317
  lines.push(`${innerIndent}if (${resultVar}) {`);
2299
2318
  lines.push(`${innerIndent}${INDENT}${node.stateVar}.set(val);`);
2300
2319
  lines.push(`${innerIndent}}`);
@@ -2305,8 +2324,8 @@ function emitCombo(node, lines, indent) {
2305
2324
  const innerIndent = indent + INDENT;
2306
2325
  const styleVar = buildWidgetStyleVar(node.style, node.width, innerIndent, lines);
2307
2326
  const styleArg = styleVar ? `, ${styleVar}` : '';
2308
- lines.push(`${innerIndent}const char* ${varName}[] = {${itemsList.join(', ')}};`);
2309
- emitBoolWidgetCall(`imx::renderer::combo(${label}, ${emitDirectBindPtr(node.valueExpr)}, ${varName}, ${count}${styleArg})`, node.item, lines, innerIndent);
2327
+ const { itemsArg, countExpr } = emitStringItemsSource(node.items, node.dynamicItems, 'combo_items', counter, innerIndent, lines);
2328
+ emitBoolWidgetCall(`imx::renderer::combo(${label}, ${emitDirectBindPtr(node.valueExpr)}, ${itemsArg}, ${countExpr}${styleArg})`, node.item, lines, innerIndent);
2310
2329
  lines.push(`${indent}}`);
2311
2330
  }
2312
2331
  else if (node.valueExpr !== undefined) {
@@ -2314,13 +2333,13 @@ function emitCombo(node, lines, indent) {
2314
2333
  const innerIndent = indent + INDENT;
2315
2334
  const styleVar = buildWidgetStyleVar(node.style, node.width, innerIndent, lines);
2316
2335
  const styleArg = styleVar ? `, ${styleVar}` : '';
2317
- lines.push(`${innerIndent}const char* ${varName}[] = {${itemsList.join(', ')}};`);
2336
+ const { itemsArg, countExpr } = emitStringItemsSource(node.items, node.dynamicItems, 'combo_items', counter, innerIndent, lines);
2318
2337
  lines.push(`${innerIndent}int val = ${node.valueExpr};`);
2319
2338
  const changedVar = nextWidgetTemp('combo_changed');
2320
- const resultVar = emitBoolWidgetCall(`imx::renderer::combo(${label}, &val, ${varName}, ${count}${styleArg})`, node.item, lines, innerIndent, changedVar);
2339
+ const resultVar = emitBoolWidgetCall(`imx::renderer::combo(${label}, &val, ${itemsArg}, ${countExpr}${styleArg})`, node.item, lines, innerIndent, changedVar);
2321
2340
  lines.push(`${innerIndent}if (${resultVar}) {`);
2322
2341
  if (node.onChangeExpr) {
2323
- lines.push(`${innerIndent}${INDENT}${node.onChangeExpr};`);
2342
+ lines.push(`${innerIndent}${INDENT}${node.onChangeExpr}`);
2324
2343
  }
2325
2344
  lines.push(`${innerIndent}}`);
2326
2345
  lines.push(`${indent}}`);
@@ -2479,18 +2498,16 @@ function emitColorEdit3(node, lines, indent) {
2479
2498
  function emitListBox(node, lines, indent) {
2480
2499
  emitLocComment(node.loc, 'ListBox', lines, indent);
2481
2500
  const label = asCharPtr(node.label);
2482
- const itemsList = node.items.split(',').map(s => s.trim()).filter(s => s.length > 0);
2483
- const count = itemsList.length;
2484
- const varName = `listbox_items_${listBoxCounter++}`;
2501
+ const counter = listBoxCounter++;
2485
2502
  if (node.stateVar) {
2486
2503
  lines.push(`${indent}{`);
2487
2504
  const innerIndent = indent + INDENT;
2488
2505
  const styleVar = buildWidgetStyleVar(node.style, node.width, innerIndent, lines);
2489
2506
  const styleArg = styleVar ? `, ${styleVar}` : '';
2490
- lines.push(`${innerIndent}const char* ${varName}[] = {${itemsList.join(', ')}};`);
2507
+ const { itemsArg, countExpr } = emitStringItemsSource(node.items, node.dynamicItems, 'listbox_items', counter, innerIndent, lines);
2491
2508
  lines.push(`${innerIndent}int val = ${node.stateVar}.get();`);
2492
2509
  const changedVar = nextWidgetTemp('list_box_changed');
2493
- const resultVar = emitBoolWidgetCall(`imx::renderer::list_box(${label}, &val, ${varName}, ${count}${styleArg})`, node.item, lines, innerIndent, changedVar);
2510
+ const resultVar = emitBoolWidgetCall(`imx::renderer::list_box(${label}, &val, ${itemsArg}, ${countExpr}${styleArg})`, node.item, lines, innerIndent, changedVar);
2494
2511
  lines.push(`${innerIndent}if (${resultVar}) {`);
2495
2512
  lines.push(`${innerIndent}${INDENT}${node.stateVar}.set(val);`);
2496
2513
  lines.push(`${innerIndent}}`);
@@ -2501,8 +2518,8 @@ function emitListBox(node, lines, indent) {
2501
2518
  const innerIndent = indent + INDENT;
2502
2519
  const styleVar = buildWidgetStyleVar(node.style, node.width, innerIndent, lines);
2503
2520
  const styleArg = styleVar ? `, ${styleVar}` : '';
2504
- lines.push(`${innerIndent}const char* ${varName}[] = {${itemsList.join(', ')}};`);
2505
- emitBoolWidgetCall(`imx::renderer::list_box(${label}, ${emitDirectBindPtr(node.valueExpr)}, ${varName}, ${count}${styleArg})`, node.item, lines, innerIndent);
2521
+ const { itemsArg, countExpr } = emitStringItemsSource(node.items, node.dynamicItems, 'listbox_items', counter, innerIndent, lines);
2522
+ emitBoolWidgetCall(`imx::renderer::list_box(${label}, ${emitDirectBindPtr(node.valueExpr)}, ${itemsArg}, ${countExpr}${styleArg})`, node.item, lines, innerIndent);
2506
2523
  lines.push(`${indent}}`);
2507
2524
  }
2508
2525
  else if (node.valueExpr !== undefined) {
@@ -2510,13 +2527,13 @@ function emitListBox(node, lines, indent) {
2510
2527
  const innerIndent = indent + INDENT;
2511
2528
  const styleVar = buildWidgetStyleVar(node.style, node.width, innerIndent, lines);
2512
2529
  const styleArg = styleVar ? `, ${styleVar}` : '';
2513
- lines.push(`${innerIndent}const char* ${varName}[] = {${itemsList.join(', ')}};`);
2530
+ const { itemsArg, countExpr } = emitStringItemsSource(node.items, node.dynamicItems, 'listbox_items', counter, innerIndent, lines);
2514
2531
  lines.push(`${innerIndent}int val = ${node.valueExpr};`);
2515
2532
  const changedVar = nextWidgetTemp('list_box_changed');
2516
- const resultVar = emitBoolWidgetCall(`imx::renderer::list_box(${label}, &val, ${varName}, ${count}${styleArg})`, node.item, lines, innerIndent, changedVar);
2533
+ const resultVar = emitBoolWidgetCall(`imx::renderer::list_box(${label}, &val, ${itemsArg}, ${countExpr}${styleArg})`, node.item, lines, innerIndent, changedVar);
2517
2534
  lines.push(`${innerIndent}if (${resultVar}) {`);
2518
2535
  if (node.onChangeExpr) {
2519
- lines.push(`${innerIndent}${INDENT}${node.onChangeExpr};`);
2536
+ lines.push(`${innerIndent}${INDENT}${node.onChangeExpr}`);
2520
2537
  }
2521
2538
  lines.push(`${innerIndent}}`);
2522
2539
  lines.push(`${indent}}`);
package/dist/init.js CHANGED
@@ -39,7 +39,7 @@ export function addToProject(projectDir) {
39
39
  console.log(' include(FetchContent)');
40
40
  console.log(' FetchContent_Declare(imx');
41
41
  console.log(' GIT_REPOSITORY https://github.com/bgocumlu/imx.git');
42
- console.log(' GIT_TAG v0.6.9');
42
+ console.log(' GIT_TAG v0.6.10');
43
43
  console.log(' )');
44
44
  console.log(' FetchContent_MakeAvailable(imx)');
45
45
  console.log(' include(ImxCompile)');
package/dist/ir.d.ts CHANGED
@@ -310,6 +310,7 @@ export interface IRCombo {
310
310
  onChangeExpr?: string;
311
311
  directBind?: boolean;
312
312
  items: string;
313
+ dynamicItems?: boolean;
313
314
  width?: string;
314
315
  style?: string;
315
316
  item?: IRItemInteraction;
@@ -359,6 +360,7 @@ export interface IRListBox {
359
360
  onChangeExpr?: string;
360
361
  directBind?: boolean;
361
362
  items: string;
363
+ dynamicItems?: boolean;
362
364
  width?: string;
363
365
  style?: string;
364
366
  item?: IRItemInteraction;
package/dist/lowering.js CHANGED
@@ -1876,6 +1876,40 @@ function lowerValueOnChange(rawAttrs, ctx) {
1876
1876
  }
1877
1877
  return { stateVar, valueExpr, onChangeExpr, directBind };
1878
1878
  }
1879
+ function lowerIndexedValueOnChange(rawAttrs, ctx, valueName) {
1880
+ let stateVar = '';
1881
+ let valueExpr;
1882
+ let onChangeExpr;
1883
+ let directBind;
1884
+ const valueRaw = rawAttrs.get('value');
1885
+ if (valueRaw && ts.isIdentifier(valueRaw) && ctx.stateVars.has(valueRaw.text)) {
1886
+ stateVar = valueRaw.text;
1887
+ }
1888
+ else if (valueRaw) {
1889
+ valueExpr = exprToCpp(valueRaw, ctx);
1890
+ const onChangeRaw = rawAttrs.get('onChange');
1891
+ if (onChangeRaw) {
1892
+ const { paramName, bodyCode } = lowerParameterizedCallback(onChangeRaw, ctx, valueName);
1893
+ onChangeExpr = paramName === valueName
1894
+ ? bodyCode
1895
+ : `auto ${paramName} = ${valueName}; ${bodyCode}`;
1896
+ }
1897
+ else if (ts.isPropertyAccessExpression(valueRaw)) {
1898
+ directBind = true;
1899
+ }
1900
+ }
1901
+ return { stateVar, valueExpr, onChangeExpr, directBind };
1902
+ }
1903
+ function lowerItemsSource(attrs, rawAttrs, ctx) {
1904
+ const itemsRaw = rawAttrs.get('items');
1905
+ if (!itemsRaw) {
1906
+ return { items: attrs['items'] ?? '' };
1907
+ }
1908
+ if (ts.isArrayLiteralExpression(itemsRaw)) {
1909
+ return { items: exprToCpp(itemsRaw, ctx) };
1910
+ }
1911
+ return { items: exprToCpp(itemsRaw, ctx), dynamicItems: true };
1912
+ }
1879
1913
  function lowerSliderFloat(attrs, rawAttrs, body, ctx, loc) {
1880
1914
  const label = attrs['label'] ?? '""';
1881
1915
  const min = attrs['min'] ?? '0.0f';
@@ -1948,12 +1982,12 @@ function lowerDragInt(attrs, rawAttrs, body, ctx, loc) {
1948
1982
  }
1949
1983
  function lowerCombo(attrs, rawAttrs, body, ctx, loc) {
1950
1984
  const label = attrs['label'] ?? '""';
1951
- const items = attrs['items'] ?? '';
1952
1985
  const width = attrs['width'];
1953
1986
  const style = attrs['style'];
1954
- const { stateVar, valueExpr, onChangeExpr, directBind } = lowerValueOnChange(rawAttrs, ctx);
1987
+ const { items, dynamicItems } = lowerItemsSource(attrs, rawAttrs, ctx);
1988
+ const { stateVar, valueExpr, onChangeExpr, directBind } = lowerIndexedValueOnChange(rawAttrs, ctx, 'val');
1955
1989
  const item = lowerItemInteraction(attrs, rawAttrs, ctx);
1956
- body.push({ kind: 'combo', label, stateVar, valueExpr, onChangeExpr, directBind, items, width, style, item, loc });
1990
+ body.push({ kind: 'combo', label, stateVar, valueExpr, onChangeExpr, directBind, items, dynamicItems, width, style, item, loc });
1957
1991
  }
1958
1992
  function lowerInputInt(attrs, rawAttrs, body, ctx, loc) {
1959
1993
  const label = attrs['label'] ?? '""';
@@ -2035,12 +2069,12 @@ function lowerColorEdit3(attrs, rawAttrs, body, ctx, loc) {
2035
2069
  }
2036
2070
  function lowerListBox(attrs, rawAttrs, body, ctx, loc) {
2037
2071
  const label = attrs['label'] ?? '""';
2038
- const items = attrs['items'] ?? '';
2039
2072
  const width = attrs['width'];
2040
2073
  const style = attrs['style'];
2041
- const { stateVar, valueExpr, onChangeExpr, directBind } = lowerValueOnChange(rawAttrs, ctx);
2074
+ const { items, dynamicItems } = lowerItemsSource(attrs, rawAttrs, ctx);
2075
+ const { stateVar, valueExpr, onChangeExpr, directBind } = lowerIndexedValueOnChange(rawAttrs, ctx, 'val');
2042
2076
  const item = lowerItemInteraction(attrs, rawAttrs, ctx);
2043
- body.push({ kind: 'list_box', label, stateVar, valueExpr, onChangeExpr, directBind, items, width, style, item, loc });
2077
+ body.push({ kind: 'list_box', label, stateVar, valueExpr, onChangeExpr, directBind, items, dynamicItems, width, style, item, loc });
2044
2078
  }
2045
2079
  function lowerProgressBar(attrs, rawAttrs, body, ctx, loc) {
2046
2080
  const value = attrs['value'] ?? '0.0f';
@@ -428,7 +428,7 @@ set(FETCHCONTENT_QUIET OFF)
428
428
  FetchContent_Declare(
429
429
  imx
430
430
  GIT_REPOSITORY https://github.com/bgocumlu/imx.git
431
- GIT_TAG v0.6.9
431
+ GIT_TAG v0.6.10
432
432
  GIT_SHALLOW TRUE
433
433
  GIT_PROGRESS TRUE
434
434
  )
@@ -313,7 +313,7 @@ set(FETCHCONTENT_QUIET OFF)
313
313
  FetchContent_Declare(
314
314
  imx
315
315
  GIT_REPOSITORY https://github.com/bgocumlu/imx.git
316
- GIT_TAG v0.6.9
316
+ GIT_TAG v0.6.10
317
317
  GIT_SHALLOW TRUE
318
318
  GIT_PROGRESS TRUE
319
319
  )
@@ -402,7 +402,7 @@ set(FETCHCONTENT_QUIET OFF)
402
402
  FetchContent_Declare(
403
403
  imx
404
404
  GIT_REPOSITORY ${repoUrl}
405
- GIT_TAG v0.6.9
405
+ GIT_TAG v0.6.10
406
406
  GIT_SHALLOW TRUE
407
407
  GIT_PROGRESS TRUE
408
408
  )
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "imxc",
3
- "version": "0.6.9",
3
+ "version": "0.6.10",
4
4
  "description": "Compiler for IMX — compiles React-like .tsx to native Dear ImGui C++",
5
5
  "type": "module",
6
6
  "bin": {