Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

implement inc/dec as desugared magic #440

Closed
wants to merge 3 commits into from
Closed
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
14 changes: 14 additions & 0 deletions lib/std/system.nim
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,20 @@ template `[]=`*[T](x: ptr T, val: T) =
template `[]=`*[T](x: ref T, val: T) =
(x[]) = val

proc inc*[T, V: Ordinal](x: T, y: V) {.magic: "Inc", noSideEffect.}
## Increments the ordinal `x` by `y`.

proc dec*[T, V: Ordinal](x: T, y: V) {.magic: "Dec", noSideEffect.}
## Decrements the ordinal `x` by `y`.

template inc*[T: Ordinal](x: T) =
# workaround for no default params
inc x, 1

template dec*[T: Ordinal](x: T) =
# workaround for no default params
dec x, 1

# integer calculations:
proc `+`*(x: int8): int8 {.magic: "UnaryPlusI", noSideEffect.}
proc `+`*(x: int16): int16 {.magic: "UnaryPlusI", noSideEffect.}
Expand Down
42 changes: 41 additions & 1 deletion src/hexer/desugar.nim
Original file line number Diff line number Diff line change
Expand Up @@ -313,7 +313,7 @@ proc genInclExcl(c: var Context; dest: var TokenBuf; n: var Cursor) =
let a: Cursor
let b: Cursor
if useTemp:
dest.add parLeToken(ExprX, info)
dest.add parLeToken(StmtsS, info)
# lift both so (n, (n = 123; n)) works
a = liftTempAddr(c, dest, aOrig, typ, info)
b = liftTemp(c, dest, bOrig, typ, info)
Expand Down Expand Up @@ -383,6 +383,44 @@ proc genInclExcl(c: var Context; dest: var TokenBuf; n: var Cursor) =
dest.addParRi()
c.tempUseBufStack.shrink(oldBufStackLen)

proc genIncDec(c: var Context; dest: var TokenBuf; n: var Cursor) =
let info = n.info
let kind = n.stmtKind
inc n
let typ = n
skip n
var argsBuf = createTokenBuf(16)
swap dest, argsBuf
let aStart = dest.len
tr(c, dest, n)
let bStart = dest.len
tr(c, dest, n)
swap dest, argsBuf
skipParRi n
let aOrig = cursorAt(argsBuf, aStart)
let bOrig = cursorAt(argsBuf, bStart)
let useTemp = needsTemp(aOrig) or needsTemp(bOrig)
let oldBufStackLen = c.tempUseBufStack.len
let a: Cursor
let b: Cursor
if useTemp:
dest.add parLeToken(StmtsS, info)
# lift both so (n, (n = 123; n)) works
a = liftTempAddr(c, dest, aOrig, typ, info)
b = liftTemp(c, dest, bOrig, typ, info)
else:
a = aOrig
b = bOrig
copyIntoKind dest, AsgnS, info:
dest.addSubtree a
copyIntoKind dest, if kind == IncS: AddX else: SubX, info:
dest.addSubtree typ
dest.addSubtree a
dest.addSubtree b
if useTemp:
dest.addParRi()
c.tempUseBufStack.shrink(oldBufStackLen)

proc tr(c: var Context; dest: var TokenBuf; n: var Cursor) =
case n.kind
of DotToken, UnknownToken, EofToken, Ident, Symbol, SymbolDef, IntLit, UIntLit, FloatLit, CharLit, StringLit:
Expand All @@ -399,6 +437,8 @@ proc tr(c: var Context; dest: var TokenBuf; n: var Cursor) =
trSons(c, dest, n)
else:
trSons(c, dest, n)
of IncS, DecS:
genIncDec(c, dest, n)
of InclSetS, ExclSetS:
genInclExcl(c, dest, n)
of CaseS:
Expand Down
2 changes: 1 addition & 1 deletion src/hexer/nifcgen.nim
Original file line number Diff line number Diff line change
Expand Up @@ -1164,7 +1164,7 @@ proc traverseStmt(e: var EContext; c: var Cursor; mode = TraverseAll) =
of BlockS: traverseBlock e, c
of IfS: traverseIf e, c
of CaseS: traverseCase e, c
of YieldS, ForS, InclSetS, ExclSetS:
of YieldS, ForS, IncS, DecS, InclSetS, ExclSetS:
error e, "BUG: not eliminated: ", c
of TryS, RaiseS:
error e, "BUG: not implemented: ", c
Expand Down
2 changes: 1 addition & 1 deletion src/hexer/xelim.nim
Original file line number Diff line number Diff line change
Expand Up @@ -367,7 +367,7 @@ proc trStmt(c: var Context; dest: var TokenBuf; n: var Cursor) =

of WhileS:
trWhile c, dest, n
of AsgnS, CallS, InclSetS, ExclSetS:
of AsgnS, CallS, IncS, DecS, InclSetS, ExclSetS:
# IMPORTANT: Stores into `tar` helper!
var tar = Target(m: IsAppend)
tar.t.copyInto n:
Expand Down
2 changes: 2 additions & 0 deletions src/nimony/magics.nim
Original file line number Diff line number Diff line change
Expand Up @@ -174,6 +174,8 @@ proc magicToTag*(m: TMagic): (string, int) =
of mDefaultObj: res DefaultObjX
of mDefaultTup: res DefaultTupX
of mOpenArray: res OpenArrayT
of mInc: res IncS, TypedMagic
of mDec: res DecS, TypedMagic
of mPlusSet: res PlusSetX, TypedMagic
of mMinusSet: res MinusSetX, TypedMagic
of mMulSet: res MulSetX, TypedMagic
Expand Down
2 changes: 2 additions & 0 deletions src/nimony/nimony_model.nim
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,8 @@ type
ExportS = "export"
CommentS = "comment"
PragmasLineS = "pragmas"
IncS = "inc"
DecS = "dec"
InclSetS = "incl"
ExclSetS = "excl"

Expand Down
17 changes: 17 additions & 0 deletions src/nimony/sem.nim
Original file line number Diff line number Diff line change
Expand Up @@ -4885,6 +4885,20 @@ proc semPragmasLine(c: var SemContext; it: var Item) =

skipParRi it.n

proc semIncDec(c: var SemContext; it: var Item) =
let info = it.n.info
let beforeExpr = c.dest.len
takeToken c, it.n
let typeStart = c.dest.len
semLocalTypeImpl c, it.n, InLocalDecl
let typ = typeToCursor(c, typeStart)
var op = Item(n: it.n, typ: typ)
semExpr c, op
semExpr c, op
it.n = op.n
wantParRi c, it.n
producesVoid c, info, it.typ

proc semInclExcl(c: var SemContext; it: var Item) =
let info = it.n.info
let beforeExpr = c.dest.len
Expand Down Expand Up @@ -5086,6 +5100,9 @@ proc semExpr(c: var SemContext; it: var Item; flags: set[SemFlag] = {}) =
of PragmasLineS:
toplevelGuard c:
semPragmasLine c, it
of IncS, DecS:
toplevelGuard c:
semIncDec c, it
of InclSetS, ExclSetS:
toplevelGuard c:
semInclExcl c, it
Expand Down
2 changes: 1 addition & 1 deletion src/nimony/sigmatch.nim
Original file line number Diff line number Diff line change
Expand Up @@ -246,7 +246,7 @@ proc matchesConstraintAux(m: var Match; f: var Cursor; a: Cursor): bool =
assert f.kind == ParRi
inc f
of OrdinalT:
result = isOrdinalType(a)
result = isOrdinalType(a) or a.typeKind == OrdinalT
skip f
else:
result = false
Expand Down
22 changes: 11 additions & 11 deletions tests/nimony/sysbasics/tforloops1.nif
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
(mul
(i -1) ~1 i.0 1 i.0)) ,2
(yld 9
(mul 20,279,lib/std/system.nim
(mul 20,307,lib/std/system.nim
(i +64) ~2
(mul
(i -1) ~1 i.0 1 i.0) 1 i.0)) 2,3
Expand Down Expand Up @@ -60,10 +60,10 @@
(le 13,~2
(i -1) ~2 i.2 3 b.0) 2,1
(stmts
(yld 6 i.2) 2,1
(asgn ~2 i.2 4
(add 13,~4
(i -1) ~2 i.2 2 +1)))))) 4,22
(yld 6 i.2) 11,227,lib/std/system.nim
(stmts
(inc 23,17,tests/nimony/sysbasics/tforloops1.nim
(i -1) 8,21,tests/nimony/sysbasics/tforloops1.nim i.2 7 +1)))))) 4,22
(for 12
(call ~7 countup.0.tfo6yv57p 1 +1 4 +5)
(unpackflat
Expand All @@ -76,7 +76,7 @@
(hconv 11,~16
(cstring) "countup start\3A %ld\0A") 25 m.1) ,2
(if 3
(elif 11,786,lib/std/system.nim
(elif 11,814,lib/std/system.nim
(expr 2,1
(lt
(i -1) 9,26,tests/nimony/sysbasics/tforloops1.nim +5 5,26,tests/nimony/sysbasics/tforloops1.nim x.0)) ~1,1
Expand All @@ -102,10 +102,10 @@
(le
(i -1) ~2 i.3 3 n.1) 2,1
(stmts
(yld 6 i.3) 2,1
(asgn ~2 i.3 4
(add
(i -1) ~2 i.3 2 +1)))))) ,37
(yld 6 i.3) 11,227,lib/std/system.nim
(stmts
(inc
(i -1) 8,36,tests/nimony/sysbasics/tforloops1.nim i.3 7 +1)))))) ,37
(iterator 9 :powers2.0.tfo6yv57p . . . 16
(params 1
(param :n.2 . . 3
Expand All @@ -123,7 +123,7 @@
(mul ~1,~9
(i -1) ~1 i.4 1 i.4)) ,2
(yld 9
(mul 20,279,lib/std/system.nim
(mul 20,307,lib/std/system.nim
(i +64) ~2
(mul ~1,~10
(i -1) ~1 i.4 1 i.4) 1 i.4)))))) 4,43
Expand Down
4 changes: 2 additions & 2 deletions tests/nimony/sysbasics/tforloops1.nim
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ iterator countup(a, b: int): int =
var i = a
while i <= b:
yield i # establish as the for loop variable
i = i + 1
inc i

for x in countup(1, 5):
let m = x
Expand All @@ -33,7 +33,7 @@ iterator countup2(n: int): int =
var i = 0
while i <= n:
yield i
i = i + 1
inc i

iterator powers2(n: int): int =
for i in countup2(n):
Expand Down
Loading