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