Merge branch 'devel' of https://github.com/Araq/Nimrod into devel
This commit is contained in:
commit
2e9950afe8
10 changed files with 313 additions and 85 deletions
|
|
@ -564,7 +564,7 @@ proc genTry(p: PProc, n: PNode, r: var TCompRes) =
|
||||||
moveInto(p, a, r)
|
moveInto(p, a, r)
|
||||||
var i = 1
|
var i = 1
|
||||||
if p.target == targetJS and length > 1 and n.sons[i].kind == nkExceptBranch:
|
if p.target == targetJS and length > 1 and n.sons[i].kind == nkExceptBranch:
|
||||||
appf(p.body, "} catch (EXC) {$n")
|
appf(p.body, "} catch (EXC) {$n lastJSError = EXC;$n")
|
||||||
elif p.target == targetLua:
|
elif p.target == targetLua:
|
||||||
appf(p.body, "end)$n")
|
appf(p.body, "end)$n")
|
||||||
while i < length and n.sons[i].kind == nkExceptBranch:
|
while i < length and n.sons[i].kind == nkExceptBranch:
|
||||||
|
|
@ -1114,6 +1114,8 @@ proc createVar(p: PProc, typ: PType, indirect: bool): PRope =
|
||||||
var e = elemType(t)
|
var e = elemType(t)
|
||||||
if length > 32:
|
if length > 32:
|
||||||
useMagic(p, "arrayConstr")
|
useMagic(p, "arrayConstr")
|
||||||
|
# XXX: arrayConstr depends on nimCopy. This line shouldn't be necessary.
|
||||||
|
useMagic(p, "nimCopy")
|
||||||
result = ropef("arrayConstr($1, $2, $3)", [toRope(length),
|
result = ropef("arrayConstr($1, $2, $3)", [toRope(length),
|
||||||
createVar(p, e, false), genTypeInfo(p, e)])
|
createVar(p, e, false), genTypeInfo(p, e)])
|
||||||
else:
|
else:
|
||||||
|
|
@ -1314,7 +1316,7 @@ proc genMagic(p: PProc, n: PNode, r: var TCompRes) =
|
||||||
if skipTypes(n.sons[1].typ, abstractVarRange).kind == tyCString:
|
if skipTypes(n.sons[1].typ, abstractVarRange).kind == tyCString:
|
||||||
binaryExpr(p, n, r, "", "$1 += $2")
|
binaryExpr(p, n, r, "", "$1 += $2")
|
||||||
else:
|
else:
|
||||||
binaryExpr(p, n, r, "", "$1 = ($1.slice(0,-1)).concat($2)")
|
binaryExpr(p, n, r, "", "$1 = ($1.slice(0, -1)).concat($2)")
|
||||||
# XXX: make a copy of $2, because of Javascript's sucking semantics
|
# XXX: make a copy of $2, because of Javascript's sucking semantics
|
||||||
of mAppendSeqElem: binaryExpr(p, n, r, "", "$1.push($2)")
|
of mAppendSeqElem: binaryExpr(p, n, r, "", "$1.push($2)")
|
||||||
of mConStrStr: genConStrStr(p, n, r)
|
of mConStrStr: genConStrStr(p, n, r)
|
||||||
|
|
@ -1341,7 +1343,7 @@ proc genMagic(p: PProc, n: PNode, r: var TCompRes) =
|
||||||
of ast.mDec:
|
of ast.mDec:
|
||||||
if optOverflowCheck notin p.options: binaryExpr(p, n, r, "", "$1 -= $2")
|
if optOverflowCheck notin p.options: binaryExpr(p, n, r, "", "$1 -= $2")
|
||||||
else: binaryExpr(p, n, r, "subInt", "$1 = subInt($1, $2)")
|
else: binaryExpr(p, n, r, "subInt", "$1 = subInt($1, $2)")
|
||||||
of mSetLengthStr: binaryExpr(p, n, r, "", "$1.length = ($2)-1")
|
of mSetLengthStr: binaryExpr(p, n, r, "", "$1.length = $2+1; $1[$1.length-1] = 0")
|
||||||
of mSetLengthSeq: binaryExpr(p, n, r, "", "$1.length = $2")
|
of mSetLengthSeq: binaryExpr(p, n, r, "", "$1.length = $2")
|
||||||
of mCard: unaryExpr(p, n, r, "SetCard", "SetCard($1)")
|
of mCard: unaryExpr(p, n, r, "SetCard", "SetCard($1)")
|
||||||
of mLtSet: binaryExpr(p, n, r, "SetLt", "SetLt($1, $2)")
|
of mLtSet: binaryExpr(p, n, r, "SetLt", "SetLt($1, $2)")
|
||||||
|
|
@ -1698,7 +1700,12 @@ proc myClose(b: PPassContext, n: PNode): PNode =
|
||||||
var m = BModule(b)
|
var m = BModule(b)
|
||||||
if sfMainModule in m.module.flags:
|
if sfMainModule in m.module.flags:
|
||||||
let code = wholeCode(m)
|
let code = wholeCode(m)
|
||||||
var outfile = changeFileExt(completeCFilePath(m.module.filename), "js")
|
let outfile =
|
||||||
|
if options.outFile.len > 0:
|
||||||
|
if options.outFile.isAbsolute: options.outFile
|
||||||
|
else: getCurrentDir() / options.outFile
|
||||||
|
else:
|
||||||
|
changeFileExt(completeCFilePath(m.module.filename), "js")
|
||||||
discard writeRopeIfNotEqual(con(genHeader(), code), outfile)
|
discard writeRopeIfNotEqual(con(genHeader(), code), outfile)
|
||||||
|
|
||||||
proc myOpenCached(s: PSym, rd: PRodReader): PPassContext =
|
proc myOpenCached(s: PSym, rd: PRodReader): PPassContext =
|
||||||
|
|
|
||||||
|
|
@ -61,8 +61,12 @@ proc handleCmdLine() =
|
||||||
tccgen.run()
|
tccgen.run()
|
||||||
if optRun in gGlobalOptions:
|
if optRun in gGlobalOptions:
|
||||||
if gCmd == cmdCompileToJS:
|
if gCmd == cmdCompileToJS:
|
||||||
var ex = quoteShell(
|
var ex: string
|
||||||
completeCFilePath(changeFileExt(gProjectFull, "js").prependCurDir))
|
if options.outFile.len > 0:
|
||||||
|
ex = options.outFile.prependCurDir.quoteShell
|
||||||
|
else:
|
||||||
|
ex = quoteShell(
|
||||||
|
completeCFilePath(changeFileExt(gProjectFull, "js").prependCurDir))
|
||||||
execExternalProgram("node " & ex & ' ' & service.arguments)
|
execExternalProgram("node " & ex & ' ' & service.arguments)
|
||||||
else:
|
else:
|
||||||
var binPath: string
|
var binPath: string
|
||||||
|
|
|
||||||
41
doc/lib.txt
41
doc/lib.txt
|
|
@ -16,10 +16,11 @@ Pure libraries do not depend on any external ``*.dll`` or ``lib*.so`` binary
|
||||||
while impure libraries do. A wrapper is an impure library that is a very
|
while impure libraries do. A wrapper is an impure library that is a very
|
||||||
low-level interface to a C library.
|
low-level interface to a C library.
|
||||||
|
|
||||||
Read this `document <apis.html>`_ for a quick overview of the API design. If
|
Read this `document <apis.html>`_ for a quick overview of the API design.
|
||||||
you can't find here some functionality you are looking for you could try using
|
|
||||||
the 3rd party `package manager Babel <https://github.com/nimrod-code/babel>`_
|
The `bottom <#babel>`_ of this page includes a list of 3rd party packages
|
||||||
and its list of packages.
|
created by the Nimrod community. These packages are a useful addition to the
|
||||||
|
modules in the standard library.
|
||||||
|
|
||||||
|
|
||||||
Pure libraries
|
Pure libraries
|
||||||
|
|
@ -573,3 +574,35 @@ Scientific computing
|
||||||
|
|
||||||
* `libsvm <libsvm.html>`_
|
* `libsvm <libsvm.html>`_
|
||||||
Low level wrapper for `lib svm <http://www.csie.ntu.edu.tw/~cjlin/libsvm/>`_.
|
Low level wrapper for `lib svm <http://www.csie.ntu.edu.tw/~cjlin/libsvm/>`_.
|
||||||
|
|
||||||
|
Babel
|
||||||
|
====================
|
||||||
|
|
||||||
|
Babel is a package manager for the Nimrod programming language.
|
||||||
|
For instructions on how to install Babel packages see
|
||||||
|
`its README <https://github.com/nimrod-code/babel#readme>`_.
|
||||||
|
|
||||||
|
Official packages
|
||||||
|
-----------------
|
||||||
|
|
||||||
|
These packages are officially supported and will therefore be continually
|
||||||
|
maintained to ensure that they work with the latest versions of the Nimrod
|
||||||
|
compiler.
|
||||||
|
|
||||||
|
.. raw:: html
|
||||||
|
|
||||||
|
<div id="officialPkgList"></div>
|
||||||
|
|
||||||
|
Unofficial packages
|
||||||
|
-------------------
|
||||||
|
|
||||||
|
These packages have been developed by independent Nimrod developers and as
|
||||||
|
such may not always be up to date with the latest developments in the
|
||||||
|
Nimrod programming language.
|
||||||
|
|
||||||
|
.. raw:: html
|
||||||
|
|
||||||
|
<div id="unofficialPkgList"></div>
|
||||||
|
|
||||||
|
<script type="text/javascript" src="babelpkglist.js"></script>
|
||||||
|
<script type="text/javascript" src="http://build.nimrod-lang.org/packages?callback=gotPackageList"></script>
|
||||||
|
|
|
||||||
|
|
@ -861,26 +861,97 @@ proc parseJson(p: var TJsonParser): PJsonNode =
|
||||||
of tkError, tkCurlyRi, tkBracketRi, tkColon, tkComma, tkEof:
|
of tkError, tkCurlyRi, tkBracketRi, tkColon, tkComma, tkEof:
|
||||||
raiseParseErr(p, "{")
|
raiseParseErr(p, "{")
|
||||||
|
|
||||||
proc parseJson*(s: PStream, filename: string): PJsonNode =
|
when not defined(js):
|
||||||
## Parses from a stream `s` into a `PJsonNode`. `filename` is only needed
|
proc parseJson*(s: PStream, filename: string): PJsonNode =
|
||||||
## for nice error messages.
|
## Parses from a stream `s` into a `PJsonNode`. `filename` is only needed
|
||||||
var p: TJsonParser
|
## for nice error messages.
|
||||||
p.open(s, filename)
|
var p: TJsonParser
|
||||||
discard getTok(p) # read first token
|
p.open(s, filename)
|
||||||
result = p.parseJson()
|
discard getTok(p) # read first token
|
||||||
p.close()
|
result = p.parseJson()
|
||||||
|
p.close()
|
||||||
|
|
||||||
proc parseJson*(buffer: string): PJsonNode =
|
proc parseJson*(buffer: string): PJsonNode =
|
||||||
## Parses JSON from `buffer`.
|
## Parses JSON from `buffer`.
|
||||||
result = parseJson(newStringStream(buffer), "input")
|
result = parseJson(newStringStream(buffer), "input")
|
||||||
|
|
||||||
|
proc parseFile*(filename: string): PJsonNode =
|
||||||
|
## Parses `file` into a `PJsonNode`.
|
||||||
|
var stream = newFileStream(filename, fmRead)
|
||||||
|
if stream == nil:
|
||||||
|
raise newException(EIO, "cannot read from file: " & filename)
|
||||||
|
result = parseJson(stream, filename)
|
||||||
|
else:
|
||||||
|
from math import `mod`
|
||||||
|
type
|
||||||
|
TJSObject = object
|
||||||
|
proc parseNativeJson(x: cstring): TJSObject {.importc: "JSON.parse".}
|
||||||
|
|
||||||
|
proc getVarType(x): TJsonNodeKind =
|
||||||
|
result = JNull
|
||||||
|
proc getProtoName(y): cstring
|
||||||
|
{.importc: "Object.prototype.toString.call".}
|
||||||
|
case $getProtoName(x) # TODO: Implicit returns fail here.
|
||||||
|
of "[object Array]": return JArray
|
||||||
|
of "[object Object]": return JObject
|
||||||
|
of "[object Number]":
|
||||||
|
if cast[float](x) mod 1.0 == 0:
|
||||||
|
return JInt
|
||||||
|
else:
|
||||||
|
return JFloat
|
||||||
|
of "[object Boolean]": return JBool
|
||||||
|
of "[object Null]": return JNull
|
||||||
|
of "[object String]": return JString
|
||||||
|
else: assert false
|
||||||
|
|
||||||
|
proc len(x: TJSObject): int =
|
||||||
|
assert x.getVarType == JArray
|
||||||
|
asm """
|
||||||
|
return `x`.length;
|
||||||
|
"""
|
||||||
|
|
||||||
|
proc `[]`(x: TJSObject, y: string): TJSObject =
|
||||||
|
assert x.getVarType == JObject
|
||||||
|
asm """
|
||||||
|
return `x`[`y`];
|
||||||
|
"""
|
||||||
|
|
||||||
|
proc `[]`(x: TJSObject, y: int): TJSObject =
|
||||||
|
assert x.getVarType == JArray
|
||||||
|
asm """
|
||||||
|
return `x`[`y`];
|
||||||
|
"""
|
||||||
|
|
||||||
|
proc convertObject(x: TJSObject): PJsonNode =
|
||||||
|
case getVarType(x)
|
||||||
|
of JArray:
|
||||||
|
result = newJArray()
|
||||||
|
for i in 0 .. <x.len:
|
||||||
|
result.add(x[i].convertObject())
|
||||||
|
of JObject:
|
||||||
|
result = newJObject()
|
||||||
|
asm """for (property in `x`) {
|
||||||
|
if (`x`.hasOwnProperty(property)) {
|
||||||
|
"""
|
||||||
|
var nimProperty: cstring
|
||||||
|
var nimValue: TJSObject
|
||||||
|
asm "`nimProperty` = property; `nimValue` = `x`[property];"
|
||||||
|
result[$nimProperty] = nimValue.convertObject()
|
||||||
|
asm "}}"
|
||||||
|
of JInt:
|
||||||
|
result = newJInt(cast[int](x))
|
||||||
|
of JFloat:
|
||||||
|
result = newJFloat(cast[float](x))
|
||||||
|
of JString:
|
||||||
|
result = newJString($cast[cstring](x))
|
||||||
|
of JBool:
|
||||||
|
result = newJBool(cast[bool](x))
|
||||||
|
of JNull:
|
||||||
|
result = newJNull()
|
||||||
|
|
||||||
|
proc parseJson*(buffer: string): PJsonNode =
|
||||||
|
return parseNativeJson(buffer).convertObject()
|
||||||
|
|
||||||
proc parseFile*(filename: string): PJsonNode =
|
|
||||||
## Parses `file` into a `PJsonNode`.
|
|
||||||
var stream = newFileStream(filename, fmRead)
|
|
||||||
if stream == nil:
|
|
||||||
raise newException(EIO, "cannot read from file: " & filename)
|
|
||||||
result = parseJson(stream, filename)
|
|
||||||
|
|
||||||
when false:
|
when false:
|
||||||
import os
|
import os
|
||||||
var s = newFileStream(ParamStr(1), fmRead)
|
var s = newFileStream(ParamStr(1), fmRead)
|
||||||
|
|
|
||||||
|
|
@ -19,8 +19,8 @@
|
||||||
|
|
||||||
when defined(Posix) and not defined(haiku):
|
when defined(Posix) and not defined(haiku):
|
||||||
{.passl: "-lm".}
|
{.passl: "-lm".}
|
||||||
|
when not defined(js):
|
||||||
import times
|
import times
|
||||||
|
|
||||||
const
|
const
|
||||||
PI* = 3.1415926535897932384626433 ## the circle constant PI (Ludolph's number)
|
PI* = 3.1415926535897932384626433 ## the circle constant PI (Ludolph's number)
|
||||||
|
|
|
||||||
|
|
@ -239,45 +239,47 @@ proc newStringStream*(s: string = ""): PStringStream =
|
||||||
result.readDataImpl = ssReadData
|
result.readDataImpl = ssReadData
|
||||||
result.writeDataImpl = ssWriteData
|
result.writeDataImpl = ssWriteData
|
||||||
|
|
||||||
type
|
when not defined(js):
|
||||||
PFileStream* = ref TFileStream ## a stream that encapsulates a `TFile`
|
|
||||||
TFileStream* = object of TStream
|
|
||||||
f: TFile
|
|
||||||
|
|
||||||
proc fsClose(s: PStream) =
|
type
|
||||||
if PFileStream(s).f != nil:
|
PFileStream* = ref TFileStream ## a stream that encapsulates a `TFile`
|
||||||
close(PFileStream(s).f)
|
TFileStream* = object of TStream
|
||||||
PFileStream(s).f = nil
|
f: TFile
|
||||||
proc fsFlush(s: PStream) = flushFile(PFileStream(s).f)
|
|
||||||
proc fsAtEnd(s: PStream): bool = return endOfFile(PFileStream(s).f)
|
|
||||||
proc fsSetPosition(s: PStream, pos: int) = setFilePos(PFileStream(s).f, pos)
|
|
||||||
proc fsGetPosition(s: PStream): int = return int(getFilePos(PFileStream(s).f))
|
|
||||||
|
|
||||||
proc fsReadData(s: PStream, buffer: pointer, bufLen: int): int =
|
proc fsClose(s: PStream) =
|
||||||
result = readBuffer(PFileStream(s).f, buffer, bufLen)
|
if PFileStream(s).f != nil:
|
||||||
|
close(PFileStream(s).f)
|
||||||
proc fsWriteData(s: PStream, buffer: pointer, bufLen: int) =
|
PFileStream(s).f = nil
|
||||||
if writeBuffer(PFileStream(s).f, buffer, bufLen) != bufLen:
|
proc fsFlush(s: PStream) = flushFile(PFileStream(s).f)
|
||||||
raise newEIO("cannot write to stream")
|
proc fsAtEnd(s: PStream): bool = return endOfFile(PFileStream(s).f)
|
||||||
|
proc fsSetPosition(s: PStream, pos: int) = setFilePos(PFileStream(s).f, pos)
|
||||||
|
proc fsGetPosition(s: PStream): int = return int(getFilePos(PFileStream(s).f))
|
||||||
|
|
||||||
proc newFileStream*(f: TFile): PFileStream =
|
proc fsReadData(s: PStream, buffer: pointer, bufLen: int): int =
|
||||||
## creates a new stream from the file `f`.
|
result = readBuffer(PFileStream(s).f, buffer, bufLen)
|
||||||
new(result)
|
|
||||||
result.f = f
|
|
||||||
result.closeImpl = fsClose
|
|
||||||
result.atEndImpl = fsAtEnd
|
|
||||||
result.setPositionImpl = fsSetPosition
|
|
||||||
result.getPositionImpl = fsGetPosition
|
|
||||||
result.readDataImpl = fsReadData
|
|
||||||
result.writeDataImpl = fsWriteData
|
|
||||||
result.flushImpl = fsFlush
|
|
||||||
|
|
||||||
proc newFileStream*(filename: string, mode: TFileMode): PFileStream =
|
proc fsWriteData(s: PStream, buffer: pointer, bufLen: int) =
|
||||||
## creates a new stream from the file named `filename` with the mode `mode`.
|
if writeBuffer(PFileStream(s).f, buffer, bufLen) != bufLen:
|
||||||
## If the file cannot be opened, nil is returned. See the `system
|
raise newEIO("cannot write to stream")
|
||||||
## <system.html>`_ module for a list of available TFileMode enums.
|
|
||||||
var f: TFile
|
proc newFileStream*(f: TFile): PFileStream =
|
||||||
if open(f, filename, mode): result = newFileStream(f)
|
## creates a new stream from the file `f`.
|
||||||
|
new(result)
|
||||||
|
result.f = f
|
||||||
|
result.closeImpl = fsClose
|
||||||
|
result.atEndImpl = fsAtEnd
|
||||||
|
result.setPositionImpl = fsSetPosition
|
||||||
|
result.getPositionImpl = fsGetPosition
|
||||||
|
result.readDataImpl = fsReadData
|
||||||
|
result.writeDataImpl = fsWriteData
|
||||||
|
result.flushImpl = fsFlush
|
||||||
|
|
||||||
|
proc newFileStream*(filename: string, mode: TFileMode): PFileStream =
|
||||||
|
## creates a new stream from the file named `filename` with the mode `mode`.
|
||||||
|
## If the file cannot be opened, nil is returned. See the `system
|
||||||
|
## <system.html>`_ module for a list of available TFileMode enums.
|
||||||
|
var f: TFile
|
||||||
|
if open(f, filename, mode): result = newFileStream(f)
|
||||||
|
|
||||||
|
|
||||||
when true:
|
when true:
|
||||||
|
|
|
||||||
|
|
@ -264,6 +264,19 @@ iterator split*(s: string, sep: char): string =
|
||||||
yield substr(s, first, last-1)
|
yield substr(s, first, last-1)
|
||||||
inc(last)
|
inc(last)
|
||||||
|
|
||||||
|
iterator split*(s: string, sep: string): string =
|
||||||
|
## Splits the string `s` into substrings using a string separator.
|
||||||
|
##
|
||||||
|
## Substrings are separated by the string `sep`.
|
||||||
|
var last = 0
|
||||||
|
if len(s) > 0:
|
||||||
|
while last <= len(s):
|
||||||
|
var first = last
|
||||||
|
while last < len(s) and s.substr(last, last + <sep.len) != sep:
|
||||||
|
inc(last)
|
||||||
|
yield substr(s, first, last-1)
|
||||||
|
inc(last, sep.len)
|
||||||
|
|
||||||
iterator splitLines*(s: string): string =
|
iterator splitLines*(s: string): string =
|
||||||
## Splits the string `s` into its containing lines. Every newline
|
## Splits the string `s` into its containing lines. Every newline
|
||||||
## combination (CR, LF, CR-LF) is supported. The result strings contain
|
## combination (CR, LF, CR-LF) is supported. The result strings contain
|
||||||
|
|
@ -329,6 +342,13 @@ proc split*(s: string, sep: char): seq[string] {.noSideEffect,
|
||||||
## of substrings.
|
## of substrings.
|
||||||
accumulateResult(split(s, sep))
|
accumulateResult(split(s, sep))
|
||||||
|
|
||||||
|
proc split*(s: string, sep: string): seq[string] {.noSideEffect,
|
||||||
|
rtl, extern: "nsuSplitString".} =
|
||||||
|
## Splits the string `s` into substrings using a string separator.
|
||||||
|
##
|
||||||
|
## Substrings are separated by the string `sep`.
|
||||||
|
accumulateResult(split(s, sep))
|
||||||
|
|
||||||
proc toHex*(x: BiggestInt, len: int): string {.noSideEffect,
|
proc toHex*(x: BiggestInt, len: int): string {.noSideEffect,
|
||||||
rtl, extern: "nsuToHex".} =
|
rtl, extern: "nsuToHex".} =
|
||||||
## Converts `x` to its hexadecimal representation. The resulting string
|
## Converts `x` to its hexadecimal representation. The resulting string
|
||||||
|
|
|
||||||
|
|
@ -12,7 +12,7 @@ when defined(nodejs):
|
||||||
else:
|
else:
|
||||||
proc alert*(s: cstring) {.importc, nodecl.}
|
proc alert*(s: cstring) {.importc, nodecl.}
|
||||||
|
|
||||||
proc log*(s: cstring) {.importc: "console.log", nodecl.}
|
proc log*(s: cstring) {.importc: "console.log", varargs, nodecl.}
|
||||||
|
|
||||||
type
|
type
|
||||||
PSafePoint = ptr TSafePoint
|
PSafePoint = ptr TSafePoint
|
||||||
|
|
@ -27,11 +27,19 @@ type
|
||||||
line: int # current line number
|
line: int # current line number
|
||||||
filename: cstring
|
filename: cstring
|
||||||
|
|
||||||
|
PJSError = ref object
|
||||||
|
columnNumber {.importc.}: int
|
||||||
|
fileName {.importc.}: cstring
|
||||||
|
lineNumber {.importc.}: int
|
||||||
|
message {.importc.}: cstring
|
||||||
|
stack {.importc.}: cstring
|
||||||
|
|
||||||
var
|
var
|
||||||
framePtr {.importc, nodecl, volatile.}: PCallFrame
|
framePtr {.importc, nodecl, volatile.}: PCallFrame
|
||||||
excHandler {.importc, nodecl, volatile.}: PSafePoint = nil
|
excHandler {.importc, nodecl, volatile.}: PSafePoint = nil
|
||||||
# list of exception handlers
|
# list of exception handlers
|
||||||
# a global variable for the root of all try blocks
|
# a global variable for the root of all try blocks
|
||||||
|
lastJSError {.importc, nodecl, volatile.}: PJSError = nil
|
||||||
|
|
||||||
{.push stacktrace: off, profiler:off.}
|
{.push stacktrace: off, profiler:off.}
|
||||||
proc nimBoolToStr(x: bool): string {.compilerproc.} =
|
proc nimBoolToStr(x: bool): string {.compilerproc.} =
|
||||||
|
|
@ -43,8 +51,12 @@ proc nimCharToStr(x: char): string {.compilerproc.} =
|
||||||
result[0] = x
|
result[0] = x
|
||||||
|
|
||||||
proc getCurrentExceptionMsg*(): string =
|
proc getCurrentExceptionMsg*(): string =
|
||||||
if excHandler != nil: return $excHandler.exc.msg
|
if excHandler != nil and excHandler.exc != nil:
|
||||||
return ""
|
return $excHandler.exc.msg
|
||||||
|
elif lastJSError != nil:
|
||||||
|
return $lastJSError.message
|
||||||
|
else:
|
||||||
|
return ""
|
||||||
|
|
||||||
proc auxWriteStackTrace(f: PCallFrame): string =
|
proc auxWriteStackTrace(f: PCallFrame): string =
|
||||||
type
|
type
|
||||||
|
|
@ -77,11 +89,13 @@ proc auxWriteStackTrace(f: PCallFrame): string =
|
||||||
add(result, "\n")
|
add(result, "\n")
|
||||||
|
|
||||||
proc rawWriteStackTrace(): string =
|
proc rawWriteStackTrace(): string =
|
||||||
if framePtr == nil:
|
if framePtr != nil:
|
||||||
result = "No stack traceback available\n"
|
result = "Traceback (most recent call last)\n" & auxWriteStackTrace(framePtr)
|
||||||
else:
|
|
||||||
result = "Traceback (most recent call last)\n"& auxWriteStackTrace(framePtr)
|
|
||||||
framePtr = nil
|
framePtr = nil
|
||||||
|
elif lastJSError != nil:
|
||||||
|
result = $lastJSError.stack
|
||||||
|
else:
|
||||||
|
result = "No stack traceback available\n"
|
||||||
|
|
||||||
proc raiseException(e: ref E_Base, ename: cstring) {.
|
proc raiseException(e: ref E_Base, ename: cstring) {.
|
||||||
compilerproc, asmNoStackFrame.} =
|
compilerproc, asmNoStackFrame.} =
|
||||||
|
|
@ -472,17 +486,17 @@ proc ze*(a: int): int {.compilerproc.} =
|
||||||
proc ze64*(a: int64): int64 {.compilerproc.} =
|
proc ze64*(a: int64): int64 {.compilerproc.} =
|
||||||
result = a
|
result = a
|
||||||
|
|
||||||
proc ToU8(a: int): int8 {.asmNoStackFrame, compilerproc.} =
|
proc toU8*(a: int): int8 {.asmNoStackFrame, compilerproc.} =
|
||||||
asm """
|
asm """
|
||||||
return `a`;
|
return `a`;
|
||||||
"""
|
"""
|
||||||
|
|
||||||
proc ToU16(a: int): int16 {.asmNoStackFrame, compilerproc.} =
|
proc toU16*(a: int): int16 {.asmNoStackFrame, compilerproc.} =
|
||||||
asm """
|
asm """
|
||||||
return `a`;
|
return `a`;
|
||||||
"""
|
"""
|
||||||
|
|
||||||
proc ToU32(a: int): int32 {.asmNoStackFrame, compilerproc.} =
|
proc toU32*(a: int64): int32 {.asmNoStackFrame, compilerproc.} =
|
||||||
asm """
|
asm """
|
||||||
return `a`;
|
return `a`;
|
||||||
"""
|
"""
|
||||||
|
|
@ -503,17 +517,17 @@ proc nimCopy(x: pointer, ti: PNimType): pointer {.compilerproc.}
|
||||||
|
|
||||||
proc nimCopyAux(dest, src: Pointer, n: ptr TNimNode) {.compilerproc.} =
|
proc nimCopyAux(dest, src: Pointer, n: ptr TNimNode) {.compilerproc.} =
|
||||||
case n.kind
|
case n.kind
|
||||||
of nkNone: sysAssert(false, "NimCopyAux")
|
of nkNone: sysAssert(false, "nimCopyAux")
|
||||||
of nkSlot:
|
of nkSlot:
|
||||||
asm "`dest`[`n`.offset] = NimCopy(`src`[`n`.offset], `n`.typ);"
|
asm "`dest`[`n`.offset] = nimCopy(`src`[`n`.offset], `n`.typ);"
|
||||||
of nkList:
|
of nkList:
|
||||||
for i in 0..n.len-1:
|
for i in 0..n.len-1:
|
||||||
NimCopyAux(dest, src, n.sons[i])
|
nimCopyAux(dest, src, n.sons[i])
|
||||||
of nkCase:
|
of nkCase:
|
||||||
asm """
|
asm """
|
||||||
`dest`[`n`.offset] = NimCopy(`src`[`n`.offset], `n`.typ);
|
`dest`[`n`.offset] = nimCopy(`src`[`n`.offset], `n`.typ);
|
||||||
for (var i = 0; i < `n`.sons.length; ++i) {
|
for (var i = 0; i < `n`.sons.length; ++i) {
|
||||||
NimCopyAux(`dest`, `src`, `n`.sons[i][1]);
|
nimCopyAux(`dest`, `src`, `n`.sons[i][1]);
|
||||||
}
|
}
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
@ -534,17 +548,17 @@ proc nimCopy(x: pointer, ti: PNimType): pointer =
|
||||||
for (var key in `x`) { `result`[key] = `x`[key]; }
|
for (var key in `x`) { `result`[key] = `x`[key]; }
|
||||||
"""
|
"""
|
||||||
of tyTuple, tyObject:
|
of tyTuple, tyObject:
|
||||||
if ti.base != nil: result = NimCopy(x, ti.base)
|
if ti.base != nil: result = nimCopy(x, ti.base)
|
||||||
elif ti.kind == tyObject:
|
elif ti.kind == tyObject:
|
||||||
asm "`result` = {m_type: `ti`};"
|
asm "`result` = {m_type: `ti`};"
|
||||||
else:
|
else:
|
||||||
asm "`result` = {};"
|
asm "`result` = {};"
|
||||||
NimCopyAux(result, x, ti.node)
|
nimCopyAux(result, x, ti.node)
|
||||||
of tySequence, tyArrayConstr, tyOpenArray, tyArray:
|
of tySequence, tyArrayConstr, tyOpenArray, tyArray:
|
||||||
asm """
|
asm """
|
||||||
`result` = new Array(`x`.length);
|
`result` = new Array(`x`.length);
|
||||||
for (var i = 0; i < `x`.length; ++i) {
|
for (var i = 0; i < `x`.length; ++i) {
|
||||||
`result`[i] = NimCopy(`x`[i], `ti`.base);
|
`result`[i] = nimCopy(`x`[i], `ti`.base);
|
||||||
}
|
}
|
||||||
"""
|
"""
|
||||||
of tyString:
|
of tyString:
|
||||||
|
|
@ -584,12 +598,12 @@ proc genericReset(x: Pointer, ti: PNimType): pointer {.compilerproc.} =
|
||||||
else:
|
else:
|
||||||
result = nil
|
result = nil
|
||||||
|
|
||||||
proc ArrayConstr(len: int, value: pointer, typ: PNimType): pointer {.
|
proc arrayConstr(len: int, value: pointer, typ: PNimType): pointer {.
|
||||||
asmNoStackFrame, compilerproc.} =
|
asmNoStackFrame, compilerproc.} =
|
||||||
# types are fake
|
# types are fake
|
||||||
asm """
|
asm """
|
||||||
var result = new Array(`len`);
|
var result = new Array(`len`);
|
||||||
for (var i = 0; i < `len`; ++i) result[i] = NimCopy(`value`, `typ`);
|
for (var i = 0; i < `len`; ++i) result[i] = nimCopy(`value`, `typ`);
|
||||||
return result;
|
return result;
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -348,6 +348,10 @@ proc buildNewsRss(c: var TConfigData, destPath: string) =
|
||||||
|
|
||||||
generateRss(destFilename, parseNewsTitles(srcFilename))
|
generateRss(destFilename, parseNewsTitles(srcFilename))
|
||||||
|
|
||||||
|
proc buildJS(destPath: string) =
|
||||||
|
exec("nimrod js -d:release --out:$1 web/babelpkglist.nim" %
|
||||||
|
[destPath / "babelpkglist.js"])
|
||||||
|
|
||||||
proc main(c: var TConfigData) =
|
proc main(c: var TConfigData) =
|
||||||
const
|
const
|
||||||
cmd = "nimrod rst2html --compileonly $1 -o:web/$2.temp web/$2.txt"
|
cmd = "nimrod rst2html --compileonly $1 -o:web/$2.temp web/$2.txt"
|
||||||
|
|
@ -377,6 +381,7 @@ proc main(c: var TConfigData) =
|
||||||
quit("[Error] cannot write file: " & outfile)
|
quit("[Error] cannot write file: " & outfile)
|
||||||
removeFile(temp)
|
removeFile(temp)
|
||||||
copyDir("web/assets", "web/upload/assets")
|
copyDir("web/assets", "web/upload/assets")
|
||||||
|
buildJS("web/upload")
|
||||||
buildNewsRss(c, "web/upload")
|
buildNewsRss(c, "web/upload")
|
||||||
buildAddDoc(c, "web/upload")
|
buildAddDoc(c, "web/upload")
|
||||||
buildDocSamples(c, "web/upload")
|
buildDocSamples(c, "web/upload")
|
||||||
|
|
|
||||||
72
web/babelpkglist.nim
Normal file
72
web/babelpkglist.nim
Normal file
|
|
@ -0,0 +1,72 @@
|
||||||
|
import base64, strutils, json, htmlgen, dom, algorithm
|
||||||
|
|
||||||
|
type
|
||||||
|
TData = object
|
||||||
|
content {.importc.}: cstring
|
||||||
|
|
||||||
|
proc decodeContent(content: string): string =
|
||||||
|
result = ""
|
||||||
|
for line in content.splitLines:
|
||||||
|
if line != "":
|
||||||
|
result.add decode(line)
|
||||||
|
|
||||||
|
proc contains(x: seq[PJSonNode], s: string): bool =
|
||||||
|
for i in x:
|
||||||
|
assert i.kind == JString
|
||||||
|
if i.str == s: return true
|
||||||
|
|
||||||
|
proc processContent(content: string) =
|
||||||
|
var jsonDoc = parseJson(content)
|
||||||
|
assert jsonDoc.kind == JArray
|
||||||
|
var jsonArr = jsonDoc.elems
|
||||||
|
|
||||||
|
jsonArr.sort do (x, y: PJsonNode) -> int:
|
||||||
|
system.cmp(x["name"].str, y["name"].str)
|
||||||
|
|
||||||
|
var
|
||||||
|
officialList = ""
|
||||||
|
officialCount = 0
|
||||||
|
unofficialList = ""
|
||||||
|
unofficialCount = 0
|
||||||
|
|
||||||
|
for pkg in jsonArr:
|
||||||
|
assert pkg.kind == JObject
|
||||||
|
let pkgWeb =
|
||||||
|
if pkg.hasKey("web"): pkg["web"].str
|
||||||
|
else: pkg["url"].str
|
||||||
|
let listItem = li(a(href=pkgWeb, pkg["name"].str), " ", pkg["description"].str)
|
||||||
|
if pkg["url"].str.startsWith("git://github.com/nimrod-code") or
|
||||||
|
"official" in pkg["tags"].elems:
|
||||||
|
officialCount.inc
|
||||||
|
officialList.add listItem & "\n"
|
||||||
|
else:
|
||||||
|
unofficialCount.inc
|
||||||
|
unofficialList.add listItem & "\n"
|
||||||
|
|
||||||
|
var officialPkgListDiv = document.getElementById("officialPkgList")
|
||||||
|
|
||||||
|
officialPkgListDiv.innerHTML.add(
|
||||||
|
p("There are currently " & $officialCount &
|
||||||
|
" official packages in the Babel package repository.") &
|
||||||
|
ul(officialList)
|
||||||
|
)
|
||||||
|
|
||||||
|
var unofficialPkgListDiv = document.getElementById("unofficialPkgList")
|
||||||
|
|
||||||
|
unofficialPkgListDiv.innerHTML.add(
|
||||||
|
p("There are currently " & $unofficialCount &
|
||||||
|
" unofficial packages in the Babel package repository.") &
|
||||||
|
ul(unofficialList)
|
||||||
|
)
|
||||||
|
|
||||||
|
proc gotPackageList(apiReply: TData) {.exportc.} =
|
||||||
|
let decoded = decodeContent($apiReply.content)
|
||||||
|
try:
|
||||||
|
processContent(decoded)
|
||||||
|
except:
|
||||||
|
var officialPkgListDiv = document.getElementById("officialPkgList")
|
||||||
|
var unofficialPkgListDiv = document.getElementById("unofficialPkgList")
|
||||||
|
let msg = p("Unable to retrieve package list: ",
|
||||||
|
code(getCurrentExceptionMsg()))
|
||||||
|
officialPkgListDiv.innerHTML = msg
|
||||||
|
unofficialPkgListDiv.innerHTML = msg
|
||||||
Loading…
Add table
Add a link
Reference in a new issue