Skip to content

Commit

Permalink
Merge pull request #1 from nim-lang/devel
Browse files Browse the repository at this point in the history
updating my fork with the head repo
  • Loading branch information
koranza authored May 18, 2018
2 parents b750082 + 06bdf83 commit 39988eb
Show file tree
Hide file tree
Showing 342 changed files with 9,767 additions and 13,341 deletions.
43 changes: 42 additions & 1 deletion changelog.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
## v0.X.X - XX/XX/2018
## v0.19.X - XX/XX/2018

### Changes affecting backwards compatibility

Expand All @@ -11,6 +11,16 @@
to deal with!
- Indexing into a ``cstring`` for the JS target is now mapped
to ``charCodeAt``.
- Assignments that would "slice" an object into its supertype are now prevented
at runtime. Use ``ref object`` with inheritance rather than ``object`` with
inheritance to prevent this issue.
- The ``not nil`` type annotation now has to be enabled explicitly
via ``{.experimental: "notnil"}`` as we are still not pleased with how this
feature works with Nim's containers.
- The parser now warns about inconsistent spacing around binary operators as
these can easily be confused with unary operators. This warning will likely
become an error in the future.


#### Breaking changes in the standard library

Expand All @@ -27,9 +37,13 @@
- ``proc `-`*(a, b: Time): int64`` in the ``times`` module has changed return type
to ``times.Duration`` in order to support higher time resolutions.
The proc is no longer deprecated.
- ``posix.Timeval.tv_sec`` has changed type to ``posix.Time``.

#### Breaking changes in the compiler

- The undocumented ``#? braces`` parsing mode was removed.
- The undocumented PHP backend was removed.

### Library additions

- ``re.split`` now also supports the ``maxsplit`` parameter for consistency
Expand All @@ -55,6 +69,12 @@
fields.
- ``system.SomeReal`` is now called ``SomeFloat`` for consistency and
correctness.
- ``algorithm.smartBinarySearch`` and ``algorithm.binarySearch`` is
now joined in ``binarySearch``. ``smartbinarySearch`` is now
deprecated.
- The `terminal` module now exports additional procs for generating ANSI color
codes as strings.
- Added the parameter ``val`` for the ``CritBitTree[int].inc`` proc.

### Language additions

Expand All @@ -76,6 +96,21 @@
Imported exceptions can be raised and caught just like Nim exceptions.
More details in language manual.

- ``nil`` for strings/seqs is finally gone. Instead the default value for
these is ``"" / @[]``.

- Accessing the binary zero terminator in Nim's native strings
is now invalid. Internally a Nim string still has the trailing zero for
zero-copy interoperability with ``cstring``. Compile your code with the
new switch ``--laxStrings:on`` if you need a transition period.

- The command syntax now supports keyword arguments after the first comma.

- Thread-local variables can now be declared inside procs. This implies all
the effects of the `global` pragma.

- Nim now supports `except` clause in the export statement.

### Tool changes

- ``jsondoc2`` has been renamed ``jsondoc``, similar to how ``doc2`` was renamed
Expand All @@ -97,4 +132,10 @@
- Added ``macros.getProjectPath`` and ``ospaths.putEnv`` procs to Nim's virtual
machine.

- The ``deadCodeElim`` option is now always turned on and the switch has no
effect anymore, but is recognized for backwards compatibility.

- ``experimental`` is now a pragma / command line switch that can enable specific
language extensions, it is not an all-or-nothing switch anymore.

### Bugfixes
4 changes: 2 additions & 2 deletions compiler/aliases.nim
Original file line number Diff line number Diff line change
Expand Up @@ -34,10 +34,10 @@ proc isPartOfAux(n: PNode, b: PType, marker: var IntSet): TAnalysisResult =
of nkOfBranch, nkElse:
result = isPartOfAux(lastSon(n.sons[i]), b, marker)
if result == arYes: return
else: internalError("isPartOfAux(record case branch)")
else: discard "isPartOfAux(record case branch)"
of nkSym:
result = isPartOfAux(n.sym.typ, b, marker)
else: internalError(n.info, "isPartOfAux()")
else: discard

proc isPartOfAux(a, b: PType, marker: var IntSet): TAnalysisResult =
result = arNo
Expand Down
72 changes: 45 additions & 27 deletions compiler/ast.nim
Original file line number Diff line number Diff line change
Expand Up @@ -262,7 +262,8 @@ type
# variable is a thread variable
sfCompileTime, # proc can be evaluated at compile time
sfConstructor, # proc is a C++ constructor
sfDeadCodeElim, # dead code elimination for the module is turned on
sfDispatcher, # copied method symbol is the dispatcher
# deprecated and unused, except for the con
sfBorrow, # proc is borrowed
sfInfixCall, # symbol needs infix call syntax in target language;
# for interfacing with C++, JS
Expand All @@ -275,10 +276,9 @@ type
TSymFlags* = set[TSymFlag]

const
sfDispatcher* = sfDeadCodeElim # copied method symbol is the dispatcher
sfNoInit* = sfMainModule # don't generate code to init the variable

sfImmediate* = sfDeadCodeElim
sfImmediate* = sfDispatcher
# macro or template is immediately expanded
# without considering any possible overloads
sfAllUntyped* = sfVolatile # macro or template is immediately expanded \
Expand Down Expand Up @@ -734,7 +734,7 @@ type
locOther # location is something other
TLocFlag* = enum
lfIndirect, # backend introduced a pointer
lfFullExternalName, # only used when 'gCmd == cmdPretty': Indicates
lfFullExternalName, # only used when 'conf.cmd == cmdPretty': Indicates
# that the symbol has been imported via 'importc: "fullname"' and
# no format string.
lfNoDeepCopy, # no need for a deep copy
Expand Down Expand Up @@ -1042,9 +1042,9 @@ proc newNode*(kind: TNodeKind): PNode =
new(result)
result.kind = kind
#result.info = UnknownLineInfo() inlined:
result.info.fileIndex = int32(-1)
result.info.fileIndex = InvalidFileIdx
result.info.col = int16(-1)
result.info.line = int16(-1)
result.info.line = uint16(0)
when defined(useNodeIds):
result.id = gNodeId
if result.id == nodeIdToDebug:
Expand Down Expand Up @@ -1078,14 +1078,14 @@ template previouslyInferred*(t: PType): PType =
if t.sons.len > 1: t.lastSon else: nil

proc newSym*(symKind: TSymKind, name: PIdent, owner: PSym,
info: TLineInfo): PSym =
info: TLineInfo; options: TOptions = {}): PSym =
# generates a symbol and initializes the hash field too
new(result)
result.name = name
result.kind = symKind
result.flags = {}
result.info = info
result.options = gOptions
result.options = options
result.owner = owner
result.offset = -1
result.id = getID()
Expand All @@ -1095,7 +1095,7 @@ proc newSym*(symKind: TSymKind, name: PIdent, owner: PSym,
# writeStacktrace()
# MessageOut(name.s & " has id: " & toString(result.id))

var emptyNode* = newNode(nkEmpty)
var emptyNode* = newNode(nkEmpty) # XXX global variable here!
# There is a single empty node that is shared! Do not overwrite it!

proc isMetaType*(t: PType): bool =
Expand All @@ -1116,13 +1116,13 @@ proc linkTo*(s: PSym, t: PType): PSym {.discardable.} =
s.typ = t
result = s

template fileIdx*(c: PSym): int32 =
template fileIdx*(c: PSym): FileIndex =
# XXX: this should be used only on module symbols
c.position.int32
c.position.FileIndex

template filename*(c: PSym): string =
# XXX: this should be used only on module symbols
c.position.int32.toFilename
c.position.FileIndex.toFilename

proc appendToModule*(m: PSym, n: PNode) =
## The compiler will use this internally to add nodes that will be
Expand Down Expand Up @@ -1325,7 +1325,7 @@ proc copyType*(t: PType, owner: PSym, keepId: bool): PType =
proc exactReplica*(t: PType): PType = copyType(t, t.owner, true)

proc copySym*(s: PSym, keepId: bool = false): PSym =
result = newSym(s.kind, s.name, s.owner, s.info)
result = newSym(s.kind, s.name, s.owner, s.info, s.options)
#result.ast = nil # BUGFIX; was: s.ast which made problems
result.typ = s.typ
if keepId:
Expand All @@ -1344,8 +1344,9 @@ proc copySym*(s: PSym, keepId: bool = false): PSym =
if result.kind in {skVar, skLet, skField}:
result.guard = s.guard

proc createModuleAlias*(s: PSym, newIdent: PIdent, info: TLineInfo): PSym =
result = newSym(s.kind, newIdent, s.owner, info)
proc createModuleAlias*(s: PSym, newIdent: PIdent, info: TLineInfo;
options: TOptions): PSym =
result = newSym(s.kind, newIdent, s.owner, info, options)
# keep ID!
result.ast = s.ast
result.id = s.id
Expand Down Expand Up @@ -1564,15 +1565,17 @@ proc getInt*(a: PNode): BiggestInt =
case a.kind
of nkCharLit..nkUInt64Lit: result = a.intVal
else:
internalError(a.info, "getInt")
result = 0
#internalError(a.info, "getInt")
doAssert false, "getInt"
#result = 0

proc getFloat*(a: PNode): BiggestFloat =
case a.kind
of nkFloatLiterals: result = a.floatVal
else:
internalError(a.info, "getFloat")
result = 0.0
doAssert false, "getFloat"
#internalError(a.info, "getFloat")
#result = 0.0

proc getStr*(a: PNode): string =
case a.kind
Expand All @@ -1581,16 +1584,18 @@ proc getStr*(a: PNode): string =
# let's hope this fixes more problems than it creates:
result = nil
else:
internalError(a.info, "getStr")
result = ""
doAssert false, "getStr"
#internalError(a.info, "getStr")
#result = ""

proc getStrOrChar*(a: PNode): string =
case a.kind
of nkStrLit..nkTripleStrLit: result = a.strVal
of nkCharLit..nkUInt64Lit: result = $chr(int(a.intVal))
else:
internalError(a.info, "getStrOrChar")
result = ""
doAssert false, "getStrOrChar"
#internalError(a.info, "getStrOrChar")
#result = ""

proc isGenericRoutine*(s: PSym): bool =
case s.kind
Expand All @@ -1615,14 +1620,27 @@ proc originatingModule*(s: PSym): PSym =
proc isRoutine*(s: PSym): bool {.inline.} =
result = s.kind in skProcKinds

proc isCompileTimeProc*(s: PSym): bool {.inline.} =
result = s.kind == skMacro or
s.kind == skProc and sfCompileTime in s.flags

proc requiredParams*(s: PSym): int =
# Returns the number of required params (without default values)
# XXX: Perhaps we can store this in the `offset` field of the
# symbol instead?
for i in 1 ..< s.typ.len:
if s.typ.n[i].sym.ast != nil:
return i - 1
return s.typ.len - 1

proc hasPattern*(s: PSym): bool {.inline.} =
result = isRoutine(s) and s.ast.sons[patternPos].kind != nkEmpty

iterator items*(n: PNode): PNode =
for i in 0..<n.safeLen: yield n.sons[i]

iterator pairs*(n: PNode): tuple[i: int, n: PNode] =
for i in 0..<n.len: yield (i, n.sons[i])
for i in 0..<n.safeLen: yield (i, n.sons[i])

proc isAtom*(n: PNode): bool {.inline.} =
result = n.kind >= nkNone and n.kind <= nkNilLit
Expand Down Expand Up @@ -1671,14 +1689,14 @@ proc isException*(t: PType): bool =

var base = t
while base != nil:
if base.sym.magic == mException:
if base.sym != nil and base.sym.magic == mException:
return true
base = base.lastSon
return false

proc isImportedException*(t: PType): bool =
proc isImportedException*(t: PType; conf: ConfigRef): bool =
assert(t != nil)
if optNoCppExceptions in gGlobalOptions:
if optNoCppExceptions in conf.globalOptions:
return false

let base = t.skipTypes({tyAlias, tyPtr, tyDistinct, tyGenericInst})
Expand Down
24 changes: 12 additions & 12 deletions compiler/astalgo.nim
Original file line number Diff line number Diff line change
Expand Up @@ -69,22 +69,22 @@ proc debug*(n: PNode) {.deprecated.}

template mdbg*: bool {.dirty.} =
when compiles(c.module):
c.module.fileIdx == gProjectMainIdx
c.module.fileIdx.int32 == gProjectMainIdx
elif compiles(c.c.module):
c.c.module.fileIdx == gProjectMainIdx
c.c.module.fileIdx.int32 == gProjectMainIdx
elif compiles(m.c.module):
m.c.module.fileIdx == gProjectMainIdx
m.c.module.fileIdx.int32 == gProjectMainIdx
elif compiles(cl.c.module):
cl.c.module.fileIdx == gProjectMainIdx
cl.c.module.fileIdx.int32 == gProjectMainIdx
elif compiles(p):
when compiles(p.lex):
p.lex.fileIdx == gProjectMainIdx
p.lex.fileIdx.int32 == gProjectMainIdx
else:
p.module.module.fileIdx == gProjectMainIdx
p.module.module.fileIdx.int32 == gProjectMainIdx
elif compiles(m.module.fileIdx):
m.module.fileIdx == gProjectMainIdx
m.module.fileIdx.int32 == gProjectMainIdx
elif compiles(L.fileIdx):
L.fileIdx == gProjectMainIdx
L.fileIdx.int32 == gProjectMainIdx
else:
error()

Expand Down Expand Up @@ -180,18 +180,18 @@ proc lookupInRecord(n: PNode, field: PIdent): PSym =
result = lookupInRecord(n.sons[i], field)
if result != nil: return
of nkRecCase:
if (n.sons[0].kind != nkSym): internalError(n.info, "lookupInRecord")
if (n.sons[0].kind != nkSym): return nil
result = lookupInRecord(n.sons[0], field)
if result != nil: return
for i in countup(1, sonsLen(n) - 1):
case n.sons[i].kind
of nkOfBranch, nkElse:
result = lookupInRecord(lastSon(n.sons[i]), field)
if result != nil: return
else: internalError(n.info, "lookupInRecord(record case branch)")
else: return nil
of nkSym:
if n.sym.name.id == field.id: result = n.sym
else: internalError(n.info, "lookupInRecord()")
else: return nil

proc getModule(s: PSym): PSym =
result = s
Expand All @@ -203,7 +203,7 @@ proc getSymFromList(list: PNode, ident: PIdent, start: int = 0): PSym =
if list.sons[i].kind == nkSym:
result = list.sons[i].sym
if result.name.id == ident.id: return
else: internalError(list.info, "getSymFromList")
else: return nil
result = nil

proc hashNode(p: RootRef): Hash =
Expand Down
Loading

0 comments on commit 39988eb

Please sign in to comment.