From cdb4d83eadef07c3ba07b1a2d408548df1b3326b Mon Sep 17 00:00:00 2001 From: Araq Date: Wed, 26 Mar 2014 01:27:22 +0100 Subject: implemented 'borrow dot' feature for distinct types --- compiler/ast.nim | 4 +++- compiler/pragmas.nim | 19 +++++++++++++++---- compiler/semexprs.nim | 10 +++++----- 3 files changed, 23 insertions(+), 10 deletions(-) (limited to 'compiler') diff --git a/compiler/ast.nim b/compiler/ast.nim index 30778c02d..dd6f47ed1 100644 --- a/compiler/ast.nim +++ b/compiler/ast.nim @@ -424,7 +424,7 @@ type nfIsRef # this node is a 'ref' node; used for the VM TNodeFlags* = set[TNodeFlag] - TTypeFlag* = enum # keep below 32 for efficiency reasons (now: 23) + TTypeFlag* = enum # keep below 32 for efficiency reasons (now: 28) tfVarargs, # procedure has C styled varargs tfNoSideEffect, # procedure type does not allow side effects tfFinal, # is the object final? @@ -464,6 +464,8 @@ type # T and I here can bind to both typedesc and static types # before this is determined, we'll consider them to be a # wildcard type. + tfGuarded # guarded pointer + tfBorrowDot # distinct type borrows '.' TTypeFlags* = set[TTypeFlag] diff --git a/compiler/pragmas.nim b/compiler/pragmas.nim index efd06eef4..b5dead5b2 100644 --- a/compiler/pragmas.nim +++ b/compiler/pragmas.nim @@ -52,7 +52,8 @@ const typePragmas* = {wImportc, wExportc, wDeprecated, wMagic, wAcyclic, wNodecl, wPure, wHeader, wCompilerproc, wFinal, wSize, wExtern, wShallow, wImportCpp, wImportObjC, wError, wIncompleteStruct, wByCopy, wByRef, - wInheritable, wGensym, wInject, wRequiresInit, wUnchecked, wUnion, wPacked} + wInheritable, wGensym, wInject, wRequiresInit, wUnchecked, wUnion, wPacked, + wBorrow} fieldPragmas* = {wImportc, wExportc, wDeprecated, wExtern, wImportCpp, wImportObjC, wError} varPragmas* = {wImportc, wExportc, wVolatile, wRegister, wThreadVar, wNodecl, @@ -511,6 +512,13 @@ proc pragmaRaisesOrTags(c: PContext, n: PNode) = else: invalidPragma(n) +proc typeBorrow(sym: PSym, n: PNode) = + if n.kind == nkExprColonExpr: + let it = n.sons[1] + if it.kind != nkAccQuoted: + localError(n.info, "a type can only borrow `.` for now") + incl(sym.typ.flags, tfBorrowDot) + proc singlePragma(c: PContext, sym: PSym, n: PNode, i: int, validPragmas: TSpecialWords): bool = var it = n.sons[i] @@ -631,9 +639,12 @@ proc singlePragma(c: PContext, sym: PSym, n: PNode, i: int, noVal(it) if sym.typ == nil: invalidPragma(it) else: incl(sym.typ.flags, tfVarargs) - of wBorrow: - noVal(it) - incl(sym.flags, sfBorrow) + of wBorrow: + if sym.kind == skType: + typeBorrow(sym, it) + else: + noVal(it) + incl(sym.flags, sfBorrow) of wFinal: noVal(it) if sym.typ == nil: invalidPragma(it) diff --git a/compiler/semexprs.nim b/compiler/semexprs.nim index b3b757640..70c57b15e 100644 --- a/compiler/semexprs.nim +++ b/compiler/semexprs.nim @@ -1001,15 +1001,15 @@ proc builtinFieldAccess(c: PContext, n: PNode, flags: TExprFlags): PNode = # reset to prevent 'nil' bug: see "tests/reject/tenumitems.nim": ty = n.sons[0].typ return nil - ty = skipTypes(ty, {tyGenericInst, tyVar, tyPtr, tyRef}) + while tfBorrowDot in ty.flags: ty = ty.skipTypes({tyDistinct}) var check: PNode = nil - if ty.kind == tyObject: - while true: + if ty.kind == tyObject: + while true: check = nil f = lookupInRecordAndBuildCheck(c, n, ty.n, i, check) - if f != nil: break - if ty.sons[0] == nil: break + if f != nil: break + if ty.sons[0] == nil: break ty = skipTypes(ty.sons[0], {tyGenericInst}) if f != nil: if fieldVisible(c, f): -- cgit 1.4.1-2-gfad0