From ccb72c784d02769e381f65c5701ac62d7e4e8c11 Mon Sep 17 00:00:00 2001 From: metagn Date: Tue, 12 Nov 2024 16:32:43 +0300 Subject: [PATCH] cbuilder: adapt `switch` generation with `if` fallbacks (#24428) Follows up #24420, uses a similar method of using `untyped` params with injected variables as #24410 to replace format string arguments. --- compiler/ccgstmts.nim | 66 ++++++++++++++++++++++++++++--------------- 1 file changed, 44 insertions(+), 22 deletions(-) diff --git a/compiler/ccgstmts.nim b/compiler/ccgstmts.nim index bc05b79058..5512ed01c8 100644 --- a/compiler/ccgstmts.nim +++ b/compiler/ccgstmts.nim @@ -884,18 +884,23 @@ proc genRaiseStmt(p: BProc, t: PNode) = p.s(cpsStmts).addCallStmt(cgsymValue(p.module, "reraiseException")) raiseInstr(p, p.s(cpsStmts)) -template genCaseGenericBranch(p: BProc, b: PNode, e: TLoc, - rangeFormat, eqFormat: FormatStr, labl: TLabel) = +template genCaseGenericBranch(p: BProc, b: PNode, e: TLoc, labl: TLabel, + rangeFormat, eqFormat: untyped) = var x, y: TLoc for i in 0.. 0: genIfForCaseUntil(p, n, d, - rangeFormat = "if ($1 >= $2 && $1 <= $3) goto $4;$n", - eqFormat = "if ($1 == $2) goto $3;$n", - splitPoint, a) else: "" + var lend: TLabel = "" + if splitPoint > 0: + lend = genIfForCaseUntil(p, n, d, splitPoint, a): + p.s(cpsStmts).addSingleIfStmt(cOp(And, + cOp(GreaterEqual, ra, rb), + cOp(LessEqual, ra, rc))): + p.s(cpsStmts).addGoto(rlabel) + do: + p.s(cpsStmts).addSingleIfStmt( + removeSinglePar(cOp(Equal, ra, rb))): + p.s(cpsStmts).addGoto(rlabel) # generate switch part (might be empty): if splitPoint+1 < n.len: @@ -1098,8 +1113,15 @@ proc genCase(p: BProc, t: PNode, d: var TLoc) = of tyCstring: genStringCase(p, t, tyCstring, d) of tyFloat..tyFloat128: - genCaseGeneric(p, t, d, "if ($1 >= $2 && $1 <= $3) goto $4;$n", - "if ($1 == $2) goto $3;$n") + genCaseGeneric(p, t, d): + p.s(cpsStmts).addSingleIfStmt(cOp(And, + cOp(GreaterEqual, ra, rb), + cOp(LessEqual, ra, rc))): + p.s(cpsStmts).addGoto(rlabel) + do: + p.s(cpsStmts).addSingleIfStmt( + removeSinglePar(cOp(Equal, ra, rb))): + p.s(cpsStmts).addGoto(rlabel) else: if t[0].kind == nkSym and sfGoto in t[0].sym.flags: genGotoForCase(p, t)