Merge branch 'devel' into Fixes-7845

This commit is contained in:
cooldome 2018-06-26 23:33:34 +01:00
commit 34170db963
208 changed files with 8873 additions and 6312 deletions

58
tests/arithm/tnot.nim Normal file
View file

@ -0,0 +1,58 @@
discard """
output: '''
-5
-5
-5
-5
4
4
4
4
251
65531
4294967291
18446744073709551611
4
4
4
4
'''
"""
# Signed types
block:
const t0: int8 = not 4
const t1: int16 = not 4
const t2: int32 = not 4
const t3: int64 = not 4
const t4: int8 = not -5
const t5: int16 = not -5
const t6: int32 = not -5
const t7: int64 = not -5
echo t0
echo t1
echo t2
echo t3
echo t4
echo t5
echo t6
echo t7
# Unsigned types
block:
const t0: uint8 = not 4'u8
const t1: uint16 = not 4'u16
const t2: uint32 = not 4'u32
const t3: uint64 = not 4'u64
const t4: uint8 = not 251'u8
const t5: uint16 = not 65531'u16
const t6: uint32 = not 4294967291'u32
const t7: uint64 = not 18446744073709551611'u64
echo t0
echo t1
echo t2
echo t3
echo t4
echo t5
echo t6
echo t7

34
tests/arithm/tshl.nim Normal file
View file

@ -0,0 +1,34 @@
discard """
output: '''
0
0
1
1
0
0
0
1
'''
"""
# Signed types
block:
const t0: int8 = 1'i8 shl 8
const t1: int16 = 1'i16 shl 16
const t2: int32 = 1'i32 shl 32
const t3: int64 = 1'i64 shl 64
echo t0
echo t1
echo t2
echo t3
# Unsigned types
block:
const t0: uint8 = 1'u8 shl 8
const t1: uint16 = 1'u16 shl 16
const t2: uint32 = 1'u32 shl 32
const t3: uint64 = 1'u64 shl 64
echo t0
echo t1
echo t2
echo t3

View file

@ -1,18 +0,0 @@
discard """
file: "tasynctry2.nim"
errormsg: "\'yield\' cannot be used within \'try\' in a non-inlined iterator"
line: 14
"""
import asyncdispatch
{.experimental: "oldIterTransf".}
proc foo(): Future[bool] {.async.} = discard
proc test5(): Future[int] {.async.} =
try:
discard await foo()
raise newException(ValueError, "Test5")
except:
discard await foo()
result = 0

View file

@ -0,0 +1,3 @@
proc addFloats*(x, y, z: float): float =
discard "implementation overriden by tcompilerapi.nim"

View file

@ -0,0 +1,9 @@
import exposed
echo "top level statements are executed!"
proc hostProgramRunsThis*(a, b: float): float =
result = addFloats(a, b, 1.0)
let hostProgramWantsThis* = "my secret"

View file

@ -0,0 +1,47 @@
discard """
output: '''top level statements are executed!
2.0
my secret
'''
"""
## Example program that demonstrates how to use the
## compiler as an API to embed into your own projects.
import "../../compiler" / [ast, vmdef, vm, nimeval]
import std / [os]
proc main() =
let std = findNimStdLib()
if std.len == 0:
quit "cannot find Nim's standard library"
var intr = createInterpreter("myscript.nim", [std, getAppDir()])
intr.implementRoutine("*", "exposed", "addFloats", proc (a: VmArgs) =
setResult(a, getFloat(a, 0) + getFloat(a, 1) + getFloat(a, 2))
)
intr.evalScript()
let foreignProc = selectRoutine(intr, "hostProgramRunsThis")
if foreignProc == nil:
quit "script does not export a proc of the name: 'hostProgramRunsThis'"
let res = intr.callRoutine(foreignProc, [newFloatNode(nkFloatLit, 0.9),
newFloatNode(nkFloatLit, 0.1)])
if res.kind == nkFloatLit:
echo res.floatVal
else:
echo "bug!"
let foreignValue = selectUniqueSymbol(intr, "hostProgramWantsThis")
if foreignValue == nil:
quit "script does not export a global of the name: hostProgramWantsThis"
let val = intr.getGlobalValue(foreignValue)
if val.kind in {nkStrLit..nkTripleStrLit}:
echo val.strVal
else:
echo "bug!"
destroyInterpreter(intr)
main()

View file

@ -0,0 +1,26 @@
import
hashes, tables, trie_database
type
MemDBTable = Table[KeccakHash, string]
MemDB* = object
tbl: MemDBTable
proc hash*(key: KeccakHash): int =
hashes.hash(key.data)
proc get*(db: MemDB, key: KeccakHash): string =
db.tbl[key]
proc del*(db: var MemDB, key: KeccakHash): bool =
if db.tbl.hasKey(key):
db.tbl.del(key)
return true
else:
return false
proc put*(db: var MemDB, key: KeccakHash, value: string): bool =
db.tbl[key] = value
return true

View file

@ -0,0 +1,12 @@
type
KeccakHash* = object
data*: string
BytesRange* = object
bytes*: string
TrieDatabase* = concept db
put(var db, KeccakHash, string) is bool
del(var db, KeccakHash) is bool
get(db, KeccakHash) is string

27
tests/concepts/t6770.nim Normal file
View file

@ -0,0 +1,27 @@
discard """
output: '''
10
10
'''
"""
type GA = concept c
c.a is int
type A = object
a: int
type AA = object
case exists: bool
of true:
a: int
else:
discard
proc print(inp: GA) =
echo inp.a
let failing = AA(exists: true, a: 10)
let working = A(a:10)
print(working)
print(failing)

View file

@ -0,0 +1,31 @@
# issue 7705, 7703, 7702
discard """
output: '''
z
e
'''
"""
type
Reversable*[T] = concept a
a[int] is T
a.high is int
a.len is int
a.low is int
proc get[T](s: Reversable[T], n: int): T =
s[n]
proc hi[T](s: Reversable[T]): int =
s.high
proc lo[T](s: Reversable[T]): int =
s.low
iterator reverse*[T](s: Reversable[T]): T =
assert hi(s) - lo(s) == len(s) - 1
for z in hi(s).countdown(lo(s)):
yield s.get(z)
for s in @["e", "z"].reverse:
echo s

View file

@ -0,0 +1,7 @@
import libs/[trie_database, trie]
proc takeDb(d: TrieDatabase) = discard
var mdb: MemDB
takeDb(mdb)

View file

@ -20,3 +20,19 @@ v.doSomething()
var vf = initVector[float]()
vf.doSomething() # Nim uses doSomething[int] here in C++
# Alternative definition:
# https://github.com/nim-lang/Nim/issues/7653
type VectorAlt* {.importcpp: "std::vector", header: "<vector>", nodecl.} [T] = object
proc mkVector*[T]: VectorAlt[T] {.importcpp: "std::vector<'*0>()", header: "<vector>", constructor, nodecl.}
proc foo(): VectorAlt[cint] =
mkVector[cint]()
proc bar(): VectorAlt[cstring] =
mkVector[cstring]()
var x = foo()
var y = bar()

View file

