Merge branch 'devel' into Fixes-7845
This commit is contained in:
commit
34170db963
208 changed files with 8873 additions and 6312 deletions
58
tests/arithm/tnot.nim
Normal file
58
tests/arithm/tnot.nim
Normal 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
34
tests/arithm/tshl.nim
Normal 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
|
||||
|
|
@ -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
|
||||
3
tests/compilerapi/exposed.nim
Normal file
3
tests/compilerapi/exposed.nim
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
|
||||
proc addFloats*(x, y, z: float): float =
|
||||
discard "implementation overriden by tcompilerapi.nim"
|
||||
9
tests/compilerapi/myscript.nim
Normal file
9
tests/compilerapi/myscript.nim
Normal 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"
|
||||
47
tests/compilerapi/tcompilerapi.nim
Normal file
47
tests/compilerapi/tcompilerapi.nim
Normal 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()
|
||||
26
tests/concepts/libs/trie.nim
Normal file
26
tests/concepts/libs/trie.nim
Normal 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
|
||||
|
||||
12
tests/concepts/libs/trie_database.nim
Normal file
12
tests/concepts/libs/trie_database.nim
Normal 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
27
tests/concepts/t6770.nim
Normal 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)
|
||||
31
tests/concepts/treversable.nim
Normal file
31
tests/concepts/treversable.nim
Normal 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
|
||||
7
tests/concepts/ttrieconcept.nim
Normal file
7
tests/concepts/ttrieconcept.nim
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
import libs/[trie_database, trie]
|
||||
|
||||
proc takeDb(d: TrieDatabase) = discard
|
||||
var mdb: MemDB
|
||||
|
||||
takeDb(mdb)
|
||||
|
||||
|
|
@ -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()
|
||||
|
||||
|
|
|
|||
|
|
@ -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"
|
||||
|
|
|
|||
49
tests/float/tfloatrange.nim
Normal file
49
tests/float/tfloatrange.nim
Normal 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"
|
||||
|
||||
|
|
@ -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
|
||||
|
|
|
|||
145
tests/generics/tlateboundgenericparams.nim
Normal file
145
tests/generics/tlateboundgenericparams.nim
Normal 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
9
tests/global/t5958.nim
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
discard """
|
||||
line: 9
|
||||
errormsg: "undeclared identifier: 'a'"
|
||||
"""
|
||||
|
||||
static:
|
||||
var a = 1
|
||||
|
||||
echo a
|
||||
|
|
@ -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] = @[]
|
||||
|
||||
|
|
|
|||
|
|
@ -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)))
|
||||
|
|
|
|||
|
|
@ -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()
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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"
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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:
|
||||
|
|
|
|||
114
tests/misc/tparamsindefault.nim
Normal file
114
tests/misc/tparamsindefault.nim
Normal 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)
|
||||
|
||||
45
tests/niminaction/Chapter1/various1.nim
Normal file
45
tests/niminaction/Chapter1/various1.nim
Normal 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]))
|
||||
|
||||
7
tests/niminaction/Chapter2/explicit_discard.nim
Normal file
7
tests/niminaction/Chapter2/explicit_discard.nim
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
discard """
|
||||
line: 7
|
||||
errormsg: "has to be discarded"
|
||||
"""
|
||||
|
||||
proc myProc(name: string): string = "Hello " & name
|
||||
myProc("Dominik")
|
||||
16
tests/niminaction/Chapter2/no_def_eq.nim
Normal file
16
tests/niminaction/Chapter2/no_def_eq.nim
Normal 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)
|
||||
7
tests/niminaction/Chapter2/no_iterator.nim
Normal file
7
tests/niminaction/Chapter2/no_iterator.nim
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
discard """
|
||||
line: 6
|
||||
errormsg: "type mismatch"
|
||||
"""
|
||||
|
||||
for i in 5:
|
||||
echo i
|
||||
6
tests/niminaction/Chapter2/no_seq_type.nim
Normal file
6
tests/niminaction/Chapter2/no_seq_type.nim
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
discard """
|
||||
line: 6
|
||||
errormsg: "cannot infer the type of the sequence"
|
||||
"""
|
||||
|
||||
var list = @[]
|
||||
28
tests/niminaction/Chapter2/resultaccept.nim
Normal file
28
tests/niminaction/Chapter2/resultaccept.nim
Normal 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"
|
||||
33
tests/niminaction/Chapter2/resultreject.nim
Normal file
33
tests/niminaction/Chapter2/resultreject.nim
Normal 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"
|
||||
369
tests/niminaction/Chapter2/various2.nim
Normal file
369
tests/niminaction/Chapter2/various2.nim
Normal 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
|
||||
93
tests/niminaction/Chapter3/various3.nim
Normal file
93
tests/niminaction/Chapter3/various3.nim
Normal 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()
|
||||
|
||||
1
tests/niminaction/Chapter3/various3.nim.cfg
Normal file
1
tests/niminaction/Chapter3/various3.nim.cfg
Normal file
|
|
@ -0,0 +1 @@
|
|||
threads:on
|
||||
|
|
@ -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"
|
||||
|
|
|
|||
|
|
@ -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
|
||||
527
tests/parser/ttypemodifiers.nim
Normal file
527
tests/parser/ttypemodifiers.nim
Normal 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
|
||||
|
||||
|
|
@ -71,5 +71,4 @@ macro make(arg: untyped): untyped =
|
|||
proc first(i: int): void =
|
||||
make(second)
|
||||
|
||||
static:
|
||||
var ss: string = ""
|
||||
var ss {.compileTime.}: string = ""
|
||||
109
tests/statictypes/tstatictypes.nim
Normal file
109
tests/statictypes/tstatictypes.nim
Normal 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
|
||||
|
||||
|
|
@ -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)
|
||||
|
|
|
|||
53
tests/stdlib/tmemmapstreams.nim
Normal file
53
tests/stdlib/tmemmapstreams.nim
Normal 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
78
tests/stdlib/tpegs.nim
Normal 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
|
||||
|
|
@ -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")
|
||||
|
|
|
|||
46
tests/template/tdefined_overload.nim
Normal file
46
tests/template/tdefined_overload.nim
Normal 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"
|
||||
27
tests/template/tpattern_with_converter.nim
Normal file
27
tests/template/tpattern_with_converter.nim
Normal 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)
|
||||
|
|
@ -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"]:
|
||||
|
|
|
|||
|
|
@ -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
33
tests/types/t7905.nim
Normal 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)
|
||||
|
|
@ -5,7 +5,7 @@ false
|
|||
false
|
||||
true
|
||||
true
|
||||
no'''
|
||||
yes'''
|
||||
"""
|
||||
|
||||
proc IsVoid[T](): string =
|
||||
|
|
|
|||
7
tests/vm/tnilref.nim
Normal file
7
tests/vm/tnilref.nim
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
discard """
|
||||
errormsg: "attempt to access a nil address"
|
||||
"""
|
||||
|
||||
static:
|
||||
var s: ref int
|
||||
s[] = 1
|
||||
|
|
@ -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")
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
@ -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]
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue