bugfix: 'final' not passed to generic
This commit is contained in:
parent
68d7c61c24
commit
dce8949b9b
10 changed files with 68 additions and 80 deletions
|
|
@ -625,13 +625,11 @@ proc ValueToString*(a: PNode): string
|
||||||
const
|
const
|
||||||
debugIds* = false
|
debugIds* = false
|
||||||
|
|
||||||
proc registerID*(id: PIdObj)
|
when debugIds:
|
||||||
# implementation
|
|
||||||
|
|
||||||
var usedIds: TIntSet
|
var usedIds: TIntSet
|
||||||
|
|
||||||
proc registerID(id: PIdObj) =
|
proc registerID*(id: PIdObj) =
|
||||||
if debugIDs:
|
when debugIDs:
|
||||||
if (id.id == - 1) or ContainsOrIncl(usedIds, id.id):
|
if (id.id == - 1) or ContainsOrIncl(usedIds, id.id):
|
||||||
InternalError("ID already used: " & $(id.id))
|
InternalError("ID already used: " & $(id.id))
|
||||||
|
|
||||||
|
|
@ -761,7 +759,7 @@ proc NewType(kind: TTypeKind, owner: PSym): PType =
|
||||||
result.size = - 1
|
result.size = - 1
|
||||||
result.align = 2 # default alignment
|
result.align = 2 # default alignment
|
||||||
result.id = getID()
|
result.id = getID()
|
||||||
if debugIds:
|
when debugIds:
|
||||||
RegisterId(result)
|
RegisterId(result)
|
||||||
#if result.id < 2000 then
|
#if result.id < 2000 then
|
||||||
# MessageOut(typeKindToStr[kind] & ' has id: ' & toString(result.id))
|
# MessageOut(typeKindToStr[kind] & ' has id: ' & toString(result.id))
|
||||||
|
|
@ -784,7 +782,7 @@ proc copyType(t: PType, owner: PSym, keepId: bool): PType =
|
||||||
result.id = t.id
|
result.id = t.id
|
||||||
else:
|
else:
|
||||||
result.id = getID()
|
result.id = getID()
|
||||||
if debugIds: RegisterId(result)
|
when debugIds: RegisterId(result)
|
||||||
result.sym = t.sym # backend-info should not be copied
|
result.sym = t.sym # backend-info should not be copied
|
||||||
|
|
||||||
proc copySym(s: PSym, keepId: bool = false): PSym =
|
proc copySym(s: PSym, keepId: bool = false): PSym =
|
||||||
|
|
@ -796,7 +794,7 @@ proc copySym(s: PSym, keepId: bool = false): PSym =
|
||||||
result.id = s.id
|
result.id = s.id
|
||||||
else:
|
else:
|
||||||
result.id = getID()
|
result.id = getID()
|
||||||
if debugIds: RegisterId(result)
|
when debugIds: RegisterId(result)
|
||||||
result.flags = s.flags
|
result.flags = s.flags
|
||||||
result.magic = s.magic
|
result.magic = s.magic
|
||||||
copyStrTable(result.tab, s.tab)
|
copyStrTable(result.tab, s.tab)
|
||||||
|
|
@ -816,7 +814,7 @@ proc NewSym(symKind: TSymKind, Name: PIdent, owner: PSym): PSym =
|
||||||
result.owner = owner
|
result.owner = owner
|
||||||
result.offset = - 1
|
result.offset = - 1
|
||||||
result.id = getID()
|
result.id = getID()
|
||||||
if debugIds:
|
when debugIds:
|
||||||
RegisterId(result)
|
RegisterId(result)
|
||||||
#if result.id < 2000:
|
#if result.id < 2000:
|
||||||
# MessageOut(name.s & " has id: " & toString(result.id))
|
# MessageOut(name.s & " has id: " & toString(result.id))
|
||||||
|
|
@ -1005,4 +1003,4 @@ proc getStrOrChar*(a: PNode): string =
|
||||||
internalError(a.info, "getStrOrChar")
|
internalError(a.info, "getStrOrChar")
|
||||||
result = ""
|
result = ""
|
||||||
|
|
||||||
if debugIDs: usedIds = InitIntSet()
|
when debugIDs: usedIds = InitIntSet()
|
||||||
|
|
|
||||||
|
|
@ -152,7 +152,7 @@ proc getGlobalTempName(): PRope =
|
||||||
inc(gId)
|
inc(gId)
|
||||||
|
|
||||||
proc ccgIntroducedPtr(s: PSym): bool =
|
proc ccgIntroducedPtr(s: PSym): bool =
|
||||||
var pt = s.typ
|
var pt = skipTypes(s.typ, abstractInst)
|
||||||
assert skResult != s.kind
|
assert skResult != s.kind
|
||||||
case pt.Kind
|
case pt.Kind
|
||||||
of tyObject:
|
of tyObject:
|
||||||
|
|
@ -352,7 +352,7 @@ proc getRecordDesc(m: BModule, typ: PType, name: PRope,
|
||||||
var hasField = false
|
var hasField = false
|
||||||
if typ.kind == tyObject:
|
if typ.kind == tyObject:
|
||||||
if typ.sons[0] == nil:
|
if typ.sons[0] == nil:
|
||||||
if typ.sym != nil and sfPure in typ.sym.flags or tfFinal in typ.flags:
|
if (typ.sym != nil and sfPure in typ.sym.flags) or tfFinal in typ.flags:
|
||||||
result = ropecg(m, "struct $1 {$n", [name])
|
result = ropecg(m, "struct $1 {$n", [name])
|
||||||
else:
|
else:
|
||||||
result = ropecg(m, "struct $1 {$n#TNimType* m_type;$n", [name])
|
result = ropecg(m, "struct $1 {$n#TNimType* m_type;$n", [name])
|
||||||
|
|
|
||||||
|
|
@ -24,23 +24,12 @@ type
|
||||||
|
|
||||||
TCompareProc* = proc (entry: PListEntry, closure: Pointer): bool
|
TCompareProc* = proc (entry: PListEntry, closure: Pointer): bool
|
||||||
|
|
||||||
proc InitLinkedList*(list: var TLinkedList)
|
proc InitLinkedList*(list: var TLinkedList) =
|
||||||
proc Append*(list: var TLinkedList, entry: PListEntry)
|
|
||||||
proc Prepend*(list: var TLinkedList, entry: PListEntry)
|
|
||||||
proc Remove*(list: var TLinkedList, entry: PListEntry)
|
|
||||||
proc InsertBefore*(list: var TLinkedList, pos, entry: PListEntry)
|
|
||||||
proc Find*(list: TLinkedList, fn: TCompareProc, closure: Pointer): PListEntry
|
|
||||||
proc AppendStr*(list: var TLinkedList, data: string)
|
|
||||||
proc IncludeStr*(list: var TLinkedList, data: string): bool
|
|
||||||
proc PrependStr*(list: var TLinkedList, data: string)
|
|
||||||
# implementation
|
|
||||||
|
|
||||||
proc InitLinkedList(list: var TLinkedList) =
|
|
||||||
list.Counter = 0
|
list.Counter = 0
|
||||||
list.head = nil
|
list.head = nil
|
||||||
list.tail = nil
|
list.tail = nil
|
||||||
|
|
||||||
proc Append(list: var TLinkedList, entry: PListEntry) =
|
proc Append*(list: var TLinkedList, entry: PListEntry) =
|
||||||
Inc(list.counter)
|
Inc(list.counter)
|
||||||
entry.next = nil
|
entry.next = nil
|
||||||
entry.prev = list.tail
|
entry.prev = list.tail
|
||||||
|
|
@ -50,16 +39,6 @@ proc Append(list: var TLinkedList, entry: PListEntry) =
|
||||||
list.tail = entry
|
list.tail = entry
|
||||||
if list.head == nil: list.head = entry
|
if list.head == nil: list.head = entry
|
||||||
|
|
||||||
proc newStrEntry(data: string): PStrEntry =
|
|
||||||
new(result)
|
|
||||||
result.data = data
|
|
||||||
|
|
||||||
proc AppendStr(list: var TLinkedList, data: string) =
|
|
||||||
append(list, newStrEntry(data))
|
|
||||||
|
|
||||||
proc PrependStr(list: var TLinkedList, data: string) =
|
|
||||||
prepend(list, newStrEntry(data))
|
|
||||||
|
|
||||||
proc Contains*(list: TLinkedList, data: string): bool =
|
proc Contains*(list: TLinkedList, data: string): bool =
|
||||||
var it = list.head
|
var it = list.head
|
||||||
while it != nil:
|
while it != nil:
|
||||||
|
|
@ -67,11 +46,31 @@ proc Contains*(list: TLinkedList, data: string): bool =
|
||||||
return true
|
return true
|
||||||
it = it.next
|
it = it.next
|
||||||
|
|
||||||
proc IncludeStr(list: var TLinkedList, data: string): bool =
|
proc newStrEntry(data: string): PStrEntry =
|
||||||
|
new(result)
|
||||||
|
result.data = data
|
||||||
|
|
||||||
|
proc AppendStr*(list: var TLinkedList, data: string) =
|
||||||
|
append(list, newStrEntry(data))
|
||||||
|
|
||||||
|
proc IncludeStr*(list: var TLinkedList, data: string): bool =
|
||||||
if Contains(list, data): return true
|
if Contains(list, data): return true
|
||||||
AppendStr(list, data) # else: add to list
|
AppendStr(list, data) # else: add to list
|
||||||
|
|
||||||
proc InsertBefore(list: var TLinkedList, pos, entry: PListEntry) =
|
proc Prepend*(list: var TLinkedList, entry: PListEntry) =
|
||||||
|
Inc(list.counter)
|
||||||
|
entry.prev = nil
|
||||||
|
entry.next = list.head
|
||||||
|
if list.head != nil:
|
||||||
|
assert(list.head.prev == nil)
|
||||||
|
list.head.prev = entry
|
||||||
|
list.head = entry
|
||||||
|
if list.tail == nil: list.tail = entry
|
||||||
|
|
||||||
|
proc PrependStr*(list: var TLinkedList, data: string) =
|
||||||
|
prepend(list, newStrEntry(data))
|
||||||
|
|
||||||
|
proc InsertBefore*(list: var TLinkedList, pos, entry: PListEntry) =
|
||||||
assert(pos != nil)
|
assert(pos != nil)
|
||||||
if pos == list.head:
|
if pos == list.head:
|
||||||
prepend(list, entry)
|
prepend(list, entry)
|
||||||
|
|
@ -82,17 +81,7 @@ proc InsertBefore(list: var TLinkedList, pos, entry: PListEntry) =
|
||||||
if pos.prev != nil: pos.prev.next = entry
|
if pos.prev != nil: pos.prev.next = entry
|
||||||
pos.prev = entry
|
pos.prev = entry
|
||||||
|
|
||||||
proc Prepend(list: var TLinkedList, entry: PListEntry) =
|
proc Remove*(list: var TLinkedList, entry: PListEntry) =
|
||||||
Inc(list.counter)
|
|
||||||
entry.prev = nil
|
|
||||||
entry.next = list.head
|
|
||||||
if list.head != nil:
|
|
||||||
assert(list.head.prev == nil)
|
|
||||||
list.head.prev = entry
|
|
||||||
list.head = entry
|
|
||||||
if list.tail == nil: list.tail = entry
|
|
||||||
|
|
||||||
proc Remove(list: var TLinkedList, entry: PListEntry) =
|
|
||||||
Dec(list.counter)
|
Dec(list.counter)
|
||||||
if entry == list.tail:
|
if entry == list.tail:
|
||||||
list.tail = entry.prev
|
list.tail = entry.prev
|
||||||
|
|
@ -101,7 +90,7 @@ proc Remove(list: var TLinkedList, entry: PListEntry) =
|
||||||
if entry.next != nil: entry.next.prev = entry.prev
|
if entry.next != nil: entry.next.prev = entry.prev
|
||||||
if entry.prev != nil: entry.prev.next = entry.next
|
if entry.prev != nil: entry.prev.next = entry.next
|
||||||
|
|
||||||
proc Find(list: TLinkedList, fn: TCompareProc, closure: Pointer): PListEntry =
|
proc Find*(list: TLinkedList, fn: TCompareProc, closure: Pointer): PListEntry =
|
||||||
result = list.head
|
result = list.head
|
||||||
while result != nil:
|
while result != nil:
|
||||||
if fn(result, closure): return
|
if fn(result, closure): return
|
||||||
|
|
|
||||||
|
|
@ -49,8 +49,8 @@
|
||||||
# The 'con' operator is associative! This does not matter however for
|
# The 'con' operator is associative! This does not matter however for
|
||||||
# the algorithms we use for ropes.
|
# the algorithms we use for ropes.
|
||||||
#
|
#
|
||||||
# Note that the left and right pointers are not needed for leafs.
|
# Note that the left and right pointers are not needed for leaves.
|
||||||
# Leafs have relatively high memory overhead (~30 bytes on a 32
|
# Leaves have relatively high memory overhead (~30 bytes on a 32
|
||||||
# bit machines) and we produce many of them. This is why we cache and
|
# bit machines) and we produce many of them. This is why we cache and
|
||||||
# share leaves accross different rope trees.
|
# share leaves accross different rope trees.
|
||||||
# To cache them they are inserted in another tree, a splay tree for best
|
# To cache them they are inserted in another tree, a splay tree for best
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,7 @@
|
||||||
# distribution, for details about the copyright.
|
# distribution, for details about the copyright.
|
||||||
#
|
#
|
||||||
|
|
||||||
# This module does the instantiation of generic procs and types.
|
# This module does the instantiation of generic types.
|
||||||
|
|
||||||
import ast, astalgo, msgs, types, semdata
|
import ast, astalgo, msgs, types, semdata
|
||||||
|
|
||||||
|
|
@ -92,17 +92,17 @@ proc lookupTypeVar(cl: TReplTypeVars, t: PType): PType =
|
||||||
InternalError(cl.info, "substitution with generic parameter")
|
InternalError(cl.info, "substitution with generic parameter")
|
||||||
|
|
||||||
proc ReplaceTypeVarsT*(cl: var TReplTypeVars, t: PType): PType =
|
proc ReplaceTypeVarsT*(cl: var TReplTypeVars, t: PType): PType =
|
||||||
var body, newbody, x, header: PType
|
|
||||||
result = t
|
result = t
|
||||||
if t == nil: return
|
if t == nil: return
|
||||||
case t.kind
|
case t.kind
|
||||||
of tyGenericParam:
|
of tyGenericParam:
|
||||||
result = lookupTypeVar(cl, t)
|
result = lookupTypeVar(cl, t)
|
||||||
of tyGenericInvokation:
|
of tyGenericInvokation:
|
||||||
body = t.sons[0]
|
var body = t.sons[0]
|
||||||
if body.kind != tyGenericBody: InternalError(cl.info, "no generic body")
|
if body.kind != tyGenericBody: InternalError(cl.info, "no generic body")
|
||||||
header = nil
|
var header: PType = nil
|
||||||
for i in countup(1, sonsLen(t) - 1):
|
for i in countup(1, sonsLen(t) - 1):
|
||||||
|
var x: PType
|
||||||
if t.sons[i].kind == tyGenericParam:
|
if t.sons[i].kind == tyGenericParam:
|
||||||
x = lookupTypeVar(cl, t.sons[i])
|
x = lookupTypeVar(cl, t.sons[i])
|
||||||
if header == nil: header = copyType(t, t.owner, false)
|
if header == nil: header = copyType(t, t.owner, false)
|
||||||
|
|
@ -119,7 +119,8 @@ proc ReplaceTypeVarsT*(cl: var TReplTypeVars, t: PType): PType =
|
||||||
# but we already raised an error!
|
# but we already raised an error!
|
||||||
addSon(result, header.sons[i])
|
addSon(result, header.sons[i])
|
||||||
idTablePut(gInstTypes, header, result)
|
idTablePut(gInstTypes, header, result)
|
||||||
newbody = ReplaceTypeVarsT(cl, lastSon(body))
|
var newbody = ReplaceTypeVarsT(cl, lastSon(body))
|
||||||
|
newbody.flags = newbody.flags + t.flags + body.flags
|
||||||
newbody.n = ReplaceTypeVarsN(cl, lastSon(body).n)
|
newbody.n = ReplaceTypeVarsN(cl, lastSon(body).n)
|
||||||
addSon(result, newbody)
|
addSon(result, newbody)
|
||||||
#writeln(output, ropeToStr(Typetoyaml(newbody)));
|
#writeln(output, ropeToStr(Typetoyaml(newbody)));
|
||||||
|
|
|
||||||
|
|
@ -15,7 +15,7 @@ type
|
||||||
TA[T] = object
|
TA[T] = object
|
||||||
|
|
||||||
|
|
||||||
# Cannot instanciate:
|
# Cannot instantiate:
|
||||||
type
|
type
|
||||||
TA[T] = object
|
TA[T] = object
|
||||||
a: PA[T]
|
a: PA[T]
|
||||||
|
|
|
||||||
|
|
@ -6,16 +6,17 @@ type
|
||||||
TEventEmitter = object of TObject
|
TEventEmitter = object of TObject
|
||||||
events*: TTable[string, TDoublyLinkedList[proc(e : TEventArgs)]]
|
events*: TTable[string, TDoublyLinkedList[proc(e : TEventArgs)]]
|
||||||
proc on*(emitter: var TEventEmitter, event: string, func: proc(e: TEventArgs)) =
|
proc on*(emitter: var TEventEmitter, event: string, func: proc(e: TEventArgs)) =
|
||||||
if hasKey(emitter.events, event) == false:
|
if not hasKey(emitter.events, event):
|
||||||
var list: TDoublyLinkedList[proc(e: TEventArgs)]
|
var list: TDoublyLinkedList[proc(e: TEventArgs)]
|
||||||
add(emitter.events,event,list) #if not, add it.
|
add(emitter.events,event,list) #if not, add it.
|
||||||
append(emitter.events[event], func) #adds the function to the event's list. I get a error here too.
|
#append(emitter.events[event], func)
|
||||||
|
#adds the function to the event's list. I get a error here too.
|
||||||
|
|
||||||
proc emit*(emitter: TEventEmitter, event: string, args: TEventArgs) =
|
proc emit*(emitter: TEventEmitter, event: string, args: TEventArgs) =
|
||||||
for func in items(emitter.events[event]):
|
for func in nodes(emitter.events[event]):
|
||||||
func(args) #call function with args.
|
func.value(args) #call function with args.
|
||||||
proc initEmitter(emitter: TEventEmitter) =
|
proc initEmitter(emitter: TEventEmitter) =
|
||||||
emitter.events = initTable[string, TSinglyLinkedList[TObject]]()
|
emitter.events = initTable[string, TDoublyLinkedList[proc(e: TEventArgs)]]()
|
||||||
|
|
||||||
var ee: TEventEmitter
|
var ee: TEventEmitter
|
||||||
ee.on("print", proc(e: TEventArgs) = echo("pie"))
|
ee.on("print", proc(e: TEventArgs) = echo("pie"))
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
discard """
|
discard """
|
||||||
file: "tvarres1.nim"
|
file: "tvarres2.nim"
|
||||||
line: 11
|
line: 11
|
||||||
errormsg: "expression has no address"
|
errormsg: "expression has no address"
|
||||||
"""
|
"""
|
||||||
|
|
|
||||||
1
todo.txt
1
todo.txt
|
|
@ -18,7 +18,6 @@ version 0.9.0
|
||||||
=============
|
=============
|
||||||
|
|
||||||
- add --deadlock_prevention:on|off switch? timeout for locks?
|
- add --deadlock_prevention:on|off switch? timeout for locks?
|
||||||
- bug: tfFinal not passed to generic
|
|
||||||
- bug: forward proc for generic seems broken
|
- bug: forward proc for generic seems broken
|
||||||
- warning for implicit openArray -> varargs convention
|
- warning for implicit openArray -> varargs convention
|
||||||
- implement explicit varargs
|
- implement explicit varargs
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue