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

clean up magic invocations, fix range types #526

Merged
merged 8 commits into from
Feb 12, 2025
Merged
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
1 change: 1 addition & 0 deletions src/hexer/desugar.nim
Original file line number Diff line number Diff line change
Expand Up @@ -233,6 +233,7 @@ proc genSetOp(c: var Context; dest: var TokenBuf; n: var Cursor) =
dest.addSubtree a
dest.addSubtree b
of InSetX:
# XXX subtract offsets for range types if implemented
let mask = size * 8 - 1
copyIntoKind dest, NeqX, info:
dest.addSubtree cType
Expand Down
2 changes: 1 addition & 1 deletion src/hexer/nifcgen.nim
Original file line number Diff line number Diff line change
Expand Up @@ -409,7 +409,7 @@ proc traverseType(e: var EContext; c: var Cursor; flags: set[TypeFlag] = {}) =
traverseType e, c
skip c
skip c
takeParRi e, c
skipParRi e, c
of UncheckedArrayT:
if IsPointerOf in flags:
inc c
Expand Down
11 changes: 11 additions & 0 deletions src/nimony/expreval.nim
Original file line number Diff line number Diff line change
Expand Up @@ -267,6 +267,17 @@ proc bitsetSizeInBytes*(baseType: Cursor): xint =
let m = asSigned(b.hi, err) + 1'i64
if err: result = createNaN()
else: result = createXint div8Roundup(m)
of RangetypeT:
var index = baseType
inc index # tag
skip index # basetype
# XXX offset not implemented
skip index # lo
let hi = evalOrdinal(nil, index)
var err = false
let m = asSigned(hi, err) + 1'i64
if err: result = createNaN()
else: result = createXint div8Roundup(m)
of DistinctT:
result = bitsetSizeInBytes(baseType.firstSon)
else:
Expand Down
91 changes: 42 additions & 49 deletions src/nimony/sem.nim
Original file line number Diff line number Diff line change
Expand Up @@ -2398,6 +2398,44 @@ const InvocableTypeMagics = {ArrayT, RangetypeT, VarargsT,
PtrT, RefT, UncheckedArrayT, SetT, StaticT, TypedescT,
SinkT, LentT}

proc semMagicInvoke(c: var SemContext; n: var Cursor; kind: TypeKind; info: PackedLineInfo) =
# `n` is at first arg
var typeBuf = createTokenBuf(16)
typeBuf.addParLe(kind, info)
# reorder invocation according to type specifications:
case kind
of ArrayT:
# invoked as array[len, elem], but needs to become (array elem len)
let indexPart = n
skip n
takeTree typeBuf, n # element type
typeBuf.addSubtree indexPart
takeParRi typeBuf, n
of RangetypeT:
# range types are invoked as `range[a..b]`
if isRangeExpr(n):
# don't bother calling semLocalTypeImpl, fully build type here
semRangeTypeFromExpr c, n, info
skipParRi n
else:
c.buildErr info, "expected `a..b` expression for range type"
skipToEnd n
return
of PtrT, RefT, UncheckedArrayT, SetT, StaticT, TypedescT, SinkT, LentT:
# unary invocations
takeTree typeBuf, n
takeParRi typeBuf, n
of VarargsT:
takeTree typeBuf, n
if n.kind != ParRi:
# optional varargs call
takeTree typeBuf, n
takeParRi typeBuf, n
else:
raiseAssert "unreachable" # see type kind check for magicKind
var m = cursorAt(typeBuf, 0)
semLocalTypeImpl c, m, InLocalDecl

proc semInvoke(c: var SemContext; n: var Cursor) =
let typeStart = c.dest.len
let info = n.info
Expand All @@ -2406,7 +2444,6 @@ proc semInvoke(c: var SemContext; n: var Cursor) =

var headId: SymId = SymId(0)
var decl = default TypeDecl
var magicKind = NoType
var ok = false
if c.dest[typeStart+1].kind == Symbol:
headId = c.dest[typeStart+1].symId
Expand All @@ -2424,8 +2461,9 @@ proc semInvoke(c: var SemContext; n: var Cursor) =
endRead(c.dest)
if kind in InvocableTypeMagics:
# magics that can be invoked
magicKind = kind
ok = true
c.dest.shrink typeStart
semMagicInvoke(c, n, kind, info)
return
else:
c.buildErr info, "cannot attempt to instantiate a non-type"

