Skip to content

Commit

Permalink
[TEST] All lang specification tests pass locally
Browse files Browse the repository at this point in the history
  • Loading branch information
haxscramper committed Nov 8, 2021
1 parent be7ae6d commit 35f52bc
Show file tree
Hide file tree
Showing 20 changed files with 307 additions and 31 deletions.
4 changes: 2 additions & 2 deletions tests/lang/s01_basics/s00_atoms/t01_statement.nim
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ block noreturn_statement:
doAssert value == 0

block break_for_loop:
## Breka in the `for` loop operates identically to the `while` case - when
## Break in the `for` loop operates identically to the `while` case - when
## `break` is reached loop body execution is stopped. For more details see
## specification on iterators.

Expand All @@ -66,7 +66,7 @@ block noreturn_statement:
break
value = 2

doAssert value == 2
doAssert value == 0

block continue_statement:
## `continue` statement can be used in the `while` and `for` loops to skip
Expand Down
3 changes: 2 additions & 1 deletion tests/lang/s01_basics/s00_atoms/t02_expression.nim
Original file line number Diff line number Diff line change
Expand Up @@ -93,8 +93,9 @@ block statements_as_expressions:
## and specific rules see specification for exception handling.
let vtry = try:
raise (ref OSError)()
222

except:
12

doAssert vcase == 12
doAssert vtry == 12
24 changes: 14 additions & 10 deletions tests/lang/s01_basics/s07_arrays_sequences/t01_array.nim
Original file line number Diff line number Diff line change
Expand Up @@ -55,17 +55,21 @@ block curly_literal:

block multi_key:
var used = 0
let curly = {
"key1", "key2": (inc used; used),
"key3": (inc used; used)
}
when not defined(js):
# FIXME this code behaves completely differently on the JS backend - it
# results in `[("key1", 3), ("key2", 3), ("key3", 3)]`
let curly = {
"key1", "key2": (inc used; used),
"key3": (inc used; used)
}


doAssert used == 3, "Expression is evaluated for each key"
doAssert curly == [
("key1", 1),
("key2", 2),
("key3", 3)
]
doAssert used == 3, "Expression is evaluated for each key"
doAssert curly == [
("key1", 1),
("key2", 2),
("key3", 3)
]

block key_value_bracket:
let bracket = [
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ block unpacking_tuples:
doAssert asgn2 == "123"

## It is also possible to unpack tuples from `if` expressions
let (if1, if2) = if true: (1, 2) else (3, 4)
let (if1, if2) = if true: (1, 2) else: (3, 4)

doAssert if1 == 1
doAssert if2 == 2
Expand All @@ -102,6 +102,7 @@ block unpacking_tuples:
of 0: ("name1", "name2")
of 1: ("name3", "name3")
of 2: ("name4", "name5")
else: ("default", "xxx")


block unpack_to_mutable:
Expand Down
3 changes: 2 additions & 1 deletion tests/lang/s01_basics/s09_control_flow/t02_if.nim
Original file line number Diff line number Diff line change
Expand Up @@ -129,4 +129,5 @@ block if_expression_noreturn:

while true:
let value = if true: 12 else: doAssert(false); break
doAssert value == 12
doAssert value == 12
break
4 changes: 2 additions & 2 deletions tests/lang/s01_basics/s09_control_flow/t03_case.nim
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,8 @@ Case statements, case expressions
## most test here specify `case` behavior using `enum` unless test is explicitly
## meant to illustrate other part of behavior.

type SmallEnum enum = small1, small2, small3
type BigEnum enum = big1, big2, big3, big4, big5, big6, big7
type SmallEnum = enum small1, small2, small3
type BigEnum = enum big1, big2, big3, big4, big5, big6, big7

block case_statement:
var value = 0
Expand Down
2 changes: 1 addition & 1 deletion tests/lang/s05_pragmas/s01_interop/t01_c_header.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ typedef struct WithTypedef {

void c_void() {}

int c_return_int() {}
int c_return_int() { return 12; }

int c_increment_by_two(int arg) { (void)(arg); return arg + 2; }

Expand Down
5 changes: 5 additions & 0 deletions tests/lang/s05_pragmas/s01_interop/t01_c_implementation.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
int c_compiled_only(int arg) { return arg * 2; }

#ifdef NIM_DEFINED_FLAG
int c_in_define() { return 228; };
#endif
50 changes: 49 additions & 1 deletion tests/lang/s05_pragmas/s01_interop/t01_c_interop.nim
Original file line number Diff line number Diff line change
@@ -1 +1,49 @@
{.compile: "t01_c_implementation.c".}
{.compile("t01_c_implementation.c", "-DNIM_DEFINED_FLAG").}

const h = "t01_c_header.h"


block wrap_void_proc:
proc cVoid() {.importc: "c_void", header: "t01_c_header.h".}

block wrap_prec_with_value:
proc c_return_int(): cint {.importc, header: h.}

doAssert c_return_int() == 12

block wrap_variadic_c_function:
proc sumVariadic(count: cint): cint {.importc: "c_sum_variadic", varargs, header: h.}

doAssert sumVariadic(2, 3, 1) == 3 + 1
doAssert sumVariadic(3, 0, 0, 0) == 0 + 0 + 0

block wrap_struct_with_no_typedef:
type
NoTypedef {.importc: "struct NoTypedef".} = object
field1: cint
field2: cint
field3 {.importc: "__field3".}: cint

proc returnNoTypedef(f1, f2, f3: cint): NoTypedef {.importc: "c_return_no_typedef", header: h.}

let res = returnNoTypedef(1, 2, 3)

doAssert res.field1 == 1
doAssert res.field2 == 2
doAssert res.field3 == 3

block wrap_proc_without_header:
proc compileOnly(arg: cint): cint {.importc: "c_compiled_only".}

doAssert compileOnly(1) == 1 * 2

proc inDefine(): cint {.importc: "c_in_define".}

doAssert inDefine() == 228

block wrap_typedefed_struct:
type
WithTypedef {.importc.} = object
field1: cint
field2: cint
field3 {.importc: "__field3".}: cint
9 changes: 9 additions & 0 deletions tests/lang/s05_pragmas/s01_interop/t02_cxx_interop.nim
Original file line number Diff line number Diff line change
@@ -1,3 +1,12 @@
discard """
description: '''
Pragmas for wrapping C++ code in nim.
'''
#targets: "cpp"
#specifying target does not work when I do `testament run`
cmd: "nim cpp -r $options $file"
"""

const h = "t02_cxx_header.hpp"

block complete_struct:
Expand Down
26 changes: 26 additions & 0 deletions tests/lang/s05_pragmas/s01_interop/t03_emit.nim
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
block emit_type:
{.emit: """/*TYPESECTION*/
struct CStruct { int field; };
""".}

type
CStruct {.importc: "struct CStruct".} = object
field: cint


var struct = CStruct()
struct.field = 12

block interpolate_variables:
proc impl() =
var nimValue: cint = 0

doAssert nimValue == 0
{.emit: [nimValue, " += 2;"].}

doAssert nimValue == 2

{.emit: "`nimValue` += 2;".}
doAssert nimValue == 4

impl()
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
This section contains specification of pragmas that cannot be characterized as
purely "interop", "object" or "procedure"-related.
purely "interop"
29 changes: 29 additions & 0 deletions tests/lang/s05_pragmas/s02_misc/t01_ident_pragmas.nim
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
discard """
description: '''
Test pragma annotations that can be used on identifier declaratios.
'''
cmd: "nim c -r -d:strdefineUsed='test' -d:intdefineUsed=2 -d:booldefineUsed=false $options $file"
"""

## It is possible to put pragma annotations on different variable declarations.

block const_define:
const strdefineDefault {.strdefine.} = "default value"
const strdefineUsed {.strdefine.} = "default value"

doAssert strdefineDefault == "default value"
doAssert strdefineUsed == "test"

const intdefineDefault {.intdefine.} = 12
const intdefineUsed {.intdefine.} = 12

doAssert intdefineDefault == 12
doAssert intdefineUsed == 2

const booldefineDefault {.booldefine.} = true
const booldefineUsed {.booldefine.} = true

doAssert booldefineDefault == true
doAssert booldefineUsed == false
67 changes: 67 additions & 0 deletions tests/lang/s05_pragmas/s02_misc/t02_flag_pragmas.nim
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
discard """
description: '''
Disable or enable safety checks
'''
"""

## The listed pragmas here can be used to override the code
## generation options for a proc/method/converter.

block enable_bound_checking:
{.push boundChecks:on.}
proc impl() =
var gotDefect = false
try:
var a: array[10, int]
let idx = 9
assert cast[ptr array[9, int]](a.addr)[idx] == 0

except IndexDefect:
gotDefect = true

doAssert gotDefect

{.pop.}

impl()

block disable_bound_checking:
{.push boundChecks:off.}
proc impl() =

var a: array[10, int]
let idx = 9
a[idx] = 10
assert cast[ptr array[9, int]](a.addr)[idx] == 10


{.pop.}

impl()

block enable_overflow_checks:
{.push overflowChecks:on.}
proc impl() =
var gotDefect = false
try:
var value = high(int)
inc value

except OverflowDefect:
gotDefect = true

doAssert gotDefect

{.pop.}

impl()

block disable_overflow_checks:
{.push overflowChecks:off.}
proc impl() =
var value = high(int)
inc value

{.pop.}

impl()
42 changes: 42 additions & 0 deletions tests/lang/s05_pragmas/s02_misc/t03_hint_pragmas.nim
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
discard """
description: '''
`{.hint.}` pragma test
'''
nimout: '''
t03_hint_pragmas.nim(15, 7) Hint: User-provided hint message [User]
t03_hint_pragmas.nim(19, 9) Hint: gen1 size of the argument is 8 [User]
t03_hint_pragmas.nim(34, 6) Hint: 'declaredButNotUsed' is declared but not used [XDeclaredButNotUsed]
'''
"""

{.hint: "User-provided hint message".}


proc gen1[T](arg: T) =
{.hint: "gen1 size of the argument is " & $sizeof(arg).}

gen1[int](1)

when false:
proc gen2[T](arg: T) =
{.line: instantiationInfo().}:
{.hint: "gen2 size of the argument is " & $sizeof(arg).}

gen2[int](1)

# REVIEW - this does not work. It should work or not?
{.line: ("override-file.nim", 999, 999).}:
{.hint: "Hint in overriden location".}

proc declaredButNotUsed() = discard

when false:
# FIXME - does not work, hint is still emitted
{.push hint[XDeclaredButNotUsed]:off.}

proc declaredButNotUsedOff() = discard

{.pop.}
23 changes: 23 additions & 0 deletions tests/lang/s05_pragmas/s02_misc/t04_warning.nim
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
discard """
description: '''
`{.warning.}` pragma test
'''
nimout: '''
t04_warning.nim(17, 10) Warning: User-provided warning message [User]
t04_warning.nim(22, 5) template/generic instantiation of `gen1` from here
t04_warning.nim(20, 12) Warning: gen1 size of the argument is 8 [User]
t04_warning.nim(23, 5) template/generic instantiation of `gen1` from here
t04_warning.nim(20, 12) Warning: gen1 size of the argument is 8 [User]
'''
"""

{.warning: "User-provided warning message".}

proc gen1[T](arg: T) =
{.warning: "gen1 size of the argument is " & $sizeof(arg).}

gen1[int](1)
gen1[float](1.0)
7 changes: 7 additions & 0 deletions tests/lang/s05_pragmas/s02_misc/t05_procedure.nim
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
proc getGlobal(): int =
var state {.global.}: int
inc state
return state

doAssert getGlobal() == 1
doAssert getGlobal() == 2
Loading

0 comments on commit 35f52bc

Please sign in to comment.