some fixes for static params usage in macros

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

View File

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

View File

@@ -94,6 +94,7 @@ type
errNewSectionExpected, errWhitespaceExpected, errXisNoValidIndexFile,
errCannotRenderX, errVarVarTypeNotAllowed, errInstantiateXExplicitely,
errOnlyACallOpCanBeDelegator, errUsingNoSymbol,
errMacroBodyDependsOnGenericTypes,
errDestructorNotGenericEnough,
errXExpectsTwoArguments,
@@ -326,6 +327,8 @@ const
errInstantiateXExplicitely: "instantiate '$1' explicitely",
errOnlyACallOpCanBeDelegator: "only a call operator can be a delegator",
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. " &
"A destructor must be associated will all instantiations of a generic type",
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
else: nil
template maybeLift(typ: PType): expr =
let lifted = liftingWalk(typ)
(if lifted != nil: lifted else: typ)
template addImplicitGeneric(e: expr): expr =
addImplicitGenericImpl(e, paramTypId)
@@ -663,7 +667,10 @@ proc liftParamType(c: PContext, procKind: TSymKind, genericParams: PNode,
of tyStatic:
# proc(a: expr{string}, b: expr{nkLambda})
# 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
of tyTypeDesc:
@@ -671,7 +678,8 @@ proc liftParamType(c: PContext, procKind: TSymKind, genericParams: PNode,
# naked typedescs are not bindOnce types
if paramType.base.kind == tyNone and paramTypId != nil and
paramTypId.id == typedescId.id: paramTypId = nil
result = addImplicitGeneric(c.newTypeWithSons(tyTypeDesc, paramType.sons))
result = addImplicitGeneric(
c.newTypeWithSons(tyTypeDesc, @[paramType.base]))
of tyDistinct:
if paramType.sonsLen == 1:

View File

@@ -1029,6 +1029,28 @@ proc paramTypesMatchAux(m: var TCandidate, f, argType: PType,
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
of isConvertible:
inc(m.convMatches)
@@ -1046,31 +1068,23 @@ proc paramTypesMatchAux(m: var TCandidate, f, argType: PType,
#result = copyTree(arg)
result = implicitConv(nkHiddenStdConv, f, copyTree(arg), m, c)
of isInferred, isInferredConvertible:
inc(m.genericMatches)
if arg.kind in {nkProcDef, nkIteratorDef} + nkLambdaKinds:
result = c.semInferredLambda(c, m.bindings, arg)
else:
let inferred = c.semGenerateInstance(c, arg.sym, m.bindings, arg.info)
result = newSymNode(inferred, arg.info)
if r == isInferredConvertible:
inc(m.convMatches)
result = implicitConv(nkHiddenStdConv, f, result, m, c)
of isGeneric:
inc(m.genericMatches)
if m.calleeSym != nil and m.calleeSym.kind in {skMacro, skTemplate}:
if f.kind == tyStmt and argOrig.kind == nkDo:
result = argOrig[bodyPos]
elif f.kind == tyTypeDesc:
result = arg
elif f.kind == tyStatic:
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
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:
# too lazy to introduce another ``*matches`` field, so we conflate
# ``isIntConv`` and ``isIntLit`` here: