parameter runtime discriminators (#11397)
* allow param for runtime discriminator construction
This commit is contained in:
parent
bfa32e8d99
commit
fc4f0808c4
3 changed files with 20 additions and 4 deletions
|
|
@ -236,7 +236,8 @@ proc enumToString*(enums: openArray[enum]): string =
|
||||||
pragmas for further analysis by macros
|
pragmas for further analysis by macros
|
||||||
- Custom pragmas are now supported for `var` and `let` symbols.
|
- Custom pragmas are now supported for `var` and `let` symbols.
|
||||||
- Tuple unpacking is now supported for constants and for loop variables.
|
- Tuple unpacking is now supported for constants and for loop variables.
|
||||||
|
- Case object branches can be initialized with a runtime discriminator if
|
||||||
|
possible discriminator values are constrained within a case statement.
|
||||||
|
|
||||||
### Language changes
|
### Language changes
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -129,8 +129,10 @@ proc formatUnsafeBranchVals(t: PType, diffVals: IntSet): string =
|
||||||
|
|
||||||
proc findUsefulCaseContext(c: PContext, discrimator: PNode): (PNode, int) =
|
proc findUsefulCaseContext(c: PContext, discrimator: PNode): (PNode, int) =
|
||||||
for i in countdown(c.p.caseContext.high, 0):
|
for i in countdown(c.p.caseContext.high, 0):
|
||||||
let (caseNode, index) = c.p.caseContext[i]
|
let
|
||||||
if caseNode[0].kind == nkSym and caseNode[0].sym == discrimator.sym:
|
(caseNode, index) = c.p.caseContext[i]
|
||||||
|
skipped = caseNode[0].skipHidden
|
||||||
|
if skipped.kind == nkSym and skipped.sym == discrimator.sym:
|
||||||
return (caseNode, index)
|
return (caseNode, index)
|
||||||
|
|
||||||
proc pickCaseBranch(caseExpr, matched: PNode): PNode =
|
proc pickCaseBranch(caseExpr, matched: PNode): PNode =
|
||||||
|
|
@ -252,7 +254,8 @@ proc semConstructFields(c: PContext, recNode: PNode,
|
||||||
let (ctorCase, ctorIdx) = findUsefulCaseContext(c, discriminatorVal)
|
let (ctorCase, ctorIdx) = findUsefulCaseContext(c, discriminatorVal)
|
||||||
if ctorCase == nil:
|
if ctorCase == nil:
|
||||||
badDiscriminatorError()
|
badDiscriminatorError()
|
||||||
elif discriminatorVal.sym.kind != skLet:
|
elif discriminatorVal.sym.kind notin {skLet, skParam} or
|
||||||
|
discriminatorVal.sym.typ.kind == tyVar:
|
||||||
localError(c.config, discriminatorVal.info,
|
localError(c.config, discriminatorVal.info,
|
||||||
"runtime discriminator must be immutable if branch fields are " &
|
"runtime discriminator must be immutable if branch fields are " &
|
||||||
"initialized, a 'let' binding is required.")
|
"initialized, a 'let' binding is required.")
|
||||||
|
|
|
||||||
|
|
@ -136,3 +136,15 @@ reject: # not immutable.
|
||||||
of k1, k2, k3: discard KindObj(varkind: kind, i32: 1)
|
of k1, k2, k3: discard KindObj(varkind: kind, i32: 1)
|
||||||
of k4: discard KindObj(varkind: kind, f32: 2.0)
|
of k4: discard KindObj(varkind: kind, f32: 2.0)
|
||||||
else: discard KindObj(varkind: kind, str: "3")
|
else: discard KindObj(varkind: kind, str: "3")
|
||||||
|
|
||||||
|
accept:
|
||||||
|
proc kindProc(kind: Kind): KindObj =
|
||||||
|
case kind:
|
||||||
|
of k1: result = KindObj(kind: kind, i32: 1)
|
||||||
|
else: discard
|
||||||
|
|
||||||
|
reject:
|
||||||
|
proc varKindProc(kind: var Kind): KindObj =
|
||||||
|
case kind:
|
||||||
|
of k1: result = KindObj(kind: kind, i32: 1)
|
||||||
|
else: discard
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue