Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion src/codegen/expressions/method-calls.ts
Original file line number Diff line number Diff line change
Expand Up @@ -343,7 +343,8 @@ export class MethodCallGenerator {
const isArr =
this.ctx.isArrayExpression(arg) ||
this.ctx.isStringArrayExpression(arg) ||
this.ctx.isObjectArrayExpression(arg);
this.ctx.isObjectArrayExpression(arg) ||
this.ctx.isUint8ArrayExpression(arg);
return isArr ? "1.0" : "0.0";
}
return null;
Expand Down
8 changes: 4 additions & 4 deletions src/codegen/infrastructure/base-generator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ export class BaseGenerator {
public labelCounter: number = 0;
public stringCounter: number = 0;
public output: string[];
public outputIsTerminator: boolean[] = [];
public outputIsTerminator: number[] = [];
public outputCount: number = 0;
public allocaInstructions: string[]; // Collected allocas to hoist to entry block
public globalStrings: string[];
Expand Down Expand Up @@ -274,7 +274,7 @@ export class BaseGenerator {
this.allocaInstructions.push(dbgInstruction);
} else {
this.output.push(dbgInstruction);
this.outputIsTerminator.push(false);
this.outputIsTerminator.push(0);
this.outputCount++;
}
} else {
Expand Down Expand Up @@ -469,14 +469,14 @@ export class BaseGenerator {
this.globalStrings.push(str);
}

protected classifyTerminator(instruction: string): boolean {
protected classifyTerminator(instruction: string): number {
return classifyTerminator(instruction);
}

lastInstructionIsTerminator(): boolean {
const len = this.outputIsTerminator.length;
if (len === 0) return false;
return this.outputIsTerminator[len - 1];
return this.outputIsTerminator[len - 1] !== 0;
}

emitRet(type: string, value: string): void {
Expand Down
8 changes: 4 additions & 4 deletions src/codegen/infrastructure/generator-context.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1007,7 +1007,7 @@ export class MockGeneratorContext implements IGeneratorContext {
private labelCount = 0;
private stringCount = 0;
public output: string[] = [];
public outputIsTerminator: boolean[] = [];
public outputIsTerminator: number[] = [];
public allocaInstructions: string[] = [];
public symbolTable: SymbolTable;
public diagnostics?: DiagnosticEngine;
Expand Down Expand Up @@ -1555,14 +1555,14 @@ export class MockGeneratorContext implements IGeneratorContext {
this.outputIsTerminator.push(this.classifyTerminatorImpl(instruction));
}

private classifyTerminatorImpl(instruction: string): boolean {
private classifyTerminatorImpl(instruction: string): number {
return classifyTerminator(instruction);
}

lastInstructionIsTerminator(): boolean {
const len = this.outputIsTerminator.length;
if (len === 0) return false;
return this.outputIsTerminator[len - 1];
return this.outputIsTerminator[len - 1] !== 0;
}

emitRet(type: string, value: string): void {
Expand Down Expand Up @@ -1657,7 +1657,7 @@ export class MockGeneratorContext implements IGeneratorContext {

setOutputLine(index: number, line: string): void {
const newOutput: string[] = [];
const newIsTerminator: boolean[] = [];
const newIsTerminator: number[] = [];
for (let i = 0; i < this.output.length; i++) {
if (i === index) {
newOutput.push(line);
Expand Down
14 changes: 7 additions & 7 deletions src/codegen/infrastructure/integer-analysis.ts
Original file line number Diff line number Diff line change
Expand Up @@ -221,14 +221,14 @@ class IntegerAnalyzer {
this.collectVarDecls(statements, allDecls);

const candidates: string[] = [];
const isConst: boolean[] = [];
const isConst: number[] = [];
const pendingDecls: VariableDeclaration[] = [];

this.candidateNames = [];
if (paramNames) {
for (let pi = 0; pi < paramNames.length; pi++) {
candidates.push(paramNames[pi]);
isConst.push(false);
isConst.push(0);
this.candidateNames.push(paramNames[pi]);
}
}
Expand All @@ -238,7 +238,7 @@ class IntegerAnalyzer {
if (!varDecl.value) continue;
if (this.isIntegerExpressionForCandidacy(varDecl.value)) {
candidates.push(varDecl.name);
isConst.push(varDecl.kind === "const");
isConst.push(varDecl.kind === "const" ? 1 : 0);
this.candidateNames.push(varDecl.name);
} else {
pendingDecls.push(varDecl);
Expand All @@ -257,7 +257,7 @@ class IntegerAnalyzer {
if (!varDecl.value) continue;
if (this.isIntegerExpressionForCandidacy(varDecl.value)) {
candidates.push(varDecl.name);
isConst.push(varDecl.kind === "const");
isConst.push(varDecl.kind === "const" ? 1 : 0);
this.candidateNames.push(varDecl.name);
added = true;
} else {
Expand All @@ -269,9 +269,9 @@ class IntegerAnalyzer {

if (candidates.length === 0) return [];

const isDemoted: boolean[] = [];
const isDemoted: number[] = [];
for (let k = 0; k < candidates.length; k++) {
isDemoted.push(false);
isDemoted.push(0);
}

const allAssignments: AssignmentStatement[] = [];
Expand All @@ -286,7 +286,7 @@ class IntegerAnalyzer {
if (candidates[j] === stmt.name) {
if (isConst[j]) break;
if (!isDemoted[j] && !this.isIntegerExpression(stmt.value)) {
isDemoted[j] = true;
isDemoted[j] = 1;
this.removeCandidate(candidates[j]);
changed = true;
}
Expand Down
8 changes: 5 additions & 3 deletions src/codegen/infrastructure/terminator-classifier.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
export function classifyTerminator(instruction: string): boolean {
export function classifyTerminator(instruction: string): number {
const trimmed = instruction.trim();
return (
if (
trimmed.startsWith("ret ") ||
trimmed === "ret void" ||
trimmed.startsWith("br ") ||
trimmed.startsWith("unreachable") ||
trimmed.startsWith("switch ")
);
)
return 1;
return 0;
}
2 changes: 2 additions & 0 deletions src/codegen/infrastructure/type-inference.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2039,6 +2039,7 @@ export class TypeInference {
isUint8ArrayExpression(expr: Expression): boolean {
const resolved = this.resolveExpressionType(expr);
if (resolved && resolved.base === "Uint8Array" && resolved.arrayDepth === 0) return true;
if (resolved && resolved.base === "boolean" && resolved.arrayDepth === 1) return true;
const e = expr as ExprBase;
if (e.type === "new") {
const newExpr = expr as NewNode;
Expand All @@ -2047,6 +2048,7 @@ export class TypeInference {
if (e.type === "variable") {
const varName = (expr as VariableNode).name;
if (this.st.isUint8Array(varName)) return true;
if (this.st.isBooleanArray(varName)) return true;
}
// ChadScript.getEmbeddedFileAsUint8Array() returns Uint8Array
if (e.type === "method_call") {
Expand Down
3 changes: 2 additions & 1 deletion src/codegen/infrastructure/type-system.ts
Original file line number Diff line number Diff line change
Expand Up @@ -194,7 +194,8 @@ function basicTypeToLlvm(tsType: string): string | null {
}

function collectionTypeToLlvm(tsType: string): string | null {
if (tsType === "number[]" || tsType === "boolean[]") return "%Array*";
if (tsType === "number[]") return "%Array*";
if (tsType === "boolean[]") return "%Uint8Array*";
if (tsType === "Uint8Array") return "%Uint8Array*";
if (tsType.endsWith("[]")) return "%ObjectArray*";
if (tsType === "Set<string>") return "%StringSet*";
Expand Down
32 changes: 29 additions & 3 deletions src/codegen/infrastructure/variable-allocator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -572,7 +572,18 @@ export class VariableAllocator {
);
this.ctx.emit(`${allocaReg} = alloca %StringArray*`);
this.ctx.emit(`store %StringArray* null, %StringArray** ${allocaReg}`);
} else if (baseType === "number[]" || baseType === "boolean[]") {
} else if (baseType === "boolean[]") {
this.ctx.defineVariableWithMetadata(
stmt.name,
allocaReg,
"%Uint8Array*",
SymbolKind_Uint8Array,
"local",
createPointerAllocaMetadata(),
);
this.ctx.emit(`${allocaReg} = alloca %Uint8Array*`);
this.ctx.emit(`store %Uint8Array* null, %Uint8Array** ${allocaReg}`);
} else if (baseType === "number[]") {
this.ctx.defineVariableWithMetadata(
stmt.name,
allocaReg,
Expand Down Expand Up @@ -711,7 +722,9 @@ export class VariableAllocator {
const strippedType = stripNullable(stmt.declaredType);
if (strippedType === "string[]") {
this.ctx.setExpectedArrayElementType("string");
} else if (strippedType === "number[]" || strippedType === "boolean[]") {
} else if (strippedType === "boolean[]") {
this.ctx.setExpectedArrayElementType("boolean");
} else if (strippedType === "number[]") {
this.ctx.setExpectedArrayElementType("number");
} else if (strippedType.endsWith("[]")) {
this.ctx.setExpectedArrayElementType("pointer");
Expand Down Expand Up @@ -1704,7 +1717,20 @@ export class VariableAllocator {
this.ctx.emit(`store %StringArray* null, %StringArray** ${allocaReg}`);
return;
}
if (baseType === "number[]" || baseType === "boolean[]") {
if (baseType === "boolean[]") {
this.ctx.defineVariableWithMetadata(
stmt.name,
allocaReg,
"%Uint8Array*",
SymbolKind_Uint8Array,
"local",
createPointerAllocaMetadata(),
);
this.ctx.emit(`${allocaReg} = alloca %Uint8Array*`);
this.ctx.emit(`store %Uint8Array* null, %Uint8Array** ${allocaReg}`);
return;
}
if (baseType === "number[]") {
this.ctx.defineVariableWithMetadata(
stmt.name,
allocaReg,
Expand Down
44 changes: 29 additions & 15 deletions src/codegen/llvm-generator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1090,7 +1090,7 @@ export class LLVMGenerator extends BaseGenerator implements IGeneratorContext {
}
public setOutputLine(index: number, line: string): void {
const newOutput: string[] = [];
const newIsTerminator: boolean[] = [];
const newIsTerminator: number[] = [];
for (let i = 0; i < this.output.length; i++) {
if (i === index) {
newOutput.push(line);
Expand Down Expand Up @@ -2213,7 +2213,8 @@ export class LLVMGenerator extends BaseGenerator implements IGeneratorContext {
isString = base === "string" && depth === 0;
isStringArray = base === "string" && depth > 0;
isObjectArray = depth > 0 && base !== "string" && base !== "number" && base !== "boolean";
isArray = depth > 0 && (base === "number" || base === "boolean");
isArray = depth > 0 && base === "number";
if (depth > 0 && base === "boolean") isUint8Array = true;
isMap = base === "Map" || base.startsWith("Map<");
isSet = base === "Set" || base.startsWith("Set<");
isRegex = base === "RegExp";
Expand Down Expand Up @@ -2268,6 +2269,10 @@ export class LLVMGenerator extends BaseGenerator implements IGeneratorContext {
isUint8Array = true;
isString = false;
}
if (!isUint8Array && stmt.declaredType === "boolean[]") {
isUint8Array = true;
isArray = false;
}
if (
!isClassInstance &&
stmt.value &&
Expand Down Expand Up @@ -2420,6 +2425,14 @@ export class LLVMGenerator extends BaseGenerator implements IGeneratorContext {
this.symbolTable.setResolvedType(name, parseTypeString(stmt.declaredType));
}
continue;
} else if (isUint8Array) {
llvmType = "%Uint8Array*";
kind = SymbolKind_Uint8Array;
defaultValue = "null";
ir += `@${name} = global ${llvmType} ${defaultValue}` + "\n";
this.globalVariables.set(name, { llvmType, kind, initialized: false });
this.defineVariable(name, `@${name}`, llvmType, kind, "global");
continue;
} else if (isArray) {
llvmType = "%Array*";
kind = SymbolKind_Array;
Expand Down Expand Up @@ -2591,14 +2604,6 @@ export class LLVMGenerator extends BaseGenerator implements IGeneratorContext {
llvmType = "i8*";
kind = SymbolKind_Regex;
defaultValue = "null";
} else if (isUint8Array) {
llvmType = "%Uint8Array*";
kind = SymbolKind_Uint8Array;
defaultValue = "null";
ir += `@${name} = global ${llvmType} ${defaultValue}` + "\n";
this.globalVariables.set(name, { llvmType, kind, initialized: false });
this.defineVariable(name, `@${name}`, llvmType, kind, "global");
continue;
} else if (isClassInstance) {
let className = "";
const stmtValueType = (stmt.value as { type: string }).type;
Expand Down Expand Up @@ -2669,10 +2674,10 @@ export class LLVMGenerator extends BaseGenerator implements IGeneratorContext {
defaultValue = "0.0";
} else if (strippedDeclaredType === "string[]") {
isStringArray = true;
} else if (
strippedDeclaredType === "number[]" ||
strippedDeclaredType === "boolean[]"
) {
} else if (strippedDeclaredType === "boolean[]") {
isUint8Array = true;
isArray = false;
} else if (strippedDeclaredType === "number[]") {
isArray = true;
} else if (strippedDeclaredType.endsWith("[]")) {
isObjectArray = true;
Expand Down Expand Up @@ -2781,7 +2786,16 @@ export class LLVMGenerator extends BaseGenerator implements IGeneratorContext {
this.defineVariable(name, `@${name}`, "%StringArray*", SymbolKind_StringArray, "global");
return `@${name} = global %StringArray* null\n`;
}
if (baseType === "number[]" || baseType === "boolean[]") {
if (baseType === "boolean[]") {
this.globalVariables.set(name, {
llvmType: "%Uint8Array*",
kind: SymbolKind_Uint8Array,
initialized: false,
});
this.defineVariable(name, `@${name}`, "%Uint8Array*", SymbolKind_Uint8Array, "global");
return `@${name} = global %Uint8Array* null\n`;
}
if (baseType === "number[]") {
this.globalVariables.set(name, {
llvmType: "%Array*",
kind: SymbolKind_Array,
Expand Down
Loading
Loading