some fixes for static params usage in macros

This commit is contained in:
Zahary Karadjov 2014-02-25 00:49:24 +02:00
commit e6b0b7ecc9
4 changed files with 51 additions and 26 deletions

View file

@ -962,8 +962,8 @@ proc genMainProc(m: BModule) =
NimMainBody = NimMainBody =
"N_CDECL(void, NimMain)(void) {$N" & "N_CDECL(void, NimMain)(void) {$N" &
"\tPreMain();$N" & "\tPreMain();$N" &
"$1$N" & "$1" &
"}$N" "}$N$N"
PosixNimMain = PosixNimMain =
"int cmdCount;$N" & "int cmdCount;$N" &
@ -977,20 +977,20 @@ proc genMainProc(m: BModule) =
"\tcmdCount = argc;$N" & "\tcmdCount = argc;$N" &
"\tgEnv = env;$N" & "\tgEnv = env;$N" &
MainProcsWithResult & MainProcsWithResult &
"}$N" "}$N$N"
StandaloneCMain = StandaloneCMain =
"int main(void) {$N" & "int main(void) {$N" &
MainProcs & MainProcs &
"\treturn 0;$N" & "\treturn 0;$N" &
"}$N" "}$N$N"
WinNimMain = NimMainBody WinNimMain = NimMainBody
WinCMain = "N_STDCALL(int, WinMain)(HINSTANCE hCurInstance, $N" & WinCMain = "N_STDCALL(int, WinMain)(HINSTANCE hCurInstance, $N" &
" HINSTANCE hPrevInstance, $N" & " HINSTANCE hPrevInstance, $N" &
" LPSTR lpCmdLine, int nCmdShow) {$N" & " LPSTR lpCmdLine, int nCmdShow) {$N" &
MainProcsWithResult & "}$N" MainProcsWithResult & "}$N$N"
WinNimDllMain = "N_LIB_EXPORT " & NimMainBody WinNimDllMain = "N_LIB_EXPORT " & NimMainBody
@ -998,14 +998,14 @@ proc genMainProc(m: BModule) =
"BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fwdreason, $N" & "BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fwdreason, $N" &
" LPVOID lpvReserved) {$N" & " LPVOID lpvReserved) {$N" &
"\tif(fwdreason == DLL_PROCESS_ATTACH) {$N" & MainProcs & "}$N" & "\tif(fwdreason == DLL_PROCESS_ATTACH) {$N" & MainProcs & "}$N" &
"\treturn 1;$N}$N" "\treturn 1;$N}$N$N"
PosixNimDllMain = WinNimDllMain PosixNimDllMain = WinNimDllMain
PosixCDllMain = PosixCDllMain =
"void NIM_POSIX_INIT NimMainInit(void) {$N" & "void NIM_POSIX_INIT NimMainInit(void) {$N" &
MainProcs & MainProcs &
"}$N" "}$N$N"
var nimMain, otherMain: TFormatStr var nimMain, otherMain: TFormatStr
if platform.targetOS == osWindows and if platform.targetOS == osWindows and
@ -1034,7 +1034,7 @@ proc genMainProc(m: BModule) =
platform.targetOS == osStandalone: "".toRope platform.targetOS == osStandalone: "".toRope
else: ropecg(m, "\t#initStackBottom();$N") else: ropecg(m, "\t#initStackBottom();$N")
inc(m.labels) inc(m.labels)
appcg(m, m.s[cfsProcs], "void PreMain() {$N" & PreMainBody & "}$N", [ appcg(m, m.s[cfsProcs], "void PreMain() {$N" & PreMainBody & "}$N$N", [
mainDatInit, initStackBottomCall, gBreakpoints, otherModsInit]) mainDatInit, initStackBottomCall, gBreakpoints, otherModsInit])
appcg(m, m.s[cfsProcs], nimMain, [mainModInit, toRope(m.labels)]) appcg(m, m.s[cfsProcs], nimMain, [mainModInit, toRope(m.labels)])

View file

@ -94,6 +94,7 @@ type
errNewSectionExpected, errWhitespaceExpected, errXisNoValidIndexFile, errNewSectionExpected, errWhitespaceExpected, errXisNoValidIndexFile,
errCannotRenderX, errVarVarTypeNotAllowed, errInstantiateXExplicitely, errCannotRenderX, errVarVarTypeNotAllowed, errInstantiateXExplicitely,
errOnlyACallOpCanBeDelegator, errUsingNoSymbol, errOnlyACallOpCanBeDelegator, errUsingNoSymbol,
errMacroBodyDependsOnGenericTypes,
errDestructorNotGenericEnough, errDestructorNotGenericEnough,
errXExpectsTwoArguments, errXExpectsTwoArguments,
@ -326,6 +327,8 @@ const
errInstantiateXExplicitely: "instantiate '$1' explicitely", errInstantiateXExplicitely: "instantiate '$1' explicitely",
errOnlyACallOpCanBeDelegator: "only a call operator can be a delegator", errOnlyACallOpCanBeDelegator: "only a call operator can be a delegator",
errUsingNoSymbol: "'$1' is not a variable, constant or a proc name", errUsingNoSymbol: "'$1' is not a variable, constant or a proc name",
errMacroBodyDependsOnGenericTypes: "the macro body cannot be compiled, " &
"because the parameter '$1' has a generic type",
errDestructorNotGenericEnough: "Destructor signarue is too specific. " & errDestructorNotGenericEnough: "Destructor signarue is too specific. " &
"A destructor must be associated will all instantiations of a generic type", "A destructor must be associated will all instantiations of a generic type",
errXExpectsTwoArguments: "\'$1\' expects two arguments", errXExpectsTwoArguments: "\'$1\' expects two arguments",

View file

@ -653,6 +653,10 @@ proc liftParamType(c: PContext, procKind: TSymKind, genericParams: PNode,
var paramTypId = if not anon and paramType.sym != nil: paramType.sym.name var paramTypId = if not anon and paramType.sym != nil: paramType.sym.name
else: nil else: nil
template maybeLift(typ: PType): expr =
let lifted = liftingWalk(typ)
(if lifted != nil: lifted else: typ)
template addImplicitGeneric(e: expr): expr = template addImplicitGeneric(e: expr): expr =
addImplicitGenericImpl(e, paramTypId) addImplicitGenericImpl(e, paramTypId)
@ -663,7 +667,10 @@ proc liftParamType(c: PContext, procKind: TSymKind, genericParams: PNode,
of tyStatic: of tyStatic:
# proc(a: expr{string}, b: expr{nkLambda}) # proc(a: expr{string}, b: expr{nkLambda})
# overload on compile time values and AST trees # overload on compile time values and AST trees
result = addImplicitGeneric(c.newTypeWithSons(tyStatic, paramType.sons)) let base = paramType.base.maybeLift
if base.isMetaType and procKind == skMacro:
localError(info, errMacroBodyDependsOnGenericTypes, paramName)
result = addImplicitGeneric(c.newTypeWithSons(tyStatic, @[base]))
result.flags.incl tfHasStatic result.flags.incl tfHasStatic
of tyTypeDesc: of tyTypeDesc:
@ -671,7 +678,8 @@ proc liftParamType(c: PContext, procKind: TSymKind, genericParams: PNode,
# naked typedescs are not bindOnce types # naked typedescs are not bindOnce types
if paramType.base.kind == tyNone and paramTypId != nil and if paramType.base.kind == tyNone and paramTypId != nil and
paramTypId.id == typedescId.id: paramTypId = nil paramTypId.id == typedescId.id: paramTypId = nil
result = addImplicitGeneric(c.newTypeWithSons(tyTypeDesc, paramType.sons)) result = addImplicitGeneric(
c.newTypeWithSons(tyTypeDesc, @[paramType.base]))
of tyDistinct: of tyDistinct:
if paramType.sonsLen == 1: if paramType.sonsLen == 1:

View file

@ -1029,6 +1029,28 @@ proc paramTypesMatchAux(m: var TCandidate, f, argType: PType,
r = typeRel(m, f, a) r = typeRel(m, f, a)
if r != isNone and m.calleeSym != nil and
m.calleeSym.kind in {skMacro, skTemplate}:
# XXX: duplicating this is ugly, maybe we should move this
# directly into typeRel using return-like templates
case r
of isConvertible, isIntConv: inc(m.convMatches)
of isSubtype, isSubrange: inc(m.subtypeMatches)
of isGeneric, isInferred: inc(m.genericMatches)
of isInferredConvertible: inc(m.genericMatches); inc(m.convMatches)
of isFromIntLit: inc(m.intConvMatches, 256)
of isEqual: inc(m.exactMatches)
of isNone: discard
if f.kind == tyStmt and argOrig.kind == nkDo:
return argOrig[bodyPos]
elif f.kind == tyTypeDesc:
return arg
elif f.kind == tyStatic:
return arg.typ.n
else:
return argOrig
case r case r
of isConvertible: of isConvertible:
inc(m.convMatches) inc(m.convMatches)
@ -1046,31 +1068,23 @@ proc paramTypesMatchAux(m: var TCandidate, f, argType: PType,
#result = copyTree(arg) #result = copyTree(arg)
result = implicitConv(nkHiddenStdConv, f, copyTree(arg), m, c) result = implicitConv(nkHiddenStdConv, f, copyTree(arg), m, c)
of isInferred, isInferredConvertible: of isInferred, isInferredConvertible:
inc(m.genericMatches)
if arg.kind in {nkProcDef, nkIteratorDef} + nkLambdaKinds: if arg.kind in {nkProcDef, nkIteratorDef} + nkLambdaKinds:
result = c.semInferredLambda(c, m.bindings, arg) result = c.semInferredLambda(c, m.bindings, arg)
else: else:
let inferred = c.semGenerateInstance(c, arg.sym, m.bindings, arg.info) let inferred = c.semGenerateInstance(c, arg.sym, m.bindings, arg.info)
result = newSymNode(inferred, arg.info) result = newSymNode(inferred, arg.info)
if r == isInferredConvertible: if r == isInferredConvertible:
inc(m.convMatches)
result = implicitConv(nkHiddenStdConv, f, result, m, c) result = implicitConv(nkHiddenStdConv, f, result, m, c)
of isGeneric: of isGeneric:
inc(m.genericMatches) inc(m.genericMatches)
if m.calleeSym != nil and m.calleeSym.kind in {skMacro, skTemplate}: result = copyTree(arg)
if f.kind == tyStmt and argOrig.kind == nkDo: result.typ = getInstantiatedType(c, arg, m, f)
result = argOrig[bodyPos] # BUG: f may not be the right key!
elif f.kind == tyTypeDesc: if skipTypes(result.typ, abstractVar-{tyTypeDesc}).kind in {tyTuple}:
result = arg result = implicitConv(nkHiddenStdConv, f, copyTree(arg), m, c)
elif f.kind == tyStatic: # BUGFIX: use ``result.typ`` and not `f` here
result = arg.typ.n
else:
result = argOrig
else:
result = copyTree(arg)
result.typ = getInstantiatedType(c, arg, m, f)
# BUG: f may not be the right key!
if skipTypes(result.typ, abstractVar-{tyTypeDesc}).kind in {tyTuple}:
result = implicitConv(nkHiddenStdConv, f, copyTree(arg), m, c)
# BUGFIX: use ``result.typ`` and not `f` here
of isFromIntLit: of isFromIntLit:
# too lazy to introduce another ``*matches`` field, so we conflate # too lazy to introduce another ``*matches`` field, so we conflate
# ``isIntConv`` and ``isIntLit`` here: # ``isIntConv`` and ``isIntLit`` here: