bugfix: 'final' not passed to generic

This commit is contained in:
Araq 2011-07-29 01:25:05 +02:00
commit dce8949b9b
10 changed files with 68 additions and 80 deletions

View file

@ -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) =
when debugIDs:
proc registerID(id: PIdObj) =
if 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()

View file

@ -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])

View file

@ -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

View file

@ -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

View file

@ -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,24 +92,24 @@ 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)
header.sons[i] = x header.sons[i] = x
else: else:
x = t.sons[i] x = t.sons[i]
idTablePut(cl.typeMap, body.sons[i - 1], x) idTablePut(cl.typeMap, body.sons[i-1], x)
if header == nil: header = t if header == nil: header = t
result = searchInstTypes(gInstTypes, header) result = searchInstTypes(gInstTypes, header)
if result != nil: return if result != nil: return
@ -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)));

View file

@ -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]

View file

@ -5,19 +5,20 @@ type
type 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"))
ee.emit("print") ee.emit("print")

View file

@ -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"
""" """

View file

@ -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