@ -1,11 +1,141 @@
discard """
outputsub: '''tproper_stacktrace.nim(7) tproper_stacktrace'''
exitcode: 1
output: '''ok'''
"""
import strscans, strutils
template fuzzy(x) =
echo x[] != 9
proc raiseTestException*() =
raise newException(Exception, "test")
var p: ptr int
fuzzy p
proc matchStackTrace(actualEntries: openarray[StackTraceEntry], expected: string) =
var expectedEntries = newSeq[StackTraceEntry]()
var i = 0
template checkEqual(actual, expected: typed, subject: string) =
if actual != expected:
echo "Unexpected ", subject, " on line ", i
echo "Actual: ", actual
echo "Expected: ", expected
doAssert(false)
for l in splitLines(expected.strip):
var procname, filename: string
var line: int
if not scanf(l, "$s$w.nim($i) $w", filename, line, procname):
doAssert(false, "Wrong expected stack trace")
checkEqual($actualEntries[i].filename, filename & ".nim", "file name")
if line != 0:
checkEqual(actualEntries[i].line, line, "line number")
checkEqual($actualEntries[i].procname, procname, "proc name")
inc i
doAssert(i == actualEntries.len, "Unexpected number of lines in stack trace")
template verifyStackTrace*(expectedStackTrace: string, body: untyped) =
var verified = false
try:
body
except Exception as e:
verified = true
# echo "Stack trace:"
# echo e.getStackTrace
matchStackTrace(e.getStackTraceEntries(), expectedStackTrace)
doAssert(verified, "No exception was raised")
when isMainModule:
# <-- Align with line 70 in the text editor
block:
proc bar() =
raiseTestException()
proc foo() =
bar()
const expectedStackTrace = """
tproper_stacktrace.nim(86) tproper_stacktrace
tproper_stacktrace.nim(76) foo
tproper_stacktrace.nim(73) bar
tproper_stacktrace.nim(7) raiseTestException
"""
verifyStackTrace expectedStackTrace:
foo()
block:
proc bar(x: int) =
raiseTestException()
template foo(x: int) =
bar(x)
const expectedStackTrace = """
tproper_stacktrace.nim(103) tproper_stacktrace
tproper_stacktrace.nim(90) bar
tproper_stacktrace.nim(7) raiseTestException
"""
verifyStackTrace expectedStackTrace:
var x: int
foo(x)
block: #6803
proc bar(x = 500) =
raiseTestException()
proc foo() =
bar()
const expectedStackTrace = """
tproper_stacktrace.nim(120) tproper_stacktrace
tproper_stacktrace.nim(110) foo
tproper_stacktrace.nim(107) bar
tproper_stacktrace.nim(7) raiseTestException
"""
verifyStackTrace expectedStackTrace:
foo()
block:
proc bar() {.stackTrace: off.} =
proc baz() = # Stack trace should be enabled
raiseTestException()
baz()
proc foo() =
bar()
const expectedStackTrace = """
tproper_stacktrace.nim(139) tproper_stacktrace
tproper_stacktrace.nim(129) foo
tproper_stacktrace.nim(125) baz
tproper_stacktrace.nim(7) raiseTestException
"""
verifyStackTrace expectedStackTrace:
foo()
echo "ok"

View file

@ -0,0 +1,49 @@
discard """
cmd: "nim c -d:release --rangeChecks:on $file"
output: '''StrictPositiveRange
float
range fail expected
range fail expected
'''
"""
import math, fenv
type
Positive = range[0.0..Inf]
StrictPositive = range[minimumPositiveValue(float)..Inf]
Negative32 = range[-maximumPositiveValue(float32) .. -1.0'f32]
proc myoverload(x: float) =
echo "float"
proc myoverload(x: Positive) =
echo "PositiveRange"
proc myoverload(x: StrictPositive) =
echo "StrictPositiveRange"
let x = 9.0.StrictPositive
myoverload(x)
myoverload(9.0)
doAssert(sqrt(x) == 3.0)
var z = -10.0
try:
myoverload(StrictPositive(z))
except:
echo "range fail expected"
proc strictOnlyProc(x: StrictPositive): bool =
if x > 1.0: true else: false
let x2 = 5.0.Positive
doAssert(strictOnlyProc(x2))
try:
let x4 = 0.0.Positive
discard strictOnlyProc(x4)
except:
echo "range fail expected"

View file

@ -1,12 +1,14 @@
discard """
output: '''42'''
output: "42\n42"
"""
type
Foo[N: static[int]] = object
proc foo[N](x: Foo[N]) =
let n = N
echo N
echo n
var f1: Foo[42]
f1.foo

View file

@ -0,0 +1,145 @@
discard """
output: "1\n10\n1\n10"
nimout: '''
bar instantiated with 1
bar instantiated with 10
'''
"""
import typetraits
type
Foo = object
proc defaultFoo: Foo = discard
proc defaultInt: int = 1
proc defaultTInt(T: type): int = 2
proc defaultTFoo[T](x: typedesc[T]): Foo = discard
proc defaultTOldSchool[T](x: typedesc[T]): T = discard
proc defaultTModern(T: type): T = discard
proc specializedDefault(T: type int): int = 10
proc specializedDefault(T: type string): string = "default"
converter intFromFoo(x: Foo): int = 3
proc consumeInt(x: int) =
discard
const activeTests = {1..100}
when true:
template test(n, body) =
when n in activeTests:
block:
body
template reject(x) =
static: assert(not compiles(x))
test 1:
proc t[T](val: T = defaultInt()) =
consumeInt val
t[int]()
reject t[string]()
test 2:
proc t1[T](val: T = defaultFoo()) =
static:
assert type(val).name == "int"
assert T.name == "int"
consumeInt val
# here, the converter should kick in, but notice
# how `val` is still typed `int` inside the proc.
t1[int]()
proc t2[T](val: T = defaultFoo()) =
discard
reject t2[string]()
test 3:
proc tInt[T](val = defaultInt()): string =
return type(val).name
doAssert tInt[int]() == "int"
doAssert tInt[string]() == "int"
proc tInt2[T](val = defaultTInt(T)): string =
return type(val).name
doAssert tInt2[int]() == "int"
doAssert tInt2[string]() == "int"
proc tDefTModern[T](val = defaultTModern(T)): string =
return type(val).name
doAssert tDefTModern[int]() == "int"
doAssert tDefTModern[string]() == "string"
doAssert tDefTModern[Foo]() == "Foo"
proc tDefTOld[T](val = defaultTOldSchool(T)): string =
return type(val).name
doAssert tDefTOld[int]() == "int"
doAssert tDefTOld[string]() == "string"
doAssert tDefTOld[Foo]() == "Foo"
test 4:
proc t[T](val: T = defaultTFoo(T)): string =
return type(val).name
doAssert t[int]() == "int"
doAssert t[Foo]() == "Foo"
reject t[string]()
test 5:
proc t1[T](a: T = specializedDefault(T)): T =
return a
doAssert t1[int]() == 10
doAssert t1[string]() == "default"
proc t2[T](a: T, b = specializedDefault(T)): auto =
return $a & $b
doAssert t2(5) == "510"
doAssert t2("string ") == "string default"
proc t3[T](a: T, b = specializedDefault(type(a))): auto =
return $a & $b
doAssert t3(100) == "10010"
doAssert t3("another ") == "another default"
test 6:
# https://github.com/nim-lang/Nim/issues/5595
type
Point[T] = object
x, y: T
proc getOrigin[T](): Point[T] = Point[T](x: 0, y: 0)
proc rotate[T](point: Point[T], radians: float,
origin = getOrigin[T]()): Point[T] =
discard
var p = getOrigin[float]()
var rotated = p.rotate(2.1)
test 7:
proc bar(x: static[int]) =
static: echo "bar instantiated with ", x
echo x
proc foo(x: static[int] = 1) =
bar(x)
foo()
foo(10)
foo(1)
foo(10)

9
tests/global/t5958.nim Normal file
View file

@ -0,0 +1,9 @@
discard """
line: 9
errormsg: "undeclared identifier: 'a'"
"""
static:
var a = 1
echo a

View file

@ -4,7 +4,7 @@ discard """
errormsg: "invalid indentation"
"""
import strutils var s: seq[int] = @[0, 1, 2, 3, 4, 5, 6]
import strutils let s: seq[int] = @[0, 1, 2, 3, 4, 5, 6]
#s[1..3] = @[]

View file

@ -12,12 +12,12 @@ macro outterMacro*(n, blck: untyped): untyped =
echo "Using arg ! " & n.repr
result = "Got: '" & $n.kind & "' " & $j
var callNode = n[0]
expectKind(n, TNimrodNodeKind.nnkCall)
if n.len != 3 or n[1].kind != TNimrodNodeKind.nnkIdent:
expectKind(n, NimNodeKind.nnkCall)
if n.len != 3 or n[1].kind != NimNodeKind.nnkIdent:
error("Macro " & callNode.repr &
" requires the ident passed as parameter (eg: " & callNode.repr &
"(the_name_you_want)): statements.")
result = newNimNode(TNimrodNodeKind.nnkStmtList)
result = newNimNode(NimNodeKind.nnkStmtList)
var ass : NimNode = newNimNode(nnkAsgn)
ass.add(newIdentNode(n[1].ident))
ass.add(newStrLitNode(innerProc(4)))

View file

@ -1,5 +1,5 @@
import macros
macro case_token(n: untyped): untyped {.immediate.} =
macro case_token(n: varargs[untyped]): untyped =
# creates a lexical analyzer from regular expressions
# ... (implementation is an exercise for the reader :-)
nil
@ -21,6 +21,6 @@ case_token: inc i
macro foo: typed =
var exp = newCall("whatwhat", newIntLitNode(1))
if compiles(getAst(exp)): return exp
else: echo "Does not compute!"
else: echo "Does not compute! (test OK)"
foo()

View file

@ -5,15 +5,16 @@ type
x: T
y: U
proc getTypeName(t: typedesc): string = t.name
proc getTypeName1(t: typedesc): string = t.name
proc getTypeName2(t: type): string = t.name
proc foo(T: typedesc[float], a: auto): string =
proc foo(T: type float, a: auto): string =
result = "float " & $(a.len > 5)
proc foo(T: typedesc[TFoo], a: int): string =
result = "TFoo " & $(a)
proc foo(T: typedesc[int or bool]): string =
proc foo(T: type[int or bool]): string =
var a: T
a = 10
result = "int or bool " & ($a)
@ -23,8 +24,8 @@ template foo(T: typedesc[seq]): string = "seq"
test "types can be used as proc params":
# XXX: `check` needs to know that TFoo[int, float] is a type and
# cannot be assigned for a local variable for later inspection
check ((string.getTypeName == "string"))
check ((getTypeName(int) == "int"))
check ((string.getTypeName1 == "string"))
check ((getTypeName2(int) == "int"))
check ((foo(TFoo[int, float], 1000) == "TFoo 1000"))
@ -37,6 +38,25 @@ test "types can be used as proc params":
check ((foo(seq[int]) == "seq"))
check ((foo(seq[TFoo[bool, string]]) == "seq"))
when false:
proc foo(T: typedesc[seq], s: T) = nil
template accept(x) =
static: assert(compiles(x))
template reject(x) =
static: assert(not compiles(x))
var
si: seq[int]
ss: seq[string]
proc foo(T: typedesc[seq], s: T) =
discard
accept:
foo seq[int], si
reject:
foo seq[string], si
reject:
foo seq[int], ss

View file

@ -34,3 +34,17 @@ when true:
type Point[T] = tuple[x, y: T]
proc origin(T: typedesc): Point[T] = discard
discard origin(int)
# https://github.com/nim-lang/Nim/issues/7516
import typetraits
proc hasDefault1(T: type = int): auto = return T.name
doAssert hasDefault1(int) == "int"
doAssert hasDefault1(string) == "string"
doAssert hasDefault1() == "int"
proc hasDefault2(T = string): auto = return T.name
doAssert hasDefault2(int) == "int"
doAssert hasDefault2(string) == "string"
doAssert hasDefault2() == "string"

View file

@ -4,9 +4,9 @@ type
Base = object of RootObj
Child = object of Base
proc pr(T: typedesc[Base]) = echo "proc " & T.name
method me(T: typedesc[Base]) = echo "method " & T.name
iterator it(T: typedesc[Base]): auto = yield "yield " & T.name
proc pr(T: type[Base]) = echo "proc " & T.name
method me(T: type[Base]) = echo "method " & T.name
iterator it(T: type[Base]): auto = yield "yield " & T.name
Base.pr
Child.pr

View file

@ -5,16 +5,16 @@ output: "8\n8\n4"
import
macros, typetraits
template selectType(x: int): typeDesc =
template selectType(x: int): type =
when x < 10:
int
else:
string
template simpleTypeTempl: typeDesc =
template simpleTypeTempl: type =
string
macro typeFromMacro: typedesc = string
macro typeFromMacro: type = string
# The tests below check that the result variable of the
# selected type matches the literal types in the code:

View file

@ -0,0 +1,114 @@
discard """
output: '''
@[1, 2, 3]@[1, 2, 3]
a
a
1
3 is an int
2 is an int
miau is a string
f1 1 1 1
f1 2 3 3
f1 10 20 30
f2 100 100 100
f2 200 300 300
f2 300 400 400
f3 10 10 20
f3 10 15 25
true true
false true
world
'''
"""
template reject(x) =
assert(not compiles(x))
block:
# https://github.com/nim-lang/Nim/issues/7756
proc foo[T](x: seq[T], y: seq[T] = x) =
echo x, y
let a = @[1, 2, 3]
foo(a)
block:
# https://github.com/nim-lang/Nim/issues/1201
proc issue1201(x: char|int = 'a') = echo x
issue1201()
issue1201('a')
issue1201(1)
# https://github.com/nim-lang/Nim/issues/7000
proc test(a: int|string = 2) =
when a is int:
echo a, " is an int"
elif a is string:
echo a, " is a string"
test(3) # works
test() # works
test("miau")
block:
# https://github.com/nim-lang/Nim/issues/3002 and similar
proc f1(a: int, b = a, c = b) =
echo "f1 ", a, " ", b, " ", c
proc f2(a: int, b = a, c: int = b) =
echo "f2 ", a, " ", b, " ", c
proc f3(a: int, b = a, c = a + b) =
echo "f3 ", a, " ", b, " ", c
f1 1
f1(2, 3)
f1 10, 20, 30
100.f2
200.f2 300
300.f2(400)
10.f3()
10.f3(15)
reject:
# This is a type mismatch error:
proc f4(a: int, b = a, c: float = b) = discard
reject:
# undeclared identifier
proc f5(a: int, b = c, c = 10) = discard
reject:
# undeclared identifier
proc f6(a: int, b = b) = discard
reject:
# undeclared identifier
proc f7(a = a) = discard
block:
proc f(a: var int, b: ptr int, c = addr(a)) =
echo addr(a) == b, " ", b == c
var x = 10
f(x, addr(x))
f(x, nil, nil)
block:
# https://github.com/nim-lang/Nim/issues/1046
proc pySubstr(s: string, start: int, endd = s.len()): string =
var
revStart = start
revEnd = endd
if start < 0:
revStart = s.len() + start
if endd < 0:
revEnd = s.len() + endd
return s[revStart .. revEnd-1]
echo pySubstr("Hello world", -5)

View file

@ -0,0 +1,45 @@
discard """
exitCode: 0
outputsub: "Woof!"
"""
import strutils
echo("hello".to_upper())
echo("world".toUpper())
type
Dog = object #<1>
age: int #<2>
let dog = Dog(age: 3) #<3>
proc showNumber(num: int | float) =
echo(num)
showNumber(3.14)
showNumber(42)
for i in 0 .. <10:
echo(i)
block: # Block added due to clash.
type
Dog = object
proc bark(self: Dog) = #<1>
echo("Woof!")
let dog = Dog()
dog.bark() #<2>
import sequtils, future, strutils
let list = @["Dominik Picheta", "Andreas Rumpf", "Desmond Hume"]
list.map(
(x: string) -> (string, string) => (x.split[0], x.split[1])
).echo
import strutils
let list1 = @["Dominik Picheta", "Andreas Rumpf", "Desmond Hume"]
for name in list1:
echo((name.split[0], name.split[1]))

View file

@ -0,0 +1,7 @@
discard """
line: 7
errormsg: "has to be discarded"
"""
proc myProc(name: string): string = "Hello " & name
myProc("Dominik")

View file

@ -0,0 +1,16 @@
discard """
line: 16
errormsg: "type mismatch"
"""
type
Dog = object
name: string
Cat = object
name: string
let dog: Dog = Dog(name: "Fluffy")
let cat: Cat = Cat(name: "Fluffy")
echo(dog == cat)

View file

@ -0,0 +1,7 @@
discard """
line: 6
errormsg: "type mismatch"
"""
for i in 5:
echo i

View file

@ -0,0 +1,6 @@
discard """
line: 6
errormsg: "cannot infer the type of the sequence"
"""
var list = @[]

View file

@ -0,0 +1,28 @@
discard """
output: ""
"""
# Page 35.
proc implicit: string =
"I will be returned"
proc discarded: string =
discard "I will not be returned"
proc explicit: string =
return "I will be returned"
proc resultVar: string =
result = "I will be returned"
proc resultVar2: string =
result = ""
result.add("I will be ")
result.add("returned")
doAssert implicit() == "I will be returned"
doAssert discarded() == nil
doAssert explicit() == "I will be returned"
doAssert resultVar() == "I will be returned"
doAssert resultVar2() == "I will be returned"

View file

@ -0,0 +1,33 @@
discard """
line: 27
errormsg: "has to be discarded"
"""
# Page 35.
proc implicit: string =
"I will be returned"
proc discarded: string =
discard "I will not be returned"
proc explicit: string =
return "I will be returned"
proc resultVar: string =
result = "I will be returned"
proc resultVar2: string =
result = ""
result.add("I will be ")
result.add("returned")
proc resultVar3: string =
result = "I am the result"
"I will cause an error"
doAssert implicit() == "I will be returned"
doAssert discarded() == nil
doAssert explicit() == "I will be returned"
doAssert resultVar() == "I will be returned"
doAssert resultVar2() == "I will be returned"

View file

@ -0,0 +1,369 @@
discard """
exitCode: 0
outputsub: '''42 is greater than 0'''
"""
if 42 >= 0:
echo "42 is greater than 0"
echo("Output: ",
5)
echo(5 +
5)
# --- Removed code that is supposed to fail here. Not going to test those. ---
# Single-line comment
#[
Multiline comment
]#
when false:
echo("Commented-out code")
let decimal = 42
let hex = 0x42
let octal = 0o42
let binary = 0b101010
let a: int16 = 42
let b = 42'i8
let c = 1'f32 # --- Changed names here to avoid clashes ---
let d = 1.0e19
let e = false
let f = true
let g = 'A'
let h = '\109'
let i = '\x79'
let text = "The book title is \"Nim in Action\""
let filepath = "C:\\Program Files\\Nim"
# --- Changed name here to avoid clashes ---
let filepath1 = r"C:\Program Files\Nim"
let multiLine = """foo
bar
baz
"""
echo multiLine
import strutils
# --- Changed name here to avoid clashes ---
let multiLine1 = """foo
bar
baz
"""
echo multiLine1.unindent
doAssert multiLine1.unindent == "foo\nbar\nbaz\n"
proc fillString(): string =
result = ""
echo("Generating string")
for i in 0 .. 4:
result.add($i) #<1>
const count = fillString()
var
text1 = "hello"
number: int = 10
isTrue = false
var 火 = "Fire"
let ogień = true
var `var` = "Hello"
echo(`var`)
proc myProc(name: string): string = "Hello " & name
discard myProc("Dominik")
proc bar(): int #<1>
proc foo(): float = bar().float
proc bar(): int = foo().int
proc noReturn() = echo("Hello")
proc noReturn2(): void = echo("Hello")
proc noReturn3 = echo("Hello")
proc message(recipient: string): auto =
"Hello " & recipient
doAssert message("Dom") == "Hello Dom"
proc max(a: int, b: int): int =
if a > b: a else: b
doAssert max(5, 10) == 10
proc max2(a, b: int): int =
if a > b: a else: b
proc genHello(name: string, surname = "Doe"): string =
"Hello " & name & " " & surname
# -- Leaving these as asserts as that is in the original code, just in case
# -- somehow in the future `assert` is removed :)
assert genHello("Peter") == "Hello Peter Doe"
assert genHello("Peter", "Smith") == "Hello Peter Smith"
proc genHello2(names: varargs[string]): string =
result = ""
for name in names:
result.add("Hello " & name & "\n")
doAssert genHello2("John", "Bob") == "Hello John\nHello Bob\n"
proc getUserCity(firstName, lastName: string): string =
case firstName
of "Damien": return "Tokyo"
of "Alex": return "New York"
else: return "Unknown"
proc getUserCity(userID: int): string =
case userID
of 1: return "Tokyo"
of 2: return "New York"
else: return "Unknown"
doAssert getUserCity("Damien", "Lundi") == "Tokyo"
doAssert getUserCity(2) == "New York" # -- Errata here: missing closing "
import sequtils
let numbers = @[1, 2, 3, 4, 5, 6]
let odd = filter(numbers, proc (x: int): bool = x mod 2 != 0)
doAssert odd == @[1, 3, 5]
import sequtils, future
let numbers1 = @[1, 2, 3, 4, 5, 6]
let odd1 = filter(numbers1, (x: int) -> bool => x mod 2 != 0)
assert odd1 == @[1, 3, 5]
proc isValid(x: int, validator: proc (x: int): bool) =
if validator(x): echo(x, " is valid")
else: echo(x, " is NOT valid")
import future
proc isValid2(x: int, validator: (x: int) -> bool) =
if validator(x): echo(x, " is valid")
else: echo(x, " is NOT valid")
var list: array[3, int]
list[0] = 1
list[1] = 42
assert list[0] == 1
assert list[1] == 42
assert list[2] == 0 #<1>
echo list.repr #<2>
# echo list[500]
var list2: array[-10 .. -9, int]
list2[-10] = 1
list2[-9] = 2
var list3 = ["Hi", "There"]
var list4 = ["My", "name", "is", "Dominik"]
for item in list4:
echo(item)
for i in list4.low .. list4.high:
echo(list4[i])
var list5: seq[int] = @[]
doAssertRaises(IndexError):
list5[0] = 1
list5.add(1)
assert list5[0] == 1
doAssertRaises(IndexError):
echo list5[42]
# -- Errata: var list: seq[int]; echo(list[0]). This now creates an exception,
# -- not a SIGSEGV.
block:
var list = newSeq[string](3)
assert list[0] == nil
list[0] = "Foo"
list[1] = "Bar"
list[2] = "Baz"
list.add("Lorem")
block:
let list = @[4, 8, 15, 16, 23, 42]
for i in 0 .. <list.len:
stdout.write($list[i] & " ")
var collection: set[int16]
doAssert collection == {}
block:
let collection = {'a', 'x', 'r'}
doAssert 'a' in collection
block:
let collection = {'a', 'T', 'z'}
let isAllLowerCase = {'A' .. 'Z'} * collection == {}
doAssert(not isAllLowerCase)
let age = 10
if age > 0 and age <= 10:
echo("You're still a child")
elif age > 10 and age < 18:
echo("You're a teenager")
else:
echo("You're an adult")
let variable = "Arthur"
case variable
of "Arthur", "Zaphod", "Ford":
echo("Male")
of "Marvin":
echo("Robot")
of "Trillian":
echo("Female")
else:
echo("Unknown")
let ageDesc = if age < 18: "Non-Adult" else: "Adult"
block:
var i = 0
while i < 3:
echo(i)
i.inc
block label:
var i = 0
while true:
while i < 5:
if i > 3: break label
i.inc
iterator values(): int =
var i = 0
while i < 5:
yield i
i.inc
for value in values():
echo(value)
import os
for filename in walkFiles("*.nim"):
echo(filename)
for item in @[1, 2, 3]:
echo(item)
for i, value in @[1, 2, 3]: echo("Value at ", i, ": ", value)
doAssertRaises(IOError):
proc second() =
raise newException(IOError, "Somebody set us up the bomb")
proc first() =
second()
first()
block:
proc second() =
raise newException(IOError, "Somebody set us up the bomb")
proc first() =
try:
second()
except:
echo("Cannot perform second action because: " &
getCurrentExceptionMsg())
first()
block:
type
Person = object
name: string
age: int
var person: Person
var person1 = Person(name: "Neo", age: 28)
block:
type
PersonObj = object
name: string
age: int
PersonRef = ref PersonObj
# proc setName(person: PersonObj) =
# person.name = "George"
proc setName(person: PersonRef) =
person.name = "George"
block:
type
Dog = object
name: string
Cat = object
name: string
let dog: Dog = Dog(name: "Fluffy")
let cat: Cat = Cat(name: "Fluffy")
block:
type
Dog = tuple
name: string
Cat = tuple
name: string
let dog: Dog = (name: "Fluffy")
let cat: Cat = (name: "Fluffy")
echo(dog == cat)
block:
type
Point = tuple[x, y: int]
Point2 = (int, int)
let pos: Point = (x: 100, y: 50)
doAssert pos == (100, 50)
let pos1: Point = (x: 100, y: 50)
let (x, y) = pos1 #<1>
let (left, _) = pos1
doAssert x == pos1[0]
doAssert y == pos1[1]
doAssert left == x
block:
type
Color = enum
colRed,
colGreen,
colBlue
let color: Color = colRed
block:
type
Color {.pure.} = enum
red, green, blue
let color = Color.red

