Merge branch 'devel' of https://github.com/nim-lang/Nim into devel
This commit is contained in:
commit
1fbeedaba2
18 changed files with 325 additions and 222 deletions
|
|
@ -50,10 +50,10 @@ proc importcSymbol*(sym: PSym): PNode =
|
||||||
# that contains the address instead:
|
# that contains the address instead:
|
||||||
result = newNodeIT(nkPtrLit, sym.info, sym.typ)
|
result = newNodeIT(nkPtrLit, sym.info, sym.typ)
|
||||||
case name
|
case name
|
||||||
of "stdin": result.intVal = cast[TAddress](system.stdin)
|
of "stdin": result.intVal = cast[ByteAddress](system.stdin)
|
||||||
of "stdout": result.intVal = cast[TAddress](system.stdout)
|
of "stdout": result.intVal = cast[ByteAddress](system.stdout)
|
||||||
of "stderr": result.intVal = cast[TAddress](system.stderr)
|
of "stderr": result.intVal = cast[ByteAddress](system.stderr)
|
||||||
of "vmErrnoWrapper": result.intVal = cast[TAddress](myerrno)
|
of "vmErrnoWrapper": result.intVal = cast[ByteAddress](myerrno)
|
||||||
else:
|
else:
|
||||||
let lib = sym.annex
|
let lib = sym.annex
|
||||||
if lib != nil and lib.path.kind notin {nkStrLit..nkTripleStrLit}:
|
if lib != nil and lib.path.kind notin {nkStrLit..nkTripleStrLit}:
|
||||||
|
|
@ -71,7 +71,7 @@ proc importcSymbol*(sym: PSym): PNode =
|
||||||
else: lib.path.strVal, sym.info)
|
else: lib.path.strVal, sym.info)
|
||||||
theAddr = dllhandle.symAddr(name)
|
theAddr = dllhandle.symAddr(name)
|
||||||
if theAddr.isNil: globalError(sym.info, "cannot import: " & sym.name.s)
|
if theAddr.isNil: globalError(sym.info, "cannot import: " & sym.name.s)
|
||||||
result.intVal = cast[TAddress](theAddr)
|
result.intVal = cast[ByteAddress](theAddr)
|
||||||
|
|
||||||
proc mapType(t: ast.PType): ptr libffi.TType =
|
proc mapType(t: ast.PType): ptr libffi.TType =
|
||||||
if t == nil: return addr libffi.type_void
|
if t == nil: return addr libffi.type_void
|
||||||
|
|
@ -107,7 +107,7 @@ proc mapCallConv(cc: TCallingConvention, info: TLineInfo): TABI =
|
||||||
template rd(T, p: expr): expr {.immediate.} = (cast[ptr T](p))[]
|
template rd(T, p: expr): expr {.immediate.} = (cast[ptr T](p))[]
|
||||||
template wr(T, p, v: expr) {.immediate.} = (cast[ptr T](p))[] = v
|
template wr(T, p, v: expr) {.immediate.} = (cast[ptr T](p))[] = v
|
||||||
template `+!`(x, y: expr): expr {.immediate.} =
|
template `+!`(x, y: expr): expr {.immediate.} =
|
||||||
cast[pointer](cast[TAddress](x) + y)
|
cast[pointer](cast[ByteAddress](x) + y)
|
||||||
|
|
||||||
proc packSize(v: PNode, typ: PType): int =
|
proc packSize(v: PNode, typ: PType): int =
|
||||||
## computes the size of the blob
|
## computes the size of the blob
|
||||||
|
|
@ -363,13 +363,13 @@ proc unpack(x: pointer, typ: PType, n: PNode): PNode =
|
||||||
# in their unboxed representation so nothing it to be unpacked:
|
# in their unboxed representation so nothing it to be unpacked:
|
||||||
result = n
|
result = n
|
||||||
else:
|
else:
|
||||||
awi(nkPtrLit, cast[TAddress](p))
|
awi(nkPtrLit, cast[ByteAddress](p))
|
||||||
of tyPtr, tyRef, tyVar:
|
of tyPtr, tyRef, tyVar:
|
||||||
let p = rd(pointer, x)
|
let p = rd(pointer, x)
|
||||||
if p.isNil:
|
if p.isNil:
|
||||||
setNil()
|
setNil()
|
||||||
elif n == nil or n.kind == nkPtrLit:
|
elif n == nil or n.kind == nkPtrLit:
|
||||||
awi(nkPtrLit, cast[TAddress](p))
|
awi(nkPtrLit, cast[ByteAddress](p))
|
||||||
elif n != nil and n.len == 1:
|
elif n != nil and n.len == 1:
|
||||||
internalAssert n.kind == nkRefTy
|
internalAssert n.kind == nkRefTy
|
||||||
n.sons[0] = unpack(p, typ.lastSon, n.sons[0])
|
n.sons[0] = unpack(p, typ.lastSon, n.sons[0])
|
||||||
|
|
|
||||||
|
|
@ -163,8 +163,31 @@ proc mangleName(s: PSym): Rope =
|
||||||
add(result, rope(s.id))
|
add(result, rope(s.id))
|
||||||
s.loc.r = result
|
s.loc.r = result
|
||||||
|
|
||||||
proc makeJSString(s: string): Rope =
|
proc escapeJSString(s: string): string =
|
||||||
(if s.isNil: "null".rope else: strutils.escape(s).rope)
|
result = newStringOfCap(s.len + s.len shr 2)
|
||||||
|
result.add("\"")
|
||||||
|
for c in items(s):
|
||||||
|
case c
|
||||||
|
of '\l': result.add("\\n")
|
||||||
|
of '\r': result.add("\\r")
|
||||||
|
of '\t': result.add("\\t")
|
||||||
|
of '\b': result.add("\\b")
|
||||||
|
of '\a': result.add("\\a")
|
||||||
|
of '\e': result.add("\\e")
|
||||||
|
of '\v': result.add("\\v")
|
||||||
|
of '\\': result.add("\\\\")
|
||||||
|
of '\'': result.add("\\'")
|
||||||
|
of '\"': result.add("\\\"")
|
||||||
|
else: add(result, c)
|
||||||
|
result.add("\"")
|
||||||
|
|
||||||
|
proc makeJSString(s: string, escapeNonAscii = true): Rope =
|
||||||
|
if s.isNil:
|
||||||
|
result = "null".rope
|
||||||
|
elif escapeNonAscii:
|
||||||
|
result = strutils.escape(s).rope
|
||||||
|
else:
|
||||||
|
result = escapeJSString(s).rope
|
||||||
|
|
||||||
include jstypes
|
include jstypes
|
||||||
|
|
||||||
|
|
@ -264,7 +287,7 @@ const # magic checked op; magic unchecked op; checked op; unchecked op
|
||||||
["", "", "($1 - $2)", "($1 - $2)"], # SubF64
|
["", "", "($1 - $2)", "($1 - $2)"], # SubF64
|
||||||
["", "", "($1 * $2)", "($1 * $2)"], # MulF64
|
["", "", "($1 * $2)", "($1 * $2)"], # MulF64
|
||||||
["", "", "($1 / $2)", "($1 / $2)"], # DivF64
|
["", "", "($1 / $2)", "($1 / $2)"], # DivF64
|
||||||
["", "", "($1 >>> $2)", "($1 >>> $2)"], # ShrI
|
["", "", "", ""], # ShrI
|
||||||
["", "", "($1 << $2)", "($1 << $2)"], # ShlI
|
["", "", "($1 << $2)", "($1 << $2)"], # ShlI
|
||||||
["", "", "($1 & $2)", "($1 & $2)"], # BitandI
|
["", "", "($1 & $2)", "($1 & $2)"], # BitandI
|
||||||
["", "", "($1 | $2)", "($1 | $2)"], # BitorI
|
["", "", "($1 | $2)", "($1 | $2)"], # BitorI
|
||||||
|
|
@ -273,21 +296,21 @@ const # magic checked op; magic unchecked op; checked op; unchecked op
|
||||||
["nimMax", "nimMax", "nimMax($1, $2)", "nimMax($1, $2)"], # MaxI
|
["nimMax", "nimMax", "nimMax($1, $2)", "nimMax($1, $2)"], # MaxI
|
||||||
["nimMin", "nimMin", "nimMin($1, $2)", "nimMin($1, $2)"], # MinF64
|
["nimMin", "nimMin", "nimMin($1, $2)", "nimMin($1, $2)"], # MinF64
|
||||||
["nimMax", "nimMax", "nimMax($1, $2)", "nimMax($1, $2)"], # MaxF64
|
["nimMax", "nimMax", "nimMax($1, $2)", "nimMax($1, $2)"], # MaxF64
|
||||||
["addU", "addU", "addU($1, $2)", "addU($1, $2)"], # addU
|
["", "", "", ""], # addU
|
||||||
["subU", "subU", "subU($1, $2)", "subU($1, $2)"], # subU
|
["", "", "", ""], # subU
|
||||||
["mulU", "mulU", "mulU($1, $2)", "mulU($1, $2)"], # mulU
|
["", "", "", ""], # mulU
|
||||||
["divU", "divU", "divU($1, $2)", "divU($1, $2)"], # divU
|
["", "", "", ""], # divU
|
||||||
["modU", "modU", "modU($1, $2)", "modU($1, $2)"], # modU
|
["", "", "($1 % $2)", "($1 % $2)"], # modU
|
||||||
["", "", "($1 == $2)", "($1 == $2)"], # EqI
|
["", "", "($1 == $2)", "($1 == $2)"], # EqI
|
||||||
["", "", "($1 <= $2)", "($1 <= $2)"], # LeI
|
["", "", "($1 <= $2)", "($1 <= $2)"], # LeI
|
||||||
["", "", "($1 < $2)", "($1 < $2)"], # LtI
|
["", "", "($1 < $2)", "($1 < $2)"], # LtI
|
||||||
["", "", "($1 == $2)", "($1 == $2)"], # EqF64
|
["", "", "($1 == $2)", "($1 == $2)"], # EqF64
|
||||||
["", "", "($1 <= $2)", "($1 <= $2)"], # LeF64
|
["", "", "($1 <= $2)", "($1 <= $2)"], # LeF64
|
||||||
["", "", "($1 < $2)", "($1 < $2)"], # LtF64
|
["", "", "($1 < $2)", "($1 < $2)"], # LtF64
|
||||||
["leU", "leU", "leU($1, $2)", "leU($1, $2)"], # leU
|
["", "", "($1 <= $2)", "($1 <= $2)"], # leU
|
||||||
["ltU", "ltU", "ltU($1, $2)", "ltU($1, $2)"], # ltU
|
["", "", "($1 < $2)", "($1 < $2)"], # ltU
|
||||||
["leU64", "leU64", "leU64($1, $2)", "leU64($1, $2)"], # leU64
|
["", "", "($1 <= $2)", "($1 <= $2)"], # leU64
|
||||||
["ltU64", "ltU64", "ltU64($1, $2)", "ltU64($1, $2)"], # ltU64
|
["", "", "($1 < $2)", "($1 < $2)"], # ltU64
|
||||||
["", "", "($1 == $2)", "($1 == $2)"], # EqEnum
|
["", "", "($1 == $2)", "($1 == $2)"], # EqEnum
|
||||||
["", "", "($1 <= $2)", "($1 <= $2)"], # LeEnum
|
["", "", "($1 <= $2)", "($1 <= $2)"], # LeEnum
|
||||||
["", "", "($1 < $2)", "($1 < $2)"], # LtEnum
|
["", "", "($1 < $2)", "($1 < $2)"], # LtEnum
|
||||||
|
|
@ -336,90 +359,6 @@ const # magic checked op; magic unchecked op; checked op; unchecked op
|
||||||
["cstrToNimstr", "cstrToNimstr", "cstrToNimstr($1)", "cstrToNimstr($1)"],
|
["cstrToNimstr", "cstrToNimstr", "cstrToNimstr($1)", "cstrToNimstr($1)"],
|
||||||
["", "", "$1", "$1"]]
|
["", "", "$1", "$1"]]
|
||||||
|
|
||||||
luaOps: TMagicOps = [
|
|
||||||
["addInt", "", "addInt($1, $2)", "($1 + $2)"], # AddI
|
|
||||||
["subInt", "", "subInt($1, $2)", "($1 - $2)"], # SubI
|
|
||||||
["mulInt", "", "mulInt($1, $2)", "($1 * $2)"], # MulI
|
|
||||||
["divInt", "", "divInt($1, $2)", "Math.floor($1 / $2)"], # DivI
|
|
||||||
["modInt", "", "modInt($1, $2)", "Math.floor($1 % $2)"], # ModI
|
|
||||||
["addInt", "", "addInt($1, $2)", "($1 + $2)"], # Succ
|
|
||||||
["subInt", "", "subInt($1, $2)", "($1 - $2)"], # Pred
|
|
||||||
["", "", "($1 + $2)", "($1 + $2)"], # AddF64
|
|
||||||
["", "", "($1 - $2)", "($1 - $2)"], # SubF64
|
|
||||||
["", "", "($1 * $2)", "($1 * $2)"], # MulF64
|
|
||||||
["", "", "($1 / $2)", "($1 / $2)"], # DivF64
|
|
||||||
["", "", "($1 >>> $2)", "($1 >>> $2)"], # ShrI
|
|
||||||
["", "", "($1 << $2)", "($1 << $2)"], # ShlI
|
|
||||||
["", "", "($1 & $2)", "($1 & $2)"], # BitandI
|
|
||||||
["", "", "($1 | $2)", "($1 | $2)"], # BitorI
|
|
||||||
["", "", "($1 ^ $2)", "($1 ^ $2)"], # BitxorI
|
|
||||||
["nimMin", "nimMin", "nimMin($1, $2)", "nimMin($1, $2)"], # MinI
|
|
||||||
["nimMax", "nimMax", "nimMax($1, $2)", "nimMax($1, $2)"], # MaxI
|
|
||||||
["nimMin", "nimMin", "nimMin($1, $2)", "nimMin($1, $2)"], # MinF64
|
|
||||||
["nimMax", "nimMax", "nimMax($1, $2)", "nimMax($1, $2)"], # MaxF64
|
|
||||||
["addU", "addU", "addU($1, $2)", "addU($1, $2)"], # addU
|
|
||||||
["subU", "subU", "subU($1, $2)", "subU($1, $2)"], # subU
|
|
||||||
["mulU", "mulU", "mulU($1, $2)", "mulU($1, $2)"], # mulU
|
|
||||||
["divU", "divU", "divU($1, $2)", "divU($1, $2)"], # divU
|
|
||||||
["modU", "modU", "modU($1, $2)", "modU($1, $2)"], # modU
|
|
||||||
["", "", "($1 == $2)", "($1 == $2)"], # EqI
|
|
||||||
["", "", "($1 <= $2)", "($1 <= $2)"], # LeI
|
|
||||||
["", "", "($1 < $2)", "($1 < $2)"], # LtI
|
|
||||||
["", "", "($1 == $2)", "($1 == $2)"], # EqF64
|
|
||||||
["", "", "($1 <= $2)", "($1 <= $2)"], # LeF64
|
|
||||||
["", "", "($1 < $2)", "($1 < $2)"], # LtF64
|
|
||||||
["leU", "leU", "leU($1, $2)", "leU($1, $2)"], # leU
|
|
||||||
["ltU", "ltU", "ltU($1, $2)", "ltU($1, $2)"], # ltU
|
|
||||||
["leU64", "leU64", "leU64($1, $2)", "leU64($1, $2)"], # leU64
|
|
||||||
["ltU64", "ltU64", "ltU64($1, $2)", "ltU64($1, $2)"], # ltU64
|
|
||||||
["", "", "($1 == $2)", "($1 == $2)"], # EqEnum
|
|
||||||
["", "", "($1 <= $2)", "($1 <= $2)"], # LeEnum
|
|
||||||
["", "", "($1 < $2)", "($1 < $2)"], # LtEnum
|
|
||||||
["", "", "($1 == $2)", "($1 == $2)"], # EqCh
|
|
||||||
["", "", "($1 <= $2)", "($1 <= $2)"], # LeCh
|
|
||||||
["", "", "($1 < $2)", "($1 < $2)"], # LtCh
|
|
||||||
["", "", "($1 == $2)", "($1 == $2)"], # EqB
|
|
||||||
["", "", "($1 <= $2)", "($1 <= $2)"], # LeB
|
|
||||||
["", "", "($1 < $2)", "($1 < $2)"], # LtB
|
|
||||||
["", "", "($1 == $2)", "($1 == $2)"], # EqRef
|
|
||||||
["", "", "($1 == $2)", "($1 == $2)"], # EqUntracedRef
|
|
||||||
["", "", "($1 <= $2)", "($1 <= $2)"], # LePtr
|
|
||||||
["", "", "($1 < $2)", "($1 < $2)"], # LtPtr
|
|
||||||
["", "", "($1 == $2)", "($1 == $2)"], # EqCString
|
|
||||||
["", "", "($1 != $2)", "($1 != $2)"], # Xor
|
|
||||||
["", "", "($1 == $2)", "($1 == $2)"], # EqProc
|
|
||||||
["negInt", "", "negInt($1)", "-($1)"], # UnaryMinusI
|
|
||||||
["negInt64", "", "negInt64($1)", "-($1)"], # UnaryMinusI64
|
|
||||||
["absInt", "", "absInt($1)", "Math.abs($1)"], # AbsI
|
|
||||||
["", "", "not ($1)", "not ($1)"], # Not
|
|
||||||
["", "", "+($1)", "+($1)"], # UnaryPlusI
|
|
||||||
["", "", "~($1)", "~($1)"], # BitnotI
|
|
||||||
["", "", "+($1)", "+($1)"], # UnaryPlusF64
|
|
||||||
["", "", "-($1)", "-($1)"], # UnaryMinusF64
|
|
||||||
["", "", "Math.abs($1)", "Math.abs($1)"], # AbsF64
|
|
||||||
["Ze8ToI", "Ze8ToI", "Ze8ToI($1)", "Ze8ToI($1)"], # mZe8ToI
|
|
||||||
["Ze8ToI64", "Ze8ToI64", "Ze8ToI64($1)", "Ze8ToI64($1)"], # mZe8ToI64
|
|
||||||
["Ze16ToI", "Ze16ToI", "Ze16ToI($1)", "Ze16ToI($1)"], # mZe16ToI
|
|
||||||
["Ze16ToI64", "Ze16ToI64", "Ze16ToI64($1)", "Ze16ToI64($1)"], # mZe16ToI64
|
|
||||||
["Ze32ToI64", "Ze32ToI64", "Ze32ToI64($1)", "Ze32ToI64($1)"], # mZe32ToI64
|
|
||||||
["ZeIToI64", "ZeIToI64", "ZeIToI64($1)", "ZeIToI64($1)"], # mZeIToI64
|
|
||||||
["toU8", "toU8", "toU8($1)", "toU8($1)"], # toU8
|
|
||||||
["toU16", "toU16", "toU16($1)", "toU16($1)"], # toU16
|
|
||||||
["toU32", "toU32", "toU32($1)", "toU32($1)"], # toU32
|
|
||||||
["", "", "$1", "$1"], # ToFloat
|
|
||||||
["", "", "$1", "$1"], # ToBiggestFloat
|
|
||||||
["", "", "Math.floor($1)", "Math.floor($1)"], # ToInt
|
|
||||||
["", "", "Math.floor($1)", "Math.floor($1)"], # ToBiggestInt
|
|
||||||
["nimCharToStr", "nimCharToStr", "nimCharToStr($1)", "nimCharToStr($1)"],
|
|
||||||
["nimBoolToStr", "nimBoolToStr", "nimBoolToStr($1)", "nimBoolToStr($1)"], [
|
|
||||||
"cstrToNimstr", "cstrToNimstr", "cstrToNimstr(($1)+\"\")",
|
|
||||||
"cstrToNimstr(($1)+\"\")"], ["cstrToNimstr", "cstrToNimstr",
|
|
||||||
"cstrToNimstr(($1)+\"\")",
|
|
||||||
"cstrToNimstr(($1)+\"\")"], ["cstrToNimstr",
|
|
||||||
"cstrToNimstr", "cstrToNimstr(($1)+\"\")", "cstrToNimstr(($1)+\"\")"],
|
|
||||||
["cstrToNimstr", "cstrToNimstr", "cstrToNimstr($1)", "cstrToNimstr($1)"],
|
|
||||||
["", "", "$1", "$1"]]
|
|
||||||
|
|
||||||
proc binaryExpr(p: PProc, n: PNode, r: var TCompRes, magic, frmt: string) =
|
proc binaryExpr(p: PProc, n: PNode, r: var TCompRes, magic, frmt: string) =
|
||||||
var x, y: TCompRes
|
var x, y: TCompRes
|
||||||
useMagic(p, magic)
|
useMagic(p, magic)
|
||||||
|
|
@ -428,6 +367,23 @@ proc binaryExpr(p: PProc, n: PNode, r: var TCompRes, magic, frmt: string) =
|
||||||
r.res = frmt % [x.rdLoc, y.rdLoc]
|
r.res = frmt % [x.rdLoc, y.rdLoc]
|
||||||
r.kind = resExpr
|
r.kind = resExpr
|
||||||
|
|
||||||
|
proc unsignedTrimmer(size: BiggestInt): Rope =
|
||||||
|
case size
|
||||||
|
of 1: rope"& 0xff"
|
||||||
|
of 2: rope"& 0xffff"
|
||||||
|
of 4: rope">>> 0"
|
||||||
|
else: rope""
|
||||||
|
|
||||||
|
proc binaryUintExpr(p: PProc, n: PNode, r: var TCompRes, op: string, reassign: bool = false) =
|
||||||
|
var x, y: TCompRes
|
||||||
|
gen(p, n.sons[1], x)
|
||||||
|
gen(p, n.sons[2], y)
|
||||||
|
let trimmer = unsignedTrimmer(n[1].typ.skipTypes(abstractRange).size)
|
||||||
|
if reassign:
|
||||||
|
r.res = "$1 = (($1 $2 $3) $4)" % [x.rdLoc, rope op, y.rdLoc, trimmer]
|
||||||
|
else:
|
||||||
|
r.res = "(($1 $2 $3) $4)" % [x.rdLoc, rope op, y.rdLoc, trimmer]
|
||||||
|
|
||||||
proc ternaryExpr(p: PProc, n: PNode, r: var TCompRes, magic, frmt: string) =
|
proc ternaryExpr(p: PProc, n: PNode, r: var TCompRes, magic, frmt: string) =
|
||||||
var x, y, z: TCompRes
|
var x, y, z: TCompRes
|
||||||
useMagic(p, magic)
|
useMagic(p, magic)
|
||||||
|
|
@ -455,10 +411,22 @@ proc arithAux(p: PProc, n: PNode, r: var TCompRes, op: TMagic, ops: TMagicOps) =
|
||||||
else:
|
else:
|
||||||
gen(p, n.sons[1], r)
|
gen(p, n.sons[1], r)
|
||||||
r.res = ops[op][i + 2] % [r.rdLoc]
|
r.res = ops[op][i + 2] % [r.rdLoc]
|
||||||
r.kind = resExpr
|
|
||||||
|
|
||||||
proc arith(p: PProc, n: PNode, r: var TCompRes, op: TMagic) =
|
proc arith(p: PProc, n: PNode, r: var TCompRes, op: TMagic) =
|
||||||
arithAux(p, n, r, op, jsOps | luaOps)
|
case op
|
||||||
|
of mAddU: binaryUintExpr(p, n, r, "+")
|
||||||
|
of mSubU: binaryUintExpr(p, n, r, "-")
|
||||||
|
of mMulU: binaryUintExpr(p, n, r, "*")
|
||||||
|
of mDivU: binaryUintExpr(p, n, r, "/")
|
||||||
|
of mShrI:
|
||||||
|
var x, y: TCompRes
|
||||||
|
gen(p, n.sons[1], x)
|
||||||
|
gen(p, n.sons[2], y)
|
||||||
|
let trimmer = unsignedTrimmer(n[1].typ.skipTypes(abstractRange).size)
|
||||||
|
r.res = "(($1 $2) >>> $3)" % [x.rdLoc, trimmer, y.rdLoc]
|
||||||
|
else:
|
||||||
|
arithAux(p, n, r, op, jsOps)
|
||||||
|
r.kind = resExpr
|
||||||
|
|
||||||
proc genLineDir(p: PProc, n: PNode) =
|
proc genLineDir(p: PProc, n: PNode) =
|
||||||
let line = toLinenumber(n.info)
|
let line = toLinenumber(n.info)
|
||||||
|
|
@ -632,7 +600,7 @@ proc genCaseJS(p: PProc, n: PNode, r: var TCompRes) =
|
||||||
if stringSwitch:
|
if stringSwitch:
|
||||||
case e.kind
|
case e.kind
|
||||||
of nkStrLit..nkTripleStrLit: addf(p.body, "case $1: ",
|
of nkStrLit..nkTripleStrLit: addf(p.body, "case $1: ",
|
||||||
[makeJSString(e.strVal)])
|
[makeJSString(e.strVal, false)])
|
||||||
else: internalError(e.info, "jsgen.genCaseStmt: 2")
|
else: internalError(e.info, "jsgen.genCaseStmt: 2")
|
||||||
else:
|
else:
|
||||||
gen(p, e, cond)
|
gen(p, e, cond)
|
||||||
|
|
@ -1388,7 +1356,7 @@ proc genMagic(p: PProc, n: PNode, r: var TCompRes) =
|
||||||
of mEqStr: binaryExpr(p, n, r, "eqStrings", "eqStrings($1, $2)")
|
of mEqStr: binaryExpr(p, n, r, "eqStrings", "eqStrings($1, $2)")
|
||||||
of mLeStr: binaryExpr(p, n, r, "cmpStrings", "(cmpStrings($1, $2) <= 0)")
|
of mLeStr: binaryExpr(p, n, r, "cmpStrings", "(cmpStrings($1, $2) <= 0)")
|
||||||
of mLtStr: binaryExpr(p, n, r, "cmpStrings", "(cmpStrings($1, $2) < 0)")
|
of mLtStr: binaryExpr(p, n, r, "cmpStrings", "(cmpStrings($1, $2) < 0)")
|
||||||
of mIsNil: unaryExpr(p, n, r, "", "$1 == null")
|
of mIsNil: unaryExpr(p, n, r, "", "($1 === null)")
|
||||||
of mEnumToStr: genRepr(p, n, r)
|
of mEnumToStr: genRepr(p, n, r)
|
||||||
of mNew, mNewFinalize: genNew(p, n)
|
of mNew, mNewFinalize: genNew(p, n)
|
||||||
of mSizeOf: r.res = rope(getSize(n.sons[1].typ))
|
of mSizeOf: r.res = rope(getSize(n.sons[1].typ))
|
||||||
|
|
@ -1406,9 +1374,15 @@ proc genMagic(p: PProc, n: PNode, r: var TCompRes) =
|
||||||
else:
|
else:
|
||||||
unaryExpr(p, n, r, "", "($1 != null ? ($1.length-1) : -1)")
|
unaryExpr(p, n, r, "", "($1 != null ? ($1.length-1) : -1)")
|
||||||
of mInc:
|
of mInc:
|
||||||
|
if n[1].typ.skipTypes(abstractRange).kind in tyUInt .. tyUInt64:
|
||||||
|
binaryUintExpr(p, n, r, "+", true)
|
||||||
|
else:
|
||||||
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, "addInt", "$1 = addInt($1, $2)")
|
else: binaryExpr(p, n, r, "addInt", "$1 = addInt($1, $2)")
|
||||||
of ast.mDec:
|
of ast.mDec:
|
||||||
|
if n[1].typ.skipTypes(abstractRange).kind in tyUInt .. tyUInt64:
|
||||||
|
binaryUintExpr(p, n, r, "-", true)
|
||||||
|
else:
|
||||||
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; $1[$1.length-1] = 0")
|
of mSetLengthStr: binaryExpr(p, n, r, "", "$1.length = $2+1; $1[$1.length-1] = 0")
|
||||||
|
|
@ -1627,6 +1601,37 @@ proc genPragma(p: PProc, n: PNode) =
|
||||||
of wEmit: genAsmOrEmitStmt(p, it.sons[1])
|
of wEmit: genAsmOrEmitStmt(p, it.sons[1])
|
||||||
else: discard
|
else: discard
|
||||||
|
|
||||||
|
proc genCast(p: PProc, n: PNode, r: var TCompRes) =
|
||||||
|
var dest = skipTypes(n.typ, abstractVarRange)
|
||||||
|
var src = skipTypes(n.sons[1].typ, abstractVarRange)
|
||||||
|
gen(p, n.sons[1], r)
|
||||||
|
if dest.kind == src.kind:
|
||||||
|
# no-op conversion
|
||||||
|
return
|
||||||
|
let toInt = (dest.kind in tyInt .. tyInt32)
|
||||||
|
let toUint = (dest.kind in tyUInt .. tyUInt32)
|
||||||
|
let fromInt = (src.kind in tyInt .. tyInt32)
|
||||||
|
let fromUint = (src.kind in tyUInt .. tyUInt32)
|
||||||
|
|
||||||
|
if toUint and (fromInt or fromUint):
|
||||||
|
let trimmer = unsignedTrimmer(dest.size)
|
||||||
|
r.res = "($1 $2)" % [r.res, trimmer]
|
||||||
|
elif toInt:
|
||||||
|
if fromInt:
|
||||||
|
let trimmer = unsignedTrimmer(dest.size)
|
||||||
|
r.res = "($1 $2)" % [r.res, trimmer]
|
||||||
|
elif fromUint:
|
||||||
|
if src.size == 4 and dest.size == 4:
|
||||||
|
r.res = "($1|0)" % [r.res]
|
||||||
|
else:
|
||||||
|
let trimmer = unsignedTrimmer(dest.size)
|
||||||
|
let minuend = case dest.size
|
||||||
|
of 1: "0xfe"
|
||||||
|
of 2: "0xfffe"
|
||||||
|
of 4: "0xfffffffe"
|
||||||
|
else: ""
|
||||||
|
r.res = "($1 - ($2 $3))" % [rope minuend, r.res, trimmer]
|
||||||
|
|
||||||
proc gen(p: PProc, n: PNode, r: var TCompRes) =
|
proc gen(p: PProc, n: PNode, r: var TCompRes) =
|
||||||
r.typ = etyNone
|
r.typ = etyNone
|
||||||
r.kind = resNone
|
r.kind = resNone
|
||||||
|
|
@ -1635,7 +1640,7 @@ proc gen(p: PProc, n: PNode, r: var TCompRes) =
|
||||||
case n.kind
|
case n.kind
|
||||||
of nkSym:
|
of nkSym:
|
||||||
genSym(p, n, r)
|
genSym(p, n, r)
|
||||||
of nkCharLit..nkInt64Lit:
|
of nkCharLit..nkUInt32Lit:
|
||||||
if n.typ.kind == tyBool:
|
if n.typ.kind == tyBool:
|
||||||
r.res = if n.intVal == 0: rope"false" else: rope"true"
|
r.res = if n.intVal == 0: rope"false" else: rope"true"
|
||||||
else:
|
else:
|
||||||
|
|
@ -1654,10 +1659,10 @@ proc gen(p: PProc, n: PNode, r: var TCompRes) =
|
||||||
r.kind = resExpr
|
r.kind = resExpr
|
||||||
of nkStrLit..nkTripleStrLit:
|
of nkStrLit..nkTripleStrLit:
|
||||||
if skipTypes(n.typ, abstractVarRange).kind == tyString:
|
if skipTypes(n.typ, abstractVarRange).kind == tyString:
|
||||||
useMagic(p, "cstrToNimstr")
|
useMagic(p, "makeNimstrLit")
|
||||||
r.res = "cstrToNimstr($1)" % [makeJSString(n.strVal)]
|
r.res = "makeNimstrLit($1)" % [makeJSString(n.strVal)]
|
||||||
else:
|
else:
|
||||||
r.res = makeJSString(n.strVal)
|
r.res = makeJSString(n.strVal, false)
|
||||||
r.kind = resExpr
|
r.kind = resExpr
|
||||||
of nkFloatLit..nkFloat64Lit:
|
of nkFloatLit..nkFloat64Lit:
|
||||||
let f = n.floatVal
|
let f = n.floatVal
|
||||||
|
|
@ -1688,7 +1693,7 @@ proc gen(p: PProc, n: PNode, r: var TCompRes) =
|
||||||
of nkCheckedFieldExpr: genCheckedFieldAccess(p, n, r)
|
of nkCheckedFieldExpr: genCheckedFieldAccess(p, n, r)
|
||||||
of nkObjDownConv: gen(p, n.sons[0], r)
|
of nkObjDownConv: gen(p, n.sons[0], r)
|
||||||
of nkObjUpConv: upConv(p, n, r)
|
of nkObjUpConv: upConv(p, n, r)
|
||||||
of nkCast: gen(p, n.sons[1], r)
|
of nkCast: genCast(p, n, r)
|
||||||
of nkChckRangeF: genRangeChck(p, n, r, "chckRangeF")
|
of nkChckRangeF: genRangeChck(p, n, r, "chckRangeF")
|
||||||
of nkChckRange64: genRangeChck(p, n, r, "chckRange64")
|
of nkChckRange64: genRangeChck(p, n, r, "chckRange64")
|
||||||
of nkChckRange: genRangeChck(p, n, r, "chckRange")
|
of nkChckRange: genRangeChck(p, n, r, "chckRange")
|
||||||
|
|
|
||||||
|
|
@ -1000,7 +1000,9 @@ JavaScript-compatible code you should remember the following:
|
||||||
- ``addr`` and ``ptr`` have slightly different semantic meaning in JavaScript.
|
- ``addr`` and ``ptr`` have slightly different semantic meaning in JavaScript.
|
||||||
It is recommended to avoid those if you're not sure how they are translated
|
It is recommended to avoid those if you're not sure how they are translated
|
||||||
to JavaScript.
|
to JavaScript.
|
||||||
- ``cast[T](x)`` in JavaScript is translated to ``(x)``.
|
- ``cast[T](x)`` in JavaScript is translated to ``(x)``, except for casting
|
||||||
|
between signed/unsigned ints, in which case it behaves as static cast in
|
||||||
|
C language.
|
||||||
- ``cstring`` in JavaScript means JavaScript string. It is a good practice to
|
- ``cstring`` in JavaScript means JavaScript string. It is a good practice to
|
||||||
use ``cstring`` only when it is semantically appropriate. E.g. don't use
|
use ``cstring`` only when it is semantically appropriate. E.g. don't use
|
||||||
``cstring`` as a binary data buffer.
|
``cstring`` as a binary data buffer.
|
||||||
|
|
|
||||||
|
|
@ -12,7 +12,7 @@
|
||||||
## report at program exit.
|
## report at program exit.
|
||||||
|
|
||||||
when not defined(profiler) and not defined(memProfiler):
|
when not defined(profiler) and not defined(memProfiler):
|
||||||
{.warning: "Profiling support is turned off!".}
|
{.error: "Profiling support is turned off! Enable profiling by passing `--profiler:on --stackTrace:on` to the compiler (see the Nim Compiler User Guide for more options).".}
|
||||||
|
|
||||||
# We don't want to profile the profiling code ...
|
# We don't want to profile the profiling code ...
|
||||||
{.push profiler: off.}
|
{.push profiler: off.}
|
||||||
|
|
|
||||||
|
|
@ -886,7 +886,7 @@ elif not defined(useNimRtl):
|
||||||
discard write(data.pErrorPipe[writeIdx], addr error, sizeof(error))
|
discard write(data.pErrorPipe[writeIdx], addr error, sizeof(error))
|
||||||
exitnow(1)
|
exitnow(1)
|
||||||
|
|
||||||
when defined(macosx) or defined(freebsd) or defined(netbsd) or defined(android):
|
when not defined(uClibc) and (not defined(linux) or defined(android)):
|
||||||
var environ {.importc.}: cstringArray
|
var environ {.importc.}: cstringArray
|
||||||
|
|
||||||
proc startProcessAfterFork(data: ptr StartProcessData) =
|
proc startProcessAfterFork(data: ptr StartProcessData) =
|
||||||
|
|
@ -916,17 +916,16 @@ elif not defined(useNimRtl):
|
||||||
discard fcntl(data.pErrorPipe[writeIdx], F_SETFD, FD_CLOEXEC)
|
discard fcntl(data.pErrorPipe[writeIdx], F_SETFD, FD_CLOEXEC)
|
||||||
|
|
||||||
if data.optionPoUsePath:
|
if data.optionPoUsePath:
|
||||||
when defined(macosx) or defined(freebsd) or defined(netbsd) or defined(android):
|
when defined(uClibc):
|
||||||
|
# uClibc environment (OpenWrt included) doesn't have the full execvpe
|
||||||
|
discard execve(data.sysCommand, data.sysArgs, data.sysEnv)
|
||||||
|
elif defined(linux) and not defined(android):
|
||||||
|
discard execvpe(data.sysCommand, data.sysArgs, data.sysEnv)
|
||||||
|
else:
|
||||||
# MacOSX doesn't have execvpe, so we need workaround.
|
# MacOSX doesn't have execvpe, so we need workaround.
|
||||||
# On MacOSX we can arrive here only from fork, so this is safe:
|
# On MacOSX we can arrive here only from fork, so this is safe:
|
||||||
environ = data.sysEnv
|
environ = data.sysEnv
|
||||||
discard execvp(data.sysCommand, data.sysArgs)
|
discard execvp(data.sysCommand, data.sysArgs)
|
||||||
else:
|
|
||||||
when defined(uClibc):
|
|
||||||
# uClibc environment (OpenWrt included) doesn't have the full execvpe
|
|
||||||
discard execve(data.sysCommand, data.sysArgs, data.sysEnv)
|
|
||||||
else:
|
|
||||||
discard execvpe(data.sysCommand, data.sysArgs, data.sysEnv)
|
|
||||||
else:
|
else:
|
||||||
discard execve(data.sysCommand, data.sysArgs, data.sysEnv)
|
discard execve(data.sysCommand, data.sysArgs, data.sysEnv)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -148,7 +148,10 @@ proc write*[T](s: Stream, x: T) =
|
||||||
proc write*(s: Stream, x: string) =
|
proc write*(s: Stream, x: string) =
|
||||||
## writes the string `x` to the the stream `s`. No length field or
|
## writes the string `x` to the the stream `s`. No length field or
|
||||||
## terminating zero is written.
|
## terminating zero is written.
|
||||||
|
when nimvm:
|
||||||
writeData(s, cstring(x), x.len)
|
writeData(s, cstring(x), x.len)
|
||||||
|
else:
|
||||||
|
if x.len > 0: writeData(s, unsafeAddr x[0], x.len)
|
||||||
|
|
||||||
proc writeLn*(s: Stream, args: varargs[string, `$`]) {.deprecated.} =
|
proc writeLn*(s: Stream, args: varargs[string, `$`]) {.deprecated.} =
|
||||||
## **Deprecated since version 0.11.4:** Use **writeLine** instead.
|
## **Deprecated since version 0.11.4:** Use **writeLine** instead.
|
||||||
|
|
|
||||||
|
|
@ -688,7 +688,7 @@ proc rawDealloc(a: var MemRegion, p: pointer) =
|
||||||
sysAssert(((cast[ByteAddress](p) and PageMask) - smallChunkOverhead()) %%
|
sysAssert(((cast[ByteAddress](p) and PageMask) - smallChunkOverhead()) %%
|
||||||
s == 0, "rawDealloc 3")
|
s == 0, "rawDealloc 3")
|
||||||
var f = cast[ptr FreeCell](p)
|
var f = cast[ptr FreeCell](p)
|
||||||
#echo("setting to nil: ", $cast[TAddress](addr(f.zeroField)))
|
#echo("setting to nil: ", $cast[ByteAddress](addr(f.zeroField)))
|
||||||
sysAssert(f.zeroField != 0, "rawDealloc 1")
|
sysAssert(f.zeroField != 0, "rawDealloc 1")
|
||||||
f.zeroField = 0
|
f.zeroField = 0
|
||||||
f.next = c.freeList
|
f.next = c.freeList
|
||||||
|
|
|
||||||
|
|
@ -659,7 +659,7 @@ when useMarkForDebug or useBackupGc:
|
||||||
proc stackMarkS(gch: var GcHeap, p: pointer) {.inline.} =
|
proc stackMarkS(gch: var GcHeap, p: pointer) {.inline.} =
|
||||||
# the addresses are not as cells on the stack, so turn them to cells:
|
# the addresses are not as cells on the stack, so turn them to cells:
|
||||||
var cell = usrToCell(p)
|
var cell = usrToCell(p)
|
||||||
var c = cast[TAddress](cell)
|
var c = cast[ByteAddress](cell)
|
||||||
if c >% PageSize:
|
if c >% PageSize:
|
||||||
# fast check: does it look like a cell?
|
# fast check: does it look like a cell?
|
||||||
var objStart = cast[PCell](interiorAllocatedPtr(gch.region, cell))
|
var objStart = cast[PCell](interiorAllocatedPtr(gch.region, cell))
|
||||||
|
|
@ -805,8 +805,8 @@ proc markThreadStacks(gch: var GcHeap) =
|
||||||
while it != nil:
|
while it != nil:
|
||||||
# mark registers:
|
# mark registers:
|
||||||
for i in 0 .. high(it.registers): gcMark(gch, it.registers[i])
|
for i in 0 .. high(it.registers): gcMark(gch, it.registers[i])
|
||||||
var sp = cast[TAddress](it.stackBottom)
|
var sp = cast[ByteAddress](it.stackBottom)
|
||||||
var max = cast[TAddress](it.stackTop)
|
var max = cast[ByteAddress](it.stackTop)
|
||||||
# XXX stack direction?
|
# XXX stack direction?
|
||||||
# XXX unroll this loop:
|
# XXX unroll this loop:
|
||||||
while sp <=% max:
|
while sp <=% max:
|
||||||
|
|
|
||||||
|
|
@ -131,9 +131,9 @@ when defined(sparc): # For SPARC architecture.
|
||||||
proc isOnStack(p: pointer): bool =
|
proc isOnStack(p: pointer): bool =
|
||||||
var stackTop {.volatile.}: pointer
|
var stackTop {.volatile.}: pointer
|
||||||
stackTop = addr(stackTop)
|
stackTop = addr(stackTop)
|
||||||
var b = cast[TAddress](gch.stackBottom)
|
var b = cast[ByteAddress](gch.stackBottom)
|
||||||
var a = cast[TAddress](stackTop)
|
var a = cast[ByteAddress](stackTop)
|
||||||
var x = cast[TAddress](p)
|
var x = cast[ByteAddress](p)
|
||||||
result = a <=% x and x <=% b
|
result = a <=% x and x <=% b
|
||||||
|
|
||||||
template forEachStackSlot(gch, gcMark: expr) {.immediate, dirty.} =
|
template forEachStackSlot(gch, gcMark: expr) {.immediate, dirty.} =
|
||||||
|
|
@ -150,7 +150,7 @@ when defined(sparc): # For SPARC architecture.
|
||||||
# Addresses decrease as the stack grows.
|
# Addresses decrease as the stack grows.
|
||||||
while sp <= max:
|
while sp <= max:
|
||||||
gcMark(gch, sp[])
|
gcMark(gch, sp[])
|
||||||
sp = cast[PPointer](cast[TAddress](sp) +% sizeof(pointer))
|
sp = cast[PPointer](cast[ByteAddress](sp) +% sizeof(pointer))
|
||||||
|
|
||||||
elif defined(ELATE):
|
elif defined(ELATE):
|
||||||
{.error: "stack marking code is to be written for this architecture".}
|
{.error: "stack marking code is to be written for this architecture".}
|
||||||
|
|
|
||||||
|
|
@ -165,15 +165,46 @@ proc SetConstr() {.varargs, asmNoStackFrame, compilerproc.} =
|
||||||
return result;
|
return result;
|
||||||
"""
|
"""
|
||||||
|
|
||||||
proc cstrToNimstr(c: cstring): string {.asmNoStackFrame, compilerproc.} =
|
proc makeNimstrLit(c: cstring): string {.asmNoStackFrame, compilerproc.} =
|
||||||
asm """
|
{.emit: """
|
||||||
var result = [];
|
var ln = `c`.length;
|
||||||
for (var i = 0; i < `c`.length; ++i) {
|
var result = new Array(ln + 1);
|
||||||
|
var i = 0;
|
||||||
|
for (; i < ln; ++i) {
|
||||||
result[i] = `c`.charCodeAt(i);
|
result[i] = `c`.charCodeAt(i);
|
||||||
}
|
}
|
||||||
result[result.length] = 0; // terminating zero
|
result[i] = 0; // terminating zero
|
||||||
return result;
|
return result;
|
||||||
"""
|
""".}
|
||||||
|
|
||||||
|
proc cstrToNimstr(c: cstring): string {.asmNoStackFrame, compilerproc.} =
|
||||||
|
{.emit: """
|
||||||
|
var ln = `c`.length;
|
||||||
|
var result = new Array(ln);
|
||||||
|
var r = 0;
|
||||||
|
for (var i = 0; i < ln; ++i) {
|
||||||
|
var ch = `c`.charCodeAt(i);
|
||||||
|
|
||||||
|
if (ch < 128) {
|
||||||
|
result[r] = ch;
|
||||||
|
}
|
||||||
|
else if((ch > 127) && (ch < 2048)) {
|
||||||
|
result[r] = (ch >> 6) | 192;
|
||||||
|
++r;
|
||||||
|
result[r] = (ch & 63) | 128;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
result[r] = (ch >> 12) | 224;
|
||||||
|
++r;
|
||||||
|
result[r] = ((ch >> 6) & 63) | 128;
|
||||||
|
++r;
|
||||||
|
result[r] = (ch & 63) | 128;
|
||||||
|
}
|
||||||
|
++r;
|
||||||
|
}
|
||||||
|
result[r] = 0; // terminating zero
|
||||||
|
return result;
|
||||||
|
""".}
|
||||||
|
|
||||||
proc toJSStr(s: string): cstring {.asmNoStackFrame, compilerproc.} =
|
proc toJSStr(s: string): cstring {.asmNoStackFrame, compilerproc.} =
|
||||||
asm """
|
asm """
|
||||||
|
|
@ -417,42 +448,6 @@ proc absInt(a: int): int {.compilerproc.} =
|
||||||
proc absInt64(a: int64): int64 {.compilerproc.} =
|
proc absInt64(a: int64): int64 {.compilerproc.} =
|
||||||
result = if a < 0: a*(-1) else: a
|
result = if a < 0: a*(-1) else: a
|
||||||
|
|
||||||
proc leU(a, b: int): bool {.compilerproc.} =
|
|
||||||
result = abs(a) <= abs(b)
|
|
||||||
|
|
||||||
proc ltU(a, b: int): bool {.compilerproc.} =
|
|
||||||
result = abs(a) < abs(b)
|
|
||||||
|
|
||||||
proc leU64(a, b: int64): bool {.compilerproc.} =
|
|
||||||
result = abs(a) <= abs(b)
|
|
||||||
proc ltU64(a, b: int64): bool {.compilerproc.} =
|
|
||||||
result = abs(a) < abs(b)
|
|
||||||
|
|
||||||
proc addU(a, b: int): int {.compilerproc.} =
|
|
||||||
result = abs(a) + abs(b)
|
|
||||||
proc addU64(a, b: int64): int64 {.compilerproc.} =
|
|
||||||
result = abs(a) + abs(b)
|
|
||||||
|
|
||||||
proc subU(a, b: int): int {.compilerproc.} =
|
|
||||||
result = abs(a) - abs(b)
|
|
||||||
proc subU64(a, b: int64): int64 {.compilerproc.} =
|
|
||||||
result = abs(a) - abs(b)
|
|
||||||
|
|
||||||
proc mulU(a, b: int): int {.compilerproc.} =
|
|
||||||
result = abs(a) * abs(b)
|
|
||||||
proc mulU64(a, b: int64): int64 {.compilerproc.} =
|
|
||||||
result = abs(a) * abs(b)
|
|
||||||
|
|
||||||
proc divU(a, b: int): int {.compilerproc.} =
|
|
||||||
result = abs(a) div abs(b)
|
|
||||||
proc divU64(a, b: int64): int64 {.compilerproc.} =
|
|
||||||
result = abs(a) div abs(b)
|
|
||||||
|
|
||||||
proc modU(a, b: int): int {.compilerproc.} =
|
|
||||||
result = abs(a) mod abs(b)
|
|
||||||
proc modU64(a, b: int64): int64 {.compilerproc.} =
|
|
||||||
result = abs(a) mod abs(b)
|
|
||||||
|
|
||||||
proc ze*(a: int): int {.compilerproc.} =
|
proc ze*(a: int): int {.compilerproc.} =
|
||||||
result = a
|
result = a
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -496,13 +496,12 @@ type
|
||||||
data: array[MD5_LBLOCK, MD5_LONG]
|
data: array[MD5_LBLOCK, MD5_LONG]
|
||||||
num: cuint
|
num: cuint
|
||||||
|
|
||||||
{.pragma: ic, importc: "$1".}
|
|
||||||
{.push callconv:cdecl, dynlib:DLLUtilName.}
|
{.push callconv:cdecl, dynlib:DLLUtilName.}
|
||||||
proc md5_Init*(c: var MD5_CTX): cint{.ic.}
|
proc md5_Init*(c: var MD5_CTX): cint{.importc: "MD5_Init".}
|
||||||
proc md5_Update*(c: var MD5_CTX; data: pointer; len: csize): cint{.ic.}
|
proc md5_Update*(c: var MD5_CTX; data: pointer; len: csize): cint{.importc: "MD5_Update".}
|
||||||
proc md5_Final*(md: cstring; c: var MD5_CTX): cint{.ic.}
|
proc md5_Final*(md: cstring; c: var MD5_CTX): cint{.importc: "MD5_Final".}
|
||||||
proc md5*(d: ptr cuchar; n: csize; md: ptr cuchar): ptr cuchar{.ic.}
|
proc md5*(d: ptr cuchar; n: csize; md: ptr cuchar): ptr cuchar{.importc: "MD5".}
|
||||||
proc md5_Transform*(c: var MD5_CTX; b: ptr cuchar){.ic.}
|
proc md5_Transform*(c: var MD5_CTX; b: ptr cuchar){.importc: "MD5_Transform".}
|
||||||
{.pop.}
|
{.pop.}
|
||||||
|
|
||||||
from strutils import toHex,toLower
|
from strutils import toHex,toLower
|
||||||
|
|
|
||||||
|
|
@ -39,9 +39,9 @@ To build from source you will need:
|
||||||
If you are on a fairly modern *nix system, the following steps should work:
|
If you are on a fairly modern *nix system, the following steps should work:
|
||||||
|
|
||||||
```
|
```
|
||||||
$ git clone git://github.com/nim-lang/Nim.git
|
$ git clone https://github.com/nim-lang/Nim.git
|
||||||
$ cd Nim
|
$ cd Nim
|
||||||
$ git clone --depth 1 git://github.com/nim-lang/csources
|
$ git clone --depth 1 https://github.com/nim-lang/csources
|
||||||
$ cd csources && sh build.sh
|
$ cd csources && sh build.sh
|
||||||
$ cd ..
|
$ cd ..
|
||||||
$ bin/nim c koch
|
$ bin/nim c koch
|
||||||
|
|
|
||||||
|
|
@ -3,22 +3,76 @@ discard """
|
||||||
Hello'''
|
Hello'''
|
||||||
"""
|
"""
|
||||||
|
|
||||||
# bug #2581
|
block: # bug #2581
|
||||||
|
const someVars = [ "Hello" ]
|
||||||
|
var someVars2 = [ "Hello" ]
|
||||||
|
|
||||||
const someVars = [ "Hello" ]
|
proc getSomeVar: string =
|
||||||
var someVars2 = [ "Hello" ]
|
|
||||||
|
|
||||||
proc getSomeVar: string =
|
|
||||||
for i in someVars:
|
for i in someVars:
|
||||||
if i == "Hello":
|
if i == "Hello":
|
||||||
result = i
|
result = i
|
||||||
break
|
break
|
||||||
|
|
||||||
proc getSomeVar2: string =
|
proc getSomeVar2: string =
|
||||||
for i in someVars2:
|
for i in someVars2:
|
||||||
if i == "Hello":
|
if i == "Hello":
|
||||||
result = i
|
result = i
|
||||||
break
|
break
|
||||||
|
|
||||||
echo getSomeVar()
|
echo getSomeVar()
|
||||||
echo getSomeVar2()
|
echo getSomeVar2()
|
||||||
|
|
||||||
|
block: # Test compile-time binary data generation, invalid unicode
|
||||||
|
proc signatureMaker(): string {. compiletime .} =
|
||||||
|
const signatureBytes = [137, 80, 78, 71, 13, 10, 26, 10]
|
||||||
|
result = ""
|
||||||
|
for c in signatureBytes: result.add chr(c)
|
||||||
|
|
||||||
|
const cSig = signatureMaker()
|
||||||
|
|
||||||
|
var rSig = newString(8)
|
||||||
|
rSig[0] = chr(137)
|
||||||
|
rSig[1] = chr(80)
|
||||||
|
rSig[2] = chr(78)
|
||||||
|
rSig[3] = chr(71)
|
||||||
|
rSig[4] = chr(13)
|
||||||
|
rSig[5] = chr(10)
|
||||||
|
rSig[6] = chr(26)
|
||||||
|
rSig[7] = chr(10)
|
||||||
|
|
||||||
|
doAssert(rSig == cSig)
|
||||||
|
|
||||||
|
block: # Test unicode strings
|
||||||
|
const constStr = "Привет!"
|
||||||
|
var jsStr : cstring
|
||||||
|
{.emit: """`jsStr`[0] = "Привет!";""".}
|
||||||
|
|
||||||
|
doAssert($jsStr == constStr)
|
||||||
|
var runtimeStr = "При"
|
||||||
|
runtimeStr &= "вет!"
|
||||||
|
|
||||||
|
doAssert(runtimeStr == constStr)
|
||||||
|
|
||||||
|
block: # Conversions from/to cstring
|
||||||
|
proc stringSaysHelloInRussian(s: cstring): bool =
|
||||||
|
{.emit: """`result` = (`s` === "Привет!");""".}
|
||||||
|
|
||||||
|
doAssert(stringSaysHelloInRussian("Привет!"))
|
||||||
|
|
||||||
|
const constStr = "Привет!"
|
||||||
|
doAssert(stringSaysHelloInRussian(constStr))
|
||||||
|
|
||||||
|
var rtStr = "Привет!"
|
||||||
|
doAssert(stringSaysHelloInRussian(rtStr))
|
||||||
|
|
||||||
|
block: # String case of
|
||||||
|
const constStr = "Привет!"
|
||||||
|
var s = "Привет!"
|
||||||
|
|
||||||
|
case s
|
||||||
|
of constStr: discard
|
||||||
|
else: doAssert(false)
|
||||||
|
|
||||||
|
case s
|
||||||
|
of "Привет!": discard
|
||||||
|
else: doAssert(false)
|
||||||
|
|
|
||||||
|
|
@ -23,24 +23,29 @@ template test(opr, a, b, c: expr): stmt {.immediate.} =
|
||||||
|
|
||||||
test(`+`, 12'i8, -13'i16, -1'i16)
|
test(`+`, 12'i8, -13'i16, -1'i16)
|
||||||
test(`shl`, 0b11, 0b100, 0b110000)
|
test(`shl`, 0b11, 0b100, 0b110000)
|
||||||
test(`shl`, 0b11'i32, 0b100'i64, 0b110000'i64)
|
when not defined(js):
|
||||||
|
test(`shl`, 0b11'i32, 0b100'i64, 0b110000'i64)
|
||||||
test(`shl`, 0b11'i32, 0b100'i32, 0b110000'i32)
|
test(`shl`, 0b11'i32, 0b100'i32, 0b110000'i32)
|
||||||
|
|
||||||
test(`or`, 0xf0f0'i16, 0x0d0d'i16, 0xfdfd'i16)
|
test(`or`, 0xf0f0'i16, 0x0d0d'i16, 0xfdfd'i16)
|
||||||
test(`and`, 0xf0f0'i16, 0xfdfd'i16, 0xf0f0'i16)
|
test(`and`, 0xf0f0'i16, 0xfdfd'i16, 0xf0f0'i16)
|
||||||
|
|
||||||
test(`shr`, 0xffffffffffffffff'i64, 0x4'i64, 0x0fffffffffffffff'i64)
|
when not defined(js):
|
||||||
|
test(`shr`, 0xffffffffffffffff'i64, 0x4'i64, 0x0fffffffffffffff'i64)
|
||||||
test(`shr`, 0xffff'i16, 0x4'i16, 0x0fff'i16)
|
test(`shr`, 0xffff'i16, 0x4'i16, 0x0fff'i16)
|
||||||
test(`shr`, 0xff'i8, 0x4'i8, 0x0f'i8)
|
test(`shr`, 0xff'i8, 0x4'i8, 0x0f'i8)
|
||||||
|
|
||||||
test(`shr`, 0xffffffff'i64, 0x4'i64, 0x0fffffff'i64)
|
when not defined(js):
|
||||||
|
test(`shr`, 0xffffffff'i64, 0x4'i64, 0x0fffffff'i64)
|
||||||
test(`shr`, 0xffffffff'i32, 0x4'i32, 0x0fffffff'i32)
|
test(`shr`, 0xffffffff'i32, 0x4'i32, 0x0fffffff'i32)
|
||||||
|
|
||||||
test(`shl`, 0xffffffffffffffff'i64, 0x4'i64, 0xfffffffffffffff0'i64)
|
when not defined(js):
|
||||||
|
test(`shl`, 0xffffffffffffffff'i64, 0x4'i64, 0xfffffffffffffff0'i64)
|
||||||
test(`shl`, 0xffff'i16, 0x4'i16, 0xfff0'i16)
|
test(`shl`, 0xffff'i16, 0x4'i16, 0xfff0'i16)
|
||||||
test(`shl`, 0xff'i8, 0x4'i8, 0xf0'i8)
|
test(`shl`, 0xff'i8, 0x4'i8, 0xf0'i8)
|
||||||
|
|
||||||
test(`shl`, 0xffffffff'i64, 0x4'i64, 0xffffffff0'i64)
|
when not defined(js):
|
||||||
|
test(`shl`, 0xffffffff'i64, 0x4'i64, 0xffffffff0'i64)
|
||||||
test(`shl`, 0xffffffff'i32, 0x4'i32, 0xfffffff0'i32)
|
test(`shl`, 0xffffffff'i32, 0x4'i32, 0xfffffff0'i32)
|
||||||
|
|
||||||
# bug #916
|
# bug #916
|
||||||
|
|
@ -50,5 +55,27 @@ proc unc(a: float): float =
|
||||||
echo int(unc(0.5)), " ", int(unc(-0.5))
|
echo int(unc(0.5)), " ", int(unc(-0.5))
|
||||||
echo int(0.5), " ", int(-0.5)
|
echo int(0.5), " ", int(-0.5)
|
||||||
|
|
||||||
echo("Success") #OUT Success
|
block: # Casts to uint
|
||||||
|
template testCast(fromValue: typed, toType: typed, expectedResult: typed) =
|
||||||
|
let src = fromValue
|
||||||
|
let dst = cast[toType](src)
|
||||||
|
if dst != expectedResult:
|
||||||
|
echo "Casting ", astToStr(fromValue), " to ", astToStr(toType), " = ", dst.int, " instead of ", astToStr(expectedResult)
|
||||||
|
doAssert(dst == expectedResult)
|
||||||
|
|
||||||
|
testCast(-1'i16, uint16, 0xffff'u16)
|
||||||
|
testCast(0xffff'u16, int16, -1'i16)
|
||||||
|
|
||||||
|
testCast(0xff'u16, uint8, 0xff'u8)
|
||||||
|
testCast(0xffff'u16, uint8, 0xff'u8)
|
||||||
|
|
||||||
|
testCast(-1'i16, uint32, 0xffffffff'u32)
|
||||||
|
testCast(0xffffffff'u32, int32, -1)
|
||||||
|
|
||||||
|
testCast(0xfffffffe'u32, int32, -2'i32)
|
||||||
|
testCast(0xffffff'u32, int16, -1'i32)
|
||||||
|
|
||||||
|
testCast(-5'i32, uint8, 251'u8)
|
||||||
|
|
||||||
|
|
||||||
|
echo("Success") #OUT Success
|
||||||
|
|
|
||||||
|
|
@ -1,14 +1,28 @@
|
||||||
discard """
|
|
||||||
output: '''253'''
|
|
||||||
"""
|
|
||||||
|
|
||||||
# bug #2427
|
block: # bug #2427
|
||||||
|
var x = 0'u8
|
||||||
|
dec x # OverflowError
|
||||||
|
x -= 1 # OverflowError
|
||||||
|
x = x - 1 # No error
|
||||||
|
|
||||||
import unsigned
|
doAssert(x == 253'u8)
|
||||||
|
|
||||||
var x = 0'u8
|
block:
|
||||||
dec x # OverflowError
|
var x = 130'u8
|
||||||
x -= 1 # OverflowError
|
x += 130'u8
|
||||||
x = x - 1 # No error
|
doAssert(x == 4'u8)
|
||||||
|
|
||||||
echo x
|
block:
|
||||||
|
var x = 40000'u16
|
||||||
|
x = x + 40000'u16
|
||||||
|
doAssert(x == 14464'u16)
|
||||||
|
|
||||||
|
block:
|
||||||
|
var x = 4000000000'u32
|
||||||
|
x = x + 4000000000'u32
|
||||||
|
doAssert(x == 3705032704'u32)
|
||||||
|
|
||||||
|
block:
|
||||||
|
var x = 123'u16
|
||||||
|
x -= 125
|
||||||
|
doAssert(x == 65534'u16)
|
||||||
|
|
|
||||||
|
|
@ -220,7 +220,7 @@ proc jsTests(r: var TResults, cat: Category, options: string) =
|
||||||
"actiontable/tactiontable", "method/tmultim1",
|
"actiontable/tactiontable", "method/tmultim1",
|
||||||
"method/tmultim3", "method/tmultim4",
|
"method/tmultim3", "method/tmultim4",
|
||||||
"varres/tvarres0", "varres/tvarres3", "varres/tvarres4",
|
"varres/tvarres0", "varres/tvarres3", "varres/tvarres4",
|
||||||
"varres/tvartup"]:
|
"varres/tvartup", "misc/tints", "misc/tunsignedinc"]:
|
||||||
test "tests/" & testfile & ".nim"
|
test "tests/" & testfile & ".nim"
|
||||||
|
|
||||||
for testfile in ["pure/strutils"]:
|
for testfile in ["pure/strutils"]:
|
||||||
|
|
|
||||||
|
|
@ -86,6 +86,13 @@ Nim's Community
|
||||||
|
|
||||||
The `G+ Nim community <https://plus.google.com/u/0/communities/106921341535068810587>`_ is another place where discussions related to the language happen. Read and follow various articles, posts and interesting links about Nim.
|
The `G+ Nim community <https://plus.google.com/u/0/communities/106921341535068810587>`_ is another place where discussions related to the language happen. Read and follow various articles, posts and interesting links about Nim.
|
||||||
|
|
||||||
|
.. container:: standout
|
||||||
|
|
||||||
|
Gitter
|
||||||
|
------
|
||||||
|
|
||||||
|
The `Gitter Chatroom for Nim <https://gitter.im/nim-lang/Nim>`_ is the persistent logged "natural" chatroom for GitHub repositories and very easy to access for GitHub users. This does not need additional software and can send notifications about messages by email.
|
||||||
|
|
||||||
.. container:: standout
|
.. container:: standout
|
||||||
|
|
||||||
Meetup
|
Meetup
|
||||||
|
|
|
||||||
|
|
@ -101,7 +101,7 @@ The following used to work as the environment creation used to be attached to th
|
||||||
var s: seq[proc(): int {.closure.}] = @[]
|
var s: seq[proc(): int {.closure.}] = @[]
|
||||||
for i in 0 ..< 30:
|
for i in 0 ..< 30:
|
||||||
let ii = i
|
let ii = i
|
||||||
s.add(proc(): int = return ii*ii))
|
s.add(proc(): int = return ii*ii)
|
||||||
|
|
||||||
This behaviour has changed in 0.13.0 and now needs to be written as:
|
This behaviour has changed in 0.13.0 and now needs to be written as:
|
||||||
|
|
||||||
|
|
@ -133,8 +133,6 @@ via a commit, for a full list see
|
||||||
(`#3498 <https://github.com/nim-lang/Nim/issues/3498>`_)
|
(`#3498 <https://github.com/nim-lang/Nim/issues/3498>`_)
|
||||||
- Fixed "multimethods: Error: internal error: cgmeth.genConv"
|
- Fixed "multimethods: Error: internal error: cgmeth.genConv"
|
||||||
(`#3550 <https://github.com/nim-lang/Nim/issues/3550>`_)
|
(`#3550 <https://github.com/nim-lang/Nim/issues/3550>`_)
|
||||||
- Fixed "multimethods: Error: internal error: cgmeth.genConv"
|
|
||||||
(`#3550 <https://github.com/nim-lang/Nim/issues/3550>`_)
|
|
||||||
- Fixed "nimscript - SIGSEGV in except block"
|
- Fixed "nimscript - SIGSEGV in except block"
|
||||||
(`#3546 <https://github.com/nim-lang/Nim/issues/3546>`_)
|
(`#3546 <https://github.com/nim-lang/Nim/issues/3546>`_)
|
||||||
- Fixed "Bool literals in macros do not work."
|
- Fixed "Bool literals in macros do not work."
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue