lua

A copy of the Lua development repository
Log | Files | Refs | README

literals.lua (11653B)


      1 -- $Id: testes/literals.lua $
      2 -- See Copyright Notice in file all.lua
      3 
      4 print('testing scanner')
      5 
      6 local debug = require "debug"
      7 
      8 
      9 local function dostring (x) return assert(load(x), "")() end
     10 
     11 dostring("x \v\f = \t\r 'a\0a' \v\f\f")
     12 assert(x == 'a\0a' and string.len(x) == 3)
     13 _G.x = nil
     14 
     15 -- escape sequences
     16 assert('\n\"\'\\' == [[
     17 
     18 "'\]])
     19 
     20 assert(string.find("\a\b\f\n\r\t\v", "^%c%c%c%c%c%c%c$"))
     21 
     22 -- assume ASCII just for tests:
     23 assert("\09912" == 'c12')
     24 assert("\99ab" == 'cab')
     25 assert("\099" == '\99')
     26 assert("\099\n" == 'c\10')
     27 assert('\0\0\0alo' == '\0' .. '\0\0' .. 'alo')
     28 
     29 assert(010 .. 020 .. -030 == "1020-30")
     30 
     31 -- hexadecimal escapes
     32 assert("\x00\x05\x10\x1f\x3C\xfF\xe8" == "\0\5\16\31\60\255\232")
     33 
     34 local function lexstring (x, y, n)
     35   local f = assert(load('return ' .. x ..
     36             ', require"debug".getinfo(1).currentline', ''))
     37   local s, l = f()
     38   assert(s == y and l == n)
     39 end
     40 
     41 lexstring("'abc\\z  \n   efg'", "abcefg", 2)
     42 lexstring("'abc\\z  \n\n\n'", "abc", 4)
     43 lexstring("'\\z  \n\t\f\v\n'",  "", 3)
     44 lexstring("[[\nalo\nalo\n\n]]", "alo\nalo\n\n", 5)
     45 lexstring("[[\nalo\ralo\n\n]]", "alo\nalo\n\n", 5)
     46 lexstring("[[\nalo\ralo\r\n]]", "alo\nalo\n", 4)
     47 lexstring("[[\ralo\n\ralo\r\n]]", "alo\nalo\n", 4)
     48 lexstring("[[alo]\n]alo]]", "alo]\n]alo", 2)
     49 
     50 assert("abc\z
     51         def\z
     52         ghi\z
     53        " == 'abcdefghi')
     54 
     55 
     56 -- UTF-8 sequences
     57 assert("\u{0}\u{00000000}\x00\0" == string.char(0, 0, 0, 0))
     58 
     59 -- limits for 1-byte sequences
     60 assert("\u{0}\u{7F}" == "\x00\x7F")
     61 
     62 -- limits for 2-byte sequences
     63 assert("\u{80}\u{7FF}" == "\xC2\x80\xDF\xBF")
     64 
     65 -- limits for 3-byte sequences
     66 assert("\u{800}\u{FFFF}" ==   "\xE0\xA0\x80\xEF\xBF\xBF")
     67 
     68 -- limits for 4-byte sequences
     69 assert("\u{10000}\u{1FFFFF}" == "\xF0\x90\x80\x80\xF7\xBF\xBF\xBF")
     70 
     71 -- limits for 5-byte sequences
     72 assert("\u{200000}\u{3FFFFFF}" == "\xF8\x88\x80\x80\x80\xFB\xBF\xBF\xBF\xBF")
     73 
     74 -- limits for 6-byte sequences
     75 assert("\u{4000000}\u{7FFFFFFF}" ==
     76        "\xFC\x84\x80\x80\x80\x80\xFD\xBF\xBF\xBF\xBF\xBF")
     77 
     78 
     79 -- Error in escape sequences
     80 local function lexerror (s, err)
     81   local st, msg = load('return ' .. s, '')
     82   if err ~= '<eof>' then err = err .. "'" end
     83   assert(not st and string.find(msg, "near .-" .. err))
     84 end
     85 
     86 lexerror([["abc\x"]], [[\x"]])
     87 lexerror([["abc\x]], [[\x]])
     88 lexerror([["\x]], [[\x]])
     89 lexerror([["\x5"]], [[\x5"]])
     90 lexerror([["\x5]], [[\x5]])
     91 lexerror([["\xr"]], [[\xr]])
     92 lexerror([["\xr]], [[\xr]])
     93 lexerror([["\x.]], [[\x.]])
     94 lexerror([["\x8%"]], [[\x8%%]])
     95 lexerror([["\xAG]], [[\xAG]])
     96 lexerror([["\g"]], [[\g]])
     97 lexerror([["\g]], [[\g]])
     98 lexerror([["\."]], [[\%.]])
     99 
    100 lexerror([["\999"]], [[\999"]])
    101 lexerror([["xyz\300"]], [[\300"]])
    102 lexerror([["   \256"]], [[\256"]])
    103 
    104 -- errors in UTF-8 sequences
    105 lexerror([["abc\u{100000000}"]], [[abc\u{100000000]])   -- too large
    106 lexerror([["abc\u11r"]], [[abc\u1]])    -- missing '{'
    107 lexerror([["abc\u"]], [[abc\u"]])    -- missing '{'
    108 lexerror([["abc\u{11r"]], [[abc\u{11r]])    -- missing '}'
    109 lexerror([["abc\u{11"]], [[abc\u{11"]])    -- missing '}'
    110 lexerror([["abc\u{11]], [[abc\u{11]])    -- missing '}'
    111 lexerror([["abc\u{r"]], [[abc\u{r]])     -- no digits
    112 
    113 -- unfinished strings
    114 lexerror("[=[alo]]", "<eof>")
    115 lexerror("[=[alo]=", "<eof>")
    116 lexerror("[=[alo]", "<eof>")
    117 lexerror("'alo", "<eof>")
    118 lexerror("'alo \\z  \n\n", "<eof>")
    119 lexerror("'alo \\z", "<eof>")
    120 lexerror([['alo \98]], "<eof>")
    121 
    122 -- valid characters in variable names
    123 for i = 0, 255 do
    124   local s = string.char(i)
    125   assert(not string.find(s, "[a-zA-Z_]") == not load(s .. "=1", ""))
    126   assert(not string.find(s, "[a-zA-Z_0-9]") ==
    127          not load("a" .. s .. "1 = 1", ""))
    128 end
    129 
    130 
    131 -- long variable names
    132 
    133 local var1 = string.rep('a', 15000) .. '1'
    134 local var2 = string.rep('a', 15000) .. '2'
    135 local prog = string.format([[
    136   %s = 5
    137   %s = %s + 1
    138   return function () return %s - %s end
    139 ]], var1, var2, var1, var1, var2)
    140 local f = dostring(prog)
    141 assert(_G[var1] == 5 and _G[var2] == 6 and f() == -1)
    142 _G[var1], _G[var2] = nil
    143 print('+')
    144 
    145 -- escapes --
    146 assert("\n\t" == [[
    147 
    148 	]])
    149 assert([[
    150 
    151  $debug]] == "\n $debug")
    152 assert([[ [ ]] ~= [[ ] ]])
    153 -- long strings --
    154 local b = "001234567890123456789012345678901234567891234567890123456789012345678901234567890012345678901234567890123456789012345678912345678901234567890123456789012345678900123456789012345678901234567890123456789123456789012345678901234567890123456789001234567890123456789012345678901234567891234567890123456789012345678901234567890012345678901234567890123456789012345678912345678901234567890123456789012345678900123456789012345678901234567890123456789123456789012345678901234567890123456789001234567890123456789012345678901234567891234567890123456789012345678901234567890012345678901234567890123456789012345678912345678901234567890123456789012345678900123456789012345678901234567890123456789123456789012345678901234567890123456789001234567890123456789012345678901234567891234567890123456789012345678901234567890012345678901234567890123456789012345678912345678901234567890123456789012345678900123456789012345678901234567890123456789123456789012345678901234567890123456789"
    155 assert(string.len(b) == 960)
    156 prog = [=[
    157 print('+')
    158 
    159 local a1 = [["this is a 'string' with several 'quotes'"]]
    160 local a2 = "'quotes'"
    161 
    162 assert(string.find(a1, a2) == 34)
    163 print('+')
    164 
    165 a1 = [==[temp = [[an arbitrary value]]; ]==]
    166 assert(load(a1))()
    167 assert(temp == 'an arbitrary value')
    168 _G.temp = nil
    169 -- long strings --
    170 local b = "001234567890123456789012345678901234567891234567890123456789012345678901234567890012345678901234567890123456789012345678912345678901234567890123456789012345678900123456789012345678901234567890123456789123456789012345678901234567890123456789001234567890123456789012345678901234567891234567890123456789012345678901234567890012345678901234567890123456789012345678912345678901234567890123456789012345678900123456789012345678901234567890123456789123456789012345678901234567890123456789001234567890123456789012345678901234567891234567890123456789012345678901234567890012345678901234567890123456789012345678912345678901234567890123456789012345678900123456789012345678901234567890123456789123456789012345678901234567890123456789001234567890123456789012345678901234567891234567890123456789012345678901234567890012345678901234567890123456789012345678912345678901234567890123456789012345678900123456789012345678901234567890123456789123456789012345678901234567890123456789"
    171 assert(string.len(b) == 960)
    172 print('+')
    173 
    174 local a = [[00123456789012345678901234567890123456789123456789012345678901234567890123456789
    175 00123456789012345678901234567890123456789123456789012345678901234567890123456789
    176 00123456789012345678901234567890123456789123456789012345678901234567890123456789
    177 00123456789012345678901234567890123456789123456789012345678901234567890123456789
    178 00123456789012345678901234567890123456789123456789012345678901234567890123456789
    179 00123456789012345678901234567890123456789123456789012345678901234567890123456789
    180 00123456789012345678901234567890123456789123456789012345678901234567890123456789
    181 00123456789012345678901234567890123456789123456789012345678901234567890123456789
    182 00123456789012345678901234567890123456789123456789012345678901234567890123456789
    183 00123456789012345678901234567890123456789123456789012345678901234567890123456789
    184 00123456789012345678901234567890123456789123456789012345678901234567890123456789
    185 00123456789012345678901234567890123456789123456789012345678901234567890123456789
    186 00123456789012345678901234567890123456789123456789012345678901234567890123456789
    187 00123456789012345678901234567890123456789123456789012345678901234567890123456789
    188 00123456789012345678901234567890123456789123456789012345678901234567890123456789
    189 00123456789012345678901234567890123456789123456789012345678901234567890123456789
    190 00123456789012345678901234567890123456789123456789012345678901234567890123456789
    191 00123456789012345678901234567890123456789123456789012345678901234567890123456789
    192 00123456789012345678901234567890123456789123456789012345678901234567890123456789
    193 00123456789012345678901234567890123456789123456789012345678901234567890123456789
    194 00123456789012345678901234567890123456789123456789012345678901234567890123456789
    195 00123456789012345678901234567890123456789123456789012345678901234567890123456789
    196 00123456789012345678901234567890123456789123456789012345678901234567890123456789
    197 ]]
    198 assert(string.len(a) == 1863)
    199 assert(string.sub(a, 1, 40) == string.sub(b, 1, 40))
    200 x = 1
    201 ]=]
    202 
    203 print('+')
    204 _G.x = nil
    205 dostring(prog)
    206 assert(x)
    207 _G.x = nil
    208 
    209 
    210 
    211 do  -- reuse of long strings
    212 
    213   -- get the address of a string
    214   local function getadd (s) return string.format("%p", s) end
    215 
    216   local s1 <const> = "01234567890123456789012345678901234567890123456789"
    217   local s2 <const> = "01234567890123456789012345678901234567890123456789"
    218   local s3 = "01234567890123456789012345678901234567890123456789"
    219   local function foo() return s1 end
    220   local function foo1() return s3 end
    221   local function foo2()
    222     return "01234567890123456789012345678901234567890123456789"
    223   end
    224   local a1 = getadd(s1)
    225   assert(a1 == getadd(s2))
    226   assert(a1 == getadd(foo()))
    227   assert(a1 == getadd(foo1()))
    228   assert(a1 == getadd(foo2()))
    229 
    230   local sd = "0123456789" .. "0123456789012345678901234567890123456789"
    231   assert(sd == s1 and getadd(sd) ~= a1)
    232 end
    233 
    234 
    235 -- testing line ends
    236 prog = [[
    237 local a = 1        -- a comment
    238 local b = 2
    239 
    240 
    241 x = [=[
    242 hi
    243 ]=]
    244 y = "\
    245 hello\r\n\
    246 "
    247 return require"debug".getinfo(1).currentline
    248 ]]
    249 
    250 for _, n in pairs{"\n", "\r", "\n\r", "\r\n"} do
    251   local prog, nn = string.gsub(prog, "\n", n)
    252   assert(dostring(prog) == nn)
    253   assert(_G.x == "hi\n" and _G.y == "\nhello\r\n\n")
    254 end
    255 _G.x, _G.y = nil
    256 
    257 
    258 -- testing comments and strings with long brackets
    259 local a = [==[]=]==]
    260 assert(a == "]=")
    261 
    262 a = [==[[===[[=[]]=][====[]]===]===]==]
    263 assert(a == "[===[[=[]]=][====[]]===]===")
    264 
    265 a = [====[[===[[=[]]=][====[]]===]===]====]
    266 assert(a == "[===[[=[]]=][====[]]===]===")
    267 
    268 a = [=[]]]]]]]]]=]
    269 assert(a == "]]]]]]]]")
    270 
    271 
    272 --[===[
    273 x y z [==[ blu foo
    274 ]==
    275 ]
    276 ]=]==]
    277 error error]=]===]
    278 
    279 -- generate all strings of four of these chars
    280 local x = {"=", "[", "]", "\n"}
    281 local len = 4
    282 local function gen (c, n)
    283   if n==0 then coroutine.yield(c)
    284   else
    285     for _, a in pairs(x) do
    286       gen(c..a, n-1)
    287     end
    288   end
    289 end
    290 
    291 for s in coroutine.wrap(function () gen("", len) end) do
    292   assert(s == load("return [====[\n"..s.."]====]", "")())
    293 end
    294 
    295 
    296 -- testing decimal point locale
    297 if os.setlocale("pt_BR") or os.setlocale("ptb") then
    298   assert(tonumber("3,4") == 3.4 and tonumber"3.4" == 3.4)
    299   assert(tonumber("  -.4  ") == -0.4)
    300   assert(tonumber("  +0x.41  ") == 0X0.41)
    301   assert(not load("a = (3,4)"))
    302   assert(assert(load("return 3.4"))() == 3.4)
    303   assert(assert(load("return .4,3"))() == .4)
    304   assert(assert(load("return 4."))() == 4.)
    305   assert(assert(load("return 4.+.5"))() == 4.5)
    306 
    307   assert(" 0x.1 " + " 0x,1" + "-0X.1\t" == 0x0.1)
    308 
    309   assert(not tonumber"inf" and not tonumber"NAN")
    310 
    311   assert(assert(load(string.format("return %q", 4.51)))() == 4.51)
    312 
    313   local a,b = load("return 4.5.")
    314   assert(string.find(b, "'4%.5%.'"))
    315 
    316   assert(os.setlocale("C"))
    317 else
    318   (Message or print)(
    319    '\n >>> pt_BR locale not available: skipping decimal point tests <<<\n')
    320 end
    321 
    322 
    323 -- testing %q x line ends
    324 local s = "a string with \r and \n and \r\n and \n\r"
    325 local c = string.format("return %q", s)
    326 assert(assert(load(c))() == s)
    327 
    328 -- testing errors
    329 assert(not load"a = 'non-ending string")
    330 assert(not load"a = 'non-ending string\n'")
    331 assert(not load"a = '\\345'")
    332 assert(not load"a = [=x]")
    333 
    334 local function malformednum (n, exp)
    335   local s, msg = load("return " .. n)
    336   assert(not s and string.find(msg, exp))
    337 end
    338 
    339 malformednum("0xe-", "near <eof>")
    340 malformednum("0xep-p", "malformed number")
    341 malformednum("1print()", "malformed number")
    342 
    343 print('OK')