View file

@ -0,0 +1,93 @@
import threadpool
proc foo: string = "Dog"
var x: FlowVar[string] = spawn foo()
assert(^x == "Dog")
block:
type
Box = object
case empty: bool
of false:
contents: string
else:
discard
var obj = Box(empty: false, contents: "Hello")
assert obj.contents == "Hello"
var obj2 = Box(empty: true)
doAssertRaises(FieldError):
echo(obj2.contents)
import json
assert parseJson("null").kind == JNull
assert parseJson("true").kind == JBool
assert parseJson("42").kind == JInt
assert parseJson("3.14").kind == JFloat
assert parseJson("\"Hi\"").kind == JString
assert parseJson("""{ "key": "value" }""").kind == JObject
assert parseJson("[1, 2, 3, 4]").kind == JArray
import json
let data = """
{"username": "Dominik"}
"""
let obj = parseJson(data)
assert obj.kind == JObject
assert obj["username"].kind == JString
assert obj["username"].str == "Dominik"
block:
proc count10(): int =
for i in 0 .. <10:
result.inc
assert count10() == 10
type
Point = tuple[x, y: int]
var point = (5, 10)
var point2 = (x: 5, y: 10)
type
Human = object
name: string
age: int
var jeff = Human(name: "Jeff", age: 23)
var amy = Human(name: "Amy", age: 20)
import asyncdispatch
var future = newFuture[int]()
doAssert(not future.finished)
future.callback =
proc (future: Future[int]) =
echo("Future is no longer empty, ", future.read)
future.complete(42)
import asyncdispatch, asyncfile
when false:
var file = openAsync("")
let dataFut = file.readAll()
dataFut.callback =
proc (future: Future[string]) =
echo(future.read())
asyncdispatch.runForever()
import asyncdispatch, asyncfile, os
proc readFiles() {.async.} =
# --- Changed to getTempDir here.
var file = openAsync(getTempDir() / "test.txt", fmReadWrite)
let data = await file.readAll()
echo(data)
await file.write("Hello!\n")
waitFor readFiles()

View file

@ -0,0 +1 @@
threads:on

View file

@ -1,21 +1,84 @@
discard """
file: "toverflw.nim"
output: "the computation overflowed"
output: "ok"
cmd: "nim $target -d:release $options $file"
"""
# Tests nim's ability to detect overflows
{.push overflowChecks: on.}
var
a, b: int
a = high(int)
b = -2
a = high(int)
b = -2
overflowDetected = false
try:
writeLine(stdout, b - a)
except OverflowError:
writeLine(stdout, "the computation overflowed")
overflowDetected = true
{.pop.} # overflow check
#OUT the computation overflowed
doAssert(overflowDetected)
block: # Overflow checks in a proc
var
a = high(int)
b = -2
overflowDetected = false
{.push overflowChecks: on.}
proc foo() =
let c = b - a
{.pop.}
try:
foo()
except OverflowError:
overflowDetected = true
doAssert(overflowDetected)
block: # Overflow checks in a forward declared proc
var
a = high(int)
b = -2
overflowDetected = false
proc foo()
{.push overflowChecks: on.}
proc foo() =
let c = b - a
{.pop.}
try:
foo()
except OverflowError:
overflowDetected = true
doAssert(overflowDetected)
block: # Overflow checks doesn't affect fwd declaration
var
a = high(int)
b = -2
overflowDetected = false
{.push overflowChecks: on.}
proc foo()
{.pop.}
proc foo() =
let c = b - a
try:
foo()
except OverflowError:
overflowDetected = true
doAssert(not overflowDetected)
echo "ok"

View file

@ -1,17 +1,42 @@
discard """
action: run
"""
type
R = ref
V = var
D = distinct
P = ptr
T = type
S = static
OBJ = object
TPL = tuple
SEQ = seq
var i: int
var x: ref int
var y: distinct int
var z: ptr int
const C = @[1, 2, 3]
static:
assert x is ref
assert y is distinct
assert z is ptr
assert C is static
assert C[1] is static[int]
assert C[0] is static[SomeInteger]
assert C isnot static[string]
assert C is SEQ|OBJ
assert C isnot OBJ|TPL
assert int is int
assert int is T
assert int is SomeInteger
assert seq[int] is type
assert seq[int] is type[seq]
assert seq[int] isnot type[seq[float]]
assert i isnot type[int]
assert type(i) is type[int]
assert x isnot T
assert y isnot S
assert z isnot enum
assert x isnot object
assert y isnot tuple
assert z isnot seq
doAssert x is ref
doAssert y is distinct
doAssert z is ptr

View file

@ -0,0 +1,527 @@
discard """
nimout: '''
StmtList
TypeSection
TypeDef
Ident "BarePtr"
Empty
PtrTy
TypeDef
Ident "GenericPtr"
Empty
PtrTy
Bracket
Ident "int"
TypeDef
Ident "PrefixPtr"
Empty
PtrTy
Ident "int"
TypeDef
Ident "PtrTuple"
Empty
PtrTy
Par
Ident "int"
Ident "string"
TypeDef
Ident "BareRef"
Empty
RefTy
TypeDef
Ident "GenericRef"
Empty
RefTy
Bracket
Ident "int"
TypeDef
Ident "RefTupleCl"
Empty
RefTy
TupleTy
TypeDef
Ident "RefTupleType"
Empty
RefTy
Par
Ident "int"
Ident "string"
TypeDef
Ident "RefTupleVars"
Empty
RefTy
Par
Ident "a"
Ident "b"
TypeDef
Ident "BareStatic"
Empty
Ident "static"
TypeDef
Ident "GenericStatic"
Empty
BracketExpr
Ident "static"
Ident "int"
TypeDef
Ident "PrefixStatic"
Empty
Command
Ident "static"
Ident "int"
TypeDef
Ident "StaticTupleCl"
Empty
Command
Ident "static"
TupleClassTy
TypeDef
Ident "StaticTuple"
Empty
Command
Ident "static"
Par
Ident "int"
Ident "string"
TypeDef
Ident "BareType"
Empty
Ident "type"
TypeDef
Ident "GenericType"
Empty
BracketExpr
Ident "type"
Ident "float"
TypeDef
Ident "TypeTupleGen"
Empty
BracketExpr
Ident "type"
TupleClassTy
TypeDef
Ident "TypeTupleCl"
Empty
Command
Ident "type"
TupleClassTy
TypeDef
Ident "TypeInstance"
Empty
Command
Ident "type"
BracketExpr
Ident "Foo"
RefTy
TypeDef
Ident "bareTypeDesc"
Empty
Ident "typedesc"
TypeDef
Ident "TypeOfVar"
Empty
Call
Ident "type"
Ident "a"
TypeDef
Ident "TypeOfVarAlt"
Empty
Command
Ident "type"
Par
Ident "a"
TypeDef
Ident "TypeOfTuple1"
Empty
Call
Ident "type"
Ident "a"
TypeDef
Ident "TypeOfTuple2"
Empty
Call
Ident "type"
Ident "a"
Ident "b"
TypeDef
Ident "TypeOfTuple1A"
Empty
Command
Ident "type"
TupleConstr
Ident "a"
TypeDef
Ident "TypeOfTuple2A"
Empty
Command
Ident "type"
Par
Ident "a"
Ident "b"
TypeDef
Ident "TypeTuple"
Empty
Command
Ident "type"
Par
Ident "int"
Ident "string"
TypeDef
Ident "GenericTypedesc"
Empty
BracketExpr
Ident "typedesc"
Ident "int"
TypeDef
Ident "T"
Empty
Ident "type"
ProcDef
Ident "foo"
Empty
Empty
FormalParams
Ident "type"
IdentDefs
Ident "bareType"
Ident "type"
Empty
IdentDefs
Ident "genType"
BracketExpr
Ident "type"
Ident "int"
Empty
IdentDefs
Ident "typeInt"
Command
Ident "type"
Ident "int"
Empty
IdentDefs
Ident "typeIntAlt"
Call
Ident "type"
Ident "int"
Empty
IdentDefs
Ident "typeOfVar"
Call
Ident "type"
Ident "a"
Empty
IdentDefs
Ident "typeDotType"
DotExpr
Ident "foo"
Ident "type"
Empty
IdentDefs
Ident "typeTupleCl"
Command
Ident "type"
TupleClassTy
Empty
IdentDefs
Ident "bareStatic"
Ident "static"
Empty
IdentDefs
Ident "genStatic"
BracketExpr
Ident "static"
Ident "int"
Empty
IdentDefs
Ident "staticInt"
Command
Ident "static"
Ident "int"
Empty
IdentDefs
Ident "staticVal1"
Command
Ident "static"
IntLit 10
Empty
IdentDefs
Ident "staticVal2"
Call
Ident "static"
StrLit "str"
Empty
IdentDefs
Ident "staticVal3"
Command
Ident "static"
StrLit "str"
Empty
IdentDefs
Ident "staticVal4"
CallStrLit
Ident "static"
RStrLit "str"
Empty
IdentDefs
Ident "staticDotVal"
DotExpr
IntLit 10
Ident "static"
Empty
IdentDefs
Ident "bareRef"
RefTy
Empty
IdentDefs
Ident "refTuple1"
RefTy
Par
Ident "int"
Empty
IdentDefs
Ident "refTuple1A"
RefTy
TupleConstr
Ident "int"
Empty
IdentDefs
Ident "refTuple2"
RefTy
Par
Ident "int"
Ident "string"
Empty
IdentDefs
Ident "genRef"
RefTy
Bracket
Ident "int"
Empty
IdentDefs
Ident "refInt"
RefTy
Ident "int"
Empty
IdentDefs
Ident "refCall"
RefTy
Par
Ident "a"
Empty
IdentDefs
Ident "macroCall1"
Command
Ident "foo"
Ident "bar"
Empty
IdentDefs
Ident "macroCall2"
Call
Ident "foo"
Ident "bar"
Empty
IdentDefs
Ident "macroCall3"
Call
DotExpr
Ident "foo"
Ident "bar"
Ident "baz"
Empty
IdentDefs
Ident "macroCall4"
Call
BracketExpr
Ident "foo"
Ident "bar"
Ident "baz"
Empty
IdentDefs
Ident "macroCall5"
Command
Ident "foo"
Command
Ident "bar"
Ident "baz"
IntLit 10
Empty
Empty
StmtList
Asgn
Ident "staticTen"
Command
Ident "static"
IntLit 10
Asgn
Ident "staticA"
Call
Ident "static"
Ident "a"
Asgn
Ident "staticCall"
Command
Ident "static"
Call
Ident "foo"
IntLit 1
Asgn
Ident "staticStrCall"
Command
Ident "static"
CallStrLit
Ident "foo"
RStrLit "x"
Asgn
Ident "staticChainCall"
Command
Ident "static"
Command
Ident "foo"
Ident "bar"
Asgn
Ident "typeTen"
Command
Ident "type"
IntLit 10
Asgn
Ident "typeA"
Call
Ident "type"
Ident "a"
Asgn
Ident "typeCall"
Command
Ident "type"
Call
Ident "foo"
IntLit 1
Asgn
Ident "typeStrCall"
Command
Ident "type"
CallStrLit
Ident "foo"
RStrLit "x"
Asgn
Ident "typeChainCall"
Command
Ident "type"
Command
Ident "foo"
Ident "bar"
Asgn
Ident "normalChainCall"
Command
Ident "foo"
Command
Ident "bar"
Ident "baz"
Asgn
Ident "normalTupleCall2"
Call
Ident "foo"
Ident "a"
Ident "b"
StaticStmt
StmtList
Ident "singleStaticStmt"
StaticStmt
StmtList
Ident "staticStmtList1"
Ident "staticStmtList2"
'''
"""
import macros
dumpTree:
type
BarePtr = ptr
GenericPtr = ptr[int]
PrefixPtr = ptr int
PtrTuple = ptr (int, string)
BareRef = ref
GenericRef = ref[int]
RefTupleCl = ref tuple
RefTupleType = ref (int, string)
RefTupleVars = ref (a, b)
BareStatic = static # Used to be Error: invalid indentation
GenericStatic = static[int]
PrefixStatic = static int
StaticTupleCl = static tuple
StaticTuple = static (int, string)
BareType = type
GenericType = type[float]
TypeTupleGen = type[tuple]
TypeTupleCl = type tuple # Used to be Error: invalid indentation
TypeInstance = type Foo[ref]
bareTypeDesc = typedesc
TypeOfVar = type(a)
TypeOfVarAlt = type (a) # Used to be Error: invalid indentation
TypeOfTuple1 = type(a,)
TypeOfTuple2 = type(a,b)
TypeOfTuple1A = type (a,) # Used to be Error: invalid indentation
TypeOfTuple2A = type (a,b) # Used to be Error: invalid indentation
TypeTuple = type (int, string) # Used to be Error: invalid indentation
GenericTypedesc = typedesc[int]
T = type
proc foo(
bareType : type,
genType : type[int],
typeInt : type int,
typeIntAlt : type(int),
typeOfVar : type(a),
typeDotType : foo.type,
typeTupleCl : type tuple, # Used to be Error: ')' expected
bareStatic : static, # Used to be Error: expression expected, but found ','
genStatic : static[int],
staticInt : static int,
staticVal1 : static 10,
staticVal2 : static("str"),
staticVal3 : static "str",
staticVal4 : static"str", # Used to be Error: expression expected, but found 'str'
staticDotVal : 10.static,
bareRef : ref,
refTuple1 : ref (int),
refTuple1A : ref (int,),
refTuple2 : ref (int,string),
genRef : ref[int],
refInt : ref int,
refCall : ref(a),
macroCall1 : foo bar,
macroCall2 : foo(bar),
macroCall3 : foo.bar(baz),
macroCall4 : foo[bar](baz),
macroCall5 : foo bar baz = 10
): type =
staticTen = static 10
staticA = static(a)
# staticAspace = static (a) # With newTypedesc: Error: invalid indentation
# staticAtuple = static (a,) # With newTypedesc: Error: invalid indentation
# staticTuple = static (a,b) # With newTypedesc: Error: invalid indentation
# staticTypeTuple = static (int,string) # With newTypedesc: Error: invalid indentation
staticCall = static foo(1)
staticStrCall = static foo"x"
staticChainCall = static foo bar
typeTen = type 10
typeA = type(a)
# typeAspace = type (a) # Error: invalid indentation
# typeAtuple = type (a,) # Error: invalid indentation
# typeTuple = type (a,b) # Error: invalid indentation
# typeTypeTuple = type (int,string) # Error: invalid indentation
typeCall = type foo(1)
typeStrCall = type foo"x"
typeChainCall = type foo bar
normalChainCall = foo bar baz
# normalTupleCall1 = foo(a,) # Error: invalid indentation
normalTupleCall2 = foo(a,b)
# normalTupleCall3 = foo (a,b) # Error: invalid indentation
static: singleStaticStmt
static:
staticStmtList1
staticStmtList2

View file

@ -71,5 +71,4 @@ macro make(arg: untyped): untyped =
proc first(i: int): void =
make(second)
static:
var ss: string = ""
var ss {.compileTime.}: string = ""

View file

@ -0,0 +1,109 @@
discard """
nimout: '''
staticAlialProc instantiated with 358
staticAlialProc instantiated with 368
'''
output: '''
16
16
b is 2 times a
17
'''
"""
import macros
template ok(x) = assert(x)
template no(x) = assert(not x)
template accept(x) =
static: assert(compiles(x))
template reject(x) =
static: assert(not compiles(x))
proc plus(a, b: int): int = a + b
template isStatic(x: static): bool = true
template isStatic(x: auto): bool = false
var v = 1
when true:
# test that `isStatic` works as expected
const C = 2
static:
ok C.isStatic
ok isStatic(plus(1, 2))
ok plus(C, 2).isStatic
no isStatic(v)
no plus(1, v).isStatic
when true:
# test that proc instantiation works as expected
type
StaticTypeAlias = static[int]
proc staticAliasProc(a: StaticTypeAlias,
b: static[int],
c: static int) =
static:
assert a.isStatic and b.isStatic and c.isStatic
assert isStatic(a + plus(b, c))
echo "staticAlialProc instantiated with ", a, b, c
when b mod a == 0:
echo "b is ", b div a, " times a"
echo a + b + c
staticAliasProc 1+2, 5, 8
staticAliasProc 3, 2+3, 9-1
staticAliasProc 3, 3+3, 4+4
when true:
# test static coercions. normal cases that should work:
accept:
var s1 = static[int] plus(1, 2)
var s2 = static(plus(1,2))
var s3 = static plus(1,2)
var s4 = static[SomeInteger](1 + 2)
# the sub-script operator can be used only with types:
reject:
var just_static3 = static[plus(1,2)]
# static coercion takes into account the type:
reject:
var x = static[string](plus(1, 2))
reject:
var x = static[string] plus(1, 2)
reject:
var x = static[SomeFloat] plus(3, 4)
# you cannot coerce a run-time variable
reject:
var x = static(v)
when true:
type
ArrayWrapper1[S: static int] = object
data: array[S + 1, int]
ArrayWrapper2[S: static[int]] = object
data: array[S.plus(2), int]
ArrayWrapper3[S: static[(int, string)]] = object
data: array[S[0], int]
var aw1: ArrayWrapper1[5]
var aw2: ArrayWrapper2[5]
var aw3: ArrayWrapper3[(10, "str")]
static:
assert aw1.data.high == 5
assert aw2.data.high == 6
assert aw3.data.high == 9

View file

@ -4,9 +4,10 @@ discard """
Half read size: 10 Data: Hello'''
"""
import memfiles, os
const
fn = "test.mmap"
var
mm, mm_full, mm_half: MemFile
fn = "test.mmap"
p: pointer
if fileExists(fn): removeFile(fn)

View file

@ -0,0 +1,53 @@
discard """
file: "tmemmapstreams.nim"
output: '''Created size: 10
Position after writing: 5
Position after writing one char: 6
Peeked data: Hello
Position after peeking: 0
Readed data: Hello!
Position after reading line: 7
Position after setting position: 6
Readed line: Hello!
Position after reading line: 7'''
"""
import os, streams, memfiles
const
fn = "test.mmapstream"
var
mms: MemMapFileStream
if fileExists(fn): removeFile(fn)
# Create a new memory mapped file, data all zeros
mms = newMemMapFileStream(fn, mode = fmReadWrite, fileSize = 10)
mms.close()
if fileExists(fn): echo "Created size: ", getFileSize(fn)
# write, flush, peek, read
mms = newMemMapFileStream(fn, mode = fmReadWrite)
let s = "Hello"
mms.write(s)
mms.flush
echo "Position after writing: ", mms.getPosition()
mms.write('!')
mms.flush
echo "Position after writing one char: ", mms.getPosition()
mms.close()
mms = newMemMapFileStream(fn, mode = fmRead)
echo "Peeked data: ", mms.peekStr(s.len)
echo "Position after peeking: ", mms.getPosition()
echo "Readed data: ", mms.readLine
echo "Position after reading line: ", mms.getPosition()
mms.setPosition(mms.getPosition() - 1)
echo "Position after setting position: ", mms.getPosition()
mms.setPosition(0)
echo "Readed line: ", mms.readLine
echo "Position after reading line: ", mms.getPosition()
mms.close()
if fileExists(fn): removeFile(fn)

78
tests/stdlib/tpegs.nim Normal file
View file

@ -0,0 +1,78 @@
discard """
output: '''
pkNonTerminal: Sum @(2, 3)
pkSequence: (Product (('+' / '-') Product)*)
pkNonTerminal: Product @(3, 7)
pkSequence: (Value (('*' / '/') Value)*)
pkNonTerminal: Value @(4, 5)
pkOrderedChoice: (([0-9] [0-9]*) / ('(' Expr ')'))
pkSequence: ([0-9] [0-9]*)
pkCharChoice: [0-9]
pkGreedyRepSet: [0-9]*
pkSequence: ('(' Expr ')')
pkChar: '('
pkNonTerminal: Expr @(1, 4)
pkNonTerminal: Sum @(2, 3)
pkChar: ')'
pkGreedyRep: (('*' / '/') Value)*
pkSequence: (('*' / '/') Value)
pkOrderedChoice: ('*' / '/')
pkChar: '*'
pkChar: '/'
pkNonTerminal: Value @(4, 5)
pkGreedyRep: (('+' / '-') Product)*
pkSequence: (('+' / '-') Product)
pkOrderedChoice: ('+' / '-')
pkChar: '+'
pkChar: '-'
pkNonTerminal: Product @(3, 7)
'''
"""
import strutils, streams
import pegs
const
indent = " "
let
pegSrc = """
Expr <- Sum
Sum <- Product (('+' / '-') Product)*
Product <- Value (('*' / '/') Value)*
Value <- [0-9]+ / '(' Expr ')'
"""
pegAst: Peg = pegSrc.peg
var
outp = newStringStream()
processed: seq[string] = @[]
proc prt(outp: Stream, kind: PegKind, s: string; level: int = 0) =
outp.writeLine indent.repeat(level) & "$1: $2" % [$kind, s]
proc recLoop(p: Peg, level: int = 0) =
case p.kind
of pkEmpty..pkWhitespace:
discard
of pkTerminal, pkTerminalIgnoreCase, pkTerminalIgnoreStyle:
outp.prt(p.kind, $p, level)
of pkChar, pkGreedyRepChar:
outp.prt(p.kind, $p, level)
of pkCharChoice, pkGreedyRepSet:
outp.prt(p.kind, $p, level)
of pkNonTerminal:
outp.prt(p.kind,
"$1 @($3, $4)" % [p.nt.name, $p.nt.rule.kind, $p.nt.line, $p.nt.col], level)
if not(p.nt.name in processed):
processed.add p.nt.name
p.nt.rule.recLoop level+1
of pkBackRef..pkBackRefIgnoreStyle:
outp.prt(p.kind, $p, level)
else:
outp.prt(p.kind, $p, level)
for s in items(p):
s.recLoop level+1
pegAst.recLoop
echo outp.data

View file

