mirror of
https://github.com/nim-lang/Nim.git
synced 2026-04-19 22:10:33 +00:00
first version of .partial objects
This commit is contained in:
@@ -804,20 +804,24 @@ proc parsePragma(p: var TParser): PNode =
|
||||
else: parMessage(p, errTokenExpected, ".}")
|
||||
dec p.inPragma
|
||||
|
||||
proc identVis(p: var TParser): PNode =
|
||||
proc identVis(p: var TParser; allowDot=false): PNode =
|
||||
#| identVis = symbol opr? # postfix position
|
||||
#| identVisDot = symbol '.' optInd symbol opr?
|
||||
var a = parseSymbol(p)
|
||||
if p.tok.tokType == tkOpr:
|
||||
result = newNodeP(nkPostfix, p)
|
||||
addSon(result, newIdentNodeP(p.tok.ident, p))
|
||||
addSon(result, a)
|
||||
getTok(p)
|
||||
elif p.tok.tokType == tkDot and allowDot:
|
||||
result = dotExpr(p, a)
|
||||
else:
|
||||
result = a
|
||||
|
||||
proc identWithPragma(p: var TParser): PNode =
|
||||
proc identWithPragma(p: var TParser; allowDot=false): PNode =
|
||||
#| identWithPragma = identVis pragma?
|
||||
var a = identVis(p)
|
||||
#| identWithPragmaDot = identVisDot pragma?
|
||||
var a = identVis(p, allowDot)
|
||||
if p.tok.tokType == tkCurlyDotLe:
|
||||
result = newNodeP(nkPragmaExpr, p)
|
||||
addSon(result, a)
|
||||
@@ -1803,10 +1807,11 @@ proc parseTypeClass(p: var TParser): PNode =
|
||||
addSon(result, parseStmt(p))
|
||||
|
||||
proc parseTypeDef(p: var TParser): PNode =
|
||||
#| typeDef = identWithPragma genericParamList? '=' optInd typeDefAux
|
||||
#|
|
||||
#| typeDef = identWithPragmaDot genericParamList? '=' optInd typeDefAux
|
||||
#| indAndComment?
|
||||
result = newNodeP(nkTypeDef, p)
|
||||
addSon(result, identWithPragma(p))
|
||||
addSon(result, identWithPragma(p, allowDot=true))
|
||||
if p.tok.tokType == tkBracketLe and p.validInd:
|
||||
addSon(result, parseGenericParamList(p))
|
||||
else:
|
||||
|
||||
@@ -55,7 +55,7 @@ const
|
||||
wPure, wHeader, wCompilerproc, wFinal, wSize, wExtern, wShallow,
|
||||
wImportCpp, wImportObjC, wError, wIncompleteStruct, wByCopy, wByRef,
|
||||
wInheritable, wGensym, wInject, wRequiresInit, wUnchecked, wUnion, wPacked,
|
||||
wBorrow, wGcSafe, wExportNims}
|
||||
wBorrow, wGcSafe, wExportNims, wPartial}
|
||||
fieldPragmas* = {wImportc, wExportc, wDeprecated, wExtern,
|
||||
wImportCpp, wImportObjC, wError, wGuard, wBitsize}
|
||||
varPragmas* = {wImportc, wExportc, wVolatile, wRegister, wThreadVar, wNodecl,
|
||||
@@ -835,6 +835,15 @@ proc singlePragma(c: PContext, sym: PSym, n: PNode, i: int,
|
||||
noVal(it)
|
||||
if sym.kind != skType or sym.typ == nil: invalidPragma(it)
|
||||
else: incl(sym.typ.flags, tfByCopy)
|
||||
of wPartial:
|
||||
noVal(it)
|
||||
if sym.kind != skType or sym.typ == nil: invalidPragma(it)
|
||||
else:
|
||||
incl(sym.typ.flags, tfPartial)
|
||||
# .partial types can only work with dead code elimination
|
||||
# to prevent the codegen from doing anything before we compiled
|
||||
# the whole program:
|
||||
incl gGlobalOptions, optDeadCodeElim
|
||||
of wInject, wGensym:
|
||||
# We check for errors, but do nothing with these pragmas otherwise
|
||||
# as they are handled directly in 'evalTemplate'.
|
||||
|
||||
@@ -661,13 +661,22 @@ proc typeSectionLeftSidePass(c: PContext, n: PNode) =
|
||||
if a.kind == nkCommentStmt: continue
|
||||
if a.kind != nkTypeDef: illFormedAst(a)
|
||||
checkSonsLen(a, 3)
|
||||
var s = semIdentDef(c, a.sons[0], skType)
|
||||
s.typ = newTypeS(tyForward, c)
|
||||
s.typ.sym = s # process pragmas:
|
||||
if a.sons[0].kind == nkPragmaExpr:
|
||||
pragma(c, s, a.sons[0].sons[1], typePragmas)
|
||||
# add it here, so that recursive types are possible:
|
||||
if sfGenSym notin s.flags: addInterfaceDecl(c, s)
|
||||
let name = a.sons[0]
|
||||
var s: PSym
|
||||
if name.kind == nkDotExpr:
|
||||
s = qualifiedLookUp(c, name)
|
||||
debug s
|
||||
debug s.typ.skipTypes(abstractPtrs)
|
||||
if s.kind != skType or s.typ.skipTypes(abstractPtrs).kind != tyObject or tfPartial notin s.typ.skipTypes(abstractPtrs).flags:
|
||||
localError(name.info, "only .partial objects can be extended")
|
||||
else:
|
||||
s = semIdentDef(c, name, skType)
|
||||
s.typ = newTypeS(tyForward, c)
|
||||
s.typ.sym = s # process pragmas:
|
||||
if name.kind == nkPragmaExpr:
|
||||
pragma(c, s, name.sons[1], typePragmas)
|
||||
# add it here, so that recursive types are possible:
|
||||
if sfGenSym notin s.flags: addInterfaceDecl(c, s)
|
||||
a.sons[0] = newSymNode(s)
|
||||
|
||||
proc typeSectionRightSidePass(c: PContext, n: PNode) =
|
||||
@@ -676,8 +685,9 @@ proc typeSectionRightSidePass(c: PContext, n: PNode) =
|
||||
if a.kind == nkCommentStmt: continue
|
||||
if (a.kind != nkTypeDef): illFormedAst(a)
|
||||
checkSonsLen(a, 3)
|
||||
if (a.sons[0].kind != nkSym): illFormedAst(a)
|
||||
var s = a.sons[0].sym
|
||||
let name = a.sons[0]
|
||||
if (name.kind != nkSym): illFormedAst(a)
|
||||
var s = name.sym
|
||||
if s.magic == mNone and a.sons[2].kind == nkEmpty:
|
||||
localError(a.info, errImplOfXexpected, s.name.s)
|
||||
if s.magic != mNone: processMagicType(c, s)
|
||||
|
||||
@@ -673,7 +673,11 @@ proc semObjectNode(c: PContext, n: PNode, prev: PType): PType =
|
||||
if n.kind != nkObjectTy: internalError(n.info, "semObjectNode")
|
||||
result = newOrPrevType(tyObject, prev, c)
|
||||
rawAddSon(result, base)
|
||||
result.n = newNodeI(nkRecList, n.info)
|
||||
if result.n.isNil:
|
||||
result.n = newNodeI(nkRecList, n.info)
|
||||
else:
|
||||
# partial object so add things to the check
|
||||
addInheritedFields(c, check, pos, result)
|
||||
semRecordNodeAux(c, n.sons[2], check, pos, result.n, result)
|
||||
if n.sons[0].kind != nkEmpty:
|
||||
# dummy symbol for `pragma`:
|
||||
|
||||
@@ -66,6 +66,7 @@ type
|
||||
wWrite, wGensym, wInject, wDirty, wInheritable, wThreadVar, wEmit,
|
||||
wAsmNoStackFrame,
|
||||
wImplicitStatic, wGlobal, wCodegenDecl, wUnchecked, wGuard, wLocks,
|
||||
wPartial,
|
||||
|
||||
wAuto, wBool, wCatch, wChar, wClass,
|
||||
wConst_cast, wDefault, wDelete, wDouble, wDynamic_cast,
|
||||
@@ -151,7 +152,7 @@ const
|
||||
"computedgoto", "injectstmt", "experimental",
|
||||
"write", "gensym", "inject", "dirty", "inheritable", "threadvar", "emit",
|
||||
"asmnostackframe", "implicitstatic", "global", "codegendecl", "unchecked",
|
||||
"guard", "locks",
|
||||
"guard", "locks", "partial",
|
||||
|
||||
"auto", "bool", "catch", "char", "class",
|
||||
"const_cast", "default", "delete", "double",
|
||||
|
||||
@@ -67,7 +67,9 @@ ifExpr = 'if' condExpr
|
||||
whenExpr = 'when' condExpr
|
||||
pragma = '{.' optInd (exprColonExpr comma?)* optPar ('.}' | '}')
|
||||
identVis = symbol opr? # postfix position
|
||||
identVisDot = symbol '.' optInd symbol opr?
|
||||
identWithPragma = identVis pragma?
|
||||
identWithPragmaDot = identVisDot pragma?
|
||||
declColonEquals = identWithPragma (comma identWithPragma)* comma?
|
||||
(':' optInd typeDesc)? ('=' optInd expr)?
|
||||
identColonEquals = ident (comma ident)* comma?
|
||||
@@ -171,7 +173,7 @@ object = 'object' pragma? ('of' typeDesc)? COMMENT? objectPart
|
||||
typeClassParam = ('var' | 'out')? symbol
|
||||
typeClass = typeClassParam ^* ',' (pragma)? ('of' typeDesc ^* ',')?
|
||||
&IND{>} stmt
|
||||
typeDef = identWithPragma genericParamList? '=' optInd typeDefAux
|
||||
typeDef = identWithPragmaDot genericParamList? '=' optInd typeDefAux
|
||||
indAndComment?
|
||||
varTuple = '(' optInd identWithPragma ^+ comma optPar ')' '=' optInd expr
|
||||
variable = (varTuple / identColonEquals) indAndComment
|
||||
|
||||
Reference in New Issue
Block a user