add switch break parsing

This commit is contained in:
Skillbert
2025-01-29 10:39:48 +01:00
parent 365f554bfe
commit e5195ded04
2 changed files with 27 additions and 4 deletions

View File

@@ -286,6 +286,19 @@ export class WhileLoopStatementNode extends AstNode {
}
}
type ControlStatementType = "break" | "continue";
export class ControlStatementNode extends AstNode {
type: ControlStatementType;
constructor(originalindex: number, type: ControlStatementType) {
super(originalindex);
this.type = type;
}
getOpcodes(ctx: OpcodeWriterContext): never {
throw new Error("break/continue statements failed to process. only break at end of switch case supported");
}
}
export class SwitchStatementNode extends AstNode {
branches: { value: number, block: CodeBlockNode }[] = [];
valueop: AstNode | null;

View File

@@ -1,5 +1,5 @@
import { has, hasMore, parse, optional, invert, isEnd } from "../libs/yieldparser";
import { AstNode, BranchingStatement, CodeBlockNode, FunctionBindNode, IfStatementNode, RawOpcodeNode, VarAssignNode, WhileLoopStatementNode, SwitchStatementNode, ClientScriptFunction, ComposedOp, parseClientScriptIm, SubcallNode, isNamedOp, getNodeStackOut, setRawOpcodeStackDiff } from "./ast";
import { AstNode, BranchingStatement, CodeBlockNode, FunctionBindNode, IfStatementNode, RawOpcodeNode, VarAssignNode, WhileLoopStatementNode, SwitchStatementNode, ClientScriptFunction, ComposedOp, parseClientScriptIm, SubcallNode, isNamedOp, getNodeStackOut, setRawOpcodeStackDiff, ControlStatementNode } from "./ast";
import { ClientscriptObfuscation, OpcodeInfo } from "./callibrator";
import { TsWriterContext } from "./codewriter";
import { binaryOpIds, binaryOpSymbols, typeToPrimitive, knownClientScriptOpNames, namedClientScriptOps, variableSources, StackDiff, StackInOut, StackList, StackTypeExt, getParamOps, dynamicOps, subtypes, subtypeToTs, ExactStack, tsToSubtype, getOpName, PrimitiveType, makeop, primitiveToUknownExact, StackConstants, longBigIntToJson } from "./definitions";
@@ -545,7 +545,7 @@ function scriptContext(ctx: ParseContext) {
yield "{";
yield whitespace;
let cases: { value: number, block: CodeBlockNode }[] = [];
let defaultcase = null;
let defaultcase: CodeBlockNode | null = null;
while (!(yield has("}"))) {
let entries: { type: "case" | "default", value: number }[] = [];
while (true) {
@@ -554,7 +554,11 @@ function scriptContext(ctx: ParseContext) {
yield whitespace;
entries.push(entry);
}
let block = yield [codeBlock];
let block: CodeBlockNode = yield [codeBlock];
let lastchild = block.children.at(-1);
if (lastchild instanceof ControlStatementNode && lastchild.type == "break") {
block.remove(lastchild);
}
yield whitespace;
for (let { type, value } of entries) {
if (type == "case") {
@@ -568,6 +572,12 @@ function scriptContext(ctx: ParseContext) {
return node;
}
function* controlStatement() {
let type = yield ["break", "continue"];
yield whitespace;
return new ControlStatementNode(-1, type);
}
function* ifStatement() {
yield "if";
yield whitespace;
@@ -711,7 +721,7 @@ function scriptContext(ctx: ParseContext) {
}
function* statement() {
return yield [functionStatement, ifStatement, whileStatement, switchStatement, returnStatement, assignStatement, valueStatement];
return yield [functionStatement, ifStatement, whileStatement, switchStatement, returnStatement, controlStatement, assignStatement, valueStatement];
}
function* statementlist() {