diff --git a/compiler/ccgtypes.nim b/compiler/ccgtypes.nim index 0de7315981..7416f11229 100755 --- a/compiler/ccgtypes.nim +++ b/compiler/ccgtypes.nim @@ -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 = diff --git a/compiler/parser.nim b/compiler/parser.nim index 835a48fcc1..3d8fc1f7c3 100755 --- a/compiler/parser.nim +++ b/compiler/parser.nim @@ -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! diff --git a/compiler/semstmts.nim b/compiler/semstmts.nim index 256d19db17..0c727b1a51 100755 --- a/compiler/semstmts.nim +++ b/compiler/semstmts.nim @@ -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) diff --git a/doc/manual.txt b/doc/manual.txt index 34389d7f9f..cd6828e5f9 100755 --- a/doc/manual.txt +++ b/doc/manual.txt @@ -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 diff --git a/tests/run/tmultim1.nim b/tests/run/tmultim1.nim index 542c846c78..4fcf81c987 100755 --- a/tests/run/tmultim1.nim +++ b/tests/run/tmultim1.nim @@ -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