diff --git a/tests/lang/s01_basics/s00_atoms/t01_statement.nim b/tests/lang/s01_basics/s00_atoms/t01_statement.nim index 287ebfc2ea1..10032a2813c 100644 --- a/tests/lang/s01_basics/s00_atoms/t01_statement.nim +++ b/tests/lang/s01_basics/s00_atoms/t01_statement.nim @@ -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. @@ -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 diff --git a/tests/lang/s01_basics/s00_atoms/t02_expression.nim b/tests/lang/s01_basics/s00_atoms/t02_expression.nim index f90b2e129d5..fbbf47206a4 100644 --- a/tests/lang/s01_basics/s00_atoms/t02_expression.nim +++ b/tests/lang/s01_basics/s00_atoms/t02_expression.nim @@ -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 diff --git a/tests/lang/s01_basics/s07_arrays_sequences/t01_array.nim b/tests/lang/s01_basics/s07_arrays_sequences/t01_array.nim index 359c3d248bf..a8c53fb63c4 100644 --- a/tests/lang/s01_basics/s07_arrays_sequences/t01_array.nim +++ b/tests/lang/s01_basics/s07_arrays_sequences/t01_array.nim @@ -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 = [ diff --git a/tests/lang/s01_basics/s08_user_defined_data_types/t01_tuples.nim b/tests/lang/s01_basics/s08_user_defined_data_types/t01_tuples.nim index 65e743b146d..73a76b07dce 100644 --- a/tests/lang/s01_basics/s08_user_defined_data_types/t01_tuples.nim +++ b/tests/lang/s01_basics/s08_user_defined_data_types/t01_tuples.nim @@ -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 @@ -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: diff --git a/tests/lang/s01_basics/s09_control_flow/t02_if.nim b/tests/lang/s01_basics/s09_control_flow/t02_if.nim index 83db86b9bdf..5e58d833091 100644 --- a/tests/lang/s01_basics/s09_control_flow/t02_if.nim +++ b/tests/lang/s01_basics/s09_control_flow/t02_if.nim @@ -129,4 +129,5 @@ block if_expression_noreturn: while true: let value = if true: 12 else: doAssert(false); break - doAssert value == 12 \ No newline at end of file + doAssert value == 12 + break \ No newline at end of file diff --git a/tests/lang/s01_basics/s09_control_flow/t03_case.nim b/tests/lang/s01_basics/s09_control_flow/t03_case.nim index e038c941b83..086bf2b1416 100644 --- a/tests/lang/s01_basics/s09_control_flow/t03_case.nim +++ b/tests/lang/s01_basics/s09_control_flow/t03_case.nim @@ -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 diff --git a/tests/lang/s05_pragmas/s01_interop/t01_c_header.h b/tests/lang/s05_pragmas/s01_interop/t01_c_header.h index 9d6c6018298..99eb47b6a7d 100644 --- a/tests/lang/s05_pragmas/s01_interop/t01_c_header.h +++ b/tests/lang/s05_pragmas/s01_interop/t01_c_header.h @@ -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; } diff --git a/tests/lang/s05_pragmas/s01_interop/t01_c_implementation.c b/tests/lang/s05_pragmas/s01_interop/t01_c_implementation.c index e69de29bb2d..947a57af876 100644 --- a/tests/lang/s05_pragmas/s01_interop/t01_c_implementation.c +++ b/tests/lang/s05_pragmas/s01_interop/t01_c_implementation.c @@ -0,0 +1,5 @@ +int c_compiled_only(int arg) { return arg * 2; } + +#ifdef NIM_DEFINED_FLAG +int c_in_define() { return 228; }; +#endif \ No newline at end of file diff --git a/tests/lang/s05_pragmas/s01_interop/t01_c_interop.nim b/tests/lang/s05_pragmas/s01_interop/t01_c_interop.nim index 03c148f31d0..b00feabedb3 100644 --- a/tests/lang/s05_pragmas/s01_interop/t01_c_interop.nim +++ b/tests/lang/s05_pragmas/s01_interop/t01_c_interop.nim @@ -1 +1,49 @@ -{.compile: "t01_c_implementation.c".} \ No newline at end of file +{.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 \ No newline at end of file diff --git a/tests/lang/s05_pragmas/s01_interop/t02_cxx_interop.nim b/tests/lang/s05_pragmas/s01_interop/t02_cxx_interop.nim index e5b6f78665b..7854ae30608 100644 --- a/tests/lang/s05_pragmas/s01_interop/t02_cxx_interop.nim +++ b/tests/lang/s05_pragmas/s01_interop/t02_cxx_interop.nim @@ -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: diff --git a/tests/lang/s05_pragmas/s01_interop/t03_emit.nim b/tests/lang/s05_pragmas/s01_interop/t03_emit.nim new file mode 100644 index 00000000000..e15d399f19d --- /dev/null +++ b/tests/lang/s05_pragmas/s01_interop/t03_emit.nim @@ -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() \ No newline at end of file diff --git a/tests/lang/s05_pragmas/s04_misc/readme.md b/tests/lang/s05_pragmas/s02_misc/readme.md similarity index 61% rename from tests/lang/s05_pragmas/s04_misc/readme.md rename to tests/lang/s05_pragmas/s02_misc/readme.md index a464da0354d..2e16b61902b 100644 --- a/tests/lang/s05_pragmas/s04_misc/readme.md +++ b/tests/lang/s05_pragmas/s02_misc/readme.md @@ -1,2 +1,2 @@ This section contains specification of pragmas that cannot be characterized as -purely "interop", "object" or "procedure"-related. \ No newline at end of file +purely "interop" \ No newline at end of file diff --git a/tests/lang/s05_pragmas/s02_misc/t01_ident_pragmas.nim b/tests/lang/s05_pragmas/s02_misc/t01_ident_pragmas.nim new file mode 100644 index 00000000000..02b05d6f02c --- /dev/null +++ b/tests/lang/s05_pragmas/s02_misc/t01_ident_pragmas.nim @@ -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 diff --git a/tests/lang/s05_pragmas/s02_misc/t02_flag_pragmas.nim b/tests/lang/s05_pragmas/s02_misc/t02_flag_pragmas.nim new file mode 100644 index 00000000000..429a743a05a --- /dev/null +++ b/tests/lang/s05_pragmas/s02_misc/t02_flag_pragmas.nim @@ -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() \ No newline at end of file diff --git a/tests/lang/s05_pragmas/s02_misc/t03_hint_pragmas.nim b/tests/lang/s05_pragmas/s02_misc/t03_hint_pragmas.nim new file mode 100644 index 00000000000..9e7f89db2f3 --- /dev/null +++ b/tests/lang/s05_pragmas/s02_misc/t03_hint_pragmas.nim @@ -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.} \ No newline at end of file diff --git a/tests/lang/s05_pragmas/s02_misc/t04_warning.nim b/tests/lang/s05_pragmas/s02_misc/t04_warning.nim new file mode 100644 index 00000000000..ce590d1c46b --- /dev/null +++ b/tests/lang/s05_pragmas/s02_misc/t04_warning.nim @@ -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) diff --git a/tests/lang/s05_pragmas/s02_misc/t05_procedure.nim b/tests/lang/s05_pragmas/s02_misc/t05_procedure.nim new file mode 100644 index 00000000000..a0108a08fbd --- /dev/null +++ b/tests/lang/s05_pragmas/s02_misc/t05_procedure.nim @@ -0,0 +1,7 @@ +proc getGlobal(): int = + var state {.global.}: int + inc state + return state + +doAssert getGlobal() == 1 +doAssert getGlobal() == 2 \ No newline at end of file diff --git a/tests/lang/s05_pragmas/s02_misc/t06_object.nim b/tests/lang/s05_pragmas/s02_misc/t06_object.nim new file mode 100644 index 00000000000..344f209260f --- /dev/null +++ b/tests/lang/s05_pragmas/s02_misc/t06_object.nim @@ -0,0 +1,24 @@ +block union_pragma: + ## The union pragma can be applied to any object type. It means all of the object's + ## fields are overlaid in memory.This produces a union instead of a struct in the + ## generated C/C++ code. + type + Union {.union.} = object + field1: int + field2: array[12, int] + field3: tuple[idx1, idx2: int] + + doAssert sizeof(Union) == max(sizeof(int), sizeof(array[12, int])) + + var uni = Union() + + uni.field1 = 10 + + doAssert uni.field2[0] == 10 + + doAssert uni.field3.idx1 == 10 + + uni = Union(field2: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]) + + doAssert uni.field1 == 1 + doAssert uni.field3 == (1, 2) \ No newline at end of file diff --git a/tests/lang/s05_pragmas/s04_misc/t01_ident_pragmas.nim b/tests/lang/s05_pragmas/s04_misc/t01_ident_pragmas.nim deleted file mode 100644 index 33157ffb39d..00000000000 --- a/tests/lang/s05_pragmas/s04_misc/t01_ident_pragmas.nim +++ /dev/null @@ -1,11 +0,0 @@ -## It is possible to put pragma annotations on different variable declarations. - -block const_define: - const constStrdefineDefault {.strdefine.} = "default value" - const constStrdefineUsed {.strdefine.} = "default value" - - const constIntdefineDefault {.intdefine.} = 12 - const constIntdefineUsed {.intdefine.} = 12 - - const constBooldefineDefault {.booldefine.} = true - const constBooldefineUsed {.booldefine.} = true diff --git a/tests/lang/s05_pragmas/s04_misc/t02_flag_pragmas.nim b/tests/lang/s05_pragmas/s04_misc/t02_flag_pragmas.nim deleted file mode 100644 index e69de29bb2d..00000000000