Expand All @@ -2436,7 +2474,7 @@ proc semInvoke(c: var SemContext; n: var Cursor) =
semLocalTypeImpl c, n, AllowValues
swap c.usedTypevars, genericArgs
takeParRi c, n
if ok and (genericArgs == 0 or magicKind != NoType or
if ok and (genericArgs == 0 or
# structural types are inlined even with generic arguments
# XXX does not instantiate properly if structural type is forward declared
# because typevar syms are not created in the SemcheckTopLevelSyms phase
Expand All @@ -2453,51 +2491,6 @@ proc semInvoke(c: var SemContext; n: var Cursor) =
sym.name = cachedSym
else:
var args = cursorAt(c.dest, beforeArgs)
if magicKind != NoType:
var magicExpr = createTokenBuf(8)
magicExpr.addParLe(magicKind, info)
# reorder invocation according to type specifications:
case magicKind
of ArrayT:
# invoked as array[len, elem], but needs to become (array elem len)
let indexPart = args
skip args
magicExpr.takeTree args # element type
magicExpr.addSubtree indexPart
skipParRi args
of RangetypeT:
# range types are invoked as `range[a..b]`
if isRangeExpr(args):
# don't bother calling semLocalTypeImpl, fully build type here
magicExpr.shrink 0
swap c.dest, magicExpr
semRangeTypeFromExpr c, args, info
swap c.dest, magicExpr
c.dest.endRead()
c.dest.shrink typeStart
c.dest.add magicExpr
return
else:
# error?
discard
of PtrT, RefT, UncheckedArrayT, SetT, StaticT, TypedescT, SinkT, LentT:
# unary invocations
magicExpr.takeTree args
skipParRi args
of VarargsT:
magicExpr.takeTree args
if args.kind != ParRi:
# optional varargs call
magicExpr.takeTree args
skipParRi args
else:
raiseAssert "unreachable" # see type kind check for magicKind
magicExpr.addParRi()
c.dest.endRead()
c.dest.shrink typeStart
var m = cursorAt(magicExpr, 0)
semLocalTypeImpl c, m, InLocalDecl
return
let targetSym = newSymId(c, headId)
if genericArgs == 0:
c.instantiatedTypes[key] = targetSym
Expand Down
1 change: 1 addition & 0 deletions tests/nimony/errmsgs/tbadrange.msgs
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
tests/nimony/errmsgs/tbadrange.nim(1, 13) Error: expected `a..b` expression for range type
1 change: 1 addition & 0 deletions tests/nimony/errmsgs/tbadrange.nim
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
var x: range[123]
9 changes: 9 additions & 0 deletions tests/nimony/generics/temptyliteral.nim
Original file line number Diff line number Diff line change
Expand Up @@ -16,3 +16,12 @@ concreteSet({})
var x: set[Enum] = {}
genericSet(x, {})

proc concreteRangeSet(arr: set[range[0..3]]) = discard

concreteRangeSet({})
var rangeSet: set[range[0..3]] = {}
genericSet(rangeSet, {})
type RangeAlias = range[0..3]
var aliasRangeSet: set[RangeAlias] = {}
genericSet(rangeSet, aliasRangeSet)

32 changes: 5 additions & 27 deletions tests/nimony/nosystem/tgeneric_obj.nif
Original file line number Diff line number Diff line change
Expand Up @@ -200,20 +200,7 @@
(asgn ~7 result.2 2 x.4) ~2,~1
(ret result.2))) 7,68
(asgn ~7 myarr2.0.tge7jvqqk1 10
(call ~8 identity.1.tge7jvqqk1 1 myarr2.0.tge7jvqqk1)) 19,56
(proc :\2E..1.tge7jvqqk1 . ~19,~3 .
(at \2E..0.tge7jvqqk1
(i -1)
(i -1)) ~3,~3
(params 1
(param :a.2 . .
(i -1) .) 7
(param :b.2 . .
(i -1) .)) 1,~3 HSlice.1.tge7jvqqk1 ~19,~3 . ~19,~3 . 26,~3
(stmts
(result :result.3 . . ~25 HSlice.1.tge7jvqqk1 .)
(discard .) ~45
(ret result.3))) 3,64
(call ~8 identity.1.tge7jvqqk1 1 myarr2.0.tge7jvqqk1)) 3,64
(proc :foo.2.tge7jvqqk1 . ~3,~1 .
(at foo.1.tge7jvqqk1 13,~47
(rangetype
Expand Down Expand Up @@ -243,13 +230,13 @@
(rangetype
(i -1) +0 +2)) ~17,~2 . ~17,~2 . ~15,~1
(stmts 7
(result :result.4 . . 19,~1
(result :result.3 . . 19,~1
(array ~8,~49
(i -1) ~12,~49
(rangetype
(i -1) +0 +2)) .) 7
(asgn ~7 result.4 2 x.9) ~2,~1
(ret result.4))) 19,27
(asgn ~7 result.3 2 x.9) ~2,~1
(ret result.3))) 19,27
(type :MyGeneric.1.tge7jvqqk1 .
(at MyGeneric.0.tge7jvqqk1 1
(i -1)) ~4,~4 . ~2,~4
Expand All @@ -261,13 +248,4 @@
(f +64)) ~3,~5 . ~1,~5
(object . ~13,1
(fld :x.2.tge7jvqqk1 . . 15,4
(f +64) .))) 20,53
(type :HSlice.1.tge7jvqqk1 .
(at HSlice.0.tge7jvqqk1
(i -1)
(i -1)) ~4,~5 . ~2,~5
(object . ~14,1
(fld :a.1.tge7jvqqk1 . .
(i -1) .) ~14,2
(fld :b.1.tge7jvqqk1 . .
(i -1) .))))
(f +64) .))))
9 changes: 9 additions & 0 deletions tests/nimony/nosystem/trangeexprtype.nim
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
type
int* {.magic: Int.}

range*[T]{.magic: Range.}
set*[T] {.magic: Set.}
array* [Index, T] {.magic: Array.}

var a: array[0..2, int]
var b: set[range[0..2]]
Loading