c-next 0.2.17 → 0.2.18
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/README.md +2 -2
- package/dist/index.js +7645 -5941
- package/dist/index.js.map +4 -4
- package/grammar/CNext.g4 +8 -0
- package/package.json +1 -3
- package/src/transpiler/Transpiler.ts +286 -26
- package/src/transpiler/__tests__/compileCommandsDiscovery.integration.test.ts +94 -0
- package/src/transpiler/__tests__/externalSymbolRecovery.integration.test.ts +215 -0
- package/src/transpiler/logic/__tests__/detectAssemblySyntax.test.ts +116 -0
- package/src/transpiler/logic/analysis/FunctionCallAnalyzer.ts +8 -0
- package/src/transpiler/logic/analysis/MixedTypeCategoryAnalyzer.ts +408 -0
- package/src/transpiler/logic/analysis/PassByValueAnalyzer.ts +16 -97
- package/src/transpiler/logic/analysis/ReturnPathAnalyzer.ts +171 -0
- package/src/transpiler/logic/analysis/__tests__/MixedTypeCategoryAnalyzer.test.ts +346 -0
- package/src/transpiler/logic/analysis/__tests__/ReturnPathAnalyzer.test.ts +232 -0
- package/src/transpiler/logic/analysis/runAnalyzers.ts +23 -2
- package/src/transpiler/logic/analysis/types/IMixedTypeCategoryError.ts +17 -0
- package/src/transpiler/logic/analysis/types/IReturnPathError.ts +12 -0
- package/src/transpiler/logic/detectAssemblySyntax.ts +80 -0
- package/src/transpiler/logic/parser/grammar/CNext.interp +4 -1
- package/src/transpiler/logic/parser/grammar/CNext.tokens +169 -167
- package/src/transpiler/logic/parser/grammar/CNextLexer.interp +4 -1
- package/src/transpiler/logic/parser/grammar/CNextLexer.tokens +169 -167
- package/src/transpiler/logic/parser/grammar/CNextLexer.ts +545 -541
- package/src/transpiler/logic/parser/grammar/CNextListener.ts +11 -0
- package/src/transpiler/logic/parser/grammar/CNextParser.ts +1257 -1185
- package/src/transpiler/logic/parser/grammar/CNextVisitor.ts +7 -0
- package/src/transpiler/logic/preprocessor/CompileCommandsReader.ts +332 -0
- package/src/transpiler/logic/preprocessor/ExternalDeclarationOracle.ts +202 -0
- package/src/transpiler/logic/preprocessor/Preprocessor.ts +24 -6
- package/src/transpiler/logic/preprocessor/ToolchainDetector.ts +42 -1
- package/src/transpiler/logic/preprocessor/__tests__/CompileCommandsReader.test.ts +216 -0
- package/src/transpiler/logic/preprocessor/__tests__/ExternalDeclarationOracle.test.ts +153 -0
- package/src/transpiler/logic/preprocessor/__tests__/Preprocessor.test.ts +43 -18
- package/src/transpiler/logic/preprocessor/__tests__/ToolchainDetector.crossCompiler.test.ts +75 -0
- package/src/transpiler/logic/preprocessor/__tests__/fixtures/oracle/dependent.h +7 -0
- package/src/transpiler/logic/preprocessor/__tests__/fixtures/oracle/predecessor.h +5 -0
- package/src/transpiler/logic/preprocessor/types/ICompileCommandsResult.ts +14 -0
- package/src/transpiler/logic/preprocessor/types/IPreprocessOptions.ts +17 -0
- package/src/transpiler/logic/symbols/SymbolTable.ts +45 -0
- package/src/transpiler/logic/symbols/__tests__/SymbolTable.test.ts +49 -0
- package/src/transpiler/output/MisraSuppressionUtils.ts +52 -0
- package/src/transpiler/output/__tests__/MisraSuppressionUtils.test.ts +67 -0
- package/src/transpiler/output/codegen/CodeGenerator.ts +45 -4
- package/src/transpiler/output/codegen/TypeResolver.ts +148 -0
- package/src/transpiler/output/codegen/TypeValidator.ts +179 -81
- package/src/transpiler/output/codegen/__tests__/CodeGenerator.test.ts +13 -1
- package/src/transpiler/output/codegen/__tests__/TypeResolver.test.ts +93 -0
- package/src/transpiler/output/codegen/__tests__/TypeValidator.alwaysTrueLoop.test.ts +91 -0
- package/src/transpiler/output/codegen/__tests__/TypeValidator.test.ts +86 -14
- package/src/transpiler/output/codegen/assignment/AssignmentClassifier.ts +13 -0
- package/src/transpiler/output/codegen/assignment/AssignmentKind.ts +1 -1
- package/src/transpiler/output/codegen/assignment/handlers/AccessPatternHandlers.ts +20 -12
- package/src/transpiler/output/codegen/assignment/handlers/ArrayHandlers.ts +424 -22
- package/src/transpiler/output/codegen/assignment/handlers/BitAccessHandlers.ts +31 -18
- package/src/transpiler/output/codegen/assignment/handlers/BitmapHandlers.ts +7 -8
- package/src/transpiler/output/codegen/assignment/handlers/RegisterHandlers.ts +6 -8
- package/src/transpiler/output/codegen/assignment/handlers/RegisterUtils.ts +12 -10
- package/src/transpiler/output/codegen/assignment/handlers/SimpleHandler.ts +3 -7
- package/src/transpiler/output/codegen/assignment/handlers/SpecialHandlers.ts +7 -9
- package/src/transpiler/output/codegen/assignment/handlers/StringHandlers.ts +12 -10
- package/src/transpiler/output/codegen/assignment/handlers/__tests__/ArrayHandlers.test.ts +479 -11
- package/src/transpiler/output/codegen/generators/IOrchestrator.ts +3 -0
- package/src/transpiler/output/codegen/generators/expressions/CallExprGenerator.ts +28 -15
- package/src/transpiler/output/codegen/generators/expressions/PostfixExpressionGenerator.ts +26 -13
- package/src/transpiler/output/codegen/generators/expressions/__tests__/PostfixExpressionGenerator.test.ts +129 -1
- package/src/transpiler/output/codegen/generators/statements/ControlFlowGenerator.ts +64 -8
- package/src/transpiler/output/codegen/generators/statements/__tests__/ControlFlowGenerator.test.ts +8 -5
- package/src/transpiler/output/codegen/helpers/AssignmentExpectedTypeResolver.ts +30 -2
- package/src/transpiler/output/codegen/helpers/StringDeclHelper.ts +16 -13
- package/src/transpiler/output/codegen/helpers/__tests__/AssignmentExpectedTypeResolver.test.ts +19 -0
- package/src/transpiler/output/codegen/helpers/__tests__/StringDeclHelper.test.ts +57 -11
- package/src/transpiler/output/codegen/subscript/SubscriptClassifier.ts +30 -11
- package/src/transpiler/output/codegen/subscript/TSubscriptKind.ts +1 -1
- package/src/transpiler/output/codegen/subscript/__tests__/SubscriptClassifier.test.ts +38 -6
- package/src/transpiler/output/headers/HeaderGeneratorUtils.ts +65 -24
- package/src/transpiler/state/CodeGenState.ts +20 -16
- package/src/transpiler/types/ICachedFileEntry.ts +7 -0
- package/src/utils/cache/CacheManager.ts +13 -2
- package/src/utils/cache/__tests__/CacheManager.test.ts +18 -1
- package/src/utils/constants/TypeConstants.ts +13 -0
|
@@ -1740,15 +1740,37 @@ describe("TypeValidator", () => {
|
|
|
1740
1740
|
// ========================================================================
|
|
1741
1741
|
|
|
1742
1742
|
describe("validateTernaryCondition", () => {
|
|
1743
|
-
it("
|
|
1743
|
+
it("throws for || of bare value operands (each operand must be a comparison)", () => {
|
|
1744
1744
|
setupState();
|
|
1745
1745
|
const ctx = createMockOrExpression("a || b", { hasOr: true });
|
|
1746
|
+
expect(() => TypeValidator.validateTernaryCondition(ctx)).toThrow(
|
|
1747
|
+
"E0701",
|
|
1748
|
+
);
|
|
1749
|
+
});
|
|
1750
|
+
|
|
1751
|
+
it("allows || of comparison operands", () => {
|
|
1752
|
+
setupState();
|
|
1753
|
+
const ctx = createMockOrExpression("a = 1 || b = 2", {
|
|
1754
|
+
hasOr: true,
|
|
1755
|
+
hasEquality: true,
|
|
1756
|
+
});
|
|
1746
1757
|
expect(() => TypeValidator.validateTernaryCondition(ctx)).not.toThrow();
|
|
1747
1758
|
});
|
|
1748
1759
|
|
|
1749
|
-
it("
|
|
1760
|
+
it("throws for && of bare value operands (each operand must be a comparison)", () => {
|
|
1750
1761
|
setupState();
|
|
1751
1762
|
const ctx = createMockOrExpression("a && b", { hasAnd: true });
|
|
1763
|
+
expect(() => TypeValidator.validateTernaryCondition(ctx)).toThrow(
|
|
1764
|
+
"E0701",
|
|
1765
|
+
);
|
|
1766
|
+
});
|
|
1767
|
+
|
|
1768
|
+
it("allows && of comparison operands", () => {
|
|
1769
|
+
setupState();
|
|
1770
|
+
const ctx = createMockOrExpression("a = 1 && b = 2", {
|
|
1771
|
+
hasAnd: true,
|
|
1772
|
+
hasEquality: true,
|
|
1773
|
+
});
|
|
1752
1774
|
expect(() => TypeValidator.validateTernaryCondition(ctx)).not.toThrow();
|
|
1753
1775
|
});
|
|
1754
1776
|
|
|
@@ -1768,7 +1790,7 @@ describe("TypeValidator", () => {
|
|
|
1768
1790
|
setupState();
|
|
1769
1791
|
const ctx = createMockOrExpression("flag");
|
|
1770
1792
|
expect(() => TypeValidator.validateTernaryCondition(ctx)).toThrow(
|
|
1771
|
-
"
|
|
1793
|
+
"E0701",
|
|
1772
1794
|
);
|
|
1773
1795
|
});
|
|
1774
1796
|
|
|
@@ -1779,7 +1801,7 @@ describe("TypeValidator", () => {
|
|
|
1779
1801
|
andExpression: antlrArray([]),
|
|
1780
1802
|
} as unknown as Parser.OrExpressionContext;
|
|
1781
1803
|
expect(() => TypeValidator.validateTernaryCondition(ctx)).toThrow(
|
|
1782
|
-
"
|
|
1804
|
+
"E0701",
|
|
1783
1805
|
);
|
|
1784
1806
|
});
|
|
1785
1807
|
|
|
@@ -1791,7 +1813,7 @@ describe("TypeValidator", () => {
|
|
|
1791
1813
|
andExpression: antlrArray([andExpr]),
|
|
1792
1814
|
} as unknown as Parser.OrExpressionContext;
|
|
1793
1815
|
expect(() => TypeValidator.validateTernaryCondition(ctx)).toThrow(
|
|
1794
|
-
"
|
|
1816
|
+
"E0701",
|
|
1795
1817
|
);
|
|
1796
1818
|
});
|
|
1797
1819
|
|
|
@@ -1804,7 +1826,7 @@ describe("TypeValidator", () => {
|
|
|
1804
1826
|
andExpression: antlrArray([andExpr]),
|
|
1805
1827
|
} as unknown as Parser.OrExpressionContext;
|
|
1806
1828
|
expect(() => TypeValidator.validateTernaryCondition(ctx)).toThrow(
|
|
1807
|
-
"
|
|
1829
|
+
"E0701",
|
|
1808
1830
|
);
|
|
1809
1831
|
});
|
|
1810
1832
|
});
|
|
@@ -1898,17 +1920,39 @@ describe("TypeValidator", () => {
|
|
|
1898
1920
|
).not.toThrow();
|
|
1899
1921
|
});
|
|
1900
1922
|
|
|
1901
|
-
it("
|
|
1923
|
+
it("throws for && of bare value operands (each operand must be a comparison)", () => {
|
|
1902
1924
|
setupState();
|
|
1903
1925
|
const ctx = createFullDoWhileExpression("a && b", { hasAnd: true });
|
|
1926
|
+
expect(() =>
|
|
1927
|
+
TypeValidator.validateConditionIsBoolean(ctx, "do-while"),
|
|
1928
|
+
).toThrow("E0701");
|
|
1929
|
+
});
|
|
1930
|
+
|
|
1931
|
+
it("allows && of comparison operands", () => {
|
|
1932
|
+
setupState();
|
|
1933
|
+
const ctx = createFullDoWhileExpression("a = 1 && b = 2", {
|
|
1934
|
+
hasAnd: true,
|
|
1935
|
+
hasEquality: true,
|
|
1936
|
+
});
|
|
1904
1937
|
expect(() =>
|
|
1905
1938
|
TypeValidator.validateConditionIsBoolean(ctx, "do-while"),
|
|
1906
1939
|
).not.toThrow();
|
|
1907
1940
|
});
|
|
1908
1941
|
|
|
1909
|
-
it("
|
|
1942
|
+
it("throws for || of bare value operands (each operand must be a comparison)", () => {
|
|
1910
1943
|
setupState();
|
|
1911
1944
|
const ctx = createFullDoWhileExpression("a || b", { hasOr: true });
|
|
1945
|
+
expect(() =>
|
|
1946
|
+
TypeValidator.validateConditionIsBoolean(ctx, "do-while"),
|
|
1947
|
+
).toThrow("E0701");
|
|
1948
|
+
});
|
|
1949
|
+
|
|
1950
|
+
it("allows || of comparison operands", () => {
|
|
1951
|
+
setupState();
|
|
1952
|
+
const ctx = createFullDoWhileExpression("a = 1 || b = 2", {
|
|
1953
|
+
hasOr: true,
|
|
1954
|
+
hasEquality: true,
|
|
1955
|
+
});
|
|
1912
1956
|
expect(() =>
|
|
1913
1957
|
TypeValidator.validateConditionIsBoolean(ctx, "do-while"),
|
|
1914
1958
|
).not.toThrow();
|
|
@@ -1938,7 +1982,7 @@ describe("TypeValidator", () => {
|
|
|
1938
1982
|
).toThrow("E0701");
|
|
1939
1983
|
});
|
|
1940
1984
|
|
|
1941
|
-
it("
|
|
1985
|
+
it("throws for boolean literal condition (Issue #1042)", () => {
|
|
1942
1986
|
setupState();
|
|
1943
1987
|
// Create full mock expression tree where getText returns "true"
|
|
1944
1988
|
const bitwiseOrExpr = {
|
|
@@ -1969,10 +2013,10 @@ describe("TypeValidator", () => {
|
|
|
1969
2013
|
} as unknown as Parser.ExpressionContext;
|
|
1970
2014
|
expect(() =>
|
|
1971
2015
|
TypeValidator.validateConditionIsBoolean(ctx, "do-while"),
|
|
1972
|
-
).
|
|
2016
|
+
).toThrow("E0701");
|
|
1973
2017
|
});
|
|
1974
2018
|
|
|
1975
|
-
it("
|
|
2019
|
+
it("throws for negation expression (Issue #1042)", () => {
|
|
1976
2020
|
setupState();
|
|
1977
2021
|
const bitwiseOrExpr = {
|
|
1978
2022
|
bitwiseXorExpression: antlrArray([]),
|
|
@@ -2002,10 +2046,10 @@ describe("TypeValidator", () => {
|
|
|
2002
2046
|
} as unknown as Parser.ExpressionContext;
|
|
2003
2047
|
expect(() =>
|
|
2004
2048
|
TypeValidator.validateConditionIsBoolean(ctx, "do-while"),
|
|
2005
|
-
).
|
|
2049
|
+
).toThrow("E0701");
|
|
2006
2050
|
});
|
|
2007
2051
|
|
|
2008
|
-
it("
|
|
2052
|
+
it("throws for bare bool type variable (Issue #1042)", () => {
|
|
2009
2053
|
const typeRegistry = new Map<string, TTypeInfo>([
|
|
2010
2054
|
[
|
|
2011
2055
|
"isReady",
|
|
@@ -2041,7 +2085,7 @@ describe("TypeValidator", () => {
|
|
|
2041
2085
|
} as unknown as Parser.ExpressionContext;
|
|
2042
2086
|
expect(() =>
|
|
2043
2087
|
TypeValidator.validateConditionIsBoolean(ctx, "do-while"),
|
|
2044
|
-
).
|
|
2088
|
+
).toThrow("E0701");
|
|
2045
2089
|
});
|
|
2046
2090
|
|
|
2047
2091
|
it("shows help message in error", () => {
|
|
@@ -2052,6 +2096,34 @@ describe("TypeValidator", () => {
|
|
|
2052
2096
|
).toThrow("help: use explicit comparison: count > 0 or count != 0");
|
|
2053
2097
|
});
|
|
2054
2098
|
|
|
2099
|
+
it("suggests `= true` for a bare bool operand (Issue #1042)", () => {
|
|
2100
|
+
const typeRegistry = new Map<string, TTypeInfo>([
|
|
2101
|
+
[
|
|
2102
|
+
"ready",
|
|
2103
|
+
{ baseType: "bool", bitWidth: 8, isArray: false, isConst: false },
|
|
2104
|
+
],
|
|
2105
|
+
]);
|
|
2106
|
+
setupState({ typeRegistry });
|
|
2107
|
+
const ctx = createFullDoWhileExpression("ready");
|
|
2108
|
+
expect(() =>
|
|
2109
|
+
TypeValidator.validateConditionIsBoolean(ctx, "do-while"),
|
|
2110
|
+
).toThrow("help: use explicit comparison: ready = true");
|
|
2111
|
+
});
|
|
2112
|
+
|
|
2113
|
+
it("suggests `= false` for a negated bool operand (Issue #1042)", () => {
|
|
2114
|
+
const typeRegistry = new Map<string, TTypeInfo>([
|
|
2115
|
+
[
|
|
2116
|
+
"ready",
|
|
2117
|
+
{ baseType: "bool", bitWidth: 8, isArray: false, isConst: false },
|
|
2118
|
+
],
|
|
2119
|
+
]);
|
|
2120
|
+
setupState({ typeRegistry });
|
|
2121
|
+
const ctx = createFullDoWhileExpression("!ready");
|
|
2122
|
+
expect(() =>
|
|
2123
|
+
TypeValidator.validateConditionIsBoolean(ctx, "do-while"),
|
|
2124
|
+
).toThrow("help: use explicit comparison: ready = false");
|
|
2125
|
+
});
|
|
2126
|
+
|
|
2055
2127
|
it("throws when no andExpression", () => {
|
|
2056
2128
|
setupState();
|
|
2057
2129
|
const orExpr = {
|
|
@@ -415,9 +415,22 @@ class AssignmentClassifier {
|
|
|
415
415
|
const firstId = ctx.identifiers[0];
|
|
416
416
|
|
|
417
417
|
if (ctx.hasArrayAccess) {
|
|
418
|
+
// Direct register: global.REG.MEMBER[bit]
|
|
418
419
|
if (CodeGenState.symbols!.knownRegisters.has(firstId)) {
|
|
419
420
|
return AssignmentKind.GLOBAL_REGISTER_BIT;
|
|
420
421
|
}
|
|
422
|
+
// Scoped register: global.Scope.REG.MEMBER[bit] — mirror
|
|
423
|
+
// classifyRegisterBitAccess so the bit-range mask/shift is expanded
|
|
424
|
+
// rather than emitting a literal subscript (Issue #1052).
|
|
425
|
+
if (
|
|
426
|
+
CodeGenState.isKnownScope(firstId) &&
|
|
427
|
+
ctx.identifiers.length >= 3 &&
|
|
428
|
+
CodeGenState.symbols!.knownRegisters.has(
|
|
429
|
+
`${firstId}_${ctx.identifiers[1]}`,
|
|
430
|
+
)
|
|
431
|
+
) {
|
|
432
|
+
return AssignmentKind.GLOBAL_REGISTER_BIT;
|
|
433
|
+
}
|
|
421
434
|
return AssignmentKind.GLOBAL_ARRAY;
|
|
422
435
|
}
|
|
423
436
|
|
|
@@ -85,7 +85,7 @@ enum AssignmentKind {
|
|
|
85
85
|
/** matrix[i][j] <- value (multi-dimensional array element) */
|
|
86
86
|
MULTI_DIM_ARRAY_ELEMENT,
|
|
87
87
|
|
|
88
|
-
/** buffer[0, 10] <- source (slice assignment
|
|
88
|
+
/** buffer[0, 10] <- source (slice assignment: per-element little-endian writes, ADR-007/#1081) */
|
|
89
89
|
ARRAY_SLICE,
|
|
90
90
|
|
|
91
91
|
// === Special operations ===
|
|
@@ -15,12 +15,6 @@ import BitUtils from "../../../../../utils/BitUtils";
|
|
|
15
15
|
import TAssignmentHandler from "./TAssignmentHandler";
|
|
16
16
|
import RegisterUtils from "./RegisterUtils";
|
|
17
17
|
import CodeGenState from "../../../../state/CodeGenState";
|
|
18
|
-
import type ICodeGenApi from "../../types/ICodeGenApi";
|
|
19
|
-
|
|
20
|
-
/** Get typed generator reference */
|
|
21
|
-
function gen(): ICodeGenApi {
|
|
22
|
-
return CodeGenState.generator as ICodeGenApi;
|
|
23
|
-
}
|
|
24
18
|
|
|
25
19
|
/**
|
|
26
20
|
* Common handler for global access patterns (GLOBAL_MEMBER and GLOBAL_ARRAY).
|
|
@@ -32,10 +26,15 @@ function handleGlobalAccess(ctx: IAssignmentContext): string {
|
|
|
32
26
|
|
|
33
27
|
// Validate cross-scope visibility if first id is a scope
|
|
34
28
|
if (CodeGenState.isKnownScope(firstId) && ctx.identifiers.length >= 2) {
|
|
35
|
-
|
|
29
|
+
CodeGenState.requireGenerator().validateCrossScopeVisibility(
|
|
30
|
+
firstId,
|
|
31
|
+
ctx.identifiers[1],
|
|
32
|
+
);
|
|
36
33
|
}
|
|
37
34
|
|
|
38
|
-
const target =
|
|
35
|
+
const target = CodeGenState.requireGenerator().generateAssignmentTarget(
|
|
36
|
+
ctx.targetCtx,
|
|
37
|
+
);
|
|
39
38
|
return `${target} ${ctx.cOp} ${ctx.generatedValue};`;
|
|
40
39
|
}
|
|
41
40
|
|
|
@@ -49,7 +48,9 @@ function handleThisAccess(ctx: IAssignmentContext): string {
|
|
|
49
48
|
throw new Error("Error: 'this' can only be used inside a scope");
|
|
50
49
|
}
|
|
51
50
|
|
|
52
|
-
const target =
|
|
51
|
+
const target = CodeGenState.requireGenerator().generateAssignmentTarget(
|
|
52
|
+
ctx.targetCtx,
|
|
53
|
+
);
|
|
53
54
|
return `${target} ${ctx.cOp} ${ctx.generatedValue};`;
|
|
54
55
|
}
|
|
55
56
|
|
|
@@ -100,7 +101,9 @@ function handleGlobalRegisterBit(ctx: IAssignmentContext): string {
|
|
|
100
101
|
}
|
|
101
102
|
|
|
102
103
|
// Single bit
|
|
103
|
-
const bitIndex =
|
|
104
|
+
const bitIndex = CodeGenState.requireGenerator().generateExpression(
|
|
105
|
+
ctx.subscripts[0],
|
|
106
|
+
);
|
|
104
107
|
|
|
105
108
|
if (isWriteOnly) {
|
|
106
109
|
if (ctx.generatedValue === "false" || ctx.generatedValue === "0") {
|
|
@@ -126,7 +129,10 @@ function handleGlobalRegisterBit(ctx: IAssignmentContext): string {
|
|
|
126
129
|
*/
|
|
127
130
|
function handleMemberChain(ctx: IAssignmentContext): string {
|
|
128
131
|
// Check if this is bit access on a struct member
|
|
129
|
-
const bitAnalysis =
|
|
132
|
+
const bitAnalysis =
|
|
133
|
+
CodeGenState.requireGenerator().analyzeMemberChainForBitAccess(
|
|
134
|
+
ctx.targetCtx,
|
|
135
|
+
);
|
|
130
136
|
|
|
131
137
|
if (bitAnalysis.isBitAccess) {
|
|
132
138
|
// Validate compound operators not supported for bit access
|
|
@@ -144,7 +150,9 @@ function handleMemberChain(ctx: IAssignmentContext): string {
|
|
|
144
150
|
}
|
|
145
151
|
|
|
146
152
|
// Normal member chain assignment
|
|
147
|
-
const target =
|
|
153
|
+
const target = CodeGenState.requireGenerator().generateAssignmentTarget(
|
|
154
|
+
ctx.targetCtx,
|
|
155
|
+
);
|
|
148
156
|
return `${target} ${ctx.cOp} ${ctx.generatedValue};`;
|
|
149
157
|
}
|
|
150
158
|
|