documented object constrs; endb works again

This commit is contained in:
Araq
2013-03-09 20:43:56 +01:00
parent 2b4922aea0
commit a64d4dc35c
11 changed files with 152 additions and 143 deletions

View File

@@ -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:

View File

@@ -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 =

View File

@@ -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)

View File

@@ -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

View File

@@ -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

View File

@@ -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)))

17
examples/debugging.nim Normal file
View File

@@ -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()

View File

@@ -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;

View File

@@ -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

View File

@@ -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

View File

@@ -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