@ -7,6 +7,14 @@ discard """
import
strutils
import macros
template rejectParse(e) =
try:
discard e
raise newException(AssertionError, "This was supposed to fail: $#!" % astToStr(e))
except ValueError: discard
proc testStrip() =
write(stdout, strip(" ha "))
@ -148,7 +156,6 @@ proc testDelete =
delete(s, 0, 0)
assert s == "1236789ABCDEFG"
proc testIsAlphaNumeric =
assert isAlphaNumeric("abcdABC1234") == true
assert isAlphaNumeric("a") == true
@ -203,10 +210,50 @@ proc testCountLines =
assertCountLines("\nabc\n123")
assertCountLines("\nabc\n123\n")
proc testParseInts =
# binary
assert "0b1111".parseBinInt == 15
assert "0B1111".parseBinInt == 15
assert "1111".parseBinInt == 15
assert "1110".parseBinInt == 14
assert "1_1_1_1".parseBinInt == 15
assert "0b1_1_1_1".parseBinInt == 15
rejectParse "".parseBinInt
rejectParse "_".parseBinInt
rejectParse "0b".parseBinInt
rejectParse "0b1234".parseBinInt
# hex
assert "0x72".parseHexInt == 114
assert "0X72".parseHexInt == 114
assert "#72".parseHexInt == 114
assert "72".parseHexInt == 114
assert "FF".parseHexInt == 255
assert "ff".parseHexInt == 255
assert "fF".parseHexInt == 255
assert "0x7_2".parseHexInt == 114
rejectParse "".parseHexInt
rejectParse "_".parseHexInt
rejectParse "0x".parseHexInt
rejectParse "0xFFG".parseHexInt
rejectParse "reject".parseHexInt
# octal
assert "0o17".parseOctInt == 15
assert "0O17".parseOctInt == 15
assert "17".parseOctInt == 15
assert "10".parseOctInt == 8
assert "0o1_0_0".parseOctInt == 64
rejectParse "".parseOctInt
rejectParse "_".parseOctInt
rejectParse "0o".parseOctInt
rejectParse "9".parseOctInt
rejectParse "0o9".parseOctInt
rejectParse "reject".parseOctInt
testDelete()
testFind()
testRFind()
testCountLines()
testParseInts()
assert(insertSep($1000_000) == "1_000_000")
assert(insertSep($232) == "232")

View file

@ -0,0 +1,46 @@
discard """
output: "Valid and not defined"
"""
# test for issue #7997
# checking for `when not defined` in a template for some compile time symbol
# results in a compilation error of:
# Error: obsolete usage of 'defined', use 'declared' instead
# if the symbol is 'overloaded' by some variable or procedure, because in
# that case the argument of `defined` is of kind `nkSym` instead of `nkIdent`
# (for which was checked in `semexprs.semDefined`).
block:
# check whether a proc with the same name as the argument to `defined`
# compiles
proc overloaded() =
discard
template definedCheck(): untyped =
when not defined(overloaded): true
else: false
doAssert definedCheck == true
block:
# check whether a variable with the same name as the argument to `defined`
# compiles
var overloaded: int
template definedCheck(): untyped =
when not defined(overloaded): true
else: false
doAssert definedCheck == true
block:
# check whether a non overloaded when check still works properly
when not defined(validIdentifier):
echo "Valid and not defined"
block:
# now check that invalid identifiers cause a compilation error
# by using reject template.
template reject(b) =
static: doAssert(not compiles(b))
reject:
when defined(123):
echo "Invalid identifier! Will not be echoed"

View file

@ -0,0 +1,27 @@
discard """
output: 10.0
"""
type
MyFloat = object
val: float
converter to_myfloat*(x: float): MyFloat {.inline.} =
MyFloat(val: x)
proc `+`(x1, x2: MyFloat): MyFloat =
MyFloat(val: x1.val + x2.val)
proc `*`(x1, x2: MyFloat): MyFloat =
MyFloat(val: x1.val * x2.val)
template optMul{`*`(a, 2.0)}(a: MyFloat): MyFloat =
a + a
func floatMyFloat(x: MyFloat): MyFloat =
result = x * 2.0
func floatDouble(x: float): float =
result = x * 2.0
echo floatDouble(5)

View file

@ -266,8 +266,17 @@ proc testNimInAction(r: var TResults, cat: Category, options: string) =
testSpec r, makeTest(filename, options, cat, actionCompile), targetCPP
let tests = [
"niminaction/Chapter1/various1",
"niminaction/Chapter2/various2",
"niminaction/Chapter2/resultaccept",
"niminaction/Chapter2/resultreject",
"niminaction/Chapter2/explicit_discard",
"niminaction/Chapter2/no_def_eq",
"niminaction/Chapter2/no_iterator",
"niminaction/Chapter2/no_seq_type",
"niminaction/Chapter3/ChatApp/src/server",
"niminaction/Chapter3/ChatApp/src/client",
"niminaction/Chapter3/various3",
"niminaction/Chapter6/WikipediaStats/concurrency_regex",
"niminaction/Chapter6/WikipediaStats/concurrency",
"niminaction/Chapter6/WikipediaStats/naive",
@ -278,8 +287,34 @@ proc testNimInAction(r: var TResults, cat: Category, options: string) =
"niminaction/Chapter7/Tweeter/src/tweeter",
"niminaction/Chapter7/Tweeter/src/createDatabase",
"niminaction/Chapter7/Tweeter/tests/database_test",
"niminaction/Chapter8/sdl/sdl_test",
"niminaction/Chapter8/sdl/sdl_test"
]
# Verify that the files have not been modified. Death shall fall upon
# whoever edits these hashes without dom96's permission, j/k. But please only
# edit when making a conscious breaking change, also please try to make your
# commit message clear and notify me so I can easily compile an errata later.
var testHashes: seq[string] = @[]
for test in tests:
testHashes.add(getMD5(readFile("tests" / test.addFileExt("nim")).string))
const refHashes = @[
"51afdfa84b3ca3d810809d6c4e5037ba", "30f07e4cd5eaec981f67868d4e91cfcf",
"d14e7c032de36d219c9548066a97e846", "2e40bfd5daadb268268727da91bb4e81",
"c5d3853ed0aba04bf6d35ba28a98dca0", "058603145ff92d46c009006b06e5b228",
"7b94a029b94ddb7efafddd546c965ff6", "586d74514394e49f2370dfc01dd9e830",
"e1901837b757c9357dc8d259fd0ef0f6", "097670c7ae12e825debaf8ec3995227b",
"a8cb7b78cc78d28535ab467361db5d6e", "bfaec2816a1848991b530c1ad17a0184",
"47cb71bb4c1198d6d29cdbee05aa10b9", "87e4436809f9d73324cfc4f57f116770",
"7b7db5cddc8cf8fa9b6776eef1d0a31d", "e6e40219f0f2b877869b738737b7685e",
"6532ee87d819f2605a443d5e94f9422a", "9a8fe78c588d08018843b64b57409a02",
"03a801275b8b76b4170c870cd0da079d", "20bb7d3e2d38d43b0cb5fcff4909a4a8",
"af6844598f534fab6942abfa4dfe9ab2", "2a7a17f84f6503d9bc89a5ab8feea127"
]
doAssert testHashes == refHashes, "Nim in Action tests were changed."
# Run the tests.
for testfile in tests:
test "tests/" & testfile & ".nim", actionCompile
@ -291,6 +326,7 @@ proc testNimInAction(r: var TResults, cat: Category, options: string) =
# ------------------------- manyloc -------------------------------------------
#proc runSpecialTests(r: var TResults, options: string) =
# for t in ["lib/packages/docutils/highlite"]:

View file

@ -129,7 +129,7 @@ proc callCCompiler(cmdTemplate, filename, options: string,
let c = parseCmdLine(cmdTemplate % ["target", targetToCmd[target],
"options", options, "file", filename.quoteShell,
"filedir", filename.getFileDir()])
var p = startProcess(command="gcc", args=c[5.. ^1],
var p = startProcess(command="gcc", args=c[5 .. ^1],
options={poStdErrToStdOut, poUsePath})
let outp = p.outputStream
var x = newStringOfCap(120)

33
tests/types/t7905.nim Normal file
View file

@ -0,0 +1,33 @@
discard """
output: '''
(member: "hello world")
(member: 123.456)
(member: "hello world", x: ...)
(member: 123.456, x: ...)
'''
"""
template foobar(arg: typed): untyped =
type
MyType = object
member: type(arg)
var myVar: MyType
myVar.member = arg
echo myVar
foobar("hello world")
foobar(123.456'f64)
template foobarRec(arg: typed): untyped =
type
MyType = object
member: type(arg)
x: ref MyType
var myVar: MyType
myVar.member = arg
echo myVar
foobarRec("hello world")
foobarRec(123.456'f64)

View file

@ -5,7 +5,7 @@ false
false
true
true
no'''
yes'''
"""
proc IsVoid[T](): string =

7
tests/vm/tnilref.nim Normal file
View file

@ -0,0 +1,7 @@
discard """
errormsg: "attempt to access a nil address"
"""
static:
var s: ref int
s[] = 1

View file

@ -4,14 +4,12 @@ proc assertEq(arg0,arg1: string): void =
if arg0 != arg1:
raiseAssert("strings not equal:\n" & arg0 & "\n" & arg1)
static:
# a simple assignment of stmtList to another variable
var node: NimNode
# an assignment of stmtList into an array
var nodeArray: array[1, NimNode]
# an assignment of stmtList into a seq
var nodeSeq = newSeq[NimNode](2)
# a simple assignment of stmtList to another variable
var node {.compileTime.}: NimNode
# an assignment of stmtList into an array
var nodeArray {.compileTime.}: array[1, NimNode]
# an assignment of stmtList into a seq
var nodeSeq {.compileTime.} = newSeq[NimNode](2)
proc checkNode(arg: NimNode; name: string): void {. compileTime .} =
echo "checking ", name
@ -35,10 +33,10 @@ proc checkNode(arg: NimNode; name: string): void {. compileTime .} =
echo "OK"
static:
# the root node that is used to generate the Ast
var stmtList: NimNode
# the root node that is used to generate the Ast
var stmtList {.compileTime.}: NimNode
static:
stmtList = newStmtList(nnkDiscardStmt.newTree(newEmptyNode()))
checkNode(stmtList, "direct construction")

View file

@ -9,4 +9,49 @@ static:
b[5] = 'c'
doAssert a[] == "Hellocworld"
doAssert b[] == "Hellocworld"
doAssert b[] == "Hellocworld"
proc notGlobal() =
var
a: ref string
b: ref string
new a
a[] = "Hello world"
b = a
b[5] = 'c'
doAssert a[] == "Hellocworld"
doAssert b[] == "Hellocworld"
notGlobal()
static: # bug 6081
block:
type Obj = object
field: ref int
var i: ref int
new(i)
var r = Obj(field: i)
var rr = r
r.field = nil
doAssert rr.field != nil
proc foo() = # Proc to avoid special global logic
var s: seq[ref int]
var i: ref int
new(i)
s.add(i)
var head = s[0]
s[0] = nil
doAssert head != nil
foo()
static:
block: # global alias
var s: ref int
new(s)
var ss = s
s[] = 1
doAssert ss[] == 1

View file

@ -19,9 +19,9 @@ block:
var x = default(type(0))
# #6379
static:
import algorithm
import algorithm
static:
var numArray = [1, 2, 3, 4, -1]
numArray.sort(cmp)
assert numArray == [-1, 1, 2, 3, 4]