bugfixes for the symbol mangling; implements #129

This commit is contained in:
Araq
2012-07-19 17:38:52 +02:00
parent 98fd408adc
commit 39235e21f5
5 changed files with 58 additions and 21 deletions

View File

@@ -12,15 +12,17 @@
# ------------------------- Name Mangling --------------------------------
proc mangle(name: string): string =
case name[0]
of 'a'..'z':
result = ""
add(result, chr(ord(name[0]) - ord('a') + ord('A')))
of '0'..'9', 'A'..'Z':
result = ""
add(result, name[0])
else: result = "HEX" & toHex(ord(name[0]), 2)
for i in countup(0 + 1, len(name) + 0 - 1):
when false:
case name[0]
of 'a'..'z':
result = ""
add(result, chr(ord(name[0]) - ord('a') + ord('A')))
of '0'..'9', 'A'..'Z':
result = ""
add(result, name[0])
else: result = "HEX" & toHex(ord(name[0]), 2)
result = ""
for i in countup(0, len(name) - 1):
case name[i]
of 'A'..'Z':
add(result, chr(ord(name[i]) - ord('A') + ord('a')))
@@ -103,7 +105,7 @@ proc mangleName(s: PSym): PRope =
# These are not properly scoped now - we need to add blocks
# around for loops in transf
if keepOrigName:
result = s.name.s.toRope
result = s.name.s.mangle.toRope
else:
app(result, toRope(mangle(s.name.s)))
app(result, "_")
@@ -120,7 +122,7 @@ proc isCompileTimeOnly(t: PType): bool =
var anonTypeName = toRope"TY"
proc typeName(typ: PType): PRope =
result = if typ.sym != nil: typ.sym.name.s.toRope
result = if typ.sym != nil: typ.sym.name.s.mangle.toRope
else: anonTypeName
proc getTypeName(typ: PType): PRope =

View File

@@ -1390,6 +1390,18 @@ proc parseDistinct(p: var TParser): PNode =
optInd(p, result)
addSon(result, parseTypeDesc(p))
proc parsePointerInTypeSection(p: var TParser, kind: TNodeKind): PNode =
result = newNodeP(kind, p)
getTok(p)
optInd(p, result)
if not isOperator(p.tok):
case p.tok.tokType
of tkObject: addSon(result, parseObject(p))
of tkTuple: addSon(result, parseTuple(p, true))
else:
if isExprStart(p):
addSon(result, parseTypeDesc(p))
proc parseTypeDef(p: var TParser): PNode =
result = newNodeP(nkTypeDef, p)
addSon(result, identWithPragma(p))
@@ -1404,9 +1416,11 @@ proc parseTypeDef(p: var TParser): PNode =
of tkEnum: a = parseEnum(p)
of tkDistinct: a = parseDistinct(p)
of tkTuple: a = parseTuple(p, true)
of tkRef: a = parsePointerInTypeSection(p, nkRefTy)
of tkPtr: a = parsePointerInTypeSection(p, nkPtrTy)
else: a = parseTypeDesc(p)
addSon(result, a)
else:
else:
addSon(result, ast.emptyNode)
indAndComment(p, result) # special extension!

View File

@@ -609,6 +609,15 @@ proc typeSectionFinalPass(c: PContext, n: PNode) =
assignType(s.typ, t)
s.typ.id = t.id # same id
checkConstructedType(s.info, s.typ)
let aa = a.sons[2]
if aa.kind in {nkRefTy, nkPtrTy} and aa.len == 1 and
aa.sons[0].kind == nkObjectTy:
# give anonymous object a dummy symbol:
assert s.typ.sons[0].sym == nil
var anonObj = newSym(skType, getIdent(s.name.s & ":ObjectType"),
getCurrOwner())
anonObj.info = s.info
s.typ.sons[0].sym = anonObj
proc SemTypeSection(c: PContext, n: PNode): PNode =
typeSectionLeftSidePass(c, n)

View File

@@ -1095,6 +1095,18 @@ dereferencing operations for reference types:
new(n)
n.data = 9
# no need to write n[].data; in fact n[].data is highly discouraged!
As a syntactical extension ``object`` types can be anonymous if
declared in a type section via the ``ref object`` or ``ptr object`` notations.
This feature is useful if an object should only gain reference semantics:
.. code-block:: nimrod
type
Node = ref object
le, ri: Node
data: int
To allocate a new traced object, the built-in procedure ``new`` has to be used.
To deal with untraced memory, the procedures ``alloc``, ``dealloc`` and

View File

@@ -5,21 +5,21 @@ discard """
# Test multi methods
type
TExpr = object
TLiteral = object of TExpr
Expression = ref object
Literal = ref object of Expression
x: int
TPlusExpr = object of TExpr
a, b: ref TExpr
PlusExpr = ref object of Expression
a, b: Expression
method eval(e: ref TExpr): int = quit "to override!"
method eval(e: ref TLiteral): int = return e.x
method eval(e: ref TPlusExpr): int = return eval(e.a) + eval(e.b)
method eval(e: Expression): int = quit "to override!"
method eval(e: Literal): int = return e.x
method eval(e: PlusExpr): int = return eval(e.a) + eval(e.b)
proc newLit(x: int): ref TLiteral =
proc newLit(x: int): Literal =
new(result)
result.x = x
proc newPlus(a, b: ref TExpr): ref TPlusExpr =
proc newPlus(a, b: Expression): PlusExpr =
new(result)
result.a = a
result.b = b