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')