diff options
-rwxr-xr-x | compiler/ccgexprs.nim | 35 | ||||
-rwxr-xr-x | compiler/ccgstmts.nim | 38 | ||||
-rwxr-xr-x | compiler/cgen.nim | 26 | ||||
-rw-r--r-- | compiler/cgendata.nim | 7 | ||||
-rwxr-xr-x | doc/manual.txt | 54 | ||||
-rwxr-xr-x | doc/tut2.txt | 43 | ||||
-rw-r--r-- | examples/debugging.nim | 17 | ||||
-rwxr-xr-x | lib/nimbase.h | 6 | ||||
-rwxr-xr-x | lib/system/debugger.nim | 11 | ||||
-rwxr-xr-x | todo.txt | 51 | ||||
-rwxr-xr-x | web/news.txt | 7 |
11 files changed, 152 insertions, 143 deletions
diff --git a/compiler/ccgexprs.nim b/compiler/ccgexprs.nim index fd70834c2..a99654cbd 100755 --- a/compiler/ccgexprs.nim +++ b/compiler/ccgexprs.nim @@ -709,12 +709,12 @@ proc genFieldCheck(p: BProc, e: PNode, obj: PRope, field: PSym) = rdLoc(test), strLit) proc genCheckedRecordField(p: BProc, e: PNode, d: var TLoc) = - var - a: TLoc - f, field: PSym - ty: PType - r: PRope if optFieldCheck in p.options: + var + a: TLoc + f, field: PSym + ty: PType + r: PRope ty = genRecordFieldAux(p, e.sons[0], d, a) r = rdLoc(a) f = e.sons[0].sons[1].sym @@ -729,31 +729,6 @@ proc genCheckedRecordField(p: BProc, e: PNode, d: var TLoc) = if field.loc.r == nil: InternalError(e.info, "genCheckedRecordField") # generate the checks: genFieldCheck(p, e, r, field) - when false: - for i in countup(1, sonsLen(e) - 1): - it = e.sons[i] - assert(it.kind in nkCallKinds) - assert(it.sons[0].kind == nkSym) - op = it.sons[0].sym - if op.magic == mNot: it = it.sons[1] - assert(it.sons[2].kind == nkSym) - initLoc(test, locNone, it.typ, OnStack) - InitLocExpr(p, it.sons[1], u) - initLoc(v, locExpr, it.sons[2].typ, OnUnknown) - v.r = ropef("$1.$2", [r, it.sons[2].sym.loc.r]) - genInExprAux(p, it, u, v, test) - id = NodeTableTestOrSet(p.module.dataCache, - newStrNode(nkStrLit, field.name.s), gBackendId) - if id == gBackendId: strLit = getStrLit(p.module, field.name.s) - else: strLit = con("TMP", toRope(id)) - if op.magic == mNot: - linefmt(p, cpsStmts, - "if ($1) #raiseFieldError(((#NimStringDesc*) &$2));$n", - rdLoc(test), strLit) - else: - linefmt(p, cpsStmts, - "if (!($1)) #raiseFieldError(((#NimStringDesc*) &$2));$n", - rdLoc(test), strLit) app(r, rfmt(nil, ".$1", field.loc.r)) putIntoDest(p, d, field.typ, r) else: diff --git a/compiler/ccgstmts.nim b/compiler/ccgstmts.nim index dd6d2bfaa..e11678861 100755 --- a/compiler/ccgstmts.nim +++ b/compiler/ccgstmts.nim @@ -45,7 +45,7 @@ proc genVarTuple(p: BProc, n: PNode) = if t.kind == tyTuple: field.r = ropef("$1.Field$2", [rdLoc(tup), toRope(i)]) else: - if (t.n.sons[i].kind != nkSym): InternalError(n.info, "genVarTuple") + if t.n.sons[i].kind != nkSym: InternalError(n.info, "genVarTuple") field.r = ropef("$1.$2", [rdLoc(tup), mangleRecFieldName(t.n.sons[i].sym, t)]) putLocIntoDest(p, v.loc, field) @@ -64,19 +64,23 @@ proc startBlock(p: BProc, start: TFormatStr = "{$n", result = len(p.blocks) setlen(p.blocks, result + 1) p.blocks[result].id = p.labels - p.blocks[result].nestedTryStmts = p.nestedTryStmts.len + p.blocks[result].nestedTryStmts = p.nestedTryStmts.len.int16 proc assignLabel(b: var TBlock): PRope {.inline.} = b.label = con("LA", b.id.toRope) result = b.label -proc blockBody(b: var TBlock): PRope {.inline.} = - return b.sections[cpsLocals].con(b.sections[cpsInit]).con(b.sections[cpsStmts]) +proc blockBody(b: var TBlock): PRope = + result = b.sections[cpsLocals] + if b.frameLen > 0: + result.appf("F.len+=$1;$n", b.frameLen.toRope) + result.app(b.sections[cpsInit]) + result.app(b.sections[cpsStmts]) proc endBlock(p: BProc, blockEnd: PRope) = - let topBlock = p.blocks.len - 1 + let topBlock = p.blocks.len-1 # the block is merged into the parent block - app(p.blocks[topBlock - 1].sections[cpsStmts], p.blocks[topBlock].blockBody) + app(p.blocks[topBlock-1].sections[cpsStmts], p.blocks[topBlock].blockBody) setlen(p.blocks, topBlock) # this is done after the block is popped so $n is # properly indented when pretty printing is enabled @@ -84,10 +88,13 @@ proc endBlock(p: BProc, blockEnd: PRope) = proc endBlock(p: BProc) = let topBlock = p.blocks.len - 1 - let blockEnd = if p.blocks[topBlock].label != nil: + var blockEnd = if p.blocks[topBlock].label != nil: rfmt(nil, "} $1: ;$n", p.blocks[topBlock].label) else: ~"}$n" + let frameLen = p.blocks[topBlock].frameLen + if frameLen > 0: + blockEnd.appf("F.len-=$1;$n", frameLen.toRope) endBlock(p, blockEnd) proc genSimpleBlock(p: BProc, stmts: PNode) {.inline.} = @@ -774,7 +781,7 @@ var proc genBreakPoint(p: BProc, t: PNode) = var name: string - if optEndb in p.Options: + if optEndb in p.Options: if t.kind == nkExprColonExpr: assert(t.sons[1].kind in {nkStrLit..nkTripleStrLit}) name = normalize(t.sons[1].strVal) @@ -784,7 +791,7 @@ proc genBreakPoint(p: BProc, t: PNode) = genLineDir(p, t) # BUGFIX appcg(p.module, gBreakpoints, "#dbgRegisterBreakpoint($1, (NCSTRING)$2, (NCSTRING)$3);$n", [ - toRope(toLinenumber(t.info)), makeCString(toFilename(t.info)), + toRope(toLinenumber(t.info)), makeCString(toFilename(t.info)), makeCString(name)]) proc genWatchpoint(p: BProc, n: PNode) = @@ -796,16 +803,13 @@ proc genWatchpoint(p: BProc, n: PNode) = [a.addrLoc, makeCString(renderTree(n.sons[1])), genTypeInfo(p.module, typ)]) -proc genPragma(p: BProc, n: PNode) = - for i in countup(0, sonsLen(n) - 1): +proc genPragma(p: BProc, n: PNode) = + for i in countup(0, sonsLen(n) - 1): var it = n.sons[i] case whichPragma(it) - of wEmit: - genEmit(p, it) - of wBreakpoint: - genBreakPoint(p, it) - of wWatchpoint: - genWatchpoint(p, it) + of wEmit: genEmit(p, it) + of wBreakpoint: genBreakPoint(p, it) + of wWatchpoint: genWatchpoint(p, it) else: nil proc FieldDiscriminantCheckNeeded(p: BProc, asgn: PNode): bool = diff --git a/compiler/cgen.nim b/compiler/cgen.nim index 399785c82..d06a6cb6f 100755 --- a/compiler/cgen.nim +++ b/compiler/cgen.nim @@ -1,7 +1,7 @@ # # # The Nimrod Compiler -# (c) Copyright 2012 Andreas Rumpf +# (c) Copyright 2013 Andreas Rumpf # # See the file "copying.txt", included in this # distribution, for details about the copyright. @@ -269,18 +269,18 @@ proc genCLineDir(r: var PRope, filename: string, line: int) = proc genCLineDir(r: var PRope, info: TLineInfo) = genCLineDir(r, info.toFullPath, info.safeLineNm) -proc genLineDir(p: BProc, t: PNode) = +proc genLineDir(p: BProc, t: PNode) = var line = t.info.safeLineNm if optEmbedOrigSrc in gGlobalOptions: app(p.s(cpsStmts), con(~"//", t.info.sourceLine, rnl)) genCLineDir(p.s(cpsStmts), t.info.toFullPath, line) if ({optStackTrace, optEndb} * p.Options == {optStackTrace, optEndb}) and - (p.prc == nil or sfPure notin p.prc.flags): - linefmt(p, cpsStmts, "#endb($1);$n", toRope(line)) + (p.prc == nil or sfPure notin p.prc.flags): + linefmt(p, cpsStmts, "#endb($1, $2);$n", + line.toRope, makeCString(toFilename(t.info))) elif ({optLineTrace, optStackTrace} * p.Options == {optLineTrace, optStackTrace}) and (p.prc == nil or sfPure notin p.prc.flags): - linefmt(p, cpsStmts, "nimln($1, $2);$n", line.toRope, t.info.quotedFilename) @@ -470,12 +470,13 @@ proc localDebugInfo(p: BProc, s: PSym) = # XXX work around a bug: No type information for open arrays possible: if skipTypes(s.typ, abstractVar).kind in {tyOpenArray, tyVarargs}: return var a = con("&", s.loc.r) - if (s.kind == skParam) and ccgIntroducedPtr(s): a = s.loc.r + if s.kind == skParam and ccgIntroducedPtr(s): a = s.loc.r lineF(p, cpsInit, "F.s[$1].address = (void*)$3; F.s[$1].typ = $4; F.s[$1].name = $2;$n", - [toRope(p.frameLen), makeCString(normalize(s.name.s)), a, + [p.maxFrameLen.toRope, makeCString(normalize(s.name.s)), a, genTypeInfo(p.module, s.loc.t)]) - inc(p.frameLen) + inc(p.maxFrameLen) + inc p.blocks[p.blocks.len-1].frameLen proc assignLocalVar(p: BProc, s: PSym) = #assert(s.loc.k == locNone) // not yet assigned @@ -488,7 +489,7 @@ proc assignLocalVar(p: BProc, s: PSym) = if sfRegister in s.flags: app(decl, " register") #elif skipTypes(s.typ, abstractInst).kind in GcTypeKinds: # app(decl, " GC_GUARD") - if (sfVolatile in s.flags) or (p.nestedTryStmts.len > 0): + if sfVolatile in s.flags or p.nestedTryStmts.len > 0: app(decl, " volatile") appf(decl, " $1;$n", [s.loc.r]) line(p, cpsLocals, decl) @@ -693,10 +694,11 @@ proc retIsNotVoid(s: PSym): bool = proc initFrame(p: BProc, procname, filename: PRope): PRope = discard cgsym(p.module, "pushFrame") - if p.frameLen > 0: + if p.maxFrameLen > 0: discard cgsym(p.module, "TVarSlot") - result = rfmt(nil, "\tnimfrs($1, $2, $3)$N", - procname, filename, p.frameLen.toRope) + result = rfmt(nil, "\tnimfrs($1, $2, $3, $4)$N", + procname, filename, p.maxFrameLen.toRope, + p.blocks[0].frameLen.toRope) else: result = rfmt(nil, "\tnimfr($1, $2)$N", procname, filename) diff --git a/compiler/cgendata.nim b/compiler/cgendata.nim index 32e9fb4ce..ad17194df 100644 --- a/compiler/cgendata.nim +++ b/compiler/cgendata.nim @@ -54,9 +54,10 @@ type id*: int # the ID of the label; positive means that it label*: PRope # generated text for the label # nil if label is not used - nestedTryStmts*: int # how many try statements is it nested into sections*: TCProcSections # the code beloging isLoop*: bool # whether block is a loop + nestedTryStmts*: int16 # how many try statements is it nested into + frameLen*: int16 TCProc{.final.} = object # represents C proc that is currently generated prc*: PSym # the Nimrod proc that this C proc belongs to @@ -74,9 +75,7 @@ type options*: TOptions # options that should be used for code # generation; this is the same as prc.options # unless prc == nil - frameLen*: int # current length of frame descriptor - sendClosure*: PType # closure record type that we pass - receiveClosure*: PType # closure record type that we get + maxFrameLen*: int # max length of frame descriptor module*: BModule # used to prevent excessive parameter passing withinLoop*: int # > 0 if we are within a loop gcFrameId*: natural # for the GC stack marking diff --git a/doc/manual.txt b/doc/manual.txt index b70dbdebc..3c2d7534b 100755 --- a/doc/manual.txt +++ b/doc/manual.txt @@ -984,7 +984,7 @@ in future versions of the compiler. .. code-block:: nimrod type - TPerson = tuple[name: string, age: int] # type representing a person + TPerson = tuple[name: string, age: int] # type representing a person: # a person consists of a name # and an age var @@ -1000,7 +1000,6 @@ For consistency with ``object`` declarations, tuples in a ``type`` section can also be defined with indentation instead of ``[]``: .. code-block:: nimrod - type TPerson = tuple # type representing a person name: string # a person consists of a name @@ -1011,7 +1010,6 @@ and information hiding. Objects have access to their type at runtime, so that the ``of`` operator can be used to determine the object's type. .. code-block:: nimrod - type TPerson {.inheritable.} = object name*: string # the * means that `name` is accessible from other modules @@ -1032,6 +1030,19 @@ and thus have no hidden type field. One can use the ``inheritable`` pragma to introduce new object roots apart from ``system.TObject``. +Object construction +------------------- + +Objects can also be created with an `object construction expression`:idx: that +has the syntax ``T(fieldA: valueA, fieldB: valueB, ...)`` where ``T`` is +an ``object`` type or a ``ref object`` type: + +.. code-block:: nimrod + var student = TStudent(name: "Anton", age: 5, id: 3) + +For a ``ref object`` type ``new`` is invoked implicitly. + + Object variants --------------- Often an object hierarchy is overkill in certain situations where simple @@ -1061,15 +1072,22 @@ An example: of nkIf: condition, thenPart, elsePart: PNode - var - n: PNode - new(n) # creates a new node - n.kind = nkFloat - n.floatVal = 0.0 # valid, because ``n.kind==nkFloat``, so that it fits + # create a new case object: + var n = PNode(kind: nkIf, condition: nil) + # accessing n.thenPart is valid because the ``nkIf`` branch is active: + n.thenPart = PNode(kind: nkFloat, floatVal: 2.0) # the following statement raises an `EInvalidField` exception, because - # n.kind's value does not fit: + # n.kind's value does not fit and the ``nkString`` branch is not active: n.strVal = "" + + # invalid: would change the active object branch: + n.kind = nkInt + + var x = PNode(kind: nkAdd, leftOp: PNode(kind: nkInt, intVal: 4), + rightOp: PNode(kind: nkInt, intVal: 2)) + # valid: does not change the active object branch: + x.kind = nkSub As can been seen from the example, an advantage to an object hierarchy is that no casting between different object types is needed. Yet, access to invalid @@ -1078,6 +1096,11 @@ object fields raises an exception. The syntax of ``case`` in an object declaration follows closely the syntax of the ``case`` statement: The branches in a ``case`` section may be indented too. +In the example the ``kind`` field is called the `discriminator`:idx:\: For +safety its address cannot be taken and assignments to it are restricted: The +new value must not lead to a change of the active object branch. For an object +branch switch ``system.reset`` has to be used. + Set type -------- @@ -2387,6 +2410,7 @@ the proc's name. Procs as expressions can appear both as nested procs and inside top level executable code. + Do notation ----------- @@ -2410,7 +2434,7 @@ Again, let's see the equivalent of the previous example: sort(cities) do (x,y: string) -> int: cmp(x.len, y.len) -Finally, more than one ``do`` blocks can appear in a single call: +Finally, more than one ``do`` block can appear in a single call: .. code-block:: nimrod proc performWithUndo(task: proc(), undo: proc()) = ... @@ -2426,6 +2450,7 @@ omitted if the supplied proc doesn't have any parameters and return value. The compatibility works in the other direction too as the ``do`` syntax can be used with macros and templates expecting ``stmt`` blocks. + Nonoverloadable builtins ------------------------ @@ -2987,8 +3012,7 @@ possibly raised exceptions; the algorithm operates on ``p``'s call graph: raise ``system.E_Base`` unless ``q`` has an explicit ``raises`` list. 3. Every call to a method ``m`` is assumed to raise ``system.E_Base`` unless ``m`` has an explicit ``raises`` list. -4. For every other call the analysis can determine an - exact ``raises`` list. +4. For every other call the analysis can determine an exact ``raises`` list. 5. For determining a ``raises`` list, the ``raise`` and ``try`` statements of ``p`` are taken into consideration. @@ -3259,7 +3283,7 @@ Symbol lookup in generics The symbol binding rules in generics are slightly subtle: There are "open" and "closed" symbols. A "closed" symbol cannot be re-bound in the instantiation -context, an "open" symbol can be. Per default overloaded symbols are open +context, an "open" symbol can. Per default overloaded symbols are open and every other symbol is closed. Open symbols are looked up in two different contexts: Both the context @@ -4106,8 +4130,8 @@ implemented with term rewriting: proc p(x, y: int; cond: bool): int = result = if cond: x + y else: x - y - template optP{p(x, y, true)}(x, y: expr): expr = x + y - template optP{p(x, y, false)}(x, y: expr): expr = x - y + template optP1{p(x, y, true)}(x, y: expr): expr = x + y + template optP2{p(x, y, false)}(x, y: expr): expr = x - y Example: hoisting diff --git a/doc/tut2.txt b/doc/tut2.txt index c080d1339..e1e36bfc4 100755 --- a/doc/tut2.txt +++ b/doc/tut2.txt @@ -46,8 +46,7 @@ Objects Like tuples, objects are a means to pack different values together in a structured way. However, objects provide many features that tuples do not: They provide inheritance and information hiding. Because objects encapsulate -data, the ``()`` tuple constructor cannot be used to construct objects. So -the order of the object's fields is not as important as it is for tuples. The +data, the ``T()`` object constructor should only be used internally and the programmer should provide a proc to initialize the object (this is called a *constructor*). @@ -55,7 +54,6 @@ Objects have access to their type at runtime. There is an ``of`` operator that can be used to check the object's type: .. code-block:: nimrod - type TPerson = object of TObject name*: string # the * means that `name` is accessible from other modules @@ -68,6 +66,8 @@ Objects have access to their type at runtime. There is an student: TStudent person: TPerson assert(student of TStudent) # is true + # object construction: + student = TStudent(name: "Anton", age: 5, id: 2) Object fields that should be visible from outside the defining module have to be marked by ``*``. In contrast to tuples, different object types are @@ -161,12 +161,7 @@ An example: of nkIf: condition, thenPart, elsePart: PNode - var - n: PNode - new(n) # creates a new node - n.kind = nkFloat - n.floatVal = 0.0 # valid, because ``n.kind==nkFloat`` - + var n = PNode(kind: nkFloat, floatVal: 1.0) # the following statement raises an `EInvalidField` exception, because # n.kind's value does not fit: n.strVal = "" @@ -288,30 +283,22 @@ Procedures always use static dispatch. For dynamic dispatch replace the .. code-block:: nimrod type - TExpr = object of TObject ## abstract base class for an expression - TLiteral = object of TExpr + PExpr = ref object of TObject ## abstract base class for an expression + PLiteral = ref object of PExpr x: int - TPlusExpr = object of TExpr - a, b: ref TExpr - - method eval(e: ref TExpr): int = + PPlusExpr = ref object of PExpr + a, b: PExpr + + # watch out: 'eval' relies on dynamic binding + method eval(e: PExpr): int = # override this base method quit "to override!" - method eval(e: ref TLiteral): int = return e.x - - method eval(e: ref TPlusExpr): int = - # watch out: relies on dynamic binding - return eval(e.a) + eval(e.b) + method eval(e: PLiteral): int = e.x + method eval(e: PPlusExpr): int = eval(e.a) + eval(e.b) - proc newLit(x: int): ref TLiteral = - new(result) - result.x = x - - proc newPlus(a, b: ref TExpr): ref TPlusExpr = - new(result) - result.a = a - result.b = b + proc newLit(x: int): PLiteral = PLiteral(x: x) + proc newPlus(a, b: PExpr): PPlusExpr = PPlusExpr(a: a, b: b) echo eval(newPlus(newPlus(newLit(1), newLit(2)), newLit(4))) diff --git a/examples/debugging.nim b/examples/debugging.nim new file mode 100644 index 000000000..89cdd3b2a --- /dev/null +++ b/examples/debugging.nim @@ -0,0 +1,17 @@ +# Simple program to test the debugger +# compile with --debugger:on + +proc someComp(x, y: int): int = + let a = x+y + if a > 7: + let b = a*90 + {.breakpoint.} + result = b + {.breakpoint.} + +proc pp() = + var aa = 45 + var bb = "abcdef" + echo someComp(23, 45) + +pp() diff --git a/lib/nimbase.h b/lib/nimbase.h index 4735cbb4f..fcbf80fc3 100755 --- a/lib/nimbase.h +++ b/lib/nimbase.h @@ -1,7 +1,7 @@ /* Nimrod's Runtime Library - (c) Copyright 2012 Andreas Rumpf + (c) Copyright 2013 Andreas Rumpf See the file "copying.txt", included in this distribution, for details about the copyright. @@ -440,9 +440,9 @@ struct TFrame { volatile TFrame F; \ F.procname = proc; F.filename = file; F.line = 0; F.len = 0; nimFrame(&F); -#define nimfrs(proc, file, slots) \ +#define nimfrs(proc, file, slots, length) \ volatile struct {TFrame* prev;NCSTRING procname;NI line;NCSTRING filename; NI len; TVarSlot s[slots];} F; \ - F.procname = proc; F.filename = file; F.line = 0; F.len = slots; nimFrame((TFrame*)&F); + F.procname = proc; F.filename = file; F.line = 0; F.len = length; nimFrame((TFrame*)&F); #define nimln(n, file) \ F.line = n; F.filename = file; diff --git a/lib/system/debugger.nim b/lib/system/debugger.nim index f234c9daf..101b3c599 100755 --- a/lib/system/debugger.nim +++ b/lib/system/debugger.nim @@ -207,9 +207,8 @@ proc fileMatches(c, bp: cstring): bool = return false var i = 0 while i < blen: - var x, y: char - x = bp[i] - y = c[i+clen-blen] + var x = bp[i] + var y = c[i+clen-blen] when FileSystemCaseInsensitive: if x >= 'A' and x <= 'Z': x = chr(ord(x) - ord('A') + ord('a')) if y >= 'A' and y <= 'Z': y = chr(ord(y) - ord('A') + ord('a')) @@ -742,7 +741,7 @@ proc checkWatchpoints = debugOut(Watchpoints[i].name) Watchpoints[i].oldValue = newHash -proc endb(line: int) {.compilerproc.} = +proc endb(line: int, file: cstring) {.compilerproc.} = # This proc is called before every Nimrod code line! # Thus, it must have as few parameters as possible to keep the # code size small! @@ -753,6 +752,7 @@ proc endb(line: int) {.compilerproc.} = #if oldState != dbOff: checkWatchpoints() framePtr.line = line # this is done here for smaller code size! + framePtr.filename = file if dbgLineHook != nil: dbgLineHook() case oldState of dbStepInto: @@ -765,7 +765,8 @@ proc endb(line: int) {.compilerproc.} = CommandPrompt() else: # breakpoints are wanted though (I guess) checkForBreakpoint() - of dbBreakpoints: # debugger is only interested in breakpoints + of dbBreakpoints: + # debugger is only interested in breakpoints checkForBreakpoint() else: nil diff --git a/todo.txt b/todo.txt index c914e0155..bb838e24d 100755 --- a/todo.txt +++ b/todo.txt @@ -1,6 +1,9 @@ version 0.9.2 ============= +- fix destructors; don't work yet when used as expression; alternative for + version 1: disallow expressions yielding a type with a destructor that are + not in a 'let/var' context (p(a.openFile, b.openFile) makes no sense anyway) - lazy overloading resolution: * get rid of ``expr[typ]``, use perhaps ``static[typ]`` instead * special case ``tyStmt`` @@ -8,16 +11,24 @@ version 0.9.2 * test libffi on windows * test: times.format with the FFI - acyclic vs prunable; introduce GC hints -- implement constructors - - more checks - - document them - CGEN: ``restrict`` pragma + backend support; computed goto support -- fix: - - 'result' is not properly cleaned for NRVO - document NimMain and check whether it works for threading -- fix destructors; don't work yet when used as expression; alternative for - version 1: disallow expressions yielding a type with a destructor that are - not in a 'let/var' context (p(a.openFile, b.openFile) makes no sense anyway) + + +Bugs +==== + +- 'result' is not properly cleaned for NRVO +- instantiated generics are listed in error messages +- sneaking with qualifiedLookup() is really broken! +- aporia.nim(968, 5) Error: ambiguous identifier: 'DELETE' -- + use a qualifier +- blocks can "export" an identifier but the CCG generates {} for them ... +- JS gen: fix exception handling +- osproc execProcesses can deadlock if all processes fail (as experienced + in c++ mode) +- bootstrapping does not work in C++ mode +- case statement exhaustiveness checking is still wrong version 0.9.4 @@ -40,7 +51,7 @@ version 0.9.X - test&finish first class iterators: * nested iterators - implement the missing features wrt inheritance -- better support for *hard* realtime systems +- object pooling support for *hard* realtime systems - improve the compiler as a service - better support for macros that rewrite procs - macros need access to types and symbols (partially implemented) @@ -71,8 +82,9 @@ version 0.9.XX ============== - object branch transitions can't work with the current 'reset'; add a 'reset' - with an additional parameter --> re-evaluate this issue after constructors - have been added + with an additional parameter --> simple: + provide a 'reset(x, TObj(k: nkValue))' instead? why bother? '=' does the + same. - document nimdoc properly finally - make 'clamp' a magic for the range stuff - better type syntax for functions and tuples: tuple(int, int); (int,int)->int @@ -103,6 +115,8 @@ Not essential for 1.0.0 * first version: mark black in write barrier * second version: introduce fake roots instead of marking black * third version: find some clever heuristic which is preferable +- object constructors: static check for fields if discriminator is known at + compile time GC @@ -122,18 +136,3 @@ Optimizations even further write barrier specialization - inlining of first class functions - proc specialization in the code gen for write barrier specialization - - -Bugs -==== - -- instantiated generics are listed in error messages -- sneaking with qualifiedLookup() is really broken! -- aporia.nim(968, 5) Error: ambiguous identifier: 'DELETE' -- - use a qualifier -- blocks can "export" an identifier but the CCG generates {} for them ... -- JS gen: fix exception handling -- the better scoping for locals is the wrong default for endb -- osproc execProcesses can deadlock if all processes fail (as experienced - in c++ mode) -- case statement exhaustiveness checking is still wrong diff --git a/web/news.txt b/web/news.txt index a0728e812..7bd0e4f4f 100755 --- a/web/news.txt +++ b/web/news.txt @@ -15,17 +15,17 @@ Bugfixes with ``GC_disableMarkAndSweep`` and run it explicitly at an appropriate time or not at all. There is also a new GC you can activate with ``--gc:markAndSweep`` which does not have this problem but is slower in - general. + general and has no realtime guarantees. Library Additions ----------------- +- There is a new experimental mark&sweep GC which can be faster (or much + slower) than the default GC. Enable with ``--gc:markAndSweep``. - Added ``system.onRaise`` to support a condition system. - Added ``macros.quote`` for AST quasi-quoting. - Added ``system.unsafeNew`` to support hacky variable length objects. -- There is a new experimental mark&sweep GC which can be faster (or much - slower) than the default GC. Enable with ``--gc:markAndSweep``. - ``system.fields`` and ``system.fieldPairs`` support ``object`` too; they used to only support tuples. @@ -68,6 +68,7 @@ Language Additions dependencies explicitly. - Overloading based on ASTs has been implemented. - Generics are now supported for multi methods. +- Objects can be initialized via an *object constructor expression*. 2012-09-23 Version 0.9.0 released |