diff options
-rw-r--r-- | changelog.md | 1 | ||||
-rw-r--r-- | compiler/ast.nim | 2 | ||||
-rw-r--r-- | compiler/ccgexprs.nim | 4 | ||||
-rw-r--r-- | compiler/condsyms.nim | 1 | ||||
-rw-r--r-- | compiler/vmgen.nim | 22 | ||||
-rw-r--r-- | lib/system.nim | 4 | ||||
-rw-r--r-- | tests/vm/treset.nim | 27 |
7 files changed, 50 insertions, 11 deletions
diff --git a/changelog.md b/changelog.md index 86bc99ef7..4cfc9f490 100644 --- a/changelog.md +++ b/changelog.md @@ -130,6 +130,7 @@ proc enumToString*(enums: openArray[enum]): string = - Added the `posix_utils` module. +- Added `system.default`. ### Library changes diff --git a/compiler/ast.nim b/compiler/ast.nim index 607b497fb..b325e6d42 100644 --- a/compiler/ast.nim +++ b/compiler/ast.nim @@ -635,7 +635,7 @@ type mSwap, mIsNil, mArrToSeq, mCopyStr, mCopyStrLast, mNewString, mNewStringOfCap, mParseBiggestFloat, mMove, mWasMoved, mDestroy, - mReset, + mDefault, mReset, mArray, mOpenArray, mRange, mSet, mSeq, mOpt, mVarargs, mRef, mPtr, mVar, mDistinct, mVoid, mTuple, mOrdinal, diff --git a/compiler/ccgexprs.nim b/compiler/ccgexprs.nim index 99b658d46..406528845 100644 --- a/compiler/ccgexprs.nim +++ b/compiler/ccgexprs.nim @@ -1153,6 +1153,9 @@ proc genReset(p: BProc, n: PNode) = addrLoc(p.config, a), genTypeInfo(p.module, skipTypes(a.t, {tyVar}), n.info)) +proc genDefault(p: BProc; n: PNode; d: var TLoc) = + resetLoc(p, d) + proc rawGenNew(p: BProc, a: TLoc, sizeExpr: Rope) = var sizeExpr = sizeExpr let typ = a.t @@ -2063,6 +2066,7 @@ proc genMagicExpr(p: BProc, e: PNode, d: var TLoc, op: TMagic) = addf(p.module.s[cfsDynLibInit], "\t$1 = ($2) hcrGetProc($3, \"$1\");$n", [mangleDynLibProc(prc), getTypeDesc(p.module, prc.loc.t), getModuleDllPath(p.module, prc)]) genCall(p, e, d) + of mDefault: genDefault(p, e, d) of mReset: genReset(p, e) of mEcho: genEcho(p, e[1].skipConv) of mArrToSeq: genArrToSeq(p, e, d) diff --git a/compiler/condsyms.nim b/compiler/condsyms.nim index 57dd55132..15127e108 100644 --- a/compiler/condsyms.nim +++ b/compiler/condsyms.nim @@ -85,6 +85,7 @@ proc initDefines*(symbols: StringTableRef) = defineSymbol("nimHasHotCodeReloading") defineSymbol("nimHasNilSeqs") defineSymbol("nimHasSignatureHashInMacro") + defineSymbol("nimHasDefault") for f in low(Feature)..high(Feature): defineSymbol("nimHas" & $f) diff --git a/compiler/vmgen.nim b/compiler/vmgen.nim index 092c25a46..2d9166be0 100644 --- a/compiler/vmgen.nim +++ b/compiler/vmgen.nim @@ -910,6 +910,15 @@ proc genBindSym(c: PCtx; n: PNode; dest: var TDest) = c.gABC(n, opcNDynBindSym, dest, x, n.len) c.freeTempRange(x, n.len) +proc fitsRegister*(t: PType): bool = + assert t != nil + t.skipTypes(abstractInst-{tyTypeDesc}).kind in { + tyRange, tyEnum, tyBool, tyInt..tyUInt64, tyChar} + +proc ldNullOpcode(t: PType): TOpcode = + assert t != nil + if fitsRegister(t): opcLdNullReg else: opcLdNull + proc genMagic(c: PCtx; n: PNode; dest: var TDest; m: TMagic) = case m of mAnd: c.genAndOr(n, opcFJmp, dest) @@ -1129,9 +1138,13 @@ proc genMagic(c: PCtx; n: PNode; dest: var TDest; m: TMagic) = of mReset: unused(c, n, dest) var d = c.genx(n.sons[1]) + # XXX use ldNullOpcode() here? c.gABx(n, opcLdNull, d, c.genType(n.sons[1].typ)) c.gABx(n, opcNodeToReg, d, d) c.genAsgnPatch(n.sons[1], d) + of mDefault: + if dest < 0: dest = c.getTemp(n.typ) + c.gABx(n, ldNullOpcode(n.typ), dest, c.genType(n.typ)) of mOf, mIs: if dest < 0: dest = c.getTemp(n.typ) var tmp = c.genx(n.sons[1]) @@ -1332,11 +1345,6 @@ const tyFloat, tyFloat32, tyFloat64, tyFloat128, tyUInt, tyUInt8, tyUInt16, tyUInt32, tyUInt64} -proc fitsRegister*(t: PType): bool = - assert t != nil - t.skipTypes(abstractInst-{tyTypeDesc}).kind in { - tyRange, tyEnum, tyBool, tyInt..tyUInt64, tyChar} - proc unneededIndirection(n: PNode): bool = n.typ.skipTypes(abstractInstOwned-{tyTypeDesc}).kind == tyRef @@ -1766,10 +1774,6 @@ proc getNullValue(typ: PType, info: TLineInfo; conf: ConfigRef): PNode = globalError(conf, info, "cannot create null element for: " & $t.kind) result = newNodeI(nkEmpty, info) -proc ldNullOpcode(t: PType): TOpcode = - assert t != nil - if fitsRegister(t): opcLdNullReg else: opcLdNull - proc genVarSection(c: PCtx; n: PNode) = for a in n: if a.kind == nkCommentStmt: continue diff --git a/lib/system.nim b/lib/system.nim index 0bfbd22f7..59565d6c6 100644 --- a/lib/system.nim +++ b/lib/system.nim @@ -4278,6 +4278,10 @@ proc `$`*(t: typedesc): string {.magic: "TypeTrait".} = doAssert $(type("Foo")) == "string" static: doAssert $(type(@['A', 'B'])) == "seq[char]" +when defined(nimHasDefault): + proc default*(T: typedesc): T {.magic: "Default", noSideEffect.} + ## returns the default value of the type ``T``. + import system/widestrs export widestrs diff --git a/tests/vm/treset.nim b/tests/vm/treset.nim index 56fe19b19..ff8bc5b83 100644 --- a/tests/vm/treset.nim +++ b/tests/vm/treset.nim @@ -1,3 +1,6 @@ +discard """ + output: '''0''' +""" static: type Obj = object field: int @@ -5,6 +8,17 @@ static: reset(o) doAssert o.field == 0 + var x = 4 + reset(x) + doAssert x == 0 + +static: + type ObjB = object + field: int + var o = ObjB(field: 1) + o = default(ObjB) + doAssert o.field == 0 + static: var i = 2 reset(i) @@ -25,4 +39,15 @@ static: var i = 2 reset(i) doAssert i == 0 - f() \ No newline at end of file + f() + +proc main = + var y = [1, 2, 3, 4] + y = default(array[4, int]) + for a in y: doAssert(a == 0) + + var x = 4 + x = default(int) + echo x + +main() |