diff options
-rwxr-xr-x | compiler/condsyms.nim | 3 | ||||
-rwxr-xr-x | compiler/semcall.nim | 4 | ||||
-rwxr-xr-x | compiler/semstmts.nim | 5 | ||||
-rwxr-xr-x | compiler/sigmatch.nim | 24 | ||||
-rwxr-xr-x | koch.nim | 117 | ||||
-rw-r--r-- | tests/compile/tgeneric.nim | 11 | ||||
-rw-r--r-- | tests/compile/tgeneric2.nim | 11 | ||||
-rw-r--r-- | tests/compile/tgenericprop.nim | 12 |
8 files changed, 118 insertions, 69 deletions
diff --git a/compiler/condsyms.nim b/compiler/condsyms.nim index fca494324..5467e3929 100755 --- a/compiler/condsyms.nim +++ b/compiler/condsyms.nim @@ -32,6 +32,9 @@ proc isDefined*(symbol: PIdent): bool = var sym = StrTableGet(gSymbols, symbol) result = sym != nil and sym.position == 1 +proc isDefined*(symbol: string): bool = + result = isDefined(getIdent(symbol)) + proc ListSymbols*() = var it: TTabIter var s = InitTabIter(it, gSymbols) diff --git a/compiler/semcall.nim b/compiler/semcall.nim index 8d6af4528..c92eff319 100755 --- a/compiler/semcall.nim +++ b/compiler/semcall.nim @@ -116,9 +116,9 @@ proc explicitGenericInstantiation(c: PContext, n: PNode, s: PSym): PNode = # type parameters: if safeLen(candidate.ast.sons[genericParamsPos]) == n.len-1: 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] # candidateCount != 1: return explicitGenericInstError(n) else: - assert false + result = explicitGenericInstError(n) diff --git a/compiler/semstmts.nim b/compiler/semstmts.nim index fdb2bfe36..52a3853f2 100755 --- a/compiler/semstmts.nim +++ b/compiler/semstmts.nim @@ -417,7 +417,10 @@ proc semFor(c: PContext, n: PNode): PNode = if iter.kind != tyTuple or length == 3: if length != 3: GlobalError(n.info, errWrongNumberOfVariables) 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) addDecl(c, v) else: diff --git a/compiler/sigmatch.nim b/compiler/sigmatch.nim index 59501f403..6b6ebb40a 100755 --- a/compiler/sigmatch.nim +++ b/compiler/sigmatch.nim @@ -12,7 +12,7 @@ import intsets, ast, astalgo, semdata, types, msgs, renderer, lookups, semtypinst, - magicsys + magicsys, condsyms, idents type TCandidateState* = enum @@ -27,7 +27,7 @@ type callee*: PType # may not be nil! calleeSym*: PSym # may be nil 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] # for example @@ -52,6 +52,12 @@ proc initCandidate*(c: var TCandidate, callee: PType) = c.calleeSym = nil 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) = initCandidateAux(c, callee.typ) 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): var formalTypeParam = typeParams.sons[i-1].typ #debug(formalTypeParam) - IdTablePut(c.bindings, formalTypeParam, binding[i].typ) + put(c.bindings, formalTypeParam, binding[i].typ) proc copyCandidate(a: var TCandidate, b: TCandidate) = a.exactMatches = b.exactMatches @@ -100,7 +106,7 @@ proc getNotFoundError*(c: PContext, n: PNode): string = # in case of an error). result = msgKindToString(errTypeMismatch) for i in countup(1, sonsLen(n) - 1): - #debug(n.sons[i].typ); + #debug(n.sons[i].typ) if n.sons[i].kind == nkExprEqExpr: add(result, renderTree(n.sons[i].sons[0])) 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: result = isNone elif tfThread in f.flags and a.flags * {tfThread, tfNoSideEffect} == {}: - # noSideEffect implies ``tfThread``! + # noSideEffect implies ``tfThread``! XXX really? result = isNone else: nil @@ -236,7 +242,7 @@ proc typeRel(mapping: var TIdTable, f, a: PType): TTypeRelation = assert(a != nil) if a.kind == tyGenericInst and skipTypes(f, {tyVar}).kind notin { - tyGenericBody, tyGenericInvokation, tyGenericParam}: + tyGenericBody, tyGenericInvokation, tyGenericParam}: return typeRel(mapping, f, lastSon(a)) if a.kind == tyVar and f.kind != tyVar: return typeRel(mapping, f, a.sons[0]) @@ -413,7 +419,7 @@ proc typeRel(mapping: var TIdTable, f, a: PType): TTypeRelation = var x = PType(idTableGet(mapping, f.sons[0].sons[i - 1])) if x == nil or x.kind in {tyGenericInvokation, tyGenericParam}: InternalError("wrong instantiated type!") - idTablePut(mapping, f.sons[i], x) + put(mapping, f.sons[i], x) of tyGenericParam: var x = PType(idTableGet(mapping, f)) if x == nil: @@ -421,7 +427,7 @@ proc typeRel(mapping: var TIdTable, f, a: PType): TTypeRelation = # no constraints var concrete = concreteType(mapping, a) if concrete != nil: - idTablePut(mapping, f, concrete) + put(mapping, f, concrete) result = isGeneric else: # check constraints: @@ -429,7 +435,7 @@ proc typeRel(mapping: var TIdTable, f, a: PType): TTypeRelation = if typeRel(mapping, f.sons[i], a) >= isSubtype: var concrete = concreteType(mapping, a) if concrete != nil: - idTablePut(mapping, f, concrete) + put(mapping, f, concrete) result = isGeneric break elif a.kind == tyEmpty: diff --git a/koch.nim b/koch.nim index a19de3f2f..35b7d7f3d 100755 --- a/koch.nim +++ b/koch.nim @@ -36,7 +36,7 @@ Possible Commands: zip builds the installation ZIP package inno [options] builds the Inno Setup installer (for Windows) 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: -d:release produce a release version of the compiler -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=$#" % 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 --------------------------------------------------------- const @@ -237,6 +181,65 @@ proc clean(args: string) = echo "removing dir: ", 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) = # we compile the tester with taintMode:on to have a basic # taint mode test :-) diff --git a/tests/compile/tgeneric.nim b/tests/compile/tgeneric.nim new file mode 100644 index 000000000..8bda15c42 --- /dev/null +++ b/tests/compile/tgeneric.nim @@ -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"] + + diff --git a/tests/compile/tgeneric2.nim b/tests/compile/tgeneric2.nim new file mode 100644 index 000000000..b9b8e5a62 --- /dev/null +++ b/tests/compile/tgeneric2.nim @@ -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"] + + diff --git a/tests/compile/tgenericprop.nim b/tests/compile/tgenericprop.nim new file mode 100644 index 000000000..211fddecf --- /dev/null +++ b/tests/compile/tgenericprop.nim @@ -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 + + |