diff options
author | Audun Wilhelmsen <skyfex@gmail.com> | 2015-01-02 22:12:11 +0100 |
---|---|---|
committer | Audun Wilhelmsen <skyfex@gmail.com> | 2015-01-02 22:12:11 +0100 |
commit | c461f5a8c6cbc753f47393de61e713b25e743661 (patch) | |
tree | 03281686f16d4a2876dc0713bca8f47ad6c9a855 | |
parent | e5bfb7d55017a0f205682f34c01ac709dcf82940 (diff) | |
parent | 5023a9043858941d311c253fd1b62017080367be (diff) | |
download | Nim-c461f5a8c6cbc753f47393de61e713b25e743661.tar.gz |
Merge branch 'devel' of https://github.com/Araq/Nim into devel
57 files changed, 668 insertions, 452 deletions
diff --git a/compiler/ast.nim b/compiler/ast.nim index 565bb4353..d85dbf42c 100644 --- a/compiler/ast.nim +++ b/compiler/ast.nim @@ -1517,8 +1517,8 @@ proc getStr*(a: PNode): string = proc getStrOrChar*(a: PNode): string = case a.kind of nkStrLit..nkTripleStrLit: result = a.strVal - of nkCharLit: result = $chr(int(a.intVal)) - else: + of nkCharLit..nkUInt64Lit: result = $chr(int(a.intVal)) + else: internalError(a.info, "getStrOrChar") result = "" diff --git a/compiler/nim.ini b/compiler/nim.ini index 576b6d2bb..1f14eb21b 100644 --- a/compiler/nim.ini +++ b/compiler/nim.ini @@ -125,7 +125,7 @@ Files: "start.bat" BinPath: r"bin;dist\mingw\bin;dist" ; Section | dir | zipFile | size hint (in KB) | url | exe start menu entry -Download: r"Documentation|doc|docs.zip|13824|http://nim-lang.org/download/docs-${version}.zip|doc\overview.html" +Download: r"Documentation|doc|docs.zip|13824|http://nim-lang.org/download/docs-${version}.zip|overview.html" Download: r"C Compiler (MingW)|dist|mingw.zip|82944|http://nim-lang.org/download/${mingw}.zip" Download: r"Aporia IDE|dist|aporia.zip|97997|http://nim-lang.org/download/aporia-0.1.3.zip|aporia\bin\aporia.exe" ; for now only NSIS supports optional downloads diff --git a/compiler/nim.nimrod.cfg b/compiler/nim.nimrod.cfg index ba7697c4c..f4d8b9dcb 100644 --- a/compiler/nim.nimrod.cfg +++ b/compiler/nim.nimrod.cfg @@ -1,7 +1,5 @@ # Special configuration file for the Nim project -# gc:markAndSweep - hint[XDeclaredButNotUsed]:off path:"llvm" path:"$projectPath/.." diff --git a/compiler/sem.nim b/compiler/sem.nim index 91adcac5e..9ac7ad139 100644 --- a/compiler/sem.nim +++ b/compiler/sem.nim @@ -67,12 +67,25 @@ proc fitNode(c: PContext, formal: PType, arg: PNode): PNode = # error correction: result = copyTree(arg) result.typ = formal + else: + let x = result.skipConv + if x.kind == nkPar and formal.kind != tyExpr: + changeType(x, formal, check=true) proc inferWithMetatype(c: PContext, formal: PType, arg: PNode, coerceDistincts = false): PNode var commonTypeBegin = PType(kind: tyExpr) +proc isEmptyContainer(t: PType): bool = + case t.kind + of tyExpr, tyNil: result = true + of tyArray, tyArrayConstr: result = t.sons[1].kind == tyEmpty + of tySet, tySequence, tyOpenArray, tyVarargs: + result = t.sons[0].kind == tyEmpty + of tyGenericInst: result = isEmptyContainer(t.lastSon) + else: result = false + proc commonType*(x, y: PType): PType = # new type relation that is used for array constructors, # if expressions, etc.: @@ -96,6 +109,13 @@ proc commonType*(x, y: PType): PType = # check for seq[empty] vs. seq[int] let idx = ord(b.kind in {tyArray, tyArrayConstr}) if a.sons[idx].kind == tyEmpty: return y + elif a.kind == tyTuple and b.kind == tyTuple and a.len == b.len: + var nt: PType + for i in 0.. <a.len: + if isEmptyContainer(a.sons[i]) and not isEmptyContainer(b.sons[i]): + if nt.isNil: nt = copyType(a, a.owner, false) + nt.sons[i] = b.sons[i] + if not nt.isNil: result = nt #elif b.sons[idx].kind == tyEmpty: return x elif a.kind == tyRange and b.kind == tyRange: # consider: (range[0..3], range[0..4]) here. We should make that diff --git a/compiler/semexprs.nim b/compiler/semexprs.nim index 25113aa5a..89110a479 100644 --- a/compiler/semexprs.nim +++ b/compiler/semexprs.nim @@ -219,7 +219,7 @@ proc maybeLiftType(t: var PType, c: PContext, info: TLineInfo) = # gnrc. params, then it won't be necessary to open a new scope here openScope(c) var lifted = liftParamType(c, skType, newNodeI(nkArgList, info), - t, ":anon", info) + t, ":anon", info) closeScope(c) if lifted != nil: t = lifted @@ -429,7 +429,8 @@ proc changeType(n: PNode, newType: PType, check: bool) = for i in countup(0, sonsLen(n) - 1): changeType(n.sons[i], elemType(newType), check) of nkPar: - if newType.kind != tyTuple: + let tup = newType.skipTypes({tyGenericInst}) + if tup.kind != tyTuple: internalError(n.info, "changeType: no tuple type for constructor") else: for i in countup(0, sonsLen(n) - 1): @@ -437,7 +438,7 @@ proc changeType(n: PNode, newType: PType, check: bool) = if m.kind == nkExprColonExpr: m = m.sons[1] n.sons[i] = m - changeType(m, newType.sons[i], check) + changeType(m, tup.sons[i], check) of nkCharLit..nkUInt64Lit: if check: let value = n.intVal @@ -925,18 +926,20 @@ const proc readTypeParameter(c: PContext, typ: PType, paramName: PIdent, info: TLineInfo): PNode = let ty = if typ.kind == tyGenericInst: typ.skipGenericAlias - else: (internalAssert(typ.kind == tyCompositeTypeClass); typ.sons[1]) - + else: (internalAssert(typ.kind == tyCompositeTypeClass); + typ.sons[1].skipGenericAlias) + #debug ty let tbody = ty.sons[0] for s in countup(0, tbody.len-2): let tParam = tbody.sons[s] - if tParam.sym.name == paramName: + if tParam.sym.name.id == paramName.id: let rawTyp = ty.sons[s + 1] if rawTyp.kind == tyStatic: return rawTyp.n else: let foundTyp = makeTypeDesc(c, rawTyp) return newSymNode(copySym(tParam.sym).linkTo(foundTyp), info) + #echo "came here: returned nil" proc builtinFieldAccess(c: PContext, n: PNode, flags: TExprFlags): PNode = ## returns nil if it's not a built-in field access @@ -963,6 +966,7 @@ proc builtinFieldAccess(c: PContext, n: PNode, flags: TExprFlags): PNode = var ty = n.sons[0].typ var f: PSym = nil result = nil + if isTypeExpr(n.sons[0]) or (ty.kind == tyTypeDesc and ty.base.kind != tyNone): if ty.kind == tyTypeDesc: ty = ty.base ty = ty.skipTypes(tyDotOpTransparent) @@ -971,7 +975,7 @@ proc builtinFieldAccess(c: PContext, n: PNode, flags: TExprFlags): PNode = # look up if the identifier belongs to the enum: while ty != nil: f = getSymFromList(ty.n, i) - if f != nil: break + if f != nil: break ty = ty.sons[0] # enum inheritance if f != nil: result = newSymNode(f) @@ -983,7 +987,7 @@ proc builtinFieldAccess(c: PContext, n: PNode, flags: TExprFlags): PNode = of tyTypeParamsHolders: return readTypeParameter(c, ty, i, n.info) of tyObject, tyTuple: - if ty.n.kind == nkRecList: + if ty.n != nil and ty.n.kind == nkRecList: for field in ty.n: if field.sym.name == i: n.typ = newTypeWithSons(c, tyFieldAccessor, @[ty, field.sym.typ]) diff --git a/compiler/semgnrc.nim b/compiler/semgnrc.nim index 7c32b0051..1ab4f5989 100644 --- a/compiler/semgnrc.nim +++ b/compiler/semgnrc.nim @@ -60,13 +60,20 @@ proc semGenericStmtSymbol(c: PContext, n: PNode, s: PSym, else: result = symChoice(c, n, s, scOpen) of skGenericParam: - result = newSymNodeTypeDesc(s, n.info) + if s.typ != nil and s.typ.kind == tyStatic: + if s.typ.n != nil: + result = s.typ.n + else: + result = n + else: + result = newSymNodeTypeDesc(s, n.info) styleCheckUse(n.info, s) of skParam: result = n styleCheckUse(n.info, s) of skType: - if (s.typ != nil) and (s.typ.kind != tyGenericParam): + if (s.typ != nil) and + (s.typ.flags * {tfGenericTypeParam, tfImplicitTypeParam} == {}): result = newSymNodeTypeDesc(s, n.info) else: result = n diff --git a/compiler/seminst.nim b/compiler/seminst.nim index 2decb5d0b..81a4465c5 100644 --- a/compiler/seminst.nim +++ b/compiler/seminst.nim @@ -21,7 +21,8 @@ proc instantiateGenericParamList(c: PContext, n: PNode, pt: TIdTable, var q = a.sym if q.typ.kind notin {tyTypeDesc, tyGenericParam, tyStatic, tyIter}+tyTypeClasses: continue - var s = newSym(skType, q.name, getCurrOwner(), q.info) + let symKind = if q.typ.kind == tyStatic: skConst else: skType + var s = newSym(symKind, q.name, getCurrOwner(), q.info) s.flags = s.flags + {sfUsed, sfFromGeneric} var t = PType(idTableGet(pt, q.typ)) if t == nil: @@ -40,6 +41,7 @@ proc instantiateGenericParamList(c: PContext, n: PNode, pt: TIdTable, t = generateTypeInstance(c, pt, a, t) #t = ReplaceTypeVarsT(cl, t) s.typ = t + if t.kind == tyStatic: s.ast = t.n addDecl(c, s) entry.concreteTypes[i] = t diff --git a/compiler/semstmts.nim b/compiler/semstmts.nim index a7603147c..3b0332939 100644 --- a/compiler/semstmts.nim +++ b/compiler/semstmts.nim @@ -653,7 +653,8 @@ proc checkForMetaFields(n: PNode) = template checkMeta(t) = if t != nil and t.isMetaType and tfGenericTypeParam notin t.flags: localError(n.info, errTIsNotAConcreteType, t.typeToString) - + + if n.isNil: return case n.kind of nkRecList, nkRecCase: for s in n: checkForMetaFields(s) diff --git a/compiler/semtypes.nim b/compiler/semtypes.nim index 4305a48e1..eb15c3809 100644 --- a/compiler/semtypes.nim +++ b/compiler/semtypes.nim @@ -214,44 +214,48 @@ proc semRange(c: PContext, n: PNode, prev: PType): PType = localError(n.info, errXExpectsOneTypeParam, "range") result = newOrPrevType(tyError, prev, c) +proc semArrayIndex(c: PContext, n: PNode): PType = + if isRange(n): result = semRangeAux(c, n, nil) + else: + let e = semExprWithType(c, n, {efDetermineType}) + if e.typ.kind == tyFromExpr: + result = makeRangeWithStaticExpr(c, e.typ.n) + elif e.kind in {nkIntLit..nkUInt64Lit}: + result = makeRangeType(c, 0, e.intVal-1, n.info, e.typ) + elif e.kind == nkSym and e.typ.kind == tyStatic: + if e.sym.ast != nil: + return semArrayIndex(c, e.sym.ast) + internalAssert c.inGenericContext > 0 + if not isOrdinalType(e.typ.lastSon): + localError(n[1].info, errOrdinalTypeExpected) + result = makeRangeWithStaticExpr(c, e) + result.flags.incl tfUnresolved + elif e.kind in nkCallKinds and hasGenericArguments(e): + if not isOrdinalType(e.typ): + localError(n[1].info, errOrdinalTypeExpected) + # This is an int returning call, depending on an + # yet unknown generic param (see tgenericshardcases). + # We are going to construct a range type that will be + # properly filled-out in semtypinst (see how tyStaticExpr + # is handled there). + result = makeRangeWithStaticExpr(c, e) + elif e.kind == nkIdent: + result = e.typ.skipTypes({tyTypeDesc}) + else: + let x = semConstExpr(c, e) + if x.kind in {nkIntLit..nkUInt64Lit}: + result = makeRangeType(c, 0, x.intVal-1, n.info, + x.typ.skipTypes({tyTypeDesc})) + else: + result = x.typ.skipTypes({tyTypeDesc}) + #localError(n[1].info, errConstExprExpected) + proc semArray(c: PContext, n: PNode, prev: PType): PType = - var indx, base: PType + var base: PType result = newOrPrevType(tyArray, prev, c) - if sonsLen(n) == 3: + if sonsLen(n) == 3: # 3 = length(array indx base) - if isRange(n[1]): indx = semRangeAux(c, n[1], nil) - else: - let e = semExprWithType(c, n.sons[1], {efDetermineType}) - if e.typ.kind == tyFromExpr: - indx = makeRangeWithStaticExpr(c, e.typ.n) - elif e.kind in {nkIntLit..nkUInt64Lit}: - indx = makeRangeType(c, 0, e.intVal-1, n.info, e.typ) - elif e.kind == nkSym and e.typ.kind == tyStatic: - if e.sym.ast != nil: return semArray(c, e.sym.ast, nil) - internalAssert c.inGenericContext > 0 - if not isOrdinalType(e.typ.lastSon): - localError(n[1].info, errOrdinalTypeExpected) - indx = makeRangeWithStaticExpr(c, e) - indx.flags.incl tfUnresolved - elif e.kind in nkCallKinds and hasGenericArguments(e): - if not isOrdinalType(e.typ): - localError(n[1].info, errOrdinalTypeExpected) - # This is an int returning call, depending on an - # yet unknown generic param (see tgenericshardcases). - # We are going to construct a range type that will be - # properly filled-out in semtypinst (see how tyStaticExpr - # is handled there). - indx = makeRangeWithStaticExpr(c, e) - elif e.kind == nkIdent: - indx = e.typ.skipTypes({tyTypeDesc}) - else: - let x = semConstExpr(c, e) - if x.kind in {nkIntLit..nkUInt64Lit}: - indx = makeRangeType(c, 0, x.intVal-1, n.info, - x.typ.skipTypes({tyTypeDesc})) - else: - indx = x.typ.skipTypes({tyTypeDesc}) - #localError(n[1].info, errConstExprExpected) + var indx = semArrayIndex(c, n[1]) addSonSkipIntLit(result, indx) if indx.kind == tyGenericInst: indx = lastSon(indx) if indx.kind notin {tyGenericParam, tyStatic, tyFromExpr}: diff --git a/compiler/sigmatch.nim b/compiler/sigmatch.nim index 1ec48bd0e..b58818a29 100644 --- a/compiler/sigmatch.nim +++ b/compiler/sigmatch.nim @@ -517,6 +517,16 @@ proc maybeSkipDistinct(t: PType, callee: PSym): PType = else: result = t +proc tryResolvingStaticExpr(c: var TCandidate, n: PNode): PNode = + # Consider this example: + # type Value[N: static[int]] = object + # proc foo[N](a: Value[N], r: range[0..(N-1)]) + # Here, N-1 will be initially nkStaticExpr that can be evaluated only after + # N is bound to a concrete value during the matching of the first param. + # This proc is used to evaluate such static expressions. + let instantiated = replaceTypesInBody(c.c, c.bindings, n) + result = c.c.semExpr(c.c, instantiated) + proc typeRel(c: var TCandidate, f, aOrig: PType, doBind = true): TTypeRelation = # typeRel can be used to establish various relationships between types: # @@ -620,6 +630,11 @@ proc typeRel(c: var TCandidate, f, aOrig: PType, doBind = true): TTypeRelation = # bugfix: accept integer conversions here #if result < isGeneric: result = isNone if result notin {isNone, isGeneric}: + # resolve any late-bound static expressions + # that may appear in the range: + for i in 0..1: + if f.n[i].kind == nkStaticExpr: + f.n.sons[i] = tryResolvingStaticExpr(c, f.n[i]) result = typeRangeRel(f, a) else: if skipTypes(f, {tyRange}).kind == a.kind: @@ -964,6 +979,9 @@ proc typeRel(c: var TCandidate, f, aOrig: PType, doBind = true): TTypeRelation = of tyStatic: if aOrig.kind == tyStatic: result = typeRel(c, f.lastSon, a) + if result != isNone and f.n != nil: + if not exprStructuralEquivalent(f.n, a.n): + result = isNone if result != isNone: put(c.bindings, f, aOrig) else: result = isNone @@ -1006,15 +1024,14 @@ proc typeRel(c: var TCandidate, f, aOrig: PType, doBind = true): TTypeRelation = of tyFromExpr: # fix the expression, so it contains the already instantiated types - let instantiated = replaceTypesInBody(c.c, c.bindings, f.n) - let reevaluted = c.c.semExpr(c.c, instantiated) - case reevaluted.typ.kind + let reevaluated = tryResolvingStaticExpr(c, f.n) + case reevaluated.typ.kind of tyTypeDesc: - result = typeRel(c, a, reevaluted.typ.base) + result = typeRel(c, a, reevaluated.typ.base) of tyStatic: - result = typeRel(c, a, reevaluted.typ.base) - if result != isNone and reevaluted.typ.n != nil: - if not exprStructuralEquivalent(aOrig.n, reevaluted.typ.n): + result = typeRel(c, a, reevaluated.typ.base) + if result != isNone and reevaluated.typ.n != nil: + if not exprStructuralEquivalent(aOrig.n, reevaluated.typ.n): result = isNone else: localError(f.n.info, errTypeExpected) @@ -1083,6 +1100,11 @@ proc localConvMatch(c: PContext, m: var TCandidate, f, a: PType, arg: PNode): PNode = # arg.typ can be nil in 'suggest': if isNil(arg.typ): return nil + + # sem'checking for 'echo' needs to be re-entrant: + # XXX we will revisit this issue after 0.10.2 is released + if f == arg.typ and arg.kind == nkHiddenStdConv: return arg + var call = newNodeI(nkCall, arg.info) call.add(f.n.copyTree) call.add(arg.copyTree) diff --git a/compiler/suggest.nim b/compiler/suggest.nim index c700db323..f7b00c8f8 100644 --- a/compiler/suggest.nim +++ b/compiler/suggest.nim @@ -74,9 +74,6 @@ proc suggestField(c: PContext, s: PSym, outputs: var int) = suggestWriteln(symToStr(s, isLocal=true, sectionSuggest)) inc outputs -when not defined(nimhygiene): - {.pragma: inject.} - template wholeSymTab(cond, section: expr) {.immediate.} = var isLocal = true for scope in walkScopes(c.currentScope): diff --git a/compiler/types.nim b/compiler/types.nim index f67cd239e..4a77773e6 100644 --- a/compiler/types.nim +++ b/compiler/types.nim @@ -17,7 +17,7 @@ proc lastOrd*(t: PType): BiggestInt proc lengthOrd*(t: PType): BiggestInt type TPreferedDesc* = enum - preferName, preferDesc, preferExported, preferModuleInfo + preferName, preferDesc, preferExported, preferModuleInfo, preferGenericArg proc typeToString*(typ: PType; prefer: TPreferedDesc = preferName): string proc base*(t: PType): PType @@ -411,11 +411,13 @@ const "UserTypeClassInst", "CompositeTypeClass", "and", "or", "not", "any", "static", "TypeFromExpr", "FieldAccessor"] +const preferToResolveSymbols = {preferName, preferModuleInfo, preferGenericArg} + proc typeToString(typ: PType, prefer: TPreferedDesc = preferName): string = var t = typ result = "" if t == nil: return - if prefer in {preferName, preferModuleInfo} and t.sym != nil and + if prefer in preferToResolveSymbols and t.sym != nil and sfAnon notin t.sym.flags: if t.kind == tyInt and isIntLit(t): return t.sym.name.s & " literal(" & $t.n.intVal & ")" @@ -428,20 +430,26 @@ proc typeToString(typ: PType, prefer: TPreferedDesc = preferName): string = if not isIntLit(t) or prefer == preferExported: result = typeToStr[t.kind] else: - result = "int literal(" & $t.n.intVal & ")" + if prefer == preferGenericArg: + result = $t.n.intVal + else: + result = "int literal(" & $t.n.intVal & ")" of tyGenericBody, tyGenericInst, tyGenericInvokation: result = typeToString(t.sons[0]) & '[' for i in countup(1, sonsLen(t) -1 -ord(t.kind != tyGenericInvokation)): if i > 1: add(result, ", ") - add(result, typeToString(t.sons[i])) + add(result, typeToString(t.sons[i], preferGenericArg)) add(result, ']') of tyTypeDesc: if t.base.kind == tyNone: result = "typedesc" else: result = "typedesc[" & typeToString(t.base) & "]" of tyStatic: internalAssert t.len > 0 - result = "static[" & typeToString(t.sons[0]) & "]" - if t.n != nil: result.add "(" & renderTree(t.n) & ")" + if prefer == preferGenericArg and t.n != nil: + result = t.n.renderTree + else: + result = "static[" & typeToString(t.sons[0]) & "]" + if t.n != nil: result.add "(" & renderTree(t.n) & ")" of tyUserTypeClass: internalAssert t.sym != nil and t.sym.owner != nil return t.sym.owner.name.s diff --git a/compiler/vmdef.nim b/compiler/vmdef.nim index c06606318..3d49cb130 100644 --- a/compiler/vmdef.nim +++ b/compiler/vmdef.nim @@ -164,7 +164,8 @@ type slotTempInt, # some temporary int slotTempFloat, # some temporary float slotTempStr, # some temporary string - slotTempComplex # some complex temporary (s.node field is used) + slotTempComplex, # some complex temporary (s.node field is used) + slotTempPerm # slot is temporary but permanent (hack) PProc* = ref object blocks*: seq[TBlock] # blocks; temp data structure diff --git a/compiler/vmgen.nim b/compiler/vmgen.nim index c4101874c..9a3fc260a 100644 --- a/compiler/vmgen.nim +++ b/compiler/vmgen.nim @@ -16,7 +16,7 @@ # types that use the 'node' field; the reason is that slots are # re-used in a register based VM. Example: # -# .. code-block:: nimrod +# .. code-block:: nim # let s = a & b # no matter what, create fresh node # s = a & b # no matter what, keep the node # @@ -28,7 +28,7 @@ # this copy depends on the involved types. import - unsigned, strutils, ast, astalgo, types, msgs, renderer, vmdef, + unsigned, strutils, ast, astalgo, types, msgs, renderer, vmdef, trees, intsets, rodread, magicsys, options, lowerings from os import splitFile @@ -58,6 +58,7 @@ proc codeListing(c: PCtx, result: var string, start=0; last = -1) = if i in jumpTargets: result.addf("L$1:\n", i) let x = c.code[i] + result.add($i) let opc = opcode(x) if opc in {opcConv, opcCast}: let y = c.code[i+1] @@ -188,7 +189,7 @@ proc getTemp(c: PCtx; typ: PType): TRegister = proc freeTemp(c: PCtx; r: TRegister) = let c = c.prc - if c.slots[r].kind >= slotSomeTemp: c.slots[r].inUse = false + if c.slots[r].kind in {slotSomeTemp..slotTempComplex}: c.slots[r].inUse = false proc getTempRange(c: PCtx; n: int; kind: TSlotKind): TRegister = # if register pressure is high, we re-use more aggressively: @@ -1074,8 +1075,10 @@ proc genAddrDeref(c: PCtx; n: PNode; dest: var TDest; opc: TOpcode; c.gABC(n, opcNodeToReg, dest, dest) elif c.prc.slots[tmp].kind >= slotTempUnknown: gABC(c, n, opcAddrNode, dest, tmp) - # XXX this can still be wrong sometimes; hopefully it's only generated - # in call contexts, where it is safe + # hack ahead; in order to fix bug #1781 we mark the temporary as + # permanent, so that it's not used for anything else: + c.prc.slots[tmp].kind = slotTempPerm + # XXX this is still a hack #message(n.info, warnUser, "suspicious opcode used") else: gABC(c, n, opcAddrReg, dest, tmp) diff --git a/copying.txt b/copying.txt index 254b91c77..908625e18 100644 --- a/copying.txt +++ b/copying.txt @@ -1,5 +1,5 @@ ===================================================== -Nimrod -- a Compiler for Nimrod. http://nimrod-lang.org/ +Nim -- a Compiler for Nim. http://nim-lang.org/ Copyright (C) 2006-2014 Andreas Rumpf. All rights reserved. diff --git a/doc/backends.txt b/doc/backends.txt index eb16217cd..ffe2d5e88 100644 --- a/doc/backends.txt +++ b/doc/backends.txt @@ -456,11 +456,7 @@ can then attach a GC to this thread via .. code-block:: nim - setStackBottom(addr(someLocal)) - initGC() - -At the moment this support is still experimental so you need to expose these -functions yourself or submit patches to request a public API. + system.setupForeignThreadGc() It is **not** safe to disable the garbage collector and enable it after the call from your background thread even if the code you are calling is short diff --git a/doc/lib.txt b/doc/lib.txt index 7d100e1ca..45d9dfd2a 100644 --- a/doc/lib.txt +++ b/doc/lib.txt @@ -154,8 +154,8 @@ Generic Operating System Services * `streams <streams.html>`_ This module provides a stream interface and two implementations thereof: - the `PFileStream` and the `PStringStream` which implement the stream - interface for Nim file objects (`TFile`) and strings. Other modules + the `FileStream` and the `StringStream` which implement the stream + interface for Nim file objects (`File`) and strings. Other modules may provide other implementations for this standard stream interface. * `marshal <marshal.html>`_ diff --git a/doc/nimc.txt b/doc/nimc.txt index 92acd3979..a2274febd 100644 --- a/doc/nimc.txt +++ b/doc/nimc.txt @@ -550,58 +550,6 @@ in C/C++). **Note**: This pragma will not exist for the LLVM backend. -Source code style -================= - -Nim allows you to `mix freely case and underscores as identifier separators -<manual.html#identifiers-keywords>`_, so variables named ``MyPrecioussInt`` and -``my_preciouss_int`` are equivalent: - -.. code-block:: Nim - var MyPrecioussInt = 3 - # Following line compiles fine! - echo my_preciouss_int - -Since this can lead to many variants of the same source code (you can use -`nimgrep <nimgrep.html>`_ instead of your typical ``grep`` to ignore style -problems) the compiler provides the command ``pretty`` to help unifying the -style of source code. Running ``nim pretty ugly_test.nim`` with this -example will generate a secondary file named ``ugly_test.pretty.nim`` with the -following content: - -.. code-block:: Nim - var MyPrecioussInt = 3 - # Following line compiles fine! - echo MyPrecioussInt - -During execution the ``pretty`` command will also run on Nim's standard -library, since it doesn't differentiate the standard library as something -special, and hence will warn of many *errors* which are out of your hand to -fix, creating respective ``.pretty.nim`` files all the way. You can ignore -these errors if they don't belong to your source and simply compare your -original version to the new pretty one. In fact, running ``pretty`` on our test -file will show the following:: - - Hint: ugly_test [Processing] - ugly_test.nim(1, 4) Error: name should be: myPrecioussInt - ugly_test.nim(1, 4) Error: name should be: myPrecioussInt - -At the moment ``pretty`` will homogenize the style of symbols but will leave -important changes for you to review. In this case the command is warning that a -variable name should not start with a capital letter, which is usually reserved -to `object types <tut2.html#objects>`_. To learn about the accepted `camel case -style <https://en.wikipedia.org/wiki/Camelcase>`_ read `Coding Guidelines in -the Internals of Nim Compiler <intern.html#coding-guidelines>`_ or `Coding -Guidelines <https://github.com/Araq/Nim/wiki/Coding-Guidelines>`_ and `NEP 1 -: Style Guide for Nim Code -<https://github.com/Araq/Nim/wiki/NEP-1-:-Style-Guide-for-Nim-Code>`_ -from the Nim `GitHub wiki<https://github.com/Araq/Nim/wiki>`_. - -This command is safe to run because it will never attempt to overwrite your -existing sources, but the respective ``.pretty.nim`` files **will** be -overwritten without notice. - - DynlibOverride ============== diff --git a/doc/tut1.txt b/doc/tut1.txt index 9d75b1ea2..4c32fa0ae 100644 --- a/doc/tut1.txt +++ b/doc/tut1.txt @@ -139,7 +139,7 @@ Numbers Numerical literals are written as in most other languages. As a special twist, underscores are allowed for better readability: ``1_000_000`` (one million). A number that contains a dot (or 'e' or 'E') is a floating point literal: -``1.0e9`` (one million). Hexadecimal literals are prefixed with ``0x``, +``1.0e9`` (one billion). Hexadecimal literals are prefixed with ``0x``, binary literals with ``0b`` and octal literals with ``0o``. A leading zero alone does not produce an octal. diff --git a/doc/tut2.txt b/doc/tut2.txt index 6e239d681..9d3409164 100644 --- a/doc/tut2.txt +++ b/doc/tut2.txt @@ -56,7 +56,7 @@ Objects have access to their type at runtime. There is an .. code-block:: nim type - TPerson = object of TObject + TPerson = object of RootObj name*: string # the * means that `name` is accessible from other modules age: int # no * means that the field is hidden from other modules @@ -76,10 +76,10 @@ never *equivalent*. New object types can only be defined within a type section. Inheritance is done with the ``object of`` syntax. Multiple inheritance is -currently not supported. If an object type has no suitable ancestor, ``TObject`` +currently not supported. If an object type has no suitable ancestor, ``RootObj`` can be used as its ancestor, but this is only a convention. Objects that have no ancestor are implicitly ``final``. You can use the ``inheritable`` pragma -to introduce new object roots apart from ``system.TObject``. (This is used +to introduce new object roots apart from ``system.RootObj``. (This is used in the GTK wrapper for instance.) @@ -228,7 +228,7 @@ is needed: .. code-block:: nim type - TSocket* = object of TObject + TSocket* = object of RootObj FHost: int # cannot be accessed from the outside of the module # the `F` prefix is a convention to avoid clashes since # the accessors are named `host` @@ -284,7 +284,7 @@ Procedures always use static dispatch. For dynamic dispatch replace the .. code-block:: nim type - PExpr = ref object of TObject ## abstract base class for an expression + PExpr = ref object of RootObj ## abstract base class for an expression PLiteral = ref object of PExpr x: int PPlusExpr = ref object of PExpr @@ -313,7 +313,7 @@ dispatching: .. code-block:: nim type - TThing = object of TObject + TThing = object of RootObj TUnit = object of TThing x: int diff --git a/koch.nim b/koch.nim index 79228c1a4..e3831617c 100644 --- a/koch.nim +++ b/koch.nim @@ -94,16 +94,16 @@ const compileNimInst = "-d:useLibzipSrc tools/niminst/niminst" proc csource(args: string) = - exec("$4 cc $1 -r $3 --var:version=$2 --var:mingw=mingw32 csource compiler/nim.ini $1" % + exec("$4 cc $1 -r $3 --var:version=$2 --var:mingw=none csource compiler/nim.ini $1" % [args, VersionAsString, compileNimInst, findNim()]) proc zip(args: string) = - exec("$3 cc -r $2 --var:version=$1 --var:mingw=mingw32 scripts compiler/nim.ini" % + exec("$3 cc -r $2 --var:version=$1 --var:mingw=none scripts compiler/nim.ini" % [VersionAsString, compileNimInst, findNim()]) - exec("$# --var:version=$# --var:mingw=mingw32 zip compiler/nim.ini" % + exec("$# --var:version=$# --var:mingw=none zip compiler/nim.ini" % ["tools/niminst/niminst".exe, VersionAsString]) - -proc buildTool(toolname, args: string) = + +proc buildTool(toolname, args: string) = exec("$# cc $# $#" % [findNim(), args, toolname]) copyFile(dest="bin"/ splitFile(toolname).name.exe, source=toolname.exe) @@ -114,11 +114,11 @@ proc nsis(args: string) = # produce 'nimrod_debug.exe': exec "nim c compiler" / "nim.nim" copyExe("compiler/nim".exe, "bin/nim_debug".exe) - exec(("tools" / "niminst" / "niminst --var:version=$# --var:mingw=mingw32" & - " nsis compiler/nim") % VersionAsString) + exec(("tools" / "niminst" / "niminst --var:version=$# --var:mingw=mingw$#" & + " nsis compiler/nim") % [VersionAsString, $(sizeof(pointer)*8)]) proc install(args: string) = - exec("$# cc -r $# --var:version=$# --var:mingw=mingw32 scripts compiler/nim.ini" % + exec("$# cc -r $# --var:version=$# --var:mingw=none scripts compiler/nim.ini" % [findNim(), compileNimInst, VersionAsString]) exec("sh ./install.sh $#" % args) diff --git a/lib/core/macros.nim b/lib/core/macros.nim index ed5d3c50c..353254d49 100644 --- a/lib/core/macros.nim +++ b/lib/core/macros.nim @@ -649,6 +649,8 @@ proc `$`*(node: PNimrodNode): string {.compileTime.} = result = $node.basename.ident & "*" of nnkStrLit..nnkTripleStrLit: result = node.strVal + of nnkSym: + result = $node.symbol else: badNodeKind node.kind, "$" diff --git a/lib/impure/osinfo_posix.nim b/lib/impure/osinfo_posix.nim index 1baff8c55..0ed4289c4 100644 --- a/lib/impure/osinfo_posix.nim +++ b/lib/impure/osinfo_posix.nim @@ -35,7 +35,15 @@ proc getSystemVersion*(): string = elif $unix_info.sysname == "Darwin": # Darwin result.add("Mac OS X ") - if "10" in $unix_info.release: + if "14" in $unix_info.release: + result.add("v10.10 Yosemite") + elif "13" in $unix_info.release: + result.add("v10.9 Mavericks") + elif "12" in $unix_info.release: + result.add("v10.8 Mountian Lion") + elif "11" in $unix_info.release: + result.add("v10.7 Lion") + elif "10" in $unix_info.release: result.add("v10.6 Snow Leopard") elif "9" in $unix_info.release: result.add("v10.5 Leopard") diff --git a/lib/impure/osinfo_win.nim b/lib/impure/osinfo_win.nim index f423a34a3..becec928e 100644 --- a/lib/impure/osinfo_win.nim +++ b/lib/impure/osinfo_win.nim @@ -245,6 +245,14 @@ proc `$`*(osvi: TVersionInfo): string = if osvi.ProductType == VER_NT_WORKSTATION: result.add("Windows 7 ") else: result.add("Windows Server 2008 R2 ") + elif osvi.minorVersion == 2: + if osvi.ProductType == VER_NT_WORKSTATION: + result.add("Windows 8 ") + else: result.add("Windows Server 2012 ") + elif osvi.minorVersion == 3: + if osvi.ProductType == VER_NT_WORKSTATION: + result.add("Windows 8.1 ") + else: result.add("Windows Server 2012 R2 ") var dwType = getProductInfo(osvi.majorVersion, osvi.minorVersion, 0, 0) case dwType diff --git a/lib/posix/posix.nim b/lib/posix/posix.nim index deb120372..0498a0e70 100644 --- a/lib/posix/posix.nim +++ b/lib/posix/posix.nim @@ -1570,9 +1570,9 @@ else: when defined(macosx): + # We can't use the NOSIGNAL flag in the ``send`` function, it has no effect var - MSG_HAVEMORE* {.importc, header: "<sys/socket.h>".}: cint - MSG_NOSIGNAL* = MSG_HAVEMORE + MSG_NOSIGNAL* = 0'i32 else: var MSG_NOSIGNAL* {.importc, header: "<sys/socket.h>".}: cint diff --git a/lib/pure/asynchttpserver.nim b/lib/pure/asynchttpserver.nim index 0b18e6bcc..4c48350aa 100644 --- a/lib/pure/asynchttpserver.nim +++ b/lib/pure/asynchttpserver.nim @@ -17,6 +17,8 @@ ## as the response body. ## ## .. code-block::nim +## import asynchttpserver, asyncdispatch +## ## var server = newAsyncHttpServer() ## proc cb(req: Request) {.async.} = ## await req.respond(Http200, "Hello World") diff --git a/lib/pure/pegs.nim b/lib/pure/pegs.nim index 8b7554661..7cef0a00d 100644 --- a/lib/pure/pegs.nim +++ b/lib/pure/pegs.nim @@ -1433,7 +1433,7 @@ proc eat(p: var PegParser, kind: TTokKind) = if p.tok.kind == kind: getTok(p) else: pegError(p, tokKindToStr[kind] & " expected") -proc parseExpr(p: var PegParser): Peg +proc parseExpr(p: var PegParser): Peg {.gcsafe.} proc getNonTerminal(p: var PegParser, name: string): NonTerminal = for i in 0..high(p.nonterms): diff --git a/lib/pure/rawsockets.nim b/lib/pure/rawsockets.nim index 62a011999..e23deea5b 100644 --- a/lib/pure/rawsockets.nim +++ b/lib/pure/rawsockets.nim @@ -428,6 +428,10 @@ proc selectWrite*(writefds: var seq[SocketHandle], pruneSocketSet(writefds, (wr)) +# We ignore signal SIGPIPE on Darwin +when defined(macosx): + signal(SIGPIPE, SIG_IGN) + when defined(Windows): var wsa: WSAData if wsaStartup(0x0101'i16, addr wsa) != 0: raiseOSError(osLastError()) diff --git a/lib/pure/unittest.nim b/lib/pure/unittest.nim index 6c0246f8b..21efea3bc 100644 --- a/lib/pure/unittest.nim +++ b/lib/pure/unittest.nim @@ -97,7 +97,9 @@ proc checkpoint*(msg: string) = template fail* = bind checkpoints for msg in items(checkpoints): - echo msg + # this used to be 'echo' which now breaks due to a bug. XXX will revisit + # this issue later. + stdout.writeln msg when not defined(ECMAScript): if abortOnError: quit(1) diff --git a/lib/system.nim b/lib/system.nim index 0cd4b84e2..b7c77e276 100644 --- a/lib/system.nim +++ b/lib/system.nim @@ -1516,7 +1516,7 @@ const NimMinor*: int = 10 ## is the minor number of Nim's version. - NimPatch*: int = 1 + NimPatch*: int = 3 ## is the patch number of Nim's version. NimVersion*: string = $NimMajor & "." & $NimMinor & "." & $NimPatch diff --git a/lib/system/channels.nim b/lib/system/channels.nim index 3e5ca0795..d07d6eae1 100644 --- a/lib/system/channels.nim +++ b/lib/system/channels.nim @@ -232,9 +232,10 @@ proc tryRecv*[TMsg](c: var TChannel[TMsg]): tuple[dataAvailable: bool, ## it returns ``(false, default(msg))``. var q = cast[PRawChannel](addr(c)) if q.mask != ChannelDeadMask: - if tryAcquireSys(q.lock): - llRecv(q, addr(result.msg), cast[PNimType](getTypeInfo(result.msg))) - result.dataAvailable = true + if tryAcquireSys(q.lock): + if q.count > 0: + llRecv(q, addr(result.msg), cast[PNimType](getTypeInfo(result.msg))) + result.dataAvailable = true releaseSys(q.lock) proc peek*[TMsg](c: var TChannel[TMsg]): int = diff --git a/lib/system/excpt.nim b/lib/system/excpt.nim index e21eeca6a..237b42482 100644 --- a/lib/system/excpt.nim +++ b/lib/system/excpt.nim @@ -296,15 +296,15 @@ when not defined(noSignalHandler): template processSignal(s, action: expr) {.immediate, dirty.} = if s == SIGINT: action("SIGINT: Interrupted by Ctrl-C.\n") elif s == SIGSEGV: - action("SIGSEGV: Illegal storage access. (Attempt to read from nil?)\n") + action("SIGSEGV: Illegal storage access. (Try to compile with -d:useSysAssert -d:useGcAssert for details.)\n") elif s == SIGABRT: when defined(endb): if dbgAborting: return # the debugger wants to abort action("SIGABRT: Abnormal termination.\n") elif s == SIGFPE: action("SIGFPE: Arithmetic error.\n") elif s == SIGILL: action("SIGILL: Illegal operation.\n") - elif s == SIGBUS: - action("SIGBUS: Illegal storage access. (Attempt to read from nil?)\n") + elif s == SIGBUS: + action("SIGBUS: Illegal storage access. (Try to compile with -d:useSysAssert -d:useGcAssert for details.)\n") else: block platformSpecificSignal: when declared(SIGPIPE): diff --git a/lib/windows/winlean.nim b/lib/windows/winlean.nim index 76d17bc4a..51a12141b 100644 --- a/lib/windows/winlean.nim +++ b/lib/windows/winlean.nim @@ -368,32 +368,32 @@ type {.deprecated: [TSocketHandle: SocketHandle].} type - WSAData* {.importc: "WSADATA", header: "Winsock2.h".} = object + WSAData* {.importc: "WSADATA", header: "winsock2.h".} = object wVersion, wHighVersion: int16 szDescription: array[0..WSADESCRIPTION_LEN, char] szSystemStatus: array[0..WSASYS_STATUS_LEN, char] iMaxSockets, iMaxUdpDg: int16 lpVendorInfo: cstring - SockAddr* {.importc: "SOCKADDR", header: "Winsock2.h".} = object + SockAddr* {.importc: "SOCKADDR", header: "winsock2.h".} = object sa_family*: int16 # unsigned sa_data: array[0..13, char] - InAddr* {.importc: "IN_ADDR", header: "Winsock2.h".} = object + InAddr* {.importc: "IN_ADDR", header: "winsock2.h".} = object s_addr*: int32 # IP address Sockaddr_in* {.importc: "SOCKADDR_IN", - header: "Winsock2.h".} = object + header: "winsock2.h".} = object sin_family*: int16 sin_port*: int16 # unsigned sin_addr*: InAddr sin_zero*: array[0..7, char] - In6_addr* {.importc: "IN6_ADDR", header: "Winsock2.h".} = object + In6_addr* {.importc: "IN6_ADDR", header: "winsock2.h".} = object bytes*: array[0..15, char] Sockaddr_in6* {.importc: "SOCKADDR_IN6", - header: "Winsock2.h".} = object + header: "winsock2.h".} = object sin6_family*: int16 sin6_port*: int16 # unsigned sin6_flowinfo*: int32 # unsigned @@ -450,22 +450,22 @@ type var - SOMAXCONN* {.importc, header: "Winsock2.h".}: cint - INVALID_SOCKET* {.importc, header: "Winsock2.h".}: SocketHandle - SOL_SOCKET* {.importc, header: "Winsock2.h".}: cint - SO_DEBUG* {.importc, header: "Winsock2.h".}: cint ## turn on debugging info recording - SO_ACCEPTCONN* {.importc, header: "Winsock2.h".}: cint # socket has had listen() - SO_REUSEADDR* {.importc, header: "Winsock2.h".}: cint # allow local address reuse - SO_KEEPALIVE* {.importc, header: "Winsock2.h".}: cint # keep connections alive - SO_DONTROUTE* {.importc, header: "Winsock2.h".}: cint # just use interface addresses - SO_BROADCAST* {.importc, header: "Winsock2.h".}: cint # permit sending of broadcast msgs - SO_USELOOPBACK* {.importc, header: "Winsock2.h".}: cint # bypass hardware when possible - SO_LINGER* {.importc, header: "Winsock2.h".}: cint # linger on close if data present - SO_OOBINLINE* {.importc, header: "Winsock2.h".}: cint # leave received OOB data in line - - SO_DONTLINGER* {.importc, header: "Winsock2.h".}: cint - SO_EXCLUSIVEADDRUSE* {.importc, header: "Winsock2.h".}: cint # disallow local address reuse - SO_ERROR* {.importc, header: "Winsock2.h".}: cint + SOMAXCONN* {.importc, header: "winsock2.h".}: cint + INVALID_SOCKET* {.importc, header: "winsock2.h".}: SocketHandle + SOL_SOCKET* {.importc, header: "winsock2.h".}: cint + SO_DEBUG* {.importc, header: "winsock2.h".}: cint ## turn on debugging info recording + SO_ACCEPTCONN* {.importc, header: "winsock2.h".}: cint # socket has had listen() + SO_REUSEADDR* {.importc, header: "winsock2.h".}: cint # allow local address reuse + SO_KEEPALIVE* {.importc, header: "winsock2.h".}: cint # keep connections alive + SO_DONTROUTE* {.importc, header: "winsock2.h".}: cint # just use interface addresses + SO_BROADCAST* {.importc, header: "winsock2.h".}: cint # permit sending of broadcast msgs + SO_USELOOPBACK* {.importc, header: "winsock2.h".}: cint # bypass hardware when possible + SO_LINGER* {.importc, header: "winsock2.h".}: cint # linger on close if data present + SO_OOBINLINE* {.importc, header: "winsock2.h".}: cint # leave received OOB data in line + + SO_DONTLINGER* {.importc, header: "winsock2.h".}: cint + SO_EXCLUSIVEADDRUSE* {.importc, header: "winsock2.h".}: cint # disallow local address reuse + SO_ERROR* {.importc, header: "winsock2.h".}: cint proc `==`*(x, y: SocketHandle): bool {.borrow.} diff --git a/lib/wrappers/openssl.nim b/lib/wrappers/openssl.nim index ba25fbf1a..f091d8f46 100644 --- a/lib/wrappers/openssl.nim +++ b/lib/wrappers/openssl.nim @@ -280,9 +280,18 @@ when not useWinVersion: proc CRYPTO_set_mem_functions(a,b,c: pointer){.cdecl, dynlib: DLLUtilName, importc.} + proc allocWrapper(size: int): pointer {.cdecl.} = alloc(size) + proc reallocWrapper(p: pointer; newsize: int): pointer {.cdecl.} = + if p == nil: + if newSize > 0: result = alloc(newsize) + elif newsize == 0: dealloc(p) + else: result = realloc(p, newsize) + proc deallocWrapper(p: pointer) {.cdecl.} = + if p != nil: dealloc(p) + proc CRYPTO_malloc_init*() = when not useWinVersion: - CRYPTO_set_mem_functions(alloc, realloc, dealloc) + CRYPTO_set_mem_functions(allocWrapper, reallocWrapper, deallocWrapper) proc SSL_CTX_ctrl*(ctx: SslCtx, cmd: cInt, larg: int, parg: pointer): int{. cdecl, dynlib: DLLSSLName, importc.} diff --git a/tests/generics/t1056.nim b/tests/generics/t1056.nim new file mode 100644 index 000000000..73a24a76a --- /dev/null +++ b/tests/generics/t1056.nim @@ -0,0 +1,26 @@ +discard """ + output: '''TMatrix[3, 3, system.int] +3 +3''' +""" + +import typetraits + +type + TMatrix*[N,M: static[int], T] = object + data*: array[0..N*M-1, T] + + TMat2[T] = TMatrix[2,2,T] + +proc echoMatrix(a: TMatrix) = + echo a.type.name + echo TMatrix.N + +proc echoMat2(a: TMat2) = + echo TMat2.M + +var m = TMatrix[3,3,int](data: [1,2,3,4,5,6,7,8,9]) + +echoMatrix m +echoMat2 m + diff --git a/tests/generics/t1789.nim b/tests/generics/t1789.nim new file mode 100644 index 000000000..188db88f6 --- /dev/null +++ b/tests/generics/t1789.nim @@ -0,0 +1,44 @@ +discard """ + output: "3\n0" +""" + +# https://github.com/Araq/Nim/issues/1789 + +type + Foo[N: static[int]] = object + +proc bindStaticN[N](foo: Foo[N]) = + var ar0: array[3, int] + var ar1: array[N, int] + var ar2: array[1..N, int] + var ar3: array[0..(N+10), float] + echo N + +var f: Foo[3] +f.bindStaticN + +# case 2 + +type + ObjectWithStatic[X, Y: static[int], T] = object + bar: array[X * Y, T] # this one works + + AliasWithStatic[X, Y: static[int], T] = array[X * Y, T] + +var + x: ObjectWithStatic[1, 2, int] + y: AliasWithStatic[2, 3, int] + +# case 3 + +type + Bar[N: static[int], T] = object + bar: array[N, T] + +proc `[]`*[N, T](f: Bar[N, T], n: range[0..(N - 1)]): T = + assert high(n) == N-1 + result = f.bar[n] + +var b: Bar[3, int] +echo b[2] + diff --git a/tests/metatype/tusertypeclasses.nim b/tests/metatype/tusertypeclasses.nim index a5d575dbf..6e9e4934b 100644 --- a/tests/metatype/tusertypeclasses.nim +++ b/tests/metatype/tusertypeclasses.nim @@ -12,7 +12,7 @@ type (x < y) is bool ObjectContainer = generic C - C.len is ordinal + C.len is Ordinal for v in items(C): v.type is tuple|object diff --git a/tests/misc/tcolonisproc.nim b/tests/misc/tcolonisproc.nim index e55587dfc..af4077284 100644 --- a/tests/misc/tcolonisproc.nim +++ b/tests/misc/tcolonisproc.nim @@ -2,10 +2,11 @@ proc p(a, b: int, c: proc ()) = c() - -p(1, 3): - echo 1 - echo 3 +when false: + # language spec changed: + p(1, 3): + echo 1 + echo 3 p(1, 1, proc() = echo 1 diff --git a/tests/misc/tnoinst.nim b/tests/misc/tnoinst.nim index db1058d09..4c8d9d1aa 100644 --- a/tests/misc/tnoinst.nim +++ b/tests/misc/tnoinst.nim @@ -1,6 +1,7 @@ discard """ line: 12 errormsg: "instantiate 'notConcrete' explicitly" + disabled: "true" """ proc wrap[T]() = diff --git a/tests/misc/tvarious.nim b/tests/misc/tvarious.nim index ed2964cf9..434d25e48 100644 --- a/tests/misc/tvarious.nim +++ b/tests/misc/tvarious.nim @@ -62,3 +62,7 @@ when false: block: var a, b: Bar[int, 0..2] discard foo(a, b) + +# bug #1788 + +echo "hello" & char(ord(' ')) & "world" diff --git a/tests/stdlib/tmath2.nim b/tests/stdlib/tmath2.nim index 935b08634..88d96c80a 100644 --- a/tests/stdlib/tmath2.nim +++ b/tests/stdlib/tmath2.nim @@ -58,7 +58,7 @@ proc TestLoops() = break break - while True: + while true: break @@ -73,7 +73,7 @@ proc main() = res: int s: string #write(stdout, mymax(23, 45)) - write(stdout, "Hallo! Wie heißt du? ") + write(stdout, "Hallo! Wie heisst du? ") s = readLine(stdin) # test the case statement case s diff --git a/tests/stdlib/tparsefloat.nim b/tests/stdlib/tparsefloat.nim deleted file mode 100644 index 38ed2db6d..000000000 --- a/tests/stdlib/tparsefloat.nim +++ /dev/null @@ -1,3 +0,0 @@ -import strutils - -echo ParseFloat("5000") / ParseFloat("10") diff --git a/tests/stdlib/tpegs.nim b/tests/stdlib/tpegs.nim index e5353e4ff..1bc2669c3 100644 --- a/tests/stdlib/tpegs.nim +++ b/tests/stdlib/tpegs.nim @@ -397,7 +397,7 @@ proc esc(c: char, reserved = {'\0'..'\255'}): string = elif c in reserved: result = '\\' & c else: result = $c -proc singleQuoteEsc(c: Char): string = return "'" & esc(c, {'\''}) & "'" +proc singleQuoteEsc(c: char): string = return "'" & esc(c, {'\''}) & "'" proc singleQuoteEsc(str: string): string = result = "'" @@ -421,11 +421,11 @@ proc charSetEscAux(cc: set[char]): string = c1 = c2 inc(c1) -proc CharSetEsc(cc: set[char]): string = +proc charSetEsc(cc: set[char]): string = if card(cc) >= 128+64: - result = "[^" & CharSetEscAux({'\1'..'\xFF'} - cc) & ']' + result = "[^" & charSetEscAux({'\1'..'\xFF'} - cc) & ']' else: - result = '[' & CharSetEscAux(cc) & ']' + result = '[' & charSetEscAux(cc) & ']' proc toStrAux(r: TPeg, res: var string) = case r.kind @@ -522,12 +522,12 @@ proc `$` *(r: TPeg): string {.rtl, extern: "npegsToString".} = type TCaptures* {.final.} = object ## contains the captured substrings. - matches: array[0..maxSubpatterns-1, tuple[first, last: int]] + matches: array[0..MaxSubpatterns-1, tuple[first, last: int]] ml: int origStart: int proc bounds*(c: TCaptures, - i: range[0..maxSubpatterns-1]): tuple[first, last: int] = + i: range[0..MaxSubpatterns-1]): tuple[first, last: int] = ## returns the bounds ``[first..last]`` of the `i`'th capture. result = c.matches[i] @@ -695,7 +695,7 @@ proc rawMatch*(s: string, p: TPeg, start: int, c: var TCaptures): int {. while start+result < s.len: var x = rawMatch(s, p.sons[0], start+result, c) if x >= 0: - if idx < maxSubpatterns: + if idx < MaxSubpatterns: c.matches[idx] = (start, start+result-1) #else: silently ignore the capture inc(result, x) @@ -739,7 +739,7 @@ proc rawMatch*(s: string, p: TPeg, start: int, c: var TCaptures): int {. inc(c.ml) result = rawMatch(s, p.sons[0], start, c) if result >= 0: - if idx < maxSubpatterns: + if idx < MaxSubpatterns: c.matches[idx] = (start, start+result-1) #else: silently ignore the capture else: @@ -836,7 +836,7 @@ iterator findAll*(s: string, pattern: TPeg, start = 0): string = while i < s.len: var L = matchLen(s, pattern, matches, i) if L < 0: break - for k in 0..maxSubPatterns-1: + for k in 0..MaxSubPatterns-1: if isNil(matches[k]): break yield matches[k] inc(i, L) @@ -866,7 +866,7 @@ template `=~`*(s: string, pattern: TPeg): expr = ## echo("syntax error") ## when not definedInScope(matches): - var matches {.inject.}: array[0..maxSubpatterns-1, string] + var matches {.inject.}: array[0..MaxSubpatterns-1, string] match(s, pattern, matches) # ------------------------- more string handling ------------------------------ @@ -907,7 +907,7 @@ proc replacef*(s: string, sub: TPeg, by: string): string {. ## "var1<-keykey; val2<-key2key2" result = "" var i = 0 - var caps: array[0..maxSubpatterns-1, string] + var caps: array[0..MaxSubpatterns-1, string] while i < s.len: var x = matchLen(s, sub, caps, i) if x <= 0: @@ -924,7 +924,7 @@ proc replace*(s: string, sub: TPeg, by = ""): string {. ## in `by`. result = "" var i = 0 - var caps: array[0..maxSubpatterns-1, string] + var caps: array[0..MaxSubpatterns-1, string] while i < s.len: var x = matchLen(s, sub, caps, i) if x <= 0: @@ -942,7 +942,7 @@ proc parallelReplace*(s: string, subs: varargs[ ## applied in parallel. result = "" var i = 0 - var caps: array[0..maxSubpatterns-1, string] + var caps: array[0..MaxSubpatterns-1, string] while i < s.len: block searchSubs: for j in 0..high(subs): @@ -1055,7 +1055,7 @@ type TPegLexer {.inheritable.} = object ## the lexer object. bufpos: int ## the current position within the buffer buf: cstring ## the buffer itself - LineNumber: int ## the current line number + lineNumber: int ## the current line number lineStart: int ## index of last line start in buffer colOffset: int ## column to add filename: string @@ -1118,38 +1118,38 @@ proc getEscapedChar(c: var TPegLexer, tok: var TToken) = case c.buf[c.bufpos] of 'r', 'R', 'c', 'C': add(tok.literal, '\c') - Inc(c.bufpos) + inc(c.bufpos) of 'l', 'L': add(tok.literal, '\L') - Inc(c.bufpos) + inc(c.bufpos) of 'f', 'F': add(tok.literal, '\f') inc(c.bufpos) of 'e', 'E': add(tok.literal, '\e') - Inc(c.bufpos) + inc(c.bufpos) of 'a', 'A': add(tok.literal, '\a') - Inc(c.bufpos) + inc(c.bufpos) of 'b', 'B': add(tok.literal, '\b') - Inc(c.bufpos) + inc(c.bufpos) of 'v', 'V': add(tok.literal, '\v') - Inc(c.bufpos) + inc(c.bufpos) of 't', 'T': add(tok.literal, '\t') - Inc(c.bufpos) + inc(c.bufpos) of 'x', 'X': inc(c.bufpos) var xi = 0 handleHexChar(c, xi) handleHexChar(c, xi) if xi == 0: tok.kind = tkInvalid - else: add(tok.literal, Chr(xi)) + else: add(tok.literal, chr(xi)) of '0'..'9': var val = ord(c.buf[c.bufpos]) - ord('0') - Inc(c.bufpos) + inc(c.bufpos) var i = 1 while (i <= 3) and (c.buf[c.bufpos] in {'0'..'9'}): val = val * 10 + ord(c.buf[c.bufpos]) - ord('0') @@ -1159,11 +1159,11 @@ proc getEscapedChar(c: var TPegLexer, tok: var TToken) = else: tok.kind = tkInvalid of '\0'..'\31': tok.kind = tkInvalid - elif c.buf[c.bufpos] in strutils.letters: + elif c.buf[c.bufpos] in strutils.Letters: tok.kind = tkInvalid else: add(tok.literal, c.buf[c.bufpos]) - Inc(c.bufpos) + inc(c.bufpos) proc skip(c: var TPegLexer) = var pos = c.bufpos @@ -1171,7 +1171,7 @@ proc skip(c: var TPegLexer) = while true: case buf[pos] of ' ', '\t': - Inc(pos) + inc(pos) of '#': while not (buf[pos] in {'\c', '\L', '\0'}): inc(pos) of '\c': @@ -1203,7 +1203,7 @@ proc getString(c: var TPegLexer, tok: var TToken) = break else: add(tok.literal, buf[pos]) - Inc(pos) + inc(pos) c.bufpos = pos proc getDollar(c: var TPegLexer, tok: var TToken) = @@ -1244,7 +1244,7 @@ proc getCharSet(c: var TPegLexer, tok: var TToken) = break else: ch = buf[pos] - Inc(pos) + inc(pos) incl(tok.charset, ch) if buf[pos] == '-': if buf[pos+1] == ']': @@ -1264,7 +1264,7 @@ proc getCharSet(c: var TPegLexer, tok: var TToken) = break else: ch2 = buf[pos] - Inc(pos) + inc(pos) for i in ord(ch)+1 .. ord(ch2): incl(tok.charset, chr(i)) c.bufpos = pos @@ -1275,7 +1275,7 @@ proc getSymbol(c: var TPegLexer, tok: var TToken) = var buf = c.buf while true: add(tok.literal, buf[pos]) - Inc(pos) + inc(pos) if buf[pos] notin strutils.IdentChars: break c.bufpos = pos tok.kind = tkIdentifier @@ -1312,11 +1312,11 @@ proc getTok(c: var TPegLexer, tok: var TToken) = getCharset(c, tok) of '(': tok.kind = tkParLe - Inc(c.bufpos) + inc(c.bufpos) add(tok.literal, '(') of ')': tok.kind = tkParRi - Inc(c.bufpos) + inc(c.bufpos) add(tok.literal, ')') of '.': tok.kind = tkAny diff --git a/tests/stdlib/tsockets.nim b/tests/stdlib/tsockets.nim deleted file mode 100644 index ff566df74..000000000 --- a/tests/stdlib/tsockets.nim +++ /dev/null @@ -1,12 +0,0 @@ -import sockets, os -var s: TSocket -s = socket() -if s == InvalidSocket: osError(osLastError()) - -s.connect("www.google.com", TPort(80)) - -var data: string = "" -s.readLine(data) -echo(data) - - diff --git a/tests/threads/ttryrecv.nim b/tests/threads/ttryrecv.nim new file mode 100644 index 000000000..acccf182c --- /dev/null +++ b/tests/threads/ttryrecv.nim @@ -0,0 +1,35 @@ +discard """ + outputsub: "channel is empty" +""" + +# bug #1816 + +from math import random +from os import sleep + +type PComm = ptr TChannel[int] + +proc doAction(outC: PComm) {.thread.} = + for i in 0.. <5: + sleep(random(100)) + send(outC[], i) + +var + thr: TThread[PComm] + chan: TChannel[int] + +open(chan) +createThread[PComm](thr, doAction, addr(chan)) + +while true: + let (flag, x) = tryRecv(chan) + if flag: + echo("received from chan: " & $x) + else: + echo "channel is empty" + break + +echo "Finished listening" + +joinThread(thr) +close(chan) diff --git a/tests/typerel/typedescs.nim b/tests/typerel/typedescs.nim new file mode 100644 index 000000000..23b9ce64f --- /dev/null +++ b/tests/typerel/typedescs.nim @@ -0,0 +1,7 @@ +# bug #1774 +proc p(T: typedesc) = discard + +p(type((5, 6))) # Compiles +(type((5, 6))).p # Doesn't compile (SIGSEGV: Illegal storage access.) +type T = type((5, 6)) # Doesn't compile (SIGSEGV: Illegal storage access.) + diff --git a/tests/types/temptyseqs.nim b/tests/types/temptyseqs.nim new file mode 100644 index 000000000..f8d22bdb8 --- /dev/null +++ b/tests/types/temptyseqs.nim @@ -0,0 +1,26 @@ +discard """ + output: "1" +""" + +# bug #1708 +let foo = { + "1" : (bar: @["1"]), + "2" : (baz: @[]) +} + +# bug #871 + +when true: + import os + + type + In_out = tuple[src, dest, options: string] + + let + nil_var: In_out = ("hey"/"there", "something", nil) + #nil_var2 = ("hey"/"there", "something", nil) + +# bug #1721 +const foo2: seq[string] = @[] + +echo foo[0][0][0] diff --git a/tests/types/tisopr.nim b/tests/types/tisopr.nim index 3c2b9ee5e..8b7fe4e46 100644 --- a/tests/types/tisopr.nim +++ b/tests/types/tisopr.nim @@ -34,3 +34,20 @@ type yes s.items is Iter[TNumber] no s.items is Iter[float] +type + Foo[N: static[int], T] = object + field: array[1..N, T] + + Bar[T] = Foo[4, T] + Baz[N: static[int]] = Foo[N, float] + +no Foo[2, float] is Foo[3, float] +no Foo[2, float] is Foo[2, int] + +yes Foo[4, string] is Foo[4, string] +yes Bar[int] is Foo[4, int] +yes Foo[4, int] is Bar[int] + +no Foo[4, int] is Baz[4] +yes Foo[4, float] is Baz[4] + diff --git a/tests/vm/triangle_array.nim b/tests/vm/triangle_array.nim new file mode 100644 index 000000000..054c66f22 --- /dev/null +++ b/tests/vm/triangle_array.nim @@ -0,0 +1,17 @@ +discard """ + output: "56" +""" + +# bug #1781 + +proc initCombinations: array[11, array[11, int]] = + result[0] = [1,2,3,4,5,6,7,8,9,10,11] + result[1][1 .. 10] = [12,13,14,15,16,17,18,19,20,21] + result[2][2 .. 10] = [22,23,24,25,26,27,28,29,30] + result[3][3 .. 10] = [31,32,33,34,35,36,37,38] + result[4][4 .. 10] = [39,40,41,42,43,44,45] + result[5][5 .. 10] = [46,47,48,49,50,51] + result[6][6 .. 10] = [52,53,54,55,56] + +const combinations = initCombinations() +echo combinations[6][10] diff --git a/tests/vm/tstringnil.nim b/tests/vm/tstringnil.nim index 5070dd6b7..61ce60ee5 100644 --- a/tests/vm/tstringnil.nim +++ b/tests/vm/tstringnil.nim @@ -32,7 +32,7 @@ proc buildSuiteContents(suiteName, suiteDesc, suiteBloc: PNimrodNode): tuple[tes testObj.testDesc = nil else: testObj.testDesc = child[2].strVal - testObj.testBlock = child[3][6] + testObj.testBlock = child[1] tests.add(testObj) diff --git a/tools/niminst/niminst.nim b/tools/niminst/niminst.nim index 9ee3eb9b9..fe1b9a192 100644 --- a/tools/niminst/niminst.nim +++ b/tools/niminst/niminst.nim @@ -522,8 +522,8 @@ proc setupDist2(c: var TConfigData) = # ------------------ generate ZIP file --------------------------------------- when haveZipLib: proc zipDist(c: var TConfigData) = - var proj = toLower(c.name) - var n = "$#_$#.zip" % [proj, c.version] + var proj = toLower(c.name) & "-" & c.version + var n = "$#.zip" % proj if c.outdir.len == 0: n = "build" / n else: n = c.outdir / n var z: TZipArchive diff --git a/tools/nimweb.nim b/tools/nimweb.nim index bbd3776d7..0596076b3 100644 --- a/tools/nimweb.nim +++ b/tools/nimweb.nim @@ -47,7 +47,7 @@ proc initConfigData(c: var TConfigData) = c.logo = "" c.ticker = "" c.vars = newStringTable(modeStyleInsensitive) - c.gitRepo = "https://github.com/Araq/Nimrod/tree" + c.gitRepo = "https://github.com/Araq/Nim/tree" c.gitCommit = "master" c.numProcessors = countProcessors() # Attempts to obtain the git current commit. @@ -262,24 +262,26 @@ proc buildDocSamples(c: var TConfigData, destPath: string) = exec("nim doc2 $# -o:$# $#" % [c.nimArgs, destPath / "docgen_sample2.html", src]) +proc pathPart(d: string): string = splitFile(d).dir.replace('\\', '/') + proc buildDoc(c: var TConfigData, destPath: string) = # call nim for the documentation: var commands = newSeq[string](len(c.doc) + len(c.srcdoc) + len(c.srcdoc2)) i = 0 for d in items(c.doc): - commands[i] = "nim rst2html $# --docSeeSrcUrl:$#/$# -o:$# --index:on $#" % - [c.nimArgs, c.gitRepo, c.gitCommit, + commands[i] = "nim rst2html $# --docSeeSrcUrl:$#/$#/$# -o:$# --index:on $#" % + [c.nimArgs, c.gitRepo, c.gitCommit, d.pathPart, destPath / changeFileExt(splitFile(d).name, "html"), d] i.inc for d in items(c.srcdoc): - commands[i] = "nim doc $# --docSeeSrcUrl:$#/$# -o:$# --index:on $#" % - [c.nimArgs, c.gitRepo, c.gitCommit, + commands[i] = "nim doc $# --docSeeSrcUrl:$#/$#/$# -o:$# --index:on $#" % + [c.nimArgs, c.gitRepo, c.gitCommit, d.pathPart, destPath / changeFileExt(splitFile(d).name, "html"), d] i.inc for d in items(c.srcdoc2): - commands[i] = "nim doc2 $# --docSeeSrcUrl:$#/$# -o:$# --index:on $#" % - [c.nimArgs, c.gitRepo, c.gitCommit, + commands[i] = "nim doc2 $# --docSeeSrcUrl:$#/$#/$# -o:$# --index:on $#" % + [c.nimArgs, c.gitRepo, c.gitCommit, d.pathPart, destPath / changeFileExt(splitFile(d).name, "html"), d] i.inc @@ -311,8 +313,8 @@ proc buildAddDoc(c: var TConfigData, destPath: string) = # build additional documentation (without the index): var commands = newSeq[string](c.webdoc.len) for i, doc in pairs(c.webdoc): - commands[i] = "nim doc $# --docSeeSrcUrl:$#/$# -o:$# $#" % - [c.nimArgs, c.gitRepo, c.gitCommit, + commands[i] = "nim doc $# --docSeeSrcUrl:$#/$#/$# -o:$# $#" % + [c.nimArgs, c.gitRepo, c.gitCommit, doc.pathPart, destPath / changeFileExt(splitFile(doc).name, "html"), doc] mexec(commands, c.numProcessors) diff --git a/tools/website.tmpl b/tools/website.tmpl index 6f7a216a5..fed52ac15 100644 --- a/tools/website.tmpl +++ b/tools/website.tmpl @@ -63,7 +63,7 @@ <span class="tab end"> </span>count += <span class="val">1</span> echo(<span class="val">"Average line length: "</span>, - <span class="kwd">if</span> count: sum / count <span class="kwd">else</span>: <span class="val">0</span>) + <span class="kwd">if</span> count > <span class="val">0</span>: sum / count <span class="kwd">else</span>: <span class="val">0</span>) </pre> </div> <div> diff --git a/web/download.txt b/web/download.txt index f57e5a249..497781ad6 100644 --- a/web/download.txt +++ b/web/download.txt @@ -1,6 +1,6 @@ -You can download the latest version of the Nimrod compiler here. +You can download the latest version of the Nim compiler here. -**Note:** The Nimrod compiler requires a C compiler to compile software. On +**Note:** The Nim compiler requires a C compiler to compile software. On Windows we recommend that you use `Mingw-w64 <http://mingw-w64.sourceforge.net/>`_. GCC is recommended on Linux and clang on Mac OS X. @@ -10,9 +10,8 @@ Binaries ======== Unfortunately for now we only provide builds for Windows. - -* 32 bit: `nimrod_0.9.6.exe <download/nimrod_0.9.6.exe>`_ -* 64 bit: `nimrod_0.9.6_x64.exe <download/nimrod_0.9.6_x64.exe>`_ +* 32 bit: `nim-0.10.2_x32.exe <download/nim-0.10.2_x32.exe>`_ +* 64 bit: `nim-0.10.2_x64.exe <download/nim-0.10.2_x64.exe>`_ Installation based on generated C code @@ -22,13 +21,13 @@ This installation method is the preferred way for Linux, Mac OS X, and other Uni like systems. Binary packages may be provided later. -Download `nimrod_0.9.6.zip <download/nimrod_0.9.6.zip>`_, extract it and follow +Download `nim-0.10.2.zip <download/nim-0.10.2.zip>`_, extract it and follow these instructions: * sh build.sh * Add ``$your_install_dir/bin`` to your PATH. -There are other ways to install Nimrod (like using the ``install.sh`` script), +There are other ways to install Nim (like using the ``install.sh`` script), but these tend to cause more problems. diff --git a/web/news.txt b/web/news.txt index d1d23aebd..ee9ad8837 100644 --- a/web/news.txt +++ b/web/news.txt @@ -2,195 +2,200 @@ News ==== -.. - 2014-10-21 Version 0.10.2 released - ================================== - - This release marks the completion of a very important change to the project: - the official renaming from Nimrod to Nim. Version 0.10.2 contains many language - changes, some of which may break your existing code. For your convenience, we - added a new tool called `nimfix <nimfix.html>`_ that will help you convert your - existing projects so that it works with the latest version of the compiler. - - Progress towards version 1.0 - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - - Although Nim is still pre-1.0, we were able to keep the number of breaking - changes to a minimum so far. Starting with version 1.0, we will not introduce - any breaking changes between major release versions. - One of Nim's goals is to ensure that the compiler is as efficient as possible. - Take a look at the - `latest benchmarks <https://github.com/logicchains/LPATHBench/blob/master/writeup.md>`_, - which show that Nim is consistently near - the top and already nearly as fast as C and C++. Recent developments, such as - the new ``asyncdispatch`` module will allow you to write efficient web server - applications using non-blocking code. Nim now also has a built-in thread pool - for lightweight threading through the use of ``spawn``. - - The unpopular "T" and "P" prefixes on types have been deprecated. Nim also - became more expressive by weakening the distinction between statements and - epxressions. We also added new and searchable forums, a new website, and our - documentation generator ``docgen`` has seen major improvements. - - What's left to be done - ~~~~~~~~~~~~~~~~~~~~~~ - - The 1.0 release is actually very close. There are only a couple of last - things that need to be done: - - * Implementing static[T] properly - * Support for the overloading of the assignment operator - - Of course, the 1.0 release is not an end to the development of Nim. - It is very much the beginning and we will be fleshing out the then - stable language. - - Nimble and other Nim tools - ~~~~~~~~~~~~~~~~~~~~~~~~~~ - - Outside of the language and the compiler itself many Nim tools have seen - considerable improvements. - - Babel the Nim package manager has been renamed to Nimble. Nimble's purpose - is the installation of packages containing libraries and/or applications - written in Nim. - Even though Nimble is still very young it already is very - functional. It can install packages by name, it does so by accessing a - packages repository which is hosted on a Github repo. Packages can also be - installed via a Git repo URL or Mercurial repo URL. The package repository - is searchable through Nimble. Anyone is free to add their own packages to - the package repository by forking the - `nim-lang/packages <https://github.com/nim-lang/packages>`_ repo and creating - a pull request. Nimble is fully cross-platform and should be fully functional - on all major operating systems. - It is of course completely written in Nim. - - Changelog - ~~~~~~~~~ - - Changes affecting backwards compatibility - ----------------------------------------- - - - **The language has been renamed from Nimrod to Nim.** The name of the - compiler changed from ``nimrod`` to ``nim`` too. - - ``system.fileHandle`` has been renamed to ``system.getFileHandle`` to - prevent name conflicts with the new type ``FileHandle``. - - Comments are now not part of the AST anymore, as such you cannot use them - in place of ``discard``. - - Large parts of the stdlib got rid of the T/P type prefixes. Instead most - types now simply start with an uppercased letter. The - so called "partial case sensitivity" rule is now active allowing for code - like ``var foo: Foo`` in more contexts. - - String case (or any non-ordinal case) statements - without 'else' are deprecated. - - Recursive tuple types are not allowed anymore. Use ``object`` instead. - - The PEGS module returns ``nil`` instead of ``""`` when an optional capture - fails to match. - - The re module returns ``nil`` instead of ``""`` when an optional capture - fails to match. - - The "symmetric set difference" operator (``-+-``) never worked and has been - removed. - - ``defer`` is a keyword now. - - ``func`` is a keyword now. - - The ``using`` language feature now needs to be activated via the new - ``{.experimental.}`` pragma that enables experimental language features. - - Destructors are now officially *experimental*. - - Standalone ``except`` and ``finally`` statements are deprecated now. - The standalone ``finally`` can be replaced with ``defer``, - standalone ``except`` requires an explicit ``try``. - - Operators ending in ``>`` are considered as "arrow like" and have their - own priority level and are right associative. This means that - the ``=>`` and ``->`` operators from the `future <future.html>`_ module - work better. - - Field names in tuples are now ignored for type comparisons. This allows - for greater interoperability between different modules. - - Statement lists are not converted to an implicit ``do`` block anymore. This - means the confusing ``nnkDo`` nodes when working with macros are gone for - good. - - - Language Additions - ------------------ - - - The new concurrency model has been implemented including ``locks`` sections, - lock levels and object field ``guards``. - - The ``parallel`` statement has been implemented. - - ``deepCopy`` has been added to the language. - - The builtin ``procCall`` can be used to get ``super``-like functionality - for multi methods. - - There is a new pragma ``{.experimental.}`` that enables experimental - language features per module, or you can enable this features on a global - level with the ``--experimental`` command line option. - - - Compiler Additions - ------------------ - - - The compiler now supports *mixed* Objective C / C++ / C code generation: - The modules that use ``importCpp`` or ``importObjc`` are compiled to C++ - or Objective C code, any other module is compiled to C code. This - improves interoperability. - - There is a new ``parallel`` statement for safe fork&join parallel computing. - - ``guard`` and ``lock`` pragmas have been implemented to support safer - concurrent programming. - - The following procs are now available at compile-time:: - - math.sqrt, math.ln, math.log10, math.log2, math.exp, math.round, - math.arccos, math.arcsin, math.arctan, math.arctan2, math.cos, math.cosh, - math.hypot, math.sinh, math.sin, math.tan, math.tanh, math.pow, - math.trunc, math.floor, math.ceil, math.fmod, - os.getEnv, os.existsEnv, os.dirExists, os.fileExists, - system.writeFile - - - Two backticks now produce a single backtick within an ``emit`` or ``asm`` - statement. - - There is a new tool, `nimfix <nimfix.html>`_ to help you in updating your - code from Nimrod to Nim. - - The compiler's output has been prettified. - - Library Additions - ----------------- - - - Added module ``fenv`` to control the handling of floating-point rounding and - exceptions (overflow, division by zero, etc.). - - ``system.setupForeignThreadGc`` can be used for better interaction with - foreign libraries that create threads and run a Nim callback from these - foreign threads. - - List comprehensions have been implemented as a macro in the ``future`` - module. - - The new Async module (``asyncnet``) now supports SSL. - - The ``smtp`` module now has an async implementation. - - Added module ``asyncfile`` which implements asynchronous file reading - and writing. - - ``osproc.kill`` has been added. - - ``asyncnet`` and ``asynchttpserver`` now support ``SO_REUSEADDR``. - - Bugfixes - -------- - - - ``nil`` and ``NULL`` are now preserved between Nim and databases in the - ``db_*`` modules. - - Fixed issue with OS module in non-unicode mode on Windows. - - Fixed issue with ``x.low`` - (`#1366 <https://github.com/Araq/Nim/issues/1366>`_). - - Fixed tuple unpacking issue inside closure iterators - (`#1067 <https://github.com/Araq/Nim/issues/1067>`_). - - Fixed ENDB compilation issues. - - Many ``asynchttpserver`` fixes. - - Macros can now keep global state across macro calls - (`#903 <https://github.com/Araq/Nim/issues/903>`_). - - ``osproc`` fixes on Windows. - - ``osproc.terminate`` fixed. - - Improvements to exception handling in async procedures. - (`#1487 <https://github.com/Araq/Nim/issues/1487>`_). - - ``try`` now works at compile-time. - - Fixes ``T = ref T`` to be an illegal recursive type. - - Self imports are now disallowed. - - Improved effect inference. - - Fixes for the ``math`` module on Windows. - - User defined pragmas will now work for generics that have - been instantiated in different modules. - - Fixed queue exhaustion bug. +2014-12-29 Version 0.10.2 released +================================== + +This release marks the completion of a very important change to the project: +the official renaming from Nimrod to Nim. Version 0.10.2 contains many language +changes, some of which may break your existing code. For your convenience, we +added a new tool called `nimfix <nimfix.html>`_ that will help you convert your +existing projects so that it works with the latest version of the compiler. + +Progress towards version 1.0 +~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Although Nim is still pre-1.0, we were able to keep the number of breaking +changes to a minimum so far. Starting with version 1.0, we will not introduce +any breaking changes between major release versions. +One of Nim's goals is to ensure that the compiler is as efficient as possible. +Take a look at the +`latest benchmarks <https://github.com/logicchains/LPATHBench/blob/master/writeup.md>`_, +which show that Nim is consistently near +the top and already nearly as fast as C and C++. Recent developments, such as +the new ``asyncdispatch`` module will allow you to write efficient web server +applications using non-blocking code. Nim now also has a built-in thread pool +for lightweight threading through the use of ``spawn``. + +The unpopular "T" and "P" prefixes on types have been deprecated. Nim also +became more expressive by weakening the distinction between statements and +expressions. We also added a new and searchable forum, a new website, and our +documentation generator ``docgen`` has seen major improvements. Many thanks to +Nick Greenfield for the much more beautiful documentation! + + + +What's left to be done +~~~~~~~~~~~~~~~~~~~~~~ + +The 1.0 release is actually very close. Apart from bug fixes, there are +two major features missing or incomplete: + +* ``static[T]`` needs to be defined precisely and the bugs in the + implementation need to be fixed. +* Overloading of the assignment operator is required for some generic + containers and needs to be implemented. + +This means that fancy matrix libraries will finally start to work, which used +to be a major point of pain in the language. + + +Nimble and other Nim tools +~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Outside of the language and the compiler itself many Nim tools have seen +considerable improvements. + +Babel the Nim package manager has been renamed to Nimble. Nimble's purpose +is the installation of packages containing libraries and/or applications +written in Nim. +Even though Nimble is still very young it already is very +functional. It can install packages by name, it does so by accessing a +packages repository which is hosted on a Github repo. Packages can also be +installed via a Git repo URL or Mercurial repo URL. The package repository +is searchable through Nimble. Anyone is free to add their own packages to +the package repository by forking the +`nim-lang/packages <https://github.com/nim-lang/packages>`_ repo and creating +a pull request. Nimble is fully cross-platform and should be fully functional +on all major operating systems. +It is of course completely written in Nim. + +Changelog +~~~~~~~~~ + +Changes affecting backwards compatibility +----------------------------------------- + +- **The language has been renamed from Nimrod to Nim.** The name of the + compiler changed from ``nimrod`` to ``nim`` too. +- ``system.fileHandle`` has been renamed to ``system.getFileHandle`` to + prevent name conflicts with the new type ``FileHandle``. +- Comments are now not part of the AST anymore, as such you cannot use them + in place of ``discard``. +- Large parts of the stdlib got rid of the T/P type prefixes. Instead most + types now simply start with an uppercased letter. The + so called "partial case sensitivity" rule is now active allowing for code + like ``var foo: Foo`` in more contexts. +- String case (or any non-ordinal case) statements + without 'else' are deprecated. +- Recursive tuple types are not allowed anymore. Use ``object`` instead. +- The PEGS module returns ``nil`` instead of ``""`` when an optional capture + fails to match. +- The re module returns ``nil`` instead of ``""`` when an optional capture + fails to match. +- The "symmetric set difference" operator (``-+-``) never worked and has been + removed. +- ``defer`` is a keyword now. +- ``func`` is a keyword now. +- The ``using`` language feature now needs to be activated via the new + ``{.experimental.}`` pragma that enables experimental language features. +- Destructors are now officially *experimental*. +- Standalone ``except`` and ``finally`` statements are deprecated now. + The standalone ``finally`` can be replaced with ``defer``, + standalone ``except`` requires an explicit ``try``. +- Operators ending in ``>`` are considered as "arrow like" and have their + own priority level and are right associative. This means that + the ``=>`` and ``->`` operators from the `future <future.html>`_ module + work better. +- Field names in tuples are now ignored for type comparisons. This allows + for greater interoperability between different modules. +- Statement lists are not converted to an implicit ``do`` block anymore. This + means the confusing ``nnkDo`` nodes when working with macros are gone for + good. + + +Language Additions +------------------ + +- The new concurrency model has been implemented including ``locks`` sections, + lock levels and object field ``guards``. +- The ``parallel`` statement has been implemented. +- ``deepCopy`` has been added to the language. +- The builtin ``procCall`` can be used to get ``super``-like functionality + for multi methods. +- There is a new pragma ``{.experimental.}`` that enables experimental + language features per module, or you can enable these features on a global + level with the ``--experimental`` command line option. + + +Compiler Additions +------------------ + +- The compiler now supports *mixed* Objective C / C++ / C code generation: + The modules that use ``importCpp`` or ``importObjc`` are compiled to C++ + or Objective C code, any other module is compiled to C code. This + improves interoperability. +- There is a new ``parallel`` statement for safe fork&join parallel computing. +- ``guard`` and ``lock`` pragmas have been implemented to support safer + concurrent programming. +- The following procs are now available at compile-time:: + + math.sqrt, math.ln, math.log10, math.log2, math.exp, math.round, + math.arccos, math.arcsin, math.arctan, math.arctan2, math.cos, + math.cosh, math.hypot, math.sinh, math.sin, math.tan, math.tanh, + math.pow, math.trunc, math.floor, math.ceil, math.fmod, + os.getEnv, os.existsEnv, os.dirExists, os.fileExists, + system.writeFile + +- Two backticks now produce a single backtick within an ``emit`` or ``asm`` + statement. +- There is a new tool, `nimfix <nimfix.html>`_ to help you in updating your + code from Nimrod to Nim. +- The compiler's output has been prettified. + +Library Additions +----------------- + +- Added module ``fenv`` to control the handling of floating-point rounding and + exceptions (overflow, division by zero, etc.). +- ``system.setupForeignThreadGc`` can be used for better interaction with + foreign libraries that create threads and run a Nim callback from these + foreign threads. +- List comprehensions have been implemented as a macro in the ``future`` + module. +- The new Async module (``asyncnet``) now supports SSL. +- The ``smtp`` module now has an async implementation. +- Added module ``asyncfile`` which implements asynchronous file reading + and writing. +- ``osproc.kill`` has been added. +- ``asyncnet`` and ``asynchttpserver`` now support ``SO_REUSEADDR``. + +Bugfixes +-------- + +- ``nil`` and ``NULL`` are now preserved between Nim and databases in the + ``db_*`` modules. +- Fixed issue with OS module in non-unicode mode on Windows. +- Fixed issue with ``x.low`` + (`#1366 <https://github.com/Araq/Nim/issues/1366>`_). +- Fixed tuple unpacking issue inside closure iterators + (`#1067 <https://github.com/Araq/Nim/issues/1067>`_). +- Fixed ENDB compilation issues. +- Many ``asynchttpserver`` fixes. +- Macros can now keep global state across macro calls + (`#903 <https://github.com/Araq/Nim/issues/903>`_). +- ``osproc`` fixes on Windows. +- ``osproc.terminate`` fixed. +- Improvements to exception handling in async procedures. + (`#1487 <https://github.com/Araq/Nim/issues/1487>`_). +- ``try`` now works at compile-time. +- Fixes ``T = ref T`` to be an illegal recursive type. +- Self imports are now disallowed. +- Improved effect inference. +- Fixes for the ``math`` module on Windows. +- User defined pragmas will now work for generics that have + been instantiated in different modules. +- Fixed queue exhaustion bug. +- Many, many more. 2014-12-09 New website design! ============================== diff --git a/web/babelpkglist.nim b/web/nimblepkglist.nim index 7070f281b..7070f281b 100644 --- a/web/babelpkglist.nim +++ b/web/nimblepkglist.nim diff --git a/web/ticker.txt b/web/ticker.txt index a0d2f0a78..64218084e 100644 --- a/web/ticker.txt +++ b/web/ticker.txt @@ -1,13 +1,13 @@ +<a class="news" href="news.html#Z2014-12-29-version-0-10-2-released"> + <h4>Dec 29, 2014</h4> + <p>Nim version 0.10.2 has been released!</p> +</a> + <a class="news" href="news.html#Z2014-12-09-new-website-design"> <h4>Dec 9, 2014</h4> <p>The new website design and forum are now online!</p> </a> -<a class="news" href="news.html#Z2014-10-19-version-0-9-6-released"> - <h4>Oct 19, 2014</h4> - <p>Nimrod version 0.9.6 has been released!</p> -</a> - <a class="news" href="news.html#Z2014-02-11-nimrod-featured-in-dr-dobb-s-journal"> <h4>Feb 11, 2014</h4> <p>Nimrod featured in Dr. Dobb's Journal</p> |