Skip to content

Commit

Permalink
tuple subscripts as overload, always generate TupAt for gear3 (#346)
Browse files Browse the repository at this point in the history
* tuple indexes, broken until untyped templates

* compiles but not in C

* updated naming

* fix names again

* delete ahead of merge

* fix merge

* always generate TupAt, transform in gear3

* test output
  • Loading branch information
metagn authored Jan 10, 2025
1 parent 36c7a43 commit 5213495
Show file tree
Hide file tree
Showing 6 changed files with 61 additions and 23 deletions.
3 changes: 3 additions & 0 deletions lib/std/system.nim
Original file line number Diff line number Diff line change
Expand Up @@ -75,8 +75,11 @@ proc low*[I, T](x: typedesc[array[I, T]]): I {.magic: "Low", noSideEffect.}
proc high*[T: Ordinal|enum|range](x: typedesc[T]): T {.magic: "High", noSideEffect.}
proc high*[I, T](x: typedesc[array[I, T]]): I {.magic: "High", noSideEffect.}

proc `[]`*[T: tuple](x: T, i: int): untyped {.magic: "TupAt".}
proc `[]`*[I, T](x: array[I, T], i: I): var T {.magic: "ArrAt".}
proc `[]`*(x: cstring, i: int): var char {.magic: "Pat".}
template `[]=`*[T: tuple](x: T, i: int, elem: typed) =
(x[i]) = elem
template `[]=`*[I, T](x: array[I, T], i: I; elem: T) =
(x[i]) = elem
template `[]=`*(x: cstring, i: int; elem: char) =
Expand Down
13 changes: 13 additions & 0 deletions src/gear3/expander.nim
Original file line number Diff line number Diff line change
Expand Up @@ -246,13 +246,16 @@ proc traverseTupleBody(e: var EContext; c: var Cursor) =
while c.kind != ParRi:
if c.substructureKind == FldS:
inc c # skip fld
e.offer c.symId
skip c # skip name
skip c # skip export marker
skip c # skip pragmas
genTupleField(e, c, counter)
skip c # skip value
skipParRi e, c
else:
if c.kind == SymbolDef:
e.offer c.symId
genTupleField(e, c, counter)
inc counter
wantParRi e, c
Expand Down Expand Up @@ -835,6 +838,16 @@ proc traverseExpr(e: var EContext; c: var Cursor) =
e.dest.add tagToken("at", c.info)
inc c
inc nested
of TupAtX:
e.dest.add tagToken("dot", c.info)
inc c # skip tag
traverseExpr e, c # tuple
expectIntLit e, c
e.dest.add symToken(ithTupleField(pool.integers[c.intId]), c.info)
inc c # skip index
e.dest.addIntLit(0, c.info) # inheritance
e.dest.add c # add right paren
inc c # skip right paren
of SufX:
e.dest.add c
inc c
Expand Down
3 changes: 2 additions & 1 deletion src/nimony/magics.nim
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ type
# not in Nim 2:
mUnpack
mDefaultObj, mDefaultTup
mArrAt, mPat
mArrAt, mPat, mTupAt
mDeref

declareMatcher parseMagic, TMagic, 1, 1
Expand All @@ -107,6 +107,7 @@ proc magicToTag*(m: TMagic): (string, int) =
of mArrGet: res AtX
of mArrAt: res ArrAtX
of mPat: res PatX
of mTupAt: res TupAtX
of mAsgn: res AsgnS
of mAddI, mAddU, mAddF64: res AddX, TypedMagic
of mSubI, mSubU, mSubF64: res SubX, TypedMagic
Expand Down
16 changes: 13 additions & 3 deletions src/nimony/sem.nim
Original file line number Diff line number Diff line change
Expand Up @@ -773,7 +773,7 @@ proc addFn(c: var SemContext; fn: FnCandidate; fnOrig: Cursor; args: openArray[I
if n.kind == ParLe:
if n.exprKind in {DefinedX, DeclaredX, CompilesX, TypeofX,
LowX, HighX, AddrX, EnumToStrX, DefaultObjX, DefaultTupX,
ArrAtX, DerefX}:
ArrAtX, DerefX, TupAtX}:
# magic needs semchecking after overloading
result = MagicCallNeedsSemcheck
else:
Expand Down Expand Up @@ -1505,19 +1505,22 @@ proc tryBuiltinDot(c: var SemContext; it: var Item; lhs: Item; fieldName: StrId;
elif t.typeKind == TupleT:
var tup = t
inc tup
var i = 0
while tup.kind != ParRi:
let field = asLocal(tup)
if field.name.kind == SymbolDef and sameIdent(field.name.symId, fieldName):
c.dest.add symToken(field.name.symId, info)
c.dest[exprStart] = parLeToken(TupAtX, info)
c.dest.addIntLit(i, info)
it.typ = field.typ # will be fit later with commonType
it.kind = FldY
result = MatchedDotField
break
skip tup
inc i
if result != MatchedDotField:
c.dest.add identToken(fieldName, info)
c.buildErr info, "undeclared field: " & pool.strings[fieldName]
c.dest.add intToken(pool.integers.getOrIncl(0), info)
c.dest.add intToken(pool.integers.getOrIncl(0), info)
else:
c.dest.add identToken(fieldName, info)
c.buildErr info, "object type expected"
Expand Down Expand Up @@ -3791,6 +3794,13 @@ proc semTupAt(c: var SemContext; it: var Item) =
takeToken c, it.n
var tup = Item(n: it.n, typ: c.types.autoType)
semExpr c, tup
if containsGenericParams(tup.typ):
# leave as is, probably enough to check tup.typ is a typevar
var index = Item(n: tup.n, typ: c.types.autoType)
semExpr c, index
it.n = index.n
wantParRi c, it.n
return
var idx = tup.n
let idxStart = c.dest.len
semConstIntExpr c, idx
Expand Down
38 changes: 19 additions & 19 deletions tests/nimony/sysbasics/tdefault.nif
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
(.nif24)
,1,tests/nimony/sysbasics/tdefault.nim(stmts
(discard 58,706,lib/std/system.nim
(discard 58,712,lib/std/system.nim
(expr "")) ,1
(discard 52,681,lib/std/system.nim
(discard 52,687,lib/std/system.nim
(expr +0)) ,3
(discard 56,709,lib/std/system.nim
(discard 56,715,lib/std/system.nim
(expr 1
(conv ~41,~709,tests/nimony/sysbasics/tdefault.nim
(conv ~41,~715,tests/nimony/sysbasics/tdefault.nim
(ptr ~12,3,lib/std/system.nim
(i -1)) 1
(nil)))) 10,4
Expand Down Expand Up @@ -40,7 +40,7 @@
(stmts
(ret "c"))))
(ret result.0))) ,5
(discard 57,703,lib/std/system.nim
(discard 57,709,lib/std/system.nim
(expr 3 a.0.tde837gue)) 9,7
(type ~4 :Obj.0.tde837gue . . . 2
(object . ~9,1
Expand All @@ -55,14 +55,14 @@
(fld :b.1.tde837gue . . 3 Enum.0.tde837gue .)) .))) ,12
(discard 15
(obj 1 Obj.0.tde837gue
(kv x.0.tde837gue 37,670,lib/std/system.nim
(kv x.0.tde837gue 37,676,lib/std/system.nim
(expr +0))
(kv y.0.tde837gue 43,694,lib/std/system.nim
(kv y.0.tde837gue 43,700,lib/std/system.nim
(expr ""))
(kv z.0.tde837gue
(tup 39,666,lib/std/system.nim
(expr ~33,~308
(false)) 42,696,lib/std/system.nim
(tup 39,672,lib/std/system.nim
(expr ~33,~311
(false)) 42,702,lib/std/system.nim
(expr 3 a.0.tde837gue))))) ,14
(proc 5 :foo.0.tde837gue . . . 8
(params 1
Expand All @@ -76,14 +76,14 @@
(i -1) .) 4
(var :data.0 . . 10,~3 Obj.0.tde837gue 10
(obj ,~3 Obj.0.tde837gue
(kv x.0.tde837gue 36,667,lib/std/system.nim
(kv x.0.tde837gue 36,673,lib/std/system.nim
(expr +0))
(kv y.0.tde837gue 42,691,lib/std/system.nim
(kv y.0.tde837gue 42,697,lib/std/system.nim
(expr ""))
(kv z.0.tde837gue
(tup 38,663,lib/std/system.nim
(expr ~33,~308
(false)) 41,693,lib/std/system.nim
(tup 38,669,lib/std/system.nim
(expr ~33,~311
(false)) 41,699,lib/std/system.nim
(expr 3 a.0.tde837gue))))) 4,1
(var :x.2 . .
(string) 4 "abc") 7,2
Expand All @@ -107,7 +107,7 @@
(asgn ~7 global.0.tde837gue 10
(obj ~5,~5 MyObject.0.tde837gue 2
(kv ~2 x.1.tde837gue 2 +123)
(kv y.1.tde837gue 35,654,lib/std/system.nim
(kv y.1.tde837gue 35,660,lib/std/system.nim
(expr +0)))) 7,29
(asgn ~7 global.0.tde837gue 10
(obj ~5,~6 MyObject.0.tde837gue 2
Expand All @@ -119,7 +119,7 @@
(asgn ~7 global.0.tde837gue 10
(obj ~7,~8 MyObject.0.tde837gue 2
(kv ~2 x.1.tde837gue 2 +123)
(kv y.1.tde837gue 33,651,lib/std/system.nim
(kv y.1.tde837gue 33,657,lib/std/system.nim
(expr +0)))) 7,1
(asgn ~7 global.0.tde837gue 10
(obj ~7,~9 MyObject.0.tde837gue 2
Expand All @@ -129,7 +129,7 @@
(asgn ~7 global.0.tde837gue 10
(obj ~7,~8 MyObject.0.tde837gue 2
(kv ~2 x.1.tde837gue 2 +123)
(kv y.1.tde837gue 33,651,lib/std/system.nim
(kv y.1.tde837gue 33,657,lib/std/system.nim
(expr +0)))) 7,1
(asgn ~7 global.0.tde837gue 10
(obj ~7,~9 MyObject.0.tde837gue 2
Expand Down Expand Up @@ -174,7 +174,7 @@
(result :result.3 . . 9,~1 GenericObj.1.tde837gue .) 7
(asgn ~7 result.3 15
(obj ~1,~4 GenericObj.1.tde837gue
(kv x.3.tde837gue 28,640,lib/std/system.nim
(kv x.3.tde837gue 28,646,lib/std/system.nim
(expr +0)))) 9,1
(asgn ~3
(dot ~6 result.3 x.3.tde837gue +0) 2 x.4) ~2,~1
Expand Down
11 changes: 11 additions & 0 deletions tests/nimony/sysbasics/tindex.nim
Original file line number Diff line number Diff line change
Expand Up @@ -12,3 +12,14 @@ proc main() =
let z = cstr[1]
let zt: char = z
cstr[1] = zt

var tup: tuple[a: int, b: string, c: bool]
let t1 = tup[0]
let t1t: int = t1
tup[0] = t1t
let t2 = tup[1]
let t2t: string = t2
tup[1] = t2t
let t3 = tup[2]
let t3t: bool = t3
tup[2] = t3t

0 comments on commit 5213495

Please sign in to comment.