fixed merge conflict
This commit is contained in:
commit
c8e33cbb75
19 changed files with 303 additions and 119 deletions
|
|
@ -4,6 +4,8 @@ language: c
|
||||||
dist: xenial
|
dist: xenial
|
||||||
|
|
||||||
matrix:
|
matrix:
|
||||||
|
fast_finish: true
|
||||||
|
|
||||||
include:
|
include:
|
||||||
- os: linux
|
- os: linux
|
||||||
env: NIM_COMPILE_TO_CPP=false
|
env: NIM_COMPILE_TO_CPP=false
|
||||||
|
|
|
||||||
14
appveyor.yml
14
appveyor.yml
|
|
@ -1,14 +1,11 @@
|
||||||
version: '{build}'
|
version: '{build}'
|
||||||
|
|
||||||
cache:
|
|
||||||
- x86_64-4.9.2-release-win32-seh-rt_v4-rev4.7z
|
|
||||||
- sqlite-dll-win64-x64-3160200.zip
|
|
||||||
# - i686-4.9.2-release-win32-dwarf-rt_v4-rev4.7z
|
|
||||||
|
|
||||||
environment:
|
environment:
|
||||||
MINGW_DIR: mingw64
|
MINGW_DIR: mingw64
|
||||||
MINGW_URL: https://sourceforge.net/projects/mingw-w64/files/Toolchains%20targetting%20Win64/Personal%20Builds/mingw-builds/4.9.2/threads-win32/seh/x86_64-4.9.2-release-win32-seh-rt_v4-rev4.7z/download
|
MINGW_URL: https://sourceforge.net/projects/mingw-w64/files/Toolchains%20targetting%20Win64/Personal%20Builds/mingw-builds/4.9.2/threads-win32/seh/x86_64-4.9.2-release-win32-seh-rt_v4-rev4.7z/download
|
||||||
MINGW_ARCHIVE: x86_64-4.9.2-release-win32-seh-rt_v4-rev4.7z
|
MINGW_ARCHIVE: x86_64-4.9.2-release-win32-seh-rt_v4-rev4.7z
|
||||||
|
OPENBLAS_URL: https://sourceforge.net/projects/openblas/files/v0.3.5/OpenBLAS%200.3.5%20version.zip/download
|
||||||
|
OPENBLAS_ARCHIVE: OpenBLAS-0.3.5.zip
|
||||||
SQLITE_URL: http://www.sqlite.org/2017/sqlite-dll-win64-x64-3160200.zip
|
SQLITE_URL: http://www.sqlite.org/2017/sqlite-dll-win64-x64-3160200.zip
|
||||||
SQLITE_ARCHIVE: sqlite-dll-win64-x64-3160200.zip
|
SQLITE_ARCHIVE: sqlite-dll-win64-x64-3160200.zip
|
||||||
platform: x64
|
platform: x64
|
||||||
|
|
@ -17,6 +14,11 @@ environment:
|
||||||
- NIM_TEST_PACKAGES: true
|
- NIM_TEST_PACKAGES: true
|
||||||
- NIM_TEST_PACKAGES: false
|
- NIM_TEST_PACKAGES: false
|
||||||
|
|
||||||
|
cache:
|
||||||
|
- '%MINGW_ARCHIVE%'
|
||||||
|
- '%SQLITE_ARCHIVE%'
|
||||||
|
- '%OPENBLAS_ARCHIVE%'
|
||||||
|
|
||||||
matrix:
|
matrix:
|
||||||
#allow_failures:
|
#allow_failures:
|
||||||
# - NIM_TEST_PACKAGES: true
|
# - NIM_TEST_PACKAGES: true
|
||||||
|
|
@ -31,6 +33,8 @@ install:
|
||||||
- 7z x -y "%SQLITE_ARCHIVE%" -o"%CD%\DIST"> nul
|
- 7z x -y "%SQLITE_ARCHIVE%" -o"%CD%\DIST"> nul
|
||||||
- IF not exist "%MINGW_ARCHIVE%" appveyor DownloadFile "%MINGW_URL%" -FileName "%MINGW_ARCHIVE%"
|
- IF not exist "%MINGW_ARCHIVE%" appveyor DownloadFile "%MINGW_URL%" -FileName "%MINGW_ARCHIVE%"
|
||||||
- 7z x -y "%MINGW_ARCHIVE%" -o"%CD%\DIST"> nul
|
- 7z x -y "%MINGW_ARCHIVE%" -o"%CD%\DIST"> nul
|
||||||
|
- IF not exist "%OPENBLAS_ARCHIVE%" appveyor DownloadFile "%OPENBLAS_URL%" -FileName "%OPENBLAS_ARCHIVE%"
|
||||||
|
- 7z x -y "%OPENBLAS_ARCHIVE%" -o"%CD%\DIST"> nul
|
||||||
- SET PATH=%CD%\DIST\%MINGW_DIR%\BIN;%CD%\BIN;%PATH%
|
- SET PATH=%CD%\DIST\%MINGW_DIR%\BIN;%CD%\BIN;%PATH%
|
||||||
- IF "%PLATFORM%" == "x64" ( copy C:\OpenSSL-Win64\libeay32.dll %CD%\BIN\libeay64.dll & copy C:\OpenSSL-Win64\libeay32.dll %CD%\BIN\libeay32.dll & copy C:\OpenSSL-Win64\libssl32.dll %CD%\BIN\libssl64.dll & copy C:\OpenSSL-Win64\libssl32.dll %CD%\BIN\libssl32.dll )
|
- IF "%PLATFORM%" == "x64" ( copy C:\OpenSSL-Win64\libeay32.dll %CD%\BIN\libeay64.dll & copy C:\OpenSSL-Win64\libeay32.dll %CD%\BIN\libeay32.dll & copy C:\OpenSSL-Win64\libssl32.dll %CD%\BIN\libssl64.dll & copy C:\OpenSSL-Win64\libssl32.dll %CD%\BIN\libssl32.dll )
|
||||||
ELSE ( copy C:\OpenSSL-Win32\libeay32.dll %CD%\BIN\libeay32.dll & copy C:\OpenSSL-Win32\libssl32.dll %CD%\BIN\libssl32.dll )
|
ELSE ( copy C:\OpenSSL-Win32\libeay32.dll %CD%\BIN\libeay32.dll & copy C:\OpenSSL-Win32\libssl32.dll %CD%\BIN\libssl32.dll )
|
||||||
|
|
|
||||||
|
|
@ -1149,7 +1149,7 @@ template isIndirect(x: PSym): bool =
|
||||||
let v = x
|
let v = x
|
||||||
({sfAddrTaken, sfGlobal} * v.flags != {} and
|
({sfAddrTaken, sfGlobal} * v.flags != {} and
|
||||||
#(mapType(v.typ) != etyObject) and
|
#(mapType(v.typ) != etyObject) and
|
||||||
{sfImportc, sfVolatile, sfExportc} * v.flags == {} and
|
{sfImportc, sfExportc} * v.flags == {} and
|
||||||
v.kind notin {skProc, skFunc, skConverter, skMethod, skIterator,
|
v.kind notin {skProc, skFunc, skConverter, skMethod, skIterator,
|
||||||
skConst, skTemp, skLet})
|
skConst, skTemp, skLet})
|
||||||
|
|
||||||
|
|
@ -1597,8 +1597,7 @@ proc createVar(p: PProc, typ: PType, indirect: bool): Rope =
|
||||||
internalError(p.config, "createVar: " & $t.kind)
|
internalError(p.config, "createVar: " & $t.kind)
|
||||||
result = nil
|
result = nil
|
||||||
|
|
||||||
template returnType: untyped =
|
template returnType: untyped = ~""
|
||||||
~""
|
|
||||||
|
|
||||||
proc genVarInit(p: PProc, v: PSym, n: PNode) =
|
proc genVarInit(p: PProc, v: PSym, n: PNode) =
|
||||||
var
|
var
|
||||||
|
|
|
||||||
|
|
@ -241,7 +241,7 @@ proc pragmaNoForward(c: PContext, n: PNode; flag=sfNoForward) =
|
||||||
|
|
||||||
# deprecated as of 0.18.1
|
# deprecated as of 0.18.1
|
||||||
message(c.config, n.info, warnDeprecated,
|
message(c.config, n.info, warnDeprecated,
|
||||||
"use {.experimental: \"codeReordering.\".} instead; " &
|
"use {.experimental: \"codeReordering\".} instead; " &
|
||||||
(if flag == sfNoForward: "{.noForward.}" else: "{.reorder.}") & " is deprecated")
|
(if flag == sfNoForward: "{.noForward.}" else: "{.reorder.}") & " is deprecated")
|
||||||
|
|
||||||
proc processCallConv(c: PContext, n: PNode) =
|
proc processCallConv(c: PContext, n: PNode) =
|
||||||
|
|
|
||||||
|
|
@ -212,7 +212,7 @@ proc mergeSections(conf: ConfigRef; comps: seq[seq[DepN]], res: PNode) =
|
||||||
# Problematic circular dependency, we arrange the nodes into
|
# Problematic circular dependency, we arrange the nodes into
|
||||||
# their original relative order and make sure to re-merge
|
# their original relative order and make sure to re-merge
|
||||||
# consecutive type and const sections
|
# consecutive type and const sections
|
||||||
var wmsg = "Circular dependency detected. reorder pragma may not be able to" &
|
var wmsg = "Circular dependency detected. `codeReordering` pragma may not be able to" &
|
||||||
" reorder some nodes properely"
|
" reorder some nodes properely"
|
||||||
when defined(debugReorder):
|
when defined(debugReorder):
|
||||||
wmsg &= ":\n"
|
wmsg &= ":\n"
|
||||||
|
|
|
||||||
|
|
@ -77,7 +77,20 @@ $content
|
||||||
doc.body_toc = """
|
doc.body_toc = """
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="three columns">
|
<div class="three columns">
|
||||||
<div>
|
<div id="global-links">
|
||||||
|
<ul class="simple-boot">
|
||||||
|
<li>
|
||||||
|
<a href="manual.html">Manual</a>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<a href="lib.html">Standard library</a>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<a href="theindex.html">Index</a>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
<div id="searchInputDiv">
|
||||||
Search: <input type="text" id="searchInput"
|
Search: <input type="text" id="searchInput"
|
||||||
onkeyup="search()" />
|
onkeyup="search()" />
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
116
doc/tut1.rst
116
doc/tut1.rst
|
|
@ -1441,31 +1441,111 @@ string that is "useless" and replace it with "useful".
|
||||||
Note: alternate ways of writing this are ``b[^8..^2] = "useful"`` or
|
Note: alternate ways of writing this are ``b[^8..^2] = "useful"`` or
|
||||||
as ``b[11..b.len-2] = "useful"`` or as ``b[11..<b.len-1] = "useful"``.
|
as ``b[11..b.len-2] = "useful"`` or as ``b[11..<b.len-1] = "useful"``.
|
||||||
|
|
||||||
Tuples
|
Objects
|
||||||
------
|
-------
|
||||||
|
|
||||||
A tuple type defines various named *fields* and an *order* of the fields.
|
The default type to pack different values together in a single
|
||||||
The constructor ``()`` can be used to construct tuples. The order of the
|
structure with a name is the object type. An object is a value type,
|
||||||
fields in the constructor must match the order in the tuple's definition.
|
which means that when an object is assigned to a new variable all its
|
||||||
Different tuple-types are *equivalent* if they specify fields of
|
components are copied as well.
|
||||||
the same type and of the same name in the same order.
|
|
||||||
|
|
||||||
The assignment operator for tuples copies each component. The notation
|
Each object type ``Foo`` has a constructor ``Foo(field: value, ...)``
|
||||||
``t.field`` is used to access a tuple's field. Another notation is
|
where all of its fields can be initialized. Unspecified fields will
|
||||||
``t[i]`` to access the ``i``'th field. Here ``i`` must be a constant
|
get their default value.
|
||||||
integer.
|
|
||||||
|
.. code-block:: nim
|
||||||
|
type
|
||||||
|
Person = object
|
||||||
|
name: string
|
||||||
|
age: int
|
||||||
|
|
||||||
|
var person1 = Person(name: "Peter", age: 30)
|
||||||
|
|
||||||
|
echo person1.name # "Peter"
|
||||||
|
echo person1.age # 30
|
||||||
|
|
||||||
|
var person2 = person1 # copy of person 1
|
||||||
|
|
||||||
|
person2.age += 14
|
||||||
|
|
||||||
|
echo person1.age # 30
|
||||||
|
echo person2.age # 44
|
||||||
|
|
||||||
|
|
||||||
|
# the order may be changed
|
||||||
|
let person3 = Person(age: 12, name: "Quentin")
|
||||||
|
|
||||||
|
# not every member needs to be specified
|
||||||
|
let person4 = Person(age: 3)
|
||||||
|
# unspecified members will be initialized with their default
|
||||||
|
# values. In this case it is the empty string.
|
||||||
|
doAssert person4.name == ""
|
||||||
|
|
||||||
|
|
||||||
|
Object fields that should be visible from outside the defining module have to
|
||||||
|
be marked with ``*``.
|
||||||
|
|
||||||
.. code-block:: nim
|
.. code-block:: nim
|
||||||
:test: "nim c $1"
|
:test: "nim c $1"
|
||||||
|
|
||||||
type
|
type
|
||||||
Person = tuple[name: string, age: int] # type representing a person:
|
Person* = object # the type is visible from other modules
|
||||||
# a person consists of a name
|
name*: string # the field of this type is visible from other modules
|
||||||
# and an age
|
age*: int
|
||||||
|
|
||||||
|
Tuples
|
||||||
|
------
|
||||||
|
|
||||||
|
Tuples are very much like what you have seen so far from objects. They
|
||||||
|
are value types where the assignment operator copies each component.
|
||||||
|
Unlike object types though, tuple types are structurally typed,
|
||||||
|
meaning different tuple-types are *equivalent* if they specify fields of
|
||||||
|
the same type and of the same name in the same order.
|
||||||
|
|
||||||
|
The constructor ``()`` can be used to construct tuples. The order of the
|
||||||
|
fields in the constructor must match the order in the tuple's
|
||||||
|
definition. But unlike objects, a name for the tuple type may not be
|
||||||
|
used here.
|
||||||
|
|
||||||
|
|
||||||
|
Like the object type the notation ``t.field`` is used to access a
|
||||||
|
tuple's field. Another notation that is not available for objects is
|
||||||
|
``t[i]`` to access the ``i``'th field. Here ``i`` must be a constant
|
||||||
|
integer.
|
||||||
|
|
||||||
|
.. code-block:: nim
|
||||||
|
:test: "nim c $1"
|
||||||
|
type
|
||||||
|
# type representing a person:
|
||||||
|
# A person consists of a name and an age.
|
||||||
|
Person = tuple
|
||||||
|
name: string
|
||||||
|
age: int
|
||||||
|
|
||||||
|
# Alternative syntax for an equivalent type.
|
||||||
|
PersonX = tuple[name: string, age: int]
|
||||||
|
|
||||||
|
# anonymous field syntax
|
||||||
|
PersonY = (string, int)
|
||||||
|
|
||||||
var
|
var
|
||||||
person: Person
|
person: Person
|
||||||
|
personX: PersonX
|
||||||
|
personY: PersonY
|
||||||
|
|
||||||
person = (name: "Peter", age: 30)
|
person = (name: "Peter", age: 30)
|
||||||
# the same, but less readable:
|
# Person and PersonX are equivalent
|
||||||
|
personX = person
|
||||||
|
|
||||||
|
# Create a tuple with anonymous fields:
|
||||||
|
personY = ("Peter", 30)
|
||||||
|
|
||||||
|
# A tuple with anonymous fields is compatible with a tuple that has
|
||||||
|
# field names.
|
||||||
|
person = personY
|
||||||
|
personY = person
|
||||||
|
|
||||||
|
# Usually used for short tuple initialization syntax
|
||||||
person = ("Peter", 30)
|
person = ("Peter", 30)
|
||||||
|
|
||||||
echo person.name # "Peter"
|
echo person.name # "Peter"
|
||||||
|
|
@ -1484,10 +1564,6 @@ integer.
|
||||||
# --> Error: type mismatch: got (tuple[street: string, number: int])
|
# --> Error: type mismatch: got (tuple[street: string, number: int])
|
||||||
# but expected 'Person'
|
# but expected 'Person'
|
||||||
|
|
||||||
# The following works because the field names and types are the same.
|
|
||||||
var teacher: tuple[name: string, age: int] = ("Mark", 42)
|
|
||||||
person = teacher
|
|
||||||
|
|
||||||
Even though you don't need to declare a type for a tuple to use it, tuples
|
Even though you don't need to declare a type for a tuple to use it, tuples
|
||||||
created with different field names will be considered different objects despite
|
created with different field names will be considered different objects despite
|
||||||
having the same field types.
|
having the same field types.
|
||||||
|
|
@ -1519,6 +1595,8 @@ variables! For example:
|
||||||
echo badname
|
echo badname
|
||||||
echo badext
|
echo badext
|
||||||
|
|
||||||
|
Fields of tuples are always public, they don't need to be explicity
|
||||||
|
marked to be exported, unlike for example fields in an object type.
|
||||||
|
|
||||||
Reference and pointer types
|
Reference and pointer types
|
||||||
---------------------------
|
---------------------------
|
||||||
|
|
|
||||||
25
doc/tut2.rst
25
doc/tut2.rst
|
|
@ -40,18 +40,16 @@ and more efficient code. In particular, preferring composition over inheritance
|
||||||
is often the better design.
|
is often the better design.
|
||||||
|
|
||||||
|
|
||||||
Objects
|
Inheritance
|
||||||
-------
|
-----------
|
||||||
|
|
||||||
Like tuples, objects are a means to pack different values together in a
|
Inheritance in Nim is entirely optional. To enable inheritance with
|
||||||
structured way. However, objects provide many features that tuples do not:
|
runtime type information the object needs to inherit from
|
||||||
They provide inheritance and information hiding. Because objects encapsulate
|
``RootObj``. This can be done directly, or indirectly by
|
||||||
data, the ``T()`` object constructor should only be used internally and the
|
inheriting from an object that inherits from ``RootObj``. Usually
|
||||||
programmer should provide a proc to initialize the object (this is called
|
types with inheritance are also marked as ``ref`` types even though
|
||||||
a *constructor*).
|
this isn't strictly enforced. To check at runtime if an object is of a certain
|
||||||
|
type, the ``of`` operator can be used.
|
||||||
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:: nim
|
.. code-block:: nim
|
||||||
:test: "nim c $1"
|
:test: "nim c $1"
|
||||||
|
|
@ -71,11 +69,6 @@ Objects have access to their type at runtime. There is an
|
||||||
student = Student(name: "Anton", age: 5, id: 2)
|
student = Student(name: "Anton", age: 5, id: 2)
|
||||||
echo student[]
|
echo student[]
|
||||||
|
|
||||||
Object fields that should be visible from outside the defining module have to
|
|
||||||
be marked by ``*``. In contrast to tuples, different object types are
|
|
||||||
never *equivalent*. New object types can only be defined within a type
|
|
||||||
section.
|
|
||||||
|
|
||||||
Inheritance is done with the ``object of`` syntax. Multiple inheritance is
|
Inheritance is done with the ``object of`` syntax. Multiple inheritance is
|
||||||
currently not supported. If an object type has no suitable ancestor, ``RootObj``
|
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
|
can be used as its ancestor, but this is only a convention. Objects that have
|
||||||
|
|
|
||||||
|
|
@ -192,7 +192,7 @@ type
|
||||||
|
|
||||||
Element* = ref ElementObj
|
Element* = ref ElementObj
|
||||||
ElementObj {.importc.} = object of NodeObj
|
ElementObj {.importc.} = object of NodeObj
|
||||||
classList*: Classlist
|
classList*: ClassList
|
||||||
checked*: bool
|
checked*: bool
|
||||||
defaultChecked*: bool
|
defaultChecked*: bool
|
||||||
defaultValue*: cstring
|
defaultValue*: cstring
|
||||||
|
|
@ -1183,9 +1183,10 @@ proc contains*(c: ClassList, class: cstring): bool
|
||||||
proc toggle*(c: ClassList, class: cstring)
|
proc toggle*(c: ClassList, class: cstring)
|
||||||
|
|
||||||
# Style "methods"
|
# Style "methods"
|
||||||
proc getAttribute*(s: Style, attr: cstring, caseSensitive=false): cstring
|
proc getPropertyValue*(s: Style, property: cstring): cstring
|
||||||
proc removeAttribute*(s: Style, attr: cstring, caseSensitive=false)
|
proc removeProperty*(s: Style, property: cstring)
|
||||||
proc setAttribute*(s: Style, attr, value: cstring, caseSensitive=false)
|
proc setProperty*(s: Style, property, value: cstring, priority = "")
|
||||||
|
proc getPropertyPriority*(s: Style, property: cstring): cstring
|
||||||
|
|
||||||
# Event "methods"
|
# Event "methods"
|
||||||
proc preventDefault*(ev: Event)
|
proc preventDefault*(ev: Event)
|
||||||
|
|
@ -1267,6 +1268,10 @@ proc inViewport*(el: Node): bool =
|
||||||
rect.right <= clientWidth().float
|
rect.right <= clientWidth().float
|
||||||
|
|
||||||
proc scrollTop*(e: Node): int {.importcpp: "#.scrollTop", nodecl.}
|
proc scrollTop*(e: Node): int {.importcpp: "#.scrollTop", nodecl.}
|
||||||
|
proc scrollLeft*(e: Node): int {.importcpp: "#.scrollLeft", nodecl.}
|
||||||
|
proc scrollHeight*(e: Node): int {.importcpp: "#.scrollHeight", nodecl.}
|
||||||
|
proc scrollWidth*(e: Node): int {.importcpp: "#.scrollWidth", nodecl.}
|
||||||
proc offsetHeight*(e: Node): int {.importcpp: "#.offsetHeight", nodecl.}
|
proc offsetHeight*(e: Node): int {.importcpp: "#.offsetHeight", nodecl.}
|
||||||
|
proc offsetWidth*(e: Node): int {.importcpp: "#.offsetWidth", nodecl.}
|
||||||
proc offsetTop*(e: Node): int {.importcpp: "#.offsetTop", nodecl.}
|
proc offsetTop*(e: Node): int {.importcpp: "#.offsetTop", nodecl.}
|
||||||
proc offsetLeft*(e: Node): int {.importcpp: "#.offsetLeft", nodecl.}
|
proc offsetLeft*(e: Node): int {.importcpp: "#.offsetLeft", nodecl.}
|
||||||
|
|
|
||||||
|
|
@ -511,7 +511,7 @@ func isSorted*[T](a: openArray[T],
|
||||||
order = SortOrder.Ascending): bool =
|
order = SortOrder.Ascending): bool =
|
||||||
## Checks to see whether ``a`` is already sorted in ``order``
|
## Checks to see whether ``a`` is already sorted in ``order``
|
||||||
## using ``cmp`` for the comparison. Parameters identical
|
## using ``cmp`` for the comparison. Parameters identical
|
||||||
## to ``sort``.
|
## to ``sort``. Requires O(n) time.
|
||||||
##
|
##
|
||||||
## **See also:**
|
## **See also:**
|
||||||
## * `isSorted proc<#isSorted,openArray[T]>`_
|
## * `isSorted proc<#isSorted,openArray[T]>`_
|
||||||
|
|
|
||||||
|
|
@ -166,6 +166,18 @@ proc newAsyncSocket*(domain: Domain = AF_INET, sockType: SockType = SOCK_STREAM,
|
||||||
raiseOSError(osLastError())
|
raiseOSError(osLastError())
|
||||||
result = newAsyncSocket(fd, domain, sockType, protocol, buffered)
|
result = newAsyncSocket(fd, domain, sockType, protocol, buffered)
|
||||||
|
|
||||||
|
proc getLocalAddr*(socket: AsyncSocket): (string, Port) =
|
||||||
|
## Get the socket's local address and port number.
|
||||||
|
##
|
||||||
|
## This is high-level interface for `getsockname`:idx:.
|
||||||
|
getLocalAddr(socket.fd, socket.domain)
|
||||||
|
|
||||||
|
proc getPeerAddr*(socket: AsyncSocket): (string, Port) =
|
||||||
|
## Get the socket's peer address and port number.
|
||||||
|
##
|
||||||
|
## This is high-level interface for `getpeername`:idx:.
|
||||||
|
getPeerAddr(socket.fd, socket.domain)
|
||||||
|
|
||||||
proc newAsyncSocket*(domain, sockType, protocol: cint,
|
proc newAsyncSocket*(domain, sockType, protocol: cint,
|
||||||
buffered = true): AsyncSocket =
|
buffered = true): AsyncSocket =
|
||||||
## Creates a new asynchronous socket.
|
## Creates a new asynchronous socket.
|
||||||
|
|
|
||||||
|
|
@ -1906,6 +1906,7 @@ func getExt*(mimedb: MimeDB, mimetype: string, default = "txt"): string =
|
||||||
for e, m in mimedb.mimes:
|
for e, m in mimedb.mimes:
|
||||||
if m == mimeLowered:
|
if m == mimeLowered:
|
||||||
result = e
|
result = e
|
||||||
|
break
|
||||||
|
|
||||||
func register*(mimedb: var MimeDB, ext: string, mimetype: string) =
|
func register*(mimedb: var MimeDB, ext: string, mimetype: string) =
|
||||||
## Adds ``mimetype`` to the ``mimedb``.
|
## Adds ``mimetype`` to the ``mimedb``.
|
||||||
|
|
|
||||||
|
|
@ -224,7 +224,7 @@ proc execProcesses*(cmds: openArray[string],
|
||||||
beforeRunEvent: proc(idx: int) = nil,
|
beforeRunEvent: proc(idx: int) = nil,
|
||||||
afterRunEvent: proc(idx: int, p: Process) = nil): int
|
afterRunEvent: proc(idx: int, p: Process) = nil): int
|
||||||
{.rtl, extern: "nosp$1",
|
{.rtl, extern: "nosp$1",
|
||||||
tags: [ExecIOEffect, TimeEffect, ReadEnvEffect, RootEffect]} =
|
tags: [ExecIOEffect, TimeEffect, ReadEnvEffect, RootEffect].} =
|
||||||
## executes the commands `cmds` in parallel. Creates `n` processes
|
## executes the commands `cmds` in parallel. Creates `n` processes
|
||||||
## that execute in parallel. The highest (absolute) return value of all processes
|
## that execute in parallel. The highest (absolute) return value of all processes
|
||||||
## is returned. Runs `beforeRunEvent` before running each command.
|
## is returned. Runs `beforeRunEvent` before running each command.
|
||||||
|
|
|
||||||
|
|
@ -904,37 +904,51 @@ proc chr*(u: range[0..255]): char {.magic: "Chr", noSideEffect.}
|
||||||
# built-in operators
|
# built-in operators
|
||||||
|
|
||||||
when not defined(JS):
|
when not defined(JS):
|
||||||
proc ze*(x: int8): int {.magic: "Ze8ToI", noSideEffect.}
|
proc ze*(x: int8): int {.magic: "Ze8ToI", noSideEffect, deprecated.}
|
||||||
## zero extends a smaller integer type to ``int``. This treats `x` as
|
## zero extends a smaller integer type to ``int``. This treats `x` as
|
||||||
## unsigned.
|
## unsigned.
|
||||||
proc ze*(x: int16): int {.magic: "Ze16ToI", noSideEffect.}
|
## **Deprecated since version 0.19.9**: Use unsigned integers instead.
|
||||||
|
|
||||||
|
proc ze*(x: int16): int {.magic: "Ze16ToI", noSideEffect, deprecated.}
|
||||||
## zero extends a smaller integer type to ``int``. This treats `x` as
|
## zero extends a smaller integer type to ``int``. This treats `x` as
|
||||||
## unsigned.
|
## unsigned.
|
||||||
|
## **Deprecated since version 0.19.9**: Use unsigned integers instead.
|
||||||
|
|
||||||
proc ze64*(x: int8): int64 {.magic: "Ze8ToI64", noSideEffect.}
|
proc ze64*(x: int8): int64 {.magic: "Ze8ToI64", noSideEffect, deprecated.}
|
||||||
## zero extends a smaller integer type to ``int64``. This treats `x` as
|
|
||||||
## unsigned.
|
|
||||||
proc ze64*(x: int16): int64 {.magic: "Ze16ToI64", noSideEffect.}
|
|
||||||
## zero extends a smaller integer type to ``int64``. This treats `x` as
|
## zero extends a smaller integer type to ``int64``. This treats `x` as
|
||||||
## unsigned.
|
## unsigned.
|
||||||
|
## **Deprecated since version 0.19.9**: Use unsigned integers instead.
|
||||||
|
|
||||||
proc ze64*(x: int32): int64 {.magic: "Ze32ToI64", noSideEffect.}
|
proc ze64*(x: int16): int64 {.magic: "Ze16ToI64", noSideEffect, deprecated.}
|
||||||
## zero extends a smaller integer type to ``int64``. This treats `x` as
|
## zero extends a smaller integer type to ``int64``. This treats `x` as
|
||||||
## unsigned.
|
## unsigned.
|
||||||
proc ze64*(x: int): int64 {.magic: "ZeIToI64", noSideEffect.}
|
## **Deprecated since version 0.19.9**: Use unsigned integers instead.
|
||||||
|
|
||||||
|
proc ze64*(x: int32): int64 {.magic: "Ze32ToI64", noSideEffect, deprecated.}
|
||||||
|
## zero extends a smaller integer type to ``int64``. This treats `x` as
|
||||||
|
## unsigned.
|
||||||
|
## **Deprecated since version 0.19.9**: Use unsigned integers instead.
|
||||||
|
|
||||||
|
proc ze64*(x: int): int64 {.magic: "ZeIToI64", noSideEffect, deprecated.}
|
||||||
## zero extends a smaller integer type to ``int64``. This treats `x` as
|
## zero extends a smaller integer type to ``int64``. This treats `x` as
|
||||||
## unsigned. Does nothing if the size of an ``int`` is the same as ``int64``.
|
## unsigned. Does nothing if the size of an ``int`` is the same as ``int64``.
|
||||||
## (This is the case on 64 bit processors.)
|
## (This is the case on 64 bit processors.)
|
||||||
|
## **Deprecated since version 0.19.9**: Use unsigned integers instead.
|
||||||
|
|
||||||
proc toU8*(x: int): int8 {.magic: "ToU8", noSideEffect.}
|
proc toU8*(x: int): int8 {.magic: "ToU8", noSideEffect, deprecated.}
|
||||||
## treats `x` as unsigned and converts it to a byte by taking the last 8 bits
|
## treats `x` as unsigned and converts it to a byte by taking the last 8 bits
|
||||||
## from `x`.
|
## from `x`.
|
||||||
proc toU16*(x: int): int16 {.magic: "ToU16", noSideEffect.}
|
## **Deprecated since version 0.19.9**: Use unsigned integers instead.
|
||||||
|
|
||||||
|
proc toU16*(x: int): int16 {.magic: "ToU16", noSideEffect, deprecated.}
|
||||||
## treats `x` as unsigned and converts it to an ``int16`` by taking the last
|
## treats `x` as unsigned and converts it to an ``int16`` by taking the last
|
||||||
## 16 bits from `x`.
|
## 16 bits from `x`.
|
||||||
proc toU32*(x: int64): int32 {.magic: "ToU32", noSideEffect.}
|
## **Deprecated since version 0.19.9**: Use unsigned integers instead.
|
||||||
|
|
||||||
|
proc toU32*(x: int64): int32 {.magic: "ToU32", noSideEffect, deprecated.}
|
||||||
## treats `x` as unsigned and converts it to an ``int32`` by taking the
|
## treats `x` as unsigned and converts it to an ``int32`` by taking the
|
||||||
## last 32 bits from `x`.
|
## last 32 bits from `x`.
|
||||||
|
## **Deprecated since version 0.19.9**: Use unsigned integers instead.
|
||||||
|
|
||||||
# integer calculations:
|
# integer calculations:
|
||||||
proc `+`*(x: int): int {.magic: "UnaryPlusI", noSideEffect.}
|
proc `+`*(x: int): int {.magic: "UnaryPlusI", noSideEffect.}
|
||||||
|
|
@ -3877,7 +3891,7 @@ when false:
|
||||||
macro payload: typed {.gensym.} = blk
|
macro payload: typed {.gensym.} = blk
|
||||||
payload()
|
payload()
|
||||||
|
|
||||||
when hasAlloc:
|
when hasAlloc or defined(nimscript):
|
||||||
proc insert*(x: var string, item: string, i = 0.Natural) {.noSideEffect.} =
|
proc insert*(x: var string, item: string, i = 0.Natural) {.noSideEffect.} =
|
||||||
## inserts `item` into `x` at position `i`.
|
## inserts `item` into `x` at position `i`.
|
||||||
var xl = x.len
|
var xl = x.len
|
||||||
|
|
|
||||||
|
|
@ -471,7 +471,8 @@ proc getPackageDir(package: string): string =
|
||||||
else:
|
else:
|
||||||
result = commandOutput[0].string
|
result = commandOutput[0].string
|
||||||
|
|
||||||
iterator listPackages(filter: PackageFilter): tuple[name, url, cmd: string] =
|
iterator listPackages(filter: PackageFilter):
|
||||||
|
tuple[name, url, cmd: string, hasDeps: bool] =
|
||||||
const defaultCmd = "nimble test"
|
const defaultCmd = "nimble test"
|
||||||
let packageList = parseFile(packageIndex)
|
let packageList = parseFile(packageIndex)
|
||||||
for package in packageList.items:
|
for package in packageList.items:
|
||||||
|
|
@ -482,12 +483,12 @@ iterator listPackages(filter: PackageFilter): tuple[name, url, cmd: string] =
|
||||||
case filter
|
case filter
|
||||||
of pfCoreOnly:
|
of pfCoreOnly:
|
||||||
if "nim-lang" in normalize(url):
|
if "nim-lang" in normalize(url):
|
||||||
yield (name, url, defaultCmd)
|
yield (name, url, defaultCmd, false)
|
||||||
of pfExtraOnly:
|
of pfExtraOnly:
|
||||||
for n, cmd, commit in important_packages.packages.items:
|
for n, cmd, commit, hasDeps in important_packages.packages.items:
|
||||||
if name == n: yield (name, url, cmd)
|
if name == n: yield (name, url, cmd, hasDeps)
|
||||||
of pfAll:
|
of pfAll:
|
||||||
yield (name, url, defaultCmd)
|
yield (name, url, defaultCmd, false)
|
||||||
|
|
||||||
proc makeSupTest(test, options: string, cat: Category): TTest =
|
proc makeSupTest(test, options: string, cat: Category): TTest =
|
||||||
result.cat = cat
|
result.cat = cat
|
||||||
|
|
@ -506,19 +507,34 @@ proc testNimblePackages(r: var TResults, cat: Category, filter: PackageFilter) =
|
||||||
|
|
||||||
let packageFileTest = makeSupTest("PackageFileParsed", "", cat)
|
let packageFileTest = makeSupTest("PackageFileParsed", "", cat)
|
||||||
var keepDir = false
|
var keepDir = false
|
||||||
|
var packagesDir = "pkgstemp"
|
||||||
try:
|
try:
|
||||||
for name, url, cmd in listPackages(filter):
|
for name, url, cmd, hasDep in listPackages(filter):
|
||||||
var test = makeSupTest(url, "", cat)
|
var test = makeSupTest(url, "", cat)
|
||||||
let buildPath = "pkgstemp" / name
|
let buildPath = packagesDir / name
|
||||||
let installProcess = startProcess("git", "", ["clone", url, buildPath])
|
if not existsDir(buildPath):
|
||||||
|
if hasDep:
|
||||||
|
let nimbleProcess = startProcess("nimble", "", ["install", "-y", name],
|
||||||
|
options = {poUsePath, poStdErrToStdOut})
|
||||||
|
let nimbleStatus = waitForExitEx(nimbleProcess)
|
||||||
|
nimbleProcess.close
|
||||||
|
if nimbleStatus != QuitSuccess:
|
||||||
|
r.addResult(test, targetC, "", "", reInstallFailed)
|
||||||
|
keepDir = true
|
||||||
|
continue
|
||||||
|
|
||||||
|
let installProcess = startProcess("git", "", ["clone", url, buildPath],
|
||||||
|
options = {poUsePath, poStdErrToStdOut})
|
||||||
let installStatus = waitForExitEx(installProcess)
|
let installStatus = waitForExitEx(installProcess)
|
||||||
installProcess.close
|
installProcess.close
|
||||||
if installStatus != QuitSuccess:
|
if installStatus != QuitSuccess:
|
||||||
r.addResult(test, targetC, "", "", reInstallFailed)
|
r.addResult(test, targetC, "", "", reInstallFailed)
|
||||||
keepDir = true
|
keepDir = true
|
||||||
else:
|
continue
|
||||||
|
|
||||||
let cmdArgs = parseCmdLine(cmd)
|
let cmdArgs = parseCmdLine(cmd)
|
||||||
let buildProcess = startProcess(cmdArgs[0], buildPath, cmdArgs[1..^1])
|
let buildProcess = startProcess(cmdArgs[0], buildPath, cmdArgs[1..^1],
|
||||||
|
options = {poUsePath, poStdErrToStdOut})
|
||||||
let buildStatus = waitForExitEx(buildProcess)
|
let buildStatus = waitForExitEx(buildProcess)
|
||||||
buildProcess.close
|
buildProcess.close
|
||||||
if buildStatus != QuitSuccess:
|
if buildStatus != QuitSuccess:
|
||||||
|
|
@ -531,7 +547,7 @@ proc testNimblePackages(r: var TResults, cat: Category, filter: PackageFilter) =
|
||||||
echo("[Warning] - Cannot run nimble tests: Invalid package file.")
|
echo("[Warning] - Cannot run nimble tests: Invalid package file.")
|
||||||
r.addResult(packageFileTest, targetC, "", "", reBuildFailed)
|
r.addResult(packageFileTest, targetC, "", "", reBuildFailed)
|
||||||
finally:
|
finally:
|
||||||
if not keepDir: removeDir("pkgstemp")
|
if not keepDir: removeDir(packagesDir)
|
||||||
|
|
||||||
|
|
||||||
# ----------------------------------------------------------------------------
|
# ----------------------------------------------------------------------------
|
||||||
|
|
|
||||||
|
|
@ -1,28 +1,44 @@
|
||||||
import strutils
|
import strutils
|
||||||
|
|
||||||
template pkg(name: string; cmd = "nimble test"; version = ""): untyped =
|
template pkg(name: string; cmd = "nimble test"; version = ""; hasDeps = false): untyped =
|
||||||
packages.add((name, cmd, version))
|
packages.add((name, cmd, version, hasDeps))
|
||||||
|
|
||||||
var packages*: seq[tuple[name, cmd, version: string]] = @[]
|
var packages*: seq[tuple[name, cmd, version: string; hasDeps: bool]] = @[]
|
||||||
|
|
||||||
pkg "karax"
|
|
||||||
pkg "cligen"
|
|
||||||
pkg "glob"
|
|
||||||
#pkg "regex"
|
|
||||||
pkg "freeimage", "nim c freeimage.nim"
|
|
||||||
pkg "zero_functional"
|
|
||||||
pkg "nimpy", "nim c nimpy.nim"
|
|
||||||
#pkg "nimongo", "nimble test_ci"
|
|
||||||
pkg "inim"
|
|
||||||
|
|
||||||
pkg "sdl1", "nim c src/sdl.nim"
|
pkg "arraymancer", "nim c src/arraymancer.nim", "", true
|
||||||
pkg "iterutils"
|
pkg "ast_pattern_matching", "nim c tests/test1.nim"
|
||||||
pkg "gnuplot"
|
|
||||||
pkg "c2nim"
|
pkg "c2nim"
|
||||||
|
pkg "cligen", "nim c -o:cligenn cligen.nim"
|
||||||
#[
|
pkg "compactdict", "nim c tests/test1.nim"
|
||||||
arraymancer
|
pkg "criterion"
|
||||||
nimpb
|
pkg "docopt"
|
||||||
jester
|
pkg "gara", "nim c tests/test_gara.nim"
|
||||||
nimx
|
pkg "glob"
|
||||||
]#
|
pkg "gnuplot"
|
||||||
|
pkg "hts", "nim c tests/all.nim"
|
||||||
|
pkg "inim"
|
||||||
|
pkg "itertools", "nim doc src/itertools.nim"
|
||||||
|
pkg "iterutils"
|
||||||
|
pkg "karax", "nim c tests/tester.nim"
|
||||||
|
pkg "loopfusion"
|
||||||
|
pkg "nake", "nim c nakefile.nim"
|
||||||
|
pkg "neo", "nim c -d:blas=openblas tests/all.nim", "", true
|
||||||
|
pkg "nigui", "nim c -o:niguii src/nigui.nim"
|
||||||
|
pkg "NimData", "nim c -o:nimdataa src/nimdata.nim", "", true
|
||||||
|
pkg "nimes", "nim c src/nimes.nim", "", true
|
||||||
|
pkg "nimgame2", "nim c nimgame2/nimgame.nim", "", true
|
||||||
|
pkg "nimongo", "nimble test_ci", "", true
|
||||||
|
pkg "nimpy", "nim c -o:nimpyy nimpy.nim"
|
||||||
|
pkg "nimsl", "nim c test.nim"
|
||||||
|
pkg "nimx", "nim c --threads:on test/main.nim", "", true
|
||||||
|
pkg "parsetoml"
|
||||||
|
pkg "patty"
|
||||||
|
pkg "plotly", "nim c examples/all.nim", "", true
|
||||||
|
pkg "protobuf", "nim c -o:protobuff src/protobuf.nim", "", true
|
||||||
|
pkg "regex", "nim c src/regex"
|
||||||
|
pkg "rosencrantz", "nim c -o:rsncntz rosencrantz.nim"
|
||||||
|
pkg "sdl1", "nim c src/sdl.nim"
|
||||||
|
pkg "sdl2_nim", "nim c sdl2/sdl.nim"
|
||||||
|
pkg "stint", "nim c -o:stintt stint.nim"
|
||||||
|
pkg "zero_functional", "nim c test.nim"
|
||||||
|
|
|
||||||
|
|
@ -26,6 +26,10 @@ proc launchSwarm(port: Port) {.async.} =
|
||||||
proc readMessages(client: AsyncFD) {.async.} =
|
proc readMessages(client: AsyncFD) {.async.} =
|
||||||
# wrapping the AsyncFd into a AsyncSocket object
|
# wrapping the AsyncFd into a AsyncSocket object
|
||||||
var sockObj = newAsyncSocket(client)
|
var sockObj = newAsyncSocket(client)
|
||||||
|
var (ipaddr, port) = sockObj.getPeerAddr()
|
||||||
|
doAssert ipaddr == "127.0.0.1"
|
||||||
|
(ipaddr, port) = sockObj.getLocalAddr()
|
||||||
|
doAssert ipaddr == "127.0.0.1"
|
||||||
while true:
|
while true:
|
||||||
var line = await recvLine(sockObj)
|
var line = await recvLine(sockObj)
|
||||||
if line == "":
|
if line == "":
|
||||||
|
|
|
||||||
|
|
@ -1,10 +0,0 @@
|
||||||
discard """
|
|
||||||
output: "ABCDC"
|
|
||||||
"""
|
|
||||||
|
|
||||||
type
|
|
||||||
MyEnum = enum
|
|
||||||
A,B,C,D
|
|
||||||
# trick the optimizer with an seq:
|
|
||||||
var x = @[A,B,C,D]
|
|
||||||
echo x[0],x[1],x[2],x[3],MyEnum(2)
|
|
||||||
37
tests/js/tbasics.nim
Normal file
37
tests/js/tbasics.nim
Normal file
|
|
@ -0,0 +1,37 @@
|
||||||
|
discard """
|
||||||
|
output: '''ABCDC
|
||||||
|
1
|
||||||
|
14
|
||||||
|
ok'''
|
||||||
|
"""
|
||||||
|
|
||||||
|
type
|
||||||
|
MyEnum = enum
|
||||||
|
A,B,C,D
|
||||||
|
# trick the optimizer with an seq:
|
||||||
|
var x = @[A,B,C,D]
|
||||||
|
echo x[0],x[1],x[2],x[3],MyEnum(2)
|
||||||
|
|
||||||
|
# bug #10651
|
||||||
|
|
||||||
|
var xa: seq[int]
|
||||||
|
var ya = @[1,2]
|
||||||
|
xa &= ya
|
||||||
|
echo xa[0]
|
||||||
|
|
||||||
|
proc test =
|
||||||
|
var yup: seq[int]
|
||||||
|
try:
|
||||||
|
yup.add 14
|
||||||
|
echo yup.pop
|
||||||
|
finally:
|
||||||
|
discard
|
||||||
|
|
||||||
|
test()
|
||||||
|
|
||||||
|
when true:
|
||||||
|
var a: seq[int]
|
||||||
|
|
||||||
|
a.setLen(0)
|
||||||
|
|
||||||
|
echo "ok"
|
||||||
Loading…
Add table
Add a link
Reference in a new issue