123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186 |
- discard """
- targets: "c cpp js"
- """
- # Test tkStrNumLit
- import std/[macros, strutils]
- import mlexerutils
- # AST checks
- assertAST dedent """
- StmtList
- ProcDef
- AccQuoted
- Ident "\'"
- Ident "wrap"
- Empty
- Empty
- FormalParams
- Ident "string"
- IdentDefs
- Ident "number"
- Ident "string"
- Empty
- Empty
- Empty
- StmtList
- Asgn
- Ident "result"
- Infix
- Ident "&"
- Infix
- Ident "&"
- StrLit "[["
- Ident "number"
- StrLit "]]"""":
- proc `'wrap`(number: string): string =
- result = "[[" & number & "]]"
- assertAST dedent """
- StmtList
- DotExpr
- RStrLit "-38383839292839283928392839283928392839283.928493849385935898243e-50000"
- Ident "\'wrap"""":
- -38383839292839283928392839283928392839283.928493849385935898243e-50000'wrap
- proc `'wrap`(number: string): string = "[[" & number & "]]"
- proc wrap2(number: string): string = "[[" & number & "]]"
- doAssert lispReprStr(-1'wrap) == """(DotExpr (RStrLit "-1") (Ident "\'wrap"))"""
- template main =
- block: # basic suffix usage
- template `'twrap`(number: string): untyped =
- number.`'wrap`
- proc extraContext(): string =
- 22.40'wrap
- proc `*`(left, right: string): string =
- result = left & "times" & right
- proc `+`(left, right: string): string =
- result = left & "plus" & right
- doAssert 1'wrap == "[[1]]"
- doAssert -1'wrap == "[[-1]]":
- "unable to resolve a negative integer-suffix pattern"
- doAssert 12345.67890'wrap == "[[12345.67890]]"
- doAssert 1'wrap*1'wrap == "[[1]]times[[1]]":
- "unable to resolve an operator between two suffixed numeric literals"
- doAssert 1'wrap+ -1'wrap == "[[1]]plus[[-1]]": # will generate a compiler warning about inconsistent spacing
- "unable to resolve a negative suffixed numeric literal following an operator"
- doAssert 1'wrap + -1'wrap == "[[1]]plus[[-1]]"
- doAssert 1'twrap == "[[1]]"
- doAssert extraContext() == "[[22.40]]":
- "unable to return a suffixed numeric literal by an implicit return"
- doAssert 0x5a3a'wrap == "[[0x5a3a]]"
- doAssert 0o5732'wrap == "[[0o5732]]"
- doAssert 0b0101111010101'wrap == "[[0b0101111010101]]"
- doAssert -38383839292839283928392839283928392839283.928493849385935898243e-50000'wrap == "[[-38383839292839283928392839283928392839283.928493849385935898243e-50000]]"
- doAssert 1234.56'wrap == "[[1234.56]]":
- "unable to properly account for context with suffixed numeric literals"
- block: # verify that the i64, f32, etc builtin suffixes still parse correctly
- const expectedF32: float32 = 123.125
- proc `'f9`(number: string): string = # proc starts with 'f' just like 'f32'
- "[[" & number & "]]"
- proc `'f32a`(number: string): string = # looks even more like 'f32'
- "[[" & number & "]]"
- proc `'d9`(number: string): string = # proc starts with 'd' just like the d suffix
- "[[" & number & "]]"
- proc `'i9`(number: string): string = # proc starts with 'i' just like 'i64'
- "[[" & number & "]]"
- proc `'u9`(number: string): string = # proc starts with 'u' just like 'u8'
- "[[" & number & "]]"
- doAssert 123.125f32 == expectedF32:
- "failing to support non-quoted legacy f32 floating point suffix"
- doAssert 123.125'f32 == expectedF32
- doAssert 123.125e0'f32 == expectedF32
- doAssert 1234.56'wrap == 1234.56'f9
- doAssert 1234.56'wrap == 1234.56'f32a
- doAssert 1234.56'wrap == 1234.56'd9
- doAssert 1234.56'wrap == 1234.56'i9
- doAssert 1234.56'wrap == 1234.56'u9
- doAssert lispReprStr(1234.56'u9) == """(DotExpr (RStrLit "1234.56") (Ident "\'u9"))""":
- "failed to properly build AST for suffix that starts with u"
- doAssert -128'i8 == (-128).int8
- block: # case checks
- doAssert 1E2 == 100:
- "lexer not handling upper-case exponent"
- doAssert 1.0E2 == 100.0
- doAssert 1e2 == 100
- doAssert 0xdeadBEEF'wrap == "[[0xdeadBEEF]]":
- "lexer not maintaining original case"
- doAssert 0.1E12'wrap == "[[0.1E12]]"
- doAssert 0.0e12'wrap == "[[0.0e12]]"
- doAssert 0.0e+12'wrap == "[[0.0e+12]]"
- doAssert 0.0e-12'wrap == "[[0.0e-12]]"
- doAssert 0e-12'wrap == "[[0e-12]]"
- block: # macro and template usage
- template `'foo`(a: string): untyped = (a, 2)
- doAssert -12'foo == ("-12", 2)
- template `'fooplus`(a: string, b: int): untyped = (a, b)
- doAssert -12'fooplus(2) == ("-12", 2)
- template `'fooplusopt`(a: string, b: int = 99): untyped = (a, b)
- doAssert -12'fooplusopt(2) == ("-12", 2)
- doAssert -12'fooplusopt() == ("-12", 99)
- doAssert -12'fooplusopt == ("-12", 99)
- macro `'bar`(a: static string): untyped = newLit(a.repr)
- doAssert -12'bar == "\"-12\""
- macro deb(a): untyped = newLit(a.repr)
- doAssert deb(-12'bar) == "-12'bar"
- block: # bug 1 from https://github.com/nim-lang/Nim/pull/17020#issuecomment-803193947
- macro deb1(a): untyped = newLit a.repr
- macro deb2(a): untyped = newLit a.lispRepr
- doAssert deb1(-12'wrap) == "-12'wrap"
- doAssert deb1(-12'nonexistent) == "-12'nonexistent"
- doAssert deb2(-12'nonexistent) == """(DotExpr (RStrLit "-12") (Ident "\'nonexistent"))"""
- when false: # xxx bug:
- # this holds:
- doAssert deb2(-12.wrap2) == """(DotExpr (IntLit -12) (Sym "wrap2"))"""
- doAssert deb2(-12'wrap) == """(DotExpr (RStrLit "-12") (Sym "\'wrap"))"""
- # but instead this should hold:
- doAssert deb2(-12.wrap2) == """(DotExpr (IntLit -12) (Ident "wrap2"))"""
- doAssert deb2(-12'wrap) == """(DotExpr (RStrLit "-12") (Ident "\'wrap"))"""
- block: # bug 2 from https://github.com/nim-lang/Nim/pull/17020#issuecomment-803193947
- template toSuf(`'suf`): untyped =
- let x = -12'suf
- x
- doAssert toSuf(`'wrap`) == "[[-12]]"
- block: # bug 10 from https://github.com/nim-lang/Nim/pull/17020#issuecomment-803193947
- proc `myecho`(a: auto): auto = a
- template fn1(): untyped =
- let a = "abc"
- -12'wrap
- template fn2(): untyped =
- `myecho` -12'wrap
- template fn3(): untyped =
- -12'wrap
- doAssert fn1() == "[[-12]]"
- doAssert fn2() == "[[-12]]"
- doAssert fn3() == "[[-12]]"
- when false: # xxx this fails; bug 9 from https://github.com/nim-lang/Nim/pull/17020#issuecomment-803193947
- #[
- possible workaround: use `genAst` (https://github.com/nim-lang/Nim/pull/17426) and this:
- let a3 = `'wrap3`("-128")
- ]#
- block:
- macro metawrap(): untyped =
- func wrap1(a: string): string = "{" & a & "}"
- func `'wrap3`(a: string): string = "{" & a & "}"
- result = quote do:
- let a1 = wrap1"-128"
- let a2 = -128'wrap3
- metawrap()
- doAssert a1 == "{-128}"
- doAssert a2 == "{-128}"
- static: main()
- main()
|