bugfix: type alias to generic; generic type not stripped away from for loop variable

This commit is contained in:
Araq 2012-01-07 20:03:41 +01:00
commit 7405278138
8 changed files with 118 additions and 69 deletions

View file

@ -32,6 +32,9 @@ proc isDefined*(symbol: PIdent): bool =
var sym = StrTableGet(gSymbols, symbol) var sym = StrTableGet(gSymbols, symbol)
result = sym != nil and sym.position == 1 result = sym != nil and sym.position == 1
proc isDefined*(symbol: string): bool =
result = isDefined(getIdent(symbol))
proc ListSymbols*() = proc ListSymbols*() =
var it: TTabIter var it: TTabIter
var s = InitTabIter(it, gSymbols) var s = InitTabIter(it, gSymbols)

View file

@ -116,9 +116,9 @@ proc explicitGenericInstantiation(c: PContext, n: PNode, s: PSym): PNode =
# type parameters: # type parameters:
if safeLen(candidate.ast.sons[genericParamsPos]) == n.len-1: if safeLen(candidate.ast.sons[genericParamsPos]) == n.len-1:
result.add(explicitGenericSym(c, n, candidate)) result.add(explicitGenericSym(c, n, candidate))
# get rid of nkSymChoice if not ambigious: # get rid of nkSymChoice if not ambiguous:
if result.len == 1: result = result[0] if result.len == 1: result = result[0]
# candidateCount != 1: return explicitGenericInstError(n) # candidateCount != 1: return explicitGenericInstError(n)
else: else:
assert false result = explicitGenericInstError(n)

View file

@ -417,7 +417,10 @@ proc semFor(c: PContext, n: PNode): PNode =
if iter.kind != tyTuple or length == 3: if iter.kind != tyTuple or length == 3:
if length != 3: GlobalError(n.info, errWrongNumberOfVariables) if length != 3: GlobalError(n.info, errWrongNumberOfVariables)
var v = newSymS(skForVar, n.sons[0], c) var v = newSymS(skForVar, n.sons[0], c)
v.typ = iter # BUGFIX: don't use `iter` here as that would strip away
# the ``tyGenericInst``! See ``tests/compile/tgeneric.nim``
# for an example:
v.typ = n.sons[length-2].typ
n.sons[0] = newSymNode(v) n.sons[0] = newSymNode(v)
addDecl(c, v) addDecl(c, v)
else: else:

View file

@ -12,7 +12,7 @@
import import
intsets, ast, astalgo, semdata, types, msgs, renderer, lookups, semtypinst, intsets, ast, astalgo, semdata, types, msgs, renderer, lookups, semtypinst,
magicsys magicsys, condsyms, idents
type type
TCandidateState* = enum TCandidateState* = enum
@ -27,7 +27,7 @@ type
callee*: PType # may not be nil! callee*: PType # may not be nil!
calleeSym*: PSym # may be nil calleeSym*: PSym # may be nil
call*: PNode # modified call call*: PNode # modified call
bindings*: TIdTable # maps sym-ids to types bindings*: TIdTable # maps types to types
baseTypeMatch: bool # needed for conversions from T to openarray[T] baseTypeMatch: bool # needed for conversions from T to openarray[T]
# for example # for example
@ -52,6 +52,12 @@ proc initCandidate*(c: var TCandidate, callee: PType) =
c.calleeSym = nil c.calleeSym = nil
initIdTable(c.bindings) initIdTable(c.bindings)
proc put(t: var TIdTable, key, val: PType) {.inline.} =
IdTablePut(t, key, val)
if val.kind == tyObject and isDefined"testme" and
IdentEq(val.sym.name, "TTable"):
assert false
proc initCandidate*(c: var TCandidate, callee: PSym, binding: PNode) = proc initCandidate*(c: var TCandidate, callee: PSym, binding: PNode) =
initCandidateAux(c, callee.typ) initCandidateAux(c, callee.typ)
c.calleeSym = callee c.calleeSym = callee
@ -61,7 +67,7 @@ proc initCandidate*(c: var TCandidate, callee: PSym, binding: PNode) =
for i in 1..min(sonsLen(typeParams), sonsLen(binding)-1): for i in 1..min(sonsLen(typeParams), sonsLen(binding)-1):
var formalTypeParam = typeParams.sons[i-1].typ var formalTypeParam = typeParams.sons[i-1].typ
#debug(formalTypeParam) #debug(formalTypeParam)
IdTablePut(c.bindings, formalTypeParam, binding[i].typ) put(c.bindings, formalTypeParam, binding[i].typ)
proc copyCandidate(a: var TCandidate, b: TCandidate) = proc copyCandidate(a: var TCandidate, b: TCandidate) =
a.exactMatches = b.exactMatches a.exactMatches = b.exactMatches
@ -100,7 +106,7 @@ proc getNotFoundError*(c: PContext, n: PNode): string =
# in case of an error). # in case of an error).
result = msgKindToString(errTypeMismatch) result = msgKindToString(errTypeMismatch)
for i in countup(1, sonsLen(n) - 1): for i in countup(1, sonsLen(n) - 1):
#debug(n.sons[i].typ); #debug(n.sons[i].typ)
if n.sons[i].kind == nkExprEqExpr: if n.sons[i].kind == nkExprEqExpr:
add(result, renderTree(n.sons[i].sons[0])) add(result, renderTree(n.sons[i].sons[0]))
add(result, ": ") add(result, ": ")
@ -225,7 +231,7 @@ proc procTypeRel(mapping: var TIdTable, f, a: PType): TTypeRelation =
if tfNoSideEffect in f.flags and tfNoSideEffect notin a.flags: if tfNoSideEffect in f.flags and tfNoSideEffect notin a.flags:
result = isNone result = isNone
elif tfThread in f.flags and a.flags * {tfThread, tfNoSideEffect} == {}: elif tfThread in f.flags and a.flags * {tfThread, tfNoSideEffect} == {}:
# noSideEffect implies ``tfThread``! # noSideEffect implies ``tfThread``! XXX really?
result = isNone result = isNone
else: nil else: nil
@ -413,7 +419,7 @@ proc typeRel(mapping: var TIdTable, f, a: PType): TTypeRelation =
var x = PType(idTableGet(mapping, f.sons[0].sons[i - 1])) var x = PType(idTableGet(mapping, f.sons[0].sons[i - 1]))
if x == nil or x.kind in {tyGenericInvokation, tyGenericParam}: if x == nil or x.kind in {tyGenericInvokation, tyGenericParam}:
InternalError("wrong instantiated type!") InternalError("wrong instantiated type!")
idTablePut(mapping, f.sons[i], x) put(mapping, f.sons[i], x)
of tyGenericParam: of tyGenericParam:
var x = PType(idTableGet(mapping, f)) var x = PType(idTableGet(mapping, f))
if x == nil: if x == nil:
@ -421,7 +427,7 @@ proc typeRel(mapping: var TIdTable, f, a: PType): TTypeRelation =
# no constraints # no constraints
var concrete = concreteType(mapping, a) var concrete = concreteType(mapping, a)
if concrete != nil: if concrete != nil:
idTablePut(mapping, f, concrete) put(mapping, f, concrete)
result = isGeneric result = isGeneric
else: else:
# check constraints: # check constraints:
@ -429,7 +435,7 @@ proc typeRel(mapping: var TIdTable, f, a: PType): TTypeRelation =
if typeRel(mapping, f.sons[i], a) >= isSubtype: if typeRel(mapping, f.sons[i], a) >= isSubtype:
var concrete = concreteType(mapping, a) var concrete = concreteType(mapping, a)
if concrete != nil: if concrete != nil:
idTablePut(mapping, f, concrete) put(mapping, f, concrete)
result = isGeneric result = isGeneric
break break
elif a.kind == tyEmpty: elif a.kind == tyEmpty:

117
koch.nim
View file

@ -36,7 +36,7 @@ Possible Commands:
zip builds the installation ZIP package zip builds the installation ZIP package
inno [options] builds the Inno Setup installer (for Windows) inno [options] builds the Inno Setup installer (for Windows)
tests run the testsuite tests run the testsuite
update updates nimrod to the latest version from the repo update updates nimrod to the latest version from github
Boot options: Boot options:
-d:release produce a release version of the compiler -d:release produce a release version of the compiler
-d:tinyc include the Tiny C backend (not supported on Windows) -d:tinyc include the Tiny C backend (not supported on Windows)
@ -83,62 +83,6 @@ proc web(args: string) =
exec("nimrod cc -r tools/nimweb.nim web/nimrod --putenv:nimrodversion=$#" % exec("nimrod cc -r tools/nimweb.nim web/nimrod --putenv:nimrodversion=$#" %
NimrodVersion) NimrodVersion)
proc update(args: string) =
when defined(windows):
echo("Windows users: Make sure to be running this in Bash. ",
"If you aren't, press CTRL+C now.")
var thisDir = getAppDir()
var git = findExe("git")
echo("Checking for git repo and git executable...")
if existsDir(thisDir & "/.git") and git != "":
echo("Git repo found!")
# use git to download latest source
echo("Checking for updates...")
discard startCmd(git & " fetch origin master")
var procs = startCmd(git & " diff origin/master master")
var errcode = procs.waitForExit()
var output = readLine(procs.outputStream)
echo(output)
if errcode == 0:
if output == "":
# No changes
echo("No update. Exiting..")
return
else:
echo("Fetching updates from repo...")
var pullout = execCmdEx(git & " pull origin master")
if pullout[1] != 0:
quit("An error has occured.")
else:
if pullout[0].startsWith("Already up-to-date."):
quit("No new changes fetched from the repo. " &
"Local branch must be ahead of it. Exiting...")
else:
quit("An error has occured.")
else:
echo("No repo or executable found!")
when defined(haveZipLib):
echo("Falling back.. Downloading source code from repo...")
# use dom96's httpclient to download zip
downloadFile("https://github.com/Araq/Nimrod/zipball/master",
thisDir / "update.zip")
try:
echo("Extracting source code from archive...")
var zip: TZipArchive
discard open(zip, thisDir & "/update.zip", fmRead)
extractAll(zip, thisDir & "/")
except:
quit("Error reading archive.")
else:
quit("No failback available. Exiting...")
echo("Starting update...")
boot(args)
echo("Update complete!")
# -------------- boot --------------------------------------------------------- # -------------- boot ---------------------------------------------------------
const const
@ -237,6 +181,65 @@ proc clean(args: string) =
echo "removing dir: ", path echo "removing dir: ", path
RemoveDir(path) RemoveDir(path)
# -------------- update -------------------------------------------------------
proc update(args: string) =
when defined(windows):
echo("Windows users: Make sure to be running this in Bash. ",
"If you aren't, press CTRL+C now.")
var thisDir = getAppDir()
var git = findExe("git")
echo("Checking for git repo and git executable...")
if existsDir(thisDir & "/.git") and git != "":
echo("Git repo found!")
# use git to download latest source
echo("Checking for updates...")
discard startCmd(git & " fetch origin master")
var procs = startCmd(git & " diff origin/master master")
var errcode = procs.waitForExit()
var output = readLine(procs.outputStream)
echo(output)
if errcode == 0:
if output == "":
# No changes
echo("No update. Exiting..")
return
else:
echo("Fetching updates from repo...")
var pullout = execCmdEx(git & " pull origin master")
if pullout[1] != 0:
quit("An error has occured.")
else:
if pullout[0].startsWith("Already up-to-date."):
quit("No new changes fetched from the repo. " &
"Local branch must be ahead of it. Exiting...")
else:
quit("An error has occured.")
else:
echo("No repo or executable found!")
when defined(haveZipLib):
echo("Falling back.. Downloading source code from repo...")
# use dom96's httpclient to download zip
downloadFile("https://github.com/Araq/Nimrod/zipball/master",
thisDir / "update.zip")
try:
echo("Extracting source code from archive...")
var zip: TZipArchive
discard open(zip, thisDir & "/update.zip", fmRead)
extractAll(zip, thisDir & "/")
except:
quit("Error reading archive.")
else:
quit("No failback available. Exiting...")
echo("Starting update...")
boot(args)
echo("Update complete!")
# -------------- tests --------------------------------------------------------
proc tests(args: string) = proc tests(args: string) =
# we compile the tester with taintMode:on to have a basic # we compile the tester with taintMode:on to have a basic
# taint mode test :-) # taint mode test :-)

View file

@ -0,0 +1,11 @@
import tables
type
TX = TTable[string, int]
proc foo(models: seq[TTable[string, float]]): seq[float] =
result = @[]
for model in models.items:
result.add model["foobar"]

View file

@ -0,0 +1,11 @@
import tables
type
TX = TTable[string, int]
proc foo(models: seq[TX]): seq[int] =
result = @[]
for model in models.items:
result.add model["foobar"]

View file

@ -0,0 +1,12 @@
type
TProperty[T] = object of TObject
getProc: proc(property: TProperty[T]): T
setProc: proc(property: TProperty[T], value: T)
value: T
proc newProperty[T](value: TObject): TProperty[T] =
result.getProc = proc (property: TProperty[T]) =
return property.value