Package evaluation to test CSTParser on Julia 1.14.0-DEV.1299 (6d6224db99*) started at 2025-11-25T12:25:38.526 ################################################################################ # Set-up # Installing PkgEval dependencies (TestEnv)... Set-up completed after 9.28s ################################################################################ # Installation # Installing CSTParser... Resolving package versions... Updating `~/.julia/environments/v1.14/Project.toml` [00ebfdb7] + CSTParser v3.4.3 Updating `~/.julia/environments/v1.14/Manifest.toml` [00ebfdb7] + CSTParser v3.4.3 [0796e94c] + Tokenize v0.5.29 Installation completed after 1.06s ################################################################################ # Precompilation # Precompiling PkgEval dependencies... ┌ Error: Failed to use TestEnv.jl; test dependencies will not be precompiled │ exception = │ UndefVarError: `project_rel_path` not defined in `TestEnv` │ Suggestion: this global was defined as `Pkg.Operations.project_rel_path` but not assigned a value. │ Stacktrace: │ [1] get_test_dir(ctx::Pkg.Types.Context, pkgspec::PackageSpec) │ @ TestEnv ~/.julia/packages/TestEnv/i9lgt/src/julia-1.11/common.jl:75 │ [2] test_dir_has_project_file │ @ ~/.julia/packages/TestEnv/i9lgt/src/julia-1.11/common.jl:52 [inlined] │ [3] maybe_gen_project_override! │ @ ~/.julia/packages/TestEnv/i9lgt/src/julia-1.11/common.jl:83 [inlined] │ [4] activate(pkg::String; allow_reresolve::Bool) │ @ TestEnv ~/.julia/packages/TestEnv/i9lgt/src/julia-1.11/activate_set.jl:12 │ [5] activate(pkg::String) │ @ TestEnv ~/.julia/packages/TestEnv/i9lgt/src/julia-1.11/activate_set.jl:9 │ [6] top-level scope │ @ /PkgEval.jl/scripts/precompile.jl:24 │ [7] include(mod::Module, _path::String) │ @ Base ./Base.jl:309 │ [8] exec_options(opts::Base.JLOptions) │ @ Base ./client.jl:344 │ [9] _start() │ @ Base ./client.jl:577 └ @ Main /PkgEval.jl/scripts/precompile.jl:26 Precompiling package dependencies... Precompiling packages... 6204.8 ms ✓ CSTParser 1 dependency successfully precompiled in 6 seconds. 1 already precompiled. Precompilation completed after 19.67s ################################################################################ # Testing # Testing CSTParser Status `/tmp/jl_E4nJ2Y/Project.toml` [00ebfdb7] CSTParser v3.4.3 [f8b46487] TestItemRunner v1.1.1 [0796e94c] Tokenize v0.5.29 [8dfed614] Test v1.11.0 Status `/tmp/jl_E4nJ2Y/Manifest.toml` [00ebfdb7] CSTParser v3.4.3 [f8b46487] TestItemRunner v1.1.1 [1c621080] TestItems v1.0.0 [0796e94c] Tokenize v0.5.29 [0dad84c5] ArgTools v1.1.2 [56f22d72] Artifacts v1.11.0 [2a0f44e3] Base64 v1.11.0 [ade2ca70] Dates v1.11.0 [f43a241f] Downloads v1.7.0 [7b1f6079] FileWatching v1.11.0 [b77e0a4c] InteractiveUtils v1.11.0 [ac6e5ff7] JuliaSyntaxHighlighting v1.12.0 [b27032c2] LibCURL v1.0.0 [76f85450] LibGit2 v1.11.0 [8f399da3] Libdl v1.11.0 [56ddb016] Logging v1.11.0 [d6f4376e] Markdown v1.11.0 [ca575930] NetworkOptions v1.3.0 [44cfe95a] Pkg v1.13.0 [de0858da] Printf v1.11.0 [9a3f8284] Random v1.11.0 [ea8e919c] SHA v1.0.0 [9e88b42a] Serialization v1.11.0 [f489334b] StyledStrings v1.13.0 [fa267f1f] TOML v1.0.3 [a4e569a6] Tar v1.10.0 [8dfed614] Test v1.11.0 [cf7118a7] UUIDs v1.11.0 [4ec0a83e] Unicode v1.11.0 [e66e0078] CompilerSupportLibraries_jll v1.3.0+1 [deac9b47] LibCURL_jll v8.17.0+0 [e37daf67] LibGit2_jll v1.9.1+0 [29816b5a] LibSSH2_jll v1.11.3+1 [14a3606d] MozillaCACerts_jll v2025.11.4 [458c3c95] OpenSSL_jll v3.5.4+0 [efcefdf7] PCRE2_jll v10.47.0+0 [83775a58] Zlib_jll v1.3.1+2 [3161d3a3] Zstd_jll v1.5.7+1 [8e850ede] nghttp2_jll v1.68.0+1 [3f19e933] p7zip_jll v17.7.0+0 Testing Running tests... Mismatch between flisp and CSTParser when parsing string for outer $ i = 1:3 end ParserState: ParseState at 23 last : INTEGER (1,19-1,19 INTEGER ) (ws) current : END (1,21-1,23 KEYWORD ) (empty) next : ENDMARKER (1,24-1,23 ENDMARKER ) (empty) CSTParser Expr: 1:23 for 1:16 1:2 OP: = 1:10 call 1:2 OP: $ 3:8 outer 9:10 i 11:14 block 11:14 call 11:11 OP: : 12:12 INTEGER: 1 13:14 INTEGER: 3 17:16 block Converted CSTParser Expr: for outer $ i = begin 1:3 end end Base EXPR: for outer $ i = 1:3 end for outer parsing: Test Failed at /home/pkgeval/.julia/packages/CSTParser/0hXvH/test/parser/test_keyword_blocks.jl:154 Expression: "for outer \$ i = 1:3 end" |> test_expr Evaluated: "for outer \$ i = 1:3 end" |> Main.var"##144".test_expr Stacktrace: [1] top-level scope @ ~/.julia/packages/CSTParser/0hXvH/test/parser/test_keyword_blocks.jl:150 [2] macro expansion @ /opt/julia/share/julia/stdlib/v1.14/Test/src/Test.jl:1961 [inlined] [3] macro expansion @ ~/.julia/packages/CSTParser/0hXvH/test/parser/test_keyword_blocks.jl:154 [inlined] [4] macro expansion @ /opt/julia/share/julia/stdlib/v1.14/Test/src/Test.jl:753 [inlined] :kw: Test Failed at /home/pkgeval/.julia/packages/CSTParser/0hXvH/test/shared.jl:37 Expression: to_codeobject(x) == jl_parse(s) Evaluated: f(::typeof(a) = begin 1 end) == f(::typeof(a) = 1) Stacktrace: [1] macro expansion @ /opt/julia/share/julia/stdlib/v1.14/Test/src/Test.jl:753 [inlined] [2] test_expr(s::String, head::Symbol, n::Int64, endswithtrivia::Bool) @ Main.var"##162" ~/.julia/packages/CSTParser/0hXvH/test/shared.jl:37 Mismatch between flisp and CSTParser when parsing string a.{1} ParserState: ParseState at 5 last : INTEGER (1,4-1,4 INTEGER ) (empty) current : RBRACE (1,5-1,5 RBRACE ) (empty) next : ENDMARKER (1,6-1,5 ENDMARKER ) (empty) CSTParser Expr: 1:5 1:1 OP: . 1:1 a 2:4 quote 2:4 braces 2:2 INTEGER: 1 Converted CSTParser Expr: a.:({1}) Base EXPR: a.:({1}) No longer broken things: Test Failed at /home/pkgeval/.julia/packages/CSTParser/0hXvH/test/parser/test_parser.jl:354 Expression: "a.{1}" |> test_expr Evaluated: "a.{1}" |> Main.var"##245".test_expr Stacktrace: [1] top-level scope @ ~/.julia/packages/CSTParser/0hXvH/test/parser/test_parser.jl:539 [2] macro expansion @ /opt/julia/share/julia/stdlib/v1.14/Test/src/Test.jl:753 [inlined] ┌ Error: parsing difference │ file = "/opt/julia/bin/../share/julia/JuliaLowering/src/desugaring.jl" └ @ Main.var"##296" ~/.julia/packages/CSTParser/0hXvH/test/test_check_base.jl:157 "svec" ::K"core" "svec"::K"core" ::K"core" K"core" K"core" @K_str ::K"core" K"core" "svec" ::K"core" "svec"::K"core" "svec" ::K"core" "svec"::K"core" ::K"core" K"core" K"core" @K_str ::K"core" K"core" "svec" ::K"core" "svec"::K"core" [K"call"; "svec" ::K"core"; arg_types...] [K"call"; "svec"::K"core"; arg_types...] "svec" ::K"core" "svec"::K"core" ::K"core" K"core" K"core" @K_str ::K"core" K"core" "svec" ::K"core" "svec"::K"core" [K"call"; "svec" ::K"core"; typevar_names...] [K"call"; "svec"::K"core"; typevar_names...] [(K"call")(callex_srcref); "svec" ::K"core"; [K"call"; "svec" ::K"core"; arg_types...]; [K"call"; "svec" ::K"core"; typevar_names...]; ::(K"SourceLocation")(callex_srcref)] [(K"call")(callex_srcref); "svec"::K"core"; [K"call"; "svec"::K"core"; arg_types...]; [K"call"; "svec"::K"core"; typevar_names...]; ::(K"SourceLocation")(callex_srcref)] method_metadata := [(K"call")(callex_srcref); "svec" ::K"core"; [K"call"; "svec" ::K"core"; arg_types...]; [K"call"; "svec" ::K"core"; typevar_names...]; ::(K"SourceLocation")(callex_srcref)] method_metadata := [(K"call")(callex_srcref); "svec"::K"core"; [K"call"; "svec"::K"core"; arg_types...]; [K"call"; "svec"::K"core"; typevar_names...]; ::(K"SourceLocation")(callex_srcref)] [K"block"; method_metadata := [(K"call")(callex_srcref); "svec" ::K"core"; [K"call"; "svec" ::K"core"; arg_types...]; [K"call"; "svec" ::K"core"; typevar_names...]; ::(K"SourceLocation")(callex_srcref)]; [K"method"; if isnothing(method_table) "nothing"::K"core" else method_table end; method_metadata; [(K"lambda")(body, is_toplevel_thunk = false, toplevel_pure = false); [K"block" arg_names...]; [K"block" typevar_names...]; body; ret_var]]; [K"removable" method_metadata]] [K"block"; method_metadata := [(K"call")(callex_srcref); "svec"::K"core"; [K"call"; "svec"::K"core"; arg_types...]; [K"call"; "svec"::K"core"; typevar_names...]; ::(K"SourceLocation")(callex_srcref)]; [K"method"; if isnothing(method_table) "nothing"::K"core" else method_table end; method_metadata; [(K"lambda")(body, is_toplevel_thunk = false, toplevel_pure = false); [K"block" arg_names...]; [K"block" typevar_names...]; body; ret_var]]; [K"removable" method_metadata]] @ast ctx srcref [K"block"; method_metadata := [(K"call")(callex_srcref); "svec" ::K"core"; [K"call"; "svec" ::K"core"; arg_types...]; [K"call"; "svec" ::K"core"; typevar_names...]; ::(K"SourceLocation")(callex_srcref)]; [K"method"; if isnothing(method_table) "nothing"::K"core" else method_table end; method_metadata; [(K"lambda")(body, is_toplevel_thunk = false, toplevel_pure = false); [K"block" arg_names...]; [K"block" typevar_names...]; body; ret_var]]; [K"removable" method_metadata]] @ast ctx srcref [K"block"; method_metadata := [(K"call")(callex_srcref); "svec"::K"core"; [K"call"; "svec"::K"core"; arg_types...]; [K"call"; "svec"::K"core"; typevar_names...]; ::(K"SourceLocation")(callex_srcref)]; [K"method"; if isnothing(method_table) "nothing"::K"core" else method_table end; method_metadata; [(K"lambda")(body, is_toplevel_thunk = false, toplevel_pure = false); [K"block" arg_names...]; [K"block" typevar_names...]; body; ret_var]]; [K"removable" method_metadata]] begin @ast ctx srcref [K"block"; method_metadata := [(K"call")(callex_srcref); "svec" ::K"core"; [K"call"; "svec" ::K"core"; arg_types...]; [K"call"; "svec" ::K"core"; typevar_names...]; ::(K"SourceLocation")(callex_srcref)]; [K"method"; if isnothing(method_table) "nothing"::K"core" else method_table end; method_metadata; [(K"lambda")(body, is_toplevel_thunk = false, toplevel_pure = false); [K"block" arg_names...]; [K"block" typevar_names...]; body; ret_var]]; [K"removable" method_metadata]] end begin @ast ctx srcref [K"block"; method_metadata := [(K"call")(callex_srcref); "svec"::K"core"; [K"call"; "svec"::K"core"; arg_types...]; [K"call"; "svec"::K"core"; typevar_names...]; ::(K"SourceLocation")(callex_srcref)]; [K"method"; if isnothing(method_table) "nothing"::K"core" else method_table end; method_metadata; [(K"lambda")(body, is_toplevel_thunk = false, toplevel_pure = false); [K"block" arg_names...]; [K"block" typevar_names...]; body; ret_var]]; [K"removable" method_metadata]] end function method_def_expr(ctx, srcref, callex_srcref, method_table, typevar_names, arg_names, arg_types, body, ret_var = nothing) @ast ctx srcref [K"block"; method_metadata := [(K"call")(callex_srcref); "svec" ::K"core"; [K"call"; "svec" ::K"core"; arg_types...]; [K"call"; "svec" ::K"core"; typevar_names...]; ::(K"SourceLocation")(callex_srcref)]; [K"method"; if isnothing(method_table) "nothing"::K"core" else method_table end; method_metadata; [(K"lambda")(body, is_toplevel_thunk = false, toplevel_pure = false); [K"block" arg_names...]; [K"block" typevar_names...]; body; ret_var]]; [K"removable" method_metadata]] end function method_def_expr(ctx, srcref, callex_srcref, method_table, typevar_names, arg_names, arg_types, body, ret_var = nothing) @ast ctx srcref [K"block"; method_metadata := [(K"call")(callex_srcref); "svec"::K"core"; [K"call"; "svec"::K"core"; arg_types...]; [K"call"; "svec"::K"core"; typevar_names...]; ::(K"SourceLocation")(callex_srcref)]; [K"method"; if isnothing(method_table) "nothing"::K"core" else method_table end; method_metadata; [(K"lambda")(body, is_toplevel_thunk = false, toplevel_pure = false); [K"block" arg_names...]; [K"block" typevar_names...]; body; ret_var]]; [K"removable" method_metadata]] end eval_using ::K"Value" eval_using::K"Value" ::K"Value" K"Value" K"Value" @K_str ::K"Value" K"Value" eval_using ::K"Value" eval_using::K"Value" ctx.mod ::K"Value" ctx.mod::K"Value" ::K"Value" K"Value" K"Value" @K_str ::K"Value" K"Value" ctx.mod ::K"Value" ctx.mod::K"Value" [K"call"; eval_using ::K"Value"; ctx.mod ::K"Value"; spec] [K"call"; eval_using::K"Value"; ctx.mod::K"Value"; spec] @ast ctx spec [K"call"; eval_using ::K"Value"; ctx.mod ::K"Value"; spec] @ast ctx spec [K"call"; eval_using::K"Value"; ctx.mod::K"Value"; spec] push!(stmts, @ast(ctx, spec, [K"call"; eval_using ::K"Value"; ctx.mod ::K"Value"; spec])) push!(stmts, @ast(ctx, spec, [K"call"; eval_using::K"Value"; ctx.mod::K"Value"; spec])) begin push!(stmts, @ast(ctx, spec, [K"call"; eval_using ::K"Value"; ctx.mod ::K"Value"; spec])) end begin push!(stmts, @ast(ctx, spec, [K"call"; eval_using::K"Value"; ctx.mod::K"Value"; spec])) end eval_import ::K"Value" eval_import::K"Value" ::K"Value" K"Value" K"Value" @K_str ::K"Value" K"Value" eval_import ::K"Value" eval_import::K"Value" !is_using ::K"Bool" (!is_using)::K"Bool" ::K"Bool" K"Bool" K"Bool" @K_str ::K"Bool" K"Bool" !is_using ::K"Bool" (!is_using)::K"Bool" ctx.mod ::K"Value" ctx.mod::K"Value" ::K"Value" K"Value" K"Value" @K_str ::K"Value" K"Value" ctx.mod ::K"Value" ctx.mod::K"Value" "nothing" ::K"top" "nothing"::K"top" ::K"top" K"top" K"top" @K_str ::K"top" K"top" "nothing" ::K"top" "nothing"::K"top" [K"call"; eval_import ::K"Value"; !is_using ::K"Bool"; ctx.mod ::K"Value"; "nothing" ::K"top"; spec] [K"call"; eval_import::K"Value"; (!is_using)::K"Bool"; ctx.mod::K"Value"; "nothing"::K"top"; spec] @ast ctx spec [K"call"; eval_import ::K"Value"; !is_using ::K"Bool"; ctx.mod ::K"Value"; "nothing" ::K"top"; spec] @ast ctx spec [K"call"; eval_import::K"Value"; (!is_using)::K"Bool"; ctx.mod::K"Value"; "nothing"::K"top"; spec] push!(stmts, @ast(ctx, spec, [K"call"; eval_import ::K"Value"; !is_using ::K"Bool"; ctx.mod ::K"Value"; "nothing" ::K"top"; spec])) push!(stmts, @ast(ctx, spec, [K"call"; eval_import::K"Value"; (!is_using)::K"Bool"; ctx.mod::K"Value"; "nothing"::K"top"; spec])) begin push!(stmts, @ast(ctx, spec, [K"call"; eval_import ::K"Value"; !is_using ::K"Bool"; ctx.mod ::K"Value"; "nothing" ::K"top"; spec])) end begin push!(stmts, @ast(ctx, spec, [K"call"; eval_import::K"Value"; (!is_using)::K"Bool"; ctx.mod::K"Value"; "nothing"::K"top"; spec])) end if is_using push!(stmts, @ast(ctx, spec, [K"call"; eval_using ::K"Value"; ctx.mod ::K"Value"; spec])) else push!(stmts, @ast(ctx, spec, [K"call"; eval_import ::K"Value"; !is_using ::K"Bool"; ctx.mod ::K"Value"; "nothing" ::K"top"; spec])) end if is_using push!(stmts, @ast(ctx, spec, [K"call"; eval_using::K"Value"; ctx.mod::K"Value"; spec])) else push!(stmts, @ast(ctx, spec, [K"call"; eval_import::K"Value"; (!is_using)::K"Bool"; ctx.mod::K"Value"; "nothing"::K"top"; spec])) end begin if is_using push!(stmts, @ast(ctx, spec, [K"call"; eval_using ::K"Value"; ctx.mod ::K"Value"; spec])) else push!(stmts, @ast(ctx, spec, [K"call"; eval_import ::K"Value"; !is_using ::K"Bool"; ctx.mod ::K"Value"; "nothing" ::K"top"; spec])) end push!(stmts, @ast(ctx, spec, ::K"latestworld")) end begin if is_using push!(stmts, @ast(ctx, spec, [K"call"; eval_using::K"Value"; ctx.mod::K"Value"; spec])) else push!(stmts, @ast(ctx, spec, [K"call"; eval_import::K"Value"; (!is_using)::K"Bool"; ctx.mod::K"Value"; "nothing"::K"top"; spec])) end push!(stmts, @ast(ctx, spec, ::K"latestworld")) end for spec = path_specs if is_using push!(stmts, @ast(ctx, spec, [K"call"; eval_using ::K"Value"; ctx.mod ::K"Value"; spec])) else push!(stmts, @ast(ctx, spec, [K"call"; eval_import ::K"Value"; !is_using ::K"Bool"; ctx.mod ::K"Value"; "nothing" ::K"top"; spec])) end push!(stmts, @ast(ctx, spec, ::K"latestworld")) end for spec = path_specs if is_using push!(stmts, @ast(ctx, spec, [K"call"; eval_using::K"Value"; ctx.mod::K"Value"; spec])) else push!(stmts, @ast(ctx, spec, [K"call"; eval_import::K"Value"; (!is_using)::K"Bool"; ctx.mod::K"Value"; "nothing"::K"top"; spec])) end push!(stmts, @ast(ctx, spec, ::K"latestworld")) end begin for spec = path_specs if is_using push!(stmts, @ast(ctx, spec, [K"call"; eval_using ::K"Value"; ctx.mod ::K"Value"; spec])) else push!(stmts, @ast(ctx, spec, [K"call"; eval_import ::K"Value"; !is_using ::K"Bool"; ctx.mod ::K"Value"; "nothing" ::K"top"; spec])) end push!(stmts, @ast(ctx, spec, ::K"latestworld")) end end begin for spec = path_specs if is_using push!(stmts, @ast(ctx, spec, [K"call"; eval_using::K"Value"; ctx.mod::K"Value"; spec])) else push!(stmts, @ast(ctx, spec, [K"call"; eval_import::K"Value"; (!is_using)::K"Bool"; ctx.mod::K"Value"; "nothing"::K"top"; spec])) end push!(stmts, @ast(ctx, spec, ::K"latestworld")) end end eval_import ::K"Value" eval_import::K"Value" ::K"Value" K"Value" K"Value" @K_str ::K"Value" K"Value" eval_import ::K"Value" eval_import::K"Value" !is_using ::K"Bool" (!is_using)::K"Bool" ::K"Bool" K"Bool" K"Bool" @K_str ::K"Bool" K"Bool" !is_using ::K"Bool" (!is_using)::K"Bool" ctx.mod ::K"Value" ctx.mod::K"Value" ::K"Value" K"Value" K"Value" @K_str ::K"Value" K"Value" ctx.mod ::K"Value" ctx.mod::K"Value" [K"call"; eval_import ::K"Value"; !is_using ::K"Bool"; ctx.mod ::K"Value"; from_path; path_specs...] [K"call"; eval_import::K"Value"; (!is_using)::K"Bool"; ctx.mod::K"Value"; from_path; path_specs...] @ast ctx ex [K"call"; eval_import ::K"Value"; !is_using ::K"Bool"; ctx.mod ::K"Value"; from_path; path_specs...] @ast ctx ex [K"call"; eval_import::K"Value"; (!is_using)::K"Bool"; ctx.mod::K"Value"; from_path; path_specs...] push!(stmts, @ast(ctx, ex, [K"call"; eval_import ::K"Value"; !is_using ::K"Bool"; ctx.mod ::K"Value"; from_path; path_specs...])) push!(stmts, @ast(ctx, ex, [K"call"; eval_import::K"Value"; (!is_using)::K"Bool"; ctx.mod::K"Value"; from_path; path_specs...])) begin push!(stmts, @ast(ctx, ex, [K"call"; eval_import ::K"Value"; !is_using ::K"Bool"; ctx.mod ::K"Value"; from_path; path_specs...])) push!(stmts, @ast(ctx, ex, ::K"latestworld")) end begin push!(stmts, @ast(ctx, ex, [K"call"; eval_import::K"Value"; (!is_using)::K"Bool"; ctx.mod::K"Value"; from_path; path_specs...])) push!(stmts, @ast(ctx, ex, ::K"latestworld")) end if isnothing(from_path) for spec = path_specs if is_using push!(stmts, @ast(ctx, spec, [K"call"; eval_using ::K"Value"; ctx.mod ::K"Value"; spec])) else push!(stmts, @ast(ctx, spec, [K"call"; eval_import ::K"Value"; !is_using ::K"Bool"; ctx.mod ::K"Value"; "nothing" ::K"top"; spec])) end push!(stmts, @ast(ctx, spec, ::K"latestworld")) end else push!(stmts, @ast(ctx, ex, [K"call"; eval_import ::K"Value"; !is_using ::K"Bool"; ctx.mod ::K"Value"; from_path; path_specs...])) push!(stmts, @ast(ctx, ex, ::K"latestworld")) end if isnothing(from_path) for spec = path_specs if is_using push!(stmts, @ast(ctx, spec, [K"call"; eval_using::K"Value"; ctx.mod::K"Value"; spec])) else push!(stmts, @ast(ctx, spec, [K"call"; eval_import::K"Value"; (!is_using)::K"Bool"; ctx.mod::K"Value"; "nothing"::K"top"; spec])) end push!(stmts, @ast(ctx, spec, ::K"latestworld")) end else push!(stmts, @ast(ctx, ex, [K"call"; eval_import::K"Value"; (!is_using)::K"Bool"; ctx.mod::K"Value"; from_path; path_specs...])) push!(stmts, @ast(ctx, ex, ::K"latestworld")) end begin if kind(ex[1]) == K":" @chk numchildren(ex[1]) >= 2 from = (ex[1])[1] from_path = @ast(ctx, from, QuoteNode(expand_importpath(from))::K"Value") paths = (ex[1])[2:var"end"] else @chk numchildren(ex) >= 1 from_path = nothing paths = children(ex) end path_specs = SyntaxList(ctx) for spec = paths as_name = nothing if kind(spec) == K"as" @chk numchildren(spec) == 2 @chk kind(spec[2]) == K"Identifier" as_name = Symbol((spec[2]).name_val) path = QuoteNode(Expr(:as, expand_importpath(spec[1]), as_name)) else path = QuoteNode(expand_importpath(spec)) end push!(path_specs, @ast(ctx, spec, path::K"Value")) end is_using = kind(ex) == K"using" stmts = SyntaxList(ctx) if isnothing(from_path) for spec = path_specs if is_using push!(stmts, @ast(ctx, spec, [K"call"; eval_using ::K"Value"; ctx.mod ::K"Value"; spec])) else push!(stmts, @ast(ctx, spec, [K"call"; eval_import ::K"Value"; !is_using ::K"Bool"; ctx.mod ::K"Value"; "nothing" ::K"top"; spec])) end push!(stmts, @ast(ctx, spec, ::K"latestworld")) end else push!(stmts, @ast(ctx, ex, [K"call"; eval_import ::K"Value"; !is_using ::K"Bool"; ctx.mod ::K"Value"; from_path; path_specs...])) push!(stmts, @ast(ctx, ex, ::K"latestworld")) end @ast ctx ex [K"block"; [K"assert" "toplevel_only"::K"Symbol" [K"inert" ex]]; stmts...; [K"removable" "nothing"::K"core"]] end begin if kind(ex[1]) == K":" @chk numchildren(ex[1]) >= 2 from = (ex[1])[1] from_path = @ast(ctx, from, QuoteNode(expand_importpath(from))::K"Value") paths = (ex[1])[2:var"end"] else @chk numchildren(ex) >= 1 from_path = nothing paths = children(ex) end path_specs = SyntaxList(ctx) for spec = paths as_name = nothing if kind(spec) == K"as" @chk numchildren(spec) == 2 @chk kind(spec[2]) == K"Identifier" as_name = Symbol((spec[2]).name_val) path = QuoteNode(Expr(:as, expand_importpath(spec[1]), as_name)) else path = QuoteNode(expand_importpath(spec)) end push!(path_specs, @ast(ctx, spec, path::K"Value")) end is_using = kind(ex) == K"using" stmts = SyntaxList(ctx) if isnothing(from_path) for spec = path_specs if is_using push!(stmts, @ast(ctx, spec, [K"call"; eval_using::K"Value"; ctx.mod::K"Value"; spec])) else push!(stmts, @ast(ctx, spec, [K"call"; eval_import::K"Value"; (!is_using)::K"Bool"; ctx.mod::K"Value"; "nothing"::K"top"; spec])) end push!(stmts, @ast(ctx, spec, ::K"latestworld")) end else push!(stmts, @ast(ctx, ex, [K"call"; eval_import::K"Value"; (!is_using)::K"Bool"; ctx.mod::K"Value"; from_path; path_specs...])) push!(stmts, @ast(ctx, ex, ::K"latestworld")) end @ast ctx ex [K"block"; [K"assert" "toplevel_only"::K"Symbol" [K"inert" ex]]; stmts...; [K"removable" "nothing"::K"core"]] end function expand_import_or_using(ctx, ex) if kind(ex[1]) == K":" @chk numchildren(ex[1]) >= 2 from = (ex[1])[1] from_path = @ast(ctx, from, QuoteNode(expand_importpath(from))::K"Value") paths = (ex[1])[2:var"end"] else @chk numchildren(ex) >= 1 from_path = nothing paths = children(ex) end path_specs = SyntaxList(ctx) for spec = paths as_name = nothing if kind(spec) == K"as" @chk numchildren(spec) == 2 @chk kind(spec[2]) == K"Identifier" as_name = Symbol((spec[2]).name_val) path = QuoteNode(Expr(:as, expand_importpath(spec[1]), as_name)) else path = QuoteNode(expand_importpath(spec)) end push!(path_specs, @ast(ctx, spec, path::K"Value")) end is_using = kind(ex) == K"using" stmts = SyntaxList(ctx) if isnothing(from_path) for spec = path_specs if is_using push!(stmts, @ast(ctx, spec, [K"call"; eval_using ::K"Value"; ctx.mod ::K"Value"; spec])) else push!(stmts, @ast(ctx, spec, [K"call"; eval_import ::K"Value"; !is_using ::K"Bool"; ctx.mod ::K"Value"; "nothing" ::K"top"; spec])) end push!(stmts, @ast(ctx, spec, ::K"latestworld")) end else push!(stmts, @ast(ctx, ex, [K"call"; eval_import ::K"Value"; !is_using ::K"Bool"; ctx.mod ::K"Value"; from_path; path_specs...])) push!(stmts, @ast(ctx, ex, ::K"latestworld")) end @ast ctx ex [K"block"; [K"assert" "toplevel_only"::K"Symbol" [K"inert" ex]]; stmts...; [K"removable" "nothing"::K"core"]] end function expand_import_or_using(ctx, ex) if kind(ex[1]) == K":" @chk numchildren(ex[1]) >= 2 from = (ex[1])[1] from_path = @ast(ctx, from, QuoteNode(expand_importpath(from))::K"Value") paths = (ex[1])[2:var"end"] else @chk numchildren(ex) >= 1 from_path = nothing paths = children(ex) end path_specs = SyntaxList(ctx) for spec = paths as_name = nothing if kind(spec) == K"as" @chk numchildren(spec) == 2 @chk kind(spec[2]) == K"Identifier" as_name = Symbol((spec[2]).name_val) path = QuoteNode(Expr(:as, expand_importpath(spec[1]), as_name)) else path = QuoteNode(expand_importpath(spec)) end push!(path_specs, @ast(ctx, spec, path::K"Value")) end is_using = kind(ex) == K"using" stmts = SyntaxList(ctx) if isnothing(from_path) for spec = path_specs if is_using push!(stmts, @ast(ctx, spec, [K"call"; eval_using::K"Value"; ctx.mod::K"Value"; spec])) else push!(stmts, @ast(ctx, spec, [K"call"; eval_import::K"Value"; (!is_using)::K"Bool"; ctx.mod::K"Value"; "nothing"::K"top"; spec])) end push!(stmts, @ast(ctx, spec, ::K"latestworld")) end else push!(stmts, @ast(ctx, ex, [K"call"; eval_import::K"Value"; (!is_using)::K"Bool"; ctx.mod::K"Value"; from_path; path_specs...])) push!(stmts, @ast(ctx, ex, ::K"latestworld")) end @ast ctx ex [K"block"; [K"assert" "toplevel_only"::K"Symbol" [K"inert" ex]]; stmts...; [K"removable" "nothing"::K"core"]] end eval ::K"Value" eval::K"Value" ::K"Value" K"Value" K"Value" @K_str ::K"Value" K"Value" eval ::K"Value" eval::K"Value" ctx.mod ::K"Value" ctx.mod::K"Value" ::K"Value" K"Value" K"Value" @K_str ::K"Value" K"Value" ctx.mod ::K"Value" ctx.mod::K"Value" [K"call"; eval ::K"Value"; ctx.mod ::K"Value"; [K"inert" ex]; [K"parameters"; [K"="; "expr_compat_mode"::K"Identifier"; ctx.expr_compat_mode::K"Bool"]]] [K"call"; eval::K"Value"; ctx.mod::K"Value"; [K"inert" ex]; [K"parameters"; [K"="; "expr_compat_mode"::K"Identifier"; ctx.expr_compat_mode::K"Bool"]]] [K"block"; [K"assert" "toplevel_only"::K"Symbol" [K"inert" ex]]; [K"call"; eval ::K"Value"; ctx.mod ::K"Value"; [K"inert" ex]; [K"parameters"; [K"="; "expr_compat_mode"::K"Identifier"; ctx.expr_compat_mode::K"Bool"]]]] [K"block"; [K"assert" "toplevel_only"::K"Symbol" [K"inert" ex]]; [K"call"; eval::K"Value"; ctx.mod::K"Value"; [K"inert" ex]; [K"parameters"; [K"="; "expr_compat_mode"::K"Identifier"; ctx.expr_compat_mode::K"Bool"]]]] @ast ctx ex [K"block"; [K"assert" "toplevel_only"::K"Symbol" [K"inert" ex]]; [K"call"; eval ::K"Value"; ctx.mod ::K"Value"; [K"inert" ex]; [K"parameters"; [K"="; "expr_compat_mode"::K"Identifier"; ctx.expr_compat_mode::K"Bool"]]]] @ast ctx ex [K"block"; [K"assert" "toplevel_only"::K"Symbol" [K"inert" ex]]; [K"call"; eval::K"Value"; ctx.mod::K"Value"; [K"inert" ex]; [K"parameters"; [K"="; "expr_compat_mode"::K"Identifier"; ctx.expr_compat_mode::K"Bool"]]]] ex2 = @ast(ctx, ex, [K"block"; [K"assert" "toplevel_only"::K"Symbol" [K"inert" ex]]; [K"call"; eval ::K"Value"; ctx.mod ::K"Value"; [K"inert" ex]; [K"parameters"; [K"="; "expr_compat_mode"::K"Identifier"; ctx.expr_compat_mode::K"Bool"]]]]) ex2 = @ast(ctx, ex, [K"block"; [K"assert" "toplevel_only"::K"Symbol" [K"inert" ex]]; [K"call"; eval::K"Value"; ctx.mod::K"Value"; [K"inert" ex]; [K"parameters"; [K"="; "expr_compat_mode"::K"Identifier"; ctx.expr_compat_mode::K"Bool"]]]]) begin ex2 = @ast(ctx, ex, [K"block"; [K"assert" "toplevel_only"::K"Symbol" [K"inert" ex]]; [K"call"; eval ::K"Value"; ctx.mod ::K"Value"; [K"inert" ex]; [K"parameters"; [K"="; "expr_compat_mode"::K"Identifier"; ctx.expr_compat_mode::K"Bool"]]]]) expand_forms_2(ctx, ex2) end begin ex2 = @ast(ctx, ex, [K"block"; [K"assert" "toplevel_only"::K"Symbol" [K"inert" ex]]; [K"call"; eval::K"Value"; ctx.mod::K"Value"; [K"inert" ex]; [K"parameters"; [K"="; "expr_compat_mode"::K"Identifier"; ctx.expr_compat_mode::K"Bool"]]]]) expand_forms_2(ctx, ex2) end elseif k == K"toplevel" ex2 = @ast(ctx, ex, [K"block"; [K"assert" "toplevel_only"::K"Symbol" [K"inert" ex]]; [K"call"; eval ::K"Value"; ctx.mod ::K"Value"; [K"inert" ex]; [K"parameters"; [K"="; "expr_compat_mode"::K"Identifier"; ctx.expr_compat_mode::K"Bool"]]]]) expand_forms_2(ctx, ex2) elseif k == K"vect" check_no_parameters(ex, "unexpected semicolon in array expression") expand_array(ctx, ex, "vect") elseif k == K"hcat" expand_array(ctx, ex, "hcat") elseif k == K"typed_hcat" expand_array(ctx, ex, "typed_hcat") elseif k == K"opaque_closure" expand_forms_2(ctx, expand_opaque_closure(ctx, ex)) elseif k == K"vcat" || k == K"typed_vcat" expand_forms_2(ctx, expand_vcat(ctx, ex)) elseif k == K"ncat" || k == K"typed_ncat" expand_forms_2(ctx, expand_ncat(ctx, ex)) elseif k == K"while" @chk numchildren(ex) == 2 @ast ctx ex [K"break_block" "loop_exit"::K"symbolic_label"; [K"_while"; expand_condition(ctx, ex[1]); [K"break_block" "loop_cont"::K"symbolic_label"; [(K"scope_block")(scope_type = :neutral); expand_forms_2(ctx, ex[2])]]]] elseif k == K"inert" ex elseif k == K"gc_preserve" s = ssavar(ctx, ex) r = ssavar(ctx, ex) @ast ctx ex [K"block"; s := [K"gc_preserve_begin" (children(ex))[2:var"end"]...]; r := expand_forms_2(ctx, (children(ex))[1]); [K"gc_preserve_end" s]; r] elseif k == K"&" throw(LoweringError(ex, "invalid syntax")) elseif k == K"$" throw(LoweringError(ex, "`\$` expression outside string or quote")) elseif k == K"..." throw(LoweringError(ex, "`...` expression outside call")) elseif is_leaf(ex) ex elseif k == K"return" if numchildren(ex) == 0 @ast ctx ex [K"return" "nothing"::K"core"] elseif numchildren(ex) == 1 mapchildren((e->begin expand_forms_2(ctx, e) end), ctx, ex) else throw(LoweringError(ex, "More than one argument to return")) end else mapchildren((e->begin expand_forms_2(ctx, e) end), ctx, ex) end elseif k == K"toplevel" ex2 = @ast(ctx, ex, [K"block"; [K"assert" "toplevel_only"::K"Symbol" [K"inert" ex]]; [K"call"; eval::K"Value"; ctx.mod::K"Value"; [K"inert" ex]; [K"parameters"; [K"="; "expr_compat_mode"::K"Identifier"; ctx.expr_compat_mode::K"Bool"]]]]) expand_forms_2(ctx, ex2) elseif k == K"vect" check_no_parameters(ex, "unexpected semicolon in array expression") expand_array(ctx, ex, "vect") elseif k == K"hcat" expand_array(ctx, ex, "hcat") elseif k == K"typed_hcat" expand_array(ctx, ex, "typed_hcat") elseif k == K"opaque_closure" expand_forms_2(ctx, expand_opaque_closure(ctx, ex)) elseif k == K"vcat" || k == K"typed_vcat" expand_forms_2(ctx, expand_vcat(ctx, ex)) elseif k == K"ncat" || k == K"typed_ncat" expand_forms_2(ctx, expand_ncat(ctx, ex)) elseif k == K"while" @chk numchildren(ex) == 2 @ast ctx ex [K"break_block" "loop_exit"::K"symbolic_label"; [K"_while"; expand_condition(ctx, ex[1]); [K"break_block" "loop_cont"::K"symbolic_label"; [(K"scope_block")(scope_type = :neutral); expand_forms_2(ctx, ex[2])]]]] elseif k == K"inert" ex elseif k == K"gc_preserve" s = ssavar(ctx, ex) r = ssavar(ctx, ex) @ast ctx ex [K"block"; s := [K"gc_preserve_begin" (children(ex))[2:var"end"]...]; r := expand_forms_2(ctx, (children(ex))[1]); [K"gc_preserve_end" s]; r] elseif k == K"&" throw(LoweringError(ex, "invalid syntax")) elseif k == K"$" throw(LoweringError(ex, "`\$` expression outside string or quote")) elseif k == K"..." throw(LoweringError(ex, "`...` expression outside call")) elseif is_leaf(ex) ex elseif k == K"return" if numchildren(ex) == 0 @ast ctx ex [K"return" "nothing"::K"core"] elseif numchildren(ex) == 1 mapchildren((e->begin expand_forms_2(ctx, e) end), ctx, ex) else throw(LoweringError(ex, "More than one argument to return")) end else mapchildren((e->begin expand_forms_2(ctx, e) end), ctx, ex) end elseif k == K"curly" expand_forms_2(ctx, expand_curly(ctx, ex)) elseif k == K"toplevel" ex2 = @ast(ctx, ex, [K"block"; [K"assert" "toplevel_only"::K"Symbol" [K"inert" ex]]; [K"call"; eval ::K"Value"; ctx.mod ::K"Value"; [K"inert" ex]; [K"parameters"; [K"="; "expr_compat_mode"::K"Identifier"; ctx.expr_compat_mode::K"Bool"]]]]) expand_forms_2(ctx, ex2) elseif k == K"vect" check_no_parameters(ex, "unexpected semicolon in array expression") expand_array(ctx, ex, "vect") elseif k == K"hcat" expand_array(ctx, ex, "hcat") elseif k == K"typed_hcat" expand_array(ctx, ex, "typed_hcat") elseif k == K"opaque_closure" expand_forms_2(ctx, expand_opaque_closure(ctx, ex)) elseif k == K"vcat" || k == K"typed_vcat" expand_forms_2(ctx, expand_vcat(ctx, ex)) elseif k == K"ncat" || k == K"typed_ncat" expand_forms_2(ctx, expand_ncat(ctx, ex)) elseif k == K"while" @chk numchildren(ex) == 2 @ast ctx ex [K"break_block" "loop_exit"::K"symbolic_label"; [K"_while"; expand_condition(ctx, ex[1]); [K"break_block" "loop_cont"::K"symbolic_label"; [(K"scope_block")(scope_type = :neutral); expand_forms_2(ctx, ex[2])]]]] elseif k == K"inert" ex elseif k == K"gc_preserve" s = ssavar(ctx, ex) r = ssavar(ctx, ex) @ast ctx ex [K"block"; s := [K"gc_preserve_begin" (children(ex))[2:var"end"]...]; r := expand_forms_2(ctx, (children(ex))[1]); [K"gc_preserve_end" s]; r] elseif k == K"&" throw(LoweringError(ex, "invalid syntax")) elseif k == K"$" throw(LoweringError(ex, "`\$` expression outside string or quote")) elseif k == K"..." throw(LoweringError(ex, "`...` expression outside call")) elseif is_leaf(ex) ex elseif k == K"return" if numchildren(ex) == 0 @ast ctx ex [K"return" "nothing"::K"core"] elseif numchildren(ex) == 1 mapchildren((e->begin expand_forms_2(ctx, e) end), ctx, ex) else throw(LoweringError(ex, "More than one argument to return")) end else mapchildren((e->begin expand_forms_2(ctx, e) end), ctx, ex) end elseif k == K"curly" expand_forms_2(ctx, expand_curly(ctx, ex)) elseif k == K"toplevel" ex2 = @ast(ctx, ex, [K"block"; [K"assert" "toplevel_only"::K"Symbol" [K"inert" ex]]; [K"call"; eval::K"Value"; ctx.mod::K"Value"; [K"inert" ex]; [K"parameters"; [K"="; "expr_compat_mode"::K"Identifier"; ctx.expr_compat_mode::K"Bool"]]]]) expand_forms_2(ctx, ex2) elseif k == K"vect" check_no_parameters(ex, "unexpected semicolon in array expression") expand_array(ctx, ex, "vect") elseif k == K"hcat" expand_array(ctx, ex, "hcat") elseif k == K"typed_hcat" expand_array(ctx, ex, "typed_hcat") elseif k == K"opaque_closure" expand_forms_2(ctx, expand_opaque_closure(ctx, ex)) elseif k == K"vcat" || k == K"typed_vcat" expand_forms_2(ctx, expand_vcat(ctx, ex)) elseif k == K"ncat" || k == K"typed_ncat" expand_forms_2(ctx, expand_ncat(ctx, ex)) elseif k == K"while" @chk numchildren(ex) == 2 @ast ctx ex [K"break_block" "loop_exit"::K"symbolic_label"; [K"_while"; expand_condition(ctx, ex[1]); [K"break_block" "loop_cont"::K"symbolic_label"; [(K"scope_block")(scope_type = :neutral); expand_forms_2(ctx, ex[2])]]]] elseif k == K"inert" ex elseif k == K"gc_preserve" s = ssavar(ctx, ex) r = ssavar(ctx, ex) @ast ctx ex [K"block"; s := [K"gc_preserve_begin" (children(ex))[2:var"end"]...]; r := expand_forms_2(ctx, (children(ex))[1]); [K"gc_preserve_end" s]; r] elseif k == K"&" throw(LoweringError(ex, "invalid syntax")) elseif k == K"$" throw(LoweringError(ex, "`\$` expression outside string or quote")) elseif k == K"..." throw(LoweringError(ex, "`...` expression outside call")) elseif is_leaf(ex) ex elseif k == K"return" if numchildren(ex) == 0 @ast ctx ex [K"return" "nothing"::K"core"] elseif numchildren(ex) == 1 mapchildren((e->begin expand_forms_2(ctx, e) end), ctx, ex) else throw(LoweringError(ex, "More than one argument to return")) end else mapchildren((e->begin expand_forms_2(ctx, e) end), ctx, ex) end elseif k == K"ref" sctx = with_stmts(ctx) (arr, idxs) = expand_ref_components(sctx, ex) expand_forms_2(ctx, @ast(ctx, ex, [K"block"; sctx.stmts...; [K"call"; "getindex"::K"top"; arr; idxs...]])) elseif k == K"curly" expand_forms_2(ctx, expand_curly(ctx, ex)) elseif k == K"toplevel" ex2 = @ast(ctx, ex, [K"block"; [K"assert" "toplevel_only"::K"Symbol" [K"inert" ex]]; [K"call"; eval ::K"Value"; ctx.mod ::K"Value"; [K"inert" ex]; [K"parameters"; [K"="; "expr_compat_mode"::K"Identifier"; ctx.expr_compat_mode::K"Bool"]]]]) expand_forms_2(ctx, ex2) elseif k == K"vect" check_no_parameters(ex, "unexpected semicolon in array expression") expand_array(ctx, ex, "vect") elseif k == K"hcat" expand_array(ctx, ex, "hcat") elseif k == K"typed_hcat" expand_array(ctx, ex, "typed_hcat") elseif k == K"opaque_closure" expand_forms_2(ctx, expand_opaque_closure(ctx, ex)) elseif k == K"vcat" || k == K"typed_vcat" expand_forms_2(ctx, expand_vcat(ctx, ex)) elseif k == K"ncat" || k == K"typed_ncat" expand_forms_2(ctx, expand_ncat(ctx, ex)) elseif k == K"while" @chk numchildren(ex) == 2 @ast ctx ex [K"break_block" "loop_exit"::K"symbolic_label"; [K"_while"; expand_condition(ctx, ex[1]); [K"break_block" "loop_cont"::K"symbolic_label"; [(K"scope_block")(scope_type = :neutral); expand_forms_2(ctx, ex[2])]]]] elseif k == K"inert" ex elseif k == K"gc_preserve" s = ssavar(ctx, ex) r = ssavar(ctx, ex) @ast ctx ex [K"block"; s := [K"gc_preserve_begin" (children(ex))[2:var"end"]...]; r := expand_forms_2(ctx, (children(ex))[1]); [K"gc_preserve_end" s]; r] elseif k == K"&" throw(LoweringError(ex, "invalid syntax")) elseif k == K"$" throw(LoweringError(ex, "`\$` expression outside string or quote")) elseif k == K"..." throw(LoweringError(ex, "`...` expression outside call")) elseif is_leaf(ex) ex elseif k == K"return" if numchildren(ex) == 0 @ast ctx ex [K"return" "nothing"::K"core"] elseif numchildren(ex) == 1 mapchildren((e->begin expand_forms_2(ctx, e) end), ctx, ex) else throw(LoweringError(ex, "More than one argument to return")) end else mapchildren((e->begin expand_forms_2(ctx, e) end), ctx, ex) end elseif k == K"ref" sctx = with_stmts(ctx) (arr, idxs) = expand_ref_components(sctx, ex) expand_forms_2(ctx, @ast(ctx, ex, [K"block"; sctx.stmts...; [K"call"; "getindex"::K"top"; arr; idxs...]])) elseif k == K"curly" expand_forms_2(ctx, expand_curly(ctx, ex)) elseif k == K"toplevel" ex2 = @ast(ctx, ex, [K"block"; [K"assert" "toplevel_only"::K"Symbol" [K"inert" ex]]; [K"call"; eval::K"Value"; ctx.mod::K"Value"; [K"inert" ex]; [K"parameters"; [K"="; "expr_compat_mode"::K"Identifier"; ctx.expr_compat_mode::K"Bool"]]]]) expand_forms_2(ctx, ex2) elseif k == K"vect" check_no_parameters(ex, "unexpected semicolon in array expression") expand_array(ctx, ex, "vect") elseif k == K"hcat" expand_array(ctx, ex, "hcat") elseif k == K"typed_hcat" expand_array(ctx, ex, "typed_hcat") elseif k == K"opaque_closure" expand_forms_2(ctx, expand_opaque_closure(ctx, ex)) elseif k == K"vcat" || k == K"typed_vcat" expand_forms_2(ctx, expand_vcat(ctx, ex)) elseif k == K"ncat" || k == K"typed_ncat" expand_forms_2(ctx, expand_ncat(ctx, ex)) elseif k == K"while" @chk numchildren(ex) == 2 @ast ctx ex [K"break_block" "loop_exit"::K"symbolic_label"; [K"_while"; expand_condition(ctx, ex[1]); [K"break_block" "loop_cont"::K"symbolic_label"; [(K"scope_block")(scope_type = :neutral); expand_forms_2(ctx, ex[2])]]]] elseif k == K"inert" ex elseif k == K"gc_preserve" s = ssavar(ctx, ex) r = ssavar(ctx, ex) @ast ctx ex [K"block"; s := [K"gc_preserve_begin" (children(ex))[2:var"end"]...]; r := expand_forms_2(ctx, (children(ex))[1]); [K"gc_preserve_end" s]; r] elseif k == K"&" throw(LoweringError(ex, "invalid syntax")) elseif k == K"$" throw(LoweringError(ex, "`\$` expression outside string or quote")) elseif k == K"..." throw(LoweringError(ex, "`...` expression outside call")) elseif is_leaf(ex) ex elseif k == K"return" if numchildren(ex) == 0 @ast ctx ex [K"return" "nothing"::K"core"] elseif numchildren(ex) == 1 mapchildren((e->begin expand_forms_2(ctx, e) end), ctx, ex) else throw(LoweringError(ex, "More than one argument to return")) end else mapchildren((e->begin expand_forms_2(ctx, e) end), ctx, ex) end elseif k == K"struct" expand_forms_2(ctx, expand_struct_def(ctx, ex, docs)) elseif k == K"ref" sctx = with_stmts(ctx) (arr, idxs) = expand_ref_components(sctx, ex) expand_forms_2(ctx, @ast(ctx, ex, [K"block"; sctx.stmts...; [K"call"; "getindex"::K"top"; arr; idxs...]])) elseif k == K"curly" expand_forms_2(ctx, expand_curly(ctx, ex)) elseif k == K"toplevel" ex2 = @ast(ctx, ex, [K"block"; [K"assert" "toplevel_only"::K"Symbol" [K"inert" ex]]; [K"call"; eval ::K"Value"; ctx.mod ::K"Value"; [K"inert" ex]; [K"parameters"; [K"="; "expr_compat_mode"::K"Identifier"; ctx.expr_compat_mode::K"Bool"]]]]) expand_forms_2(ctx, ex2) elseif k == K"vect" check_no_parameters(ex, "unexpected semicolon in array expression") expand_array(ctx, ex, "vect") elseif k == K"hcat" expand_array(ctx, ex, "hcat") elseif k == K"typed_hcat" expand_array(ctx, ex, "typed_hcat") elseif k == K"opaque_closure" expand_forms_2(ctx, expand_opaque_closure(ctx, ex)) elseif k == K"vcat" || k == K"typed_vcat" expand_forms_2(ctx, expand_vcat(ctx, ex)) elseif k == K"ncat" || k == K"typed_ncat" expand_forms_2(ctx, expand_ncat(ctx, ex)) elseif k == K"while" @chk numchildren(ex) == 2 @ast ctx ex [K"break_block" "loop_exit"::K"symbolic_label"; [K"_while"; expand_condition(ctx, ex[1]); [K"break_block" "loop_cont"::K"symbolic_label"; [(K"scope_block")(scope_type = :neutral); expand_forms_2(ctx, ex[2])]]]] elseif k == K"inert" ex elseif k == K"gc_preserve" s = ssavar(ctx, ex) r = ssavar(ctx, ex) @ast ctx ex [K"block"; s := [K"gc_preserve_begin" (children(ex))[2:var"end"]...]; r := expand_forms_2(ctx, (children(ex))[1]); [K"gc_preserve_end" s]; r] elseif k == K"&" throw(LoweringError(ex, "invalid syntax")) elseif k == K"$" throw(LoweringError(ex, "`\$` expression outside string or quote")) elseif k == K"..." throw(LoweringError(ex, "`...` expression outside call")) elseif is_leaf(ex) ex elseif k == K"return" if numchildren(ex) == 0 @ast ctx ex [K"return" "nothing"::K"core"] elseif numchildren(ex) == 1 mapchildren((e->begin expand_forms_2(ctx, e) end), ctx, ex) else throw(LoweringError(ex, "More than one argument to return")) end else mapchildren((e->begin expand_forms_2(ctx, e) end), ctx, ex) end elseif k == K"struct" expand_forms_2(ctx, expand_struct_def(ctx, ex, docs)) elseif k == K"ref" sctx = with_stmts(ctx) (arr, idxs) = expand_ref_components(sctx, ex) expand_forms_2(ctx, @ast(ctx, ex, [K"block"; sctx.stmts...; [K"call"; "getindex"::K"top"; arr; idxs...]])) elseif k == K"curly" expand_forms_2(ctx, expand_curly(ctx, ex)) elseif k == K"toplevel" ex2 = @ast(ctx, ex, [K"block"; [K"assert" "toplevel_only"::K"Symbol" [K"inert" ex]]; [K"call"; eval::K"Value"; ctx.mod::K"Value"; [K"inert" ex]; [K"parameters"; [K"="; "expr_compat_mode"::K"Identifier"; ctx.expr_compat_mode::K"Bool"]]]]) expand_forms_2(ctx, ex2) elseif k == K"vect" check_no_parameters(ex, "unexpected semicolon in array expression") expand_array(ctx, ex, "vect") elseif k == K"hcat" expand_array(ctx, ex, "hcat") elseif k == K"typed_hcat" expand_array(ctx, ex, "typed_hcat") elseif k == K"opaque_closure" expand_forms_2(ctx, expand_opaque_closure(ctx, ex)) elseif k == K"vcat" || k == K"typed_vcat" expand_forms_2(ctx, expand_vcat(ctx, ex)) elseif k == K"ncat" || k == K"typed_ncat" expand_forms_2(ctx, expand_ncat(ctx, ex)) elseif k == K"while" @chk numchildren(ex) == 2 @ast ctx ex [K"break_block" "loop_exit"::K"symbolic_label"; [K"_while"; expand_condition(ctx, ex[1]); [K"break_block" "loop_cont"::K"symbolic_label"; [(K"scope_block")(scope_type = :neutral); expand_forms_2(ctx, ex[2])]]]] elseif k == K"inert" ex elseif k == K"gc_preserve" s = ssavar(ctx, ex) r = ssavar(ctx, ex) @ast ctx ex [K"block"; s := [K"gc_preserve_begin" (children(ex))[2:var"end"]...]; r := expand_forms_2(ctx, (children(ex))[1]); [K"gc_preserve_end" s]; r] elseif k == K"&" throw(LoweringError(ex, "invalid syntax")) elseif k == K"$" throw(LoweringError(ex, "`\$` expression outside string or quote")) elseif k == K"..." throw(LoweringError(ex, "`...` expression outside call")) elseif is_leaf(ex) ex elseif k == K"return" if numchildren(ex) == 0 @ast ctx ex [K"return" "nothing"::K"core"] elseif numchildren(ex) == 1 mapchildren((e->begin expand_forms_2(ctx, e) end), ctx, ex) else throw(LoweringError(ex, "More than one argument to return")) end else mapchildren((e->begin expand_forms_2(ctx, e) end), ctx, ex) end elseif k == K"abstract" || k == K"primitive" expand_forms_2(ctx, expand_abstract_or_primitive_type(ctx, ex)) elseif k == K"struct" expand_forms_2(ctx, expand_struct_def(ctx, ex, docs)) elseif k == K"ref" sctx = with_stmts(ctx) (arr, idxs) = expand_ref_components(sctx, ex) expand_forms_2(ctx, @ast(ctx, ex, [K"block"; sctx.stmts...; [K"call"; "getindex"::K"top"; arr; idxs...]])) elseif k == K"curly" expand_forms_2(ctx, expand_curly(ctx, ex)) elseif k == K"toplevel" ex2 = @ast(ctx, ex, [K"block"; [K"assert" "toplevel_only"::K"Symbol" [K"inert" ex]]; [K"call"; eval ::K"Value"; ctx.mod ::K"Value"; [K"inert" ex]; [K"parameters"; [K"="; "expr_compat_mode"::K"Identifier"; ctx.expr_compat_mode::K"Bool"]]]]) expand_forms_2(ctx, ex2) elseif k == K"vect" check_no_parameters(ex, "unexpected semicolon in array expression") expand_array(ctx, ex, "vect") elseif k == K"hcat" expand_array(ctx, ex, "hcat") elseif k == K"typed_hcat" expand_array(ctx, ex, "typed_hcat") elseif k == K"opaque_closure" expand_forms_2(ctx, expand_opaque_closure(ctx, ex)) elseif k == K"vcat" || k == K"typed_vcat" expand_forms_2(ctx, expand_vcat(ctx, ex)) elseif k == K"ncat" || k == K"typed_ncat" expand_forms_2(ctx, expand_ncat(ctx, ex)) elseif k == K"while" @chk numchildren(ex) == 2 @ast ctx ex [K"break_block" "loop_exit"::K"symbolic_label"; [K"_while"; expand_condition(ctx, ex[1]); [K"break_block" "loop_cont"::K"symbolic_label"; [(K"scope_block")(scope_type = :neutral); expand_forms_2(ctx, ex[2])]]]] elseif k == K"inert" ex elseif k == K"gc_preserve" s = ssavar(ctx, ex) r = ssavar(ctx, ex) @ast ctx ex [K"block"; s := [K"gc_preserve_begin" (children(ex))[2:var"end"]...]; r := expand_forms_2(ctx, (children(ex))[1]); [K"gc_preserve_end" s]; r] elseif k == K"&" throw(LoweringError(ex, "invalid syntax")) elseif k == K"$" throw(LoweringError(ex, "`\$` expression outside string or quote")) elseif k == K"..." throw(LoweringError(ex, "`...` expression outside call")) elseif is_leaf(ex) ex elseif k == K"return" if numchildren(ex) == 0 @ast ctx ex [K"return" "nothing"::K"core"] elseif numchildren(ex) == 1 mapchildren((e->begin expand_forms_2(ctx, e) end), ctx, ex) else throw(LoweringError(ex, "More than one argument to return")) end else mapchildren((e->begin expand_forms_2(ctx, e) end), ctx, ex) end elseif k == K"abstract" || k == K"primitive" expand_forms_2(ctx, expand_abstract_or_primitive_type(ctx, ex)) elseif k == K"struct" expand_forms_2(ctx, expand_struct_def(ctx, ex, docs)) elseif k == K"ref" sctx = with_stmts(ctx) (arr, idxs) = expand_ref_components(sctx, ex) expand_forms_2(ctx, @ast(ctx, ex, [K"block"; sctx.stmts...; [K"call"; "getindex"::K"top"; arr; idxs...]])) elseif k == K"curly" expand_forms_2(ctx, expand_curly(ctx, ex)) elseif k == K"toplevel" ex2 = @ast(ctx, ex, [K"block"; [K"assert" "toplevel_only"::K"Symbol" [K"inert" ex]]; [K"call"; eval::K"Value"; ctx.mod::K"Value"; [K"inert" ex]; [K"parameters"; [K"="; "expr_compat_mode"::K"Identifier"; ctx.expr_compat_mode::K"Bool"]]]]) expand_forms_2(ctx, ex2) elseif k == K"vect" check_no_parameters(ex, "unexpected semicolon in array expression") expand_array(ctx, ex, "vect") elseif k == K"hcat" expand_array(ctx, ex, "hcat") elseif k == K"typed_hcat" expand_array(ctx, ex, "typed_hcat") elseif k == K"opaque_closure" expand_forms_2(ctx, expand_opaque_closure(ctx, ex)) elseif k == K"vcat" || k == K"typed_vcat" expand_forms_2(ctx, expand_vcat(ctx, ex)) elseif k == K"ncat" || k == K"typed_ncat" expand_forms_2(ctx, expand_ncat(ctx, ex)) elseif k == K"while" @chk numchildren(ex) == 2 @ast ctx ex [K"break_block" "loop_exit"::K"symbolic_label"; [K"_while"; expand_condition(ctx, ex[1]); [K"break_block" "loop_cont"::K"symbolic_label"; [(K"scope_block")(scope_type = :neutral); expand_forms_2(ctx, ex[2])]]]] elseif k == K"inert" ex elseif k == K"gc_preserve" s = ssavar(ctx, ex) r = ssavar(ctx, ex) @ast ctx ex [K"block"; s := [K"gc_preserve_begin" (children(ex))[2:var"end"]...]; r := expand_forms_2(ctx, (children(ex))[1]); [K"gc_preserve_end" s]; r] elseif k == K"&" throw(LoweringError(ex, "invalid syntax")) elseif k == K"$" throw(LoweringError(ex, "`\$` expression outside string or quote")) elseif k == K"..." throw(LoweringError(ex, "`...` expression outside call")) elseif is_leaf(ex) ex elseif k == K"return" if numchildren(ex) == 0 @ast ctx ex [K"return" "nothing"::K"core"] elseif numchildren(ex) == 1 mapchildren((e->begin expand_forms_2(ctx, e) end), ctx, ex) else throw(LoweringError(ex, "More than one argument to return")) end else mapchildren((e->begin expand_forms_2(ctx, e) end), ctx, ex) end elseif k == K"export" || k == K"public" expand_public(ctx, ex) elseif k == K"abstract" || k == K"primitive" expand_forms_2(ctx, expand_abstract_or_primitive_type(ctx, ex)) elseif k == K"struct" expand_forms_2(ctx, expand_struct_def(ctx, ex, docs)) elseif k == K"ref" sctx = with_stmts(ctx) (arr, idxs) = expand_ref_components(sctx, ex) expand_forms_2(ctx, @ast(ctx, ex, [K"block"; sctx.stmts...; [K"call"; "getindex"::K"top"; arr; idxs...]])) elseif k == K"curly" expand_forms_2(ctx, expand_curly(ctx, ex)) elseif k == K"toplevel" ex2 = @ast(ctx, ex, [K"block"; [K"assert" "toplevel_only"::K"Symbol" [K"inert" ex]]; [K"call"; eval ::K"Value"; ctx.mod ::K"Value"; [K"inert" ex]; [K"parameters"; [K"="; "expr_compat_mode"::K"Identifier"; ctx.expr_compat_mode::K"Bool"]]]]) expand_forms_2(ctx, ex2) elseif k == K"vect" check_no_parameters(ex, "unexpected semicolon in array expression") expand_array(ctx, ex, "vect") elseif k == K"hcat" expand_array(ctx, ex, "hcat") elseif k == K"typed_hcat" expand_array(ctx, ex, "typed_hcat") elseif k == K"opaque_closure" expand_forms_2(ctx, expand_opaque_closure(ctx, ex)) elseif k == K"vcat" || k == K"typed_vcat" expand_forms_2(ctx, expand_vcat(ctx, ex)) elseif k == K"ncat" || k == K"typed_ncat" expand_forms_2(ctx, expand_ncat(ctx, ex)) elseif k == K"while" @chk numchildren(ex) == 2 @ast ctx ex [K"break_block" "loop_exit"::K"symbolic_label"; [K"_while"; expand_condition(ctx, ex[1]); [K"break_block" "loop_cont"::K"symbolic_label"; [(K"scope_block")(scope_type = :neutral); expand_forms_2(ctx, ex[2])]]]] elseif k == K"inert" ex elseif k == K"gc_preserve" s = ssavar(ctx, ex) r = ssavar(ctx, ex) @ast ctx ex [K"block"; s := [K"gc_preserve_begin" (children(ex))[2:var"end"]...]; r := expand_forms_2(ctx, (children(ex))[1]); [K"gc_preserve_end" s]; r] elseif k == K"&" throw(LoweringError(ex, "invalid syntax")) elseif k == K"$" throw(LoweringError(ex, "`\$` expression outside string or quote")) elseif k == K"..." throw(LoweringError(ex, "`...` expression outside call")) elseif is_leaf(ex) ex elseif k == K"return" if numchildren(ex) == 0 @ast ctx ex [K"return" "nothing"::K"core"] elseif numchildren(ex) == 1 mapchildren((e->begin expand_forms_2(ctx, e) end), ctx, ex) else throw(LoweringError(ex, "More than one argument to return")) end else mapchildren((e->begin expand_forms_2(ctx, e) end), ctx, ex) end elseif k == K"export" || k == K"public" expand_public(ctx, ex) elseif k == K"abstract" || k == K"primitive" expand_forms_2(ctx, expand_abstract_or_primitive_type(ctx, ex)) elseif k == K"struct" expand_forms_2(ctx, expand_struct_def(ctx, ex, docs)) elseif k == K"ref" sctx = with_stmts(ctx) (arr, idxs) = expand_ref_components(sctx, ex) expand_forms_2(ctx, @ast(ctx, ex, [K"block"; sctx.stmts...; [K"call"; "getindex"::K"top"; arr; idxs...]])) elseif k == K"curly" expand_forms_2(ctx, expand_curly(ctx, ex)) elseif k == K"toplevel" ex2 = @ast(ctx, ex, [K"block"; [K"assert" "toplevel_only"::K"Symbol" [K"inert" ex]]; [K"call"; eval::K"Value"; ctx.mod::K"Value"; [K"inert" ex]; [K"parameters"; [K"="; "expr_compat_mode"::K"Identifier"; ctx.expr_compat_mode::K"Bool"]]]]) expand_forms_2(ctx, ex2) elseif k == K"vect" check_no_parameters(ex, "unexpected semicolon in array expression") expand_array(ctx, ex, "vect") elseif k == K"hcat" expand_array(ctx, ex, "hcat") elseif k == K"typed_hcat" expand_array(ctx, ex, "typed_hcat") elseif k == K"opaque_closure" expand_forms_2(ctx, expand_opaque_closure(ctx, ex)) elseif k == K"vcat" || k == K"typed_vcat" expand_forms_2(ctx, expand_vcat(ctx, ex)) elseif k == K"ncat" || k == K"typed_ncat" expand_forms_2(ctx, expand_ncat(ctx, ex)) elseif k == K"while" @chk numchildren(ex) == 2 @ast ctx ex [K"break_block" "loop_exit"::K"symbolic_label"; [K"_while"; expand_condition(ctx, ex[1]); [K"break_block" "loop_cont"::K"symbolic_label"; [(K"scope_block")(scope_type = :neutral); expand_forms_2(ctx, ex[2])]]]] elseif k == K"inert" ex elseif k == K"gc_preserve" s = ssavar(ctx, ex) r = ssavar(ctx, ex) @ast ctx ex [K"block"; s := [K"gc_preserve_begin" (children(ex))[2:var"end"]...]; r := expand_forms_2(ctx, (children(ex))[1]); [K"gc_preserve_end" s]; r] elseif k == K"&" throw(LoweringError(ex, "invalid syntax")) elseif k == K"$" throw(LoweringError(ex, "`\$` expression outside string or quote")) elseif k == K"..." throw(LoweringError(ex, "`...` expression outside call")) elseif is_leaf(ex) ex elseif k == K"return" if numchildren(ex) == 0 @ast ctx ex [K"return" "nothing"::K"core"] elseif numchildren(ex) == 1 mapchildren((e->begin expand_forms_2(ctx, e) end), ctx, ex) else throw(LoweringError(ex, "More than one argument to return")) end else mapchildren((e->begin expand_forms_2(ctx, e) end), ctx, ex) end elseif k == K"import" || k == K"using" expand_import_or_using(ctx, ex) elseif k == K"export" || k == K"public" expand_public(ctx, ex) elseif k == K"abstract" || k == K"primitive" expand_forms_2(ctx, expand_abstract_or_primitive_type(ctx, ex)) elseif k == K"struct" expand_forms_2(ctx, expand_struct_def(ctx, ex, docs)) elseif k == K"ref" sctx = with_stmts(ctx) (arr, idxs) = expand_ref_components(sctx, ex) expand_forms_2(ctx, @ast(ctx, ex, [K"block"; sctx.stmts...; [K"call"; "getindex"::K"top"; arr; idxs...]])) elseif k == K"curly" expand_forms_2(ctx, expand_curly(ctx, ex)) elseif k == K"toplevel" ex2 = @ast(ctx, ex, [K"block"; [K"assert" "toplevel_only"::K"Symbol" [K"inert" ex]]; [K"call"; eval ::K"Value"; ctx.mod ::K"Value"; [K"inert" ex]; [K"parameters"; [K"="; "expr_compat_mode"::K"Identifier"; ctx.expr_compat_mode::K"Bool"]]]]) expand_forms_2(ctx, ex2) elseif k == K"vect" check_no_parameters(ex, "unexpected semicolon in array expression") expand_array(ctx, ex, "vect") elseif k == K"hcat" expand_array(ctx, ex, "hcat") elseif k == K"typed_hcat" expand_array(ctx, ex, "typed_hcat") elseif k == K"opaque_closure" expand_forms_2(ctx, expand_opaque_closure(ctx, ex)) elseif k == K"vcat" || k == K"typed_vcat" expand_forms_2(ctx, expand_vcat(ctx, ex)) elseif k == K"ncat" || k == K"typed_ncat" expand_forms_2(ctx, expand_ncat(ctx, ex)) elseif k == K"while" @chk numchildren(ex) == 2 @ast ctx ex [K"break_block" "loop_exit"::K"symbolic_label"; [K"_while"; expand_condition(ctx, ex[1]); [K"break_block" "loop_cont"::K"symbolic_label"; [(K"scope_block")(scope_type = :neutral); expand_forms_2(ctx, ex[2])]]]] elseif k == K"inert" ex elseif k == K"gc_preserve" s = ssavar(ctx, ex) r = ssavar(ctx, ex) @ast ctx ex [K"block"; s := [K"gc_preserve_begin" (children(ex))[2:var"end"]...]; r := expand_forms_2(ctx, (children(ex))[1]); [K"gc_preserve_end" s]; r] elseif k == K"&" throw(LoweringError(ex, "invalid syntax")) elseif k == K"$" throw(LoweringError(ex, "`\$` expression outside string or quote")) elseif k == K"..." throw(LoweringError(ex, "`...` expression outside call")) elseif is_leaf(ex) ex elseif k == K"return" if numchildren(ex) == 0 @ast ctx ex [K"return" "nothing"::K"core"] elseif numchildren(ex) == 1 mapchildren((e->begin expand_forms_2(ctx, e) end), ctx, ex) else throw(LoweringError(ex, "More than one argument to return")) end else mapchildren((e->begin expand_forms_2(ctx, e) end), ctx, ex) end elseif k == K"import" || k == K"using" expand_import_or_using(ctx, ex) elseif k == K"export" || k == K"public" expand_public(ctx, ex) elseif k == K"abstract" || k == K"primitive" expand_forms_2(ctx, expand_abstract_or_primitive_type(ctx, ex)) elseif k == K"struct" expand_forms_2(ctx, expand_struct_def(ctx, ex, docs)) elseif k == K"ref" sctx = with_stmts(ctx) (arr, idxs) = expand_ref_components(sctx, ex) expand_forms_2(ctx, @ast(ctx, ex, [K"block"; sctx.stmts...; [K"call"; "getindex"::K"top"; arr; idxs...]])) elseif k == K"curly" expand_forms_2(ctx, expand_curly(ctx, ex)) elseif k == K"toplevel" ex2 = @ast(ctx, ex, [K"block"; [K"assert" "toplevel_only"::K"Symbol" [K"inert" ex]]; [K"call"; eval::K"Value"; ctx.mod::K"Value"; [K"inert" ex]; [K"parameters"; [K"="; "expr_compat_mode"::K"Identifier"; ctx.expr_compat_mode::K"Bool"]]]]) expand_forms_2(ctx, ex2) elseif k == K"vect" check_no_parameters(ex, "unexpected semicolon in array expression") expand_array(ctx, ex, "vect") elseif k == K"hcat" expand_array(ctx, ex, "hcat") elseif k == K"typed_hcat" expand_array(ctx, ex, "typed_hcat") elseif k == K"opaque_closure" expand_forms_2(ctx, expand_opaque_closure(ctx, ex)) elseif k == K"vcat" || k == K"typed_vcat" expand_forms_2(ctx, expand_vcat(ctx, ex)) elseif k == K"ncat" || k == K"typed_ncat" expand_forms_2(ctx, expand_ncat(ctx, ex)) elseif k == K"while" @chk numchildren(ex) == 2 @ast ctx ex [K"break_block" "loop_exit"::K"symbolic_label"; [K"_while"; expand_condition(ctx, ex[1]); [K"break_block" "loop_cont"::K"symbolic_label"; [(K"scope_block")(scope_type = :neutral); expand_forms_2(ctx, ex[2])]]]] elseif k == K"inert" ex elseif k == K"gc_preserve" s = ssavar(ctx, ex) r = ssavar(ctx, ex) @ast ctx ex [K"block"; s := [K"gc_preserve_begin" (children(ex))[2:var"end"]...]; r := expand_forms_2(ctx, (children(ex))[1]); [K"gc_preserve_end" s]; r] elseif k == K"&" throw(LoweringError(ex, "invalid syntax")) elseif k == K"$" throw(LoweringError(ex, "`\$` expression outside string or quote")) elseif k == K"..." throw(LoweringError(ex, "`...` expression outside call")) elseif is_leaf(ex) ex elseif k == K"return" if numchildren(ex) == 0 @ast ctx ex [K"return" "nothing"::K"core"] elseif numchildren(ex) == 1 mapchildren((e->begin expand_forms_2(ctx, e) end), ctx, ex) else throw(LoweringError(ex, "More than one argument to return")) end else mapchildren((e->begin expand_forms_2(ctx, e) end), ctx, ex) end elseif k == K"module" throw(LoweringError(ex, "`module` is only allowed at top level")) elseif k == K"import" || k == K"using" expand_import_or_using(ctx, ex) elseif k == K"export" || k == K"public" expand_public(ctx, ex) elseif k == K"abstract" || k == K"primitive" expand_forms_2(ctx, expand_abstract_or_primitive_type(ctx, ex)) elseif k == K"struct" expand_forms_2(ctx, expand_struct_def(ctx, ex, docs)) elseif k == K"ref" sctx = with_stmts(ctx) (arr, idxs) = expand_ref_components(sctx, ex) expand_forms_2(ctx, @ast(ctx, ex, [K"block"; sctx.stmts...; [K"call"; "getindex"::K"top"; arr; idxs...]])) elseif k == K"curly" expand_forms_2(ctx, expand_curly(ctx, ex)) elseif k == K"toplevel" ex2 = @ast(ctx, ex, [K"block"; [K"assert" "toplevel_only"::K"Symbol" [K"inert" ex]]; [K"call"; eval ::K"Value"; ctx.mod ::K"Value"; [K"inert" ex]; [K"parameters"; [K"="; "expr_compat_mode"::K"Identifier"; ctx.expr_compat_mode::K"Bool"]]]]) expand_forms_2(ctx, ex2) elseif k == K"vect" check_no_parameters(ex, "unexpected semicolon in array expression") expand_array(ctx, ex, "vect") elseif k == K"hcat" expand_array(ctx, ex, "hcat") elseif k == K"typed_hcat" expand_array(ctx, ex, "typed_hcat") elseif k == K"opaque_closure" expand_forms_2(ctx, expand_opaque_closure(ctx, ex)) elseif k == K"vcat" || k == K"typed_vcat" expand_forms_2(ctx, expand_vcat(ctx, ex)) elseif k == K"ncat" || k == K"typed_ncat" expand_forms_2(ctx, expand_ncat(ctx, ex)) elseif k == K"while" @chk numchildren(ex) == 2 @ast ctx ex [K"break_block" "loop_exit"::K"symbolic_label"; [K"_while"; expand_condition(ctx, ex[1]); [K"break_block" "loop_cont"::K"symbolic_label"; [(K"scope_block")(scope_type = :neutral); expand_forms_2(ctx, ex[2])]]]] elseif k == K"inert" ex elseif k == K"gc_preserve" s = ssavar(ctx, ex) r = ssavar(ctx, ex) @ast ctx ex [K"block"; s := [K"gc_preserve_begin" (children(ex))[2:var"end"]...]; r := expand_forms_2(ctx, (children(ex))[1]); [K"gc_preserve_end" s]; r] elseif k == K"&" throw(LoweringError(ex, "invalid syntax")) elseif k == K"$" throw(LoweringError(ex, "`\$` expression outside string or quote")) elseif k == K"..." throw(LoweringError(ex, "`...` expression outside call")) elseif is_leaf(ex) ex elseif k == K"return" if numchildren(ex) == 0 @ast ctx ex [K"return" "nothing"::K"core"] elseif numchildren(ex) == 1 mapchildren((e->begin expand_forms_2(ctx, e) end), ctx, ex) else throw(LoweringError(ex, "More than one argument to return")) end else mapchildren((e->begin expand_forms_2(ctx, e) end), ctx, ex) end elseif k == K"module" throw(LoweringError(ex, "`module` is only allowed at top level")) elseif k == K"import" || k == K"using" expand_import_or_using(ctx, ex) elseif k == K"export" || k == K"public" expand_public(ctx, ex) elseif k == K"abstract" || k == K"primitive" expand_forms_2(ctx, expand_abstract_or_primitive_type(ctx, ex)) elseif k == K"struct" expand_forms_2(ctx, expand_struct_def(ctx, ex, docs)) elseif k == K"ref" sctx = with_stmts(ctx) (arr, idxs) = expand_ref_components(sctx, ex) expand_forms_2(ctx, @ast(ctx, ex, [K"block"; sctx.stmts...; [K"call"; "getindex"::K"top"; arr; idxs...]])) elseif k == K"curly" expand_forms_2(ctx, expand_curly(ctx, ex)) elseif k == K"toplevel" ex2 = @ast(ctx, ex, [K"block"; [K"assert" "toplevel_only"::K"Symbol" [K"inert" ex]]; [K"call"; eval::K"Value"; ctx.mod::K"Value"; [K"inert" ex]; [K"parameters"; [K"="; "expr_compat_mode"::K"Identifier"; ctx.expr_compat_mode::K"Bool"]]]]) expand_forms_2(ctx, ex2) elseif k == K"vect" check_no_parameters(ex, "unexpected semicolon in array expression") expand_array(ctx, ex, "vect") elseif k == K"hcat" expand_array(ctx, ex, "hcat") elseif k == K"typed_hcat" expand_array(ctx, ex, "typed_hcat") elseif k == K"opaque_closure" expand_forms_2(ctx, expand_opaque_closure(ctx, ex)) elseif k == K"vcat" || k == K"typed_vcat" expand_forms_2(ctx, expand_vcat(ctx, ex)) elseif k == K"ncat" || k == K"typed_ncat" expand_forms_2(ctx, expand_ncat(ctx, ex)) elseif k == K"while" @chk numchildren(ex) == 2 @ast ctx ex [K"break_block" "loop_exit"::K"symbolic_label"; [K"_while"; expand_condition(ctx, ex[1]); [K"break_block" "loop_cont"::K"symbolic_label"; [(K"scope_block")(scope_type = :neutral); expand_forms_2(ctx, ex[2])]]]] elseif k == K"inert" ex elseif k == K"gc_preserve" s = ssavar(ctx, ex) r = ssavar(ctx, ex) @ast ctx ex [K"block"; s := [K"gc_preserve_begin" (children(ex))[2:var"end"]...]; r := expand_forms_2(ctx, (children(ex))[1]); [K"gc_preserve_end" s]; r] elseif k == K"&" throw(LoweringError(ex, "invalid syntax")) elseif k == K"$" throw(LoweringError(ex, "`\$` expression outside string or quote")) elseif k == K"..." throw(LoweringError(ex, "`...` expression outside call")) elseif is_leaf(ex) ex elseif k == K"return" if numchildren(ex) == 0 @ast ctx ex [K"return" "nothing"::K"core"] elseif numchildren(ex) == 1 mapchildren((e->begin expand_forms_2(ctx, e) end), ctx, ex) else throw(LoweringError(ex, "More than one argument to return")) end else mapchildren((e->begin expand_forms_2(ctx, e) end), ctx, ex) end elseif k == K"$" throw(LoweringError(ex, "`\$` expression outside string or quote block")) elseif k == K"module" throw(LoweringError(ex, "`module` is only allowed at top level")) elseif k == K"import" || k == K"using" expand_import_or_using(ctx, ex) elseif k == K"export" || k == K"public" expand_public(ctx, ex) elseif k == K"abstract" || k == K"primitive" expand_forms_2(ctx, expand_abstract_or_primitive_type(ctx, ex)) elseif k == K"struct" expand_forms_2(ctx, expand_struct_def(ctx, ex, docs)) elseif k == K"ref" sctx = with_stmts(ctx) (arr, idxs) = expand_ref_components(sctx, ex) expand_forms_2(ctx, @ast(ctx, ex, [K"block"; sctx.stmts...; [K"call"; "getindex"::K"top"; arr; idxs...]])) elseif k == K"curly" expand_forms_2(ctx, expand_curly(ctx, ex)) elseif k == K"toplevel" ex2 = @ast(ctx, ex, [K"block"; [K"assert" "toplevel_only"::K"Symbol" [K"inert" ex]]; [K"call"; eval ::K"Value"; ctx.mod ::K"Value"; [K"inert" ex]; [K"parameters"; [K"="; "expr_compat_mode"::K"Identifier"; ctx.expr_compat_mode::K"Bool"]]]]) expand_forms_2(ctx, ex2) elseif k == K"vect" check_no_parameters(ex, "unexpected semicolon in array expression") expand_array(ctx, ex, "vect") elseif k == K"hcat" expand_array(ctx, ex, "hcat") elseif k == K"typed_hcat" expand_array(ctx, ex, "typed_hcat") elseif k == K"opaque_closure" expand_forms_2(ctx, expand_opaque_closure(ctx, ex)) elseif k == K"vcat" || k == K"typed_vcat" expand_forms_2(ctx, expand_vcat(ctx, ex)) elseif k == K"ncat" || k == K"typed_ncat" expand_forms_2(ctx, expand_ncat(ctx, ex)) elseif k == K"while" @chk numchildren(ex) == 2 @ast ctx ex [K"break_block" "loop_exit"::K"symbolic_label"; [K"_while"; expand_condition(ctx, ex[1]); [K"break_block" "loop_cont"::K"symbolic_label"; [(K"scope_block")(scope_type = :neutral); expand_forms_2(ctx, ex[2])]]]] elseif k == K"inert" ex elseif k == K"gc_preserve" s = ssavar(ctx, ex) r = ssavar(ctx, ex) @ast ctx ex [K"block"; s := [K"gc_preserve_begin" (children(ex))[2:var"end"]...]; r := expand_forms_2(ctx, (children(ex))[1]); [K"gc_preserve_end" s]; r] elseif k == K"&" throw(LoweringError(ex, "invalid syntax")) elseif k == K"$" throw(LoweringError(ex, "`\$` expression outside string or quote")) elseif k == K"..." throw(LoweringError(ex, "`...` expression outside call")) elseif is_leaf(ex) ex elseif k == K"return" if numchildren(ex) == 0 @ast ctx ex [K"return" "nothing"::K"core"] elseif numchildren(ex) == 1 mapchildren((e->begin expand_forms_2(ctx, e) end), ctx, ex) else throw(LoweringError(ex, "More than one argument to return")) end else mapchildren((e->begin expand_forms_2(ctx, e) end), ctx, ex) end elseif k == K"$" throw(LoweringError(ex, "`\$` expression outside string or quote block")) elseif k == K"module" throw(LoweringError(ex, "`module` is only allowed at top level")) elseif k == K"import" || k == K"using" expand_import_or_using(ctx, ex) elseif k == K"export" || k == K"public" expand_public(ctx, ex) elseif k == K"abstract" || k == K"primitive" expand_forms_2(ctx, expand_abstract_or_primitive_type(ctx, ex)) elseif k == K"struct" expand_forms_2(ctx, expand_struct_def(ctx, ex, docs)) elseif k == K"ref" sctx = with_stmts(ctx) (arr, idxs) = expand_ref_components(sctx, ex) expand_forms_2(ctx, @ast(ctx, ex, [K"block"; sctx.stmts...; [K"call"; "getindex"::K"top"; arr; idxs...]])) elseif k == K"curly" expand_forms_2(ctx, expand_curly(ctx, ex)) elseif k == K"toplevel" ex2 = @ast(ctx, ex, [K"block"; [K"assert" "toplevel_only"::K"Symbol" [K"inert" ex]]; [K"call"; eval::K"Value"; ctx.mod::K"Value"; [K"inert" ex]; [K"parameters"; [K"="; "expr_compat_mode"::K"Identifier"; ctx.expr_compat_mode::K"Bool"]]]]) expand_forms_2(ctx, ex2) elseif k == K"vect" check_no_parameters(ex, "unexpected semicolon in array expression") expand_array(ctx, ex, "vect") elseif k == K"hcat" expand_array(ctx, ex, "hcat") elseif k == K"typed_hcat" expand_array(ctx, ex, "typed_hcat") elseif k == K"opaque_closure" expand_forms_2(ctx, expand_opaque_closure(ctx, ex)) elseif k == K"vcat" || k == K"typed_vcat" expand_forms_2(ctx, expand_vcat(ctx, ex)) elseif k == K"ncat" || k == K"typed_ncat" expand_forms_2(ctx, expand_ncat(ctx, ex)) elseif k == K"while" @chk numchildren(ex) == 2 @ast ctx ex [K"break_block" "loop_exit"::K"symbolic_label"; [K"_while"; expand_condition(ctx, ex[1]); [K"break_block" "loop_cont"::K"symbolic_label"; [(K"scope_block")(scope_type = :neutral); expand_forms_2(ctx, ex[2])]]]] elseif k == K"inert" ex elseif k == K"gc_preserve" s = ssavar(ctx, ex) r = ssavar(ctx, ex) @ast ctx ex [K"block"; s := [K"gc_preserve_begin" (children(ex))[2:var"end"]...]; r := expand_forms_2(ctx, (children(ex))[1]); [K"gc_preserve_end" s]; r] elseif k == K"&" throw(LoweringError(ex, "invalid syntax")) elseif k == K"$" throw(LoweringError(ex, "`\$` expression outside string or quote")) elseif k == K"..." throw(LoweringError(ex, "`...` expression outside call")) elseif is_leaf(ex) ex elseif k == K"return" if numchildren(ex) == 0 @ast ctx ex [K"return" "nothing"::K"core"] elseif numchildren(ex) == 1 mapchildren((e->begin expand_forms_2(ctx, e) end), ctx, ex) else throw(LoweringError(ex, "More than one argument to return")) end else mapchildren((e->begin expand_forms_2(ctx, e) end), ctx, ex) end elseif k == K"tuple" if has_parameters(ex) if numchildren(ex) > 1 throw(LoweringError(ex[var"end"], "unexpected semicolon in tuple - use `,` to separate tuple elements")) end expand_forms_2(ctx, expand_named_tuple(ctx, ex, children(ex[1]))) elseif any_assignment(children(ex)) expand_forms_2(ctx, expand_named_tuple(ctx, ex, children(ex))) else expand_forms_2(ctx, @ast(ctx, ex, [K"call"; "tuple"::K"core"; children(ex)...])) end elseif k == K"$" throw(LoweringError(ex, "`\$` expression outside string or quote block")) elseif k == K"module" throw(LoweringError(ex, "`module` is only allowed at top level")) elseif k == K"import" || k == K"using" expand_import_or_using(ctx, ex) elseif k == K"export" || k == K"public" expand_public(ctx, ex) elseif k == K"abstract" || k == K"primitive" expand_forms_2(ctx, expand_abstract_or_primitive_type(ctx, ex)) elseif k == K"struct" expand_forms_2(ctx, expand_struct_def(ctx, ex, docs)) elseif k == K"ref" sctx = with_stmts(ctx) (arr, idxs) = expand_ref_components(sctx, ex) expand_forms_2(ctx, @ast(ctx, ex, [K"block"; sctx.stmts...; [K"call"; "getindex"::K"top"; arr; idxs...]])) elseif k == K"curly" expand_forms_2(ctx, expand_curly(ctx, ex)) elseif k == K"toplevel" ex2 = @ast(ctx, ex, [K"block"; [K"assert" "toplevel_only"::K"Symbol" [K"inert" ex]]; [K"call"; eval ::K"Value"; ctx.mod ::K"Value"; [K"inert" ex]; [K"parameters"; [K"="; "expr_compat_mode"::K"Identifier"; ctx.expr_compat_mode::K"Bool"]]]]) expand_forms_2(ctx, ex2) elseif k == K"vect" check_no_parameters(ex, "unexpected semicolon in array expression") expand_array(ctx, ex, "vect") elseif k == K"hcat" expand_array(ctx, ex, "hcat") elseif k == K"typed_hcat" expand_array(ctx, ex, "typed_hcat") elseif k == K"opaque_closure" expand_forms_2(ctx, expand_opaque_closure(ctx, ex)) elseif k == K"vcat" || k == K"typed_vcat" expand_forms_2(ctx, expand_vcat(ctx, ex)) elseif k == K"ncat" || k == K"typed_ncat" expand_forms_2(ctx, expand_ncat(ctx, ex)) elseif k == K"while" @chk numchildren(ex) == 2 @ast ctx ex [K"break_block" "loop_exit"::K"symbolic_label"; [K"_while"; expand_condition(ctx, ex[1]); [K"break_block" "loop_cont"::K"symbolic_label"; [(K"scope_block")(scope_type = :neutral); expand_forms_2(ctx, ex[2])]]]] elseif k == K"inert" ex elseif k == K"gc_preserve" s = ssavar(ctx, ex) r = ssavar(ctx, ex) @ast ctx ex [K"block"; s := [K"gc_preserve_begin" (children(ex))[2:var"end"]...]; r := expand_forms_2(ctx, (children(ex))[1]); [K"gc_preserve_end" s]; r] elseif k == K"&" throw(LoweringError(ex, "invalid syntax")) elseif k == K"$" throw(LoweringError(ex, "`\$` expression outside string or quote")) elseif k == K"..." throw(LoweringError(ex, "`...` expression outside call")) elseif is_leaf(ex) ex elseif k == K"return" if numchildren(ex) == 0 @ast ctx ex [K"return" "nothing"::K"core"] elseif numchildren(ex) == 1 mapchildren((e->begin expand_forms_2(ctx, e) end), ctx, ex) else throw(LoweringError(ex, "More than one argument to return")) end else mapchildren((e->begin expand_forms_2(ctx, e) end), ctx, ex) end elseif k == K"tuple" if has_parameters(ex) if numchildren(ex) > 1 throw(LoweringError(ex[var"end"], "unexpected semicolon in tuple - use `,` to separate tuple elements")) end expand_forms_2(ctx, expand_named_tuple(ctx, ex, children(ex[1]))) elseif any_assignment(children(ex)) expand_forms_2(ctx, expand_named_tuple(ctx, ex, children(ex))) else expand_forms_2(ctx, @ast(ctx, ex, [K"call"; "tuple"::K"core"; children(ex)...])) end elseif k == K"$" throw(LoweringError(ex, "`\$` expression outside string or quote block")) elseif k == K"module" throw(LoweringError(ex, "`module` is only allowed at top level")) elseif k == K"import" || k == K"using" expand_import_or_using(ctx, ex) elseif k == K"export" || k == K"public" expand_public(ctx, ex) elseif k == K"abstract" || k == K"primitive" expand_forms_2(ctx, expand_abstract_or_primitive_type(ctx, ex)) elseif k == K"struct" expand_forms_2(ctx, expand_struct_def(ctx, ex, docs)) elseif k == K"ref" sctx = with_stmts(ctx) (arr, idxs) = expand_ref_components(sctx, ex) expand_forms_2(ctx, @ast(ctx, ex, [K"block"; sctx.stmts...; [K"call"; "getindex"::K"top"; arr; idxs...]])) elseif k == K"curly" expand_forms_2(ctx, expand_curly(ctx, ex)) elseif k == K"toplevel" ex2 = @ast(ctx, ex, [K"block"; [K"assert" "toplevel_only"::K"Symbol" [K"inert" ex]]; [K"call"; eval::K"Value"; ctx.mod::K"Value"; [K"inert" ex]; [K"parameters"; [K"="; "expr_compat_mode"::K"Identifier"; ctx.expr_compat_mode::K"Bool"]]]]) expand_forms_2(ctx, ex2) elseif k == K"vect" check_no_parameters(ex, "unexpected semicolon in array expression") expand_array(ctx, ex, "vect") elseif k == K"hcat" expand_array(ctx, ex, "hcat") elseif k == K"typed_hcat" expand_array(ctx, ex, "typed_hcat") elseif k == K"opaque_closure" expand_forms_2(ctx, expand_opaque_closure(ctx, ex)) elseif k == K"vcat" || k == K"typed_vcat" expand_forms_2(ctx, expand_vcat(ctx, ex)) elseif k == K"ncat" || k == K"typed_ncat" expand_forms_2(ctx, expand_ncat(ctx, ex)) elseif k == K"while" @chk numchildren(ex) == 2 @ast ctx ex [K"break_block" "loop_exit"::K"symbolic_label"; [K"_while"; expand_condition(ctx, ex[1]); [K"break_block" "loop_cont"::K"symbolic_label"; [(K"scope_block")(scope_type = :neutral); expand_forms_2(ctx, ex[2])]]]] elseif k == K"inert" ex elseif k == K"gc_preserve" s = ssavar(ctx, ex) r = ssavar(ctx, ex) @ast ctx ex [K"block"; s := [K"gc_preserve_begin" (children(ex))[2:var"end"]...]; r := expand_forms_2(ctx, (children(ex))[1]); [K"gc_preserve_end" s]; r] elseif k == K"&" throw(LoweringError(ex, "invalid syntax")) elseif k == K"$" throw(LoweringError(ex, "`\$` expression outside string or quote")) elseif k == K"..." throw(LoweringError(ex, "`...` expression outside call")) elseif is_leaf(ex) ex elseif k == K"return" if numchildren(ex) == 0 @ast ctx ex [K"return" "nothing"::K"core"] elseif numchildren(ex) == 1 mapchildren((e->begin expand_forms_2(ctx, e) end), ctx, ex) else throw(LoweringError(ex, "More than one argument to return")) end else mapchildren((e->begin expand_forms_2(ctx, e) end), ctx, ex) end elseif k == K"try" expand_forms_2(ctx, expand_try(ctx, ex)) elseif k == K"tuple" if has_parameters(ex) if numchildren(ex) > 1 throw(LoweringError(ex[var"end"], "unexpected semicolon in tuple - use `,` to separate tuple elements")) end expand_forms_2(ctx, expand_named_tuple(ctx, ex, children(ex[1]))) elseif any_assignment(children(ex)) expand_forms_2(ctx, expand_named_tuple(ctx, ex, children(ex))) else expand_forms_2(ctx, @ast(ctx, ex, [K"call"; "tuple"::K"core"; children(ex)...])) end elseif k == K"$" throw(LoweringError(ex, "`\$` expression outside string or quote block")) elseif k == K"module" throw(LoweringError(ex, "`module` is only allowed at top level")) elseif k == K"import" || k == K"using" expand_import_or_using(ctx, ex) elseif k == K"export" || k == K"public" expand_public(ctx, ex) elseif k == K"abstract" || k == K"primitive" expand_forms_2(ctx, expand_abstract_or_primitive_type(ctx, ex)) elseif k == K"struct" expand_forms_2(ctx, expand_struct_def(ctx, ex, docs)) elseif k == K"ref" sctx = with_stmts(ctx) (arr, idxs) = expand_ref_components(sctx, ex) expand_forms_2(ctx, @ast(ctx, ex, [K"block"; sctx.stmts...; [K"call"; "getindex"::K"top"; arr; idxs...]])) elseif k == K"curly" expand_forms_2(ctx, expand_curly(ctx, ex)) elseif k == K"toplevel" ex2 = @ast(ctx, ex, [K"block"; [K"assert" "toplevel_only"::K"Symbol" [K"inert" ex]]; [K"call"; eval ::K"Value"; ctx.mod ::K"Value"; [K"inert" ex]; [K"parameters"; [K"="; "expr_compat_mode"::K"Identifier"; ctx.expr_compat_mode::K"Bool"]]]]) expand_forms_2(ctx, ex2) elseif k == K"vect" check_no_parameters(ex, "unexpected semicolon in array expression") expand_array(ctx, ex, "vect") elseif k == K"hcat" expand_array(ctx, ex, "hcat") elseif k == K"typed_hcat" expand_array(ctx, ex, "typed_hcat") elseif k == K"opaque_closure" expand_forms_2(ctx, expand_opaque_closure(ctx, ex)) elseif k == K"vcat" || k == K"typed_vcat" expand_forms_2(ctx, expand_vcat(ctx, ex)) elseif k == K"ncat" || k == K"typed_ncat" expand_forms_2(ctx, expand_ncat(ctx, ex)) elseif k == K"while" @chk numchildren(ex) == 2 @ast ctx ex [K"break_block" "loop_exit"::K"symbolic_label"; [K"_while"; expand_condition(ctx, ex[1]); [K"break_block" "loop_cont"::K"symbolic_label"; [(K"scope_block")(scope_type = :neutral); expand_forms_2(ctx, ex[2])]]]] elseif k == K"inert" ex elseif k == K"gc_preserve" s = ssavar(ctx, ex) r = ssavar(ctx, ex) @ast ctx ex [K"block"; s := [K"gc_preserve_begin" (children(ex))[2:var"end"]...]; r := expand_forms_2(ctx, (children(ex))[1]); [K"gc_preserve_end" s]; r] elseif k == K"&" throw(LoweringError(ex, "invalid syntax")) elseif k == K"$" throw(LoweringError(ex, "`\$` expression outside string or quote")) elseif k == K"..." throw(LoweringError(ex, "`...` expression outside call")) elseif is_leaf(ex) ex elseif k == K"return" if numchildren(ex) == 0 @ast ctx ex [K"return" "nothing"::K"core"] elseif numchildren(ex) == 1 mapchildren((e->begin expand_forms_2(ctx, e) end), ctx, ex) else throw(LoweringError(ex, "More than one argument to return")) end else mapchildren((e->begin expand_forms_2(ctx, e) end), ctx, ex) end elseif k == K"try" expand_forms_2(ctx, expand_try(ctx, ex)) elseif k == K"tuple" if has_parameters(ex) if numchildren(ex) > 1 throw(LoweringError(ex[var"end"], "unexpected semicolon in tuple - use `,` to separate tuple elements")) end expand_forms_2(ctx, expand_named_tuple(ctx, ex, children(ex[1]))) elseif any_assignment(children(ex)) expand_forms_2(ctx, expand_named_tuple(ctx, ex, children(ex))) else expand_forms_2(ctx, @ast(ctx, ex, [K"call"; "tuple"::K"core"; children(ex)...])) end elseif k == K"$" throw(LoweringError(ex, "`\$` expression outside string or quote block")) elseif k == K"module" throw(LoweringError(ex, "`module` is only allowed at top level")) elseif k == K"import" || k == K"using" expand_import_or_using(ctx, ex) elseif k == K"export" || k == K"public" expand_public(ctx, ex) elseif k == K"abstract" || k == K"primitive" expand_forms_2(ctx, expand_abstract_or_primitive_type(ctx, ex)) elseif k == K"struct" expand_forms_2(ctx, expand_struct_def(ctx, ex, docs)) elseif k == K"ref" sctx = with_stmts(ctx) (arr, idxs) = expand_ref_components(sctx, ex) expand_forms_2(ctx, @ast(ctx, ex, [K"block"; sctx.stmts...; [K"call"; "getindex"::K"top"; arr; idxs...]])) elseif k == K"curly" expand_forms_2(ctx, expand_curly(ctx, ex)) elseif k == K"toplevel" ex2 = @ast(ctx, ex, [K"block"; [K"assert" "toplevel_only"::K"Symbol" [K"inert" ex]]; [K"call"; eval::K"Value"; ctx.mod::K"Value"; [K"inert" ex]; [K"parameters"; [K"="; "expr_compat_mode"::K"Identifier"; ctx.expr_compat_mode::K"Bool"]]]]) expand_forms_2(ctx, ex2) elseif k == K"vect" check_no_parameters(ex, "unexpected semicolon in array expression") expand_array(ctx, ex, "vect") elseif k == K"hcat" expand_array(ctx, ex, "hcat") elseif k == K"typed_hcat" expand_array(ctx, ex, "typed_hcat") elseif k == K"opaque_closure" expand_forms_2(ctx, expand_opaque_closure(ctx, ex)) elseif k == K"vcat" || k == K"typed_vcat" expand_forms_2(ctx, expand_vcat(ctx, ex)) elseif k == K"ncat" || k == K"typed_ncat" expand_forms_2(ctx, expand_ncat(ctx, ex)) elseif k == K"while" @chk numchildren(ex) == 2 @ast ctx ex [K"break_block" "loop_exit"::K"symbolic_label"; [K"_while"; expand_condition(ctx, ex[1]); [K"break_block" "loop_cont"::K"symbolic_label"; [(K"scope_block")(scope_type = :neutral); expand_forms_2(ctx, ex[2])]]]] elseif k == K"inert" ex elseif k == K"gc_preserve" s = ssavar(ctx, ex) r = ssavar(ctx, ex) @ast ctx ex [K"block"; s := [K"gc_preserve_begin" (children(ex))[2:var"end"]...]; r := expand_forms_2(ctx, (children(ex))[1]); [K"gc_preserve_end" s]; r] elseif k == K"&" throw(LoweringError(ex, "invalid syntax")) elseif k == K"$" throw(LoweringError(ex, "`\$` expression outside string or quote")) elseif k == K"..." throw(LoweringError(ex, "`...` expression outside call")) elseif is_leaf(ex) ex elseif k == K"return" if numchildren(ex) == 0 @ast ctx ex [K"return" "nothing"::K"core"] elseif numchildren(ex) == 1 mapchildren((e->begin expand_forms_2(ctx, e) end), ctx, ex) else throw(LoweringError(ex, "More than one argument to return")) end else mapchildren((e->begin expand_forms_2(ctx, e) end), ctx, ex) end elseif k == K"string" if numchildren(ex) == 1 && kind(ex[1]) == K"String" ex[1] else @ast ctx ex [K"call"; "string"::K"top"; expand_forms_2(ctx, children(ex))...] end elseif k == K"try" expand_forms_2(ctx, expand_try(ctx, ex)) elseif k == K"tuple" if has_parameters(ex) if numchildren(ex) > 1 throw(LoweringError(ex[var"end"], "unexpected semicolon in tuple - use `,` to separate tuple elements")) end expand_forms_2(ctx, expand_named_tuple(ctx, ex, children(ex[1]))) elseif any_assignment(children(ex)) expand_forms_2(ctx, expand_named_tuple(ctx, ex, children(ex))) else expand_forms_2(ctx, @ast(ctx, ex, [K"call"; "tuple"::K"core"; children(ex)...])) end elseif k == K"$" throw(LoweringError(ex, "`\$` expression outside string or quote block")) elseif k == K"module" throw(LoweringError(ex, "`module` is only allowed at top level")) elseif k == K"import" || k == K"using" expand_import_or_using(ctx, ex) elseif k == K"export" || k == K"public" expand_public(ctx, ex) elseif k == K"abstract" || k == K"primitive" expand_forms_2(ctx, expand_abstract_or_primitive_type(ctx, ex)) elseif k == K"struct" expand_forms_2(ctx, expand_struct_def(ctx, ex, docs)) elseif k == K"ref" sctx = with_stmts(ctx) (arr, idxs) = expand_ref_components(sctx, ex) expand_forms_2(ctx, @ast(ctx, ex, [K"block"; sctx.stmts...; [K"call"; "getindex"::K"top"; arr; idxs...]])) elseif k == K"curly" expand_forms_2(ctx, expand_curly(ctx, ex)) elseif k == K"toplevel" ex2 = @ast(ctx, ex, [K"block"; [K"assert" "toplevel_only"::K"Symbol" [K"inert" ex]]; [K"call"; eval ::K"Value"; ctx.mod ::K"Value"; [K"inert" ex]; [K"parameters"; [K"="; "expr_compat_mode"::K"Identifier"; ctx.expr_compat_mode::K"Bool"]]]]) expand_forms_2(ctx, ex2) elseif k == K"vect" check_no_parameters(ex, "unexpected semicolon in array expression") expand_array(ctx, ex, "vect") elseif k == K"hcat" expand_array(ctx, ex, "hcat") elseif k == K"typed_hcat" expand_array(ctx, ex, "typed_hcat") elseif k == K"opaque_closure" expand_forms_2(ctx, expand_opaque_closure(ctx, ex)) elseif k == K"vcat" || k == K"typed_vcat" expand_forms_2(ctx, expand_vcat(ctx, ex)) elseif k == K"ncat" || k == K"typed_ncat" expand_forms_2(ctx, expand_ncat(ctx, ex)) elseif k == K"while" @chk numchildren(ex) == 2 @ast ctx ex [K"break_block" "loop_exit"::K"symbolic_label"; [K"_while"; expand_condition(ctx, ex[1]); [K"break_block" "loop_cont"::K"symbolic_label"; [(K"scope_block")(scope_type = :neutral); expand_forms_2(ctx, ex[2])]]]] elseif k == K"inert" ex elseif k == K"gc_preserve" s = ssavar(ctx, ex) r = ssavar(ctx, ex) @ast ctx ex [K"block"; s := [K"gc_preserve_begin" (children(ex))[2:var"end"]...]; r := expand_forms_2(ctx, (children(ex))[1]); [K"gc_preserve_end" s]; r] elseif k == K"&" throw(LoweringError(ex, "invalid syntax")) elseif k == K"$" throw(LoweringError(ex, "`\$` expression outside string or quote")) elseif k == K"..." throw(LoweringError(ex, "`...` expression outside call")) elseif is_leaf(ex) ex elseif k == K"return" if numchildren(ex) == 0 @ast ctx ex [K"return" "nothing"::K"core"] elseif numchildren(ex) == 1 mapchildren((e->begin expand_forms_2(ctx, e) end), ctx, ex) else throw(LoweringError(ex, "More than one argument to return")) end else mapchildren((e->begin expand_forms_2(ctx, e) end), ctx, ex) end elseif k == K"string" if numchildren(ex) == 1 && kind(ex[1]) == K"String" ex[1] else @ast ctx ex [K"call"; "string"::K"top"; expand_forms_2(ctx, children(ex))...] end elseif k == K"try" expand_forms_2(ctx, expand_try(ctx, ex)) elseif k == K"tuple" if has_parameters(ex) if numchildren(ex) > 1 throw(LoweringError(ex[var"end"], "unexpected semicolon in tuple - use `,` to separate tuple elements")) end expand_forms_2(ctx, expand_named_tuple(ctx, ex, children(ex[1]))) elseif any_assignment(children(ex)) expand_forms_2(ctx, expand_named_tuple(ctx, ex, children(ex))) else expand_forms_2(ctx, @ast(ctx, ex, [K"call"; "tuple"::K"core"; children(ex)...])) end elseif k == K"$" throw(LoweringError(ex, "`\$` expression outside string or quote block")) elseif k == K"module" throw(LoweringError(ex, "`module` is only allowed at top level")) elseif k == K"import" || k == K"using" expand_import_or_using(ctx, ex) elseif k == K"export" || k == K"public" expand_public(ctx, ex) elseif k == K"abstract" || k == K"primitive" expand_forms_2(ctx, expand_abstract_or_primitive_type(ctx, ex)) elseif k == K"struct" expand_forms_2(ctx, expand_struct_def(ctx, ex, docs)) elseif k == K"ref" sctx = with_stmts(ctx) (arr, idxs) = expand_ref_components(sctx, ex) expand_forms_2(ctx, @ast(ctx, ex, [K"block"; sctx.stmts...; [K"call"; "getindex"::K"top"; arr; idxs...]])) elseif k == K"curly" expand_forms_2(ctx, expand_curly(ctx, ex)) elseif k == K"toplevel" ex2 = @ast(ctx, ex, [K"block"; [K"assert" "toplevel_only"::K"Symbol" [K"inert" ex]]; [K"call"; eval::K"Value"; ctx.mod::K"Value"; [K"inert" ex]; [K"parameters"; [K"="; "expr_compat_mode"::K"Identifier"; ctx.expr_compat_mode::K"Bool"]]]]) expand_forms_2(ctx, ex2) elseif k == K"vect" check_no_parameters(ex, "unexpected semicolon in array expression") expand_array(ctx, ex, "vect") elseif k == K"hcat" expand_array(ctx, ex, "hcat") elseif k == K"typed_hcat" expand_array(ctx, ex, "typed_hcat") elseif k == K"opaque_closure" expand_forms_2(ctx, expand_opaque_closure(ctx, ex)) elseif k == K"vcat" || k == K"typed_vcat" expand_forms_2(ctx, expand_vcat(ctx, ex)) elseif k == K"ncat" || k == K"typed_ncat" expand_forms_2(ctx, expand_ncat(ctx, ex)) elseif k == K"while" @chk numchildren(ex) == 2 @ast ctx ex [K"break_block" "loop_exit"::K"symbolic_label"; [K"_while"; expand_condition(ctx, ex[1]); [K"break_block" "loop_cont"::K"symbolic_label"; [(K"scope_block")(scope_type = :neutral); expand_forms_2(ctx, ex[2])]]]] elseif k == K"inert" ex elseif k == K"gc_preserve" s = ssavar(ctx, ex) r = ssavar(ctx, ex) @ast ctx ex [K"block"; s := [K"gc_preserve_begin" (children(ex))[2:var"end"]...]; r := expand_forms_2(ctx, (children(ex))[1]); [K"gc_preserve_end" s]; r] elseif k == K"&" throw(LoweringError(ex, "invalid syntax")) elseif k == K"$" throw(LoweringError(ex, "`\$` expression outside string or quote")) elseif k == K"..." throw(LoweringError(ex, "`...` expression outside call")) elseif is_leaf(ex) ex elseif k == K"return" if numchildren(ex) == 0 @ast ctx ex [K"return" "nothing"::K"core"] elseif numchildren(ex) == 1 mapchildren((e->begin expand_forms_2(ctx, e) end), ctx, ex) else throw(LoweringError(ex, "More than one argument to return")) end else mapchildren((e->begin expand_forms_2(ctx, e) end), ctx, ex) end elseif k == K"braces" || k == K"bracescat" throw(LoweringError(ex, "{ } syntax is reserved for future use")) elseif k == K"string" if numchildren(ex) == 1 && kind(ex[1]) == K"String" ex[1] else @ast ctx ex [K"call"; "string"::K"top"; expand_forms_2(ctx, children(ex))...] end elseif k == K"try" expand_forms_2(ctx, expand_try(ctx, ex)) elseif k == K"tuple" if has_parameters(ex) if numchildren(ex) > 1 throw(LoweringError(ex[var"end"], "unexpected semicolon in tuple - use `,` to separate tuple elements")) end expand_forms_2(ctx, expand_named_tuple(ctx, ex, children(ex[1]))) elseif any_assignment(children(ex)) expand_forms_2(ctx, expand_named_tuple(ctx, ex, children(ex))) else expand_forms_2(ctx, @ast(ctx, ex, [K"call"; "tuple"::K"core"; children(ex)...])) end elseif k == K"$" throw(LoweringError(ex, "`\$` expression outside string or quote block")) elseif k == K"module" throw(LoweringError(ex, "`module` is only allowed at top level")) elseif k == K"import" || k == K"using" expand_import_or_using(ctx, ex) elseif k == K"export" || k == K"public" expand_public(ctx, ex) elseif k == K"abstract" || k == K"primitive" expand_forms_2(ctx, expand_abstract_or_primitive_type(ctx, ex)) elseif k == K"struct" expand_forms_2(ctx, expand_struct_def(ctx, ex, docs)) elseif k == K"ref" sctx = with_stmts(ctx) (arr, idxs) = expand_ref_components(sctx, ex) expand_forms_2(ctx, @ast(ctx, ex, [K"block"; sctx.stmts...; [K"call"; "getindex"::K"top"; arr; idxs...]])) elseif k == K"curly" expand_forms_2(ctx, expand_curly(ctx, ex)) elseif k == K"toplevel" ex2 = @ast(ctx, ex, [K"block"; [K"assert" "toplevel_only"::K"Symbol" [K"inert" ex]]; [K"call"; eval ::K"Value"; ctx.mod ::K"Value"; [K"inert" ex]; [K"parameters"; [K"="; "expr_compat_mode"::K"Identifier"; ctx.expr_compat_mode::K"Bool"]]]]) expand_forms_2(ctx, ex2) elseif k == K"vect" check_no_parameters(ex, "unexpected semicolon in array expression") expand_array(ctx, ex, "vect") elseif k == K"hcat" expand_array(ctx, ex, "hcat") elseif k == K"typed_hcat" expand_array(ctx, ex, "typed_hcat") elseif k == K"opaque_closure" expand_forms_2(ctx, expand_opaque_closure(ctx, ex)) elseif k == K"vcat" || k == K"typed_vcat" expand_forms_2(ctx, expand_vcat(ctx, ex)) elseif k == K"ncat" || k == K"typed_ncat" expand_forms_2(ctx, expand_ncat(ctx, ex)) elseif k == K"while" @chk numchildren(ex) == 2 @ast ctx ex [K"break_block" "loop_exit"::K"symbolic_label"; [K"_while"; expand_condition(ctx, ex[1]); [K"break_block" "loop_cont"::K"symbolic_label"; [(K"scope_block")(scope_type = :neutral); expand_forms_2(ctx, ex[2])]]]] elseif k == K"inert" ex elseif k == K"gc_preserve" s = ssavar(ctx, ex) r = ssavar(ctx, ex) @ast ctx ex [K"block"; s := [K"gc_preserve_begin" (children(ex))[2:var"end"]...]; r := expand_forms_2(ctx, (children(ex))[1]); [K"gc_preserve_end" s]; r] elseif k == K"&" throw(LoweringError(ex, "invalid syntax")) elseif k == K"$" throw(LoweringError(ex, "`\$` expression outside string or quote")) elseif k == K"..." throw(LoweringError(ex, "`...` expression outside call")) elseif is_leaf(ex) ex elseif k == K"return" if numchildren(ex) == 0 @ast ctx ex [K"return" "nothing"::K"core"] elseif numchildren(ex) == 1 mapchildren((e->begin expand_forms_2(ctx, e) end), ctx, ex) else throw(LoweringError(ex, "More than one argument to return")) end else mapchildren((e->begin expand_forms_2(ctx, e) end), ctx, ex) end elseif k == K"braces" || k == K"bracescat" throw(LoweringError(ex, "{ } syntax is reserved for future use")) elseif k == K"string" if numchildren(ex) == 1 && kind(ex[1]) == K"String" ex[1] else @ast ctx ex [K"call"; "string"::K"top"; expand_forms_2(ctx, children(ex))...] end elseif k == K"try" expand_forms_2(ctx, expand_try(ctx, ex)) elseif k == K"tuple" if has_parameters(ex) if numchildren(ex) > 1 throw(LoweringError(ex[var"end"], "unexpected semicolon in tuple - use `,` to separate tuple elements")) end expand_forms_2(ctx, expand_named_tuple(ctx, ex, children(ex[1]))) elseif any_assignment(children(ex)) expand_forms_2(ctx, expand_named_tuple(ctx, ex, children(ex))) else expand_forms_2(ctx, @ast(ctx, ex, [K"call"; "tuple"::K"core"; children(ex)...])) end elseif k == K"$" throw(LoweringError(ex, "`\$` expression outside string or quote block")) elseif k == K"module" throw(LoweringError(ex, "`module` is only allowed at top level")) elseif k == K"import" || k == K"using" expand_import_or_using(ctx, ex) elseif k == K"export" || k == K"public" expand_public(ctx, ex) elseif k == K"abstract" || k == K"primitive" expand_forms_2(ctx, expand_abstract_or_primitive_type(ctx, ex)) elseif k == K"struct" expand_forms_2(ctx, expand_struct_def(ctx, ex, docs)) elseif k == K"ref" sctx = with_stmts(ctx) (arr, idxs) = expand_ref_components(sctx, ex) expand_forms_2(ctx, @ast(ctx, ex, [K"block"; sctx.stmts...; [K"call"; "getindex"::K"top"; arr; idxs...]])) elseif k == K"curly" expand_forms_2(ctx, expand_curly(ctx, ex)) elseif k == K"toplevel" ex2 = @ast(ctx, ex, [K"block"; [K"assert" "toplevel_only"::K"Symbol" [K"inert" ex]]; [K"call"; eval::K"Value"; ctx.mod::K"Value"; [K"inert" ex]; [K"parameters"; [K"="; "expr_compat_mode"::K"Identifier"; ctx.expr_compat_mode::K"Bool"]]]]) expand_forms_2(ctx, ex2) elseif k == K"vect" check_no_parameters(ex, "unexpected semicolon in array expression") expand_array(ctx, ex, "vect") elseif k == K"hcat" expand_array(ctx, ex, "hcat") elseif k == K"typed_hcat" expand_array(ctx, ex, "typed_hcat") elseif k == K"opaque_closure" expand_forms_2(ctx, expand_opaque_closure(ctx, ex)) elseif k == K"vcat" || k == K"typed_vcat" expand_forms_2(ctx, expand_vcat(ctx, ex)) elseif k == K"ncat" || k == K"typed_ncat" expand_forms_2(ctx, expand_ncat(ctx, ex)) elseif k == K"while" @chk numchildren(ex) == 2 @ast ctx ex [K"break_block" "loop_exit"::K"symbolic_label"; [K"_while"; expand_condition(ctx, ex[1]); [K"break_block" "loop_cont"::K"symbolic_label"; [(K"scope_block")(scope_type = :neutral); expand_forms_2(ctx, ex[2])]]]] elseif k == K"inert" ex elseif k == K"gc_preserve" s = ssavar(ctx, ex) r = ssavar(ctx, ex) @ast ctx ex [K"block"; s := [K"gc_preserve_begin" (children(ex))[2:var"end"]...]; r := expand_forms_2(ctx, (children(ex))[1]); [K"gc_preserve_end" s]; r] elseif k == K"&" throw(LoweringError(ex, "invalid syntax")) elseif k == K"$" throw(LoweringError(ex, "`\$` expression outside string or quote")) elseif k == K"..." throw(LoweringError(ex, "`...` expression outside call")) elseif is_leaf(ex) ex elseif k == K"return" if numchildren(ex) == 0 @ast ctx ex [K"return" "nothing"::K"core"] elseif numchildren(ex) == 1 mapchildren((e->begin expand_forms_2(ctx, e) end), ctx, ex) else throw(LoweringError(ex, "More than one argument to return")) end else mapchildren((e->begin expand_forms_2(ctx, e) end), ctx, ex) end elseif k == K"where" expand_forms_2(ctx, expand_wheres(ctx, ex)) elseif k == K"braces" || k == K"bracescat" throw(LoweringError(ex, "{ } syntax is reserved for future use")) elseif k == K"string" if numchildren(ex) == 1 && kind(ex[1]) == K"String" ex[1] else @ast ctx ex [K"call"; "string"::K"top"; expand_forms_2(ctx, children(ex))...] end elseif k == K"try" expand_forms_2(ctx, expand_try(ctx, ex)) elseif k == K"tuple" if has_parameters(ex) if numchildren(ex) > 1 throw(LoweringError(ex[var"end"], "unexpected semicolon in tuple - use `,` to separate tuple elements")) end expand_forms_2(ctx, expand_named_tuple(ctx, ex, children(ex[1]))) elseif any_assignment(children(ex)) expand_forms_2(ctx, expand_named_tuple(ctx, ex, children(ex))) else expand_forms_2(ctx, @ast(ctx, ex, [K"call"; "tuple"::K"core"; children(ex)...])) end elseif k == K"$" throw(LoweringError(ex, "`\$` expression outside string or quote block")) elseif k == K"module" throw(LoweringError(ex, "`module` is only allowed at top level")) elseif k == K"import" || k == K"using" expand_import_or_using(ctx, ex) elseif k == K"export" || k == K"public" expand_public(ctx, ex) elseif k == K"abstract" || k == K"primitive" expand_forms_2(ctx, expand_abstract_or_primitive_type(ctx, ex)) elseif k == K"struct" expand_forms_2(ctx, expand_struct_def(ctx, ex, docs)) elseif k == K"ref" sctx = with_stmts(ctx) (arr, idxs) = expand_ref_components(sctx, ex) expand_forms_2(ctx, @ast(ctx, ex, [K"block"; sctx.stmts...; [K"call"; "getindex"::K"top"; arr; idxs...]])) elseif k == K"curly" expand_forms_2(ctx, expand_curly(ctx, ex)) elseif k == K"toplevel" ex2 = @ast(ctx, ex, [K"block"; [K"assert" "toplevel_only"::K"Symbol" [K"inert" ex]]; [K"call"; eval ::K"Value"; ctx.mod ::K"Value"; [K"inert" ex]; [K"parameters"; [K"="; "expr_compat_mode"::K"Identifier"; ctx.expr_compat_mode::K"Bool"]]]]) expand_forms_2(ctx, ex2) elseif k == K"vect" check_no_parameters(ex, "unexpected semicolon in array expression") expand_array(ctx, ex, "vect") elseif k == K"hcat" expand_array(ctx, ex, "hcat") elseif k == K"typed_hcat" expand_array(ctx, ex, "typed_hcat") elseif k == K"opaque_closure" expand_forms_2(ctx, expand_opaque_closure(ctx, ex)) elseif k == K"vcat" || k == K"typed_vcat" expand_forms_2(ctx, expand_vcat(ctx, ex)) elseif k == K"ncat" || k == K"typed_ncat" expand_forms_2(ctx, expand_ncat(ctx, ex)) elseif k == K"while" @chk numchildren(ex) == 2 @ast ctx ex [K"break_block" "loop_exit"::K"symbolic_label"; [K"_while"; expand_condition(ctx, ex[1]); [K"break_block" "loop_cont"::K"symbolic_label"; [(K"scope_block")(scope_type = :neutral); expand_forms_2(ctx, ex[2])]]]] elseif k == K"inert" ex elseif k == K"gc_preserve" s = ssavar(ctx, ex) r = ssavar(ctx, ex) @ast ctx ex [K"block"; s := [K"gc_preserve_begin" (children(ex))[2:var"end"]...]; r := expand_forms_2(ctx, (children(ex))[1]); [K"gc_preserve_end" s]; r] elseif k == K"&" throw(LoweringError(ex, "invalid syntax")) elseif k == K"$" throw(LoweringError(ex, "`\$` expression outside string or quote")) elseif k == K"..." throw(LoweringError(ex, "`...` expression outside call")) elseif is_leaf(ex) ex elseif k == K"return" if numchildren(ex) == 0 @ast ctx ex [K"return" "nothing"::K"core"] elseif numchildren(ex) == 1 mapchildren((e->begin expand_forms_2(ctx, e) end), ctx, ex) else throw(LoweringError(ex, "More than one argument to return")) end else mapchildren((e->begin expand_forms_2(ctx, e) end), ctx, ex) end elseif k == K"where" expand_forms_2(ctx, expand_wheres(ctx, ex)) elseif k == K"braces" || k == K"bracescat" throw(LoweringError(ex, "{ } syntax is reserved for future use")) elseif k == K"string" if numchildren(ex) == 1 && kind(ex[1]) == K"String" ex[1] else @ast ctx ex [K"call"; "string"::K"top"; expand_forms_2(ctx, children(ex))...] end elseif k == K"try" expand_forms_2(ctx, expand_try(ctx, ex)) elseif k == K"tuple" if has_parameters(ex) if numchildren(ex) > 1 throw(LoweringError(ex[var"end"], "unexpected semicolon in tuple - use `,` to separate tuple elements")) end expand_forms_2(ctx, expand_named_tuple(ctx, ex, children(ex[1]))) elseif any_assignment(children(ex)) expand_forms_2(ctx, expand_named_tuple(ctx, ex, children(ex))) else expand_forms_2(ctx, @ast(ctx, ex, [K"call"; "tuple"::K"core"; children(ex)...])) end elseif k == K"$" throw(LoweringError(ex, "`\$` expression outside string or quote block")) elseif k == K"module" throw(LoweringError(ex, "`module` is only allowed at top level")) elseif k == K"import" || k == K"using" expand_import_or_using(ctx, ex) elseif k == K"export" || k == K"public" expand_public(ctx, ex) elseif k == K"abstract" || k == K"primitive" expand_forms_2(ctx, expand_abstract_or_primitive_type(ctx, ex)) elseif k == K"struct" expand_forms_2(ctx, expand_struct_def(ctx, ex, docs)) elseif k == K"ref" sctx = with_stmts(ctx) (arr, idxs) = expand_ref_components(sctx, ex) expand_forms_2(ctx, @ast(ctx, ex, [K"block"; sctx.stmts...; [K"call"; "getindex"::K"top"; arr; idxs...]])) elseif k == K"curly" expand_forms_2(ctx, expand_curly(ctx, ex)) elseif k == K"toplevel" ex2 = @ast(ctx, ex, [K"block"; [K"assert" "toplevel_only"::K"Symbol" [K"inert" ex]]; [K"call"; eval::K"Value"; ctx.mod::K"Value"; [K"inert" ex]; [K"parameters"; [K"="; "expr_compat_mode"::K"Identifier"; ctx.expr_compat_mode::K"Bool"]]]]) expand_forms_2(ctx, ex2) elseif k == K"vect" check_no_parameters(ex, "unexpected semicolon in array expression") expand_array(ctx, ex, "vect") elseif k == K"hcat" expand_array(ctx, ex, "hcat") elseif k == K"typed_hcat" expand_array(ctx, ex, "typed_hcat") elseif k == K"opaque_closure" expand_forms_2(ctx, expand_opaque_closure(ctx, ex)) elseif k == K"vcat" || k == K"typed_vcat" expand_forms_2(ctx, expand_vcat(ctx, ex)) elseif k == K"ncat" || k == K"typed_ncat" expand_forms_2(ctx, expand_ncat(ctx, ex)) elseif k == K"while" @chk numchildren(ex) == 2 @ast ctx ex [K"break_block" "loop_exit"::K"symbolic_label"; [K"_while"; expand_condition(ctx, ex[1]); [K"break_block" "loop_cont"::K"symbolic_label"; [(K"scope_block")(scope_type = :neutral); expand_forms_2(ctx, ex[2])]]]] elseif k == K"inert" ex elseif k == K"gc_preserve" s = ssavar(ctx, ex) r = ssavar(ctx, ex) @ast ctx ex [K"block"; s := [K"gc_preserve_begin" (children(ex))[2:var"end"]...]; r := expand_forms_2(ctx, (children(ex))[1]); [K"gc_preserve_end" s]; r] elseif k == K"&" throw(LoweringError(ex, "invalid syntax")) elseif k == K"$" throw(LoweringError(ex, "`\$` expression outside string or quote")) elseif k == K"..." throw(LoweringError(ex, "`...` expression outside call")) elseif is_leaf(ex) ex elseif k == K"return" if numchildren(ex) == 0 @ast ctx ex [K"return" "nothing"::K"core"] elseif numchildren(ex) == 1 mapchildren((e->begin expand_forms_2(ctx, e) end), ctx, ex) else throw(LoweringError(ex, "More than one argument to return")) end else mapchildren((e->begin expand_forms_2(ctx, e) end), ctx, ex) end elseif k == K"local" || k == K"global" if k == K"global" && kind(ex[1]) == K"const" expand_const_decl(ctx, @ast(ctx, ex, [K"const" [K"global" (ex[1])[1]]])) else expand_decls(ctx, ex) end elseif k == K"where" expand_forms_2(ctx, expand_wheres(ctx, ex)) elseif k == K"braces" || k == K"bracescat" throw(LoweringError(ex, "{ } syntax is reserved for future use")) elseif k == K"string" if numchildren(ex) == 1 && kind(ex[1]) == K"String" ex[1] else @ast ctx ex [K"call"; "string"::K"top"; expand_forms_2(ctx, children(ex))...] end elseif k == K"try" expand_forms_2(ctx, expand_try(ctx, ex)) elseif k == K"tuple" if has_parameters(ex) if numchildren(ex) > 1 throw(LoweringError(ex[var"end"], "unexpected semicolon in tuple - use `,` to separate tuple elements")) end expand_forms_2(ctx, expand_named_tuple(ctx, ex, children(ex[1]))) elseif any_assignment(children(ex)) expand_forms_2(ctx, expand_named_tuple(ctx, ex, children(ex))) else expand_forms_2(ctx, @ast(ctx, ex, [K"call"; "tuple"::K"core"; children(ex)...])) end elseif k == K"$" throw(LoweringError(ex, "`\$` expression outside string or quote block")) elseif k == K"module" throw(LoweringError(ex, "`module` is only allowed at top level")) elseif k == K"import" || k == K"using" expand_import_or_using(ctx, ex) elseif k == K"export" || k == K"public" expand_public(ctx, ex) elseif k == K"abstract" || k == K"primitive" expand_forms_2(ctx, expand_abstract_or_primitive_type(ctx, ex)) elseif k == K"struct" expand_forms_2(ctx, expand_struct_def(ctx, ex, docs)) elseif k == K"ref" sctx = with_stmts(ctx) (arr, idxs) = expand_ref_components(sctx, ex) expand_forms_2(ctx, @ast(ctx, ex, [K"block"; sctx.stmts...; [K"call"; "getindex"::K"top"; arr; idxs...]])) elseif k == K"curly" expand_forms_2(ctx, expand_curly(ctx, ex)) elseif k == K"toplevel" ex2 = @ast(ctx, ex, [K"block"; [K"assert" "toplevel_only"::K"Symbol" [K"inert" ex]]; [K"call"; eval ::K"Value"; ctx.mod ::K"Value"; [K"inert" ex]; [K"parameters"; [K"="; "expr_compat_mode"::K"Identifier"; ctx.expr_compat_mode::K"Bool"]]]]) expand_forms_2(ctx, ex2) elseif k == K"vect" check_no_parameters(ex, "unexpected semicolon in array expression") expand_array(ctx, ex, "vect") elseif k == K"hcat" expand_array(ctx, ex, "hcat") elseif k == K"typed_hcat" expand_array(ctx, ex, "typed_hcat") elseif k == K"opaque_closure" expand_forms_2(ctx, expand_opaque_closure(ctx, ex)) elseif k == K"vcat" || k == K"typed_vcat" expand_forms_2(ctx, expand_vcat(ctx, ex)) elseif k == K"ncat" || k == K"typed_ncat" expand_forms_2(ctx, expand_ncat(ctx, ex)) elseif k == K"while" @chk numchildren(ex) == 2 @ast ctx ex [K"break_block" "loop_exit"::K"symbolic_label"; [K"_while"; expand_condition(ctx, ex[1]); [K"break_block" "loop_cont"::K"symbolic_label"; [(K"scope_block")(scope_type = :neutral); expand_forms_2(ctx, ex[2])]]]] elseif k == K"inert" ex elseif k == K"gc_preserve" s = ssavar(ctx, ex) r = ssavar(ctx, ex) @ast ctx ex [K"block"; s := [K"gc_preserve_begin" (children(ex))[2:var"end"]...]; r := expand_forms_2(ctx, (children(ex))[1]); [K"gc_preserve_end" s]; r] elseif k == K"&" throw(LoweringError(ex, "invalid syntax")) elseif k == K"$" throw(LoweringError(ex, "`\$` expression outside string or quote")) elseif k == K"..." throw(LoweringError(ex, "`...` expression outside call")) elseif is_leaf(ex) ex elseif k == K"return" if numchildren(ex) == 0 @ast ctx ex [K"return" "nothing"::K"core"] elseif numchildren(ex) == 1 mapchildren((e->begin expand_forms_2(ctx, e) end), ctx, ex) else throw(LoweringError(ex, "More than one argument to return")) end else mapchildren((e->begin expand_forms_2(ctx, e) end), ctx, ex) end elseif k == K"local" || k == K"global" if k == K"global" && kind(ex[1]) == K"const" expand_const_decl(ctx, @ast(ctx, ex, [K"const" [K"global" (ex[1])[1]]])) else expand_decls(ctx, ex) end elseif k == K"where" expand_forms_2(ctx, expand_wheres(ctx, ex)) elseif k == K"braces" || k == K"bracescat" throw(LoweringError(ex, "{ } syntax is reserved for future use")) elseif k == K"string" if numchildren(ex) == 1 && kind(ex[1]) == K"String" ex[1] else @ast ctx ex [K"call"; "string"::K"top"; expand_forms_2(ctx, children(ex))...] end elseif k == K"try" expand_forms_2(ctx, expand_try(ctx, ex)) elseif k == K"tuple" if has_parameters(ex) if numchildren(ex) > 1 throw(LoweringError(ex[var"end"], "unexpected semicolon in tuple - use `,` to separate tuple elements")) end expand_forms_2(ctx, expand_named_tuple(ctx, ex, children(ex[1]))) elseif any_assignment(children(ex)) expand_forms_2(ctx, expand_named_tuple(ctx, ex, children(ex))) else expand_forms_2(ctx, @ast(ctx, ex, [K"call"; "tuple"::K"core"; children(ex)...])) end elseif k == K"$" throw(LoweringError(ex, "`\$` expression outside string or quote block")) elseif k == K"module" throw(LoweringError(ex, "`module` is only allowed at top level")) elseif k == K"import" || k == K"using" expand_import_or_using(ctx, ex) elseif k == K"export" || k == K"public" expand_public(ctx, ex) elseif k == K"abstract" || k == K"primitive" expand_forms_2(ctx, expand_abstract_or_primitive_type(ctx, ex)) elseif k == K"struct" expand_forms_2(ctx, expand_struct_def(ctx, ex, docs)) elseif k == K"ref" sctx = with_stmts(ctx) (arr, idxs) = expand_ref_components(sctx, ex) expand_forms_2(ctx, @ast(ctx, ex, [K"block"; sctx.stmts...; [K"call"; "getindex"::K"top"; arr; idxs...]])) elseif k == K"curly" expand_forms_2(ctx, expand_curly(ctx, ex)) elseif k == K"toplevel" ex2 = @ast(ctx, ex, [K"block"; [K"assert" "toplevel_only"::K"Symbol" [K"inert" ex]]; [K"call"; eval::K"Value"; ctx.mod::K"Value"; [K"inert" ex]; [K"parameters"; [K"="; "expr_compat_mode"::K"Identifier"; ctx.expr_compat_mode::K"Bool"]]]]) expand_forms_2(ctx, ex2) elseif k == K"vect" check_no_parameters(ex, "unexpected semicolon in array expression") expand_array(ctx, ex, "vect") elseif k == K"hcat" expand_array(ctx, ex, "hcat") elseif k == K"typed_hcat" expand_array(ctx, ex, "typed_hcat") elseif k == K"opaque_closure" expand_forms_2(ctx, expand_opaque_closure(ctx, ex)) elseif k == K"vcat" || k == K"typed_vcat" expand_forms_2(ctx, expand_vcat(ctx, ex)) elseif k == K"ncat" || k == K"typed_ncat" expand_forms_2(ctx, expand_ncat(ctx, ex)) elseif k == K"while" @chk numchildren(ex) == 2 @ast ctx ex [K"break_block" "loop_exit"::K"symbolic_label"; [K"_while"; expand_condition(ctx, ex[1]); [K"break_block" "loop_cont"::K"symbolic_label"; [(K"scope_block")(scope_type = :neutral); expand_forms_2(ctx, ex[2])]]]] elseif k == K"inert" ex elseif k == K"gc_preserve" s = ssavar(ctx, ex) r = ssavar(ctx, ex) @ast ctx ex [K"block"; s := [K"gc_preserve_begin" (children(ex))[2:var"end"]...]; r := expand_forms_2(ctx, (children(ex))[1]); [K"gc_preserve_end" s]; r] elseif k == K"&" throw(LoweringError(ex, "invalid syntax")) elseif k == K"$" throw(LoweringError(ex, "`\$` expression outside string or quote")) elseif k == K"..." throw(LoweringError(ex, "`...` expression outside call")) elseif is_leaf(ex) ex elseif k == K"return" if numchildren(ex) == 0 @ast ctx ex [K"return" "nothing"::K"core"] elseif numchildren(ex) == 1 mapchildren((e->begin expand_forms_2(ctx, e) end), ctx, ex) else throw(LoweringError(ex, "More than one argument to return")) end else mapchildren((e->begin expand_forms_2(ctx, e) end), ctx, ex) end elseif k == K"const" expand_const_decl(ctx, ex) elseif k == K"local" || k == K"global" if k == K"global" && kind(ex[1]) == K"const" expand_const_decl(ctx, @ast(ctx, ex, [K"const" [K"global" (ex[1])[1]]])) else expand_decls(ctx, ex) end elseif k == K"where" expand_forms_2(ctx, expand_wheres(ctx, ex)) elseif k == K"braces" || k == K"bracescat" throw(LoweringError(ex, "{ } syntax is reserved for future use")) elseif k == K"string" if numchildren(ex) == 1 && kind(ex[1]) == K"String" ex[1] else @ast ctx ex [K"call"; "string"::K"top"; expand_forms_2(ctx, children(ex))...] end elseif k == K"try" expand_forms_2(ctx, expand_try(ctx, ex)) elseif k == K"tuple" if has_parameters(ex) if numchildren(ex) > 1 throw(LoweringError(ex[var"end"], "unexpected semicolon in tuple - use `,` to separate tuple elements")) end expand_forms_2(ctx, expand_named_tuple(ctx, ex, children(ex[1]))) elseif any_assignment(children(ex)) expand_forms_2(ctx, expand_named_tuple(ctx, ex, children(ex))) else expand_forms_2(ctx, @ast(ctx, ex, [K"call"; "tuple"::K"core"; children(ex)...])) end elseif k == K"$" throw(LoweringError(ex, "`\$` expression outside string or quote block")) elseif k == K"module" throw(LoweringError(ex, "`module` is only allowed at top level")) elseif k == K"import" || k == K"using" expand_import_or_using(ctx, ex) elseif k == K"export" || k == K"public" expand_public(ctx, ex) elseif k == K"abstract" || k == K"primitive" expand_forms_2(ctx, expand_abstract_or_primitive_type(ctx, ex)) elseif k == K"struct" expand_forms_2(ctx, expand_struct_def(ctx, ex, docs)) elseif k == K"ref" sctx = with_stmts(ctx) (arr, idxs) = expand_ref_components(sctx, ex) expand_forms_2(ctx, @ast(ctx, ex, [K"block"; sctx.stmts...; [K"call"; "getindex"::K"top"; arr; idxs...]])) elseif k == K"curly" expand_forms_2(ctx, expand_curly(ctx, ex)) elseif k == K"toplevel" ex2 = @ast(ctx, ex, [K"block"; [K"assert" "toplevel_only"::K"Symbol" [K"inert" ex]]; [K"call"; eval ::K"Value"; ctx.mod ::K"Value"; [K"inert" ex]; [K"parameters"; [K"="; "expr_compat_mode"::K"Identifier"; ctx.expr_compat_mode::K"Bool"]]]]) expand_forms_2(ctx, ex2) elseif k == K"vect" check_no_parameters(ex, "unexpected semicolon in array expression") expand_array(ctx, ex, "vect") elseif k == K"hcat" expand_array(ctx, ex, "hcat") elseif k == K"typed_hcat" expand_array(ctx, ex, "typed_hcat") elseif k == K"opaque_closure" expand_forms_2(ctx, expand_opaque_closure(ctx, ex)) elseif k == K"vcat" || k == K"typed_vcat" expand_forms_2(ctx, expand_vcat(ctx, ex)) elseif k == K"ncat" || k == K"typed_ncat" expand_forms_2(ctx, expand_ncat(ctx, ex)) elseif k == K"while" @chk numchildren(ex) == 2 @ast ctx ex [K"break_block" "loop_exit"::K"symbolic_label"; [K"_while"; expand_condition(ctx, ex[1]); [K"break_block" "loop_cont"::K"symbolic_label"; [(K"scope_block")(scope_type = :neutral); expand_forms_2(ctx, ex[2])]]]] elseif k == K"inert" ex elseif k == K"gc_preserve" s = ssavar(ctx, ex) r = ssavar(ctx, ex) @ast ctx ex [K"block"; s := [K"gc_preserve_begin" (children(ex))[2:var"end"]...]; r := expand_forms_2(ctx, (children(ex))[1]); [K"gc_preserve_end" s]; r] elseif k == K"&" throw(LoweringError(ex, "invalid syntax")) elseif k == K"$" throw(LoweringError(ex, "`\$` expression outside string or quote")) elseif k == K"..." throw(LoweringError(ex, "`...` expression outside call")) elseif is_leaf(ex) ex elseif k == K"return" if numchildren(ex) == 0 @ast ctx ex [K"return" "nothing"::K"core"] elseif numchildren(ex) == 1 mapchildren((e->begin expand_forms_2(ctx, e) end), ctx, ex) else throw(LoweringError(ex, "More than one argument to return")) end else mapchildren((e->begin expand_forms_2(ctx, e) end), ctx, ex) end elseif k == K"const" expand_const_decl(ctx, ex) elseif k == K"local" || k == K"global" if k == K"global" && kind(ex[1]) == K"const" expand_const_decl(ctx, @ast(ctx, ex, [K"const" [K"global" (ex[1])[1]]])) else expand_decls(ctx, ex) end elseif k == K"where" expand_forms_2(ctx, expand_wheres(ctx, ex)) elseif k == K"braces" || k == K"bracescat" throw(LoweringError(ex, "{ } syntax is reserved for future use")) elseif k == K"string" if numchildren(ex) == 1 && kind(ex[1]) == K"String" ex[1] else @ast ctx ex [K"call"; "string"::K"top"; expand_forms_2(ctx, children(ex))...] end elseif k == K"try" expand_forms_2(ctx, expand_try(ctx, ex)) elseif k == K"tuple" if has_parameters(ex) if numchildren(ex) > 1 throw(LoweringError(ex[var"end"], "unexpected semicolon in tuple - use `,` to separate tuple elements")) end expand_forms_2(ctx, expand_named_tuple(ctx, ex, children(ex[1]))) elseif any_assignment(children(ex)) expand_forms_2(ctx, expand_named_tuple(ctx, ex, children(ex))) else expand_forms_2(ctx, @ast(ctx, ex, [K"call"; "tuple"::K"core"; children(ex)...])) end elseif k == K"$" throw(LoweringError(ex, "`\$` expression outside string or quote block")) elseif k == K"module" throw(LoweringError(ex, "`module` is only allowed at top level")) elseif k == K"import" || k == K"using" expand_import_or_using(ctx, ex) elseif k == K"export" || k == K"public" expand_public(ctx, ex) elseif k == K"abstract" || k == K"primitive" expand_forms_2(ctx, expand_abstract_or_primitive_type(ctx, ex)) elseif k == K"struct" expand_forms_2(ctx, expand_struct_def(ctx, ex, docs)) elseif k == K"ref" sctx = with_stmts(ctx) (arr, idxs) = expand_ref_components(sctx, ex) expand_forms_2(ctx, @ast(ctx, ex, [K"block"; sctx.stmts...; [K"call"; "getindex"::K"top"; arr; idxs...]])) elseif k == K"curly" expand_forms_2(ctx, expand_curly(ctx, ex)) elseif k == K"toplevel" ex2 = @ast(ctx, ex, [K"block"; [K"assert" "toplevel_only"::K"Symbol" [K"inert" ex]]; [K"call"; eval::K"Value"; ctx.mod::K"Value"; [K"inert" ex]; [K"parameters"; [K"="; "expr_compat_mode"::K"Identifier"; ctx.expr_compat_mode::K"Bool"]]]]) expand_forms_2(ctx, ex2) elseif k == K"vect" check_no_parameters(ex, "unexpected semicolon in array expression") expand_array(ctx, ex, "vect") elseif k == K"hcat" expand_array(ctx, ex, "hcat") elseif k == K"typed_hcat" expand_array(ctx, ex, "typed_hcat") elseif k == K"opaque_closure" expand_forms_2(ctx, expand_opaque_closure(ctx, ex)) elseif k == K"vcat" || k == K"typed_vcat" expand_forms_2(ctx, expand_vcat(ctx, ex)) elseif k == K"ncat" || k == K"typed_ncat" expand_forms_2(ctx, expand_ncat(ctx, ex)) elseif k == K"while" @chk numchildren(ex) == 2 @ast ctx ex [K"break_block" "loop_exit"::K"symbolic_label"; [K"_while"; expand_condition(ctx, ex[1]); [K"break_block" "loop_cont"::K"symbolic_label"; [(K"scope_block")(scope_type = :neutral); expand_forms_2(ctx, ex[2])]]]] elseif k == K"inert" ex elseif k == K"gc_preserve" s = ssavar(ctx, ex) r = ssavar(ctx, ex) @ast ctx ex [K"block"; s := [K"gc_preserve_begin" (children(ex))[2:var"end"]...]; r := expand_forms_2(ctx, (children(ex))[1]); [K"gc_preserve_end" s]; r] elseif k == K"&" throw(LoweringError(ex, "invalid syntax")) elseif k == K"$" throw(LoweringError(ex, "`\$` expression outside string or quote")) elseif k == K"..." throw(LoweringError(ex, "`...` expression outside call")) elseif is_leaf(ex) ex elseif k == K"return" if numchildren(ex) == 0 @ast ctx ex [K"return" "nothing"::K"core"] elseif numchildren(ex) == 1 mapchildren((e->begin expand_forms_2(ctx, e) end), ctx, ex) else throw(LoweringError(ex, "More than one argument to return")) end else mapchildren((e->begin expand_forms_2(ctx, e) end), ctx, ex) end elseif k == K"let" expand_forms_2(ctx, expand_let(ctx, ex)) elseif k == K"const" expand_const_decl(ctx, ex) elseif k == K"local" || k == K"global" if k == K"global" && kind(ex[1]) == K"const" expand_const_decl(ctx, @ast(ctx, ex, [K"const" [K"global" (ex[1])[1]]])) else expand_decls(ctx, ex) end elseif k == K"where" expand_forms_2(ctx, expand_wheres(ctx, ex)) elseif k == K"braces" || k == K"bracescat" throw(LoweringError(ex, "{ } syntax is reserved for future use")) elseif k == K"string" if numchildren(ex) == 1 && kind(ex[1]) == K"String" ex[1] else @ast ctx ex [K"call"; "string"::K"top"; expand_forms_2(ctx, children(ex))...] end elseif k == K"try" expand_forms_2(ctx, expand_try(ctx, ex)) elseif k == K"tuple" if has_parameters(ex) if numchildren(ex) > 1 throw(LoweringError(ex[var"end"], "unexpected semicolon in tuple - use `,` to separate tuple elements")) end expand_forms_2(ctx, expand_named_tuple(ctx, ex, children(ex[1]))) elseif any_assignment(children(ex)) expand_forms_2(ctx, expand_named_tuple(ctx, ex, children(ex))) else expand_forms_2(ctx, @ast(ctx, ex, [K"call"; "tuple"::K"core"; children(ex)...])) end elseif k == K"$" throw(LoweringError(ex, "`\$` expression outside string or quote block")) elseif k == K"module" throw(LoweringError(ex, "`module` is only allowed at top level")) elseif k == K"import" || k == K"using" expand_import_or_using(ctx, ex) elseif k == K"export" || k == K"public" expand_public(ctx, ex) elseif k == K"abstract" || k == K"primitive" expand_forms_2(ctx, expand_abstract_or_primitive_type(ctx, ex)) elseif k == K"struct" expand_forms_2(ctx, expand_struct_def(ctx, ex, docs)) elseif k == K"ref" sctx = with_stmts(ctx) (arr, idxs) = expand_ref_components(sctx, ex) expand_forms_2(ctx, @ast(ctx, ex, [K"block"; sctx.stmts...; [K"call"; "getindex"::K"top"; arr; idxs...]])) elseif k == K"curly" expand_forms_2(ctx, expand_curly(ctx, ex)) elseif k == K"toplevel" ex2 = @ast(ctx, ex, [K"block"; [K"assert" "toplevel_only"::K"Symbol" [K"inert" ex]]; [K"call"; eval ::K"Value"; ctx.mod ::K"Value"; [K"inert" ex]; [K"parameters"; [K"="; "expr_compat_mode"::K"Identifier"; ctx.expr_compat_mode::K"Bool"]]]]) expand_forms_2(ctx, ex2) elseif k == K"vect" check_no_parameters(ex, "unexpected semicolon in array expression") expand_array(ctx, ex, "vect") elseif k == K"hcat" expand_array(ctx, ex, "hcat") elseif k == K"typed_hcat" expand_array(ctx, ex, "typed_hcat") elseif k == K"opaque_closure" expand_forms_2(ctx, expand_opaque_closure(ctx, ex)) elseif k == K"vcat" || k == K"typed_vcat" expand_forms_2(ctx, expand_vcat(ctx, ex)) elseif k == K"ncat" || k == K"typed_ncat" expand_forms_2(ctx, expand_ncat(ctx, ex)) elseif k == K"while" @chk numchildren(ex) == 2 @ast ctx ex [K"break_block" "loop_exit"::K"symbolic_label"; [K"_while"; expand_condition(ctx, ex[1]); [K"break_block" "loop_cont"::K"symbolic_label"; [(K"scope_block")(scope_type = :neutral); expand_forms_2(ctx, ex[2])]]]] elseif k == K"inert" ex elseif k == K"gc_preserve" s = ssavar(ctx, ex) r = ssavar(ctx, ex) @ast ctx ex [K"block"; s := [K"gc_preserve_begin" (children(ex))[2:var"end"]...]; r := expand_forms_2(ctx, (children(ex))[1]); [K"gc_preserve_end" s]; r] elseif k == K"&" throw(LoweringError(ex, "invalid syntax")) elseif k == K"$" throw(LoweringError(ex, "`\$` expression outside string or quote")) elseif k == K"..." throw(LoweringError(ex, "`...` expression outside call")) elseif is_leaf(ex) ex elseif k == K"return" if numchildren(ex) == 0 @ast ctx ex [K"return" "nothing"::K"core"] elseif numchildren(ex) == 1 mapchildren((e->begin expand_forms_2(ctx, e) end), ctx, ex) else throw(LoweringError(ex, "More than one argument to return")) end else mapchildren((e->begin expand_forms_2(ctx, e) end), ctx, ex) end elseif k == K"let" expand_forms_2(ctx, expand_let(ctx, ex)) elseif k == K"const" expand_const_decl(ctx, ex) elseif k == K"local" || k == K"global" if k == K"global" && kind(ex[1]) == K"const" expand_const_decl(ctx, @ast(ctx, ex, [K"const" [K"global" (ex[1])[1]]])) else expand_decls(ctx, ex) end elseif k == K"where" expand_forms_2(ctx, expand_wheres(ctx, ex)) elseif k == K"braces" || k == K"bracescat" throw(LoweringError(ex, "{ } syntax is reserved for future use")) elseif k == K"string" if numchildren(ex) == 1 && kind(ex[1]) == K"String" ex[1] else @ast ctx ex [K"call"; "string"::K"top"; expand_forms_2(ctx, children(ex))...] end elseif k == K"try" expand_forms_2(ctx, expand_try(ctx, ex)) elseif k == K"tuple" if has_parameters(ex) if numchildren(ex) > 1 throw(LoweringError(ex[var"end"], "unexpected semicolon in tuple - use `,` to separate tuple elements")) end expand_forms_2(ctx, expand_named_tuple(ctx, ex, children(ex[1]))) elseif any_assignment(children(ex)) expand_forms_2(ctx, expand_named_tuple(ctx, ex, children(ex))) else expand_forms_2(ctx, @ast(ctx, ex, [K"call"; "tuple"::K"core"; children(ex)...])) end elseif k == K"$" throw(LoweringError(ex, "`\$` expression outside string or quote block")) elseif k == K"module" throw(LoweringError(ex, "`module` is only allowed at top level")) elseif k == K"import" || k == K"using" expand_import_or_using(ctx, ex) elseif k == K"export" || k == K"public" expand_public(ctx, ex) elseif k == K"abstract" || k == K"primitive" expand_forms_2(ctx, expand_abstract_or_primitive_type(ctx, ex)) elseif k == K"struct" expand_forms_2(ctx, expand_struct_def(ctx, ex, docs)) elseif k == K"ref" sctx = with_stmts(ctx) (arr, idxs) = expand_ref_components(sctx, ex) expand_forms_2(ctx, @ast(ctx, ex, [K"block"; sctx.stmts...; [K"call"; "getindex"::K"top"; arr; idxs...]])) elseif k == K"curly" expand_forms_2(ctx, expand_curly(ctx, ex)) elseif k == K"toplevel" ex2 = @ast(ctx, ex, [K"block"; [K"assert" "toplevel_only"::K"Symbol" [K"inert" ex]]; [K"call"; eval::K"Value"; ctx.mod::K"Value"; [K"inert" ex]; [K"parameters"; [K"="; "expr_compat_mode"::K"Identifier"; ctx.expr_compat_mode::K"Bool"]]]]) expand_forms_2(ctx, ex2) elseif k == K"vect" check_no_parameters(ex, "unexpected semicolon in array expression") expand_array(ctx, ex, "vect") elseif k == K"hcat" expand_array(ctx, ex, "hcat") elseif k == K"typed_hcat" expand_array(ctx, ex, "typed_hcat") elseif k == K"opaque_closure" expand_forms_2(ctx, expand_opaque_closure(ctx, ex)) elseif k == K"vcat" || k == K"typed_vcat" expand_forms_2(ctx, expand_vcat(ctx, ex)) elseif k == K"ncat" || k == K"typed_ncat" expand_forms_2(ctx, expand_ncat(ctx, ex)) elseif k == K"while" @chk numchildren(ex) == 2 @ast ctx ex [K"break_block" "loop_exit"::K"symbolic_label"; [K"_while"; expand_condition(ctx, ex[1]); [K"break_block" "loop_cont"::K"symbolic_label"; [(K"scope_block")(scope_type = :neutral); expand_forms_2(ctx, ex[2])]]]] elseif k == K"inert" ex elseif k == K"gc_preserve" s = ssavar(ctx, ex) r = ssavar(ctx, ex) @ast ctx ex [K"block"; s := [K"gc_preserve_begin" (children(ex))[2:var"end"]...]; r := expand_forms_2(ctx, (children(ex))[1]); [K"gc_preserve_end" s]; r] elseif k == K"&" throw(LoweringError(ex, "invalid syntax")) elseif k == K"$" throw(LoweringError(ex, "`\$` expression outside string or quote")) elseif k == K"..." throw(LoweringError(ex, "`...` expression outside call")) elseif is_leaf(ex) ex elseif k == K"return" if numchildren(ex) == 0 @ast ctx ex [K"return" "nothing"::K"core"] elseif numchildren(ex) == 1 mapchildren((e->begin expand_forms_2(ctx, e) end), ctx, ex) else throw(LoweringError(ex, "More than one argument to return")) end else mapchildren((e->begin expand_forms_2(ctx, e) end), ctx, ex) end elseif k == K"if" || k == K"elseif" @chk numchildren(ex) >= 2 @ast ctx ex [k; expand_condition(ctx, ex[1]); expand_forms_2(ctx, ex[2:var"end"])...] elseif k == K"let" expand_forms_2(ctx, expand_let(ctx, ex)) elseif k == K"const" expand_const_decl(ctx, ex) elseif k == K"local" || k == K"global" if k == K"global" && kind(ex[1]) == K"const" expand_const_decl(ctx, @ast(ctx, ex, [K"const" [K"global" (ex[1])[1]]])) else expand_decls(ctx, ex) end elseif k == K"where" expand_forms_2(ctx, expand_wheres(ctx, ex)) elseif k == K"braces" || k == K"bracescat" throw(LoweringError(ex, "{ } syntax is reserved for future use")) elseif k == K"string" if numchildren(ex) == 1 && kind(ex[1]) == K"String" ex[1] else @ast ctx ex [K"call"; "string"::K"top"; expand_forms_2(ctx, children(ex))...] end elseif k == K"try" expand_forms_2(ctx, expand_try(ctx, ex)) elseif k == K"tuple" if has_parameters(ex) if numchildren(ex) > 1 throw(LoweringError(ex[var"end"], "unexpected semicolon in tuple - use `,` to separate tuple elements")) end expand_forms_2(ctx, expand_named_tuple(ctx, ex, children(ex[1]))) elseif any_assignment(children(ex)) expand_forms_2(ctx, expand_named_tuple(ctx, ex, children(ex))) else expand_forms_2(ctx, @ast(ctx, ex, [K"call"; "tuple"::K"core"; children(ex)...])) end elseif k == K"$" throw(LoweringError(ex, "`\$` expression outside string or quote block")) elseif k == K"module" throw(LoweringError(ex, "`module` is only allowed at top level")) elseif k == K"import" || k == K"using" expand_import_or_using(ctx, ex) elseif k == K"export" || k == K"public" expand_public(ctx, ex) elseif k == K"abstract" || k == K"primitive" expand_forms_2(ctx, expand_abstract_or_primitive_type(ctx, ex)) elseif k == K"struct" expand_forms_2(ctx, expand_struct_def(ctx, ex, docs)) elseif k == K"ref" sctx = with_stmts(ctx) (arr, idxs) = expand_ref_components(sctx, ex) expand_forms_2(ctx, @ast(ctx, ex, [K"block"; sctx.stmts...; [K"call"; "getindex"::K"top"; arr; idxs...]])) elseif k == K"curly" expand_forms_2(ctx, expand_curly(ctx, ex)) elseif k == K"toplevel" ex2 = @ast(ctx, ex, [K"block"; [K"assert" "toplevel_only"::K"Symbol" [K"inert" ex]]; [K"call"; eval ::K"Value"; ctx.mod ::K"Value"; [K"inert" ex]; [K"parameters"; [K"="; "expr_compat_mode"::K"Identifier"; ctx.expr_compat_mode::K"Bool"]]]]) expand_forms_2(ctx, ex2) elseif k == K"vect" check_no_parameters(ex, "unexpected semicolon in array expression") expand_array(ctx, ex, "vect") elseif k == K"hcat" expand_array(ctx, ex, "hcat") elseif k == K"typed_hcat" expand_array(ctx, ex, "typed_hcat") elseif k == K"opaque_closure" expand_forms_2(ctx, expand_opaque_closure(ctx, ex)) elseif k == K"vcat" || k == K"typed_vcat" expand_forms_2(ctx, expand_vcat(ctx, ex)) elseif k == K"ncat" || k == K"typed_ncat" expand_forms_2(ctx, expand_ncat(ctx, ex)) elseif k == K"while" @chk numchildren(ex) == 2 @ast ctx ex [K"break_block" "loop_exit"::K"symbolic_label"; [K"_while"; expand_condition(ctx, ex[1]); [K"break_block" "loop_cont"::K"symbolic_label"; [(K"scope_block")(scope_type = :neutral); expand_forms_2(ctx, ex[2])]]]] elseif k == K"inert" ex elseif k == K"gc_preserve" s = ssavar(ctx, ex) r = ssavar(ctx, ex) @ast ctx ex [K"block"; s := [K"gc_preserve_begin" (children(ex))[2:var"end"]...]; r := expand_forms_2(ctx, (children(ex))[1]); [K"gc_preserve_end" s]; r] elseif k == K"&" throw(LoweringError(ex, "invalid syntax")) elseif k == K"$" throw(LoweringError(ex, "`\$` expression outside string or quote")) elseif k == K"..." throw(LoweringError(ex, "`...` expression outside call")) elseif is_leaf(ex) ex elseif k == K"return" if numchildren(ex) == 0 @ast ctx ex [K"return" "nothing"::K"core"] elseif numchildren(ex) == 1 mapchildren((e->begin expand_forms_2(ctx, e) end), ctx, ex) else throw(LoweringError(ex, "More than one argument to return")) end else mapchildren((e->begin expand_forms_2(ctx, e) end), ctx, ex) end elseif k == K"if" || k == K"elseif" @chk numchildren(ex) >= 2 @ast ctx ex [k; expand_condition(ctx, ex[1]); expand_forms_2(ctx, ex[2:var"end"])...] elseif k == K"let" expand_forms_2(ctx, expand_let(ctx, ex)) elseif k == K"const" expand_const_decl(ctx, ex) elseif k == K"local" || k == K"global" if k == K"global" && kind(ex[1]) == K"const" expand_const_decl(ctx, @ast(ctx, ex, [K"const" [K"global" (ex[1])[1]]])) else expand_decls(ctx, ex) end elseif k == K"where" expand_forms_2(ctx, expand_wheres(ctx, ex)) elseif k == K"braces" || k == K"bracescat" throw(LoweringError(ex, "{ } syntax is reserved for future use")) elseif k == K"string" if numchildren(ex) == 1 && kind(ex[1]) == K"String" ex[1] else @ast ctx ex [K"call"; "string"::K"top"; expand_forms_2(ctx, children(ex))...] end elseif k == K"try" expand_forms_2(ctx, expand_try(ctx, ex)) elseif k == K"tuple" if has_parameters(ex) if numchildren(ex) > 1 throw(LoweringError(ex[var"end"], "unexpected semicolon in tuple - use `,` to separate tuple elements")) end expand_forms_2(ctx, expand_named_tuple(ctx, ex, children(ex[1]))) elseif any_assignment(children(ex)) expand_forms_2(ctx, expand_named_tuple(ctx, ex, children(ex))) else expand_forms_2(ctx, @ast(ctx, ex, [K"call"; "tuple"::K"core"; children(ex)...])) end elseif k == K"$" throw(LoweringError(ex, "`\$` expression outside string or quote block")) elseif k == K"module" throw(LoweringError(ex, "`module` is only allowed at top level")) elseif k == K"import" || k == K"using" expand_import_or_using(ctx, ex) elseif k == K"export" || k == K"public" expand_public(ctx, ex) elseif k == K"abstract" || k == K"primitive" expand_forms_2(ctx, expand_abstract_or_primitive_type(ctx, ex)) elseif k == K"struct" expand_forms_2(ctx, expand_struct_def(ctx, ex, docs)) elseif k == K"ref" sctx = with_stmts(ctx) (arr, idxs) = expand_ref_components(sctx, ex) expand_forms_2(ctx, @ast(ctx, ex, [K"block"; sctx.stmts...; [K"call"; "getindex"::K"top"; arr; idxs...]])) elseif k == K"curly" expand_forms_2(ctx, expand_curly(ctx, ex)) elseif k == K"toplevel" ex2 = @ast(ctx, ex, [K"block"; [K"assert" "toplevel_only"::K"Symbol" [K"inert" ex]]; [K"call"; eval::K"Value"; ctx.mod::K"Value"; [K"inert" ex]; [K"parameters"; [K"="; "expr_compat_mode"::K"Identifier"; ctx.expr_compat_mode::K"Bool"]]]]) expand_forms_2(ctx, ex2) elseif k == K"vect" check_no_parameters(ex, "unexpected semicolon in array expression") expand_array(ctx, ex, "vect") elseif k == K"hcat" expand_array(ctx, ex, "hcat") elseif k == K"typed_hcat" expand_array(ctx, ex, "typed_hcat") elseif k == K"opaque_closure" expand_forms_2(ctx, expand_opaque_closure(ctx, ex)) elseif k == K"vcat" || k == K"typed_vcat" expand_forms_2(ctx, expand_vcat(ctx, ex)) elseif k == K"ncat" || k == K"typed_ncat" expand_forms_2(ctx, expand_ncat(ctx, ex)) elseif k == K"while" @chk numchildren(ex) == 2 @ast ctx ex [K"break_block" "loop_exit"::K"symbolic_label"; [K"_while"; expand_condition(ctx, ex[1]); [K"break_block" "loop_cont"::K"symbolic_label"; [(K"scope_block")(scope_type = :neutral); expand_forms_2(ctx, ex[2])]]]] elseif k == K"inert" ex elseif k == K"gc_preserve" s = ssavar(ctx, ex) r = ssavar(ctx, ex) @ast ctx ex [K"block"; s := [K"gc_preserve_begin" (children(ex))[2:var"end"]...]; r := expand_forms_2(ctx, (children(ex))[1]); [K"gc_preserve_end" s]; r] elseif k == K"&" throw(LoweringError(ex, "invalid syntax")) elseif k == K"$" throw(LoweringError(ex, "`\$` expression outside string or quote")) elseif k == K"..." throw(LoweringError(ex, "`...` expression outside call")) elseif is_leaf(ex) ex elseif k == K"return" if numchildren(ex) == 0 @ast ctx ex [K"return" "nothing"::K"core"] elseif numchildren(ex) == 1 mapchildren((e->begin expand_forms_2(ctx, e) end), ctx, ex) else throw(LoweringError(ex, "More than one argument to return")) end else mapchildren((e->begin expand_forms_2(ctx, e) end), ctx, ex) end elseif k == K"macro" @ast ctx ex [K"block"; [K"assert"; "global_toplevel_only"::K"Symbol"; [K"inert" ex]]; expand_forms_2(ctx, expand_macro_def(ctx, ex))] elseif k == K"if" || k == K"elseif" @chk numchildren(ex) >= 2 @ast ctx ex [k; expand_condition(ctx, ex[1]); expand_forms_2(ctx, ex[2:var"end"])...] elseif k == K"let" expand_forms_2(ctx, expand_let(ctx, ex)) elseif k == K"const" expand_const_decl(ctx, ex) elseif k == K"local" || k == K"global" if k == K"global" && kind(ex[1]) == K"const" expand_const_decl(ctx, @ast(ctx, ex, [K"const" [K"global" (ex[1])[1]]])) else expand_decls(ctx, ex) end elseif k == K"where" expand_forms_2(ctx, expand_wheres(ctx, ex)) elseif k == K"braces" || k == K"bracescat" throw(LoweringError(ex, "{ } syntax is reserved for future use")) elseif k == K"string" if numchildren(ex) == 1 && kind(ex[1]) == K"String" ex[1] else @ast ctx ex [K"call"; "string"::K"top"; expand_forms_2(ctx, children(ex))...] end elseif k == K"try" expand_forms_2(ctx, expand_try(ctx, ex)) elseif k == K"tuple" if has_parameters(ex) if numchildren(ex) > 1 throw(LoweringError(ex[var"end"], "unexpected semicolon in tuple - use `,` to separate tuple elements")) end expand_forms_2(ctx, expand_named_tuple(ctx, ex, children(ex[1]))) elseif any_assignment(children(ex)) expand_forms_2(ctx, expand_named_tuple(ctx, ex, children(ex))) else expand_forms_2(ctx, @ast(ctx, ex, [K"call"; "tuple"::K"core"; children(ex)...])) end elseif k == K"$" throw(LoweringError(ex, "`\$` expression outside string or quote block")) elseif k == K"module" throw(LoweringError(ex, "`module` is only allowed at top level")) elseif k == K"import" || k == K"using" expand_import_or_using(ctx, ex) elseif k == K"export" || k == K"public" expand_public(ctx, ex) elseif k == K"abstract" || k == K"primitive" expand_forms_2(ctx, expand_abstract_or_primitive_type(ctx, ex)) elseif k == K"struct" expand_forms_2(ctx, expand_struct_def(ctx, ex, docs)) elseif k == K"ref" sctx = with_stmts(ctx) (arr, idxs) = expand_ref_components(sctx, ex) expand_forms_2(ctx, @ast(ctx, ex, [K"block"; sctx.stmts...; [K"call"; "getindex"::K"top"; arr; idxs...]])) elseif k == K"curly" expand_forms_2(ctx, expand_curly(ctx, ex)) elseif k == K"toplevel" ex2 = @ast(ctx, ex, [K"block"; [K"assert" "toplevel_only"::K"Symbol" [K"inert" ex]]; [K"call"; eval ::K"Value"; ctx.mod ::K"Value"; [K"inert" ex]; [K"parameters"; [K"="; "expr_compat_mode"::K"Identifier"; ctx.expr_compat_mode::K"Bool"]]]]) expand_forms_2(ctx, ex2) elseif k == K"vect" check_no_parameters(ex, "unexpected semicolon in array expression") expand_array(ctx, ex, "vect") elseif k == K"hcat" expand_array(ctx, ex, "hcat") elseif k == K"typed_hcat" expand_array(ctx, ex, "typed_hcat") elseif k == K"opaque_closure" expand_forms_2(ctx, expand_opaque_closure(ctx, ex)) elseif k == K"vcat" || k == K"typed_vcat" expand_forms_2(ctx, expand_vcat(ctx, ex)) elseif k == K"ncat" || k == K"typed_ncat" expand_forms_2(ctx, expand_ncat(ctx, ex)) elseif k == K"while" @chk numchildren(ex) == 2 @ast ctx ex [K"break_block" "loop_exit"::K"symbolic_label"; [K"_while"; expand_condition(ctx, ex[1]); [K"break_block" "loop_cont"::K"symbolic_label"; [(K"scope_block")(scope_type = :neutral); expand_forms_2(ctx, ex[2])]]]] elseif k == K"inert" ex elseif k == K"gc_preserve" s = ssavar(ctx, ex) r = ssavar(ctx, ex) @ast ctx ex [K"block"; s := [K"gc_preserve_begin" (children(ex))[2:var"end"]...]; r := expand_forms_2(ctx, (children(ex))[1]); [K"gc_preserve_end" s]; r] elseif k == K"&" throw(LoweringError(ex, "invalid syntax")) elseif k == K"$" throw(LoweringError(ex, "`\$` expression outside string or quote")) elseif k == K"..." throw(LoweringError(ex, "`...` expression outside call")) elseif is_leaf(ex) ex elseif k == K"return" if numchildren(ex) == 0 @ast ctx ex [K"return" "nothing"::K"core"] elseif numchildren(ex) == 1 mapchildren((e->begin expand_forms_2(ctx, e) end), ctx, ex) else throw(LoweringError(ex, "More than one argument to return")) end else mapchildren((e->begin expand_forms_2(ctx, e) end), ctx, ex) end elseif k == K"macro" @ast ctx ex [K"block"; [K"assert"; "global_toplevel_only"::K"Symbol"; [K"inert" ex]]; expand_forms_2(ctx, expand_macro_def(ctx, ex))] elseif k == K"if" || k == K"elseif" @chk numchildren(ex) >= 2 @ast ctx ex [k; expand_condition(ctx, ex[1]); expand_forms_2(ctx, ex[2:var"end"])...] elseif k == K"let" expand_forms_2(ctx, expand_let(ctx, ex)) elseif k == K"const" expand_const_decl(ctx, ex) elseif k == K"local" || k == K"global" if k == K"global" && kind(ex[1]) == K"const" expand_const_decl(ctx, @ast(ctx, ex, [K"const" [K"global" (ex[1])[1]]])) else expand_decls(ctx, ex) end elseif k == K"where" expand_forms_2(ctx, expand_wheres(ctx, ex)) elseif k == K"braces" || k == K"bracescat" throw(LoweringError(ex, "{ } syntax is reserved for future use")) elseif k == K"string" if numchildren(ex) == 1 && kind(ex[1]) == K"String" ex[1] else @ast ctx ex [K"call"; "string"::K"top"; expand_forms_2(ctx, children(ex))...] end elseif k == K"try" expand_forms_2(ctx, expand_try(ctx, ex)) elseif k == K"tuple" if has_parameters(ex) if numchildren(ex) > 1 throw(LoweringError(ex[var"end"], "unexpected semicolon in tuple - use `,` to separate tuple elements")) end expand_forms_2(ctx, expand_named_tuple(ctx, ex, children(ex[1]))) elseif any_assignment(children(ex)) expand_forms_2(ctx, expand_named_tuple(ctx, ex, children(ex))) else expand_forms_2(ctx, @ast(ctx, ex, [K"call"; "tuple"::K"core"; children(ex)...])) end elseif k == K"$" throw(LoweringError(ex, "`\$` expression outside string or quote block")) elseif k == K"module" throw(LoweringError(ex, "`module` is only allowed at top level")) elseif k == K"import" || k == K"using" expand_import_or_using(ctx, ex) elseif k == K"export" || k == K"public" expand_public(ctx, ex) elseif k == K"abstract" || k == K"primitive" expand_forms_2(ctx, expand_abstract_or_primitive_type(ctx, ex)) elseif k == K"struct" expand_forms_2(ctx, expand_struct_def(ctx, ex, docs)) elseif k == K"ref" sctx = with_stmts(ctx) (arr, idxs) = expand_ref_components(sctx, ex) expand_forms_2(ctx, @ast(ctx, ex, [K"block"; sctx.stmts...; [K"call"; "getindex"::K"top"; arr; idxs...]])) elseif k == K"curly" expand_forms_2(ctx, expand_curly(ctx, ex)) elseif k == K"toplevel" ex2 = @ast(ctx, ex, [K"block"; [K"assert" "toplevel_only"::K"Symbol" [K"inert" ex]]; [K"call"; eval::K"Value"; ctx.mod::K"Value"; [K"inert" ex]; [K"parameters"; [K"="; "expr_compat_mode"::K"Identifier"; ctx.expr_compat_mode::K"Bool"]]]]) expand_forms_2(ctx, ex2) elseif k == K"vect" check_no_parameters(ex, "unexpected semicolon in array expression") expand_array(ctx, ex, "vect") elseif k == K"hcat" expand_array(ctx, ex, "hcat") elseif k == K"typed_hcat" expand_array(ctx, ex, "typed_hcat") elseif k == K"opaque_closure" expand_forms_2(ctx, expand_opaque_closure(ctx, ex)) elseif k == K"vcat" || k == K"typed_vcat" expand_forms_2(ctx, expand_vcat(ctx, ex)) elseif k == K"ncat" || k == K"typed_ncat" expand_forms_2(ctx, expand_ncat(ctx, ex)) elseif k == K"while" @chk numchildren(ex) == 2 @ast ctx ex [K"break_block" "loop_exit"::K"symbolic_label"; [K"_while"; expand_condition(ctx, ex[1]); [K"break_block" "loop_cont"::K"symbolic_label"; [(K"scope_block")(scope_type = :neutral); expand_forms_2(ctx, ex[2])]]]] elseif k == K"inert" ex elseif k == K"gc_preserve" s = ssavar(ctx, ex) r = ssavar(ctx, ex) @ast ctx ex [K"block"; s := [K"gc_preserve_begin" (children(ex))[2:var"end"]...]; r := expand_forms_2(ctx, (children(ex))[1]); [K"gc_preserve_end" s]; r] elseif k == K"&" throw(LoweringError(ex, "invalid syntax")) elseif k == K"$" throw(LoweringError(ex, "`\$` expression outside string or quote")) elseif k == K"..." throw(LoweringError(ex, "`...` expression outside call")) elseif is_leaf(ex) ex elseif k == K"return" if numchildren(ex) == 0 @ast ctx ex [K"return" "nothing"::K"core"] elseif numchildren(ex) == 1 mapchildren((e->begin expand_forms_2(ctx, e) end), ctx, ex) else throw(LoweringError(ex, "More than one argument to return")) end else mapchildren((e->begin expand_forms_2(ctx, e) end), ctx, ex) end elseif k == K"function" expand_forms_2(ctx, expand_function_def(ctx, ex, docs)) elseif k == K"macro" @ast ctx ex [K"block"; [K"assert"; "global_toplevel_only"::K"Symbol"; [K"inert" ex]]; expand_forms_2(ctx, expand_macro_def(ctx, ex))] elseif k == K"if" || k == K"elseif" @chk numchildren(ex) >= 2 @ast ctx ex [k; expand_condition(ctx, ex[1]); expand_forms_2(ctx, ex[2:var"end"])...] elseif k == K"let" expand_forms_2(ctx, expand_let(ctx, ex)) elseif k == K"const" expand_const_decl(ctx, ex) elseif k == K"local" || k == K"global" if k == K"global" && kind(ex[1]) == K"const" expand_const_decl(ctx, @ast(ctx, ex, [K"const" [K"global" (ex[1])[1]]])) else expand_decls(ctx, ex) end elseif k == K"where" expand_forms_2(ctx, expand_wheres(ctx, ex)) elseif k == K"braces" || k == K"bracescat" throw(LoweringError(ex, "{ } syntax is reserved for future use")) elseif k == K"string" if numchildren(ex) == 1 && kind(ex[1]) == K"String" ex[1] else @ast ctx ex [K"call"; "string"::K"top"; expand_forms_2(ctx, children(ex))...] end elseif k == K"try" expand_forms_2(ctx, expand_try(ctx, ex)) elseif k == K"tuple" if has_parameters(ex) if numchildren(ex) > 1 throw(LoweringError(ex[var"end"], "unexpected semicolon in tuple - use `,` to separate tuple elements")) end expand_forms_2(ctx, expand_named_tuple(ctx, ex, children(ex[1]))) elseif any_assignment(children(ex)) expand_forms_2(ctx, expand_named_tuple(ctx, ex, children(ex))) else expand_forms_2(ctx, @ast(ctx, ex, [K"call"; "tuple"::K"core"; children(ex)...])) end elseif k == K"$" throw(LoweringError(ex, "`\$` expression outside string or quote block")) elseif k == K"module" throw(LoweringError(ex, "`module` is only allowed at top level")) elseif k == K"import" || k == K"using" expand_import_or_using(ctx, ex) elseif k == K"export" || k == K"public" expand_public(ctx, ex) elseif k == K"abstract" || k == K"primitive" expand_forms_2(ctx, expand_abstract_or_primitive_type(ctx, ex)) elseif k == K"struct" expand_forms_2(ctx, expand_struct_def(ctx, ex, docs)) elseif k == K"ref" sctx = with_stmts(ctx) (arr, idxs) = expand_ref_components(sctx, ex) expand_forms_2(ctx, @ast(ctx, ex, [K"block"; sctx.stmts...; [K"call"; "getindex"::K"top"; arr; idxs...]])) elseif k == K"curly" expand_forms_2(ctx, expand_curly(ctx, ex)) elseif k == K"toplevel" ex2 = @ast(ctx, ex, [K"block"; [K"assert" "toplevel_only"::K"Symbol" [K"inert" ex]]; [K"call"; eval ::K"Value"; ctx.mod ::K"Value"; [K"inert" ex]; [K"parameters"; [K"="; "expr_compat_mode"::K"Identifier"; ctx.expr_compat_mode::K"Bool"]]]]) expand_forms_2(ctx, ex2) elseif k == K"vect" check_no_parameters(ex, "unexpected semicolon in array expression") expand_array(ctx, ex, "vect") elseif k == K"hcat" expand_array(ctx, ex, "hcat") elseif k == K"typed_hcat" expand_array(ctx, ex, "typed_hcat") elseif k == K"opaque_closure" expand_forms_2(ctx, expand_opaque_closure(ctx, ex)) elseif k == K"vcat" || k == K"typed_vcat" expand_forms_2(ctx, expand_vcat(ctx, ex)) elseif k == K"ncat" || k == K"typed_ncat" expand_forms_2(ctx, expand_ncat(ctx, ex)) elseif k == K"while" @chk numchildren(ex) == 2 @ast ctx ex [K"break_block" "loop_exit"::K"symbolic_label"; [K"_while"; expand_condition(ctx, ex[1]); [K"break_block" "loop_cont"::K"symbolic_label"; [(K"scope_block")(scope_type = :neutral); expand_forms_2(ctx, ex[2])]]]] elseif k == K"inert" ex elseif k == K"gc_preserve" s = ssavar(ctx, ex) r = ssavar(ctx, ex) @ast ctx ex [K"block"; s := [K"gc_preserve_begin" (children(ex))[2:var"end"]...]; r := expand_forms_2(ctx, (children(ex))[1]); [K"gc_preserve_end" s]; r] elseif k == K"&" throw(LoweringError(ex, "invalid syntax")) elseif k == K"$" throw(LoweringError(ex, "`\$` expression outside string or quote")) elseif k == K"..." throw(LoweringError(ex, "`...` expression outside call")) elseif is_leaf(ex) ex elseif k == K"return" if numchildren(ex) == 0 @ast ctx ex [K"return" "nothing"::K"core"] elseif numchildren(ex) == 1 mapchildren((e->begin expand_forms_2(ctx, e) end), ctx, ex) else throw(LoweringError(ex, "More than one argument to return")) end else mapchildren((e->begin expand_forms_2(ctx, e) end), ctx, ex) end elseif k == K"function" expand_forms_2(ctx, expand_function_def(ctx, ex, docs)) elseif k == K"macro" @ast ctx ex [K"block"; [K"assert"; "global_toplevel_only"::K"Symbol"; [K"inert" ex]]; expand_forms_2(ctx, expand_macro_def(ctx, ex))] elseif k == K"if" || k == K"elseif" @chk numchildren(ex) >= 2 @ast ctx ex [k; expand_condition(ctx, ex[1]); expand_forms_2(ctx, ex[2:var"end"])...] elseif k == K"let" expand_forms_2(ctx, expand_let(ctx, ex)) elseif k == K"const" expand_const_decl(ctx, ex) elseif k == K"local" || k == K"global" if k == K"global" && kind(ex[1]) == K"const" expand_const_decl(ctx, @ast(ctx, ex, [K"const" [K"global" (ex[1])[1]]])) else expand_decls(ctx, ex) end elseif k == K"where" expand_forms_2(ctx, expand_wheres(ctx, ex)) elseif k == K"braces" || k == K"bracescat" throw(LoweringError(ex, "{ } syntax is reserved for future use")) elseif k == K"string" if numchildren(ex) == 1 && kind(ex[1]) == K"String" ex[1] else @ast ctx ex [K"call"; "string"::K"top"; expand_forms_2(ctx, children(ex))...] end elseif k == K"try" expand_forms_2(ctx, expand_try(ctx, ex)) elseif k == K"tuple" if has_parameters(ex) if numchildren(ex) > 1 throw(LoweringError(ex[var"end"], "unexpected semicolon in tuple - use `,` to separate tuple elements")) end expand_forms_2(ctx, expand_named_tuple(ctx, ex, children(ex[1]))) elseif any_assignment(children(ex)) expand_forms_2(ctx, expand_named_tuple(ctx, ex, children(ex))) else expand_forms_2(ctx, @ast(ctx, ex, [K"call"; "tuple"::K"core"; children(ex)...])) end elseif k == K"$" throw(LoweringError(ex, "`\$` expression outside string or quote block")) elseif k == K"module" throw(LoweringError(ex, "`module` is only allowed at top level")) elseif k == K"import" || k == K"using" expand_import_or_using(ctx, ex) elseif k == K"export" || k == K"public" expand_public(ctx, ex) elseif k == K"abstract" || k == K"primitive" expand_forms_2(ctx, expand_abstract_or_primitive_type(ctx, ex)) elseif k == K"struct" expand_forms_2(ctx, expand_struct_def(ctx, ex, docs)) elseif k == K"ref" sctx = with_stmts(ctx) (arr, idxs) = expand_ref_components(sctx, ex) expand_forms_2(ctx, @ast(ctx, ex, [K"block"; sctx.stmts...; [K"call"; "getindex"::K"top"; arr; idxs...]])) elseif k == K"curly" expand_forms_2(ctx, expand_curly(ctx, ex)) elseif k == K"toplevel" ex2 = @ast(ctx, ex, [K"block"; [K"assert" "toplevel_only"::K"Symbol" [K"inert" ex]]; [K"call"; eval::K"Value"; ctx.mod::K"Value"; [K"inert" ex]; [K"parameters"; [K"="; "expr_compat_mode"::K"Identifier"; ctx.expr_compat_mode::K"Bool"]]]]) expand_forms_2(ctx, ex2) elseif k == K"vect" check_no_parameters(ex, "unexpected semicolon in array expression") expand_array(ctx, ex, "vect") elseif k == K"hcat" expand_array(ctx, ex, "hcat") elseif k == K"typed_hcat" expand_array(ctx, ex, "typed_hcat") elseif k == K"opaque_closure" expand_forms_2(ctx, expand_opaque_closure(ctx, ex)) elseif k == K"vcat" || k == K"typed_vcat" expand_forms_2(ctx, expand_vcat(ctx, ex)) elseif k == K"ncat" || k == K"typed_ncat" expand_forms_2(ctx, expand_ncat(ctx, ex)) elseif k == K"while" @chk numchildren(ex) == 2 @ast ctx ex [K"break_block" "loop_exit"::K"symbolic_label"; [K"_while"; expand_condition(ctx, ex[1]); [K"break_block" "loop_cont"::K"symbolic_label"; [(K"scope_block")(scope_type = :neutral); expand_forms_2(ctx, ex[2])]]]] elseif k == K"inert" ex elseif k == K"gc_preserve" s = ssavar(ctx, ex) r = ssavar(ctx, ex) @ast ctx ex [K"block"; s := [K"gc_preserve_begin" (children(ex))[2:var"end"]...]; r := expand_forms_2(ctx, (children(ex))[1]); [K"gc_preserve_end" s]; r] elseif k == K"&" throw(LoweringError(ex, "invalid syntax")) elseif k == K"$" throw(LoweringError(ex, "`\$` expression outside string or quote")) elseif k == K"..." throw(LoweringError(ex, "`...` expression outside call")) elseif is_leaf(ex) ex elseif k == K"return" if numchildren(ex) == 0 @ast ctx ex [K"return" "nothing"::K"core"] elseif numchildren(ex) == 1 mapchildren((e->begin expand_forms_2(ctx, e) end), ctx, ex) else throw(LoweringError(ex, "More than one argument to return")) end else mapchildren((e->begin expand_forms_2(ctx, e) end), ctx, ex) end elseif k == K"->" || k == K"do" expand_forms_2(ctx, expand_arrow(ctx, ex)) elseif k == K"function" expand_forms_2(ctx, expand_function_def(ctx, ex, docs)) elseif k == K"macro" @ast ctx ex [K"block"; [K"assert"; "global_toplevel_only"::K"Symbol"; [K"inert" ex]]; expand_forms_2(ctx, expand_macro_def(ctx, ex))] elseif k == K"if" || k == K"elseif" @chk numchildren(ex) >= 2 @ast ctx ex [k; expand_condition(ctx, ex[1]); expand_forms_2(ctx, ex[2:var"end"])...] elseif k == K"let" expand_forms_2(ctx, expand_let(ctx, ex)) elseif k == K"const" expand_const_decl(ctx, ex) elseif k == K"local" || k == K"global" if k == K"global" && kind(ex[1]) == K"const" expand_const_decl(ctx, @ast(ctx, ex, [K"const" [K"global" (ex[1])[1]]])) else expand_decls(ctx, ex) end elseif k == K"where" expand_forms_2(ctx, expand_wheres(ctx, ex)) elseif k == K"braces" || k == K"bracescat" throw(LoweringError(ex, "{ } syntax is reserved for future use")) elseif k == K"string" if numchildren(ex) == 1 && kind(ex[1]) == K"String" ex[1] else @ast ctx ex [K"call"; "string"::K"top"; expand_forms_2(ctx, children(ex))...] end elseif k == K"try" expand_forms_2(ctx, expand_try(ctx, ex)) elseif k == K"tuple" if has_parameters(ex) if numchildren(ex) > 1 throw(LoweringError(ex[var"end"], "unexpected semicolon in tuple - use `,` to separate tuple elements")) end expand_forms_2(ctx, expand_named_tuple(ctx, ex, children(ex[1]))) elseif any_assignment(children(ex)) expand_forms_2(ctx, expand_named_tuple(ctx, ex, children(ex))) else expand_forms_2(ctx, @ast(ctx, ex, [K"call"; "tuple"::K"core"; children(ex)...])) end elseif k == K"$" throw(LoweringError(ex, "`\$` expression outside string or quote block")) elseif k == K"module" throw(LoweringError(ex, "`module` is only allowed at top level")) elseif k == K"import" || k == K"using" expand_import_or_using(ctx, ex) elseif k == K"export" || k == K"public" expand_public(ctx, ex) elseif k == K"abstract" || k == K"primitive" expand_forms_2(ctx, expand_abstract_or_primitive_type(ctx, ex)) elseif k == K"struct" expand_forms_2(ctx, expand_struct_def(ctx, ex, docs)) elseif k == K"ref" sctx = with_stmts(ctx) (arr, idxs) = expand_ref_components(sctx, ex) expand_forms_2(ctx, @ast(ctx, ex, [K"block"; sctx.stmts...; [K"call"; "getindex"::K"top"; arr; idxs...]])) elseif k == K"curly" expand_forms_2(ctx, expand_curly(ctx, ex)) elseif k == K"toplevel" ex2 = @ast(ctx, ex, [K"block"; [K"assert" "toplevel_only"::K"Symbol" [K"inert" ex]]; [K"call"; eval ::K"Value"; ctx.mod ::K"Value"; [K"inert" ex]; [K"parameters"; [K"="; "expr_compat_mode"::K"Identifier"; ctx.expr_compat_mode::K"Bool"]]]]) expand_forms_2(ctx, ex2) elseif k == K"vect" check_no_parameters(ex, "unexpected semicolon in array expression") expand_array(ctx, ex, "vect") elseif k == K"hcat" expand_array(ctx, ex, "hcat") elseif k == K"typed_hcat" expand_array(ctx, ex, "typed_hcat") elseif k == K"opaque_closure" expand_forms_2(ctx, expand_opaque_closure(ctx, ex)) elseif k == K"vcat" || k == K"typed_vcat" expand_forms_2(ctx, expand_vcat(ctx, ex)) elseif k == K"ncat" || k == K"typed_ncat" expand_forms_2(ctx, expand_ncat(ctx, ex)) elseif k == K"while" @chk numchildren(ex) == 2 @ast ctx ex [K"break_block" "loop_exit"::K"symbolic_label"; [K"_while"; expand_condition(ctx, ex[1]); [K"break_block" "loop_cont"::K"symbolic_label"; [(K"scope_block")(scope_type = :neutral); expand_forms_2(ctx, ex[2])]]]] elseif k == K"inert" ex elseif k == K"gc_preserve" s = ssavar(ctx, ex) r = ssavar(ctx, ex) @ast ctx ex [K"block"; s := [K"gc_preserve_begin" (children(ex))[2:var"end"]...]; r := expand_forms_2(ctx, (children(ex))[1]); [K"gc_preserve_end" s]; r] elseif k == K"&" throw(LoweringError(ex, "invalid syntax")) elseif k == K"$" throw(LoweringError(ex, "`\$` expression outside string or quote")) elseif k == K"..." throw(LoweringError(ex, "`...` expression outside call")) elseif is_leaf(ex) ex elseif k == K"return" if numchildren(ex) == 0 @ast ctx ex [K"return" "nothing"::K"core"] elseif numchildren(ex) == 1 mapchildren((e->begin expand_forms_2(ctx, e) end), ctx, ex) else throw(LoweringError(ex, "More than one argument to return")) end else mapchildren((e->begin expand_forms_2(ctx, e) end), ctx, ex) end elseif k == K"->" || k == K"do" expand_forms_2(ctx, expand_arrow(ctx, ex)) elseif k == K"function" expand_forms_2(ctx, expand_function_def(ctx, ex, docs)) elseif k == K"macro" @ast ctx ex [K"block"; [K"assert"; "global_toplevel_only"::K"Symbol"; [K"inert" ex]]; expand_forms_2(ctx, expand_macro_def(ctx, ex))] elseif k == K"if" || k == K"elseif" @chk numchildren(ex) >= 2 @ast ctx ex [k; expand_condition(ctx, ex[1]); expand_forms_2(ctx, ex[2:var"end"])...] elseif k == K"let" expand_forms_2(ctx, expand_let(ctx, ex)) elseif k == K"const" expand_const_decl(ctx, ex) elseif k == K"local" || k == K"global" if k == K"global" && kind(ex[1]) == K"const" expand_const_decl(ctx, @ast(ctx, ex, [K"const" [K"global" (ex[1])[1]]])) else expand_decls(ctx, ex) end elseif k == K"where" expand_forms_2(ctx, expand_wheres(ctx, ex)) elseif k == K"braces" || k == K"bracescat" throw(LoweringError(ex, "{ } syntax is reserved for future use")) elseif k == K"string" if numchildren(ex) == 1 && kind(ex[1]) == K"String" ex[1] else @ast ctx ex [K"call"; "string"::K"top"; expand_forms_2(ctx, children(ex))...] end elseif k == K"try" expand_forms_2(ctx, expand_try(ctx, ex)) elseif k == K"tuple" if has_parameters(ex) if numchildren(ex) > 1 throw(LoweringError(ex[var"end"], "unexpected semicolon in tuple - use `,` to separate tuple elements")) end expand_forms_2(ctx, expand_named_tuple(ctx, ex, children(ex[1]))) elseif any_assignment(children(ex)) expand_forms_2(ctx, expand_named_tuple(ctx, ex, children(ex))) else expand_forms_2(ctx, @ast(ctx, ex, [K"call"; "tuple"::K"core"; children(ex)...])) end elseif k == K"$" throw(LoweringError(ex, "`\$` expression outside string or quote block")) elseif k == K"module" throw(LoweringError(ex, "`module` is only allowed at top level")) elseif k == K"import" || k == K"using" expand_import_or_using(ctx, ex) elseif k == K"export" || k == K"public" expand_public(ctx, ex) elseif k == K"abstract" || k == K"primitive" expand_forms_2(ctx, expand_abstract_or_primitive_type(ctx, ex)) elseif k == K"struct" expand_forms_2(ctx, expand_struct_def(ctx, ex, docs)) elseif k == K"ref" sctx = with_stmts(ctx) (arr, idxs) = expand_ref_components(sctx, ex) expand_forms_2(ctx, @ast(ctx, ex, [K"block"; sctx.stmts...; [K"call"; "getindex"::K"top"; arr; idxs...]])) elseif k == K"curly" expand_forms_2(ctx, expand_curly(ctx, ex)) elseif k == K"toplevel" ex2 = @ast(ctx, ex, [K"block"; [K"assert" "toplevel_only"::K"Symbol" [K"inert" ex]]; [K"call"; eval::K"Value"; ctx.mod::K"Value"; [K"inert" ex]; [K"parameters"; [K"="; "expr_compat_mode"::K"Identifier"; ctx.expr_compat_mode::K"Bool"]]]]) expand_forms_2(ctx, ex2) elseif k == K"vect" check_no_parameters(ex, "unexpected semicolon in array expression") expand_array(ctx, ex, "vect") elseif k == K"hcat" expand_array(ctx, ex, "hcat") elseif k == K"typed_hcat" expand_array(ctx, ex, "typed_hcat") elseif k == K"opaque_closure" expand_forms_2(ctx, expand_opaque_closure(ctx, ex)) elseif k == K"vcat" || k == K"typed_vcat" expand_forms_2(ctx, expand_vcat(ctx, ex)) elseif k == K"ncat" || k == K"typed_ncat" expand_forms_2(ctx, expand_ncat(ctx, ex)) elseif k == K"while" @chk numchildren(ex) == 2 @ast ctx ex [K"break_block" "loop_exit"::K"symbolic_label"; [K"_while"; expand_condition(ctx, ex[1]); [K"break_block" "loop_cont"::K"symbolic_label"; [(K"scope_block")(scope_type = :neutral); expand_forms_2(ctx, ex[2])]]]] elseif k == K"inert" ex elseif k == K"gc_preserve" s = ssavar(ctx, ex) r = ssavar(ctx, ex) @ast ctx ex [K"block"; s := [K"gc_preserve_begin" (children(ex))[2:var"end"]...]; r := expand_forms_2(ctx, (children(ex))[1]); [K"gc_preserve_end" s]; r] elseif k == K"&" throw(LoweringError(ex, "invalid syntax")) elseif k == K"$" throw(LoweringError(ex, "`\$` expression outside string or quote")) elseif k == K"..." throw(LoweringError(ex, "`...` expression outside call")) elseif is_leaf(ex) ex elseif k == K"return" if numchildren(ex) == 0 @ast ctx ex [K"return" "nothing"::K"core"] elseif numchildren(ex) == 1 mapchildren((e->begin expand_forms_2(ctx, e) end), ctx, ex) else throw(LoweringError(ex, "More than one argument to return")) end else mapchildren((e->begin expand_forms_2(ctx, e) end), ctx, ex) end elseif k == K"generator" expand_forms_2(ctx, expand_generator(ctx, ex)) elseif k == K"->" || k == K"do" expand_forms_2(ctx, expand_arrow(ctx, ex)) elseif k == K"function" expand_forms_2(ctx, expand_function_def(ctx, ex, docs)) elseif k == K"macro" @ast ctx ex [K"block"; [K"assert"; "global_toplevel_only"::K"Symbol"; [K"inert" ex]]; expand_forms_2(ctx, expand_macro_def(ctx, ex))] elseif k == K"if" || k == K"elseif" @chk numchildren(ex) >= 2 @ast ctx ex [k; expand_condition(ctx, ex[1]); expand_forms_2(ctx, ex[2:var"end"])...] elseif k == K"let" expand_forms_2(ctx, expand_let(ctx, ex)) elseif k == K"const" expand_const_decl(ctx, ex) elseif k == K"local" || k == K"global" if k == K"global" && kind(ex[1]) == K"const" expand_const_decl(ctx, @ast(ctx, ex, [K"const" [K"global" (ex[1])[1]]])) else expand_decls(ctx, ex) end elseif k == K"where" expand_forms_2(ctx, expand_wheres(ctx, ex)) elseif k == K"braces" || k == K"bracescat" throw(LoweringError(ex, "{ } syntax is reserved for future use")) elseif k == K"string" if numchildren(ex) == 1 && kind(ex[1]) == K"String" ex[1] else @ast ctx ex [K"call"; "string"::K"top"; expand_forms_2(ctx, children(ex))...] end elseif k == K"try" expand_forms_2(ctx, expand_try(ctx, ex)) elseif k == K"tuple" if has_parameters(ex) if numchildren(ex) > 1 throw(LoweringError(ex[var"end"], "unexpected semicolon in tuple - use `,` to separate tuple elements")) end expand_forms_2(ctx, expand_named_tuple(ctx, ex, children(ex[1]))) elseif any_assignment(children(ex)) expand_forms_2(ctx, expand_named_tuple(ctx, ex, children(ex))) else expand_forms_2(ctx, @ast(ctx, ex, [K"call"; "tuple"::K"core"; children(ex)...])) end elseif k == K"$" throw(LoweringError(ex, "`\$` expression outside string or quote block")) elseif k == K"module" throw(LoweringError(ex, "`module` is only allowed at top level")) elseif k == K"import" || k == K"using" expand_import_or_using(ctx, ex) elseif k == K"export" || k == K"public" expand_public(ctx, ex) elseif k == K"abstract" || k == K"primitive" expand_forms_2(ctx, expand_abstract_or_primitive_type(ctx, ex)) elseif k == K"struct" expand_forms_2(ctx, expand_struct_def(ctx, ex, docs)) elseif k == K"ref" sctx = with_stmts(ctx) (arr, idxs) = expand_ref_components(sctx, ex) expand_forms_2(ctx, @ast(ctx, ex, [K"block"; sctx.stmts...; [K"call"; "getindex"::K"top"; arr; idxs...]])) elseif k == K"curly" expand_forms_2(ctx, expand_curly(ctx, ex)) elseif k == K"toplevel" ex2 = @ast(ctx, ex, [K"block"; [K"assert" "toplevel_only"::K"Symbol" [K"inert" ex]]; [K"call"; eval ::K"Value"; ctx.mod ::K"Value"; [K"inert" ex]; [K"parameters"; [K"="; "expr_compat_mode"::K"Identifier"; ctx.expr_compat_mode::K"Bool"]]]]) expand_forms_2(ctx, ex2) elseif k == K"vect" check_no_parameters(ex, "unexpected semicolon in array expression") expand_array(ctx, ex, "vect") elseif k == K"hcat" expand_array(ctx, ex, "hcat") elseif k == K"typed_hcat" expand_array(ctx, ex, "typed_hcat") elseif k == K"opaque_closure" expand_forms_2(ctx, expand_opaque_closure(ctx, ex)) elseif k == K"vcat" || k == K"typed_vcat" expand_forms_2(ctx, expand_vcat(ctx, ex)) elseif k == K"ncat" || k == K"typed_ncat" expand_forms_2(ctx, expand_ncat(ctx, ex)) elseif k == K"while" @chk numchildren(ex) == 2 @ast ctx ex [K"break_block" "loop_exit"::K"symbolic_label"; [K"_while"; expand_condition(ctx, ex[1]); [K"break_block" "loop_cont"::K"symbolic_label"; [(K"scope_block")(scope_type = :neutral); expand_forms_2(ctx, ex[2])]]]] elseif k == K"inert" ex elseif k == K"gc_preserve" s = ssavar(ctx, ex) r = ssavar(ctx, ex) @ast ctx ex [K"block"; s := [K"gc_preserve_begin" (children(ex))[2:var"end"]...]; r := expand_forms_2(ctx, (children(ex))[1]); [K"gc_preserve_end" s]; r] elseif k == K"&" throw(LoweringError(ex, "invalid syntax")) elseif k == K"$" throw(LoweringError(ex, "`\$` expression outside string or quote")) elseif k == K"..." throw(LoweringError(ex, "`...` expression outside call")) elseif is_leaf(ex) ex elseif k == K"return" if numchildren(ex) == 0 @ast ctx ex [K"return" "nothing"::K"core"] elseif numchildren(ex) == 1 mapchildren((e->begin expand_forms_2(ctx, e) end), ctx, ex) else throw(LoweringError(ex, "More than one argument to return")) end else mapchildren((e->begin expand_forms_2(ctx, e) end), ctx, ex) end elseif k == K"generator" expand_forms_2(ctx, expand_generator(ctx, ex)) elseif k == K"->" || k == K"do" expand_forms_2(ctx, expand_arrow(ctx, ex)) elseif k == K"function" expand_forms_2(ctx, expand_function_def(ctx, ex, docs)) elseif k == K"macro" @ast ctx ex [K"block"; [K"assert"; "global_toplevel_only"::K"Symbol"; [K"inert" ex]]; expand_forms_2(ctx, expand_macro_def(ctx, ex))] elseif k == K"if" || k == K"elseif" @chk numchildren(ex) >= 2 @ast ctx ex [k; expand_condition(ctx, ex[1]); expand_forms_2(ctx, ex[2:var"end"])...] elseif k == K"let" expand_forms_2(ctx, expand_let(ctx, ex)) elseif k == K"const" expand_const_decl(ctx, ex) elseif k == K"local" || k == K"global" if k == K"global" && kind(ex[1]) == K"const" expand_const_decl(ctx, @ast(ctx, ex, [K"const" [K"global" (ex[1])[1]]])) else expand_decls(ctx, ex) end elseif k == K"where" expand_forms_2(ctx, expand_wheres(ctx, ex)) elseif k == K"braces" || k == K"bracescat" throw(LoweringError(ex, "{ } syntax is reserved for future use")) elseif k == K"string" if numchildren(ex) == 1 && kind(ex[1]) == K"String" ex[1] else @ast ctx ex [K"call"; "string"::K"top"; expand_forms_2(ctx, children(ex))...] end elseif k == K"try" expand_forms_2(ctx, expand_try(ctx, ex)) elseif k == K"tuple" if has_parameters(ex) if numchildren(ex) > 1 throw(LoweringError(ex[var"end"], "unexpected semicolon in tuple - use `,` to separate tuple elements")) end expand_forms_2(ctx, expand_named_tuple(ctx, ex, children(ex[1]))) elseif any_assignment(children(ex)) expand_forms_2(ctx, expand_named_tuple(ctx, ex, children(ex))) else expand_forms_2(ctx, @ast(ctx, ex, [K"call"; "tuple"::K"core"; children(ex)...])) end elseif k == K"$" throw(LoweringError(ex, "`\$` expression outside string or quote block")) elseif k == K"module" throw(LoweringError(ex, "`module` is only allowed at top level")) elseif k == K"import" || k == K"using" expand_import_or_using(ctx, ex) elseif k == K"export" || k == K"public" expand_public(ctx, ex) elseif k == K"abstract" || k == K"primitive" expand_forms_2(ctx, expand_abstract_or_primitive_type(ctx, ex)) elseif k == K"struct" expand_forms_2(ctx, expand_struct_def(ctx, ex, docs)) elseif k == K"ref" sctx = with_stmts(ctx) (arr, idxs) = expand_ref_components(sctx, ex) expand_forms_2(ctx, @ast(ctx, ex, [K"block"; sctx.stmts...; [K"call"; "getindex"::K"top"; arr; idxs...]])) elseif k == K"curly" expand_forms_2(ctx, expand_curly(ctx, ex)) elseif k == K"toplevel" ex2 = @ast(ctx, ex, [K"block"; [K"assert" "toplevel_only"::K"Symbol" [K"inert" ex]]; [K"call"; eval::K"Value"; ctx.mod::K"Value"; [K"inert" ex]; [K"parameters"; [K"="; "expr_compat_mode"::K"Identifier"; ctx.expr_compat_mode::K"Bool"]]]]) expand_forms_2(ctx, ex2) elseif k == K"vect" check_no_parameters(ex, "unexpected semicolon in array expression") expand_array(ctx, ex, "vect") elseif k == K"hcat" expand_array(ctx, ex, "hcat") elseif k == K"typed_hcat" expand_array(ctx, ex, "typed_hcat") elseif k == K"opaque_closure" expand_forms_2(ctx, expand_opaque_closure(ctx, ex)) elseif k == K"vcat" || k == K"typed_vcat" expand_forms_2(ctx, expand_vcat(ctx, ex)) elseif k == K"ncat" || k == K"typed_ncat" expand_forms_2(ctx, expand_ncat(ctx, ex)) elseif k == K"while" @chk numchildren(ex) == 2 @ast ctx ex [K"break_block" "loop_exit"::K"symbolic_label"; [K"_while"; expand_condition(ctx, ex[1]); [K"break_block" "loop_cont"::K"symbolic_label"; [(K"scope_block")(scope_type = :neutral); expand_forms_2(ctx, ex[2])]]]] elseif k == K"inert" ex elseif k == K"gc_preserve" s = ssavar(ctx, ex) r = ssavar(ctx, ex) @ast ctx ex [K"block"; s := [K"gc_preserve_begin" (children(ex))[2:var"end"]...]; r := expand_forms_2(ctx, (children(ex))[1]); [K"gc_preserve_end" s]; r] elseif k == K"&" throw(LoweringError(ex, "invalid syntax")) elseif k == K"$" throw(LoweringError(ex, "`\$` expression outside string or quote")) elseif k == K"..." throw(LoweringError(ex, "`...` expression outside call")) elseif is_leaf(ex) ex elseif k == K"return" if numchildren(ex) == 0 @ast ctx ex [K"return" "nothing"::K"core"] elseif numchildren(ex) == 1 mapchildren((e->begin expand_forms_2(ctx, e) end), ctx, ex) else throw(LoweringError(ex, "More than one argument to return")) end else mapchildren((e->begin expand_forms_2(ctx, e) end), ctx, ex) end elseif k == K"typed_comprehension" @chk numchildren(ex) == 2 @chk kind(ex[2]) == K"generator" if numchildren(ex[2]) == 2 && kind((ex[2])[2]) == K"iteration" expand_forms_2(ctx, expand_comprehension_to_loops(ctx, ex)) else @ast ctx ex [K"call"; "collect"::K"top"; expand_forms_2(ctx, ex[1]); expand_forms_2(ctx, ex[2])] end elseif k == K"generator" expand_forms_2(ctx, expand_generator(ctx, ex)) elseif k == K"->" || k == K"do" expand_forms_2(ctx, expand_arrow(ctx, ex)) elseif k == K"function" expand_forms_2(ctx, expand_function_def(ctx, ex, docs)) elseif k == K"macro" @ast ctx ex [K"block"; [K"assert"; "global_toplevel_only"::K"Symbol"; [K"inert" ex]]; expand_forms_2(ctx, expand_macro_def(ctx, ex))] elseif k == K"if" || k == K"elseif" @chk numchildren(ex) >= 2 @ast ctx ex [k; expand_condition(ctx, ex[1]); expand_forms_2(ctx, ex[2:var"end"])...] elseif k == K"let" expand_forms_2(ctx, expand_let(ctx, ex)) elseif k == K"const" expand_const_decl(ctx, ex) elseif k == K"local" || k == K"global" if k == K"global" && kind(ex[1]) == K"const" expand_const_decl(ctx, @ast(ctx, ex, [K"const" [K"global" (ex[1])[1]]])) else expand_decls(ctx, ex) end elseif k == K"where" expand_forms_2(ctx, expand_wheres(ctx, ex)) elseif k == K"braces" || k == K"bracescat" throw(LoweringError(ex, "{ } syntax is reserved for future use")) elseif k == K"string" if numchildren(ex) == 1 && kind(ex[1]) == K"String" ex[1] else @ast ctx ex [K"call"; "string"::K"top"; expand_forms_2(ctx, children(ex))...] end elseif k == K"try" expand_forms_2(ctx, expand_try(ctx, ex)) elseif k == K"tuple" if has_parameters(ex) if numchildren(ex) > 1 throw(LoweringError(ex[var"end"], "unexpected semicolon in tuple - use `,` to separate tuple elements")) end expand_forms_2(ctx, expand_named_tuple(ctx, ex, children(ex[1]))) elseif any_assignment(children(ex)) expand_forms_2(ctx, expand_named_tuple(ctx, ex, children(ex))) else expand_forms_2(ctx, @ast(ctx, ex, [K"call"; "tuple"::K"core"; children(ex)...])) end elseif k == K"$" throw(LoweringError(ex, "`\$` expression outside string or quote block")) elseif k == K"module" throw(LoweringError(ex, "`module` is only allowed at top level")) elseif k == K"import" || k == K"using" expand_import_or_using(ctx, ex) elseif k == K"export" || k == K"public" expand_public(ctx, ex) elseif k == K"abstract" || k == K"primitive" expand_forms_2(ctx, expand_abstract_or_primitive_type(ctx, ex)) elseif k == K"struct" expand_forms_2(ctx, expand_struct_def(ctx, ex, docs)) elseif k == K"ref" sctx = with_stmts(ctx) (arr, idxs) = expand_ref_components(sctx, ex) expand_forms_2(ctx, @ast(ctx, ex, [K"block"; sctx.stmts...; [K"call"; "getindex"::K"top"; arr; idxs...]])) elseif k == K"curly" expand_forms_2(ctx, expand_curly(ctx, ex)) elseif k == K"toplevel" ex2 = @ast(ctx, ex, [K"block"; [K"assert" "toplevel_only"::K"Symbol" [K"inert" ex]]; [K"call"; eval ::K"Value"; ctx.mod ::K"Value"; [K"inert" ex]; [K"parameters"; [K"="; "expr_compat_mode"::K"Identifier"; ctx.expr_compat_mode::K"Bool"]]]]) expand_forms_2(ctx, ex2) elseif k == K"vect" check_no_parameters(ex, "unexpected semicolon in array expression") expand_array(ctx, ex, "vect") elseif k == K"hcat" expand_array(ctx, ex, "hcat") elseif k == K"typed_hcat" expand_array(ctx, ex, "typed_hcat") elseif k == K"opaque_closure" expand_forms_2(ctx, expand_opaque_closure(ctx, ex)) elseif k == K"vcat" || k == K"typed_vcat" expand_forms_2(ctx, expand_vcat(ctx, ex)) elseif k == K"ncat" || k == K"typed_ncat" expand_forms_2(ctx, expand_ncat(ctx, ex)) elseif k == K"while" @chk numchildren(ex) == 2 @ast ctx ex [K"break_block" "loop_exit"::K"symbolic_label"; [K"_while"; expand_condition(ctx, ex[1]); [K"break_block" "loop_cont"::K"symbolic_label"; [(K"scope_block")(scope_type = :neutral); expand_forms_2(ctx, ex[2])]]]] elseif k == K"inert" ex elseif k == K"gc_preserve" s = ssavar(ctx, ex) r = ssavar(ctx, ex) @ast ctx ex [K"block"; s := [K"gc_preserve_begin" (children(ex))[2:var"end"]...]; r := expand_forms_2(ctx, (children(ex))[1]); [K"gc_preserve_end" s]; r] elseif k == K"&" throw(LoweringError(ex, "invalid syntax")) elseif k == K"$" throw(LoweringError(ex, "`\$` expression outside string or quote")) elseif k == K"..." throw(LoweringError(ex, "`...` expression outside call")) elseif is_leaf(ex) ex elseif k == K"return" if numchildren(ex) == 0 @ast ctx ex [K"return" "nothing"::K"core"] elseif numchildren(ex) == 1 mapchildren((e->begin expand_forms_2(ctx, e) end), ctx, ex) else throw(LoweringError(ex, "More than one argument to return")) end else mapchildren((e->begin expand_forms_2(ctx, e) end), ctx, ex) end elseif k == K"typed_comprehension" @chk numchildren(ex) == 2 @chk kind(ex[2]) == K"generator" if numchildren(ex[2]) == 2 && kind((ex[2])[2]) == K"iteration" expand_forms_2(ctx, expand_comprehension_to_loops(ctx, ex)) else @ast ctx ex [K"call"; "collect"::K"top"; expand_forms_2(ctx, ex[1]); expand_forms_2(ctx, ex[2])] end elseif k == K"generator" expand_forms_2(ctx, expand_generator(ctx, ex)) elseif k == K"->" || k == K"do" expand_forms_2(ctx, expand_arrow(ctx, ex)) elseif k == K"function" expand_forms_2(ctx, expand_function_def(ctx, ex, docs)) elseif k == K"macro" @ast ctx ex [K"block"; [K"assert"; "global_toplevel_only"::K"Symbol"; [K"inert" ex]]; expand_forms_2(ctx, expand_macro_def(ctx, ex))] elseif k == K"if" || k == K"elseif" @chk numchildren(ex) >= 2 @ast ctx ex [k; expand_condition(ctx, ex[1]); expand_forms_2(ctx, ex[2:var"end"])...] elseif k == K"let" expand_forms_2(ctx, expand_let(ctx, ex)) elseif k == K"const" expand_const_decl(ctx, ex) elseif k == K"local" || k == K"global" if k == K"global" && kind(ex[1]) == K"const" expand_const_decl(ctx, @ast(ctx, ex, [K"const" [K"global" (ex[1])[1]]])) else expand_decls(ctx, ex) end elseif k == K"where" expand_forms_2(ctx, expand_wheres(ctx, ex)) elseif k == K"braces" || k == K"bracescat" throw(LoweringError(ex, "{ } syntax is reserved for future use")) elseif k == K"string" if numchildren(ex) == 1 && kind(ex[1]) == K"String" ex[1] else @ast ctx ex [K"call"; "string"::K"top"; expand_forms_2(ctx, children(ex))...] end elseif k == K"try" expand_forms_2(ctx, expand_try(ctx, ex)) elseif k == K"tuple" if has_parameters(ex) if numchildren(ex) > 1 throw(LoweringError(ex[var"end"], "unexpected semicolon in tuple - use `,` to separate tuple elements")) end expand_forms_2(ctx, expand_named_tuple(ctx, ex, children(ex[1]))) elseif any_assignment(children(ex)) expand_forms_2(ctx, expand_named_tuple(ctx, ex, children(ex))) else expand_forms_2(ctx, @ast(ctx, ex, [K"call"; "tuple"::K"core"; children(ex)...])) end elseif k == K"$" throw(LoweringError(ex, "`\$` expression outside string or quote block")) elseif k == K"module" throw(LoweringError(ex, "`module` is only allowed at top level")) elseif k == K"import" || k == K"using" expand_import_or_using(ctx, ex) elseif k == K"export" || k == K"public" expand_public(ctx, ex) elseif k == K"abstract" || k == K"primitive" expand_forms_2(ctx, expand_abstract_or_primitive_type(ctx, ex)) elseif k == K"struct" expand_forms_2(ctx, expand_struct_def(ctx, ex, docs)) elseif k == K"ref" sctx = with_stmts(ctx) (arr, idxs) = expand_ref_components(sctx, ex) expand_forms_2(ctx, @ast(ctx, ex, [K"block"; sctx.stmts...; [K"call"; "getindex"::K"top"; arr; idxs...]])) elseif k == K"curly" expand_forms_2(ctx, expand_curly(ctx, ex)) elseif k == K"toplevel" ex2 = @ast(ctx, ex, [K"block"; [K"assert" "toplevel_only"::K"Symbol" [K"inert" ex]]; [K"call"; eval::K"Value"; ctx.mod::K"Value"; [K"inert" ex]; [K"parameters"; [K"="; "expr_compat_mode"::K"Identifier"; ctx.expr_compat_mode::K"Bool"]]]]) expand_forms_2(ctx, ex2) elseif k == K"vect" check_no_parameters(ex, "unexpected semicolon in array expression") expand_array(ctx, ex, "vect") elseif k == K"hcat" expand_array(ctx, ex, "hcat") elseif k == K"typed_hcat" expand_array(ctx, ex, "typed_hcat") elseif k == K"opaque_closure" expand_forms_2(ctx, expand_opaque_closure(ctx, ex)) elseif k == K"vcat" || k == K"typed_vcat" expand_forms_2(ctx, expand_vcat(ctx, ex)) elseif k == K"ncat" || k == K"typed_ncat" expand_forms_2(ctx, expand_ncat(ctx, ex)) elseif k == K"while" @chk numchildren(ex) == 2 @ast ctx ex [K"break_block" "loop_exit"::K"symbolic_label"; [K"_while"; expand_condition(ctx, ex[1]); [K"break_block" "loop_cont"::K"symbolic_label"; [(K"scope_block")(scope_type = :neutral); expand_forms_2(ctx, ex[2])]]]] elseif k == K"inert" ex elseif k == K"gc_preserve" s = ssavar(ctx, ex) r = ssavar(ctx, ex) @ast ctx ex [K"block"; s := [K"gc_preserve_begin" (children(ex))[2:var"end"]...]; r := expand_forms_2(ctx, (children(ex))[1]); [K"gc_preserve_end" s]; r] elseif k == K"&" throw(LoweringError(ex, "invalid syntax")) elseif k == K"$" throw(LoweringError(ex, "`\$` expression outside string or quote")) elseif k == K"..." throw(LoweringError(ex, "`...` expression outside call")) elseif is_leaf(ex) ex elseif k == K"return" if numchildren(ex) == 0 @ast ctx ex [K"return" "nothing"::K"core"] elseif numchildren(ex) == 1 mapchildren((e->begin expand_forms_2(ctx, e) end), ctx, ex) else throw(LoweringError(ex, "More than one argument to return")) end else mapchildren((e->begin expand_forms_2(ctx, e) end), ctx, ex) end elseif k == K"comprehension" @chk numchildren(ex) == 1 @chk kind(ex[1]) == K"generator" @ast ctx ex [K"call"; "collect"::K"top"; expand_forms_2(ctx, ex[1])] elseif k == K"typed_comprehension" @chk numchildren(ex) == 2 @chk kind(ex[2]) == K"generator" if numchildren(ex[2]) == 2 && kind((ex[2])[2]) == K"iteration" expand_forms_2(ctx, expand_comprehension_to_loops(ctx, ex)) else @ast ctx ex [K"call"; "collect"::K"top"; expand_forms_2(ctx, ex[1]); expand_forms_2(ctx, ex[2])] end elseif k == K"generator" expand_forms_2(ctx, expand_generator(ctx, ex)) elseif k == K"->" || k == K"do" expand_forms_2(ctx, expand_arrow(ctx, ex)) elseif k == K"function" expand_forms_2(ctx, expand_function_def(ctx, ex, docs)) elseif k == K"macro" @ast ctx ex [K"block"; [K"assert"; "global_toplevel_only"::K"Symbol"; [K"inert" ex]]; expand_forms_2(ctx, expand_macro_def(ctx, ex))] elseif k == K"if" || k == K"elseif" @chk numchildren(ex) >= 2 @ast ctx ex [k; expand_condition(ctx, ex[1]); expand_forms_2(ctx, ex[2:var"end"])...] elseif k == K"let" expand_forms_2(ctx, expand_let(ctx, ex)) elseif k == K"const" expand_const_decl(ctx, ex) elseif k == K"local" || k == K"global" if k == K"global" && kind(ex[1]) == K"const" expand_const_decl(ctx, @ast(ctx, ex, [K"const" [K"global" (ex[1])[1]]])) else expand_decls(ctx, ex) end elseif k == K"where" expand_forms_2(ctx, expand_wheres(ctx, ex)) elseif k == K"braces" || k == K"bracescat" throw(LoweringError(ex, "{ } syntax is reserved for future use")) elseif k == K"string" if numchildren(ex) == 1 && kind(ex[1]) == K"String" ex[1] else @ast ctx ex [K"call"; "string"::K"top"; expand_forms_2(ctx, children(ex))...] end elseif k == K"try" expand_forms_2(ctx, expand_try(ctx, ex)) elseif k == K"tuple" if has_parameters(ex) if numchildren(ex) > 1 throw(LoweringError(ex[var"end"], "unexpected semicolon in tuple - use `,` to separate tuple elements")) end expand_forms_2(ctx, expand_named_tuple(ctx, ex, children(ex[1]))) elseif any_assignment(children(ex)) expand_forms_2(ctx, expand_named_tuple(ctx, ex, children(ex))) else expand_forms_2(ctx, @ast(ctx, ex, [K"call"; "tuple"::K"core"; children(ex)...])) end elseif k == K"$" throw(LoweringError(ex, "`\$` expression outside string or quote block")) elseif k == K"module" throw(LoweringError(ex, "`module` is only allowed at top level")) elseif k == K"import" || k == K"using" expand_import_or_using(ctx, ex) elseif k == K"export" || k == K"public" expand_public(ctx, ex) elseif k == K"abstract" || k == K"primitive" expand_forms_2(ctx, expand_abstract_or_primitive_type(ctx, ex)) elseif k == K"struct" expand_forms_2(ctx, expand_struct_def(ctx, ex, docs)) elseif k == K"ref" sctx = with_stmts(ctx) (arr, idxs) = expand_ref_components(sctx, ex) expand_forms_2(ctx, @ast(ctx, ex, [K"block"; sctx.stmts...; [K"call"; "getindex"::K"top"; arr; idxs...]])) elseif k == K"curly" expand_forms_2(ctx, expand_curly(ctx, ex)) elseif k == K"toplevel" ex2 = @ast(ctx, ex, [K"block"; [K"assert" "toplevel_only"::K"Symbol" [K"inert" ex]]; [K"call"; eval ::K"Value"; ctx.mod ::K"Value"; [K"inert" ex]; [K"parameters"; [K"="; "expr_compat_mode"::K"Identifier"; ctx.expr_compat_mode::K"Bool"]]]]) expand_forms_2(ctx, ex2) elseif k == K"vect" check_no_parameters(ex, "unexpected semicolon in array expression") expand_array(ctx, ex, "vect") elseif k == K"hcat" expand_array(ctx, ex, "hcat") elseif k == K"typed_hcat" expand_array(ctx, ex, "typed_hcat") elseif k == K"opaque_closure" expand_forms_2(ctx, expand_opaque_closure(ctx, ex)) elseif k == K"vcat" || k == K"typed_vcat" expand_forms_2(ctx, expand_vcat(ctx, ex)) elseif k == K"ncat" || k == K"typed_ncat" expand_forms_2(ctx, expand_ncat(ctx, ex)) elseif k == K"while" @chk numchildren(ex) == 2 @ast ctx ex [K"break_block" "loop_exit"::K"symbolic_label"; [K"_while"; expand_condition(ctx, ex[1]); [K"break_block" "loop_cont"::K"symbolic_label"; [(K"scope_block")(scope_type = :neutral); expand_forms_2(ctx, ex[2])]]]] elseif k == K"inert" ex elseif k == K"gc_preserve" s = ssavar(ctx, ex) r = ssavar(ctx, ex) @ast ctx ex [K"block"; s := [K"gc_preserve_begin" (children(ex))[2:var"end"]...]; r := expand_forms_2(ctx, (children(ex))[1]); [K"gc_preserve_end" s]; r] elseif k == K"&" throw(LoweringError(ex, "invalid syntax")) elseif k == K"$" throw(LoweringError(ex, "`\$` expression outside string or quote")) elseif k == K"..." throw(LoweringError(ex, "`...` expression outside call")) elseif is_leaf(ex) ex elseif k == K"return" if numchildren(ex) == 0 @ast ctx ex [K"return" "nothing"::K"core"] elseif numchildren(ex) == 1 mapchildren((e->begin expand_forms_2(ctx, e) end), ctx, ex) else throw(LoweringError(ex, "More than one argument to return")) end else mapchildren((e->begin expand_forms_2(ctx, e) end), ctx, ex) end elseif k == K"comprehension" @chk numchildren(ex) == 1 @chk kind(ex[1]) == K"generator" @ast ctx ex [K"call"; "collect"::K"top"; expand_forms_2(ctx, ex[1])] elseif k == K"typed_comprehension" @chk numchildren(ex) == 2 @chk kind(ex[2]) == K"generator" if numchildren(ex[2]) == 2 && kind((ex[2])[2]) == K"iteration" expand_forms_2(ctx, expand_comprehension_to_loops(ctx, ex)) else @ast ctx ex [K"call"; "collect"::K"top"; expand_forms_2(ctx, ex[1]); expand_forms_2(ctx, ex[2])] end elseif k == K"generator" expand_forms_2(ctx, expand_generator(ctx, ex)) elseif k == K"->" || k == K"do" expand_forms_2(ctx, expand_arrow(ctx, ex)) elseif k == K"function" expand_forms_2(ctx, expand_function_def(ctx, ex, docs)) elseif k == K"macro" @ast ctx ex [K"block"; [K"assert"; "global_toplevel_only"::K"Symbol"; [K"inert" ex]]; expand_forms_2(ctx, expand_macro_def(ctx, ex))] elseif k == K"if" || k == K"elseif" @chk numchildren(ex) >= 2 @ast ctx ex [k; expand_condition(ctx, ex[1]); expand_forms_2(ctx, ex[2:var"end"])...] elseif k == K"let" expand_forms_2(ctx, expand_let(ctx, ex)) elseif k == K"const" expand_const_decl(ctx, ex) elseif k == K"local" || k == K"global" if k == K"global" && kind(ex[1]) == K"const" expand_const_decl(ctx, @ast(ctx, ex, [K"const" [K"global" (ex[1])[1]]])) else expand_decls(ctx, ex) end elseif k == K"where" expand_forms_2(ctx, expand_wheres(ctx, ex)) elseif k == K"braces" || k == K"bracescat" throw(LoweringError(ex, "{ } syntax is reserved for future use")) elseif k == K"string" if numchildren(ex) == 1 && kind(ex[1]) == K"String" ex[1] else @ast ctx ex [K"call"; "string"::K"top"; expand_forms_2(ctx, children(ex))...] end elseif k == K"try" expand_forms_2(ctx, expand_try(ctx, ex)) elseif k == K"tuple" if has_parameters(ex) if numchildren(ex) > 1 throw(LoweringError(ex[var"end"], "unexpected semicolon in tuple - use `,` to separate tuple elements")) end expand_forms_2(ctx, expand_named_tuple(ctx, ex, children(ex[1]))) elseif any_assignment(children(ex)) expand_forms_2(ctx, expand_named_tuple(ctx, ex, children(ex))) else expand_forms_2(ctx, @ast(ctx, ex, [K"call"; "tuple"::K"core"; children(ex)...])) end elseif k == K"$" throw(LoweringError(ex, "`\$` expression outside string or quote block")) elseif k == K"module" throw(LoweringError(ex, "`module` is only allowed at top level")) elseif k == K"import" || k == K"using" expand_import_or_using(ctx, ex) elseif k == K"export" || k == K"public" expand_public(ctx, ex) elseif k == K"abstract" || k == K"primitive" expand_forms_2(ctx, expand_abstract_or_primitive_type(ctx, ex)) elseif k == K"struct" expand_forms_2(ctx, expand_struct_def(ctx, ex, docs)) elseif k == K"ref" sctx = with_stmts(ctx) (arr, idxs) = expand_ref_components(sctx, ex) expand_forms_2(ctx, @ast(ctx, ex, [K"block"; sctx.stmts...; [K"call"; "getindex"::K"top"; arr; idxs...]])) elseif k == K"curly" expand_forms_2(ctx, expand_curly(ctx, ex)) elseif k == K"toplevel" ex2 = @ast(ctx, ex, [K"block"; [K"assert" "toplevel_only"::K"Symbol" [K"inert" ex]]; [K"call"; eval::K"Value"; ctx.mod::K"Value"; [K"inert" ex]; [K"parameters"; [K"="; "expr_compat_mode"::K"Identifier"; ctx.expr_compat_mode::K"Bool"]]]]) expand_forms_2(ctx, ex2) elseif k == K"vect" check_no_parameters(ex, "unexpected semicolon in array expression") expand_array(ctx, ex, "vect") elseif k == K"hcat" expand_array(ctx, ex, "hcat") elseif k == K"typed_hcat" expand_array(ctx, ex, "typed_hcat") elseif k == K"opaque_closure" expand_forms_2(ctx, expand_opaque_closure(ctx, ex)) elseif k == K"vcat" || k == K"typed_vcat" expand_forms_2(ctx, expand_vcat(ctx, ex)) elseif k == K"ncat" || k == K"typed_ncat" expand_forms_2(ctx, expand_ncat(ctx, ex)) elseif k == K"while" @chk numchildren(ex) == 2 @ast ctx ex [K"break_block" "loop_exit"::K"symbolic_label"; [K"_while"; expand_condition(ctx, ex[1]); [K"break_block" "loop_cont"::K"symbolic_label"; [(K"scope_block")(scope_type = :neutral); expand_forms_2(ctx, ex[2])]]]] elseif k == K"inert" ex elseif k == K"gc_preserve" s = ssavar(ctx, ex) r = ssavar(ctx, ex) @ast ctx ex [K"block"; s := [K"gc_preserve_begin" (children(ex))[2:var"end"]...]; r := expand_forms_2(ctx, (children(ex))[1]); [K"gc_preserve_end" s]; r] elseif k == K"&" throw(LoweringError(ex, "invalid syntax")) elseif k == K"$" throw(LoweringError(ex, "`\$` expression outside string or quote")) elseif k == K"..." throw(LoweringError(ex, "`...` expression outside call")) elseif is_leaf(ex) ex elseif k == K"return" if numchildren(ex) == 0 @ast ctx ex [K"return" "nothing"::K"core"] elseif numchildren(ex) == 1 mapchildren((e->begin expand_forms_2(ctx, e) end), ctx, ex) else throw(LoweringError(ex, "More than one argument to return")) end else mapchildren((e->begin expand_forms_2(ctx, e) end), ctx, ex) end elseif k == K"for" expand_forms_2(ctx, expand_for(ctx, ex)) elseif k == K"comprehension" @chk numchildren(ex) == 1 @chk kind(ex[1]) == K"generator" @ast ctx ex [K"call"; "collect"::K"top"; expand_forms_2(ctx, ex[1])] elseif k == K"typed_comprehension" @chk numchildren(ex) == 2 @chk kind(ex[2]) == K"generator" if numchildren(ex[2]) == 2 && kind((ex[2])[2]) == K"iteration" expand_forms_2(ctx, expand_comprehension_to_loops(ctx, ex)) else @ast ctx ex [K"call"; "collect"::K"top"; expand_forms_2(ctx, ex[1]); expand_forms_2(ctx, ex[2])] end elseif k == K"generator" expand_forms_2(ctx, expand_generator(ctx, ex)) elseif k == K"->" || k == K"do" expand_forms_2(ctx, expand_arrow(ctx, ex)) elseif k == K"function" expand_forms_2(ctx, expand_function_def(ctx, ex, docs)) elseif k == K"macro" @ast ctx ex [K"block"; [K"assert"; "global_toplevel_only"::K"Symbol"; [K"inert" ex]]; expand_forms_2(ctx, expand_macro_def(ctx, ex))] elseif k == K"if" || k == K"elseif" @chk numchildren(ex) >= 2 @ast ctx ex [k; expand_condition(ctx, ex[1]); expand_forms_2(ctx, ex[2:var"end"])...] elseif k == K"let" expand_forms_2(ctx, expand_let(ctx, ex)) elseif k == K"const" expand_const_decl(ctx, ex) elseif k == K"local" || k == K"global" if k == K"global" && kind(ex[1]) == K"const" expand_const_decl(ctx, @ast(ctx, ex, [K"const" [K"global" (ex[1])[1]]])) else expand_decls(ctx, ex) end elseif k == K"where" expand_forms_2(ctx, expand_wheres(ctx, ex)) elseif k == K"braces" || k == K"bracescat" throw(LoweringError(ex, "{ } syntax is reserved for future use")) elseif k == K"string" if numchildren(ex) == 1 && kind(ex[1]) == K"String" ex[1] else @ast ctx ex [K"call"; "string"::K"top"; expand_forms_2(ctx, children(ex))...] end elseif k == K"try" expand_forms_2(ctx, expand_try(ctx, ex)) elseif k == K"tuple" if has_parameters(ex) if numchildren(ex) > 1 throw(LoweringError(ex[var"end"], "unexpected semicolon in tuple - use `,` to separate tuple elements")) end expand_forms_2(ctx, expand_named_tuple(ctx, ex, children(ex[1]))) elseif any_assignment(children(ex)) expand_forms_2(ctx, expand_named_tuple(ctx, ex, children(ex))) else expand_forms_2(ctx, @ast(ctx, ex, [K"call"; "tuple"::K"core"; children(ex)...])) end elseif k == K"$" throw(LoweringError(ex, "`\$` expression outside string or quote block")) elseif k == K"module" throw(LoweringError(ex, "`module` is only allowed at top level")) elseif k == K"import" || k == K"using" expand_import_or_using(ctx, ex) elseif k == K"export" || k == K"public" expand_public(ctx, ex) elseif k == K"abstract" || k == K"primitive" expand_forms_2(ctx, expand_abstract_or_primitive_type(ctx, ex)) elseif k == K"struct" expand_forms_2(ctx, expand_struct_def(ctx, ex, docs)) elseif k == K"ref" sctx = with_stmts(ctx) (arr, idxs) = expand_ref_components(sctx, ex) expand_forms_2(ctx, @ast(ctx, ex, [K"block"; sctx.stmts...; [K"call"; "getindex"::K"top"; arr; idxs...]])) elseif k == K"curly" expand_forms_2(ctx, expand_curly(ctx, ex)) elseif k == K"toplevel" ex2 = @ast(ctx, ex, [K"block"; [K"assert" "toplevel_only"::K"Symbol" [K"inert" ex]]; [K"call"; eval ::K"Value"; ctx.mod ::K"Value"; [K"inert" ex]; [K"parameters"; [K"="; "expr_compat_mode"::K"Identifier"; ctx.expr_compat_mode::K"Bool"]]]]) expand_forms_2(ctx, ex2) elseif k == K"vect" check_no_parameters(ex, "unexpected semicolon in array expression") expand_array(ctx, ex, "vect") elseif k == K"hcat" expand_array(ctx, ex, "hcat") elseif k == K"typed_hcat" expand_array(ctx, ex, "typed_hcat") elseif k == K"opaque_closure" expand_forms_2(ctx, expand_opaque_closure(ctx, ex)) elseif k == K"vcat" || k == K"typed_vcat" expand_forms_2(ctx, expand_vcat(ctx, ex)) elseif k == K"ncat" || k == K"typed_ncat" expand_forms_2(ctx, expand_ncat(ctx, ex)) elseif k == K"while" @chk numchildren(ex) == 2 @ast ctx ex [K"break_block" "loop_exit"::K"symbolic_label"; [K"_while"; expand_condition(ctx, ex[1]); [K"break_block" "loop_cont"::K"symbolic_label"; [(K"scope_block")(scope_type = :neutral); expand_forms_2(ctx, ex[2])]]]] elseif k == K"inert" ex elseif k == K"gc_preserve" s = ssavar(ctx, ex) r = ssavar(ctx, ex) @ast ctx ex [K"block"; s := [K"gc_preserve_begin" (children(ex))[2:var"end"]...]; r := expand_forms_2(ctx, (children(ex))[1]); [K"gc_preserve_end" s]; r] elseif k == K"&" throw(LoweringError(ex, "invalid syntax")) elseif k == K"$" throw(LoweringError(ex, "`\$` expression outside string or quote")) elseif k == K"..." throw(LoweringError(ex, "`...` expression outside call")) elseif is_leaf(ex) ex elseif k == K"return" if numchildren(ex) == 0 @ast ctx ex [K"return" "nothing"::K"core"] elseif numchildren(ex) == 1 mapchildren((e->begin expand_forms_2(ctx, e) end), ctx, ex) else throw(LoweringError(ex, "More than one argument to return")) end else mapchildren((e->begin expand_forms_2(ctx, e) end), ctx, ex) end elseif k == K"for" expand_forms_2(ctx, expand_for(ctx, ex)) elseif k == K"comprehension" @chk numchildren(ex) == 1 @chk kind(ex[1]) == K"generator" @ast ctx ex [K"call"; "collect"::K"top"; expand_forms_2(ctx, ex[1])] elseif k == K"typed_comprehension" @chk numchildren(ex) == 2 @chk kind(ex[2]) == K"generator" if numchildren(ex[2]) == 2 && kind((ex[2])[2]) == K"iteration" expand_forms_2(ctx, expand_comprehension_to_loops(ctx, ex)) else @ast ctx ex [K"call"; "collect"::K"top"; expand_forms_2(ctx, ex[1]); expand_forms_2(ctx, ex[2])] end elseif k == K"generator" expand_forms_2(ctx, expand_generator(ctx, ex)) elseif k == K"->" || k == K"do" expand_forms_2(ctx, expand_arrow(ctx, ex)) elseif k == K"function" expand_forms_2(ctx, expand_function_def(ctx, ex, docs)) elseif k == K"macro" @ast ctx ex [K"block"; [K"assert"; "global_toplevel_only"::K"Symbol"; [K"inert" ex]]; expand_forms_2(ctx, expand_macro_def(ctx, ex))] elseif k == K"if" || k == K"elseif" @chk numchildren(ex) >= 2 @ast ctx ex [k; expand_condition(ctx, ex[1]); expand_forms_2(ctx, ex[2:var"end"])...] elseif k == K"let" expand_forms_2(ctx, expand_let(ctx, ex)) elseif k == K"const" expand_const_decl(ctx, ex) elseif k == K"local" || k == K"global" if k == K"global" && kind(ex[1]) == K"const" expand_const_decl(ctx, @ast(ctx, ex, [K"const" [K"global" (ex[1])[1]]])) else expand_decls(ctx, ex) end elseif k == K"where" expand_forms_2(ctx, expand_wheres(ctx, ex)) elseif k == K"braces" || k == K"bracescat" throw(LoweringError(ex, "{ } syntax is reserved for future use")) elseif k == K"string" if numchildren(ex) == 1 && kind(ex[1]) == K"String" ex[1] else @ast ctx ex [K"call"; "string"::K"top"; expand_forms_2(ctx, children(ex))...] end elseif k == K"try" expand_forms_2(ctx, expand_try(ctx, ex)) elseif k == K"tuple" if has_parameters(ex) if numchildren(ex) > 1 throw(LoweringError(ex[var"end"], "unexpected semicolon in tuple - use `,` to separate tuple elements")) end expand_forms_2(ctx, expand_named_tuple(ctx, ex, children(ex[1]))) elseif any_assignment(children(ex)) expand_forms_2(ctx, expand_named_tuple(ctx, ex, children(ex))) else expand_forms_2(ctx, @ast(ctx, ex, [K"call"; "tuple"::K"core"; children(ex)...])) end elseif k == K"$" throw(LoweringError(ex, "`\$` expression outside string or quote block")) elseif k == K"module" throw(LoweringError(ex, "`module` is only allowed at top level")) elseif k == K"import" || k == K"using" expand_import_or_using(ctx, ex) elseif k == K"export" || k == K"public" expand_public(ctx, ex) elseif k == K"abstract" || k == K"primitive" expand_forms_2(ctx, expand_abstract_or_primitive_type(ctx, ex)) elseif k == K"struct" expand_forms_2(ctx, expand_struct_def(ctx, ex, docs)) elseif k == K"ref" sctx = with_stmts(ctx) (arr, idxs) = expand_ref_components(sctx, ex) expand_forms_2(ctx, @ast(ctx, ex, [K"block"; sctx.stmts...; [K"call"; "getindex"::K"top"; arr; idxs...]])) elseif k == K"curly" expand_forms_2(ctx, expand_curly(ctx, ex)) elseif k == K"toplevel" ex2 = @ast(ctx, ex, [K"block"; [K"assert" "toplevel_only"::K"Symbol" [K"inert" ex]]; [K"call"; eval::K"Value"; ctx.mod::K"Value"; [K"inert" ex]; [K"parameters"; [K"="; "expr_compat_mode"::K"Identifier"; ctx.expr_compat_mode::K"Bool"]]]]) expand_forms_2(ctx, ex2) elseif k == K"vect" check_no_parameters(ex, "unexpected semicolon in array expression") expand_array(ctx, ex, "vect") elseif k == K"hcat" expand_array(ctx, ex, "hcat") elseif k == K"typed_hcat" expand_array(ctx, ex, "typed_hcat") elseif k == K"opaque_closure" expand_forms_2(ctx, expand_opaque_closure(ctx, ex)) elseif k == K"vcat" || k == K"typed_vcat" expand_forms_2(ctx, expand_vcat(ctx, ex)) elseif k == K"ncat" || k == K"typed_ncat" expand_forms_2(ctx, expand_ncat(ctx, ex)) elseif k == K"while" @chk numchildren(ex) == 2 @ast ctx ex [K"break_block" "loop_exit"::K"symbolic_label"; [K"_while"; expand_condition(ctx, ex[1]); [K"break_block" "loop_cont"::K"symbolic_label"; [(K"scope_block")(scope_type = :neutral); expand_forms_2(ctx, ex[2])]]]] elseif k == K"inert" ex elseif k == K"gc_preserve" s = ssavar(ctx, ex) r = ssavar(ctx, ex) @ast ctx ex [K"block"; s := [K"gc_preserve_begin" (children(ex))[2:var"end"]...]; r := expand_forms_2(ctx, (children(ex))[1]); [K"gc_preserve_end" s]; r] elseif k == K"&" throw(LoweringError(ex, "invalid syntax")) elseif k == K"$" throw(LoweringError(ex, "`\$` expression outside string or quote")) elseif k == K"..." throw(LoweringError(ex, "`...` expression outside call")) elseif is_leaf(ex) ex elseif k == K"return" if numchildren(ex) == 0 @ast ctx ex [K"return" "nothing"::K"core"] elseif numchildren(ex) == 1 mapchildren((e->begin expand_forms_2(ctx, e) end), ctx, ex) else throw(LoweringError(ex, "More than one argument to return")) end else mapchildren((e->begin expand_forms_2(ctx, e) end), ctx, ex) end elseif k == K"doc" @chk numchildren(ex) == 2 expand_doc(ctx, ex[2], ex) elseif k == K"for" expand_forms_2(ctx, expand_for(ctx, ex)) elseif k == K"comprehension" @chk numchildren(ex) == 1 @chk kind(ex[1]) == K"generator" @ast ctx ex [K"call"; "collect"::K"top"; expand_forms_2(ctx, ex[1])] elseif k == K"typed_comprehension" @chk numchildren(ex) == 2 @chk kind(ex[2]) == K"generator" if numchildren(ex[2]) == 2 && kind((ex[2])[2]) == K"iteration" expand_forms_2(ctx, expand_comprehension_to_loops(ctx, ex)) else @ast ctx ex [K"call"; "collect"::K"top"; expand_forms_2(ctx, ex[1]); expand_forms_2(ctx, ex[2])] end elseif k == K"generator" expand_forms_2(ctx, expand_generator(ctx, ex)) elseif k == K"->" || k == K"do" expand_forms_2(ctx, expand_arrow(ctx, ex)) elseif k == K"function" expand_forms_2(ctx, expand_function_def(ctx, ex, docs)) elseif k == K"macro" @ast ctx ex [K"block"; [K"assert"; "global_toplevel_only"::K"Symbol"; [K"inert" ex]]; expand_forms_2(ctx, expand_macro_def(ctx, ex))] elseif k == K"if" || k == K"elseif" @chk numchildren(ex) >= 2 @ast ctx ex [k; expand_condition(ctx, ex[1]); expand_forms_2(ctx, ex[2:var"end"])...] elseif k == K"let" expand_forms_2(ctx, expand_let(ctx, ex)) elseif k == K"const" expand_const_decl(ctx, ex) elseif k == K"local" || k == K"global" if k == K"global" && kind(ex[1]) == K"const" expand_const_decl(ctx, @ast(ctx, ex, [K"const" [K"global" (ex[1])[1]]])) else expand_decls(ctx, ex) end elseif k == K"where" expand_forms_2(ctx, expand_wheres(ctx, ex)) elseif k == K"braces" || k == K"bracescat" throw(LoweringError(ex, "{ } syntax is reserved for future use")) elseif k == K"string" if numchildren(ex) == 1 && kind(ex[1]) == K"String" ex[1] else @ast ctx ex [K"call"; "string"::K"top"; expand_forms_2(ctx, children(ex))...] end elseif k == K"try" expand_forms_2(ctx, expand_try(ctx, ex)) elseif k == K"tuple" if has_parameters(ex) if numchildren(ex) > 1 throw(LoweringError(ex[var"end"], "unexpected semicolon in tuple - use `,` to separate tuple elements")) end expand_forms_2(ctx, expand_named_tuple(ctx, ex, children(ex[1]))) elseif any_assignment(children(ex)) expand_forms_2(ctx, expand_named_tuple(ctx, ex, children(ex))) else expand_forms_2(ctx, @ast(ctx, ex, [K"call"; "tuple"::K"core"; children(ex)...])) end elseif k == K"$" throw(LoweringError(ex, "`\$` expression outside string or quote block")) elseif k == K"module" throw(LoweringError(ex, "`module` is only allowed at top level")) elseif k == K"import" || k == K"using" expand_import_or_using(ctx, ex) elseif k == K"export" || k == K"public" expand_public(ctx, ex) elseif k == K"abstract" || k == K"primitive" expand_forms_2(ctx, expand_abstract_or_primitive_type(ctx, ex)) elseif k == K"struct" expand_forms_2(ctx, expand_struct_def(ctx, ex, docs)) elseif k == K"ref" sctx = with_stmts(ctx) (arr, idxs) = expand_ref_components(sctx, ex) expand_forms_2(ctx, @ast(ctx, ex, [K"block"; sctx.stmts...; [K"call"; "getindex"::K"top"; arr; idxs...]])) elseif k == K"curly" expand_forms_2(ctx, expand_curly(ctx, ex)) elseif k == K"toplevel" ex2 = @ast(ctx, ex, [K"block"; [K"assert" "toplevel_only"::K"Symbol" [K"inert" ex]]; [K"call"; eval ::K"Value"; ctx.mod ::K"Value"; [K"inert" ex]; [K"parameters"; [K"="; "expr_compat_mode"::K"Identifier"; ctx.expr_compat_mode::K"Bool"]]]]) expand_forms_2(ctx, ex2) elseif k == K"vect" check_no_parameters(ex, "unexpected semicolon in array expression") expand_array(ctx, ex, "vect") elseif k == K"hcat" expand_array(ctx, ex, "hcat") elseif k == K"typed_hcat" expand_array(ctx, ex, "typed_hcat") elseif k == K"opaque_closure" expand_forms_2(ctx, expand_opaque_closure(ctx, ex)) elseif k == K"vcat" || k == K"typed_vcat" expand_forms_2(ctx, expand_vcat(ctx, ex)) elseif k == K"ncat" || k == K"typed_ncat" expand_forms_2(ctx, expand_ncat(ctx, ex)) elseif k == K"while" @chk numchildren(ex) == 2 @ast ctx ex [K"break_block" "loop_exit"::K"symbolic_label"; [K"_while"; expand_condition(ctx, ex[1]); [K"break_block" "loop_cont"::K"symbolic_label"; [(K"scope_block")(scope_type = :neutral); expand_forms_2(ctx, ex[2])]]]] elseif k == K"inert" ex elseif k == K"gc_preserve" s = ssavar(ctx, ex) r = ssavar(ctx, ex) @ast ctx ex [K"block"; s := [K"gc_preserve_begin" (children(ex))[2:var"end"]...]; r := expand_forms_2(ctx, (children(ex))[1]); [K"gc_preserve_end" s]; r] elseif k == K"&" throw(LoweringError(ex, "invalid syntax")) elseif k == K"$" throw(LoweringError(ex, "`\$` expression outside string or quote")) elseif k == K"..." throw(LoweringError(ex, "`...` expression outside call")) elseif is_leaf(ex) ex elseif k == K"return" if numchildren(ex) == 0 @ast ctx ex [K"return" "nothing"::K"core"] elseif numchildren(ex) == 1 mapchildren((e->begin expand_forms_2(ctx, e) end), ctx, ex) else throw(LoweringError(ex, "More than one argument to return")) end else mapchildren((e->begin expand_forms_2(ctx, e) end), ctx, ex) end elseif k == K"doc" @chk numchildren(ex) == 2 expand_doc(ctx, ex[2], ex) elseif k == K"for" expand_forms_2(ctx, expand_for(ctx, ex)) elseif k == K"comprehension" @chk numchildren(ex) == 1 @chk kind(ex[1]) == K"generator" @ast ctx ex [K"call"; "collect"::K"top"; expand_forms_2(ctx, ex[1])] elseif k == K"typed_comprehension" @chk numchildren(ex) == 2 @chk kind(ex[2]) == K"generator" if numchildren(ex[2]) == 2 && kind((ex[2])[2]) == K"iteration" expand_forms_2(ctx, expand_comprehension_to_loops(ctx, ex)) else @ast ctx ex [K"call"; "collect"::K"top"; expand_forms_2(ctx, ex[1]); expand_forms_2(ctx, ex[2])] end elseif k == K"generator" expand_forms_2(ctx, expand_generator(ctx, ex)) elseif k == K"->" || k == K"do" expand_forms_2(ctx, expand_arrow(ctx, ex)) elseif k == K"function" expand_forms_2(ctx, expand_function_def(ctx, ex, docs)) elseif k == K"macro" @ast ctx ex [K"block"; [K"assert"; "global_toplevel_only"::K"Symbol"; [K"inert" ex]]; expand_forms_2(ctx, expand_macro_def(ctx, ex))] elseif k == K"if" || k == K"elseif" @chk numchildren(ex) >= 2 @ast ctx ex [k; expand_condition(ctx, ex[1]); expand_forms_2(ctx, ex[2:var"end"])...] elseif k == K"let" expand_forms_2(ctx, expand_let(ctx, ex)) elseif k == K"const" expand_const_decl(ctx, ex) elseif k == K"local" || k == K"global" if k == K"global" && kind(ex[1]) == K"const" expand_const_decl(ctx, @ast(ctx, ex, [K"const" [K"global" (ex[1])[1]]])) else expand_decls(ctx, ex) end elseif k == K"where" expand_forms_2(ctx, expand_wheres(ctx, ex)) elseif k == K"braces" || k == K"bracescat" throw(LoweringError(ex, "{ } syntax is reserved for future use")) elseif k == K"string" if numchildren(ex) == 1 && kind(ex[1]) == K"String" ex[1] else @ast ctx ex [K"call"; "string"::K"top"; expand_forms_2(ctx, children(ex))...] end elseif k == K"try" expand_forms_2(ctx, expand_try(ctx, ex)) elseif k == K"tuple" if has_parameters(ex) if numchildren(ex) > 1 throw(LoweringError(ex[var"end"], "unexpected semicolon in tuple - use `,` to separate tuple elements")) end expand_forms_2(ctx, expand_named_tuple(ctx, ex, children(ex[1]))) elseif any_assignment(children(ex)) expand_forms_2(ctx, expand_named_tuple(ctx, ex, children(ex))) else expand_forms_2(ctx, @ast(ctx, ex, [K"call"; "tuple"::K"core"; children(ex)...])) end elseif k == K"$" throw(LoweringError(ex, "`\$` expression outside string or quote block")) elseif k == K"module" throw(LoweringError(ex, "`module` is only allowed at top level")) elseif k == K"import" || k == K"using" expand_import_or_using(ctx, ex) elseif k == K"export" || k == K"public" expand_public(ctx, ex) elseif k == K"abstract" || k == K"primitive" expand_forms_2(ctx, expand_abstract_or_primitive_type(ctx, ex)) elseif k == K"struct" expand_forms_2(ctx, expand_struct_def(ctx, ex, docs)) elseif k == K"ref" sctx = with_stmts(ctx) (arr, idxs) = expand_ref_components(sctx, ex) expand_forms_2(ctx, @ast(ctx, ex, [K"block"; sctx.stmts...; [K"call"; "getindex"::K"top"; arr; idxs...]])) elseif k == K"curly" expand_forms_2(ctx, expand_curly(ctx, ex)) elseif k == K"toplevel" ex2 = @ast(ctx, ex, [K"block"; [K"assert" "toplevel_only"::K"Symbol" [K"inert" ex]]; [K"call"; eval::K"Value"; ctx.mod::K"Value"; [K"inert" ex]; [K"parameters"; [K"="; "expr_compat_mode"::K"Identifier"; ctx.expr_compat_mode::K"Bool"]]]]) expand_forms_2(ctx, ex2) elseif k == K"vect" check_no_parameters(ex, "unexpected semicolon in array expression") expand_array(ctx, ex, "vect") elseif k == K"hcat" expand_array(ctx, ex, "hcat") elseif k == K"typed_hcat" expand_array(ctx, ex, "typed_hcat") elseif k == K"opaque_closure" expand_forms_2(ctx, expand_opaque_closure(ctx, ex)) elseif k == K"vcat" || k == K"typed_vcat" expand_forms_2(ctx, expand_vcat(ctx, ex)) elseif k == K"ncat" || k == K"typed_ncat" expand_forms_2(ctx, expand_ncat(ctx, ex)) elseif k == K"while" @chk numchildren(ex) == 2 @ast ctx ex [K"break_block" "loop_exit"::K"symbolic_label"; [K"_while"; expand_condition(ctx, ex[1]); [K"break_block" "loop_cont"::K"symbolic_label"; [(K"scope_block")(scope_type = :neutral); expand_forms_2(ctx, ex[2])]]]] elseif k == K"inert" ex elseif k == K"gc_preserve" s = ssavar(ctx, ex) r = ssavar(ctx, ex) @ast ctx ex [K"block"; s := [K"gc_preserve_begin" (children(ex))[2:var"end"]...]; r := expand_forms_2(ctx, (children(ex))[1]); [K"gc_preserve_end" s]; r] elseif k == K"&" throw(LoweringError(ex, "invalid syntax")) elseif k == K"$" throw(LoweringError(ex, "`\$` expression outside string or quote")) elseif k == K"..." throw(LoweringError(ex, "`...` expression outside call")) elseif is_leaf(ex) ex elseif k == K"return" if numchildren(ex) == 0 @ast ctx ex [K"return" "nothing"::K"core"] elseif numchildren(ex) == 1 mapchildren((e->begin expand_forms_2(ctx, e) end), ctx, ex) else throw(LoweringError(ex, "More than one argument to return")) end else mapchildren((e->begin expand_forms_2(ctx, e) end), ctx, ex) end elseif k == K"comparison" expand_forms_2(ctx, expand_compare_chain(ctx, ex)) elseif k == K"doc" @chk numchildren(ex) == 2 expand_doc(ctx, ex[2], ex) elseif k == K"for" expand_forms_2(ctx, expand_for(ctx, ex)) elseif k == K"comprehension" @chk numchildren(ex) == 1 @chk kind(ex[1]) == K"generator" @ast ctx ex [K"call"; "collect"::K"top"; expand_forms_2(ctx, ex[1])] elseif k == K"typed_comprehension" @chk numchildren(ex) == 2 @chk kind(ex[2]) == K"generator" if numchildren(ex[2]) == 2 && kind((ex[2])[2]) == K"iteration" expand_forms_2(ctx, expand_comprehension_to_loops(ctx, ex)) else @ast ctx ex [K"call"; "collect"::K"top"; expand_forms_2(ctx, ex[1]); expand_forms_2(ctx, ex[2])] end elseif k == K"generator" expand_forms_2(ctx, expand_generator(ctx, ex)) elseif k == K"->" || k == K"do" expand_forms_2(ctx, expand_arrow(ctx, ex)) elseif k == K"function" expand_forms_2(ctx, expand_function_def(ctx, ex, docs)) elseif k == K"macro" @ast ctx ex [K"block"; [K"assert"; "global_toplevel_only"::K"Symbol"; [K"inert" ex]]; expand_forms_2(ctx, expand_macro_def(ctx, ex))] elseif k == K"if" || k == K"elseif" @chk numchildren(ex) >= 2 @ast ctx ex [k; expand_condition(ctx, ex[1]); expand_forms_2(ctx, ex[2:var"end"])...] elseif k == K"let" expand_forms_2(ctx, expand_let(ctx, ex)) elseif k == K"const" expand_const_decl(ctx, ex) elseif k == K"local" || k == K"global" if k == K"global" && kind(ex[1]) == K"const" expand_const_decl(ctx, @ast(ctx, ex, [K"const" [K"global" (ex[1])[1]]])) else expand_decls(ctx, ex) end elseif k == K"where" expand_forms_2(ctx, expand_wheres(ctx, ex)) elseif k == K"braces" || k == K"bracescat" throw(LoweringError(ex, "{ } syntax is reserved for future use")) elseif k == K"string" if numchildren(ex) == 1 && kind(ex[1]) == K"String" ex[1] else @ast ctx ex [K"call"; "string"::K"top"; expand_forms_2(ctx, children(ex))...] end elseif k == K"try" expand_forms_2(ctx, expand_try(ctx, ex)) elseif k == K"tuple" if has_parameters(ex) if numchildren(ex) > 1 throw(LoweringError(ex[var"end"], "unexpected semicolon in tuple - use `,` to separate tuple elements")) end expand_forms_2(ctx, expand_named_tuple(ctx, ex, children(ex[1]))) elseif any_assignment(children(ex)) expand_forms_2(ctx, expand_named_tuple(ctx, ex, children(ex))) else expand_forms_2(ctx, @ast(ctx, ex, [K"call"; "tuple"::K"core"; children(ex)...])) end elseif k == K"$" throw(LoweringError(ex, "`\$` expression outside string or quote block")) elseif k == K"module" throw(LoweringError(ex, "`module` is only allowed at top level")) elseif k == K"import" || k == K"using" expand_import_or_using(ctx, ex) elseif k == K"export" || k == K"public" expand_public(ctx, ex) elseif k == K"abstract" || k == K"primitive" expand_forms_2(ctx, expand_abstract_or_primitive_type(ctx, ex)) elseif k == K"struct" expand_forms_2(ctx, expand_struct_def(ctx, ex, docs)) elseif k == K"ref" sctx = with_stmts(ctx) (arr, idxs) = expand_ref_components(sctx, ex) expand_forms_2(ctx, @ast(ctx, ex, [K"block"; sctx.stmts...; [K"call"; "getindex"::K"top"; arr; idxs...]])) elseif k == K"curly" expand_forms_2(ctx, expand_curly(ctx, ex)) elseif k == K"toplevel" ex2 = @ast(ctx, ex, [K"block"; [K"assert" "toplevel_only"::K"Symbol" [K"inert" ex]]; [K"call"; eval ::K"Value"; ctx.mod ::K"Value"; [K"inert" ex]; [K"parameters"; [K"="; "expr_compat_mode"::K"Identifier"; ctx.expr_compat_mode::K"Bool"]]]]) expand_forms_2(ctx, ex2) elseif k == K"vect" check_no_parameters(ex, "unexpected semicolon in array expression") expand_array(ctx, ex, "vect") elseif k == K"hcat" expand_array(ctx, ex, "hcat") elseif k == K"typed_hcat" expand_array(ctx, ex, "typed_hcat") elseif k == K"opaque_closure" expand_forms_2(ctx, expand_opaque_closure(ctx, ex)) elseif k == K"vcat" || k == K"typed_vcat" expand_forms_2(ctx, expand_vcat(ctx, ex)) elseif k == K"ncat" || k == K"typed_ncat" expand_forms_2(ctx, expand_ncat(ctx, ex)) elseif k == K"while" @chk numchildren(ex) == 2 @ast ctx ex [K"break_block" "loop_exit"::K"symbolic_label"; [K"_while"; expand_condition(ctx, ex[1]); [K"break_block" "loop_cont"::K"symbolic_label"; [(K"scope_block")(scope_type = :neutral); expand_forms_2(ctx, ex[2])]]]] elseif k == K"inert" ex elseif k == K"gc_preserve" s = ssavar(ctx, ex) r = ssavar(ctx, ex) @ast ctx ex [K"block"; s := [K"gc_preserve_begin" (children(ex))[2:var"end"]...]; r := expand_forms_2(ctx, (children(ex))[1]); [K"gc_preserve_end" s]; r] elseif k == K"&" throw(LoweringError(ex, "invalid syntax")) elseif k == K"$" throw(LoweringError(ex, "`\$` expression outside string or quote")) elseif k == K"..." throw(LoweringError(ex, "`...` expression outside call")) elseif is_leaf(ex) ex elseif k == K"return" if numchildren(ex) == 0 @ast ctx ex [K"return" "nothing"::K"core"] elseif numchildren(ex) == 1 mapchildren((e->begin expand_forms_2(ctx, e) end), ctx, ex) else throw(LoweringError(ex, "More than one argument to return")) end else mapchildren((e->begin expand_forms_2(ctx, e) end), ctx, ex) end elseif k == K"comparison" expand_forms_2(ctx, expand_compare_chain(ctx, ex)) elseif k == K"doc" @chk numchildren(ex) == 2 expand_doc(ctx, ex[2], ex) elseif k == K"for" expand_forms_2(ctx, expand_for(ctx, ex)) elseif k == K"comprehension" @chk numchildren(ex) == 1 @chk kind(ex[1]) == K"generator" @ast ctx ex [K"call"; "collect"::K"top"; expand_forms_2(ctx, ex[1])] elseif k == K"typed_comprehension" @chk numchildren(ex) == 2 @chk kind(ex[2]) == K"generator" if numchildren(ex[2]) == 2 && kind((ex[2])[2]) == K"iteration" expand_forms_2(ctx, expand_comprehension_to_loops(ctx, ex)) else @ast ctx ex [K"call"; "collect"::K"top"; expand_forms_2(ctx, ex[1]); expand_forms_2(ctx, ex[2])] end elseif k == K"generator" expand_forms_2(ctx, expand_generator(ctx, ex)) elseif k == K"->" || k == K"do" expand_forms_2(ctx, expand_arrow(ctx, ex)) elseif k == K"function" expand_forms_2(ctx, expand_function_def(ctx, ex, docs)) elseif k == K"macro" @ast ctx ex [K"block"; [K"assert"; "global_toplevel_only"::K"Symbol"; [K"inert" ex]]; expand_forms_2(ctx, expand_macro_def(ctx, ex))] elseif k == K"if" || k == K"elseif" @chk numchildren(ex) >= 2 @ast ctx ex [k; expand_condition(ctx, ex[1]); expand_forms_2(ctx, ex[2:var"end"])...] elseif k == K"let" expand_forms_2(ctx, expand_let(ctx, ex)) elseif k == K"const" expand_const_decl(ctx, ex) elseif k == K"local" || k == K"global" if k == K"global" && kind(ex[1]) == K"const" expand_const_decl(ctx, @ast(ctx, ex, [K"const" [K"global" (ex[1])[1]]])) else expand_decls(ctx, ex) end elseif k == K"where" expand_forms_2(ctx, expand_wheres(ctx, ex)) elseif k == K"braces" || k == K"bracescat" throw(LoweringError(ex, "{ } syntax is reserved for future use")) elseif k == K"string" if numchildren(ex) == 1 && kind(ex[1]) == K"String" ex[1] else @ast ctx ex [K"call"; "string"::K"top"; expand_forms_2(ctx, children(ex))...] end elseif k == K"try" expand_forms_2(ctx, expand_try(ctx, ex)) elseif k == K"tuple" if has_parameters(ex) if numchildren(ex) > 1 throw(LoweringError(ex[var"end"], "unexpected semicolon in tuple - use `,` to separate tuple elements")) end expand_forms_2(ctx, expand_named_tuple(ctx, ex, children(ex[1]))) elseif any_assignment(children(ex)) expand_forms_2(ctx, expand_named_tuple(ctx, ex, children(ex))) else expand_forms_2(ctx, @ast(ctx, ex, [K"call"; "tuple"::K"core"; children(ex)...])) end elseif k == K"$" throw(LoweringError(ex, "`\$` expression outside string or quote block")) elseif k == K"module" throw(LoweringError(ex, "`module` is only allowed at top level")) elseif k == K"import" || k == K"using" expand_import_or_using(ctx, ex) elseif k == K"export" || k == K"public" expand_public(ctx, ex) elseif k == K"abstract" || k == K"primitive" expand_forms_2(ctx, expand_abstract_or_primitive_type(ctx, ex)) elseif k == K"struct" expand_forms_2(ctx, expand_struct_def(ctx, ex, docs)) elseif k == K"ref" sctx = with_stmts(ctx) (arr, idxs) = expand_ref_components(sctx, ex) expand_forms_2(ctx, @ast(ctx, ex, [K"block"; sctx.stmts...; [K"call"; "getindex"::K"top"; arr; idxs...]])) elseif k == K"curly" expand_forms_2(ctx, expand_curly(ctx, ex)) elseif k == K"toplevel" ex2 = @ast(ctx, ex, [K"block"; [K"assert" "toplevel_only"::K"Symbol" [K"inert" ex]]; [K"call"; eval::K"Value"; ctx.mod::K"Value"; [K"inert" ex]; [K"parameters"; [K"="; "expr_compat_mode"::K"Identifier"; ctx.expr_compat_mode::K"Bool"]]]]) expand_forms_2(ctx, ex2) elseif k == K"vect" check_no_parameters(ex, "unexpected semicolon in array expression") expand_array(ctx, ex, "vect") elseif k == K"hcat" expand_array(ctx, ex, "hcat") elseif k == K"typed_hcat" expand_array(ctx, ex, "typed_hcat") elseif k == K"opaque_closure" expand_forms_2(ctx, expand_opaque_closure(ctx, ex)) elseif k == K"vcat" || k == K"typed_vcat" expand_forms_2(ctx, expand_vcat(ctx, ex)) elseif k == K"ncat" || k == K"typed_ncat" expand_forms_2(ctx, expand_ncat(ctx, ex)) elseif k == K"while" @chk numchildren(ex) == 2 @ast ctx ex [K"break_block" "loop_exit"::K"symbolic_label"; [K"_while"; expand_condition(ctx, ex[1]); [K"break_block" "loop_cont"::K"symbolic_label"; [(K"scope_block")(scope_type = :neutral); expand_forms_2(ctx, ex[2])]]]] elseif k == K"inert" ex elseif k == K"gc_preserve" s = ssavar(ctx, ex) r = ssavar(ctx, ex) @ast ctx ex [K"block"; s := [K"gc_preserve_begin" (children(ex))[2:var"end"]...]; r := expand_forms_2(ctx, (children(ex))[1]); [K"gc_preserve_end" s]; r] elseif k == K"&" throw(LoweringError(ex, "invalid syntax")) elseif k == K"$" throw(LoweringError(ex, "`\$` expression outside string or quote")) elseif k == K"..." throw(LoweringError(ex, "`...` expression outside call")) elseif is_leaf(ex) ex elseif k == K"return" if numchildren(ex) == 0 @ast ctx ex [K"return" "nothing"::K"core"] elseif numchildren(ex) == 1 mapchildren((e->begin expand_forms_2(ctx, e) end), ctx, ex) else throw(LoweringError(ex, "More than one argument to return")) end else mapchildren((e->begin expand_forms_2(ctx, e) end), ctx, ex) end elseif k == K"continue" @ast ctx ex [K"break" "loop_cont"::K"symbolic_label"] elseif k == K"comparison" expand_forms_2(ctx, expand_compare_chain(ctx, ex)) elseif k == K"doc" @chk numchildren(ex) == 2 expand_doc(ctx, ex[2], ex) elseif k == K"for" expand_forms_2(ctx, expand_for(ctx, ex)) elseif k == K"comprehension" @chk numchildren(ex) == 1 @chk kind(ex[1]) == K"generator" @ast ctx ex [K"call"; "collect"::K"top"; expand_forms_2(ctx, ex[1])] elseif k == K"typed_comprehension" @chk numchildren(ex) == 2 @chk kind(ex[2]) == K"generator" if numchildren(ex[2]) == 2 && kind((ex[2])[2]) == K"iteration" expand_forms_2(ctx, expand_comprehension_to_loops(ctx, ex)) else @ast ctx ex [K"call"; "collect"::K"top"; expand_forms_2(ctx, ex[1]); expand_forms_2(ctx, ex[2])] end elseif k == K"generator" expand_forms_2(ctx, expand_generator(ctx, ex)) elseif k == K"->" || k == K"do" expand_forms_2(ctx, expand_arrow(ctx, ex)) elseif k == K"function" expand_forms_2(ctx, expand_function_def(ctx, ex, docs)) elseif k == K"macro" @ast ctx ex [K"block"; [K"assert"; "global_toplevel_only"::K"Symbol"; [K"inert" ex]]; expand_forms_2(ctx, expand_macro_def(ctx, ex))] elseif k == K"if" || k == K"elseif" @chk numchildren(ex) >= 2 @ast ctx ex [k; expand_condition(ctx, ex[1]); expand_forms_2(ctx, ex[2:var"end"])...] elseif k == K"let" expand_forms_2(ctx, expand_let(ctx, ex)) elseif k == K"const" expand_const_decl(ctx, ex) elseif k == K"local" || k == K"global" if k == K"global" && kind(ex[1]) == K"const" expand_const_decl(ctx, @ast(ctx, ex, [K"const" [K"global" (ex[1])[1]]])) else expand_decls(ctx, ex) end elseif k == K"where" expand_forms_2(ctx, expand_wheres(ctx, ex)) elseif k == K"braces" || k == K"bracescat" throw(LoweringError(ex, "{ } syntax is reserved for future use")) elseif k == K"string" if numchildren(ex) == 1 && kind(ex[1]) == K"String" ex[1] else @ast ctx ex [K"call"; "string"::K"top"; expand_forms_2(ctx, children(ex))...] end elseif k == K"try" expand_forms_2(ctx, expand_try(ctx, ex)) elseif k == K"tuple" if has_parameters(ex) if numchildren(ex) > 1 throw(LoweringError(ex[var"end"], "unexpected semicolon in tuple - use `,` to separate tuple elements")) end expand_forms_2(ctx, expand_named_tuple(ctx, ex, children(ex[1]))) elseif any_assignment(children(ex)) expand_forms_2(ctx, expand_named_tuple(ctx, ex, children(ex))) else expand_forms_2(ctx, @ast(ctx, ex, [K"call"; "tuple"::K"core"; children(ex)...])) end elseif k == K"$" throw(LoweringError(ex, "`\$` expression outside string or quote block")) elseif k == K"module" throw(LoweringError(ex, "`module` is only allowed at top level")) elseif k == K"import" || k == K"using" expand_import_or_using(ctx, ex) elseif k == K"export" || k == K"public" expand_public(ctx, ex) elseif k == K"abstract" || k == K"primitive" expand_forms_2(ctx, expand_abstract_or_primitive_type(ctx, ex)) elseif k == K"struct" expand_forms_2(ctx, expand_struct_def(ctx, ex, docs)) elseif k == K"ref" sctx = with_stmts(ctx) (arr, idxs) = expand_ref_components(sctx, ex) expand_forms_2(ctx, @ast(ctx, ex, [K"block"; sctx.stmts...; [K"call"; "getindex"::K"top"; arr; idxs...]])) elseif k == K"curly" expand_forms_2(ctx, expand_curly(ctx, ex)) elseif k == K"toplevel" ex2 = @ast(ctx, ex, [K"block"; [K"assert" "toplevel_only"::K"Symbol" [K"inert" ex]]; [K"call"; eval ::K"Value"; ctx.mod ::K"Value"; [K"inert" ex]; [K"parameters"; [K"="; "expr_compat_mode"::K"Identifier"; ctx.expr_compat_mode::K"Bool"]]]]) expand_forms_2(ctx, ex2) elseif k == K"vect" check_no_parameters(ex, "unexpected semicolon in array expression") expand_array(ctx, ex, "vect") elseif k == K"hcat" expand_array(ctx, ex, "hcat") elseif k == K"typed_hcat" expand_array(ctx, ex, "typed_hcat") elseif k == K"opaque_closure" expand_forms_2(ctx, expand_opaque_closure(ctx, ex)) elseif k == K"vcat" || k == K"typed_vcat" expand_forms_2(ctx, expand_vcat(ctx, ex)) elseif k == K"ncat" || k == K"typed_ncat" expand_forms_2(ctx, expand_ncat(ctx, ex)) elseif k == K"while" @chk numchildren(ex) == 2 @ast ctx ex [K"break_block" "loop_exit"::K"symbolic_label"; [K"_while"; expand_condition(ctx, ex[1]); [K"break_block" "loop_cont"::K"symbolic_label"; [(K"scope_block")(scope_type = :neutral); expand_forms_2(ctx, ex[2])]]]] elseif k == K"inert" ex elseif k == K"gc_preserve" s = ssavar(ctx, ex) r = ssavar(ctx, ex) @ast ctx ex [K"block"; s := [K"gc_preserve_begin" (children(ex))[2:var"end"]...]; r := expand_forms_2(ctx, (children(ex))[1]); [K"gc_preserve_end" s]; r] elseif k == K"&" throw(LoweringError(ex, "invalid syntax")) elseif k == K"$" throw(LoweringError(ex, "`\$` expression outside string or quote")) elseif k == K"..." throw(LoweringError(ex, "`...` expression outside call")) elseif is_leaf(ex) ex elseif k == K"return" if numchildren(ex) == 0 @ast ctx ex [K"return" "nothing"::K"core"] elseif numchildren(ex) == 1 mapchildren((e->begin expand_forms_2(ctx, e) end), ctx, ex) else throw(LoweringError(ex, "More than one argument to return")) end else mapchildren((e->begin expand_forms_2(ctx, e) end), ctx, ex) end elseif k == K"continue" @ast ctx ex [K"break" "loop_cont"::K"symbolic_label"] elseif k == K"comparison" expand_forms_2(ctx, expand_compare_chain(ctx, ex)) elseif k == K"doc" @chk numchildren(ex) == 2 expand_doc(ctx, ex[2], ex) elseif k == K"for" expand_forms_2(ctx, expand_for(ctx, ex)) elseif k == K"comprehension" @chk numchildren(ex) == 1 @chk kind(ex[1]) == K"generator" @ast ctx ex [K"call"; "collect"::K"top"; expand_forms_2(ctx, ex[1])] elseif k == K"typed_comprehension" @chk numchildren(ex) == 2 @chk kind(ex[2]) == K"generator" if numchildren(ex[2]) == 2 && kind((ex[2])[2]) == K"iteration" expand_forms_2(ctx, expand_comprehension_to_loops(ctx, ex)) else @ast ctx ex [K"call"; "collect"::K"top"; expand_forms_2(ctx, ex[1]); expand_forms_2(ctx, ex[2])] end elseif k == K"generator" expand_forms_2(ctx, expand_generator(ctx, ex)) elseif k == K"->" || k == K"do" expand_forms_2(ctx, expand_arrow(ctx, ex)) elseif k == K"function" expand_forms_2(ctx, expand_function_def(ctx, ex, docs)) elseif k == K"macro" @ast ctx ex [K"block"; [K"assert"; "global_toplevel_only"::K"Symbol"; [K"inert" ex]]; expand_forms_2(ctx, expand_macro_def(ctx, ex))] elseif k == K"if" || k == K"elseif" @chk numchildren(ex) >= 2 @ast ctx ex [k; expand_condition(ctx, ex[1]); expand_forms_2(ctx, ex[2:var"end"])...] elseif k == K"let" expand_forms_2(ctx, expand_let(ctx, ex)) elseif k == K"const" expand_const_decl(ctx, ex) elseif k == K"local" || k == K"global" if k == K"global" && kind(ex[1]) == K"const" expand_const_decl(ctx, @ast(ctx, ex, [K"const" [K"global" (ex[1])[1]]])) else expand_decls(ctx, ex) end elseif k == K"where" expand_forms_2(ctx, expand_wheres(ctx, ex)) elseif k == K"braces" || k == K"bracescat" throw(LoweringError(ex, "{ } syntax is reserved for future use")) elseif k == K"string" if numchildren(ex) == 1 && kind(ex[1]) == K"String" ex[1] else @ast ctx ex [K"call"; "string"::K"top"; expand_forms_2(ctx, children(ex))...] end elseif k == K"try" expand_forms_2(ctx, expand_try(ctx, ex)) elseif k == K"tuple" if has_parameters(ex) if numchildren(ex) > 1 throw(LoweringError(ex[var"end"], "unexpected semicolon in tuple - use `,` to separate tuple elements")) end expand_forms_2(ctx, expand_named_tuple(ctx, ex, children(ex[1]))) elseif any_assignment(children(ex)) expand_forms_2(ctx, expand_named_tuple(ctx, ex, children(ex))) else expand_forms_2(ctx, @ast(ctx, ex, [K"call"; "tuple"::K"core"; children(ex)...])) end elseif k == K"$" throw(LoweringError(ex, "`\$` expression outside string or quote block")) elseif k == K"module" throw(LoweringError(ex, "`module` is only allowed at top level")) elseif k == K"import" || k == K"using" expand_import_or_using(ctx, ex) elseif k == K"export" || k == K"public" expand_public(ctx, ex) elseif k == K"abstract" || k == K"primitive" expand_forms_2(ctx, expand_abstract_or_primitive_type(ctx, ex)) elseif k == K"struct" expand_forms_2(ctx, expand_struct_def(ctx, ex, docs)) elseif k == K"ref" sctx = with_stmts(ctx) (arr, idxs) = expand_ref_components(sctx, ex) expand_forms_2(ctx, @ast(ctx, ex, [K"block"; sctx.stmts...; [K"call"; "getindex"::K"top"; arr; idxs...]])) elseif k == K"curly" expand_forms_2(ctx, expand_curly(ctx, ex)) elseif k == K"toplevel" ex2 = @ast(ctx, ex, [K"block"; [K"assert" "toplevel_only"::K"Symbol" [K"inert" ex]]; [K"call"; eval::K"Value"; ctx.mod::K"Value"; [K"inert" ex]; [K"parameters"; [K"="; "expr_compat_mode"::K"Identifier"; ctx.expr_compat_mode::K"Bool"]]]]) expand_forms_2(ctx, ex2) elseif k == K"vect" check_no_parameters(ex, "unexpected semicolon in array expression") expand_array(ctx, ex, "vect") elseif k == K"hcat" expand_array(ctx, ex, "hcat") elseif k == K"typed_hcat" expand_array(ctx, ex, "typed_hcat") elseif k == K"opaque_closure" expand_forms_2(ctx, expand_opaque_closure(ctx, ex)) elseif k == K"vcat" || k == K"typed_vcat" expand_forms_2(ctx, expand_vcat(ctx, ex)) elseif k == K"ncat" || k == K"typed_ncat" expand_forms_2(ctx, expand_ncat(ctx, ex)) elseif k == K"while" @chk numchildren(ex) == 2 @ast ctx ex [K"break_block" "loop_exit"::K"symbolic_label"; [K"_while"; expand_condition(ctx, ex[1]); [K"break_block" "loop_cont"::K"symbolic_label"; [(K"scope_block")(scope_type = :neutral); expand_forms_2(ctx, ex[2])]]]] elseif k == K"inert" ex elseif k == K"gc_preserve" s = ssavar(ctx, ex) r = ssavar(ctx, ex) @ast ctx ex [K"block"; s := [K"gc_preserve_begin" (children(ex))[2:var"end"]...]; r := expand_forms_2(ctx, (children(ex))[1]); [K"gc_preserve_end" s]; r] elseif k == K"&" throw(LoweringError(ex, "invalid syntax")) elseif k == K"$" throw(LoweringError(ex, "`\$` expression outside string or quote")) elseif k == K"..." throw(LoweringError(ex, "`...` expression outside call")) elseif is_leaf(ex) ex elseif k == K"return" if numchildren(ex) == 0 @ast ctx ex [K"return" "nothing"::K"core"] elseif numchildren(ex) == 1 mapchildren((e->begin expand_forms_2(ctx, e) end), ctx, ex) else throw(LoweringError(ex, "More than one argument to return")) end else mapchildren((e->begin expand_forms_2(ctx, e) end), ctx, ex) end elseif k == K"break" if numchildren(ex) > 0 ex else @ast ctx ex [K"break" "loop_exit"::K"symbolic_label"] end elseif k == K"continue" @ast ctx ex [K"break" "loop_cont"::K"symbolic_label"] elseif k == K"comparison" expand_forms_2(ctx, expand_compare_chain(ctx, ex)) elseif k == K"doc" @chk numchildren(ex) == 2 expand_doc(ctx, ex[2], ex) elseif k == K"for" expand_forms_2(ctx, expand_for(ctx, ex)) elseif k == K"comprehension" @chk numchildren(ex) == 1 @chk kind(ex[1]) == K"generator" @ast ctx ex [K"call"; "collect"::K"top"; expand_forms_2(ctx, ex[1])] elseif k == K"typed_comprehension" @chk numchildren(ex) == 2 @chk kind(ex[2]) == K"generator" if numchildren(ex[2]) == 2 && kind((ex[2])[2]) == K"iteration" expand_forms_2(ctx, expand_comprehension_to_loops(ctx, ex)) else @ast ctx ex [K"call"; "collect"::K"top"; expand_forms_2(ctx, ex[1]); expand_forms_2(ctx, ex[2])] end elseif k == K"generator" expand_forms_2(ctx, expand_generator(ctx, ex)) elseif k == K"->" || k == K"do" expand_forms_2(ctx, expand_arrow(ctx, ex)) elseif k == K"function" expand_forms_2(ctx, expand_function_def(ctx, ex, docs)) elseif k == K"macro" @ast ctx ex [K"block"; [K"assert"; "global_toplevel_only"::K"Symbol"; [K"inert" ex]]; expand_forms_2(ctx, expand_macro_def(ctx, ex))] elseif k == K"if" || k == K"elseif" @chk numchildren(ex) >= 2 @ast ctx ex [k; expand_condition(ctx, ex[1]); expand_forms_2(ctx, ex[2:var"end"])...] elseif k == K"let" expand_forms_2(ctx, expand_let(ctx, ex)) elseif k == K"const" expand_const_decl(ctx, ex) elseif k == K"local" || k == K"global" if k == K"global" && kind(ex[1]) == K"const" expand_const_decl(ctx, @ast(ctx, ex, [K"const" [K"global" (ex[1])[1]]])) else expand_decls(ctx, ex) end elseif k == K"where" expand_forms_2(ctx, expand_wheres(ctx, ex)) elseif k == K"braces" || k == K"bracescat" throw(LoweringError(ex, "{ } syntax is reserved for future use")) elseif k == K"string" if numchildren(ex) == 1 && kind(ex[1]) == K"String" ex[1] else @ast ctx ex [K"call"; "string"::K"top"; expand_forms_2(ctx, children(ex))...] end elseif k == K"try" expand_forms_2(ctx, expand_try(ctx, ex)) elseif k == K"tuple" if has_parameters(ex) if numchildren(ex) > 1 throw(LoweringError(ex[var"end"], "unexpected semicolon in tuple - use `,` to separate tuple elements")) end expand_forms_2(ctx, expand_named_tuple(ctx, ex, children(ex[1]))) elseif any_assignment(children(ex)) expand_forms_2(ctx, expand_named_tuple(ctx, ex, children(ex))) else expand_forms_2(ctx, @ast(ctx, ex, [K"call"; "tuple"::K"core"; children(ex)...])) end elseif k == K"$" throw(LoweringError(ex, "`\$` expression outside string or quote block")) elseif k == K"module" throw(LoweringError(ex, "`module` is only allowed at top level")) elseif k == K"import" || k == K"using" expand_import_or_using(ctx, ex) elseif k == K"export" || k == K"public" expand_public(ctx, ex) elseif k == K"abstract" || k == K"primitive" expand_forms_2(ctx, expand_abstract_or_primitive_type(ctx, ex)) elseif k == K"struct" expand_forms_2(ctx, expand_struct_def(ctx, ex, docs)) elseif k == K"ref" sctx = with_stmts(ctx) (arr, idxs) = expand_ref_components(sctx, ex) expand_forms_2(ctx, @ast(ctx, ex, [K"block"; sctx.stmts...; [K"call"; "getindex"::K"top"; arr; idxs...]])) elseif k == K"curly" expand_forms_2(ctx, expand_curly(ctx, ex)) elseif k == K"toplevel" ex2 = @ast(ctx, ex, [K"block"; [K"assert" "toplevel_only"::K"Symbol" [K"inert" ex]]; [K"call"; eval ::K"Value"; ctx.mod ::K"Value"; [K"inert" ex]; [K"parameters"; [K"="; "expr_compat_mode"::K"Identifier"; ctx.expr_compat_mode::K"Bool"]]]]) expand_forms_2(ctx, ex2) elseif k == K"vect" check_no_parameters(ex, "unexpected semicolon in array expression") expand_array(ctx, ex, "vect") elseif k == K"hcat" expand_array(ctx, ex, "hcat") elseif k == K"typed_hcat" expand_array(ctx, ex, "typed_hcat") elseif k == K"opaque_closure" expand_forms_2(ctx, expand_opaque_closure(ctx, ex)) elseif k == K"vcat" || k == K"typed_vcat" expand_forms_2(ctx, expand_vcat(ctx, ex)) elseif k == K"ncat" || k == K"typed_ncat" expand_forms_2(ctx, expand_ncat(ctx, ex)) elseif k == K"while" @chk numchildren(ex) == 2 @ast ctx ex [K"break_block" "loop_exit"::K"symbolic_label"; [K"_while"; expand_condition(ctx, ex[1]); [K"break_block" "loop_cont"::K"symbolic_label"; [(K"scope_block")(scope_type = :neutral); expand_forms_2(ctx, ex[2])]]]] elseif k == K"inert" ex elseif k == K"gc_preserve" s = ssavar(ctx, ex) r = ssavar(ctx, ex) @ast ctx ex [K"block"; s := [K"gc_preserve_begin" (children(ex))[2:var"end"]...]; r := expand_forms_2(ctx, (children(ex))[1]); [K"gc_preserve_end" s]; r] elseif k == K"&" throw(LoweringError(ex, "invalid syntax")) elseif k == K"$" throw(LoweringError(ex, "`\$` expression outside string or quote")) elseif k == K"..." throw(LoweringError(ex, "`...` expression outside call")) elseif is_leaf(ex) ex elseif k == K"return" if numchildren(ex) == 0 @ast ctx ex [K"return" "nothing"::K"core"] elseif numchildren(ex) == 1 mapchildren((e->begin expand_forms_2(ctx, e) end), ctx, ex) else throw(LoweringError(ex, "More than one argument to return")) end else mapchildren((e->begin expand_forms_2(ctx, e) end), ctx, ex) end elseif k == K"break" if numchildren(ex) > 0 ex else @ast ctx ex [K"break" "loop_exit"::K"symbolic_label"] end elseif k == K"continue" @ast ctx ex [K"break" "loop_cont"::K"symbolic_label"] elseif k == K"comparison" expand_forms_2(ctx, expand_compare_chain(ctx, ex)) elseif k == K"doc" @chk numchildren(ex) == 2 expand_doc(ctx, ex[2], ex) elseif k == K"for" expand_forms_2(ctx, expand_for(ctx, ex)) elseif k == K"comprehension" @chk numchildren(ex) == 1 @chk kind(ex[1]) == K"generator" @ast ctx ex [K"call"; "collect"::K"top"; expand_forms_2(ctx, ex[1])] elseif k == K"typed_comprehension" @chk numchildren(ex) == 2 @chk kind(ex[2]) == K"generator" if numchildren(ex[2]) == 2 && kind((ex[2])[2]) == K"iteration" expand_forms_2(ctx, expand_comprehension_to_loops(ctx, ex)) else @ast ctx ex [K"call"; "collect"::K"top"; expand_forms_2(ctx, ex[1]); expand_forms_2(ctx, ex[2])] end elseif k == K"generator" expand_forms_2(ctx, expand_generator(ctx, ex)) elseif k == K"->" || k == K"do" expand_forms_2(ctx, expand_arrow(ctx, ex)) elseif k == K"function" expand_forms_2(ctx, expand_function_def(ctx, ex, docs)) elseif k == K"macro" @ast ctx ex [K"block"; [K"assert"; "global_toplevel_only"::K"Symbol"; [K"inert" ex]]; expand_forms_2(ctx, expand_macro_def(ctx, ex))] elseif k == K"if" || k == K"elseif" @chk numchildren(ex) >= 2 @ast ctx ex [k; expand_condition(ctx, ex[1]); expand_forms_2(ctx, ex[2:var"end"])...] elseif k == K"let" expand_forms_2(ctx, expand_let(ctx, ex)) elseif k == K"const" expand_const_decl(ctx, ex) elseif k == K"local" || k == K"global" if k == K"global" && kind(ex[1]) == K"const" expand_const_decl(ctx, @ast(ctx, ex, [K"const" [K"global" (ex[1])[1]]])) else expand_decls(ctx, ex) end elseif k == K"where" expand_forms_2(ctx, expand_wheres(ctx, ex)) elseif k == K"braces" || k == K"bracescat" throw(LoweringError(ex, "{ } syntax is reserved for future use")) elseif k == K"string" if numchildren(ex) == 1 && kind(ex[1]) == K"String" ex[1] else @ast ctx ex [K"call"; "string"::K"top"; expand_forms_2(ctx, children(ex))...] end elseif k == K"try" expand_forms_2(ctx, expand_try(ctx, ex)) elseif k == K"tuple" if has_parameters(ex) if numchildren(ex) > 1 throw(LoweringError(ex[var"end"], "unexpected semicolon in tuple - use `,` to separate tuple elements")) end expand_forms_2(ctx, expand_named_tuple(ctx, ex, children(ex[1]))) elseif any_assignment(children(ex)) expand_forms_2(ctx, expand_named_tuple(ctx, ex, children(ex))) else expand_forms_2(ctx, @ast(ctx, ex, [K"call"; "tuple"::K"core"; children(ex)...])) end elseif k == K"$" throw(LoweringError(ex, "`\$` expression outside string or quote block")) elseif k == K"module" throw(LoweringError(ex, "`module` is only allowed at top level")) elseif k == K"import" || k == K"using" expand_import_or_using(ctx, ex) elseif k == K"export" || k == K"public" expand_public(ctx, ex) elseif k == K"abstract" || k == K"primitive" expand_forms_2(ctx, expand_abstract_or_primitive_type(ctx, ex)) elseif k == K"struct" expand_forms_2(ctx, expand_struct_def(ctx, ex, docs)) elseif k == K"ref" sctx = with_stmts(ctx) (arr, idxs) = expand_ref_components(sctx, ex) expand_forms_2(ctx, @ast(ctx, ex, [K"block"; sctx.stmts...; [K"call"; "getindex"::K"top"; arr; idxs...]])) elseif k == K"curly" expand_forms_2(ctx, expand_curly(ctx, ex)) elseif k == K"toplevel" ex2 = @ast(ctx, ex, [K"block"; [K"assert" "toplevel_only"::K"Symbol" [K"inert" ex]]; [K"call"; eval::K"Value"; ctx.mod::K"Value"; [K"inert" ex]; [K"parameters"; [K"="; "expr_compat_mode"::K"Identifier"; ctx.expr_compat_mode::K"Bool"]]]]) expand_forms_2(ctx, ex2) elseif k == K"vect" check_no_parameters(ex, "unexpected semicolon in array expression") expand_array(ctx, ex, "vect") elseif k == K"hcat" expand_array(ctx, ex, "hcat") elseif k == K"typed_hcat" expand_array(ctx, ex, "typed_hcat") elseif k == K"opaque_closure" expand_forms_2(ctx, expand_opaque_closure(ctx, ex)) elseif k == K"vcat" || k == K"typed_vcat" expand_forms_2(ctx, expand_vcat(ctx, ex)) elseif k == K"ncat" || k == K"typed_ncat" expand_forms_2(ctx, expand_ncat(ctx, ex)) elseif k == K"while" @chk numchildren(ex) == 2 @ast ctx ex [K"break_block" "loop_exit"::K"symbolic_label"; [K"_while"; expand_condition(ctx, ex[1]); [K"break_block" "loop_cont"::K"symbolic_label"; [(K"scope_block")(scope_type = :neutral); expand_forms_2(ctx, ex[2])]]]] elseif k == K"inert" ex elseif k == K"gc_preserve" s = ssavar(ctx, ex) r = ssavar(ctx, ex) @ast ctx ex [K"block"; s := [K"gc_preserve_begin" (children(ex))[2:var"end"]...]; r := expand_forms_2(ctx, (children(ex))[1]); [K"gc_preserve_end" s]; r] elseif k == K"&" throw(LoweringError(ex, "invalid syntax")) elseif k == K"$" throw(LoweringError(ex, "`\$` expression outside string or quote")) elseif k == K"..." throw(LoweringError(ex, "`...` expression outside call")) elseif is_leaf(ex) ex elseif k == K"return" if numchildren(ex) == 0 @ast ctx ex [K"return" "nothing"::K"core"] elseif numchildren(ex) == 1 mapchildren((e->begin expand_forms_2(ctx, e) end), ctx, ex) else throw(LoweringError(ex, "More than one argument to return")) end else mapchildren((e->begin expand_forms_2(ctx, e) end), ctx, ex) end elseif k == K"=" expand_assignment(ctx, ex) elseif k == K"break" if numchildren(ex) > 0 ex else @ast ctx ex [K"break" "loop_exit"::K"symbolic_label"] end elseif k == K"continue" @ast ctx ex [K"break" "loop_cont"::K"symbolic_label"] elseif k == K"comparison" expand_forms_2(ctx, expand_compare_chain(ctx, ex)) elseif k == K"doc" @chk numchildren(ex) == 2 expand_doc(ctx, ex[2], ex) elseif k == K"for" expand_forms_2(ctx, expand_for(ctx, ex)) elseif k == K"comprehension" @chk numchildren(ex) == 1 @chk kind(ex[1]) == K"generator" @ast ctx ex [K"call"; "collect"::K"top"; expand_forms_2(ctx, ex[1])] elseif k == K"typed_comprehension" @chk numchildren(ex) == 2 @chk kind(ex[2]) == K"generator" if numchildren(ex[2]) == 2 && kind((ex[2])[2]) == K"iteration" expand_forms_2(ctx, expand_comprehension_to_loops(ctx, ex)) else @ast ctx ex [K"call"; "collect"::K"top"; expand_forms_2(ctx, ex[1]); expand_forms_2(ctx, ex[2])] end elseif k == K"generator" expand_forms_2(ctx, expand_generator(ctx, ex)) elseif k == K"->" || k == K"do" expand_forms_2(ctx, expand_arrow(ctx, ex)) elseif k == K"function" expand_forms_2(ctx, expand_function_def(ctx, ex, docs)) elseif k == K"macro" @ast ctx ex [K"block"; [K"assert"; "global_toplevel_only"::K"Symbol"; [K"inert" ex]]; expand_forms_2(ctx, expand_macro_def(ctx, ex))] elseif k == K"if" || k == K"elseif" @chk numchildren(ex) >= 2 @ast ctx ex [k; expand_condition(ctx, ex[1]); expand_forms_2(ctx, ex[2:var"end"])...] elseif k == K"let" expand_forms_2(ctx, expand_let(ctx, ex)) elseif k == K"const" expand_const_decl(ctx, ex) elseif k == K"local" || k == K"global" if k == K"global" && kind(ex[1]) == K"const" expand_const_decl(ctx, @ast(ctx, ex, [K"const" [K"global" (ex[1])[1]]])) else expand_decls(ctx, ex) end elseif k == K"where" expand_forms_2(ctx, expand_wheres(ctx, ex)) elseif k == K"braces" || k == K"bracescat" throw(LoweringError(ex, "{ } syntax is reserved for future use")) elseif k == K"string" if numchildren(ex) == 1 && kind(ex[1]) == K"String" ex[1] else @ast ctx ex [K"call"; "string"::K"top"; expand_forms_2(ctx, children(ex))...] end elseif k == K"try" expand_forms_2(ctx, expand_try(ctx, ex)) elseif k == K"tuple" if has_parameters(ex) if numchildren(ex) > 1 throw(LoweringError(ex[var"end"], "unexpected semicolon in tuple - use `,` to separate tuple elements")) end expand_forms_2(ctx, expand_named_tuple(ctx, ex, children(ex[1]))) elseif any_assignment(children(ex)) expand_forms_2(ctx, expand_named_tuple(ctx, ex, children(ex))) else expand_forms_2(ctx, @ast(ctx, ex, [K"call"; "tuple"::K"core"; children(ex)...])) end elseif k == K"$" throw(LoweringError(ex, "`\$` expression outside string or quote block")) elseif k == K"module" throw(LoweringError(ex, "`module` is only allowed at top level")) elseif k == K"import" || k == K"using" expand_import_or_using(ctx, ex) elseif k == K"export" || k == K"public" expand_public(ctx, ex) elseif k == K"abstract" || k == K"primitive" expand_forms_2(ctx, expand_abstract_or_primitive_type(ctx, ex)) elseif k == K"struct" expand_forms_2(ctx, expand_struct_def(ctx, ex, docs)) elseif k == K"ref" sctx = with_stmts(ctx) (arr, idxs) = expand_ref_components(sctx, ex) expand_forms_2(ctx, @ast(ctx, ex, [K"block"; sctx.stmts...; [K"call"; "getindex"::K"top"; arr; idxs...]])) elseif k == K"curly" expand_forms_2(ctx, expand_curly(ctx, ex)) elseif k == K"toplevel" ex2 = @ast(ctx, ex, [K"block"; [K"assert" "toplevel_only"::K"Symbol" [K"inert" ex]]; [K"call"; eval ::K"Value"; ctx.mod ::K"Value"; [K"inert" ex]; [K"parameters"; [K"="; "expr_compat_mode"::K"Identifier"; ctx.expr_compat_mode::K"Bool"]]]]) expand_forms_2(ctx, ex2) elseif k == K"vect" check_no_parameters(ex, "unexpected semicolon in array expression") expand_array(ctx, ex, "vect") elseif k == K"hcat" expand_array(ctx, ex, "hcat") elseif k == K"typed_hcat" expand_array(ctx, ex, "typed_hcat") elseif k == K"opaque_closure" expand_forms_2(ctx, expand_opaque_closure(ctx, ex)) elseif k == K"vcat" || k == K"typed_vcat" expand_forms_2(ctx, expand_vcat(ctx, ex)) elseif k == K"ncat" || k == K"typed_ncat" expand_forms_2(ctx, expand_ncat(ctx, ex)) elseif k == K"while" @chk numchildren(ex) == 2 @ast ctx ex [K"break_block" "loop_exit"::K"symbolic_label"; [K"_while"; expand_condition(ctx, ex[1]); [K"break_block" "loop_cont"::K"symbolic_label"; [(K"scope_block")(scope_type = :neutral); expand_forms_2(ctx, ex[2])]]]] elseif k == K"inert" ex elseif k == K"gc_preserve" s = ssavar(ctx, ex) r = ssavar(ctx, ex) @ast ctx ex [K"block"; s := [K"gc_preserve_begin" (children(ex))[2:var"end"]...]; r := expand_forms_2(ctx, (children(ex))[1]); [K"gc_preserve_end" s]; r] elseif k == K"&" throw(LoweringError(ex, "invalid syntax")) elseif k == K"$" throw(LoweringError(ex, "`\$` expression outside string or quote")) elseif k == K"..." throw(LoweringError(ex, "`...` expression outside call")) elseif is_leaf(ex) ex elseif k == K"return" if numchildren(ex) == 0 @ast ctx ex [K"return" "nothing"::K"core"] elseif numchildren(ex) == 1 mapchildren((e->begin expand_forms_2(ctx, e) end), ctx, ex) else throw(LoweringError(ex, "More than one argument to return")) end else mapchildren((e->begin expand_forms_2(ctx, e) end), ctx, ex) end elseif k == K"=" expand_assignment(ctx, ex) elseif k == K"break" if numchildren(ex) > 0 ex else @ast ctx ex [K"break" "loop_exit"::K"symbolic_label"] end elseif k == K"continue" @ast ctx ex [K"break" "loop_cont"::K"symbolic_label"] elseif k == K"comparison" expand_forms_2(ctx, expand_compare_chain(ctx, ex)) elseif k == K"doc" @chk numchildren(ex) == 2 expand_doc(ctx, ex[2], ex) elseif k == K"for" expand_forms_2(ctx, expand_for(ctx, ex)) elseif k == K"comprehension" @chk numchildren(ex) == 1 @chk kind(ex[1]) == K"generator" @ast ctx ex [K"call"; "collect"::K"top"; expand_forms_2(ctx, ex[1])] elseif k == K"typed_comprehension" @chk numchildren(ex) == 2 @chk kind(ex[2]) == K"generator" if numchildren(ex[2]) == 2 && kind((ex[2])[2]) == K"iteration" expand_forms_2(ctx, expand_comprehension_to_loops(ctx, ex)) else @ast ctx ex [K"call"; "collect"::K"top"; expand_forms_2(ctx, ex[1]); expand_forms_2(ctx, ex[2])] end elseif k == K"generator" expand_forms_2(ctx, expand_generator(ctx, ex)) elseif k == K"->" || k == K"do" expand_forms_2(ctx, expand_arrow(ctx, ex)) elseif k == K"function" expand_forms_2(ctx, expand_function_def(ctx, ex, docs)) elseif k == K"macro" @ast ctx ex [K"block"; [K"assert"; "global_toplevel_only"::K"Symbol"; [K"inert" ex]]; expand_forms_2(ctx, expand_macro_def(ctx, ex))] elseif k == K"if" || k == K"elseif" @chk numchildren(ex) >= 2 @ast ctx ex [k; expand_condition(ctx, ex[1]); expand_forms_2(ctx, ex[2:var"end"])...] elseif k == K"let" expand_forms_2(ctx, expand_let(ctx, ex)) elseif k == K"const" expand_const_decl(ctx, ex) elseif k == K"local" || k == K"global" if k == K"global" && kind(ex[1]) == K"const" expand_const_decl(ctx, @ast(ctx, ex, [K"const" [K"global" (ex[1])[1]]])) else expand_decls(ctx, ex) end elseif k == K"where" expand_forms_2(ctx, expand_wheres(ctx, ex)) elseif k == K"braces" || k == K"bracescat" throw(LoweringError(ex, "{ } syntax is reserved for future use")) elseif k == K"string" if numchildren(ex) == 1 && kind(ex[1]) == K"String" ex[1] else @ast ctx ex [K"call"; "string"::K"top"; expand_forms_2(ctx, children(ex))...] end elseif k == K"try" expand_forms_2(ctx, expand_try(ctx, ex)) elseif k == K"tuple" if has_parameters(ex) if numchildren(ex) > 1 throw(LoweringError(ex[var"end"], "unexpected semicolon in tuple - use `,` to separate tuple elements")) end expand_forms_2(ctx, expand_named_tuple(ctx, ex, children(ex[1]))) elseif any_assignment(children(ex)) expand_forms_2(ctx, expand_named_tuple(ctx, ex, children(ex))) else expand_forms_2(ctx, @ast(ctx, ex, [K"call"; "tuple"::K"core"; children(ex)...])) end elseif k == K"$" throw(LoweringError(ex, "`\$` expression outside string or quote block")) elseif k == K"module" throw(LoweringError(ex, "`module` is only allowed at top level")) elseif k == K"import" || k == K"using" expand_import_or_using(ctx, ex) elseif k == K"export" || k == K"public" expand_public(ctx, ex) elseif k == K"abstract" || k == K"primitive" expand_forms_2(ctx, expand_abstract_or_primitive_type(ctx, ex)) elseif k == K"struct" expand_forms_2(ctx, expand_struct_def(ctx, ex, docs)) elseif k == K"ref" sctx = with_stmts(ctx) (arr, idxs) = expand_ref_components(sctx, ex) expand_forms_2(ctx, @ast(ctx, ex, [K"block"; sctx.stmts...; [K"call"; "getindex"::K"top"; arr; idxs...]])) elseif k == K"curly" expand_forms_2(ctx, expand_curly(ctx, ex)) elseif k == K"toplevel" ex2 = @ast(ctx, ex, [K"block"; [K"assert" "toplevel_only"::K"Symbol" [K"inert" ex]]; [K"call"; eval::K"Value"; ctx.mod::K"Value"; [K"inert" ex]; [K"parameters"; [K"="; "expr_compat_mode"::K"Identifier"; ctx.expr_compat_mode::K"Bool"]]]]) expand_forms_2(ctx, ex2) elseif k == K"vect" check_no_parameters(ex, "unexpected semicolon in array expression") expand_array(ctx, ex, "vect") elseif k == K"hcat" expand_array(ctx, ex, "hcat") elseif k == K"typed_hcat" expand_array(ctx, ex, "typed_hcat") elseif k == K"opaque_closure" expand_forms_2(ctx, expand_opaque_closure(ctx, ex)) elseif k == K"vcat" || k == K"typed_vcat" expand_forms_2(ctx, expand_vcat(ctx, ex)) elseif k == K"ncat" || k == K"typed_ncat" expand_forms_2(ctx, expand_ncat(ctx, ex)) elseif k == K"while" @chk numchildren(ex) == 2 @ast ctx ex [K"break_block" "loop_exit"::K"symbolic_label"; [K"_while"; expand_condition(ctx, ex[1]); [K"break_block" "loop_cont"::K"symbolic_label"; [(K"scope_block")(scope_type = :neutral); expand_forms_2(ctx, ex[2])]]]] elseif k == K"inert" ex elseif k == K"gc_preserve" s = ssavar(ctx, ex) r = ssavar(ctx, ex) @ast ctx ex [K"block"; s := [K"gc_preserve_begin" (children(ex))[2:var"end"]...]; r := expand_forms_2(ctx, (children(ex))[1]); [K"gc_preserve_end" s]; r] elseif k == K"&" throw(LoweringError(ex, "invalid syntax")) elseif k == K"$" throw(LoweringError(ex, "`\$` expression outside string or quote")) elseif k == K"..." throw(LoweringError(ex, "`...` expression outside call")) elseif is_leaf(ex) ex elseif k == K"return" if numchildren(ex) == 0 @ast ctx ex [K"return" "nothing"::K"core"] elseif numchildren(ex) == 1 mapchildren((e->begin expand_forms_2(ctx, e) end), ctx, ex) else throw(LoweringError(ex, "More than one argument to return")) end else mapchildren((e->begin expand_forms_2(ctx, e) end), ctx, ex) end elseif k == K"op=" || k == K".op=" expand_forms_2(ctx, expand_update_operator(ctx, ex)) elseif k == K"=" expand_assignment(ctx, ex) elseif k == K"break" if numchildren(ex) > 0 ex else @ast ctx ex [K"break" "loop_exit"::K"symbolic_label"] end elseif k == K"continue" @ast ctx ex [K"break" "loop_cont"::K"symbolic_label"] elseif k == K"comparison" expand_forms_2(ctx, expand_compare_chain(ctx, ex)) elseif k == K"doc" @chk numchildren(ex) == 2 expand_doc(ctx, ex[2], ex) elseif k == K"for" expand_forms_2(ctx, expand_for(ctx, ex)) elseif k == K"comprehension" @chk numchildren(ex) == 1 @chk kind(ex[1]) == K"generator" @ast ctx ex [K"call"; "collect"::K"top"; expand_forms_2(ctx, ex[1])] elseif k == K"typed_comprehension" @chk numchildren(ex) == 2 @chk kind(ex[2]) == K"generator" if numchildren(ex[2]) == 2 && kind((ex[2])[2]) == K"iteration" expand_forms_2(ctx, expand_comprehension_to_loops(ctx, ex)) else @ast ctx ex [K"call"; "collect"::K"top"; expand_forms_2(ctx, ex[1]); expand_forms_2(ctx, ex[2])] end elseif k == K"generator" expand_forms_2(ctx, expand_generator(ctx, ex)) elseif k == K"->" || k == K"do" expand_forms_2(ctx, expand_arrow(ctx, ex)) elseif k == K"function" expand_forms_2(ctx, expand_function_def(ctx, ex, docs)) elseif k == K"macro" @ast ctx ex [K"block"; [K"assert"; "global_toplevel_only"::K"Symbol"; [K"inert" ex]]; expand_forms_2(ctx, expand_macro_def(ctx, ex))] elseif k == K"if" || k == K"elseif" @chk numchildren(ex) >= 2 @ast ctx ex [k; expand_condition(ctx, ex[1]); expand_forms_2(ctx, ex[2:var"end"])...] elseif k == K"let" expand_forms_2(ctx, expand_let(ctx, ex)) elseif k == K"const" expand_const_decl(ctx, ex) elseif k == K"local" || k == K"global" if k == K"global" && kind(ex[1]) == K"const" expand_const_decl(ctx, @ast(ctx, ex, [K"const" [K"global" (ex[1])[1]]])) else expand_decls(ctx, ex) end elseif k == K"where" expand_forms_2(ctx, expand_wheres(ctx, ex)) elseif k == K"braces" || k == K"bracescat" throw(LoweringError(ex, "{ } syntax is reserved for future use")) elseif k == K"string" if numchildren(ex) == 1 && kind(ex[1]) == K"String" ex[1] else @ast ctx ex [K"call"; "string"::K"top"; expand_forms_2(ctx, children(ex))...] end elseif k == K"try" expand_forms_2(ctx, expand_try(ctx, ex)) elseif k == K"tuple" if has_parameters(ex) if numchildren(ex) > 1 throw(LoweringError(ex[var"end"], "unexpected semicolon in tuple - use `,` to separate tuple elements")) end expand_forms_2(ctx, expand_named_tuple(ctx, ex, children(ex[1]))) elseif any_assignment(children(ex)) expand_forms_2(ctx, expand_named_tuple(ctx, ex, children(ex))) else expand_forms_2(ctx, @ast(ctx, ex, [K"call"; "tuple"::K"core"; children(ex)...])) end elseif k == K"$" throw(LoweringError(ex, "`\$` expression outside string or quote block")) elseif k == K"module" throw(LoweringError(ex, "`module` is only allowed at top level")) elseif k == K"import" || k == K"using" expand_import_or_using(ctx, ex) elseif k == K"export" || k == K"public" expand_public(ctx, ex) elseif k == K"abstract" || k == K"primitive" expand_forms_2(ctx, expand_abstract_or_primitive_type(ctx, ex)) elseif k == K"struct" expand_forms_2(ctx, expand_struct_def(ctx, ex, docs)) elseif k == K"ref" sctx = with_stmts(ctx) (arr, idxs) = expand_ref_components(sctx, ex) expand_forms_2(ctx, @ast(ctx, ex, [K"block"; sctx.stmts...; [K"call"; "getindex"::K"top"; arr; idxs...]])) elseif k == K"curly" expand_forms_2(ctx, expand_curly(ctx, ex)) elseif k == K"toplevel" ex2 = @ast(ctx, ex, [K"block"; [K"assert" "toplevel_only"::K"Symbol" [K"inert" ex]]; [K"call"; eval ::K"Value"; ctx.mod ::K"Value"; [K"inert" ex]; [K"parameters"; [K"="; "expr_compat_mode"::K"Identifier"; ctx.expr_compat_mode::K"Bool"]]]]) expand_forms_2(ctx, ex2) elseif k == K"vect" check_no_parameters(ex, "unexpected semicolon in array expression") expand_array(ctx, ex, "vect") elseif k == K"hcat" expand_array(ctx, ex, "hcat") elseif k == K"typed_hcat" expand_array(ctx, ex, "typed_hcat") elseif k == K"opaque_closure" expand_forms_2(ctx, expand_opaque_closure(ctx, ex)) elseif k == K"vcat" || k == K"typed_vcat" expand_forms_2(ctx, expand_vcat(ctx, ex)) elseif k == K"ncat" || k == K"typed_ncat" expand_forms_2(ctx, expand_ncat(ctx, ex)) elseif k == K"while" @chk numchildren(ex) == 2 @ast ctx ex [K"break_block" "loop_exit"::K"symbolic_label"; [K"_while"; expand_condition(ctx, ex[1]); [K"break_block" "loop_cont"::K"symbolic_label"; [(K"scope_block")(scope_type = :neutral); expand_forms_2(ctx, ex[2])]]]] elseif k == K"inert" ex elseif k == K"gc_preserve" s = ssavar(ctx, ex) r = ssavar(ctx, ex) @ast ctx ex [K"block"; s := [K"gc_preserve_begin" (children(ex))[2:var"end"]...]; r := expand_forms_2(ctx, (children(ex))[1]); [K"gc_preserve_end" s]; r] elseif k == K"&" throw(LoweringError(ex, "invalid syntax")) elseif k == K"$" throw(LoweringError(ex, "`\$` expression outside string or quote")) elseif k == K"..." throw(LoweringError(ex, "`...` expression outside call")) elseif is_leaf(ex) ex elseif k == K"return" if numchildren(ex) == 0 @ast ctx ex [K"return" "nothing"::K"core"] elseif numchildren(ex) == 1 mapchildren((e->begin expand_forms_2(ctx, e) end), ctx, ex) else throw(LoweringError(ex, "More than one argument to return")) end else mapchildren((e->begin expand_forms_2(ctx, e) end), ctx, ex) end elseif k == K"op=" || k == K".op=" expand_forms_2(ctx, expand_update_operator(ctx, ex)) elseif k == K"=" expand_assignment(ctx, ex) elseif k == K"break" if numchildren(ex) > 0 ex else @ast ctx ex [K"break" "loop_exit"::K"symbolic_label"] end elseif k == K"continue" @ast ctx ex [K"break" "loop_cont"::K"symbolic_label"] elseif k == K"comparison" expand_forms_2(ctx, expand_compare_chain(ctx, ex)) elseif k == K"doc" @chk numchildren(ex) == 2 expand_doc(ctx, ex[2], ex) elseif k == K"for" expand_forms_2(ctx, expand_for(ctx, ex)) elseif k == K"comprehension" @chk numchildren(ex) == 1 @chk kind(ex[1]) == K"generator" @ast ctx ex [K"call"; "collect"::K"top"; expand_forms_2(ctx, ex[1])] elseif k == K"typed_comprehension" @chk numchildren(ex) == 2 @chk kind(ex[2]) == K"generator" if numchildren(ex[2]) == 2 && kind((ex[2])[2]) == K"iteration" expand_forms_2(ctx, expand_comprehension_to_loops(ctx, ex)) else @ast ctx ex [K"call"; "collect"::K"top"; expand_forms_2(ctx, ex[1]); expand_forms_2(ctx, ex[2])] end elseif k == K"generator" expand_forms_2(ctx, expand_generator(ctx, ex)) elseif k == K"->" || k == K"do" expand_forms_2(ctx, expand_arrow(ctx, ex)) elseif k == K"function" expand_forms_2(ctx, expand_function_def(ctx, ex, docs)) elseif k == K"macro" @ast ctx ex [K"block"; [K"assert"; "global_toplevel_only"::K"Symbol"; [K"inert" ex]]; expand_forms_2(ctx, expand_macro_def(ctx, ex))] elseif k == K"if" || k == K"elseif" @chk numchildren(ex) >= 2 @ast ctx ex [k; expand_condition(ctx, ex[1]); expand_forms_2(ctx, ex[2:var"end"])...] elseif k == K"let" expand_forms_2(ctx, expand_let(ctx, ex)) elseif k == K"const" expand_const_decl(ctx, ex) elseif k == K"local" || k == K"global" if k == K"global" && kind(ex[1]) == K"const" expand_const_decl(ctx, @ast(ctx, ex, [K"const" [K"global" (ex[1])[1]]])) else expand_decls(ctx, ex) end elseif k == K"where" expand_forms_2(ctx, expand_wheres(ctx, ex)) elseif k == K"braces" || k == K"bracescat" throw(LoweringError(ex, "{ } syntax is reserved for future use")) elseif k == K"string" if numchildren(ex) == 1 && kind(ex[1]) == K"String" ex[1] else @ast ctx ex [K"call"; "string"::K"top"; expand_forms_2(ctx, children(ex))...] end elseif k == K"try" expand_forms_2(ctx, expand_try(ctx, ex)) elseif k == K"tuple" if has_parameters(ex) if numchildren(ex) > 1 throw(LoweringError(ex[var"end"], "unexpected semicolon in tuple - use `,` to separate tuple elements")) end expand_forms_2(ctx, expand_named_tuple(ctx, ex, children(ex[1]))) elseif any_assignment(children(ex)) expand_forms_2(ctx, expand_named_tuple(ctx, ex, children(ex))) else expand_forms_2(ctx, @ast(ctx, ex, [K"call"; "tuple"::K"core"; children(ex)...])) end elseif k == K"$" throw(LoweringError(ex, "`\$` expression outside string or quote block")) elseif k == K"module" throw(LoweringError(ex, "`module` is only allowed at top level")) elseif k == K"import" || k == K"using" expand_import_or_using(ctx, ex) elseif k == K"export" || k == K"public" expand_public(ctx, ex) elseif k == K"abstract" || k == K"primitive" expand_forms_2(ctx, expand_abstract_or_primitive_type(ctx, ex)) elseif k == K"struct" expand_forms_2(ctx, expand_struct_def(ctx, ex, docs)) elseif k == K"ref" sctx = with_stmts(ctx) (arr, idxs) = expand_ref_components(sctx, ex) expand_forms_2(ctx, @ast(ctx, ex, [K"block"; sctx.stmts...; [K"call"; "getindex"::K"top"; arr; idxs...]])) elseif k == K"curly" expand_forms_2(ctx, expand_curly(ctx, ex)) elseif k == K"toplevel" ex2 = @ast(ctx, ex, [K"block"; [K"assert" "toplevel_only"::K"Symbol" [K"inert" ex]]; [K"call"; eval::K"Value"; ctx.mod::K"Value"; [K"inert" ex]; [K"parameters"; [K"="; "expr_compat_mode"::K"Identifier"; ctx.expr_compat_mode::K"Bool"]]]]) expand_forms_2(ctx, ex2) elseif k == K"vect" check_no_parameters(ex, "unexpected semicolon in array expression") expand_array(ctx, ex, "vect") elseif k == K"hcat" expand_array(ctx, ex, "hcat") elseif k == K"typed_hcat" expand_array(ctx, ex, "typed_hcat") elseif k == K"opaque_closure" expand_forms_2(ctx, expand_opaque_closure(ctx, ex)) elseif k == K"vcat" || k == K"typed_vcat" expand_forms_2(ctx, expand_vcat(ctx, ex)) elseif k == K"ncat" || k == K"typed_ncat" expand_forms_2(ctx, expand_ncat(ctx, ex)) elseif k == K"while" @chk numchildren(ex) == 2 @ast ctx ex [K"break_block" "loop_exit"::K"symbolic_label"; [K"_while"; expand_condition(ctx, ex[1]); [K"break_block" "loop_cont"::K"symbolic_label"; [(K"scope_block")(scope_type = :neutral); expand_forms_2(ctx, ex[2])]]]] elseif k == K"inert" ex elseif k == K"gc_preserve" s = ssavar(ctx, ex) r = ssavar(ctx, ex) @ast ctx ex [K"block"; s := [K"gc_preserve_begin" (children(ex))[2:var"end"]...]; r := expand_forms_2(ctx, (children(ex))[1]); [K"gc_preserve_end" s]; r] elseif k == K"&" throw(LoweringError(ex, "invalid syntax")) elseif k == K"$" throw(LoweringError(ex, "`\$` expression outside string or quote")) elseif k == K"..." throw(LoweringError(ex, "`...` expression outside call")) elseif is_leaf(ex) ex elseif k == K"return" if numchildren(ex) == 0 @ast ctx ex [K"return" "nothing"::K"core"] elseif numchildren(ex) == 1 mapchildren((e->begin expand_forms_2(ctx, e) end), ctx, ex) else throw(LoweringError(ex, "More than one argument to return")) end else mapchildren((e->begin expand_forms_2(ctx, e) end), ctx, ex) end elseif k == K"<:" || (k == K">:" || k == K"-->") expand_forms_2(ctx, @ast(ctx, ex, [K"call"; adopt_scope(string(k)::K"Identifier", ex); children(ex)...])) elseif k == K"op=" || k == K".op=" expand_forms_2(ctx, expand_update_operator(ctx, ex)) elseif k == K"=" expand_assignment(ctx, ex) elseif k == K"break" if numchildren(ex) > 0 ex else @ast ctx ex [K"break" "loop_exit"::K"symbolic_label"] end elseif k == K"continue" @ast ctx ex [K"break" "loop_cont"::K"symbolic_label"] elseif k == K"comparison" expand_forms_2(ctx, expand_compare_chain(ctx, ex)) elseif k == K"doc" @chk numchildren(ex) == 2 expand_doc(ctx, ex[2], ex) elseif k == K"for" expand_forms_2(ctx, expand_for(ctx, ex)) elseif k == K"comprehension" @chk numchildren(ex) == 1 @chk kind(ex[1]) == K"generator" @ast ctx ex [K"call"; "collect"::K"top"; expand_forms_2(ctx, ex[1])] elseif k == K"typed_comprehension" @chk numchildren(ex) == 2 @chk kind(ex[2]) == K"generator" if numchildren(ex[2]) == 2 && kind((ex[2])[2]) == K"iteration" expand_forms_2(ctx, expand_comprehension_to_loops(ctx, ex)) else @ast ctx ex [K"call"; "collect"::K"top"; expand_forms_2(ctx, ex[1]); expand_forms_2(ctx, ex[2])] end elseif k == K"generator" expand_forms_2(ctx, expand_generator(ctx, ex)) elseif k == K"->" || k == K"do" expand_forms_2(ctx, expand_arrow(ctx, ex)) elseif k == K"function" expand_forms_2(ctx, expand_function_def(ctx, ex, docs)) elseif k == K"macro" @ast ctx ex [K"block"; [K"assert"; "global_toplevel_only"::K"Symbol"; [K"inert" ex]]; expand_forms_2(ctx, expand_macro_def(ctx, ex))] elseif k == K"if" || k == K"elseif" @chk numchildren(ex) >= 2 @ast ctx ex [k; expand_condition(ctx, ex[1]); expand_forms_2(ctx, ex[2:var"end"])...] elseif k == K"let" expand_forms_2(ctx, expand_let(ctx, ex)) elseif k == K"const" expand_const_decl(ctx, ex) elseif k == K"local" || k == K"global" if k == K"global" && kind(ex[1]) == K"const" expand_const_decl(ctx, @ast(ctx, ex, [K"const" [K"global" (ex[1])[1]]])) else expand_decls(ctx, ex) end elseif k == K"where" expand_forms_2(ctx, expand_wheres(ctx, ex)) elseif k == K"braces" || k == K"bracescat" throw(LoweringError(ex, "{ } syntax is reserved for future use")) elseif k == K"string" if numchildren(ex) == 1 && kind(ex[1]) == K"String" ex[1] else @ast ctx ex [K"call"; "string"::K"top"; expand_forms_2(ctx, children(ex))...] end elseif k == K"try" expand_forms_2(ctx, expand_try(ctx, ex)) elseif k == K"tuple" if has_parameters(ex) if numchildren(ex) > 1 throw(LoweringError(ex[var"end"], "unexpected semicolon in tuple - use `,` to separate tuple elements")) end expand_forms_2(ctx, expand_named_tuple(ctx, ex, children(ex[1]))) elseif any_assignment(children(ex)) expand_forms_2(ctx, expand_named_tuple(ctx, ex, children(ex))) else expand_forms_2(ctx, @ast(ctx, ex, [K"call"; "tuple"::K"core"; children(ex)...])) end elseif k == K"$" throw(LoweringError(ex, "`\$` expression outside string or quote block")) elseif k == K"module" throw(LoweringError(ex, "`module` is only allowed at top level")) elseif k == K"import" || k == K"using" expand_import_or_using(ctx, ex) elseif k == K"export" || k == K"public" expand_public(ctx, ex) elseif k == K"abstract" || k == K"primitive" expand_forms_2(ctx, expand_abstract_or_primitive_type(ctx, ex)) elseif k == K"struct" expand_forms_2(ctx, expand_struct_def(ctx, ex, docs)) elseif k == K"ref" sctx = with_stmts(ctx) (arr, idxs) = expand_ref_components(sctx, ex) expand_forms_2(ctx, @ast(ctx, ex, [K"block"; sctx.stmts...; [K"call"; "getindex"::K"top"; arr; idxs...]])) elseif k == K"curly" expand_forms_2(ctx, expand_curly(ctx, ex)) elseif k == K"toplevel" ex2 = @ast(ctx, ex, [K"block"; [K"assert" "toplevel_only"::K"Symbol" [K"inert" ex]]; [K"call"; eval ::K"Value"; ctx.mod ::K"Value"; [K"inert" ex]; [K"parameters"; [K"="; "expr_compat_mode"::K"Identifier"; ctx.expr_compat_mode::K"Bool"]]]]) expand_forms_2(ctx, ex2) elseif k == K"vect" check_no_parameters(ex, "unexpected semicolon in array expression") expand_array(ctx, ex, "vect") elseif k == K"hcat" expand_array(ctx, ex, "hcat") elseif k == K"typed_hcat" expand_array(ctx, ex, "typed_hcat") elseif k == K"opaque_closure" expand_forms_2(ctx, expand_opaque_closure(ctx, ex)) elseif k == K"vcat" || k == K"typed_vcat" expand_forms_2(ctx, expand_vcat(ctx, ex)) elseif k == K"ncat" || k == K"typed_ncat" expand_forms_2(ctx, expand_ncat(ctx, ex)) elseif k == K"while" @chk numchildren(ex) == 2 @ast ctx ex [K"break_block" "loop_exit"::K"symbolic_label"; [K"_while"; expand_condition(ctx, ex[1]); [K"break_block" "loop_cont"::K"symbolic_label"; [(K"scope_block")(scope_type = :neutral); expand_forms_2(ctx, ex[2])]]]] elseif k == K"inert" ex elseif k == K"gc_preserve" s = ssavar(ctx, ex) r = ssavar(ctx, ex) @ast ctx ex [K"block"; s := [K"gc_preserve_begin" (children(ex))[2:var"end"]...]; r := expand_forms_2(ctx, (children(ex))[1]); [K"gc_preserve_end" s]; r] elseif k == K"&" throw(LoweringError(ex, "invalid syntax")) elseif k == K"$" throw(LoweringError(ex, "`\$` expression outside string or quote")) elseif k == K"..." throw(LoweringError(ex, "`...` expression outside call")) elseif is_leaf(ex) ex elseif k == K"return" if numchildren(ex) == 0 @ast ctx ex [K"return" "nothing"::K"core"] elseif numchildren(ex) == 1 mapchildren((e->begin expand_forms_2(ctx, e) end), ctx, ex) else throw(LoweringError(ex, "More than one argument to return")) end else mapchildren((e->begin expand_forms_2(ctx, e) end), ctx, ex) end elseif k == K"<:" || (k == K">:" || k == K"-->") expand_forms_2(ctx, @ast(ctx, ex, [K"call"; adopt_scope(string(k)::K"Identifier", ex); children(ex)...])) elseif k == K"op=" || k == K".op=" expand_forms_2(ctx, expand_update_operator(ctx, ex)) elseif k == K"=" expand_assignment(ctx, ex) elseif k == K"break" if numchildren(ex) > 0 ex else @ast ctx ex [K"break" "loop_exit"::K"symbolic_label"] end elseif k == K"continue" @ast ctx ex [K"break" "loop_cont"::K"symbolic_label"] elseif k == K"comparison" expand_forms_2(ctx, expand_compare_chain(ctx, ex)) elseif k == K"doc" @chk numchildren(ex) == 2 expand_doc(ctx, ex[2], ex) elseif k == K"for" expand_forms_2(ctx, expand_for(ctx, ex)) elseif k == K"comprehension" @chk numchildren(ex) == 1 @chk kind(ex[1]) == K"generator" @ast ctx ex [K"call"; "collect"::K"top"; expand_forms_2(ctx, ex[1])] elseif k == K"typed_comprehension" @chk numchildren(ex) == 2 @chk kind(ex[2]) == K"generator" if numchildren(ex[2]) == 2 && kind((ex[2])[2]) == K"iteration" expand_forms_2(ctx, expand_comprehension_to_loops(ctx, ex)) else @ast ctx ex [K"call"; "collect"::K"top"; expand_forms_2(ctx, ex[1]); expand_forms_2(ctx, ex[2])] end elseif k == K"generator" expand_forms_2(ctx, expand_generator(ctx, ex)) elseif k == K"->" || k == K"do" expand_forms_2(ctx, expand_arrow(ctx, ex)) elseif k == K"function" expand_forms_2(ctx, expand_function_def(ctx, ex, docs)) elseif k == K"macro" @ast ctx ex [K"block"; [K"assert"; "global_toplevel_only"::K"Symbol"; [K"inert" ex]]; expand_forms_2(ctx, expand_macro_def(ctx, ex))] elseif k == K"if" || k == K"elseif" @chk numchildren(ex) >= 2 @ast ctx ex [k; expand_condition(ctx, ex[1]); expand_forms_2(ctx, ex[2:var"end"])...] elseif k == K"let" expand_forms_2(ctx, expand_let(ctx, ex)) elseif k == K"const" expand_const_decl(ctx, ex) elseif k == K"local" || k == K"global" if k == K"global" && kind(ex[1]) == K"const" expand_const_decl(ctx, @ast(ctx, ex, [K"const" [K"global" (ex[1])[1]]])) else expand_decls(ctx, ex) end elseif k == K"where" expand_forms_2(ctx, expand_wheres(ctx, ex)) elseif k == K"braces" || k == K"bracescat" throw(LoweringError(ex, "{ } syntax is reserved for future use")) elseif k == K"string" if numchildren(ex) == 1 && kind(ex[1]) == K"String" ex[1] else @ast ctx ex [K"call"; "string"::K"top"; expand_forms_2(ctx, children(ex))...] end elseif k == K"try" expand_forms_2(ctx, expand_try(ctx, ex)) elseif k == K"tuple" if has_parameters(ex) if numchildren(ex) > 1 throw(LoweringError(ex[var"end"], "unexpected semicolon in tuple - use `,` to separate tuple elements")) end expand_forms_2(ctx, expand_named_tuple(ctx, ex, children(ex[1]))) elseif any_assignment(children(ex)) expand_forms_2(ctx, expand_named_tuple(ctx, ex, children(ex))) else expand_forms_2(ctx, @ast(ctx, ex, [K"call"; "tuple"::K"core"; children(ex)...])) end elseif k == K"$" throw(LoweringError(ex, "`\$` expression outside string or quote block")) elseif k == K"module" throw(LoweringError(ex, "`module` is only allowed at top level")) elseif k == K"import" || k == K"using" expand_import_or_using(ctx, ex) elseif k == K"export" || k == K"public" expand_public(ctx, ex) elseif k == K"abstract" || k == K"primitive" expand_forms_2(ctx, expand_abstract_or_primitive_type(ctx, ex)) elseif k == K"struct" expand_forms_2(ctx, expand_struct_def(ctx, ex, docs)) elseif k == K"ref" sctx = with_stmts(ctx) (arr, idxs) = expand_ref_components(sctx, ex) expand_forms_2(ctx, @ast(ctx, ex, [K"block"; sctx.stmts...; [K"call"; "getindex"::K"top"; arr; idxs...]])) elseif k == K"curly" expand_forms_2(ctx, expand_curly(ctx, ex)) elseif k == K"toplevel" ex2 = @ast(ctx, ex, [K"block"; [K"assert" "toplevel_only"::K"Symbol" [K"inert" ex]]; [K"call"; eval::K"Value"; ctx.mod::K"Value"; [K"inert" ex]; [K"parameters"; [K"="; "expr_compat_mode"::K"Identifier"; ctx.expr_compat_mode::K"Bool"]]]]) expand_forms_2(ctx, ex2) elseif k == K"vect" check_no_parameters(ex, "unexpected semicolon in array expression") expand_array(ctx, ex, "vect") elseif k == K"hcat" expand_array(ctx, ex, "hcat") elseif k == K"typed_hcat" expand_array(ctx, ex, "typed_hcat") elseif k == K"opaque_closure" expand_forms_2(ctx, expand_opaque_closure(ctx, ex)) elseif k == K"vcat" || k == K"typed_vcat" expand_forms_2(ctx, expand_vcat(ctx, ex)) elseif k == K"ncat" || k == K"typed_ncat" expand_forms_2(ctx, expand_ncat(ctx, ex)) elseif k == K"while" @chk numchildren(ex) == 2 @ast ctx ex [K"break_block" "loop_exit"::K"symbolic_label"; [K"_while"; expand_condition(ctx, ex[1]); [K"break_block" "loop_cont"::K"symbolic_label"; [(K"scope_block")(scope_type = :neutral); expand_forms_2(ctx, ex[2])]]]] elseif k == K"inert" ex elseif k == K"gc_preserve" s = ssavar(ctx, ex) r = ssavar(ctx, ex) @ast ctx ex [K"block"; s := [K"gc_preserve_begin" (children(ex))[2:var"end"]...]; r := expand_forms_2(ctx, (children(ex))[1]); [K"gc_preserve_end" s]; r] elseif k == K"&" throw(LoweringError(ex, "invalid syntax")) elseif k == K"$" throw(LoweringError(ex, "`\$` expression outside string or quote")) elseif k == K"..." throw(LoweringError(ex, "`...` expression outside call")) elseif is_leaf(ex) ex elseif k == K"return" if numchildren(ex) == 0 @ast ctx ex [K"return" "nothing"::K"core"] elseif numchildren(ex) == 1 mapchildren((e->begin expand_forms_2(ctx, e) end), ctx, ex) else throw(LoweringError(ex, "More than one argument to return")) end else mapchildren((e->begin expand_forms_2(ctx, e) end), ctx, ex) end elseif k == K"::" @chk numchildren(ex) == 2 "`::` must be written `value::type` outside function argument lists" @ast ctx ex [K"call"; "typeassert"::K"core"; expand_forms_2(ctx, ex[1]); expand_forms_2(ctx, ex[2])] elseif k == K"<:" || (k == K">:" || k == K"-->") expand_forms_2(ctx, @ast(ctx, ex, [K"call"; adopt_scope(string(k)::K"Identifier", ex); children(ex)...])) elseif k == K"op=" || k == K".op=" expand_forms_2(ctx, expand_update_operator(ctx, ex)) elseif k == K"=" expand_assignment(ctx, ex) elseif k == K"break" if numchildren(ex) > 0 ex else @ast ctx ex [K"break" "loop_exit"::K"symbolic_label"] end elseif k == K"continue" @ast ctx ex [K"break" "loop_cont"::K"symbolic_label"] elseif k == K"comparison" expand_forms_2(ctx, expand_compare_chain(ctx, ex)) elseif k == K"doc" @chk numchildren(ex) == 2 expand_doc(ctx, ex[2], ex) elseif k == K"for" expand_forms_2(ctx, expand_for(ctx, ex)) elseif k == K"comprehension" @chk numchildren(ex) == 1 @chk kind(ex[1]) == K"generator" @ast ctx ex [K"call"; "collect"::K"top"; expand_forms_2(ctx, ex[1])] elseif k == K"typed_comprehension" @chk numchildren(ex) == 2 @chk kind(ex[2]) == K"generator" if numchildren(ex[2]) == 2 && kind((ex[2])[2]) == K"iteration" expand_forms_2(ctx, expand_comprehension_to_loops(ctx, ex)) else @ast ctx ex [K"call"; "collect"::K"top"; expand_forms_2(ctx, ex[1]); expand_forms_2(ctx, ex[2])] end elseif k == K"generator" expand_forms_2(ctx, expand_generator(ctx, ex)) elseif k == K"->" || k == K"do" expand_forms_2(ctx, expand_arrow(ctx, ex)) elseif k == K"function" expand_forms_2(ctx, expand_function_def(ctx, ex, docs)) elseif k == K"macro" @ast ctx ex [K"block"; [K"assert"; "global_toplevel_only"::K"Symbol"; [K"inert" ex]]; expand_forms_2(ctx, expand_macro_def(ctx, ex))] elseif k == K"if" || k == K"elseif" @chk numchildren(ex) >= 2 @ast ctx ex [k; expand_condition(ctx, ex[1]); expand_forms_2(ctx, ex[2:var"end"])...] elseif k == K"let" expand_forms_2(ctx, expand_let(ctx, ex)) elseif k == K"const" expand_const_decl(ctx, ex) elseif k == K"local" || k == K"global" if k == K"global" && kind(ex[1]) == K"const" expand_const_decl(ctx, @ast(ctx, ex, [K"const" [K"global" (ex[1])[1]]])) else expand_decls(ctx, ex) end elseif k == K"where" expand_forms_2(ctx, expand_wheres(ctx, ex)) elseif k == K"braces" || k == K"bracescat" throw(LoweringError(ex, "{ } syntax is reserved for future use")) elseif k == K"string" if numchildren(ex) == 1 && kind(ex[1]) == K"String" ex[1] else @ast ctx ex [K"call"; "string"::K"top"; expand_forms_2(ctx, children(ex))...] end elseif k == K"try" expand_forms_2(ctx, expand_try(ctx, ex)) elseif k == K"tuple" if has_parameters(ex) if numchildren(ex) > 1 throw(LoweringError(ex[var"end"], "unexpected semicolon in tuple - use `,` to separate tuple elements")) end expand_forms_2(ctx, expand_named_tuple(ctx, ex, children(ex[1]))) elseif any_assignment(children(ex)) expand_forms_2(ctx, expand_named_tuple(ctx, ex, children(ex))) else expand_forms_2(ctx, @ast(ctx, ex, [K"call"; "tuple"::K"core"; children(ex)...])) end elseif k == K"$" throw(LoweringError(ex, "`\$` expression outside string or quote block")) elseif k == K"module" throw(LoweringError(ex, "`module` is only allowed at top level")) elseif k == K"import" || k == K"using" expand_import_or_using(ctx, ex) elseif k == K"export" || k == K"public" expand_public(ctx, ex) elseif k == K"abstract" || k == K"primitive" expand_forms_2(ctx, expand_abstract_or_primitive_type(ctx, ex)) elseif k == K"struct" expand_forms_2(ctx, expand_struct_def(ctx, ex, docs)) elseif k == K"ref" sctx = with_stmts(ctx) (arr, idxs) = expand_ref_components(sctx, ex) expand_forms_2(ctx, @ast(ctx, ex, [K"block"; sctx.stmts...; [K"call"; "getindex"::K"top"; arr; idxs...]])) elseif k == K"curly" expand_forms_2(ctx, expand_curly(ctx, ex)) elseif k == K"toplevel" ex2 = @ast(ctx, ex, [K"block"; [K"assert" "toplevel_only"::K"Symbol" [K"inert" ex]]; [K"call"; eval ::K"Value"; ctx.mod ::K"Value"; [K"inert" ex]; [K"parameters"; [K"="; "expr_compat_mode"::K"Identifier"; ctx.expr_compat_mode::K"Bool"]]]]) expand_forms_2(ctx, ex2) elseif k == K"vect" check_no_parameters(ex, "unexpected semicolon in array expression") expand_array(ctx, ex, "vect") elseif k == K"hcat" expand_array(ctx, ex, "hcat") elseif k == K"typed_hcat" expand_array(ctx, ex, "typed_hcat") elseif k == K"opaque_closure" expand_forms_2(ctx, expand_opaque_closure(ctx, ex)) elseif k == K"vcat" || k == K"typed_vcat" expand_forms_2(ctx, expand_vcat(ctx, ex)) elseif k == K"ncat" || k == K"typed_ncat" expand_forms_2(ctx, expand_ncat(ctx, ex)) elseif k == K"while" @chk numchildren(ex) == 2 @ast ctx ex [K"break_block" "loop_exit"::K"symbolic_label"; [K"_while"; expand_condition(ctx, ex[1]); [K"break_block" "loop_cont"::K"symbolic_label"; [(K"scope_block")(scope_type = :neutral); expand_forms_2(ctx, ex[2])]]]] elseif k == K"inert" ex elseif k == K"gc_preserve" s = ssavar(ctx, ex) r = ssavar(ctx, ex) @ast ctx ex [K"block"; s := [K"gc_preserve_begin" (children(ex))[2:var"end"]...]; r := expand_forms_2(ctx, (children(ex))[1]); [K"gc_preserve_end" s]; r] elseif k == K"&" throw(LoweringError(ex, "invalid syntax")) elseif k == K"$" throw(LoweringError(ex, "`\$` expression outside string or quote")) elseif k == K"..." throw(LoweringError(ex, "`...` expression outside call")) elseif is_leaf(ex) ex elseif k == K"return" if numchildren(ex) == 0 @ast ctx ex [K"return" "nothing"::K"core"] elseif numchildren(ex) == 1 mapchildren((e->begin expand_forms_2(ctx, e) end), ctx, ex) else throw(LoweringError(ex, "More than one argument to return")) end else mapchildren((e->begin expand_forms_2(ctx, e) end), ctx, ex) end elseif k == K"::" @chk numchildren(ex) == 2 "`::` must be written `value::type` outside function argument lists" @ast ctx ex [K"call"; "typeassert"::K"core"; expand_forms_2(ctx, ex[1]); expand_forms_2(ctx, ex[2])] elseif k == K"<:" || (k == K">:" || k == K"-->") expand_forms_2(ctx, @ast(ctx, ex, [K"call"; adopt_scope(string(k)::K"Identifier", ex); children(ex)...])) elseif k == K"op=" || k == K".op=" expand_forms_2(ctx, expand_update_operator(ctx, ex)) elseif k == K"=" expand_assignment(ctx, ex) elseif k == K"break" if numchildren(ex) > 0 ex else @ast ctx ex [K"break" "loop_exit"::K"symbolic_label"] end elseif k == K"continue" @ast ctx ex [K"break" "loop_cont"::K"symbolic_label"] elseif k == K"comparison" expand_forms_2(ctx, expand_compare_chain(ctx, ex)) elseif k == K"doc" @chk numchildren(ex) == 2 expand_doc(ctx, ex[2], ex) elseif k == K"for" expand_forms_2(ctx, expand_for(ctx, ex)) elseif k == K"comprehension" @chk numchildren(ex) == 1 @chk kind(ex[1]) == K"generator" @ast ctx ex [K"call"; "collect"::K"top"; expand_forms_2(ctx, ex[1])] elseif k == K"typed_comprehension" @chk numchildren(ex) == 2 @chk kind(ex[2]) == K"generator" if numchildren(ex[2]) == 2 && kind((ex[2])[2]) == K"iteration" expand_forms_2(ctx, expand_comprehension_to_loops(ctx, ex)) else @ast ctx ex [K"call"; "collect"::K"top"; expand_forms_2(ctx, ex[1]); expand_forms_2(ctx, ex[2])] end elseif k == K"generator" expand_forms_2(ctx, expand_generator(ctx, ex)) elseif k == K"->" || k == K"do" expand_forms_2(ctx, expand_arrow(ctx, ex)) elseif k == K"function" expand_forms_2(ctx, expand_function_def(ctx, ex, docs)) elseif k == K"macro" @ast ctx ex [K"block"; [K"assert"; "global_toplevel_only"::K"Symbol"; [K"inert" ex]]; expand_forms_2(ctx, expand_macro_def(ctx, ex))] elseif k == K"if" || k == K"elseif" @chk numchildren(ex) >= 2 @ast ctx ex [k; expand_condition(ctx, ex[1]); expand_forms_2(ctx, ex[2:var"end"])...] elseif k == K"let" expand_forms_2(ctx, expand_let(ctx, ex)) elseif k == K"const" expand_const_decl(ctx, ex) elseif k == K"local" || k == K"global" if k == K"global" && kind(ex[1]) == K"const" expand_const_decl(ctx, @ast(ctx, ex, [K"const" [K"global" (ex[1])[1]]])) else expand_decls(ctx, ex) end elseif k == K"where" expand_forms_2(ctx, expand_wheres(ctx, ex)) elseif k == K"braces" || k == K"bracescat" throw(LoweringError(ex, "{ } syntax is reserved for future use")) elseif k == K"string" if numchildren(ex) == 1 && kind(ex[1]) == K"String" ex[1] else @ast ctx ex [K"call"; "string"::K"top"; expand_forms_2(ctx, children(ex))...] end elseif k == K"try" expand_forms_2(ctx, expand_try(ctx, ex)) elseif k == K"tuple" if has_parameters(ex) if numchildren(ex) > 1 throw(LoweringError(ex[var"end"], "unexpected semicolon in tuple - use `,` to separate tuple elements")) end expand_forms_2(ctx, expand_named_tuple(ctx, ex, children(ex[1]))) elseif any_assignment(children(ex)) expand_forms_2(ctx, expand_named_tuple(ctx, ex, children(ex))) else expand_forms_2(ctx, @ast(ctx, ex, [K"call"; "tuple"::K"core"; children(ex)...])) end elseif k == K"$" throw(LoweringError(ex, "`\$` expression outside string or quote block")) elseif k == K"module" throw(LoweringError(ex, "`module` is only allowed at top level")) elseif k == K"import" || k == K"using" expand_import_or_using(ctx, ex) elseif k == K"export" || k == K"public" expand_public(ctx, ex) elseif k == K"abstract" || k == K"primitive" expand_forms_2(ctx, expand_abstract_or_primitive_type(ctx, ex)) elseif k == K"struct" expand_forms_2(ctx, expand_struct_def(ctx, ex, docs)) elseif k == K"ref" sctx = with_stmts(ctx) (arr, idxs) = expand_ref_components(sctx, ex) expand_forms_2(ctx, @ast(ctx, ex, [K"block"; sctx.stmts...; [K"call"; "getindex"::K"top"; arr; idxs...]])) elseif k == K"curly" expand_forms_2(ctx, expand_curly(ctx, ex)) elseif k == K"toplevel" ex2 = @ast(ctx, ex, [K"block"; [K"assert" "toplevel_only"::K"Symbol" [K"inert" ex]]; [K"call"; eval::K"Value"; ctx.mod::K"Value"; [K"inert" ex]; [K"parameters"; [K"="; "expr_compat_mode"::K"Identifier"; ctx.expr_compat_mode::K"Bool"]]]]) expand_forms_2(ctx, ex2) elseif k == K"vect" check_no_parameters(ex, "unexpected semicolon in array expression") expand_array(ctx, ex, "vect") elseif k == K"hcat" expand_array(ctx, ex, "hcat") elseif k == K"typed_hcat" expand_array(ctx, ex, "typed_hcat") elseif k == K"opaque_closure" expand_forms_2(ctx, expand_opaque_closure(ctx, ex)) elseif k == K"vcat" || k == K"typed_vcat" expand_forms_2(ctx, expand_vcat(ctx, ex)) elseif k == K"ncat" || k == K"typed_ncat" expand_forms_2(ctx, expand_ncat(ctx, ex)) elseif k == K"while" @chk numchildren(ex) == 2 @ast ctx ex [K"break_block" "loop_exit"::K"symbolic_label"; [K"_while"; expand_condition(ctx, ex[1]); [K"break_block" "loop_cont"::K"symbolic_label"; [(K"scope_block")(scope_type = :neutral); expand_forms_2(ctx, ex[2])]]]] elseif k == K"inert" ex elseif k == K"gc_preserve" s = ssavar(ctx, ex) r = ssavar(ctx, ex) @ast ctx ex [K"block"; s := [K"gc_preserve_begin" (children(ex))[2:var"end"]...]; r := expand_forms_2(ctx, (children(ex))[1]); [K"gc_preserve_end" s]; r] elseif k == K"&" throw(LoweringError(ex, "invalid syntax")) elseif k == K"$" throw(LoweringError(ex, "`\$` expression outside string or quote")) elseif k == K"..." throw(LoweringError(ex, "`...` expression outside call")) elseif is_leaf(ex) ex elseif k == K"return" if numchildren(ex) == 0 @ast ctx ex [K"return" "nothing"::K"core"] elseif numchildren(ex) == 1 mapchildren((e->begin expand_forms_2(ctx, e) end), ctx, ex) else throw(LoweringError(ex, "More than one argument to return")) end else mapchildren((e->begin expand_forms_2(ctx, e) end), ctx, ex) end elseif k == K"&&" || k == K"||" @chk numchildren(ex) > 1 cs = expand_cond_children(ctx, ex) cond = if length(cs) == 2 cs[1] else makenode(ctx, ex, k, cs[1:var"end" - 1]) end if k == K"&&" @ast ctx ex [K"if" cond cs[var"end"] false::K"Bool"] else @ast ctx ex [K"if" cond true::K"Bool" cs[var"end"]] end elseif k == K"::" @chk numchildren(ex) == 2 "`::` must be written `value::type` outside function argument lists" @ast ctx ex [K"call"; "typeassert"::K"core"; expand_forms_2(ctx, ex[1]); expand_forms_2(ctx, ex[2])] elseif k == K"<:" || (k == K">:" || k == K"-->") expand_forms_2(ctx, @ast(ctx, ex, [K"call"; adopt_scope(string(k)::K"Identifier", ex); children(ex)...])) elseif k == K"op=" || k == K".op=" expand_forms_2(ctx, expand_update_operator(ctx, ex)) elseif k == K"=" expand_assignment(ctx, ex) elseif k == K"break" if numchildren(ex) > 0 ex else @ast ctx ex [K"break" "loop_exit"::K"symbolic_label"] end elseif k == K"continue" @ast ctx ex [K"break" "loop_cont"::K"symbolic_label"] elseif k == K"comparison" expand_forms_2(ctx, expand_compare_chain(ctx, ex)) elseif k == K"doc" @chk numchildren(ex) == 2 expand_doc(ctx, ex[2], ex) elseif k == K"for" expand_forms_2(ctx, expand_for(ctx, ex)) elseif k == K"comprehension" @chk numchildren(ex) == 1 @chk kind(ex[1]) == K"generator" @ast ctx ex [K"call"; "collect"::K"top"; expand_forms_2(ctx, ex[1])] elseif k == K"typed_comprehension" @chk numchildren(ex) == 2 @chk kind(ex[2]) == K"generator" if numchildren(ex[2]) == 2 && kind((ex[2])[2]) == K"iteration" expand_forms_2(ctx, expand_comprehension_to_loops(ctx, ex)) else @ast ctx ex [K"call"; "collect"::K"top"; expand_forms_2(ctx, ex[1]); expand_forms_2(ctx, ex[2])] end elseif k == K"generator" expand_forms_2(ctx, expand_generator(ctx, ex)) elseif k == K"->" || k == K"do" expand_forms_2(ctx, expand_arrow(ctx, ex)) elseif k == K"function" expand_forms_2(ctx, expand_function_def(ctx, ex, docs)) elseif k == K"macro" @ast ctx ex [K"block"; [K"assert"; "global_toplevel_only"::K"Symbol"; [K"inert" ex]]; expand_forms_2(ctx, expand_macro_def(ctx, ex))] elseif k == K"if" || k == K"elseif" @chk numchildren(ex) >= 2 @ast ctx ex [k; expand_condition(ctx, ex[1]); expand_forms_2(ctx, ex[2:var"end"])...] elseif k == K"let" expand_forms_2(ctx, expand_let(ctx, ex)) elseif k == K"const" expand_const_decl(ctx, ex) elseif k == K"local" || k == K"global" if k == K"global" && kind(ex[1]) == K"const" expand_const_decl(ctx, @ast(ctx, ex, [K"const" [K"global" (ex[1])[1]]])) else expand_decls(ctx, ex) end elseif k == K"where" expand_forms_2(ctx, expand_wheres(ctx, ex)) elseif k == K"braces" || k == K"bracescat" throw(LoweringError(ex, "{ } syntax is reserved for future use")) elseif k == K"string" if numchildren(ex) == 1 && kind(ex[1]) == K"String" ex[1] else @ast ctx ex [K"call"; "string"::K"top"; expand_forms_2(ctx, children(ex))...] end elseif k == K"try" expand_forms_2(ctx, expand_try(ctx, ex)) elseif k == K"tuple" if has_parameters(ex) if numchildren(ex) > 1 throw(LoweringError(ex[var"end"], "unexpected semicolon in tuple - use `,` to separate tuple elements")) end expand_forms_2(ctx, expand_named_tuple(ctx, ex, children(ex[1]))) elseif any_assignment(children(ex)) expand_forms_2(ctx, expand_named_tuple(ctx, ex, children(ex))) else expand_forms_2(ctx, @ast(ctx, ex, [K"call"; "tuple"::K"core"; children(ex)...])) end elseif k == K"$" throw(LoweringError(ex, "`\$` expression outside string or quote block")) elseif k == K"module" throw(LoweringError(ex, "`module` is only allowed at top level")) elseif k == K"import" || k == K"using" expand_import_or_using(ctx, ex) elseif k == K"export" || k == K"public" expand_public(ctx, ex) elseif k == K"abstract" || k == K"primitive" expand_forms_2(ctx, expand_abstract_or_primitive_type(ctx, ex)) elseif k == K"struct" expand_forms_2(ctx, expand_struct_def(ctx, ex, docs)) elseif k == K"ref" sctx = with_stmts(ctx) (arr, idxs) = expand_ref_components(sctx, ex) expand_forms_2(ctx, @ast(ctx, ex, [K"block"; sctx.stmts...; [K"call"; "getindex"::K"top"; arr; idxs...]])) elseif k == K"curly" expand_forms_2(ctx, expand_curly(ctx, ex)) elseif k == K"toplevel" ex2 = @ast(ctx, ex, [K"block"; [K"assert" "toplevel_only"::K"Symbol" [K"inert" ex]]; [K"call"; eval ::K"Value"; ctx.mod ::K"Value"; [K"inert" ex]; [K"parameters"; [K"="; "expr_compat_mode"::K"Identifier"; ctx.expr_compat_mode::K"Bool"]]]]) expand_forms_2(ctx, ex2) elseif k == K"vect" check_no_parameters(ex, "unexpected semicolon in array expression") expand_array(ctx, ex, "vect") elseif k == K"hcat" expand_array(ctx, ex, "hcat") elseif k == K"typed_hcat" expand_array(ctx, ex, "typed_hcat") elseif k == K"opaque_closure" expand_forms_2(ctx, expand_opaque_closure(ctx, ex)) elseif k == K"vcat" || k == K"typed_vcat" expand_forms_2(ctx, expand_vcat(ctx, ex)) elseif k == K"ncat" || k == K"typed_ncat" expand_forms_2(ctx, expand_ncat(ctx, ex)) elseif k == K"while" @chk numchildren(ex) == 2 @ast ctx ex [K"break_block" "loop_exit"::K"symbolic_label"; [K"_while"; expand_condition(ctx, ex[1]); [K"break_block" "loop_cont"::K"symbolic_label"; [(K"scope_block")(scope_type = :neutral); expand_forms_2(ctx, ex[2])]]]] elseif k == K"inert" ex elseif k == K"gc_preserve" s = ssavar(ctx, ex) r = ssavar(ctx, ex) @ast ctx ex [K"block"; s := [K"gc_preserve_begin" (children(ex))[2:var"end"]...]; r := expand_forms_2(ctx, (children(ex))[1]); [K"gc_preserve_end" s]; r] elseif k == K"&" throw(LoweringError(ex, "invalid syntax")) elseif k == K"$" throw(LoweringError(ex, "`\$` expression outside string or quote")) elseif k == K"..." throw(LoweringError(ex, "`...` expression outside call")) elseif is_leaf(ex) ex elseif k == K"return" if numchildren(ex) == 0 @ast ctx ex [K"return" "nothing"::K"core"] elseif numchildren(ex) == 1 mapchildren((e->begin expand_forms_2(ctx, e) end), ctx, ex) else throw(LoweringError(ex, "More than one argument to return")) end else mapchildren((e->begin expand_forms_2(ctx, e) end), ctx, ex) end elseif k == K"&&" || k == K"||" @chk numchildren(ex) > 1 cs = expand_cond_children(ctx, ex) cond = if length(cs) == 2 cs[1] else makenode(ctx, ex, k, cs[1:var"end" - 1]) end if k == K"&&" @ast ctx ex [K"if" cond cs[var"end"] false::K"Bool"] else @ast ctx ex [K"if" cond true::K"Bool" cs[var"end"]] end elseif k == K"::" @chk numchildren(ex) == 2 "`::` must be written `value::type` outside function argument lists" @ast ctx ex [K"call"; "typeassert"::K"core"; expand_forms_2(ctx, ex[1]); expand_forms_2(ctx, ex[2])] elseif k == K"<:" || (k == K">:" || k == K"-->") expand_forms_2(ctx, @ast(ctx, ex, [K"call"; adopt_scope(string(k)::K"Identifier", ex); children(ex)...])) elseif k == K"op=" || k == K".op=" expand_forms_2(ctx, expand_update_operator(ctx, ex)) elseif k == K"=" expand_assignment(ctx, ex) elseif k == K"break" if numchildren(ex) > 0 ex else @ast ctx ex [K"break" "loop_exit"::K"symbolic_label"] end elseif k == K"continue" @ast ctx ex [K"break" "loop_cont"::K"symbolic_label"] elseif k == K"comparison" expand_forms_2(ctx, expand_compare_chain(ctx, ex)) elseif k == K"doc" @chk numchildren(ex) == 2 expand_doc(ctx, ex[2], ex) elseif k == K"for" expand_forms_2(ctx, expand_for(ctx, ex)) elseif k == K"comprehension" @chk numchildren(ex) == 1 @chk kind(ex[1]) == K"generator" @ast ctx ex [K"call"; "collect"::K"top"; expand_forms_2(ctx, ex[1])] elseif k == K"typed_comprehension" @chk numchildren(ex) == 2 @chk kind(ex[2]) == K"generator" if numchildren(ex[2]) == 2 && kind((ex[2])[2]) == K"iteration" expand_forms_2(ctx, expand_comprehension_to_loops(ctx, ex)) else @ast ctx ex [K"call"; "collect"::K"top"; expand_forms_2(ctx, ex[1]); expand_forms_2(ctx, ex[2])] end elseif k == K"generator" expand_forms_2(ctx, expand_generator(ctx, ex)) elseif k == K"->" || k == K"do" expand_forms_2(ctx, expand_arrow(ctx, ex)) elseif k == K"function" expand_forms_2(ctx, expand_function_def(ctx, ex, docs)) elseif k == K"macro" @ast ctx ex [K"block"; [K"assert"; "global_toplevel_only"::K"Symbol"; [K"inert" ex]]; expand_forms_2(ctx, expand_macro_def(ctx, ex))] elseif k == K"if" || k == K"elseif" @chk numchildren(ex) >= 2 @ast ctx ex [k; expand_condition(ctx, ex[1]); expand_forms_2(ctx, ex[2:var"end"])...] elseif k == K"let" expand_forms_2(ctx, expand_let(ctx, ex)) elseif k == K"const" expand_const_decl(ctx, ex) elseif k == K"local" || k == K"global" if k == K"global" && kind(ex[1]) == K"const" expand_const_decl(ctx, @ast(ctx, ex, [K"const" [K"global" (ex[1])[1]]])) else expand_decls(ctx, ex) end elseif k == K"where" expand_forms_2(ctx, expand_wheres(ctx, ex)) elseif k == K"braces" || k == K"bracescat" throw(LoweringError(ex, "{ } syntax is reserved for future use")) elseif k == K"string" if numchildren(ex) == 1 && kind(ex[1]) == K"String" ex[1] else @ast ctx ex [K"call"; "string"::K"top"; expand_forms_2(ctx, children(ex))...] end elseif k == K"try" expand_forms_2(ctx, expand_try(ctx, ex)) elseif k == K"tuple" if has_parameters(ex) if numchildren(ex) > 1 throw(LoweringError(ex[var"end"], "unexpected semicolon in tuple - use `,` to separate tuple elements")) end expand_forms_2(ctx, expand_named_tuple(ctx, ex, children(ex[1]))) elseif any_assignment(children(ex)) expand_forms_2(ctx, expand_named_tuple(ctx, ex, children(ex))) else expand_forms_2(ctx, @ast(ctx, ex, [K"call"; "tuple"::K"core"; children(ex)...])) end elseif k == K"$" throw(LoweringError(ex, "`\$` expression outside string or quote block")) elseif k == K"module" throw(LoweringError(ex, "`module` is only allowed at top level")) elseif k == K"import" || k == K"using" expand_import_or_using(ctx, ex) elseif k == K"export" || k == K"public" expand_public(ctx, ex) elseif k == K"abstract" || k == K"primitive" expand_forms_2(ctx, expand_abstract_or_primitive_type(ctx, ex)) elseif k == K"struct" expand_forms_2(ctx, expand_struct_def(ctx, ex, docs)) elseif k == K"ref" sctx = with_stmts(ctx) (arr, idxs) = expand_ref_components(sctx, ex) expand_forms_2(ctx, @ast(ctx, ex, [K"block"; sctx.stmts...; [K"call"; "getindex"::K"top"; arr; idxs...]])) elseif k == K"curly" expand_forms_2(ctx, expand_curly(ctx, ex)) elseif k == K"toplevel" ex2 = @ast(ctx, ex, [K"block"; [K"assert" "toplevel_only"::K"Symbol" [K"inert" ex]]; [K"call"; eval::K"Value"; ctx.mod::K"Value"; [K"inert" ex]; [K"parameters"; [K"="; "expr_compat_mode"::K"Identifier"; ctx.expr_compat_mode::K"Bool"]]]]) expand_forms_2(ctx, ex2) elseif k == K"vect" check_no_parameters(ex, "unexpected semicolon in array expression") expand_array(ctx, ex, "vect") elseif k == K"hcat" expand_array(ctx, ex, "hcat") elseif k == K"typed_hcat" expand_array(ctx, ex, "typed_hcat") elseif k == K"opaque_closure" expand_forms_2(ctx, expand_opaque_closure(ctx, ex)) elseif k == K"vcat" || k == K"typed_vcat" expand_forms_2(ctx, expand_vcat(ctx, ex)) elseif k == K"ncat" || k == K"typed_ncat" expand_forms_2(ctx, expand_ncat(ctx, ex)) elseif k == K"while" @chk numchildren(ex) == 2 @ast ctx ex [K"break_block" "loop_exit"::K"symbolic_label"; [K"_while"; expand_condition(ctx, ex[1]); [K"break_block" "loop_cont"::K"symbolic_label"; [(K"scope_block")(scope_type = :neutral); expand_forms_2(ctx, ex[2])]]]] elseif k == K"inert" ex elseif k == K"gc_preserve" s = ssavar(ctx, ex) r = ssavar(ctx, ex) @ast ctx ex [K"block"; s := [K"gc_preserve_begin" (children(ex))[2:var"end"]...]; r := expand_forms_2(ctx, (children(ex))[1]); [K"gc_preserve_end" s]; r] elseif k == K"&" throw(LoweringError(ex, "invalid syntax")) elseif k == K"$" throw(LoweringError(ex, "`\$` expression outside string or quote")) elseif k == K"..." throw(LoweringError(ex, "`...` expression outside call")) elseif is_leaf(ex) ex elseif k == K"return" if numchildren(ex) == 0 @ast ctx ex [K"return" "nothing"::K"core"] elseif numchildren(ex) == 1 mapchildren((e->begin expand_forms_2(ctx, e) end), ctx, ex) else throw(LoweringError(ex, "More than one argument to return")) end else mapchildren((e->begin expand_forms_2(ctx, e) end), ctx, ex) end elseif k == K"?" @chk numchildren(ex) == 3 expand_forms_2(ctx, @ast(ctx, ex, [K"if" children(ex)...])) elseif k == K"&&" || k == K"||" @chk numchildren(ex) > 1 cs = expand_cond_children(ctx, ex) cond = if length(cs) == 2 cs[1] else makenode(ctx, ex, k, cs[1:var"end" - 1]) end if k == K"&&" @ast ctx ex [K"if" cond cs[var"end"] false::K"Bool"] else @ast ctx ex [K"if" cond true::K"Bool" cs[var"end"]] end elseif k == K"::" @chk numchildren(ex) == 2 "`::` must be written `value::type` outside function argument lists" @ast ctx ex [K"call"; "typeassert"::K"core"; expand_forms_2(ctx, ex[1]); expand_forms_2(ctx, ex[2])] elseif k == K"<:" || (k == K">:" || k == K"-->") expand_forms_2(ctx, @ast(ctx, ex, [K"call"; adopt_scope(string(k)::K"Identifier", ex); children(ex)...])) elseif k == K"op=" || k == K".op=" expand_forms_2(ctx, expand_update_operator(ctx, ex)) elseif k == K"=" expand_assignment(ctx, ex) elseif k == K"break" if numchildren(ex) > 0 ex else @ast ctx ex [K"break" "loop_exit"::K"symbolic_label"] end elseif k == K"continue" @ast ctx ex [K"break" "loop_cont"::K"symbolic_label"] elseif k == K"comparison" expand_forms_2(ctx, expand_compare_chain(ctx, ex)) elseif k == K"doc" @chk numchildren(ex) == 2 expand_doc(ctx, ex[2], ex) elseif k == K"for" expand_forms_2(ctx, expand_for(ctx, ex)) elseif k == K"comprehension" @chk numchildren(ex) == 1 @chk kind(ex[1]) == K"generator" @ast ctx ex [K"call"; "collect"::K"top"; expand_forms_2(ctx, ex[1])] elseif k == K"typed_comprehension" @chk numchildren(ex) == 2 @chk kind(ex[2]) == K"generator" if numchildren(ex[2]) == 2 && kind((ex[2])[2]) == K"iteration" expand_forms_2(ctx, expand_comprehension_to_loops(ctx, ex)) else @ast ctx ex [K"call"; "collect"::K"top"; expand_forms_2(ctx, ex[1]); expand_forms_2(ctx, ex[2])] end elseif k == K"generator" expand_forms_2(ctx, expand_generator(ctx, ex)) elseif k == K"->" || k == K"do" expand_forms_2(ctx, expand_arrow(ctx, ex)) elseif k == K"function" expand_forms_2(ctx, expand_function_def(ctx, ex, docs)) elseif k == K"macro" @ast ctx ex [K"block"; [K"assert"; "global_toplevel_only"::K"Symbol"; [K"inert" ex]]; expand_forms_2(ctx, expand_macro_def(ctx, ex))] elseif k == K"if" || k == K"elseif" @chk numchildren(ex) >= 2 @ast ctx ex [k; expand_condition(ctx, ex[1]); expand_forms_2(ctx, ex[2:var"end"])...] elseif k == K"let" expand_forms_2(ctx, expand_let(ctx, ex)) elseif k == K"const" expand_const_decl(ctx, ex) elseif k == K"local" || k == K"global" if k == K"global" && kind(ex[1]) == K"const" expand_const_decl(ctx, @ast(ctx, ex, [K"const" [K"global" (ex[1])[1]]])) else expand_decls(ctx, ex) end elseif k == K"where" expand_forms_2(ctx, expand_wheres(ctx, ex)) elseif k == K"braces" || k == K"bracescat" throw(LoweringError(ex, "{ } syntax is reserved for future use")) elseif k == K"string" if numchildren(ex) == 1 && kind(ex[1]) == K"String" ex[1] else @ast ctx ex [K"call"; "string"::K"top"; expand_forms_2(ctx, children(ex))...] end elseif k == K"try" expand_forms_2(ctx, expand_try(ctx, ex)) elseif k == K"tuple" if has_parameters(ex) if numchildren(ex) > 1 throw(LoweringError(ex[var"end"], "unexpected semicolon in tuple - use `,` to separate tuple elements")) end expand_forms_2(ctx, expand_named_tuple(ctx, ex, children(ex[1]))) elseif any_assignment(children(ex)) expand_forms_2(ctx, expand_named_tuple(ctx, ex, children(ex))) else expand_forms_2(ctx, @ast(ctx, ex, [K"call"; "tuple"::K"core"; children(ex)...])) end elseif k == K"$" throw(LoweringError(ex, "`\$` expression outside string or quote block")) elseif k == K"module" throw(LoweringError(ex, "`module` is only allowed at top level")) elseif k == K"import" || k == K"using" expand_import_or_using(ctx, ex) elseif k == K"export" || k == K"public" expand_public(ctx, ex) elseif k == K"abstract" || k == K"primitive" expand_forms_2(ctx, expand_abstract_or_primitive_type(ctx, ex)) elseif k == K"struct" expand_forms_2(ctx, expand_struct_def(ctx, ex, docs)) elseif k == K"ref" sctx = with_stmts(ctx) (arr, idxs) = expand_ref_components(sctx, ex) expand_forms_2(ctx, @ast(ctx, ex, [K"block"; sctx.stmts...; [K"call"; "getindex"::K"top"; arr; idxs...]])) elseif k == K"curly" expand_forms_2(ctx, expand_curly(ctx, ex)) elseif k == K"toplevel" ex2 = @ast(ctx, ex, [K"block"; [K"assert" "toplevel_only"::K"Symbol" [K"inert" ex]]; [K"call"; eval ::K"Value"; ctx.mod ::K"Value"; [K"inert" ex]; [K"parameters"; [K"="; "expr_compat_mode"::K"Identifier"; ctx.expr_compat_mode::K"Bool"]]]]) expand_forms_2(ctx, ex2) elseif k == K"vect" check_no_parameters(ex, "unexpected semicolon in array expression") expand_array(ctx, ex, "vect") elseif k == K"hcat" expand_array(ctx, ex, "hcat") elseif k == K"typed_hcat" expand_array(ctx, ex, "typed_hcat") elseif k == K"opaque_closure" expand_forms_2(ctx, expand_opaque_closure(ctx, ex)) elseif k == K"vcat" || k == K"typed_vcat" expand_forms_2(ctx, expand_vcat(ctx, ex)) elseif k == K"ncat" || k == K"typed_ncat" expand_forms_2(ctx, expand_ncat(ctx, ex)) elseif k == K"while" @chk numchildren(ex) == 2 @ast ctx ex [K"break_block" "loop_exit"::K"symbolic_label"; [K"_while"; expand_condition(ctx, ex[1]); [K"break_block" "loop_cont"::K"symbolic_label"; [(K"scope_block")(scope_type = :neutral); expand_forms_2(ctx, ex[2])]]]] elseif k == K"inert" ex elseif k == K"gc_preserve" s = ssavar(ctx, ex) r = ssavar(ctx, ex) @ast ctx ex [K"block"; s := [K"gc_preserve_begin" (children(ex))[2:var"end"]...]; r := expand_forms_2(ctx, (children(ex))[1]); [K"gc_preserve_end" s]; r] elseif k == K"&" throw(LoweringError(ex, "invalid syntax")) elseif k == K"$" throw(LoweringError(ex, "`\$` expression outside string or quote")) elseif k == K"..." throw(LoweringError(ex, "`...` expression outside call")) elseif is_leaf(ex) ex elseif k == K"return" if numchildren(ex) == 0 @ast ctx ex [K"return" "nothing"::K"core"] elseif numchildren(ex) == 1 mapchildren((e->begin expand_forms_2(ctx, e) end), ctx, ex) else throw(LoweringError(ex, "More than one argument to return")) end else mapchildren((e->begin expand_forms_2(ctx, e) end), ctx, ex) end elseif k == K"?" @chk numchildren(ex) == 3 expand_forms_2(ctx, @ast(ctx, ex, [K"if" children(ex)...])) elseif k == K"&&" || k == K"||" @chk numchildren(ex) > 1 cs = expand_cond_children(ctx, ex) cond = if length(cs) == 2 cs[1] else makenode(ctx, ex, k, cs[1:var"end" - 1]) end if k == K"&&" @ast ctx ex [K"if" cond cs[var"end"] false::K"Bool"] else @ast ctx ex [K"if" cond true::K"Bool" cs[var"end"]] end elseif k == K"::" @chk numchildren(ex) == 2 "`::` must be written `value::type` outside function argument lists" @ast ctx ex [K"call"; "typeassert"::K"core"; expand_forms_2(ctx, ex[1]); expand_forms_2(ctx, ex[2])] elseif k == K"<:" || (k == K">:" || k == K"-->") expand_forms_2(ctx, @ast(ctx, ex, [K"call"; adopt_scope(string(k)::K"Identifier", ex); children(ex)...])) elseif k == K"op=" || k == K".op=" expand_forms_2(ctx, expand_update_operator(ctx, ex)) elseif k == K"=" expand_assignment(ctx, ex) elseif k == K"break" if numchildren(ex) > 0 ex else @ast ctx ex [K"break" "loop_exit"::K"symbolic_label"] end elseif k == K"continue" @ast ctx ex [K"break" "loop_cont"::K"symbolic_label"] elseif k == K"comparison" expand_forms_2(ctx, expand_compare_chain(ctx, ex)) elseif k == K"doc" @chk numchildren(ex) == 2 expand_doc(ctx, ex[2], ex) elseif k == K"for" expand_forms_2(ctx, expand_for(ctx, ex)) elseif k == K"comprehension" @chk numchildren(ex) == 1 @chk kind(ex[1]) == K"generator" @ast ctx ex [K"call"; "collect"::K"top"; expand_forms_2(ctx, ex[1])] elseif k == K"typed_comprehension" @chk numchildren(ex) == 2 @chk kind(ex[2]) == K"generator" if numchildren(ex[2]) == 2 && kind((ex[2])[2]) == K"iteration" expand_forms_2(ctx, expand_comprehension_to_loops(ctx, ex)) else @ast ctx ex [K"call"; "collect"::K"top"; expand_forms_2(ctx, ex[1]); expand_forms_2(ctx, ex[2])] end elseif k == K"generator" expand_forms_2(ctx, expand_generator(ctx, ex)) elseif k == K"->" || k == K"do" expand_forms_2(ctx, expand_arrow(ctx, ex)) elseif k == K"function" expand_forms_2(ctx, expand_function_def(ctx, ex, docs)) elseif k == K"macro" @ast ctx ex [K"block"; [K"assert"; "global_toplevel_only"::K"Symbol"; [K"inert" ex]]; expand_forms_2(ctx, expand_macro_def(ctx, ex))] elseif k == K"if" || k == K"elseif" @chk numchildren(ex) >= 2 @ast ctx ex [k; expand_condition(ctx, ex[1]); expand_forms_2(ctx, ex[2:var"end"])...] elseif k == K"let" expand_forms_2(ctx, expand_let(ctx, ex)) elseif k == K"const" expand_const_decl(ctx, ex) elseif k == K"local" || k == K"global" if k == K"global" && kind(ex[1]) == K"const" expand_const_decl(ctx, @ast(ctx, ex, [K"const" [K"global" (ex[1])[1]]])) else expand_decls(ctx, ex) end elseif k == K"where" expand_forms_2(ctx, expand_wheres(ctx, ex)) elseif k == K"braces" || k == K"bracescat" throw(LoweringError(ex, "{ } syntax is reserved for future use")) elseif k == K"string" if numchildren(ex) == 1 && kind(ex[1]) == K"String" ex[1] else @ast ctx ex [K"call"; "string"::K"top"; expand_forms_2(ctx, children(ex))...] end elseif k == K"try" expand_forms_2(ctx, expand_try(ctx, ex)) elseif k == K"tuple" if has_parameters(ex) if numchildren(ex) > 1 throw(LoweringError(ex[var"end"], "unexpected semicolon in tuple - use `,` to separate tuple elements")) end expand_forms_2(ctx, expand_named_tuple(ctx, ex, children(ex[1]))) elseif any_assignment(children(ex)) expand_forms_2(ctx, expand_named_tuple(ctx, ex, children(ex))) else expand_forms_2(ctx, @ast(ctx, ex, [K"call"; "tuple"::K"core"; children(ex)...])) end elseif k == K"$" throw(LoweringError(ex, "`\$` expression outside string or quote block")) elseif k == K"module" throw(LoweringError(ex, "`module` is only allowed at top level")) elseif k == K"import" || k == K"using" expand_import_or_using(ctx, ex) elseif k == K"export" || k == K"public" expand_public(ctx, ex) elseif k == K"abstract" || k == K"primitive" expand_forms_2(ctx, expand_abstract_or_primitive_type(ctx, ex)) elseif k == K"struct" expand_forms_2(ctx, expand_struct_def(ctx, ex, docs)) elseif k == K"ref" sctx = with_stmts(ctx) (arr, idxs) = expand_ref_components(sctx, ex) expand_forms_2(ctx, @ast(ctx, ex, [K"block"; sctx.stmts...; [K"call"; "getindex"::K"top"; arr; idxs...]])) elseif k == K"curly" expand_forms_2(ctx, expand_curly(ctx, ex)) elseif k == K"toplevel" ex2 = @ast(ctx, ex, [K"block"; [K"assert" "toplevel_only"::K"Symbol" [K"inert" ex]]; [K"call"; eval::K"Value"; ctx.mod::K"Value"; [K"inert" ex]; [K"parameters"; [K"="; "expr_compat_mode"::K"Identifier"; ctx.expr_compat_mode::K"Bool"]]]]) expand_forms_2(ctx, ex2) elseif k == K"vect" check_no_parameters(ex, "unexpected semicolon in array expression") expand_array(ctx, ex, "vect") elseif k == K"hcat" expand_array(ctx, ex, "hcat") elseif k == K"typed_hcat" expand_array(ctx, ex, "typed_hcat") elseif k == K"opaque_closure" expand_forms_2(ctx, expand_opaque_closure(ctx, ex)) elseif k == K"vcat" || k == K"typed_vcat" expand_forms_2(ctx, expand_vcat(ctx, ex)) elseif k == K"ncat" || k == K"typed_ncat" expand_forms_2(ctx, expand_ncat(ctx, ex)) elseif k == K"while" @chk numchildren(ex) == 2 @ast ctx ex [K"break_block" "loop_exit"::K"symbolic_label"; [K"_while"; expand_condition(ctx, ex[1]); [K"break_block" "loop_cont"::K"symbolic_label"; [(K"scope_block")(scope_type = :neutral); expand_forms_2(ctx, ex[2])]]]] elseif k == K"inert" ex elseif k == K"gc_preserve" s = ssavar(ctx, ex) r = ssavar(ctx, ex) @ast ctx ex [K"block"; s := [K"gc_preserve_begin" (children(ex))[2:var"end"]...]; r := expand_forms_2(ctx, (children(ex))[1]); [K"gc_preserve_end" s]; r] elseif k == K"&" throw(LoweringError(ex, "invalid syntax")) elseif k == K"$" throw(LoweringError(ex, "`\$` expression outside string or quote")) elseif k == K"..." throw(LoweringError(ex, "`...` expression outside call")) elseif is_leaf(ex) ex elseif k == K"return" if numchildren(ex) == 0 @ast ctx ex [K"return" "nothing"::K"core"] elseif numchildren(ex) == 1 mapchildren((e->begin expand_forms_2(ctx, e) end), ctx, ex) else throw(LoweringError(ex, "More than one argument to return")) end else mapchildren((e->begin expand_forms_2(ctx, e) end), ctx, ex) end elseif k == K"." expand_forms_2(ctx, expand_dot(ctx, ex)) elseif k == K"?" @chk numchildren(ex) == 3 expand_forms_2(ctx, @ast(ctx, ex, [K"if" children(ex)...])) elseif k == K"&&" || k == K"||" @chk numchildren(ex) > 1 cs = expand_cond_children(ctx, ex) cond = if length(cs) == 2 cs[1] else makenode(ctx, ex, k, cs[1:var"end" - 1]) end if k == K"&&" @ast ctx ex [K"if" cond cs[var"end"] false::K"Bool"] else @ast ctx ex [K"if" cond true::K"Bool" cs[var"end"]] end elseif k == K"::" @chk numchildren(ex) == 2 "`::` must be written `value::type` outside function argument lists" @ast ctx ex [K"call"; "typeassert"::K"core"; expand_forms_2(ctx, ex[1]); expand_forms_2(ctx, ex[2])] elseif k == K"<:" || (k == K">:" || k == K"-->") expand_forms_2(ctx, @ast(ctx, ex, [K"call"; adopt_scope(string(k)::K"Identifier", ex); children(ex)...])) elseif k == K"op=" || k == K".op=" expand_forms_2(ctx, expand_update_operator(ctx, ex)) elseif k == K"=" expand_assignment(ctx, ex) elseif k == K"break" if numchildren(ex) > 0 ex else @ast ctx ex [K"break" "loop_exit"::K"symbolic_label"] end elseif k == K"continue" @ast ctx ex [K"break" "loop_cont"::K"symbolic_label"] elseif k == K"comparison" expand_forms_2(ctx, expand_compare_chain(ctx, ex)) elseif k == K"doc" @chk numchildren(ex) == 2 expand_doc(ctx, ex[2], ex) elseif k == K"for" expand_forms_2(ctx, expand_for(ctx, ex)) elseif k == K"comprehension" @chk numchildren(ex) == 1 @chk kind(ex[1]) == K"generator" @ast ctx ex [K"call"; "collect"::K"top"; expand_forms_2(ctx, ex[1])] elseif k == K"typed_comprehension" @chk numchildren(ex) == 2 @chk kind(ex[2]) == K"generator" if numchildren(ex[2]) == 2 && kind((ex[2])[2]) == K"iteration" expand_forms_2(ctx, expand_comprehension_to_loops(ctx, ex)) else @ast ctx ex [K"call"; "collect"::K"top"; expand_forms_2(ctx, ex[1]); expand_forms_2(ctx, ex[2])] end elseif k == K"generator" expand_forms_2(ctx, expand_generator(ctx, ex)) elseif k == K"->" || k == K"do" expand_forms_2(ctx, expand_arrow(ctx, ex)) elseif k == K"function" expand_forms_2(ctx, expand_function_def(ctx, ex, docs)) elseif k == K"macro" @ast ctx ex [K"block"; [K"assert"; "global_toplevel_only"::K"Symbol"; [K"inert" ex]]; expand_forms_2(ctx, expand_macro_def(ctx, ex))] elseif k == K"if" || k == K"elseif" @chk numchildren(ex) >= 2 @ast ctx ex [k; expand_condition(ctx, ex[1]); expand_forms_2(ctx, ex[2:var"end"])...] elseif k == K"let" expand_forms_2(ctx, expand_let(ctx, ex)) elseif k == K"const" expand_const_decl(ctx, ex) elseif k == K"local" || k == K"global" if k == K"global" && kind(ex[1]) == K"const" expand_const_decl(ctx, @ast(ctx, ex, [K"const" [K"global" (ex[1])[1]]])) else expand_decls(ctx, ex) end elseif k == K"where" expand_forms_2(ctx, expand_wheres(ctx, ex)) elseif k == K"braces" || k == K"bracescat" throw(LoweringError(ex, "{ } syntax is reserved for future use")) elseif k == K"string" if numchildren(ex) == 1 && kind(ex[1]) == K"String" ex[1] else @ast ctx ex [K"call"; "string"::K"top"; expand_forms_2(ctx, children(ex))...] end elseif k == K"try" expand_forms_2(ctx, expand_try(ctx, ex)) elseif k == K"tuple" if has_parameters(ex) if numchildren(ex) > 1 throw(LoweringError(ex[var"end"], "unexpected semicolon in tuple - use `,` to separate tuple elements")) end expand_forms_2(ctx, expand_named_tuple(ctx, ex, children(ex[1]))) elseif any_assignment(children(ex)) expand_forms_2(ctx, expand_named_tuple(ctx, ex, children(ex))) else expand_forms_2(ctx, @ast(ctx, ex, [K"call"; "tuple"::K"core"; children(ex)...])) end elseif k == K"$" throw(LoweringError(ex, "`\$` expression outside string or quote block")) elseif k == K"module" throw(LoweringError(ex, "`module` is only allowed at top level")) elseif k == K"import" || k == K"using" expand_import_or_using(ctx, ex) elseif k == K"export" || k == K"public" expand_public(ctx, ex) elseif k == K"abstract" || k == K"primitive" expand_forms_2(ctx, expand_abstract_or_primitive_type(ctx, ex)) elseif k == K"struct" expand_forms_2(ctx, expand_struct_def(ctx, ex, docs)) elseif k == K"ref" sctx = with_stmts(ctx) (arr, idxs) = expand_ref_components(sctx, ex) expand_forms_2(ctx, @ast(ctx, ex, [K"block"; sctx.stmts...; [K"call"; "getindex"::K"top"; arr; idxs...]])) elseif k == K"curly" expand_forms_2(ctx, expand_curly(ctx, ex)) elseif k == K"toplevel" ex2 = @ast(ctx, ex, [K"block"; [K"assert" "toplevel_only"::K"Symbol" [K"inert" ex]]; [K"call"; eval ::K"Value"; ctx.mod ::K"Value"; [K"inert" ex]; [K"parameters"; [K"="; "expr_compat_mode"::K"Identifier"; ctx.expr_compat_mode::K"Bool"]]]]) expand_forms_2(ctx, ex2) elseif k == K"vect" check_no_parameters(ex, "unexpected semicolon in array expression") expand_array(ctx, ex, "vect") elseif k == K"hcat" expand_array(ctx, ex, "hcat") elseif k == K"typed_hcat" expand_array(ctx, ex, "typed_hcat") elseif k == K"opaque_closure" expand_forms_2(ctx, expand_opaque_closure(ctx, ex)) elseif k == K"vcat" || k == K"typed_vcat" expand_forms_2(ctx, expand_vcat(ctx, ex)) elseif k == K"ncat" || k == K"typed_ncat" expand_forms_2(ctx, expand_ncat(ctx, ex)) elseif k == K"while" @chk numchildren(ex) == 2 @ast ctx ex [K"break_block" "loop_exit"::K"symbolic_label"; [K"_while"; expand_condition(ctx, ex[1]); [K"break_block" "loop_cont"::K"symbolic_label"; [(K"scope_block")(scope_type = :neutral); expand_forms_2(ctx, ex[2])]]]] elseif k == K"inert" ex elseif k == K"gc_preserve" s = ssavar(ctx, ex) r = ssavar(ctx, ex) @ast ctx ex [K"block"; s := [K"gc_preserve_begin" (children(ex))[2:var"end"]...]; r := expand_forms_2(ctx, (children(ex))[1]); [K"gc_preserve_end" s]; r] elseif k == K"&" throw(LoweringError(ex, "invalid syntax")) elseif k == K"$" throw(LoweringError(ex, "`\$` expression outside string or quote")) elseif k == K"..." throw(LoweringError(ex, "`...` expression outside call")) elseif is_leaf(ex) ex elseif k == K"return" if numchildren(ex) == 0 @ast ctx ex [K"return" "nothing"::K"core"] elseif numchildren(ex) == 1 mapchildren((e->begin expand_forms_2(ctx, e) end), ctx, ex) else throw(LoweringError(ex, "More than one argument to return")) end else mapchildren((e->begin expand_forms_2(ctx, e) end), ctx, ex) end elseif k == K"." expand_forms_2(ctx, expand_dot(ctx, ex)) elseif k == K"?" @chk numchildren(ex) == 3 expand_forms_2(ctx, @ast(ctx, ex, [K"if" children(ex)...])) elseif k == K"&&" || k == K"||" @chk numchildren(ex) > 1 cs = expand_cond_children(ctx, ex) cond = if length(cs) == 2 cs[1] else makenode(ctx, ex, k, cs[1:var"end" - 1]) end if k == K"&&" @ast ctx ex [K"if" cond cs[var"end"] false::K"Bool"] else @ast ctx ex [K"if" cond true::K"Bool" cs[var"end"]] end elseif k == K"::" @chk numchildren(ex) == 2 "`::` must be written `value::type` outside function argument lists" @ast ctx ex [K"call"; "typeassert"::K"core"; expand_forms_2(ctx, ex[1]); expand_forms_2(ctx, ex[2])] elseif k == K"<:" || (k == K">:" || k == K"-->") expand_forms_2(ctx, @ast(ctx, ex, [K"call"; adopt_scope(string(k)::K"Identifier", ex); children(ex)...])) elseif k == K"op=" || k == K".op=" expand_forms_2(ctx, expand_update_operator(ctx, ex)) elseif k == K"=" expand_assignment(ctx, ex) elseif k == K"break" if numchildren(ex) > 0 ex else @ast ctx ex [K"break" "loop_exit"::K"symbolic_label"] end elseif k == K"continue" @ast ctx ex [K"break" "loop_cont"::K"symbolic_label"] elseif k == K"comparison" expand_forms_2(ctx, expand_compare_chain(ctx, ex)) elseif k == K"doc" @chk numchildren(ex) == 2 expand_doc(ctx, ex[2], ex) elseif k == K"for" expand_forms_2(ctx, expand_for(ctx, ex)) elseif k == K"comprehension" @chk numchildren(ex) == 1 @chk kind(ex[1]) == K"generator" @ast ctx ex [K"call"; "collect"::K"top"; expand_forms_2(ctx, ex[1])] elseif k == K"typed_comprehension" @chk numchildren(ex) == 2 @chk kind(ex[2]) == K"generator" if numchildren(ex[2]) == 2 && kind((ex[2])[2]) == K"iteration" expand_forms_2(ctx, expand_comprehension_to_loops(ctx, ex)) else @ast ctx ex [K"call"; "collect"::K"top"; expand_forms_2(ctx, ex[1]); expand_forms_2(ctx, ex[2])] end elseif k == K"generator" expand_forms_2(ctx, expand_generator(ctx, ex)) elseif k == K"->" || k == K"do" expand_forms_2(ctx, expand_arrow(ctx, ex)) elseif k == K"function" expand_forms_2(ctx, expand_function_def(ctx, ex, docs)) elseif k == K"macro" @ast ctx ex [K"block"; [K"assert"; "global_toplevel_only"::K"Symbol"; [K"inert" ex]]; expand_forms_2(ctx, expand_macro_def(ctx, ex))] elseif k == K"if" || k == K"elseif" @chk numchildren(ex) >= 2 @ast ctx ex [k; expand_condition(ctx, ex[1]); expand_forms_2(ctx, ex[2:var"end"])...] elseif k == K"let" expand_forms_2(ctx, expand_let(ctx, ex)) elseif k == K"const" expand_const_decl(ctx, ex) elseif k == K"local" || k == K"global" if k == K"global" && kind(ex[1]) == K"const" expand_const_decl(ctx, @ast(ctx, ex, [K"const" [K"global" (ex[1])[1]]])) else expand_decls(ctx, ex) end elseif k == K"where" expand_forms_2(ctx, expand_wheres(ctx, ex)) elseif k == K"braces" || k == K"bracescat" throw(LoweringError(ex, "{ } syntax is reserved for future use")) elseif k == K"string" if numchildren(ex) == 1 && kind(ex[1]) == K"String" ex[1] else @ast ctx ex [K"call"; "string"::K"top"; expand_forms_2(ctx, children(ex))...] end elseif k == K"try" expand_forms_2(ctx, expand_try(ctx, ex)) elseif k == K"tuple" if has_parameters(ex) if numchildren(ex) > 1 throw(LoweringError(ex[var"end"], "unexpected semicolon in tuple - use `,` to separate tuple elements")) end expand_forms_2(ctx, expand_named_tuple(ctx, ex, children(ex[1]))) elseif any_assignment(children(ex)) expand_forms_2(ctx, expand_named_tuple(ctx, ex, children(ex))) else expand_forms_2(ctx, @ast(ctx, ex, [K"call"; "tuple"::K"core"; children(ex)...])) end elseif k == K"$" throw(LoweringError(ex, "`\$` expression outside string or quote block")) elseif k == K"module" throw(LoweringError(ex, "`module` is only allowed at top level")) elseif k == K"import" || k == K"using" expand_import_or_using(ctx, ex) elseif k == K"export" || k == K"public" expand_public(ctx, ex) elseif k == K"abstract" || k == K"primitive" expand_forms_2(ctx, expand_abstract_or_primitive_type(ctx, ex)) elseif k == K"struct" expand_forms_2(ctx, expand_struct_def(ctx, ex, docs)) elseif k == K"ref" sctx = with_stmts(ctx) (arr, idxs) = expand_ref_components(sctx, ex) expand_forms_2(ctx, @ast(ctx, ex, [K"block"; sctx.stmts...; [K"call"; "getindex"::K"top"; arr; idxs...]])) elseif k == K"curly" expand_forms_2(ctx, expand_curly(ctx, ex)) elseif k == K"toplevel" ex2 = @ast(ctx, ex, [K"block"; [K"assert" "toplevel_only"::K"Symbol" [K"inert" ex]]; [K"call"; eval::K"Value"; ctx.mod::K"Value"; [K"inert" ex]; [K"parameters"; [K"="; "expr_compat_mode"::K"Identifier"; ctx.expr_compat_mode::K"Bool"]]]]) expand_forms_2(ctx, ex2) elseif k == K"vect" check_no_parameters(ex, "unexpected semicolon in array expression") expand_array(ctx, ex, "vect") elseif k == K"hcat" expand_array(ctx, ex, "hcat") elseif k == K"typed_hcat" expand_array(ctx, ex, "typed_hcat") elseif k == K"opaque_closure" expand_forms_2(ctx, expand_opaque_closure(ctx, ex)) elseif k == K"vcat" || k == K"typed_vcat" expand_forms_2(ctx, expand_vcat(ctx, ex)) elseif k == K"ncat" || k == K"typed_ncat" expand_forms_2(ctx, expand_ncat(ctx, ex)) elseif k == K"while" @chk numchildren(ex) == 2 @ast ctx ex [K"break_block" "loop_exit"::K"symbolic_label"; [K"_while"; expand_condition(ctx, ex[1]); [K"break_block" "loop_cont"::K"symbolic_label"; [(K"scope_block")(scope_type = :neutral); expand_forms_2(ctx, ex[2])]]]] elseif k == K"inert" ex elseif k == K"gc_preserve" s = ssavar(ctx, ex) r = ssavar(ctx, ex) @ast ctx ex [K"block"; s := [K"gc_preserve_begin" (children(ex))[2:var"end"]...]; r := expand_forms_2(ctx, (children(ex))[1]); [K"gc_preserve_end" s]; r] elseif k == K"&" throw(LoweringError(ex, "invalid syntax")) elseif k == K"$" throw(LoweringError(ex, "`\$` expression outside string or quote")) elseif k == K"..." throw(LoweringError(ex, "`...` expression outside call")) elseif is_leaf(ex) ex elseif k == K"return" if numchildren(ex) == 0 @ast ctx ex [K"return" "nothing"::K"core"] elseif numchildren(ex) == 1 mapchildren((e->begin expand_forms_2(ctx, e) end), ctx, ex) else throw(LoweringError(ex, "More than one argument to return")) end else mapchildren((e->begin expand_forms_2(ctx, e) end), ctx, ex) end elseif k == K"dotcall" || (k == K".&&" || (k == K".||" || k == K".=")) expand_forms_2(ctx, expand_fuse_broadcast(ctx, ex)) elseif k == K"." expand_forms_2(ctx, expand_dot(ctx, ex)) elseif k == K"?" @chk numchildren(ex) == 3 expand_forms_2(ctx, @ast(ctx, ex, [K"if" children(ex)...])) elseif k == K"&&" || k == K"||" @chk numchildren(ex) > 1 cs = expand_cond_children(ctx, ex) cond = if length(cs) == 2 cs[1] else makenode(ctx, ex, k, cs[1:var"end" - 1]) end if k == K"&&" @ast ctx ex [K"if" cond cs[var"end"] false::K"Bool"] else @ast ctx ex [K"if" cond true::K"Bool" cs[var"end"]] end elseif k == K"::" @chk numchildren(ex) == 2 "`::` must be written `value::type` outside function argument lists" @ast ctx ex [K"call"; "typeassert"::K"core"; expand_forms_2(ctx, ex[1]); expand_forms_2(ctx, ex[2])] elseif k == K"<:" || (k == K">:" || k == K"-->") expand_forms_2(ctx, @ast(ctx, ex, [K"call"; adopt_scope(string(k)::K"Identifier", ex); children(ex)...])) elseif k == K"op=" || k == K".op=" expand_forms_2(ctx, expand_update_operator(ctx, ex)) elseif k == K"=" expand_assignment(ctx, ex) elseif k == K"break" if numchildren(ex) > 0 ex else @ast ctx ex [K"break" "loop_exit"::K"symbolic_label"] end elseif k == K"continue" @ast ctx ex [K"break" "loop_cont"::K"symbolic_label"] elseif k == K"comparison" expand_forms_2(ctx, expand_compare_chain(ctx, ex)) elseif k == K"doc" @chk numchildren(ex) == 2 expand_doc(ctx, ex[2], ex) elseif k == K"for" expand_forms_2(ctx, expand_for(ctx, ex)) elseif k == K"comprehension" @chk numchildren(ex) == 1 @chk kind(ex[1]) == K"generator" @ast ctx ex [K"call"; "collect"::K"top"; expand_forms_2(ctx, ex[1])] elseif k == K"typed_comprehension" @chk numchildren(ex) == 2 @chk kind(ex[2]) == K"generator" if numchildren(ex[2]) == 2 && kind((ex[2])[2]) == K"iteration" expand_forms_2(ctx, expand_comprehension_to_loops(ctx, ex)) else @ast ctx ex [K"call"; "collect"::K"top"; expand_forms_2(ctx, ex[1]); expand_forms_2(ctx, ex[2])] end elseif k == K"generator" expand_forms_2(ctx, expand_generator(ctx, ex)) elseif k == K"->" || k == K"do" expand_forms_2(ctx, expand_arrow(ctx, ex)) elseif k == K"function" expand_forms_2(ctx, expand_function_def(ctx, ex, docs)) elseif k == K"macro" @ast ctx ex [K"block"; [K"assert"; "global_toplevel_only"::K"Symbol"; [K"inert" ex]]; expand_forms_2(ctx, expand_macro_def(ctx, ex))] elseif k == K"if" || k == K"elseif" @chk numchildren(ex) >= 2 @ast ctx ex [k; expand_condition(ctx, ex[1]); expand_forms_2(ctx, ex[2:var"end"])...] elseif k == K"let" expand_forms_2(ctx, expand_let(ctx, ex)) elseif k == K"const" expand_const_decl(ctx, ex) elseif k == K"local" || k == K"global" if k == K"global" && kind(ex[1]) == K"const" expand_const_decl(ctx, @ast(ctx, ex, [K"const" [K"global" (ex[1])[1]]])) else expand_decls(ctx, ex) end elseif k == K"where" expand_forms_2(ctx, expand_wheres(ctx, ex)) elseif k == K"braces" || k == K"bracescat" throw(LoweringError(ex, "{ } syntax is reserved for future use")) elseif k == K"string" if numchildren(ex) == 1 && kind(ex[1]) == K"String" ex[1] else @ast ctx ex [K"call"; "string"::K"top"; expand_forms_2(ctx, children(ex))...] end elseif k == K"try" expand_forms_2(ctx, expand_try(ctx, ex)) elseif k == K"tuple" if has_parameters(ex) if numchildren(ex) > 1 throw(LoweringError(ex[var"end"], "unexpected semicolon in tuple - use `,` to separate tuple elements")) end expand_forms_2(ctx, expand_named_tuple(ctx, ex, children(ex[1]))) elseif any_assignment(children(ex)) expand_forms_2(ctx, expand_named_tuple(ctx, ex, children(ex))) else expand_forms_2(ctx, @ast(ctx, ex, [K"call"; "tuple"::K"core"; children(ex)...])) end elseif k == K"$" throw(LoweringError(ex, "`\$` expression outside string or quote block")) elseif k == K"module" throw(LoweringError(ex, "`module` is only allowed at top level")) elseif k == K"import" || k == K"using" expand_import_or_using(ctx, ex) elseif k == K"export" || k == K"public" expand_public(ctx, ex) elseif k == K"abstract" || k == K"primitive" expand_forms_2(ctx, expand_abstract_or_primitive_type(ctx, ex)) elseif k == K"struct" expand_forms_2(ctx, expand_struct_def(ctx, ex, docs)) elseif k == K"ref" sctx = with_stmts(ctx) (arr, idxs) = expand_ref_components(sctx, ex) expand_forms_2(ctx, @ast(ctx, ex, [K"block"; sctx.stmts...; [K"call"; "getindex"::K"top"; arr; idxs...]])) elseif k == K"curly" expand_forms_2(ctx, expand_curly(ctx, ex)) elseif k == K"toplevel" ex2 = @ast(ctx, ex, [K"block"; [K"assert" "toplevel_only"::K"Symbol" [K"inert" ex]]; [K"call"; eval ::K"Value"; ctx.mod ::K"Value"; [K"inert" ex]; [K"parameters"; [K"="; "expr_compat_mode"::K"Identifier"; ctx.expr_compat_mode::K"Bool"]]]]) expand_forms_2(ctx, ex2) elseif k == K"vect" check_no_parameters(ex, "unexpected semicolon in array expression") expand_array(ctx, ex, "vect") elseif k == K"hcat" expand_array(ctx, ex, "hcat") elseif k == K"typed_hcat" expand_array(ctx, ex, "typed_hcat") elseif k == K"opaque_closure" expand_forms_2(ctx, expand_opaque_closure(ctx, ex)) elseif k == K"vcat" || k == K"typed_vcat" expand_forms_2(ctx, expand_vcat(ctx, ex)) elseif k == K"ncat" || k == K"typed_ncat" expand_forms_2(ctx, expand_ncat(ctx, ex)) elseif k == K"while" @chk numchildren(ex) == 2 @ast ctx ex [K"break_block" "loop_exit"::K"symbolic_label"; [K"_while"; expand_condition(ctx, ex[1]); [K"break_block" "loop_cont"::K"symbolic_label"; [(K"scope_block")(scope_type = :neutral); expand_forms_2(ctx, ex[2])]]]] elseif k == K"inert" ex elseif k == K"gc_preserve" s = ssavar(ctx, ex) r = ssavar(ctx, ex) @ast ctx ex [K"block"; s := [K"gc_preserve_begin" (children(ex))[2:var"end"]...]; r := expand_forms_2(ctx, (children(ex))[1]); [K"gc_preserve_end" s]; r] elseif k == K"&" throw(LoweringError(ex, "invalid syntax")) elseif k == K"$" throw(LoweringError(ex, "`\$` expression outside string or quote")) elseif k == K"..." throw(LoweringError(ex, "`...` expression outside call")) elseif is_leaf(ex) ex elseif k == K"return" if numchildren(ex) == 0 @ast ctx ex [K"return" "nothing"::K"core"] elseif numchildren(ex) == 1 mapchildren((e->begin expand_forms_2(ctx, e) end), ctx, ex) else throw(LoweringError(ex, "More than one argument to return")) end else mapchildren((e->begin expand_forms_2(ctx, e) end), ctx, ex) end elseif k == K"dotcall" || (k == K".&&" || (k == K".||" || k == K".=")) expand_forms_2(ctx, expand_fuse_broadcast(ctx, ex)) elseif k == K"." expand_forms_2(ctx, expand_dot(ctx, ex)) elseif k == K"?" @chk numchildren(ex) == 3 expand_forms_2(ctx, @ast(ctx, ex, [K"if" children(ex)...])) elseif k == K"&&" || k == K"||" @chk numchildren(ex) > 1 cs = expand_cond_children(ctx, ex) cond = if length(cs) == 2 cs[1] else makenode(ctx, ex, k, cs[1:var"end" - 1]) end if k == K"&&" @ast ctx ex [K"if" cond cs[var"end"] false::K"Bool"] else @ast ctx ex [K"if" cond true::K"Bool" cs[var"end"]] end elseif k == K"::" @chk numchildren(ex) == 2 "`::` must be written `value::type` outside function argument lists" @ast ctx ex [K"call"; "typeassert"::K"core"; expand_forms_2(ctx, ex[1]); expand_forms_2(ctx, ex[2])] elseif k == K"<:" || (k == K">:" || k == K"-->") expand_forms_2(ctx, @ast(ctx, ex, [K"call"; adopt_scope(string(k)::K"Identifier", ex); children(ex)...])) elseif k == K"op=" || k == K".op=" expand_forms_2(ctx, expand_update_operator(ctx, ex)) elseif k == K"=" expand_assignment(ctx, ex) elseif k == K"break" if numchildren(ex) > 0 ex else @ast ctx ex [K"break" "loop_exit"::K"symbolic_label"] end elseif k == K"continue" @ast ctx ex [K"break" "loop_cont"::K"symbolic_label"] elseif k == K"comparison" expand_forms_2(ctx, expand_compare_chain(ctx, ex)) elseif k == K"doc" @chk numchildren(ex) == 2 expand_doc(ctx, ex[2], ex) elseif k == K"for" expand_forms_2(ctx, expand_for(ctx, ex)) elseif k == K"comprehension" @chk numchildren(ex) == 1 @chk kind(ex[1]) == K"generator" @ast ctx ex [K"call"; "collect"::K"top"; expand_forms_2(ctx, ex[1])] elseif k == K"typed_comprehension" @chk numchildren(ex) == 2 @chk kind(ex[2]) == K"generator" if numchildren(ex[2]) == 2 && kind((ex[2])[2]) == K"iteration" expand_forms_2(ctx, expand_comprehension_to_loops(ctx, ex)) else @ast ctx ex [K"call"; "collect"::K"top"; expand_forms_2(ctx, ex[1]); expand_forms_2(ctx, ex[2])] end elseif k == K"generator" expand_forms_2(ctx, expand_generator(ctx, ex)) elseif k == K"->" || k == K"do" expand_forms_2(ctx, expand_arrow(ctx, ex)) elseif k == K"function" expand_forms_2(ctx, expand_function_def(ctx, ex, docs)) elseif k == K"macro" @ast ctx ex [K"block"; [K"assert"; "global_toplevel_only"::K"Symbol"; [K"inert" ex]]; expand_forms_2(ctx, expand_macro_def(ctx, ex))] elseif k == K"if" || k == K"elseif" @chk numchildren(ex) >= 2 @ast ctx ex [k; expand_condition(ctx, ex[1]); expand_forms_2(ctx, ex[2:var"end"])...] elseif k == K"let" expand_forms_2(ctx, expand_let(ctx, ex)) elseif k == K"const" expand_const_decl(ctx, ex) elseif k == K"local" || k == K"global" if k == K"global" && kind(ex[1]) == K"const" expand_const_decl(ctx, @ast(ctx, ex, [K"const" [K"global" (ex[1])[1]]])) else expand_decls(ctx, ex) end elseif k == K"where" expand_forms_2(ctx, expand_wheres(ctx, ex)) elseif k == K"braces" || k == K"bracescat" throw(LoweringError(ex, "{ } syntax is reserved for future use")) elseif k == K"string" if numchildren(ex) == 1 && kind(ex[1]) == K"String" ex[1] else @ast ctx ex [K"call"; "string"::K"top"; expand_forms_2(ctx, children(ex))...] end elseif k == K"try" expand_forms_2(ctx, expand_try(ctx, ex)) elseif k == K"tuple" if has_parameters(ex) if numchildren(ex) > 1 throw(LoweringError(ex[var"end"], "unexpected semicolon in tuple - use `,` to separate tuple elements")) end expand_forms_2(ctx, expand_named_tuple(ctx, ex, children(ex[1]))) elseif any_assignment(children(ex)) expand_forms_2(ctx, expand_named_tuple(ctx, ex, children(ex))) else expand_forms_2(ctx, @ast(ctx, ex, [K"call"; "tuple"::K"core"; children(ex)...])) end elseif k == K"$" throw(LoweringError(ex, "`\$` expression outside string or quote block")) elseif k == K"module" throw(LoweringError(ex, "`module` is only allowed at top level")) elseif k == K"import" || k == K"using" expand_import_or_using(ctx, ex) elseif k == K"export" || k == K"public" expand_public(ctx, ex) elseif k == K"abstract" || k == K"primitive" expand_forms_2(ctx, expand_abstract_or_primitive_type(ctx, ex)) elseif k == K"struct" expand_forms_2(ctx, expand_struct_def(ctx, ex, docs)) elseif k == K"ref" sctx = with_stmts(ctx) (arr, idxs) = expand_ref_components(sctx, ex) expand_forms_2(ctx, @ast(ctx, ex, [K"block"; sctx.stmts...; [K"call"; "getindex"::K"top"; arr; idxs...]])) elseif k == K"curly" expand_forms_2(ctx, expand_curly(ctx, ex)) elseif k == K"toplevel" ex2 = @ast(ctx, ex, [K"block"; [K"assert" "toplevel_only"::K"Symbol" [K"inert" ex]]; [K"call"; eval::K"Value"; ctx.mod::K"Value"; [K"inert" ex]; [K"parameters"; [K"="; "expr_compat_mode"::K"Identifier"; ctx.expr_compat_mode::K"Bool"]]]]) expand_forms_2(ctx, ex2) elseif k == K"vect" check_no_parameters(ex, "unexpected semicolon in array expression") expand_array(ctx, ex, "vect") elseif k == K"hcat" expand_array(ctx, ex, "hcat") elseif k == K"typed_hcat" expand_array(ctx, ex, "typed_hcat") elseif k == K"opaque_closure" expand_forms_2(ctx, expand_opaque_closure(ctx, ex)) elseif k == K"vcat" || k == K"typed_vcat" expand_forms_2(ctx, expand_vcat(ctx, ex)) elseif k == K"ncat" || k == K"typed_ncat" expand_forms_2(ctx, expand_ncat(ctx, ex)) elseif k == K"while" @chk numchildren(ex) == 2 @ast ctx ex [K"break_block" "loop_exit"::K"symbolic_label"; [K"_while"; expand_condition(ctx, ex[1]); [K"break_block" "loop_cont"::K"symbolic_label"; [(K"scope_block")(scope_type = :neutral); expand_forms_2(ctx, ex[2])]]]] elseif k == K"inert" ex elseif k == K"gc_preserve" s = ssavar(ctx, ex) r = ssavar(ctx, ex) @ast ctx ex [K"block"; s := [K"gc_preserve_begin" (children(ex))[2:var"end"]...]; r := expand_forms_2(ctx, (children(ex))[1]); [K"gc_preserve_end" s]; r] elseif k == K"&" throw(LoweringError(ex, "invalid syntax")) elseif k == K"$" throw(LoweringError(ex, "`\$` expression outside string or quote")) elseif k == K"..." throw(LoweringError(ex, "`...` expression outside call")) elseif is_leaf(ex) ex elseif k == K"return" if numchildren(ex) == 0 @ast ctx ex [K"return" "nothing"::K"core"] elseif numchildren(ex) == 1 mapchildren((e->begin expand_forms_2(ctx, e) end), ctx, ex) else throw(LoweringError(ex, "More than one argument to return")) end else mapchildren((e->begin expand_forms_2(ctx, e) end), ctx, ex) end elseif k == K"call" expand_call(ctx, ex) elseif k == K"dotcall" || (k == K".&&" || (k == K".||" || k == K".=")) expand_forms_2(ctx, expand_fuse_broadcast(ctx, ex)) elseif k == K"." expand_forms_2(ctx, expand_dot(ctx, ex)) elseif k == K"?" @chk numchildren(ex) == 3 expand_forms_2(ctx, @ast(ctx, ex, [K"if" children(ex)...])) elseif k == K"&&" || k == K"||" @chk numchildren(ex) > 1 cs = expand_cond_children(ctx, ex) cond = if length(cs) == 2 cs[1] else makenode(ctx, ex, k, cs[1:var"end" - 1]) end if k == K"&&" @ast ctx ex [K"if" cond cs[var"end"] false::K"Bool"] else @ast ctx ex [K"if" cond true::K"Bool" cs[var"end"]] end elseif k == K"::" @chk numchildren(ex) == 2 "`::` must be written `value::type` outside function argument lists" @ast ctx ex [K"call"; "typeassert"::K"core"; expand_forms_2(ctx, ex[1]); expand_forms_2(ctx, ex[2])] elseif k == K"<:" || (k == K">:" || k == K"-->") expand_forms_2(ctx, @ast(ctx, ex, [K"call"; adopt_scope(string(k)::K"Identifier", ex); children(ex)...])) elseif k == K"op=" || k == K".op=" expand_forms_2(ctx, expand_update_operator(ctx, ex)) elseif k == K"=" expand_assignment(ctx, ex) elseif k == K"break" if numchildren(ex) > 0 ex else @ast ctx ex [K"break" "loop_exit"::K"symbolic_label"] end elseif k == K"continue" @ast ctx ex [K"break" "loop_cont"::K"symbolic_label"] elseif k == K"comparison" expand_forms_2(ctx, expand_compare_chain(ctx, ex)) elseif k == K"doc" @chk numchildren(ex) == 2 expand_doc(ctx, ex[2], ex) elseif k == K"for" expand_forms_2(ctx, expand_for(ctx, ex)) elseif k == K"comprehension" @chk numchildren(ex) == 1 @chk kind(ex[1]) == K"generator" @ast ctx ex [K"call"; "collect"::K"top"; expand_forms_2(ctx, ex[1])] elseif k == K"typed_comprehension" @chk numchildren(ex) == 2 @chk kind(ex[2]) == K"generator" if numchildren(ex[2]) == 2 && kind((ex[2])[2]) == K"iteration" expand_forms_2(ctx, expand_comprehension_to_loops(ctx, ex)) else @ast ctx ex [K"call"; "collect"::K"top"; expand_forms_2(ctx, ex[1]); expand_forms_2(ctx, ex[2])] end elseif k == K"generator" expand_forms_2(ctx, expand_generator(ctx, ex)) elseif k == K"->" || k == K"do" expand_forms_2(ctx, expand_arrow(ctx, ex)) elseif k == K"function" expand_forms_2(ctx, expand_function_def(ctx, ex, docs)) elseif k == K"macro" @ast ctx ex [K"block"; [K"assert"; "global_toplevel_only"::K"Symbol"; [K"inert" ex]]; expand_forms_2(ctx, expand_macro_def(ctx, ex))] elseif k == K"if" || k == K"elseif" @chk numchildren(ex) >= 2 @ast ctx ex [k; expand_condition(ctx, ex[1]); expand_forms_2(ctx, ex[2:var"end"])...] elseif k == K"let" expand_forms_2(ctx, expand_let(ctx, ex)) elseif k == K"const" expand_const_decl(ctx, ex) elseif k == K"local" || k == K"global" if k == K"global" && kind(ex[1]) == K"const" expand_const_decl(ctx, @ast(ctx, ex, [K"const" [K"global" (ex[1])[1]]])) else expand_decls(ctx, ex) end elseif k == K"where" expand_forms_2(ctx, expand_wheres(ctx, ex)) elseif k == K"braces" || k == K"bracescat" throw(LoweringError(ex, "{ } syntax is reserved for future use")) elseif k == K"string" if numchildren(ex) == 1 && kind(ex[1]) == K"String" ex[1] else @ast ctx ex [K"call"; "string"::K"top"; expand_forms_2(ctx, children(ex))...] end elseif k == K"try" expand_forms_2(ctx, expand_try(ctx, ex)) elseif k == K"tuple" if has_parameters(ex) if numchildren(ex) > 1 throw(LoweringError(ex[var"end"], "unexpected semicolon in tuple - use `,` to separate tuple elements")) end expand_forms_2(ctx, expand_named_tuple(ctx, ex, children(ex[1]))) elseif any_assignment(children(ex)) expand_forms_2(ctx, expand_named_tuple(ctx, ex, children(ex))) else expand_forms_2(ctx, @ast(ctx, ex, [K"call"; "tuple"::K"core"; children(ex)...])) end elseif k == K"$" throw(LoweringError(ex, "`\$` expression outside string or quote block")) elseif k == K"module" throw(LoweringError(ex, "`module` is only allowed at top level")) elseif k == K"import" || k == K"using" expand_import_or_using(ctx, ex) elseif k == K"export" || k == K"public" expand_public(ctx, ex) elseif k == K"abstract" || k == K"primitive" expand_forms_2(ctx, expand_abstract_or_primitive_type(ctx, ex)) elseif k == K"struct" expand_forms_2(ctx, expand_struct_def(ctx, ex, docs)) elseif k == K"ref" sctx = with_stmts(ctx) (arr, idxs) = expand_ref_components(sctx, ex) expand_forms_2(ctx, @ast(ctx, ex, [K"block"; sctx.stmts...; [K"call"; "getindex"::K"top"; arr; idxs...]])) elseif k == K"curly" expand_forms_2(ctx, expand_curly(ctx, ex)) elseif k == K"toplevel" ex2 = @ast(ctx, ex, [K"block"; [K"assert" "toplevel_only"::K"Symbol" [K"inert" ex]]; [K"call"; eval ::K"Value"; ctx.mod ::K"Value"; [K"inert" ex]; [K"parameters"; [K"="; "expr_compat_mode"::K"Identifier"; ctx.expr_compat_mode::K"Bool"]]]]) expand_forms_2(ctx, ex2) elseif k == K"vect" check_no_parameters(ex, "unexpected semicolon in array expression") expand_array(ctx, ex, "vect") elseif k == K"hcat" expand_array(ctx, ex, "hcat") elseif k == K"typed_hcat" expand_array(ctx, ex, "typed_hcat") elseif k == K"opaque_closure" expand_forms_2(ctx, expand_opaque_closure(ctx, ex)) elseif k == K"vcat" || k == K"typed_vcat" expand_forms_2(ctx, expand_vcat(ctx, ex)) elseif k == K"ncat" || k == K"typed_ncat" expand_forms_2(ctx, expand_ncat(ctx, ex)) elseif k == K"while" @chk numchildren(ex) == 2 @ast ctx ex [K"break_block" "loop_exit"::K"symbolic_label"; [K"_while"; expand_condition(ctx, ex[1]); [K"break_block" "loop_cont"::K"symbolic_label"; [(K"scope_block")(scope_type = :neutral); expand_forms_2(ctx, ex[2])]]]] elseif k == K"inert" ex elseif k == K"gc_preserve" s = ssavar(ctx, ex) r = ssavar(ctx, ex) @ast ctx ex [K"block"; s := [K"gc_preserve_begin" (children(ex))[2:var"end"]...]; r := expand_forms_2(ctx, (children(ex))[1]); [K"gc_preserve_end" s]; r] elseif k == K"&" throw(LoweringError(ex, "invalid syntax")) elseif k == K"$" throw(LoweringError(ex, "`\$` expression outside string or quote")) elseif k == K"..." throw(LoweringError(ex, "`...` expression outside call")) elseif is_leaf(ex) ex elseif k == K"return" if numchildren(ex) == 0 @ast ctx ex [K"return" "nothing"::K"core"] elseif numchildren(ex) == 1 mapchildren((e->begin expand_forms_2(ctx, e) end), ctx, ex) else throw(LoweringError(ex, "More than one argument to return")) end else mapchildren((e->begin expand_forms_2(ctx, e) end), ctx, ex) end elseif k == K"call" expand_call(ctx, ex) elseif k == K"dotcall" || (k == K".&&" || (k == K".||" || k == K".=")) expand_forms_2(ctx, expand_fuse_broadcast(ctx, ex)) elseif k == K"." expand_forms_2(ctx, expand_dot(ctx, ex)) elseif k == K"?" @chk numchildren(ex) == 3 expand_forms_2(ctx, @ast(ctx, ex, [K"if" children(ex)...])) elseif k == K"&&" || k == K"||" @chk numchildren(ex) > 1 cs = expand_cond_children(ctx, ex) cond = if length(cs) == 2 cs[1] else makenode(ctx, ex, k, cs[1:var"end" - 1]) end if k == K"&&" @ast ctx ex [K"if" cond cs[var"end"] false::K"Bool"] else @ast ctx ex [K"if" cond true::K"Bool" cs[var"end"]] end elseif k == K"::" @chk numchildren(ex) == 2 "`::` must be written `value::type` outside function argument lists" @ast ctx ex [K"call"; "typeassert"::K"core"; expand_forms_2(ctx, ex[1]); expand_forms_2(ctx, ex[2])] elseif k == K"<:" || (k == K">:" || k == K"-->") expand_forms_2(ctx, @ast(ctx, ex, [K"call"; adopt_scope(string(k)::K"Identifier", ex); children(ex)...])) elseif k == K"op=" || k == K".op=" expand_forms_2(ctx, expand_update_operator(ctx, ex)) elseif k == K"=" expand_assignment(ctx, ex) elseif k == K"break" if numchildren(ex) > 0 ex else @ast ctx ex [K"break" "loop_exit"::K"symbolic_label"] end elseif k == K"continue" @ast ctx ex [K"break" "loop_cont"::K"symbolic_label"] elseif k == K"comparison" expand_forms_2(ctx, expand_compare_chain(ctx, ex)) elseif k == K"doc" @chk numchildren(ex) == 2 expand_doc(ctx, ex[2], ex) elseif k == K"for" expand_forms_2(ctx, expand_for(ctx, ex)) elseif k == K"comprehension" @chk numchildren(ex) == 1 @chk kind(ex[1]) == K"generator" @ast ctx ex [K"call"; "collect"::K"top"; expand_forms_2(ctx, ex[1])] elseif k == K"typed_comprehension" @chk numchildren(ex) == 2 @chk kind(ex[2]) == K"generator" if numchildren(ex[2]) == 2 && kind((ex[2])[2]) == K"iteration" expand_forms_2(ctx, expand_comprehension_to_loops(ctx, ex)) else @ast ctx ex [K"call"; "collect"::K"top"; expand_forms_2(ctx, ex[1]); expand_forms_2(ctx, ex[2])] end elseif k == K"generator" expand_forms_2(ctx, expand_generator(ctx, ex)) elseif k == K"->" || k == K"do" expand_forms_2(ctx, expand_arrow(ctx, ex)) elseif k == K"function" expand_forms_2(ctx, expand_function_def(ctx, ex, docs)) elseif k == K"macro" @ast ctx ex [K"block"; [K"assert"; "global_toplevel_only"::K"Symbol"; [K"inert" ex]]; expand_forms_2(ctx, expand_macro_def(ctx, ex))] elseif k == K"if" || k == K"elseif" @chk numchildren(ex) >= 2 @ast ctx ex [k; expand_condition(ctx, ex[1]); expand_forms_2(ctx, ex[2:var"end"])...] elseif k == K"let" expand_forms_2(ctx, expand_let(ctx, ex)) elseif k == K"const" expand_const_decl(ctx, ex) elseif k == K"local" || k == K"global" if k == K"global" && kind(ex[1]) == K"const" expand_const_decl(ctx, @ast(ctx, ex, [K"const" [K"global" (ex[1])[1]]])) else expand_decls(ctx, ex) end elseif k == K"where" expand_forms_2(ctx, expand_wheres(ctx, ex)) elseif k == K"braces" || k == K"bracescat" throw(LoweringError(ex, "{ } syntax is reserved for future use")) elseif k == K"string" if numchildren(ex) == 1 && kind(ex[1]) == K"String" ex[1] else @ast ctx ex [K"call"; "string"::K"top"; expand_forms_2(ctx, children(ex))...] end elseif k == K"try" expand_forms_2(ctx, expand_try(ctx, ex)) elseif k == K"tuple" if has_parameters(ex) if numchildren(ex) > 1 throw(LoweringError(ex[var"end"], "unexpected semicolon in tuple - use `,` to separate tuple elements")) end expand_forms_2(ctx, expand_named_tuple(ctx, ex, children(ex[1]))) elseif any_assignment(children(ex)) expand_forms_2(ctx, expand_named_tuple(ctx, ex, children(ex))) else expand_forms_2(ctx, @ast(ctx, ex, [K"call"; "tuple"::K"core"; children(ex)...])) end elseif k == K"$" throw(LoweringError(ex, "`\$` expression outside string or quote block")) elseif k == K"module" throw(LoweringError(ex, "`module` is only allowed at top level")) elseif k == K"import" || k == K"using" expand_import_or_using(ctx, ex) elseif k == K"export" || k == K"public" expand_public(ctx, ex) elseif k == K"abstract" || k == K"primitive" expand_forms_2(ctx, expand_abstract_or_primitive_type(ctx, ex)) elseif k == K"struct" expand_forms_2(ctx, expand_struct_def(ctx, ex, docs)) elseif k == K"ref" sctx = with_stmts(ctx) (arr, idxs) = expand_ref_components(sctx, ex) expand_forms_2(ctx, @ast(ctx, ex, [K"block"; sctx.stmts...; [K"call"; "getindex"::K"top"; arr; idxs...]])) elseif k == K"curly" expand_forms_2(ctx, expand_curly(ctx, ex)) elseif k == K"toplevel" ex2 = @ast(ctx, ex, [K"block"; [K"assert" "toplevel_only"::K"Symbol" [K"inert" ex]]; [K"call"; eval::K"Value"; ctx.mod::K"Value"; [K"inert" ex]; [K"parameters"; [K"="; "expr_compat_mode"::K"Identifier"; ctx.expr_compat_mode::K"Bool"]]]]) expand_forms_2(ctx, ex2) elseif k == K"vect" check_no_parameters(ex, "unexpected semicolon in array expression") expand_array(ctx, ex, "vect") elseif k == K"hcat" expand_array(ctx, ex, "hcat") elseif k == K"typed_hcat" expand_array(ctx, ex, "typed_hcat") elseif k == K"opaque_closure" expand_forms_2(ctx, expand_opaque_closure(ctx, ex)) elseif k == K"vcat" || k == K"typed_vcat" expand_forms_2(ctx, expand_vcat(ctx, ex)) elseif k == K"ncat" || k == K"typed_ncat" expand_forms_2(ctx, expand_ncat(ctx, ex)) elseif k == K"while" @chk numchildren(ex) == 2 @ast ctx ex [K"break_block" "loop_exit"::K"symbolic_label"; [K"_while"; expand_condition(ctx, ex[1]); [K"break_block" "loop_cont"::K"symbolic_label"; [(K"scope_block")(scope_type = :neutral); expand_forms_2(ctx, ex[2])]]]] elseif k == K"inert" ex elseif k == K"gc_preserve" s = ssavar(ctx, ex) r = ssavar(ctx, ex) @ast ctx ex [K"block"; s := [K"gc_preserve_begin" (children(ex))[2:var"end"]...]; r := expand_forms_2(ctx, (children(ex))[1]); [K"gc_preserve_end" s]; r] elseif k == K"&" throw(LoweringError(ex, "invalid syntax")) elseif k == K"$" throw(LoweringError(ex, "`\$` expression outside string or quote")) elseif k == K"..." throw(LoweringError(ex, "`...` expression outside call")) elseif is_leaf(ex) ex elseif k == K"return" if numchildren(ex) == 0 @ast ctx ex [K"return" "nothing"::K"core"] elseif numchildren(ex) == 1 mapchildren((e->begin expand_forms_2(ctx, e) end), ctx, ex) else throw(LoweringError(ex, "More than one argument to return")) end else mapchildren((e->begin expand_forms_2(ctx, e) end), ctx, ex) end if k == K"atomic" throw(LoweringError(ex, "unimplemented or unsupported atomic declaration")) elseif k == K"call" expand_call(ctx, ex) elseif k == K"dotcall" || (k == K".&&" || (k == K".||" || k == K".=")) expand_forms_2(ctx, expand_fuse_broadcast(ctx, ex)) elseif k == K"." expand_forms_2(ctx, expand_dot(ctx, ex)) elseif k == K"?" @chk numchildren(ex) == 3 expand_forms_2(ctx, @ast(ctx, ex, [K"if" children(ex)...])) elseif k == K"&&" || k == K"||" @chk numchildren(ex) > 1 cs = expand_cond_children(ctx, ex) cond = if length(cs) == 2 cs[1] else makenode(ctx, ex, k, cs[1:var"end" - 1]) end if k == K"&&" @ast ctx ex [K"if" cond cs[var"end"] false::K"Bool"] else @ast ctx ex [K"if" cond true::K"Bool" cs[var"end"]] end elseif k == K"::" @chk numchildren(ex) == 2 "`::` must be written `value::type` outside function argument lists" @ast ctx ex [K"call"; "typeassert"::K"core"; expand_forms_2(ctx, ex[1]); expand_forms_2(ctx, ex[2])] elseif k == K"<:" || (k == K">:" || k == K"-->") expand_forms_2(ctx, @ast(ctx, ex, [K"call"; adopt_scope(string(k)::K"Identifier", ex); children(ex)...])) elseif k == K"op=" || k == K".op=" expand_forms_2(ctx, expand_update_operator(ctx, ex)) elseif k == K"=" expand_assignment(ctx, ex) elseif k == K"break" if numchildren(ex) > 0 ex else @ast ctx ex [K"break" "loop_exit"::K"symbolic_label"] end elseif k == K"continue" @ast ctx ex [K"break" "loop_cont"::K"symbolic_label"] elseif k == K"comparison" expand_forms_2(ctx, expand_compare_chain(ctx, ex)) elseif k == K"doc" @chk numchildren(ex) == 2 expand_doc(ctx, ex[2], ex) elseif k == K"for" expand_forms_2(ctx, expand_for(ctx, ex)) elseif k == K"comprehension" @chk numchildren(ex) == 1 @chk kind(ex[1]) == K"generator" @ast ctx ex [K"call"; "collect"::K"top"; expand_forms_2(ctx, ex[1])] elseif k == K"typed_comprehension" @chk numchildren(ex) == 2 @chk kind(ex[2]) == K"generator" if numchildren(ex[2]) == 2 && kind((ex[2])[2]) == K"iteration" expand_forms_2(ctx, expand_comprehension_to_loops(ctx, ex)) else @ast ctx ex [K"call"; "collect"::K"top"; expand_forms_2(ctx, ex[1]); expand_forms_2(ctx, ex[2])] end elseif k == K"generator" expand_forms_2(ctx, expand_generator(ctx, ex)) elseif k == K"->" || k == K"do" expand_forms_2(ctx, expand_arrow(ctx, ex)) elseif k == K"function" expand_forms_2(ctx, expand_function_def(ctx, ex, docs)) elseif k == K"macro" @ast ctx ex [K"block"; [K"assert"; "global_toplevel_only"::K"Symbol"; [K"inert" ex]]; expand_forms_2(ctx, expand_macro_def(ctx, ex))] elseif k == K"if" || k == K"elseif" @chk numchildren(ex) >= 2 @ast ctx ex [k; expand_condition(ctx, ex[1]); expand_forms_2(ctx, ex[2:var"end"])...] elseif k == K"let" expand_forms_2(ctx, expand_let(ctx, ex)) elseif k == K"const" expand_const_decl(ctx, ex) elseif k == K"local" || k == K"global" if k == K"global" && kind(ex[1]) == K"const" expand_const_decl(ctx, @ast(ctx, ex, [K"const" [K"global" (ex[1])[1]]])) else expand_decls(ctx, ex) end elseif k == K"where" expand_forms_2(ctx, expand_wheres(ctx, ex)) elseif k == K"braces" || k == K"bracescat" throw(LoweringError(ex, "{ } syntax is reserved for future use")) elseif k == K"string" if numchildren(ex) == 1 && kind(ex[1]) == K"String" ex[1] else @ast ctx ex [K"call"; "string"::K"top"; expand_forms_2(ctx, children(ex))...] end elseif k == K"try" expand_forms_2(ctx, expand_try(ctx, ex)) elseif k == K"tuple" if has_parameters(ex) if numchildren(ex) > 1 throw(LoweringError(ex[var"end"], "unexpected semicolon in tuple - use `,` to separate tuple elements")) end expand_forms_2(ctx, expand_named_tuple(ctx, ex, children(ex[1]))) elseif any_assignment(children(ex)) expand_forms_2(ctx, expand_named_tuple(ctx, ex, children(ex))) else expand_forms_2(ctx, @ast(ctx, ex, [K"call"; "tuple"::K"core"; children(ex)...])) end elseif k == K"$" throw(LoweringError(ex, "`\$` expression outside string or quote block")) elseif k == K"module" throw(LoweringError(ex, "`module` is only allowed at top level")) elseif k == K"import" || k == K"using" expand_import_or_using(ctx, ex) elseif k == K"export" || k == K"public" expand_public(ctx, ex) elseif k == K"abstract" || k == K"primitive" expand_forms_2(ctx, expand_abstract_or_primitive_type(ctx, ex)) elseif k == K"struct" expand_forms_2(ctx, expand_struct_def(ctx, ex, docs)) elseif k == K"ref" sctx = with_stmts(ctx) (arr, idxs) = expand_ref_components(sctx, ex) expand_forms_2(ctx, @ast(ctx, ex, [K"block"; sctx.stmts...; [K"call"; "getindex"::K"top"; arr; idxs...]])) elseif k == K"curly" expand_forms_2(ctx, expand_curly(ctx, ex)) elseif k == K"toplevel" ex2 = @ast(ctx, ex, [K"block"; [K"assert" "toplevel_only"::K"Symbol" [K"inert" ex]]; [K"call"; eval ::K"Value"; ctx.mod ::K"Value"; [K"inert" ex]; [K"parameters"; [K"="; "expr_compat_mode"::K"Identifier"; ctx.expr_compat_mode::K"Bool"]]]]) expand_forms_2(ctx, ex2) elseif k == K"vect" check_no_parameters(ex, "unexpected semicolon in array expression") expand_array(ctx, ex, "vect") elseif k == K"hcat" expand_array(ctx, ex, "hcat") elseif k == K"typed_hcat" expand_array(ctx, ex, "typed_hcat") elseif k == K"opaque_closure" expand_forms_2(ctx, expand_opaque_closure(ctx, ex)) elseif k == K"vcat" || k == K"typed_vcat" expand_forms_2(ctx, expand_vcat(ctx, ex)) elseif k == K"ncat" || k == K"typed_ncat" expand_forms_2(ctx, expand_ncat(ctx, ex)) elseif k == K"while" @chk numchildren(ex) == 2 @ast ctx ex [K"break_block" "loop_exit"::K"symbolic_label"; [K"_while"; expand_condition(ctx, ex[1]); [K"break_block" "loop_cont"::K"symbolic_label"; [(K"scope_block")(scope_type = :neutral); expand_forms_2(ctx, ex[2])]]]] elseif k == K"inert" ex elseif k == K"gc_preserve" s = ssavar(ctx, ex) r = ssavar(ctx, ex) @ast ctx ex [K"block"; s := [K"gc_preserve_begin" (children(ex))[2:var"end"]...]; r := expand_forms_2(ctx, (children(ex))[1]); [K"gc_preserve_end" s]; r] elseif k == K"&" throw(LoweringError(ex, "invalid syntax")) elseif k == K"$" throw(LoweringError(ex, "`\$` expression outside string or quote")) elseif k == K"..." throw(LoweringError(ex, "`...` expression outside call")) elseif is_leaf(ex) ex elseif k == K"return" if numchildren(ex) == 0 @ast ctx ex [K"return" "nothing"::K"core"] elseif numchildren(ex) == 1 mapchildren((e->begin expand_forms_2(ctx, e) end), ctx, ex) else throw(LoweringError(ex, "More than one argument to return")) end else mapchildren((e->begin expand_forms_2(ctx, e) end), ctx, ex) end if k == K"atomic" throw(LoweringError(ex, "unimplemented or unsupported atomic declaration")) elseif k == K"call" expand_call(ctx, ex) elseif k == K"dotcall" || (k == K".&&" || (k == K".||" || k == K".=")) expand_forms_2(ctx, expand_fuse_broadcast(ctx, ex)) elseif k == K"." expand_forms_2(ctx, expand_dot(ctx, ex)) elseif k == K"?" @chk numchildren(ex) == 3 expand_forms_2(ctx, @ast(ctx, ex, [K"if" children(ex)...])) elseif k == K"&&" || k == K"||" @chk numchildren(ex) > 1 cs = expand_cond_children(ctx, ex) cond = if length(cs) == 2 cs[1] else makenode(ctx, ex, k, cs[1:var"end" - 1]) end if k == K"&&" @ast ctx ex [K"if" cond cs[var"end"] false::K"Bool"] else @ast ctx ex [K"if" cond true::K"Bool" cs[var"end"]] end elseif k == K"::" @chk numchildren(ex) == 2 "`::` must be written `value::type` outside function argument lists" @ast ctx ex [K"call"; "typeassert"::K"core"; expand_forms_2(ctx, ex[1]); expand_forms_2(ctx, ex[2])] elseif k == K"<:" || (k == K">:" || k == K"-->") expand_forms_2(ctx, @ast(ctx, ex, [K"call"; adopt_scope(string(k)::K"Identifier", ex); children(ex)...])) elseif k == K"op=" || k == K".op=" expand_forms_2(ctx, expand_update_operator(ctx, ex)) elseif k == K"=" expand_assignment(ctx, ex) elseif k == K"break" if numchildren(ex) > 0 ex else @ast ctx ex [K"break" "loop_exit"::K"symbolic_label"] end elseif k == K"continue" @ast ctx ex [K"break" "loop_cont"::K"symbolic_label"] elseif k == K"comparison" expand_forms_2(ctx, expand_compare_chain(ctx, ex)) elseif k == K"doc" @chk numchildren(ex) == 2 expand_doc(ctx, ex[2], ex) elseif k == K"for" expand_forms_2(ctx, expand_for(ctx, ex)) elseif k == K"comprehension" @chk numchildren(ex) == 1 @chk kind(ex[1]) == K"generator" @ast ctx ex [K"call"; "collect"::K"top"; expand_forms_2(ctx, ex[1])] elseif k == K"typed_comprehension" @chk numchildren(ex) == 2 @chk kind(ex[2]) == K"generator" if numchildren(ex[2]) == 2 && kind((ex[2])[2]) == K"iteration" expand_forms_2(ctx, expand_comprehension_to_loops(ctx, ex)) else @ast ctx ex [K"call"; "collect"::K"top"; expand_forms_2(ctx, ex[1]); expand_forms_2(ctx, ex[2])] end elseif k == K"generator" expand_forms_2(ctx, expand_generator(ctx, ex)) elseif k == K"->" || k == K"do" expand_forms_2(ctx, expand_arrow(ctx, ex)) elseif k == K"function" expand_forms_2(ctx, expand_function_def(ctx, ex, docs)) elseif k == K"macro" @ast ctx ex [K"block"; [K"assert"; "global_toplevel_only"::K"Symbol"; [K"inert" ex]]; expand_forms_2(ctx, expand_macro_def(ctx, ex))] elseif k == K"if" || k == K"elseif" @chk numchildren(ex) >= 2 @ast ctx ex [k; expand_condition(ctx, ex[1]); expand_forms_2(ctx, ex[2:var"end"])...] elseif k == K"let" expand_forms_2(ctx, expand_let(ctx, ex)) elseif k == K"const" expand_const_decl(ctx, ex) elseif k == K"local" || k == K"global" if k == K"global" && kind(ex[1]) == K"const" expand_const_decl(ctx, @ast(ctx, ex, [K"const" [K"global" (ex[1])[1]]])) else expand_decls(ctx, ex) end elseif k == K"where" expand_forms_2(ctx, expand_wheres(ctx, ex)) elseif k == K"braces" || k == K"bracescat" throw(LoweringError(ex, "{ } syntax is reserved for future use")) elseif k == K"string" if numchildren(ex) == 1 && kind(ex[1]) == K"String" ex[1] else @ast ctx ex [K"call"; "string"::K"top"; expand_forms_2(ctx, children(ex))...] end elseif k == K"try" expand_forms_2(ctx, expand_try(ctx, ex)) elseif k == K"tuple" if has_parameters(ex) if numchildren(ex) > 1 throw(LoweringError(ex[var"end"], "unexpected semicolon in tuple - use `,` to separate tuple elements")) end expand_forms_2(ctx, expand_named_tuple(ctx, ex, children(ex[1]))) elseif any_assignment(children(ex)) expand_forms_2(ctx, expand_named_tuple(ctx, ex, children(ex))) else expand_forms_2(ctx, @ast(ctx, ex, [K"call"; "tuple"::K"core"; children(ex)...])) end elseif k == K"$" throw(LoweringError(ex, "`\$` expression outside string or quote block")) elseif k == K"module" throw(LoweringError(ex, "`module` is only allowed at top level")) elseif k == K"import" || k == K"using" expand_import_or_using(ctx, ex) elseif k == K"export" || k == K"public" expand_public(ctx, ex) elseif k == K"abstract" || k == K"primitive" expand_forms_2(ctx, expand_abstract_or_primitive_type(ctx, ex)) elseif k == K"struct" expand_forms_2(ctx, expand_struct_def(ctx, ex, docs)) elseif k == K"ref" sctx = with_stmts(ctx) (arr, idxs) = expand_ref_components(sctx, ex) expand_forms_2(ctx, @ast(ctx, ex, [K"block"; sctx.stmts...; [K"call"; "getindex"::K"top"; arr; idxs...]])) elseif k == K"curly" expand_forms_2(ctx, expand_curly(ctx, ex)) elseif k == K"toplevel" ex2 = @ast(ctx, ex, [K"block"; [K"assert" "toplevel_only"::K"Symbol" [K"inert" ex]]; [K"call"; eval::K"Value"; ctx.mod::K"Value"; [K"inert" ex]; [K"parameters"; [K"="; "expr_compat_mode"::K"Identifier"; ctx.expr_compat_mode::K"Bool"]]]]) expand_forms_2(ctx, ex2) elseif k == K"vect" check_no_parameters(ex, "unexpected semicolon in array expression") expand_array(ctx, ex, "vect") elseif k == K"hcat" expand_array(ctx, ex, "hcat") elseif k == K"typed_hcat" expand_array(ctx, ex, "typed_hcat") elseif k == K"opaque_closure" expand_forms_2(ctx, expand_opaque_closure(ctx, ex)) elseif k == K"vcat" || k == K"typed_vcat" expand_forms_2(ctx, expand_vcat(ctx, ex)) elseif k == K"ncat" || k == K"typed_ncat" expand_forms_2(ctx, expand_ncat(ctx, ex)) elseif k == K"while" @chk numchildren(ex) == 2 @ast ctx ex [K"break_block" "loop_exit"::K"symbolic_label"; [K"_while"; expand_condition(ctx, ex[1]); [K"break_block" "loop_cont"::K"symbolic_label"; [(K"scope_block")(scope_type = :neutral); expand_forms_2(ctx, ex[2])]]]] elseif k == K"inert" ex elseif k == K"gc_preserve" s = ssavar(ctx, ex) r = ssavar(ctx, ex) @ast ctx ex [K"block"; s := [K"gc_preserve_begin" (children(ex))[2:var"end"]...]; r := expand_forms_2(ctx, (children(ex))[1]); [K"gc_preserve_end" s]; r] elseif k == K"&" throw(LoweringError(ex, "invalid syntax")) elseif k == K"$" throw(LoweringError(ex, "`\$` expression outside string or quote")) elseif k == K"..." throw(LoweringError(ex, "`...` expression outside call")) elseif is_leaf(ex) ex elseif k == K"return" if numchildren(ex) == 0 @ast ctx ex [K"return" "nothing"::K"core"] elseif numchildren(ex) == 1 mapchildren((e->begin expand_forms_2(ctx, e) end), ctx, ex) else throw(LoweringError(ex, "More than one argument to return")) end else mapchildren((e->begin expand_forms_2(ctx, e) end), ctx, ex) end begin k = kind(ex) if k == K"atomic" throw(LoweringError(ex, "unimplemented or unsupported atomic declaration")) elseif k == K"call" expand_call(ctx, ex) elseif k == K"dotcall" || (k == K".&&" || (k == K".||" || k == K".=")) expand_forms_2(ctx, expand_fuse_broadcast(ctx, ex)) elseif k == K"." expand_forms_2(ctx, expand_dot(ctx, ex)) elseif k == K"?" @chk numchildren(ex) == 3 expand_forms_2(ctx, @ast(ctx, ex, [K"if" children(ex)...])) elseif k == K"&&" || k == K"||" @chk numchildren(ex) > 1 cs = expand_cond_children(ctx, ex) cond = if length(cs) == 2 cs[1] else makenode(ctx, ex, k, cs[1:var"end" - 1]) end if k == K"&&" @ast ctx ex [K"if" cond cs[var"end"] false::K"Bool"] else @ast ctx ex [K"if" cond true::K"Bool" cs[var"end"]] end elseif k == K"::" @chk numchildren(ex) == 2 "`::` must be written `value::type` outside function argument lists" @ast ctx ex [K"call"; "typeassert"::K"core"; expand_forms_2(ctx, ex[1]); expand_forms_2(ctx, ex[2])] elseif k == K"<:" || (k == K">:" || k == K"-->") expand_forms_2(ctx, @ast(ctx, ex, [K"call"; adopt_scope(string(k)::K"Identifier", ex); children(ex)...])) elseif k == K"op=" || k == K".op=" expand_forms_2(ctx, expand_update_operator(ctx, ex)) elseif k == K"=" expand_assignment(ctx, ex) elseif k == K"break" if numchildren(ex) > 0 ex else @ast ctx ex [K"break" "loop_exit"::K"symbolic_label"] end elseif k == K"continue" @ast ctx ex [K"break" "loop_cont"::K"symbolic_label"] elseif k == K"comparison" expand_forms_2(ctx, expand_compare_chain(ctx, ex)) elseif k == K"doc" @chk numchildren(ex) == 2 expand_doc(ctx, ex[2], ex) elseif k == K"for" expand_forms_2(ctx, expand_for(ctx, ex)) elseif k == K"comprehension" @chk numchildren(ex) == 1 @chk kind(ex[1]) == K"generator" @ast ctx ex [K"call"; "collect"::K"top"; expand_forms_2(ctx, ex[1])] elseif k == K"typed_comprehension" @chk numchildren(ex) == 2 @chk kind(ex[2]) == K"generator" if numchildren(ex[2]) == 2 && kind((ex[2])[2]) == K"iteration" expand_forms_2(ctx, expand_comprehension_to_loops(ctx, ex)) else @ast ctx ex [K"call"; "collect"::K"top"; expand_forms_2(ctx, ex[1]); expand_forms_2(ctx, ex[2])] end elseif k == K"generator" expand_forms_2(ctx, expand_generator(ctx, ex)) elseif k == K"->" || k == K"do" expand_forms_2(ctx, expand_arrow(ctx, ex)) elseif k == K"function" expand_forms_2(ctx, expand_function_def(ctx, ex, docs)) elseif k == K"macro" @ast ctx ex [K"block"; [K"assert"; "global_toplevel_only"::K"Symbol"; [K"inert" ex]]; expand_forms_2(ctx, expand_macro_def(ctx, ex))] elseif k == K"if" || k == K"elseif" @chk numchildren(ex) >= 2 @ast ctx ex [k; expand_condition(ctx, ex[1]); expand_forms_2(ctx, ex[2:var"end"])...] elseif k == K"let" expand_forms_2(ctx, expand_let(ctx, ex)) elseif k == K"const" expand_const_decl(ctx, ex) elseif k == K"local" || k == K"global" if k == K"global" && kind(ex[1]) == K"const" expand_const_decl(ctx, @ast(ctx, ex, [K"const" [K"global" (ex[1])[1]]])) else expand_decls(ctx, ex) end elseif k == K"where" expand_forms_2(ctx, expand_wheres(ctx, ex)) elseif k == K"braces" || k == K"bracescat" throw(LoweringError(ex, "{ } syntax is reserved for future use")) elseif k == K"string" if numchildren(ex) == 1 && kind(ex[1]) == K"String" ex[1] else @ast ctx ex [K"call"; "string"::K"top"; expand_forms_2(ctx, children(ex))...] end elseif k == K"try" expand_forms_2(ctx, expand_try(ctx, ex)) elseif k == K"tuple" if has_parameters(ex) if numchildren(ex) > 1 throw(LoweringError(ex[var"end"], "unexpected semicolon in tuple - use `,` to separate tuple elements")) end expand_forms_2(ctx, expand_named_tuple(ctx, ex, children(ex[1]))) elseif any_assignment(children(ex)) expand_forms_2(ctx, expand_named_tuple(ctx, ex, children(ex))) else expand_forms_2(ctx, @ast(ctx, ex, [K"call"; "tuple"::K"core"; children(ex)...])) end elseif k == K"$" throw(LoweringError(ex, "`\$` expression outside string or quote block")) elseif k == K"module" throw(LoweringError(ex, "`module` is only allowed at top level")) elseif k == K"import" || k == K"using" expand_import_or_using(ctx, ex) elseif k == K"export" || k == K"public" expand_public(ctx, ex) elseif k == K"abstract" || k == K"primitive" expand_forms_2(ctx, expand_abstract_or_primitive_type(ctx, ex)) elseif k == K"struct" expand_forms_2(ctx, expand_struct_def(ctx, ex, docs)) elseif k == K"ref" sctx = with_stmts(ctx) (arr, idxs) = expand_ref_components(sctx, ex) expand_forms_2(ctx, @ast(ctx, ex, [K"block"; sctx.stmts...; [K"call"; "getindex"::K"top"; arr; idxs...]])) elseif k == K"curly" expand_forms_2(ctx, expand_curly(ctx, ex)) elseif k == K"toplevel" ex2 = @ast(ctx, ex, [K"block"; [K"assert" "toplevel_only"::K"Symbol" [K"inert" ex]]; [K"call"; eval ::K"Value"; ctx.mod ::K"Value"; [K"inert" ex]; [K"parameters"; [K"="; "expr_compat_mode"::K"Identifier"; ctx.expr_compat_mode::K"Bool"]]]]) expand_forms_2(ctx, ex2) elseif k == K"vect" check_no_parameters(ex, "unexpected semicolon in array expression") expand_array(ctx, ex, "vect") elseif k == K"hcat" expand_array(ctx, ex, "hcat") elseif k == K"typed_hcat" expand_array(ctx, ex, "typed_hcat") elseif k == K"opaque_closure" expand_forms_2(ctx, expand_opaque_closure(ctx, ex)) elseif k == K"vcat" || k == K"typed_vcat" expand_forms_2(ctx, expand_vcat(ctx, ex)) elseif k == K"ncat" || k == K"typed_ncat" expand_forms_2(ctx, expand_ncat(ctx, ex)) elseif k == K"while" @chk numchildren(ex) == 2 @ast ctx ex [K"break_block" "loop_exit"::K"symbolic_label"; [K"_while"; expand_condition(ctx, ex[1]); [K"break_block" "loop_cont"::K"symbolic_label"; [(K"scope_block")(scope_type = :neutral); expand_forms_2(ctx, ex[2])]]]] elseif k == K"inert" ex elseif k == K"gc_preserve" s = ssavar(ctx, ex) r = ssavar(ctx, ex) @ast ctx ex [K"block"; s := [K"gc_preserve_begin" (children(ex))[2:var"end"]...]; r := expand_forms_2(ctx, (children(ex))[1]); [K"gc_preserve_end" s]; r] elseif k == K"&" throw(LoweringError(ex, "invalid syntax")) elseif k == K"$" throw(LoweringError(ex, "`\$` expression outside string or quote")) elseif k == K"..." throw(LoweringError(ex, "`...` expression outside call")) elseif is_leaf(ex) ex elseif k == K"return" if numchildren(ex) == 0 @ast ctx ex [K"return" "nothing"::K"core"] elseif numchildren(ex) == 1 mapchildren((e->begin expand_forms_2(ctx, e) end), ctx, ex) else throw(LoweringError(ex, "More than one argument to return")) end else mapchildren((e->begin expand_forms_2(ctx, e) end), ctx, ex) end end begin k = kind(ex) if k == K"atomic" throw(LoweringError(ex, "unimplemented or unsupported atomic declaration")) elseif k == K"call" expand_call(ctx, ex) elseif k == K"dotcall" || (k == K".&&" || (k == K".||" || k == K".=")) expand_forms_2(ctx, expand_fuse_broadcast(ctx, ex)) elseif k == K"." expand_forms_2(ctx, expand_dot(ctx, ex)) elseif k == K"?" @chk numchildren(ex) == 3 expand_forms_2(ctx, @ast(ctx, ex, [K"if" children(ex)...])) elseif k == K"&&" || k == K"||" @chk numchildren(ex) > 1 cs = expand_cond_children(ctx, ex) cond = if length(cs) == 2 cs[1] else makenode(ctx, ex, k, cs[1:var"end" - 1]) end if k == K"&&" @ast ctx ex [K"if" cond cs[var"end"] false::K"Bool"] else @ast ctx ex [K"if" cond true::K"Bool" cs[var"end"]] end elseif k == K"::" @chk numchildren(ex) == 2 "`::` must be written `value::type` outside function argument lists" @ast ctx ex [K"call"; "typeassert"::K"core"; expand_forms_2(ctx, ex[1]); expand_forms_2(ctx, ex[2])] elseif k == K"<:" || (k == K">:" || k == K"-->") expand_forms_2(ctx, @ast(ctx, ex, [K"call"; adopt_scope(string(k)::K"Identifier", ex); children(ex)...])) elseif k == K"op=" || k == K".op=" expand_forms_2(ctx, expand_update_operator(ctx, ex)) elseif k == K"=" expand_assignment(ctx, ex) elseif k == K"break" if numchildren(ex) > 0 ex else @ast ctx ex [K"break" "loop_exit"::K"symbolic_label"] end elseif k == K"continue" @ast ctx ex [K"break" "loop_cont"::K"symbolic_label"] elseif k == K"comparison" expand_forms_2(ctx, expand_compare_chain(ctx, ex)) elseif k == K"doc" @chk numchildren(ex) == 2 expand_doc(ctx, ex[2], ex) elseif k == K"for" expand_forms_2(ctx, expand_for(ctx, ex)) elseif k == K"comprehension" @chk numchildren(ex) == 1 @chk kind(ex[1]) == K"generator" @ast ctx ex [K"call"; "collect"::K"top"; expand_forms_2(ctx, ex[1])] elseif k == K"typed_comprehension" @chk numchildren(ex) == 2 @chk kind(ex[2]) == K"generator" if numchildren(ex[2]) == 2 && kind((ex[2])[2]) == K"iteration" expand_forms_2(ctx, expand_comprehension_to_loops(ctx, ex)) else @ast ctx ex [K"call"; "collect"::K"top"; expand_forms_2(ctx, ex[1]); expand_forms_2(ctx, ex[2])] end elseif k == K"generator" expand_forms_2(ctx, expand_generator(ctx, ex)) elseif k == K"->" || k == K"do" expand_forms_2(ctx, expand_arrow(ctx, ex)) elseif k == K"function" expand_forms_2(ctx, expand_function_def(ctx, ex, docs)) elseif k == K"macro" @ast ctx ex [K"block"; [K"assert"; "global_toplevel_only"::K"Symbol"; [K"inert" ex]]; expand_forms_2(ctx, expand_macro_def(ctx, ex))] elseif k == K"if" || k == K"elseif" @chk numchildren(ex) >= 2 @ast ctx ex [k; expand_condition(ctx, ex[1]); expand_forms_2(ctx, ex[2:var"end"])...] elseif k == K"let" expand_forms_2(ctx, expand_let(ctx, ex)) elseif k == K"const" expand_const_decl(ctx, ex) elseif k == K"local" || k == K"global" if k == K"global" && kind(ex[1]) == K"const" expand_const_decl(ctx, @ast(ctx, ex, [K"const" [K"global" (ex[1])[1]]])) else expand_decls(ctx, ex) end elseif k == K"where" expand_forms_2(ctx, expand_wheres(ctx, ex)) elseif k == K"braces" || k == K"bracescat" throw(LoweringError(ex, "{ } syntax is reserved for future use")) elseif k == K"string" if numchildren(ex) == 1 && kind(ex[1]) == K"String" ex[1] else @ast ctx ex [K"call"; "string"::K"top"; expand_forms_2(ctx, children(ex))...] end elseif k == K"try" expand_forms_2(ctx, expand_try(ctx, ex)) elseif k == K"tuple" if has_parameters(ex) if numchildren(ex) > 1 throw(LoweringError(ex[var"end"], "unexpected semicolon in tuple - use `,` to separate tuple elements")) end expand_forms_2(ctx, expand_named_tuple(ctx, ex, children(ex[1]))) elseif any_assignment(children(ex)) expand_forms_2(ctx, expand_named_tuple(ctx, ex, children(ex))) else expand_forms_2(ctx, @ast(ctx, ex, [K"call"; "tuple"::K"core"; children(ex)...])) end elseif k == K"$" throw(LoweringError(ex, "`\$` expression outside string or quote block")) elseif k == K"module" throw(LoweringError(ex, "`module` is only allowed at top level")) elseif k == K"import" || k == K"using" expand_import_or_using(ctx, ex) elseif k == K"export" || k == K"public" expand_public(ctx, ex) elseif k == K"abstract" || k == K"primitive" expand_forms_2(ctx, expand_abstract_or_primitive_type(ctx, ex)) elseif k == K"struct" expand_forms_2(ctx, expand_struct_def(ctx, ex, docs)) elseif k == K"ref" sctx = with_stmts(ctx) (arr, idxs) = expand_ref_components(sctx, ex) expand_forms_2(ctx, @ast(ctx, ex, [K"block"; sctx.stmts...; [K"call"; "getindex"::K"top"; arr; idxs...]])) elseif k == K"curly" expand_forms_2(ctx, expand_curly(ctx, ex)) elseif k == K"toplevel" ex2 = @ast(ctx, ex, [K"block"; [K"assert" "toplevel_only"::K"Symbol" [K"inert" ex]]; [K"call"; eval::K"Value"; ctx.mod::K"Value"; [K"inert" ex]; [K"parameters"; [K"="; "expr_compat_mode"::K"Identifier"; ctx.expr_compat_mode::K"Bool"]]]]) expand_forms_2(ctx, ex2) elseif k == K"vect" check_no_parameters(ex, "unexpected semicolon in array expression") expand_array(ctx, ex, "vect") elseif k == K"hcat" expand_array(ctx, ex, "hcat") elseif k == K"typed_hcat" expand_array(ctx, ex, "typed_hcat") elseif k == K"opaque_closure" expand_forms_2(ctx, expand_opaque_closure(ctx, ex)) elseif k == K"vcat" || k == K"typed_vcat" expand_forms_2(ctx, expand_vcat(ctx, ex)) elseif k == K"ncat" || k == K"typed_ncat" expand_forms_2(ctx, expand_ncat(ctx, ex)) elseif k == K"while" @chk numchildren(ex) == 2 @ast ctx ex [K"break_block" "loop_exit"::K"symbolic_label"; [K"_while"; expand_condition(ctx, ex[1]); [K"break_block" "loop_cont"::K"symbolic_label"; [(K"scope_block")(scope_type = :neutral); expand_forms_2(ctx, ex[2])]]]] elseif k == K"inert" ex elseif k == K"gc_preserve" s = ssavar(ctx, ex) r = ssavar(ctx, ex) @ast ctx ex [K"block"; s := [K"gc_preserve_begin" (children(ex))[2:var"end"]...]; r := expand_forms_2(ctx, (children(ex))[1]); [K"gc_preserve_end" s]; r] elseif k == K"&" throw(LoweringError(ex, "invalid syntax")) elseif k == K"$" throw(LoweringError(ex, "`\$` expression outside string or quote")) elseif k == K"..." throw(LoweringError(ex, "`...` expression outside call")) elseif is_leaf(ex) ex elseif k == K"return" if numchildren(ex) == 0 @ast ctx ex [K"return" "nothing"::K"core"] elseif numchildren(ex) == 1 mapchildren((e->begin expand_forms_2(ctx, e) end), ctx, ex) else throw(LoweringError(ex, "More than one argument to return")) end else mapchildren((e->begin expand_forms_2(ctx, e) end), ctx, ex) end end function expand_forms_2(ctx::DesugaringContext, ex::SyntaxTree, docs = nothing) k = kind(ex) if k == K"atomic" throw(LoweringError(ex, "unimplemented or unsupported atomic declaration")) elseif k == K"call" expand_call(ctx, ex) elseif k == K"dotcall" || (k == K".&&" || (k == K".||" || k == K".=")) expand_forms_2(ctx, expand_fuse_broadcast(ctx, ex)) elseif k == K"." expand_forms_2(ctx, expand_dot(ctx, ex)) elseif k == K"?" @chk numchildren(ex) == 3 expand_forms_2(ctx, @ast(ctx, ex, [K"if" children(ex)...])) elseif k == K"&&" || k == K"||" @chk numchildren(ex) > 1 cs = expand_cond_children(ctx, ex) cond = if length(cs) == 2 cs[1] else makenode(ctx, ex, k, cs[1:var"end" - 1]) end if k == K"&&" @ast ctx ex [K"if" cond cs[var"end"] false::K"Bool"] else @ast ctx ex [K"if" cond true::K"Bool" cs[var"end"]] end elseif k == K"::" @chk numchildren(ex) == 2 "`::` must be written `value::type` outside function argument lists" @ast ctx ex [K"call"; "typeassert"::K"core"; expand_forms_2(ctx, ex[1]); expand_forms_2(ctx, ex[2])] elseif k == K"<:" || (k == K">:" || k == K"-->") expand_forms_2(ctx, @ast(ctx, ex, [K"call"; adopt_scope(string(k)::K"Identifier", ex); children(ex)...])) elseif k == K"op=" || k == K".op=" expand_forms_2(ctx, expand_update_operator(ctx, ex)) elseif k == K"=" expand_assignment(ctx, ex) elseif k == K"break" if numchildren(ex) > 0 ex else @ast ctx ex [K"break" "loop_exit"::K"symbolic_label"] end elseif k == K"continue" @ast ctx ex [K"break" "loop_cont"::K"symbolic_label"] elseif k == K"comparison" expand_forms_2(ctx, expand_compare_chain(ctx, ex)) elseif k == K"doc" @chk numchildren(ex) == 2 expand_doc(ctx, ex[2], ex) elseif k == K"for" expand_forms_2(ctx, expand_for(ctx, ex)) elseif k == K"comprehension" @chk numchildren(ex) == 1 @chk kind(ex[1]) == K"generator" @ast ctx ex [K"call"; "collect"::K"top"; expand_forms_2(ctx, ex[1])] elseif k == K"typed_comprehension" @chk numchildren(ex) == 2 @chk kind(ex[2]) == K"generator" if numchildren(ex[2]) == 2 && kind((ex[2])[2]) == K"iteration" expand_forms_2(ctx, expand_comprehension_to_loops(ctx, ex)) else @ast ctx ex [K"call"; "collect"::K"top"; expand_forms_2(ctx, ex[1]); expand_forms_2(ctx, ex[2])] end elseif k == K"generator" expand_forms_2(ctx, expand_generator(ctx, ex)) elseif k == K"->" || k == K"do" expand_forms_2(ctx, expand_arrow(ctx, ex)) elseif k == K"function" expand_forms_2(ctx, expand_function_def(ctx, ex, docs)) elseif k == K"macro" @ast ctx ex [K"block"; [K"assert"; "global_toplevel_only"::K"Symbol"; [K"inert" ex]]; expand_forms_2(ctx, expand_macro_def(ctx, ex))] elseif k == K"if" || k == K"elseif" @chk numchildren(ex) >= 2 @ast ctx ex [k; expand_condition(ctx, ex[1]); expand_forms_2(ctx, ex[2:var"end"])...] elseif k == K"let" expand_forms_2(ctx, expand_let(ctx, ex)) elseif k == K"const" expand_const_decl(ctx, ex) elseif k == K"local" || k == K"global" if k == K"global" && kind(ex[1]) == K"const" expand_const_decl(ctx, @ast(ctx, ex, [K"const" [K"global" (ex[1])[1]]])) else expand_decls(ctx, ex) end elseif k == K"where" expand_forms_2(ctx, expand_wheres(ctx, ex)) elseif k == K"braces" || k == K"bracescat" throw(LoweringError(ex, "{ } syntax is reserved for future use")) elseif k == K"string" if numchildren(ex) == 1 && kind(ex[1]) == K"String" ex[1] else @ast ctx ex [K"call"; "string"::K"top"; expand_forms_2(ctx, children(ex))...] end elseif k == K"try" expand_forms_2(ctx, expand_try(ctx, ex)) elseif k == K"tuple" if has_parameters(ex) if numchildren(ex) > 1 throw(LoweringError(ex[var"end"], "unexpected semicolon in tuple - use `,` to separate tuple elements")) end expand_forms_2(ctx, expand_named_tuple(ctx, ex, children(ex[1]))) elseif any_assignment(children(ex)) expand_forms_2(ctx, expand_named_tuple(ctx, ex, children(ex))) else expand_forms_2(ctx, @ast(ctx, ex, [K"call"; "tuple"::K"core"; children(ex)...])) end elseif k == K"$" throw(LoweringError(ex, "`\$` expression outside string or quote block")) elseif k == K"module" throw(LoweringError(ex, "`module` is only allowed at top level")) elseif k == K"import" || k == K"using" expand_import_or_using(ctx, ex) elseif k == K"export" || k == K"public" expand_public(ctx, ex) elseif k == K"abstract" || k == K"primitive" expand_forms_2(ctx, expand_abstract_or_primitive_type(ctx, ex)) elseif k == K"struct" expand_forms_2(ctx, expand_struct_def(ctx, ex, docs)) elseif k == K"ref" sctx = with_stmts(ctx) (arr, idxs) = expand_ref_components(sctx, ex) expand_forms_2(ctx, @ast(ctx, ex, [K"block"; sctx.stmts...; [K"call"; "getindex"::K"top"; arr; idxs...]])) elseif k == K"curly" expand_forms_2(ctx, expand_curly(ctx, ex)) elseif k == K"toplevel" ex2 = @ast(ctx, ex, [K"block"; [K"assert" "toplevel_only"::K"Symbol" [K"inert" ex]]; [K"call"; eval ::K"Value"; ctx.mod ::K"Value"; [K"inert" ex]; [K"parameters"; [K"="; "expr_compat_mode"::K"Identifier"; ctx.expr_compat_mode::K"Bool"]]]]) expand_forms_2(ctx, ex2) elseif k == K"vect" check_no_parameters(ex, "unexpected semicolon in array expression") expand_array(ctx, ex, "vect") elseif k == K"hcat" expand_array(ctx, ex, "hcat") elseif k == K"typed_hcat" expand_array(ctx, ex, "typed_hcat") elseif k == K"opaque_closure" expand_forms_2(ctx, expand_opaque_closure(ctx, ex)) elseif k == K"vcat" || k == K"typed_vcat" expand_forms_2(ctx, expand_vcat(ctx, ex)) elseif k == K"ncat" || k == K"typed_ncat" expand_forms_2(ctx, expand_ncat(ctx, ex)) elseif k == K"while" @chk numchildren(ex) == 2 @ast ctx ex [K"break_block" "loop_exit"::K"symbolic_label"; [K"_while"; expand_condition(ctx, ex[1]); [K"break_block" "loop_cont"::K"symbolic_label"; [(K"scope_block")(scope_type = :neutral); expand_forms_2(ctx, ex[2])]]]] elseif k == K"inert" ex elseif k == K"gc_preserve" s = ssavar(ctx, ex) r = ssavar(ctx, ex) @ast ctx ex [K"block"; s := [K"gc_preserve_begin" (children(ex))[2:var"end"]...]; r := expand_forms_2(ctx, (children(ex))[1]); [K"gc_preserve_end" s]; r] elseif k == K"&" throw(LoweringError(ex, "invalid syntax")) elseif k == K"$" throw(LoweringError(ex, "`\$` expression outside string or quote")) elseif k == K"..." throw(LoweringError(ex, "`...` expression outside call")) elseif is_leaf(ex) ex elseif k == K"return" if numchildren(ex) == 0 @ast ctx ex [K"return" "nothing"::K"core"] elseif numchildren(ex) == 1 mapchildren((e->begin expand_forms_2(ctx, e) end), ctx, ex) else throw(LoweringError(ex, "More than one argument to return")) end else mapchildren((e->begin expand_forms_2(ctx, e) end), ctx, ex) end end function expand_forms_2(ctx::DesugaringContext, ex::SyntaxTree, docs = nothing) k = kind(ex) if k == K"atomic" throw(LoweringError(ex, "unimplemented or unsupported atomic declaration")) elseif k == K"call" expand_call(ctx, ex) elseif k == K"dotcall" || (k == K".&&" || (k == K".||" || k == K".=")) expand_forms_2(ctx, expand_fuse_broadcast(ctx, ex)) elseif k == K"." expand_forms_2(ctx, expand_dot(ctx, ex)) elseif k == K"?" @chk numchildren(ex) == 3 expand_forms_2(ctx, @ast(ctx, ex, [K"if" children(ex)...])) elseif k == K"&&" || k == K"||" @chk numchildren(ex) > 1 cs = expand_cond_children(ctx, ex) cond = if length(cs) == 2 cs[1] else makenode(ctx, ex, k, cs[1:var"end" - 1]) end if k == K"&&" @ast ctx ex [K"if" cond cs[var"end"] false::K"Bool"] else @ast ctx ex [K"if" cond true::K"Bool" cs[var"end"]] end elseif k == K"::" @chk numchildren(ex) == 2 "`::` must be written `value::type` outside function argument lists" @ast ctx ex [K"call"; "typeassert"::K"core"; expand_forms_2(ctx, ex[1]); expand_forms_2(ctx, ex[2])] elseif k == K"<:" || (k == K">:" || k == K"-->") expand_forms_2(ctx, @ast(ctx, ex, [K"call"; adopt_scope(string(k)::K"Identifier", ex); children(ex)...])) elseif k == K"op=" || k == K".op=" expand_forms_2(ctx, expand_update_operator(ctx, ex)) elseif k == K"=" expand_assignment(ctx, ex) elseif k == K"break" if numchildren(ex) > 0 ex else @ast ctx ex [K"break" "loop_exit"::K"symbolic_label"] end elseif k == K"continue" @ast ctx ex [K"break" "loop_cont"::K"symbolic_label"] elseif k == K"comparison" expand_forms_2(ctx, expand_compare_chain(ctx, ex)) elseif k == K"doc" @chk numchildren(ex) == 2 expand_doc(ctx, ex[2], ex) elseif k == K"for" expand_forms_2(ctx, expand_for(ctx, ex)) elseif k == K"comprehension" @chk numchildren(ex) == 1 @chk kind(ex[1]) == K"generator" @ast ctx ex [K"call"; "collect"::K"top"; expand_forms_2(ctx, ex[1])] elseif k == K"typed_comprehension" @chk numchildren(ex) == 2 @chk kind(ex[2]) == K"generator" if numchildren(ex[2]) == 2 && kind((ex[2])[2]) == K"iteration" expand_forms_2(ctx, expand_comprehension_to_loops(ctx, ex)) else @ast ctx ex [K"call"; "collect"::K"top"; expand_forms_2(ctx, ex[1]); expand_forms_2(ctx, ex[2])] end elseif k == K"generator" expand_forms_2(ctx, expand_generator(ctx, ex)) elseif k == K"->" || k == K"do" expand_forms_2(ctx, expand_arrow(ctx, ex)) elseif k == K"function" expand_forms_2(ctx, expand_function_def(ctx, ex, docs)) elseif k == K"macro" @ast ctx ex [K"block"; [K"assert"; "global_toplevel_only"::K"Symbol"; [K"inert" ex]]; expand_forms_2(ctx, expand_macro_def(ctx, ex))] elseif k == K"if" || k == K"elseif" @chk numchildren(ex) >= 2 @ast ctx ex [k; expand_condition(ctx, ex[1]); expand_forms_2(ctx, ex[2:var"end"])...] elseif k == K"let" expand_forms_2(ctx, expand_let(ctx, ex)) elseif k == K"const" expand_const_decl(ctx, ex) elseif k == K"local" || k == K"global" if k == K"global" && kind(ex[1]) == K"const" expand_const_decl(ctx, @ast(ctx, ex, [K"const" [K"global" (ex[1])[1]]])) else expand_decls(ctx, ex) end elseif k == K"where" expand_forms_2(ctx, expand_wheres(ctx, ex)) elseif k == K"braces" || k == K"bracescat" throw(LoweringError(ex, "{ } syntax is reserved for future use")) elseif k == K"string" if numchildren(ex) == 1 && kind(ex[1]) == K"String" ex[1] else @ast ctx ex [K"call"; "string"::K"top"; expand_forms_2(ctx, children(ex))...] end elseif k == K"try" expand_forms_2(ctx, expand_try(ctx, ex)) elseif k == K"tuple" if has_parameters(ex) if numchildren(ex) > 1 throw(LoweringError(ex[var"end"], "unexpected semicolon in tuple - use `,` to separate tuple elements")) end expand_forms_2(ctx, expand_named_tuple(ctx, ex, children(ex[1]))) elseif any_assignment(children(ex)) expand_forms_2(ctx, expand_named_tuple(ctx, ex, children(ex))) else expand_forms_2(ctx, @ast(ctx, ex, [K"call"; "tuple"::K"core"; children(ex)...])) end elseif k == K"$" throw(LoweringError(ex, "`\$` expression outside string or quote block")) elseif k == K"module" throw(LoweringError(ex, "`module` is only allowed at top level")) elseif k == K"import" || k == K"using" expand_import_or_using(ctx, ex) elseif k == K"export" || k == K"public" expand_public(ctx, ex) elseif k == K"abstract" || k == K"primitive" expand_forms_2(ctx, expand_abstract_or_primitive_type(ctx, ex)) elseif k == K"struct" expand_forms_2(ctx, expand_struct_def(ctx, ex, docs)) elseif k == K"ref" sctx = with_stmts(ctx) (arr, idxs) = expand_ref_components(sctx, ex) expand_forms_2(ctx, @ast(ctx, ex, [K"block"; sctx.stmts...; [K"call"; "getindex"::K"top"; arr; idxs...]])) elseif k == K"curly" expand_forms_2(ctx, expand_curly(ctx, ex)) elseif k == K"toplevel" ex2 = @ast(ctx, ex, [K"block"; [K"assert" "toplevel_only"::K"Symbol" [K"inert" ex]]; [K"call"; eval::K"Value"; ctx.mod::K"Value"; [K"inert" ex]; [K"parameters"; [K"="; "expr_compat_mode"::K"Identifier"; ctx.expr_compat_mode::K"Bool"]]]]) expand_forms_2(ctx, ex2) elseif k == K"vect" check_no_parameters(ex, "unexpected semicolon in array expression") expand_array(ctx, ex, "vect") elseif k == K"hcat" expand_array(ctx, ex, "hcat") elseif k == K"typed_hcat" expand_array(ctx, ex, "typed_hcat") elseif k == K"opaque_closure" expand_forms_2(ctx, expand_opaque_closure(ctx, ex)) elseif k == K"vcat" || k == K"typed_vcat" expand_forms_2(ctx, expand_vcat(ctx, ex)) elseif k == K"ncat" || k == K"typed_ncat" expand_forms_2(ctx, expand_ncat(ctx, ex)) elseif k == K"while" @chk numchildren(ex) == 2 @ast ctx ex [K"break_block" "loop_exit"::K"symbolic_label"; [K"_while"; expand_condition(ctx, ex[1]); [K"break_block" "loop_cont"::K"symbolic_label"; [(K"scope_block")(scope_type = :neutral); expand_forms_2(ctx, ex[2])]]]] elseif k == K"inert" ex elseif k == K"gc_preserve" s = ssavar(ctx, ex) r = ssavar(ctx, ex) @ast ctx ex [K"block"; s := [K"gc_preserve_begin" (children(ex))[2:var"end"]...]; r := expand_forms_2(ctx, (children(ex))[1]); [K"gc_preserve_end" s]; r] elseif k == K"&" throw(LoweringError(ex, "invalid syntax")) elseif k == K"$" throw(LoweringError(ex, "`\$` expression outside string or quote")) elseif k == K"..." throw(LoweringError(ex, "`...` expression outside call")) elseif is_leaf(ex) ex elseif k == K"return" if numchildren(ex) == 0 @ast ctx ex [K"return" "nothing"::K"core"] elseif numchildren(ex) == 1 mapchildren((e->begin expand_forms_2(ctx, e) end), ctx, ex) else throw(LoweringError(ex, "More than one argument to return")) end else mapchildren((e->begin expand_forms_2(ctx, e) end), ctx, ex) end end Core.@doc "Lowering pass 2 - desugaring\n\nThis pass simplifies expressions by expanding complicated syntax sugar into a\nsmall set of core syntactic forms. For example, field access syntax `a.b` is\nexpanded to a function call `getproperty(a, :b)`.\n" function expand_forms_2(ctx::DesugaringContext, ex::SyntaxTree, docs = nothing) k = kind(ex) if k == K"atomic" throw(LoweringError(ex, "unimplemented or unsupported atomic declaration")) elseif k == K"call" expand_call(ctx, ex) elseif k == K"dotcall" || (k == K".&&" || (k == K".||" || k == K".=")) expand_forms_2(ctx, expand_fuse_broadcast(ctx, ex)) elseif k == K"." expand_forms_2(ctx, expand_dot(ctx, ex)) elseif k == K"?" @chk numchildren(ex) == 3 expand_forms_2(ctx, @ast(ctx, ex, [K"if" children(ex)...])) elseif k == K"&&" || k == K"||" @chk numchildren(ex) > 1 cs = expand_cond_children(ctx, ex) cond = if length(cs) == 2 cs[1] else makenode(ctx, ex, k, cs[1:var"end" - 1]) end if k == K"&&" @ast ctx ex [K"if" cond cs[var"end"] false::K"Bool"] else @ast ctx ex [K"if" cond true::K"Bool" cs[var"end"]] end elseif k == K"::" @chk numchildren(ex) == 2 "`::` must be written `value::type` outside function argument lists" @ast ctx ex [K"call"; "typeassert"::K"core"; expand_forms_2(ctx, ex[1]); expand_forms_2(ctx, ex[2])] elseif k == K"<:" || (k == K">:" || k == K"-->") expand_forms_2(ctx, @ast(ctx, ex, [K"call"; adopt_scope(string(k)::K"Identifier", ex); children(ex)...])) elseif k == K"op=" || k == K".op=" expand_forms_2(ctx, expand_update_operator(ctx, ex)) elseif k == K"=" expand_assignment(ctx, ex) elseif k == K"break" if numchildren(ex) > 0 ex else @ast ctx ex [K"break" "loop_exit"::K"symbolic_label"] end elseif k == K"continue" @ast ctx ex [K"break" "loop_cont"::K"symbolic_label"] elseif k == K"comparison" expand_forms_2(ctx, expand_compare_chain(ctx, ex)) elseif k == K"doc" @chk numchildren(ex) == 2 expand_doc(ctx, ex[2], ex) elseif k == K"for" expand_forms_2(ctx, expand_for(ctx, ex)) elseif k == K"comprehension" @chk numchildren(ex) == 1 @chk kind(ex[1]) == K"generator" @ast ctx ex [K"call"; "collect"::K"top"; expand_forms_2(ctx, ex[1])] elseif k == K"typed_comprehension" @chk numchildren(ex) == 2 @chk kind(ex[2]) == K"generator" if numchildren(ex[2]) == 2 && kind((ex[2])[2]) == K"iteration" expand_forms_2(ctx, expand_comprehension_to_loops(ctx, ex)) else @ast ctx ex [K"call"; "collect"::K"top"; expand_forms_2(ctx, ex[1]); expand_forms_2(ctx, ex[2])] end elseif k == K"generator" expand_forms_2(ctx, expand_generator(ctx, ex)) elseif k == K"->" || k == K"do" expand_forms_2(ctx, expand_arrow(ctx, ex)) elseif k == K"function" expand_forms_2(ctx, expand_function_def(ctx, ex, docs)) elseif k == K"macro" @ast ctx ex [K"block"; [K"assert"; "global_toplevel_only"::K"Symbol"; [K"inert" ex]]; expand_forms_2(ctx, expand_macro_def(ctx, ex))] elseif k == K"if" || k == K"elseif" @chk numchildren(ex) >= 2 @ast ctx ex [k; expand_condition(ctx, ex[1]); expand_forms_2(ctx, ex[2:var"end"])...] elseif k == K"let" expand_forms_2(ctx, expand_let(ctx, ex)) elseif k == K"const" expand_const_decl(ctx, ex) elseif k == K"local" || k == K"global" if k == K"global" && kind(ex[1]) == K"const" expand_const_decl(ctx, @ast(ctx, ex, [K"const" [K"global" (ex[1])[1]]])) else expand_decls(ctx, ex) end elseif k == K"where" expand_forms_2(ctx, expand_wheres(ctx, ex)) elseif k == K"braces" || k == K"bracescat" throw(LoweringError(ex, "{ } syntax is reserved for future use")) elseif k == K"string" if numchildren(ex) == 1 && kind(ex[1]) == K"String" ex[1] else @ast ctx ex [K"call"; "string"::K"top"; expand_forms_2(ctx, children(ex))...] end elseif k == K"try" expand_forms_2(ctx, expand_try(ctx, ex)) elseif k == K"tuple" if has_parameters(ex) if numchildren(ex) > 1 throw(LoweringError(ex[var"end"], "unexpected semicolon in tuple - use `,` to separate tuple elements")) end expand_forms_2(ctx, expand_named_tuple(ctx, ex, children(ex[1]))) elseif any_assignment(children(ex)) expand_forms_2(ctx, expand_named_tuple(ctx, ex, children(ex))) else expand_forms_2(ctx, @ast(ctx, ex, [K"call"; "tuple"::K"core"; children(ex)...])) end elseif k == K"$" throw(LoweringError(ex, "`\$` expression outside string or quote block")) elseif k == K"module" throw(LoweringError(ex, "`module` is only allowed at top level")) elseif k == K"import" || k == K"using" expand_import_or_using(ctx, ex) elseif k == K"export" || k == K"public" expand_public(ctx, ex) elseif k == K"abstract" || k == K"primitive" expand_forms_2(ctx, expand_abstract_or_primitive_type(ctx, ex)) elseif k == K"struct" expand_forms_2(ctx, expand_struct_def(ctx, ex, docs)) elseif k == K"ref" sctx = with_stmts(ctx) (arr, idxs) = expand_ref_components(sctx, ex) expand_forms_2(ctx, @ast(ctx, ex, [K"block"; sctx.stmts...; [K"call"; "getindex"::K"top"; arr; idxs...]])) elseif k == K"curly" expand_forms_2(ctx, expand_curly(ctx, ex)) elseif k == K"toplevel" ex2 = @ast(ctx, ex, [K"block"; [K"assert" "toplevel_only"::K"Symbol" [K"inert" ex]]; [K"call"; eval ::K"Value"; ctx.mod ::K"Value"; [K"inert" ex]; [K"parameters"; [K"="; "expr_compat_mode"::K"Identifier"; ctx.expr_compat_mode::K"Bool"]]]]) expand_forms_2(ctx, ex2) elseif k == K"vect" check_no_parameters(ex, "unexpected semicolon in array expression") expand_array(ctx, ex, "vect") elseif k == K"hcat" expand_array(ctx, ex, "hcat") elseif k == K"typed_hcat" expand_array(ctx, ex, "typed_hcat") elseif k == K"opaque_closure" expand_forms_2(ctx, expand_opaque_closure(ctx, ex)) elseif k == K"vcat" || k == K"typed_vcat" expand_forms_2(ctx, expand_vcat(ctx, ex)) elseif k == K"ncat" || k == K"typed_ncat" expand_forms_2(ctx, expand_ncat(ctx, ex)) elseif k == K"while" @chk numchildren(ex) == 2 @ast ctx ex [K"break_block" "loop_exit"::K"symbolic_label"; [K"_while"; expand_condition(ctx, ex[1]); [K"break_block" "loop_cont"::K"symbolic_label"; [(K"scope_block")(scope_type = :neutral); expand_forms_2(ctx, ex[2])]]]] elseif k == K"inert" ex elseif k == K"gc_preserve" s = ssavar(ctx, ex) r = ssavar(ctx, ex) @ast ctx ex [K"block"; s := [K"gc_preserve_begin" (children(ex))[2:var"end"]...]; r := expand_forms_2(ctx, (children(ex))[1]); [K"gc_preserve_end" s]; r] elseif k == K"&" throw(LoweringError(ex, "invalid syntax")) elseif k == K"$" throw(LoweringError(ex, "`\$` expression outside string or quote")) elseif k == K"..." throw(LoweringError(ex, "`...` expression outside call")) elseif is_leaf(ex) ex elseif k == K"return" if numchildren(ex) == 0 @ast ctx ex [K"return" "nothing"::K"core"] elseif numchildren(ex) == 1 mapchildren((e->begin expand_forms_2(ctx, e) end), ctx, ex) else throw(LoweringError(ex, "More than one argument to return")) end else mapchildren((e->begin expand_forms_2(ctx, e) end), ctx, ex) end end Core.@doc "Lowering pass 2 - desugaring\n\nThis pass simplifies expressions by expanding complicated syntax sugar into a\nsmall set of core syntactic forms. For example, field access syntax `a.b` is\nexpanded to a function call `getproperty(a, :b)`.\n" function expand_forms_2(ctx::DesugaringContext, ex::SyntaxTree, docs = nothing) k = kind(ex) if k == K"atomic" throw(LoweringError(ex, "unimplemented or unsupported atomic declaration")) elseif k == K"call" expand_call(ctx, ex) elseif k == K"dotcall" || (k == K".&&" || (k == K".||" || k == K".=")) expand_forms_2(ctx, expand_fuse_broadcast(ctx, ex)) elseif k == K"." expand_forms_2(ctx, expand_dot(ctx, ex)) elseif k == K"?" @chk numchildren(ex) == 3 expand_forms_2(ctx, @ast(ctx, ex, [K"if" children(ex)...])) elseif k == K"&&" || k == K"||" @chk numchildren(ex) > 1 cs = expand_cond_children(ctx, ex) cond = if length(cs) == 2 cs[1] else makenode(ctx, ex, k, cs[1:var"end" - 1]) end if k == K"&&" @ast ctx ex [K"if" cond cs[var"end"] false::K"Bool"] else @ast ctx ex [K"if" cond true::K"Bool" cs[var"end"]] end elseif k == K"::" @chk numchildren(ex) == 2 "`::` must be written `value::type` outside function argument lists" @ast ctx ex [K"call"; "typeassert"::K"core"; expand_forms_2(ctx, ex[1]); expand_forms_2(ctx, ex[2])] elseif k == K"<:" || (k == K">:" || k == K"-->") expand_forms_2(ctx, @ast(ctx, ex, [K"call"; adopt_scope(string(k)::K"Identifier", ex); children(ex)...])) elseif k == K"op=" || k == K".op=" expand_forms_2(ctx, expand_update_operator(ctx, ex)) elseif k == K"=" expand_assignment(ctx, ex) elseif k == K"break" if numchildren(ex) > 0 ex else @ast ctx ex [K"break" "loop_exit"::K"symbolic_label"] end elseif k == K"continue" @ast ctx ex [K"break" "loop_cont"::K"symbolic_label"] elseif k == K"comparison" expand_forms_2(ctx, expand_compare_chain(ctx, ex)) elseif k == K"doc" @chk numchildren(ex) == 2 expand_doc(ctx, ex[2], ex) elseif k == K"for" expand_forms_2(ctx, expand_for(ctx, ex)) elseif k == K"comprehension" @chk numchildren(ex) == 1 @chk kind(ex[1]) == K"generator" @ast ctx ex [K"call"; "collect"::K"top"; expand_forms_2(ctx, ex[1])] elseif k == K"typed_comprehension" @chk numchildren(ex) == 2 @chk kind(ex[2]) == K"generator" if numchildren(ex[2]) == 2 && kind((ex[2])[2]) == K"iteration" expand_forms_2(ctx, expand_comprehension_to_loops(ctx, ex)) else @ast ctx ex [K"call"; "collect"::K"top"; expand_forms_2(ctx, ex[1]); expand_forms_2(ctx, ex[2])] end elseif k == K"generator" expand_forms_2(ctx, expand_generator(ctx, ex)) elseif k == K"->" || k == K"do" expand_forms_2(ctx, expand_arrow(ctx, ex)) elseif k == K"function" expand_forms_2(ctx, expand_function_def(ctx, ex, docs)) elseif k == K"macro" @ast ctx ex [K"block"; [K"assert"; "global_toplevel_only"::K"Symbol"; [K"inert" ex]]; expand_forms_2(ctx, expand_macro_def(ctx, ex))] elseif k == K"if" || k == K"elseif" @chk numchildren(ex) >= 2 @ast ctx ex [k; expand_condition(ctx, ex[1]); expand_forms_2(ctx, ex[2:var"end"])...] elseif k == K"let" expand_forms_2(ctx, expand_let(ctx, ex)) elseif k == K"const" expand_const_decl(ctx, ex) elseif k == K"local" || k == K"global" if k == K"global" && kind(ex[1]) == K"const" expand_const_decl(ctx, @ast(ctx, ex, [K"const" [K"global" (ex[1])[1]]])) else expand_decls(ctx, ex) end elseif k == K"where" expand_forms_2(ctx, expand_wheres(ctx, ex)) elseif k == K"braces" || k == K"bracescat" throw(LoweringError(ex, "{ } syntax is reserved for future use")) elseif k == K"string" if numchildren(ex) == 1 && kind(ex[1]) == K"String" ex[1] else @ast ctx ex [K"call"; "string"::K"top"; expand_forms_2(ctx, children(ex))...] end elseif k == K"try" expand_forms_2(ctx, expand_try(ctx, ex)) elseif k == K"tuple" if has_parameters(ex) if numchildren(ex) > 1 throw(LoweringError(ex[var"end"], "unexpected semicolon in tuple - use `,` to separate tuple elements")) end expand_forms_2(ctx, expand_named_tuple(ctx, ex, children(ex[1]))) elseif any_assignment(children(ex)) expand_forms_2(ctx, expand_named_tuple(ctx, ex, children(ex))) else expand_forms_2(ctx, @ast(ctx, ex, [K"call"; "tuple"::K"core"; children(ex)...])) end elseif k == K"$" throw(LoweringError(ex, "`\$` expression outside string or quote block")) elseif k == K"module" throw(LoweringError(ex, "`module` is only allowed at top level")) elseif k == K"import" || k == K"using" expand_import_or_using(ctx, ex) elseif k == K"export" || k == K"public" expand_public(ctx, ex) elseif k == K"abstract" || k == K"primitive" expand_forms_2(ctx, expand_abstract_or_primitive_type(ctx, ex)) elseif k == K"struct" expand_forms_2(ctx, expand_struct_def(ctx, ex, docs)) elseif k == K"ref" sctx = with_stmts(ctx) (arr, idxs) = expand_ref_components(sctx, ex) expand_forms_2(ctx, @ast(ctx, ex, [K"block"; sctx.stmts...; [K"call"; "getindex"::K"top"; arr; idxs...]])) elseif k == K"curly" expand_forms_2(ctx, expand_curly(ctx, ex)) elseif k == K"toplevel" ex2 = @ast(ctx, ex, [K"block"; [K"assert" "toplevel_only"::K"Symbol" [K"inert" ex]]; [K"call"; eval::K"Value"; ctx.mod::K"Value"; [K"inert" ex]; [K"parameters"; [K"="; "expr_compat_mode"::K"Identifier"; ctx.expr_compat_mode::K"Bool"]]]]) expand_forms_2(ctx, ex2) elseif k == K"vect" check_no_parameters(ex, "unexpected semicolon in array expression") expand_array(ctx, ex, "vect") elseif k == K"hcat" expand_array(ctx, ex, "hcat") elseif k == K"typed_hcat" expand_array(ctx, ex, "typed_hcat") elseif k == K"opaque_closure" expand_forms_2(ctx, expand_opaque_closure(ctx, ex)) elseif k == K"vcat" || k == K"typed_vcat" expand_forms_2(ctx, expand_vcat(ctx, ex)) elseif k == K"ncat" || k == K"typed_ncat" expand_forms_2(ctx, expand_ncat(ctx, ex)) elseif k == K"while" @chk numchildren(ex) == 2 @ast ctx ex [K"break_block" "loop_exit"::K"symbolic_label"; [K"_while"; expand_condition(ctx, ex[1]); [K"break_block" "loop_cont"::K"symbolic_label"; [(K"scope_block")(scope_type = :neutral); expand_forms_2(ctx, ex[2])]]]] elseif k == K"inert" ex elseif k == K"gc_preserve" s = ssavar(ctx, ex) r = ssavar(ctx, ex) @ast ctx ex [K"block"; s := [K"gc_preserve_begin" (children(ex))[2:var"end"]...]; r := expand_forms_2(ctx, (children(ex))[1]); [K"gc_preserve_end" s]; r] elseif k == K"&" throw(LoweringError(ex, "invalid syntax")) elseif k == K"$" throw(LoweringError(ex, "`\$` expression outside string or quote")) elseif k == K"..." throw(LoweringError(ex, "`...` expression outside call")) elseif is_leaf(ex) ex elseif k == K"return" if numchildren(ex) == 0 @ast ctx ex [K"return" "nothing"::K"core"] elseif numchildren(ex) == 1 mapchildren((e->begin expand_forms_2(ctx, e) end), ctx, ex) else throw(LoweringError(ex, "More than one argument to return")) end else mapchildren((e->begin expand_forms_2(ctx, e) end), ctx, ex) end end Parsing files in Base: Test Failed at /home/pkgeval/.julia/packages/CSTParser/0hXvH/test/test_check_base.jl:166 Expression: false Stacktrace: [1] macro expansion @ /opt/julia/share/julia/stdlib/v1.14/Test/src/Test.jl:753 [inlined] [2] top-level scope @ ~/.julia/packages/CSTParser/0hXvH/test/test_check_base.jl:166 ┌ Error: parsing difference │ file = "/opt/julia/bin/../share/julia/JuliaSyntax/test/literal_parsing.jl" └ @ Main.var"##296" ~/.julia/packages/CSTParser/0hXvH/test/test_check_base.jl:157 n == 340282366920938463463374607431768211456 n == 340282366920938463463374607431768211456 n isa BigInt && n == 340282366920938463463374607431768211456 n isa BigInt && n == 340282366920938463463374607431768211456 begin n = hexint("0x100000000000000000000000000000000") n isa BigInt && n == 340282366920938463463374607431768211456 end begin n = hexint("0x100000000000000000000000000000000") n isa BigInt && n == 340282366920938463463374607431768211456 end @test begin n = hexint("0x100000000000000000000000000000000") n isa BigInt && n == 340282366920938463463374607431768211456 end @test begin n = hexint("0x100000000000000000000000000000000") n isa BigInt && n == 340282366920938463463374607431768211456 end begin @test hexint("0xff") === UInt8(0xff) @test hexint("0x100") === UInt16(0x0100) @test hexint("0xffff") === UInt16(0xffff) @test hexint("0x10000") === UInt32(0x00010000) @test hexint("0xffffffff") === UInt32(0xffffffff) @test hexint("0x100000000") === UInt64(0x0000000100000000) @test hexint("0xffffffffffffffff") === UInt64(0xffffffffffffffff) @test hexint("0x10000000000000000") === UInt128(0x10000000000000000) @test hexint("0xffffffffffffffffffffffffffffffff") === UInt128(0xffffffffffffffffffffffffffffffff) @test begin n = hexint("0x100000000000000000000000000000000") n isa BigInt && n == 340282366920938463463374607431768211456 end end begin @test hexint("0xff") === UInt8(0xff) @test hexint("0x100") === UInt16(0x0100) @test hexint("0xffff") === UInt16(0xffff) @test hexint("0x10000") === UInt32(0x00010000) @test hexint("0xffffffff") === UInt32(0xffffffff) @test hexint("0x100000000") === UInt64(0x0000000100000000) @test hexint("0xffffffffffffffff") === UInt64(0xffffffffffffffff) @test hexint("0x10000000000000000") === UInt128(0x10000000000000000) @test hexint("0xffffffffffffffffffffffffffffffff") === UInt128(0xffffffffffffffffffffffffffffffff) @test begin n = hexint("0x100000000000000000000000000000000") n isa BigInt && n == 340282366920938463463374607431768211456 end end @testset "HexInt numeric limits for different types" begin @test hexint("0xff") === UInt8(0xff) @test hexint("0x100") === UInt16(0x0100) @test hexint("0xffff") === UInt16(0xffff) @test hexint("0x10000") === UInt32(0x00010000) @test hexint("0xffffffff") === UInt32(0xffffffff) @test hexint("0x100000000") === UInt64(0x0000000100000000) @test hexint("0xffffffffffffffff") === UInt64(0xffffffffffffffff) @test hexint("0x10000000000000000") === UInt128(0x10000000000000000) @test hexint("0xffffffffffffffffffffffffffffffff") === UInt128(0xffffffffffffffffffffffffffffffff) @test begin n = hexint("0x100000000000000000000000000000000") n isa BigInt && n == 340282366920938463463374607431768211456 end end @testset "HexInt numeric limits for different types" begin @test hexint("0xff") === UInt8(0xff) @test hexint("0x100") === UInt16(0x0100) @test hexint("0xffff") === UInt16(0xffff) @test hexint("0x10000") === UInt32(0x00010000) @test hexint("0xffffffff") === UInt32(0xffffffff) @test hexint("0x100000000") === UInt64(0x0000000100000000) @test hexint("0xffffffffffffffff") === UInt64(0xffffffffffffffff) @test hexint("0x10000000000000000") === UInt128(0x10000000000000000) @test hexint("0xffffffffffffffffffffffffffffffff") === UInt128(0xffffffffffffffffffffffffffffffff) @test begin n = hexint("0x100000000000000000000000000000000") n isa BigInt && n == 340282366920938463463374607431768211456 end end n == 340282366920938463463374607431768211456 n == 340282366920938463463374607431768211456 n isa BigInt && n == 340282366920938463463374607431768211456 n isa BigInt && n == 340282366920938463463374607431768211456 begin n = binint("0b100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000") n isa BigInt && n == 340282366920938463463374607431768211456 end begin n = binint("0b100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000") n isa BigInt && n == 340282366920938463463374607431768211456 end @test begin n = binint("0b100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000") n isa BigInt && n == 340282366920938463463374607431768211456 end @test begin n = binint("0b100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000") n isa BigInt && n == 340282366920938463463374607431768211456 end begin @test binint("0b11111111") === UInt8(0xff) @test binint("0b100000000") === UInt16(0x0100) @test binint("0b1111111111111111") === UInt16(0xffff) @test binint("0b10000000000000000") === UInt32(0x00010000) @test binint("0b11111111111111111111111111111111") === UInt32(0xffffffff) @test binint("0b100000000000000000000000000000000") === UInt64(0x0000000100000000) @test binint("0b1111111111111111111111111111111111111111111111111111111111111111") === UInt64(0xffffffffffffffff) @test binint("0b10000000000000000000000000000000000000000000000000000000000000000") === UInt128(0x10000000000000000) @test binint("0b11111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111") === UInt128(0xffffffffffffffffffffffffffffffff) @test begin n = binint("0b100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000") n isa BigInt && n == 340282366920938463463374607431768211456 end end begin @test binint("0b11111111") === UInt8(0xff) @test binint("0b100000000") === UInt16(0x0100) @test binint("0b1111111111111111") === UInt16(0xffff) @test binint("0b10000000000000000") === UInt32(0x00010000) @test binint("0b11111111111111111111111111111111") === UInt32(0xffffffff) @test binint("0b100000000000000000000000000000000") === UInt64(0x0000000100000000) @test binint("0b1111111111111111111111111111111111111111111111111111111111111111") === UInt64(0xffffffffffffffff) @test binint("0b10000000000000000000000000000000000000000000000000000000000000000") === UInt128(0x10000000000000000) @test binint("0b11111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111") === UInt128(0xffffffffffffffffffffffffffffffff) @test begin n = binint("0b100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000") n isa BigInt && n == 340282366920938463463374607431768211456 end end @testset "BinInt numeric limits for different types" begin @test binint("0b11111111") === UInt8(0xff) @test binint("0b100000000") === UInt16(0x0100) @test binint("0b1111111111111111") === UInt16(0xffff) @test binint("0b10000000000000000") === UInt32(0x00010000) @test binint("0b11111111111111111111111111111111") === UInt32(0xffffffff) @test binint("0b100000000000000000000000000000000") === UInt64(0x0000000100000000) @test binint("0b1111111111111111111111111111111111111111111111111111111111111111") === UInt64(0xffffffffffffffff) @test binint("0b10000000000000000000000000000000000000000000000000000000000000000") === UInt128(0x10000000000000000) @test binint("0b11111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111") === UInt128(0xffffffffffffffffffffffffffffffff) @test begin n = binint("0b100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000") n isa BigInt && n == 340282366920938463463374607431768211456 end end @testset "BinInt numeric limits for different types" begin @test binint("0b11111111") === UInt8(0xff) @test binint("0b100000000") === UInt16(0x0100) @test binint("0b1111111111111111") === UInt16(0xffff) @test binint("0b10000000000000000") === UInt32(0x00010000) @test binint("0b11111111111111111111111111111111") === UInt32(0xffffffff) @test binint("0b100000000000000000000000000000000") === UInt64(0x0000000100000000) @test binint("0b1111111111111111111111111111111111111111111111111111111111111111") === UInt64(0xffffffffffffffff) @test binint("0b10000000000000000000000000000000000000000000000000000000000000000") === UInt128(0x10000000000000000) @test binint("0b11111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111") === UInt128(0xffffffffffffffffffffffffffffffff) @test begin n = binint("0b100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000") n isa BigInt && n == 340282366920938463463374607431768211456 end end n == 340282366920938463463374607431768211456 n == 340282366920938463463374607431768211456 n isa BigInt && n == 340282366920938463463374607431768211456 n isa BigInt && n == 340282366920938463463374607431768211456 begin n = octint("0o4000000000000000000000000000000000000000000") n isa BigInt && n == 340282366920938463463374607431768211456 end begin n = octint("0o4000000000000000000000000000000000000000000") n isa BigInt && n == 340282366920938463463374607431768211456 end @test begin n = octint("0o4000000000000000000000000000000000000000000") n isa BigInt && n == 340282366920938463463374607431768211456 end @test begin n = octint("0o4000000000000000000000000000000000000000000") n isa BigInt && n == 340282366920938463463374607431768211456 end begin @test octint("0o377") === UInt8(0xff) @test octint("0o400") === UInt16(0x0100) @test octint("0o177777") === UInt16(0xffff) @test octint("0o200000") === UInt32(0x00010000) @test octint("0o37777777777") === UInt32(0xffffffff) @test octint("0o40000000000") === UInt64(0x0000000100000000) @test octint("0o1777777777777777777777") === UInt64(0xffffffffffffffff) @test octint("0o2000000000000000000000") === UInt128(0x10000000000000000) @test octint("0o3777777777777777777777777777777777777777777") === UInt128(0xffffffffffffffffffffffffffffffff) @test begin n = octint("0o4000000000000000000000000000000000000000000") n isa BigInt && n == 340282366920938463463374607431768211456 end end begin @test octint("0o377") === UInt8(0xff) @test octint("0o400") === UInt16(0x0100) @test octint("0o177777") === UInt16(0xffff) @test octint("0o200000") === UInt32(0x00010000) @test octint("0o37777777777") === UInt32(0xffffffff) @test octint("0o40000000000") === UInt64(0x0000000100000000) @test octint("0o1777777777777777777777") === UInt64(0xffffffffffffffff) @test octint("0o2000000000000000000000") === UInt128(0x10000000000000000) @test octint("0o3777777777777777777777777777777777777777777") === UInt128(0xffffffffffffffffffffffffffffffff) @test begin n = octint("0o4000000000000000000000000000000000000000000") n isa BigInt && n == 340282366920938463463374607431768211456 end end @testset "OctInt numeric limits for different types" begin @test octint("0o377") === UInt8(0xff) @test octint("0o400") === UInt16(0x0100) @test octint("0o177777") === UInt16(0xffff) @test octint("0o200000") === UInt32(0x00010000) @test octint("0o37777777777") === UInt32(0xffffffff) @test octint("0o40000000000") === UInt64(0x0000000100000000) @test octint("0o1777777777777777777777") === UInt64(0xffffffffffffffff) @test octint("0o2000000000000000000000") === UInt128(0x10000000000000000) @test octint("0o3777777777777777777777777777777777777777777") === UInt128(0xffffffffffffffffffffffffffffffff) @test begin n = octint("0o4000000000000000000000000000000000000000000") n isa BigInt && n == 340282366920938463463374607431768211456 end end @testset "OctInt numeric limits for different types" begin @test octint("0o377") === UInt8(0xff) @test octint("0o400") === UInt16(0x0100) @test octint("0o177777") === UInt16(0xffff) @test octint("0o200000") === UInt32(0x00010000) @test octint("0o37777777777") === UInt32(0xffffffff) @test octint("0o40000000000") === UInt64(0x0000000100000000) @test octint("0o1777777777777777777777") === UInt64(0xffffffffffffffff) @test octint("0o2000000000000000000000") === UInt128(0x10000000000000000) @test octint("0o3777777777777777777777777777777777777777777") === UInt128(0xffffffffffffffffffffffffffffffff) @test begin n = octint("0o4000000000000000000000000000000000000000000") n isa BigInt && n == 340282366920938463463374607431768211456 end end begin @testset "Signed Integers" begin @test parse_int_literal("-1") isa Int @test parse_int_literal("1") isa Int @test parse_int_literal("2147483647") isa Int @test parse_int_literal("9223372036854775807") isa Int64 @test parse_int_literal("9223372036854775808") isa Int128 @test parse_int_literal("170141183460469231731687303715884105727") isa Int128 @test parse_int_literal("170141183460469231731687303715884105728") isa BigInt end @testset "HexInt numeric limits for different types" begin @test hexint("0xff") === UInt8(0xff) @test hexint("0x100") === UInt16(0x0100) @test hexint("0xffff") === UInt16(0xffff) @test hexint("0x10000") === UInt32(0x00010000) @test hexint("0xffffffff") === UInt32(0xffffffff) @test hexint("0x100000000") === UInt64(0x0000000100000000) @test hexint("0xffffffffffffffff") === UInt64(0xffffffffffffffff) @test hexint("0x10000000000000000") === UInt128(0x10000000000000000) @test hexint("0xffffffffffffffffffffffffffffffff") === UInt128(0xffffffffffffffffffffffffffffffff) @test begin n = hexint("0x100000000000000000000000000000000") n isa BigInt && n == 340282366920938463463374607431768211456 end end @testset "HexInt string length limits for different types" begin @test hexint("0x00") === UInt8(0) @test hexint("0x000") === UInt16(0) @test hexint("0x0000") === UInt16(0) @test hexint("0x00000") === UInt32(0) @test hexint("0x00000000") === UInt32(0) @test hexint("0x000000000") === UInt64(0) @test hexint("0x0000000000000000") === UInt64(0) @test hexint("0x00000000000000000") === UInt128(0) @test hexint("0x00000000000000000000000000000000") === UInt128(0) @test begin n = hexint("0x000000000000000000000000000000000") n isa BigInt && n == 0 end end @testset "BinInt numeric limits for different types" begin @test binint("0b11111111") === UInt8(0xff) @test binint("0b100000000") === UInt16(0x0100) @test binint("0b1111111111111111") === UInt16(0xffff) @test binint("0b10000000000000000") === UInt32(0x00010000) @test binint("0b11111111111111111111111111111111") === UInt32(0xffffffff) @test binint("0b100000000000000000000000000000000") === UInt64(0x0000000100000000) @test binint("0b1111111111111111111111111111111111111111111111111111111111111111") === UInt64(0xffffffffffffffff) @test binint("0b10000000000000000000000000000000000000000000000000000000000000000") === UInt128(0x10000000000000000) @test binint("0b11111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111") === UInt128(0xffffffffffffffffffffffffffffffff) @test begin n = binint("0b100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000") n isa BigInt && n == 340282366920938463463374607431768211456 end end @testset "BinInt string length limits for different types" begin @test binint("0b00000000") === UInt8(0) @test binint("0b000000000") === UInt16(0) @test binint("0b0000000000000000") === UInt16(0) @test binint("0b00000000000000000") === UInt32(0) @test binint("0b00000000000000000000000000000000") === UInt32(0) @test binint("0b000000000000000000000000000000000") === UInt64(0) @test binint("0b0000000000000000000000000000000000000000000000000000000000000000") === UInt64(0) @test binint("0b00000000000000000000000000000000000000000000000000000000000000000") === UInt128(0) @test binint("0b00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000") === UInt128(0) @test begin n = binint("0b000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000") n isa BigInt && n == 0 end end @testset "OctInt numeric limits for different types" begin @test octint("0o377") === UInt8(0xff) @test octint("0o400") === UInt16(0x0100) @test octint("0o177777") === UInt16(0xffff) @test octint("0o200000") === UInt32(0x00010000) @test octint("0o37777777777") === UInt32(0xffffffff) @test octint("0o40000000000") === UInt64(0x0000000100000000) @test octint("0o1777777777777777777777") === UInt64(0xffffffffffffffff) @test octint("0o2000000000000000000000") === UInt128(0x10000000000000000) @test octint("0o3777777777777777777777777777777777777777777") === UInt128(0xffffffffffffffffffffffffffffffff) @test begin n = octint("0o4000000000000000000000000000000000000000000") n isa BigInt && n == 340282366920938463463374607431768211456 end end @testset "OctInt string length limits for different types" begin @test octint("0o000") === UInt8(0) @test octint("0o0000") === UInt16(0) @test octint("0o000000") === UInt16(0) @test octint("0o0000000") === UInt32(0) @test octint("0o00000000000") === UInt32(0) @test octint("0o000000000000") === UInt64(0) @test octint("0o0000000000000000000000") === UInt64(0) @test octint("0o00000000000000000000000") === UInt128(0) @test octint("0o0000000000000000000000000000000000000000000") === UInt128(0) @test begin n = octint("0o00000000000000000000000000000000000000000000") n isa BigInt && n == 0 end end @testset "Underscore separators" begin @test parse_int_literal("10_000") === 10000 @test parse_uint_literal("0xff_ff", K"HexInt") === 0xffff @test parse_uint_literal("0b1111_1111", K"BinInt") === 0xff @test parse_uint_literal("0o177_777", K"OctInt") === 0xffff end @testset "\\minus ('\\u2212' / '−') allowed in numbers" begin @test parse_int_literal("−10") === -10 end end begin @testset "Signed Integers" begin @test parse_int_literal("-1") isa Int @test parse_int_literal("1") isa Int @test parse_int_literal("2147483647") isa Int @test parse_int_literal("9223372036854775807") isa Int64 @test parse_int_literal("9223372036854775808") isa Int128 @test parse_int_literal("170141183460469231731687303715884105727") isa Int128 @test parse_int_literal("170141183460469231731687303715884105728") isa BigInt end @testset "HexInt numeric limits for different types" begin @test hexint("0xff") === UInt8(0xff) @test hexint("0x100") === UInt16(0x0100) @test hexint("0xffff") === UInt16(0xffff) @test hexint("0x10000") === UInt32(0x00010000) @test hexint("0xffffffff") === UInt32(0xffffffff) @test hexint("0x100000000") === UInt64(0x0000000100000000) @test hexint("0xffffffffffffffff") === UInt64(0xffffffffffffffff) @test hexint("0x10000000000000000") === UInt128(0x10000000000000000) @test hexint("0xffffffffffffffffffffffffffffffff") === UInt128(0xffffffffffffffffffffffffffffffff) @test begin n = hexint("0x100000000000000000000000000000000") n isa BigInt && n == 340282366920938463463374607431768211456 end end @testset "HexInt string length limits for different types" begin @test hexint("0x00") === UInt8(0) @test hexint("0x000") === UInt16(0) @test hexint("0x0000") === UInt16(0) @test hexint("0x00000") === UInt32(0) @test hexint("0x00000000") === UInt32(0) @test hexint("0x000000000") === UInt64(0) @test hexint("0x0000000000000000") === UInt64(0) @test hexint("0x00000000000000000") === UInt128(0) @test hexint("0x00000000000000000000000000000000") === UInt128(0) @test begin n = hexint("0x000000000000000000000000000000000") n isa BigInt && n == 0 end end @testset "BinInt numeric limits for different types" begin @test binint("0b11111111") === UInt8(0xff) @test binint("0b100000000") === UInt16(0x0100) @test binint("0b1111111111111111") === UInt16(0xffff) @test binint("0b10000000000000000") === UInt32(0x00010000) @test binint("0b11111111111111111111111111111111") === UInt32(0xffffffff) @test binint("0b100000000000000000000000000000000") === UInt64(0x0000000100000000) @test binint("0b1111111111111111111111111111111111111111111111111111111111111111") === UInt64(0xffffffffffffffff) @test binint("0b10000000000000000000000000000000000000000000000000000000000000000") === UInt128(0x10000000000000000) @test binint("0b11111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111") === UInt128(0xffffffffffffffffffffffffffffffff) @test begin n = binint("0b100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000") n isa BigInt && n == 340282366920938463463374607431768211456 end end @testset "BinInt string length limits for different types" begin @test binint("0b00000000") === UInt8(0) @test binint("0b000000000") === UInt16(0) @test binint("0b0000000000000000") === UInt16(0) @test binint("0b00000000000000000") === UInt32(0) @test binint("0b00000000000000000000000000000000") === UInt32(0) @test binint("0b000000000000000000000000000000000") === UInt64(0) @test binint("0b0000000000000000000000000000000000000000000000000000000000000000") === UInt64(0) @test binint("0b00000000000000000000000000000000000000000000000000000000000000000") === UInt128(0) @test binint("0b00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000") === UInt128(0) @test begin n = binint("0b000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000") n isa BigInt && n == 0 end end @testset "OctInt numeric limits for different types" begin @test octint("0o377") === UInt8(0xff) @test octint("0o400") === UInt16(0x0100) @test octint("0o177777") === UInt16(0xffff) @test octint("0o200000") === UInt32(0x00010000) @test octint("0o37777777777") === UInt32(0xffffffff) @test octint("0o40000000000") === UInt64(0x0000000100000000) @test octint("0o1777777777777777777777") === UInt64(0xffffffffffffffff) @test octint("0o2000000000000000000000") === UInt128(0x10000000000000000) @test octint("0o3777777777777777777777777777777777777777777") === UInt128(0xffffffffffffffffffffffffffffffff) @test begin n = octint("0o4000000000000000000000000000000000000000000") n isa BigInt && n == 340282366920938463463374607431768211456 end end @testset "OctInt string length limits for different types" begin @test octint("0o000") === UInt8(0) @test octint("0o0000") === UInt16(0) @test octint("0o000000") === UInt16(0) @test octint("0o0000000") === UInt32(0) @test octint("0o00000000000") === UInt32(0) @test octint("0o000000000000") === UInt64(0) @test octint("0o0000000000000000000000") === UInt64(0) @test octint("0o00000000000000000000000") === UInt128(0) @test octint("0o0000000000000000000000000000000000000000000") === UInt128(0) @test begin n = octint("0o00000000000000000000000000000000000000000000") n isa BigInt && n == 0 end end @testset "Underscore separators" begin @test parse_int_literal("10_000") === 10000 @test parse_uint_literal("0xff_ff", K"HexInt") === 0xffff @test parse_uint_literal("0b1111_1111", K"BinInt") === 0xff @test parse_uint_literal("0o177_777", K"OctInt") === 0xffff end @testset "\\minus ('\\u2212' / '−') allowed in numbers" begin @test parse_int_literal("−10") === -10 end end @testset "Integer parsing" begin @testset "Signed Integers" begin @test parse_int_literal("-1") isa Int @test parse_int_literal("1") isa Int @test parse_int_literal("2147483647") isa Int @test parse_int_literal("9223372036854775807") isa Int64 @test parse_int_literal("9223372036854775808") isa Int128 @test parse_int_literal("170141183460469231731687303715884105727") isa Int128 @test parse_int_literal("170141183460469231731687303715884105728") isa BigInt end @testset "HexInt numeric limits for different types" begin @test hexint("0xff") === UInt8(0xff) @test hexint("0x100") === UInt16(0x0100) @test hexint("0xffff") === UInt16(0xffff) @test hexint("0x10000") === UInt32(0x00010000) @test hexint("0xffffffff") === UInt32(0xffffffff) @test hexint("0x100000000") === UInt64(0x0000000100000000) @test hexint("0xffffffffffffffff") === UInt64(0xffffffffffffffff) @test hexint("0x10000000000000000") === UInt128(0x10000000000000000) @test hexint("0xffffffffffffffffffffffffffffffff") === UInt128(0xffffffffffffffffffffffffffffffff) @test begin n = hexint("0x100000000000000000000000000000000") n isa BigInt && n == 340282366920938463463374607431768211456 end end @testset "HexInt string length limits for different types" begin @test hexint("0x00") === UInt8(0) @test hexint("0x000") === UInt16(0) @test hexint("0x0000") === UInt16(0) @test hexint("0x00000") === UInt32(0) @test hexint("0x00000000") === UInt32(0) @test hexint("0x000000000") === UInt64(0) @test hexint("0x0000000000000000") === UInt64(0) @test hexint("0x00000000000000000") === UInt128(0) @test hexint("0x00000000000000000000000000000000") === UInt128(0) @test begin n = hexint("0x000000000000000000000000000000000") n isa BigInt && n == 0 end end @testset "BinInt numeric limits for different types" begin @test binint("0b11111111") === UInt8(0xff) @test binint("0b100000000") === UInt16(0x0100) @test binint("0b1111111111111111") === UInt16(0xffff) @test binint("0b10000000000000000") === UInt32(0x00010000) @test binint("0b11111111111111111111111111111111") === UInt32(0xffffffff) @test binint("0b100000000000000000000000000000000") === UInt64(0x0000000100000000) @test binint("0b1111111111111111111111111111111111111111111111111111111111111111") === UInt64(0xffffffffffffffff) @test binint("0b10000000000000000000000000000000000000000000000000000000000000000") === UInt128(0x10000000000000000) @test binint("0b11111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111") === UInt128(0xffffffffffffffffffffffffffffffff) @test begin n = binint("0b100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000") n isa BigInt && n == 340282366920938463463374607431768211456 end end @testset "BinInt string length limits for different types" begin @test binint("0b00000000") === UInt8(0) @test binint("0b000000000") === UInt16(0) @test binint("0b0000000000000000") === UInt16(0) @test binint("0b00000000000000000") === UInt32(0) @test binint("0b00000000000000000000000000000000") === UInt32(0) @test binint("0b000000000000000000000000000000000") === UInt64(0) @test binint("0b0000000000000000000000000000000000000000000000000000000000000000") === UInt64(0) @test binint("0b00000000000000000000000000000000000000000000000000000000000000000") === UInt128(0) @test binint("0b00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000") === UInt128(0) @test begin n = binint("0b000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000") n isa BigInt && n == 0 end end @testset "OctInt numeric limits for different types" begin @test octint("0o377") === UInt8(0xff) @test octint("0o400") === UInt16(0x0100) @test octint("0o177777") === UInt16(0xffff) @test octint("0o200000") === UInt32(0x00010000) @test octint("0o37777777777") === UInt32(0xffffffff) @test octint("0o40000000000") === UInt64(0x0000000100000000) @test octint("0o1777777777777777777777") === UInt64(0xffffffffffffffff) @test octint("0o2000000000000000000000") === UInt128(0x10000000000000000) @test octint("0o3777777777777777777777777777777777777777777") === UInt128(0xffffffffffffffffffffffffffffffff) @test begin n = octint("0o4000000000000000000000000000000000000000000") n isa BigInt && n == 340282366920938463463374607431768211456 end end @testset "OctInt string length limits for different types" begin @test octint("0o000") === UInt8(0) @test octint("0o0000") === UInt16(0) @test octint("0o000000") === UInt16(0) @test octint("0o0000000") === UInt32(0) @test octint("0o00000000000") === UInt32(0) @test octint("0o000000000000") === UInt64(0) @test octint("0o0000000000000000000000") === UInt64(0) @test octint("0o00000000000000000000000") === UInt128(0) @test octint("0o0000000000000000000000000000000000000000000") === UInt128(0) @test begin n = octint("0o00000000000000000000000000000000000000000000") n isa BigInt && n == 0 end end @testset "Underscore separators" begin @test parse_int_literal("10_000") === 10000 @test parse_uint_literal("0xff_ff", K"HexInt") === 0xffff @test parse_uint_literal("0b1111_1111", K"BinInt") === 0xff @test parse_uint_literal("0o177_777", K"OctInt") === 0xffff end @testset "\\minus ('\\u2212' / '−') allowed in numbers" begin @test parse_int_literal("−10") === -10 end end @testset "Integer parsing" begin @testset "Signed Integers" begin @test parse_int_literal("-1") isa Int @test parse_int_literal("1") isa Int @test parse_int_literal("2147483647") isa Int @test parse_int_literal("9223372036854775807") isa Int64 @test parse_int_literal("9223372036854775808") isa Int128 @test parse_int_literal("170141183460469231731687303715884105727") isa Int128 @test parse_int_literal("170141183460469231731687303715884105728") isa BigInt end @testset "HexInt numeric limits for different types" begin @test hexint("0xff") === UInt8(0xff) @test hexint("0x100") === UInt16(0x0100) @test hexint("0xffff") === UInt16(0xffff) @test hexint("0x10000") === UInt32(0x00010000) @test hexint("0xffffffff") === UInt32(0xffffffff) @test hexint("0x100000000") === UInt64(0x0000000100000000) @test hexint("0xffffffffffffffff") === UInt64(0xffffffffffffffff) @test hexint("0x10000000000000000") === UInt128(0x10000000000000000) @test hexint("0xffffffffffffffffffffffffffffffff") === UInt128(0xffffffffffffffffffffffffffffffff) @test begin n = hexint("0x100000000000000000000000000000000") n isa BigInt && n == 340282366920938463463374607431768211456 end end @testset "HexInt string length limits for different types" begin @test hexint("0x00") === UInt8(0) @test hexint("0x000") === UInt16(0) @test hexint("0x0000") === UInt16(0) @test hexint("0x00000") === UInt32(0) @test hexint("0x00000000") === UInt32(0) @test hexint("0x000000000") === UInt64(0) @test hexint("0x0000000000000000") === UInt64(0) @test hexint("0x00000000000000000") === UInt128(0) @test hexint("0x00000000000000000000000000000000") === UInt128(0) @test begin n = hexint("0x000000000000000000000000000000000") n isa BigInt && n == 0 end end @testset "BinInt numeric limits for different types" begin @test binint("0b11111111") === UInt8(0xff) @test binint("0b100000000") === UInt16(0x0100) @test binint("0b1111111111111111") === UInt16(0xffff) @test binint("0b10000000000000000") === UInt32(0x00010000) @test binint("0b11111111111111111111111111111111") === UInt32(0xffffffff) @test binint("0b100000000000000000000000000000000") === UInt64(0x0000000100000000) @test binint("0b1111111111111111111111111111111111111111111111111111111111111111") === UInt64(0xffffffffffffffff) @test binint("0b10000000000000000000000000000000000000000000000000000000000000000") === UInt128(0x10000000000000000) @test binint("0b11111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111") === UInt128(0xffffffffffffffffffffffffffffffff) @test begin n = binint("0b100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000") n isa BigInt && n == 340282366920938463463374607431768211456 end end @testset "BinInt string length limits for different types" begin @test binint("0b00000000") === UInt8(0) @test binint("0b000000000") === UInt16(0) @test binint("0b0000000000000000") === UInt16(0) @test binint("0b00000000000000000") === UInt32(0) @test binint("0b00000000000000000000000000000000") === UInt32(0) @test binint("0b000000000000000000000000000000000") === UInt64(0) @test binint("0b0000000000000000000000000000000000000000000000000000000000000000") === UInt64(0) @test binint("0b00000000000000000000000000000000000000000000000000000000000000000") === UInt128(0) @test binint("0b00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000") === UInt128(0) @test begin n = binint("0b000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000") n isa BigInt && n == 0 end end @testset "OctInt numeric limits for different types" begin @test octint("0o377") === UInt8(0xff) @test octint("0o400") === UInt16(0x0100) @test octint("0o177777") === UInt16(0xffff) @test octint("0o200000") === UInt32(0x00010000) @test octint("0o37777777777") === UInt32(0xffffffff) @test octint("0o40000000000") === UInt64(0x0000000100000000) @test octint("0o1777777777777777777777") === UInt64(0xffffffffffffffff) @test octint("0o2000000000000000000000") === UInt128(0x10000000000000000) @test octint("0o3777777777777777777777777777777777777777777") === UInt128(0xffffffffffffffffffffffffffffffff) @test begin n = octint("0o4000000000000000000000000000000000000000000") n isa BigInt && n == 340282366920938463463374607431768211456 end end @testset "OctInt string length limits for different types" begin @test octint("0o000") === UInt8(0) @test octint("0o0000") === UInt16(0) @test octint("0o000000") === UInt16(0) @test octint("0o0000000") === UInt32(0) @test octint("0o00000000000") === UInt32(0) @test octint("0o000000000000") === UInt64(0) @test octint("0o0000000000000000000000") === UInt64(0) @test octint("0o00000000000000000000000") === UInt128(0) @test octint("0o0000000000000000000000000000000000000000000") === UInt128(0) @test begin n = octint("0o00000000000000000000000000000000000000000000") n isa BigInt && n == 0 end end @testset "Underscore separators" begin @test parse_int_literal("10_000") === 10000 @test parse_uint_literal("0xff_ff", K"HexInt") === 0xffff @test parse_uint_literal("0b1111_1111", K"BinInt") === 0xff @test parse_uint_literal("0o177_777", K"OctInt") === 0xffff end @testset "\\minus ('\\u2212' / '−') allowed in numbers" begin @test parse_int_literal("−10") === -10 end end Parsing files in Base: Test Failed at /home/pkgeval/.julia/packages/CSTParser/0hXvH/test/test_check_base.jl:166 Expression: false Stacktrace: [1] macro expansion @ /opt/julia/share/julia/stdlib/v1.14/Test/src/Test.jl:753 [inlined] [2] top-level scope @ ~/.julia/packages/CSTParser/0hXvH/test/test_check_base.jl:166 Parsing files in Base: Test Failed at /home/pkgeval/.julia/packages/CSTParser/0hXvH/test/test_check_base.jl:143 Expression: cst_err == meta_err Evaluated: true == false Stacktrace: [1] macro expansion @ /opt/julia/share/julia/stdlib/v1.14/Test/src/Test.jl:753 [inlined] [2] top-level scope @ ~/.julia/packages/CSTParser/0hXvH/test/test_check_base.jl:143 ┌ Error: CSTParser.parse errored, but Meta.parse didn't. │ file = "/opt/julia/bin/../share/julia/base/binaryplatforms.jl" └ @ Main.var"##296" ~/.julia/packages/CSTParser/0hXvH/test/test_check_base.jl:149 ┌ Error: parsing difference │ file = "/opt/julia/bin/../share/julia/base/gmp.jl" └ @ Main.var"##296" ~/.julia/packages/CSTParser/0hXvH/test/test_check_base.jl:157 begin RoundToZero end RoundToZero $(Expr(:kw, :(::typeof(RoundToZero)), quote RoundToZero end)) $(Expr(:kw, :(::typeof(RoundToZero)), :RoundToZero)) divrem(x::BigInt, y::BigInt, ::typeof(RoundToZero) = begin RoundToZero end) divrem(x::BigInt, y::BigInt, ::typeof(RoundToZero) = RoundToZero) divrem(x::BigInt, y::BigInt, ::typeof(RoundToZero) = begin RoundToZero end) = begin MPZ.tdiv_qr(x, y) end divrem(x::BigInt, y::BigInt, ::typeof(RoundToZero) = RoundToZero) = begin MPZ.tdiv_qr(x, y) end begin RoundToZero end RoundToZero $(Expr(:kw, :(::typeof(RoundToZero)), quote RoundToZero end)) $(Expr(:kw, :(::typeof(RoundToZero)), :RoundToZero)) divrem(x::BigInt, y::Integer, ::typeof(RoundToZero) = begin RoundToZero end) divrem(x::BigInt, y::Integer, ::typeof(RoundToZero) = RoundToZero) divrem(x::BigInt, y::Integer, ::typeof(RoundToZero) = begin RoundToZero end) = begin MPZ.tdiv_qr(x, BigInt(y)) end divrem(x::BigInt, y::Integer, ::typeof(RoundToZero) = RoundToZero) = begin MPZ.tdiv_qr(x, BigInt(y)) end begin export BigInt import .Base: *, +, -, /, <, <<, >>, >>>, <=, ==, >, >=, ^, ~, &, |, xor, nand, nor, binomial, cmp, convert, div, divrem, factorial, cld, fld, gcd, gcdx, lcm, mod, ndigits, promote_rule, rem, show, isqrt, string, powermod, sum, prod, trailing_zeros, trailing_ones, count_ones, count_zeros, tryparse_internal, bin, oct, dec, hex, isequal, invmod, _prevpow2, _nextpow2, ndigits0zpb, widen, signed, unsafe_trunc, trunc, iszero, isone, big, flipsign, signbit, sign, isodd, iseven, digits!, hash, hash_integer, top_set_bit, ispositive, isnegative, clamp, unsafe_takestring import Core: Signed, Float16, Float32, Float64 if Clong == Int32 const ClongMax = Union{Int8, Int16, Int32} const CulongMax = Union{UInt8, UInt16, UInt32} else const ClongMax = Union{Int8, Int16, Int32, Int64} const CulongMax = Union{UInt8, UInt16, UInt32, UInt64} end const CdoubleMax = Union{Float16, Float32, Float64} if Sys.iswindows() const libgmp = "libgmp-10.dll" elseif Sys.isapple() const libgmp = "@rpath/libgmp.10.dylib" else const libgmp = "libgmp.so.10" end _version() = begin unsafe_string(unsafe_load(cglobal((:__gmp_version, libgmp), Ptr{Cchar}))) end version() = begin VersionNumber(_version()) end major_version() = begin (_version())[1] end bits_per_limb() = begin Int(unsafe_load(cglobal((:__gmp_bits_per_limb, libgmp), Cint))) end const VERSION = version() const MAJOR_VERSION = major_version() const BITS_PER_LIMB = bits_per_limb() if BITS_PER_LIMB == 32 const Limb = UInt32 const SLimbMax = Union{Int8, Int16, Int32} const ULimbMax = Union{UInt8, UInt16, UInt32} elseif BITS_PER_LIMB == 64 const Limb = UInt64 const SLimbMax = Union{Int8, Int16, Int32, Int64} const ULimbMax = Union{UInt8, UInt16, UInt32, UInt64} else error("GMP: cannot determine the type mp_limb_t (__gmp_bits_per_limb == $(BITS_PER_LIMB))") end Core.@doc " BigInt <: Signed\n\nArbitrary precision integer type.\n" mutable struct BigInt <: Signed alloc::Cint size::Cint d::Ptr{Limb} function BigInt(; nbits::Integer = 0) b = MPZ.init2!(new(), nbits) finalizer(cglobal((:__gmpz_clear, libgmp)), b) return b end end Core.@doc " BigInt(x)\n\nCreate an arbitrary precision integer. `x` may be an `Int` (or anything that can be\nconverted to an `Int`). The usual mathematical operators are defined for this type, and\nresults are promoted to a [`BigInt`](@ref).\n\nInstances can be constructed from strings via [`parse`](@ref), or using the `big`\nstring literal.\n\n# Examples\n```jldoctest\njulia> parse(BigInt, \"42\")\n42\n\njulia> big\"313\"\n313\n\njulia> BigInt(10)^19\n10000000000000000000\n```\n" BigInt(x) Core.@doc " ALLOC_OVERFLOW_FUNCTION\n\nA reference that holds a boolean, if true, indicating julia is linked with a patched GMP that\ndoes not abort on huge allocation and throws OutOfMemoryError instead.\n" const ALLOC_OVERFLOW_FUNCTION = Ref(false) function __init__() try if major_version() != MAJOR_VERSION || bits_per_limb() != BITS_PER_LIMB msg = "The dynamically loaded GMP library (v\"$(version())\" with __gmp_bits_per_limb == $(bits_per_limb()))\ndoes not correspond to the compile time version (v\"$(VERSION)\" with __gmp_bits_per_limb == $(BITS_PER_LIMB)).\nPlease rebuild Julia." if bits_per_limb() != BITS_PER_LIMB @error msg else @warn msg end end ccall((:__gmp_set_memory_functions, libgmp), Cvoid, (Ptr{Cvoid}, Ptr{Cvoid}, Ptr{Cvoid}), cglobal(:jl_gc_counted_malloc), cglobal(:jl_gc_counted_realloc_with_old_size), cglobal(:jl_gc_counted_free_with_size)) (ZERO.alloc, ZERO.size, ZERO.d) = (0, 0, C_NULL) (ONE.alloc, ONE.size, ONE.d) = (1, 1, pointer(_ONE)) catch ex Base.showerror_nostdio(ex, "WARNING: Error during initialization of module GMP") end try ccall((:__gmp_set_alloc_overflow_function, libgmp), Cvoid, (Ptr{Cvoid},), cglobal(:jl_throw_out_of_memory_error)) ALLOC_OVERFLOW_FUNCTION[] = true catch ex if typeof(ex) != ErrorException rethrow() end end end module MPZ using ..GMP: BigInt, Limb, BITS_PER_LIMB, libgmp const mpz_t = Ref{BigInt} const bitcnt_t = Culong gmpz(op::Symbol) = begin Expr(:tuple, QuoteNode(Symbol(:__gmpz_, op)), GlobalRef(MPZ, :libgmp)) end init!(x::BigInt) = begin ccall((:__gmpz_init, libgmp), Cvoid, (mpz_t,), x) x end init2!(x::BigInt, a) = begin ccall((:__gmpz_init2, libgmp), Cvoid, (mpz_t, bitcnt_t), x, a) x end realloc2!(x, a) = begin ccall((:__gmpz_realloc2, libgmp), Cvoid, (mpz_t, bitcnt_t), x, a) x end realloc2(a) = begin realloc2!(BigInt(), a) end sizeinbase(a::BigInt, b) = begin Int(ccall((:__gmpz_sizeinbase, libgmp), Csize_t, (mpz_t, Cint), a, b)) end for (op, nbits) = (:add => :(BITS_PER_LIMB * (1 + max(abs(a.size), abs(b.size)))), :sub => :(BITS_PER_LIMB * (1 + max(abs(a.size), abs(b.size)))), :mul => 0, :fdiv_q => 0, :tdiv_q => 0, :cdiv_q => 0, :fdiv_r => 0, :tdiv_r => 0, :cdiv_r => 0, :gcd => 0, :lcm => 0, :and => 0, :ior => 0, :xor => 0) op! = Symbol(op, :!) @eval begin ($op!)(x::BigInt, a::BigInt, b::BigInt) = begin ccall($(gmpz(op)), Cvoid, (mpz_t, mpz_t, mpz_t), x, a, b) x end ($op)(a::BigInt, b::BigInt) = begin ($op!)(BigInt(nbits = $nbits), a, b) end ($op!)(x::BigInt, b::BigInt) = begin ($op!)(x, x, b) end end end invert!(x::BigInt, a::BigInt, b::BigInt) = begin ccall((:__gmpz_invert, libgmp), Cint, (mpz_t, mpz_t, mpz_t), x, a, b) end invert!(x::BigInt, b::BigInt) = begin invert!(x, x, b) end invert(a::BigInt, b::BigInt) = begin ret = BigInt() invert!(ret, a, b) ret end for op = (:add_ui, :sub_ui, :mul_ui, :mul_2exp, :fdiv_q_2exp, :pow_ui, :bin_ui) op! = Symbol(op, :!) @eval begin ($op!)(x::BigInt, a::BigInt, b) = begin ccall($(gmpz(op)), Cvoid, (mpz_t, mpz_t, Culong), x, a, b) x end ($op)(a::BigInt, b) = begin ($op!)(BigInt(), a, b) end ($op!)(x::BigInt, b) = begin ($op!)(x, x, b) end end end ui_sub!(x::BigInt, a, b::BigInt) = begin ccall((:__gmpz_ui_sub, libgmp), Cvoid, (mpz_t, Culong, mpz_t), x, a, b) x end ui_sub(a, b::BigInt) = begin ui_sub!(BigInt(), a, b) end for op = (:scan1, :scan0) @eval ($op)(a::BigInt, b) = begin Int(signed(ccall($(gmpz(op)), Culong, (mpz_t, Culong), a, b))) end end mul_si!(x::BigInt, a::BigInt, b) = begin ccall((:__gmpz_mul_si, libgmp), Cvoid, (mpz_t, mpz_t, Clong), x, a, b) x end mul_si(a::BigInt, b) = begin mul_si!(BigInt(), a, b) end mul_si!(x::BigInt, b) = begin mul_si!(x, x, b) end for op = (:neg, :com, :sqrt, :set) op! = Symbol(op, :!) @eval begin ($op!)(x::BigInt, a::BigInt) = begin ccall($(gmpz(op)), Cvoid, (mpz_t, mpz_t), x, a) x end ($op)(a::BigInt) = begin ($op!)(BigInt(), a) end end op === :set && continue @eval ($op!)(x::BigInt) = begin ($op!)(x, x) end end for (op, T) = ((:fac_ui, Culong), (:set_ui, Culong), (:set_si, Clong), (:set_d, Cdouble)) op! = Symbol(op, :!) @eval begin ($op!)(x::BigInt, a) = begin ccall($(gmpz(op)), Cvoid, (mpz_t, $T), x, a) x end ($op)(a) = begin ($op!)(BigInt(), a) end end end popcount(a::BigInt) = begin Int(signed(ccall((:__gmpz_popcount, libgmp), Culong, (mpz_t,), a))) end mpn_popcount(d::Ptr{Limb}, s::Integer) = begin Int(ccall((:__gmpn_popcount, libgmp), Culong, (Ptr{Limb}, Csize_t), d, s)) end mpn_popcount(a::BigInt) = begin mpn_popcount(a.d, abs(a.size)) end function tdiv_qr!(x::BigInt, y::BigInt, a::BigInt, b::BigInt) ccall((:__gmpz_tdiv_qr, libgmp), Cvoid, (mpz_t, mpz_t, mpz_t, mpz_t), x, y, a, b) (x, y) end tdiv_qr(a::BigInt, b::BigInt) = begin tdiv_qr!(BigInt(), BigInt(), a, b) end powm!(x::BigInt, a::BigInt, b::BigInt, c::BigInt) = begin ccall((:__gmpz_powm, libgmp), Cvoid, (mpz_t, mpz_t, mpz_t, mpz_t), x, a, b, c) x end powm(a::BigInt, b::BigInt, c::BigInt) = begin powm!(BigInt(), a, b, c) end powm!(x::BigInt, b::BigInt, c::BigInt) = begin powm!(x, x, b, c) end function gcdext!(x::BigInt, y::BigInt, z::BigInt, a::BigInt, b::BigInt) ccall((:__gmpz_gcdext, libgmp), Cvoid, (mpz_t, mpz_t, mpz_t, mpz_t, mpz_t), x, y, z, a, b) (x, y, z) end gcdext(a::BigInt, b::BigInt) = begin gcdext!(BigInt(), BigInt(), BigInt(), a, b) end cmp(a::BigInt, b::BigInt) = begin Int(ccall((:__gmpz_cmp, libgmp), Cint, (mpz_t, mpz_t), a, b)) end cmp_si(a::BigInt, b) = begin Int(ccall((:__gmpz_cmp_si, libgmp), Cint, (mpz_t, Clong), a, b)) end cmp_ui(a::BigInt, b) = begin Int(ccall((:__gmpz_cmp_ui, libgmp), Cint, (mpz_t, Culong), a, b)) end cmp_d(a::BigInt, b) = begin Int(ccall((:__gmpz_cmp_d, libgmp), Cint, (mpz_t, Cdouble), a, b)) end mpn_cmp(a::Ptr{Limb}, b::Ptr{Limb}, c) = begin ccall((:__gmpn_cmp, libgmp), Cint, (Ptr{Limb}, Ptr{Limb}, Clong), a, b, c) end mpn_cmp(a::BigInt, b::BigInt, c) = begin mpn_cmp(a.d, b.d, c) end get_str!(x, a, b::BigInt) = begin ccall((:__gmpz_get_str, libgmp), Ptr{Cchar}, (Ptr{Cchar}, Cint, mpz_t), x, a, b) x end set_str!(x::BigInt, a, b) = begin Int(ccall((:__gmpz_set_str, libgmp), Cint, (mpz_t, Ptr{UInt8}, Cint), x, a, b)) end get_d(a::BigInt) = begin ccall((:__gmpz_get_d, libgmp), Cdouble, (mpz_t,), a) end function export!(a::AbstractVector{T}, n::BigInt; order::Integer = -1, nails::Integer = 0, endian::Integer = 0) where T <: Base.BitInteger stride(a, 1) == 1 || throw(ArgumentError("a must have stride 1")) ndigits = cld(sizeinbase(n, 2), 8 * sizeof(T) - nails) length(a) < ndigits && resize!(a, ndigits) fill!(a, zero(T)) count = Ref{Csize_t}() ccall((:__gmpz_export, libgmp), Ptr{T}, (Ptr{T}, Ref{Csize_t}, Cint, Csize_t, Cint, Csize_t, mpz_t), a, count, order, sizeof(T), endian, nails, n) @assert count[] ≤ length(a) return (a, Int(count[])) end limbs_write!(x::BigInt, a) = begin ccall((:__gmpz_limbs_write, libgmp), Ptr{Limb}, (mpz_t, Clong), x, a) end limbs_finish!(x::BigInt, a) = begin ccall((:__gmpz_limbs_finish, libgmp), Cvoid, (mpz_t, Clong), x, a) end setbit!(x, a) = begin ccall((:__gmpz_setbit, libgmp), Cvoid, (mpz_t, bitcnt_t), x, a) x end tstbit(a::BigInt, b) = begin ccall((:__gmpz_tstbit, libgmp), Cint, (mpz_t, bitcnt_t), a, b) % Bool end end const ZERO = BigInt() const ONE = BigInt() const _ONE = Limb[1] widen(::Type{Int128}) = begin BigInt end widen(::Type{UInt128}) = begin BigInt end widen(::Type{BigInt}) = begin BigInt end signed(x::BigInt) = begin x end BigInt(x::BigInt) = begin x end Signed(x::BigInt) = begin x end function tryparse_internal(::Type{BigInt}, s::AbstractString, startpos::Int, endpos::Int, base_::Integer, raise::Bool) bstr = if startpos == firstindex(s) && endpos == lastindex(s) String(s) else String(SubString(s, startpos, endpos)) end (sgn, base, i) = Base.parseint_preamble(true, Int(base_), bstr, firstindex(bstr), lastindex(bstr)) if !(2 <= base <= 62) raise && throw(ArgumentError("invalid base: base must be 2 ≤ base ≤ 62, got $(base)")) return nothing end if i == 0 raise && throw(ArgumentError("premature end of integer: $(repr(bstr))")) return nothing end z = BigInt() if Base.containsnul(bstr) err = -1 else err = GC.@preserve(bstr, MPZ.set_str!(z, pointer(bstr) + (i - firstindex(bstr)), base)) end if err != 0 raise && throw(ArgumentError("invalid BigInt: $(repr(bstr))")) return nothing end flipsign!(z, sgn) end BigInt(x::Union{Clong, Int32}) = begin MPZ.set_si(x) end BigInt(x::Union{Culong, UInt32}) = begin MPZ.set_ui(x) end BigInt(x::Bool) = begin BigInt(UInt(x)) end unsafe_trunc(::Type{BigInt}, x::Union{Float16, Float32, Float64}) = begin MPZ.set_d(x) end function BigInt(x::Float64) isinteger(x) || throw(InexactError(:BigInt, BigInt, x)) unsafe_trunc(BigInt, x) end BigInt(x::Float16) = begin BigInt(Float64(x)) end BigInt(x::Float32) = begin BigInt(Float64(x)) end function BigInt(x::Integer) isbits(x) && (typemin(Clong) <= x <= typemax(Clong) && return BigInt((x % Clong)::Clong)) nd = ndigits(x, base = 2) z = MPZ.realloc2(nd) ux = unsigned(if x < 0 -x else x end) size = 0 limbnbits = sizeof(Limb) << 3 while nd > 0 size += 1 unsafe_store!(z.d, ux % Limb, size) ux >>= limbnbits nd -= limbnbits end z.size = if x < 0 -size else size end z end rem(x::BigInt, ::Type{Bool}) = begin (!(iszero(x)) & unsafe_load(x.d)) % Bool end (rem(x::BigInt, ::Type{T}) where T <: Union{SLimbMax, ULimbMax}) = begin if iszero(x) zero(T) else flipsign(unsafe_load(x.d) % T, x.size) end end function rem(x::BigInt, ::Type{T}) where T <: Union{Base.BitUnsigned, Base.BitSigned} u = zero(T) for l = 1:min(abs(x.size), cld(sizeof(T), sizeof(Limb))) u += (unsafe_load(x.d, l) % T) << (sizeof(Limb) << 3 * (l - 1)) end flipsign(u, x.size) end rem(x::Integer, ::Type{BigInt}) = begin BigInt(x) end clamp(x, ::Type{BigInt}) = begin convert(BigInt, x) end isodd(x::BigInt) = begin MPZ.tstbit(x, 0) end iseven(x::BigInt) = begin !(isodd(x)) end function (::Type{T})(x::BigInt) where T <: Base.BitUnsigned if sizeof(T) < sizeof(Limb) convert(T, convert(Limb, x)) else 0 <= x.size <= cld(sizeof(T), sizeof(Limb)) || throw(InexactError(nameof(T), T, x)) x % T end end function (::Type{T})(x::BigInt) where T <: Base.BitSigned n = abs(x.size) if sizeof(T) < sizeof(Limb) SLimb = typeof(Signed(one(Limb))) convert(T, convert(SLimb, x)) else 0 <= n <= cld(sizeof(T), sizeof(Limb)) || throw(InexactError(nameof(T), T, x)) y = x % T ispositive(x) ⊻ (y > 0) && throw(InexactError(nameof(T), T, x)) y end end Float64(n::BigInt, ::RoundingMode{:ToZero}) = begin MPZ.get_d(n) end function (::Type{T})(n::BigInt, ::RoundingMode{:ToZero}) where T <: Union{Float16, Float32} T(Float64(n, RoundToZero), RoundToZero) end function (::Type{T})(n::BigInt, ::RoundingMode{:Down}) where T <: CdoubleMax x = T(n, RoundToZero) if x > n prevfloat(x) else x end end function (::Type{T})(n::BigInt, ::RoundingMode{:Up}) where T <: CdoubleMax x = T(n, RoundToZero) if x < n nextfloat(x) else x end end function Float64(x::BigInt, ::RoundingMode{:Nearest}) x == 0 && return 0.0 xsize = abs(x.size) if xsize * BITS_PER_LIMB > 1024 z = Inf64 elseif xsize == 1 z = Float64(unsafe_load(x.d)) elseif Limb == UInt32 && xsize == 2 z = Float64((unsafe_load(x.d, 2) % UInt64) << BITS_PER_LIMB + unsafe_load(x.d)) else y1 = unsafe_load(x.d, xsize) % UInt64 n = top_set_bit(y1) y = y1 >> (n - (precision(Float64) + 1)) if Limb == UInt64 y += if n > precision(Float64) 0 else unsafe_load(x.d, xsize - 1) >> (10 + n) end else y += (unsafe_load(x.d, xsize - 1) % UInt64) >> (n - 22) y += if n > precision(Float64) - 32 0 else unsafe_load(x.d, xsize - 2) >> (10 + n) end end y = (y + 1) >> 1 y &= ~(UInt64(trailing_zeros(x) == (n - 54) + (xsize - 1) * BITS_PER_LIMB)) d = ((n + 1021) % UInt64) << 52 z = reinterpret(Float64, d + y) z = ldexp(z, (xsize - 1) * BITS_PER_LIMB) end return flipsign(z, x.size) end function Float32(x::BigInt, ::RoundingMode{:Nearest}) x == 0 && return 0.0f0 xsize = abs(x.size) if xsize * BITS_PER_LIMB > 128 z = Inf32 elseif xsize == 1 z = Float32(unsafe_load(x.d)) else y1 = unsafe_load(x.d, xsize) n = BITS_PER_LIMB - leading_zeros(y1) y = y1 >> (n - (precision(Float32) + 1)) % UInt32 y += if n > precision(Float32) 0 else unsafe_load(x.d, xsize - 1) >> (BITS_PER_LIMB - -25) end % UInt32 y = (y + one(UInt32)) >> 1 y &= ~(UInt32(trailing_zeros(x) == (n - 25) + (xsize - 1) * BITS_PER_LIMB)) d = ((n + 125) % UInt32) << 23 z = reinterpret(Float32, d + y) z = ldexp(z, (xsize - 1) * BITS_PER_LIMB) end return flipsign(z, x.size) end function Float16(x::BigInt, ::RoundingMode{:Nearest}) x == 0 && return Float16(0.0) y1 = unsafe_load(x.d) n = BITS_PER_LIMB - leading_zeros(y1) if n > 16 || abs(x.size) > 1 z = Inf16 else y = y1 >> (n - (precision(Float16) + 1)) % UInt16 y = (y + one(UInt16)) >> 1 y &= ~(UInt16(trailing_zeros(x) == n - 12)) d = ((n + 13) % UInt16) << 10 z = reinterpret(Float16, d + y) end return flipsign(z, x.size) end Float64(n::BigInt) = begin Float64(n, RoundNearest) end Float32(n::BigInt) = begin Float32(n, RoundNearest) end Float16(n::BigInt) = begin Float16(n, RoundNearest) end promote_rule(::Type{BigInt}, ::Type{<:Integer}) = begin BigInt end Core.@doc " big(x)\n\nConvert a number to a maximum precision representation (typically [`BigInt`](@ref) or\n`BigFloat`). See [`BigFloat`](@ref BigFloat(::Any, rounding::RoundingMode)) for\ninformation about some pitfalls with floating-point numbers.\n" function big end big(::Type{<:Integer}) = begin BigInt end big(::Type{<:Rational}) = begin Rational{BigInt} end big(n::Integer) = begin convert(BigInt, n) end for (fJ, fC) = ((:+, :add), (:-, :sub), (:*, :mul), (:mod, :fdiv_r), (:rem, :tdiv_r), (:gcd, :gcd), (:lcm, :lcm), (:&, :and), (:|, :ior), (:xor, :xor)) @eval begin ($fJ)(x::BigInt, y::BigInt) = begin MPZ.:($fC)(x, y) end end end for (r, f) = ((RoundToZero, :tdiv_q), (RoundDown, :fdiv_q), (RoundUp, :cdiv_q)) @eval div(x::BigInt, y::BigInt, ::typeof($r)) = begin MPZ.:($f)(x, y) end end div(x::BigInt, y::BigInt) = begin div(x, y, RoundToZero) end fld(x::BigInt, y::BigInt) = begin div(x, y, RoundDown) end cld(x::BigInt, y::BigInt) = begin div(x, y, RoundUp) end x::BigInt / y::BigInt = begin float(x) / float(y) end function invmod(x::BigInt, y::BigInt) z = zero(BigInt) ya = abs(y) if ya == 1 return z end if y == 0 || MPZ.invert!(z, x, ya) == 0 throw(DomainError(y)) end if y < 0 MPZ.add!(z, y) end return z end for (fJ, fC) = ((:+, :add), (:*, :mul), (:&, :and), (:|, :ior), (:xor, :xor)) fC! = Symbol(fC, :!) @eval begin ($fJ)(a::BigInt, b::BigInt, c::BigInt) = begin MPZ.:($fC!)(MPZ.:($fC)(a, b), c) end ($fJ)(a::BigInt, b::BigInt, c::BigInt, d::BigInt) = begin MPZ.:($fC!)(MPZ.:($fC!)(MPZ.:($fC)(a, b), c), d) end ($fJ)(a::BigInt, b::BigInt, c::BigInt, d::BigInt, e::BigInt) = begin MPZ.:($fC!)(MPZ.:($fC!)(MPZ.:($fC!)(MPZ.:($fC)(a, b), c), d), e) end end end x::BigInt + c::CulongMax = begin MPZ.add_ui(x, c) end c::CulongMax + x::BigInt = begin x + c end x::BigInt - c::CulongMax = begin MPZ.sub_ui(x, c) end c::CulongMax - x::BigInt = begin MPZ.ui_sub(c, x) end x::BigInt + c::ClongMax = begin if c < 0 x - -(c % Culong) else x + convert(Culong, c) end end c::ClongMax + x::BigInt = begin if c < 0 x - -(c % Culong) else x + convert(Culong, c) end end x::BigInt - c::ClongMax = begin if c < 0 x + -(c % Culong) else x - convert(Culong, c) end end c::ClongMax - x::BigInt = begin if c < 0 -((x + -(c % Culong))) else convert(Culong, c) - x end end x::BigInt * c::CulongMax = begin MPZ.mul_ui(x, c) end c::CulongMax * x::BigInt = begin x * c end x::BigInt * c::ClongMax = begin MPZ.mul_si(x, c) end c::ClongMax * x::BigInt = begin x * c end x::BigInt / y::Union{ClongMax, CulongMax} = begin float(x) / y end x::Union{ClongMax, CulongMax} / y::BigInt = begin x / float(y) end -(x::BigInt) = begin MPZ.neg(x) end ~(x::BigInt) = begin MPZ.com(x) end x::BigInt << c::UInt = begin if c == 0 x else MPZ.mul_2exp(x, c) end end x::BigInt >> c::UInt = begin if c == 0 x else MPZ.fdiv_q_2exp(x, c) end end x::BigInt >>> c::UInt = begin x >> c end function trailing_zeros(x::BigInt) c = MPZ.scan1(x, 0) c == -1 && throw(DomainError(x, "`x` must be non-zero")) c end function trailing_ones(x::BigInt) c = MPZ.scan0(x, 0) c == -1 && throw(DomainError(x, "`x` must not be equal to -1")) c end function count_ones(x::BigInt) c = MPZ.popcount(x) c == -1 && throw(DomainError(x, "`x` cannot be negative")) c end function count_zeros(x::BigInt) c = MPZ.popcount(~x) c == -1 && throw(DomainError(x, "`x` must be negative")) c end Core.@doc " count_ones_abs(x::BigInt)\n\nNumber of ones in the binary representation of abs(x).\n" count_ones_abs(x::BigInt) = begin if iszero(x) 0 else MPZ.mpn_popcount(x) end end _bit_magnitude(x::BigInt) = begin x.size * sizeof(Limb) << 3 - leading_zeros(GC.@preserve(x, unsafe_load(x.d, x.size))) end function exponent(x::BigInt) iszero(x) && throw(DomainError(x, "cannot be zero")) ux = abs(x) return _bit_magnitude(ux) - 1 end function top_set_bit(x::BigInt) isnegative(x) && throw(DomainError(x, "top_set_bit only supports negative arguments when they have type BitSigned.")) iszero(x) && return 0 return _bit_magnitude(x) end divrem(x::BigInt, y::BigInt, ::typeof(RoundToZero) = begin RoundToZero end) = begin MPZ.tdiv_qr(x, y) end divrem(x::BigInt, y::Integer, ::typeof(RoundToZero) = begin RoundToZero end) = begin MPZ.tdiv_qr(x, BigInt(y)) end cmp(x::BigInt, y::BigInt) = begin sign(MPZ.cmp(x, y)) end cmp(x::BigInt, y::ClongMax) = begin sign(MPZ.cmp_si(x, y)) end cmp(x::BigInt, y::CulongMax) = begin sign(MPZ.cmp_ui(x, y)) end cmp(x::BigInt, y::Integer) = begin cmp(x, big(y)) end cmp(x::Integer, y::BigInt) = begin -(cmp(y, x)) end cmp(x::BigInt, y::CdoubleMax) = begin if isnan(y) -1 else sign(MPZ.cmp_d(x, y)) end end cmp(x::CdoubleMax, y::BigInt) = begin -(cmp(y, x)) end isqrt(x::BigInt) = begin MPZ.sqrt(x) end x::BigInt ^ y::Culong = begin MPZ.pow_ui(x, y) end function bigint_pow(x::BigInt, y::Integer) x == 1 && return x x == -1 && return if isodd(y) x else -x end if y < 0 throw(DomainError(y, "`y` cannot be negative.")) end @noinline throw1(y) = begin throw(OverflowError("exponent $(y) is too large and computation will overflow")) end if y > typemax(Culong) x == 0 && return x throw1(y) end return x ^ convert(Culong, y) end x::BigInt ^ y::BigInt = begin bigint_pow(x, y) end x::BigInt ^ y::Bool = begin if y x else one(x) end end x::BigInt ^ y::Integer = begin bigint_pow(x, y) end x::Integer ^ y::BigInt = begin bigint_pow(BigInt(x), y) end x::Bool ^ y::BigInt = begin Base.power_by_squaring(x, y) end function powermod(x::BigInt, p::BigInt, m::BigInt) r = MPZ.powm(x, p, m) return if m < 0 && r > 0 MPZ.add!(r, m) else r end end powermod(x::Integer, p::Integer, m::BigInt) = begin powermod(big(x), big(p), m) end function gcdx(a::BigInt, b::BigInt) (g, s, t) = MPZ.gcdext(a, b) if t == 0 if a == b return (g, t, s) elseif abs(a) == abs(b) return (g, t, -s) end end (g, s, t) end +(x::BigInt, y::BigInt, rest::BigInt...) = begin sum(tuple(x, y, rest...)) end sum(arr::Union{AbstractArray{BigInt}, Tuple{BigInt, Vararg{BigInt}}}) = begin foldl(MPZ.add!, arr; init = BigInt(0)) end function prod(arr::AbstractArray{BigInt}) any(iszero, arr) && return zero(BigInt) _prod(arr, firstindex(arr), lastindex(arr)) end function _prod(arr::AbstractArray{BigInt}, lo, hi) if (hi - lo) + 1 <= 16 nlimbs = 0 for i = lo:hi nlimbs += abs((arr[i]).size) end init = BigInt(; nbits = nlimbs * BITS_PER_LIMB) MPZ.set_si!(init, 1) for i = lo:hi MPZ.mul!(init, arr[i]) end init else mid = (lo + hi) ÷ 2 MPZ.mul!(_prod(arr, lo, mid), _prod(arr, mid + 1, hi)) end end factorial(n::BigInt) = begin if !(isnegative(n)) MPZ.fac_ui(n) else throw(DomainError(n, "`n` must not be negative.")) end end function binomial(n::BigInt, k::Integer) k < 0 && return BigInt(0) k <= typemax(Culong) && return binomial(n, Culong(k)) n < 0 && return if isodd(k) -(binomial((k - n) - 1, k)) else binomial((k - n) - 1, k) end κ = n - k κ < 0 && return BigInt(0) κ <= typemax(Culong) && return binomial(n, Culong(κ)) throw(OverflowError("Computation would exceed memory")) end binomial(n::BigInt, k::Culong) = begin MPZ.bin_ui(n, k) end x::BigInt == y::BigInt = begin cmp(x, y) == 0 end x::BigInt == i::Integer = begin cmp(x, i) == 0 end i::Integer == x::BigInt = begin cmp(x, i) == 0 end x::BigInt == f::CdoubleMax = begin if isnan(f) false else cmp(x, f) == 0 end end f::CdoubleMax == x::BigInt = begin if isnan(f) false else cmp(x, f) == 0 end end iszero(x::BigInt) = begin x.size == 0 end isone(x::BigInt) = begin x == Culong(1) end x::BigInt <= y::BigInt = begin cmp(x, y) <= 0 end x::BigInt <= i::Integer = begin cmp(x, i) <= 0 end i::Integer <= x::BigInt = begin cmp(x, i) >= 0 end x::BigInt <= f::CdoubleMax = begin if isnan(f) false else cmp(x, f) <= 0 end end f::CdoubleMax <= x::BigInt = begin if isnan(f) false else cmp(x, f) >= 0 end end x::BigInt < y::BigInt = begin cmp(x, y) < 0 end x::BigInt < i::Integer = begin cmp(x, i) < 0 end i::Integer < x::BigInt = begin cmp(x, i) > 0 end x::BigInt < f::CdoubleMax = begin if isnan(f) false else cmp(x, f) < 0 end end f::CdoubleMax < x::BigInt = begin if isnan(f) false else cmp(x, f) > 0 end end isnegative(x::BigInt) = begin x.size < 0 end ispositive(x::BigInt) = begin x.size > 0 end signbit(x::BigInt) = begin isnegative(x) end flipsign!(x::BigInt, y::Integer) = begin signbit(y) && (x.size = -(x.size)) x end flipsign(x::BigInt, y::Integer) = begin if signbit(y) -x else x end end flipsign(x::BigInt, y::BigInt) = begin if signbit(y) -x else x end end function sign(x::BigInt) isnegative(x) && return -(one(x)) ispositive(x) && return one(x) return x end show(io::IO, x::BigInt) = begin print(io, string(x)) end function string(n::BigInt; base::Integer = 10, pad::Integer = 1) base < 0 && return Base._base(Int(base), n, pad, (base > 0) & (n.size < 0)) 2 <= base <= 62 || throw(ArgumentError("base must be 2 ≤ base ≤ 62, got $(base)")) iszero(n) && (pad < 1 && return "") nd1 = ndigits(n, base = base) nd = max(nd1, pad) sv = Base.StringMemory(nd + isnegative(n)) GC.@preserve sv MPZ.get_str!((pointer(sv) + nd) - nd1, base, n) @inbounds for i = (1:nd - nd1) .+ isnegative(n) sv[i] = '0' % UInt8 end isnegative(n) && (sv[1] = '-' % UInt8) unsafe_takestring(sv) end function digits!(a::AbstractVector{T}, n::BigInt; base::Integer = 10) where T <: Integer if base ≥ 2 if base ≤ 62 s = codeunits(string(n; base)) (i, j) = (firstindex(a) - 1, length(s) + 1) lasti = min(lastindex(a), ((firstindex(a) + length(s)) - 1) - isnegative(n)) while i < lasti x = s[j -= 1] a[i += 1] = if base ≤ 36 if x > 0x39 x - 0x57 else x - 0x30 end else if x > 0x39 if x > 0x60 x - 0x3d else x - 0x37 end else x - 0x30 end end end lasti = lastindex(a) while i < lasti a[i += 1] = zero(T) end return if isnegative(n) map!(-, a, a) else a end elseif a isa StridedVector{<:Base.BitInteger} && (stride(a, 1) == 1 && (ispow2(base) && base - 1 ≤ typemax(T))) origlen = length(a) (_, writelen) = MPZ.export!(a, n; nails = 8 * sizeof(T) - trailing_zeros(base)) length(a) != origlen && resize!(a, origlen) a[var"begin" + writelen:var"end"] .= zero(T) return if isnegative(n) map!(-, a, a) else a end end end return invoke(digits!, Tuple{typeof(a), Integer}, a, n; base) end function ndigits0zpb(x::BigInt, b::Integer) b < 2 && throw(DomainError(b, "`b` cannot be less than 2.")) x.size == 0 && return 0 if ispow2(b) && 2 <= b <= 62 MPZ.sizeinbase(x, b) else n = MPZ.sizeinbase(x, 2) lb = log2(b) (q, r) = divrem(n, lb) iq = Int(q) maxerr = q * eps(lb) if r - 1.0 < maxerr if abs(x) >= big(b) ^ iq iq + 1 else iq end elseif lb - r < maxerr if abs(x) >= big(b) ^ (iq + 1) iq + 2 else iq + 1 end else iq + 1 end end end _prevpow2(x::BigInt) = begin if -2 <= x <= 2 x else flipsign!(ONE << (ndigits(x, base = 2) - 1), x) end end _nextpow2(x::BigInt) = begin if count_ones_abs(x) <= 1 x else flipsign!(ONE << ndigits(x, base = 2), x) end end Base.checked_abs(x::BigInt) = begin abs(x) end Base.checked_neg(x::BigInt) = begin -x end Base.checked_add(a::BigInt, b::BigInt) = begin a + b end Base.checked_sub(a::BigInt, b::BigInt) = begin a - b end Base.checked_mul(a::BigInt, b::BigInt) = begin a * b end Base.checked_div(a::BigInt, b::BigInt) = begin div(a, b) end Base.checked_rem(a::BigInt, b::BigInt) = begin rem(a, b) end Base.checked_fld(a::BigInt, b::BigInt) = begin fld(a, b) end Base.checked_mod(a::BigInt, b::BigInt) = begin mod(a, b) end Base.checked_cld(a::BigInt, b::BigInt) = begin cld(a, b) end Base.add_with_overflow(a::BigInt, b::BigInt) = begin (a + b, false) end Base.sub_with_overflow(a::BigInt, b::BigInt) = begin (a - b, false) end Base.mul_with_overflow(a::BigInt, b::BigInt) = begin (a * b, false) end Base.checked_pow(x::BigInt, p::Integer) = begin x ^ p end Base.checked_pow(x::Integer, p::BigInt) = begin x ^ p end Base.checked_pow(x::BigInt, p::BigInt) = begin x ^ p end Base.deepcopy_internal(x::BigInt, stackdict::IdDict) = begin get!((()->begin MPZ.set(x) end), stackdict, x)::BigInt end Base._hash_shl!(x::BigInt, n) = begin MPZ.mul_2exp!(x, n) end if Limb === UInt64 === UInt using .Base: HASH_SECRET, hash_bytes, hash_finalizer struct UnsafeLimbView <: AbstractVector{UInt8} bigint::BigInt start_byte::Int num_bytes::Int end function Base.size(view::UnsafeLimbView) return (view.num_bytes,) end function Base.getindex(view::UnsafeLimbView, i::Int) @boundscheck checkbounds(view, i) GC.@preserve view begin limb_index = div((view.start_byte + i) - 2, 8) + 1 byte_in_limb = ((view.start_byte + i) - 2) % 8 limb = unsafe_load(view.bigint.d, limb_index) return UInt8(limb >> (8byte_in_limb) & 0xff) end end function Base.iterate(view::UnsafeLimbView, state::Int = 1) state > view.num_bytes && return nothing return (@inbounds(view[state]), state + 1) end function Base.length(view::UnsafeLimbView) return view.num_bytes end function hash_integer(n::BigInt, h::UInt) iszero(n) && return hash_integer(0, h) s = n.size h ⊻= s < 0 us = abs(s) leading_zero_bytes = div(leading_zeros(unsafe_load(n.d, us)), 8) num_bytes = 8us - leading_zero_bytes limb_view = UnsafeLimbView(n, 1, num_bytes) return hash_bytes(limb_view, h, HASH_SECRET) end function hash(x::BigInt, h::UInt) GC.@preserve x begin sz = x.size sz == 0 && return hash(0, h) ptr = Ptr{UInt64}(x.d) if sz == 1 return hash(unsafe_load(ptr), h) elseif sz == -1 limb = unsafe_load(ptr) limb <= typemin(Int) % UInt && return hash(-(limb % Int), h) end pow = trailing_zeros(x) nd = Base.ndigits0z(x, 2) idx = pow >>> 6 + 1 shift = (pow & 63) % UInt upshift = BITS_PER_LIMB - shift asz = abs(sz) if shift == 0 limb = unsafe_load(ptr, idx) else limb1 = unsafe_load(ptr, idx) limb2 = if idx < asz unsafe_load(ptr, idx + 1) else UInt(0) end limb = limb2 << upshift | limb1 >> shift end if nd <= 1024 && nd - pow <= 53 return hash(ldexp(flipsign(Float64(limb), sz), pow), h) end h = hash_integer(pow, h) h ⊻= sz < 0 leading_zero_bytes = div(leading_zeros(unsafe_load(x.d, asz)), 8) trailing_zero_bytes = div(pow, 8) num_bytes = 8asz - (leading_zero_bytes + trailing_zero_bytes) limb_view = UnsafeLimbView(x, trailing_zero_bytes + 1, num_bytes) return hash_bytes(limb_view, h, HASH_SECRET) end end end module MPQ import .Base: unsafe_rational, __throw_rational_argerror_zero import ..GMP: BigInt, MPZ, Limb, libgmp gmpq(op::Symbol) = begin Expr(:tuple, QuoteNode(Symbol(:__gmpq_, op)), GlobalRef(MPZ, :libgmp)) end mutable struct _MPQ num_alloc::Cint num_size::Cint num_d::Ptr{Limb} den_alloc::Cint den_size::Cint den_d::Ptr{Limb} rat::Rational{BigInt} end const mpq_t = Ref{_MPQ} _MPQ(x::BigInt, y::BigInt) = begin _MPQ(x.alloc, x.size, x.d, y.alloc, y.size, y.d, unsafe_rational(BigInt, x, y)) end _MPQ() = begin _MPQ(BigInt(), BigInt()) end _MPQ(x::Rational{BigInt}) = begin _MPQ(x.num, x.den) end function sync_rational!(xq::_MPQ) xq.rat.num.alloc = xq.num_alloc xq.rat.num.size = xq.num_size xq.rat.num.d = xq.num_d xq.rat.den.alloc = xq.den_alloc xq.rat.den.size = xq.den_size xq.rat.den.d = xq.den_d return xq.rat end function Rational{BigInt}(num::BigInt, den::BigInt) if iszero(den) iszero(num) && __throw_rational_argerror_zero(BigInt) return set_si(flipsign(1, num), 0) end xq = _MPQ(MPZ.set(num), MPZ.set(den)) ccall((:__gmpq_canonicalize, libgmp), Cvoid, (mpq_t,), xq) return sync_rational!(xq) end function set!(z::Rational{BigInt}, x::Rational{BigInt}) zq = _MPQ(z) ccall((:__gmpq_set, libgmp), Cvoid, (mpq_t, mpq_t), zq, _MPQ(x)) return sync_rational!(zq) end function set_z!(z::Rational{BigInt}, x::BigInt) zq = _MPQ(z) ccall((:__gmpq_set_z, libgmp), Cvoid, (mpq_t, MPZ.mpz_t), zq, x) return sync_rational!(zq) end for (op, T) = ((:set, Rational{BigInt}), (:set_z, BigInt)) op! = Symbol(op, :!) @eval ($op)(a::$T) = begin ($op!)(unsafe_rational(BigInt(), BigInt()), a) end end for (op, T1, T2) = ((:set_ui, Culong, Culong), (:set_si, Clong, Culong)) op! = Symbol(op, :!) @eval begin function ($op!)(z::Rational{BigInt}, a, b) zq = _MPQ(z) ccall($(gmpq(op)), Cvoid, (mpq_t, $T1, $T2), zq, a, b) return sync_rational!(zq) end ($op)(a, b) = begin ($op!)(unsafe_rational(BigInt(), BigInt()), a, b) end end end function add!(z::Rational{BigInt}, x::Rational{BigInt}, y::Rational{BigInt}) if iszero(x.den) || iszero(y.den) if iszero(x.den) && (iszero(y.den) && isnegative(x.num) != isnegative(y.num)) throw(DivideError()) end return set!(z, if iszero(x.den) x else y end) end zq = _MPQ(z) ccall((:__gmpq_add, libgmp), Cvoid, (mpq_t, mpq_t, mpq_t), zq, _MPQ(x), _MPQ(y)) return sync_rational!(zq) end function sub!(z::Rational{BigInt}, x::Rational{BigInt}, y::Rational{BigInt}) if iszero(x.den) || iszero(y.den) if iszero(x.den) && (iszero(y.den) && isnegative(x.num) == isnegative(y.num)) throw(DivideError()) end iszero(x.den) && return set!(z, x) return set_si!(z, flipsign(-1, y.num), 0) end zq = _MPQ(z) ccall((:__gmpq_sub, libgmp), Cvoid, (mpq_t, mpq_t, mpq_t), zq, _MPQ(x), _MPQ(y)) return sync_rational!(zq) end function mul!(z::Rational{BigInt}, x::Rational{BigInt}, y::Rational{BigInt}) if iszero(x.den) || iszero(y.den) if iszero(x.num) || iszero(y.num) throw(DivideError()) end return set_si!(z, ifelse(xor(isnegative(x.num), isnegative(y.num)), -1, 1), 0) end zq = _MPQ(z) ccall((:__gmpq_mul, libgmp), Cvoid, (mpq_t, mpq_t, mpq_t), zq, _MPQ(x), _MPQ(y)) return sync_rational!(zq) end function div!(z::Rational{BigInt}, x::Rational{BigInt}, y::Rational{BigInt}) if iszero(x.den) if iszero(y.den) throw(DivideError()) end isnegative(y.num) || return set!(z, x) return set_si!(z, flipsign(-1, x.num), 0) elseif iszero(y.den) return set_si!(z, 0, 1) elseif iszero(y.num) if iszero(x.num) throw(DivideError()) end return set_si!(z, flipsign(1, x.num), 0) end zq = _MPQ(z) ccall((:__gmpq_div, libgmp), Cvoid, (mpq_t, mpq_t, mpq_t), zq, _MPQ(x), _MPQ(y)) return sync_rational!(zq) end for (fJ, fC) = ((:+, :add), (:-, :sub), (:*, :mul), (://, :div)) fC! = Symbol(fC, :!) @eval begin ($fC!)(x::Rational{BigInt}, y::Rational{BigInt}) = begin ($fC!)(x, x, y) end Base.:($fJ)(x::Rational{BigInt}, y::Rational{BigInt}) = begin ($fC!)(unsafe_rational(BigInt(), BigInt()), x, y) end end end function Base.cmp(x::Rational{BigInt}, y::Rational{BigInt}) Int(ccall((:__gmpq_cmp, libgmp), Cint, (mpq_t, mpq_t), _MPQ(x), _MPQ(y))) end end end begin export BigInt import .Base: *, +, -, /, <, <<, >>, >>>, <=, ==, >, >=, ^, ~, &, |, xor, nand, nor, binomial, cmp, convert, div, divrem, factorial, cld, fld, gcd, gcdx, lcm, mod, ndigits, promote_rule, rem, show, isqrt, string, powermod, sum, prod, trailing_zeros, trailing_ones, count_ones, count_zeros, tryparse_internal, bin, oct, dec, hex, isequal, invmod, _prevpow2, _nextpow2, ndigits0zpb, widen, signed, unsafe_trunc, trunc, iszero, isone, big, flipsign, signbit, sign, isodd, iseven, digits!, hash, hash_integer, top_set_bit, ispositive, isnegative, clamp, unsafe_takestring import Core: Signed, Float16, Float32, Float64 if Clong == Int32 const ClongMax = Union{Int8, Int16, Int32} const CulongMax = Union{UInt8, UInt16, UInt32} else const ClongMax = Union{Int8, Int16, Int32, Int64} const CulongMax = Union{UInt8, UInt16, UInt32, UInt64} end const CdoubleMax = Union{Float16, Float32, Float64} if Sys.iswindows() const libgmp = "libgmp-10.dll" elseif Sys.isapple() const libgmp = "@rpath/libgmp.10.dylib" else const libgmp = "libgmp.so.10" end _version() = begin unsafe_string(unsafe_load(cglobal((:__gmp_version, libgmp), Ptr{Cchar}))) end version() = begin VersionNumber(_version()) end major_version() = begin (_version())[1] end bits_per_limb() = begin Int(unsafe_load(cglobal((:__gmp_bits_per_limb, libgmp), Cint))) end const VERSION = version() const MAJOR_VERSION = major_version() const BITS_PER_LIMB = bits_per_limb() if BITS_PER_LIMB == 32 const Limb = UInt32 const SLimbMax = Union{Int8, Int16, Int32} const ULimbMax = Union{UInt8, UInt16, UInt32} elseif BITS_PER_LIMB == 64 const Limb = UInt64 const SLimbMax = Union{Int8, Int16, Int32, Int64} const ULimbMax = Union{UInt8, UInt16, UInt32, UInt64} else error("GMP: cannot determine the type mp_limb_t (__gmp_bits_per_limb == $(BITS_PER_LIMB))") end Core.@doc " BigInt <: Signed\n\nArbitrary precision integer type.\n" mutable struct BigInt <: Signed alloc::Cint size::Cint d::Ptr{Limb} function BigInt(; nbits::Integer = 0) b = MPZ.init2!(new(), nbits) finalizer(cglobal((:__gmpz_clear, libgmp)), b) return b end end Core.@doc " BigInt(x)\n\nCreate an arbitrary precision integer. `x` may be an `Int` (or anything that can be\nconverted to an `Int`). The usual mathematical operators are defined for this type, and\nresults are promoted to a [`BigInt`](@ref).\n\nInstances can be constructed from strings via [`parse`](@ref), or using the `big`\nstring literal.\n\n# Examples\n```jldoctest\njulia> parse(BigInt, \"42\")\n42\n\njulia> big\"313\"\n313\n\njulia> BigInt(10)^19\n10000000000000000000\n```\n" BigInt(x) Core.@doc " ALLOC_OVERFLOW_FUNCTION\n\nA reference that holds a boolean, if true, indicating julia is linked with a patched GMP that\ndoes not abort on huge allocation and throws OutOfMemoryError instead.\n" const ALLOC_OVERFLOW_FUNCTION = Ref(false) function __init__() try if major_version() != MAJOR_VERSION || bits_per_limb() != BITS_PER_LIMB msg = "The dynamically loaded GMP library (v\"$(version())\" with __gmp_bits_per_limb == $(bits_per_limb()))\ndoes not correspond to the compile time version (v\"$(VERSION)\" with __gmp_bits_per_limb == $(BITS_PER_LIMB)).\nPlease rebuild Julia." if bits_per_limb() != BITS_PER_LIMB @error msg else @warn msg end end ccall((:__gmp_set_memory_functions, libgmp), Cvoid, (Ptr{Cvoid}, Ptr{Cvoid}, Ptr{Cvoid}), cglobal(:jl_gc_counted_malloc), cglobal(:jl_gc_counted_realloc_with_old_size), cglobal(:jl_gc_counted_free_with_size)) (ZERO.alloc, ZERO.size, ZERO.d) = (0, 0, C_NULL) (ONE.alloc, ONE.size, ONE.d) = (1, 1, pointer(_ONE)) catch ex Base.showerror_nostdio(ex, "WARNING: Error during initialization of module GMP") end try ccall((:__gmp_set_alloc_overflow_function, libgmp), Cvoid, (Ptr{Cvoid},), cglobal(:jl_throw_out_of_memory_error)) ALLOC_OVERFLOW_FUNCTION[] = true catch ex if typeof(ex) != ErrorException rethrow() end end end module MPZ using ..GMP: BigInt, Limb, BITS_PER_LIMB, libgmp const mpz_t = Ref{BigInt} const bitcnt_t = Culong gmpz(op::Symbol) = begin Expr(:tuple, QuoteNode(Symbol(:__gmpz_, op)), GlobalRef(MPZ, :libgmp)) end init!(x::BigInt) = begin ccall((:__gmpz_init, libgmp), Cvoid, (mpz_t,), x) x end init2!(x::BigInt, a) = begin ccall((:__gmpz_init2, libgmp), Cvoid, (mpz_t, bitcnt_t), x, a) x end realloc2!(x, a) = begin ccall((:__gmpz_realloc2, libgmp), Cvoid, (mpz_t, bitcnt_t), x, a) x end realloc2(a) = begin realloc2!(BigInt(), a) end sizeinbase(a::BigInt, b) = begin Int(ccall((:__gmpz_sizeinbase, libgmp), Csize_t, (mpz_t, Cint), a, b)) end for (op, nbits) = (:add => :(BITS_PER_LIMB * (1 + max(abs(a.size), abs(b.size)))), :sub => :(BITS_PER_LIMB * (1 + max(abs(a.size), abs(b.size)))), :mul => 0, :fdiv_q => 0, :tdiv_q => 0, :cdiv_q => 0, :fdiv_r => 0, :tdiv_r => 0, :cdiv_r => 0, :gcd => 0, :lcm => 0, :and => 0, :ior => 0, :xor => 0) op! = Symbol(op, :!) @eval begin ($op!)(x::BigInt, a::BigInt, b::BigInt) = begin ccall($(gmpz(op)), Cvoid, (mpz_t, mpz_t, mpz_t), x, a, b) x end ($op)(a::BigInt, b::BigInt) = begin ($op!)(BigInt(nbits = $nbits), a, b) end ($op!)(x::BigInt, b::BigInt) = begin ($op!)(x, x, b) end end end invert!(x::BigInt, a::BigInt, b::BigInt) = begin ccall((:__gmpz_invert, libgmp), Cint, (mpz_t, mpz_t, mpz_t), x, a, b) end invert!(x::BigInt, b::BigInt) = begin invert!(x, x, b) end invert(a::BigInt, b::BigInt) = begin ret = BigInt() invert!(ret, a, b) ret end for op = (:add_ui, :sub_ui, :mul_ui, :mul_2exp, :fdiv_q_2exp, :pow_ui, :bin_ui) op! = Symbol(op, :!) @eval begin ($op!)(x::BigInt, a::BigInt, b) = begin ccall($(gmpz(op)), Cvoid, (mpz_t, mpz_t, Culong), x, a, b) x end ($op)(a::BigInt, b) = begin ($op!)(BigInt(), a, b) end ($op!)(x::BigInt, b) = begin ($op!)(x, x, b) end end end ui_sub!(x::BigInt, a, b::BigInt) = begin ccall((:__gmpz_ui_sub, libgmp), Cvoid, (mpz_t, Culong, mpz_t), x, a, b) x end ui_sub(a, b::BigInt) = begin ui_sub!(BigInt(), a, b) end for op = (:scan1, :scan0) @eval ($op)(a::BigInt, b) = begin Int(signed(ccall($(gmpz(op)), Culong, (mpz_t, Culong), a, b))) end end mul_si!(x::BigInt, a::BigInt, b) = begin ccall((:__gmpz_mul_si, libgmp), Cvoid, (mpz_t, mpz_t, Clong), x, a, b) x end mul_si(a::BigInt, b) = begin mul_si!(BigInt(), a, b) end mul_si!(x::BigInt, b) = begin mul_si!(x, x, b) end for op = (:neg, :com, :sqrt, :set) op! = Symbol(op, :!) @eval begin ($op!)(x::BigInt, a::BigInt) = begin ccall($(gmpz(op)), Cvoid, (mpz_t, mpz_t), x, a) x end ($op)(a::BigInt) = begin ($op!)(BigInt(), a) end end op === :set && continue @eval ($op!)(x::BigInt) = begin ($op!)(x, x) end end for (op, T) = ((:fac_ui, Culong), (:set_ui, Culong), (:set_si, Clong), (:set_d, Cdouble)) op! = Symbol(op, :!) @eval begin ($op!)(x::BigInt, a) = begin ccall($(gmpz(op)), Cvoid, (mpz_t, $T), x, a) x end ($op)(a) = begin ($op!)(BigInt(), a) end end end popcount(a::BigInt) = begin Int(signed(ccall((:__gmpz_popcount, libgmp), Culong, (mpz_t,), a))) end mpn_popcount(d::Ptr{Limb}, s::Integer) = begin Int(ccall((:__gmpn_popcount, libgmp), Culong, (Ptr{Limb}, Csize_t), d, s)) end mpn_popcount(a::BigInt) = begin mpn_popcount(a.d, abs(a.size)) end function tdiv_qr!(x::BigInt, y::BigInt, a::BigInt, b::BigInt) ccall((:__gmpz_tdiv_qr, libgmp), Cvoid, (mpz_t, mpz_t, mpz_t, mpz_t), x, y, a, b) (x, y) end tdiv_qr(a::BigInt, b::BigInt) = begin tdiv_qr!(BigInt(), BigInt(), a, b) end powm!(x::BigInt, a::BigInt, b::BigInt, c::BigInt) = begin ccall((:__gmpz_powm, libgmp), Cvoid, (mpz_t, mpz_t, mpz_t, mpz_t), x, a, b, c) x end powm(a::BigInt, b::BigInt, c::BigInt) = begin powm!(BigInt(), a, b, c) end powm!(x::BigInt, b::BigInt, c::BigInt) = begin powm!(x, x, b, c) end function gcdext!(x::BigInt, y::BigInt, z::BigInt, a::BigInt, b::BigInt) ccall((:__gmpz_gcdext, libgmp), Cvoid, (mpz_t, mpz_t, mpz_t, mpz_t, mpz_t), x, y, z, a, b) (x, y, z) end gcdext(a::BigInt, b::BigInt) = begin gcdext!(BigInt(), BigInt(), BigInt(), a, b) end cmp(a::BigInt, b::BigInt) = begin Int(ccall((:__gmpz_cmp, libgmp), Cint, (mpz_t, mpz_t), a, b)) end cmp_si(a::BigInt, b) = begin Int(ccall((:__gmpz_cmp_si, libgmp), Cint, (mpz_t, Clong), a, b)) end cmp_ui(a::BigInt, b) = begin Int(ccall((:__gmpz_cmp_ui, libgmp), Cint, (mpz_t, Culong), a, b)) end cmp_d(a::BigInt, b) = begin Int(ccall((:__gmpz_cmp_d, libgmp), Cint, (mpz_t, Cdouble), a, b)) end mpn_cmp(a::Ptr{Limb}, b::Ptr{Limb}, c) = begin ccall((:__gmpn_cmp, libgmp), Cint, (Ptr{Limb}, Ptr{Limb}, Clong), a, b, c) end mpn_cmp(a::BigInt, b::BigInt, c) = begin mpn_cmp(a.d, b.d, c) end get_str!(x, a, b::BigInt) = begin ccall((:__gmpz_get_str, libgmp), Ptr{Cchar}, (Ptr{Cchar}, Cint, mpz_t), x, a, b) x end set_str!(x::BigInt, a, b) = begin Int(ccall((:__gmpz_set_str, libgmp), Cint, (mpz_t, Ptr{UInt8}, Cint), x, a, b)) end get_d(a::BigInt) = begin ccall((:__gmpz_get_d, libgmp), Cdouble, (mpz_t,), a) end function export!(a::AbstractVector{T}, n::BigInt; order::Integer = -1, nails::Integer = 0, endian::Integer = 0) where T <: Base.BitInteger stride(a, 1) == 1 || throw(ArgumentError("a must have stride 1")) ndigits = cld(sizeinbase(n, 2), 8 * sizeof(T) - nails) length(a) < ndigits && resize!(a, ndigits) fill!(a, zero(T)) count = Ref{Csize_t}() ccall((:__gmpz_export, libgmp), Ptr{T}, (Ptr{T}, Ref{Csize_t}, Cint, Csize_t, Cint, Csize_t, mpz_t), a, count, order, sizeof(T), endian, nails, n) @assert count[] ≤ length(a) return (a, Int(count[])) end limbs_write!(x::BigInt, a) = begin ccall((:__gmpz_limbs_write, libgmp), Ptr{Limb}, (mpz_t, Clong), x, a) end limbs_finish!(x::BigInt, a) = begin ccall((:__gmpz_limbs_finish, libgmp), Cvoid, (mpz_t, Clong), x, a) end setbit!(x, a) = begin ccall((:__gmpz_setbit, libgmp), Cvoid, (mpz_t, bitcnt_t), x, a) x end tstbit(a::BigInt, b) = begin ccall((:__gmpz_tstbit, libgmp), Cint, (mpz_t, bitcnt_t), a, b) % Bool end end const ZERO = BigInt() const ONE = BigInt() const _ONE = Limb[1] widen(::Type{Int128}) = begin BigInt end widen(::Type{UInt128}) = begin BigInt end widen(::Type{BigInt}) = begin BigInt end signed(x::BigInt) = begin x end BigInt(x::BigInt) = begin x end Signed(x::BigInt) = begin x end function tryparse_internal(::Type{BigInt}, s::AbstractString, startpos::Int, endpos::Int, base_::Integer, raise::Bool) bstr = if startpos == firstindex(s) && endpos == lastindex(s) String(s) else String(SubString(s, startpos, endpos)) end (sgn, base, i) = Base.parseint_preamble(true, Int(base_), bstr, firstindex(bstr), lastindex(bstr)) if !(2 <= base <= 62) raise && throw(ArgumentError("invalid base: base must be 2 ≤ base ≤ 62, got $(base)")) return nothing end if i == 0 raise && throw(ArgumentError("premature end of integer: $(repr(bstr))")) return nothing end z = BigInt() if Base.containsnul(bstr) err = -1 else err = GC.@preserve(bstr, MPZ.set_str!(z, pointer(bstr) + (i - firstindex(bstr)), base)) end if err != 0 raise && throw(ArgumentError("invalid BigInt: $(repr(bstr))")) return nothing end flipsign!(z, sgn) end BigInt(x::Union{Clong, Int32}) = begin MPZ.set_si(x) end BigInt(x::Union{Culong, UInt32}) = begin MPZ.set_ui(x) end BigInt(x::Bool) = begin BigInt(UInt(x)) end unsafe_trunc(::Type{BigInt}, x::Union{Float16, Float32, Float64}) = begin MPZ.set_d(x) end function BigInt(x::Float64) isinteger(x) || throw(InexactError(:BigInt, BigInt, x)) unsafe_trunc(BigInt, x) end BigInt(x::Float16) = begin BigInt(Float64(x)) end BigInt(x::Float32) = begin BigInt(Float64(x)) end function BigInt(x::Integer) isbits(x) && (typemin(Clong) <= x <= typemax(Clong) && return BigInt((x % Clong)::Clong)) nd = ndigits(x, base = 2) z = MPZ.realloc2(nd) ux = unsigned(if x < 0 -x else x end) size = 0 limbnbits = sizeof(Limb) << 3 while nd > 0 size += 1 unsafe_store!(z.d, ux % Limb, size) ux >>= limbnbits nd -= limbnbits end z.size = if x < 0 -size else size end z end rem(x::BigInt, ::Type{Bool}) = begin (!(iszero(x)) & unsafe_load(x.d)) % Bool end (rem(x::BigInt, ::Type{T}) where T <: Union{SLimbMax, ULimbMax}) = begin if iszero(x) zero(T) else flipsign(unsafe_load(x.d) % T, x.size) end end function rem(x::BigInt, ::Type{T}) where T <: Union{Base.BitUnsigned, Base.BitSigned} u = zero(T) for l = 1:min(abs(x.size), cld(sizeof(T), sizeof(Limb))) u += (unsafe_load(x.d, l) % T) << (sizeof(Limb) << 3 * (l - 1)) end flipsign(u, x.size) end rem(x::Integer, ::Type{BigInt}) = begin BigInt(x) end clamp(x, ::Type{BigInt}) = begin convert(BigInt, x) end isodd(x::BigInt) = begin MPZ.tstbit(x, 0) end iseven(x::BigInt) = begin !(isodd(x)) end function (::Type{T})(x::BigInt) where T <: Base.BitUnsigned if sizeof(T) < sizeof(Limb) convert(T, convert(Limb, x)) else 0 <= x.size <= cld(sizeof(T), sizeof(Limb)) || throw(InexactError(nameof(T), T, x)) x % T end end function (::Type{T})(x::BigInt) where T <: Base.BitSigned n = abs(x.size) if sizeof(T) < sizeof(Limb) SLimb = typeof(Signed(one(Limb))) convert(T, convert(SLimb, x)) else 0 <= n <= cld(sizeof(T), sizeof(Limb)) || throw(InexactError(nameof(T), T, x)) y = x % T ispositive(x) ⊻ (y > 0) && throw(InexactError(nameof(T), T, x)) y end end Float64(n::BigInt, ::RoundingMode{:ToZero}) = begin MPZ.get_d(n) end function (::Type{T})(n::BigInt, ::RoundingMode{:ToZero}) where T <: Union{Float16, Float32} T(Float64(n, RoundToZero), RoundToZero) end function (::Type{T})(n::BigInt, ::RoundingMode{:Down}) where T <: CdoubleMax x = T(n, RoundToZero) if x > n prevfloat(x) else x end end function (::Type{T})(n::BigInt, ::RoundingMode{:Up}) where T <: CdoubleMax x = T(n, RoundToZero) if x < n nextfloat(x) else x end end function Float64(x::BigInt, ::RoundingMode{:Nearest}) x == 0 && return 0.0 xsize = abs(x.size) if xsize * BITS_PER_LIMB > 1024 z = Inf64 elseif xsize == 1 z = Float64(unsafe_load(x.d)) elseif Limb == UInt32 && xsize == 2 z = Float64((unsafe_load(x.d, 2) % UInt64) << BITS_PER_LIMB + unsafe_load(x.d)) else y1 = unsafe_load(x.d, xsize) % UInt64 n = top_set_bit(y1) y = y1 >> (n - (precision(Float64) + 1)) if Limb == UInt64 y += if n > precision(Float64) 0 else unsafe_load(x.d, xsize - 1) >> (10 + n) end else y += (unsafe_load(x.d, xsize - 1) % UInt64) >> (n - 22) y += if n > precision(Float64) - 32 0 else unsafe_load(x.d, xsize - 2) >> (10 + n) end end y = (y + 1) >> 1 y &= ~(UInt64(trailing_zeros(x) == (n - 54) + (xsize - 1) * BITS_PER_LIMB)) d = ((n + 1021) % UInt64) << 52 z = reinterpret(Float64, d + y) z = ldexp(z, (xsize - 1) * BITS_PER_LIMB) end return flipsign(z, x.size) end function Float32(x::BigInt, ::RoundingMode{:Nearest}) x == 0 && return 0.0f0 xsize = abs(x.size) if xsize * BITS_PER_LIMB > 128 z = Inf32 elseif xsize == 1 z = Float32(unsafe_load(x.d)) else y1 = unsafe_load(x.d, xsize) n = BITS_PER_LIMB - leading_zeros(y1) y = y1 >> (n - (precision(Float32) + 1)) % UInt32 y += if n > precision(Float32) 0 else unsafe_load(x.d, xsize - 1) >> (BITS_PER_LIMB - -25) end % UInt32 y = (y + one(UInt32)) >> 1 y &= ~(UInt32(trailing_zeros(x) == (n - 25) + (xsize - 1) * BITS_PER_LIMB)) d = ((n + 125) % UInt32) << 23 z = reinterpret(Float32, d + y) z = ldexp(z, (xsize - 1) * BITS_PER_LIMB) end return flipsign(z, x.size) end function Float16(x::BigInt, ::RoundingMode{:Nearest}) x == 0 && return Float16(0.0) y1 = unsafe_load(x.d) n = BITS_PER_LIMB - leading_zeros(y1) if n > 16 || abs(x.size) > 1 z = Inf16 else y = y1 >> (n - (precision(Float16) + 1)) % UInt16 y = (y + one(UInt16)) >> 1 y &= ~(UInt16(trailing_zeros(x) == n - 12)) d = ((n + 13) % UInt16) << 10 z = reinterpret(Float16, d + y) end return flipsign(z, x.size) end Float64(n::BigInt) = begin Float64(n, RoundNearest) end Float32(n::BigInt) = begin Float32(n, RoundNearest) end Float16(n::BigInt) = begin Float16(n, RoundNearest) end promote_rule(::Type{BigInt}, ::Type{<:Integer}) = begin BigInt end Core.@doc " big(x)\n\nConvert a number to a maximum precision representation (typically [`BigInt`](@ref) or\n`BigFloat`). See [`BigFloat`](@ref BigFloat(::Any, rounding::RoundingMode)) for\ninformation about some pitfalls with floating-point numbers.\n" function big end big(::Type{<:Integer}) = begin BigInt end big(::Type{<:Rational}) = begin Rational{BigInt} end big(n::Integer) = begin convert(BigInt, n) end for (fJ, fC) = ((:+, :add), (:-, :sub), (:*, :mul), (:mod, :fdiv_r), (:rem, :tdiv_r), (:gcd, :gcd), (:lcm, :lcm), (:&, :and), (:|, :ior), (:xor, :xor)) @eval begin ($fJ)(x::BigInt, y::BigInt) = begin MPZ.:($fC)(x, y) end end end for (r, f) = ((RoundToZero, :tdiv_q), (RoundDown, :fdiv_q), (RoundUp, :cdiv_q)) @eval div(x::BigInt, y::BigInt, ::typeof($r)) = begin MPZ.:($f)(x, y) end end div(x::BigInt, y::BigInt) = begin div(x, y, RoundToZero) end fld(x::BigInt, y::BigInt) = begin div(x, y, RoundDown) end cld(x::BigInt, y::BigInt) = begin div(x, y, RoundUp) end x::BigInt / y::BigInt = begin float(x) / float(y) end function invmod(x::BigInt, y::BigInt) z = zero(BigInt) ya = abs(y) if ya == 1 return z end if y == 0 || MPZ.invert!(z, x, ya) == 0 throw(DomainError(y)) end if y < 0 MPZ.add!(z, y) end return z end for (fJ, fC) = ((:+, :add), (:*, :mul), (:&, :and), (:|, :ior), (:xor, :xor)) fC! = Symbol(fC, :!) @eval begin ($fJ)(a::BigInt, b::BigInt, c::BigInt) = begin MPZ.:($fC!)(MPZ.:($fC)(a, b), c) end ($fJ)(a::BigInt, b::BigInt, c::BigInt, d::BigInt) = begin MPZ.:($fC!)(MPZ.:($fC!)(MPZ.:($fC)(a, b), c), d) end ($fJ)(a::BigInt, b::BigInt, c::BigInt, d::BigInt, e::BigInt) = begin MPZ.:($fC!)(MPZ.:($fC!)(MPZ.:($fC!)(MPZ.:($fC)(a, b), c), d), e) end end end x::BigInt + c::CulongMax = begin MPZ.add_ui(x, c) end c::CulongMax + x::BigInt = begin x + c end x::BigInt - c::CulongMax = begin MPZ.sub_ui(x, c) end c::CulongMax - x::BigInt = begin MPZ.ui_sub(c, x) end x::BigInt + c::ClongMax = begin if c < 0 x - -(c % Culong) else x + convert(Culong, c) end end c::ClongMax + x::BigInt = begin if c < 0 x - -(c % Culong) else x + convert(Culong, c) end end x::BigInt - c::ClongMax = begin if c < 0 x + -(c % Culong) else x - convert(Culong, c) end end c::ClongMax - x::BigInt = begin if c < 0 -((x + -(c % Culong))) else convert(Culong, c) - x end end x::BigInt * c::CulongMax = begin MPZ.mul_ui(x, c) end c::CulongMax * x::BigInt = begin x * c end x::BigInt * c::ClongMax = begin MPZ.mul_si(x, c) end c::ClongMax * x::BigInt = begin x * c end x::BigInt / y::Union{ClongMax, CulongMax} = begin float(x) / y end x::Union{ClongMax, CulongMax} / y::BigInt = begin x / float(y) end -(x::BigInt) = begin MPZ.neg(x) end ~(x::BigInt) = begin MPZ.com(x) end x::BigInt << c::UInt = begin if c == 0 x else MPZ.mul_2exp(x, c) end end x::BigInt >> c::UInt = begin if c == 0 x else MPZ.fdiv_q_2exp(x, c) end end x::BigInt >>> c::UInt = begin x >> c end function trailing_zeros(x::BigInt) c = MPZ.scan1(x, 0) c == -1 && throw(DomainError(x, "`x` must be non-zero")) c end function trailing_ones(x::BigInt) c = MPZ.scan0(x, 0) c == -1 && throw(DomainError(x, "`x` must not be equal to -1")) c end function count_ones(x::BigInt) c = MPZ.popcount(x) c == -1 && throw(DomainError(x, "`x` cannot be negative")) c end function count_zeros(x::BigInt) c = MPZ.popcount(~x) c == -1 && throw(DomainError(x, "`x` must be negative")) c end Core.@doc " count_ones_abs(x::BigInt)\n\nNumber of ones in the binary representation of abs(x).\n" count_ones_abs(x::BigInt) = begin if iszero(x) 0 else MPZ.mpn_popcount(x) end end _bit_magnitude(x::BigInt) = begin x.size * sizeof(Limb) << 3 - leading_zeros(GC.@preserve(x, unsafe_load(x.d, x.size))) end function exponent(x::BigInt) iszero(x) && throw(DomainError(x, "cannot be zero")) ux = abs(x) return _bit_magnitude(ux) - 1 end function top_set_bit(x::BigInt) isnegative(x) && throw(DomainError(x, "top_set_bit only supports negative arguments when they have type BitSigned.")) iszero(x) && return 0 return _bit_magnitude(x) end divrem(x::BigInt, y::BigInt, ::typeof(RoundToZero) = RoundToZero) = begin MPZ.tdiv_qr(x, y) end divrem(x::BigInt, y::Integer, ::typeof(RoundToZero) = RoundToZero) = begin MPZ.tdiv_qr(x, BigInt(y)) end cmp(x::BigInt, y::BigInt) = begin sign(MPZ.cmp(x, y)) end cmp(x::BigInt, y::ClongMax) = begin sign(MPZ.cmp_si(x, y)) end cmp(x::BigInt, y::CulongMax) = begin sign(MPZ.cmp_ui(x, y)) end cmp(x::BigInt, y::Integer) = begin cmp(x, big(y)) end cmp(x::Integer, y::BigInt) = begin -(cmp(y, x)) end cmp(x::BigInt, y::CdoubleMax) = begin if isnan(y) -1 else sign(MPZ.cmp_d(x, y)) end end cmp(x::CdoubleMax, y::BigInt) = begin -(cmp(y, x)) end isqrt(x::BigInt) = begin MPZ.sqrt(x) end x::BigInt ^ y::Culong = begin MPZ.pow_ui(x, y) end function bigint_pow(x::BigInt, y::Integer) x == 1 && return x x == -1 && return if isodd(y) x else -x end if y < 0 throw(DomainError(y, "`y` cannot be negative.")) end @noinline throw1(y) = begin throw(OverflowError("exponent $(y) is too large and computation will overflow")) end if y > typemax(Culong) x == 0 && return x throw1(y) end return x ^ convert(Culong, y) end x::BigInt ^ y::BigInt = begin bigint_pow(x, y) end x::BigInt ^ y::Bool = begin if y x else one(x) end end x::BigInt ^ y::Integer = begin bigint_pow(x, y) end x::Integer ^ y::BigInt = begin bigint_pow(BigInt(x), y) end x::Bool ^ y::BigInt = begin Base.power_by_squaring(x, y) end function powermod(x::BigInt, p::BigInt, m::BigInt) r = MPZ.powm(x, p, m) return if m < 0 && r > 0 MPZ.add!(r, m) else r end end powermod(x::Integer, p::Integer, m::BigInt) = begin powermod(big(x), big(p), m) end function gcdx(a::BigInt, b::BigInt) (g, s, t) = MPZ.gcdext(a, b) if t == 0 if a == b return (g, t, s) elseif abs(a) == abs(b) return (g, t, -s) end end (g, s, t) end +(x::BigInt, y::BigInt, rest::BigInt...) = begin sum(tuple(x, y, rest...)) end sum(arr::Union{AbstractArray{BigInt}, Tuple{BigInt, Vararg{BigInt}}}) = begin foldl(MPZ.add!, arr; init = BigInt(0)) end function prod(arr::AbstractArray{BigInt}) any(iszero, arr) && return zero(BigInt) _prod(arr, firstindex(arr), lastindex(arr)) end function _prod(arr::AbstractArray{BigInt}, lo, hi) if (hi - lo) + 1 <= 16 nlimbs = 0 for i = lo:hi nlimbs += abs((arr[i]).size) end init = BigInt(; nbits = nlimbs * BITS_PER_LIMB) MPZ.set_si!(init, 1) for i = lo:hi MPZ.mul!(init, arr[i]) end init else mid = (lo + hi) ÷ 2 MPZ.mul!(_prod(arr, lo, mid), _prod(arr, mid + 1, hi)) end end factorial(n::BigInt) = begin if !(isnegative(n)) MPZ.fac_ui(n) else throw(DomainError(n, "`n` must not be negative.")) end end function binomial(n::BigInt, k::Integer) k < 0 && return BigInt(0) k <= typemax(Culong) && return binomial(n, Culong(k)) n < 0 && return if isodd(k) -(binomial((k - n) - 1, k)) else binomial((k - n) - 1, k) end κ = n - k κ < 0 && return BigInt(0) κ <= typemax(Culong) && return binomial(n, Culong(κ)) throw(OverflowError("Computation would exceed memory")) end binomial(n::BigInt, k::Culong) = begin MPZ.bin_ui(n, k) end x::BigInt == y::BigInt = begin cmp(x, y) == 0 end x::BigInt == i::Integer = begin cmp(x, i) == 0 end i::Integer == x::BigInt = begin cmp(x, i) == 0 end x::BigInt == f::CdoubleMax = begin if isnan(f) false else cmp(x, f) == 0 end end f::CdoubleMax == x::BigInt = begin if isnan(f) false else cmp(x, f) == 0 end end iszero(x::BigInt) = begin x.size == 0 end isone(x::BigInt) = begin x == Culong(1) end x::BigInt <= y::BigInt = begin cmp(x, y) <= 0 end x::BigInt <= i::Integer = begin cmp(x, i) <= 0 end i::Integer <= x::BigInt = begin cmp(x, i) >= 0 end x::BigInt <= f::CdoubleMax = begin if isnan(f) false else cmp(x, f) <= 0 end end f::CdoubleMax <= x::BigInt = begin if isnan(f) false else cmp(x, f) >= 0 end end x::BigInt < y::BigInt = begin cmp(x, y) < 0 end x::BigInt < i::Integer = begin cmp(x, i) < 0 end i::Integer < x::BigInt = begin cmp(x, i) > 0 end x::BigInt < f::CdoubleMax = begin if isnan(f) false else cmp(x, f) < 0 end end f::CdoubleMax < x::BigInt = begin if isnan(f) false else cmp(x, f) > 0 end end isnegative(x::BigInt) = begin x.size < 0 end ispositive(x::BigInt) = begin x.size > 0 end signbit(x::BigInt) = begin isnegative(x) end flipsign!(x::BigInt, y::Integer) = begin signbit(y) && (x.size = -(x.size)) x end flipsign(x::BigInt, y::Integer) = begin if signbit(y) -x else x end end flipsign(x::BigInt, y::BigInt) = begin if signbit(y) -x else x end end function sign(x::BigInt) isnegative(x) && return -(one(x)) ispositive(x) && return one(x) return x end show(io::IO, x::BigInt) = begin print(io, string(x)) end function string(n::BigInt; base::Integer = 10, pad::Integer = 1) base < 0 && return Base._base(Int(base), n, pad, (base > 0) & (n.size < 0)) 2 <= base <= 62 || throw(ArgumentError("base must be 2 ≤ base ≤ 62, got $(base)")) iszero(n) && (pad < 1 && return "") nd1 = ndigits(n, base = base) nd = max(nd1, pad) sv = Base.StringMemory(nd + isnegative(n)) GC.@preserve sv MPZ.get_str!((pointer(sv) + nd) - nd1, base, n) @inbounds for i = (1:nd - nd1) .+ isnegative(n) sv[i] = '0' % UInt8 end isnegative(n) && (sv[1] = '-' % UInt8) unsafe_takestring(sv) end function digits!(a::AbstractVector{T}, n::BigInt; base::Integer = 10) where T <: Integer if base ≥ 2 if base ≤ 62 s = codeunits(string(n; base)) (i, j) = (firstindex(a) - 1, length(s) + 1) lasti = min(lastindex(a), ((firstindex(a) + length(s)) - 1) - isnegative(n)) while i < lasti x = s[j -= 1] a[i += 1] = if base ≤ 36 if x > 0x39 x - 0x57 else x - 0x30 end else if x > 0x39 if x > 0x60 x - 0x3d else x - 0x37 end else x - 0x30 end end end lasti = lastindex(a) while i < lasti a[i += 1] = zero(T) end return if isnegative(n) map!(-, a, a) else a end elseif a isa StridedVector{<:Base.BitInteger} && (stride(a, 1) == 1 && (ispow2(base) && base - 1 ≤ typemax(T))) origlen = length(a) (_, writelen) = MPZ.export!(a, n; nails = 8 * sizeof(T) - trailing_zeros(base)) length(a) != origlen && resize!(a, origlen) a[var"begin" + writelen:var"end"] .= zero(T) return if isnegative(n) map!(-, a, a) else a end end end return invoke(digits!, Tuple{typeof(a), Integer}, a, n; base) end function ndigits0zpb(x::BigInt, b::Integer) b < 2 && throw(DomainError(b, "`b` cannot be less than 2.")) x.size == 0 && return 0 if ispow2(b) && 2 <= b <= 62 MPZ.sizeinbase(x, b) else n = MPZ.sizeinbase(x, 2) lb = log2(b) (q, r) = divrem(n, lb) iq = Int(q) maxerr = q * eps(lb) if r - 1.0 < maxerr if abs(x) >= big(b) ^ iq iq + 1 else iq end elseif lb - r < maxerr if abs(x) >= big(b) ^ (iq + 1) iq + 2 else iq + 1 end else iq + 1 end end end _prevpow2(x::BigInt) = begin if -2 <= x <= 2 x else flipsign!(ONE << (ndigits(x, base = 2) - 1), x) end end _nextpow2(x::BigInt) = begin if count_ones_abs(x) <= 1 x else flipsign!(ONE << ndigits(x, base = 2), x) end end Base.checked_abs(x::BigInt) = begin abs(x) end Base.checked_neg(x::BigInt) = begin -x end Base.checked_add(a::BigInt, b::BigInt) = begin a + b end Base.checked_sub(a::BigInt, b::BigInt) = begin a - b end Base.checked_mul(a::BigInt, b::BigInt) = begin a * b end Base.checked_div(a::BigInt, b::BigInt) = begin div(a, b) end Base.checked_rem(a::BigInt, b::BigInt) = begin rem(a, b) end Base.checked_fld(a::BigInt, b::BigInt) = begin fld(a, b) end Base.checked_mod(a::BigInt, b::BigInt) = begin mod(a, b) end Base.checked_cld(a::BigInt, b::BigInt) = begin cld(a, b) end Base.add_with_overflow(a::BigInt, b::BigInt) = begin (a + b, false) end Base.sub_with_overflow(a::BigInt, b::BigInt) = begin (a - b, false) end Base.mul_with_overflow(a::BigInt, b::BigInt) = begin (a * b, false) end Base.checked_pow(x::BigInt, p::Integer) = begin x ^ p end Base.checked_pow(x::Integer, p::BigInt) = begin x ^ p end Base.checked_pow(x::BigInt, p::BigInt) = begin x ^ p end Base.deepcopy_internal(x::BigInt, stackdict::IdDict) = begin get!((()->begin MPZ.set(x) end), stackdict, x)::BigInt end Base._hash_shl!(x::BigInt, n) = begin MPZ.mul_2exp!(x, n) end if Limb === UInt64 === UInt using .Base: HASH_SECRET, hash_bytes, hash_finalizer struct UnsafeLimbView <: AbstractVector{UInt8} bigint::BigInt start_byte::Int num_bytes::Int end function Base.size(view::UnsafeLimbView) return (view.num_bytes,) end function Base.getindex(view::UnsafeLimbView, i::Int) @boundscheck checkbounds(view, i) GC.@preserve view begin limb_index = div((view.start_byte + i) - 2, 8) + 1 byte_in_limb = ((view.start_byte + i) - 2) % 8 limb = unsafe_load(view.bigint.d, limb_index) return UInt8(limb >> (8byte_in_limb) & 0xff) end end function Base.iterate(view::UnsafeLimbView, state::Int = 1) state > view.num_bytes && return nothing return (@inbounds(view[state]), state + 1) end function Base.length(view::UnsafeLimbView) return view.num_bytes end function hash_integer(n::BigInt, h::UInt) iszero(n) && return hash_integer(0, h) s = n.size h ⊻= s < 0 us = abs(s) leading_zero_bytes = div(leading_zeros(unsafe_load(n.d, us)), 8) num_bytes = 8us - leading_zero_bytes limb_view = UnsafeLimbView(n, 1, num_bytes) return hash_bytes(limb_view, h, HASH_SECRET) end function hash(x::BigInt, h::UInt) GC.@preserve x begin sz = x.size sz == 0 && return hash(0, h) ptr = Ptr{UInt64}(x.d) if sz == 1 return hash(unsafe_load(ptr), h) elseif sz == -1 limb = unsafe_load(ptr) limb <= typemin(Int) % UInt && return hash(-(limb % Int), h) end pow = trailing_zeros(x) nd = Base.ndigits0z(x, 2) idx = pow >>> 6 + 1 shift = (pow & 63) % UInt upshift = BITS_PER_LIMB - shift asz = abs(sz) if shift == 0 limb = unsafe_load(ptr, idx) else limb1 = unsafe_load(ptr, idx) limb2 = if idx < asz unsafe_load(ptr, idx + 1) else UInt(0) end limb = limb2 << upshift | limb1 >> shift end if nd <= 1024 && nd - pow <= 53 return hash(ldexp(flipsign(Float64(limb), sz), pow), h) end h = hash_integer(pow, h) h ⊻= sz < 0 leading_zero_bytes = div(leading_zeros(unsafe_load(x.d, asz)), 8) trailing_zero_bytes = div(pow, 8) num_bytes = 8asz - (leading_zero_bytes + trailing_zero_bytes) limb_view = UnsafeLimbView(x, trailing_zero_bytes + 1, num_bytes) return hash_bytes(limb_view, h, HASH_SECRET) end end end module MPQ import .Base: unsafe_rational, __throw_rational_argerror_zero import ..GMP: BigInt, MPZ, Limb, libgmp gmpq(op::Symbol) = begin Expr(:tuple, QuoteNode(Symbol(:__gmpq_, op)), GlobalRef(MPZ, :libgmp)) end mutable struct _MPQ num_alloc::Cint num_size::Cint num_d::Ptr{Limb} den_alloc::Cint den_size::Cint den_d::Ptr{Limb} rat::Rational{BigInt} end const mpq_t = Ref{_MPQ} _MPQ(x::BigInt, y::BigInt) = begin _MPQ(x.alloc, x.size, x.d, y.alloc, y.size, y.d, unsafe_rational(BigInt, x, y)) end _MPQ() = begin _MPQ(BigInt(), BigInt()) end _MPQ(x::Rational{BigInt}) = begin _MPQ(x.num, x.den) end function sync_rational!(xq::_MPQ) xq.rat.num.alloc = xq.num_alloc xq.rat.num.size = xq.num_size xq.rat.num.d = xq.num_d xq.rat.den.alloc = xq.den_alloc xq.rat.den.size = xq.den_size xq.rat.den.d = xq.den_d return xq.rat end function Rational{BigInt}(num::BigInt, den::BigInt) if iszero(den) iszero(num) && __throw_rational_argerror_zero(BigInt) return set_si(flipsign(1, num), 0) end xq = _MPQ(MPZ.set(num), MPZ.set(den)) ccall((:__gmpq_canonicalize, libgmp), Cvoid, (mpq_t,), xq) return sync_rational!(xq) end function set!(z::Rational{BigInt}, x::Rational{BigInt}) zq = _MPQ(z) ccall((:__gmpq_set, libgmp), Cvoid, (mpq_t, mpq_t), zq, _MPQ(x)) return sync_rational!(zq) end function set_z!(z::Rational{BigInt}, x::BigInt) zq = _MPQ(z) ccall((:__gmpq_set_z, libgmp), Cvoid, (mpq_t, MPZ.mpz_t), zq, x) return sync_rational!(zq) end for (op, T) = ((:set, Rational{BigInt}), (:set_z, BigInt)) op! = Symbol(op, :!) @eval ($op)(a::$T) = begin ($op!)(unsafe_rational(BigInt(), BigInt()), a) end end for (op, T1, T2) = ((:set_ui, Culong, Culong), (:set_si, Clong, Culong)) op! = Symbol(op, :!) @eval begin function ($op!)(z::Rational{BigInt}, a, b) zq = _MPQ(z) ccall($(gmpq(op)), Cvoid, (mpq_t, $T1, $T2), zq, a, b) return sync_rational!(zq) end ($op)(a, b) = begin ($op!)(unsafe_rational(BigInt(), BigInt()), a, b) end end end function add!(z::Rational{BigInt}, x::Rational{BigInt}, y::Rational{BigInt}) if iszero(x.den) || iszero(y.den) if iszero(x.den) && (iszero(y.den) && isnegative(x.num) != isnegative(y.num)) throw(DivideError()) end return set!(z, if iszero(x.den) x else y end) end zq = _MPQ(z) ccall((:__gmpq_add, libgmp), Cvoid, (mpq_t, mpq_t, mpq_t), zq, _MPQ(x), _MPQ(y)) return sync_rational!(zq) end function sub!(z::Rational{BigInt}, x::Rational{BigInt}, y::Rational{BigInt}) if iszero(x.den) || iszero(y.den) if iszero(x.den) && (iszero(y.den) && isnegative(x.num) == isnegative(y.num)) throw(DivideError()) end iszero(x.den) && return set!(z, x) return set_si!(z, flipsign(-1, y.num), 0) end zq = _MPQ(z) ccall((:__gmpq_sub, libgmp), Cvoid, (mpq_t, mpq_t, mpq_t), zq, _MPQ(x), _MPQ(y)) return sync_rational!(zq) end function mul!(z::Rational{BigInt}, x::Rational{BigInt}, y::Rational{BigInt}) if iszero(x.den) || iszero(y.den) if iszero(x.num) || iszero(y.num) throw(DivideError()) end return set_si!(z, ifelse(xor(isnegative(x.num), isnegative(y.num)), -1, 1), 0) end zq = _MPQ(z) ccall((:__gmpq_mul, libgmp), Cvoid, (mpq_t, mpq_t, mpq_t), zq, _MPQ(x), _MPQ(y)) return sync_rational!(zq) end function div!(z::Rational{BigInt}, x::Rational{BigInt}, y::Rational{BigInt}) if iszero(x.den) if iszero(y.den) throw(DivideError()) end isnegative(y.num) || return set!(z, x) return set_si!(z, flipsign(-1, x.num), 0) elseif iszero(y.den) return set_si!(z, 0, 1) elseif iszero(y.num) if iszero(x.num) throw(DivideError()) end return set_si!(z, flipsign(1, x.num), 0) end zq = _MPQ(z) ccall((:__gmpq_div, libgmp), Cvoid, (mpq_t, mpq_t, mpq_t), zq, _MPQ(x), _MPQ(y)) return sync_rational!(zq) end for (fJ, fC) = ((:+, :add), (:-, :sub), (:*, :mul), (://, :div)) fC! = Symbol(fC, :!) @eval begin ($fC!)(x::Rational{BigInt}, y::Rational{BigInt}) = begin ($fC!)(x, x, y) end Base.:($fJ)(x::Rational{BigInt}, y::Rational{BigInt}) = begin ($fC!)(unsafe_rational(BigInt(), BigInt()), x, y) end end end function Base.cmp(x::Rational{BigInt}, y::Rational{BigInt}) Int(ccall((:__gmpq_cmp, libgmp), Cint, (mpq_t, mpq_t), _MPQ(x), _MPQ(y))) end end end module GMP export BigInt import .Base: *, +, -, /, <, <<, >>, >>>, <=, ==, >, >=, ^, ~, &, |, xor, nand, nor, binomial, cmp, convert, div, divrem, factorial, cld, fld, gcd, gcdx, lcm, mod, ndigits, promote_rule, rem, show, isqrt, string, powermod, sum, prod, trailing_zeros, trailing_ones, count_ones, count_zeros, tryparse_internal, bin, oct, dec, hex, isequal, invmod, _prevpow2, _nextpow2, ndigits0zpb, widen, signed, unsafe_trunc, trunc, iszero, isone, big, flipsign, signbit, sign, isodd, iseven, digits!, hash, hash_integer, top_set_bit, ispositive, isnegative, clamp, unsafe_takestring import Core: Signed, Float16, Float32, Float64 if Clong == Int32 const ClongMax = Union{Int8, Int16, Int32} const CulongMax = Union{UInt8, UInt16, UInt32} else const ClongMax = Union{Int8, Int16, Int32, Int64} const CulongMax = Union{UInt8, UInt16, UInt32, UInt64} end const CdoubleMax = Union{Float16, Float32, Float64} if Sys.iswindows() const libgmp = "libgmp-10.dll" elseif Sys.isapple() const libgmp = "@rpath/libgmp.10.dylib" else const libgmp = "libgmp.so.10" end _version() = begin unsafe_string(unsafe_load(cglobal((:__gmp_version, libgmp), Ptr{Cchar}))) end version() = begin VersionNumber(_version()) end major_version() = begin (_version())[1] end bits_per_limb() = begin Int(unsafe_load(cglobal((:__gmp_bits_per_limb, libgmp), Cint))) end const VERSION = version() const MAJOR_VERSION = major_version() const BITS_PER_LIMB = bits_per_limb() if BITS_PER_LIMB == 32 const Limb = UInt32 const SLimbMax = Union{Int8, Int16, Int32} const ULimbMax = Union{UInt8, UInt16, UInt32} elseif BITS_PER_LIMB == 64 const Limb = UInt64 const SLimbMax = Union{Int8, Int16, Int32, Int64} const ULimbMax = Union{UInt8, UInt16, UInt32, UInt64} else error("GMP: cannot determine the type mp_limb_t (__gmp_bits_per_limb == $(BITS_PER_LIMB))") end Core.@doc " BigInt <: Signed\n\nArbitrary precision integer type.\n" mutable struct BigInt <: Signed alloc::Cint size::Cint d::Ptr{Limb} function BigInt(; nbits::Integer = 0) b = MPZ.init2!(new(), nbits) finalizer(cglobal((:__gmpz_clear, libgmp)), b) return b end end Core.@doc " BigInt(x)\n\nCreate an arbitrary precision integer. `x` may be an `Int` (or anything that can be\nconverted to an `Int`). The usual mathematical operators are defined for this type, and\nresults are promoted to a [`BigInt`](@ref).\n\nInstances can be constructed from strings via [`parse`](@ref), or using the `big`\nstring literal.\n\n# Examples\n```jldoctest\njulia> parse(BigInt, \"42\")\n42\n\njulia> big\"313\"\n313\n\njulia> BigInt(10)^19\n10000000000000000000\n```\n" BigInt(x) Core.@doc " ALLOC_OVERFLOW_FUNCTION\n\nA reference that holds a boolean, if true, indicating julia is linked with a patched GMP that\ndoes not abort on huge allocation and throws OutOfMemoryError instead.\n" const ALLOC_OVERFLOW_FUNCTION = Ref(false) function __init__() try if major_version() != MAJOR_VERSION || bits_per_limb() != BITS_PER_LIMB msg = "The dynamically loaded GMP library (v\"$(version())\" with __gmp_bits_per_limb == $(bits_per_limb()))\ndoes not correspond to the compile time version (v\"$(VERSION)\" with __gmp_bits_per_limb == $(BITS_PER_LIMB)).\nPlease rebuild Julia." if bits_per_limb() != BITS_PER_LIMB @error msg else @warn msg end end ccall((:__gmp_set_memory_functions, libgmp), Cvoid, (Ptr{Cvoid}, Ptr{Cvoid}, Ptr{Cvoid}), cglobal(:jl_gc_counted_malloc), cglobal(:jl_gc_counted_realloc_with_old_size), cglobal(:jl_gc_counted_free_with_size)) (ZERO.alloc, ZERO.size, ZERO.d) = (0, 0, C_NULL) (ONE.alloc, ONE.size, ONE.d) = (1, 1, pointer(_ONE)) catch ex Base.showerror_nostdio(ex, "WARNING: Error during initialization of module GMP") end try ccall((:__gmp_set_alloc_overflow_function, libgmp), Cvoid, (Ptr{Cvoid},), cglobal(:jl_throw_out_of_memory_error)) ALLOC_OVERFLOW_FUNCTION[] = true catch ex if typeof(ex) != ErrorException rethrow() end end end module MPZ using ..GMP: BigInt, Limb, BITS_PER_LIMB, libgmp const mpz_t = Ref{BigInt} const bitcnt_t = Culong gmpz(op::Symbol) = begin Expr(:tuple, QuoteNode(Symbol(:__gmpz_, op)), GlobalRef(MPZ, :libgmp)) end init!(x::BigInt) = begin ccall((:__gmpz_init, libgmp), Cvoid, (mpz_t,), x) x end init2!(x::BigInt, a) = begin ccall((:__gmpz_init2, libgmp), Cvoid, (mpz_t, bitcnt_t), x, a) x end realloc2!(x, a) = begin ccall((:__gmpz_realloc2, libgmp), Cvoid, (mpz_t, bitcnt_t), x, a) x end realloc2(a) = begin realloc2!(BigInt(), a) end sizeinbase(a::BigInt, b) = begin Int(ccall((:__gmpz_sizeinbase, libgmp), Csize_t, (mpz_t, Cint), a, b)) end for (op, nbits) = (:add => :(BITS_PER_LIMB * (1 + max(abs(a.size), abs(b.size)))), :sub => :(BITS_PER_LIMB * (1 + max(abs(a.size), abs(b.size)))), :mul => 0, :fdiv_q => 0, :tdiv_q => 0, :cdiv_q => 0, :fdiv_r => 0, :tdiv_r => 0, :cdiv_r => 0, :gcd => 0, :lcm => 0, :and => 0, :ior => 0, :xor => 0) op! = Symbol(op, :!) @eval begin ($op!)(x::BigInt, a::BigInt, b::BigInt) = begin ccall($(gmpz(op)), Cvoid, (mpz_t, mpz_t, mpz_t), x, a, b) x end ($op)(a::BigInt, b::BigInt) = begin ($op!)(BigInt(nbits = $nbits), a, b) end ($op!)(x::BigInt, b::BigInt) = begin ($op!)(x, x, b) end end end invert!(x::BigInt, a::BigInt, b::BigInt) = begin ccall((:__gmpz_invert, libgmp), Cint, (mpz_t, mpz_t, mpz_t), x, a, b) end invert!(x::BigInt, b::BigInt) = begin invert!(x, x, b) end invert(a::BigInt, b::BigInt) = begin ret = BigInt() invert!(ret, a, b) ret end for op = (:add_ui, :sub_ui, :mul_ui, :mul_2exp, :fdiv_q_2exp, :pow_ui, :bin_ui) op! = Symbol(op, :!) @eval begin ($op!)(x::BigInt, a::BigInt, b) = begin ccall($(gmpz(op)), Cvoid, (mpz_t, mpz_t, Culong), x, a, b) x end ($op)(a::BigInt, b) = begin ($op!)(BigInt(), a, b) end ($op!)(x::BigInt, b) = begin ($op!)(x, x, b) end end end ui_sub!(x::BigInt, a, b::BigInt) = begin ccall((:__gmpz_ui_sub, libgmp), Cvoid, (mpz_t, Culong, mpz_t), x, a, b) x end ui_sub(a, b::BigInt) = begin ui_sub!(BigInt(), a, b) end for op = (:scan1, :scan0) @eval ($op)(a::BigInt, b) = begin Int(signed(ccall($(gmpz(op)), Culong, (mpz_t, Culong), a, b))) end end mul_si!(x::BigInt, a::BigInt, b) = begin ccall((:__gmpz_mul_si, libgmp), Cvoid, (mpz_t, mpz_t, Clong), x, a, b) x end mul_si(a::BigInt, b) = begin mul_si!(BigInt(), a, b) end mul_si!(x::BigInt, b) = begin mul_si!(x, x, b) end for op = (:neg, :com, :sqrt, :set) op! = Symbol(op, :!) @eval begin ($op!)(x::BigInt, a::BigInt) = begin ccall($(gmpz(op)), Cvoid, (mpz_t, mpz_t), x, a) x end ($op)(a::BigInt) = begin ($op!)(BigInt(), a) end end op === :set && continue @eval ($op!)(x::BigInt) = begin ($op!)(x, x) end end for (op, T) = ((:fac_ui, Culong), (:set_ui, Culong), (:set_si, Clong), (:set_d, Cdouble)) op! = Symbol(op, :!) @eval begin ($op!)(x::BigInt, a) = begin ccall($(gmpz(op)), Cvoid, (mpz_t, $T), x, a) x end ($op)(a) = begin ($op!)(BigInt(), a) end end end popcount(a::BigInt) = begin Int(signed(ccall((:__gmpz_popcount, libgmp), Culong, (mpz_t,), a))) end mpn_popcount(d::Ptr{Limb}, s::Integer) = begin Int(ccall((:__gmpn_popcount, libgmp), Culong, (Ptr{Limb}, Csize_t), d, s)) end mpn_popcount(a::BigInt) = begin mpn_popcount(a.d, abs(a.size)) end function tdiv_qr!(x::BigInt, y::BigInt, a::BigInt, b::BigInt) ccall((:__gmpz_tdiv_qr, libgmp), Cvoid, (mpz_t, mpz_t, mpz_t, mpz_t), x, y, a, b) (x, y) end tdiv_qr(a::BigInt, b::BigInt) = begin tdiv_qr!(BigInt(), BigInt(), a, b) end powm!(x::BigInt, a::BigInt, b::BigInt, c::BigInt) = begin ccall((:__gmpz_powm, libgmp), Cvoid, (mpz_t, mpz_t, mpz_t, mpz_t), x, a, b, c) x end powm(a::BigInt, b::BigInt, c::BigInt) = begin powm!(BigInt(), a, b, c) end powm!(x::BigInt, b::BigInt, c::BigInt) = begin powm!(x, x, b, c) end function gcdext!(x::BigInt, y::BigInt, z::BigInt, a::BigInt, b::BigInt) ccall((:__gmpz_gcdext, libgmp), Cvoid, (mpz_t, mpz_t, mpz_t, mpz_t, mpz_t), x, y, z, a, b) (x, y, z) end gcdext(a::BigInt, b::BigInt) = begin gcdext!(BigInt(), BigInt(), BigInt(), a, b) end cmp(a::BigInt, b::BigInt) = begin Int(ccall((:__gmpz_cmp, libgmp), Cint, (mpz_t, mpz_t), a, b)) end cmp_si(a::BigInt, b) = begin Int(ccall((:__gmpz_cmp_si, libgmp), Cint, (mpz_t, Clong), a, b)) end cmp_ui(a::BigInt, b) = begin Int(ccall((:__gmpz_cmp_ui, libgmp), Cint, (mpz_t, Culong), a, b)) end cmp_d(a::BigInt, b) = begin Int(ccall((:__gmpz_cmp_d, libgmp), Cint, (mpz_t, Cdouble), a, b)) end mpn_cmp(a::Ptr{Limb}, b::Ptr{Limb}, c) = begin ccall((:__gmpn_cmp, libgmp), Cint, (Ptr{Limb}, Ptr{Limb}, Clong), a, b, c) end mpn_cmp(a::BigInt, b::BigInt, c) = begin mpn_cmp(a.d, b.d, c) end get_str!(x, a, b::BigInt) = begin ccall((:__gmpz_get_str, libgmp), Ptr{Cchar}, (Ptr{Cchar}, Cint, mpz_t), x, a, b) x end set_str!(x::BigInt, a, b) = begin Int(ccall((:__gmpz_set_str, libgmp), Cint, (mpz_t, Ptr{UInt8}, Cint), x, a, b)) end get_d(a::BigInt) = begin ccall((:__gmpz_get_d, libgmp), Cdouble, (mpz_t,), a) end function export!(a::AbstractVector{T}, n::BigInt; order::Integer = -1, nails::Integer = 0, endian::Integer = 0) where T <: Base.BitInteger stride(a, 1) == 1 || throw(ArgumentError("a must have stride 1")) ndigits = cld(sizeinbase(n, 2), 8 * sizeof(T) - nails) length(a) < ndigits && resize!(a, ndigits) fill!(a, zero(T)) count = Ref{Csize_t}() ccall((:__gmpz_export, libgmp), Ptr{T}, (Ptr{T}, Ref{Csize_t}, Cint, Csize_t, Cint, Csize_t, mpz_t), a, count, order, sizeof(T), endian, nails, n) @assert count[] ≤ length(a) return (a, Int(count[])) end limbs_write!(x::BigInt, a) = begin ccall((:__gmpz_limbs_write, libgmp), Ptr{Limb}, (mpz_t, Clong), x, a) end limbs_finish!(x::BigInt, a) = begin ccall((:__gmpz_limbs_finish, libgmp), Cvoid, (mpz_t, Clong), x, a) end setbit!(x, a) = begin ccall((:__gmpz_setbit, libgmp), Cvoid, (mpz_t, bitcnt_t), x, a) x end tstbit(a::BigInt, b) = begin ccall((:__gmpz_tstbit, libgmp), Cint, (mpz_t, bitcnt_t), a, b) % Bool end end const ZERO = BigInt() const ONE = BigInt() const _ONE = Limb[1] widen(::Type{Int128}) = begin BigInt end widen(::Type{UInt128}) = begin BigInt end widen(::Type{BigInt}) = begin BigInt end signed(x::BigInt) = begin x end BigInt(x::BigInt) = begin x end Signed(x::BigInt) = begin x end function tryparse_internal(::Type{BigInt}, s::AbstractString, startpos::Int, endpos::Int, base_::Integer, raise::Bool) bstr = if startpos == firstindex(s) && endpos == lastindex(s) String(s) else String(SubString(s, startpos, endpos)) end (sgn, base, i) = Base.parseint_preamble(true, Int(base_), bstr, firstindex(bstr), lastindex(bstr)) if !(2 <= base <= 62) raise && throw(ArgumentError("invalid base: base must be 2 ≤ base ≤ 62, got $(base)")) return nothing end if i == 0 raise && throw(ArgumentError("premature end of integer: $(repr(bstr))")) return nothing end z = BigInt() if Base.containsnul(bstr) err = -1 else err = GC.@preserve(bstr, MPZ.set_str!(z, pointer(bstr) + (i - firstindex(bstr)), base)) end if err != 0 raise && throw(ArgumentError("invalid BigInt: $(repr(bstr))")) return nothing end flipsign!(z, sgn) end BigInt(x::Union{Clong, Int32}) = begin MPZ.set_si(x) end BigInt(x::Union{Culong, UInt32}) = begin MPZ.set_ui(x) end BigInt(x::Bool) = begin BigInt(UInt(x)) end unsafe_trunc(::Type{BigInt}, x::Union{Float16, Float32, Float64}) = begin MPZ.set_d(x) end function BigInt(x::Float64) isinteger(x) || throw(InexactError(:BigInt, BigInt, x)) unsafe_trunc(BigInt, x) end BigInt(x::Float16) = begin BigInt(Float64(x)) end BigInt(x::Float32) = begin BigInt(Float64(x)) end function BigInt(x::Integer) isbits(x) && (typemin(Clong) <= x <= typemax(Clong) && return BigInt((x % Clong)::Clong)) nd = ndigits(x, base = 2) z = MPZ.realloc2(nd) ux = unsigned(if x < 0 -x else x end) size = 0 limbnbits = sizeof(Limb) << 3 while nd > 0 size += 1 unsafe_store!(z.d, ux % Limb, size) ux >>= limbnbits nd -= limbnbits end z.size = if x < 0 -size else size end z end rem(x::BigInt, ::Type{Bool}) = begin (!(iszero(x)) & unsafe_load(x.d)) % Bool end (rem(x::BigInt, ::Type{T}) where T <: Union{SLimbMax, ULimbMax}) = begin if iszero(x) zero(T) else flipsign(unsafe_load(x.d) % T, x.size) end end function rem(x::BigInt, ::Type{T}) where T <: Union{Base.BitUnsigned, Base.BitSigned} u = zero(T) for l = 1:min(abs(x.size), cld(sizeof(T), sizeof(Limb))) u += (unsafe_load(x.d, l) % T) << (sizeof(Limb) << 3 * (l - 1)) end flipsign(u, x.size) end rem(x::Integer, ::Type{BigInt}) = begin BigInt(x) end clamp(x, ::Type{BigInt}) = begin convert(BigInt, x) end isodd(x::BigInt) = begin MPZ.tstbit(x, 0) end iseven(x::BigInt) = begin !(isodd(x)) end function (::Type{T})(x::BigInt) where T <: Base.BitUnsigned if sizeof(T) < sizeof(Limb) convert(T, convert(Limb, x)) else 0 <= x.size <= cld(sizeof(T), sizeof(Limb)) || throw(InexactError(nameof(T), T, x)) x % T end end function (::Type{T})(x::BigInt) where T <: Base.BitSigned n = abs(x.size) if sizeof(T) < sizeof(Limb) SLimb = typeof(Signed(one(Limb))) convert(T, convert(SLimb, x)) else 0 <= n <= cld(sizeof(T), sizeof(Limb)) || throw(InexactError(nameof(T), T, x)) y = x % T ispositive(x) ⊻ (y > 0) && throw(InexactError(nameof(T), T, x)) y end end Float64(n::BigInt, ::RoundingMode{:ToZero}) = begin MPZ.get_d(n) end function (::Type{T})(n::BigInt, ::RoundingMode{:ToZero}) where T <: Union{Float16, Float32} T(Float64(n, RoundToZero), RoundToZero) end function (::Type{T})(n::BigInt, ::RoundingMode{:Down}) where T <: CdoubleMax x = T(n, RoundToZero) if x > n prevfloat(x) else x end end function (::Type{T})(n::BigInt, ::RoundingMode{:Up}) where T <: CdoubleMax x = T(n, RoundToZero) if x < n nextfloat(x) else x end end function Float64(x::BigInt, ::RoundingMode{:Nearest}) x == 0 && return 0.0 xsize = abs(x.size) if xsize * BITS_PER_LIMB > 1024 z = Inf64 elseif xsize == 1 z = Float64(unsafe_load(x.d)) elseif Limb == UInt32 && xsize == 2 z = Float64((unsafe_load(x.d, 2) % UInt64) << BITS_PER_LIMB + unsafe_load(x.d)) else y1 = unsafe_load(x.d, xsize) % UInt64 n = top_set_bit(y1) y = y1 >> (n - (precision(Float64) + 1)) if Limb == UInt64 y += if n > precision(Float64) 0 else unsafe_load(x.d, xsize - 1) >> (10 + n) end else y += (unsafe_load(x.d, xsize - 1) % UInt64) >> (n - 22) y += if n > precision(Float64) - 32 0 else unsafe_load(x.d, xsize - 2) >> (10 + n) end end y = (y + 1) >> 1 y &= ~(UInt64(trailing_zeros(x) == (n - 54) + (xsize - 1) * BITS_PER_LIMB)) d = ((n + 1021) % UInt64) << 52 z = reinterpret(Float64, d + y) z = ldexp(z, (xsize - 1) * BITS_PER_LIMB) end return flipsign(z, x.size) end function Float32(x::BigInt, ::RoundingMode{:Nearest}) x == 0 && return 0.0f0 xsize = abs(x.size) if xsize * BITS_PER_LIMB > 128 z = Inf32 elseif xsize == 1 z = Float32(unsafe_load(x.d)) else y1 = unsafe_load(x.d, xsize) n = BITS_PER_LIMB - leading_zeros(y1) y = y1 >> (n - (precision(Float32) + 1)) % UInt32 y += if n > precision(Float32) 0 else unsafe_load(x.d, xsize - 1) >> (BITS_PER_LIMB - -25) end % UInt32 y = (y + one(UInt32)) >> 1 y &= ~(UInt32(trailing_zeros(x) == (n - 25) + (xsize - 1) * BITS_PER_LIMB)) d = ((n + 125) % UInt32) << 23 z = reinterpret(Float32, d + y) z = ldexp(z, (xsize - 1) * BITS_PER_LIMB) end return flipsign(z, x.size) end function Float16(x::BigInt, ::RoundingMode{:Nearest}) x == 0 && return Float16(0.0) y1 = unsafe_load(x.d) n = BITS_PER_LIMB - leading_zeros(y1) if n > 16 || abs(x.size) > 1 z = Inf16 else y = y1 >> (n - (precision(Float16) + 1)) % UInt16 y = (y + one(UInt16)) >> 1 y &= ~(UInt16(trailing_zeros(x) == n - 12)) d = ((n + 13) % UInt16) << 10 z = reinterpret(Float16, d + y) end return flipsign(z, x.size) end Float64(n::BigInt) = begin Float64(n, RoundNearest) end Float32(n::BigInt) = begin Float32(n, RoundNearest) end Float16(n::BigInt) = begin Float16(n, RoundNearest) end promote_rule(::Type{BigInt}, ::Type{<:Integer}) = begin BigInt end Core.@doc " big(x)\n\nConvert a number to a maximum precision representation (typically [`BigInt`](@ref) or\n`BigFloat`). See [`BigFloat`](@ref BigFloat(::Any, rounding::RoundingMode)) for\ninformation about some pitfalls with floating-point numbers.\n" function big end big(::Type{<:Integer}) = begin BigInt end big(::Type{<:Rational}) = begin Rational{BigInt} end big(n::Integer) = begin convert(BigInt, n) end for (fJ, fC) = ((:+, :add), (:-, :sub), (:*, :mul), (:mod, :fdiv_r), (:rem, :tdiv_r), (:gcd, :gcd), (:lcm, :lcm), (:&, :and), (:|, :ior), (:xor, :xor)) @eval begin ($fJ)(x::BigInt, y::BigInt) = begin MPZ.:($fC)(x, y) end end end for (r, f) = ((RoundToZero, :tdiv_q), (RoundDown, :fdiv_q), (RoundUp, :cdiv_q)) @eval div(x::BigInt, y::BigInt, ::typeof($r)) = begin MPZ.:($f)(x, y) end end div(x::BigInt, y::BigInt) = begin div(x, y, RoundToZero) end fld(x::BigInt, y::BigInt) = begin div(x, y, RoundDown) end cld(x::BigInt, y::BigInt) = begin div(x, y, RoundUp) end x::BigInt / y::BigInt = begin float(x) / float(y) end function invmod(x::BigInt, y::BigInt) z = zero(BigInt) ya = abs(y) if ya == 1 return z end if y == 0 || MPZ.invert!(z, x, ya) == 0 throw(DomainError(y)) end if y < 0 MPZ.add!(z, y) end return z end for (fJ, fC) = ((:+, :add), (:*, :mul), (:&, :and), (:|, :ior), (:xor, :xor)) fC! = Symbol(fC, :!) @eval begin ($fJ)(a::BigInt, b::BigInt, c::BigInt) = begin MPZ.:($fC!)(MPZ.:($fC)(a, b), c) end ($fJ)(a::BigInt, b::BigInt, c::BigInt, d::BigInt) = begin MPZ.:($fC!)(MPZ.:($fC!)(MPZ.:($fC)(a, b), c), d) end ($fJ)(a::BigInt, b::BigInt, c::BigInt, d::BigInt, e::BigInt) = begin MPZ.:($fC!)(MPZ.:($fC!)(MPZ.:($fC!)(MPZ.:($fC)(a, b), c), d), e) end end end x::BigInt + c::CulongMax = begin MPZ.add_ui(x, c) end c::CulongMax + x::BigInt = begin x + c end x::BigInt - c::CulongMax = begin MPZ.sub_ui(x, c) end c::CulongMax - x::BigInt = begin MPZ.ui_sub(c, x) end x::BigInt + c::ClongMax = begin if c < 0 x - -(c % Culong) else x + convert(Culong, c) end end c::ClongMax + x::BigInt = begin if c < 0 x - -(c % Culong) else x + convert(Culong, c) end end x::BigInt - c::ClongMax = begin if c < 0 x + -(c % Culong) else x - convert(Culong, c) end end c::ClongMax - x::BigInt = begin if c < 0 -((x + -(c % Culong))) else convert(Culong, c) - x end end x::BigInt * c::CulongMax = begin MPZ.mul_ui(x, c) end c::CulongMax * x::BigInt = begin x * c end x::BigInt * c::ClongMax = begin MPZ.mul_si(x, c) end c::ClongMax * x::BigInt = begin x * c end x::BigInt / y::Union{ClongMax, CulongMax} = begin float(x) / y end x::Union{ClongMax, CulongMax} / y::BigInt = begin x / float(y) end -(x::BigInt) = begin MPZ.neg(x) end ~(x::BigInt) = begin MPZ.com(x) end x::BigInt << c::UInt = begin if c == 0 x else MPZ.mul_2exp(x, c) end end x::BigInt >> c::UInt = begin if c == 0 x else MPZ.fdiv_q_2exp(x, c) end end x::BigInt >>> c::UInt = begin x >> c end function trailing_zeros(x::BigInt) c = MPZ.scan1(x, 0) c == -1 && throw(DomainError(x, "`x` must be non-zero")) c end function trailing_ones(x::BigInt) c = MPZ.scan0(x, 0) c == -1 && throw(DomainError(x, "`x` must not be equal to -1")) c end function count_ones(x::BigInt) c = MPZ.popcount(x) c == -1 && throw(DomainError(x, "`x` cannot be negative")) c end function count_zeros(x::BigInt) c = MPZ.popcount(~x) c == -1 && throw(DomainError(x, "`x` must be negative")) c end Core.@doc " count_ones_abs(x::BigInt)\n\nNumber of ones in the binary representation of abs(x).\n" count_ones_abs(x::BigInt) = begin if iszero(x) 0 else MPZ.mpn_popcount(x) end end _bit_magnitude(x::BigInt) = begin x.size * sizeof(Limb) << 3 - leading_zeros(GC.@preserve(x, unsafe_load(x.d, x.size))) end function exponent(x::BigInt) iszero(x) && throw(DomainError(x, "cannot be zero")) ux = abs(x) return _bit_magnitude(ux) - 1 end function top_set_bit(x::BigInt) isnegative(x) && throw(DomainError(x, "top_set_bit only supports negative arguments when they have type BitSigned.")) iszero(x) && return 0 return _bit_magnitude(x) end divrem(x::BigInt, y::BigInt, ::typeof(RoundToZero) = begin RoundToZero end) = begin MPZ.tdiv_qr(x, y) end divrem(x::BigInt, y::Integer, ::typeof(RoundToZero) = begin RoundToZero end) = begin MPZ.tdiv_qr(x, BigInt(y)) end cmp(x::BigInt, y::BigInt) = begin sign(MPZ.cmp(x, y)) end cmp(x::BigInt, y::ClongMax) = begin sign(MPZ.cmp_si(x, y)) end cmp(x::BigInt, y::CulongMax) = begin sign(MPZ.cmp_ui(x, y)) end cmp(x::BigInt, y::Integer) = begin cmp(x, big(y)) end cmp(x::Integer, y::BigInt) = begin -(cmp(y, x)) end cmp(x::BigInt, y::CdoubleMax) = begin if isnan(y) -1 else sign(MPZ.cmp_d(x, y)) end end cmp(x::CdoubleMax, y::BigInt) = begin -(cmp(y, x)) end isqrt(x::BigInt) = begin MPZ.sqrt(x) end x::BigInt ^ y::Culong = begin MPZ.pow_ui(x, y) end function bigint_pow(x::BigInt, y::Integer) x == 1 && return x x == -1 && return if isodd(y) x else -x end if y < 0 throw(DomainError(y, "`y` cannot be negative.")) end @noinline throw1(y) = begin throw(OverflowError("exponent $(y) is too large and computation will overflow")) end if y > typemax(Culong) x == 0 && return x throw1(y) end return x ^ convert(Culong, y) end x::BigInt ^ y::BigInt = begin bigint_pow(x, y) end x::BigInt ^ y::Bool = begin if y x else one(x) end end x::BigInt ^ y::Integer = begin bigint_pow(x, y) end x::Integer ^ y::BigInt = begin bigint_pow(BigInt(x), y) end x::Bool ^ y::BigInt = begin Base.power_by_squaring(x, y) end function powermod(x::BigInt, p::BigInt, m::BigInt) r = MPZ.powm(x, p, m) return if m < 0 && r > 0 MPZ.add!(r, m) else r end end powermod(x::Integer, p::Integer, m::BigInt) = begin powermod(big(x), big(p), m) end function gcdx(a::BigInt, b::BigInt) (g, s, t) = MPZ.gcdext(a, b) if t == 0 if a == b return (g, t, s) elseif abs(a) == abs(b) return (g, t, -s) end end (g, s, t) end +(x::BigInt, y::BigInt, rest::BigInt...) = begin sum(tuple(x, y, rest...)) end sum(arr::Union{AbstractArray{BigInt}, Tuple{BigInt, Vararg{BigInt}}}) = begin foldl(MPZ.add!, arr; init = BigInt(0)) end function prod(arr::AbstractArray{BigInt}) any(iszero, arr) && return zero(BigInt) _prod(arr, firstindex(arr), lastindex(arr)) end function _prod(arr::AbstractArray{BigInt}, lo, hi) if (hi - lo) + 1 <= 16 nlimbs = 0 for i = lo:hi nlimbs += abs((arr[i]).size) end init = BigInt(; nbits = nlimbs * BITS_PER_LIMB) MPZ.set_si!(init, 1) for i = lo:hi MPZ.mul!(init, arr[i]) end init else mid = (lo + hi) ÷ 2 MPZ.mul!(_prod(arr, lo, mid), _prod(arr, mid + 1, hi)) end end factorial(n::BigInt) = begin if !(isnegative(n)) MPZ.fac_ui(n) else throw(DomainError(n, "`n` must not be negative.")) end end function binomial(n::BigInt, k::Integer) k < 0 && return BigInt(0) k <= typemax(Culong) && return binomial(n, Culong(k)) n < 0 && return if isodd(k) -(binomial((k - n) - 1, k)) else binomial((k - n) - 1, k) end κ = n - k κ < 0 && return BigInt(0) κ <= typemax(Culong) && return binomial(n, Culong(κ)) throw(OverflowError("Computation would exceed memory")) end binomial(n::BigInt, k::Culong) = begin MPZ.bin_ui(n, k) end x::BigInt == y::BigInt = begin cmp(x, y) == 0 end x::BigInt == i::Integer = begin cmp(x, i) == 0 end i::Integer == x::BigInt = begin cmp(x, i) == 0 end x::BigInt == f::CdoubleMax = begin if isnan(f) false else cmp(x, f) == 0 end end f::CdoubleMax == x::BigInt = begin if isnan(f) false else cmp(x, f) == 0 end end iszero(x::BigInt) = begin x.size == 0 end isone(x::BigInt) = begin x == Culong(1) end x::BigInt <= y::BigInt = begin cmp(x, y) <= 0 end x::BigInt <= i::Integer = begin cmp(x, i) <= 0 end i::Integer <= x::BigInt = begin cmp(x, i) >= 0 end x::BigInt <= f::CdoubleMax = begin if isnan(f) false else cmp(x, f) <= 0 end end f::CdoubleMax <= x::BigInt = begin if isnan(f) false else cmp(x, f) >= 0 end end x::BigInt < y::BigInt = begin cmp(x, y) < 0 end x::BigInt < i::Integer = begin cmp(x, i) < 0 end i::Integer < x::BigInt = begin cmp(x, i) > 0 end x::BigInt < f::CdoubleMax = begin if isnan(f) false else cmp(x, f) < 0 end end f::CdoubleMax < x::BigInt = begin if isnan(f) false else cmp(x, f) > 0 end end isnegative(x::BigInt) = begin x.size < 0 end ispositive(x::BigInt) = begin x.size > 0 end signbit(x::BigInt) = begin isnegative(x) end flipsign!(x::BigInt, y::Integer) = begin signbit(y) && (x.size = -(x.size)) x end flipsign(x::BigInt, y::Integer) = begin if signbit(y) -x else x end end flipsign(x::BigInt, y::BigInt) = begin if signbit(y) -x else x end end function sign(x::BigInt) isnegative(x) && return -(one(x)) ispositive(x) && return one(x) return x end show(io::IO, x::BigInt) = begin print(io, string(x)) end function string(n::BigInt; base::Integer = 10, pad::Integer = 1) base < 0 && return Base._base(Int(base), n, pad, (base > 0) & (n.size < 0)) 2 <= base <= 62 || throw(ArgumentError("base must be 2 ≤ base ≤ 62, got $(base)")) iszero(n) && (pad < 1 && return "") nd1 = ndigits(n, base = base) nd = max(nd1, pad) sv = Base.StringMemory(nd + isnegative(n)) GC.@preserve sv MPZ.get_str!((pointer(sv) + nd) - nd1, base, n) @inbounds for i = (1:nd - nd1) .+ isnegative(n) sv[i] = '0' % UInt8 end isnegative(n) && (sv[1] = '-' % UInt8) unsafe_takestring(sv) end function digits!(a::AbstractVector{T}, n::BigInt; base::Integer = 10) where T <: Integer if base ≥ 2 if base ≤ 62 s = codeunits(string(n; base)) (i, j) = (firstindex(a) - 1, length(s) + 1) lasti = min(lastindex(a), ((firstindex(a) + length(s)) - 1) - isnegative(n)) while i < lasti x = s[j -= 1] a[i += 1] = if base ≤ 36 if x > 0x39 x - 0x57 else x - 0x30 end else if x > 0x39 if x > 0x60 x - 0x3d else x - 0x37 end else x - 0x30 end end end lasti = lastindex(a) while i < lasti a[i += 1] = zero(T) end return if isnegative(n) map!(-, a, a) else a end elseif a isa StridedVector{<:Base.BitInteger} && (stride(a, 1) == 1 && (ispow2(base) && base - 1 ≤ typemax(T))) origlen = length(a) (_, writelen) = MPZ.export!(a, n; nails = 8 * sizeof(T) - trailing_zeros(base)) length(a) != origlen && resize!(a, origlen) a[var"begin" + writelen:var"end"] .= zero(T) return if isnegative(n) map!(-, a, a) else a end end end return invoke(digits!, Tuple{typeof(a), Integer}, a, n; base) end function ndigits0zpb(x::BigInt, b::Integer) b < 2 && throw(DomainError(b, "`b` cannot be less than 2.")) x.size == 0 && return 0 if ispow2(b) && 2 <= b <= 62 MPZ.sizeinbase(x, b) else n = MPZ.sizeinbase(x, 2) lb = log2(b) (q, r) = divrem(n, lb) iq = Int(q) maxerr = q * eps(lb) if r - 1.0 < maxerr if abs(x) >= big(b) ^ iq iq + 1 else iq end elseif lb - r < maxerr if abs(x) >= big(b) ^ (iq + 1) iq + 2 else iq + 1 end else iq + 1 end end end _prevpow2(x::BigInt) = begin if -2 <= x <= 2 x else flipsign!(ONE << (ndigits(x, base = 2) - 1), x) end end _nextpow2(x::BigInt) = begin if count_ones_abs(x) <= 1 x else flipsign!(ONE << ndigits(x, base = 2), x) end end Base.checked_abs(x::BigInt) = begin abs(x) end Base.checked_neg(x::BigInt) = begin -x end Base.checked_add(a::BigInt, b::BigInt) = begin a + b end Base.checked_sub(a::BigInt, b::BigInt) = begin a - b end Base.checked_mul(a::BigInt, b::BigInt) = begin a * b end Base.checked_div(a::BigInt, b::BigInt) = begin div(a, b) end Base.checked_rem(a::BigInt, b::BigInt) = begin rem(a, b) end Base.checked_fld(a::BigInt, b::BigInt) = begin fld(a, b) end Base.checked_mod(a::BigInt, b::BigInt) = begin mod(a, b) end Base.checked_cld(a::BigInt, b::BigInt) = begin cld(a, b) end Base.add_with_overflow(a::BigInt, b::BigInt) = begin (a + b, false) end Base.sub_with_overflow(a::BigInt, b::BigInt) = begin (a - b, false) end Base.mul_with_overflow(a::BigInt, b::BigInt) = begin (a * b, false) end Base.checked_pow(x::BigInt, p::Integer) = begin x ^ p end Base.checked_pow(x::Integer, p::BigInt) = begin x ^ p end Base.checked_pow(x::BigInt, p::BigInt) = begin x ^ p end Base.deepcopy_internal(x::BigInt, stackdict::IdDict) = begin get!((()->begin MPZ.set(x) end), stackdict, x)::BigInt end Base._hash_shl!(x::BigInt, n) = begin MPZ.mul_2exp!(x, n) end if Limb === UInt64 === UInt using .Base: HASH_SECRET, hash_bytes, hash_finalizer struct UnsafeLimbView <: AbstractVector{UInt8} bigint::BigInt start_byte::Int num_bytes::Int end function Base.size(view::UnsafeLimbView) return (view.num_bytes,) end function Base.getindex(view::UnsafeLimbView, i::Int) @boundscheck checkbounds(view, i) GC.@preserve view begin limb_index = div((view.start_byte + i) - 2, 8) + 1 byte_in_limb = ((view.start_byte + i) - 2) % 8 limb = unsafe_load(view.bigint.d, limb_index) return UInt8(limb >> (8byte_in_limb) & 0xff) end end function Base.iterate(view::UnsafeLimbView, state::Int = 1) state > view.num_bytes && return nothing return (@inbounds(view[state]), state + 1) end function Base.length(view::UnsafeLimbView) return view.num_bytes end function hash_integer(n::BigInt, h::UInt) iszero(n) && return hash_integer(0, h) s = n.size h ⊻= s < 0 us = abs(s) leading_zero_bytes = div(leading_zeros(unsafe_load(n.d, us)), 8) num_bytes = 8us - leading_zero_bytes limb_view = UnsafeLimbView(n, 1, num_bytes) return hash_bytes(limb_view, h, HASH_SECRET) end function hash(x::BigInt, h::UInt) GC.@preserve x begin sz = x.size sz == 0 && return hash(0, h) ptr = Ptr{UInt64}(x.d) if sz == 1 return hash(unsafe_load(ptr), h) elseif sz == -1 limb = unsafe_load(ptr) limb <= typemin(Int) % UInt && return hash(-(limb % Int), h) end pow = trailing_zeros(x) nd = Base.ndigits0z(x, 2) idx = pow >>> 6 + 1 shift = (pow & 63) % UInt upshift = BITS_PER_LIMB - shift asz = abs(sz) if shift == 0 limb = unsafe_load(ptr, idx) else limb1 = unsafe_load(ptr, idx) limb2 = if idx < asz unsafe_load(ptr, idx + 1) else UInt(0) end limb = limb2 << upshift | limb1 >> shift end if nd <= 1024 && nd - pow <= 53 return hash(ldexp(flipsign(Float64(limb), sz), pow), h) end h = hash_integer(pow, h) h ⊻= sz < 0 leading_zero_bytes = div(leading_zeros(unsafe_load(x.d, asz)), 8) trailing_zero_bytes = div(pow, 8) num_bytes = 8asz - (leading_zero_bytes + trailing_zero_bytes) limb_view = UnsafeLimbView(x, trailing_zero_bytes + 1, num_bytes) return hash_bytes(limb_view, h, HASH_SECRET) end end end module MPQ import .Base: unsafe_rational, __throw_rational_argerror_zero import ..GMP: BigInt, MPZ, Limb, libgmp gmpq(op::Symbol) = begin Expr(:tuple, QuoteNode(Symbol(:__gmpq_, op)), GlobalRef(MPZ, :libgmp)) end mutable struct _MPQ num_alloc::Cint num_size::Cint num_d::Ptr{Limb} den_alloc::Cint den_size::Cint den_d::Ptr{Limb} rat::Rational{BigInt} end const mpq_t = Ref{_MPQ} _MPQ(x::BigInt, y::BigInt) = begin _MPQ(x.alloc, x.size, x.d, y.alloc, y.size, y.d, unsafe_rational(BigInt, x, y)) end _MPQ() = begin _MPQ(BigInt(), BigInt()) end _MPQ(x::Rational{BigInt}) = begin _MPQ(x.num, x.den) end function sync_rational!(xq::_MPQ) xq.rat.num.alloc = xq.num_alloc xq.rat.num.size = xq.num_size xq.rat.num.d = xq.num_d xq.rat.den.alloc = xq.den_alloc xq.rat.den.size = xq.den_size xq.rat.den.d = xq.den_d return xq.rat end function Rational{BigInt}(num::BigInt, den::BigInt) if iszero(den) iszero(num) && __throw_rational_argerror_zero(BigInt) return set_si(flipsign(1, num), 0) end xq = _MPQ(MPZ.set(num), MPZ.set(den)) ccall((:__gmpq_canonicalize, libgmp), Cvoid, (mpq_t,), xq) return sync_rational!(xq) end function set!(z::Rational{BigInt}, x::Rational{BigInt}) zq = _MPQ(z) ccall((:__gmpq_set, libgmp), Cvoid, (mpq_t, mpq_t), zq, _MPQ(x)) return sync_rational!(zq) end function set_z!(z::Rational{BigInt}, x::BigInt) zq = _MPQ(z) ccall((:__gmpq_set_z, libgmp), Cvoid, (mpq_t, MPZ.mpz_t), zq, x) return sync_rational!(zq) end for (op, T) = ((:set, Rational{BigInt}), (:set_z, BigInt)) op! = Symbol(op, :!) @eval ($op)(a::$T) = begin ($op!)(unsafe_rational(BigInt(), BigInt()), a) end end for (op, T1, T2) = ((:set_ui, Culong, Culong), (:set_si, Clong, Culong)) op! = Symbol(op, :!) @eval begin function ($op!)(z::Rational{BigInt}, a, b) zq = _MPQ(z) ccall($(gmpq(op)), Cvoid, (mpq_t, $T1, $T2), zq, a, b) return sync_rational!(zq) end ($op)(a, b) = begin ($op!)(unsafe_rational(BigInt(), BigInt()), a, b) end end end function add!(z::Rational{BigInt}, x::Rational{BigInt}, y::Rational{BigInt}) if iszero(x.den) || iszero(y.den) if iszero(x.den) && (iszero(y.den) && isnegative(x.num) != isnegative(y.num)) throw(DivideError()) end return set!(z, if iszero(x.den) x else y end) end zq = _MPQ(z) ccall((:__gmpq_add, libgmp), Cvoid, (mpq_t, mpq_t, mpq_t), zq, _MPQ(x), _MPQ(y)) return sync_rational!(zq) end function sub!(z::Rational{BigInt}, x::Rational{BigInt}, y::Rational{BigInt}) if iszero(x.den) || iszero(y.den) if iszero(x.den) && (iszero(y.den) && isnegative(x.num) == isnegative(y.num)) throw(DivideError()) end iszero(x.den) && return set!(z, x) return set_si!(z, flipsign(-1, y.num), 0) end zq = _MPQ(z) ccall((:__gmpq_sub, libgmp), Cvoid, (mpq_t, mpq_t, mpq_t), zq, _MPQ(x), _MPQ(y)) return sync_rational!(zq) end function mul!(z::Rational{BigInt}, x::Rational{BigInt}, y::Rational{BigInt}) if iszero(x.den) || iszero(y.den) if iszero(x.num) || iszero(y.num) throw(DivideError()) end return set_si!(z, ifelse(xor(isnegative(x.num), isnegative(y.num)), -1, 1), 0) end zq = _MPQ(z) ccall((:__gmpq_mul, libgmp), Cvoid, (mpq_t, mpq_t, mpq_t), zq, _MPQ(x), _MPQ(y)) return sync_rational!(zq) end function div!(z::Rational{BigInt}, x::Rational{BigInt}, y::Rational{BigInt}) if iszero(x.den) if iszero(y.den) throw(DivideError()) end isnegative(y.num) || return set!(z, x) return set_si!(z, flipsign(-1, x.num), 0) elseif iszero(y.den) return set_si!(z, 0, 1) elseif iszero(y.num) if iszero(x.num) throw(DivideError()) end return set_si!(z, flipsign(1, x.num), 0) end zq = _MPQ(z) ccall((:__gmpq_div, libgmp), Cvoid, (mpq_t, mpq_t, mpq_t), zq, _MPQ(x), _MPQ(y)) return sync_rational!(zq) end for (fJ, fC) = ((:+, :add), (:-, :sub), (:*, :mul), (://, :div)) fC! = Symbol(fC, :!) @eval begin ($fC!)(x::Rational{BigInt}, y::Rational{BigInt}) = begin ($fC!)(x, x, y) end Base.:($fJ)(x::Rational{BigInt}, y::Rational{BigInt}) = begin ($fC!)(unsafe_rational(BigInt(), BigInt()), x, y) end end end function Base.cmp(x::Rational{BigInt}, y::Rational{BigInt}) Int(ccall((:__gmpq_cmp, libgmp), Cint, (mpq_t, mpq_t), _MPQ(x), _MPQ(y))) end end end module GMP export BigInt import .Base: *, +, -, /, <, <<, >>, >>>, <=, ==, >, >=, ^, ~, &, |, xor, nand, nor, binomial, cmp, convert, div, divrem, factorial, cld, fld, gcd, gcdx, lcm, mod, ndigits, promote_rule, rem, show, isqrt, string, powermod, sum, prod, trailing_zeros, trailing_ones, count_ones, count_zeros, tryparse_internal, bin, oct, dec, hex, isequal, invmod, _prevpow2, _nextpow2, ndigits0zpb, widen, signed, unsafe_trunc, trunc, iszero, isone, big, flipsign, signbit, sign, isodd, iseven, digits!, hash, hash_integer, top_set_bit, ispositive, isnegative, clamp, unsafe_takestring import Core: Signed, Float16, Float32, Float64 if Clong == Int32 const ClongMax = Union{Int8, Int16, Int32} const CulongMax = Union{UInt8, UInt16, UInt32} else const ClongMax = Union{Int8, Int16, Int32, Int64} const CulongMax = Union{UInt8, UInt16, UInt32, UInt64} end const CdoubleMax = Union{Float16, Float32, Float64} if Sys.iswindows() const libgmp = "libgmp-10.dll" elseif Sys.isapple() const libgmp = "@rpath/libgmp.10.dylib" else const libgmp = "libgmp.so.10" end _version() = begin unsafe_string(unsafe_load(cglobal((:__gmp_version, libgmp), Ptr{Cchar}))) end version() = begin VersionNumber(_version()) end major_version() = begin (_version())[1] end bits_per_limb() = begin Int(unsafe_load(cglobal((:__gmp_bits_per_limb, libgmp), Cint))) end const VERSION = version() const MAJOR_VERSION = major_version() const BITS_PER_LIMB = bits_per_limb() if BITS_PER_LIMB == 32 const Limb = UInt32 const SLimbMax = Union{Int8, Int16, Int32} const ULimbMax = Union{UInt8, UInt16, UInt32} elseif BITS_PER_LIMB == 64 const Limb = UInt64 const SLimbMax = Union{Int8, Int16, Int32, Int64} const ULimbMax = Union{UInt8, UInt16, UInt32, UInt64} else error("GMP: cannot determine the type mp_limb_t (__gmp_bits_per_limb == $(BITS_PER_LIMB))") end Core.@doc " BigInt <: Signed\n\nArbitrary precision integer type.\n" mutable struct BigInt <: Signed alloc::Cint size::Cint d::Ptr{Limb} function BigInt(; nbits::Integer = 0) b = MPZ.init2!(new(), nbits) finalizer(cglobal((:__gmpz_clear, libgmp)), b) return b end end Core.@doc " BigInt(x)\n\nCreate an arbitrary precision integer. `x` may be an `Int` (or anything that can be\nconverted to an `Int`). The usual mathematical operators are defined for this type, and\nresults are promoted to a [`BigInt`](@ref).\n\nInstances can be constructed from strings via [`parse`](@ref), or using the `big`\nstring literal.\n\n# Examples\n```jldoctest\njulia> parse(BigInt, \"42\")\n42\n\njulia> big\"313\"\n313\n\njulia> BigInt(10)^19\n10000000000000000000\n```\n" BigInt(x) Core.@doc " ALLOC_OVERFLOW_FUNCTION\n\nA reference that holds a boolean, if true, indicating julia is linked with a patched GMP that\ndoes not abort on huge allocation and throws OutOfMemoryError instead.\n" const ALLOC_OVERFLOW_FUNCTION = Ref(false) function __init__() try if major_version() != MAJOR_VERSION || bits_per_limb() != BITS_PER_LIMB msg = "The dynamically loaded GMP library (v\"$(version())\" with __gmp_bits_per_limb == $(bits_per_limb()))\ndoes not correspond to the compile time version (v\"$(VERSION)\" with __gmp_bits_per_limb == $(BITS_PER_LIMB)).\nPlease rebuild Julia." if bits_per_limb() != BITS_PER_LIMB @error msg else @warn msg end end ccall((:__gmp_set_memory_functions, libgmp), Cvoid, (Ptr{Cvoid}, Ptr{Cvoid}, Ptr{Cvoid}), cglobal(:jl_gc_counted_malloc), cglobal(:jl_gc_counted_realloc_with_old_size), cglobal(:jl_gc_counted_free_with_size)) (ZERO.alloc, ZERO.size, ZERO.d) = (0, 0, C_NULL) (ONE.alloc, ONE.size, ONE.d) = (1, 1, pointer(_ONE)) catch ex Base.showerror_nostdio(ex, "WARNING: Error during initialization of module GMP") end try ccall((:__gmp_set_alloc_overflow_function, libgmp), Cvoid, (Ptr{Cvoid},), cglobal(:jl_throw_out_of_memory_error)) ALLOC_OVERFLOW_FUNCTION[] = true catch ex if typeof(ex) != ErrorException rethrow() end end end module MPZ using ..GMP: BigInt, Limb, BITS_PER_LIMB, libgmp const mpz_t = Ref{BigInt} const bitcnt_t = Culong gmpz(op::Symbol) = begin Expr(:tuple, QuoteNode(Symbol(:__gmpz_, op)), GlobalRef(MPZ, :libgmp)) end init!(x::BigInt) = begin ccall((:__gmpz_init, libgmp), Cvoid, (mpz_t,), x) x end init2!(x::BigInt, a) = begin ccall((:__gmpz_init2, libgmp), Cvoid, (mpz_t, bitcnt_t), x, a) x end realloc2!(x, a) = begin ccall((:__gmpz_realloc2, libgmp), Cvoid, (mpz_t, bitcnt_t), x, a) x end realloc2(a) = begin realloc2!(BigInt(), a) end sizeinbase(a::BigInt, b) = begin Int(ccall((:__gmpz_sizeinbase, libgmp), Csize_t, (mpz_t, Cint), a, b)) end for (op, nbits) = (:add => :(BITS_PER_LIMB * (1 + max(abs(a.size), abs(b.size)))), :sub => :(BITS_PER_LIMB * (1 + max(abs(a.size), abs(b.size)))), :mul => 0, :fdiv_q => 0, :tdiv_q => 0, :cdiv_q => 0, :fdiv_r => 0, :tdiv_r => 0, :cdiv_r => 0, :gcd => 0, :lcm => 0, :and => 0, :ior => 0, :xor => 0) op! = Symbol(op, :!) @eval begin ($op!)(x::BigInt, a::BigInt, b::BigInt) = begin ccall($(gmpz(op)), Cvoid, (mpz_t, mpz_t, mpz_t), x, a, b) x end ($op)(a::BigInt, b::BigInt) = begin ($op!)(BigInt(nbits = $nbits), a, b) end ($op!)(x::BigInt, b::BigInt) = begin ($op!)(x, x, b) end end end invert!(x::BigInt, a::BigInt, b::BigInt) = begin ccall((:__gmpz_invert, libgmp), Cint, (mpz_t, mpz_t, mpz_t), x, a, b) end invert!(x::BigInt, b::BigInt) = begin invert!(x, x, b) end invert(a::BigInt, b::BigInt) = begin ret = BigInt() invert!(ret, a, b) ret end for op = (:add_ui, :sub_ui, :mul_ui, :mul_2exp, :fdiv_q_2exp, :pow_ui, :bin_ui) op! = Symbol(op, :!) @eval begin ($op!)(x::BigInt, a::BigInt, b) = begin ccall($(gmpz(op)), Cvoid, (mpz_t, mpz_t, Culong), x, a, b) x end ($op)(a::BigInt, b) = begin ($op!)(BigInt(), a, b) end ($op!)(x::BigInt, b) = begin ($op!)(x, x, b) end end end ui_sub!(x::BigInt, a, b::BigInt) = begin ccall((:__gmpz_ui_sub, libgmp), Cvoid, (mpz_t, Culong, mpz_t), x, a, b) x end ui_sub(a, b::BigInt) = begin ui_sub!(BigInt(), a, b) end for op = (:scan1, :scan0) @eval ($op)(a::BigInt, b) = begin Int(signed(ccall($(gmpz(op)), Culong, (mpz_t, Culong), a, b))) end end mul_si!(x::BigInt, a::BigInt, b) = begin ccall((:__gmpz_mul_si, libgmp), Cvoid, (mpz_t, mpz_t, Clong), x, a, b) x end mul_si(a::BigInt, b) = begin mul_si!(BigInt(), a, b) end mul_si!(x::BigInt, b) = begin mul_si!(x, x, b) end for op = (:neg, :com, :sqrt, :set) op! = Symbol(op, :!) @eval begin ($op!)(x::BigInt, a::BigInt) = begin ccall($(gmpz(op)), Cvoid, (mpz_t, mpz_t), x, a) x end ($op)(a::BigInt) = begin ($op!)(BigInt(), a) end end op === :set && continue @eval ($op!)(x::BigInt) = begin ($op!)(x, x) end end for (op, T) = ((:fac_ui, Culong), (:set_ui, Culong), (:set_si, Clong), (:set_d, Cdouble)) op! = Symbol(op, :!) @eval begin ($op!)(x::BigInt, a) = begin ccall($(gmpz(op)), Cvoid, (mpz_t, $T), x, a) x end ($op)(a) = begin ($op!)(BigInt(), a) end end end popcount(a::BigInt) = begin Int(signed(ccall((:__gmpz_popcount, libgmp), Culong, (mpz_t,), a))) end mpn_popcount(d::Ptr{Limb}, s::Integer) = begin Int(ccall((:__gmpn_popcount, libgmp), Culong, (Ptr{Limb}, Csize_t), d, s)) end mpn_popcount(a::BigInt) = begin mpn_popcount(a.d, abs(a.size)) end function tdiv_qr!(x::BigInt, y::BigInt, a::BigInt, b::BigInt) ccall((:__gmpz_tdiv_qr, libgmp), Cvoid, (mpz_t, mpz_t, mpz_t, mpz_t), x, y, a, b) (x, y) end tdiv_qr(a::BigInt, b::BigInt) = begin tdiv_qr!(BigInt(), BigInt(), a, b) end powm!(x::BigInt, a::BigInt, b::BigInt, c::BigInt) = begin ccall((:__gmpz_powm, libgmp), Cvoid, (mpz_t, mpz_t, mpz_t, mpz_t), x, a, b, c) x end powm(a::BigInt, b::BigInt, c::BigInt) = begin powm!(BigInt(), a, b, c) end powm!(x::BigInt, b::BigInt, c::BigInt) = begin powm!(x, x, b, c) end function gcdext!(x::BigInt, y::BigInt, z::BigInt, a::BigInt, b::BigInt) ccall((:__gmpz_gcdext, libgmp), Cvoid, (mpz_t, mpz_t, mpz_t, mpz_t, mpz_t), x, y, z, a, b) (x, y, z) end gcdext(a::BigInt, b::BigInt) = begin gcdext!(BigInt(), BigInt(), BigInt(), a, b) end cmp(a::BigInt, b::BigInt) = begin Int(ccall((:__gmpz_cmp, libgmp), Cint, (mpz_t, mpz_t), a, b)) end cmp_si(a::BigInt, b) = begin Int(ccall((:__gmpz_cmp_si, libgmp), Cint, (mpz_t, Clong), a, b)) end cmp_ui(a::BigInt, b) = begin Int(ccall((:__gmpz_cmp_ui, libgmp), Cint, (mpz_t, Culong), a, b)) end cmp_d(a::BigInt, b) = begin Int(ccall((:__gmpz_cmp_d, libgmp), Cint, (mpz_t, Cdouble), a, b)) end mpn_cmp(a::Ptr{Limb}, b::Ptr{Limb}, c) = begin ccall((:__gmpn_cmp, libgmp), Cint, (Ptr{Limb}, Ptr{Limb}, Clong), a, b, c) end mpn_cmp(a::BigInt, b::BigInt, c) = begin mpn_cmp(a.d, b.d, c) end get_str!(x, a, b::BigInt) = begin ccall((:__gmpz_get_str, libgmp), Ptr{Cchar}, (Ptr{Cchar}, Cint, mpz_t), x, a, b) x end set_str!(x::BigInt, a, b) = begin Int(ccall((:__gmpz_set_str, libgmp), Cint, (mpz_t, Ptr{UInt8}, Cint), x, a, b)) end get_d(a::BigInt) = begin ccall((:__gmpz_get_d, libgmp), Cdouble, (mpz_t,), a) end function export!(a::AbstractVector{T}, n::BigInt; order::Integer = -1, nails::Integer = 0, endian::Integer = 0) where T <: Base.BitInteger stride(a, 1) == 1 || throw(ArgumentError("a must have stride 1")) ndigits = cld(sizeinbase(n, 2), 8 * sizeof(T) - nails) length(a) < ndigits && resize!(a, ndigits) fill!(a, zero(T)) count = Ref{Csize_t}() ccall((:__gmpz_export, libgmp), Ptr{T}, (Ptr{T}, Ref{Csize_t}, Cint, Csize_t, Cint, Csize_t, mpz_t), a, count, order, sizeof(T), endian, nails, n) @assert count[] ≤ length(a) return (a, Int(count[])) end limbs_write!(x::BigInt, a) = begin ccall((:__gmpz_limbs_write, libgmp), Ptr{Limb}, (mpz_t, Clong), x, a) end limbs_finish!(x::BigInt, a) = begin ccall((:__gmpz_limbs_finish, libgmp), Cvoid, (mpz_t, Clong), x, a) end setbit!(x, a) = begin ccall((:__gmpz_setbit, libgmp), Cvoid, (mpz_t, bitcnt_t), x, a) x end tstbit(a::BigInt, b) = begin ccall((:__gmpz_tstbit, libgmp), Cint, (mpz_t, bitcnt_t), a, b) % Bool end end const ZERO = BigInt() const ONE = BigInt() const _ONE = Limb[1] widen(::Type{Int128}) = begin BigInt end widen(::Type{UInt128}) = begin BigInt end widen(::Type{BigInt}) = begin BigInt end signed(x::BigInt) = begin x end BigInt(x::BigInt) = begin x end Signed(x::BigInt) = begin x end function tryparse_internal(::Type{BigInt}, s::AbstractString, startpos::Int, endpos::Int, base_::Integer, raise::Bool) bstr = if startpos == firstindex(s) && endpos == lastindex(s) String(s) else String(SubString(s, startpos, endpos)) end (sgn, base, i) = Base.parseint_preamble(true, Int(base_), bstr, firstindex(bstr), lastindex(bstr)) if !(2 <= base <= 62) raise && throw(ArgumentError("invalid base: base must be 2 ≤ base ≤ 62, got $(base)")) return nothing end if i == 0 raise && throw(ArgumentError("premature end of integer: $(repr(bstr))")) return nothing end z = BigInt() if Base.containsnul(bstr) err = -1 else err = GC.@preserve(bstr, MPZ.set_str!(z, pointer(bstr) + (i - firstindex(bstr)), base)) end if err != 0 raise && throw(ArgumentError("invalid BigInt: $(repr(bstr))")) return nothing end flipsign!(z, sgn) end BigInt(x::Union{Clong, Int32}) = begin MPZ.set_si(x) end BigInt(x::Union{Culong, UInt32}) = begin MPZ.set_ui(x) end BigInt(x::Bool) = begin BigInt(UInt(x)) end unsafe_trunc(::Type{BigInt}, x::Union{Float16, Float32, Float64}) = begin MPZ.set_d(x) end function BigInt(x::Float64) isinteger(x) || throw(InexactError(:BigInt, BigInt, x)) unsafe_trunc(BigInt, x) end BigInt(x::Float16) = begin BigInt(Float64(x)) end BigInt(x::Float32) = begin BigInt(Float64(x)) end function BigInt(x::Integer) isbits(x) && (typemin(Clong) <= x <= typemax(Clong) && return BigInt((x % Clong)::Clong)) nd = ndigits(x, base = 2) z = MPZ.realloc2(nd) ux = unsigned(if x < 0 -x else x end) size = 0 limbnbits = sizeof(Limb) << 3 while nd > 0 size += 1 unsafe_store!(z.d, ux % Limb, size) ux >>= limbnbits nd -= limbnbits end z.size = if x < 0 -size else size end z end rem(x::BigInt, ::Type{Bool}) = begin (!(iszero(x)) & unsafe_load(x.d)) % Bool end (rem(x::BigInt, ::Type{T}) where T <: Union{SLimbMax, ULimbMax}) = begin if iszero(x) zero(T) else flipsign(unsafe_load(x.d) % T, x.size) end end function rem(x::BigInt, ::Type{T}) where T <: Union{Base.BitUnsigned, Base.BitSigned} u = zero(T) for l = 1:min(abs(x.size), cld(sizeof(T), sizeof(Limb))) u += (unsafe_load(x.d, l) % T) << (sizeof(Limb) << 3 * (l - 1)) end flipsign(u, x.size) end rem(x::Integer, ::Type{BigInt}) = begin BigInt(x) end clamp(x, ::Type{BigInt}) = begin convert(BigInt, x) end isodd(x::BigInt) = begin MPZ.tstbit(x, 0) end iseven(x::BigInt) = begin !(isodd(x)) end function (::Type{T})(x::BigInt) where T <: Base.BitUnsigned if sizeof(T) < sizeof(Limb) convert(T, convert(Limb, x)) else 0 <= x.size <= cld(sizeof(T), sizeof(Limb)) || throw(InexactError(nameof(T), T, x)) x % T end end function (::Type{T})(x::BigInt) where T <: Base.BitSigned n = abs(x.size) if sizeof(T) < sizeof(Limb) SLimb = typeof(Signed(one(Limb))) convert(T, convert(SLimb, x)) else 0 <= n <= cld(sizeof(T), sizeof(Limb)) || throw(InexactError(nameof(T), T, x)) y = x % T ispositive(x) ⊻ (y > 0) && throw(InexactError(nameof(T), T, x)) y end end Float64(n::BigInt, ::RoundingMode{:ToZero}) = begin MPZ.get_d(n) end function (::Type{T})(n::BigInt, ::RoundingMode{:ToZero}) where T <: Union{Float16, Float32} T(Float64(n, RoundToZero), RoundToZero) end function (::Type{T})(n::BigInt, ::RoundingMode{:Down}) where T <: CdoubleMax x = T(n, RoundToZero) if x > n prevfloat(x) else x end end function (::Type{T})(n::BigInt, ::RoundingMode{:Up}) where T <: CdoubleMax x = T(n, RoundToZero) if x < n nextfloat(x) else x end end function Float64(x::BigInt, ::RoundingMode{:Nearest}) x == 0 && return 0.0 xsize = abs(x.size) if xsize * BITS_PER_LIMB > 1024 z = Inf64 elseif xsize == 1 z = Float64(unsafe_load(x.d)) elseif Limb == UInt32 && xsize == 2 z = Float64((unsafe_load(x.d, 2) % UInt64) << BITS_PER_LIMB + unsafe_load(x.d)) else y1 = unsafe_load(x.d, xsize) % UInt64 n = top_set_bit(y1) y = y1 >> (n - (precision(Float64) + 1)) if Limb == UInt64 y += if n > precision(Float64) 0 else unsafe_load(x.d, xsize - 1) >> (10 + n) end else y += (unsafe_load(x.d, xsize - 1) % UInt64) >> (n - 22) y += if n > precision(Float64) - 32 0 else unsafe_load(x.d, xsize - 2) >> (10 + n) end end y = (y + 1) >> 1 y &= ~(UInt64(trailing_zeros(x) == (n - 54) + (xsize - 1) * BITS_PER_LIMB)) d = ((n + 1021) % UInt64) << 52 z = reinterpret(Float64, d + y) z = ldexp(z, (xsize - 1) * BITS_PER_LIMB) end return flipsign(z, x.size) end function Float32(x::BigInt, ::RoundingMode{:Nearest}) x == 0 && return 0.0f0 xsize = abs(x.size) if xsize * BITS_PER_LIMB > 128 z = Inf32 elseif xsize == 1 z = Float32(unsafe_load(x.d)) else y1 = unsafe_load(x.d, xsize) n = BITS_PER_LIMB - leading_zeros(y1) y = y1 >> (n - (precision(Float32) + 1)) % UInt32 y += if n > precision(Float32) 0 else unsafe_load(x.d, xsize - 1) >> (BITS_PER_LIMB - -25) end % UInt32 y = (y + one(UInt32)) >> 1 y &= ~(UInt32(trailing_zeros(x) == (n - 25) + (xsize - 1) * BITS_PER_LIMB)) d = ((n + 125) % UInt32) << 23 z = reinterpret(Float32, d + y) z = ldexp(z, (xsize - 1) * BITS_PER_LIMB) end return flipsign(z, x.size) end function Float16(x::BigInt, ::RoundingMode{:Nearest}) x == 0 && return Float16(0.0) y1 = unsafe_load(x.d) n = BITS_PER_LIMB - leading_zeros(y1) if n > 16 || abs(x.size) > 1 z = Inf16 else y = y1 >> (n - (precision(Float16) + 1)) % UInt16 y = (y + one(UInt16)) >> 1 y &= ~(UInt16(trailing_zeros(x) == n - 12)) d = ((n + 13) % UInt16) << 10 z = reinterpret(Float16, d + y) end return flipsign(z, x.size) end Float64(n::BigInt) = begin Float64(n, RoundNearest) end Float32(n::BigInt) = begin Float32(n, RoundNearest) end Float16(n::BigInt) = begin Float16(n, RoundNearest) end promote_rule(::Type{BigInt}, ::Type{<:Integer}) = begin BigInt end Core.@doc " big(x)\n\nConvert a number to a maximum precision representation (typically [`BigInt`](@ref) or\n`BigFloat`). See [`BigFloat`](@ref BigFloat(::Any, rounding::RoundingMode)) for\ninformation about some pitfalls with floating-point numbers.\n" function big end big(::Type{<:Integer}) = begin BigInt end big(::Type{<:Rational}) = begin Rational{BigInt} end big(n::Integer) = begin convert(BigInt, n) end for (fJ, fC) = ((:+, :add), (:-, :sub), (:*, :mul), (:mod, :fdiv_r), (:rem, :tdiv_r), (:gcd, :gcd), (:lcm, :lcm), (:&, :and), (:|, :ior), (:xor, :xor)) @eval begin ($fJ)(x::BigInt, y::BigInt) = begin MPZ.:($fC)(x, y) end end end for (r, f) = ((RoundToZero, :tdiv_q), (RoundDown, :fdiv_q), (RoundUp, :cdiv_q)) @eval div(x::BigInt, y::BigInt, ::typeof($r)) = begin MPZ.:($f)(x, y) end end div(x::BigInt, y::BigInt) = begin div(x, y, RoundToZero) end fld(x::BigInt, y::BigInt) = begin div(x, y, RoundDown) end cld(x::BigInt, y::BigInt) = begin div(x, y, RoundUp) end x::BigInt / y::BigInt = begin float(x) / float(y) end function invmod(x::BigInt, y::BigInt) z = zero(BigInt) ya = abs(y) if ya == 1 return z end if y == 0 || MPZ.invert!(z, x, ya) == 0 throw(DomainError(y)) end if y < 0 MPZ.add!(z, y) end return z end for (fJ, fC) = ((:+, :add), (:*, :mul), (:&, :and), (:|, :ior), (:xor, :xor)) fC! = Symbol(fC, :!) @eval begin ($fJ)(a::BigInt, b::BigInt, c::BigInt) = begin MPZ.:($fC!)(MPZ.:($fC)(a, b), c) end ($fJ)(a::BigInt, b::BigInt, c::BigInt, d::BigInt) = begin MPZ.:($fC!)(MPZ.:($fC!)(MPZ.:($fC)(a, b), c), d) end ($fJ)(a::BigInt, b::BigInt, c::BigInt, d::BigInt, e::BigInt) = begin MPZ.:($fC!)(MPZ.:($fC!)(MPZ.:($fC!)(MPZ.:($fC)(a, b), c), d), e) end end end x::BigInt + c::CulongMax = begin MPZ.add_ui(x, c) end c::CulongMax + x::BigInt = begin x + c end x::BigInt - c::CulongMax = begin MPZ.sub_ui(x, c) end c::CulongMax - x::BigInt = begin MPZ.ui_sub(c, x) end x::BigInt + c::ClongMax = begin if c < 0 x - -(c % Culong) else x + convert(Culong, c) end end c::ClongMax + x::BigInt = begin if c < 0 x - -(c % Culong) else x + convert(Culong, c) end end x::BigInt - c::ClongMax = begin if c < 0 x + -(c % Culong) else x - convert(Culong, c) end end c::ClongMax - x::BigInt = begin if c < 0 -((x + -(c % Culong))) else convert(Culong, c) - x end end x::BigInt * c::CulongMax = begin MPZ.mul_ui(x, c) end c::CulongMax * x::BigInt = begin x * c end x::BigInt * c::ClongMax = begin MPZ.mul_si(x, c) end c::ClongMax * x::BigInt = begin x * c end x::BigInt / y::Union{ClongMax, CulongMax} = begin float(x) / y end x::Union{ClongMax, CulongMax} / y::BigInt = begin x / float(y) end -(x::BigInt) = begin MPZ.neg(x) end ~(x::BigInt) = begin MPZ.com(x) end x::BigInt << c::UInt = begin if c == 0 x else MPZ.mul_2exp(x, c) end end x::BigInt >> c::UInt = begin if c == 0 x else MPZ.fdiv_q_2exp(x, c) end end x::BigInt >>> c::UInt = begin x >> c end function trailing_zeros(x::BigInt) c = MPZ.scan1(x, 0) c == -1 && throw(DomainError(x, "`x` must be non-zero")) c end function trailing_ones(x::BigInt) c = MPZ.scan0(x, 0) c == -1 && throw(DomainError(x, "`x` must not be equal to -1")) c end function count_ones(x::BigInt) c = MPZ.popcount(x) c == -1 && throw(DomainError(x, "`x` cannot be negative")) c end function count_zeros(x::BigInt) c = MPZ.popcount(~x) c == -1 && throw(DomainError(x, "`x` must be negative")) c end Core.@doc " count_ones_abs(x::BigInt)\n\nNumber of ones in the binary representation of abs(x).\n" count_ones_abs(x::BigInt) = begin if iszero(x) 0 else MPZ.mpn_popcount(x) end end _bit_magnitude(x::BigInt) = begin x.size * sizeof(Limb) << 3 - leading_zeros(GC.@preserve(x, unsafe_load(x.d, x.size))) end function exponent(x::BigInt) iszero(x) && throw(DomainError(x, "cannot be zero")) ux = abs(x) return _bit_magnitude(ux) - 1 end function top_set_bit(x::BigInt) isnegative(x) && throw(DomainError(x, "top_set_bit only supports negative arguments when they have type BitSigned.")) iszero(x) && return 0 return _bit_magnitude(x) end divrem(x::BigInt, y::BigInt, ::typeof(RoundToZero) = RoundToZero) = begin MPZ.tdiv_qr(x, y) end divrem(x::BigInt, y::Integer, ::typeof(RoundToZero) = RoundToZero) = begin MPZ.tdiv_qr(x, BigInt(y)) end cmp(x::BigInt, y::BigInt) = begin sign(MPZ.cmp(x, y)) end cmp(x::BigInt, y::ClongMax) = begin sign(MPZ.cmp_si(x, y)) end cmp(x::BigInt, y::CulongMax) = begin sign(MPZ.cmp_ui(x, y)) end cmp(x::BigInt, y::Integer) = begin cmp(x, big(y)) end cmp(x::Integer, y::BigInt) = begin -(cmp(y, x)) end cmp(x::BigInt, y::CdoubleMax) = begin if isnan(y) -1 else sign(MPZ.cmp_d(x, y)) end end cmp(x::CdoubleMax, y::BigInt) = begin -(cmp(y, x)) end isqrt(x::BigInt) = begin MPZ.sqrt(x) end x::BigInt ^ y::Culong = begin MPZ.pow_ui(x, y) end function bigint_pow(x::BigInt, y::Integer) x == 1 && return x x == -1 && return if isodd(y) x else -x end if y < 0 throw(DomainError(y, "`y` cannot be negative.")) end @noinline throw1(y) = begin throw(OverflowError("exponent $(y) is too large and computation will overflow")) end if y > typemax(Culong) x == 0 && return x throw1(y) end return x ^ convert(Culong, y) end x::BigInt ^ y::BigInt = begin bigint_pow(x, y) end x::BigInt ^ y::Bool = begin if y x else one(x) end end x::BigInt ^ y::Integer = begin bigint_pow(x, y) end x::Integer ^ y::BigInt = begin bigint_pow(BigInt(x), y) end x::Bool ^ y::BigInt = begin Base.power_by_squaring(x, y) end function powermod(x::BigInt, p::BigInt, m::BigInt) r = MPZ.powm(x, p, m) return if m < 0 && r > 0 MPZ.add!(r, m) else r end end powermod(x::Integer, p::Integer, m::BigInt) = begin powermod(big(x), big(p), m) end function gcdx(a::BigInt, b::BigInt) (g, s, t) = MPZ.gcdext(a, b) if t == 0 if a == b return (g, t, s) elseif abs(a) == abs(b) return (g, t, -s) end end (g, s, t) end +(x::BigInt, y::BigInt, rest::BigInt...) = begin sum(tuple(x, y, rest...)) end sum(arr::Union{AbstractArray{BigInt}, Tuple{BigInt, Vararg{BigInt}}}) = begin foldl(MPZ.add!, arr; init = BigInt(0)) end function prod(arr::AbstractArray{BigInt}) any(iszero, arr) && return zero(BigInt) _prod(arr, firstindex(arr), lastindex(arr)) end function _prod(arr::AbstractArray{BigInt}, lo, hi) if (hi - lo) + 1 <= 16 nlimbs = 0 for i = lo:hi nlimbs += abs((arr[i]).size) end init = BigInt(; nbits = nlimbs * BITS_PER_LIMB) MPZ.set_si!(init, 1) for i = lo:hi MPZ.mul!(init, arr[i]) end init else mid = (lo + hi) ÷ 2 MPZ.mul!(_prod(arr, lo, mid), _prod(arr, mid + 1, hi)) end end factorial(n::BigInt) = begin if !(isnegative(n)) MPZ.fac_ui(n) else throw(DomainError(n, "`n` must not be negative.")) end end function binomial(n::BigInt, k::Integer) k < 0 && return BigInt(0) k <= typemax(Culong) && return binomial(n, Culong(k)) n < 0 && return if isodd(k) -(binomial((k - n) - 1, k)) else binomial((k - n) - 1, k) end κ = n - k κ < 0 && return BigInt(0) κ <= typemax(Culong) && return binomial(n, Culong(κ)) throw(OverflowError("Computation would exceed memory")) end binomial(n::BigInt, k::Culong) = begin MPZ.bin_ui(n, k) end x::BigInt == y::BigInt = begin cmp(x, y) == 0 end x::BigInt == i::Integer = begin cmp(x, i) == 0 end i::Integer == x::BigInt = begin cmp(x, i) == 0 end x::BigInt == f::CdoubleMax = begin if isnan(f) false else cmp(x, f) == 0 end end f::CdoubleMax == x::BigInt = begin if isnan(f) false else cmp(x, f) == 0 end end iszero(x::BigInt) = begin x.size == 0 end isone(x::BigInt) = begin x == Culong(1) end x::BigInt <= y::BigInt = begin cmp(x, y) <= 0 end x::BigInt <= i::Integer = begin cmp(x, i) <= 0 end i::Integer <= x::BigInt = begin cmp(x, i) >= 0 end x::BigInt <= f::CdoubleMax = begin if isnan(f) false else cmp(x, f) <= 0 end end f::CdoubleMax <= x::BigInt = begin if isnan(f) false else cmp(x, f) >= 0 end end x::BigInt < y::BigInt = begin cmp(x, y) < 0 end x::BigInt < i::Integer = begin cmp(x, i) < 0 end i::Integer < x::BigInt = begin cmp(x, i) > 0 end x::BigInt < f::CdoubleMax = begin if isnan(f) false else cmp(x, f) < 0 end end f::CdoubleMax < x::BigInt = begin if isnan(f) false else cmp(x, f) > 0 end end isnegative(x::BigInt) = begin x.size < 0 end ispositive(x::BigInt) = begin x.size > 0 end signbit(x::BigInt) = begin isnegative(x) end flipsign!(x::BigInt, y::Integer) = begin signbit(y) && (x.size = -(x.size)) x end flipsign(x::BigInt, y::Integer) = begin if signbit(y) -x else x end end flipsign(x::BigInt, y::BigInt) = begin if signbit(y) -x else x end end function sign(x::BigInt) isnegative(x) && return -(one(x)) ispositive(x) && return one(x) return x end show(io::IO, x::BigInt) = begin print(io, string(x)) end function string(n::BigInt; base::Integer = 10, pad::Integer = 1) base < 0 && return Base._base(Int(base), n, pad, (base > 0) & (n.size < 0)) 2 <= base <= 62 || throw(ArgumentError("base must be 2 ≤ base ≤ 62, got $(base)")) iszero(n) && (pad < 1 && return "") nd1 = ndigits(n, base = base) nd = max(nd1, pad) sv = Base.StringMemory(nd + isnegative(n)) GC.@preserve sv MPZ.get_str!((pointer(sv) + nd) - nd1, base, n) @inbounds for i = (1:nd - nd1) .+ isnegative(n) sv[i] = '0' % UInt8 end isnegative(n) && (sv[1] = '-' % UInt8) unsafe_takestring(sv) end function digits!(a::AbstractVector{T}, n::BigInt; base::Integer = 10) where T <: Integer if base ≥ 2 if base ≤ 62 s = codeunits(string(n; base)) (i, j) = (firstindex(a) - 1, length(s) + 1) lasti = min(lastindex(a), ((firstindex(a) + length(s)) - 1) - isnegative(n)) while i < lasti x = s[j -= 1] a[i += 1] = if base ≤ 36 if x > 0x39 x - 0x57 else x - 0x30 end else if x > 0x39 if x > 0x60 x - 0x3d else x - 0x37 end else x - 0x30 end end end lasti = lastindex(a) while i < lasti a[i += 1] = zero(T) end return if isnegative(n) map!(-, a, a) else a end elseif a isa StridedVector{<:Base.BitInteger} && (stride(a, 1) == 1 && (ispow2(base) && base - 1 ≤ typemax(T))) origlen = length(a) (_, writelen) = MPZ.export!(a, n; nails = 8 * sizeof(T) - trailing_zeros(base)) length(a) != origlen && resize!(a, origlen) a[var"begin" + writelen:var"end"] .= zero(T) return if isnegative(n) map!(-, a, a) else a end end end return invoke(digits!, Tuple{typeof(a), Integer}, a, n; base) end function ndigits0zpb(x::BigInt, b::Integer) b < 2 && throw(DomainError(b, "`b` cannot be less than 2.")) x.size == 0 && return 0 if ispow2(b) && 2 <= b <= 62 MPZ.sizeinbase(x, b) else n = MPZ.sizeinbase(x, 2) lb = log2(b) (q, r) = divrem(n, lb) iq = Int(q) maxerr = q * eps(lb) if r - 1.0 < maxerr if abs(x) >= big(b) ^ iq iq + 1 else iq end elseif lb - r < maxerr if abs(x) >= big(b) ^ (iq + 1) iq + 2 else iq + 1 end else iq + 1 end end end _prevpow2(x::BigInt) = begin if -2 <= x <= 2 x else flipsign!(ONE << (ndigits(x, base = 2) - 1), x) end end _nextpow2(x::BigInt) = begin if count_ones_abs(x) <= 1 x else flipsign!(ONE << ndigits(x, base = 2), x) end end Base.checked_abs(x::BigInt) = begin abs(x) end Base.checked_neg(x::BigInt) = begin -x end Base.checked_add(a::BigInt, b::BigInt) = begin a + b end Base.checked_sub(a::BigInt, b::BigInt) = begin a - b end Base.checked_mul(a::BigInt, b::BigInt) = begin a * b end Base.checked_div(a::BigInt, b::BigInt) = begin div(a, b) end Base.checked_rem(a::BigInt, b::BigInt) = begin rem(a, b) end Base.checked_fld(a::BigInt, b::BigInt) = begin fld(a, b) end Base.checked_mod(a::BigInt, b::BigInt) = begin mod(a, b) end Base.checked_cld(a::BigInt, b::BigInt) = begin cld(a, b) end Base.add_with_overflow(a::BigInt, b::BigInt) = begin (a + b, false) end Base.sub_with_overflow(a::BigInt, b::BigInt) = begin (a - b, false) end Base.mul_with_overflow(a::BigInt, b::BigInt) = begin (a * b, false) end Base.checked_pow(x::BigInt, p::Integer) = begin x ^ p end Base.checked_pow(x::Integer, p::BigInt) = begin x ^ p end Base.checked_pow(x::BigInt, p::BigInt) = begin x ^ p end Base.deepcopy_internal(x::BigInt, stackdict::IdDict) = begin get!((()->begin MPZ.set(x) end), stackdict, x)::BigInt end Base._hash_shl!(x::BigInt, n) = begin MPZ.mul_2exp!(x, n) end if Limb === UInt64 === UInt using .Base: HASH_SECRET, hash_bytes, hash_finalizer struct UnsafeLimbView <: AbstractVector{UInt8} bigint::BigInt start_byte::Int num_bytes::Int end function Base.size(view::UnsafeLimbView) return (view.num_bytes,) end function Base.getindex(view::UnsafeLimbView, i::Int) @boundscheck checkbounds(view, i) GC.@preserve view begin limb_index = div((view.start_byte + i) - 2, 8) + 1 byte_in_limb = ((view.start_byte + i) - 2) % 8 limb = unsafe_load(view.bigint.d, limb_index) return UInt8(limb >> (8byte_in_limb) & 0xff) end end function Base.iterate(view::UnsafeLimbView, state::Int = 1) state > view.num_bytes && return nothing return (@inbounds(view[state]), state + 1) end function Base.length(view::UnsafeLimbView) return view.num_bytes end function hash_integer(n::BigInt, h::UInt) iszero(n) && return hash_integer(0, h) s = n.size h ⊻= s < 0 us = abs(s) leading_zero_bytes = div(leading_zeros(unsafe_load(n.d, us)), 8) num_bytes = 8us - leading_zero_bytes limb_view = UnsafeLimbView(n, 1, num_bytes) return hash_bytes(limb_view, h, HASH_SECRET) end function hash(x::BigInt, h::UInt) GC.@preserve x begin sz = x.size sz == 0 && return hash(0, h) ptr = Ptr{UInt64}(x.d) if sz == 1 return hash(unsafe_load(ptr), h) elseif sz == -1 limb = unsafe_load(ptr) limb <= typemin(Int) % UInt && return hash(-(limb % Int), h) end pow = trailing_zeros(x) nd = Base.ndigits0z(x, 2) idx = pow >>> 6 + 1 shift = (pow & 63) % UInt upshift = BITS_PER_LIMB - shift asz = abs(sz) if shift == 0 limb = unsafe_load(ptr, idx) else limb1 = unsafe_load(ptr, idx) limb2 = if idx < asz unsafe_load(ptr, idx + 1) else UInt(0) end limb = limb2 << upshift | limb1 >> shift end if nd <= 1024 && nd - pow <= 53 return hash(ldexp(flipsign(Float64(limb), sz), pow), h) end h = hash_integer(pow, h) h ⊻= sz < 0 leading_zero_bytes = div(leading_zeros(unsafe_load(x.d, asz)), 8) trailing_zero_bytes = div(pow, 8) num_bytes = 8asz - (leading_zero_bytes + trailing_zero_bytes) limb_view = UnsafeLimbView(x, trailing_zero_bytes + 1, num_bytes) return hash_bytes(limb_view, h, HASH_SECRET) end end end module MPQ import .Base: unsafe_rational, __throw_rational_argerror_zero import ..GMP: BigInt, MPZ, Limb, libgmp gmpq(op::Symbol) = begin Expr(:tuple, QuoteNode(Symbol(:__gmpq_, op)), GlobalRef(MPZ, :libgmp)) end mutable struct _MPQ num_alloc::Cint num_size::Cint num_d::Ptr{Limb} den_alloc::Cint den_size::Cint den_d::Ptr{Limb} rat::Rational{BigInt} end const mpq_t = Ref{_MPQ} _MPQ(x::BigInt, y::BigInt) = begin _MPQ(x.alloc, x.size, x.d, y.alloc, y.size, y.d, unsafe_rational(BigInt, x, y)) end _MPQ() = begin _MPQ(BigInt(), BigInt()) end _MPQ(x::Rational{BigInt}) = begin _MPQ(x.num, x.den) end function sync_rational!(xq::_MPQ) xq.rat.num.alloc = xq.num_alloc xq.rat.num.size = xq.num_size xq.rat.num.d = xq.num_d xq.rat.den.alloc = xq.den_alloc xq.rat.den.size = xq.den_size xq.rat.den.d = xq.den_d return xq.rat end function Rational{BigInt}(num::BigInt, den::BigInt) if iszero(den) iszero(num) && __throw_rational_argerror_zero(BigInt) return set_si(flipsign(1, num), 0) end xq = _MPQ(MPZ.set(num), MPZ.set(den)) ccall((:__gmpq_canonicalize, libgmp), Cvoid, (mpq_t,), xq) return sync_rational!(xq) end function set!(z::Rational{BigInt}, x::Rational{BigInt}) zq = _MPQ(z) ccall((:__gmpq_set, libgmp), Cvoid, (mpq_t, mpq_t), zq, _MPQ(x)) return sync_rational!(zq) end function set_z!(z::Rational{BigInt}, x::BigInt) zq = _MPQ(z) ccall((:__gmpq_set_z, libgmp), Cvoid, (mpq_t, MPZ.mpz_t), zq, x) return sync_rational!(zq) end for (op, T) = ((:set, Rational{BigInt}), (:set_z, BigInt)) op! = Symbol(op, :!) @eval ($op)(a::$T) = begin ($op!)(unsafe_rational(BigInt(), BigInt()), a) end end for (op, T1, T2) = ((:set_ui, Culong, Culong), (:set_si, Clong, Culong)) op! = Symbol(op, :!) @eval begin function ($op!)(z::Rational{BigInt}, a, b) zq = _MPQ(z) ccall($(gmpq(op)), Cvoid, (mpq_t, $T1, $T2), zq, a, b) return sync_rational!(zq) end ($op)(a, b) = begin ($op!)(unsafe_rational(BigInt(), BigInt()), a, b) end end end function add!(z::Rational{BigInt}, x::Rational{BigInt}, y::Rational{BigInt}) if iszero(x.den) || iszero(y.den) if iszero(x.den) && (iszero(y.den) && isnegative(x.num) != isnegative(y.num)) throw(DivideError()) end return set!(z, if iszero(x.den) x else y end) end zq = _MPQ(z) ccall((:__gmpq_add, libgmp), Cvoid, (mpq_t, mpq_t, mpq_t), zq, _MPQ(x), _MPQ(y)) return sync_rational!(zq) end function sub!(z::Rational{BigInt}, x::Rational{BigInt}, y::Rational{BigInt}) if iszero(x.den) || iszero(y.den) if iszero(x.den) && (iszero(y.den) && isnegative(x.num) == isnegative(y.num)) throw(DivideError()) end iszero(x.den) && return set!(z, x) return set_si!(z, flipsign(-1, y.num), 0) end zq = _MPQ(z) ccall((:__gmpq_sub, libgmp), Cvoid, (mpq_t, mpq_t, mpq_t), zq, _MPQ(x), _MPQ(y)) return sync_rational!(zq) end function mul!(z::Rational{BigInt}, x::Rational{BigInt}, y::Rational{BigInt}) if iszero(x.den) || iszero(y.den) if iszero(x.num) || iszero(y.num) throw(DivideError()) end return set_si!(z, ifelse(xor(isnegative(x.num), isnegative(y.num)), -1, 1), 0) end zq = _MPQ(z) ccall((:__gmpq_mul, libgmp), Cvoid, (mpq_t, mpq_t, mpq_t), zq, _MPQ(x), _MPQ(y)) return sync_rational!(zq) end function div!(z::Rational{BigInt}, x::Rational{BigInt}, y::Rational{BigInt}) if iszero(x.den) if iszero(y.den) throw(DivideError()) end isnegative(y.num) || return set!(z, x) return set_si!(z, flipsign(-1, x.num), 0) elseif iszero(y.den) return set_si!(z, 0, 1) elseif iszero(y.num) if iszero(x.num) throw(DivideError()) end return set_si!(z, flipsign(1, x.num), 0) end zq = _MPQ(z) ccall((:__gmpq_div, libgmp), Cvoid, (mpq_t, mpq_t, mpq_t), zq, _MPQ(x), _MPQ(y)) return sync_rational!(zq) end for (fJ, fC) = ((:+, :add), (:-, :sub), (:*, :mul), (://, :div)) fC! = Symbol(fC, :!) @eval begin ($fC!)(x::Rational{BigInt}, y::Rational{BigInt}) = begin ($fC!)(x, x, y) end Base.:($fJ)(x::Rational{BigInt}, y::Rational{BigInt}) = begin ($fC!)(unsafe_rational(BigInt(), BigInt()), x, y) end end end function Base.cmp(x::Rational{BigInt}, y::Rational{BigInt}) Int(ccall((:__gmpq_cmp, libgmp), Cint, (mpq_t, mpq_t), _MPQ(x), _MPQ(y))) end end end Parsing files in Base: Test Failed at /home/pkgeval/.julia/packages/CSTParser/0hXvH/test/test_check_base.jl:166 Expression: false Stacktrace: [1] macro expansion @ /opt/julia/share/julia/stdlib/v1.14/Test/src/Test.jl:753 [inlined] [2] top-level scope @ ~/.julia/packages/CSTParser/0hXvH/test/test_check_base.jl:166 ┌ Error: parsing difference │ file = "/opt/julia/bin/../share/julia/stdlib/v1.14/Distributed/src/workerpool.jl" └ @ Main.var"##296" ~/.julia/packages/CSTParser/0hXvH/test/test_check_base.jl:157 false begin end try wait(x) finally put!(pool, worker) end try wait(x) catch finally put!(pool, worker) end Threads.@spawn Threads.threadpool() try wait(x) finally put!(pool, worker) end Threads.@spawn Threads.threadpool() try wait(x) catch finally put!(pool, worker) end t = Threads.@spawn(Threads.threadpool(), try wait(x) finally put!(pool, worker) end) t = Threads.@spawn(Threads.threadpool(), try wait(x) catch finally put!(pool, worker) end) begin worker = take!(pool) local x try x = rc_f(f, worker, args...; kwargs...) catch put!(pool, worker) rethrow() end t = Threads.@spawn(Threads.threadpool(), try wait(x) finally put!(pool, worker) end) errormonitor(t) return x end begin worker = take!(pool) local x try x = rc_f(f, worker, args...; kwargs...) catch put!(pool, worker) rethrow() end t = Threads.@spawn(Threads.threadpool(), try wait(x) catch finally put!(pool, worker) end) errormonitor(t) return x end function remotecall_pool(rc_f::typeof(remotecall), f, pool::AbstractWorkerPool, args...; kwargs...) worker = take!(pool) local x try x = rc_f(f, worker, args...; kwargs...) catch put!(pool, worker) rethrow() end t = Threads.@spawn(Threads.threadpool(), try wait(x) finally put!(pool, worker) end) errormonitor(t) return x end function remotecall_pool(rc_f::typeof(remotecall), f, pool::AbstractWorkerPool, args...; kwargs...) worker = take!(pool) local x try x = rc_f(f, worker, args...; kwargs...) catch put!(pool, worker) rethrow() end t = Threads.@spawn(Threads.threadpool(), try wait(x) catch finally put!(pool, worker) end) errormonitor(t) return x end false begin end try wait(x) finally put!(pool, worker) end try wait(x) catch finally put!(pool, worker) end Threads.@spawn Threads.threadpool() try wait(x) finally put!(pool, worker) end Threads.@spawn Threads.threadpool() try wait(x) catch finally put!(pool, worker) end t = Threads.@spawn(Threads.threadpool(), try wait(x) finally put!(pool, worker) end) t = Threads.@spawn(Threads.threadpool(), try wait(x) catch finally put!(pool, worker) end) begin worker = take!(pool) f_ref = get(pool.map_obj2ref, (worker, f), (f, RemoteChannel(worker))) f_ref isa Tuple && (pool.map_obj2ref[(worker, f)] = f_ref[2]) local x try x = rc_f(exec_from_cache, worker, f_ref, args...; kwargs...) catch put!(pool, worker) rethrow() end t = Threads.@spawn(Threads.threadpool(), try wait(x) finally put!(pool, worker) end) errormonitor(t) return x end begin worker = take!(pool) f_ref = get(pool.map_obj2ref, (worker, f), (f, RemoteChannel(worker))) f_ref isa Tuple && (pool.map_obj2ref[(worker, f)] = f_ref[2]) local x try x = rc_f(exec_from_cache, worker, f_ref, args...; kwargs...) catch put!(pool, worker) rethrow() end t = Threads.@spawn(Threads.threadpool(), try wait(x) catch finally put!(pool, worker) end) errormonitor(t) return x end function remotecall_pool(rc_f::typeof(remotecall), f, pool::CachingPool, args...; kwargs...) worker = take!(pool) f_ref = get(pool.map_obj2ref, (worker, f), (f, RemoteChannel(worker))) f_ref isa Tuple && (pool.map_obj2ref[(worker, f)] = f_ref[2]) local x try x = rc_f(exec_from_cache, worker, f_ref, args...; kwargs...) catch put!(pool, worker) rethrow() end t = Threads.@spawn(Threads.threadpool(), try wait(x) finally put!(pool, worker) end) errormonitor(t) return x end function remotecall_pool(rc_f::typeof(remotecall), f, pool::CachingPool, args...; kwargs...) worker = take!(pool) f_ref = get(pool.map_obj2ref, (worker, f), (f, RemoteChannel(worker))) f_ref isa Tuple && (pool.map_obj2ref[(worker, f)] = f_ref[2]) local x try x = rc_f(exec_from_cache, worker, f_ref, args...; kwargs...) catch put!(pool, worker) rethrow() end t = Threads.@spawn(Threads.threadpool(), try wait(x) catch finally put!(pool, worker) end) errormonitor(t) return x end Parsing files in Base: Test Failed at /home/pkgeval/.julia/packages/CSTParser/0hXvH/test/test_check_base.jl:166 Expression: false Stacktrace: [1] macro expansion @ /opt/julia/share/julia/stdlib/v1.14/Test/src/Test.jl:753 [inlined] [2] top-level scope @ ~/.julia/packages/CSTParser/0hXvH/test/test_check_base.jl:166 ┌ Error: parsing difference │ file = "/opt/julia/bin/../share/julia/stdlib/v1.14/InteractiveUtils/test/runtests.jl" └ @ Main.var"##296" ~/.julia/packages/CSTParser/0hXvH/test/test_check_base.jl:157 @code_typed optimize = false ::Vector{Int} .= ::Int @code_typed optimize = (false::Vector{Int} .= ::Int) false false::Vector{Int} .= ::Int optimize = false optimize = (false::Vector{Int} .= ::Int) @code_typed optimize = false ::Vector{Int} .= ::Int @code_typed optimize = (false::Vector{Int} .= ::Int) (@code_typed(optimize = false, ::Vector{Int} .= ::Int))[2] (@code_typed(optimize = (false::Vector{Int} .= ::Int)))[2] (@code_typed(optimize = false, ::Vector{Int} .= ::Int))[2] == Vector{Int} (@code_typed(optimize = (false::Vector{Int} .= ::Int)))[2] == Vector{Int} @test (@code_typed(optimize = false, ::Vector{Int} .= ::Int))[2] == Vector{Int} @test (@code_typed(optimize = (false::Vector{Int} .= ::Int)))[2] == Vector{Int} @code_typed optimize = false ::Vector{Float64} .= 1 .+ ::Vector{Int} @code_typed optimize = (false::Vector{Float64} .= 1 .+ ::Vector{Int}) false false::Vector{Float64} .= 1 .+ ::Vector{Int} optimize = false optimize = (false::Vector{Float64} .= 1 .+ ::Vector{Int}) @code_typed optimize = false ::Vector{Float64} .= 1 .+ ::Vector{Int} @code_typed optimize = (false::Vector{Float64} .= 1 .+ ::Vector{Int}) (@code_typed(optimize = false, ::Vector{Float64} .= 1 .+ ::Vector{Int}))[2] (@code_typed(optimize = (false::Vector{Float64} .= 1 .+ ::Vector{Int})))[2] (@code_typed(optimize = false, ::Vector{Float64} .= 1 .+ ::Vector{Int}))[2] == Vector{Float64} (@code_typed(optimize = (false::Vector{Float64} .= 1 .+ ::Vector{Int})))[2] == Vector{Float64} @test (@code_typed(optimize = false, ::Vector{Float64} .= 1 .+ ::Vector{Int}))[2] == Vector{Float64} @test (@code_typed(optimize = (false::Vector{Float64} .= 1 .+ ::Vector{Int})))[2] == Vector{Float64} @code_typed optimize = false ::Vector{Float64} .= 1 .+ round.(base = ::Int, ::Vector{Int}; digits = 3) @code_typed optimize = (false::Vector{Float64} .= 1 .+ round.(base = ::Int, ::Vector{Int}; digits = 3)) false false::Vector{Float64} .= 1 .+ round.(base = ::Int, ::Vector{Int}; digits = 3) optimize = false optimize = (false::Vector{Float64} .= 1 .+ round.(base = ::Int, ::Vector{Int}; digits = 3)) @code_typed optimize = false ::Vector{Float64} .= 1 .+ round.(base = ::Int, ::Vector{Int}; digits = 3) @code_typed optimize = (false::Vector{Float64} .= 1 .+ round.(base = ::Int, ::Vector{Int}; digits = 3)) (@code_typed(optimize = false, ::Vector{Float64} .= 1 .+ round.(base = ::Int, ::Vector{Int}; digits = 3)))[2] (@code_typed(optimize = (false::Vector{Float64} .= 1 .+ round.(base = ::Int, ::Vector{Int}; digits = 3))))[2] (@code_typed(optimize = false, ::Vector{Float64} .= 1 .+ round.(base = ::Int, ::Vector{Int}; digits = 3)))[2] == Vector{Float64} (@code_typed(optimize = (false::Vector{Float64} .= 1 .+ round.(base = ::Int, ::Vector{Int}; digits = 3))))[2] == Vector{Float64} @test (@code_typed(optimize = false, ::Vector{Float64} .= 1 .+ round.(base = ::Int, ::Vector{Int}; digits = 3)))[2] == Vector{Float64} @test (@code_typed(optimize = (false::Vector{Float64} .= 1 .+ round.(base = ::Int, ::Vector{Int}; digits = 3))))[2] == Vector{Float64} begin @test (@code_typed(optimize = false, round.([1.0, 2.0]; digits = ::Int64)))[2] == Vector{Float64} @test (@code_typed(optimize = false, round.(::Vector{Float64}, base = 2; digits = ::Int64)))[2] == Vector{Float64} @test (@code_typed(optimize = false, round.(base = ::Int64, ::Vector{Float64}; digits = ::Int64)))[2] == Vector{Float64} @test (@code_typed(optimize = false, [1, 2] .= ::Int))[2] == Vector{Int} @test (@code_typed(optimize = false, ::Vector{Int} .= ::Int))[2] == Vector{Int} @test (@code_typed(optimize = false, ::Vector{Float64} .= 1 .+ ::Vector{Int}))[2] == Vector{Float64} @test (@code_typed(optimize = false, ::Vector{Float64} .= 1 .+ round.(base = ::Int, ::Vector{Int}; digits = 3)))[2] == Vector{Float64} end begin @test (@code_typed(optimize = false, round.([1.0, 2.0]; digits = ::Int64)))[2] == Vector{Float64} @test (@code_typed(optimize = false, round.(::Vector{Float64}, base = 2; digits = ::Int64)))[2] == Vector{Float64} @test (@code_typed(optimize = false, round.(base = ::Int64, ::Vector{Float64}; digits = ::Int64)))[2] == Vector{Float64} @test (@code_typed(optimize = false, [1, 2] .= ::Int))[2] == Vector{Int} @test (@code_typed(optimize = (false::Vector{Int} .= ::Int)))[2] == Vector{Int} @test (@code_typed(optimize = (false::Vector{Float64} .= 1 .+ ::Vector{Int})))[2] == Vector{Float64} @test (@code_typed(optimize = (false::Vector{Float64} .= 1 .+ round.(base = ::Int, ::Vector{Int}; digits = 3))))[2] == Vector{Float64} end @testset "Broadcasting" begin @test (@code_typed(optimize = false, round.([1.0, 2.0]; digits = ::Int64)))[2] == Vector{Float64} @test (@code_typed(optimize = false, round.(::Vector{Float64}, base = 2; digits = ::Int64)))[2] == Vector{Float64} @test (@code_typed(optimize = false, round.(base = ::Int64, ::Vector{Float64}; digits = ::Int64)))[2] == Vector{Float64} @test (@code_typed(optimize = false, [1, 2] .= ::Int))[2] == Vector{Int} @test (@code_typed(optimize = false, ::Vector{Int} .= ::Int))[2] == Vector{Int} @test (@code_typed(optimize = false, ::Vector{Float64} .= 1 .+ ::Vector{Int}))[2] == Vector{Float64} @test (@code_typed(optimize = false, ::Vector{Float64} .= 1 .+ round.(base = ::Int, ::Vector{Int}; digits = 3)))[2] == Vector{Float64} end @testset "Broadcasting" begin @test (@code_typed(optimize = false, round.([1.0, 2.0]; digits = ::Int64)))[2] == Vector{Float64} @test (@code_typed(optimize = false, round.(::Vector{Float64}, base = 2; digits = ::Int64)))[2] == Vector{Float64} @test (@code_typed(optimize = false, round.(base = ::Int64, ::Vector{Float64}; digits = ::Int64)))[2] == Vector{Float64} @test (@code_typed(optimize = false, [1, 2] .= ::Int))[2] == Vector{Int} @test (@code_typed(optimize = (false::Vector{Int} .= ::Int)))[2] == Vector{Int} @test (@code_typed(optimize = (false::Vector{Float64} .= 1 .+ ::Vector{Int})))[2] == Vector{Float64} @test (@code_typed(optimize = (false::Vector{Float64} .= 1 .+ round.(base = ::Int, ::Vector{Int}; digits = 3))))[2] == Vector{Float64} end begin @testset "`getindex`/`setindex!`" begin @test (@which((::Vector{Int})[::Int])).name === :getindex @test (@which(([1, 2])[::Int])).name === :getindex @test (@which(([1 2])[var"begin", ::Int])).name === :getindex @test (@which(([1 2])[::Int, var"end"])).name === :getindex @test (@which(([1 2])[var"begin", var"end"])).name === :getindex @test (@which(([1 2])[1:var"end"])).name === :getindex @test (@which(([1 2])[var"begin":var"end"])).name === :getindex @test_throws "`begin` or `end` cannot be used" @which((::Vector{Int})[var"begin"]) @test_throws "`begin` or `end` cannot be used" @which((::Vector{Int})[var"end"]) @test (@which((::Vector{Int})[::Int] = ::Int)).name === :setindex! end @testset "`getproperty`/`setproperty!`" begin @test (@which((::Base.RefValue{Int}).x)).name === :getproperty @test (@which((::Base.RefValue{Int}).x = ::Int)).name === :setproperty! end @testset "Array syntax" begin @test (@which([::Int])).name === :vect @test (@which([undef_var::Int])).name === :vect @test (@which([::Int 2])).name === :hcat @test (@which([::Int; 2])).name === :vcat @test (@which(Int[::Int 2])).name === :typed_hcat @test (@which(Int[::Int; 2])).name === :typed_vcat @test (@which([::Int 2; 3 ::Int])).name === :hvcat @test (@which(Int[::Int 2; 3 ::Int])).name === :typed_hvcat @test (@which(::Type{Int}[::Int 2; 3 ::Int])).name === :typed_hvcat @test (@which(::Type{T}[::T 2; 3 ::T] where T <: Real)).name === :typed_hvcat end @test (@which(::Float64 ^ 2)).name === :literal_pow @test (@which((::Vector{Float64})')).name === :adjoint @test (@which("$(::Symbol) is a symbol")).sig === Tuple{typeof(string), Vararg{Union{Char, String, Symbol}}} @test (@which(::Int ^ 4)).name === :literal_pow @test (@which(some_x::Int + some_y::Float64)).name === :+ @test (@which(+(::Any, ::Any, ::Any, ::Any...))).sig === Tuple{typeof(+), Any, Any, Any, Vararg{Any}} @test (@which(::Any + ::Any + ::Any + ::Vararg{Any})).sig === Tuple{typeof(+), Any, Any, Any, Vararg{Any}} n = length(@code_typed(::Float64 + ::Vararg{Float64})) @test n ≥ 2 @test length(@code_typed(+(::Float64, ::Float64...))) == n @test (@which(1 + ::Float64)).sig === Tuple{typeof(+), Number, Number} @test (@which(+(((1, 2)...)))).name === :+ @test (@which((::typeof(+))(::Int, ::Float64))).sig === Tuple{typeof(+), Number, Number} @test @code_typed(::Float64 .+ ::Vector{Float64}) isa Pair @test @code_typed(::Float64 .+ ::Vector{Float64} .* ::Int) isa Pair @test (@which((::T + ::T) where T <: Number)).sig === (Tuple{typeof(+), T, T} where T <: Number) @testset "Keyword arguments" begin @test (@which(round(::Float64; digits = 3))).name === :round @test (@which(round(1.2; digits = ::Int))).name === :round @test (@which(round(1.2; digits::Int))).name === :round @test (@code_typed(round(::T; digits = ::T) where T <: Float64))[2] === Union{} @test (@code_typed(round(::T; digits = ::T) where T <: Int))[2] === Float64 base = 10 kwargs_1 = (; digits = 3) kwargs_2 = (; sigdigits = 3) @test (@which(round(1.2; kwargs_1...))).name === :round @test (@which(round(1.2; digits = 1, kwargs_1...))).name === :round @test (@code_typed(round(1.2; digits = ::Float64, kwargs_1...)))[2] === Float64 @test (@code_typed(round(1.2; kwargs_1..., digits = ::Float64)))[2] === Union{} @test (@which(round(1.2; digits = ::Float64, kwargs_1...))).name === :round @test (@which(round(1.2; sigdigits = ::Int, kwargs_1...))).name === :round @test (@which(round(1.2; kwargs_1..., kwargs_2..., base))).name === :round end @testset "Broadcasting" begin @test (@code_typed(optimize = false, round.([1.0, 2.0]; digits = ::Int64)))[2] == Vector{Float64} @test (@code_typed(optimize = false, round.(::Vector{Float64}, base = 2; digits = ::Int64)))[2] == Vector{Float64} @test (@code_typed(optimize = false, round.(base = ::Int64, ::Vector{Float64}; digits = ::Int64)))[2] == Vector{Float64} @test (@code_typed(optimize = false, [1, 2] .= ::Int))[2] == Vector{Int} @test (@code_typed(optimize = false, ::Vector{Int} .= ::Int))[2] == Vector{Int} @test (@code_typed(optimize = false, ::Vector{Float64} .= 1 .+ ::Vector{Int}))[2] == Vector{Float64} @test (@code_typed(optimize = false, ::Vector{Float64} .= 1 .+ round.(base = ::Int, ::Vector{Int}; digits = 3)))[2] == Vector{Float64} end @testset "Callable objects" begin @test (@code_typed((::Base.Fix2{typeof(+), Float64})(3)))[2] === Float64 @test (@code_typed(optimize = false, (::Returns{Float64})(::Int64; name::String)))[2] === Float64 @test (@code_typed((::Returns{T})(3.0) where T <: Real))[2] === Real end @testset "Opaque closures" begin opaque_f(@nospecialize(x::Type), @nospecialize(y::Type)) = begin sizeof(x) == sizeof(y) end (src, _) = only(code_typed(opaque_f, (Type, Type))) src.slottypes[1] = Tuple{} oc = Core.OpaqueClosure(src; sig = Tuple{Type, Type}, rettype = Bool, nargs = 2) ret = @code_typed(oc(Int64, Float64)) @test [ret] == code_typed(oc) (_, rt) = ret @test rt === Bool ir = Core.Compiler.inflate_ir(src) oc = Core.OpaqueClosure(ir) ret = @code_typed(oc(Int64, Float64)) @test [ret] == code_typed(oc) (_, rt) = ret @test rt === Bool end @testset "Vararg handling" begin @test_throws "More than one `Core.Vararg`" @eval(@code_typed(1 + 2::Vararg{Int} + 3 + 4::Vararg{Float64})) @test_throws "Inconsistent type `Float64`" @eval(@code_typed(1 + 2 + 3 + 4::Vararg{Int} + 5.0)) @test_throws "Inconsistent type `Float64`" @eval(@code_typed(+(1, 2, 3, 4::Int..., 5.0))) @test_throws "Inconsistent type `Float64`" @eval(@code_typed(1 + 2 + 3 + 4::Vararg{Int} + ::Float64)) @test_throws "Inconsistent type `Any`" @eval(@code_typed(1 + 2 + 3 + 4::Vararg{Int} + ::Any)) @test_throws r"at most 2 types .* found 3 instead" @eval(@code_typed(1 + 2 + 3 + 4::Vararg{Int, 2} + 5 + 6)) @test (@code_typed(1 + 2 + 3 + 4::Vararg{Int}))[2] === Int @test (@code_typed(1 + 2 + 3 + 4::Vararg{Int} + 5))[2] === Int @test (@code_typed(1 + 2 + 3 + 4::Vararg{Int, 3}))[2] === Int @test (@code_typed(1 + 2 + 3 + 4::Vararg{Int, 3} + 5))[2] === Int @test (@code_typed(1 + 2 + 3 + 4::Vararg{Int, 3} + 5 + 6))[2] === Int @test (@code_typed(1 + 2 + 3 + 4::Vararg))[2] === Any @test (@code_typed(1 + 2 + 3 + 4::Vararg + 5.0))[2] === Any @test (@code_typed(+(1, 2, 3, ::Int...)))[2] === Int @test (@code_typed(+(1, 2, 3, ::Int..., 5)))[2] === Int @test @code_typed((::T + ::Vararg{T} + ::T) where T) isa Vector{Any} @test @code_typed((::T + ::Vararg{T} + ::Float64) where T <: Real) isa Vector{Any} @test @code_typed((::T + ::Vararg{T} + ::Float64) where T <: Real) isa Vector{Any} @test @code_typed((::T + ::Vararg{T} + ::Int) where T <: Real) isa Vector{Any} @test @code_typed((::T + ::Vararg{Vector{T}} + ::Int) where T <: Real) isa Vector{Any} @test @code_typed((::T + ::Vararg{Int} + ::T) where T <: Real) isa Vector{Any} end end begin @testset "`getindex`/`setindex!`" begin @test (@which((::Vector{Int})[::Int])).name === :getindex @test (@which(([1, 2])[::Int])).name === :getindex @test (@which(([1 2])[var"begin", ::Int])).name === :getindex @test (@which(([1 2])[::Int, var"end"])).name === :getindex @test (@which(([1 2])[var"begin", var"end"])).name === :getindex @test (@which(([1 2])[1:var"end"])).name === :getindex @test (@which(([1 2])[var"begin":var"end"])).name === :getindex @test_throws "`begin` or `end` cannot be used" @which((::Vector{Int})[var"begin"]) @test_throws "`begin` or `end` cannot be used" @which((::Vector{Int})[var"end"]) @test (@which((::Vector{Int})[::Int] = ::Int)).name === :setindex! end @testset "`getproperty`/`setproperty!`" begin @test (@which((::Base.RefValue{Int}).x)).name === :getproperty @test (@which((::Base.RefValue{Int}).x = ::Int)).name === :setproperty! end @testset "Array syntax" begin @test (@which([::Int])).name === :vect @test (@which([undef_var::Int])).name === :vect @test (@which([::Int 2])).name === :hcat @test (@which([::Int; 2])).name === :vcat @test (@which(Int[::Int 2])).name === :typed_hcat @test (@which(Int[::Int; 2])).name === :typed_vcat @test (@which([::Int 2; 3 ::Int])).name === :hvcat @test (@which(Int[::Int 2; 3 ::Int])).name === :typed_hvcat @test (@which(::Type{Int}[::Int 2; 3 ::Int])).name === :typed_hvcat @test (@which(::Type{T}[::T 2; 3 ::T] where T <: Real)).name === :typed_hvcat end @test (@which(::Float64 ^ 2)).name === :literal_pow @test (@which((::Vector{Float64})')).name === :adjoint @test (@which("$(::Symbol) is a symbol")).sig === Tuple{typeof(string), Vararg{Union{Char, String, Symbol}}} @test (@which(::Int ^ 4)).name === :literal_pow @test (@which(some_x::Int + some_y::Float64)).name === :+ @test (@which(+(::Any, ::Any, ::Any, ::Any...))).sig === Tuple{typeof(+), Any, Any, Any, Vararg{Any}} @test (@which(::Any + ::Any + ::Any + ::Vararg{Any})).sig === Tuple{typeof(+), Any, Any, Any, Vararg{Any}} n = length(@code_typed(::Float64 + ::Vararg{Float64})) @test n ≥ 2 @test length(@code_typed(+(::Float64, ::Float64...))) == n @test (@which(1 + ::Float64)).sig === Tuple{typeof(+), Number, Number} @test (@which(+(((1, 2)...)))).name === :+ @test (@which((::typeof(+))(::Int, ::Float64))).sig === Tuple{typeof(+), Number, Number} @test @code_typed(::Float64 .+ ::Vector{Float64}) isa Pair @test @code_typed(::Float64 .+ ::Vector{Float64} .* ::Int) isa Pair @test (@which((::T + ::T) where T <: Number)).sig === (Tuple{typeof(+), T, T} where T <: Number) @testset "Keyword arguments" begin @test (@which(round(::Float64; digits = 3))).name === :round @test (@which(round(1.2; digits = ::Int))).name === :round @test (@which(round(1.2; digits::Int))).name === :round @test (@code_typed(round(::T; digits = ::T) where T <: Float64))[2] === Union{} @test (@code_typed(round(::T; digits = ::T) where T <: Int))[2] === Float64 base = 10 kwargs_1 = (; digits = 3) kwargs_2 = (; sigdigits = 3) @test (@which(round(1.2; kwargs_1...))).name === :round @test (@which(round(1.2; digits = 1, kwargs_1...))).name === :round @test (@code_typed(round(1.2; digits = ::Float64, kwargs_1...)))[2] === Float64 @test (@code_typed(round(1.2; kwargs_1..., digits = ::Float64)))[2] === Union{} @test (@which(round(1.2; digits = ::Float64, kwargs_1...))).name === :round @test (@which(round(1.2; sigdigits = ::Int, kwargs_1...))).name === :round @test (@which(round(1.2; kwargs_1..., kwargs_2..., base))).name === :round end @testset "Broadcasting" begin @test (@code_typed(optimize = false, round.([1.0, 2.0]; digits = ::Int64)))[2] == Vector{Float64} @test (@code_typed(optimize = false, round.(::Vector{Float64}, base = 2; digits = ::Int64)))[2] == Vector{Float64} @test (@code_typed(optimize = false, round.(base = ::Int64, ::Vector{Float64}; digits = ::Int64)))[2] == Vector{Float64} @test (@code_typed(optimize = false, [1, 2] .= ::Int))[2] == Vector{Int} @test (@code_typed(optimize = (false::Vector{Int} .= ::Int)))[2] == Vector{Int} @test (@code_typed(optimize = (false::Vector{Float64} .= 1 .+ ::Vector{Int})))[2] == Vector{Float64} @test (@code_typed(optimize = (false::Vector{Float64} .= 1 .+ round.(base = ::Int, ::Vector{Int}; digits = 3))))[2] == Vector{Float64} end @testset "Callable objects" begin @test (@code_typed((::Base.Fix2{typeof(+), Float64})(3)))[2] === Float64 @test (@code_typed(optimize = false, (::Returns{Float64})(::Int64; name::String)))[2] === Float64 @test (@code_typed((::Returns{T})(3.0) where T <: Real))[2] === Real end @testset "Opaque closures" begin opaque_f(@nospecialize(x::Type), @nospecialize(y::Type)) = begin sizeof(x) == sizeof(y) end (src, _) = only(code_typed(opaque_f, (Type, Type))) src.slottypes[1] = Tuple{} oc = Core.OpaqueClosure(src; sig = Tuple{Type, Type}, rettype = Bool, nargs = 2) ret = @code_typed(oc(Int64, Float64)) @test [ret] == code_typed(oc) (_, rt) = ret @test rt === Bool ir = Core.Compiler.inflate_ir(src) oc = Core.OpaqueClosure(ir) ret = @code_typed(oc(Int64, Float64)) @test [ret] == code_typed(oc) (_, rt) = ret @test rt === Bool end @testset "Vararg handling" begin @test_throws "More than one `Core.Vararg`" @eval(@code_typed(1 + 2::Vararg{Int} + 3 + 4::Vararg{Float64})) @test_throws "Inconsistent type `Float64`" @eval(@code_typed(1 + 2 + 3 + 4::Vararg{Int} + 5.0)) @test_throws "Inconsistent type `Float64`" @eval(@code_typed(+(1, 2, 3, 4::Int..., 5.0))) @test_throws "Inconsistent type `Float64`" @eval(@code_typed(1 + 2 + 3 + 4::Vararg{Int} + ::Float64)) @test_throws "Inconsistent type `Any`" @eval(@code_typed(1 + 2 + 3 + 4::Vararg{Int} + ::Any)) @test_throws r"at most 2 types .* found 3 instead" @eval(@code_typed(1 + 2 + 3 + 4::Vararg{Int, 2} + 5 + 6)) @test (@code_typed(1 + 2 + 3 + 4::Vararg{Int}))[2] === Int @test (@code_typed(1 + 2 + 3 + 4::Vararg{Int} + 5))[2] === Int @test (@code_typed(1 + 2 + 3 + 4::Vararg{Int, 3}))[2] === Int @test (@code_typed(1 + 2 + 3 + 4::Vararg{Int, 3} + 5))[2] === Int @test (@code_typed(1 + 2 + 3 + 4::Vararg{Int, 3} + 5 + 6))[2] === Int @test (@code_typed(1 + 2 + 3 + 4::Vararg))[2] === Any @test (@code_typed(1 + 2 + 3 + 4::Vararg + 5.0))[2] === Any @test (@code_typed(+(1, 2, 3, ::Int...)))[2] === Int @test (@code_typed(+(1, 2, 3, ::Int..., 5)))[2] === Int @test @code_typed((::T + ::Vararg{T} + ::T) where T) isa Vector{Any} @test @code_typed((::T + ::Vararg{T} + ::Float64) where T <: Real) isa Vector{Any} @test @code_typed((::T + ::Vararg{T} + ::Float64) where T <: Real) isa Vector{Any} @test @code_typed((::T + ::Vararg{T} + ::Int) where T <: Real) isa Vector{Any} @test @code_typed((::T + ::Vararg{Vector{T}} + ::Int) where T <: Real) isa Vector{Any} @test @code_typed((::T + ::Vararg{Int} + ::T) where T <: Real) isa Vector{Any} end end @testset "Support for type annotations as arguments" begin @testset "`getindex`/`setindex!`" begin @test (@which((::Vector{Int})[::Int])).name === :getindex @test (@which(([1, 2])[::Int])).name === :getindex @test (@which(([1 2])[var"begin", ::Int])).name === :getindex @test (@which(([1 2])[::Int, var"end"])).name === :getindex @test (@which(([1 2])[var"begin", var"end"])).name === :getindex @test (@which(([1 2])[1:var"end"])).name === :getindex @test (@which(([1 2])[var"begin":var"end"])).name === :getindex @test_throws "`begin` or `end` cannot be used" @which((::Vector{Int})[var"begin"]) @test_throws "`begin` or `end` cannot be used" @which((::Vector{Int})[var"end"]) @test (@which((::Vector{Int})[::Int] = ::Int)).name === :setindex! end @testset "`getproperty`/`setproperty!`" begin @test (@which((::Base.RefValue{Int}).x)).name === :getproperty @test (@which((::Base.RefValue{Int}).x = ::Int)).name === :setproperty! end @testset "Array syntax" begin @test (@which([::Int])).name === :vect @test (@which([undef_var::Int])).name === :vect @test (@which([::Int 2])).name === :hcat @test (@which([::Int; 2])).name === :vcat @test (@which(Int[::Int 2])).name === :typed_hcat @test (@which(Int[::Int; 2])).name === :typed_vcat @test (@which([::Int 2; 3 ::Int])).name === :hvcat @test (@which(Int[::Int 2; 3 ::Int])).name === :typed_hvcat @test (@which(::Type{Int}[::Int 2; 3 ::Int])).name === :typed_hvcat @test (@which(::Type{T}[::T 2; 3 ::T] where T <: Real)).name === :typed_hvcat end @test (@which(::Float64 ^ 2)).name === :literal_pow @test (@which((::Vector{Float64})')).name === :adjoint @test (@which("$(::Symbol) is a symbol")).sig === Tuple{typeof(string), Vararg{Union{Char, String, Symbol}}} @test (@which(::Int ^ 4)).name === :literal_pow @test (@which(some_x::Int + some_y::Float64)).name === :+ @test (@which(+(::Any, ::Any, ::Any, ::Any...))).sig === Tuple{typeof(+), Any, Any, Any, Vararg{Any}} @test (@which(::Any + ::Any + ::Any + ::Vararg{Any})).sig === Tuple{typeof(+), Any, Any, Any, Vararg{Any}} n = length(@code_typed(::Float64 + ::Vararg{Float64})) @test n ≥ 2 @test length(@code_typed(+(::Float64, ::Float64...))) == n @test (@which(1 + ::Float64)).sig === Tuple{typeof(+), Number, Number} @test (@which(+(((1, 2)...)))).name === :+ @test (@which((::typeof(+))(::Int, ::Float64))).sig === Tuple{typeof(+), Number, Number} @test @code_typed(::Float64 .+ ::Vector{Float64}) isa Pair @test @code_typed(::Float64 .+ ::Vector{Float64} .* ::Int) isa Pair @test (@which((::T + ::T) where T <: Number)).sig === (Tuple{typeof(+), T, T} where T <: Number) @testset "Keyword arguments" begin @test (@which(round(::Float64; digits = 3))).name === :round @test (@which(round(1.2; digits = ::Int))).name === :round @test (@which(round(1.2; digits::Int))).name === :round @test (@code_typed(round(::T; digits = ::T) where T <: Float64))[2] === Union{} @test (@code_typed(round(::T; digits = ::T) where T <: Int))[2] === Float64 base = 10 kwargs_1 = (; digits = 3) kwargs_2 = (; sigdigits = 3) @test (@which(round(1.2; kwargs_1...))).name === :round @test (@which(round(1.2; digits = 1, kwargs_1...))).name === :round @test (@code_typed(round(1.2; digits = ::Float64, kwargs_1...)))[2] === Float64 @test (@code_typed(round(1.2; kwargs_1..., digits = ::Float64)))[2] === Union{} @test (@which(round(1.2; digits = ::Float64, kwargs_1...))).name === :round @test (@which(round(1.2; sigdigits = ::Int, kwargs_1...))).name === :round @test (@which(round(1.2; kwargs_1..., kwargs_2..., base))).name === :round end @testset "Broadcasting" begin @test (@code_typed(optimize = false, round.([1.0, 2.0]; digits = ::Int64)))[2] == Vector{Float64} @test (@code_typed(optimize = false, round.(::Vector{Float64}, base = 2; digits = ::Int64)))[2] == Vector{Float64} @test (@code_typed(optimize = false, round.(base = ::Int64, ::Vector{Float64}; digits = ::Int64)))[2] == Vector{Float64} @test (@code_typed(optimize = false, [1, 2] .= ::Int))[2] == Vector{Int} @test (@code_typed(optimize = false, ::Vector{Int} .= ::Int))[2] == Vector{Int} @test (@code_typed(optimize = false, ::Vector{Float64} .= 1 .+ ::Vector{Int}))[2] == Vector{Float64} @test (@code_typed(optimize = false, ::Vector{Float64} .= 1 .+ round.(base = ::Int, ::Vector{Int}; digits = 3)))[2] == Vector{Float64} end @testset "Callable objects" begin @test (@code_typed((::Base.Fix2{typeof(+), Float64})(3)))[2] === Float64 @test (@code_typed(optimize = false, (::Returns{Float64})(::Int64; name::String)))[2] === Float64 @test (@code_typed((::Returns{T})(3.0) where T <: Real))[2] === Real end @testset "Opaque closures" begin opaque_f(@nospecialize(x::Type), @nospecialize(y::Type)) = begin sizeof(x) == sizeof(y) end (src, _) = only(code_typed(opaque_f, (Type, Type))) src.slottypes[1] = Tuple{} oc = Core.OpaqueClosure(src; sig = Tuple{Type, Type}, rettype = Bool, nargs = 2) ret = @code_typed(oc(Int64, Float64)) @test [ret] == code_typed(oc) (_, rt) = ret @test rt === Bool ir = Core.Compiler.inflate_ir(src) oc = Core.OpaqueClosure(ir) ret = @code_typed(oc(Int64, Float64)) @test [ret] == code_typed(oc) (_, rt) = ret @test rt === Bool end @testset "Vararg handling" begin @test_throws "More than one `Core.Vararg`" @eval(@code_typed(1 + 2::Vararg{Int} + 3 + 4::Vararg{Float64})) @test_throws "Inconsistent type `Float64`" @eval(@code_typed(1 + 2 + 3 + 4::Vararg{Int} + 5.0)) @test_throws "Inconsistent type `Float64`" @eval(@code_typed(+(1, 2, 3, 4::Int..., 5.0))) @test_throws "Inconsistent type `Float64`" @eval(@code_typed(1 + 2 + 3 + 4::Vararg{Int} + ::Float64)) @test_throws "Inconsistent type `Any`" @eval(@code_typed(1 + 2 + 3 + 4::Vararg{Int} + ::Any)) @test_throws r"at most 2 types .* found 3 instead" @eval(@code_typed(1 + 2 + 3 + 4::Vararg{Int, 2} + 5 + 6)) @test (@code_typed(1 + 2 + 3 + 4::Vararg{Int}))[2] === Int @test (@code_typed(1 + 2 + 3 + 4::Vararg{Int} + 5))[2] === Int @test (@code_typed(1 + 2 + 3 + 4::Vararg{Int, 3}))[2] === Int @test (@code_typed(1 + 2 + 3 + 4::Vararg{Int, 3} + 5))[2] === Int @test (@code_typed(1 + 2 + 3 + 4::Vararg{Int, 3} + 5 + 6))[2] === Int @test (@code_typed(1 + 2 + 3 + 4::Vararg))[2] === Any @test (@code_typed(1 + 2 + 3 + 4::Vararg + 5.0))[2] === Any @test (@code_typed(+(1, 2, 3, ::Int...)))[2] === Int @test (@code_typed(+(1, 2, 3, ::Int..., 5)))[2] === Int @test @code_typed((::T + ::Vararg{T} + ::T) where T) isa Vector{Any} @test @code_typed((::T + ::Vararg{T} + ::Float64) where T <: Real) isa Vector{Any} @test @code_typed((::T + ::Vararg{T} + ::Float64) where T <: Real) isa Vector{Any} @test @code_typed((::T + ::Vararg{T} + ::Int) where T <: Real) isa Vector{Any} @test @code_typed((::T + ::Vararg{Vector{T}} + ::Int) where T <: Real) isa Vector{Any} @test @code_typed((::T + ::Vararg{Int} + ::T) where T <: Real) isa Vector{Any} end end @testset "Support for type annotations as arguments" begin @testset "`getindex`/`setindex!`" begin @test (@which((::Vector{Int})[::Int])).name === :getindex @test (@which(([1, 2])[::Int])).name === :getindex @test (@which(([1 2])[var"begin", ::Int])).name === :getindex @test (@which(([1 2])[::Int, var"end"])).name === :getindex @test (@which(([1 2])[var"begin", var"end"])).name === :getindex @test (@which(([1 2])[1:var"end"])).name === :getindex @test (@which(([1 2])[var"begin":var"end"])).name === :getindex @test_throws "`begin` or `end` cannot be used" @which((::Vector{Int})[var"begin"]) @test_throws "`begin` or `end` cannot be used" @which((::Vector{Int})[var"end"]) @test (@which((::Vector{Int})[::Int] = ::Int)).name === :setindex! end @testset "`getproperty`/`setproperty!`" begin @test (@which((::Base.RefValue{Int}).x)).name === :getproperty @test (@which((::Base.RefValue{Int}).x = ::Int)).name === :setproperty! end @testset "Array syntax" begin @test (@which([::Int])).name === :vect @test (@which([undef_var::Int])).name === :vect @test (@which([::Int 2])).name === :hcat @test (@which([::Int; 2])).name === :vcat @test (@which(Int[::Int 2])).name === :typed_hcat @test (@which(Int[::Int; 2])).name === :typed_vcat @test (@which([::Int 2; 3 ::Int])).name === :hvcat @test (@which(Int[::Int 2; 3 ::Int])).name === :typed_hvcat @test (@which(::Type{Int}[::Int 2; 3 ::Int])).name === :typed_hvcat @test (@which(::Type{T}[::T 2; 3 ::T] where T <: Real)).name === :typed_hvcat end @test (@which(::Float64 ^ 2)).name === :literal_pow @test (@which((::Vector{Float64})')).name === :adjoint @test (@which("$(::Symbol) is a symbol")).sig === Tuple{typeof(string), Vararg{Union{Char, String, Symbol}}} @test (@which(::Int ^ 4)).name === :literal_pow @test (@which(some_x::Int + some_y::Float64)).name === :+ @test (@which(+(::Any, ::Any, ::Any, ::Any...))).sig === Tuple{typeof(+), Any, Any, Any, Vararg{Any}} @test (@which(::Any + ::Any + ::Any + ::Vararg{Any})).sig === Tuple{typeof(+), Any, Any, Any, Vararg{Any}} n = length(@code_typed(::Float64 + ::Vararg{Float64})) @test n ≥ 2 @test length(@code_typed(+(::Float64, ::Float64...))) == n @test (@which(1 + ::Float64)).sig === Tuple{typeof(+), Number, Number} @test (@which(+(((1, 2)...)))).name === :+ @test (@which((::typeof(+))(::Int, ::Float64))).sig === Tuple{typeof(+), Number, Number} @test @code_typed(::Float64 .+ ::Vector{Float64}) isa Pair @test @code_typed(::Float64 .+ ::Vector{Float64} .* ::Int) isa Pair @test (@which((::T + ::T) where T <: Number)).sig === (Tuple{typeof(+), T, T} where T <: Number) @testset "Keyword arguments" begin @test (@which(round(::Float64; digits = 3))).name === :round @test (@which(round(1.2; digits = ::Int))).name === :round @test (@which(round(1.2; digits::Int))).name === :round @test (@code_typed(round(::T; digits = ::T) where T <: Float64))[2] === Union{} @test (@code_typed(round(::T; digits = ::T) where T <: Int))[2] === Float64 base = 10 kwargs_1 = (; digits = 3) kwargs_2 = (; sigdigits = 3) @test (@which(round(1.2; kwargs_1...))).name === :round @test (@which(round(1.2; digits = 1, kwargs_1...))).name === :round @test (@code_typed(round(1.2; digits = ::Float64, kwargs_1...)))[2] === Float64 @test (@code_typed(round(1.2; kwargs_1..., digits = ::Float64)))[2] === Union{} @test (@which(round(1.2; digits = ::Float64, kwargs_1...))).name === :round @test (@which(round(1.2; sigdigits = ::Int, kwargs_1...))).name === :round @test (@which(round(1.2; kwargs_1..., kwargs_2..., base))).name === :round end @testset "Broadcasting" begin @test (@code_typed(optimize = false, round.([1.0, 2.0]; digits = ::Int64)))[2] == Vector{Float64} @test (@code_typed(optimize = false, round.(::Vector{Float64}, base = 2; digits = ::Int64)))[2] == Vector{Float64} @test (@code_typed(optimize = false, round.(base = ::Int64, ::Vector{Float64}; digits = ::Int64)))[2] == Vector{Float64} @test (@code_typed(optimize = false, [1, 2] .= ::Int))[2] == Vector{Int} @test (@code_typed(optimize = (false::Vector{Int} .= ::Int)))[2] == Vector{Int} @test (@code_typed(optimize = (false::Vector{Float64} .= 1 .+ ::Vector{Int})))[2] == Vector{Float64} @test (@code_typed(optimize = (false::Vector{Float64} .= 1 .+ round.(base = ::Int, ::Vector{Int}; digits = 3))))[2] == Vector{Float64} end @testset "Callable objects" begin @test (@code_typed((::Base.Fix2{typeof(+), Float64})(3)))[2] === Float64 @test (@code_typed(optimize = false, (::Returns{Float64})(::Int64; name::String)))[2] === Float64 @test (@code_typed((::Returns{T})(3.0) where T <: Real))[2] === Real end @testset "Opaque closures" begin opaque_f(@nospecialize(x::Type), @nospecialize(y::Type)) = begin sizeof(x) == sizeof(y) end (src, _) = only(code_typed(opaque_f, (Type, Type))) src.slottypes[1] = Tuple{} oc = Core.OpaqueClosure(src; sig = Tuple{Type, Type}, rettype = Bool, nargs = 2) ret = @code_typed(oc(Int64, Float64)) @test [ret] == code_typed(oc) (_, rt) = ret @test rt === Bool ir = Core.Compiler.inflate_ir(src) oc = Core.OpaqueClosure(ir) ret = @code_typed(oc(Int64, Float64)) @test [ret] == code_typed(oc) (_, rt) = ret @test rt === Bool end @testset "Vararg handling" begin @test_throws "More than one `Core.Vararg`" @eval(@code_typed(1 + 2::Vararg{Int} + 3 + 4::Vararg{Float64})) @test_throws "Inconsistent type `Float64`" @eval(@code_typed(1 + 2 + 3 + 4::Vararg{Int} + 5.0)) @test_throws "Inconsistent type `Float64`" @eval(@code_typed(+(1, 2, 3, 4::Int..., 5.0))) @test_throws "Inconsistent type `Float64`" @eval(@code_typed(1 + 2 + 3 + 4::Vararg{Int} + ::Float64)) @test_throws "Inconsistent type `Any`" @eval(@code_typed(1 + 2 + 3 + 4::Vararg{Int} + ::Any)) @test_throws r"at most 2 types .* found 3 instead" @eval(@code_typed(1 + 2 + 3 + 4::Vararg{Int, 2} + 5 + 6)) @test (@code_typed(1 + 2 + 3 + 4::Vararg{Int}))[2] === Int @test (@code_typed(1 + 2 + 3 + 4::Vararg{Int} + 5))[2] === Int @test (@code_typed(1 + 2 + 3 + 4::Vararg{Int, 3}))[2] === Int @test (@code_typed(1 + 2 + 3 + 4::Vararg{Int, 3} + 5))[2] === Int @test (@code_typed(1 + 2 + 3 + 4::Vararg{Int, 3} + 5 + 6))[2] === Int @test (@code_typed(1 + 2 + 3 + 4::Vararg))[2] === Any @test (@code_typed(1 + 2 + 3 + 4::Vararg + 5.0))[2] === Any @test (@code_typed(+(1, 2, 3, ::Int...)))[2] === Int @test (@code_typed(+(1, 2, 3, ::Int..., 5)))[2] === Int @test @code_typed((::T + ::Vararg{T} + ::T) where T) isa Vector{Any} @test @code_typed((::T + ::Vararg{T} + ::Float64) where T <: Real) isa Vector{Any} @test @code_typed((::T + ::Vararg{T} + ::Float64) where T <: Real) isa Vector{Any} @test @code_typed((::T + ::Vararg{T} + ::Int) where T <: Real) isa Vector{Any} @test @code_typed((::T + ::Vararg{Vector{T}} + ::Int) where T <: Real) isa Vector{Any} @test @code_typed((::T + ::Vararg{Int} + ::T) where T <: Real) isa Vector{Any} end end Parsing files in Base: Test Failed at /home/pkgeval/.julia/packages/CSTParser/0hXvH/test/test_check_base.jl:166 Expression: false Stacktrace: [1] macro expansion @ /opt/julia/share/julia/stdlib/v1.14/Test/src/Test.jl:753 [inlined] [2] top-level scope @ ~/.julia/packages/CSTParser/0hXvH/test/test_check_base.jl:166 ┌ Error: parsing difference │ file = "/opt/julia/bin/../share/julia/stdlib/v1.14/Printf/test/runtests.jl" └ @ Main.var"##296" ~/.julia/packages/CSTParser/0hXvH/test/test_check_base.jl:157 Printf.@sprintf "%a" 1.5 Printf.@sprintf "%a" 1.5 Printf.@sprintf("%a", 1.5) == "0x1.8p+0" Printf.@sprintf("%a", 1.5) == "0x1.8p+0" @test Printf.@sprintf("%a", 1.5) == "0x1.8p+0" @test Printf.@sprintf("%a", 1.5) == "0x1.8p+0" begin @test Printf.@sprintf("%a", 0.0) == "0x0p+0" @test Printf.@sprintf("%a", -0.0) == "-0x0p+0" @test Printf.@sprintf("%.3a", 0.0) == "0x0.000p+0" @test Printf.@sprintf("%a", 1.5) == "0x1.8p+0" @test Printf.@sprintf("%a", 1.5f0) == "0x1.8p+0" @test Printf.@sprintf("%a", 1.5) == "0x1.8p+0" @test Printf.@sprintf("%#.0a", 1.5) == "0x2.p+0" @test Printf.@sprintf("%+30a", 1 / 3) == " +0x1.5555555555555p-2" @test Printf.@sprintf("%a", 1.5) == "0x1.8p+0" @test Printf.@sprintf("%a", 3.14) == "0x1.91eb851eb851fp+1" @test Printf.@sprintf("%.0a", 3.14) == "0x2p+1" @test Printf.@sprintf("%.1a", 3.14) == "0x1.9p+1" @test Printf.@sprintf("%.2a", 3.14) == "0x1.92p+1" @test Printf.@sprintf("%#a", 3.14) == "0x1.91eb851eb851fp+1" @test Printf.@sprintf("%#.0a", 3.14) == "0x2.p+1" @test Printf.@sprintf("%#.1a", 3.14) == "0x1.9p+1" @test Printf.@sprintf("%#.2a", 3.14) == "0x1.92p+1" @test Printf.@sprintf("%.6a", 1.5) == "0x1.800000p+0" end begin @test Printf.@sprintf("%a", 0.0) == "0x0p+0" @test Printf.@sprintf("%a", -0.0) == "-0x0p+0" @test Printf.@sprintf("%.3a", 0.0) == "0x0.000p+0" @test Printf.@sprintf("%a", 1.5) == "0x1.8p+0" @test Printf.@sprintf("%a", 1.5f0) == "0x1.8p+0" @test Printf.@sprintf("%a", 1.5) == "0x1.8p+0" @test Printf.@sprintf("%#.0a", 1.5) == "0x2.p+0" @test Printf.@sprintf("%+30a", 1 / 3) == " +0x1.5555555555555p-2" @test Printf.@sprintf("%a", 1.5) == "0x1.8p+0" @test Printf.@sprintf("%a", 3.14) == "0x1.91eb851eb851fp+1" @test Printf.@sprintf("%.0a", 3.14) == "0x2p+1" @test Printf.@sprintf("%.1a", 3.14) == "0x1.9p+1" @test Printf.@sprintf("%.2a", 3.14) == "0x1.92p+1" @test Printf.@sprintf("%#a", 3.14) == "0x1.91eb851eb851fp+1" @test Printf.@sprintf("%#.0a", 3.14) == "0x2.p+1" @test Printf.@sprintf("%#.1a", 3.14) == "0x1.9p+1" @test Printf.@sprintf("%#.2a", 3.14) == "0x1.92p+1" @test Printf.@sprintf("%.6a", 1.5) == "0x1.800000p+0" end @testset "%a" begin @test Printf.@sprintf("%a", 0.0) == "0x0p+0" @test Printf.@sprintf("%a", -0.0) == "-0x0p+0" @test Printf.@sprintf("%.3a", 0.0) == "0x0.000p+0" @test Printf.@sprintf("%a", 1.5) == "0x1.8p+0" @test Printf.@sprintf("%a", 1.5f0) == "0x1.8p+0" @test Printf.@sprintf("%a", 1.5) == "0x1.8p+0" @test Printf.@sprintf("%#.0a", 1.5) == "0x2.p+0" @test Printf.@sprintf("%+30a", 1 / 3) == " +0x1.5555555555555p-2" @test Printf.@sprintf("%a", 1.5) == "0x1.8p+0" @test Printf.@sprintf("%a", 3.14) == "0x1.91eb851eb851fp+1" @test Printf.@sprintf("%.0a", 3.14) == "0x2p+1" @test Printf.@sprintf("%.1a", 3.14) == "0x1.9p+1" @test Printf.@sprintf("%.2a", 3.14) == "0x1.92p+1" @test Printf.@sprintf("%#a", 3.14) == "0x1.91eb851eb851fp+1" @test Printf.@sprintf("%#.0a", 3.14) == "0x2.p+1" @test Printf.@sprintf("%#.1a", 3.14) == "0x1.9p+1" @test Printf.@sprintf("%#.2a", 3.14) == "0x1.92p+1" @test Printf.@sprintf("%.6a", 1.5) == "0x1.800000p+0" end @testset "%a" begin @test Printf.@sprintf("%a", 0.0) == "0x0p+0" @test Printf.@sprintf("%a", -0.0) == "-0x0p+0" @test Printf.@sprintf("%.3a", 0.0) == "0x0.000p+0" @test Printf.@sprintf("%a", 1.5) == "0x1.8p+0" @test Printf.@sprintf("%a", 1.5f0) == "0x1.8p+0" @test Printf.@sprintf("%a", 1.5) == "0x1.8p+0" @test Printf.@sprintf("%#.0a", 1.5) == "0x2.p+0" @test Printf.@sprintf("%+30a", 1 / 3) == " +0x1.5555555555555p-2" @test Printf.@sprintf("%a", 1.5) == "0x1.8p+0" @test Printf.@sprintf("%a", 3.14) == "0x1.91eb851eb851fp+1" @test Printf.@sprintf("%.0a", 3.14) == "0x2p+1" @test Printf.@sprintf("%.1a", 3.14) == "0x1.9p+1" @test Printf.@sprintf("%.2a", 3.14) == "0x1.92p+1" @test Printf.@sprintf("%#a", 3.14) == "0x1.91eb851eb851fp+1" @test Printf.@sprintf("%#.0a", 3.14) == "0x2.p+1" @test Printf.@sprintf("%#.1a", 3.14) == "0x1.9p+1" @test Printf.@sprintf("%#.2a", 3.14) == "0x1.92p+1" @test Printf.@sprintf("%.6a", 1.5) == "0x1.800000p+0" end (1.2345678e7, "1.23457e+07") (1.2345678e7, "1.23457e+07") (1.234567799999999999999999999999999999999999999999999999999999999999999999999993e6, "1.23457e+06") (1.234567799999999999999999999999999999999999999999999999999999999999999999999993e6, "1.23457e+06") (123456.7800000000000000000000000000000000000000000000000000000000000000000000004, "123457") (123456.7800000000000000000000000000000000000000000000000000000000000000000000004, "123457") (12345.67800000000000000000000000000000000000000000000000000000000000000000000007, "12345.7") (12345.67800000000000000000000000000000000000000000000000000000000000000000000007, "12345.7") ((1.2345678e7, "1.23457e+07"), (1.234567799999999999999999999999999999999999999999999999999999999999999999999993e6, "1.23457e+06"), (123456.7800000000000000000000000000000000000000000000000000000000000000000000004, "123457"), (12345.67800000000000000000000000000000000000000000000000000000000000000000000007, "12345.7")) ((1.2345678e7, "1.23457e+07"), (1.234567799999999999999999999999999999999999999999999999999999999999999999999993e6, "1.23457e+06"), (123456.7800000000000000000000000000000000000000000000000000000000000000000000004, "123457"), (12345.67800000000000000000000000000000000000000000000000000000000000000000000007, "12345.7")) (val, res) = ((1.2345678e7, "1.23457e+07"), (1.234567799999999999999999999999999999999999999999999999999999999999999999999993e6, "1.23457e+06"), (123456.7800000000000000000000000000000000000000000000000000000000000000000000004, "123457"), (12345.67800000000000000000000000000000000000000000000000000000000000000000000007, "12345.7")) (val, res) = ((1.2345678e7, "1.23457e+07"), (1.234567799999999999999999999999999999999999999999999999999999999999999999999993e6, "1.23457e+06"), (123456.7800000000000000000000000000000000000000000000000000000000000000000000004, "123457"), (12345.67800000000000000000000000000000000000000000000000000000000000000000000007, "12345.7")) for (val, res) = ((1.2345678e7, "1.23457e+07"), (1.234567799999999999999999999999999999999999999999999999999999999999999999999993e6, "1.23457e+06"), (123456.7800000000000000000000000000000000000000000000000000000000000000000000004, "123457"), (12345.67800000000000000000000000000000000000000000000000000000000000000000000007, "12345.7")) @test Printf.@sprintf("%.6g", val) == res end for (val, res) = ((1.2345678e7, "1.23457e+07"), (1.234567799999999999999999999999999999999999999999999999999999999999999999999993e6, "1.23457e+06"), (123456.7800000000000000000000000000000000000000000000000000000000000000000000004, "123457"), (12345.67800000000000000000000000000000000000000000000000000000000000000000000007, "12345.7")) @test Printf.@sprintf("%.6g", val) == res end (123.4, 123.4000000000000000000000000000000000000000000000000000000000000000000000000002) (123.4, 123.4000000000000000000000000000000000000000000000000000000000000000000000000002) num = (123.4, 123.4000000000000000000000000000000000000000000000000000000000000000000000000002) num = (123.4, 123.4000000000000000000000000000000000000000000000000000000000000000000000000002) begin (fmt, val) = (("%10.5g", " 123.4"), ("%+10.5g", " +123.4"), ("% 10.5g", " 123.4"), ("%#10.5g", " 123.40"), ("%-10.5g", "123.4 "), ("%-+10.5g", "+123.4 "), ("%010.5g", "00000123.4")) num = (123.4, 123.4000000000000000000000000000000000000000000000000000000000000000000000000002) end begin (fmt, val) = (("%10.5g", " 123.4"), ("%+10.5g", " +123.4"), ("% 10.5g", " 123.4"), ("%#10.5g", " 123.40"), ("%-10.5g", "123.4 "), ("%-+10.5g", "+123.4 "), ("%010.5g", "00000123.4")) num = (123.4, 123.4000000000000000000000000000000000000000000000000000000000000000000000000002) end for (fmt, val) = (("%10.5g", " 123.4"), ("%+10.5g", " +123.4"), ("% 10.5g", " 123.4"), ("%#10.5g", " 123.40"), ("%-10.5g", "123.4 "), ("%-+10.5g", "+123.4 "), ("%010.5g", "00000123.4")), num = (123.4, 123.4000000000000000000000000000000000000000000000000000000000000000000000000002) @test Printf.format(Printf.Format(fmt), num) == val end for (fmt, val) = (("%10.5g", " 123.4"), ("%+10.5g", " +123.4"), ("% 10.5g", " 123.4"), ("%#10.5g", " 123.40"), ("%-10.5g", "123.4 "), ("%-+10.5g", "+123.4 "), ("%010.5g", "00000123.4")), num = (123.4, 123.4000000000000000000000000000000000000000000000000000000000000000000000000002) @test Printf.format(Printf.Format(fmt), num) == val end Printf.@sprintf "%10.5g" -123.4000000000000000000000000000000000000000000000000000000000000000000000000002 Printf.@sprintf "%10.5g" -123.4000000000000000000000000000000000000000000000000000000000000000000000000002 Printf.@sprintf("%10.5g", -123.4000000000000000000000000000000000000000000000000000000000000000000000000002) == " -123.4" Printf.@sprintf("%10.5g", -123.4000000000000000000000000000000000000000000000000000000000000000000000000002) == " -123.4" @test Printf.@sprintf("%10.5g", -123.4000000000000000000000000000000000000000000000000000000000000000000000000002) == " -123.4" @test Printf.@sprintf("%10.5g", -123.4000000000000000000000000000000000000000000000000000000000000000000000000002) == " -123.4" Printf.@sprintf "%010.5g" -123.4000000000000000000000000000000000000000000000000000000000000000000000000002 Printf.@sprintf "%010.5g" -123.4000000000000000000000000000000000000000000000000000000000000000000000000002 Printf.@sprintf("%010.5g", -123.4000000000000000000000000000000000000000000000000000000000000000000000000002) == "-0000123.4" Printf.@sprintf("%010.5g", -123.4000000000000000000000000000000000000000000000000000000000000000000000000002) == "-0000123.4" @test Printf.@sprintf("%010.5g", -123.4000000000000000000000000000000000000000000000000000000000000000000000000002) == "-0000123.4" @test Printf.@sprintf("%010.5g", -123.4000000000000000000000000000000000000000000000000000000000000000000000000002) == "-0000123.4" Printf.@sprintf "%.6g" 1.234e7 Printf.@sprintf "%.6g" 1.234e7 Printf.@sprintf("%.6g", 1.234e7) == "1.234e+07" Printf.@sprintf("%.6g", 1.234e7) == "1.234e+07" @test Printf.@sprintf("%.6g", 1.234e7) == "1.234e+07" @test Printf.@sprintf("%.6g", 1.234e7) == "1.234e+07" Printf.@sprintf "%#.6g" 1.234e7 Printf.@sprintf "%#.6g" 1.234e7 Printf.@sprintf("%#.6g", 1.234e7) == "1.23400e+07" Printf.@sprintf("%#.6g", 1.234e7) == "1.23400e+07" @test Printf.@sprintf("%#.6g", 1.234e7) == "1.23400e+07" @test Printf.@sprintf("%#.6g", 1.234e7) == "1.23400e+07" begin for (val, res) = ((1.2345678e7, "1.23457e+07"), (1.2345678e6, "1.23457e+06"), (123456.78, "123457"), (12345.678, "12345.7"), (1.234e7, "1.234e+07")) @test Printf.@sprintf("%.6g", val) == res end for (val, res) = ((1.2345678e7, "1.23457e+07"), (1.234567799999999999999999999999999999999999999999999999999999999999999999999993e6, "1.23457e+06"), (123456.7800000000000000000000000000000000000000000000000000000000000000000000004, "123457"), (12345.67800000000000000000000000000000000000000000000000000000000000000000000007, "12345.7")) @test Printf.@sprintf("%.6g", val) == res end for (fmt, val) = (("%10.5g", " 123.4"), ("%+10.5g", " +123.4"), ("% 10.5g", " 123.4"), ("%#10.5g", " 123.40"), ("%-10.5g", "123.4 "), ("%-+10.5g", "+123.4 "), ("%010.5g", "00000123.4")), num = (123.4, 123.4000000000000000000000000000000000000000000000000000000000000000000000000002) @test Printf.format(Printf.Format(fmt), num) == val end @test Printf.@sprintf("%10.5g", -123.4) == " -123.4" @test Printf.@sprintf("%010.5g", -123.4) == "-0000123.4" @test Printf.@sprintf("%.6g", 1.234e7) == "1.234e+07" @test Printf.@sprintf("%#.6g", 1.234e7) == "1.23400e+07" @test Printf.@sprintf("%10.5g", -123.4000000000000000000000000000000000000000000000000000000000000000000000000002) == " -123.4" @test Printf.@sprintf("%010.5g", -123.4000000000000000000000000000000000000000000000000000000000000000000000000002) == "-0000123.4" @test Printf.@sprintf("%.6g", 1.234e7) == "1.234e+07" @test Printf.@sprintf("%#.6g", 1.234e7) == "1.23400e+07" @test Printf.@sprintf("%.5g", 42) == "42" @test Printf.@sprintf("%#.2g", 42) == "42." @test Printf.@sprintf("%#.5g", 42) == "42.000" @test Printf.@sprintf("%g", 0.00012) == "0.00012" @test Printf.@sprintf("%g", 1.2e-5) == "1.2e-05" @test Printf.@sprintf("%g", 123456.7) == "123457" @test Printf.@sprintf("%g", 1.2345678e6) == "1.23457e+06" for (val, res) = ((Inf, "Inf"), (-Inf, "-Inf"), (NaN, "NaN"), (-NaN, "NaN")) @test Printf.@sprintf("%g", val) == res @test Printf.@sprintf("%G", val) == res end @test Printf.@sprintf("%.15g", 0) == "0" @test Printf.@sprintf("%#.15g", 0) == "0.00000000000000" end begin for (val, res) = ((1.2345678e7, "1.23457e+07"), (1.2345678e6, "1.23457e+06"), (123456.78, "123457"), (12345.678, "12345.7"), (1.234e7, "1.234e+07")) @test Printf.@sprintf("%.6g", val) == res end for (val, res) = ((1.2345678e7, "1.23457e+07"), (1.234567799999999999999999999999999999999999999999999999999999999999999999999993e6, "1.23457e+06"), (123456.7800000000000000000000000000000000000000000000000000000000000000000000004, "123457"), (12345.67800000000000000000000000000000000000000000000000000000000000000000000007, "12345.7")) @test Printf.@sprintf("%.6g", val) == res end for (fmt, val) = (("%10.5g", " 123.4"), ("%+10.5g", " +123.4"), ("% 10.5g", " 123.4"), ("%#10.5g", " 123.40"), ("%-10.5g", "123.4 "), ("%-+10.5g", "+123.4 "), ("%010.5g", "00000123.4")), num = (123.4, 123.4000000000000000000000000000000000000000000000000000000000000000000000000002) @test Printf.format(Printf.Format(fmt), num) == val end @test Printf.@sprintf("%10.5g", -123.4) == " -123.4" @test Printf.@sprintf("%010.5g", -123.4) == "-0000123.4" @test Printf.@sprintf("%.6g", 1.234e7) == "1.234e+07" @test Printf.@sprintf("%#.6g", 1.234e7) == "1.23400e+07" @test Printf.@sprintf("%10.5g", -123.4000000000000000000000000000000000000000000000000000000000000000000000000002) == " -123.4" @test Printf.@sprintf("%010.5g", -123.4000000000000000000000000000000000000000000000000000000000000000000000000002) == "-0000123.4" @test Printf.@sprintf("%.6g", 1.234e7) == "1.234e+07" @test Printf.@sprintf("%#.6g", 1.234e7) == "1.23400e+07" @test Printf.@sprintf("%.5g", 42) == "42" @test Printf.@sprintf("%#.2g", 42) == "42." @test Printf.@sprintf("%#.5g", 42) == "42.000" @test Printf.@sprintf("%g", 0.00012) == "0.00012" @test Printf.@sprintf("%g", 1.2e-5) == "1.2e-05" @test Printf.@sprintf("%g", 123456.7) == "123457" @test Printf.@sprintf("%g", 1.2345678e6) == "1.23457e+06" for (val, res) = ((Inf, "Inf"), (-Inf, "-Inf"), (NaN, "NaN"), (-NaN, "NaN")) @test Printf.@sprintf("%g", val) == res @test Printf.@sprintf("%G", val) == res end @test Printf.@sprintf("%.15g", 0) == "0" @test Printf.@sprintf("%#.15g", 0) == "0.00000000000000" end @testset "%g" begin for (val, res) = ((1.2345678e7, "1.23457e+07"), (1.2345678e6, "1.23457e+06"), (123456.78, "123457"), (12345.678, "12345.7"), (1.234e7, "1.234e+07")) @test Printf.@sprintf("%.6g", val) == res end for (val, res) = ((1.2345678e7, "1.23457e+07"), (1.234567799999999999999999999999999999999999999999999999999999999999999999999993e6, "1.23457e+06"), (123456.7800000000000000000000000000000000000000000000000000000000000000000000004, "123457"), (12345.67800000000000000000000000000000000000000000000000000000000000000000000007, "12345.7")) @test Printf.@sprintf("%.6g", val) == res end for (fmt, val) = (("%10.5g", " 123.4"), ("%+10.5g", " +123.4"), ("% 10.5g", " 123.4"), ("%#10.5g", " 123.40"), ("%-10.5g", "123.4 "), ("%-+10.5g", "+123.4 "), ("%010.5g", "00000123.4")), num = (123.4, 123.4000000000000000000000000000000000000000000000000000000000000000000000000002) @test Printf.format(Printf.Format(fmt), num) == val end @test Printf.@sprintf("%10.5g", -123.4) == " -123.4" @test Printf.@sprintf("%010.5g", -123.4) == "-0000123.4" @test Printf.@sprintf("%.6g", 1.234e7) == "1.234e+07" @test Printf.@sprintf("%#.6g", 1.234e7) == "1.23400e+07" @test Printf.@sprintf("%10.5g", -123.4000000000000000000000000000000000000000000000000000000000000000000000000002) == " -123.4" @test Printf.@sprintf("%010.5g", -123.4000000000000000000000000000000000000000000000000000000000000000000000000002) == "-0000123.4" @test Printf.@sprintf("%.6g", 1.234e7) == "1.234e+07" @test Printf.@sprintf("%#.6g", 1.234e7) == "1.23400e+07" @test Printf.@sprintf("%.5g", 42) == "42" @test Printf.@sprintf("%#.2g", 42) == "42." @test Printf.@sprintf("%#.5g", 42) == "42.000" @test Printf.@sprintf("%g", 0.00012) == "0.00012" @test Printf.@sprintf("%g", 1.2e-5) == "1.2e-05" @test Printf.@sprintf("%g", 123456.7) == "123457" @test Printf.@sprintf("%g", 1.2345678e6) == "1.23457e+06" for (val, res) = ((Inf, "Inf"), (-Inf, "-Inf"), (NaN, "NaN"), (-NaN, "NaN")) @test Printf.@sprintf("%g", val) == res @test Printf.@sprintf("%G", val) == res end @test Printf.@sprintf("%.15g", 0) == "0" @test Printf.@sprintf("%#.15g", 0) == "0.00000000000000" end @testset "%g" begin for (val, res) = ((1.2345678e7, "1.23457e+07"), (1.2345678e6, "1.23457e+06"), (123456.78, "123457"), (12345.678, "12345.7"), (1.234e7, "1.234e+07")) @test Printf.@sprintf("%.6g", val) == res end for (val, res) = ((1.2345678e7, "1.23457e+07"), (1.234567799999999999999999999999999999999999999999999999999999999999999999999993e6, "1.23457e+06"), (123456.7800000000000000000000000000000000000000000000000000000000000000000000004, "123457"), (12345.67800000000000000000000000000000000000000000000000000000000000000000000007, "12345.7")) @test Printf.@sprintf("%.6g", val) == res end for (fmt, val) = (("%10.5g", " 123.4"), ("%+10.5g", " +123.4"), ("% 10.5g", " 123.4"), ("%#10.5g", " 123.40"), ("%-10.5g", "123.4 "), ("%-+10.5g", "+123.4 "), ("%010.5g", "00000123.4")), num = (123.4, 123.4000000000000000000000000000000000000000000000000000000000000000000000000002) @test Printf.format(Printf.Format(fmt), num) == val end @test Printf.@sprintf("%10.5g", -123.4) == " -123.4" @test Printf.@sprintf("%010.5g", -123.4) == "-0000123.4" @test Printf.@sprintf("%.6g", 1.234e7) == "1.234e+07" @test Printf.@sprintf("%#.6g", 1.234e7) == "1.23400e+07" @test Printf.@sprintf("%10.5g", -123.4000000000000000000000000000000000000000000000000000000000000000000000000002) == " -123.4" @test Printf.@sprintf("%010.5g", -123.4000000000000000000000000000000000000000000000000000000000000000000000000002) == "-0000123.4" @test Printf.@sprintf("%.6g", 1.234e7) == "1.234e+07" @test Printf.@sprintf("%#.6g", 1.234e7) == "1.23400e+07" @test Printf.@sprintf("%.5g", 42) == "42" @test Printf.@sprintf("%#.2g", 42) == "42." @test Printf.@sprintf("%#.5g", 42) == "42.000" @test Printf.@sprintf("%g", 0.00012) == "0.00012" @test Printf.@sprintf("%g", 1.2e-5) == "1.2e-05" @test Printf.@sprintf("%g", 123456.7) == "123457" @test Printf.@sprintf("%g", 1.2345678e6) == "1.23457e+06" for (val, res) = ((Inf, "Inf"), (-Inf, "-Inf"), (NaN, "NaN"), (-NaN, "NaN")) @test Printf.@sprintf("%g", val) == res @test Printf.@sprintf("%G", val) == res end @test Printf.@sprintf("%.15g", 0) == "0" @test Printf.@sprintf("%#.15g", 0) == "0.00000000000000" end Printf.@sprintf "%e" Inf Printf.@sprintf "%e" Inf Printf.@sprintf("%e", Inf) == "Inf" Printf.@sprintf("%e", Inf) == "Inf" @test Printf.@sprintf("%e", Inf) == "Inf" @test Printf.@sprintf("%e", Inf) == "Inf" begin @test Printf.@sprintf("%f", Inf) == "Inf" @test Printf.@sprintf("%+f", Inf) == "+Inf" @test Printf.@sprintf("% f", Inf) == " Inf" @test Printf.@sprintf("% #f", Inf) == " Inf" @test Printf.@sprintf("%07f", Inf) == " Inf" @test Printf.@sprintf("%f", -Inf) == "-Inf" @test Printf.@sprintf("%+f", -Inf) == "-Inf" @test Printf.@sprintf("%07f", -Inf) == " -Inf" @test Printf.@sprintf("%f", NaN) == "NaN" @test Printf.@sprintf("%+f", NaN) == "+NaN" @test Printf.@sprintf("% f", NaN) == " NaN" @test Printf.@sprintf("% #f", NaN) == " NaN" @test Printf.@sprintf("%07f", NaN) == " NaN" @test Printf.@sprintf("%e", Inf) == "Inf" @test Printf.@sprintf("%e", NaN) == "NaN" @test Printf.@sprintf("%.0f", 3.0e142) == "29999999999999997463140672961703247153805615792184250659629251954072073858354858644285983761764971823910371920726635399393477049701891710124032" @test Printf.@sprintf("%f", 1.234) == "1.234000" @test Printf.@sprintf("%F", 1.234) == "1.234000" @test Printf.@sprintf("%+f", 1.234) == "+1.234000" @test Printf.@sprintf("% f", 1.234) == " 1.234000" @test Printf.@sprintf("%f", -1.234) == "-1.234000" @test Printf.@sprintf("%+f", -1.234) == "-1.234000" @test Printf.@sprintf("% f", -1.234) == "-1.234000" @test Printf.@sprintf("%#f", 1.234) == "1.234000" @test Printf.@sprintf("%.2f", 1.234) == "1.23" @test Printf.@sprintf("%.2f", 1.235) == "1.24" @test Printf.@sprintf("%.2f", 0.235) == "0.23" @test Printf.@sprintf("%4.1f", 1.234) == " 1.2" @test Printf.@sprintf("%8.1f", 1.234) == " 1.2" @test Printf.@sprintf("%+8.1f", 1.234) == " +1.2" @test Printf.@sprintf("% 8.1f", 1.234) == " 1.2" @test Printf.@sprintf("% 7.1f", 1.234) == " 1.2" @test Printf.@sprintf("% 08.1f", 1.234) == " 00001.2" @test Printf.@sprintf("%08.1f", 1.234) == "000001.2" @test Printf.@sprintf("%-08.1f", 1.234) == "1.2 " @test Printf.@sprintf("%-8.1f", 1.234) == "1.2 " @test Printf.@sprintf("%08.1f", -1.234) == "-00001.2" @test Printf.@sprintf("%09.1f", -1.234) == "-000001.2" @test Printf.@sprintf("%09.1f", 1.234) == "0000001.2" @test Printf.@sprintf("%+09.1f", 1.234) == "+000001.2" @test Printf.@sprintf("% 09.1f", 1.234) == " 000001.2" @test Printf.@sprintf("%+ 09.1f", 1.234) == "+000001.2" @test Printf.@sprintf("%+ 09.1f", 1.234) == "+000001.2" @test Printf.@sprintf("%+ 09.0f", 1.234) == "+00000001" @test Printf.@sprintf("%+ #09.0f", 1.234) == "+0000001." @test Printf.@sprintf("%+7.1f", 9.96) == " +10.0" @test Printf.@sprintf("% 7.1f", 9.96) == " 10.0" end begin @test Printf.@sprintf("%f", Inf) == "Inf" @test Printf.@sprintf("%+f", Inf) == "+Inf" @test Printf.@sprintf("% f", Inf) == " Inf" @test Printf.@sprintf("% #f", Inf) == " Inf" @test Printf.@sprintf("%07f", Inf) == " Inf" @test Printf.@sprintf("%f", -Inf) == "-Inf" @test Printf.@sprintf("%+f", -Inf) == "-Inf" @test Printf.@sprintf("%07f", -Inf) == " -Inf" @test Printf.@sprintf("%f", NaN) == "NaN" @test Printf.@sprintf("%+f", NaN) == "+NaN" @test Printf.@sprintf("% f", NaN) == " NaN" @test Printf.@sprintf("% #f", NaN) == " NaN" @test Printf.@sprintf("%07f", NaN) == " NaN" @test Printf.@sprintf("%e", Inf) == "Inf" @test Printf.@sprintf("%e", NaN) == "NaN" @test Printf.@sprintf("%.0f", 3.0e142) == "29999999999999997463140672961703247153805615792184250659629251954072073858354858644285983761764971823910371920726635399393477049701891710124032" @test Printf.@sprintf("%f", 1.234) == "1.234000" @test Printf.@sprintf("%F", 1.234) == "1.234000" @test Printf.@sprintf("%+f", 1.234) == "+1.234000" @test Printf.@sprintf("% f", 1.234) == " 1.234000" @test Printf.@sprintf("%f", -1.234) == "-1.234000" @test Printf.@sprintf("%+f", -1.234) == "-1.234000" @test Printf.@sprintf("% f", -1.234) == "-1.234000" @test Printf.@sprintf("%#f", 1.234) == "1.234000" @test Printf.@sprintf("%.2f", 1.234) == "1.23" @test Printf.@sprintf("%.2f", 1.235) == "1.24" @test Printf.@sprintf("%.2f", 0.235) == "0.23" @test Printf.@sprintf("%4.1f", 1.234) == " 1.2" @test Printf.@sprintf("%8.1f", 1.234) == " 1.2" @test Printf.@sprintf("%+8.1f", 1.234) == " +1.2" @test Printf.@sprintf("% 8.1f", 1.234) == " 1.2" @test Printf.@sprintf("% 7.1f", 1.234) == " 1.2" @test Printf.@sprintf("% 08.1f", 1.234) == " 00001.2" @test Printf.@sprintf("%08.1f", 1.234) == "000001.2" @test Printf.@sprintf("%-08.1f", 1.234) == "1.2 " @test Printf.@sprintf("%-8.1f", 1.234) == "1.2 " @test Printf.@sprintf("%08.1f", -1.234) == "-00001.2" @test Printf.@sprintf("%09.1f", -1.234) == "-000001.2" @test Printf.@sprintf("%09.1f", 1.234) == "0000001.2" @test Printf.@sprintf("%+09.1f", 1.234) == "+000001.2" @test Printf.@sprintf("% 09.1f", 1.234) == " 000001.2" @test Printf.@sprintf("%+ 09.1f", 1.234) == "+000001.2" @test Printf.@sprintf("%+ 09.1f", 1.234) == "+000001.2" @test Printf.@sprintf("%+ 09.0f", 1.234) == "+00000001" @test Printf.@sprintf("%+ #09.0f", 1.234) == "+0000001." @test Printf.@sprintf("%+7.1f", 9.96) == " +10.0" @test Printf.@sprintf("% 7.1f", 9.96) == " 10.0" end @testset "%f" begin @test Printf.@sprintf("%f", Inf) == "Inf" @test Printf.@sprintf("%+f", Inf) == "+Inf" @test Printf.@sprintf("% f", Inf) == " Inf" @test Printf.@sprintf("% #f", Inf) == " Inf" @test Printf.@sprintf("%07f", Inf) == " Inf" @test Printf.@sprintf("%f", -Inf) == "-Inf" @test Printf.@sprintf("%+f", -Inf) == "-Inf" @test Printf.@sprintf("%07f", -Inf) == " -Inf" @test Printf.@sprintf("%f", NaN) == "NaN" @test Printf.@sprintf("%+f", NaN) == "+NaN" @test Printf.@sprintf("% f", NaN) == " NaN" @test Printf.@sprintf("% #f", NaN) == " NaN" @test Printf.@sprintf("%07f", NaN) == " NaN" @test Printf.@sprintf("%e", Inf) == "Inf" @test Printf.@sprintf("%e", NaN) == "NaN" @test Printf.@sprintf("%.0f", 3.0e142) == "29999999999999997463140672961703247153805615792184250659629251954072073858354858644285983761764971823910371920726635399393477049701891710124032" @test Printf.@sprintf("%f", 1.234) == "1.234000" @test Printf.@sprintf("%F", 1.234) == "1.234000" @test Printf.@sprintf("%+f", 1.234) == "+1.234000" @test Printf.@sprintf("% f", 1.234) == " 1.234000" @test Printf.@sprintf("%f", -1.234) == "-1.234000" @test Printf.@sprintf("%+f", -1.234) == "-1.234000" @test Printf.@sprintf("% f", -1.234) == "-1.234000" @test Printf.@sprintf("%#f", 1.234) == "1.234000" @test Printf.@sprintf("%.2f", 1.234) == "1.23" @test Printf.@sprintf("%.2f", 1.235) == "1.24" @test Printf.@sprintf("%.2f", 0.235) == "0.23" @test Printf.@sprintf("%4.1f", 1.234) == " 1.2" @test Printf.@sprintf("%8.1f", 1.234) == " 1.2" @test Printf.@sprintf("%+8.1f", 1.234) == " +1.2" @test Printf.@sprintf("% 8.1f", 1.234) == " 1.2" @test Printf.@sprintf("% 7.1f", 1.234) == " 1.2" @test Printf.@sprintf("% 08.1f", 1.234) == " 00001.2" @test Printf.@sprintf("%08.1f", 1.234) == "000001.2" @test Printf.@sprintf("%-08.1f", 1.234) == "1.2 " @test Printf.@sprintf("%-8.1f", 1.234) == "1.2 " @test Printf.@sprintf("%08.1f", -1.234) == "-00001.2" @test Printf.@sprintf("%09.1f", -1.234) == "-000001.2" @test Printf.@sprintf("%09.1f", 1.234) == "0000001.2" @test Printf.@sprintf("%+09.1f", 1.234) == "+000001.2" @test Printf.@sprintf("% 09.1f", 1.234) == " 000001.2" @test Printf.@sprintf("%+ 09.1f", 1.234) == "+000001.2" @test Printf.@sprintf("%+ 09.1f", 1.234) == "+000001.2" @test Printf.@sprintf("%+ 09.0f", 1.234) == "+00000001" @test Printf.@sprintf("%+ #09.0f", 1.234) == "+0000001." @test Printf.@sprintf("%+7.1f", 9.96) == " +10.0" @test Printf.@sprintf("% 7.1f", 9.96) == " 10.0" end @testset "%f" begin @test Printf.@sprintf("%f", Inf) == "Inf" @test Printf.@sprintf("%+f", Inf) == "+Inf" @test Printf.@sprintf("% f", Inf) == " Inf" @test Printf.@sprintf("% #f", Inf) == " Inf" @test Printf.@sprintf("%07f", Inf) == " Inf" @test Printf.@sprintf("%f", -Inf) == "-Inf" @test Printf.@sprintf("%+f", -Inf) == "-Inf" @test Printf.@sprintf("%07f", -Inf) == " -Inf" @test Printf.@sprintf("%f", NaN) == "NaN" @test Printf.@sprintf("%+f", NaN) == "+NaN" @test Printf.@sprintf("% f", NaN) == " NaN" @test Printf.@sprintf("% #f", NaN) == " NaN" @test Printf.@sprintf("%07f", NaN) == " NaN" @test Printf.@sprintf("%e", Inf) == "Inf" @test Printf.@sprintf("%e", NaN) == "NaN" @test Printf.@sprintf("%.0f", 3.0e142) == "29999999999999997463140672961703247153805615792184250659629251954072073858354858644285983761764971823910371920726635399393477049701891710124032" @test Printf.@sprintf("%f", 1.234) == "1.234000" @test Printf.@sprintf("%F", 1.234) == "1.234000" @test Printf.@sprintf("%+f", 1.234) == "+1.234000" @test Printf.@sprintf("% f", 1.234) == " 1.234000" @test Printf.@sprintf("%f", -1.234) == "-1.234000" @test Printf.@sprintf("%+f", -1.234) == "-1.234000" @test Printf.@sprintf("% f", -1.234) == "-1.234000" @test Printf.@sprintf("%#f", 1.234) == "1.234000" @test Printf.@sprintf("%.2f", 1.234) == "1.23" @test Printf.@sprintf("%.2f", 1.235) == "1.24" @test Printf.@sprintf("%.2f", 0.235) == "0.23" @test Printf.@sprintf("%4.1f", 1.234) == " 1.2" @test Printf.@sprintf("%8.1f", 1.234) == " 1.2" @test Printf.@sprintf("%+8.1f", 1.234) == " +1.2" @test Printf.@sprintf("% 8.1f", 1.234) == " 1.2" @test Printf.@sprintf("% 7.1f", 1.234) == " 1.2" @test Printf.@sprintf("% 08.1f", 1.234) == " 00001.2" @test Printf.@sprintf("%08.1f", 1.234) == "000001.2" @test Printf.@sprintf("%-08.1f", 1.234) == "1.2 " @test Printf.@sprintf("%-8.1f", 1.234) == "1.2 " @test Printf.@sprintf("%08.1f", -1.234) == "-00001.2" @test Printf.@sprintf("%09.1f", -1.234) == "-000001.2" @test Printf.@sprintf("%09.1f", 1.234) == "0000001.2" @test Printf.@sprintf("%+09.1f", 1.234) == "+000001.2" @test Printf.@sprintf("% 09.1f", 1.234) == " 000001.2" @test Printf.@sprintf("%+ 09.1f", 1.234) == "+000001.2" @test Printf.@sprintf("%+ 09.1f", 1.234) == "+000001.2" @test Printf.@sprintf("%+ 09.0f", 1.234) == "+00000001" @test Printf.@sprintf("%+ #09.0f", 1.234) == "+0000001." @test Printf.@sprintf("%+7.1f", 9.96) == " +10.0" @test Printf.@sprintf("% 7.1f", 9.96) == " 10.0" end Printf.@sprintf "%e" Inf Printf.@sprintf "%e" Inf Printf.@sprintf("%e", Inf) == "Inf" Printf.@sprintf("%e", Inf) == "Inf" @test Printf.@sprintf("%e", Inf) == "Inf" @test Printf.@sprintf("%e", Inf) == "Inf" Printf.@sprintf "%.0e" 2.999999999999999999999999999999999999999999999999999999999999999999999999999996e142 Printf.@sprintf "%.0e" 2.999999999999999999999999999999999999999999999999999999999999999999999999999996e142 Printf.@sprintf("%.0e", 2.999999999999999999999999999999999999999999999999999999999999999999999999999996e142) == "3e+142" Printf.@sprintf("%.0e", 2.999999999999999999999999999999999999999999999999999999999999999999999999999996e142) == "3e+142" @test Printf.@sprintf("%.0e", 2.999999999999999999999999999999999999999999999999999999999999999999999999999996e142) == "3e+142" @test Printf.@sprintf("%.0e", 2.999999999999999999999999999999999999999999999999999999999999999999999999999996e142) == "3e+142" Printf.@sprintf "%#.0e" 2.999999999999999999999999999999999999999999999999999999999999999999999999999996e142 Printf.@sprintf "%#.0e" 2.999999999999999999999999999999999999999999999999999999999999999999999999999996e142 Printf.@sprintf("%#.0e", 2.999999999999999999999999999999999999999999999999999999999999999999999999999996e142) == "3.e+142" Printf.@sprintf("%#.0e", 2.999999999999999999999999999999999999999999999999999999999999999999999999999996e142) == "3.e+142" @test Printf.@sprintf("%#.0e", 2.999999999999999999999999999999999999999999999999999999999999999999999999999996e142) == "3.e+142" @test Printf.@sprintf("%#.0e", 2.999999999999999999999999999999999999999999999999999999999999999999999999999996e142) == "3.e+142" Printf.@sprintf "%.0e" 3.000000000000000000000000000000000000000000000000000000000000000000000000000024e1042 Printf.@sprintf "%.0e" 3.000000000000000000000000000000000000000000000000000000000000000000000000000024e1042 Printf.@sprintf("%.0e", 3.000000000000000000000000000000000000000000000000000000000000000000000000000024e1042) == "3e+1042" Printf.@sprintf("%.0e", 3.000000000000000000000000000000000000000000000000000000000000000000000000000024e1042) == "3e+1042" @test Printf.@sprintf("%.0e", 3.000000000000000000000000000000000000000000000000000000000000000000000000000024e1042) == "3e+1042" @test Printf.@sprintf("%.0e", 3.000000000000000000000000000000000000000000000000000000000000000000000000000024e1042) == "3e+1042" begin @test Printf.@sprintf("%e", Inf) == "Inf" @test Printf.@sprintf("%+e", Inf) == "+Inf" @test Printf.@sprintf("% e", Inf) == " Inf" @test Printf.@sprintf("% #e", Inf) == " Inf" @test Printf.@sprintf("%07e", Inf) == " Inf" @test Printf.@sprintf("%e", -Inf) == "-Inf" @test Printf.@sprintf("%+e", -Inf) == "-Inf" @test Printf.@sprintf("%07e", -Inf) == " -Inf" @test Printf.@sprintf("%e", NaN) == "NaN" @test Printf.@sprintf("%+e", NaN) == "+NaN" @test Printf.@sprintf("% e", NaN) == " NaN" @test Printf.@sprintf("% #e", NaN) == " NaN" @test Printf.@sprintf("%07e", NaN) == " NaN" @test Printf.@sprintf("%e", Inf) == "Inf" @test Printf.@sprintf("%e", NaN) == "NaN" @test Printf.@sprintf("%.0e", 3.0e142) == "3e+142" @test Printf.@sprintf("%#.0e", 3.0e142) == "3.e+142" @test Printf.@sprintf("%.0e", 2.999999999999999999999999999999999999999999999999999999999999999999999999999996e142) == "3e+142" @test Printf.@sprintf("%#.0e", 2.999999999999999999999999999999999999999999999999999999999999999999999999999996e142) == "3.e+142" @test Printf.@sprintf("%.0e", 3.000000000000000000000000000000000000000000000000000000000000000000000000000024e1042) == "3e+1042" @test Printf.@sprintf("%e", 3.0e42) == "3.000000e+42" @test Printf.@sprintf("%E", 3.0e42) == "3.000000E+42" @test Printf.@sprintf("%e", 3.0e-42) == "3.000000e-42" @test Printf.@sprintf("%E", 3.0e-42) == "3.000000E-42" @test Printf.@sprintf("%e", 1.234) == "1.234000e+00" @test Printf.@sprintf("%E", 1.234) == "1.234000E+00" @test Printf.@sprintf("%+e", 1.234) == "+1.234000e+00" @test Printf.@sprintf("% e", 1.234) == " 1.234000e+00" @test Printf.@sprintf("%e", -1.234) == "-1.234000e+00" @test Printf.@sprintf("%+e", -1.234) == "-1.234000e+00" @test Printf.@sprintf("% e", -1.234) == "-1.234000e+00" @test Printf.@sprintf("%#e", 1.234) == "1.234000e+00" @test Printf.@sprintf("%.2e", 1.234) == "1.23e+00" @test Printf.@sprintf("%.2e", 1.235) == "1.24e+00" @test Printf.@sprintf("%.2e", 0.235) == "2.35e-01" @test Printf.@sprintf("%4.1e", 1.234) == "1.2e+00" @test Printf.@sprintf("%8.1e", 1.234) == " 1.2e+00" @test Printf.@sprintf("%+8.1e", 1.234) == "+1.2e+00" @test Printf.@sprintf("% 8.1e", 1.234) == " 1.2e+00" @test Printf.@sprintf("% 7.1e", 1.234) == " 1.2e+00" @test Printf.@sprintf("% 08.1e", 1.234) == " 1.2e+00" @test Printf.@sprintf("%08.1e", 1.234) == "01.2e+00" @test Printf.@sprintf("%-08.1e", 1.234) == "1.2e+00 " @test Printf.@sprintf("%-8.1e", 1.234) == "1.2e+00 " @test Printf.@sprintf("%-8.1e", 1.234) == "1.2e+00 " @test Printf.@sprintf("%08.1e", -1.234) == "-1.2e+00" @test Printf.@sprintf("%09.1e", -1.234) == "-01.2e+00" @test Printf.@sprintf("%09.1e", 1.234) == "001.2e+00" @test Printf.@sprintf("%+09.1e", 1.234) == "+01.2e+00" @test Printf.@sprintf("% 09.1e", 1.234) == " 01.2e+00" @test Printf.@sprintf("%+ 09.1e", 1.234) == "+01.2e+00" @test Printf.@sprintf("%+ 09.1e", 1.234) == "+01.2e+00" @test Printf.@sprintf("%+ 09.0e", 1.234) == "+0001e+00" @test Printf.@sprintf("%+ #09.0e", 1.234) == "+001.e+00" @test Printf.@sprintf("%+9.1e", 9.96) == " +1.0e+01" @test Printf.@sprintf("% 9.1e", 9.96) == " 1.0e+01" end begin @test Printf.@sprintf("%e", Inf) == "Inf" @test Printf.@sprintf("%+e", Inf) == "+Inf" @test Printf.@sprintf("% e", Inf) == " Inf" @test Printf.@sprintf("% #e", Inf) == " Inf" @test Printf.@sprintf("%07e", Inf) == " Inf" @test Printf.@sprintf("%e", -Inf) == "-Inf" @test Printf.@sprintf("%+e", -Inf) == "-Inf" @test Printf.@sprintf("%07e", -Inf) == " -Inf" @test Printf.@sprintf("%e", NaN) == "NaN" @test Printf.@sprintf("%+e", NaN) == "+NaN" @test Printf.@sprintf("% e", NaN) == " NaN" @test Printf.@sprintf("% #e", NaN) == " NaN" @test Printf.@sprintf("%07e", NaN) == " NaN" @test Printf.@sprintf("%e", Inf) == "Inf" @test Printf.@sprintf("%e", NaN) == "NaN" @test Printf.@sprintf("%.0e", 3.0e142) == "3e+142" @test Printf.@sprintf("%#.0e", 3.0e142) == "3.e+142" @test Printf.@sprintf("%.0e", 2.999999999999999999999999999999999999999999999999999999999999999999999999999996e142) == "3e+142" @test Printf.@sprintf("%#.0e", 2.999999999999999999999999999999999999999999999999999999999999999999999999999996e142) == "3.e+142" @test Printf.@sprintf("%.0e", 3.000000000000000000000000000000000000000000000000000000000000000000000000000024e1042) == "3e+1042" @test Printf.@sprintf("%e", 3.0e42) == "3.000000e+42" @test Printf.@sprintf("%E", 3.0e42) == "3.000000E+42" @test Printf.@sprintf("%e", 3.0e-42) == "3.000000e-42" @test Printf.@sprintf("%E", 3.0e-42) == "3.000000E-42" @test Printf.@sprintf("%e", 1.234) == "1.234000e+00" @test Printf.@sprintf("%E", 1.234) == "1.234000E+00" @test Printf.@sprintf("%+e", 1.234) == "+1.234000e+00" @test Printf.@sprintf("% e", 1.234) == " 1.234000e+00" @test Printf.@sprintf("%e", -1.234) == "-1.234000e+00" @test Printf.@sprintf("%+e", -1.234) == "-1.234000e+00" @test Printf.@sprintf("% e", -1.234) == "-1.234000e+00" @test Printf.@sprintf("%#e", 1.234) == "1.234000e+00" @test Printf.@sprintf("%.2e", 1.234) == "1.23e+00" @test Printf.@sprintf("%.2e", 1.235) == "1.24e+00" @test Printf.@sprintf("%.2e", 0.235) == "2.35e-01" @test Printf.@sprintf("%4.1e", 1.234) == "1.2e+00" @test Printf.@sprintf("%8.1e", 1.234) == " 1.2e+00" @test Printf.@sprintf("%+8.1e", 1.234) == "+1.2e+00" @test Printf.@sprintf("% 8.1e", 1.234) == " 1.2e+00" @test Printf.@sprintf("% 7.1e", 1.234) == " 1.2e+00" @test Printf.@sprintf("% 08.1e", 1.234) == " 1.2e+00" @test Printf.@sprintf("%08.1e", 1.234) == "01.2e+00" @test Printf.@sprintf("%-08.1e", 1.234) == "1.2e+00 " @test Printf.@sprintf("%-8.1e", 1.234) == "1.2e+00 " @test Printf.@sprintf("%-8.1e", 1.234) == "1.2e+00 " @test Printf.@sprintf("%08.1e", -1.234) == "-1.2e+00" @test Printf.@sprintf("%09.1e", -1.234) == "-01.2e+00" @test Printf.@sprintf("%09.1e", 1.234) == "001.2e+00" @test Printf.@sprintf("%+09.1e", 1.234) == "+01.2e+00" @test Printf.@sprintf("% 09.1e", 1.234) == " 01.2e+00" @test Printf.@sprintf("%+ 09.1e", 1.234) == "+01.2e+00" @test Printf.@sprintf("%+ 09.1e", 1.234) == "+01.2e+00" @test Printf.@sprintf("%+ 09.0e", 1.234) == "+0001e+00" @test Printf.@sprintf("%+ #09.0e", 1.234) == "+001.e+00" @test Printf.@sprintf("%+9.1e", 9.96) == " +1.0e+01" @test Printf.@sprintf("% 9.1e", 9.96) == " 1.0e+01" end @testset "%e" begin @test Printf.@sprintf("%e", Inf) == "Inf" @test Printf.@sprintf("%+e", Inf) == "+Inf" @test Printf.@sprintf("% e", Inf) == " Inf" @test Printf.@sprintf("% #e", Inf) == " Inf" @test Printf.@sprintf("%07e", Inf) == " Inf" @test Printf.@sprintf("%e", -Inf) == "-Inf" @test Printf.@sprintf("%+e", -Inf) == "-Inf" @test Printf.@sprintf("%07e", -Inf) == " -Inf" @test Printf.@sprintf("%e", NaN) == "NaN" @test Printf.@sprintf("%+e", NaN) == "+NaN" @test Printf.@sprintf("% e", NaN) == " NaN" @test Printf.@sprintf("% #e", NaN) == " NaN" @test Printf.@sprintf("%07e", NaN) == " NaN" @test Printf.@sprintf("%e", Inf) == "Inf" @test Printf.@sprintf("%e", NaN) == "NaN" @test Printf.@sprintf("%.0e", 3.0e142) == "3e+142" @test Printf.@sprintf("%#.0e", 3.0e142) == "3.e+142" @test Printf.@sprintf("%.0e", 2.999999999999999999999999999999999999999999999999999999999999999999999999999996e142) == "3e+142" @test Printf.@sprintf("%#.0e", 2.999999999999999999999999999999999999999999999999999999999999999999999999999996e142) == "3.e+142" @test Printf.@sprintf("%.0e", 3.000000000000000000000000000000000000000000000000000000000000000000000000000024e1042) == "3e+1042" @test Printf.@sprintf("%e", 3.0e42) == "3.000000e+42" @test Printf.@sprintf("%E", 3.0e42) == "3.000000E+42" @test Printf.@sprintf("%e", 3.0e-42) == "3.000000e-42" @test Printf.@sprintf("%E", 3.0e-42) == "3.000000E-42" @test Printf.@sprintf("%e", 1.234) == "1.234000e+00" @test Printf.@sprintf("%E", 1.234) == "1.234000E+00" @test Printf.@sprintf("%+e", 1.234) == "+1.234000e+00" @test Printf.@sprintf("% e", 1.234) == " 1.234000e+00" @test Printf.@sprintf("%e", -1.234) == "-1.234000e+00" @test Printf.@sprintf("%+e", -1.234) == "-1.234000e+00" @test Printf.@sprintf("% e", -1.234) == "-1.234000e+00" @test Printf.@sprintf("%#e", 1.234) == "1.234000e+00" @test Printf.@sprintf("%.2e", 1.234) == "1.23e+00" @test Printf.@sprintf("%.2e", 1.235) == "1.24e+00" @test Printf.@sprintf("%.2e", 0.235) == "2.35e-01" @test Printf.@sprintf("%4.1e", 1.234) == "1.2e+00" @test Printf.@sprintf("%8.1e", 1.234) == " 1.2e+00" @test Printf.@sprintf("%+8.1e", 1.234) == "+1.2e+00" @test Printf.@sprintf("% 8.1e", 1.234) == " 1.2e+00" @test Printf.@sprintf("% 7.1e", 1.234) == " 1.2e+00" @test Printf.@sprintf("% 08.1e", 1.234) == " 1.2e+00" @test Printf.@sprintf("%08.1e", 1.234) == "01.2e+00" @test Printf.@sprintf("%-08.1e", 1.234) == "1.2e+00 " @test Printf.@sprintf("%-8.1e", 1.234) == "1.2e+00 " @test Printf.@sprintf("%-8.1e", 1.234) == "1.2e+00 " @test Printf.@sprintf("%08.1e", -1.234) == "-1.2e+00" @test Printf.@sprintf("%09.1e", -1.234) == "-01.2e+00" @test Printf.@sprintf("%09.1e", 1.234) == "001.2e+00" @test Printf.@sprintf("%+09.1e", 1.234) == "+01.2e+00" @test Printf.@sprintf("% 09.1e", 1.234) == " 01.2e+00" @test Printf.@sprintf("%+ 09.1e", 1.234) == "+01.2e+00" @test Printf.@sprintf("%+ 09.1e", 1.234) == "+01.2e+00" @test Printf.@sprintf("%+ 09.0e", 1.234) == "+0001e+00" @test Printf.@sprintf("%+ #09.0e", 1.234) == "+001.e+00" @test Printf.@sprintf("%+9.1e", 9.96) == " +1.0e+01" @test Printf.@sprintf("% 9.1e", 9.96) == " 1.0e+01" end @testset "%e" begin @test Printf.@sprintf("%e", Inf) == "Inf" @test Printf.@sprintf("%+e", Inf) == "+Inf" @test Printf.@sprintf("% e", Inf) == " Inf" @test Printf.@sprintf("% #e", Inf) == " Inf" @test Printf.@sprintf("%07e", Inf) == " Inf" @test Printf.@sprintf("%e", -Inf) == "-Inf" @test Printf.@sprintf("%+e", -Inf) == "-Inf" @test Printf.@sprintf("%07e", -Inf) == " -Inf" @test Printf.@sprintf("%e", NaN) == "NaN" @test Printf.@sprintf("%+e", NaN) == "+NaN" @test Printf.@sprintf("% e", NaN) == " NaN" @test Printf.@sprintf("% #e", NaN) == " NaN" @test Printf.@sprintf("%07e", NaN) == " NaN" @test Printf.@sprintf("%e", Inf) == "Inf" @test Printf.@sprintf("%e", NaN) == "NaN" @test Printf.@sprintf("%.0e", 3.0e142) == "3e+142" @test Printf.@sprintf("%#.0e", 3.0e142) == "3.e+142" @test Printf.@sprintf("%.0e", 2.999999999999999999999999999999999999999999999999999999999999999999999999999996e142) == "3e+142" @test Printf.@sprintf("%#.0e", 2.999999999999999999999999999999999999999999999999999999999999999999999999999996e142) == "3.e+142" @test Printf.@sprintf("%.0e", 3.000000000000000000000000000000000000000000000000000000000000000000000000000024e1042) == "3e+1042" @test Printf.@sprintf("%e", 3.0e42) == "3.000000e+42" @test Printf.@sprintf("%E", 3.0e42) == "3.000000E+42" @test Printf.@sprintf("%e", 3.0e-42) == "3.000000e-42" @test Printf.@sprintf("%E", 3.0e-42) == "3.000000E-42" @test Printf.@sprintf("%e", 1.234) == "1.234000e+00" @test Printf.@sprintf("%E", 1.234) == "1.234000E+00" @test Printf.@sprintf("%+e", 1.234) == "+1.234000e+00" @test Printf.@sprintf("% e", 1.234) == " 1.234000e+00" @test Printf.@sprintf("%e", -1.234) == "-1.234000e+00" @test Printf.@sprintf("%+e", -1.234) == "-1.234000e+00" @test Printf.@sprintf("% e", -1.234) == "-1.234000e+00" @test Printf.@sprintf("%#e", 1.234) == "1.234000e+00" @test Printf.@sprintf("%.2e", 1.234) == "1.23e+00" @test Printf.@sprintf("%.2e", 1.235) == "1.24e+00" @test Printf.@sprintf("%.2e", 0.235) == "2.35e-01" @test Printf.@sprintf("%4.1e", 1.234) == "1.2e+00" @test Printf.@sprintf("%8.1e", 1.234) == " 1.2e+00" @test Printf.@sprintf("%+8.1e", 1.234) == "+1.2e+00" @test Printf.@sprintf("% 8.1e", 1.234) == " 1.2e+00" @test Printf.@sprintf("% 7.1e", 1.234) == " 1.2e+00" @test Printf.@sprintf("% 08.1e", 1.234) == " 1.2e+00" @test Printf.@sprintf("%08.1e", 1.234) == "01.2e+00" @test Printf.@sprintf("%-08.1e", 1.234) == "1.2e+00 " @test Printf.@sprintf("%-8.1e", 1.234) == "1.2e+00 " @test Printf.@sprintf("%-8.1e", 1.234) == "1.2e+00 " @test Printf.@sprintf("%08.1e", -1.234) == "-1.2e+00" @test Printf.@sprintf("%09.1e", -1.234) == "-01.2e+00" @test Printf.@sprintf("%09.1e", 1.234) == "001.2e+00" @test Printf.@sprintf("%+09.1e", 1.234) == "+01.2e+00" @test Printf.@sprintf("% 09.1e", 1.234) == " 01.2e+00" @test Printf.@sprintf("%+ 09.1e", 1.234) == "+01.2e+00" @test Printf.@sprintf("%+ 09.1e", 1.234) == "+01.2e+00" @test Printf.@sprintf("%+ 09.0e", 1.234) == "+0001e+00" @test Printf.@sprintf("%+ #09.0e", 1.234) == "+001.e+00" @test Printf.@sprintf("%+9.1e", 9.96) == " +1.0e+01" @test Printf.@sprintf("% 9.1e", 9.96) == " 1.0e+01" end (1.2345, 1.234499999999999999999999999999999999999999999999999999999999999999999999999991) (1.2345, 1.234499999999999999999999999999999999999999999999999999999999999999999999999991) num = (1.2345, 1.234499999999999999999999999999999999999999999999999999999999999999999999999991) num = (1.2345, 1.234499999999999999999999999999999999999999999999999999999999999999999999999991) begin (fmt, val) = (("%7.2f", " 1.23"), ("%-7.2f", "1.23 "), ("%07.2f", "0001.23"), ("%.0f", "1"), ("%#.0f", "1."), ("%.4e", "1.2345e+00"), ("%.4E", "1.2345E+00"), ("%.2a", "0x1.3cp+0"), ("%.2A", "0X1.3CP+0")) num = (1.2345, 1.234499999999999999999999999999999999999999999999999999999999999999999999999991) end begin (fmt, val) = (("%7.2f", " 1.23"), ("%-7.2f", "1.23 "), ("%07.2f", "0001.23"), ("%.0f", "1"), ("%#.0f", "1."), ("%.4e", "1.2345e+00"), ("%.4E", "1.2345E+00"), ("%.2a", "0x1.3cp+0"), ("%.2A", "0X1.3CP+0")) num = (1.2345, 1.234499999999999999999999999999999999999999999999999999999999999999999999999991) end for (fmt, val) = (("%7.2f", " 1.23"), ("%-7.2f", "1.23 "), ("%07.2f", "0001.23"), ("%.0f", "1"), ("%#.0f", "1."), ("%.4e", "1.2345e+00"), ("%.4E", "1.2345E+00"), ("%.2a", "0x1.3cp+0"), ("%.2A", "0X1.3CP+0")), num = (1.2345, 1.234499999999999999999999999999999999999999999999999999999999999999999999999991) @test Printf.format(Printf.Format(fmt), num) == val end for (fmt, val) = (("%7.2f", " 1.23"), ("%-7.2f", "1.23 "), ("%07.2f", "0001.23"), ("%.0f", "1"), ("%#.0f", "1."), ("%.4e", "1.2345e+00"), ("%.4E", "1.2345E+00"), ("%.2a", "0x1.3cp+0"), ("%.2A", "0X1.3CP+0")), num = (1.2345, 1.234499999999999999999999999999999999999999999999999999999999999999999999999991) @test Printf.format(Printf.Format(fmt), num) == val end (UInt16(42), UInt32(42), UInt64(42), UInt128(42), Int16(42), Int32(42), Int64(42), Int128(42), 42) (UInt16(42), UInt32(42), UInt64(42), UInt128(42), Int16(42), Int32(42), Int64(42), Int128(42), 42) num = (UInt16(42), UInt32(42), UInt64(42), UInt128(42), Int16(42), Int32(42), Int64(42), Int128(42), 42) num = (UInt16(42), UInt32(42), UInt64(42), UInt128(42), Int16(42), Int32(42), Int64(42), Int128(42), 42) begin (fmt, val) = (("%i", "42"), ("%u", "42"), ("Test: %i", "Test: 42"), ("%#x", "0x2a"), ("%x", "2a"), ("%X", "2A"), ("% i", " 42"), ("%+i", "+42"), ("%4i", " 42"), ("%-4i", "42 "), ("%f", "42.000000"), ("%g", "42"), ("%e", "4.200000e+01")) num = (UInt16(42), UInt32(42), UInt64(42), UInt128(42), Int16(42), Int32(42), Int64(42), Int128(42), 42) end begin (fmt, val) = (("%i", "42"), ("%u", "42"), ("Test: %i", "Test: 42"), ("%#x", "0x2a"), ("%x", "2a"), ("%X", "2A"), ("% i", " 42"), ("%+i", "+42"), ("%4i", " 42"), ("%-4i", "42 "), ("%f", "42.000000"), ("%g", "42"), ("%e", "4.200000e+01")) num = (UInt16(42), UInt32(42), UInt64(42), UInt128(42), Int16(42), Int32(42), Int64(42), Int128(42), 42) end for (fmt, val) = (("%i", "42"), ("%u", "42"), ("Test: %i", "Test: 42"), ("%#x", "0x2a"), ("%x", "2a"), ("%X", "2A"), ("% i", " 42"), ("%+i", "+42"), ("%4i", " 42"), ("%-4i", "42 "), ("%f", "42.000000"), ("%g", "42"), ("%e", "4.200000e+01")), num = (UInt16(42), UInt32(42), UInt64(42), UInt128(42), Int16(42), Int32(42), Int64(42), Int128(42), 42) @test Printf.format(Printf.Format(fmt), num) == val end for (fmt, val) = (("%i", "42"), ("%u", "42"), ("Test: %i", "Test: 42"), ("%#x", "0x2a"), ("%x", "2a"), ("%X", "2A"), ("% i", " 42"), ("%+i", "+42"), ("%4i", " 42"), ("%-4i", "42 "), ("%f", "42.000000"), ("%g", "42"), ("%e", "4.200000e+01")), num = (UInt16(42), UInt32(42), UInt64(42), UInt128(42), Int16(42), Int32(42), Int64(42), Int128(42), 42) @test Printf.format(Printf.Format(fmt), num) == val end begin @test Printf.@sprintf("%%") == "%" @test Printf.@sprintf("1%%") == "1%" @test Printf.@sprintf("%%1") == "%1" @test Printf.@sprintf("1%%2") == "1%2" @test Printf.@sprintf("1%%%d", 2) == "1%2" @test Printf.@sprintf("1%%2%%3") == "1%2%3" @test Printf.@sprintf("GAP[%%]") == "GAP[%]" @test Printf.@sprintf("hey there") == "hey there" @test_throws Printf.InvalidFormatStringError Printf.Format("%+") @test_throws Printf.InvalidFormatStringError Printf.Format("%.") @test_throws Printf.InvalidFormatStringError Printf.Format("%.0") @test isempty((Printf.Format("%%")).formats) @test Printf.@sprintf("%d%d", 1, 2) == "12" @test Printf.@sprintf("%d%d", [1 2]...) == "12" @test Printf.@sprintf("X%d", 2) == "X2" @test Printf.@sprintf("Ð%d", 2) == "Ð2" @test Printf.@sprintf("ༀ%d", 2) == "ༀ2" @test Printf.@sprintf("\U1ffff%d", 2) == "\U0001ffff2" @test Printf.@sprintf("%dX%d", 1, 2) == "1X2" @test Printf.@sprintf("%dÐ%d", 1, 2) == "1Ð2" @test Printf.@sprintf("%dༀ%d", 1, 2) == "1ༀ2" @test Printf.@sprintf("%d\U1ffff%d", 1, 2) == "1\U0001ffff2" @test Printf.@sprintf("%d∃%dȃ", 1, 2) == "1∃2ȃ" @test_throws Printf.InvalidFormatStringError Printf.Format("%y%d") @test_throws Printf.InvalidFormatStringError Printf.Format("%Ð%d") @test_throws Printf.InvalidFormatStringError Printf.Format("%ༀ%d") @test_throws Printf.InvalidFormatStringError Printf.Format("%\U1ffff%d") @test Printf.@sprintf("%10.5d", 4) == " 00004" @test Printf.@sprintf("%d", typemax(Int64)) == "9223372036854775807" for (fmt, val) = (("%7.2f", " 1.23"), ("%-7.2f", "1.23 "), ("%07.2f", "0001.23"), ("%.0f", "1"), ("%#.0f", "1."), ("%.4e", "1.2345e+00"), ("%.4E", "1.2345E+00"), ("%.2a", "0x1.3cp+0"), ("%.2A", "0X1.3CP+0")), num = (1.2345, 1.234499999999999999999999999999999999999999999999999999999999999999999999999991) @test Printf.format(Printf.Format(fmt), num) == val end for (fmt, val) = (("%i", "42"), ("%u", "42"), ("Test: %i", "Test: 42"), ("%#x", "0x2a"), ("%x", "2a"), ("%X", "2A"), ("% i", " 42"), ("%+i", "+42"), ("%4i", " 42"), ("%-4i", "42 "), ("%f", "42.000000"), ("%g", "42"), ("%e", "4.200000e+01")), num = (UInt16(42), UInt32(42), UInt64(42), UInt128(42), Int16(42), Int32(42), Int64(42), Int128(42), 42) @test Printf.format(Printf.Format(fmt), num) == val end for i = ((42, "", "i", "42", ""), (42, "", "d", "42", ""), (42, "", "u", "42", ""), (42, "", "x", "2a", ""), (42, "", "X", "2A", ""), (42, "", "o", "52", ""), (42, "#", "x", "2a", "0x"), (42, "#", "X", "2A", "0X"), (42, "#", "o", "052", ""), (1.2345, "", ".2f", "1.23", ""), (1.2345, "", ".2e", "1.23e+00", ""), (1.2345, "", ".2E", "1.23E+00", ""), (1.2345, "#", ".0f", "1.", ""), (1.2345, "#", ".0e", "1.e+00", ""), (1.2345, "#", ".0E", "1.E+00", ""), (1.2345, "", ".2a", "1.3cp+0", "0x"), (1.2345, "", ".2A", "1.3CP+0", "0X")) _test_flags(i...) _test_flags(-(i[1]), i[2:5]...) end @test Printf.@sprintf("Test: %s%c%C%c%#-.0f.", "t", 65, 66, 67, -42) == "Test: tABC-42.." @test Printf.@sprintf("%f %d %d %f", 1.0, [3 4]..., 5) == "1.000000 3 4 5.000000" @test Printf.@sprintf("%s %f %9.5f %d %d %d %d%d%d%d", [1:6;]..., [7, 8, 9, 10]...) == "1 2.000000 3.00000 4 5 6 78910" @test Printf.@sprintf("%s %s %s %d %d %d %f %f %f", Any[10 ^ x + y for x = 1:3, y = 1:3]...) == "11 101 1001 12 102 1002 13.000000 103.000000 1003.000000" @test Printf.@sprintf("%s %s %s %d %d %d %f %f %f %s %s %s %d %d %d %f %f %f", Any[10x + (x + 1) for x = 1:18]...) == "12 23 34 45 56 67 78.000000 89.000000 100.000000 111 122 133 144 155 166 177.000000 188.000000 199.000000" @test (Printf.@sprintf("%.330f", BigFloat(1)))[var"end"] != '\0' @test Printf.@sprintf("%f", parse(BigFloat, "1e400")) == "10000000000000000000000000000000000000000000000000000000000000000000000000000025262527574416492004687051900140830217136998040684679611623086405387447100385714565637522507383770691831689647535911648520404034824470543643098638520633064715221151920028135130764414460468236314621044034960475540018328999334468948008954289495190631358190153259681118693204411689043999084305348398480210026863210192871358464.000000" @test_throws ArgumentError Printf.@sprintf("%f", parse(BigFloat, "1e99999")) @test Printf.@sprintf("%4.2s", "a") == " a" @test Printf.@sprintf("%12.3e", pi * 1.0e100) == " 3.142e+100" @test string((Printf.Format("%a")).formats[1]) == "%a" @test string((Printf.Format("%a")).formats[1]; modifier = "R") == "%Ra" @test Printf.@sprintf("%d", 3.14) == "3" @test Printf.@sprintf("%2d", 3.14) == " 3" @test Printf.@sprintf("%2d", big(3.14)) == " 3" @test Printf.@sprintf("%s", 1) == "1" @test Printf.@sprintf("%f", 1) == "1.000000" @test Printf.@sprintf("%e", 1) == "1.000000e+00" @test Printf.@sprintf("%g", 1) == "1" @test Printf.@sprintf("%.16g", 194.4778127560983) == "194.4778127560983" @test Printf.@sprintf("%.17g", 194.4778127560983) == "194.4778127560983" @test Printf.@sprintf("%.18g", 194.4778127560983) == "194.477812756098302" @test Printf.@sprintf("%.1g", 1.7976931348623157e308) == "2e+308" @test Printf.@sprintf("%.2g", 1.7976931348623157e308) == "1.8e+308" @test Printf.@sprintf("%.3g", 1.7976931348623157e308) == "1.8e+308" @test_throws ArgumentError @sprintf("%s%%%s", "a") @test @sprintf("%s%%%s", "a", "b") == "a%b" @test @sprintf("%d", 25.5) == "26" @test @sprintf(" %.1e\n", 0.999) == " 1.0e+00\n" @test @sprintf(" %.1f", 9.999) == " 10.0" @test @sprintf("%d", 1.0e100) == "10000000000000000159028911097599180468360808563945281389781327557747838772170381060813469985856815104" @test @sprintf("%d", 3 // 1) == "3" @test @sprintf("%d", Inf) == "Inf" @test @sprintf(" %d", NaN) == " NaN" @test Printf.@sprintf("") == "" @test Printf.format(Printf.Format("")) == "" end begin @test Printf.@sprintf("%%") == "%" @test Printf.@sprintf("1%%") == "1%" @test Printf.@sprintf("%%1") == "%1" @test Printf.@sprintf("1%%2") == "1%2" @test Printf.@sprintf("1%%%d", 2) == "1%2" @test Printf.@sprintf("1%%2%%3") == "1%2%3" @test Printf.@sprintf("GAP[%%]") == "GAP[%]" @test Printf.@sprintf("hey there") == "hey there" @test_throws Printf.InvalidFormatStringError Printf.Format("%+") @test_throws Printf.InvalidFormatStringError Printf.Format("%.") @test_throws Printf.InvalidFormatStringError Printf.Format("%.0") @test isempty((Printf.Format("%%")).formats) @test Printf.@sprintf("%d%d", 1, 2) == "12" @test Printf.@sprintf("%d%d", [1 2]...) == "12" @test Printf.@sprintf("X%d", 2) == "X2" @test Printf.@sprintf("Ð%d", 2) == "Ð2" @test Printf.@sprintf("ༀ%d", 2) == "ༀ2" @test Printf.@sprintf("\U1ffff%d", 2) == "\U0001ffff2" @test Printf.@sprintf("%dX%d", 1, 2) == "1X2" @test Printf.@sprintf("%dÐ%d", 1, 2) == "1Ð2" @test Printf.@sprintf("%dༀ%d", 1, 2) == "1ༀ2" @test Printf.@sprintf("%d\U1ffff%d", 1, 2) == "1\U0001ffff2" @test Printf.@sprintf("%d∃%dȃ", 1, 2) == "1∃2ȃ" @test_throws Printf.InvalidFormatStringError Printf.Format("%y%d") @test_throws Printf.InvalidFormatStringError Printf.Format("%Ð%d") @test_throws Printf.InvalidFormatStringError Printf.Format("%ༀ%d") @test_throws Printf.InvalidFormatStringError Printf.Format("%\U1ffff%d") @test Printf.@sprintf("%10.5d", 4) == " 00004" @test Printf.@sprintf("%d", typemax(Int64)) == "9223372036854775807" for (fmt, val) = (("%7.2f", " 1.23"), ("%-7.2f", "1.23 "), ("%07.2f", "0001.23"), ("%.0f", "1"), ("%#.0f", "1."), ("%.4e", "1.2345e+00"), ("%.4E", "1.2345E+00"), ("%.2a", "0x1.3cp+0"), ("%.2A", "0X1.3CP+0")), num = (1.2345, 1.234499999999999999999999999999999999999999999999999999999999999999999999999991) @test Printf.format(Printf.Format(fmt), num) == val end for (fmt, val) = (("%i", "42"), ("%u", "42"), ("Test: %i", "Test: 42"), ("%#x", "0x2a"), ("%x", "2a"), ("%X", "2A"), ("% i", " 42"), ("%+i", "+42"), ("%4i", " 42"), ("%-4i", "42 "), ("%f", "42.000000"), ("%g", "42"), ("%e", "4.200000e+01")), num = (UInt16(42), UInt32(42), UInt64(42), UInt128(42), Int16(42), Int32(42), Int64(42), Int128(42), 42) @test Printf.format(Printf.Format(fmt), num) == val end for i = ((42, "", "i", "42", ""), (42, "", "d", "42", ""), (42, "", "u", "42", ""), (42, "", "x", "2a", ""), (42, "", "X", "2A", ""), (42, "", "o", "52", ""), (42, "#", "x", "2a", "0x"), (42, "#", "X", "2A", "0X"), (42, "#", "o", "052", ""), (1.2345, "", ".2f", "1.23", ""), (1.2345, "", ".2e", "1.23e+00", ""), (1.2345, "", ".2E", "1.23E+00", ""), (1.2345, "#", ".0f", "1.", ""), (1.2345, "#", ".0e", "1.e+00", ""), (1.2345, "#", ".0E", "1.E+00", ""), (1.2345, "", ".2a", "1.3cp+0", "0x"), (1.2345, "", ".2A", "1.3CP+0", "0X")) _test_flags(i...) _test_flags(-(i[1]), i[2:5]...) end @test Printf.@sprintf("Test: %s%c%C%c%#-.0f.", "t", 65, 66, 67, -42) == "Test: tABC-42.." @test Printf.@sprintf("%f %d %d %f", 1.0, [3 4]..., 5) == "1.000000 3 4 5.000000" @test Printf.@sprintf("%s %f %9.5f %d %d %d %d%d%d%d", [1:6;]..., [7, 8, 9, 10]...) == "1 2.000000 3.00000 4 5 6 78910" @test Printf.@sprintf("%s %s %s %d %d %d %f %f %f", Any[10 ^ x + y for x = 1:3, y = 1:3]...) == "11 101 1001 12 102 1002 13.000000 103.000000 1003.000000" @test Printf.@sprintf("%s %s %s %d %d %d %f %f %f %s %s %s %d %d %d %f %f %f", Any[10x + (x + 1) for x = 1:18]...) == "12 23 34 45 56 67 78.000000 89.000000 100.000000 111 122 133 144 155 166 177.000000 188.000000 199.000000" @test (Printf.@sprintf("%.330f", BigFloat(1)))[var"end"] != '\0' @test Printf.@sprintf("%f", parse(BigFloat, "1e400")) == "10000000000000000000000000000000000000000000000000000000000000000000000000000025262527574416492004687051900140830217136998040684679611623086405387447100385714565637522507383770691831689647535911648520404034824470543643098638520633064715221151920028135130764414460468236314621044034960475540018328999334468948008954289495190631358190153259681118693204411689043999084305348398480210026863210192871358464.000000" @test_throws ArgumentError Printf.@sprintf("%f", parse(BigFloat, "1e99999")) @test Printf.@sprintf("%4.2s", "a") == " a" @test Printf.@sprintf("%12.3e", pi * 1.0e100) == " 3.142e+100" @test string((Printf.Format("%a")).formats[1]) == "%a" @test string((Printf.Format("%a")).formats[1]; modifier = "R") == "%Ra" @test Printf.@sprintf("%d", 3.14) == "3" @test Printf.@sprintf("%2d", 3.14) == " 3" @test Printf.@sprintf("%2d", big(3.14)) == " 3" @test Printf.@sprintf("%s", 1) == "1" @test Printf.@sprintf("%f", 1) == "1.000000" @test Printf.@sprintf("%e", 1) == "1.000000e+00" @test Printf.@sprintf("%g", 1) == "1" @test Printf.@sprintf("%.16g", 194.4778127560983) == "194.4778127560983" @test Printf.@sprintf("%.17g", 194.4778127560983) == "194.4778127560983" @test Printf.@sprintf("%.18g", 194.4778127560983) == "194.477812756098302" @test Printf.@sprintf("%.1g", 1.7976931348623157e308) == "2e+308" @test Printf.@sprintf("%.2g", 1.7976931348623157e308) == "1.8e+308" @test Printf.@sprintf("%.3g", 1.7976931348623157e308) == "1.8e+308" @test_throws ArgumentError @sprintf("%s%%%s", "a") @test @sprintf("%s%%%s", "a", "b") == "a%b" @test @sprintf("%d", 25.5) == "26" @test @sprintf(" %.1e\n", 0.999) == " 1.0e+00\n" @test @sprintf(" %.1f", 9.999) == " 10.0" @test @sprintf("%d", 1.0e100) == "10000000000000000159028911097599180468360808563945281389781327557747838772170381060813469985856815104" @test @sprintf("%d", 3 // 1) == "3" @test @sprintf("%d", Inf) == "Inf" @test @sprintf(" %d", NaN) == " NaN" @test Printf.@sprintf("") == "" @test Printf.format(Printf.Format("")) == "" end @testset "basics" begin @test Printf.@sprintf("%%") == "%" @test Printf.@sprintf("1%%") == "1%" @test Printf.@sprintf("%%1") == "%1" @test Printf.@sprintf("1%%2") == "1%2" @test Printf.@sprintf("1%%%d", 2) == "1%2" @test Printf.@sprintf("1%%2%%3") == "1%2%3" @test Printf.@sprintf("GAP[%%]") == "GAP[%]" @test Printf.@sprintf("hey there") == "hey there" @test_throws Printf.InvalidFormatStringError Printf.Format("%+") @test_throws Printf.InvalidFormatStringError Printf.Format("%.") @test_throws Printf.InvalidFormatStringError Printf.Format("%.0") @test isempty((Printf.Format("%%")).formats) @test Printf.@sprintf("%d%d", 1, 2) == "12" @test Printf.@sprintf("%d%d", [1 2]...) == "12" @test Printf.@sprintf("X%d", 2) == "X2" @test Printf.@sprintf("Ð%d", 2) == "Ð2" @test Printf.@sprintf("ༀ%d", 2) == "ༀ2" @test Printf.@sprintf("\U1ffff%d", 2) == "\U0001ffff2" @test Printf.@sprintf("%dX%d", 1, 2) == "1X2" @test Printf.@sprintf("%dÐ%d", 1, 2) == "1Ð2" @test Printf.@sprintf("%dༀ%d", 1, 2) == "1ༀ2" @test Printf.@sprintf("%d\U1ffff%d", 1, 2) == "1\U0001ffff2" @test Printf.@sprintf("%d∃%dȃ", 1, 2) == "1∃2ȃ" @test_throws Printf.InvalidFormatStringError Printf.Format("%y%d") @test_throws Printf.InvalidFormatStringError Printf.Format("%Ð%d") @test_throws Printf.InvalidFormatStringError Printf.Format("%ༀ%d") @test_throws Printf.InvalidFormatStringError Printf.Format("%\U1ffff%d") @test Printf.@sprintf("%10.5d", 4) == " 00004" @test Printf.@sprintf("%d", typemax(Int64)) == "9223372036854775807" for (fmt, val) = (("%7.2f", " 1.23"), ("%-7.2f", "1.23 "), ("%07.2f", "0001.23"), ("%.0f", "1"), ("%#.0f", "1."), ("%.4e", "1.2345e+00"), ("%.4E", "1.2345E+00"), ("%.2a", "0x1.3cp+0"), ("%.2A", "0X1.3CP+0")), num = (1.2345, 1.234499999999999999999999999999999999999999999999999999999999999999999999999991) @test Printf.format(Printf.Format(fmt), num) == val end for (fmt, val) = (("%i", "42"), ("%u", "42"), ("Test: %i", "Test: 42"), ("%#x", "0x2a"), ("%x", "2a"), ("%X", "2A"), ("% i", " 42"), ("%+i", "+42"), ("%4i", " 42"), ("%-4i", "42 "), ("%f", "42.000000"), ("%g", "42"), ("%e", "4.200000e+01")), num = (UInt16(42), UInt32(42), UInt64(42), UInt128(42), Int16(42), Int32(42), Int64(42), Int128(42), 42) @test Printf.format(Printf.Format(fmt), num) == val end for i = ((42, "", "i", "42", ""), (42, "", "d", "42", ""), (42, "", "u", "42", ""), (42, "", "x", "2a", ""), (42, "", "X", "2A", ""), (42, "", "o", "52", ""), (42, "#", "x", "2a", "0x"), (42, "#", "X", "2A", "0X"), (42, "#", "o", "052", ""), (1.2345, "", ".2f", "1.23", ""), (1.2345, "", ".2e", "1.23e+00", ""), (1.2345, "", ".2E", "1.23E+00", ""), (1.2345, "#", ".0f", "1.", ""), (1.2345, "#", ".0e", "1.e+00", ""), (1.2345, "#", ".0E", "1.E+00", ""), (1.2345, "", ".2a", "1.3cp+0", "0x"), (1.2345, "", ".2A", "1.3CP+0", "0X")) _test_flags(i...) _test_flags(-(i[1]), i[2:5]...) end @test Printf.@sprintf("Test: %s%c%C%c%#-.0f.", "t", 65, 66, 67, -42) == "Test: tABC-42.." @test Printf.@sprintf("%f %d %d %f", 1.0, [3 4]..., 5) == "1.000000 3 4 5.000000" @test Printf.@sprintf("%s %f %9.5f %d %d %d %d%d%d%d", [1:6;]..., [7, 8, 9, 10]...) == "1 2.000000 3.00000 4 5 6 78910" @test Printf.@sprintf("%s %s %s %d %d %d %f %f %f", Any[10 ^ x + y for x = 1:3, y = 1:3]...) == "11 101 1001 12 102 1002 13.000000 103.000000 1003.000000" @test Printf.@sprintf("%s %s %s %d %d %d %f %f %f %s %s %s %d %d %d %f %f %f", Any[10x + (x + 1) for x = 1:18]...) == "12 23 34 45 56 67 78.000000 89.000000 100.000000 111 122 133 144 155 166 177.000000 188.000000 199.000000" @test (Printf.@sprintf("%.330f", BigFloat(1)))[var"end"] != '\0' @test Printf.@sprintf("%f", parse(BigFloat, "1e400")) == "10000000000000000000000000000000000000000000000000000000000000000000000000000025262527574416492004687051900140830217136998040684679611623086405387447100385714565637522507383770691831689647535911648520404034824470543643098638520633064715221151920028135130764414460468236314621044034960475540018328999334468948008954289495190631358190153259681118693204411689043999084305348398480210026863210192871358464.000000" @test_throws ArgumentError Printf.@sprintf("%f", parse(BigFloat, "1e99999")) @test Printf.@sprintf("%4.2s", "a") == " a" @test Printf.@sprintf("%12.3e", pi * 1.0e100) == " 3.142e+100" @test string((Printf.Format("%a")).formats[1]) == "%a" @test string((Printf.Format("%a")).formats[1]; modifier = "R") == "%Ra" @test Printf.@sprintf("%d", 3.14) == "3" @test Printf.@sprintf("%2d", 3.14) == " 3" @test Printf.@sprintf("%2d", big(3.14)) == " 3" @test Printf.@sprintf("%s", 1) == "1" @test Printf.@sprintf("%f", 1) == "1.000000" @test Printf.@sprintf("%e", 1) == "1.000000e+00" @test Printf.@sprintf("%g", 1) == "1" @test Printf.@sprintf("%.16g", 194.4778127560983) == "194.4778127560983" @test Printf.@sprintf("%.17g", 194.4778127560983) == "194.4778127560983" @test Printf.@sprintf("%.18g", 194.4778127560983) == "194.477812756098302" @test Printf.@sprintf("%.1g", 1.7976931348623157e308) == "2e+308" @test Printf.@sprintf("%.2g", 1.7976931348623157e308) == "1.8e+308" @test Printf.@sprintf("%.3g", 1.7976931348623157e308) == "1.8e+308" @test_throws ArgumentError @sprintf("%s%%%s", "a") @test @sprintf("%s%%%s", "a", "b") == "a%b" @test @sprintf("%d", 25.5) == "26" @test @sprintf(" %.1e\n", 0.999) == " 1.0e+00\n" @test @sprintf(" %.1f", 9.999) == " 10.0" @test @sprintf("%d", 1.0e100) == "10000000000000000159028911097599180468360808563945281389781327557747838772170381060813469985856815104" @test @sprintf("%d", 3 // 1) == "3" @test @sprintf("%d", Inf) == "Inf" @test @sprintf(" %d", NaN) == " NaN" @test Printf.@sprintf("") == "" @test Printf.format(Printf.Format("")) == "" end @testset "basics" begin @test Printf.@sprintf("%%") == "%" @test Printf.@sprintf("1%%") == "1%" @test Printf.@sprintf("%%1") == "%1" @test Printf.@sprintf("1%%2") == "1%2" @test Printf.@sprintf("1%%%d", 2) == "1%2" @test Printf.@sprintf("1%%2%%3") == "1%2%3" @test Printf.@sprintf("GAP[%%]") == "GAP[%]" @test Printf.@sprintf("hey there") == "hey there" @test_throws Printf.InvalidFormatStringError Printf.Format("%+") @test_throws Printf.InvalidFormatStringError Printf.Format("%.") @test_throws Printf.InvalidFormatStringError Printf.Format("%.0") @test isempty((Printf.Format("%%")).formats) @test Printf.@sprintf("%d%d", 1, 2) == "12" @test Printf.@sprintf("%d%d", [1 2]...) == "12" @test Printf.@sprintf("X%d", 2) == "X2" @test Printf.@sprintf("Ð%d", 2) == "Ð2" @test Printf.@sprintf("ༀ%d", 2) == "ༀ2" @test Printf.@sprintf("\U1ffff%d", 2) == "\U0001ffff2" @test Printf.@sprintf("%dX%d", 1, 2) == "1X2" @test Printf.@sprintf("%dÐ%d", 1, 2) == "1Ð2" @test Printf.@sprintf("%dༀ%d", 1, 2) == "1ༀ2" @test Printf.@sprintf("%d\U1ffff%d", 1, 2) == "1\U0001ffff2" @test Printf.@sprintf("%d∃%dȃ", 1, 2) == "1∃2ȃ" @test_throws Printf.InvalidFormatStringError Printf.Format("%y%d") @test_throws Printf.InvalidFormatStringError Printf.Format("%Ð%d") @test_throws Printf.InvalidFormatStringError Printf.Format("%ༀ%d") @test_throws Printf.InvalidFormatStringError Printf.Format("%\U1ffff%d") @test Printf.@sprintf("%10.5d", 4) == " 00004" @test Printf.@sprintf("%d", typemax(Int64)) == "9223372036854775807" for (fmt, val) = (("%7.2f", " 1.23"), ("%-7.2f", "1.23 "), ("%07.2f", "0001.23"), ("%.0f", "1"), ("%#.0f", "1."), ("%.4e", "1.2345e+00"), ("%.4E", "1.2345E+00"), ("%.2a", "0x1.3cp+0"), ("%.2A", "0X1.3CP+0")), num = (1.2345, 1.234499999999999999999999999999999999999999999999999999999999999999999999999991) @test Printf.format(Printf.Format(fmt), num) == val end for (fmt, val) = (("%i", "42"), ("%u", "42"), ("Test: %i", "Test: 42"), ("%#x", "0x2a"), ("%x", "2a"), ("%X", "2A"), ("% i", " 42"), ("%+i", "+42"), ("%4i", " 42"), ("%-4i", "42 "), ("%f", "42.000000"), ("%g", "42"), ("%e", "4.200000e+01")), num = (UInt16(42), UInt32(42), UInt64(42), UInt128(42), Int16(42), Int32(42), Int64(42), Int128(42), 42) @test Printf.format(Printf.Format(fmt), num) == val end for i = ((42, "", "i", "42", ""), (42, "", "d", "42", ""), (42, "", "u", "42", ""), (42, "", "x", "2a", ""), (42, "", "X", "2A", ""), (42, "", "o", "52", ""), (42, "#", "x", "2a", "0x"), (42, "#", "X", "2A", "0X"), (42, "#", "o", "052", ""), (1.2345, "", ".2f", "1.23", ""), (1.2345, "", ".2e", "1.23e+00", ""), (1.2345, "", ".2E", "1.23E+00", ""), (1.2345, "#", ".0f", "1.", ""), (1.2345, "#", ".0e", "1.e+00", ""), (1.2345, "#", ".0E", "1.E+00", ""), (1.2345, "", ".2a", "1.3cp+0", "0x"), (1.2345, "", ".2A", "1.3CP+0", "0X")) _test_flags(i...) _test_flags(-(i[1]), i[2:5]...) end @test Printf.@sprintf("Test: %s%c%C%c%#-.0f.", "t", 65, 66, 67, -42) == "Test: tABC-42.." @test Printf.@sprintf("%f %d %d %f", 1.0, [3 4]..., 5) == "1.000000 3 4 5.000000" @test Printf.@sprintf("%s %f %9.5f %d %d %d %d%d%d%d", [1:6;]..., [7, 8, 9, 10]...) == "1 2.000000 3.00000 4 5 6 78910" @test Printf.@sprintf("%s %s %s %d %d %d %f %f %f", Any[10 ^ x + y for x = 1:3, y = 1:3]...) == "11 101 1001 12 102 1002 13.000000 103.000000 1003.000000" @test Printf.@sprintf("%s %s %s %d %d %d %f %f %f %s %s %s %d %d %d %f %f %f", Any[10x + (x + 1) for x = 1:18]...) == "12 23 34 45 56 67 78.000000 89.000000 100.000000 111 122 133 144 155 166 177.000000 188.000000 199.000000" @test (Printf.@sprintf("%.330f", BigFloat(1)))[var"end"] != '\0' @test Printf.@sprintf("%f", parse(BigFloat, "1e400")) == "10000000000000000000000000000000000000000000000000000000000000000000000000000025262527574416492004687051900140830217136998040684679611623086405387447100385714565637522507383770691831689647535911648520404034824470543643098638520633064715221151920028135130764414460468236314621044034960475540018328999334468948008954289495190631358190153259681118693204411689043999084305348398480210026863210192871358464.000000" @test_throws ArgumentError Printf.@sprintf("%f", parse(BigFloat, "1e99999")) @test Printf.@sprintf("%4.2s", "a") == " a" @test Printf.@sprintf("%12.3e", pi * 1.0e100) == " 3.142e+100" @test string((Printf.Format("%a")).formats[1]) == "%a" @test string((Printf.Format("%a")).formats[1]; modifier = "R") == "%Ra" @test Printf.@sprintf("%d", 3.14) == "3" @test Printf.@sprintf("%2d", 3.14) == " 3" @test Printf.@sprintf("%2d", big(3.14)) == " 3" @test Printf.@sprintf("%s", 1) == "1" @test Printf.@sprintf("%f", 1) == "1.000000" @test Printf.@sprintf("%e", 1) == "1.000000e+00" @test Printf.@sprintf("%g", 1) == "1" @test Printf.@sprintf("%.16g", 194.4778127560983) == "194.4778127560983" @test Printf.@sprintf("%.17g", 194.4778127560983) == "194.4778127560983" @test Printf.@sprintf("%.18g", 194.4778127560983) == "194.477812756098302" @test Printf.@sprintf("%.1g", 1.7976931348623157e308) == "2e+308" @test Printf.@sprintf("%.2g", 1.7976931348623157e308) == "1.8e+308" @test Printf.@sprintf("%.3g", 1.7976931348623157e308) == "1.8e+308" @test_throws ArgumentError @sprintf("%s%%%s", "a") @test @sprintf("%s%%%s", "a", "b") == "a%b" @test @sprintf("%d", 25.5) == "26" @test @sprintf(" %.1e\n", 0.999) == " 1.0e+00\n" @test @sprintf(" %.1f", 9.999) == " 10.0" @test @sprintf("%d", 1.0e100) == "10000000000000000159028911097599180468360808563945281389781327557747838772170381060813469985856815104" @test @sprintf("%d", 3 // 1) == "3" @test @sprintf("%d", Inf) == "Inf" @test @sprintf(" %d", NaN) == " NaN" @test Printf.@sprintf("") == "" @test Printf.format(Printf.Format("")) == "" end Printf.@sprintf "%*.*g" 10 5 -123.4000000000000000000000000000000000000000000000000000000000000000000000000002 Printf.@sprintf "%*.*g" 10 5 -123.4000000000000000000000000000000000000000000000000000000000000000000000000002 Printf.@sprintf "%10.5g" -123.4000000000000000000000000000000000000000000000000000000000000000000000000002 Printf.@sprintf "%10.5g" -123.4000000000000000000000000000000000000000000000000000000000000000000000000002 Printf.@sprintf("%*.*g", 10, 5, -123.4000000000000000000000000000000000000000000000000000000000000000000000000002) == Printf.@sprintf("%10.5g", -123.4000000000000000000000000000000000000000000000000000000000000000000000000002) Printf.@sprintf("%*.*g", 10, 5, -123.4000000000000000000000000000000000000000000000000000000000000000000000000002) == Printf.@sprintf("%10.5g", -123.4000000000000000000000000000000000000000000000000000000000000000000000000002) @test Printf.@sprintf("%*.*g", 10, 5, -123.4000000000000000000000000000000000000000000000000000000000000000000000000002) == Printf.@sprintf("%10.5g", -123.4000000000000000000000000000000000000000000000000000000000000000000000000002) @test Printf.@sprintf("%*.*g", 10, 5, -123.4000000000000000000000000000000000000000000000000000000000000000000000000002) == Printf.@sprintf("%10.5g", -123.4000000000000000000000000000000000000000000000000000000000000000000000000002) Printf.@sprintf "%0*.*g" 10 5 -123.4000000000000000000000000000000000000000000000000000000000000000000000000002 Printf.@sprintf "%0*.*g" 10 5 -123.4000000000000000000000000000000000000000000000000000000000000000000000000002 Printf.@sprintf "%010.5g" -123.4000000000000000000000000000000000000000000000000000000000000000000000000002 Printf.@sprintf "%010.5g" -123.4000000000000000000000000000000000000000000000000000000000000000000000000002 Printf.@sprintf("%0*.*g", 10, 5, -123.4000000000000000000000000000000000000000000000000000000000000000000000000002) == Printf.@sprintf("%010.5g", -123.4000000000000000000000000000000000000000000000000000000000000000000000000002) Printf.@sprintf("%0*.*g", 10, 5, -123.4000000000000000000000000000000000000000000000000000000000000000000000000002) == Printf.@sprintf("%010.5g", -123.4000000000000000000000000000000000000000000000000000000000000000000000000002) @test Printf.@sprintf("%0*.*g", 10, 5, -123.4000000000000000000000000000000000000000000000000000000000000000000000000002) == Printf.@sprintf("%010.5g", -123.4000000000000000000000000000000000000000000000000000000000000000000000000002) @test Printf.@sprintf("%0*.*g", 10, 5, -123.4000000000000000000000000000000000000000000000000000000000000000000000000002) == Printf.@sprintf("%010.5g", -123.4000000000000000000000000000000000000000000000000000000000000000000000000002) Printf.@sprintf "%.*g" 6 1.234e7 Printf.@sprintf "%.*g" 6 1.234e7 Printf.@sprintf "%.6g" 1.234e7 Printf.@sprintf "%.6g" 1.234e7 Printf.@sprintf("%.*g", 6, 1.234e7) == Printf.@sprintf("%.6g", 1.234e7) Printf.@sprintf("%.*g", 6, 1.234e7) == Printf.@sprintf("%.6g", 1.234e7) @test Printf.@sprintf("%.*g", 6, 1.234e7) == Printf.@sprintf("%.6g", 1.234e7) @test Printf.@sprintf("%.*g", 6, 1.234e7) == Printf.@sprintf("%.6g", 1.234e7) Printf.@sprintf "%#.*g" 6 1.234e7 Printf.@sprintf "%#.*g" 6 1.234e7 Printf.@sprintf "%#.6g" 1.234e7 Printf.@sprintf "%#.6g" 1.234e7 Printf.@sprintf("%#.*g", 6, 1.234e7) == Printf.@sprintf("%#.6g", 1.234e7) Printf.@sprintf("%#.*g", 6, 1.234e7) == Printf.@sprintf("%#.6g", 1.234e7) @test Printf.@sprintf("%#.*g", 6, 1.234e7) == Printf.@sprintf("%#.6g", 1.234e7) @test Printf.@sprintf("%#.*g", 6, 1.234e7) == Printf.@sprintf("%#.6g", 1.234e7) Printf.@sprintf "%*.*e" 10 4 Inf Printf.@sprintf "%*.*e" 10 4 Inf Printf.@sprintf "%10.4e" Inf Printf.@sprintf "%10.4e" Inf Printf.@sprintf("%*.*e", 10, 4, Inf) == Printf.@sprintf("%10.4e", Inf) Printf.@sprintf("%*.*e", 10, 4, Inf) == Printf.@sprintf("%10.4e", Inf) @test Printf.@sprintf("%*.*e", 10, 4, Inf) == Printf.@sprintf("%10.4e", Inf) @test Printf.@sprintf("%*.*e", 10, 4, Inf) == Printf.@sprintf("%10.4e", Inf) Printf.@sprintf "%.*e" 0 2.999999999999999999999999999999999999999999999999999999999999999999999999999996e142 Printf.@sprintf "%.*e" 0 2.999999999999999999999999999999999999999999999999999999999999999999999999999996e142 Printf.@sprintf "%.0e" 2.999999999999999999999999999999999999999999999999999999999999999999999999999996e142 Printf.@sprintf "%.0e" 2.999999999999999999999999999999999999999999999999999999999999999999999999999996e142 Printf.@sprintf("%.*e", 0, 2.999999999999999999999999999999999999999999999999999999999999999999999999999996e142) == Printf.@sprintf("%.0e", 2.999999999999999999999999999999999999999999999999999999999999999999999999999996e142) Printf.@sprintf("%.*e", 0, 2.999999999999999999999999999999999999999999999999999999999999999999999999999996e142) == Printf.@sprintf("%.0e", 2.999999999999999999999999999999999999999999999999999999999999999999999999999996e142) @test Printf.@sprintf("%.*e", 0, 2.999999999999999999999999999999999999999999999999999999999999999999999999999996e142) == Printf.@sprintf("%.0e", 2.999999999999999999999999999999999999999999999999999999999999999999999999999996e142) @test Printf.@sprintf("%.*e", 0, 2.999999999999999999999999999999999999999999999999999999999999999999999999999996e142) == Printf.@sprintf("%.0e", 2.999999999999999999999999999999999999999999999999999999999999999999999999999996e142) Printf.@sprintf "%#.*e" 0 2.999999999999999999999999999999999999999999999999999999999999999999999999999996e142 Printf.@sprintf "%#.*e" 0 2.999999999999999999999999999999999999999999999999999999999999999999999999999996e142 Printf.@sprintf "%#.0e" 2.999999999999999999999999999999999999999999999999999999999999999999999999999996e142 Printf.@sprintf "%#.0e" 2.999999999999999999999999999999999999999999999999999999999999999999999999999996e142 Printf.@sprintf("%#.*e", 0, 2.999999999999999999999999999999999999999999999999999999999999999999999999999996e142) == Printf.@sprintf("%#.0e", 2.999999999999999999999999999999999999999999999999999999999999999999999999999996e142) Printf.@sprintf("%#.*e", 0, 2.999999999999999999999999999999999999999999999999999999999999999999999999999996e142) == Printf.@sprintf("%#.0e", 2.999999999999999999999999999999999999999999999999999999999999999999999999999996e142) @test Printf.@sprintf("%#.*e", 0, 2.999999999999999999999999999999999999999999999999999999999999999999999999999996e142) == Printf.@sprintf("%#.0e", 2.999999999999999999999999999999999999999999999999999999999999999999999999999996e142) @test Printf.@sprintf("%#.*e", 0, 2.999999999999999999999999999999999999999999999999999999999999999999999999999996e142) == Printf.@sprintf("%#.0e", 2.999999999999999999999999999999999999999999999999999999999999999999999999999996e142) Printf.@sprintf "%.*e" 0 3.000000000000000000000000000000000000000000000000000000000000000000000000000024e1042 Printf.@sprintf "%.*e" 0 3.000000000000000000000000000000000000000000000000000000000000000000000000000024e1042 Printf.@sprintf "%.0e" 3.000000000000000000000000000000000000000000000000000000000000000000000000000024e1042 Printf.@sprintf "%.0e" 3.000000000000000000000000000000000000000000000000000000000000000000000000000024e1042 Printf.@sprintf("%.*e", 0, 3.000000000000000000000000000000000000000000000000000000000000000000000000000024e1042) == Printf.@sprintf("%.0e", 3.000000000000000000000000000000000000000000000000000000000000000000000000000024e1042) Printf.@sprintf("%.*e", 0, 3.000000000000000000000000000000000000000000000000000000000000000000000000000024e1042) == Printf.@sprintf("%.0e", 3.000000000000000000000000000000000000000000000000000000000000000000000000000024e1042) @test Printf.@sprintf("%.*e", 0, 3.000000000000000000000000000000000000000000000000000000000000000000000000000024e1042) == Printf.@sprintf("%.0e", 3.000000000000000000000000000000000000000000000000000000000000000000000000000024e1042) @test Printf.@sprintf("%.*e", 0, 3.000000000000000000000000000000000000000000000000000000000000000000000000000024e1042) == Printf.@sprintf("%.0e", 3.000000000000000000000000000000000000000000000000000000000000000000000000000024e1042) begin @test Printf.@sprintf("%*d", 10, 12) == " 12" @test Printf.@sprintf("%.*d", 4, 12) == "0012" @test Printf.@sprintf("%*.*d", 10, 4, 12) == " 0012" @test Printf.@sprintf("%+*.*d", 10, 4, 12) == " +0012" @test Printf.@sprintf("%0*.*d", 10, 4, 12) == " 0012" @test Printf.@sprintf("%*d%*d%*d", 4, 12, 4, 13, 4, 14) == " 12 13 14" @test Printf.@sprintf("%*d%*d%*d", 4, 12, 5, 13, 6, 14) == " 12 13 14" @test Printf.@sprintf("%*p", 20, 0) == Printf.@sprintf("%20p", 0) @test Printf.@sprintf("%-*p", 20, 0) == Printf.@sprintf("%-20p", 0) @test Printf.@sprintf("%*p", 20, C_NULL) == Printf.@sprintf("%20p", C_NULL) @test Printf.@sprintf("%-*p", 20, C_NULL) == Printf.@sprintf("%-20p", C_NULL) @test Printf.@sprintf("%.*a", 0, 3.14) == Printf.@sprintf("%.0a", 3.14) @test Printf.@sprintf("%.*a", 1, 3.14) == Printf.@sprintf("%.1a", 3.14) @test Printf.@sprintf("%.*a", 2, 3.14) == Printf.@sprintf("%.2a", 3.14) @test Printf.@sprintf("%#.*a", 0, 3.14) == Printf.@sprintf("%#.0a", 3.14) @test Printf.@sprintf("%#.*a", 1, 3.14) == Printf.@sprintf("%#.1a", 3.14) @test Printf.@sprintf("%#.*a", 2, 3.14) == Printf.@sprintf("%#.2a", 3.14) @test Printf.@sprintf("%.*a", 6, 1.5) == Printf.@sprintf("%.6a", 1.5) @test Printf.@sprintf("%*.*g", 10, 5, -123.4) == Printf.@sprintf("%10.5g", -123.4) @test Printf.@sprintf("%0*.*g", 10, 5, -123.4) == Printf.@sprintf("%010.5g", -123.4) @test Printf.@sprintf("%.*g", 6, 1.234e7) == Printf.@sprintf("%.6g", 1.234e7) @test Printf.@sprintf("%#.*g", 6, 1.234e7) == Printf.@sprintf("%#.6g", 1.234e7) @test Printf.@sprintf("%*.*g", 10, 5, -123.4000000000000000000000000000000000000000000000000000000000000000000000000002) == Printf.@sprintf("%10.5g", -123.4000000000000000000000000000000000000000000000000000000000000000000000000002) @test Printf.@sprintf("%0*.*g", 10, 5, -123.4000000000000000000000000000000000000000000000000000000000000000000000000002) == Printf.@sprintf("%010.5g", -123.4000000000000000000000000000000000000000000000000000000000000000000000000002) @test Printf.@sprintf("%.*g", 6, 1.234e7) == Printf.@sprintf("%.6g", 1.234e7) @test Printf.@sprintf("%#.*g", 6, 1.234e7) == Printf.@sprintf("%#.6g", 1.234e7) @test Printf.@sprintf("%.*g", 5, 42) == Printf.@sprintf("%.5g", 42) @test Printf.@sprintf("%#.*g", 2, 42) == Printf.@sprintf("%#.2g", 42) @test Printf.@sprintf("%#.*g", 5, 42) == Printf.@sprintf("%#.5g", 42) @test Printf.@sprintf("%.*g", 15, 0) == Printf.@sprintf("%.15g", 0) @test Printf.@sprintf("%#.*g", 15, 0) == Printf.@sprintf("%#.15g", 0) @test Printf.@sprintf("%.*f", 0, 3.0e142) == Printf.@sprintf("%.0f", 3.0e142) @test Printf.@sprintf("%.*f", 2, 1.234) == Printf.@sprintf("%.2f", 1.234) @test Printf.@sprintf("%.*f", 2, 1.235) == Printf.@sprintf("%.2f", 1.235) @test Printf.@sprintf("%.*f", 2, 0.235) == Printf.@sprintf("%.2f", 0.235) @test Printf.@sprintf("%*.*f", 4, 1, 1.234) == Printf.@sprintf("%4.1f", 1.234) @test Printf.@sprintf("%*.*f", 8, 1, 1.234) == Printf.@sprintf("%8.1f", 1.234) @test Printf.@sprintf("%+*.*f", 8, 1, 1.234) == Printf.@sprintf("%+8.1f", 1.234) @test Printf.@sprintf("% *.*f", 8, 1, 1.234) == Printf.@sprintf("% 8.1f", 1.234) @test Printf.@sprintf("% *.*f", 7, 1, 1.234) == Printf.@sprintf("% 7.1f", 1.234) @test Printf.@sprintf("% 0*.*f", 8, 1, 1.234) == Printf.@sprintf("% 08.1f", 1.234) @test Printf.@sprintf("%0*.*f", 8, 1, 1.234) == Printf.@sprintf("%08.1f", 1.234) @test Printf.@sprintf("%-0*.*f", 8, 1, 1.234) == Printf.@sprintf("%-08.1f", 1.234) @test Printf.@sprintf("%-*.*f", 8, 1, 1.234) == Printf.@sprintf("%-8.1f", 1.234) @test Printf.@sprintf("%0*.*f", 8, 1, -1.234) == Printf.@sprintf("%08.1f", -1.234) @test Printf.@sprintf("%0*.*f", 9, 1, -1.234) == Printf.@sprintf("%09.1f", -1.234) @test Printf.@sprintf("%0*.*f", 9, 1, 1.234) == Printf.@sprintf("%09.1f", 1.234) @test Printf.@sprintf("%+0*.*f", 9, 1, 1.234) == Printf.@sprintf("%+09.1f", 1.234) @test Printf.@sprintf("% 0*.*f", 9, 1, 1.234) == Printf.@sprintf("% 09.1f", 1.234) @test Printf.@sprintf("%+ 0*.*f", 9, 1, 1.234) == Printf.@sprintf("%+ 09.1f", 1.234) @test Printf.@sprintf("%+ 0*.*f", 9, 1, 1.234) == Printf.@sprintf("%+ 09.1f", 1.234) @test Printf.@sprintf("%+ 0*.*f", 9, 0, 1.234) == Printf.@sprintf("%+ 09.0f", 1.234) @test Printf.@sprintf("%+ #0*.*f", 9, 0, 1.234) == Printf.@sprintf("%+ #09.0f", 1.234) @test Printf.@sprintf("%*.*e", 10, 4, Inf) == Printf.@sprintf("%10.4e", Inf) @test Printf.@sprintf("%*.*e", 10, 4, NaN) == Printf.@sprintf("%10.4e", NaN) @test Printf.@sprintf("%*.*e", 10, 4, Inf) == Printf.@sprintf("%10.4e", Inf) @test Printf.@sprintf("%*.*e", 10, 4, NaN) == Printf.@sprintf("%10.4e", NaN) @test Printf.@sprintf("%.*e", 0, 3.0e142) == Printf.@sprintf("%.0e", 3.0e142) @test Printf.@sprintf("%#.*e", 0, 3.0e142) == Printf.@sprintf("%#.0e", 3.0e142) @test Printf.@sprintf("%.*e", 0, 2.999999999999999999999999999999999999999999999999999999999999999999999999999996e142) == Printf.@sprintf("%.0e", 2.999999999999999999999999999999999999999999999999999999999999999999999999999996e142) @test Printf.@sprintf("%#.*e", 0, 2.999999999999999999999999999999999999999999999999999999999999999999999999999996e142) == Printf.@sprintf("%#.0e", 2.999999999999999999999999999999999999999999999999999999999999999999999999999996e142) @test Printf.@sprintf("%.*e", 0, 3.000000000000000000000000000000000000000000000000000000000000000000000000000024e1042) == Printf.@sprintf("%.0e", 3.000000000000000000000000000000000000000000000000000000000000000000000000000024e1042) @test Printf.@sprintf("%.*e", 2, 1.234) == Printf.@sprintf("%.2e", 1.234) @test Printf.@sprintf("%.*e", 2, 1.235) == Printf.@sprintf("%.2e", 1.235) @test Printf.@sprintf("%.*e", 2, 0.235) == Printf.@sprintf("%.2e", 0.235) @test Printf.@sprintf("%*.*e", 4, 1, 1.234) == Printf.@sprintf("%4.1e", 1.234) @test Printf.@sprintf("%*.*e", 8, 1, 1.234) == Printf.@sprintf("%8.1e", 1.234) @test Printf.@sprintf("%+*.*e", 8, 1, 1.234) == Printf.@sprintf("%+8.1e", 1.234) @test Printf.@sprintf("% *.*e", 8, 1, 1.234) == Printf.@sprintf("% 8.1e", 1.234) @test Printf.@sprintf("% *.*e", 7, 1, 1.234) == Printf.@sprintf("% 7.1e", 1.234) @test Printf.@sprintf("% 0*.*e", 8, 1, 1.234) == Printf.@sprintf("% 08.1e", 1.234) @test Printf.@sprintf("%0*.*e", 8, 1, 1.234) == Printf.@sprintf("%08.1e", 1.234) @test Printf.@sprintf("%-0*.*e", 8, 1, 1.234) == Printf.@sprintf("%-08.1e", 1.234) @test Printf.@sprintf("%-*.*e", 8, 1, 1.234) == Printf.@sprintf("%-8.1e", 1.234) @test Printf.@sprintf("%-*.*e", 8, 1, 1.234) == Printf.@sprintf("%-8.1e", 1.234) @test Printf.@sprintf("%0*.*e", 8, 1, -1.234) == Printf.@sprintf("%08.1e", -1.234) @test Printf.@sprintf("%0*.*e", 9, 1, -1.234) == Printf.@sprintf("%09.1e", -1.234) @test Printf.@sprintf("%0*.*e", 9, 1, 1.234) == Printf.@sprintf("%09.1e", 1.234) @test Printf.@sprintf("%+0*.*e", 9, 1, 1.234) == Printf.@sprintf("%+09.1e", 1.234) @test Printf.@sprintf("% 0*.*e", 9, 1, 1.234) == Printf.@sprintf("% 09.1e", 1.234) @test Printf.@sprintf("%+ 0*.*e", 9, 1, 1.234) == Printf.@sprintf("%+ 09.1e", 1.234) @test Printf.@sprintf("%+ 0*.*e", 9, 1, 1.234) == Printf.@sprintf("%+ 09.1e", 1.234) @test Printf.@sprintf("%+ 0*.*e", 9, 0, 1.234) == Printf.@sprintf("%+ 09.0e", 1.234) @test Printf.@sprintf("%+ #0*.*e", 9, 0, 1.234) == Printf.@sprintf("%+ #09.0e", 1.234) @test Printf.@sprintf("%.*s", 1, "foo") == Printf.@sprintf("%.1s", "foo") @test Printf.@sprintf("%*s", 1, "Hallo heimur") == Printf.@sprintf("%1s", "Hallo heimur") @test Printf.@sprintf("%*s", 20, "Hallo") == Printf.@sprintf("%20s", "Hallo") @test Printf.@sprintf("%-*s", 20, "Hallo") == Printf.@sprintf("%-20s", "Hallo") @test Printf.@sprintf("%0-*s", 20, "Hallo") == Printf.@sprintf("%0-20s", "Hallo") @test Printf.@sprintf("%.*s", 20, "Hallo heimur") == Printf.@sprintf("%.20s", "Hallo heimur") @test Printf.@sprintf("%*.*s", 20, 5, "Hallo heimur") == Printf.@sprintf("%20.5s", "Hallo heimur") @test Printf.@sprintf("%.*s", 0, "Hallo heimur") == Printf.@sprintf("%.0s", "Hallo heimur") @test Printf.@sprintf("%*.*s", 20, 0, "Hallo heimur") == Printf.@sprintf("%20.0s", "Hallo heimur") @test Printf.@sprintf("%.s", "Hallo heimur") == Printf.@sprintf("%.s", "Hallo heimur") @test Printf.@sprintf("%*.s", 20, "Hallo heimur") == Printf.@sprintf("%20.s", "Hallo heimur") @test Printf.@sprintf("%*sø", 4, "ø") == Printf.@sprintf("%4sø", "ø") @test Printf.@sprintf("%-*sø", 4, "ø") == Printf.@sprintf("%-4sø", "ø") @test Printf.@sprintf("%*s", 8, "test") == Printf.@sprintf("%8s", "test") @test Printf.@sprintf("%-*s", 8, "test") == Printf.@sprintf("%-8s", "test") @test Printf.@sprintf("%#*s", 8, :test) == Printf.@sprintf("%#8s", :test) @test Printf.@sprintf("%#-*s", 8, :test) == Printf.@sprintf("%#-8s", :test) @test Printf.@sprintf("%*.*s", 8, 3, "test") == Printf.@sprintf("%8.3s", "test") @test Printf.@sprintf("%#*.*s", 8, 3, "test") == Printf.@sprintf("%#8.3s", "test") @test Printf.@sprintf("%-*.*s", 8, 3, "test") == Printf.@sprintf("%-8.3s", "test") @test Printf.@sprintf("%#-*.*s", 8, 3, "test") == Printf.@sprintf("%#-8.3s", "test") @test Printf.@sprintf("%.*s", 3, "test") == Printf.@sprintf("%.3s", "test") @test Printf.@sprintf("%#.*s", 3, "test") == Printf.@sprintf("%#.3s", "test") @test Printf.@sprintf("%-.*s", 3, "test") == Printf.@sprintf("%-.3s", "test") @test Printf.@sprintf("%#-.*s", 3, "test") == Printf.@sprintf("%#-.3s", "test") @test Printf.@sprintf("%*c", 3, 'a') == Printf.@sprintf("%3c", 'a') @test Printf.@sprintf("%*c", 1, 'x') == Printf.@sprintf("%1c", 'x') @test Printf.@sprintf("%*c", 20, 'x') == Printf.@sprintf("%20c", 'x') @test Printf.@sprintf("%-*c", 20, 'x') == Printf.@sprintf("%-20c", 'x') @test Printf.@sprintf("%-0*c", 20, 'x') == Printf.@sprintf("%-020c", 'x') @test Printf.@sprintf("%*c", 3, 'A') == Printf.@sprintf("%3c", 'A') @test Printf.@sprintf("%-*c", 3, 'A') == Printf.@sprintf("%-3c", 'A') @test Printf.@sprintf("%*.*f %*.*f %*.*f %*.*f %*.*f %*.*f %*.*f %*.*f %*.*f %*.*f %*.*f %*.*f %*.*f %*.*f %*.*f %*.*f %*.*f %*.*f", 4, 2, 1.2345, 4, 2, 1.2345, 4, 2, 1.2345, 4, 2, 1.2345, 4, 2, 1.2345, 4, 2, 1.2345, 4, 2, 1.2345, 4, 2, 1.2345, 4, 2, 1.2345, 4, 2, 1.2345, 4, 2, 1.2345, 4, 2, 1.2345, 4, 2, 1.2345, 4, 2, 1.2345, 4, 2, 1.2345, 4, 2, 1.2345, 4, 2, 1.2345, 4, 2, 1.2345) == Printf.@sprintf("%4.2f %4.2f %4.2f %4.2f %4.2f %4.2f %4.2f %4.2f %4.2f %4.2f %4.2f %4.2f %4.2f %4.2f %4.2f %4.2f %4.2f %4.2f", 1.2345, 1.2345, 1.2345, 1.2345, 1.2345, 1.2345, 1.2345, 1.2345, 1.2345, 1.2345, 1.2345, 1.2345, 1.2345, 1.2345, 1.2345, 1.2345, 1.2345, 1.2345) @test (Printf.@sprintf("%.*f", 330, BigFloat(1)))[var"end"] != '\0' @test Printf.@sprintf("%*.*s", 4, 2, "a") == Printf.@sprintf("%4.2s", "a") @test Printf.@sprintf("%*.*e", 12, 3, pi * 1.0e100) == Printf.@sprintf("%12.3e", pi * 1.0e100) @test Printf.@sprintf("%*d", 2, 3.14) == Printf.@sprintf("%*d", 2, 3.14) @test Printf.@sprintf("%*d", 2, big(3.14)) == Printf.@sprintf("%*d", 2, big(3.14)) @test Printf.@sprintf(" %.*e\n", 1, 0.999) == Printf.@sprintf(" %.1e\n", 0.999) @test Printf.@sprintf(" %.*f", 1, 9.999) == Printf.@sprintf(" %.1f", 9.999) @test Printf.@sprintf("%*d", 10, 12) == Printf.@sprintf("%10d", 12) @test Printf.@sprintf("%.*d", 4, 12) == Printf.@sprintf("%.4d", 12) @test Printf.@sprintf("%*.*d", 10, 4, 12) == Printf.@sprintf("%10.4d", 12) @test Printf.@sprintf("%+*.*d", 10, 4, 12) == Printf.@sprintf("%+10.4d", 12) @test Printf.@sprintf("%0*.*d", 10, 4, 12) == Printf.@sprintf("%010.4d", 12) @test Printf.@sprintf("% *d", 5, 42) == Printf.@sprintf("% 5d", 42) @test Printf.@sprintf("% *d", 5, -42) == Printf.@sprintf("% 5d", -42) @test Printf.@sprintf("% *d", 15, 42) == Printf.@sprintf("% 15d", 42) @test Printf.@sprintf("% *d", 15, -42) == Printf.@sprintf("% 15d", -42) @test Printf.@sprintf("%+*d", 5, 42) == Printf.@sprintf("%+5d", 42) @test Printf.@sprintf("%+*d", 5, -42) == Printf.@sprintf("%+5d", -42) @test Printf.@sprintf("%+*d", 15, 42) == Printf.@sprintf("%+15d", 42) @test Printf.@sprintf("%+*d", 15, -42) == Printf.@sprintf("%+15d", -42) @test Printf.@sprintf("%*d", 0, 42) == Printf.@sprintf("%0d", 42) @test Printf.@sprintf("%*d", 0, -42) == Printf.@sprintf("%0d", -42) @test Printf.@sprintf("%-*d", 5, 42) == Printf.@sprintf("%-5d", 42) @test Printf.@sprintf("%-*d", 5, -42) == Printf.@sprintf("%-5d", -42) @test Printf.@sprintf("%-*d", 15, 42) == Printf.@sprintf("%-15d", 42) @test Printf.@sprintf("%-*d", 15, -42) == Printf.@sprintf("%-15d", -42) @test Printf.@sprintf("%+*lld", 8, 100) == Printf.@sprintf("%+8lld", 100) @test Printf.@sprintf("%+.*lld", 8, 100) == Printf.@sprintf("%+.8lld", 100) @test Printf.@sprintf("%+*.*lld", 10, 8, 100) == Printf.@sprintf("%+10.8lld", 100) @test Printf.@sprintf("%-*.*lld", 1, 5, -100) == Printf.@sprintf("%-1.5lld", -100) @test Printf.@sprintf("%*lld", 5, 100) == Printf.@sprintf("%5lld", 100) @test Printf.@sprintf("%*lld", 5, -100) == Printf.@sprintf("%5lld", -100) @test Printf.@sprintf("%-*lld", 5, 100) == Printf.@sprintf("%-5lld", 100) @test Printf.@sprintf("%-*lld", 5, -100) == Printf.@sprintf("%-5lld", -100) @test Printf.@sprintf("%-.*lld", 5, 100) == Printf.@sprintf("%-.5lld", 100) @test Printf.@sprintf("%-.*lld", 5, -100) == Printf.@sprintf("%-.5lld", -100) @test Printf.@sprintf("%-*.*lld", 8, 5, 100) == Printf.@sprintf("%-8.5lld", 100) @test Printf.@sprintf("%-*.*lld", 8, 5, -100) == Printf.@sprintf("%-8.5lld", -100) @test Printf.@sprintf("%0*lld", 5, 100) == Printf.@sprintf("%05lld", 100) @test Printf.@sprintf("%0*lld", 5, -100) == Printf.@sprintf("%05lld", -100) @test Printf.@sprintf("% *lld", 5, 100) == Printf.@sprintf("% 5lld", 100) @test Printf.@sprintf("% *lld", 5, -100) == Printf.@sprintf("% 5lld", -100) @test Printf.@sprintf("% .*lld", 5, 100) == Printf.@sprintf("% .5lld", 100) @test Printf.@sprintf("% .*lld", 5, -100) == Printf.@sprintf("% .5lld", -100) @test Printf.@sprintf("% *.*lld", 8, 5, 100) == Printf.@sprintf("% 8.5lld", 100) @test Printf.@sprintf("% *.*lld", 8, 5, -100) == Printf.@sprintf("% 8.5lld", -100) @test Printf.@sprintf("%.*lld", 0, 0) == Printf.@sprintf("%.0lld", 0) @test Printf.@sprintf("%#+*.*llx", 21, 18, -100) == Printf.@sprintf("%#+21.18llx", -100) @test Printf.@sprintf("%#.*llo", 25, -100) == Printf.@sprintf("%#.25llo", -100) @test Printf.@sprintf("%#+*.*llo", 24, 20, -100) == Printf.@sprintf("%#+24.20llo", -100) @test Printf.@sprintf("%#+*.*llX", 18, 21, -100) == Printf.@sprintf("%#+18.21llX", -100) @test Printf.@sprintf("%#+*.*llo", 20, 24, -100) == Printf.@sprintf("%#+20.24llo", -100) @test Printf.@sprintf("%#+*.*llu", 25, 22, -1) == Printf.@sprintf("%#+25.22llu", -1) @test Printf.@sprintf("%#+*.*llu", 30, 25, -1) == Printf.@sprintf("%#+30.25llu", -1) @test Printf.@sprintf("%+#*.*lld", 25, 22, -1) == Printf.@sprintf("%+#25.22lld", -1) @test Printf.@sprintf("%#-*.*llo", 8, 5, 100) == Printf.@sprintf("%#-8.5llo", 100) @test Printf.@sprintf("%#-+ 0*.*lld", 8, 5, 100) == Printf.@sprintf("%#-+ 08.5lld", 100) @test Printf.@sprintf("%#-+ 0*.*lld", 8, 5, 100) == Printf.@sprintf("%#-+ 08.5lld", 100) @test Printf.@sprintf("%.*lld", 40, 1) == Printf.@sprintf("%.40lld", 1) @test Printf.@sprintf("% .*lld", 40, 1) == Printf.@sprintf("% .40lld", 1) @test Printf.@sprintf("% .*d", 40, 1) == Printf.@sprintf("% .40d", 1) @test Printf.@sprintf("%#0*x", 12, 1) == Printf.@sprintf("%#012x", 1) @test Printf.@sprintf("%#0*.*x", 4, 8, 1) == Printf.@sprintf("%#04.8x", 1) @test Printf.@sprintf("%#-0*.*x", 8, 2, 1) == Printf.@sprintf("%#-08.2x", 1) @test Printf.@sprintf("%#0*o", 8, 1) == Printf.@sprintf("%#08o", 1) @test Printf.@sprintf("%*d", 20, 1024) == Printf.@sprintf("%20d", 1024) @test Printf.@sprintf("%*d", 20, -1024) == Printf.@sprintf("%20d", -1024) @test Printf.@sprintf("%*i", 20, 1024) == Printf.@sprintf("%20i", 1024) @test Printf.@sprintf("%*i", 20, -1024) == Printf.@sprintf("%20i", -1024) @test Printf.@sprintf("%*u", 20, 1024) == Printf.@sprintf("%20u", 1024) @test Printf.@sprintf("%*u", 20, UInt(4294966272)) == Printf.@sprintf("%20u", UInt(4294966272)) @test Printf.@sprintf("%*o", 20, 511) == Printf.@sprintf("%20o", 511) @test Printf.@sprintf("%*o", 20, UInt(4294966785)) == Printf.@sprintf("%20o", UInt(4294966785)) @test Printf.@sprintf("%*x", 20, 305441741) == Printf.@sprintf("%20x", 305441741) @test Printf.@sprintf("%*x", 20, UInt(3989525555)) == Printf.@sprintf("%20x", UInt(3989525555)) @test Printf.@sprintf("%*X", 20, 305441741) == Printf.@sprintf("%20X", 305441741) @test Printf.@sprintf("%*X", 20, UInt(3989525555)) == Printf.@sprintf("%20X", UInt(3989525555)) @test Printf.@sprintf("%-*d", 20, 1024) == Printf.@sprintf("%-20d", 1024) @test Printf.@sprintf("%-*d", 20, -1024) == Printf.@sprintf("%-20d", -1024) @test Printf.@sprintf("%-*i", 20, 1024) == Printf.@sprintf("%-20i", 1024) @test Printf.@sprintf("%-*i", 20, -1024) == Printf.@sprintf("%-20i", -1024) @test Printf.@sprintf("%-*u", 20, 1024) == Printf.@sprintf("%-20u", 1024) @test Printf.@sprintf("%-*u", 20, UInt(4294966272)) == Printf.@sprintf("%-20u", UInt(4294966272)) @test Printf.@sprintf("%-*o", 20, 511) == Printf.@sprintf("%-20o", 511) @test Printf.@sprintf("%-*o", 20, UInt(4294966785)) == Printf.@sprintf("%-20o", UInt(4294966785)) @test Printf.@sprintf("%-*x", 20, 305441741) == Printf.@sprintf("%-20x", 305441741) @test Printf.@sprintf("%-*x", 20, UInt(3989525555)) == Printf.@sprintf("%-20x", UInt(3989525555)) @test Printf.@sprintf("%-*X", 20, 305441741) == Printf.@sprintf("%-20X", 305441741) @test Printf.@sprintf("%-*X", 20, UInt(3989525555)) == Printf.@sprintf("%-20X", UInt(3989525555)) @test Printf.@sprintf("%0*d", 20, 1024) == Printf.@sprintf("%020d", 1024) @test Printf.@sprintf("%0*d", 20, -1024) == Printf.@sprintf("%020d", -1024) @test Printf.@sprintf("%0*i", 20, 1024) == Printf.@sprintf("%020i", 1024) @test Printf.@sprintf("%0*i", 20, -1024) == Printf.@sprintf("%020i", -1024) @test Printf.@sprintf("%0*u", 20, 1024) == Printf.@sprintf("%020u", 1024) @test Printf.@sprintf("%0*u", 20, UInt(4294966272)) == Printf.@sprintf("%020u", UInt(4294966272)) @test Printf.@sprintf("%0*o", 20, 511) == Printf.@sprintf("%020o", 511) @test Printf.@sprintf("%0*o", 20, UInt(4294966785)) == Printf.@sprintf("%020o", UInt(4294966785)) @test Printf.@sprintf("%0*x", 20, 305441741) == Printf.@sprintf("%020x", 305441741) @test Printf.@sprintf("%0*x", 20, UInt(3989525555)) == Printf.@sprintf("%020x", UInt(3989525555)) @test Printf.@sprintf("%0*X", 20, 305441741) == Printf.@sprintf("%020X", 305441741) @test Printf.@sprintf("%0*X", 20, UInt(3989525555)) == Printf.@sprintf("%020X", UInt(3989525555)) @test Printf.@sprintf("%#*o", 20, 511) == Printf.@sprintf("%#20o", 511) @test Printf.@sprintf("%#*o", 20, UInt(4294966785)) == Printf.@sprintf("%#20o", UInt(4294966785)) @test Printf.@sprintf("%#*x", 20, 305441741) == Printf.@sprintf("%#20x", 305441741) @test Printf.@sprintf("%#*x", 20, UInt(3989525555)) == Printf.@sprintf("%#20x", UInt(3989525555)) @test Printf.@sprintf("%#*X", 20, 305441741) == Printf.@sprintf("%#20X", 305441741) @test Printf.@sprintf("%#*X", 20, UInt(3989525555)) == Printf.@sprintf("%#20X", UInt(3989525555)) @test Printf.@sprintf("%#0*o", 20, 511) == Printf.@sprintf("%#020o", 511) @test Printf.@sprintf("%#0*o", 20, UInt(4294966785)) == Printf.@sprintf("%#020o", UInt(4294966785)) @test Printf.@sprintf("%#0*x", 20, 305441741) == Printf.@sprintf("%#020x", 305441741) @test Printf.@sprintf("%#0*x", 20, UInt(3989525555)) == Printf.@sprintf("%#020x", UInt(3989525555)) @test Printf.@sprintf("%#0*X", 20, 305441741) == Printf.@sprintf("%#020X", 305441741) @test Printf.@sprintf("%#0*X", 20, UInt(3989525555)) == Printf.@sprintf("%#020X", UInt(3989525555)) @test Printf.@sprintf("%0-*d", 20, 1024) == Printf.@sprintf("%0-20d", 1024) @test Printf.@sprintf("%0-*d", 20, -1024) == Printf.@sprintf("%0-20d", -1024) @test Printf.@sprintf("%0-*i", 20, 1024) == Printf.@sprintf("%0-20i", 1024) @test Printf.@sprintf("%0-*i", 20, -1024) == Printf.@sprintf("%0-20i", -1024) @test Printf.@sprintf("%0-*u", 20, 1024) == Printf.@sprintf("%0-20u", 1024) @test Printf.@sprintf("%0-*u", 20, UInt(4294966272)) == Printf.@sprintf("%0-20u", UInt(4294966272)) @test Printf.@sprintf("%-0*o", 20, 511) == Printf.@sprintf("%-020o", 511) @test Printf.@sprintf("%-0*o", 20, UInt(4294966785)) == Printf.@sprintf("%-020o", UInt(4294966785)) @test Printf.@sprintf("%-0*x", 20, 305441741) == Printf.@sprintf("%-020x", 305441741) @test Printf.@sprintf("%-0*x", 20, UInt(3989525555)) == Printf.@sprintf("%-020x", UInt(3989525555)) @test Printf.@sprintf("%-0*X", 20, 305441741) == Printf.@sprintf("%-020X", 305441741) @test Printf.@sprintf("%-0*X", 20, UInt(3989525555)) == Printf.@sprintf("%-020X", UInt(3989525555)) @test Printf.@sprintf("%.*d", 20, 1024) == Printf.@sprintf("%.20d", 1024) @test Printf.@sprintf("%.*d", 20, -1024) == Printf.@sprintf("%.20d", -1024) @test Printf.@sprintf("%.*i", 20, 1024) == Printf.@sprintf("%.20i", 1024) @test Printf.@sprintf("%.*i", 20, -1024) == Printf.@sprintf("%.20i", -1024) @test Printf.@sprintf("%.*u", 20, 1024) == Printf.@sprintf("%.20u", 1024) @test Printf.@sprintf("%.*u", 20, UInt(4294966272)) == Printf.@sprintf("%.20u", UInt(4294966272)) @test Printf.@sprintf("%.*o", 20, 511) == Printf.@sprintf("%.20o", 511) @test Printf.@sprintf("%.*o", 20, UInt(4294966785)) == Printf.@sprintf("%.20o", UInt(4294966785)) @test Printf.@sprintf("%.*x", 20, 305441741) == Printf.@sprintf("%.20x", 305441741) @test Printf.@sprintf("%.*x", 20, UInt(3989525555)) == Printf.@sprintf("%.20x", UInt(3989525555)) @test Printf.@sprintf("%.*X", 20, 305441741) == Printf.@sprintf("%.20X", 305441741) @test Printf.@sprintf("%.*X", 20, UInt(3989525555)) == Printf.@sprintf("%.20X", UInt(3989525555)) @test Printf.@sprintf("%*.*d", 20, 5, 1024) == Printf.@sprintf("%20.5d", 1024) @test Printf.@sprintf("%*.*d", 20, 5, -1024) == Printf.@sprintf("%20.5d", -1024) @test Printf.@sprintf("%*.*i", 20, 5, 1024) == Printf.@sprintf("%20.5i", 1024) @test Printf.@sprintf("%*.*i", 20, 5, -1024) == Printf.@sprintf("%20.5i", -1024) @test Printf.@sprintf("%*.*u", 20, 5, 1024) == Printf.@sprintf("%20.5u", 1024) @test Printf.@sprintf("%*.*u", 20, 5, UInt(4294966272)) == Printf.@sprintf("%20.5u", UInt(4294966272)) @test Printf.@sprintf("%*.*o", 20, 5, 511) == Printf.@sprintf("%20.5o", 511) @test Printf.@sprintf("%*.*o", 20, 5, UInt(4294966785)) == Printf.@sprintf("%20.5o", UInt(4294966785)) @test Printf.@sprintf("%*.*x", 20, 5, 305441741) == Printf.@sprintf("%20.5x", 305441741) @test Printf.@sprintf("%*.*x", 20, 10, UInt(3989525555)) == Printf.@sprintf("%20.10x", UInt(3989525555)) @test Printf.@sprintf("%*.*X", 20, 5, 305441741) == Printf.@sprintf("%20.5X", 305441741) @test Printf.@sprintf("%*.*X", 20, 10, UInt(3989525555)) == Printf.@sprintf("%20.10X", UInt(3989525555)) @test Printf.@sprintf("%0*.*d", 20, 5, 1024) == Printf.@sprintf("%020.5d", 1024) @test Printf.@sprintf("%0*.*d", 20, 5, -1024) == Printf.@sprintf("%020.5d", -1024) @test Printf.@sprintf("%0*.*i", 20, 5, 1024) == Printf.@sprintf("%020.5i", 1024) @test Printf.@sprintf("%0*.*i", 20, 5, -1024) == Printf.@sprintf("%020.5i", -1024) @test Printf.@sprintf("%0*.*u", 20, 5, 1024) == Printf.@sprintf("%020.5u", 1024) @test Printf.@sprintf("%0*.*u", 20, 5, UInt(4294966272)) == Printf.@sprintf("%020.5u", UInt(4294966272)) @test Printf.@sprintf("%0*.*o", 20, 5, 511) == Printf.@sprintf("%020.5o", 511) @test Printf.@sprintf("%0*.*o", 20, 5, UInt(4294966785)) == Printf.@sprintf("%020.5o", UInt(4294966785)) @test Printf.@sprintf("%0*.*x", 20, 5, 305441741) == Printf.@sprintf("%020.5x", 305441741) @test Printf.@sprintf("%0*.*x", 20, 10, UInt(3989525555)) == Printf.@sprintf("%020.10x", UInt(3989525555)) @test Printf.@sprintf("%0*.*X", 20, 5, 305441741) == Printf.@sprintf("%020.5X", 305441741) @test Printf.@sprintf("%0*.*X", 20, 10, UInt(3989525555)) == Printf.@sprintf("%020.10X", UInt(3989525555)) @test Printf.@sprintf("%*.0d", 20, 1024) == Printf.@sprintf("%20.0d", 1024) @test Printf.@sprintf("%*.d", 20, -1024) == Printf.@sprintf("%20.d", -1024) @test Printf.@sprintf("%*.d", 20, 0) == Printf.@sprintf("%20.d", 0) @test Printf.@sprintf("%*.0i", 20, 1024) == Printf.@sprintf("%20.0i", 1024) @test Printf.@sprintf("%*.i", 20, -1024) == Printf.@sprintf("%20.i", -1024) @test Printf.@sprintf("%*.i", 20, 0) == Printf.@sprintf("%20.i", 0) @test Printf.@sprintf("%*.u", 20, 1024) == Printf.@sprintf("%20.u", 1024) @test Printf.@sprintf("%*.0u", 20, UInt(4294966272)) == Printf.@sprintf("%20.0u", UInt(4294966272)) @test Printf.@sprintf("%*.u", 20, UInt(0)) == Printf.@sprintf("%20.u", UInt(0)) @test Printf.@sprintf("%*.o", 20, 511) == Printf.@sprintf("%20.o", 511) @test Printf.@sprintf("%*.0o", 20, UInt(4294966785)) == Printf.@sprintf("%20.0o", UInt(4294966785)) @test Printf.@sprintf("%*.o", 20, UInt(0)) == Printf.@sprintf("%20.o", UInt(0)) @test Printf.@sprintf("%*.x", 20, 305441741) == Printf.@sprintf("%20.x", 305441741) @test Printf.@sprintf("%*.0x", 20, UInt(3989525555)) == Printf.@sprintf("%20.0x", UInt(3989525555)) @test Printf.@sprintf("%*.x", 20, UInt(0)) == Printf.@sprintf("%20.x", UInt(0)) @test Printf.@sprintf("%*.X", 20, 305441741) == Printf.@sprintf("%20.X", 305441741) @test Printf.@sprintf("%*.0X", 20, UInt(3989525555)) == Printf.@sprintf("%20.0X", UInt(3989525555)) @test Printf.@sprintf("%*.X", 20, UInt(0)) == Printf.@sprintf("%20.X", UInt(0)) x = Ref{Int}() y = Ref{Int}() @test begin Printf.@sprintf "%10s%n" "😉" x Printf.@sprintf "%*s%n" 10 "😉" y x[] == y[] end @test begin Printf.@sprintf "%10s%n" "1234" x Printf.@sprintf "%*s%n" 10 "1234" y x[] == y[] end end begin @test Printf.@sprintf("%*d", 10, 12) == " 12" @test Printf.@sprintf("%.*d", 4, 12) == "0012" @test Printf.@sprintf("%*.*d", 10, 4, 12) == " 0012" @test Printf.@sprintf("%+*.*d", 10, 4, 12) == " +0012" @test Printf.@sprintf("%0*.*d", 10, 4, 12) == " 0012" @test Printf.@sprintf("%*d%*d%*d", 4, 12, 4, 13, 4, 14) == " 12 13 14" @test Printf.@sprintf("%*d%*d%*d", 4, 12, 5, 13, 6, 14) == " 12 13 14" @test Printf.@sprintf("%*p", 20, 0) == Printf.@sprintf("%20p", 0) @test Printf.@sprintf("%-*p", 20, 0) == Printf.@sprintf("%-20p", 0) @test Printf.@sprintf("%*p", 20, C_NULL) == Printf.@sprintf("%20p", C_NULL) @test Printf.@sprintf("%-*p", 20, C_NULL) == Printf.@sprintf("%-20p", C_NULL) @test Printf.@sprintf("%.*a", 0, 3.14) == Printf.@sprintf("%.0a", 3.14) @test Printf.@sprintf("%.*a", 1, 3.14) == Printf.@sprintf("%.1a", 3.14) @test Printf.@sprintf("%.*a", 2, 3.14) == Printf.@sprintf("%.2a", 3.14) @test Printf.@sprintf("%#.*a", 0, 3.14) == Printf.@sprintf("%#.0a", 3.14) @test Printf.@sprintf("%#.*a", 1, 3.14) == Printf.@sprintf("%#.1a", 3.14) @test Printf.@sprintf("%#.*a", 2, 3.14) == Printf.@sprintf("%#.2a", 3.14) @test Printf.@sprintf("%.*a", 6, 1.5) == Printf.@sprintf("%.6a", 1.5) @test Printf.@sprintf("%*.*g", 10, 5, -123.4) == Printf.@sprintf("%10.5g", -123.4) @test Printf.@sprintf("%0*.*g", 10, 5, -123.4) == Printf.@sprintf("%010.5g", -123.4) @test Printf.@sprintf("%.*g", 6, 1.234e7) == Printf.@sprintf("%.6g", 1.234e7) @test Printf.@sprintf("%#.*g", 6, 1.234e7) == Printf.@sprintf("%#.6g", 1.234e7) @test Printf.@sprintf("%*.*g", 10, 5, -123.4000000000000000000000000000000000000000000000000000000000000000000000000002) == Printf.@sprintf("%10.5g", -123.4000000000000000000000000000000000000000000000000000000000000000000000000002) @test Printf.@sprintf("%0*.*g", 10, 5, -123.4000000000000000000000000000000000000000000000000000000000000000000000000002) == Printf.@sprintf("%010.5g", -123.4000000000000000000000000000000000000000000000000000000000000000000000000002) @test Printf.@sprintf("%.*g", 6, 1.234e7) == Printf.@sprintf("%.6g", 1.234e7) @test Printf.@sprintf("%#.*g", 6, 1.234e7) == Printf.@sprintf("%#.6g", 1.234e7) @test Printf.@sprintf("%.*g", 5, 42) == Printf.@sprintf("%.5g", 42) @test Printf.@sprintf("%#.*g", 2, 42) == Printf.@sprintf("%#.2g", 42) @test Printf.@sprintf("%#.*g", 5, 42) == Printf.@sprintf("%#.5g", 42) @test Printf.@sprintf("%.*g", 15, 0) == Printf.@sprintf("%.15g", 0) @test Printf.@sprintf("%#.*g", 15, 0) == Printf.@sprintf("%#.15g", 0) @test Printf.@sprintf("%.*f", 0, 3.0e142) == Printf.@sprintf("%.0f", 3.0e142) @test Printf.@sprintf("%.*f", 2, 1.234) == Printf.@sprintf("%.2f", 1.234) @test Printf.@sprintf("%.*f", 2, 1.235) == Printf.@sprintf("%.2f", 1.235) @test Printf.@sprintf("%.*f", 2, 0.235) == Printf.@sprintf("%.2f", 0.235) @test Printf.@sprintf("%*.*f", 4, 1, 1.234) == Printf.@sprintf("%4.1f", 1.234) @test Printf.@sprintf("%*.*f", 8, 1, 1.234) == Printf.@sprintf("%8.1f", 1.234) @test Printf.@sprintf("%+*.*f", 8, 1, 1.234) == Printf.@sprintf("%+8.1f", 1.234) @test Printf.@sprintf("% *.*f", 8, 1, 1.234) == Printf.@sprintf("% 8.1f", 1.234) @test Printf.@sprintf("% *.*f", 7, 1, 1.234) == Printf.@sprintf("% 7.1f", 1.234) @test Printf.@sprintf("% 0*.*f", 8, 1, 1.234) == Printf.@sprintf("% 08.1f", 1.234) @test Printf.@sprintf("%0*.*f", 8, 1, 1.234) == Printf.@sprintf("%08.1f", 1.234) @test Printf.@sprintf("%-0*.*f", 8, 1, 1.234) == Printf.@sprintf("%-08.1f", 1.234) @test Printf.@sprintf("%-*.*f", 8, 1, 1.234) == Printf.@sprintf("%-8.1f", 1.234) @test Printf.@sprintf("%0*.*f", 8, 1, -1.234) == Printf.@sprintf("%08.1f", -1.234) @test Printf.@sprintf("%0*.*f", 9, 1, -1.234) == Printf.@sprintf("%09.1f", -1.234) @test Printf.@sprintf("%0*.*f", 9, 1, 1.234) == Printf.@sprintf("%09.1f", 1.234) @test Printf.@sprintf("%+0*.*f", 9, 1, 1.234) == Printf.@sprintf("%+09.1f", 1.234) @test Printf.@sprintf("% 0*.*f", 9, 1, 1.234) == Printf.@sprintf("% 09.1f", 1.234) @test Printf.@sprintf("%+ 0*.*f", 9, 1, 1.234) == Printf.@sprintf("%+ 09.1f", 1.234) @test Printf.@sprintf("%+ 0*.*f", 9, 1, 1.234) == Printf.@sprintf("%+ 09.1f", 1.234) @test Printf.@sprintf("%+ 0*.*f", 9, 0, 1.234) == Printf.@sprintf("%+ 09.0f", 1.234) @test Printf.@sprintf("%+ #0*.*f", 9, 0, 1.234) == Printf.@sprintf("%+ #09.0f", 1.234) @test Printf.@sprintf("%*.*e", 10, 4, Inf) == Printf.@sprintf("%10.4e", Inf) @test Printf.@sprintf("%*.*e", 10, 4, NaN) == Printf.@sprintf("%10.4e", NaN) @test Printf.@sprintf("%*.*e", 10, 4, Inf) == Printf.@sprintf("%10.4e", Inf) @test Printf.@sprintf("%*.*e", 10, 4, NaN) == Printf.@sprintf("%10.4e", NaN) @test Printf.@sprintf("%.*e", 0, 3.0e142) == Printf.@sprintf("%.0e", 3.0e142) @test Printf.@sprintf("%#.*e", 0, 3.0e142) == Printf.@sprintf("%#.0e", 3.0e142) @test Printf.@sprintf("%.*e", 0, 2.999999999999999999999999999999999999999999999999999999999999999999999999999996e142) == Printf.@sprintf("%.0e", 2.999999999999999999999999999999999999999999999999999999999999999999999999999996e142) @test Printf.@sprintf("%#.*e", 0, 2.999999999999999999999999999999999999999999999999999999999999999999999999999996e142) == Printf.@sprintf("%#.0e", 2.999999999999999999999999999999999999999999999999999999999999999999999999999996e142) @test Printf.@sprintf("%.*e", 0, 3.000000000000000000000000000000000000000000000000000000000000000000000000000024e1042) == Printf.@sprintf("%.0e", 3.000000000000000000000000000000000000000000000000000000000000000000000000000024e1042) @test Printf.@sprintf("%.*e", 2, 1.234) == Printf.@sprintf("%.2e", 1.234) @test Printf.@sprintf("%.*e", 2, 1.235) == Printf.@sprintf("%.2e", 1.235) @test Printf.@sprintf("%.*e", 2, 0.235) == Printf.@sprintf("%.2e", 0.235) @test Printf.@sprintf("%*.*e", 4, 1, 1.234) == Printf.@sprintf("%4.1e", 1.234) @test Printf.@sprintf("%*.*e", 8, 1, 1.234) == Printf.@sprintf("%8.1e", 1.234) @test Printf.@sprintf("%+*.*e", 8, 1, 1.234) == Printf.@sprintf("%+8.1e", 1.234) @test Printf.@sprintf("% *.*e", 8, 1, 1.234) == Printf.@sprintf("% 8.1e", 1.234) @test Printf.@sprintf("% *.*e", 7, 1, 1.234) == Printf.@sprintf("% 7.1e", 1.234) @test Printf.@sprintf("% 0*.*e", 8, 1, 1.234) == Printf.@sprintf("% 08.1e", 1.234) @test Printf.@sprintf("%0*.*e", 8, 1, 1.234) == Printf.@sprintf("%08.1e", 1.234) @test Printf.@sprintf("%-0*.*e", 8, 1, 1.234) == Printf.@sprintf("%-08.1e", 1.234) @test Printf.@sprintf("%-*.*e", 8, 1, 1.234) == Printf.@sprintf("%-8.1e", 1.234) @test Printf.@sprintf("%-*.*e", 8, 1, 1.234) == Printf.@sprintf("%-8.1e", 1.234) @test Printf.@sprintf("%0*.*e", 8, 1, -1.234) == Printf.@sprintf("%08.1e", -1.234) @test Printf.@sprintf("%0*.*e", 9, 1, -1.234) == Printf.@sprintf("%09.1e", -1.234) @test Printf.@sprintf("%0*.*e", 9, 1, 1.234) == Printf.@sprintf("%09.1e", 1.234) @test Printf.@sprintf("%+0*.*e", 9, 1, 1.234) == Printf.@sprintf("%+09.1e", 1.234) @test Printf.@sprintf("% 0*.*e", 9, 1, 1.234) == Printf.@sprintf("% 09.1e", 1.234) @test Printf.@sprintf("%+ 0*.*e", 9, 1, 1.234) == Printf.@sprintf("%+ 09.1e", 1.234) @test Printf.@sprintf("%+ 0*.*e", 9, 1, 1.234) == Printf.@sprintf("%+ 09.1e", 1.234) @test Printf.@sprintf("%+ 0*.*e", 9, 0, 1.234) == Printf.@sprintf("%+ 09.0e", 1.234) @test Printf.@sprintf("%+ #0*.*e", 9, 0, 1.234) == Printf.@sprintf("%+ #09.0e", 1.234) @test Printf.@sprintf("%.*s", 1, "foo") == Printf.@sprintf("%.1s", "foo") @test Printf.@sprintf("%*s", 1, "Hallo heimur") == Printf.@sprintf("%1s", "Hallo heimur") @test Printf.@sprintf("%*s", 20, "Hallo") == Printf.@sprintf("%20s", "Hallo") @test Printf.@sprintf("%-*s", 20, "Hallo") == Printf.@sprintf("%-20s", "Hallo") @test Printf.@sprintf("%0-*s", 20, "Hallo") == Printf.@sprintf("%0-20s", "Hallo") @test Printf.@sprintf("%.*s", 20, "Hallo heimur") == Printf.@sprintf("%.20s", "Hallo heimur") @test Printf.@sprintf("%*.*s", 20, 5, "Hallo heimur") == Printf.@sprintf("%20.5s", "Hallo heimur") @test Printf.@sprintf("%.*s", 0, "Hallo heimur") == Printf.@sprintf("%.0s", "Hallo heimur") @test Printf.@sprintf("%*.*s", 20, 0, "Hallo heimur") == Printf.@sprintf("%20.0s", "Hallo heimur") @test Printf.@sprintf("%.s", "Hallo heimur") == Printf.@sprintf("%.s", "Hallo heimur") @test Printf.@sprintf("%*.s", 20, "Hallo heimur") == Printf.@sprintf("%20.s", "Hallo heimur") @test Printf.@sprintf("%*sø", 4, "ø") == Printf.@sprintf("%4sø", "ø") @test Printf.@sprintf("%-*sø", 4, "ø") == Printf.@sprintf("%-4sø", "ø") @test Printf.@sprintf("%*s", 8, "test") == Printf.@sprintf("%8s", "test") @test Printf.@sprintf("%-*s", 8, "test") == Printf.@sprintf("%-8s", "test") @test Printf.@sprintf("%#*s", 8, :test) == Printf.@sprintf("%#8s", :test) @test Printf.@sprintf("%#-*s", 8, :test) == Printf.@sprintf("%#-8s", :test) @test Printf.@sprintf("%*.*s", 8, 3, "test") == Printf.@sprintf("%8.3s", "test") @test Printf.@sprintf("%#*.*s", 8, 3, "test") == Printf.@sprintf("%#8.3s", "test") @test Printf.@sprintf("%-*.*s", 8, 3, "test") == Printf.@sprintf("%-8.3s", "test") @test Printf.@sprintf("%#-*.*s", 8, 3, "test") == Printf.@sprintf("%#-8.3s", "test") @test Printf.@sprintf("%.*s", 3, "test") == Printf.@sprintf("%.3s", "test") @test Printf.@sprintf("%#.*s", 3, "test") == Printf.@sprintf("%#.3s", "test") @test Printf.@sprintf("%-.*s", 3, "test") == Printf.@sprintf("%-.3s", "test") @test Printf.@sprintf("%#-.*s", 3, "test") == Printf.@sprintf("%#-.3s", "test") @test Printf.@sprintf("%*c", 3, 'a') == Printf.@sprintf("%3c", 'a') @test Printf.@sprintf("%*c", 1, 'x') == Printf.@sprintf("%1c", 'x') @test Printf.@sprintf("%*c", 20, 'x') == Printf.@sprintf("%20c", 'x') @test Printf.@sprintf("%-*c", 20, 'x') == Printf.@sprintf("%-20c", 'x') @test Printf.@sprintf("%-0*c", 20, 'x') == Printf.@sprintf("%-020c", 'x') @test Printf.@sprintf("%*c", 3, 'A') == Printf.@sprintf("%3c", 'A') @test Printf.@sprintf("%-*c", 3, 'A') == Printf.@sprintf("%-3c", 'A') @test Printf.@sprintf("%*.*f %*.*f %*.*f %*.*f %*.*f %*.*f %*.*f %*.*f %*.*f %*.*f %*.*f %*.*f %*.*f %*.*f %*.*f %*.*f %*.*f %*.*f", 4, 2, 1.2345, 4, 2, 1.2345, 4, 2, 1.2345, 4, 2, 1.2345, 4, 2, 1.2345, 4, 2, 1.2345, 4, 2, 1.2345, 4, 2, 1.2345, 4, 2, 1.2345, 4, 2, 1.2345, 4, 2, 1.2345, 4, 2, 1.2345, 4, 2, 1.2345, 4, 2, 1.2345, 4, 2, 1.2345, 4, 2, 1.2345, 4, 2, 1.2345, 4, 2, 1.2345) == Printf.@sprintf("%4.2f %4.2f %4.2f %4.2f %4.2f %4.2f %4.2f %4.2f %4.2f %4.2f %4.2f %4.2f %4.2f %4.2f %4.2f %4.2f %4.2f %4.2f", 1.2345, 1.2345, 1.2345, 1.2345, 1.2345, 1.2345, 1.2345, 1.2345, 1.2345, 1.2345, 1.2345, 1.2345, 1.2345, 1.2345, 1.2345, 1.2345, 1.2345, 1.2345) @test (Printf.@sprintf("%.*f", 330, BigFloat(1)))[var"end"] != '\0' @test Printf.@sprintf("%*.*s", 4, 2, "a") == Printf.@sprintf("%4.2s", "a") @test Printf.@sprintf("%*.*e", 12, 3, pi * 1.0e100) == Printf.@sprintf("%12.3e", pi * 1.0e100) @test Printf.@sprintf("%*d", 2, 3.14) == Printf.@sprintf("%*d", 2, 3.14) @test Printf.@sprintf("%*d", 2, big(3.14)) == Printf.@sprintf("%*d", 2, big(3.14)) @test Printf.@sprintf(" %.*e\n", 1, 0.999) == Printf.@sprintf(" %.1e\n", 0.999) @test Printf.@sprintf(" %.*f", 1, 9.999) == Printf.@sprintf(" %.1f", 9.999) @test Printf.@sprintf("%*d", 10, 12) == Printf.@sprintf("%10d", 12) @test Printf.@sprintf("%.*d", 4, 12) == Printf.@sprintf("%.4d", 12) @test Printf.@sprintf("%*.*d", 10, 4, 12) == Printf.@sprintf("%10.4d", 12) @test Printf.@sprintf("%+*.*d", 10, 4, 12) == Printf.@sprintf("%+10.4d", 12) @test Printf.@sprintf("%0*.*d", 10, 4, 12) == Printf.@sprintf("%010.4d", 12) @test Printf.@sprintf("% *d", 5, 42) == Printf.@sprintf("% 5d", 42) @test Printf.@sprintf("% *d", 5, -42) == Printf.@sprintf("% 5d", -42) @test Printf.@sprintf("% *d", 15, 42) == Printf.@sprintf("% 15d", 42) @test Printf.@sprintf("% *d", 15, -42) == Printf.@sprintf("% 15d", -42) @test Printf.@sprintf("%+*d", 5, 42) == Printf.@sprintf("%+5d", 42) @test Printf.@sprintf("%+*d", 5, -42) == Printf.@sprintf("%+5d", -42) @test Printf.@sprintf("%+*d", 15, 42) == Printf.@sprintf("%+15d", 42) @test Printf.@sprintf("%+*d", 15, -42) == Printf.@sprintf("%+15d", -42) @test Printf.@sprintf("%*d", 0, 42) == Printf.@sprintf("%0d", 42) @test Printf.@sprintf("%*d", 0, -42) == Printf.@sprintf("%0d", -42) @test Printf.@sprintf("%-*d", 5, 42) == Printf.@sprintf("%-5d", 42) @test Printf.@sprintf("%-*d", 5, -42) == Printf.@sprintf("%-5d", -42) @test Printf.@sprintf("%-*d", 15, 42) == Printf.@sprintf("%-15d", 42) @test Printf.@sprintf("%-*d", 15, -42) == Printf.@sprintf("%-15d", -42) @test Printf.@sprintf("%+*lld", 8, 100) == Printf.@sprintf("%+8lld", 100) @test Printf.@sprintf("%+.*lld", 8, 100) == Printf.@sprintf("%+.8lld", 100) @test Printf.@sprintf("%+*.*lld", 10, 8, 100) == Printf.@sprintf("%+10.8lld", 100) @test Printf.@sprintf("%-*.*lld", 1, 5, -100) == Printf.@sprintf("%-1.5lld", -100) @test Printf.@sprintf("%*lld", 5, 100) == Printf.@sprintf("%5lld", 100) @test Printf.@sprintf("%*lld", 5, -100) == Printf.@sprintf("%5lld", -100) @test Printf.@sprintf("%-*lld", 5, 100) == Printf.@sprintf("%-5lld", 100) @test Printf.@sprintf("%-*lld", 5, -100) == Printf.@sprintf("%-5lld", -100) @test Printf.@sprintf("%-.*lld", 5, 100) == Printf.@sprintf("%-.5lld", 100) @test Printf.@sprintf("%-.*lld", 5, -100) == Printf.@sprintf("%-.5lld", -100) @test Printf.@sprintf("%-*.*lld", 8, 5, 100) == Printf.@sprintf("%-8.5lld", 100) @test Printf.@sprintf("%-*.*lld", 8, 5, -100) == Printf.@sprintf("%-8.5lld", -100) @test Printf.@sprintf("%0*lld", 5, 100) == Printf.@sprintf("%05lld", 100) @test Printf.@sprintf("%0*lld", 5, -100) == Printf.@sprintf("%05lld", -100) @test Printf.@sprintf("% *lld", 5, 100) == Printf.@sprintf("% 5lld", 100) @test Printf.@sprintf("% *lld", 5, -100) == Printf.@sprintf("% 5lld", -100) @test Printf.@sprintf("% .*lld", 5, 100) == Printf.@sprintf("% .5lld", 100) @test Printf.@sprintf("% .*lld", 5, -100) == Printf.@sprintf("% .5lld", -100) @test Printf.@sprintf("% *.*lld", 8, 5, 100) == Printf.@sprintf("% 8.5lld", 100) @test Printf.@sprintf("% *.*lld", 8, 5, -100) == Printf.@sprintf("% 8.5lld", -100) @test Printf.@sprintf("%.*lld", 0, 0) == Printf.@sprintf("%.0lld", 0) @test Printf.@sprintf("%#+*.*llx", 21, 18, -100) == Printf.@sprintf("%#+21.18llx", -100) @test Printf.@sprintf("%#.*llo", 25, -100) == Printf.@sprintf("%#.25llo", -100) @test Printf.@sprintf("%#+*.*llo", 24, 20, -100) == Printf.@sprintf("%#+24.20llo", -100) @test Printf.@sprintf("%#+*.*llX", 18, 21, -100) == Printf.@sprintf("%#+18.21llX", -100) @test Printf.@sprintf("%#+*.*llo", 20, 24, -100) == Printf.@sprintf("%#+20.24llo", -100) @test Printf.@sprintf("%#+*.*llu", 25, 22, -1) == Printf.@sprintf("%#+25.22llu", -1) @test Printf.@sprintf("%#+*.*llu", 30, 25, -1) == Printf.@sprintf("%#+30.25llu", -1) @test Printf.@sprintf("%+#*.*lld", 25, 22, -1) == Printf.@sprintf("%+#25.22lld", -1) @test Printf.@sprintf("%#-*.*llo", 8, 5, 100) == Printf.@sprintf("%#-8.5llo", 100) @test Printf.@sprintf("%#-+ 0*.*lld", 8, 5, 100) == Printf.@sprintf("%#-+ 08.5lld", 100) @test Printf.@sprintf("%#-+ 0*.*lld", 8, 5, 100) == Printf.@sprintf("%#-+ 08.5lld", 100) @test Printf.@sprintf("%.*lld", 40, 1) == Printf.@sprintf("%.40lld", 1) @test Printf.@sprintf("% .*lld", 40, 1) == Printf.@sprintf("% .40lld", 1) @test Printf.@sprintf("% .*d", 40, 1) == Printf.@sprintf("% .40d", 1) @test Printf.@sprintf("%#0*x", 12, 1) == Printf.@sprintf("%#012x", 1) @test Printf.@sprintf("%#0*.*x", 4, 8, 1) == Printf.@sprintf("%#04.8x", 1) @test Printf.@sprintf("%#-0*.*x", 8, 2, 1) == Printf.@sprintf("%#-08.2x", 1) @test Printf.@sprintf("%#0*o", 8, 1) == Printf.@sprintf("%#08o", 1) @test Printf.@sprintf("%*d", 20, 1024) == Printf.@sprintf("%20d", 1024) @test Printf.@sprintf("%*d", 20, -1024) == Printf.@sprintf("%20d", -1024) @test Printf.@sprintf("%*i", 20, 1024) == Printf.@sprintf("%20i", 1024) @test Printf.@sprintf("%*i", 20, -1024) == Printf.@sprintf("%20i", -1024) @test Printf.@sprintf("%*u", 20, 1024) == Printf.@sprintf("%20u", 1024) @test Printf.@sprintf("%*u", 20, UInt(4294966272)) == Printf.@sprintf("%20u", UInt(4294966272)) @test Printf.@sprintf("%*o", 20, 511) == Printf.@sprintf("%20o", 511) @test Printf.@sprintf("%*o", 20, UInt(4294966785)) == Printf.@sprintf("%20o", UInt(4294966785)) @test Printf.@sprintf("%*x", 20, 305441741) == Printf.@sprintf("%20x", 305441741) @test Printf.@sprintf("%*x", 20, UInt(3989525555)) == Printf.@sprintf("%20x", UInt(3989525555)) @test Printf.@sprintf("%*X", 20, 305441741) == Printf.@sprintf("%20X", 305441741) @test Printf.@sprintf("%*X", 20, UInt(3989525555)) == Printf.@sprintf("%20X", UInt(3989525555)) @test Printf.@sprintf("%-*d", 20, 1024) == Printf.@sprintf("%-20d", 1024) @test Printf.@sprintf("%-*d", 20, -1024) == Printf.@sprintf("%-20d", -1024) @test Printf.@sprintf("%-*i", 20, 1024) == Printf.@sprintf("%-20i", 1024) @test Printf.@sprintf("%-*i", 20, -1024) == Printf.@sprintf("%-20i", -1024) @test Printf.@sprintf("%-*u", 20, 1024) == Printf.@sprintf("%-20u", 1024) @test Printf.@sprintf("%-*u", 20, UInt(4294966272)) == Printf.@sprintf("%-20u", UInt(4294966272)) @test Printf.@sprintf("%-*o", 20, 511) == Printf.@sprintf("%-20o", 511) @test Printf.@sprintf("%-*o", 20, UInt(4294966785)) == Printf.@sprintf("%-20o", UInt(4294966785)) @test Printf.@sprintf("%-*x", 20, 305441741) == Printf.@sprintf("%-20x", 305441741) @test Printf.@sprintf("%-*x", 20, UInt(3989525555)) == Printf.@sprintf("%-20x", UInt(3989525555)) @test Printf.@sprintf("%-*X", 20, 305441741) == Printf.@sprintf("%-20X", 305441741) @test Printf.@sprintf("%-*X", 20, UInt(3989525555)) == Printf.@sprintf("%-20X", UInt(3989525555)) @test Printf.@sprintf("%0*d", 20, 1024) == Printf.@sprintf("%020d", 1024) @test Printf.@sprintf("%0*d", 20, -1024) == Printf.@sprintf("%020d", -1024) @test Printf.@sprintf("%0*i", 20, 1024) == Printf.@sprintf("%020i", 1024) @test Printf.@sprintf("%0*i", 20, -1024) == Printf.@sprintf("%020i", -1024) @test Printf.@sprintf("%0*u", 20, 1024) == Printf.@sprintf("%020u", 1024) @test Printf.@sprintf("%0*u", 20, UInt(4294966272)) == Printf.@sprintf("%020u", UInt(4294966272)) @test Printf.@sprintf("%0*o", 20, 511) == Printf.@sprintf("%020o", 511) @test Printf.@sprintf("%0*o", 20, UInt(4294966785)) == Printf.@sprintf("%020o", UInt(4294966785)) @test Printf.@sprintf("%0*x", 20, 305441741) == Printf.@sprintf("%020x", 305441741) @test Printf.@sprintf("%0*x", 20, UInt(3989525555)) == Printf.@sprintf("%020x", UInt(3989525555)) @test Printf.@sprintf("%0*X", 20, 305441741) == Printf.@sprintf("%020X", 305441741) @test Printf.@sprintf("%0*X", 20, UInt(3989525555)) == Printf.@sprintf("%020X", UInt(3989525555)) @test Printf.@sprintf("%#*o", 20, 511) == Printf.@sprintf("%#20o", 511) @test Printf.@sprintf("%#*o", 20, UInt(4294966785)) == Printf.@sprintf("%#20o", UInt(4294966785)) @test Printf.@sprintf("%#*x", 20, 305441741) == Printf.@sprintf("%#20x", 305441741) @test Printf.@sprintf("%#*x", 20, UInt(3989525555)) == Printf.@sprintf("%#20x", UInt(3989525555)) @test Printf.@sprintf("%#*X", 20, 305441741) == Printf.@sprintf("%#20X", 305441741) @test Printf.@sprintf("%#*X", 20, UInt(3989525555)) == Printf.@sprintf("%#20X", UInt(3989525555)) @test Printf.@sprintf("%#0*o", 20, 511) == Printf.@sprintf("%#020o", 511) @test Printf.@sprintf("%#0*o", 20, UInt(4294966785)) == Printf.@sprintf("%#020o", UInt(4294966785)) @test Printf.@sprintf("%#0*x", 20, 305441741) == Printf.@sprintf("%#020x", 305441741) @test Printf.@sprintf("%#0*x", 20, UInt(3989525555)) == Printf.@sprintf("%#020x", UInt(3989525555)) @test Printf.@sprintf("%#0*X", 20, 305441741) == Printf.@sprintf("%#020X", 305441741) @test Printf.@sprintf("%#0*X", 20, UInt(3989525555)) == Printf.@sprintf("%#020X", UInt(3989525555)) @test Printf.@sprintf("%0-*d", 20, 1024) == Printf.@sprintf("%0-20d", 1024) @test Printf.@sprintf("%0-*d", 20, -1024) == Printf.@sprintf("%0-20d", -1024) @test Printf.@sprintf("%0-*i", 20, 1024) == Printf.@sprintf("%0-20i", 1024) @test Printf.@sprintf("%0-*i", 20, -1024) == Printf.@sprintf("%0-20i", -1024) @test Printf.@sprintf("%0-*u", 20, 1024) == Printf.@sprintf("%0-20u", 1024) @test Printf.@sprintf("%0-*u", 20, UInt(4294966272)) == Printf.@sprintf("%0-20u", UInt(4294966272)) @test Printf.@sprintf("%-0*o", 20, 511) == Printf.@sprintf("%-020o", 511) @test Printf.@sprintf("%-0*o", 20, UInt(4294966785)) == Printf.@sprintf("%-020o", UInt(4294966785)) @test Printf.@sprintf("%-0*x", 20, 305441741) == Printf.@sprintf("%-020x", 305441741) @test Printf.@sprintf("%-0*x", 20, UInt(3989525555)) == Printf.@sprintf("%-020x", UInt(3989525555)) @test Printf.@sprintf("%-0*X", 20, 305441741) == Printf.@sprintf("%-020X", 305441741) @test Printf.@sprintf("%-0*X", 20, UInt(3989525555)) == Printf.@sprintf("%-020X", UInt(3989525555)) @test Printf.@sprintf("%.*d", 20, 1024) == Printf.@sprintf("%.20d", 1024) @test Printf.@sprintf("%.*d", 20, -1024) == Printf.@sprintf("%.20d", -1024) @test Printf.@sprintf("%.*i", 20, 1024) == Printf.@sprintf("%.20i", 1024) @test Printf.@sprintf("%.*i", 20, -1024) == Printf.@sprintf("%.20i", -1024) @test Printf.@sprintf("%.*u", 20, 1024) == Printf.@sprintf("%.20u", 1024) @test Printf.@sprintf("%.*u", 20, UInt(4294966272)) == Printf.@sprintf("%.20u", UInt(4294966272)) @test Printf.@sprintf("%.*o", 20, 511) == Printf.@sprintf("%.20o", 511) @test Printf.@sprintf("%.*o", 20, UInt(4294966785)) == Printf.@sprintf("%.20o", UInt(4294966785)) @test Printf.@sprintf("%.*x", 20, 305441741) == Printf.@sprintf("%.20x", 305441741) @test Printf.@sprintf("%.*x", 20, UInt(3989525555)) == Printf.@sprintf("%.20x", UInt(3989525555)) @test Printf.@sprintf("%.*X", 20, 305441741) == Printf.@sprintf("%.20X", 305441741) @test Printf.@sprintf("%.*X", 20, UInt(3989525555)) == Printf.@sprintf("%.20X", UInt(3989525555)) @test Printf.@sprintf("%*.*d", 20, 5, 1024) == Printf.@sprintf("%20.5d", 1024) @test Printf.@sprintf("%*.*d", 20, 5, -1024) == Printf.@sprintf("%20.5d", -1024) @test Printf.@sprintf("%*.*i", 20, 5, 1024) == Printf.@sprintf("%20.5i", 1024) @test Printf.@sprintf("%*.*i", 20, 5, -1024) == Printf.@sprintf("%20.5i", -1024) @test Printf.@sprintf("%*.*u", 20, 5, 1024) == Printf.@sprintf("%20.5u", 1024) @test Printf.@sprintf("%*.*u", 20, 5, UInt(4294966272)) == Printf.@sprintf("%20.5u", UInt(4294966272)) @test Printf.@sprintf("%*.*o", 20, 5, 511) == Printf.@sprintf("%20.5o", 511) @test Printf.@sprintf("%*.*o", 20, 5, UInt(4294966785)) == Printf.@sprintf("%20.5o", UInt(4294966785)) @test Printf.@sprintf("%*.*x", 20, 5, 305441741) == Printf.@sprintf("%20.5x", 305441741) @test Printf.@sprintf("%*.*x", 20, 10, UInt(3989525555)) == Printf.@sprintf("%20.10x", UInt(3989525555)) @test Printf.@sprintf("%*.*X", 20, 5, 305441741) == Printf.@sprintf("%20.5X", 305441741) @test Printf.@sprintf("%*.*X", 20, 10, UInt(3989525555)) == Printf.@sprintf("%20.10X", UInt(3989525555)) @test Printf.@sprintf("%0*.*d", 20, 5, 1024) == Printf.@sprintf("%020.5d", 1024) @test Printf.@sprintf("%0*.*d", 20, 5, -1024) == Printf.@sprintf("%020.5d", -1024) @test Printf.@sprintf("%0*.*i", 20, 5, 1024) == Printf.@sprintf("%020.5i", 1024) @test Printf.@sprintf("%0*.*i", 20, 5, -1024) == Printf.@sprintf("%020.5i", -1024) @test Printf.@sprintf("%0*.*u", 20, 5, 1024) == Printf.@sprintf("%020.5u", 1024) @test Printf.@sprintf("%0*.*u", 20, 5, UInt(4294966272)) == Printf.@sprintf("%020.5u", UInt(4294966272)) @test Printf.@sprintf("%0*.*o", 20, 5, 511) == Printf.@sprintf("%020.5o", 511) @test Printf.@sprintf("%0*.*o", 20, 5, UInt(4294966785)) == Printf.@sprintf("%020.5o", UInt(4294966785)) @test Printf.@sprintf("%0*.*x", 20, 5, 305441741) == Printf.@sprintf("%020.5x", 305441741) @test Printf.@sprintf("%0*.*x", 20, 10, UInt(3989525555)) == Printf.@sprintf("%020.10x", UInt(3989525555)) @test Printf.@sprintf("%0*.*X", 20, 5, 305441741) == Printf.@sprintf("%020.5X", 305441741) @test Printf.@sprintf("%0*.*X", 20, 10, UInt(3989525555)) == Printf.@sprintf("%020.10X", UInt(3989525555)) @test Printf.@sprintf("%*.0d", 20, 1024) == Printf.@sprintf("%20.0d", 1024) @test Printf.@sprintf("%*.d", 20, -1024) == Printf.@sprintf("%20.d", -1024) @test Printf.@sprintf("%*.d", 20, 0) == Printf.@sprintf("%20.d", 0) @test Printf.@sprintf("%*.0i", 20, 1024) == Printf.@sprintf("%20.0i", 1024) @test Printf.@sprintf("%*.i", 20, -1024) == Printf.@sprintf("%20.i", -1024) @test Printf.@sprintf("%*.i", 20, 0) == Printf.@sprintf("%20.i", 0) @test Printf.@sprintf("%*.u", 20, 1024) == Printf.@sprintf("%20.u", 1024) @test Printf.@sprintf("%*.0u", 20, UInt(4294966272)) == Printf.@sprintf("%20.0u", UInt(4294966272)) @test Printf.@sprintf("%*.u", 20, UInt(0)) == Printf.@sprintf("%20.u", UInt(0)) @test Printf.@sprintf("%*.o", 20, 511) == Printf.@sprintf("%20.o", 511) @test Printf.@sprintf("%*.0o", 20, UInt(4294966785)) == Printf.@sprintf("%20.0o", UInt(4294966785)) @test Printf.@sprintf("%*.o", 20, UInt(0)) == Printf.@sprintf("%20.o", UInt(0)) @test Printf.@sprintf("%*.x", 20, 305441741) == Printf.@sprintf("%20.x", 305441741) @test Printf.@sprintf("%*.0x", 20, UInt(3989525555)) == Printf.@sprintf("%20.0x", UInt(3989525555)) @test Printf.@sprintf("%*.x", 20, UInt(0)) == Printf.@sprintf("%20.x", UInt(0)) @test Printf.@sprintf("%*.X", 20, 305441741) == Printf.@sprintf("%20.X", 305441741) @test Printf.@sprintf("%*.0X", 20, UInt(3989525555)) == Printf.@sprintf("%20.0X", UInt(3989525555)) @test Printf.@sprintf("%*.X", 20, UInt(0)) == Printf.@sprintf("%20.X", UInt(0)) x = Ref{Int}() y = Ref{Int}() @test begin Printf.@sprintf "%10s%n" "😉" x Printf.@sprintf "%*s%n" 10 "😉" y x[] == y[] end @test begin Printf.@sprintf "%10s%n" "1234" x Printf.@sprintf "%*s%n" 10 "1234" y x[] == y[] end end @testset "dynamic" begin @test Printf.@sprintf("%*d", 10, 12) == " 12" @test Printf.@sprintf("%.*d", 4, 12) == "0012" @test Printf.@sprintf("%*.*d", 10, 4, 12) == " 0012" @test Printf.@sprintf("%+*.*d", 10, 4, 12) == " +0012" @test Printf.@sprintf("%0*.*d", 10, 4, 12) == " 0012" @test Printf.@sprintf("%*d%*d%*d", 4, 12, 4, 13, 4, 14) == " 12 13 14" @test Printf.@sprintf("%*d%*d%*d", 4, 12, 5, 13, 6, 14) == " 12 13 14" @test Printf.@sprintf("%*p", 20, 0) == Printf.@sprintf("%20p", 0) @test Printf.@sprintf("%-*p", 20, 0) == Printf.@sprintf("%-20p", 0) @test Printf.@sprintf("%*p", 20, C_NULL) == Printf.@sprintf("%20p", C_NULL) @test Printf.@sprintf("%-*p", 20, C_NULL) == Printf.@sprintf("%-20p", C_NULL) @test Printf.@sprintf("%.*a", 0, 3.14) == Printf.@sprintf("%.0a", 3.14) @test Printf.@sprintf("%.*a", 1, 3.14) == Printf.@sprintf("%.1a", 3.14) @test Printf.@sprintf("%.*a", 2, 3.14) == Printf.@sprintf("%.2a", 3.14) @test Printf.@sprintf("%#.*a", 0, 3.14) == Printf.@sprintf("%#.0a", 3.14) @test Printf.@sprintf("%#.*a", 1, 3.14) == Printf.@sprintf("%#.1a", 3.14) @test Printf.@sprintf("%#.*a", 2, 3.14) == Printf.@sprintf("%#.2a", 3.14) @test Printf.@sprintf("%.*a", 6, 1.5) == Printf.@sprintf("%.6a", 1.5) @test Printf.@sprintf("%*.*g", 10, 5, -123.4) == Printf.@sprintf("%10.5g", -123.4) @test Printf.@sprintf("%0*.*g", 10, 5, -123.4) == Printf.@sprintf("%010.5g", -123.4) @test Printf.@sprintf("%.*g", 6, 1.234e7) == Printf.@sprintf("%.6g", 1.234e7) @test Printf.@sprintf("%#.*g", 6, 1.234e7) == Printf.@sprintf("%#.6g", 1.234e7) @test Printf.@sprintf("%*.*g", 10, 5, -123.4000000000000000000000000000000000000000000000000000000000000000000000000002) == Printf.@sprintf("%10.5g", -123.4000000000000000000000000000000000000000000000000000000000000000000000000002) @test Printf.@sprintf("%0*.*g", 10, 5, -123.4000000000000000000000000000000000000000000000000000000000000000000000000002) == Printf.@sprintf("%010.5g", -123.4000000000000000000000000000000000000000000000000000000000000000000000000002) @test Printf.@sprintf("%.*g", 6, 1.234e7) == Printf.@sprintf("%.6g", 1.234e7) @test Printf.@sprintf("%#.*g", 6, 1.234e7) == Printf.@sprintf("%#.6g", 1.234e7) @test Printf.@sprintf("%.*g", 5, 42) == Printf.@sprintf("%.5g", 42) @test Printf.@sprintf("%#.*g", 2, 42) == Printf.@sprintf("%#.2g", 42) @test Printf.@sprintf("%#.*g", 5, 42) == Printf.@sprintf("%#.5g", 42) @test Printf.@sprintf("%.*g", 15, 0) == Printf.@sprintf("%.15g", 0) @test Printf.@sprintf("%#.*g", 15, 0) == Printf.@sprintf("%#.15g", 0) @test Printf.@sprintf("%.*f", 0, 3.0e142) == Printf.@sprintf("%.0f", 3.0e142) @test Printf.@sprintf("%.*f", 2, 1.234) == Printf.@sprintf("%.2f", 1.234) @test Printf.@sprintf("%.*f", 2, 1.235) == Printf.@sprintf("%.2f", 1.235) @test Printf.@sprintf("%.*f", 2, 0.235) == Printf.@sprintf("%.2f", 0.235) @test Printf.@sprintf("%*.*f", 4, 1, 1.234) == Printf.@sprintf("%4.1f", 1.234) @test Printf.@sprintf("%*.*f", 8, 1, 1.234) == Printf.@sprintf("%8.1f", 1.234) @test Printf.@sprintf("%+*.*f", 8, 1, 1.234) == Printf.@sprintf("%+8.1f", 1.234) @test Printf.@sprintf("% *.*f", 8, 1, 1.234) == Printf.@sprintf("% 8.1f", 1.234) @test Printf.@sprintf("% *.*f", 7, 1, 1.234) == Printf.@sprintf("% 7.1f", 1.234) @test Printf.@sprintf("% 0*.*f", 8, 1, 1.234) == Printf.@sprintf("% 08.1f", 1.234) @test Printf.@sprintf("%0*.*f", 8, 1, 1.234) == Printf.@sprintf("%08.1f", 1.234) @test Printf.@sprintf("%-0*.*f", 8, 1, 1.234) == Printf.@sprintf("%-08.1f", 1.234) @test Printf.@sprintf("%-*.*f", 8, 1, 1.234) == Printf.@sprintf("%-8.1f", 1.234) @test Printf.@sprintf("%0*.*f", 8, 1, -1.234) == Printf.@sprintf("%08.1f", -1.234) @test Printf.@sprintf("%0*.*f", 9, 1, -1.234) == Printf.@sprintf("%09.1f", -1.234) @test Printf.@sprintf("%0*.*f", 9, 1, 1.234) == Printf.@sprintf("%09.1f", 1.234) @test Printf.@sprintf("%+0*.*f", 9, 1, 1.234) == Printf.@sprintf("%+09.1f", 1.234) @test Printf.@sprintf("% 0*.*f", 9, 1, 1.234) == Printf.@sprintf("% 09.1f", 1.234) @test Printf.@sprintf("%+ 0*.*f", 9, 1, 1.234) == Printf.@sprintf("%+ 09.1f", 1.234) @test Printf.@sprintf("%+ 0*.*f", 9, 1, 1.234) == Printf.@sprintf("%+ 09.1f", 1.234) @test Printf.@sprintf("%+ 0*.*f", 9, 0, 1.234) == Printf.@sprintf("%+ 09.0f", 1.234) @test Printf.@sprintf("%+ #0*.*f", 9, 0, 1.234) == Printf.@sprintf("%+ #09.0f", 1.234) @test Printf.@sprintf("%*.*e", 10, 4, Inf) == Printf.@sprintf("%10.4e", Inf) @test Printf.@sprintf("%*.*e", 10, 4, NaN) == Printf.@sprintf("%10.4e", NaN) @test Printf.@sprintf("%*.*e", 10, 4, Inf) == Printf.@sprintf("%10.4e", Inf) @test Printf.@sprintf("%*.*e", 10, 4, NaN) == Printf.@sprintf("%10.4e", NaN) @test Printf.@sprintf("%.*e", 0, 3.0e142) == Printf.@sprintf("%.0e", 3.0e142) @test Printf.@sprintf("%#.*e", 0, 3.0e142) == Printf.@sprintf("%#.0e", 3.0e142) @test Printf.@sprintf("%.*e", 0, 2.999999999999999999999999999999999999999999999999999999999999999999999999999996e142) == Printf.@sprintf("%.0e", 2.999999999999999999999999999999999999999999999999999999999999999999999999999996e142) @test Printf.@sprintf("%#.*e", 0, 2.999999999999999999999999999999999999999999999999999999999999999999999999999996e142) == Printf.@sprintf("%#.0e", 2.999999999999999999999999999999999999999999999999999999999999999999999999999996e142) @test Printf.@sprintf("%.*e", 0, 3.000000000000000000000000000000000000000000000000000000000000000000000000000024e1042) == Printf.@sprintf("%.0e", 3.000000000000000000000000000000000000000000000000000000000000000000000000000024e1042) @test Printf.@sprintf("%.*e", 2, 1.234) == Printf.@sprintf("%.2e", 1.234) @test Printf.@sprintf("%.*e", 2, 1.235) == Printf.@sprintf("%.2e", 1.235) @test Printf.@sprintf("%.*e", 2, 0.235) == Printf.@sprintf("%.2e", 0.235) @test Printf.@sprintf("%*.*e", 4, 1, 1.234) == Printf.@sprintf("%4.1e", 1.234) @test Printf.@sprintf("%*.*e", 8, 1, 1.234) == Printf.@sprintf("%8.1e", 1.234) @test Printf.@sprintf("%+*.*e", 8, 1, 1.234) == Printf.@sprintf("%+8.1e", 1.234) @test Printf.@sprintf("% *.*e", 8, 1, 1.234) == Printf.@sprintf("% 8.1e", 1.234) @test Printf.@sprintf("% *.*e", 7, 1, 1.234) == Printf.@sprintf("% 7.1e", 1.234) @test Printf.@sprintf("% 0*.*e", 8, 1, 1.234) == Printf.@sprintf("% 08.1e", 1.234) @test Printf.@sprintf("%0*.*e", 8, 1, 1.234) == Printf.@sprintf("%08.1e", 1.234) @test Printf.@sprintf("%-0*.*e", 8, 1, 1.234) == Printf.@sprintf("%-08.1e", 1.234) @test Printf.@sprintf("%-*.*e", 8, 1, 1.234) == Printf.@sprintf("%-8.1e", 1.234) @test Printf.@sprintf("%-*.*e", 8, 1, 1.234) == Printf.@sprintf("%-8.1e", 1.234) @test Printf.@sprintf("%0*.*e", 8, 1, -1.234) == Printf.@sprintf("%08.1e", -1.234) @test Printf.@sprintf("%0*.*e", 9, 1, -1.234) == Printf.@sprintf("%09.1e", -1.234) @test Printf.@sprintf("%0*.*e", 9, 1, 1.234) == Printf.@sprintf("%09.1e", 1.234) @test Printf.@sprintf("%+0*.*e", 9, 1, 1.234) == Printf.@sprintf("%+09.1e", 1.234) @test Printf.@sprintf("% 0*.*e", 9, 1, 1.234) == Printf.@sprintf("% 09.1e", 1.234) @test Printf.@sprintf("%+ 0*.*e", 9, 1, 1.234) == Printf.@sprintf("%+ 09.1e", 1.234) @test Printf.@sprintf("%+ 0*.*e", 9, 1, 1.234) == Printf.@sprintf("%+ 09.1e", 1.234) @test Printf.@sprintf("%+ 0*.*e", 9, 0, 1.234) == Printf.@sprintf("%+ 09.0e", 1.234) @test Printf.@sprintf("%+ #0*.*e", 9, 0, 1.234) == Printf.@sprintf("%+ #09.0e", 1.234) @test Printf.@sprintf("%.*s", 1, "foo") == Printf.@sprintf("%.1s", "foo") @test Printf.@sprintf("%*s", 1, "Hallo heimur") == Printf.@sprintf("%1s", "Hallo heimur") @test Printf.@sprintf("%*s", 20, "Hallo") == Printf.@sprintf("%20s", "Hallo") @test Printf.@sprintf("%-*s", 20, "Hallo") == Printf.@sprintf("%-20s", "Hallo") @test Printf.@sprintf("%0-*s", 20, "Hallo") == Printf.@sprintf("%0-20s", "Hallo") @test Printf.@sprintf("%.*s", 20, "Hallo heimur") == Printf.@sprintf("%.20s", "Hallo heimur") @test Printf.@sprintf("%*.*s", 20, 5, "Hallo heimur") == Printf.@sprintf("%20.5s", "Hallo heimur") @test Printf.@sprintf("%.*s", 0, "Hallo heimur") == Printf.@sprintf("%.0s", "Hallo heimur") @test Printf.@sprintf("%*.*s", 20, 0, "Hallo heimur") == Printf.@sprintf("%20.0s", "Hallo heimur") @test Printf.@sprintf("%.s", "Hallo heimur") == Printf.@sprintf("%.s", "Hallo heimur") @test Printf.@sprintf("%*.s", 20, "Hallo heimur") == Printf.@sprintf("%20.s", "Hallo heimur") @test Printf.@sprintf("%*sø", 4, "ø") == Printf.@sprintf("%4sø", "ø") @test Printf.@sprintf("%-*sø", 4, "ø") == Printf.@sprintf("%-4sø", "ø") @test Printf.@sprintf("%*s", 8, "test") == Printf.@sprintf("%8s", "test") @test Printf.@sprintf("%-*s", 8, "test") == Printf.@sprintf("%-8s", "test") @test Printf.@sprintf("%#*s", 8, :test) == Printf.@sprintf("%#8s", :test) @test Printf.@sprintf("%#-*s", 8, :test) == Printf.@sprintf("%#-8s", :test) @test Printf.@sprintf("%*.*s", 8, 3, "test") == Printf.@sprintf("%8.3s", "test") @test Printf.@sprintf("%#*.*s", 8, 3, "test") == Printf.@sprintf("%#8.3s", "test") @test Printf.@sprintf("%-*.*s", 8, 3, "test") == Printf.@sprintf("%-8.3s", "test") @test Printf.@sprintf("%#-*.*s", 8, 3, "test") == Printf.@sprintf("%#-8.3s", "test") @test Printf.@sprintf("%.*s", 3, "test") == Printf.@sprintf("%.3s", "test") @test Printf.@sprintf("%#.*s", 3, "test") == Printf.@sprintf("%#.3s", "test") @test Printf.@sprintf("%-.*s", 3, "test") == Printf.@sprintf("%-.3s", "test") @test Printf.@sprintf("%#-.*s", 3, "test") == Printf.@sprintf("%#-.3s", "test") @test Printf.@sprintf("%*c", 3, 'a') == Printf.@sprintf("%3c", 'a') @test Printf.@sprintf("%*c", 1, 'x') == Printf.@sprintf("%1c", 'x') @test Printf.@sprintf("%*c", 20, 'x') == Printf.@sprintf("%20c", 'x') @test Printf.@sprintf("%-*c", 20, 'x') == Printf.@sprintf("%-20c", 'x') @test Printf.@sprintf("%-0*c", 20, 'x') == Printf.@sprintf("%-020c", 'x') @test Printf.@sprintf("%*c", 3, 'A') == Printf.@sprintf("%3c", 'A') @test Printf.@sprintf("%-*c", 3, 'A') == Printf.@sprintf("%-3c", 'A') @test Printf.@sprintf("%*.*f %*.*f %*.*f %*.*f %*.*f %*.*f %*.*f %*.*f %*.*f %*.*f %*.*f %*.*f %*.*f %*.*f %*.*f %*.*f %*.*f %*.*f", 4, 2, 1.2345, 4, 2, 1.2345, 4, 2, 1.2345, 4, 2, 1.2345, 4, 2, 1.2345, 4, 2, 1.2345, 4, 2, 1.2345, 4, 2, 1.2345, 4, 2, 1.2345, 4, 2, 1.2345, 4, 2, 1.2345, 4, 2, 1.2345, 4, 2, 1.2345, 4, 2, 1.2345, 4, 2, 1.2345, 4, 2, 1.2345, 4, 2, 1.2345, 4, 2, 1.2345) == Printf.@sprintf("%4.2f %4.2f %4.2f %4.2f %4.2f %4.2f %4.2f %4.2f %4.2f %4.2f %4.2f %4.2f %4.2f %4.2f %4.2f %4.2f %4.2f %4.2f", 1.2345, 1.2345, 1.2345, 1.2345, 1.2345, 1.2345, 1.2345, 1.2345, 1.2345, 1.2345, 1.2345, 1.2345, 1.2345, 1.2345, 1.2345, 1.2345, 1.2345, 1.2345) @test (Printf.@sprintf("%.*f", 330, BigFloat(1)))[var"end"] != '\0' @test Printf.@sprintf("%*.*s", 4, 2, "a") == Printf.@sprintf("%4.2s", "a") @test Printf.@sprintf("%*.*e", 12, 3, pi * 1.0e100) == Printf.@sprintf("%12.3e", pi * 1.0e100) @test Printf.@sprintf("%*d", 2, 3.14) == Printf.@sprintf("%*d", 2, 3.14) @test Printf.@sprintf("%*d", 2, big(3.14)) == Printf.@sprintf("%*d", 2, big(3.14)) @test Printf.@sprintf(" %.*e\n", 1, 0.999) == Printf.@sprintf(" %.1e\n", 0.999) @test Printf.@sprintf(" %.*f", 1, 9.999) == Printf.@sprintf(" %.1f", 9.999) @test Printf.@sprintf("%*d", 10, 12) == Printf.@sprintf("%10d", 12) @test Printf.@sprintf("%.*d", 4, 12) == Printf.@sprintf("%.4d", 12) @test Printf.@sprintf("%*.*d", 10, 4, 12) == Printf.@sprintf("%10.4d", 12) @test Printf.@sprintf("%+*.*d", 10, 4, 12) == Printf.@sprintf("%+10.4d", 12) @test Printf.@sprintf("%0*.*d", 10, 4, 12) == Printf.@sprintf("%010.4d", 12) @test Printf.@sprintf("% *d", 5, 42) == Printf.@sprintf("% 5d", 42) @test Printf.@sprintf("% *d", 5, -42) == Printf.@sprintf("% 5d", -42) @test Printf.@sprintf("% *d", 15, 42) == Printf.@sprintf("% 15d", 42) @test Printf.@sprintf("% *d", 15, -42) == Printf.@sprintf("% 15d", -42) @test Printf.@sprintf("%+*d", 5, 42) == Printf.@sprintf("%+5d", 42) @test Printf.@sprintf("%+*d", 5, -42) == Printf.@sprintf("%+5d", -42) @test Printf.@sprintf("%+*d", 15, 42) == Printf.@sprintf("%+15d", 42) @test Printf.@sprintf("%+*d", 15, -42) == Printf.@sprintf("%+15d", -42) @test Printf.@sprintf("%*d", 0, 42) == Printf.@sprintf("%0d", 42) @test Printf.@sprintf("%*d", 0, -42) == Printf.@sprintf("%0d", -42) @test Printf.@sprintf("%-*d", 5, 42) == Printf.@sprintf("%-5d", 42) @test Printf.@sprintf("%-*d", 5, -42) == Printf.@sprintf("%-5d", -42) @test Printf.@sprintf("%-*d", 15, 42) == Printf.@sprintf("%-15d", 42) @test Printf.@sprintf("%-*d", 15, -42) == Printf.@sprintf("%-15d", -42) @test Printf.@sprintf("%+*lld", 8, 100) == Printf.@sprintf("%+8lld", 100) @test Printf.@sprintf("%+.*lld", 8, 100) == Printf.@sprintf("%+.8lld", 100) @test Printf.@sprintf("%+*.*lld", 10, 8, 100) == Printf.@sprintf("%+10.8lld", 100) @test Printf.@sprintf("%-*.*lld", 1, 5, -100) == Printf.@sprintf("%-1.5lld", -100) @test Printf.@sprintf("%*lld", 5, 100) == Printf.@sprintf("%5lld", 100) @test Printf.@sprintf("%*lld", 5, -100) == Printf.@sprintf("%5lld", -100) @test Printf.@sprintf("%-*lld", 5, 100) == Printf.@sprintf("%-5lld", 100) @test Printf.@sprintf("%-*lld", 5, -100) == Printf.@sprintf("%-5lld", -100) @test Printf.@sprintf("%-.*lld", 5, 100) == Printf.@sprintf("%-.5lld", 100) @test Printf.@sprintf("%-.*lld", 5, -100) == Printf.@sprintf("%-.5lld", -100) @test Printf.@sprintf("%-*.*lld", 8, 5, 100) == Printf.@sprintf("%-8.5lld", 100) @test Printf.@sprintf("%-*.*lld", 8, 5, -100) == Printf.@sprintf("%-8.5lld", -100) @test Printf.@sprintf("%0*lld", 5, 100) == Printf.@sprintf("%05lld", 100) @test Printf.@sprintf("%0*lld", 5, -100) == Printf.@sprintf("%05lld", -100) @test Printf.@sprintf("% *lld", 5, 100) == Printf.@sprintf("% 5lld", 100) @test Printf.@sprintf("% *lld", 5, -100) == Printf.@sprintf("% 5lld", -100) @test Printf.@sprintf("% .*lld", 5, 100) == Printf.@sprintf("% .5lld", 100) @test Printf.@sprintf("% .*lld", 5, -100) == Printf.@sprintf("% .5lld", -100) @test Printf.@sprintf("% *.*lld", 8, 5, 100) == Printf.@sprintf("% 8.5lld", 100) @test Printf.@sprintf("% *.*lld", 8, 5, -100) == Printf.@sprintf("% 8.5lld", -100) @test Printf.@sprintf("%.*lld", 0, 0) == Printf.@sprintf("%.0lld", 0) @test Printf.@sprintf("%#+*.*llx", 21, 18, -100) == Printf.@sprintf("%#+21.18llx", -100) @test Printf.@sprintf("%#.*llo", 25, -100) == Printf.@sprintf("%#.25llo", -100) @test Printf.@sprintf("%#+*.*llo", 24, 20, -100) == Printf.@sprintf("%#+24.20llo", -100) @test Printf.@sprintf("%#+*.*llX", 18, 21, -100) == Printf.@sprintf("%#+18.21llX", -100) @test Printf.@sprintf("%#+*.*llo", 20, 24, -100) == Printf.@sprintf("%#+20.24llo", -100) @test Printf.@sprintf("%#+*.*llu", 25, 22, -1) == Printf.@sprintf("%#+25.22llu", -1) @test Printf.@sprintf("%#+*.*llu", 30, 25, -1) == Printf.@sprintf("%#+30.25llu", -1) @test Printf.@sprintf("%+#*.*lld", 25, 22, -1) == Printf.@sprintf("%+#25.22lld", -1) @test Printf.@sprintf("%#-*.*llo", 8, 5, 100) == Printf.@sprintf("%#-8.5llo", 100) @test Printf.@sprintf("%#-+ 0*.*lld", 8, 5, 100) == Printf.@sprintf("%#-+ 08.5lld", 100) @test Printf.@sprintf("%#-+ 0*.*lld", 8, 5, 100) == Printf.@sprintf("%#-+ 08.5lld", 100) @test Printf.@sprintf("%.*lld", 40, 1) == Printf.@sprintf("%.40lld", 1) @test Printf.@sprintf("% .*lld", 40, 1) == Printf.@sprintf("% .40lld", 1) @test Printf.@sprintf("% .*d", 40, 1) == Printf.@sprintf("% .40d", 1) @test Printf.@sprintf("%#0*x", 12, 1) == Printf.@sprintf("%#012x", 1) @test Printf.@sprintf("%#0*.*x", 4, 8, 1) == Printf.@sprintf("%#04.8x", 1) @test Printf.@sprintf("%#-0*.*x", 8, 2, 1) == Printf.@sprintf("%#-08.2x", 1) @test Printf.@sprintf("%#0*o", 8, 1) == Printf.@sprintf("%#08o", 1) @test Printf.@sprintf("%*d", 20, 1024) == Printf.@sprintf("%20d", 1024) @test Printf.@sprintf("%*d", 20, -1024) == Printf.@sprintf("%20d", -1024) @test Printf.@sprintf("%*i", 20, 1024) == Printf.@sprintf("%20i", 1024) @test Printf.@sprintf("%*i", 20, -1024) == Printf.@sprintf("%20i", -1024) @test Printf.@sprintf("%*u", 20, 1024) == Printf.@sprintf("%20u", 1024) @test Printf.@sprintf("%*u", 20, UInt(4294966272)) == Printf.@sprintf("%20u", UInt(4294966272)) @test Printf.@sprintf("%*o", 20, 511) == Printf.@sprintf("%20o", 511) @test Printf.@sprintf("%*o", 20, UInt(4294966785)) == Printf.@sprintf("%20o", UInt(4294966785)) @test Printf.@sprintf("%*x", 20, 305441741) == Printf.@sprintf("%20x", 305441741) @test Printf.@sprintf("%*x", 20, UInt(3989525555)) == Printf.@sprintf("%20x", UInt(3989525555)) @test Printf.@sprintf("%*X", 20, 305441741) == Printf.@sprintf("%20X", 305441741) @test Printf.@sprintf("%*X", 20, UInt(3989525555)) == Printf.@sprintf("%20X", UInt(3989525555)) @test Printf.@sprintf("%-*d", 20, 1024) == Printf.@sprintf("%-20d", 1024) @test Printf.@sprintf("%-*d", 20, -1024) == Printf.@sprintf("%-20d", -1024) @test Printf.@sprintf("%-*i", 20, 1024) == Printf.@sprintf("%-20i", 1024) @test Printf.@sprintf("%-*i", 20, -1024) == Printf.@sprintf("%-20i", -1024) @test Printf.@sprintf("%-*u", 20, 1024) == Printf.@sprintf("%-20u", 1024) @test Printf.@sprintf("%-*u", 20, UInt(4294966272)) == Printf.@sprintf("%-20u", UInt(4294966272)) @test Printf.@sprintf("%-*o", 20, 511) == Printf.@sprintf("%-20o", 511) @test Printf.@sprintf("%-*o", 20, UInt(4294966785)) == Printf.@sprintf("%-20o", UInt(4294966785)) @test Printf.@sprintf("%-*x", 20, 305441741) == Printf.@sprintf("%-20x", 305441741) @test Printf.@sprintf("%-*x", 20, UInt(3989525555)) == Printf.@sprintf("%-20x", UInt(3989525555)) @test Printf.@sprintf("%-*X", 20, 305441741) == Printf.@sprintf("%-20X", 305441741) @test Printf.@sprintf("%-*X", 20, UInt(3989525555)) == Printf.@sprintf("%-20X", UInt(3989525555)) @test Printf.@sprintf("%0*d", 20, 1024) == Printf.@sprintf("%020d", 1024) @test Printf.@sprintf("%0*d", 20, -1024) == Printf.@sprintf("%020d", -1024) @test Printf.@sprintf("%0*i", 20, 1024) == Printf.@sprintf("%020i", 1024) @test Printf.@sprintf("%0*i", 20, -1024) == Printf.@sprintf("%020i", -1024) @test Printf.@sprintf("%0*u", 20, 1024) == Printf.@sprintf("%020u", 1024) @test Printf.@sprintf("%0*u", 20, UInt(4294966272)) == Printf.@sprintf("%020u", UInt(4294966272)) @test Printf.@sprintf("%0*o", 20, 511) == Printf.@sprintf("%020o", 511) @test Printf.@sprintf("%0*o", 20, UInt(4294966785)) == Printf.@sprintf("%020o", UInt(4294966785)) @test Printf.@sprintf("%0*x", 20, 305441741) == Printf.@sprintf("%020x", 305441741) @test Printf.@sprintf("%0*x", 20, UInt(3989525555)) == Printf.@sprintf("%020x", UInt(3989525555)) @test Printf.@sprintf("%0*X", 20, 305441741) == Printf.@sprintf("%020X", 305441741) @test Printf.@sprintf("%0*X", 20, UInt(3989525555)) == Printf.@sprintf("%020X", UInt(3989525555)) @test Printf.@sprintf("%#*o", 20, 511) == Printf.@sprintf("%#20o", 511) @test Printf.@sprintf("%#*o", 20, UInt(4294966785)) == Printf.@sprintf("%#20o", UInt(4294966785)) @test Printf.@sprintf("%#*x", 20, 305441741) == Printf.@sprintf("%#20x", 305441741) @test Printf.@sprintf("%#*x", 20, UInt(3989525555)) == Printf.@sprintf("%#20x", UInt(3989525555)) @test Printf.@sprintf("%#*X", 20, 305441741) == Printf.@sprintf("%#20X", 305441741) @test Printf.@sprintf("%#*X", 20, UInt(3989525555)) == Printf.@sprintf("%#20X", UInt(3989525555)) @test Printf.@sprintf("%#0*o", 20, 511) == Printf.@sprintf("%#020o", 511) @test Printf.@sprintf("%#0*o", 20, UInt(4294966785)) == Printf.@sprintf("%#020o", UInt(4294966785)) @test Printf.@sprintf("%#0*x", 20, 305441741) == Printf.@sprintf("%#020x", 305441741) @test Printf.@sprintf("%#0*x", 20, UInt(3989525555)) == Printf.@sprintf("%#020x", UInt(3989525555)) @test Printf.@sprintf("%#0*X", 20, 305441741) == Printf.@sprintf("%#020X", 305441741) @test Printf.@sprintf("%#0*X", 20, UInt(3989525555)) == Printf.@sprintf("%#020X", UInt(3989525555)) @test Printf.@sprintf("%0-*d", 20, 1024) == Printf.@sprintf("%0-20d", 1024) @test Printf.@sprintf("%0-*d", 20, -1024) == Printf.@sprintf("%0-20d", -1024) @test Printf.@sprintf("%0-*i", 20, 1024) == Printf.@sprintf("%0-20i", 1024) @test Printf.@sprintf("%0-*i", 20, -1024) == Printf.@sprintf("%0-20i", -1024) @test Printf.@sprintf("%0-*u", 20, 1024) == Printf.@sprintf("%0-20u", 1024) @test Printf.@sprintf("%0-*u", 20, UInt(4294966272)) == Printf.@sprintf("%0-20u", UInt(4294966272)) @test Printf.@sprintf("%-0*o", 20, 511) == Printf.@sprintf("%-020o", 511) @test Printf.@sprintf("%-0*o", 20, UInt(4294966785)) == Printf.@sprintf("%-020o", UInt(4294966785)) @test Printf.@sprintf("%-0*x", 20, 305441741) == Printf.@sprintf("%-020x", 305441741) @test Printf.@sprintf("%-0*x", 20, UInt(3989525555)) == Printf.@sprintf("%-020x", UInt(3989525555)) @test Printf.@sprintf("%-0*X", 20, 305441741) == Printf.@sprintf("%-020X", 305441741) @test Printf.@sprintf("%-0*X", 20, UInt(3989525555)) == Printf.@sprintf("%-020X", UInt(3989525555)) @test Printf.@sprintf("%.*d", 20, 1024) == Printf.@sprintf("%.20d", 1024) @test Printf.@sprintf("%.*d", 20, -1024) == Printf.@sprintf("%.20d", -1024) @test Printf.@sprintf("%.*i", 20, 1024) == Printf.@sprintf("%.20i", 1024) @test Printf.@sprintf("%.*i", 20, -1024) == Printf.@sprintf("%.20i", -1024) @test Printf.@sprintf("%.*u", 20, 1024) == Printf.@sprintf("%.20u", 1024) @test Printf.@sprintf("%.*u", 20, UInt(4294966272)) == Printf.@sprintf("%.20u", UInt(4294966272)) @test Printf.@sprintf("%.*o", 20, 511) == Printf.@sprintf("%.20o", 511) @test Printf.@sprintf("%.*o", 20, UInt(4294966785)) == Printf.@sprintf("%.20o", UInt(4294966785)) @test Printf.@sprintf("%.*x", 20, 305441741) == Printf.@sprintf("%.20x", 305441741) @test Printf.@sprintf("%.*x", 20, UInt(3989525555)) == Printf.@sprintf("%.20x", UInt(3989525555)) @test Printf.@sprintf("%.*X", 20, 305441741) == Printf.@sprintf("%.20X", 305441741) @test Printf.@sprintf("%.*X", 20, UInt(3989525555)) == Printf.@sprintf("%.20X", UInt(3989525555)) @test Printf.@sprintf("%*.*d", 20, 5, 1024) == Printf.@sprintf("%20.5d", 1024) @test Printf.@sprintf("%*.*d", 20, 5, -1024) == Printf.@sprintf("%20.5d", -1024) @test Printf.@sprintf("%*.*i", 20, 5, 1024) == Printf.@sprintf("%20.5i", 1024) @test Printf.@sprintf("%*.*i", 20, 5, -1024) == Printf.@sprintf("%20.5i", -1024) @test Printf.@sprintf("%*.*u", 20, 5, 1024) == Printf.@sprintf("%20.5u", 1024) @test Printf.@sprintf("%*.*u", 20, 5, UInt(4294966272)) == Printf.@sprintf("%20.5u", UInt(4294966272)) @test Printf.@sprintf("%*.*o", 20, 5, 511) == Printf.@sprintf("%20.5o", 511) @test Printf.@sprintf("%*.*o", 20, 5, UInt(4294966785)) == Printf.@sprintf("%20.5o", UInt(4294966785)) @test Printf.@sprintf("%*.*x", 20, 5, 305441741) == Printf.@sprintf("%20.5x", 305441741) @test Printf.@sprintf("%*.*x", 20, 10, UInt(3989525555)) == Printf.@sprintf("%20.10x", UInt(3989525555)) @test Printf.@sprintf("%*.*X", 20, 5, 305441741) == Printf.@sprintf("%20.5X", 305441741) @test Printf.@sprintf("%*.*X", 20, 10, UInt(3989525555)) == Printf.@sprintf("%20.10X", UInt(3989525555)) @test Printf.@sprintf("%0*.*d", 20, 5, 1024) == Printf.@sprintf("%020.5d", 1024) @test Printf.@sprintf("%0*.*d", 20, 5, -1024) == Printf.@sprintf("%020.5d", -1024) @test Printf.@sprintf("%0*.*i", 20, 5, 1024) == Printf.@sprintf("%020.5i", 1024) @test Printf.@sprintf("%0*.*i", 20, 5, -1024) == Printf.@sprintf("%020.5i", -1024) @test Printf.@sprintf("%0*.*u", 20, 5, 1024) == Printf.@sprintf("%020.5u", 1024) @test Printf.@sprintf("%0*.*u", 20, 5, UInt(4294966272)) == Printf.@sprintf("%020.5u", UInt(4294966272)) @test Printf.@sprintf("%0*.*o", 20, 5, 511) == Printf.@sprintf("%020.5o", 511) @test Printf.@sprintf("%0*.*o", 20, 5, UInt(4294966785)) == Printf.@sprintf("%020.5o", UInt(4294966785)) @test Printf.@sprintf("%0*.*x", 20, 5, 305441741) == Printf.@sprintf("%020.5x", 305441741) @test Printf.@sprintf("%0*.*x", 20, 10, UInt(3989525555)) == Printf.@sprintf("%020.10x", UInt(3989525555)) @test Printf.@sprintf("%0*.*X", 20, 5, 305441741) == Printf.@sprintf("%020.5X", 305441741) @test Printf.@sprintf("%0*.*X", 20, 10, UInt(3989525555)) == Printf.@sprintf("%020.10X", UInt(3989525555)) @test Printf.@sprintf("%*.0d", 20, 1024) == Printf.@sprintf("%20.0d", 1024) @test Printf.@sprintf("%*.d", 20, -1024) == Printf.@sprintf("%20.d", -1024) @test Printf.@sprintf("%*.d", 20, 0) == Printf.@sprintf("%20.d", 0) @test Printf.@sprintf("%*.0i", 20, 1024) == Printf.@sprintf("%20.0i", 1024) @test Printf.@sprintf("%*.i", 20, -1024) == Printf.@sprintf("%20.i", -1024) @test Printf.@sprintf("%*.i", 20, 0) == Printf.@sprintf("%20.i", 0) @test Printf.@sprintf("%*.u", 20, 1024) == Printf.@sprintf("%20.u", 1024) @test Printf.@sprintf("%*.0u", 20, UInt(4294966272)) == Printf.@sprintf("%20.0u", UInt(4294966272)) @test Printf.@sprintf("%*.u", 20, UInt(0)) == Printf.@sprintf("%20.u", UInt(0)) @test Printf.@sprintf("%*.o", 20, 511) == Printf.@sprintf("%20.o", 511) @test Printf.@sprintf("%*.0o", 20, UInt(4294966785)) == Printf.@sprintf("%20.0o", UInt(4294966785)) @test Printf.@sprintf("%*.o", 20, UInt(0)) == Printf.@sprintf("%20.o", UInt(0)) @test Printf.@sprintf("%*.x", 20, 305441741) == Printf.@sprintf("%20.x", 305441741) @test Printf.@sprintf("%*.0x", 20, UInt(3989525555)) == Printf.@sprintf("%20.0x", UInt(3989525555)) @test Printf.@sprintf("%*.x", 20, UInt(0)) == Printf.@sprintf("%20.x", UInt(0)) @test Printf.@sprintf("%*.X", 20, 305441741) == Printf.@sprintf("%20.X", 305441741) @test Printf.@sprintf("%*.0X", 20, UInt(3989525555)) == Printf.@sprintf("%20.0X", UInt(3989525555)) @test Printf.@sprintf("%*.X", 20, UInt(0)) == Printf.@sprintf("%20.X", UInt(0)) x = Ref{Int}() y = Ref{Int}() @test begin Printf.@sprintf "%10s%n" "😉" x Printf.@sprintf "%*s%n" 10 "😉" y x[] == y[] end @test begin Printf.@sprintf "%10s%n" "1234" x Printf.@sprintf "%*s%n" 10 "1234" y x[] == y[] end end @testset "dynamic" begin @test Printf.@sprintf("%*d", 10, 12) == " 12" @test Printf.@sprintf("%.*d", 4, 12) == "0012" @test Printf.@sprintf("%*.*d", 10, 4, 12) == " 0012" @test Printf.@sprintf("%+*.*d", 10, 4, 12) == " +0012" @test Printf.@sprintf("%0*.*d", 10, 4, 12) == " 0012" @test Printf.@sprintf("%*d%*d%*d", 4, 12, 4, 13, 4, 14) == " 12 13 14" @test Printf.@sprintf("%*d%*d%*d", 4, 12, 5, 13, 6, 14) == " 12 13 14" @test Printf.@sprintf("%*p", 20, 0) == Printf.@sprintf("%20p", 0) @test Printf.@sprintf("%-*p", 20, 0) == Printf.@sprintf("%-20p", 0) @test Printf.@sprintf("%*p", 20, C_NULL) == Printf.@sprintf("%20p", C_NULL) @test Printf.@sprintf("%-*p", 20, C_NULL) == Printf.@sprintf("%-20p", C_NULL) @test Printf.@sprintf("%.*a", 0, 3.14) == Printf.@sprintf("%.0a", 3.14) @test Printf.@sprintf("%.*a", 1, 3.14) == Printf.@sprintf("%.1a", 3.14) @test Printf.@sprintf("%.*a", 2, 3.14) == Printf.@sprintf("%.2a", 3.14) @test Printf.@sprintf("%#.*a", 0, 3.14) == Printf.@sprintf("%#.0a", 3.14) @test Printf.@sprintf("%#.*a", 1, 3.14) == Printf.@sprintf("%#.1a", 3.14) @test Printf.@sprintf("%#.*a", 2, 3.14) == Printf.@sprintf("%#.2a", 3.14) @test Printf.@sprintf("%.*a", 6, 1.5) == Printf.@sprintf("%.6a", 1.5) @test Printf.@sprintf("%*.*g", 10, 5, -123.4) == Printf.@sprintf("%10.5g", -123.4) @test Printf.@sprintf("%0*.*g", 10, 5, -123.4) == Printf.@sprintf("%010.5g", -123.4) @test Printf.@sprintf("%.*g", 6, 1.234e7) == Printf.@sprintf("%.6g", 1.234e7) @test Printf.@sprintf("%#.*g", 6, 1.234e7) == Printf.@sprintf("%#.6g", 1.234e7) @test Printf.@sprintf("%*.*g", 10, 5, -123.4000000000000000000000000000000000000000000000000000000000000000000000000002) == Printf.@sprintf("%10.5g", -123.4000000000000000000000000000000000000000000000000000000000000000000000000002) @test Printf.@sprintf("%0*.*g", 10, 5, -123.4000000000000000000000000000000000000000000000000000000000000000000000000002) == Printf.@sprintf("%010.5g", -123.4000000000000000000000000000000000000000000000000000000000000000000000000002) @test Printf.@sprintf("%.*g", 6, 1.234e7) == Printf.@sprintf("%.6g", 1.234e7) @test Printf.@sprintf("%#.*g", 6, 1.234e7) == Printf.@sprintf("%#.6g", 1.234e7) @test Printf.@sprintf("%.*g", 5, 42) == Printf.@sprintf("%.5g", 42) @test Printf.@sprintf("%#.*g", 2, 42) == Printf.@sprintf("%#.2g", 42) @test Printf.@sprintf("%#.*g", 5, 42) == Printf.@sprintf("%#.5g", 42) @test Printf.@sprintf("%.*g", 15, 0) == Printf.@sprintf("%.15g", 0) @test Printf.@sprintf("%#.*g", 15, 0) == Printf.@sprintf("%#.15g", 0) @test Printf.@sprintf("%.*f", 0, 3.0e142) == Printf.@sprintf("%.0f", 3.0e142) @test Printf.@sprintf("%.*f", 2, 1.234) == Printf.@sprintf("%.2f", 1.234) @test Printf.@sprintf("%.*f", 2, 1.235) == Printf.@sprintf("%.2f", 1.235) @test Printf.@sprintf("%.*f", 2, 0.235) == Printf.@sprintf("%.2f", 0.235) @test Printf.@sprintf("%*.*f", 4, 1, 1.234) == Printf.@sprintf("%4.1f", 1.234) @test Printf.@sprintf("%*.*f", 8, 1, 1.234) == Printf.@sprintf("%8.1f", 1.234) @test Printf.@sprintf("%+*.*f", 8, 1, 1.234) == Printf.@sprintf("%+8.1f", 1.234) @test Printf.@sprintf("% *.*f", 8, 1, 1.234) == Printf.@sprintf("% 8.1f", 1.234) @test Printf.@sprintf("% *.*f", 7, 1, 1.234) == Printf.@sprintf("% 7.1f", 1.234) @test Printf.@sprintf("% 0*.*f", 8, 1, 1.234) == Printf.@sprintf("% 08.1f", 1.234) @test Printf.@sprintf("%0*.*f", 8, 1, 1.234) == Printf.@sprintf("%08.1f", 1.234) @test Printf.@sprintf("%-0*.*f", 8, 1, 1.234) == Printf.@sprintf("%-08.1f", 1.234) @test Printf.@sprintf("%-*.*f", 8, 1, 1.234) == Printf.@sprintf("%-8.1f", 1.234) @test Printf.@sprintf("%0*.*f", 8, 1, -1.234) == Printf.@sprintf("%08.1f", -1.234) @test Printf.@sprintf("%0*.*f", 9, 1, -1.234) == Printf.@sprintf("%09.1f", -1.234) @test Printf.@sprintf("%0*.*f", 9, 1, 1.234) == Printf.@sprintf("%09.1f", 1.234) @test Printf.@sprintf("%+0*.*f", 9, 1, 1.234) == Printf.@sprintf("%+09.1f", 1.234) @test Printf.@sprintf("% 0*.*f", 9, 1, 1.234) == Printf.@sprintf("% 09.1f", 1.234) @test Printf.@sprintf("%+ 0*.*f", 9, 1, 1.234) == Printf.@sprintf("%+ 09.1f", 1.234) @test Printf.@sprintf("%+ 0*.*f", 9, 1, 1.234) == Printf.@sprintf("%+ 09.1f", 1.234) @test Printf.@sprintf("%+ 0*.*f", 9, 0, 1.234) == Printf.@sprintf("%+ 09.0f", 1.234) @test Printf.@sprintf("%+ #0*.*f", 9, 0, 1.234) == Printf.@sprintf("%+ #09.0f", 1.234) @test Printf.@sprintf("%*.*e", 10, 4, Inf) == Printf.@sprintf("%10.4e", Inf) @test Printf.@sprintf("%*.*e", 10, 4, NaN) == Printf.@sprintf("%10.4e", NaN) @test Printf.@sprintf("%*.*e", 10, 4, Inf) == Printf.@sprintf("%10.4e", Inf) @test Printf.@sprintf("%*.*e", 10, 4, NaN) == Printf.@sprintf("%10.4e", NaN) @test Printf.@sprintf("%.*e", 0, 3.0e142) == Printf.@sprintf("%.0e", 3.0e142) @test Printf.@sprintf("%#.*e", 0, 3.0e142) == Printf.@sprintf("%#.0e", 3.0e142) @test Printf.@sprintf("%.*e", 0, 2.999999999999999999999999999999999999999999999999999999999999999999999999999996e142) == Printf.@sprintf("%.0e", 2.999999999999999999999999999999999999999999999999999999999999999999999999999996e142) @test Printf.@sprintf("%#.*e", 0, 2.999999999999999999999999999999999999999999999999999999999999999999999999999996e142) == Printf.@sprintf("%#.0e", 2.999999999999999999999999999999999999999999999999999999999999999999999999999996e142) @test Printf.@sprintf("%.*e", 0, 3.000000000000000000000000000000000000000000000000000000000000000000000000000024e1042) == Printf.@sprintf("%.0e", 3.000000000000000000000000000000000000000000000000000000000000000000000000000024e1042) @test Printf.@sprintf("%.*e", 2, 1.234) == Printf.@sprintf("%.2e", 1.234) @test Printf.@sprintf("%.*e", 2, 1.235) == Printf.@sprintf("%.2e", 1.235) @test Printf.@sprintf("%.*e", 2, 0.235) == Printf.@sprintf("%.2e", 0.235) @test Printf.@sprintf("%*.*e", 4, 1, 1.234) == Printf.@sprintf("%4.1e", 1.234) @test Printf.@sprintf("%*.*e", 8, 1, 1.234) == Printf.@sprintf("%8.1e", 1.234) @test Printf.@sprintf("%+*.*e", 8, 1, 1.234) == Printf.@sprintf("%+8.1e", 1.234) @test Printf.@sprintf("% *.*e", 8, 1, 1.234) == Printf.@sprintf("% 8.1e", 1.234) @test Printf.@sprintf("% *.*e", 7, 1, 1.234) == Printf.@sprintf("% 7.1e", 1.234) @test Printf.@sprintf("% 0*.*e", 8, 1, 1.234) == Printf.@sprintf("% 08.1e", 1.234) @test Printf.@sprintf("%0*.*e", 8, 1, 1.234) == Printf.@sprintf("%08.1e", 1.234) @test Printf.@sprintf("%-0*.*e", 8, 1, 1.234) == Printf.@sprintf("%-08.1e", 1.234) @test Printf.@sprintf("%-*.*e", 8, 1, 1.234) == Printf.@sprintf("%-8.1e", 1.234) @test Printf.@sprintf("%-*.*e", 8, 1, 1.234) == Printf.@sprintf("%-8.1e", 1.234) @test Printf.@sprintf("%0*.*e", 8, 1, -1.234) == Printf.@sprintf("%08.1e", -1.234) @test Printf.@sprintf("%0*.*e", 9, 1, -1.234) == Printf.@sprintf("%09.1e", -1.234) @test Printf.@sprintf("%0*.*e", 9, 1, 1.234) == Printf.@sprintf("%09.1e", 1.234) @test Printf.@sprintf("%+0*.*e", 9, 1, 1.234) == Printf.@sprintf("%+09.1e", 1.234) @test Printf.@sprintf("% 0*.*e", 9, 1, 1.234) == Printf.@sprintf("% 09.1e", 1.234) @test Printf.@sprintf("%+ 0*.*e", 9, 1, 1.234) == Printf.@sprintf("%+ 09.1e", 1.234) @test Printf.@sprintf("%+ 0*.*e", 9, 1, 1.234) == Printf.@sprintf("%+ 09.1e", 1.234) @test Printf.@sprintf("%+ 0*.*e", 9, 0, 1.234) == Printf.@sprintf("%+ 09.0e", 1.234) @test Printf.@sprintf("%+ #0*.*e", 9, 0, 1.234) == Printf.@sprintf("%+ #09.0e", 1.234) @test Printf.@sprintf("%.*s", 1, "foo") == Printf.@sprintf("%.1s", "foo") @test Printf.@sprintf("%*s", 1, "Hallo heimur") == Printf.@sprintf("%1s", "Hallo heimur") @test Printf.@sprintf("%*s", 20, "Hallo") == Printf.@sprintf("%20s", "Hallo") @test Printf.@sprintf("%-*s", 20, "Hallo") == Printf.@sprintf("%-20s", "Hallo") @test Printf.@sprintf("%0-*s", 20, "Hallo") == Printf.@sprintf("%0-20s", "Hallo") @test Printf.@sprintf("%.*s", 20, "Hallo heimur") == Printf.@sprintf("%.20s", "Hallo heimur") @test Printf.@sprintf("%*.*s", 20, 5, "Hallo heimur") == Printf.@sprintf("%20.5s", "Hallo heimur") @test Printf.@sprintf("%.*s", 0, "Hallo heimur") == Printf.@sprintf("%.0s", "Hallo heimur") @test Printf.@sprintf("%*.*s", 20, 0, "Hallo heimur") == Printf.@sprintf("%20.0s", "Hallo heimur") @test Printf.@sprintf("%.s", "Hallo heimur") == Printf.@sprintf("%.s", "Hallo heimur") @test Printf.@sprintf("%*.s", 20, "Hallo heimur") == Printf.@sprintf("%20.s", "Hallo heimur") @test Printf.@sprintf("%*sø", 4, "ø") == Printf.@sprintf("%4sø", "ø") @test Printf.@sprintf("%-*sø", 4, "ø") == Printf.@sprintf("%-4sø", "ø") @test Printf.@sprintf("%*s", 8, "test") == Printf.@sprintf("%8s", "test") @test Printf.@sprintf("%-*s", 8, "test") == Printf.@sprintf("%-8s", "test") @test Printf.@sprintf("%#*s", 8, :test) == Printf.@sprintf("%#8s", :test) @test Printf.@sprintf("%#-*s", 8, :test) == Printf.@sprintf("%#-8s", :test) @test Printf.@sprintf("%*.*s", 8, 3, "test") == Printf.@sprintf("%8.3s", "test") @test Printf.@sprintf("%#*.*s", 8, 3, "test") == Printf.@sprintf("%#8.3s", "test") @test Printf.@sprintf("%-*.*s", 8, 3, "test") == Printf.@sprintf("%-8.3s", "test") @test Printf.@sprintf("%#-*.*s", 8, 3, "test") == Printf.@sprintf("%#-8.3s", "test") @test Printf.@sprintf("%.*s", 3, "test") == Printf.@sprintf("%.3s", "test") @test Printf.@sprintf("%#.*s", 3, "test") == Printf.@sprintf("%#.3s", "test") @test Printf.@sprintf("%-.*s", 3, "test") == Printf.@sprintf("%-.3s", "test") @test Printf.@sprintf("%#-.*s", 3, "test") == Printf.@sprintf("%#-.3s", "test") @test Printf.@sprintf("%*c", 3, 'a') == Printf.@sprintf("%3c", 'a') @test Printf.@sprintf("%*c", 1, 'x') == Printf.@sprintf("%1c", 'x') @test Printf.@sprintf("%*c", 20, 'x') == Printf.@sprintf("%20c", 'x') @test Printf.@sprintf("%-*c", 20, 'x') == Printf.@sprintf("%-20c", 'x') @test Printf.@sprintf("%-0*c", 20, 'x') == Printf.@sprintf("%-020c", 'x') @test Printf.@sprintf("%*c", 3, 'A') == Printf.@sprintf("%3c", 'A') @test Printf.@sprintf("%-*c", 3, 'A') == Printf.@sprintf("%-3c", 'A') @test Printf.@sprintf("%*.*f %*.*f %*.*f %*.*f %*.*f %*.*f %*.*f %*.*f %*.*f %*.*f %*.*f %*.*f %*.*f %*.*f %*.*f %*.*f %*.*f %*.*f", 4, 2, 1.2345, 4, 2, 1.2345, 4, 2, 1.2345, 4, 2, 1.2345, 4, 2, 1.2345, 4, 2, 1.2345, 4, 2, 1.2345, 4, 2, 1.2345, 4, 2, 1.2345, 4, 2, 1.2345, 4, 2, 1.2345, 4, 2, 1.2345, 4, 2, 1.2345, 4, 2, 1.2345, 4, 2, 1.2345, 4, 2, 1.2345, 4, 2, 1.2345, 4, 2, 1.2345) == Printf.@sprintf("%4.2f %4.2f %4.2f %4.2f %4.2f %4.2f %4.2f %4.2f %4.2f %4.2f %4.2f %4.2f %4.2f %4.2f %4.2f %4.2f %4.2f %4.2f", 1.2345, 1.2345, 1.2345, 1.2345, 1.2345, 1.2345, 1.2345, 1.2345, 1.2345, 1.2345, 1.2345, 1.2345, 1.2345, 1.2345, 1.2345, 1.2345, 1.2345, 1.2345) @test (Printf.@sprintf("%.*f", 330, BigFloat(1)))[var"end"] != '\0' @test Printf.@sprintf("%*.*s", 4, 2, "a") == Printf.@sprintf("%4.2s", "a") @test Printf.@sprintf("%*.*e", 12, 3, pi * 1.0e100) == Printf.@sprintf("%12.3e", pi * 1.0e100) @test Printf.@sprintf("%*d", 2, 3.14) == Printf.@sprintf("%*d", 2, 3.14) @test Printf.@sprintf("%*d", 2, big(3.14)) == Printf.@sprintf("%*d", 2, big(3.14)) @test Printf.@sprintf(" %.*e\n", 1, 0.999) == Printf.@sprintf(" %.1e\n", 0.999) @test Printf.@sprintf(" %.*f", 1, 9.999) == Printf.@sprintf(" %.1f", 9.999) @test Printf.@sprintf("%*d", 10, 12) == Printf.@sprintf("%10d", 12) @test Printf.@sprintf("%.*d", 4, 12) == Printf.@sprintf("%.4d", 12) @test Printf.@sprintf("%*.*d", 10, 4, 12) == Printf.@sprintf("%10.4d", 12) @test Printf.@sprintf("%+*.*d", 10, 4, 12) == Printf.@sprintf("%+10.4d", 12) @test Printf.@sprintf("%0*.*d", 10, 4, 12) == Printf.@sprintf("%010.4d", 12) @test Printf.@sprintf("% *d", 5, 42) == Printf.@sprintf("% 5d", 42) @test Printf.@sprintf("% *d", 5, -42) == Printf.@sprintf("% 5d", -42) @test Printf.@sprintf("% *d", 15, 42) == Printf.@sprintf("% 15d", 42) @test Printf.@sprintf("% *d", 15, -42) == Printf.@sprintf("% 15d", -42) @test Printf.@sprintf("%+*d", 5, 42) == Printf.@sprintf("%+5d", 42) @test Printf.@sprintf("%+*d", 5, -42) == Printf.@sprintf("%+5d", -42) @test Printf.@sprintf("%+*d", 15, 42) == Printf.@sprintf("%+15d", 42) @test Printf.@sprintf("%+*d", 15, -42) == Printf.@sprintf("%+15d", -42) @test Printf.@sprintf("%*d", 0, 42) == Printf.@sprintf("%0d", 42) @test Printf.@sprintf("%*d", 0, -42) == Printf.@sprintf("%0d", -42) @test Printf.@sprintf("%-*d", 5, 42) == Printf.@sprintf("%-5d", 42) @test Printf.@sprintf("%-*d", 5, -42) == Printf.@sprintf("%-5d", -42) @test Printf.@sprintf("%-*d", 15, 42) == Printf.@sprintf("%-15d", 42) @test Printf.@sprintf("%-*d", 15, -42) == Printf.@sprintf("%-15d", -42) @test Printf.@sprintf("%+*lld", 8, 100) == Printf.@sprintf("%+8lld", 100) @test Printf.@sprintf("%+.*lld", 8, 100) == Printf.@sprintf("%+.8lld", 100) @test Printf.@sprintf("%+*.*lld", 10, 8, 100) == Printf.@sprintf("%+10.8lld", 100) @test Printf.@sprintf("%-*.*lld", 1, 5, -100) == Printf.@sprintf("%-1.5lld", -100) @test Printf.@sprintf("%*lld", 5, 100) == Printf.@sprintf("%5lld", 100) @test Printf.@sprintf("%*lld", 5, -100) == Printf.@sprintf("%5lld", -100) @test Printf.@sprintf("%-*lld", 5, 100) == Printf.@sprintf("%-5lld", 100) @test Printf.@sprintf("%-*lld", 5, -100) == Printf.@sprintf("%-5lld", -100) @test Printf.@sprintf("%-.*lld", 5, 100) == Printf.@sprintf("%-.5lld", 100) @test Printf.@sprintf("%-.*lld", 5, -100) == Printf.@sprintf("%-.5lld", -100) @test Printf.@sprintf("%-*.*lld", 8, 5, 100) == Printf.@sprintf("%-8.5lld", 100) @test Printf.@sprintf("%-*.*lld", 8, 5, -100) == Printf.@sprintf("%-8.5lld", -100) @test Printf.@sprintf("%0*lld", 5, 100) == Printf.@sprintf("%05lld", 100) @test Printf.@sprintf("%0*lld", 5, -100) == Printf.@sprintf("%05lld", -100) @test Printf.@sprintf("% *lld", 5, 100) == Printf.@sprintf("% 5lld", 100) @test Printf.@sprintf("% *lld", 5, -100) == Printf.@sprintf("% 5lld", -100) @test Printf.@sprintf("% .*lld", 5, 100) == Printf.@sprintf("% .5lld", 100) @test Printf.@sprintf("% .*lld", 5, -100) == Printf.@sprintf("% .5lld", -100) @test Printf.@sprintf("% *.*lld", 8, 5, 100) == Printf.@sprintf("% 8.5lld", 100) @test Printf.@sprintf("% *.*lld", 8, 5, -100) == Printf.@sprintf("% 8.5lld", -100) @test Printf.@sprintf("%.*lld", 0, 0) == Printf.@sprintf("%.0lld", 0) @test Printf.@sprintf("%#+*.*llx", 21, 18, -100) == Printf.@sprintf("%#+21.18llx", -100) @test Printf.@sprintf("%#.*llo", 25, -100) == Printf.@sprintf("%#.25llo", -100) @test Printf.@sprintf("%#+*.*llo", 24, 20, -100) == Printf.@sprintf("%#+24.20llo", -100) @test Printf.@sprintf("%#+*.*llX", 18, 21, -100) == Printf.@sprintf("%#+18.21llX", -100) @test Printf.@sprintf("%#+*.*llo", 20, 24, -100) == Printf.@sprintf("%#+20.24llo", -100) @test Printf.@sprintf("%#+*.*llu", 25, 22, -1) == Printf.@sprintf("%#+25.22llu", -1) @test Printf.@sprintf("%#+*.*llu", 30, 25, -1) == Printf.@sprintf("%#+30.25llu", -1) @test Printf.@sprintf("%+#*.*lld", 25, 22, -1) == Printf.@sprintf("%+#25.22lld", -1) @test Printf.@sprintf("%#-*.*llo", 8, 5, 100) == Printf.@sprintf("%#-8.5llo", 100) @test Printf.@sprintf("%#-+ 0*.*lld", 8, 5, 100) == Printf.@sprintf("%#-+ 08.5lld", 100) @test Printf.@sprintf("%#-+ 0*.*lld", 8, 5, 100) == Printf.@sprintf("%#-+ 08.5lld", 100) @test Printf.@sprintf("%.*lld", 40, 1) == Printf.@sprintf("%.40lld", 1) @test Printf.@sprintf("% .*lld", 40, 1) == Printf.@sprintf("% .40lld", 1) @test Printf.@sprintf("% .*d", 40, 1) == Printf.@sprintf("% .40d", 1) @test Printf.@sprintf("%#0*x", 12, 1) == Printf.@sprintf("%#012x", 1) @test Printf.@sprintf("%#0*.*x", 4, 8, 1) == Printf.@sprintf("%#04.8x", 1) @test Printf.@sprintf("%#-0*.*x", 8, 2, 1) == Printf.@sprintf("%#-08.2x", 1) @test Printf.@sprintf("%#0*o", 8, 1) == Printf.@sprintf("%#08o", 1) @test Printf.@sprintf("%*d", 20, 1024) == Printf.@sprintf("%20d", 1024) @test Printf.@sprintf("%*d", 20, -1024) == Printf.@sprintf("%20d", -1024) @test Printf.@sprintf("%*i", 20, 1024) == Printf.@sprintf("%20i", 1024) @test Printf.@sprintf("%*i", 20, -1024) == Printf.@sprintf("%20i", -1024) @test Printf.@sprintf("%*u", 20, 1024) == Printf.@sprintf("%20u", 1024) @test Printf.@sprintf("%*u", 20, UInt(4294966272)) == Printf.@sprintf("%20u", UInt(4294966272)) @test Printf.@sprintf("%*o", 20, 511) == Printf.@sprintf("%20o", 511) @test Printf.@sprintf("%*o", 20, UInt(4294966785)) == Printf.@sprintf("%20o", UInt(4294966785)) @test Printf.@sprintf("%*x", 20, 305441741) == Printf.@sprintf("%20x", 305441741) @test Printf.@sprintf("%*x", 20, UInt(3989525555)) == Printf.@sprintf("%20x", UInt(3989525555)) @test Printf.@sprintf("%*X", 20, 305441741) == Printf.@sprintf("%20X", 305441741) @test Printf.@sprintf("%*X", 20, UInt(3989525555)) == Printf.@sprintf("%20X", UInt(3989525555)) @test Printf.@sprintf("%-*d", 20, 1024) == Printf.@sprintf("%-20d", 1024) @test Printf.@sprintf("%-*d", 20, -1024) == Printf.@sprintf("%-20d", -1024) @test Printf.@sprintf("%-*i", 20, 1024) == Printf.@sprintf("%-20i", 1024) @test Printf.@sprintf("%-*i", 20, -1024) == Printf.@sprintf("%-20i", -1024) @test Printf.@sprintf("%-*u", 20, 1024) == Printf.@sprintf("%-20u", 1024) @test Printf.@sprintf("%-*u", 20, UInt(4294966272)) == Printf.@sprintf("%-20u", UInt(4294966272)) @test Printf.@sprintf("%-*o", 20, 511) == Printf.@sprintf("%-20o", 511) @test Printf.@sprintf("%-*o", 20, UInt(4294966785)) == Printf.@sprintf("%-20o", UInt(4294966785)) @test Printf.@sprintf("%-*x", 20, 305441741) == Printf.@sprintf("%-20x", 305441741) @test Printf.@sprintf("%-*x", 20, UInt(3989525555)) == Printf.@sprintf("%-20x", UInt(3989525555)) @test Printf.@sprintf("%-*X", 20, 305441741) == Printf.@sprintf("%-20X", 305441741) @test Printf.@sprintf("%-*X", 20, UInt(3989525555)) == Printf.@sprintf("%-20X", UInt(3989525555)) @test Printf.@sprintf("%0*d", 20, 1024) == Printf.@sprintf("%020d", 1024) @test Printf.@sprintf("%0*d", 20, -1024) == Printf.@sprintf("%020d", -1024) @test Printf.@sprintf("%0*i", 20, 1024) == Printf.@sprintf("%020i", 1024) @test Printf.@sprintf("%0*i", 20, -1024) == Printf.@sprintf("%020i", -1024) @test Printf.@sprintf("%0*u", 20, 1024) == Printf.@sprintf("%020u", 1024) @test Printf.@sprintf("%0*u", 20, UInt(4294966272)) == Printf.@sprintf("%020u", UInt(4294966272)) @test Printf.@sprintf("%0*o", 20, 511) == Printf.@sprintf("%020o", 511) @test Printf.@sprintf("%0*o", 20, UInt(4294966785)) == Printf.@sprintf("%020o", UInt(4294966785)) @test Printf.@sprintf("%0*x", 20, 305441741) == Printf.@sprintf("%020x", 305441741) @test Printf.@sprintf("%0*x", 20, UInt(3989525555)) == Printf.@sprintf("%020x", UInt(3989525555)) @test Printf.@sprintf("%0*X", 20, 305441741) == Printf.@sprintf("%020X", 305441741) @test Printf.@sprintf("%0*X", 20, UInt(3989525555)) == Printf.@sprintf("%020X", UInt(3989525555)) @test Printf.@sprintf("%#*o", 20, 511) == Printf.@sprintf("%#20o", 511) @test Printf.@sprintf("%#*o", 20, UInt(4294966785)) == Printf.@sprintf("%#20o", UInt(4294966785)) @test Printf.@sprintf("%#*x", 20, 305441741) == Printf.@sprintf("%#20x", 305441741) @test Printf.@sprintf("%#*x", 20, UInt(3989525555)) == Printf.@sprintf("%#20x", UInt(3989525555)) @test Printf.@sprintf("%#*X", 20, 305441741) == Printf.@sprintf("%#20X", 305441741) @test Printf.@sprintf("%#*X", 20, UInt(3989525555)) == Printf.@sprintf("%#20X", UInt(3989525555)) @test Printf.@sprintf("%#0*o", 20, 511) == Printf.@sprintf("%#020o", 511) @test Printf.@sprintf("%#0*o", 20, UInt(4294966785)) == Printf.@sprintf("%#020o", UInt(4294966785)) @test Printf.@sprintf("%#0*x", 20, 305441741) == Printf.@sprintf("%#020x", 305441741) @test Printf.@sprintf("%#0*x", 20, UInt(3989525555)) == Printf.@sprintf("%#020x", UInt(3989525555)) @test Printf.@sprintf("%#0*X", 20, 305441741) == Printf.@sprintf("%#020X", 305441741) @test Printf.@sprintf("%#0*X", 20, UInt(3989525555)) == Printf.@sprintf("%#020X", UInt(3989525555)) @test Printf.@sprintf("%0-*d", 20, 1024) == Printf.@sprintf("%0-20d", 1024) @test Printf.@sprintf("%0-*d", 20, -1024) == Printf.@sprintf("%0-20d", -1024) @test Printf.@sprintf("%0-*i", 20, 1024) == Printf.@sprintf("%0-20i", 1024) @test Printf.@sprintf("%0-*i", 20, -1024) == Printf.@sprintf("%0-20i", -1024) @test Printf.@sprintf("%0-*u", 20, 1024) == Printf.@sprintf("%0-20u", 1024) @test Printf.@sprintf("%0-*u", 20, UInt(4294966272)) == Printf.@sprintf("%0-20u", UInt(4294966272)) @test Printf.@sprintf("%-0*o", 20, 511) == Printf.@sprintf("%-020o", 511) @test Printf.@sprintf("%-0*o", 20, UInt(4294966785)) == Printf.@sprintf("%-020o", UInt(4294966785)) @test Printf.@sprintf("%-0*x", 20, 305441741) == Printf.@sprintf("%-020x", 305441741) @test Printf.@sprintf("%-0*x", 20, UInt(3989525555)) == Printf.@sprintf("%-020x", UInt(3989525555)) @test Printf.@sprintf("%-0*X", 20, 305441741) == Printf.@sprintf("%-020X", 305441741) @test Printf.@sprintf("%-0*X", 20, UInt(3989525555)) == Printf.@sprintf("%-020X", UInt(3989525555)) @test Printf.@sprintf("%.*d", 20, 1024) == Printf.@sprintf("%.20d", 1024) @test Printf.@sprintf("%.*d", 20, -1024) == Printf.@sprintf("%.20d", -1024) @test Printf.@sprintf("%.*i", 20, 1024) == Printf.@sprintf("%.20i", 1024) @test Printf.@sprintf("%.*i", 20, -1024) == Printf.@sprintf("%.20i", -1024) @test Printf.@sprintf("%.*u", 20, 1024) == Printf.@sprintf("%.20u", 1024) @test Printf.@sprintf("%.*u", 20, UInt(4294966272)) == Printf.@sprintf("%.20u", UInt(4294966272)) @test Printf.@sprintf("%.*o", 20, 511) == Printf.@sprintf("%.20o", 511) @test Printf.@sprintf("%.*o", 20, UInt(4294966785)) == Printf.@sprintf("%.20o", UInt(4294966785)) @test Printf.@sprintf("%.*x", 20, 305441741) == Printf.@sprintf("%.20x", 305441741) @test Printf.@sprintf("%.*x", 20, UInt(3989525555)) == Printf.@sprintf("%.20x", UInt(3989525555)) @test Printf.@sprintf("%.*X", 20, 305441741) == Printf.@sprintf("%.20X", 305441741) @test Printf.@sprintf("%.*X", 20, UInt(3989525555)) == Printf.@sprintf("%.20X", UInt(3989525555)) @test Printf.@sprintf("%*.*d", 20, 5, 1024) == Printf.@sprintf("%20.5d", 1024) @test Printf.@sprintf("%*.*d", 20, 5, -1024) == Printf.@sprintf("%20.5d", -1024) @test Printf.@sprintf("%*.*i", 20, 5, 1024) == Printf.@sprintf("%20.5i", 1024) @test Printf.@sprintf("%*.*i", 20, 5, -1024) == Printf.@sprintf("%20.5i", -1024) @test Printf.@sprintf("%*.*u", 20, 5, 1024) == Printf.@sprintf("%20.5u", 1024) @test Printf.@sprintf("%*.*u", 20, 5, UInt(4294966272)) == Printf.@sprintf("%20.5u", UInt(4294966272)) @test Printf.@sprintf("%*.*o", 20, 5, 511) == Printf.@sprintf("%20.5o", 511) @test Printf.@sprintf("%*.*o", 20, 5, UInt(4294966785)) == Printf.@sprintf("%20.5o", UInt(4294966785)) @test Printf.@sprintf("%*.*x", 20, 5, 305441741) == Printf.@sprintf("%20.5x", 305441741) @test Printf.@sprintf("%*.*x", 20, 10, UInt(3989525555)) == Printf.@sprintf("%20.10x", UInt(3989525555)) @test Printf.@sprintf("%*.*X", 20, 5, 305441741) == Printf.@sprintf("%20.5X", 305441741) @test Printf.@sprintf("%*.*X", 20, 10, UInt(3989525555)) == Printf.@sprintf("%20.10X", UInt(3989525555)) @test Printf.@sprintf("%0*.*d", 20, 5, 1024) == Printf.@sprintf("%020.5d", 1024) @test Printf.@sprintf("%0*.*d", 20, 5, -1024) == Printf.@sprintf("%020.5d", -1024) @test Printf.@sprintf("%0*.*i", 20, 5, 1024) == Printf.@sprintf("%020.5i", 1024) @test Printf.@sprintf("%0*.*i", 20, 5, -1024) == Printf.@sprintf("%020.5i", -1024) @test Printf.@sprintf("%0*.*u", 20, 5, 1024) == Printf.@sprintf("%020.5u", 1024) @test Printf.@sprintf("%0*.*u", 20, 5, UInt(4294966272)) == Printf.@sprintf("%020.5u", UInt(4294966272)) @test Printf.@sprintf("%0*.*o", 20, 5, 511) == Printf.@sprintf("%020.5o", 511) @test Printf.@sprintf("%0*.*o", 20, 5, UInt(4294966785)) == Printf.@sprintf("%020.5o", UInt(4294966785)) @test Printf.@sprintf("%0*.*x", 20, 5, 305441741) == Printf.@sprintf("%020.5x", 305441741) @test Printf.@sprintf("%0*.*x", 20, 10, UInt(3989525555)) == Printf.@sprintf("%020.10x", UInt(3989525555)) @test Printf.@sprintf("%0*.*X", 20, 5, 305441741) == Printf.@sprintf("%020.5X", 305441741) @test Printf.@sprintf("%0*.*X", 20, 10, UInt(3989525555)) == Printf.@sprintf("%020.10X", UInt(3989525555)) @test Printf.@sprintf("%*.0d", 20, 1024) == Printf.@sprintf("%20.0d", 1024) @test Printf.@sprintf("%*.d", 20, -1024) == Printf.@sprintf("%20.d", -1024) @test Printf.@sprintf("%*.d", 20, 0) == Printf.@sprintf("%20.d", 0) @test Printf.@sprintf("%*.0i", 20, 1024) == Printf.@sprintf("%20.0i", 1024) @test Printf.@sprintf("%*.i", 20, -1024) == Printf.@sprintf("%20.i", -1024) @test Printf.@sprintf("%*.i", 20, 0) == Printf.@sprintf("%20.i", 0) @test Printf.@sprintf("%*.u", 20, 1024) == Printf.@sprintf("%20.u", 1024) @test Printf.@sprintf("%*.0u", 20, UInt(4294966272)) == Printf.@sprintf("%20.0u", UInt(4294966272)) @test Printf.@sprintf("%*.u", 20, UInt(0)) == Printf.@sprintf("%20.u", UInt(0)) @test Printf.@sprintf("%*.o", 20, 511) == Printf.@sprintf("%20.o", 511) @test Printf.@sprintf("%*.0o", 20, UInt(4294966785)) == Printf.@sprintf("%20.0o", UInt(4294966785)) @test Printf.@sprintf("%*.o", 20, UInt(0)) == Printf.@sprintf("%20.o", UInt(0)) @test Printf.@sprintf("%*.x", 20, 305441741) == Printf.@sprintf("%20.x", 305441741) @test Printf.@sprintf("%*.0x", 20, UInt(3989525555)) == Printf.@sprintf("%20.0x", UInt(3989525555)) @test Printf.@sprintf("%*.x", 20, UInt(0)) == Printf.@sprintf("%20.x", UInt(0)) @test Printf.@sprintf("%*.X", 20, 305441741) == Printf.@sprintf("%20.X", 305441741) @test Printf.@sprintf("%*.0X", 20, UInt(3989525555)) == Printf.@sprintf("%20.0X", UInt(3989525555)) @test Printf.@sprintf("%*.X", 20, UInt(0)) == Printf.@sprintf("%20.X", UInt(0)) x = Ref{Int}() y = Ref{Int}() @test begin Printf.@sprintf "%10s%n" "😉" x Printf.@sprintf "%*s%n" 10 "😉" y x[] == y[] end @test begin Printf.@sprintf "%10s%n" "1234" x Printf.@sprintf "%*s%n" 10 "1234" y x[] == y[] end end begin @testset "%p" begin if Sys.WORD_SIZE == 64 @test Printf.@sprintf("%20p", 0) == " 0x0000000000000000" @test Printf.@sprintf("%-20p", 0) == "0x0000000000000000 " @test Printf.@sprintf("%20p", C_NULL) == " 0x0000000000000000" @test @sprintf("%-20p", C_NULL) == "0x0000000000000000 " elseif Sys.WORD_SIZE == 32 @test Printf.@sprintf("%20p", 0) == " 0x00000000" @test Printf.@sprintf("%-20p", 0) == "0x00000000 " @test @sprintf("%20p", C_NULL) == " 0x00000000" @test @sprintf("%-20p", C_NULL) == "0x00000000 " end @test @sprintf("%p", 0xfffffffffffe0000) == "0xfffffffffffe0000" end @testset "%a" begin @test Printf.@sprintf("%a", 0.0) == "0x0p+0" @test Printf.@sprintf("%a", -0.0) == "-0x0p+0" @test Printf.@sprintf("%.3a", 0.0) == "0x0.000p+0" @test Printf.@sprintf("%a", 1.5) == "0x1.8p+0" @test Printf.@sprintf("%a", 1.5f0) == "0x1.8p+0" @test Printf.@sprintf("%a", 1.5) == "0x1.8p+0" @test Printf.@sprintf("%#.0a", 1.5) == "0x2.p+0" @test Printf.@sprintf("%+30a", 1 / 3) == " +0x1.5555555555555p-2" @test Printf.@sprintf("%a", 1.5) == "0x1.8p+0" @test Printf.@sprintf("%a", 3.14) == "0x1.91eb851eb851fp+1" @test Printf.@sprintf("%.0a", 3.14) == "0x2p+1" @test Printf.@sprintf("%.1a", 3.14) == "0x1.9p+1" @test Printf.@sprintf("%.2a", 3.14) == "0x1.92p+1" @test Printf.@sprintf("%#a", 3.14) == "0x1.91eb851eb851fp+1" @test Printf.@sprintf("%#.0a", 3.14) == "0x2.p+1" @test Printf.@sprintf("%#.1a", 3.14) == "0x1.9p+1" @test Printf.@sprintf("%#.2a", 3.14) == "0x1.92p+1" @test Printf.@sprintf("%.6a", 1.5) == "0x1.800000p+0" end @testset "%g" begin for (val, res) = ((1.2345678e7, "1.23457e+07"), (1.2345678e6, "1.23457e+06"), (123456.78, "123457"), (12345.678, "12345.7"), (1.234e7, "1.234e+07")) @test Printf.@sprintf("%.6g", val) == res end for (val, res) = ((1.2345678e7, "1.23457e+07"), (1.234567799999999999999999999999999999999999999999999999999999999999999999999993e6, "1.23457e+06"), (123456.7800000000000000000000000000000000000000000000000000000000000000000000004, "123457"), (12345.67800000000000000000000000000000000000000000000000000000000000000000000007, "12345.7")) @test Printf.@sprintf("%.6g", val) == res end for (fmt, val) = (("%10.5g", " 123.4"), ("%+10.5g", " +123.4"), ("% 10.5g", " 123.4"), ("%#10.5g", " 123.40"), ("%-10.5g", "123.4 "), ("%-+10.5g", "+123.4 "), ("%010.5g", "00000123.4")), num = (123.4, 123.4000000000000000000000000000000000000000000000000000000000000000000000000002) @test Printf.format(Printf.Format(fmt), num) == val end @test Printf.@sprintf("%10.5g", -123.4) == " -123.4" @test Printf.@sprintf("%010.5g", -123.4) == "-0000123.4" @test Printf.@sprintf("%.6g", 1.234e7) == "1.234e+07" @test Printf.@sprintf("%#.6g", 1.234e7) == "1.23400e+07" @test Printf.@sprintf("%10.5g", -123.4000000000000000000000000000000000000000000000000000000000000000000000000002) == " -123.4" @test Printf.@sprintf("%010.5g", -123.4000000000000000000000000000000000000000000000000000000000000000000000000002) == "-0000123.4" @test Printf.@sprintf("%.6g", 1.234e7) == "1.234e+07" @test Printf.@sprintf("%#.6g", 1.234e7) == "1.23400e+07" @test Printf.@sprintf("%.5g", 42) == "42" @test Printf.@sprintf("%#.2g", 42) == "42." @test Printf.@sprintf("%#.5g", 42) == "42.000" @test Printf.@sprintf("%g", 0.00012) == "0.00012" @test Printf.@sprintf("%g", 1.2e-5) == "1.2e-05" @test Printf.@sprintf("%g", 123456.7) == "123457" @test Printf.@sprintf("%g", 1.2345678e6) == "1.23457e+06" for (val, res) = ((Inf, "Inf"), (-Inf, "-Inf"), (NaN, "NaN"), (-NaN, "NaN")) @test Printf.@sprintf("%g", val) == res @test Printf.@sprintf("%G", val) == res end @test Printf.@sprintf("%.15g", 0) == "0" @test Printf.@sprintf("%#.15g", 0) == "0.00000000000000" end @testset "%f" begin @test Printf.@sprintf("%f", Inf) == "Inf" @test Printf.@sprintf("%+f", Inf) == "+Inf" @test Printf.@sprintf("% f", Inf) == " Inf" @test Printf.@sprintf("% #f", Inf) == " Inf" @test Printf.@sprintf("%07f", Inf) == " Inf" @test Printf.@sprintf("%f", -Inf) == "-Inf" @test Printf.@sprintf("%+f", -Inf) == "-Inf" @test Printf.@sprintf("%07f", -Inf) == " -Inf" @test Printf.@sprintf("%f", NaN) == "NaN" @test Printf.@sprintf("%+f", NaN) == "+NaN" @test Printf.@sprintf("% f", NaN) == " NaN" @test Printf.@sprintf("% #f", NaN) == " NaN" @test Printf.@sprintf("%07f", NaN) == " NaN" @test Printf.@sprintf("%e", Inf) == "Inf" @test Printf.@sprintf("%e", NaN) == "NaN" @test Printf.@sprintf("%.0f", 3.0e142) == "29999999999999997463140672961703247153805615792184250659629251954072073858354858644285983761764971823910371920726635399393477049701891710124032" @test Printf.@sprintf("%f", 1.234) == "1.234000" @test Printf.@sprintf("%F", 1.234) == "1.234000" @test Printf.@sprintf("%+f", 1.234) == "+1.234000" @test Printf.@sprintf("% f", 1.234) == " 1.234000" @test Printf.@sprintf("%f", -1.234) == "-1.234000" @test Printf.@sprintf("%+f", -1.234) == "-1.234000" @test Printf.@sprintf("% f", -1.234) == "-1.234000" @test Printf.@sprintf("%#f", 1.234) == "1.234000" @test Printf.@sprintf("%.2f", 1.234) == "1.23" @test Printf.@sprintf("%.2f", 1.235) == "1.24" @test Printf.@sprintf("%.2f", 0.235) == "0.23" @test Printf.@sprintf("%4.1f", 1.234) == " 1.2" @test Printf.@sprintf("%8.1f", 1.234) == " 1.2" @test Printf.@sprintf("%+8.1f", 1.234) == " +1.2" @test Printf.@sprintf("% 8.1f", 1.234) == " 1.2" @test Printf.@sprintf("% 7.1f", 1.234) == " 1.2" @test Printf.@sprintf("% 08.1f", 1.234) == " 00001.2" @test Printf.@sprintf("%08.1f", 1.234) == "000001.2" @test Printf.@sprintf("%-08.1f", 1.234) == "1.2 " @test Printf.@sprintf("%-8.1f", 1.234) == "1.2 " @test Printf.@sprintf("%08.1f", -1.234) == "-00001.2" @test Printf.@sprintf("%09.1f", -1.234) == "-000001.2" @test Printf.@sprintf("%09.1f", 1.234) == "0000001.2" @test Printf.@sprintf("%+09.1f", 1.234) == "+000001.2" @test Printf.@sprintf("% 09.1f", 1.234) == " 000001.2" @test Printf.@sprintf("%+ 09.1f", 1.234) == "+000001.2" @test Printf.@sprintf("%+ 09.1f", 1.234) == "+000001.2" @test Printf.@sprintf("%+ 09.0f", 1.234) == "+00000001" @test Printf.@sprintf("%+ #09.0f", 1.234) == "+0000001." @test Printf.@sprintf("%+7.1f", 9.96) == " +10.0" @test Printf.@sprintf("% 7.1f", 9.96) == " 10.0" end @testset "%e" begin @test Printf.@sprintf("%e", Inf) == "Inf" @test Printf.@sprintf("%+e", Inf) == "+Inf" @test Printf.@sprintf("% e", Inf) == " Inf" @test Printf.@sprintf("% #e", Inf) == " Inf" @test Printf.@sprintf("%07e", Inf) == " Inf" @test Printf.@sprintf("%e", -Inf) == "-Inf" @test Printf.@sprintf("%+e", -Inf) == "-Inf" @test Printf.@sprintf("%07e", -Inf) == " -Inf" @test Printf.@sprintf("%e", NaN) == "NaN" @test Printf.@sprintf("%+e", NaN) == "+NaN" @test Printf.@sprintf("% e", NaN) == " NaN" @test Printf.@sprintf("% #e", NaN) == " NaN" @test Printf.@sprintf("%07e", NaN) == " NaN" @test Printf.@sprintf("%e", Inf) == "Inf" @test Printf.@sprintf("%e", NaN) == "NaN" @test Printf.@sprintf("%.0e", 3.0e142) == "3e+142" @test Printf.@sprintf("%#.0e", 3.0e142) == "3.e+142" @test Printf.@sprintf("%.0e", 2.999999999999999999999999999999999999999999999999999999999999999999999999999996e142) == "3e+142" @test Printf.@sprintf("%#.0e", 2.999999999999999999999999999999999999999999999999999999999999999999999999999996e142) == "3.e+142" @test Printf.@sprintf("%.0e", 3.000000000000000000000000000000000000000000000000000000000000000000000000000024e1042) == "3e+1042" @test Printf.@sprintf("%e", 3.0e42) == "3.000000e+42" @test Printf.@sprintf("%E", 3.0e42) == "3.000000E+42" @test Printf.@sprintf("%e", 3.0e-42) == "3.000000e-42" @test Printf.@sprintf("%E", 3.0e-42) == "3.000000E-42" @test Printf.@sprintf("%e", 1.234) == "1.234000e+00" @test Printf.@sprintf("%E", 1.234) == "1.234000E+00" @test Printf.@sprintf("%+e", 1.234) == "+1.234000e+00" @test Printf.@sprintf("% e", 1.234) == " 1.234000e+00" @test Printf.@sprintf("%e", -1.234) == "-1.234000e+00" @test Printf.@sprintf("%+e", -1.234) == "-1.234000e+00" @test Printf.@sprintf("% e", -1.234) == "-1.234000e+00" @test Printf.@sprintf("%#e", 1.234) == "1.234000e+00" @test Printf.@sprintf("%.2e", 1.234) == "1.23e+00" @test Printf.@sprintf("%.2e", 1.235) == "1.24e+00" @test Printf.@sprintf("%.2e", 0.235) == "2.35e-01" @test Printf.@sprintf("%4.1e", 1.234) == "1.2e+00" @test Printf.@sprintf("%8.1e", 1.234) == " 1.2e+00" @test Printf.@sprintf("%+8.1e", 1.234) == "+1.2e+00" @test Printf.@sprintf("% 8.1e", 1.234) == " 1.2e+00" @test Printf.@sprintf("% 7.1e", 1.234) == " 1.2e+00" @test Printf.@sprintf("% 08.1e", 1.234) == " 1.2e+00" @test Printf.@sprintf("%08.1e", 1.234) == "01.2e+00" @test Printf.@sprintf("%-08.1e", 1.234) == "1.2e+00 " @test Printf.@sprintf("%-8.1e", 1.234) == "1.2e+00 " @test Printf.@sprintf("%-8.1e", 1.234) == "1.2e+00 " @test Printf.@sprintf("%08.1e", -1.234) == "-1.2e+00" @test Printf.@sprintf("%09.1e", -1.234) == "-01.2e+00" @test Printf.@sprintf("%09.1e", 1.234) == "001.2e+00" @test Printf.@sprintf("%+09.1e", 1.234) == "+01.2e+00" @test Printf.@sprintf("% 09.1e", 1.234) == " 01.2e+00" @test Printf.@sprintf("%+ 09.1e", 1.234) == "+01.2e+00" @test Printf.@sprintf("%+ 09.1e", 1.234) == "+01.2e+00" @test Printf.@sprintf("%+ 09.0e", 1.234) == "+0001e+00" @test Printf.@sprintf("%+ #09.0e", 1.234) == "+001.e+00" @test Printf.@sprintf("%+9.1e", 9.96) == " +1.0e+01" @test Printf.@sprintf("% 9.1e", 9.96) == " 1.0e+01" end @testset "strings" begin @test Printf.@sprintf("Hallo heimur") == "Hallo heimur" @test Printf.@sprintf("+%s+", "hello") == "+hello+" @test Printf.@sprintf("%.1s", "foo") == "f" @test Printf.@sprintf("%s", "%%%%") == "%%%%" @test Printf.@sprintf("%s", "Hallo heimur") == "Hallo heimur" @test Printf.@sprintf("%+s", "Hallo heimur") == "Hallo heimur" @test Printf.@sprintf("% s", "Hallo heimur") == "Hallo heimur" @test Printf.@sprintf("%+ s", "Hallo heimur") == "Hallo heimur" @test Printf.@sprintf("%1s", "Hallo heimur") == "Hallo heimur" @test Printf.@sprintf("%20s", "Hallo") == " Hallo" @test Printf.@sprintf("%-20s", "Hallo") == "Hallo " @test Printf.@sprintf("%0-20s", "Hallo") == "Hallo " @test Printf.@sprintf("%.20s", "Hallo heimur") == "Hallo heimur" @test Printf.@sprintf("%20.5s", "Hallo heimur") == " Hallo" @test Printf.@sprintf("%.0s", "Hallo heimur") == "" @test Printf.@sprintf("%20.0s", "Hallo heimur") == " " @test Printf.@sprintf("%.s", "Hallo heimur") == "" @test Printf.@sprintf("%20.s", "Hallo heimur") == " " @test Printf.@sprintf("%s", "test") == "test" @test Printf.@sprintf("%s", "tést") == "tést" @test Printf.@sprintf("ø%sø", "hey") == "øheyø" @test Printf.@sprintf("%4sø", "ø") == " øø" @test Printf.@sprintf("%-4sø", "ø") == "ø ø" @test Printf.@sprintf("%8s", "test") == " test" @test Printf.@sprintf("%-8s", "test") == "test " @test Printf.@sprintf("%s", :test) == "test" @test Printf.@sprintf("%#s", :test) == ":test" @test Printf.@sprintf("%#8s", :test) == " :test" @test Printf.@sprintf("%#-8s", :test) == ":test " @test Printf.@sprintf("%8.3s", "test") == " tes" @test Printf.@sprintf("%#8.3s", "test") == " \"te" @test Printf.@sprintf("%-8.3s", "test") == "tes " @test Printf.@sprintf("%#-8.3s", "test") == "\"te " @test Printf.@sprintf("%.3s", "test") == "tes" @test Printf.@sprintf("%#.3s", "test") == "\"te" @test Printf.@sprintf("%-.3s", "test") == "tes" @test Printf.@sprintf("%#-.3s", "test") == "\"te" @test Printf.@sprintf("%.2s", "föó") == "fö" @test Printf.@sprintf("%5s", "föó") == " föó" @test Printf.@sprintf("%6s", "😍🍕") == " 😍🍕" @test Printf.@sprintf("%2c", '🍕') == "🍕" @test Printf.@sprintf("%3c", '🍕') == " 🍕" end @testset "chars" begin @test Printf.@sprintf("%c", 'a') == "a" @test Printf.@sprintf("%c", 32) == " " @test Printf.@sprintf("%c", 36) == "\$" @test Printf.@sprintf("%3c", 'a') == " a" @test Printf.@sprintf("%c", 'x') == "x" @test Printf.@sprintf("%+c", 'x') == "x" @test Printf.@sprintf("% c", 'x') == "x" @test Printf.@sprintf("%+ c", 'x') == "x" @test Printf.@sprintf("%1c", 'x') == "x" @test Printf.@sprintf("%20c", 'x') == " x" @test Printf.@sprintf("%-20c", 'x') == "x " @test Printf.@sprintf("%-020c", 'x') == "x " @test Printf.@sprintf("%c", 65) == "A" @test Printf.@sprintf("%c", 'A') == "A" @test Printf.@sprintf("%3c", 'A') == " A" @test Printf.@sprintf("%-3c", 'A') == "A " @test Printf.@sprintf("%c", 248) == "ø" @test Printf.@sprintf("%c", 'ø') == "ø" @test Printf.@sprintf("%c", "ø") == "ø" @test Printf.@sprintf("%c", '𐀀') == "𐀀" end function _test_flags(val, vflag::AbstractString, fmt::AbstractString, res::AbstractString, prefix::AbstractString) vflag = string("%", vflag) space_fmt = string(length(res) + length(prefix) + 3, fmt) fsign = string(if val < 0 "-" else "+" end, prefix) nsign = string(if val < 0 "-" else " " end, prefix) osign = if val < 0 string("-", prefix) else string(prefix, "0") end esign = string(if val < 0 "-" else "" end, prefix) esignend = if val < 0 "" else " " end for (flag::AbstractString, ans::AbstractString) = (("", string(" ", nsign, res)), ("+", string(" ", fsign, res)), (" ", string(" ", nsign, res)), ("0", string(osign, "00", res)), ("-", string(esign, res, " ", esignend)), ("0+", string(fsign, "00", res)), ("0 ", string(nsign, "00", res)), ("-+", string(fsign, res, " ")), ("- ", string(nsign, res, " "))) fmt_string = string(vflag, flag, space_fmt) fmtd = Printf.format(Printf.Format(fmt_string), val) @test fmtd == ans end end @testset "basics" begin @test Printf.@sprintf("%%") == "%" @test Printf.@sprintf("1%%") == "1%" @test Printf.@sprintf("%%1") == "%1" @test Printf.@sprintf("1%%2") == "1%2" @test Printf.@sprintf("1%%%d", 2) == "1%2" @test Printf.@sprintf("1%%2%%3") == "1%2%3" @test Printf.@sprintf("GAP[%%]") == "GAP[%]" @test Printf.@sprintf("hey there") == "hey there" @test_throws Printf.InvalidFormatStringError Printf.Format("%+") @test_throws Printf.InvalidFormatStringError Printf.Format("%.") @test_throws Printf.InvalidFormatStringError Printf.Format("%.0") @test isempty((Printf.Format("%%")).formats) @test Printf.@sprintf("%d%d", 1, 2) == "12" @test Printf.@sprintf("%d%d", [1 2]...) == "12" @test Printf.@sprintf("X%d", 2) == "X2" @test Printf.@sprintf("Ð%d", 2) == "Ð2" @test Printf.@sprintf("ༀ%d", 2) == "ༀ2" @test Printf.@sprintf("\U1ffff%d", 2) == "\U0001ffff2" @test Printf.@sprintf("%dX%d", 1, 2) == "1X2" @test Printf.@sprintf("%dÐ%d", 1, 2) == "1Ð2" @test Printf.@sprintf("%dༀ%d", 1, 2) == "1ༀ2" @test Printf.@sprintf("%d\U1ffff%d", 1, 2) == "1\U0001ffff2" @test Printf.@sprintf("%d∃%dȃ", 1, 2) == "1∃2ȃ" @test_throws Printf.InvalidFormatStringError Printf.Format("%y%d") @test_throws Printf.InvalidFormatStringError Printf.Format("%Ð%d") @test_throws Printf.InvalidFormatStringError Printf.Format("%ༀ%d") @test_throws Printf.InvalidFormatStringError Printf.Format("%\U1ffff%d") @test Printf.@sprintf("%10.5d", 4) == " 00004" @test Printf.@sprintf("%d", typemax(Int64)) == "9223372036854775807" for (fmt, val) = (("%7.2f", " 1.23"), ("%-7.2f", "1.23 "), ("%07.2f", "0001.23"), ("%.0f", "1"), ("%#.0f", "1."), ("%.4e", "1.2345e+00"), ("%.4E", "1.2345E+00"), ("%.2a", "0x1.3cp+0"), ("%.2A", "0X1.3CP+0")), num = (1.2345, 1.234499999999999999999999999999999999999999999999999999999999999999999999999991) @test Printf.format(Printf.Format(fmt), num) == val end for (fmt, val) = (("%i", "42"), ("%u", "42"), ("Test: %i", "Test: 42"), ("%#x", "0x2a"), ("%x", "2a"), ("%X", "2A"), ("% i", " 42"), ("%+i", "+42"), ("%4i", " 42"), ("%-4i", "42 "), ("%f", "42.000000"), ("%g", "42"), ("%e", "4.200000e+01")), num = (UInt16(42), UInt32(42), UInt64(42), UInt128(42), Int16(42), Int32(42), Int64(42), Int128(42), 42) @test Printf.format(Printf.Format(fmt), num) == val end for i = ((42, "", "i", "42", ""), (42, "", "d", "42", ""), (42, "", "u", "42", ""), (42, "", "x", "2a", ""), (42, "", "X", "2A", ""), (42, "", "o", "52", ""), (42, "#", "x", "2a", "0x"), (42, "#", "X", "2A", "0X"), (42, "#", "o", "052", ""), (1.2345, "", ".2f", "1.23", ""), (1.2345, "", ".2e", "1.23e+00", ""), (1.2345, "", ".2E", "1.23E+00", ""), (1.2345, "#", ".0f", "1.", ""), (1.2345, "#", ".0e", "1.e+00", ""), (1.2345, "#", ".0E", "1.E+00", ""), (1.2345, "", ".2a", "1.3cp+0", "0x"), (1.2345, "", ".2A", "1.3CP+0", "0X")) _test_flags(i...) _test_flags(-(i[1]), i[2:5]...) end @test Printf.@sprintf("Test: %s%c%C%c%#-.0f.", "t", 65, 66, 67, -42) == "Test: tABC-42.." @test Printf.@sprintf("%f %d %d %f", 1.0, [3 4]..., 5) == "1.000000 3 4 5.000000" @test Printf.@sprintf("%s %f %9.5f %d %d %d %d%d%d%d", [1:6;]..., [7, 8, 9, 10]...) == "1 2.000000 3.00000 4 5 6 78910" @test Printf.@sprintf("%s %s %s %d %d %d %f %f %f", Any[10 ^ x + y for x = 1:3, y = 1:3]...) == "11 101 1001 12 102 1002 13.000000 103.000000 1003.000000" @test Printf.@sprintf("%s %s %s %d %d %d %f %f %f %s %s %s %d %d %d %f %f %f", Any[10x + (x + 1) for x = 1:18]...) == "12 23 34 45 56 67 78.000000 89.000000 100.000000 111 122 133 144 155 166 177.000000 188.000000 199.000000" @test (Printf.@sprintf("%.330f", BigFloat(1)))[var"end"] != '\0' @test Printf.@sprintf("%f", parse(BigFloat, "1e400")) == "10000000000000000000000000000000000000000000000000000000000000000000000000000025262527574416492004687051900140830217136998040684679611623086405387447100385714565637522507383770691831689647535911648520404034824470543643098638520633064715221151920028135130764414460468236314621044034960475540018328999334468948008954289495190631358190153259681118693204411689043999084305348398480210026863210192871358464.000000" @test_throws ArgumentError Printf.@sprintf("%f", parse(BigFloat, "1e99999")) @test Printf.@sprintf("%4.2s", "a") == " a" @test Printf.@sprintf("%12.3e", pi * 1.0e100) == " 3.142e+100" @test string((Printf.Format("%a")).formats[1]) == "%a" @test string((Printf.Format("%a")).formats[1]; modifier = "R") == "%Ra" @test Printf.@sprintf("%d", 3.14) == "3" @test Printf.@sprintf("%2d", 3.14) == " 3" @test Printf.@sprintf("%2d", big(3.14)) == " 3" @test Printf.@sprintf("%s", 1) == "1" @test Printf.@sprintf("%f", 1) == "1.000000" @test Printf.@sprintf("%e", 1) == "1.000000e+00" @test Printf.@sprintf("%g", 1) == "1" @test Printf.@sprintf("%.16g", 194.4778127560983) == "194.4778127560983" @test Printf.@sprintf("%.17g", 194.4778127560983) == "194.4778127560983" @test Printf.@sprintf("%.18g", 194.4778127560983) == "194.477812756098302" @test Printf.@sprintf("%.1g", 1.7976931348623157e308) == "2e+308" @test Printf.@sprintf("%.2g", 1.7976931348623157e308) == "1.8e+308" @test Printf.@sprintf("%.3g", 1.7976931348623157e308) == "1.8e+308" @test_throws ArgumentError @sprintf("%s%%%s", "a") @test @sprintf("%s%%%s", "a", "b") == "a%b" @test @sprintf("%d", 25.5) == "26" @test @sprintf(" %.1e\n", 0.999) == " 1.0e+00\n" @test @sprintf(" %.1f", 9.999) == " 10.0" @test @sprintf("%d", 1.0e100) == "10000000000000000159028911097599180468360808563945281389781327557747838772170381060813469985856815104" @test @sprintf("%d", 3 // 1) == "3" @test @sprintf("%d", Inf) == "Inf" @test @sprintf(" %d", NaN) == " NaN" @test Printf.@sprintf("") == "" @test Printf.format(Printf.Format("")) == "" end @testset "integers" begin @test Printf.@sprintf("% d", 42) == " 42" @test Printf.@sprintf("% d", -42) == "-42" @test Printf.@sprintf("% 5d", 42) == " 42" @test Printf.@sprintf("% 5d", -42) == " -42" @test Printf.@sprintf("% 15d", 42) == " 42" @test Printf.@sprintf("% 15d", -42) == " -42" @test Printf.@sprintf("%+d", 42) == "+42" @test Printf.@sprintf("%+d", -42) == "-42" @test Printf.@sprintf("%+5d", 42) == " +42" @test Printf.@sprintf("%+5d", -42) == " -42" @test Printf.@sprintf("%+15d", 42) == " +42" @test Printf.@sprintf("%+15d", -42) == " -42" @test Printf.@sprintf("%0d", 42) == "42" @test Printf.@sprintf("%0d", -42) == "-42" @test Printf.@sprintf("%05d", 42) == "00042" @test Printf.@sprintf("%05d", -42) == "-0042" @test Printf.@sprintf("%015d", 42) == "000000000000042" @test Printf.@sprintf("%015d", -42) == "-00000000000042" @test Printf.@sprintf("%-d", 42) == "42" @test Printf.@sprintf("%-d", -42) == "-42" @test Printf.@sprintf("%-5d", 42) == "42 " @test Printf.@sprintf("%-5d", -42) == "-42 " @test Printf.@sprintf("%-15d", 42) == "42 " @test Printf.@sprintf("%-15d", -42) == "-42 " @test Printf.@sprintf("%-0d", 42) == "42" @test Printf.@sprintf("%-0d", -42) == "-42" @test Printf.@sprintf("%-05d", 42) == "42 " @test Printf.@sprintf("%-05d", -42) == "-42 " @test Printf.@sprintf("%-015d", 42) == "42 " @test Printf.@sprintf("%-015d", -42) == "-42 " @test Printf.@sprintf("%0-d", 42) == "42" @test Printf.@sprintf("%0-d", -42) == "-42" @test Printf.@sprintf("%0-5d", 42) == "42 " @test Printf.@sprintf("%0-5d", -42) == "-42 " @test Printf.@sprintf("%0-15d", 42) == "42 " @test Printf.@sprintf("%0-15d", -42) == "-42 " @test_throws Printf.InvalidFormatStringError Printf.Format("%d %") @test Printf.@sprintf("%lld", 18446744065119617025) == "18446744065119617025" @test Printf.@sprintf("%+8lld", 100) == " +100" @test Printf.@sprintf("%+.8lld", 100) == "+00000100" @test Printf.@sprintf("%+10.8lld", 100) == " +00000100" @test_throws Printf.InvalidFormatStringError Printf.Format("%_1lld") @test Printf.@sprintf("%-1.5lld", -100) == "-00100" @test Printf.@sprintf("%5lld", 100) == " 100" @test Printf.@sprintf("%5lld", -100) == " -100" @test Printf.@sprintf("%-5lld", 100) == "100 " @test Printf.@sprintf("%-5lld", -100) == "-100 " @test Printf.@sprintf("%-.5lld", 100) == "00100" @test Printf.@sprintf("%-.5lld", -100) == "-00100" @test Printf.@sprintf("%-8.5lld", 100) == "00100 " @test Printf.@sprintf("%-8.5lld", -100) == "-00100 " @test Printf.@sprintf("%05lld", 100) == "00100" @test Printf.@sprintf("%05lld", -100) == "-0100" @test Printf.@sprintf("% lld", 100) == " 100" @test Printf.@sprintf("% lld", -100) == "-100" @test Printf.@sprintf("% 5lld", 100) == " 100" @test Printf.@sprintf("% 5lld", -100) == " -100" @test Printf.@sprintf("% .5lld", 100) == " 00100" @test Printf.@sprintf("% .5lld", -100) == "-00100" @test Printf.@sprintf("% 8.5lld", 100) == " 00100" @test Printf.@sprintf("% 8.5lld", -100) == " -00100" @test Printf.@sprintf("%.0lld", 0) == "0" @test Printf.@sprintf("%#+21.18llx", -100) == "-0x000000000000000064" @test Printf.@sprintf("%#.25llo", -100) == "-00000000000000000000000144" @test Printf.@sprintf("%#+24.20llo", -100) == " -000000000000000000144" @test Printf.@sprintf("%#+18.21llX", -100) == "-0X000000000000000000064" @test Printf.@sprintf("%#+20.24llo", -100) == "-0000000000000000000000144" @test Printf.@sprintf("%#+25.22llu", -1) == " -0000000000000000000001" @test Printf.@sprintf("%#+25.22llu", -1) == " -0000000000000000000001" @test Printf.@sprintf("%#+30.25llu", -1) == " -0000000000000000000000001" @test Printf.@sprintf("%+#25.22lld", -1) == " -0000000000000000000001" @test Printf.@sprintf("%#-8.5llo", 100) == "000144 " @test Printf.@sprintf("%#-+ 08.5lld", 100) == "+00100 " @test Printf.@sprintf("%#-+ 08.5lld", 100) == "+00100 " @test Printf.@sprintf("%.40lld", 1) == "0000000000000000000000000000000000000001" @test Printf.@sprintf("% .40lld", 1) == " 0000000000000000000000000000000000000001" @test Printf.@sprintf("% .40d", 1) == " 0000000000000000000000000000000000000001" @test Printf.@sprintf("%lld", 18446744065119617025) == "18446744065119617025" @test Printf.@sprintf("+%d+", 10) == "+10+" @test Printf.@sprintf("%#012x", 1) == "0x0000000001" @test Printf.@sprintf("%#04.8x", 1) == "0x00000001" @test Printf.@sprintf("%#-08.2x", 1) == "0x01 " @test Printf.@sprintf("%#08o", 1) == "00000001" @test Printf.@sprintf("%d", 1024) == "1024" @test Printf.@sprintf("%d", -1024) == "-1024" @test Printf.@sprintf("%i", 1024) == "1024" @test Printf.@sprintf("%i", -1024) == "-1024" @test Printf.@sprintf("%u", 1024) == "1024" @test Printf.@sprintf("%u", UInt(4294966272)) == "4294966272" @test Printf.@sprintf("%o", 511) == "777" @test Printf.@sprintf("%o", UInt(4294966785)) == "37777777001" @test Printf.@sprintf("%x", 305441741) == "1234abcd" @test Printf.@sprintf("%x", UInt(3989525555)) == "edcb5433" @test Printf.@sprintf("%X", 305441741) == "1234ABCD" @test Printf.@sprintf("%X", UInt(3989525555)) == "EDCB5433" @test Printf.@sprintf("%+d", 1024) == "+1024" @test Printf.@sprintf("%+d", -1024) == "-1024" @test Printf.@sprintf("%+i", 1024) == "+1024" @test Printf.@sprintf("%+i", -1024) == "-1024" @test Printf.@sprintf("%+u", 1024) == "+1024" @test Printf.@sprintf("%+u", UInt(4294966272)) == "+4294966272" @test Printf.@sprintf("%+o", 511) == "+777" @test Printf.@sprintf("%+o", UInt(4294966785)) == "+37777777001" @test Printf.@sprintf("%+x", 305441741) == "+1234abcd" @test Printf.@sprintf("%+x", UInt(3989525555)) == "+edcb5433" @test Printf.@sprintf("%+X", 305441741) == "+1234ABCD" @test Printf.@sprintf("%+X", UInt(3989525555)) == "+EDCB5433" @test Printf.@sprintf("% d", 1024) == " 1024" @test Printf.@sprintf("% d", -1024) == "-1024" @test Printf.@sprintf("% i", 1024) == " 1024" @test Printf.@sprintf("% i", -1024) == "-1024" @test Printf.@sprintf("% u", 1024) == " 1024" @test Printf.@sprintf("% u", UInt(4294966272)) == " 4294966272" @test Printf.@sprintf("% o", 511) == " 777" @test Printf.@sprintf("% o", UInt(4294966785)) == " 37777777001" @test Printf.@sprintf("% x", 305441741) == " 1234abcd" @test Printf.@sprintf("% x", UInt(3989525555)) == " edcb5433" @test Printf.@sprintf("% X", 305441741) == " 1234ABCD" @test Printf.@sprintf("% X", UInt(3989525555)) == " EDCB5433" @test Printf.@sprintf("%+ d", 1024) == "+1024" @test Printf.@sprintf("%+ d", -1024) == "-1024" @test Printf.@sprintf("%+ i", 1024) == "+1024" @test Printf.@sprintf("%+ i", -1024) == "-1024" @test Printf.@sprintf("%+ u", 1024) == "+1024" @test Printf.@sprintf("%+ u", UInt(4294966272)) == "+4294966272" @test Printf.@sprintf("%+ o", 511) == "+777" @test Printf.@sprintf("%+ o", UInt(4294966785)) == "+37777777001" @test Printf.@sprintf("%+ x", 305441741) == "+1234abcd" @test Printf.@sprintf("%+ x", UInt(3989525555)) == "+edcb5433" @test Printf.@sprintf("%+ X", 305441741) == "+1234ABCD" @test Printf.@sprintf("%+ X", UInt(3989525555)) == "+EDCB5433" @test Printf.@sprintf("%#o", 511) == "0777" @test Printf.@sprintf("%#o", UInt(4294966785)) == "037777777001" @test Printf.@sprintf("%#x", 305441741) == "0x1234abcd" @test Printf.@sprintf("%#x", UInt(3989525555)) == "0xedcb5433" @test Printf.@sprintf("%#X", 305441741) == "0X1234ABCD" @test Printf.@sprintf("%#X", UInt(3989525555)) == "0XEDCB5433" @test Printf.@sprintf("%#o", UInt(0)) == "00" @test Printf.@sprintf("%#x", UInt(0)) == "0x0" @test Printf.@sprintf("%#X", UInt(0)) == "0X0" @test Printf.@sprintf("%1d", 1024) == "1024" @test Printf.@sprintf("%1d", -1024) == "-1024" @test Printf.@sprintf("%1i", 1024) == "1024" @test Printf.@sprintf("%1i", -1024) == "-1024" @test Printf.@sprintf("%1u", 1024) == "1024" @test Printf.@sprintf("%1u", UInt(4294966272)) == "4294966272" @test Printf.@sprintf("%1o", 511) == "777" @test Printf.@sprintf("%1o", UInt(4294966785)) == "37777777001" @test Printf.@sprintf("%1x", 305441741) == "1234abcd" @test Printf.@sprintf("%1x", UInt(3989525555)) == "edcb5433" @test Printf.@sprintf("%1X", 305441741) == "1234ABCD" @test Printf.@sprintf("%1X", UInt(3989525555)) == "EDCB5433" @test Printf.@sprintf("%20d", 1024) == " 1024" @test Printf.@sprintf("%20d", -1024) == " -1024" @test Printf.@sprintf("%20i", 1024) == " 1024" @test Printf.@sprintf("%20i", -1024) == " -1024" @test Printf.@sprintf("%20u", 1024) == " 1024" @test Printf.@sprintf("%20u", UInt(4294966272)) == " 4294966272" @test Printf.@sprintf("%20o", 511) == " 777" @test Printf.@sprintf("%20o", UInt(4294966785)) == " 37777777001" @test Printf.@sprintf("%20x", 305441741) == " 1234abcd" @test Printf.@sprintf("%20x", UInt(3989525555)) == " edcb5433" @test Printf.@sprintf("%20X", 305441741) == " 1234ABCD" @test Printf.@sprintf("%20X", UInt(3989525555)) == " EDCB5433" @test Printf.@sprintf("%-20d", 1024) == "1024 " @test Printf.@sprintf("%-20d", -1024) == "-1024 " @test Printf.@sprintf("%-20i", 1024) == "1024 " @test Printf.@sprintf("%-20i", -1024) == "-1024 " @test Printf.@sprintf("%-20u", 1024) == "1024 " @test Printf.@sprintf("%-20u", UInt(4294966272)) == "4294966272 " @test Printf.@sprintf("%-20o", 511) == "777 " @test Printf.@sprintf("%-20o", UInt(4294966785)) == "37777777001 " @test Printf.@sprintf("%-20x", 305441741) == "1234abcd " @test Printf.@sprintf("%-20x", UInt(3989525555)) == "edcb5433 " @test Printf.@sprintf("%-20X", 305441741) == "1234ABCD " @test Printf.@sprintf("%-20X", UInt(3989525555)) == "EDCB5433 " @test Printf.@sprintf("%020d", 1024) == "00000000000000001024" @test Printf.@sprintf("%020d", -1024) == "-0000000000000001024" @test Printf.@sprintf("%020i", 1024) == "00000000000000001024" @test Printf.@sprintf("%020i", -1024) == "-0000000000000001024" @test Printf.@sprintf("%020u", 1024) == "00000000000000001024" @test Printf.@sprintf("%020u", UInt(4294966272)) == "00000000004294966272" @test Printf.@sprintf("%020o", 511) == "00000000000000000777" @test Printf.@sprintf("%020o", UInt(4294966785)) == "00000000037777777001" @test Printf.@sprintf("%020x", 305441741) == "0000000000001234abcd" @test Printf.@sprintf("%020x", UInt(3989525555)) == "000000000000edcb5433" @test Printf.@sprintf("%020X", 305441741) == "0000000000001234ABCD" @test Printf.@sprintf("%020X", UInt(3989525555)) == "000000000000EDCB5433" @test Printf.@sprintf("%#20o", 511) == " 0777" @test Printf.@sprintf("%#20o", UInt(4294966785)) == " 037777777001" @test Printf.@sprintf("%#20x", 305441741) == " 0x1234abcd" @test Printf.@sprintf("%#20x", UInt(3989525555)) == " 0xedcb5433" @test Printf.@sprintf("%#20X", 305441741) == " 0X1234ABCD" @test Printf.@sprintf("%#20X", UInt(3989525555)) == " 0XEDCB5433" @test Printf.@sprintf("%#020o", 511) == "00000000000000000777" @test Printf.@sprintf("%#020o", UInt(4294966785)) == "00000000037777777001" @test Printf.@sprintf("%#020x", 305441741) == "0x00000000001234abcd" @test Printf.@sprintf("%#020x", UInt(3989525555)) == "0x0000000000edcb5433" @test Printf.@sprintf("%#020X", 305441741) == "0X00000000001234ABCD" @test Printf.@sprintf("%#020X", UInt(3989525555)) == "0X0000000000EDCB5433" @test Printf.@sprintf("%0-20d", 1024) == "1024 " @test Printf.@sprintf("%0-20d", -1024) == "-1024 " @test Printf.@sprintf("%0-20i", 1024) == "1024 " @test Printf.@sprintf("%0-20i", -1024) == "-1024 " @test Printf.@sprintf("%0-20u", 1024) == "1024 " @test Printf.@sprintf("%0-20u", UInt(4294966272)) == "4294966272 " @test Printf.@sprintf("%-020o", 511) == "777 " @test Printf.@sprintf("%-020o", UInt(4294966785)) == "37777777001 " @test Printf.@sprintf("%-020x", 305441741) == "1234abcd " @test Printf.@sprintf("%-020x", UInt(3989525555)) == "edcb5433 " @test Printf.@sprintf("%-020X", 305441741) == "1234ABCD " @test Printf.@sprintf("%-020X", UInt(3989525555)) == "EDCB5433 " @test Printf.@sprintf("%.20d", 1024) == "00000000000000001024" @test Printf.@sprintf("%.20d", -1024) == "-00000000000000001024" @test Printf.@sprintf("%.20i", 1024) == "00000000000000001024" @test Printf.@sprintf("%.20i", -1024) == "-00000000000000001024" @test Printf.@sprintf("%.20u", 1024) == "00000000000000001024" @test Printf.@sprintf("%.20u", UInt(4294966272)) == "00000000004294966272" @test Printf.@sprintf("%.20o", 511) == "00000000000000000777" @test Printf.@sprintf("%.20o", UInt(4294966785)) == "00000000037777777001" @test Printf.@sprintf("%.20x", 305441741) == "0000000000001234abcd" @test Printf.@sprintf("%.20x", UInt(3989525555)) == "000000000000edcb5433" @test Printf.@sprintf("%.20X", 305441741) == "0000000000001234ABCD" @test Printf.@sprintf("%.20X", UInt(3989525555)) == "000000000000EDCB5433" @test Printf.@sprintf("%20.5d", 1024) == " 01024" @test Printf.@sprintf("%20.5d", -1024) == " -01024" @test Printf.@sprintf("%20.5i", 1024) == " 01024" @test Printf.@sprintf("%20.5i", -1024) == " -01024" @test Printf.@sprintf("%20.5u", 1024) == " 01024" @test Printf.@sprintf("%20.5u", UInt(4294966272)) == " 4294966272" @test Printf.@sprintf("%20.5o", 511) == " 00777" @test Printf.@sprintf("%20.5o", UInt(4294966785)) == " 37777777001" @test Printf.@sprintf("%20.5x", 305441741) == " 1234abcd" @test Printf.@sprintf("%20.10x", UInt(3989525555)) == " 00edcb5433" @test Printf.@sprintf("%20.5X", 305441741) == " 1234ABCD" @test Printf.@sprintf("%20.10X", UInt(3989525555)) == " 00EDCB5433" @test Printf.@sprintf("%020.5d", 1024) == " 01024" @test Printf.@sprintf("%020.5d", -1024) == " -01024" @test Printf.@sprintf("%020.5i", 1024) == " 01024" @test Printf.@sprintf("%020.5i", -1024) == " -01024" @test Printf.@sprintf("%020.5u", 1024) == " 01024" @test Printf.@sprintf("%020.5u", UInt(4294966272)) == " 4294966272" @test Printf.@sprintf("%020.5o", 511) == " 00777" @test Printf.@sprintf("%020.5o", UInt(4294966785)) == " 37777777001" @test Printf.@sprintf("%020.5x", 305441741) == " 1234abcd" @test Printf.@sprintf("%020.10x", UInt(3989525555)) == " 00edcb5433" @test Printf.@sprintf("%020.5X", 305441741) == " 1234ABCD" @test Printf.@sprintf("%020.10X", UInt(3989525555)) == " 00EDCB5433" @test Printf.@sprintf("%20.0d", 1024) == " 1024" @test Printf.@sprintf("%20.d", -1024) == " -1024" @test Printf.@sprintf("%20.d", 0) == " 0" @test Printf.@sprintf("%20.0i", 1024) == " 1024" @test Printf.@sprintf("%20.i", -1024) == " -1024" @test Printf.@sprintf("%20.i", 0) == " 0" @test Printf.@sprintf("%20.u", 1024) == " 1024" @test Printf.@sprintf("%20.0u", UInt(4294966272)) == " 4294966272" @test Printf.@sprintf("%20.u", UInt(0)) == " 0" @test Printf.@sprintf("%20.o", 511) == " 777" @test Printf.@sprintf("%20.0o", UInt(4294966785)) == " 37777777001" @test Printf.@sprintf("%20.o", UInt(0)) == " 0" @test Printf.@sprintf("%20.x", 305441741) == " 1234abcd" @test Printf.@sprintf("%20.0x", UInt(3989525555)) == " edcb5433" @test Printf.@sprintf("%20.x", UInt(0)) == " 0" @test Printf.@sprintf("%20.X", 305441741) == " 1234ABCD" @test Printf.@sprintf("%20.0X", UInt(3989525555)) == " EDCB5433" @test Printf.@sprintf("%20.X", UInt(0)) == " 0" @test Printf.@sprintf("%4d", typemin(Int8)) == "-128" @test Printf.@sprintf("%4d", typemax(Int8)) == " 127" @test Printf.@sprintf("%6d", typemin(Int16)) == "-32768" @test Printf.@sprintf("%6d", typemax(Int16)) == " 32767" @test Printf.@sprintf("%11d", typemin(Int32)) == "-2147483648" @test Printf.@sprintf("%11d", typemax(Int32)) == " 2147483647" @test Printf.@sprintf("%20d", typemin(Int64)) == "-9223372036854775808" @test Printf.@sprintf("%20d", typemax(Int64)) == " 9223372036854775807" @test Printf.@sprintf("%40d", typemin(Int128)) == "-170141183460469231731687303715884105728" @test Printf.@sprintf("%40d", typemax(Int128)) == " 170141183460469231731687303715884105727" end @testset "%n" begin x = Ref{Int}() @test begin Printf.@sprintf "%d4%n" 123 x x[] == 4 end @test begin Printf.@sprintf "%s%n" "😉" x x[] == 4 end @test begin Printf.@sprintf "%s%n" "1234" x x[] == 4 end end @testset "dynamic" begin @test Printf.@sprintf("%*d", 10, 12) == " 12" @test Printf.@sprintf("%.*d", 4, 12) == "0012" @test Printf.@sprintf("%*.*d", 10, 4, 12) == " 0012" @test Printf.@sprintf("%+*.*d", 10, 4, 12) == " +0012" @test Printf.@sprintf("%0*.*d", 10, 4, 12) == " 0012" @test Printf.@sprintf("%*d%*d%*d", 4, 12, 4, 13, 4, 14) == " 12 13 14" @test Printf.@sprintf("%*d%*d%*d", 4, 12, 5, 13, 6, 14) == " 12 13 14" @test Printf.@sprintf("%*p", 20, 0) == Printf.@sprintf("%20p", 0) @test Printf.@sprintf("%-*p", 20, 0) == Printf.@sprintf("%-20p", 0) @test Printf.@sprintf("%*p", 20, C_NULL) == Printf.@sprintf("%20p", C_NULL) @test Printf.@sprintf("%-*p", 20, C_NULL) == Printf.@sprintf("%-20p", C_NULL) @test Printf.@sprintf("%.*a", 0, 3.14) == Printf.@sprintf("%.0a", 3.14) @test Printf.@sprintf("%.*a", 1, 3.14) == Printf.@sprintf("%.1a", 3.14) @test Printf.@sprintf("%.*a", 2, 3.14) == Printf.@sprintf("%.2a", 3.14) @test Printf.@sprintf("%#.*a", 0, 3.14) == Printf.@sprintf("%#.0a", 3.14) @test Printf.@sprintf("%#.*a", 1, 3.14) == Printf.@sprintf("%#.1a", 3.14) @test Printf.@sprintf("%#.*a", 2, 3.14) == Printf.@sprintf("%#.2a", 3.14) @test Printf.@sprintf("%.*a", 6, 1.5) == Printf.@sprintf("%.6a", 1.5) @test Printf.@sprintf("%*.*g", 10, 5, -123.4) == Printf.@sprintf("%10.5g", -123.4) @test Printf.@sprintf("%0*.*g", 10, 5, -123.4) == Printf.@sprintf("%010.5g", -123.4) @test Printf.@sprintf("%.*g", 6, 1.234e7) == Printf.@sprintf("%.6g", 1.234e7) @test Printf.@sprintf("%#.*g", 6, 1.234e7) == Printf.@sprintf("%#.6g", 1.234e7) @test Printf.@sprintf("%*.*g", 10, 5, -123.4000000000000000000000000000000000000000000000000000000000000000000000000002) == Printf.@sprintf("%10.5g", -123.4000000000000000000000000000000000000000000000000000000000000000000000000002) @test Printf.@sprintf("%0*.*g", 10, 5, -123.4000000000000000000000000000000000000000000000000000000000000000000000000002) == Printf.@sprintf("%010.5g", -123.4000000000000000000000000000000000000000000000000000000000000000000000000002) @test Printf.@sprintf("%.*g", 6, 1.234e7) == Printf.@sprintf("%.6g", 1.234e7) @test Printf.@sprintf("%#.*g", 6, 1.234e7) == Printf.@sprintf("%#.6g", 1.234e7) @test Printf.@sprintf("%.*g", 5, 42) == Printf.@sprintf("%.5g", 42) @test Printf.@sprintf("%#.*g", 2, 42) == Printf.@sprintf("%#.2g", 42) @test Printf.@sprintf("%#.*g", 5, 42) == Printf.@sprintf("%#.5g", 42) @test Printf.@sprintf("%.*g", 15, 0) == Printf.@sprintf("%.15g", 0) @test Printf.@sprintf("%#.*g", 15, 0) == Printf.@sprintf("%#.15g", 0) @test Printf.@sprintf("%.*f", 0, 3.0e142) == Printf.@sprintf("%.0f", 3.0e142) @test Printf.@sprintf("%.*f", 2, 1.234) == Printf.@sprintf("%.2f", 1.234) @test Printf.@sprintf("%.*f", 2, 1.235) == Printf.@sprintf("%.2f", 1.235) @test Printf.@sprintf("%.*f", 2, 0.235) == Printf.@sprintf("%.2f", 0.235) @test Printf.@sprintf("%*.*f", 4, 1, 1.234) == Printf.@sprintf("%4.1f", 1.234) @test Printf.@sprintf("%*.*f", 8, 1, 1.234) == Printf.@sprintf("%8.1f", 1.234) @test Printf.@sprintf("%+*.*f", 8, 1, 1.234) == Printf.@sprintf("%+8.1f", 1.234) @test Printf.@sprintf("% *.*f", 8, 1, 1.234) == Printf.@sprintf("% 8.1f", 1.234) @test Printf.@sprintf("% *.*f", 7, 1, 1.234) == Printf.@sprintf("% 7.1f", 1.234) @test Printf.@sprintf("% 0*.*f", 8, 1, 1.234) == Printf.@sprintf("% 08.1f", 1.234) @test Printf.@sprintf("%0*.*f", 8, 1, 1.234) == Printf.@sprintf("%08.1f", 1.234) @test Printf.@sprintf("%-0*.*f", 8, 1, 1.234) == Printf.@sprintf("%-08.1f", 1.234) @test Printf.@sprintf("%-*.*f", 8, 1, 1.234) == Printf.@sprintf("%-8.1f", 1.234) @test Printf.@sprintf("%0*.*f", 8, 1, -1.234) == Printf.@sprintf("%08.1f", -1.234) @test Printf.@sprintf("%0*.*f", 9, 1, -1.234) == Printf.@sprintf("%09.1f", -1.234) @test Printf.@sprintf("%0*.*f", 9, 1, 1.234) == Printf.@sprintf("%09.1f", 1.234) @test Printf.@sprintf("%+0*.*f", 9, 1, 1.234) == Printf.@sprintf("%+09.1f", 1.234) @test Printf.@sprintf("% 0*.*f", 9, 1, 1.234) == Printf.@sprintf("% 09.1f", 1.234) @test Printf.@sprintf("%+ 0*.*f", 9, 1, 1.234) == Printf.@sprintf("%+ 09.1f", 1.234) @test Printf.@sprintf("%+ 0*.*f", 9, 1, 1.234) == Printf.@sprintf("%+ 09.1f", 1.234) @test Printf.@sprintf("%+ 0*.*f", 9, 0, 1.234) == Printf.@sprintf("%+ 09.0f", 1.234) @test Printf.@sprintf("%+ #0*.*f", 9, 0, 1.234) == Printf.@sprintf("%+ #09.0f", 1.234) @test Printf.@sprintf("%*.*e", 10, 4, Inf) == Printf.@sprintf("%10.4e", Inf) @test Printf.@sprintf("%*.*e", 10, 4, NaN) == Printf.@sprintf("%10.4e", NaN) @test Printf.@sprintf("%*.*e", 10, 4, Inf) == Printf.@sprintf("%10.4e", Inf) @test Printf.@sprintf("%*.*e", 10, 4, NaN) == Printf.@sprintf("%10.4e", NaN) @test Printf.@sprintf("%.*e", 0, 3.0e142) == Printf.@sprintf("%.0e", 3.0e142) @test Printf.@sprintf("%#.*e", 0, 3.0e142) == Printf.@sprintf("%#.0e", 3.0e142) @test Printf.@sprintf("%.*e", 0, 2.999999999999999999999999999999999999999999999999999999999999999999999999999996e142) == Printf.@sprintf("%.0e", 2.999999999999999999999999999999999999999999999999999999999999999999999999999996e142) @test Printf.@sprintf("%#.*e", 0, 2.999999999999999999999999999999999999999999999999999999999999999999999999999996e142) == Printf.@sprintf("%#.0e", 2.999999999999999999999999999999999999999999999999999999999999999999999999999996e142) @test Printf.@sprintf("%.*e", 0, 3.000000000000000000000000000000000000000000000000000000000000000000000000000024e1042) == Printf.@sprintf("%.0e", 3.000000000000000000000000000000000000000000000000000000000000000000000000000024e1042) @test Printf.@sprintf("%.*e", 2, 1.234) == Printf.@sprintf("%.2e", 1.234) @test Printf.@sprintf("%.*e", 2, 1.235) == Printf.@sprintf("%.2e", 1.235) @test Printf.@sprintf("%.*e", 2, 0.235) == Printf.@sprintf("%.2e", 0.235) @test Printf.@sprintf("%*.*e", 4, 1, 1.234) == Printf.@sprintf("%4.1e", 1.234) @test Printf.@sprintf("%*.*e", 8, 1, 1.234) == Printf.@sprintf("%8.1e", 1.234) @test Printf.@sprintf("%+*.*e", 8, 1, 1.234) == Printf.@sprintf("%+8.1e", 1.234) @test Printf.@sprintf("% *.*e", 8, 1, 1.234) == Printf.@sprintf("% 8.1e", 1.234) @test Printf.@sprintf("% *.*e", 7, 1, 1.234) == Printf.@sprintf("% 7.1e", 1.234) @test Printf.@sprintf("% 0*.*e", 8, 1, 1.234) == Printf.@sprintf("% 08.1e", 1.234) @test Printf.@sprintf("%0*.*e", 8, 1, 1.234) == Printf.@sprintf("%08.1e", 1.234) @test Printf.@sprintf("%-0*.*e", 8, 1, 1.234) == Printf.@sprintf("%-08.1e", 1.234) @test Printf.@sprintf("%-*.*e", 8, 1, 1.234) == Printf.@sprintf("%-8.1e", 1.234) @test Printf.@sprintf("%-*.*e", 8, 1, 1.234) == Printf.@sprintf("%-8.1e", 1.234) @test Printf.@sprintf("%0*.*e", 8, 1, -1.234) == Printf.@sprintf("%08.1e", -1.234) @test Printf.@sprintf("%0*.*e", 9, 1, -1.234) == Printf.@sprintf("%09.1e", -1.234) @test Printf.@sprintf("%0*.*e", 9, 1, 1.234) == Printf.@sprintf("%09.1e", 1.234) @test Printf.@sprintf("%+0*.*e", 9, 1, 1.234) == Printf.@sprintf("%+09.1e", 1.234) @test Printf.@sprintf("% 0*.*e", 9, 1, 1.234) == Printf.@sprintf("% 09.1e", 1.234) @test Printf.@sprintf("%+ 0*.*e", 9, 1, 1.234) == Printf.@sprintf("%+ 09.1e", 1.234) @test Printf.@sprintf("%+ 0*.*e", 9, 1, 1.234) == Printf.@sprintf("%+ 09.1e", 1.234) @test Printf.@sprintf("%+ 0*.*e", 9, 0, 1.234) == Printf.@sprintf("%+ 09.0e", 1.234) @test Printf.@sprintf("%+ #0*.*e", 9, 0, 1.234) == Printf.@sprintf("%+ #09.0e", 1.234) @test Printf.@sprintf("%.*s", 1, "foo") == Printf.@sprintf("%.1s", "foo") @test Printf.@sprintf("%*s", 1, "Hallo heimur") == Printf.@sprintf("%1s", "Hallo heimur") @test Printf.@sprintf("%*s", 20, "Hallo") == Printf.@sprintf("%20s", "Hallo") @test Printf.@sprintf("%-*s", 20, "Hallo") == Printf.@sprintf("%-20s", "Hallo") @test Printf.@sprintf("%0-*s", 20, "Hallo") == Printf.@sprintf("%0-20s", "Hallo") @test Printf.@sprintf("%.*s", 20, "Hallo heimur") == Printf.@sprintf("%.20s", "Hallo heimur") @test Printf.@sprintf("%*.*s", 20, 5, "Hallo heimur") == Printf.@sprintf("%20.5s", "Hallo heimur") @test Printf.@sprintf("%.*s", 0, "Hallo heimur") == Printf.@sprintf("%.0s", "Hallo heimur") @test Printf.@sprintf("%*.*s", 20, 0, "Hallo heimur") == Printf.@sprintf("%20.0s", "Hallo heimur") @test Printf.@sprintf("%.s", "Hallo heimur") == Printf.@sprintf("%.s", "Hallo heimur") @test Printf.@sprintf("%*.s", 20, "Hallo heimur") == Printf.@sprintf("%20.s", "Hallo heimur") @test Printf.@sprintf("%*sø", 4, "ø") == Printf.@sprintf("%4sø", "ø") @test Printf.@sprintf("%-*sø", 4, "ø") == Printf.@sprintf("%-4sø", "ø") @test Printf.@sprintf("%*s", 8, "test") == Printf.@sprintf("%8s", "test") @test Printf.@sprintf("%-*s", 8, "test") == Printf.@sprintf("%-8s", "test") @test Printf.@sprintf("%#*s", 8, :test) == Printf.@sprintf("%#8s", :test) @test Printf.@sprintf("%#-*s", 8, :test) == Printf.@sprintf("%#-8s", :test) @test Printf.@sprintf("%*.*s", 8, 3, "test") == Printf.@sprintf("%8.3s", "test") @test Printf.@sprintf("%#*.*s", 8, 3, "test") == Printf.@sprintf("%#8.3s", "test") @test Printf.@sprintf("%-*.*s", 8, 3, "test") == Printf.@sprintf("%-8.3s", "test") @test Printf.@sprintf("%#-*.*s", 8, 3, "test") == Printf.@sprintf("%#-8.3s", "test") @test Printf.@sprintf("%.*s", 3, "test") == Printf.@sprintf("%.3s", "test") @test Printf.@sprintf("%#.*s", 3, "test") == Printf.@sprintf("%#.3s", "test") @test Printf.@sprintf("%-.*s", 3, "test") == Printf.@sprintf("%-.3s", "test") @test Printf.@sprintf("%#-.*s", 3, "test") == Printf.@sprintf("%#-.3s", "test") @test Printf.@sprintf("%*c", 3, 'a') == Printf.@sprintf("%3c", 'a') @test Printf.@sprintf("%*c", 1, 'x') == Printf.@sprintf("%1c", 'x') @test Printf.@sprintf("%*c", 20, 'x') == Printf.@sprintf("%20c", 'x') @test Printf.@sprintf("%-*c", 20, 'x') == Printf.@sprintf("%-20c", 'x') @test Printf.@sprintf("%-0*c", 20, 'x') == Printf.@sprintf("%-020c", 'x') @test Printf.@sprintf("%*c", 3, 'A') == Printf.@sprintf("%3c", 'A') @test Printf.@sprintf("%-*c", 3, 'A') == Printf.@sprintf("%-3c", 'A') @test Printf.@sprintf("%*.*f %*.*f %*.*f %*.*f %*.*f %*.*f %*.*f %*.*f %*.*f %*.*f %*.*f %*.*f %*.*f %*.*f %*.*f %*.*f %*.*f %*.*f", 4, 2, 1.2345, 4, 2, 1.2345, 4, 2, 1.2345, 4, 2, 1.2345, 4, 2, 1.2345, 4, 2, 1.2345, 4, 2, 1.2345, 4, 2, 1.2345, 4, 2, 1.2345, 4, 2, 1.2345, 4, 2, 1.2345, 4, 2, 1.2345, 4, 2, 1.2345, 4, 2, 1.2345, 4, 2, 1.2345, 4, 2, 1.2345, 4, 2, 1.2345, 4, 2, 1.2345) == Printf.@sprintf("%4.2f %4.2f %4.2f %4.2f %4.2f %4.2f %4.2f %4.2f %4.2f %4.2f %4.2f %4.2f %4.2f %4.2f %4.2f %4.2f %4.2f %4.2f", 1.2345, 1.2345, 1.2345, 1.2345, 1.2345, 1.2345, 1.2345, 1.2345, 1.2345, 1.2345, 1.2345, 1.2345, 1.2345, 1.2345, 1.2345, 1.2345, 1.2345, 1.2345) @test (Printf.@sprintf("%.*f", 330, BigFloat(1)))[var"end"] != '\0' @test Printf.@sprintf("%*.*s", 4, 2, "a") == Printf.@sprintf("%4.2s", "a") @test Printf.@sprintf("%*.*e", 12, 3, pi * 1.0e100) == Printf.@sprintf("%12.3e", pi * 1.0e100) @test Printf.@sprintf("%*d", 2, 3.14) == Printf.@sprintf("%*d", 2, 3.14) @test Printf.@sprintf("%*d", 2, big(3.14)) == Printf.@sprintf("%*d", 2, big(3.14)) @test Printf.@sprintf(" %.*e\n", 1, 0.999) == Printf.@sprintf(" %.1e\n", 0.999) @test Printf.@sprintf(" %.*f", 1, 9.999) == Printf.@sprintf(" %.1f", 9.999) @test Printf.@sprintf("%*d", 10, 12) == Printf.@sprintf("%10d", 12) @test Printf.@sprintf("%.*d", 4, 12) == Printf.@sprintf("%.4d", 12) @test Printf.@sprintf("%*.*d", 10, 4, 12) == Printf.@sprintf("%10.4d", 12) @test Printf.@sprintf("%+*.*d", 10, 4, 12) == Printf.@sprintf("%+10.4d", 12) @test Printf.@sprintf("%0*.*d", 10, 4, 12) == Printf.@sprintf("%010.4d", 12) @test Printf.@sprintf("% *d", 5, 42) == Printf.@sprintf("% 5d", 42) @test Printf.@sprintf("% *d", 5, -42) == Printf.@sprintf("% 5d", -42) @test Printf.@sprintf("% *d", 15, 42) == Printf.@sprintf("% 15d", 42) @test Printf.@sprintf("% *d", 15, -42) == Printf.@sprintf("% 15d", -42) @test Printf.@sprintf("%+*d", 5, 42) == Printf.@sprintf("%+5d", 42) @test Printf.@sprintf("%+*d", 5, -42) == Printf.@sprintf("%+5d", -42) @test Printf.@sprintf("%+*d", 15, 42) == Printf.@sprintf("%+15d", 42) @test Printf.@sprintf("%+*d", 15, -42) == Printf.@sprintf("%+15d", -42) @test Printf.@sprintf("%*d", 0, 42) == Printf.@sprintf("%0d", 42) @test Printf.@sprintf("%*d", 0, -42) == Printf.@sprintf("%0d", -42) @test Printf.@sprintf("%-*d", 5, 42) == Printf.@sprintf("%-5d", 42) @test Printf.@sprintf("%-*d", 5, -42) == Printf.@sprintf("%-5d", -42) @test Printf.@sprintf("%-*d", 15, 42) == Printf.@sprintf("%-15d", 42) @test Printf.@sprintf("%-*d", 15, -42) == Printf.@sprintf("%-15d", -42) @test Printf.@sprintf("%+*lld", 8, 100) == Printf.@sprintf("%+8lld", 100) @test Printf.@sprintf("%+.*lld", 8, 100) == Printf.@sprintf("%+.8lld", 100) @test Printf.@sprintf("%+*.*lld", 10, 8, 100) == Printf.@sprintf("%+10.8lld", 100) @test Printf.@sprintf("%-*.*lld", 1, 5, -100) == Printf.@sprintf("%-1.5lld", -100) @test Printf.@sprintf("%*lld", 5, 100) == Printf.@sprintf("%5lld", 100) @test Printf.@sprintf("%*lld", 5, -100) == Printf.@sprintf("%5lld", -100) @test Printf.@sprintf("%-*lld", 5, 100) == Printf.@sprintf("%-5lld", 100) @test Printf.@sprintf("%-*lld", 5, -100) == Printf.@sprintf("%-5lld", -100) @test Printf.@sprintf("%-.*lld", 5, 100) == Printf.@sprintf("%-.5lld", 100) @test Printf.@sprintf("%-.*lld", 5, -100) == Printf.@sprintf("%-.5lld", -100) @test Printf.@sprintf("%-*.*lld", 8, 5, 100) == Printf.@sprintf("%-8.5lld", 100) @test Printf.@sprintf("%-*.*lld", 8, 5, -100) == Printf.@sprintf("%-8.5lld", -100) @test Printf.@sprintf("%0*lld", 5, 100) == Printf.@sprintf("%05lld", 100) @test Printf.@sprintf("%0*lld", 5, -100) == Printf.@sprintf("%05lld", -100) @test Printf.@sprintf("% *lld", 5, 100) == Printf.@sprintf("% 5lld", 100) @test Printf.@sprintf("% *lld", 5, -100) == Printf.@sprintf("% 5lld", -100) @test Printf.@sprintf("% .*lld", 5, 100) == Printf.@sprintf("% .5lld", 100) @test Printf.@sprintf("% .*lld", 5, -100) == Printf.@sprintf("% .5lld", -100) @test Printf.@sprintf("% *.*lld", 8, 5, 100) == Printf.@sprintf("% 8.5lld", 100) @test Printf.@sprintf("% *.*lld", 8, 5, -100) == Printf.@sprintf("% 8.5lld", -100) @test Printf.@sprintf("%.*lld", 0, 0) == Printf.@sprintf("%.0lld", 0) @test Printf.@sprintf("%#+*.*llx", 21, 18, -100) == Printf.@sprintf("%#+21.18llx", -100) @test Printf.@sprintf("%#.*llo", 25, -100) == Printf.@sprintf("%#.25llo", -100) @test Printf.@sprintf("%#+*.*llo", 24, 20, -100) == Printf.@sprintf("%#+24.20llo", -100) @test Printf.@sprintf("%#+*.*llX", 18, 21, -100) == Printf.@sprintf("%#+18.21llX", -100) @test Printf.@sprintf("%#+*.*llo", 20, 24, -100) == Printf.@sprintf("%#+20.24llo", -100) @test Printf.@sprintf("%#+*.*llu", 25, 22, -1) == Printf.@sprintf("%#+25.22llu", -1) @test Printf.@sprintf("%#+*.*llu", 30, 25, -1) == Printf.@sprintf("%#+30.25llu", -1) @test Printf.@sprintf("%+#*.*lld", 25, 22, -1) == Printf.@sprintf("%+#25.22lld", -1) @test Printf.@sprintf("%#-*.*llo", 8, 5, 100) == Printf.@sprintf("%#-8.5llo", 100) @test Printf.@sprintf("%#-+ 0*.*lld", 8, 5, 100) == Printf.@sprintf("%#-+ 08.5lld", 100) @test Printf.@sprintf("%#-+ 0*.*lld", 8, 5, 100) == Printf.@sprintf("%#-+ 08.5lld", 100) @test Printf.@sprintf("%.*lld", 40, 1) == Printf.@sprintf("%.40lld", 1) @test Printf.@sprintf("% .*lld", 40, 1) == Printf.@sprintf("% .40lld", 1) @test Printf.@sprintf("% .*d", 40, 1) == Printf.@sprintf("% .40d", 1) @test Printf.@sprintf("%#0*x", 12, 1) == Printf.@sprintf("%#012x", 1) @test Printf.@sprintf("%#0*.*x", 4, 8, 1) == Printf.@sprintf("%#04.8x", 1) @test Printf.@sprintf("%#-0*.*x", 8, 2, 1) == Printf.@sprintf("%#-08.2x", 1) @test Printf.@sprintf("%#0*o", 8, 1) == Printf.@sprintf("%#08o", 1) @test Printf.@sprintf("%*d", 20, 1024) == Printf.@sprintf("%20d", 1024) @test Printf.@sprintf("%*d", 20, -1024) == Printf.@sprintf("%20d", -1024) @test Printf.@sprintf("%*i", 20, 1024) == Printf.@sprintf("%20i", 1024) @test Printf.@sprintf("%*i", 20, -1024) == Printf.@sprintf("%20i", -1024) @test Printf.@sprintf("%*u", 20, 1024) == Printf.@sprintf("%20u", 1024) @test Printf.@sprintf("%*u", 20, UInt(4294966272)) == Printf.@sprintf("%20u", UInt(4294966272)) @test Printf.@sprintf("%*o", 20, 511) == Printf.@sprintf("%20o", 511) @test Printf.@sprintf("%*o", 20, UInt(4294966785)) == Printf.@sprintf("%20o", UInt(4294966785)) @test Printf.@sprintf("%*x", 20, 305441741) == Printf.@sprintf("%20x", 305441741) @test Printf.@sprintf("%*x", 20, UInt(3989525555)) == Printf.@sprintf("%20x", UInt(3989525555)) @test Printf.@sprintf("%*X", 20, 305441741) == Printf.@sprintf("%20X", 305441741) @test Printf.@sprintf("%*X", 20, UInt(3989525555)) == Printf.@sprintf("%20X", UInt(3989525555)) @test Printf.@sprintf("%-*d", 20, 1024) == Printf.@sprintf("%-20d", 1024) @test Printf.@sprintf("%-*d", 20, -1024) == Printf.@sprintf("%-20d", -1024) @test Printf.@sprintf("%-*i", 20, 1024) == Printf.@sprintf("%-20i", 1024) @test Printf.@sprintf("%-*i", 20, -1024) == Printf.@sprintf("%-20i", -1024) @test Printf.@sprintf("%-*u", 20, 1024) == Printf.@sprintf("%-20u", 1024) @test Printf.@sprintf("%-*u", 20, UInt(4294966272)) == Printf.@sprintf("%-20u", UInt(4294966272)) @test Printf.@sprintf("%-*o", 20, 511) == Printf.@sprintf("%-20o", 511) @test Printf.@sprintf("%-*o", 20, UInt(4294966785)) == Printf.@sprintf("%-20o", UInt(4294966785)) @test Printf.@sprintf("%-*x", 20, 305441741) == Printf.@sprintf("%-20x", 305441741) @test Printf.@sprintf("%-*x", 20, UInt(3989525555)) == Printf.@sprintf("%-20x", UInt(3989525555)) @test Printf.@sprintf("%-*X", 20, 305441741) == Printf.@sprintf("%-20X", 305441741) @test Printf.@sprintf("%-*X", 20, UInt(3989525555)) == Printf.@sprintf("%-20X", UInt(3989525555)) @test Printf.@sprintf("%0*d", 20, 1024) == Printf.@sprintf("%020d", 1024) @test Printf.@sprintf("%0*d", 20, -1024) == Printf.@sprintf("%020d", -1024) @test Printf.@sprintf("%0*i", 20, 1024) == Printf.@sprintf("%020i", 1024) @test Printf.@sprintf("%0*i", 20, -1024) == Printf.@sprintf("%020i", -1024) @test Printf.@sprintf("%0*u", 20, 1024) == Printf.@sprintf("%020u", 1024) @test Printf.@sprintf("%0*u", 20, UInt(4294966272)) == Printf.@sprintf("%020u", UInt(4294966272)) @test Printf.@sprintf("%0*o", 20, 511) == Printf.@sprintf("%020o", 511) @test Printf.@sprintf("%0*o", 20, UInt(4294966785)) == Printf.@sprintf("%020o", UInt(4294966785)) @test Printf.@sprintf("%0*x", 20, 305441741) == Printf.@sprintf("%020x", 305441741) @test Printf.@sprintf("%0*x", 20, UInt(3989525555)) == Printf.@sprintf("%020x", UInt(3989525555)) @test Printf.@sprintf("%0*X", 20, 305441741) == Printf.@sprintf("%020X", 305441741) @test Printf.@sprintf("%0*X", 20, UInt(3989525555)) == Printf.@sprintf("%020X", UInt(3989525555)) @test Printf.@sprintf("%#*o", 20, 511) == Printf.@sprintf("%#20o", 511) @test Printf.@sprintf("%#*o", 20, UInt(4294966785)) == Printf.@sprintf("%#20o", UInt(4294966785)) @test Printf.@sprintf("%#*x", 20, 305441741) == Printf.@sprintf("%#20x", 305441741) @test Printf.@sprintf("%#*x", 20, UInt(3989525555)) == Printf.@sprintf("%#20x", UInt(3989525555)) @test Printf.@sprintf("%#*X", 20, 305441741) == Printf.@sprintf("%#20X", 305441741) @test Printf.@sprintf("%#*X", 20, UInt(3989525555)) == Printf.@sprintf("%#20X", UInt(3989525555)) @test Printf.@sprintf("%#0*o", 20, 511) == Printf.@sprintf("%#020o", 511) @test Printf.@sprintf("%#0*o", 20, UInt(4294966785)) == Printf.@sprintf("%#020o", UInt(4294966785)) @test Printf.@sprintf("%#0*x", 20, 305441741) == Printf.@sprintf("%#020x", 305441741) @test Printf.@sprintf("%#0*x", 20, UInt(3989525555)) == Printf.@sprintf("%#020x", UInt(3989525555)) @test Printf.@sprintf("%#0*X", 20, 305441741) == Printf.@sprintf("%#020X", 305441741) @test Printf.@sprintf("%#0*X", 20, UInt(3989525555)) == Printf.@sprintf("%#020X", UInt(3989525555)) @test Printf.@sprintf("%0-*d", 20, 1024) == Printf.@sprintf("%0-20d", 1024) @test Printf.@sprintf("%0-*d", 20, -1024) == Printf.@sprintf("%0-20d", -1024) @test Printf.@sprintf("%0-*i", 20, 1024) == Printf.@sprintf("%0-20i", 1024) @test Printf.@sprintf("%0-*i", 20, -1024) == Printf.@sprintf("%0-20i", -1024) @test Printf.@sprintf("%0-*u", 20, 1024) == Printf.@sprintf("%0-20u", 1024) @test Printf.@sprintf("%0-*u", 20, UInt(4294966272)) == Printf.@sprintf("%0-20u", UInt(4294966272)) @test Printf.@sprintf("%-0*o", 20, 511) == Printf.@sprintf("%-020o", 511) @test Printf.@sprintf("%-0*o", 20, UInt(4294966785)) == Printf.@sprintf("%-020o", UInt(4294966785)) @test Printf.@sprintf("%-0*x", 20, 305441741) == Printf.@sprintf("%-020x", 305441741) @test Printf.@sprintf("%-0*x", 20, UInt(3989525555)) == Printf.@sprintf("%-020x", UInt(3989525555)) @test Printf.@sprintf("%-0*X", 20, 305441741) == Printf.@sprintf("%-020X", 305441741) @test Printf.@sprintf("%-0*X", 20, UInt(3989525555)) == Printf.@sprintf("%-020X", UInt(3989525555)) @test Printf.@sprintf("%.*d", 20, 1024) == Printf.@sprintf("%.20d", 1024) @test Printf.@sprintf("%.*d", 20, -1024) == Printf.@sprintf("%.20d", -1024) @test Printf.@sprintf("%.*i", 20, 1024) == Printf.@sprintf("%.20i", 1024) @test Printf.@sprintf("%.*i", 20, -1024) == Printf.@sprintf("%.20i", -1024) @test Printf.@sprintf("%.*u", 20, 1024) == Printf.@sprintf("%.20u", 1024) @test Printf.@sprintf("%.*u", 20, UInt(4294966272)) == Printf.@sprintf("%.20u", UInt(4294966272)) @test Printf.@sprintf("%.*o", 20, 511) == Printf.@sprintf("%.20o", 511) @test Printf.@sprintf("%.*o", 20, UInt(4294966785)) == Printf.@sprintf("%.20o", UInt(4294966785)) @test Printf.@sprintf("%.*x", 20, 305441741) == Printf.@sprintf("%.20x", 305441741) @test Printf.@sprintf("%.*x", 20, UInt(3989525555)) == Printf.@sprintf("%.20x", UInt(3989525555)) @test Printf.@sprintf("%.*X", 20, 305441741) == Printf.@sprintf("%.20X", 305441741) @test Printf.@sprintf("%.*X", 20, UInt(3989525555)) == Printf.@sprintf("%.20X", UInt(3989525555)) @test Printf.@sprintf("%*.*d", 20, 5, 1024) == Printf.@sprintf("%20.5d", 1024) @test Printf.@sprintf("%*.*d", 20, 5, -1024) == Printf.@sprintf("%20.5d", -1024) @test Printf.@sprintf("%*.*i", 20, 5, 1024) == Printf.@sprintf("%20.5i", 1024) @test Printf.@sprintf("%*.*i", 20, 5, -1024) == Printf.@sprintf("%20.5i", -1024) @test Printf.@sprintf("%*.*u", 20, 5, 1024) == Printf.@sprintf("%20.5u", 1024) @test Printf.@sprintf("%*.*u", 20, 5, UInt(4294966272)) == Printf.@sprintf("%20.5u", UInt(4294966272)) @test Printf.@sprintf("%*.*o", 20, 5, 511) == Printf.@sprintf("%20.5o", 511) @test Printf.@sprintf("%*.*o", 20, 5, UInt(4294966785)) == Printf.@sprintf("%20.5o", UInt(4294966785)) @test Printf.@sprintf("%*.*x", 20, 5, 305441741) == Printf.@sprintf("%20.5x", 305441741) @test Printf.@sprintf("%*.*x", 20, 10, UInt(3989525555)) == Printf.@sprintf("%20.10x", UInt(3989525555)) @test Printf.@sprintf("%*.*X", 20, 5, 305441741) == Printf.@sprintf("%20.5X", 305441741) @test Printf.@sprintf("%*.*X", 20, 10, UInt(3989525555)) == Printf.@sprintf("%20.10X", UInt(3989525555)) @test Printf.@sprintf("%0*.*d", 20, 5, 1024) == Printf.@sprintf("%020.5d", 1024) @test Printf.@sprintf("%0*.*d", 20, 5, -1024) == Printf.@sprintf("%020.5d", -1024) @test Printf.@sprintf("%0*.*i", 20, 5, 1024) == Printf.@sprintf("%020.5i", 1024) @test Printf.@sprintf("%0*.*i", 20, 5, -1024) == Printf.@sprintf("%020.5i", -1024) @test Printf.@sprintf("%0*.*u", 20, 5, 1024) == Printf.@sprintf("%020.5u", 1024) @test Printf.@sprintf("%0*.*u", 20, 5, UInt(4294966272)) == Printf.@sprintf("%020.5u", UInt(4294966272)) @test Printf.@sprintf("%0*.*o", 20, 5, 511) == Printf.@sprintf("%020.5o", 511) @test Printf.@sprintf("%0*.*o", 20, 5, UInt(4294966785)) == Printf.@sprintf("%020.5o", UInt(4294966785)) @test Printf.@sprintf("%0*.*x", 20, 5, 305441741) == Printf.@sprintf("%020.5x", 305441741) @test Printf.@sprintf("%0*.*x", 20, 10, UInt(3989525555)) == Printf.@sprintf("%020.10x", UInt(3989525555)) @test Printf.@sprintf("%0*.*X", 20, 5, 305441741) == Printf.@sprintf("%020.5X", 305441741) @test Printf.@sprintf("%0*.*X", 20, 10, UInt(3989525555)) == Printf.@sprintf("%020.10X", UInt(3989525555)) @test Printf.@sprintf("%*.0d", 20, 1024) == Printf.@sprintf("%20.0d", 1024) @test Printf.@sprintf("%*.d", 20, -1024) == Printf.@sprintf("%20.d", -1024) @test Printf.@sprintf("%*.d", 20, 0) == Printf.@sprintf("%20.d", 0) @test Printf.@sprintf("%*.0i", 20, 1024) == Printf.@sprintf("%20.0i", 1024) @test Printf.@sprintf("%*.i", 20, -1024) == Printf.@sprintf("%20.i", -1024) @test Printf.@sprintf("%*.i", 20, 0) == Printf.@sprintf("%20.i", 0) @test Printf.@sprintf("%*.u", 20, 1024) == Printf.@sprintf("%20.u", 1024) @test Printf.@sprintf("%*.0u", 20, UInt(4294966272)) == Printf.@sprintf("%20.0u", UInt(4294966272)) @test Printf.@sprintf("%*.u", 20, UInt(0)) == Printf.@sprintf("%20.u", UInt(0)) @test Printf.@sprintf("%*.o", 20, 511) == Printf.@sprintf("%20.o", 511) @test Printf.@sprintf("%*.0o", 20, UInt(4294966785)) == Printf.@sprintf("%20.0o", UInt(4294966785)) @test Printf.@sprintf("%*.o", 20, UInt(0)) == Printf.@sprintf("%20.o", UInt(0)) @test Printf.@sprintf("%*.x", 20, 305441741) == Printf.@sprintf("%20.x", 305441741) @test Printf.@sprintf("%*.0x", 20, UInt(3989525555)) == Printf.@sprintf("%20.0x", UInt(3989525555)) @test Printf.@sprintf("%*.x", 20, UInt(0)) == Printf.@sprintf("%20.x", UInt(0)) @test Printf.@sprintf("%*.X", 20, 305441741) == Printf.@sprintf("%20.X", 305441741) @test Printf.@sprintf("%*.0X", 20, UInt(3989525555)) == Printf.@sprintf("%20.0X", UInt(3989525555)) @test Printf.@sprintf("%*.X", 20, UInt(0)) == Printf.@sprintf("%20.X", UInt(0)) x = Ref{Int}() y = Ref{Int}() @test begin Printf.@sprintf "%10s%n" "😉" x Printf.@sprintf "%*s%n" 10 "😉" y x[] == y[] end @test begin Printf.@sprintf "%10s%n" "1234" x Printf.@sprintf "%*s%n" 10 "1234" y x[] == y[] end end @testset "length modifiers" begin @test_throws Printf.InvalidFormatStringError Printf.Format("%h") @test_throws Printf.InvalidFormatStringError Printf.Format("%hh") @test_throws Printf.InvalidFormatStringError Printf.Format("%z") end @testset "Docstrings" begin @test isempty(Docs.undocumented_names(Printf)) end @test @sprintf("%.160g", 1.38e-23) == "1.380000000000000060010582465734078799297660966782642624395399644741944111814291318296454846858978271484375e-23" end begin @testset "%p" begin if Sys.WORD_SIZE == 64 @test Printf.@sprintf("%20p", 0) == " 0x0000000000000000" @test Printf.@sprintf("%-20p", 0) == "0x0000000000000000 " @test Printf.@sprintf("%20p", C_NULL) == " 0x0000000000000000" @test @sprintf("%-20p", C_NULL) == "0x0000000000000000 " elseif Sys.WORD_SIZE == 32 @test Printf.@sprintf("%20p", 0) == " 0x00000000" @test Printf.@sprintf("%-20p", 0) == "0x00000000 " @test @sprintf("%20p", C_NULL) == " 0x00000000" @test @sprintf("%-20p", C_NULL) == "0x00000000 " end @test @sprintf("%p", 0xfffffffffffe0000) == "0xfffffffffffe0000" end @testset "%a" begin @test Printf.@sprintf("%a", 0.0) == "0x0p+0" @test Printf.@sprintf("%a", -0.0) == "-0x0p+0" @test Printf.@sprintf("%.3a", 0.0) == "0x0.000p+0" @test Printf.@sprintf("%a", 1.5) == "0x1.8p+0" @test Printf.@sprintf("%a", 1.5f0) == "0x1.8p+0" @test Printf.@sprintf("%a", 1.5) == "0x1.8p+0" @test Printf.@sprintf("%#.0a", 1.5) == "0x2.p+0" @test Printf.@sprintf("%+30a", 1 / 3) == " +0x1.5555555555555p-2" @test Printf.@sprintf("%a", 1.5) == "0x1.8p+0" @test Printf.@sprintf("%a", 3.14) == "0x1.91eb851eb851fp+1" @test Printf.@sprintf("%.0a", 3.14) == "0x2p+1" @test Printf.@sprintf("%.1a", 3.14) == "0x1.9p+1" @test Printf.@sprintf("%.2a", 3.14) == "0x1.92p+1" @test Printf.@sprintf("%#a", 3.14) == "0x1.91eb851eb851fp+1" @test Printf.@sprintf("%#.0a", 3.14) == "0x2.p+1" @test Printf.@sprintf("%#.1a", 3.14) == "0x1.9p+1" @test Printf.@sprintf("%#.2a", 3.14) == "0x1.92p+1" @test Printf.@sprintf("%.6a", 1.5) == "0x1.800000p+0" end @testset "%g" begin for (val, res) = ((1.2345678e7, "1.23457e+07"), (1.2345678e6, "1.23457e+06"), (123456.78, "123457"), (12345.678, "12345.7"), (1.234e7, "1.234e+07")) @test Printf.@sprintf("%.6g", val) == res end for (val, res) = ((1.2345678e7, "1.23457e+07"), (1.234567799999999999999999999999999999999999999999999999999999999999999999999993e6, "1.23457e+06"), (123456.7800000000000000000000000000000000000000000000000000000000000000000000004, "123457"), (12345.67800000000000000000000000000000000000000000000000000000000000000000000007, "12345.7")) @test Printf.@sprintf("%.6g", val) == res end for (fmt, val) = (("%10.5g", " 123.4"), ("%+10.5g", " +123.4"), ("% 10.5g", " 123.4"), ("%#10.5g", " 123.40"), ("%-10.5g", "123.4 "), ("%-+10.5g", "+123.4 "), ("%010.5g", "00000123.4")), num = (123.4, 123.4000000000000000000000000000000000000000000000000000000000000000000000000002) @test Printf.format(Printf.Format(fmt), num) == val end @test Printf.@sprintf("%10.5g", -123.4) == " -123.4" @test Printf.@sprintf("%010.5g", -123.4) == "-0000123.4" @test Printf.@sprintf("%.6g", 1.234e7) == "1.234e+07" @test Printf.@sprintf("%#.6g", 1.234e7) == "1.23400e+07" @test Printf.@sprintf("%10.5g", -123.4000000000000000000000000000000000000000000000000000000000000000000000000002) == " -123.4" @test Printf.@sprintf("%010.5g", -123.4000000000000000000000000000000000000000000000000000000000000000000000000002) == "-0000123.4" @test Printf.@sprintf("%.6g", 1.234e7) == "1.234e+07" @test Printf.@sprintf("%#.6g", 1.234e7) == "1.23400e+07" @test Printf.@sprintf("%.5g", 42) == "42" @test Printf.@sprintf("%#.2g", 42) == "42." @test Printf.@sprintf("%#.5g", 42) == "42.000" @test Printf.@sprintf("%g", 0.00012) == "0.00012" @test Printf.@sprintf("%g", 1.2e-5) == "1.2e-05" @test Printf.@sprintf("%g", 123456.7) == "123457" @test Printf.@sprintf("%g", 1.2345678e6) == "1.23457e+06" for (val, res) = ((Inf, "Inf"), (-Inf, "-Inf"), (NaN, "NaN"), (-NaN, "NaN")) @test Printf.@sprintf("%g", val) == res @test Printf.@sprintf("%G", val) == res end @test Printf.@sprintf("%.15g", 0) == "0" @test Printf.@sprintf("%#.15g", 0) == "0.00000000000000" end @testset "%f" begin @test Printf.@sprintf("%f", Inf) == "Inf" @test Printf.@sprintf("%+f", Inf) == "+Inf" @test Printf.@sprintf("% f", Inf) == " Inf" @test Printf.@sprintf("% #f", Inf) == " Inf" @test Printf.@sprintf("%07f", Inf) == " Inf" @test Printf.@sprintf("%f", -Inf) == "-Inf" @test Printf.@sprintf("%+f", -Inf) == "-Inf" @test Printf.@sprintf("%07f", -Inf) == " -Inf" @test Printf.@sprintf("%f", NaN) == "NaN" @test Printf.@sprintf("%+f", NaN) == "+NaN" @test Printf.@sprintf("% f", NaN) == " NaN" @test Printf.@sprintf("% #f", NaN) == " NaN" @test Printf.@sprintf("%07f", NaN) == " NaN" @test Printf.@sprintf("%e", Inf) == "Inf" @test Printf.@sprintf("%e", NaN) == "NaN" @test Printf.@sprintf("%.0f", 3.0e142) == "29999999999999997463140672961703247153805615792184250659629251954072073858354858644285983761764971823910371920726635399393477049701891710124032" @test Printf.@sprintf("%f", 1.234) == "1.234000" @test Printf.@sprintf("%F", 1.234) == "1.234000" @test Printf.@sprintf("%+f", 1.234) == "+1.234000" @test Printf.@sprintf("% f", 1.234) == " 1.234000" @test Printf.@sprintf("%f", -1.234) == "-1.234000" @test Printf.@sprintf("%+f", -1.234) == "-1.234000" @test Printf.@sprintf("% f", -1.234) == "-1.234000" @test Printf.@sprintf("%#f", 1.234) == "1.234000" @test Printf.@sprintf("%.2f", 1.234) == "1.23" @test Printf.@sprintf("%.2f", 1.235) == "1.24" @test Printf.@sprintf("%.2f", 0.235) == "0.23" @test Printf.@sprintf("%4.1f", 1.234) == " 1.2" @test Printf.@sprintf("%8.1f", 1.234) == " 1.2" @test Printf.@sprintf("%+8.1f", 1.234) == " +1.2" @test Printf.@sprintf("% 8.1f", 1.234) == " 1.2" @test Printf.@sprintf("% 7.1f", 1.234) == " 1.2" @test Printf.@sprintf("% 08.1f", 1.234) == " 00001.2" @test Printf.@sprintf("%08.1f", 1.234) == "000001.2" @test Printf.@sprintf("%-08.1f", 1.234) == "1.2 " @test Printf.@sprintf("%-8.1f", 1.234) == "1.2 " @test Printf.@sprintf("%08.1f", -1.234) == "-00001.2" @test Printf.@sprintf("%09.1f", -1.234) == "-000001.2" @test Printf.@sprintf("%09.1f", 1.234) == "0000001.2" @test Printf.@sprintf("%+09.1f", 1.234) == "+000001.2" @test Printf.@sprintf("% 09.1f", 1.234) == " 000001.2" @test Printf.@sprintf("%+ 09.1f", 1.234) == "+000001.2" @test Printf.@sprintf("%+ 09.1f", 1.234) == "+000001.2" @test Printf.@sprintf("%+ 09.0f", 1.234) == "+00000001" @test Printf.@sprintf("%+ #09.0f", 1.234) == "+0000001." @test Printf.@sprintf("%+7.1f", 9.96) == " +10.0" @test Printf.@sprintf("% 7.1f", 9.96) == " 10.0" end @testset "%e" begin @test Printf.@sprintf("%e", Inf) == "Inf" @test Printf.@sprintf("%+e", Inf) == "+Inf" @test Printf.@sprintf("% e", Inf) == " Inf" @test Printf.@sprintf("% #e", Inf) == " Inf" @test Printf.@sprintf("%07e", Inf) == " Inf" @test Printf.@sprintf("%e", -Inf) == "-Inf" @test Printf.@sprintf("%+e", -Inf) == "-Inf" @test Printf.@sprintf("%07e", -Inf) == " -Inf" @test Printf.@sprintf("%e", NaN) == "NaN" @test Printf.@sprintf("%+e", NaN) == "+NaN" @test Printf.@sprintf("% e", NaN) == " NaN" @test Printf.@sprintf("% #e", NaN) == " NaN" @test Printf.@sprintf("%07e", NaN) == " NaN" @test Printf.@sprintf("%e", Inf) == "Inf" @test Printf.@sprintf("%e", NaN) == "NaN" @test Printf.@sprintf("%.0e", 3.0e142) == "3e+142" @test Printf.@sprintf("%#.0e", 3.0e142) == "3.e+142" @test Printf.@sprintf("%.0e", 2.999999999999999999999999999999999999999999999999999999999999999999999999999996e142) == "3e+142" @test Printf.@sprintf("%#.0e", 2.999999999999999999999999999999999999999999999999999999999999999999999999999996e142) == "3.e+142" @test Printf.@sprintf("%.0e", 3.000000000000000000000000000000000000000000000000000000000000000000000000000024e1042) == "3e+1042" @test Printf.@sprintf("%e", 3.0e42) == "3.000000e+42" @test Printf.@sprintf("%E", 3.0e42) == "3.000000E+42" @test Printf.@sprintf("%e", 3.0e-42) == "3.000000e-42" @test Printf.@sprintf("%E", 3.0e-42) == "3.000000E-42" @test Printf.@sprintf("%e", 1.234) == "1.234000e+00" @test Printf.@sprintf("%E", 1.234) == "1.234000E+00" @test Printf.@sprintf("%+e", 1.234) == "+1.234000e+00" @test Printf.@sprintf("% e", 1.234) == " 1.234000e+00" @test Printf.@sprintf("%e", -1.234) == "-1.234000e+00" @test Printf.@sprintf("%+e", -1.234) == "-1.234000e+00" @test Printf.@sprintf("% e", -1.234) == "-1.234000e+00" @test Printf.@sprintf("%#e", 1.234) == "1.234000e+00" @test Printf.@sprintf("%.2e", 1.234) == "1.23e+00" @test Printf.@sprintf("%.2e", 1.235) == "1.24e+00" @test Printf.@sprintf("%.2e", 0.235) == "2.35e-01" @test Printf.@sprintf("%4.1e", 1.234) == "1.2e+00" @test Printf.@sprintf("%8.1e", 1.234) == " 1.2e+00" @test Printf.@sprintf("%+8.1e", 1.234) == "+1.2e+00" @test Printf.@sprintf("% 8.1e", 1.234) == " 1.2e+00" @test Printf.@sprintf("% 7.1e", 1.234) == " 1.2e+00" @test Printf.@sprintf("% 08.1e", 1.234) == " 1.2e+00" @test Printf.@sprintf("%08.1e", 1.234) == "01.2e+00" @test Printf.@sprintf("%-08.1e", 1.234) == "1.2e+00 " @test Printf.@sprintf("%-8.1e", 1.234) == "1.2e+00 " @test Printf.@sprintf("%-8.1e", 1.234) == "1.2e+00 " @test Printf.@sprintf("%08.1e", -1.234) == "-1.2e+00" @test Printf.@sprintf("%09.1e", -1.234) == "-01.2e+00" @test Printf.@sprintf("%09.1e", 1.234) == "001.2e+00" @test Printf.@sprintf("%+09.1e", 1.234) == "+01.2e+00" @test Printf.@sprintf("% 09.1e", 1.234) == " 01.2e+00" @test Printf.@sprintf("%+ 09.1e", 1.234) == "+01.2e+00" @test Printf.@sprintf("%+ 09.1e", 1.234) == "+01.2e+00" @test Printf.@sprintf("%+ 09.0e", 1.234) == "+0001e+00" @test Printf.@sprintf("%+ #09.0e", 1.234) == "+001.e+00" @test Printf.@sprintf("%+9.1e", 9.96) == " +1.0e+01" @test Printf.@sprintf("% 9.1e", 9.96) == " 1.0e+01" end @testset "strings" begin @test Printf.@sprintf("Hallo heimur") == "Hallo heimur" @test Printf.@sprintf("+%s+", "hello") == "+hello+" @test Printf.@sprintf("%.1s", "foo") == "f" @test Printf.@sprintf("%s", "%%%%") == "%%%%" @test Printf.@sprintf("%s", "Hallo heimur") == "Hallo heimur" @test Printf.@sprintf("%+s", "Hallo heimur") == "Hallo heimur" @test Printf.@sprintf("% s", "Hallo heimur") == "Hallo heimur" @test Printf.@sprintf("%+ s", "Hallo heimur") == "Hallo heimur" @test Printf.@sprintf("%1s", "Hallo heimur") == "Hallo heimur" @test Printf.@sprintf("%20s", "Hallo") == " Hallo" @test Printf.@sprintf("%-20s", "Hallo") == "Hallo " @test Printf.@sprintf("%0-20s", "Hallo") == "Hallo " @test Printf.@sprintf("%.20s", "Hallo heimur") == "Hallo heimur" @test Printf.@sprintf("%20.5s", "Hallo heimur") == " Hallo" @test Printf.@sprintf("%.0s", "Hallo heimur") == "" @test Printf.@sprintf("%20.0s", "Hallo heimur") == " " @test Printf.@sprintf("%.s", "Hallo heimur") == "" @test Printf.@sprintf("%20.s", "Hallo heimur") == " " @test Printf.@sprintf("%s", "test") == "test" @test Printf.@sprintf("%s", "tést") == "tést" @test Printf.@sprintf("ø%sø", "hey") == "øheyø" @test Printf.@sprintf("%4sø", "ø") == " øø" @test Printf.@sprintf("%-4sø", "ø") == "ø ø" @test Printf.@sprintf("%8s", "test") == " test" @test Printf.@sprintf("%-8s", "test") == "test " @test Printf.@sprintf("%s", :test) == "test" @test Printf.@sprintf("%#s", :test) == ":test" @test Printf.@sprintf("%#8s", :test) == " :test" @test Printf.@sprintf("%#-8s", :test) == ":test " @test Printf.@sprintf("%8.3s", "test") == " tes" @test Printf.@sprintf("%#8.3s", "test") == " \"te" @test Printf.@sprintf("%-8.3s", "test") == "tes " @test Printf.@sprintf("%#-8.3s", "test") == "\"te " @test Printf.@sprintf("%.3s", "test") == "tes" @test Printf.@sprintf("%#.3s", "test") == "\"te" @test Printf.@sprintf("%-.3s", "test") == "tes" @test Printf.@sprintf("%#-.3s", "test") == "\"te" @test Printf.@sprintf("%.2s", "föó") == "fö" @test Printf.@sprintf("%5s", "föó") == " föó" @test Printf.@sprintf("%6s", "😍🍕") == " 😍🍕" @test Printf.@sprintf("%2c", '🍕') == "🍕" @test Printf.@sprintf("%3c", '🍕') == " 🍕" end @testset "chars" begin @test Printf.@sprintf("%c", 'a') == "a" @test Printf.@sprintf("%c", 32) == " " @test Printf.@sprintf("%c", 36) == "\$" @test Printf.@sprintf("%3c", 'a') == " a" @test Printf.@sprintf("%c", 'x') == "x" @test Printf.@sprintf("%+c", 'x') == "x" @test Printf.@sprintf("% c", 'x') == "x" @test Printf.@sprintf("%+ c", 'x') == "x" @test Printf.@sprintf("%1c", 'x') == "x" @test Printf.@sprintf("%20c", 'x') == " x" @test Printf.@sprintf("%-20c", 'x') == "x " @test Printf.@sprintf("%-020c", 'x') == "x " @test Printf.@sprintf("%c", 65) == "A" @test Printf.@sprintf("%c", 'A') == "A" @test Printf.@sprintf("%3c", 'A') == " A" @test Printf.@sprintf("%-3c", 'A') == "A " @test Printf.@sprintf("%c", 248) == "ø" @test Printf.@sprintf("%c", 'ø') == "ø" @test Printf.@sprintf("%c", "ø") == "ø" @test Printf.@sprintf("%c", '𐀀') == "𐀀" end function _test_flags(val, vflag::AbstractString, fmt::AbstractString, res::AbstractString, prefix::AbstractString) vflag = string("%", vflag) space_fmt = string(length(res) + length(prefix) + 3, fmt) fsign = string(if val < 0 "-" else "+" end, prefix) nsign = string(if val < 0 "-" else " " end, prefix) osign = if val < 0 string("-", prefix) else string(prefix, "0") end esign = string(if val < 0 "-" else "" end, prefix) esignend = if val < 0 "" else " " end for (flag::AbstractString, ans::AbstractString) = (("", string(" ", nsign, res)), ("+", string(" ", fsign, res)), (" ", string(" ", nsign, res)), ("0", string(osign, "00", res)), ("-", string(esign, res, " ", esignend)), ("0+", string(fsign, "00", res)), ("0 ", string(nsign, "00", res)), ("-+", string(fsign, res, " ")), ("- ", string(nsign, res, " "))) fmt_string = string(vflag, flag, space_fmt) fmtd = Printf.format(Printf.Format(fmt_string), val) @test fmtd == ans end end @testset "basics" begin @test Printf.@sprintf("%%") == "%" @test Printf.@sprintf("1%%") == "1%" @test Printf.@sprintf("%%1") == "%1" @test Printf.@sprintf("1%%2") == "1%2" @test Printf.@sprintf("1%%%d", 2) == "1%2" @test Printf.@sprintf("1%%2%%3") == "1%2%3" @test Printf.@sprintf("GAP[%%]") == "GAP[%]" @test Printf.@sprintf("hey there") == "hey there" @test_throws Printf.InvalidFormatStringError Printf.Format("%+") @test_throws Printf.InvalidFormatStringError Printf.Format("%.") @test_throws Printf.InvalidFormatStringError Printf.Format("%.0") @test isempty((Printf.Format("%%")).formats) @test Printf.@sprintf("%d%d", 1, 2) == "12" @test Printf.@sprintf("%d%d", [1 2]...) == "12" @test Printf.@sprintf("X%d", 2) == "X2" @test Printf.@sprintf("Ð%d", 2) == "Ð2" @test Printf.@sprintf("ༀ%d", 2) == "ༀ2" @test Printf.@sprintf("\U1ffff%d", 2) == "\U0001ffff2" @test Printf.@sprintf("%dX%d", 1, 2) == "1X2" @test Printf.@sprintf("%dÐ%d", 1, 2) == "1Ð2" @test Printf.@sprintf("%dༀ%d", 1, 2) == "1ༀ2" @test Printf.@sprintf("%d\U1ffff%d", 1, 2) == "1\U0001ffff2" @test Printf.@sprintf("%d∃%dȃ", 1, 2) == "1∃2ȃ" @test_throws Printf.InvalidFormatStringError Printf.Format("%y%d") @test_throws Printf.InvalidFormatStringError Printf.Format("%Ð%d") @test_throws Printf.InvalidFormatStringError Printf.Format("%ༀ%d") @test_throws Printf.InvalidFormatStringError Printf.Format("%\U1ffff%d") @test Printf.@sprintf("%10.5d", 4) == " 00004" @test Printf.@sprintf("%d", typemax(Int64)) == "9223372036854775807" for (fmt, val) = (("%7.2f", " 1.23"), ("%-7.2f", "1.23 "), ("%07.2f", "0001.23"), ("%.0f", "1"), ("%#.0f", "1."), ("%.4e", "1.2345e+00"), ("%.4E", "1.2345E+00"), ("%.2a", "0x1.3cp+0"), ("%.2A", "0X1.3CP+0")), num = (1.2345, 1.234499999999999999999999999999999999999999999999999999999999999999999999999991) @test Printf.format(Printf.Format(fmt), num) == val end for (fmt, val) = (("%i", "42"), ("%u", "42"), ("Test: %i", "Test: 42"), ("%#x", "0x2a"), ("%x", "2a"), ("%X", "2A"), ("% i", " 42"), ("%+i", "+42"), ("%4i", " 42"), ("%-4i", "42 "), ("%f", "42.000000"), ("%g", "42"), ("%e", "4.200000e+01")), num = (UInt16(42), UInt32(42), UInt64(42), UInt128(42), Int16(42), Int32(42), Int64(42), Int128(42), 42) @test Printf.format(Printf.Format(fmt), num) == val end for i = ((42, "", "i", "42", ""), (42, "", "d", "42", ""), (42, "", "u", "42", ""), (42, "", "x", "2a", ""), (42, "", "X", "2A", ""), (42, "", "o", "52", ""), (42, "#", "x", "2a", "0x"), (42, "#", "X", "2A", "0X"), (42, "#", "o", "052", ""), (1.2345, "", ".2f", "1.23", ""), (1.2345, "", ".2e", "1.23e+00", ""), (1.2345, "", ".2E", "1.23E+00", ""), (1.2345, "#", ".0f", "1.", ""), (1.2345, "#", ".0e", "1.e+00", ""), (1.2345, "#", ".0E", "1.E+00", ""), (1.2345, "", ".2a", "1.3cp+0", "0x"), (1.2345, "", ".2A", "1.3CP+0", "0X")) _test_flags(i...) _test_flags(-(i[1]), i[2:5]...) end @test Printf.@sprintf("Test: %s%c%C%c%#-.0f.", "t", 65, 66, 67, -42) == "Test: tABC-42.." @test Printf.@sprintf("%f %d %d %f", 1.0, [3 4]..., 5) == "1.000000 3 4 5.000000" @test Printf.@sprintf("%s %f %9.5f %d %d %d %d%d%d%d", [1:6;]..., [7, 8, 9, 10]...) == "1 2.000000 3.00000 4 5 6 78910" @test Printf.@sprintf("%s %s %s %d %d %d %f %f %f", Any[10 ^ x + y for x = 1:3, y = 1:3]...) == "11 101 1001 12 102 1002 13.000000 103.000000 1003.000000" @test Printf.@sprintf("%s %s %s %d %d %d %f %f %f %s %s %s %d %d %d %f %f %f", Any[10x + (x + 1) for x = 1:18]...) == "12 23 34 45 56 67 78.000000 89.000000 100.000000 111 122 133 144 155 166 177.000000 188.000000 199.000000" @test (Printf.@sprintf("%.330f", BigFloat(1)))[var"end"] != '\0' @test Printf.@sprintf("%f", parse(BigFloat, "1e400")) == "10000000000000000000000000000000000000000000000000000000000000000000000000000025262527574416492004687051900140830217136998040684679611623086405387447100385714565637522507383770691831689647535911648520404034824470543643098638520633064715221151920028135130764414460468236314621044034960475540018328999334468948008954289495190631358190153259681118693204411689043999084305348398480210026863210192871358464.000000" @test_throws ArgumentError Printf.@sprintf("%f", parse(BigFloat, "1e99999")) @test Printf.@sprintf("%4.2s", "a") == " a" @test Printf.@sprintf("%12.3e", pi * 1.0e100) == " 3.142e+100" @test string((Printf.Format("%a")).formats[1]) == "%a" @test string((Printf.Format("%a")).formats[1]; modifier = "R") == "%Ra" @test Printf.@sprintf("%d", 3.14) == "3" @test Printf.@sprintf("%2d", 3.14) == " 3" @test Printf.@sprintf("%2d", big(3.14)) == " 3" @test Printf.@sprintf("%s", 1) == "1" @test Printf.@sprintf("%f", 1) == "1.000000" @test Printf.@sprintf("%e", 1) == "1.000000e+00" @test Printf.@sprintf("%g", 1) == "1" @test Printf.@sprintf("%.16g", 194.4778127560983) == "194.4778127560983" @test Printf.@sprintf("%.17g", 194.4778127560983) == "194.4778127560983" @test Printf.@sprintf("%.18g", 194.4778127560983) == "194.477812756098302" @test Printf.@sprintf("%.1g", 1.7976931348623157e308) == "2e+308" @test Printf.@sprintf("%.2g", 1.7976931348623157e308) == "1.8e+308" @test Printf.@sprintf("%.3g", 1.7976931348623157e308) == "1.8e+308" @test_throws ArgumentError @sprintf("%s%%%s", "a") @test @sprintf("%s%%%s", "a", "b") == "a%b" @test @sprintf("%d", 25.5) == "26" @test @sprintf(" %.1e\n", 0.999) == " 1.0e+00\n" @test @sprintf(" %.1f", 9.999) == " 10.0" @test @sprintf("%d", 1.0e100) == "10000000000000000159028911097599180468360808563945281389781327557747838772170381060813469985856815104" @test @sprintf("%d", 3 // 1) == "3" @test @sprintf("%d", Inf) == "Inf" @test @sprintf(" %d", NaN) == " NaN" @test Printf.@sprintf("") == "" @test Printf.format(Printf.Format("")) == "" end @testset "integers" begin @test Printf.@sprintf("% d", 42) == " 42" @test Printf.@sprintf("% d", -42) == "-42" @test Printf.@sprintf("% 5d", 42) == " 42" @test Printf.@sprintf("% 5d", -42) == " -42" @test Printf.@sprintf("% 15d", 42) == " 42" @test Printf.@sprintf("% 15d", -42) == " -42" @test Printf.@sprintf("%+d", 42) == "+42" @test Printf.@sprintf("%+d", -42) == "-42" @test Printf.@sprintf("%+5d", 42) == " +42" @test Printf.@sprintf("%+5d", -42) == " -42" @test Printf.@sprintf("%+15d", 42) == " +42" @test Printf.@sprintf("%+15d", -42) == " -42" @test Printf.@sprintf("%0d", 42) == "42" @test Printf.@sprintf("%0d", -42) == "-42" @test Printf.@sprintf("%05d", 42) == "00042" @test Printf.@sprintf("%05d", -42) == "-0042" @test Printf.@sprintf("%015d", 42) == "000000000000042" @test Printf.@sprintf("%015d", -42) == "-00000000000042" @test Printf.@sprintf("%-d", 42) == "42" @test Printf.@sprintf("%-d", -42) == "-42" @test Printf.@sprintf("%-5d", 42) == "42 " @test Printf.@sprintf("%-5d", -42) == "-42 " @test Printf.@sprintf("%-15d", 42) == "42 " @test Printf.@sprintf("%-15d", -42) == "-42 " @test Printf.@sprintf("%-0d", 42) == "42" @test Printf.@sprintf("%-0d", -42) == "-42" @test Printf.@sprintf("%-05d", 42) == "42 " @test Printf.@sprintf("%-05d", -42) == "-42 " @test Printf.@sprintf("%-015d", 42) == "42 " @test Printf.@sprintf("%-015d", -42) == "-42 " @test Printf.@sprintf("%0-d", 42) == "42" @test Printf.@sprintf("%0-d", -42) == "-42" @test Printf.@sprintf("%0-5d", 42) == "42 " @test Printf.@sprintf("%0-5d", -42) == "-42 " @test Printf.@sprintf("%0-15d", 42) == "42 " @test Printf.@sprintf("%0-15d", -42) == "-42 " @test_throws Printf.InvalidFormatStringError Printf.Format("%d %") @test Printf.@sprintf("%lld", 18446744065119617025) == "18446744065119617025" @test Printf.@sprintf("%+8lld", 100) == " +100" @test Printf.@sprintf("%+.8lld", 100) == "+00000100" @test Printf.@sprintf("%+10.8lld", 100) == " +00000100" @test_throws Printf.InvalidFormatStringError Printf.Format("%_1lld") @test Printf.@sprintf("%-1.5lld", -100) == "-00100" @test Printf.@sprintf("%5lld", 100) == " 100" @test Printf.@sprintf("%5lld", -100) == " -100" @test Printf.@sprintf("%-5lld", 100) == "100 " @test Printf.@sprintf("%-5lld", -100) == "-100 " @test Printf.@sprintf("%-.5lld", 100) == "00100" @test Printf.@sprintf("%-.5lld", -100) == "-00100" @test Printf.@sprintf("%-8.5lld", 100) == "00100 " @test Printf.@sprintf("%-8.5lld", -100) == "-00100 " @test Printf.@sprintf("%05lld", 100) == "00100" @test Printf.@sprintf("%05lld", -100) == "-0100" @test Printf.@sprintf("% lld", 100) == " 100" @test Printf.@sprintf("% lld", -100) == "-100" @test Printf.@sprintf("% 5lld", 100) == " 100" @test Printf.@sprintf("% 5lld", -100) == " -100" @test Printf.@sprintf("% .5lld", 100) == " 00100" @test Printf.@sprintf("% .5lld", -100) == "-00100" @test Printf.@sprintf("% 8.5lld", 100) == " 00100" @test Printf.@sprintf("% 8.5lld", -100) == " -00100" @test Printf.@sprintf("%.0lld", 0) == "0" @test Printf.@sprintf("%#+21.18llx", -100) == "-0x000000000000000064" @test Printf.@sprintf("%#.25llo", -100) == "-00000000000000000000000144" @test Printf.@sprintf("%#+24.20llo", -100) == " -000000000000000000144" @test Printf.@sprintf("%#+18.21llX", -100) == "-0X000000000000000000064" @test Printf.@sprintf("%#+20.24llo", -100) == "-0000000000000000000000144" @test Printf.@sprintf("%#+25.22llu", -1) == " -0000000000000000000001" @test Printf.@sprintf("%#+25.22llu", -1) == " -0000000000000000000001" @test Printf.@sprintf("%#+30.25llu", -1) == " -0000000000000000000000001" @test Printf.@sprintf("%+#25.22lld", -1) == " -0000000000000000000001" @test Printf.@sprintf("%#-8.5llo", 100) == "000144 " @test Printf.@sprintf("%#-+ 08.5lld", 100) == "+00100 " @test Printf.@sprintf("%#-+ 08.5lld", 100) == "+00100 " @test Printf.@sprintf("%.40lld", 1) == "0000000000000000000000000000000000000001" @test Printf.@sprintf("% .40lld", 1) == " 0000000000000000000000000000000000000001" @test Printf.@sprintf("% .40d", 1) == " 0000000000000000000000000000000000000001" @test Printf.@sprintf("%lld", 18446744065119617025) == "18446744065119617025" @test Printf.@sprintf("+%d+", 10) == "+10+" @test Printf.@sprintf("%#012x", 1) == "0x0000000001" @test Printf.@sprintf("%#04.8x", 1) == "0x00000001" @test Printf.@sprintf("%#-08.2x", 1) == "0x01 " @test Printf.@sprintf("%#08o", 1) == "00000001" @test Printf.@sprintf("%d", 1024) == "1024" @test Printf.@sprintf("%d", -1024) == "-1024" @test Printf.@sprintf("%i", 1024) == "1024" @test Printf.@sprintf("%i", -1024) == "-1024" @test Printf.@sprintf("%u", 1024) == "1024" @test Printf.@sprintf("%u", UInt(4294966272)) == "4294966272" @test Printf.@sprintf("%o", 511) == "777" @test Printf.@sprintf("%o", UInt(4294966785)) == "37777777001" @test Printf.@sprintf("%x", 305441741) == "1234abcd" @test Printf.@sprintf("%x", UInt(3989525555)) == "edcb5433" @test Printf.@sprintf("%X", 305441741) == "1234ABCD" @test Printf.@sprintf("%X", UInt(3989525555)) == "EDCB5433" @test Printf.@sprintf("%+d", 1024) == "+1024" @test Printf.@sprintf("%+d", -1024) == "-1024" @test Printf.@sprintf("%+i", 1024) == "+1024" @test Printf.@sprintf("%+i", -1024) == "-1024" @test Printf.@sprintf("%+u", 1024) == "+1024" @test Printf.@sprintf("%+u", UInt(4294966272)) == "+4294966272" @test Printf.@sprintf("%+o", 511) == "+777" @test Printf.@sprintf("%+o", UInt(4294966785)) == "+37777777001" @test Printf.@sprintf("%+x", 305441741) == "+1234abcd" @test Printf.@sprintf("%+x", UInt(3989525555)) == "+edcb5433" @test Printf.@sprintf("%+X", 305441741) == "+1234ABCD" @test Printf.@sprintf("%+X", UInt(3989525555)) == "+EDCB5433" @test Printf.@sprintf("% d", 1024) == " 1024" @test Printf.@sprintf("% d", -1024) == "-1024" @test Printf.@sprintf("% i", 1024) == " 1024" @test Printf.@sprintf("% i", -1024) == "-1024" @test Printf.@sprintf("% u", 1024) == " 1024" @test Printf.@sprintf("% u", UInt(4294966272)) == " 4294966272" @test Printf.@sprintf("% o", 511) == " 777" @test Printf.@sprintf("% o", UInt(4294966785)) == " 37777777001" @test Printf.@sprintf("% x", 305441741) == " 1234abcd" @test Printf.@sprintf("% x", UInt(3989525555)) == " edcb5433" @test Printf.@sprintf("% X", 305441741) == " 1234ABCD" @test Printf.@sprintf("% X", UInt(3989525555)) == " EDCB5433" @test Printf.@sprintf("%+ d", 1024) == "+1024" @test Printf.@sprintf("%+ d", -1024) == "-1024" @test Printf.@sprintf("%+ i", 1024) == "+1024" @test Printf.@sprintf("%+ i", -1024) == "-1024" @test Printf.@sprintf("%+ u", 1024) == "+1024" @test Printf.@sprintf("%+ u", UInt(4294966272)) == "+4294966272" @test Printf.@sprintf("%+ o", 511) == "+777" @test Printf.@sprintf("%+ o", UInt(4294966785)) == "+37777777001" @test Printf.@sprintf("%+ x", 305441741) == "+1234abcd" @test Printf.@sprintf("%+ x", UInt(3989525555)) == "+edcb5433" @test Printf.@sprintf("%+ X", 305441741) == "+1234ABCD" @test Printf.@sprintf("%+ X", UInt(3989525555)) == "+EDCB5433" @test Printf.@sprintf("%#o", 511) == "0777" @test Printf.@sprintf("%#o", UInt(4294966785)) == "037777777001" @test Printf.@sprintf("%#x", 305441741) == "0x1234abcd" @test Printf.@sprintf("%#x", UInt(3989525555)) == "0xedcb5433" @test Printf.@sprintf("%#X", 305441741) == "0X1234ABCD" @test Printf.@sprintf("%#X", UInt(3989525555)) == "0XEDCB5433" @test Printf.@sprintf("%#o", UInt(0)) == "00" @test Printf.@sprintf("%#x", UInt(0)) == "0x0" @test Printf.@sprintf("%#X", UInt(0)) == "0X0" @test Printf.@sprintf("%1d", 1024) == "1024" @test Printf.@sprintf("%1d", -1024) == "-1024" @test Printf.@sprintf("%1i", 1024) == "1024" @test Printf.@sprintf("%1i", -1024) == "-1024" @test Printf.@sprintf("%1u", 1024) == "1024" @test Printf.@sprintf("%1u", UInt(4294966272)) == "4294966272" @test Printf.@sprintf("%1o", 511) == "777" @test Printf.@sprintf("%1o", UInt(4294966785)) == "37777777001" @test Printf.@sprintf("%1x", 305441741) == "1234abcd" @test Printf.@sprintf("%1x", UInt(3989525555)) == "edcb5433" @test Printf.@sprintf("%1X", 305441741) == "1234ABCD" @test Printf.@sprintf("%1X", UInt(3989525555)) == "EDCB5433" @test Printf.@sprintf("%20d", 1024) == " 1024" @test Printf.@sprintf("%20d", -1024) == " -1024" @test Printf.@sprintf("%20i", 1024) == " 1024" @test Printf.@sprintf("%20i", -1024) == " -1024" @test Printf.@sprintf("%20u", 1024) == " 1024" @test Printf.@sprintf("%20u", UInt(4294966272)) == " 4294966272" @test Printf.@sprintf("%20o", 511) == " 777" @test Printf.@sprintf("%20o", UInt(4294966785)) == " 37777777001" @test Printf.@sprintf("%20x", 305441741) == " 1234abcd" @test Printf.@sprintf("%20x", UInt(3989525555)) == " edcb5433" @test Printf.@sprintf("%20X", 305441741) == " 1234ABCD" @test Printf.@sprintf("%20X", UInt(3989525555)) == " EDCB5433" @test Printf.@sprintf("%-20d", 1024) == "1024 " @test Printf.@sprintf("%-20d", -1024) == "-1024 " @test Printf.@sprintf("%-20i", 1024) == "1024 " @test Printf.@sprintf("%-20i", -1024) == "-1024 " @test Printf.@sprintf("%-20u", 1024) == "1024 " @test Printf.@sprintf("%-20u", UInt(4294966272)) == "4294966272 " @test Printf.@sprintf("%-20o", 511) == "777 " @test Printf.@sprintf("%-20o", UInt(4294966785)) == "37777777001 " @test Printf.@sprintf("%-20x", 305441741) == "1234abcd " @test Printf.@sprintf("%-20x", UInt(3989525555)) == "edcb5433 " @test Printf.@sprintf("%-20X", 305441741) == "1234ABCD " @test Printf.@sprintf("%-20X", UInt(3989525555)) == "EDCB5433 " @test Printf.@sprintf("%020d", 1024) == "00000000000000001024" @test Printf.@sprintf("%020d", -1024) == "-0000000000000001024" @test Printf.@sprintf("%020i", 1024) == "00000000000000001024" @test Printf.@sprintf("%020i", -1024) == "-0000000000000001024" @test Printf.@sprintf("%020u", 1024) == "00000000000000001024" @test Printf.@sprintf("%020u", UInt(4294966272)) == "00000000004294966272" @test Printf.@sprintf("%020o", 511) == "00000000000000000777" @test Printf.@sprintf("%020o", UInt(4294966785)) == "00000000037777777001" @test Printf.@sprintf("%020x", 305441741) == "0000000000001234abcd" @test Printf.@sprintf("%020x", UInt(3989525555)) == "000000000000edcb5433" @test Printf.@sprintf("%020X", 305441741) == "0000000000001234ABCD" @test Printf.@sprintf("%020X", UInt(3989525555)) == "000000000000EDCB5433" @test Printf.@sprintf("%#20o", 511) == " 0777" @test Printf.@sprintf("%#20o", UInt(4294966785)) == " 037777777001" @test Printf.@sprintf("%#20x", 305441741) == " 0x1234abcd" @test Printf.@sprintf("%#20x", UInt(3989525555)) == " 0xedcb5433" @test Printf.@sprintf("%#20X", 305441741) == " 0X1234ABCD" @test Printf.@sprintf("%#20X", UInt(3989525555)) == " 0XEDCB5433" @test Printf.@sprintf("%#020o", 511) == "00000000000000000777" @test Printf.@sprintf("%#020o", UInt(4294966785)) == "00000000037777777001" @test Printf.@sprintf("%#020x", 305441741) == "0x00000000001234abcd" @test Printf.@sprintf("%#020x", UInt(3989525555)) == "0x0000000000edcb5433" @test Printf.@sprintf("%#020X", 305441741) == "0X00000000001234ABCD" @test Printf.@sprintf("%#020X", UInt(3989525555)) == "0X0000000000EDCB5433" @test Printf.@sprintf("%0-20d", 1024) == "1024 " @test Printf.@sprintf("%0-20d", -1024) == "-1024 " @test Printf.@sprintf("%0-20i", 1024) == "1024 " @test Printf.@sprintf("%0-20i", -1024) == "-1024 " @test Printf.@sprintf("%0-20u", 1024) == "1024 " @test Printf.@sprintf("%0-20u", UInt(4294966272)) == "4294966272 " @test Printf.@sprintf("%-020o", 511) == "777 " @test Printf.@sprintf("%-020o", UInt(4294966785)) == "37777777001 " @test Printf.@sprintf("%-020x", 305441741) == "1234abcd " @test Printf.@sprintf("%-020x", UInt(3989525555)) == "edcb5433 " @test Printf.@sprintf("%-020X", 305441741) == "1234ABCD " @test Printf.@sprintf("%-020X", UInt(3989525555)) == "EDCB5433 " @test Printf.@sprintf("%.20d", 1024) == "00000000000000001024" @test Printf.@sprintf("%.20d", -1024) == "-00000000000000001024" @test Printf.@sprintf("%.20i", 1024) == "00000000000000001024" @test Printf.@sprintf("%.20i", -1024) == "-00000000000000001024" @test Printf.@sprintf("%.20u", 1024) == "00000000000000001024" @test Printf.@sprintf("%.20u", UInt(4294966272)) == "00000000004294966272" @test Printf.@sprintf("%.20o", 511) == "00000000000000000777" @test Printf.@sprintf("%.20o", UInt(4294966785)) == "00000000037777777001" @test Printf.@sprintf("%.20x", 305441741) == "0000000000001234abcd" @test Printf.@sprintf("%.20x", UInt(3989525555)) == "000000000000edcb5433" @test Printf.@sprintf("%.20X", 305441741) == "0000000000001234ABCD" @test Printf.@sprintf("%.20X", UInt(3989525555)) == "000000000000EDCB5433" @test Printf.@sprintf("%20.5d", 1024) == " 01024" @test Printf.@sprintf("%20.5d", -1024) == " -01024" @test Printf.@sprintf("%20.5i", 1024) == " 01024" @test Printf.@sprintf("%20.5i", -1024) == " -01024" @test Printf.@sprintf("%20.5u", 1024) == " 01024" @test Printf.@sprintf("%20.5u", UInt(4294966272)) == " 4294966272" @test Printf.@sprintf("%20.5o", 511) == " 00777" @test Printf.@sprintf("%20.5o", UInt(4294966785)) == " 37777777001" @test Printf.@sprintf("%20.5x", 305441741) == " 1234abcd" @test Printf.@sprintf("%20.10x", UInt(3989525555)) == " 00edcb5433" @test Printf.@sprintf("%20.5X", 305441741) == " 1234ABCD" @test Printf.@sprintf("%20.10X", UInt(3989525555)) == " 00EDCB5433" @test Printf.@sprintf("%020.5d", 1024) == " 01024" @test Printf.@sprintf("%020.5d", -1024) == " -01024" @test Printf.@sprintf("%020.5i", 1024) == " 01024" @test Printf.@sprintf("%020.5i", -1024) == " -01024" @test Printf.@sprintf("%020.5u", 1024) == " 01024" @test Printf.@sprintf("%020.5u", UInt(4294966272)) == " 4294966272" @test Printf.@sprintf("%020.5o", 511) == " 00777" @test Printf.@sprintf("%020.5o", UInt(4294966785)) == " 37777777001" @test Printf.@sprintf("%020.5x", 305441741) == " 1234abcd" @test Printf.@sprintf("%020.10x", UInt(3989525555)) == " 00edcb5433" @test Printf.@sprintf("%020.5X", 305441741) == " 1234ABCD" @test Printf.@sprintf("%020.10X", UInt(3989525555)) == " 00EDCB5433" @test Printf.@sprintf("%20.0d", 1024) == " 1024" @test Printf.@sprintf("%20.d", -1024) == " -1024" @test Printf.@sprintf("%20.d", 0) == " 0" @test Printf.@sprintf("%20.0i", 1024) == " 1024" @test Printf.@sprintf("%20.i", -1024) == " -1024" @test Printf.@sprintf("%20.i", 0) == " 0" @test Printf.@sprintf("%20.u", 1024) == " 1024" @test Printf.@sprintf("%20.0u", UInt(4294966272)) == " 4294966272" @test Printf.@sprintf("%20.u", UInt(0)) == " 0" @test Printf.@sprintf("%20.o", 511) == " 777" @test Printf.@sprintf("%20.0o", UInt(4294966785)) == " 37777777001" @test Printf.@sprintf("%20.o", UInt(0)) == " 0" @test Printf.@sprintf("%20.x", 305441741) == " 1234abcd" @test Printf.@sprintf("%20.0x", UInt(3989525555)) == " edcb5433" @test Printf.@sprintf("%20.x", UInt(0)) == " 0" @test Printf.@sprintf("%20.X", 305441741) == " 1234ABCD" @test Printf.@sprintf("%20.0X", UInt(3989525555)) == " EDCB5433" @test Printf.@sprintf("%20.X", UInt(0)) == " 0" @test Printf.@sprintf("%4d", typemin(Int8)) == "-128" @test Printf.@sprintf("%4d", typemax(Int8)) == " 127" @test Printf.@sprintf("%6d", typemin(Int16)) == "-32768" @test Printf.@sprintf("%6d", typemax(Int16)) == " 32767" @test Printf.@sprintf("%11d", typemin(Int32)) == "-2147483648" @test Printf.@sprintf("%11d", typemax(Int32)) == " 2147483647" @test Printf.@sprintf("%20d", typemin(Int64)) == "-9223372036854775808" @test Printf.@sprintf("%20d", typemax(Int64)) == " 9223372036854775807" @test Printf.@sprintf("%40d", typemin(Int128)) == "-170141183460469231731687303715884105728" @test Printf.@sprintf("%40d", typemax(Int128)) == " 170141183460469231731687303715884105727" end @testset "%n" begin x = Ref{Int}() @test begin Printf.@sprintf "%d4%n" 123 x x[] == 4 end @test begin Printf.@sprintf "%s%n" "😉" x x[] == 4 end @test begin Printf.@sprintf "%s%n" "1234" x x[] == 4 end end @testset "dynamic" begin @test Printf.@sprintf("%*d", 10, 12) == " 12" @test Printf.@sprintf("%.*d", 4, 12) == "0012" @test Printf.@sprintf("%*.*d", 10, 4, 12) == " 0012" @test Printf.@sprintf("%+*.*d", 10, 4, 12) == " +0012" @test Printf.@sprintf("%0*.*d", 10, 4, 12) == " 0012" @test Printf.@sprintf("%*d%*d%*d", 4, 12, 4, 13, 4, 14) == " 12 13 14" @test Printf.@sprintf("%*d%*d%*d", 4, 12, 5, 13, 6, 14) == " 12 13 14" @test Printf.@sprintf("%*p", 20, 0) == Printf.@sprintf("%20p", 0) @test Printf.@sprintf("%-*p", 20, 0) == Printf.@sprintf("%-20p", 0) @test Printf.@sprintf("%*p", 20, C_NULL) == Printf.@sprintf("%20p", C_NULL) @test Printf.@sprintf("%-*p", 20, C_NULL) == Printf.@sprintf("%-20p", C_NULL) @test Printf.@sprintf("%.*a", 0, 3.14) == Printf.@sprintf("%.0a", 3.14) @test Printf.@sprintf("%.*a", 1, 3.14) == Printf.@sprintf("%.1a", 3.14) @test Printf.@sprintf("%.*a", 2, 3.14) == Printf.@sprintf("%.2a", 3.14) @test Printf.@sprintf("%#.*a", 0, 3.14) == Printf.@sprintf("%#.0a", 3.14) @test Printf.@sprintf("%#.*a", 1, 3.14) == Printf.@sprintf("%#.1a", 3.14) @test Printf.@sprintf("%#.*a", 2, 3.14) == Printf.@sprintf("%#.2a", 3.14) @test Printf.@sprintf("%.*a", 6, 1.5) == Printf.@sprintf("%.6a", 1.5) @test Printf.@sprintf("%*.*g", 10, 5, -123.4) == Printf.@sprintf("%10.5g", -123.4) @test Printf.@sprintf("%0*.*g", 10, 5, -123.4) == Printf.@sprintf("%010.5g", -123.4) @test Printf.@sprintf("%.*g", 6, 1.234e7) == Printf.@sprintf("%.6g", 1.234e7) @test Printf.@sprintf("%#.*g", 6, 1.234e7) == Printf.@sprintf("%#.6g", 1.234e7) @test Printf.@sprintf("%*.*g", 10, 5, -123.4000000000000000000000000000000000000000000000000000000000000000000000000002) == Printf.@sprintf("%10.5g", -123.4000000000000000000000000000000000000000000000000000000000000000000000000002) @test Printf.@sprintf("%0*.*g", 10, 5, -123.4000000000000000000000000000000000000000000000000000000000000000000000000002) == Printf.@sprintf("%010.5g", -123.4000000000000000000000000000000000000000000000000000000000000000000000000002) @test Printf.@sprintf("%.*g", 6, 1.234e7) == Printf.@sprintf("%.6g", 1.234e7) @test Printf.@sprintf("%#.*g", 6, 1.234e7) == Printf.@sprintf("%#.6g", 1.234e7) @test Printf.@sprintf("%.*g", 5, 42) == Printf.@sprintf("%.5g", 42) @test Printf.@sprintf("%#.*g", 2, 42) == Printf.@sprintf("%#.2g", 42) @test Printf.@sprintf("%#.*g", 5, 42) == Printf.@sprintf("%#.5g", 42) @test Printf.@sprintf("%.*g", 15, 0) == Printf.@sprintf("%.15g", 0) @test Printf.@sprintf("%#.*g", 15, 0) == Printf.@sprintf("%#.15g", 0) @test Printf.@sprintf("%.*f", 0, 3.0e142) == Printf.@sprintf("%.0f", 3.0e142) @test Printf.@sprintf("%.*f", 2, 1.234) == Printf.@sprintf("%.2f", 1.234) @test Printf.@sprintf("%.*f", 2, 1.235) == Printf.@sprintf("%.2f", 1.235) @test Printf.@sprintf("%.*f", 2, 0.235) == Printf.@sprintf("%.2f", 0.235) @test Printf.@sprintf("%*.*f", 4, 1, 1.234) == Printf.@sprintf("%4.1f", 1.234) @test Printf.@sprintf("%*.*f", 8, 1, 1.234) == Printf.@sprintf("%8.1f", 1.234) @test Printf.@sprintf("%+*.*f", 8, 1, 1.234) == Printf.@sprintf("%+8.1f", 1.234) @test Printf.@sprintf("% *.*f", 8, 1, 1.234) == Printf.@sprintf("% 8.1f", 1.234) @test Printf.@sprintf("% *.*f", 7, 1, 1.234) == Printf.@sprintf("% 7.1f", 1.234) @test Printf.@sprintf("% 0*.*f", 8, 1, 1.234) == Printf.@sprintf("% 08.1f", 1.234) @test Printf.@sprintf("%0*.*f", 8, 1, 1.234) == Printf.@sprintf("%08.1f", 1.234) @test Printf.@sprintf("%-0*.*f", 8, 1, 1.234) == Printf.@sprintf("%-08.1f", 1.234) @test Printf.@sprintf("%-*.*f", 8, 1, 1.234) == Printf.@sprintf("%-8.1f", 1.234) @test Printf.@sprintf("%0*.*f", 8, 1, -1.234) == Printf.@sprintf("%08.1f", -1.234) @test Printf.@sprintf("%0*.*f", 9, 1, -1.234) == Printf.@sprintf("%09.1f", -1.234) @test Printf.@sprintf("%0*.*f", 9, 1, 1.234) == Printf.@sprintf("%09.1f", 1.234) @test Printf.@sprintf("%+0*.*f", 9, 1, 1.234) == Printf.@sprintf("%+09.1f", 1.234) @test Printf.@sprintf("% 0*.*f", 9, 1, 1.234) == Printf.@sprintf("% 09.1f", 1.234) @test Printf.@sprintf("%+ 0*.*f", 9, 1, 1.234) == Printf.@sprintf("%+ 09.1f", 1.234) @test Printf.@sprintf("%+ 0*.*f", 9, 1, 1.234) == Printf.@sprintf("%+ 09.1f", 1.234) @test Printf.@sprintf("%+ 0*.*f", 9, 0, 1.234) == Printf.@sprintf("%+ 09.0f", 1.234) @test Printf.@sprintf("%+ #0*.*f", 9, 0, 1.234) == Printf.@sprintf("%+ #09.0f", 1.234) @test Printf.@sprintf("%*.*e", 10, 4, Inf) == Printf.@sprintf("%10.4e", Inf) @test Printf.@sprintf("%*.*e", 10, 4, NaN) == Printf.@sprintf("%10.4e", NaN) @test Printf.@sprintf("%*.*e", 10, 4, Inf) == Printf.@sprintf("%10.4e", Inf) @test Printf.@sprintf("%*.*e", 10, 4, NaN) == Printf.@sprintf("%10.4e", NaN) @test Printf.@sprintf("%.*e", 0, 3.0e142) == Printf.@sprintf("%.0e", 3.0e142) @test Printf.@sprintf("%#.*e", 0, 3.0e142) == Printf.@sprintf("%#.0e", 3.0e142) @test Printf.@sprintf("%.*e", 0, 2.999999999999999999999999999999999999999999999999999999999999999999999999999996e142) == Printf.@sprintf("%.0e", 2.999999999999999999999999999999999999999999999999999999999999999999999999999996e142) @test Printf.@sprintf("%#.*e", 0, 2.999999999999999999999999999999999999999999999999999999999999999999999999999996e142) == Printf.@sprintf("%#.0e", 2.999999999999999999999999999999999999999999999999999999999999999999999999999996e142) @test Printf.@sprintf("%.*e", 0, 3.000000000000000000000000000000000000000000000000000000000000000000000000000024e1042) == Printf.@sprintf("%.0e", 3.000000000000000000000000000000000000000000000000000000000000000000000000000024e1042) @test Printf.@sprintf("%.*e", 2, 1.234) == Printf.@sprintf("%.2e", 1.234) @test Printf.@sprintf("%.*e", 2, 1.235) == Printf.@sprintf("%.2e", 1.235) @test Printf.@sprintf("%.*e", 2, 0.235) == Printf.@sprintf("%.2e", 0.235) @test Printf.@sprintf("%*.*e", 4, 1, 1.234) == Printf.@sprintf("%4.1e", 1.234) @test Printf.@sprintf("%*.*e", 8, 1, 1.234) == Printf.@sprintf("%8.1e", 1.234) @test Printf.@sprintf("%+*.*e", 8, 1, 1.234) == Printf.@sprintf("%+8.1e", 1.234) @test Printf.@sprintf("% *.*e", 8, 1, 1.234) == Printf.@sprintf("% 8.1e", 1.234) @test Printf.@sprintf("% *.*e", 7, 1, 1.234) == Printf.@sprintf("% 7.1e", 1.234) @test Printf.@sprintf("% 0*.*e", 8, 1, 1.234) == Printf.@sprintf("% 08.1e", 1.234) @test Printf.@sprintf("%0*.*e", 8, 1, 1.234) == Printf.@sprintf("%08.1e", 1.234) @test Printf.@sprintf("%-0*.*e", 8, 1, 1.234) == Printf.@sprintf("%-08.1e", 1.234) @test Printf.@sprintf("%-*.*e", 8, 1, 1.234) == Printf.@sprintf("%-8.1e", 1.234) @test Printf.@sprintf("%-*.*e", 8, 1, 1.234) == Printf.@sprintf("%-8.1e", 1.234) @test Printf.@sprintf("%0*.*e", 8, 1, -1.234) == Printf.@sprintf("%08.1e", -1.234) @test Printf.@sprintf("%0*.*e", 9, 1, -1.234) == Printf.@sprintf("%09.1e", -1.234) @test Printf.@sprintf("%0*.*e", 9, 1, 1.234) == Printf.@sprintf("%09.1e", 1.234) @test Printf.@sprintf("%+0*.*e", 9, 1, 1.234) == Printf.@sprintf("%+09.1e", 1.234) @test Printf.@sprintf("% 0*.*e", 9, 1, 1.234) == Printf.@sprintf("% 09.1e", 1.234) @test Printf.@sprintf("%+ 0*.*e", 9, 1, 1.234) == Printf.@sprintf("%+ 09.1e", 1.234) @test Printf.@sprintf("%+ 0*.*e", 9, 1, 1.234) == Printf.@sprintf("%+ 09.1e", 1.234) @test Printf.@sprintf("%+ 0*.*e", 9, 0, 1.234) == Printf.@sprintf("%+ 09.0e", 1.234) @test Printf.@sprintf("%+ #0*.*e", 9, 0, 1.234) == Printf.@sprintf("%+ #09.0e", 1.234) @test Printf.@sprintf("%.*s", 1, "foo") == Printf.@sprintf("%.1s", "foo") @test Printf.@sprintf("%*s", 1, "Hallo heimur") == Printf.@sprintf("%1s", "Hallo heimur") @test Printf.@sprintf("%*s", 20, "Hallo") == Printf.@sprintf("%20s", "Hallo") @test Printf.@sprintf("%-*s", 20, "Hallo") == Printf.@sprintf("%-20s", "Hallo") @test Printf.@sprintf("%0-*s", 20, "Hallo") == Printf.@sprintf("%0-20s", "Hallo") @test Printf.@sprintf("%.*s", 20, "Hallo heimur") == Printf.@sprintf("%.20s", "Hallo heimur") @test Printf.@sprintf("%*.*s", 20, 5, "Hallo heimur") == Printf.@sprintf("%20.5s", "Hallo heimur") @test Printf.@sprintf("%.*s", 0, "Hallo heimur") == Printf.@sprintf("%.0s", "Hallo heimur") @test Printf.@sprintf("%*.*s", 20, 0, "Hallo heimur") == Printf.@sprintf("%20.0s", "Hallo heimur") @test Printf.@sprintf("%.s", "Hallo heimur") == Printf.@sprintf("%.s", "Hallo heimur") @test Printf.@sprintf("%*.s", 20, "Hallo heimur") == Printf.@sprintf("%20.s", "Hallo heimur") @test Printf.@sprintf("%*sø", 4, "ø") == Printf.@sprintf("%4sø", "ø") @test Printf.@sprintf("%-*sø", 4, "ø") == Printf.@sprintf("%-4sø", "ø") @test Printf.@sprintf("%*s", 8, "test") == Printf.@sprintf("%8s", "test") @test Printf.@sprintf("%-*s", 8, "test") == Printf.@sprintf("%-8s", "test") @test Printf.@sprintf("%#*s", 8, :test) == Printf.@sprintf("%#8s", :test) @test Printf.@sprintf("%#-*s", 8, :test) == Printf.@sprintf("%#-8s", :test) @test Printf.@sprintf("%*.*s", 8, 3, "test") == Printf.@sprintf("%8.3s", "test") @test Printf.@sprintf("%#*.*s", 8, 3, "test") == Printf.@sprintf("%#8.3s", "test") @test Printf.@sprintf("%-*.*s", 8, 3, "test") == Printf.@sprintf("%-8.3s", "test") @test Printf.@sprintf("%#-*.*s", 8, 3, "test") == Printf.@sprintf("%#-8.3s", "test") @test Printf.@sprintf("%.*s", 3, "test") == Printf.@sprintf("%.3s", "test") @test Printf.@sprintf("%#.*s", 3, "test") == Printf.@sprintf("%#.3s", "test") @test Printf.@sprintf("%-.*s", 3, "test") == Printf.@sprintf("%-.3s", "test") @test Printf.@sprintf("%#-.*s", 3, "test") == Printf.@sprintf("%#-.3s", "test") @test Printf.@sprintf("%*c", 3, 'a') == Printf.@sprintf("%3c", 'a') @test Printf.@sprintf("%*c", 1, 'x') == Printf.@sprintf("%1c", 'x') @test Printf.@sprintf("%*c", 20, 'x') == Printf.@sprintf("%20c", 'x') @test Printf.@sprintf("%-*c", 20, 'x') == Printf.@sprintf("%-20c", 'x') @test Printf.@sprintf("%-0*c", 20, 'x') == Printf.@sprintf("%-020c", 'x') @test Printf.@sprintf("%*c", 3, 'A') == Printf.@sprintf("%3c", 'A') @test Printf.@sprintf("%-*c", 3, 'A') == Printf.@sprintf("%-3c", 'A') @test Printf.@sprintf("%*.*f %*.*f %*.*f %*.*f %*.*f %*.*f %*.*f %*.*f %*.*f %*.*f %*.*f %*.*f %*.*f %*.*f %*.*f %*.*f %*.*f %*.*f", 4, 2, 1.2345, 4, 2, 1.2345, 4, 2, 1.2345, 4, 2, 1.2345, 4, 2, 1.2345, 4, 2, 1.2345, 4, 2, 1.2345, 4, 2, 1.2345, 4, 2, 1.2345, 4, 2, 1.2345, 4, 2, 1.2345, 4, 2, 1.2345, 4, 2, 1.2345, 4, 2, 1.2345, 4, 2, 1.2345, 4, 2, 1.2345, 4, 2, 1.2345, 4, 2, 1.2345) == Printf.@sprintf("%4.2f %4.2f %4.2f %4.2f %4.2f %4.2f %4.2f %4.2f %4.2f %4.2f %4.2f %4.2f %4.2f %4.2f %4.2f %4.2f %4.2f %4.2f", 1.2345, 1.2345, 1.2345, 1.2345, 1.2345, 1.2345, 1.2345, 1.2345, 1.2345, 1.2345, 1.2345, 1.2345, 1.2345, 1.2345, 1.2345, 1.2345, 1.2345, 1.2345) @test (Printf.@sprintf("%.*f", 330, BigFloat(1)))[var"end"] != '\0' @test Printf.@sprintf("%*.*s", 4, 2, "a") == Printf.@sprintf("%4.2s", "a") @test Printf.@sprintf("%*.*e", 12, 3, pi * 1.0e100) == Printf.@sprintf("%12.3e", pi * 1.0e100) @test Printf.@sprintf("%*d", 2, 3.14) == Printf.@sprintf("%*d", 2, 3.14) @test Printf.@sprintf("%*d", 2, big(3.14)) == Printf.@sprintf("%*d", 2, big(3.14)) @test Printf.@sprintf(" %.*e\n", 1, 0.999) == Printf.@sprintf(" %.1e\n", 0.999) @test Printf.@sprintf(" %.*f", 1, 9.999) == Printf.@sprintf(" %.1f", 9.999) @test Printf.@sprintf("%*d", 10, 12) == Printf.@sprintf("%10d", 12) @test Printf.@sprintf("%.*d", 4, 12) == Printf.@sprintf("%.4d", 12) @test Printf.@sprintf("%*.*d", 10, 4, 12) == Printf.@sprintf("%10.4d", 12) @test Printf.@sprintf("%+*.*d", 10, 4, 12) == Printf.@sprintf("%+10.4d", 12) @test Printf.@sprintf("%0*.*d", 10, 4, 12) == Printf.@sprintf("%010.4d", 12) @test Printf.@sprintf("% *d", 5, 42) == Printf.@sprintf("% 5d", 42) @test Printf.@sprintf("% *d", 5, -42) == Printf.@sprintf("% 5d", -42) @test Printf.@sprintf("% *d", 15, 42) == Printf.@sprintf("% 15d", 42) @test Printf.@sprintf("% *d", 15, -42) == Printf.@sprintf("% 15d", -42) @test Printf.@sprintf("%+*d", 5, 42) == Printf.@sprintf("%+5d", 42) @test Printf.@sprintf("%+*d", 5, -42) == Printf.@sprintf("%+5d", -42) @test Printf.@sprintf("%+*d", 15, 42) == Printf.@sprintf("%+15d", 42) @test Printf.@sprintf("%+*d", 15, -42) == Printf.@sprintf("%+15d", -42) @test Printf.@sprintf("%*d", 0, 42) == Printf.@sprintf("%0d", 42) @test Printf.@sprintf("%*d", 0, -42) == Printf.@sprintf("%0d", -42) @test Printf.@sprintf("%-*d", 5, 42) == Printf.@sprintf("%-5d", 42) @test Printf.@sprintf("%-*d", 5, -42) == Printf.@sprintf("%-5d", -42) @test Printf.@sprintf("%-*d", 15, 42) == Printf.@sprintf("%-15d", 42) @test Printf.@sprintf("%-*d", 15, -42) == Printf.@sprintf("%-15d", -42) @test Printf.@sprintf("%+*lld", 8, 100) == Printf.@sprintf("%+8lld", 100) @test Printf.@sprintf("%+.*lld", 8, 100) == Printf.@sprintf("%+.8lld", 100) @test Printf.@sprintf("%+*.*lld", 10, 8, 100) == Printf.@sprintf("%+10.8lld", 100) @test Printf.@sprintf("%-*.*lld", 1, 5, -100) == Printf.@sprintf("%-1.5lld", -100) @test Printf.@sprintf("%*lld", 5, 100) == Printf.@sprintf("%5lld", 100) @test Printf.@sprintf("%*lld", 5, -100) == Printf.@sprintf("%5lld", -100) @test Printf.@sprintf("%-*lld", 5, 100) == Printf.@sprintf("%-5lld", 100) @test Printf.@sprintf("%-*lld", 5, -100) == Printf.@sprintf("%-5lld", -100) @test Printf.@sprintf("%-.*lld", 5, 100) == Printf.@sprintf("%-.5lld", 100) @test Printf.@sprintf("%-.*lld", 5, -100) == Printf.@sprintf("%-.5lld", -100) @test Printf.@sprintf("%-*.*lld", 8, 5, 100) == Printf.@sprintf("%-8.5lld", 100) @test Printf.@sprintf("%-*.*lld", 8, 5, -100) == Printf.@sprintf("%-8.5lld", -100) @test Printf.@sprintf("%0*lld", 5, 100) == Printf.@sprintf("%05lld", 100) @test Printf.@sprintf("%0*lld", 5, -100) == Printf.@sprintf("%05lld", -100) @test Printf.@sprintf("% *lld", 5, 100) == Printf.@sprintf("% 5lld", 100) @test Printf.@sprintf("% *lld", 5, -100) == Printf.@sprintf("% 5lld", -100) @test Printf.@sprintf("% .*lld", 5, 100) == Printf.@sprintf("% .5lld", 100) @test Printf.@sprintf("% .*lld", 5, -100) == Printf.@sprintf("% .5lld", -100) @test Printf.@sprintf("% *.*lld", 8, 5, 100) == Printf.@sprintf("% 8.5lld", 100) @test Printf.@sprintf("% *.*lld", 8, 5, -100) == Printf.@sprintf("% 8.5lld", -100) @test Printf.@sprintf("%.*lld", 0, 0) == Printf.@sprintf("%.0lld", 0) @test Printf.@sprintf("%#+*.*llx", 21, 18, -100) == Printf.@sprintf("%#+21.18llx", -100) @test Printf.@sprintf("%#.*llo", 25, -100) == Printf.@sprintf("%#.25llo", -100) @test Printf.@sprintf("%#+*.*llo", 24, 20, -100) == Printf.@sprintf("%#+24.20llo", -100) @test Printf.@sprintf("%#+*.*llX", 18, 21, -100) == Printf.@sprintf("%#+18.21llX", -100) @test Printf.@sprintf("%#+*.*llo", 20, 24, -100) == Printf.@sprintf("%#+20.24llo", -100) @test Printf.@sprintf("%#+*.*llu", 25, 22, -1) == Printf.@sprintf("%#+25.22llu", -1) @test Printf.@sprintf("%#+*.*llu", 30, 25, -1) == Printf.@sprintf("%#+30.25llu", -1) @test Printf.@sprintf("%+#*.*lld", 25, 22, -1) == Printf.@sprintf("%+#25.22lld", -1) @test Printf.@sprintf("%#-*.*llo", 8, 5, 100) == Printf.@sprintf("%#-8.5llo", 100) @test Printf.@sprintf("%#-+ 0*.*lld", 8, 5, 100) == Printf.@sprintf("%#-+ 08.5lld", 100) @test Printf.@sprintf("%#-+ 0*.*lld", 8, 5, 100) == Printf.@sprintf("%#-+ 08.5lld", 100) @test Printf.@sprintf("%.*lld", 40, 1) == Printf.@sprintf("%.40lld", 1) @test Printf.@sprintf("% .*lld", 40, 1) == Printf.@sprintf("% .40lld", 1) @test Printf.@sprintf("% .*d", 40, 1) == Printf.@sprintf("% .40d", 1) @test Printf.@sprintf("%#0*x", 12, 1) == Printf.@sprintf("%#012x", 1) @test Printf.@sprintf("%#0*.*x", 4, 8, 1) == Printf.@sprintf("%#04.8x", 1) @test Printf.@sprintf("%#-0*.*x", 8, 2, 1) == Printf.@sprintf("%#-08.2x", 1) @test Printf.@sprintf("%#0*o", 8, 1) == Printf.@sprintf("%#08o", 1) @test Printf.@sprintf("%*d", 20, 1024) == Printf.@sprintf("%20d", 1024) @test Printf.@sprintf("%*d", 20, -1024) == Printf.@sprintf("%20d", -1024) @test Printf.@sprintf("%*i", 20, 1024) == Printf.@sprintf("%20i", 1024) @test Printf.@sprintf("%*i", 20, -1024) == Printf.@sprintf("%20i", -1024) @test Printf.@sprintf("%*u", 20, 1024) == Printf.@sprintf("%20u", 1024) @test Printf.@sprintf("%*u", 20, UInt(4294966272)) == Printf.@sprintf("%20u", UInt(4294966272)) @test Printf.@sprintf("%*o", 20, 511) == Printf.@sprintf("%20o", 511) @test Printf.@sprintf("%*o", 20, UInt(4294966785)) == Printf.@sprintf("%20o", UInt(4294966785)) @test Printf.@sprintf("%*x", 20, 305441741) == Printf.@sprintf("%20x", 305441741) @test Printf.@sprintf("%*x", 20, UInt(3989525555)) == Printf.@sprintf("%20x", UInt(3989525555)) @test Printf.@sprintf("%*X", 20, 305441741) == Printf.@sprintf("%20X", 305441741) @test Printf.@sprintf("%*X", 20, UInt(3989525555)) == Printf.@sprintf("%20X", UInt(3989525555)) @test Printf.@sprintf("%-*d", 20, 1024) == Printf.@sprintf("%-20d", 1024) @test Printf.@sprintf("%-*d", 20, -1024) == Printf.@sprintf("%-20d", -1024) @test Printf.@sprintf("%-*i", 20, 1024) == Printf.@sprintf("%-20i", 1024) @test Printf.@sprintf("%-*i", 20, -1024) == Printf.@sprintf("%-20i", -1024) @test Printf.@sprintf("%-*u", 20, 1024) == Printf.@sprintf("%-20u", 1024) @test Printf.@sprintf("%-*u", 20, UInt(4294966272)) == Printf.@sprintf("%-20u", UInt(4294966272)) @test Printf.@sprintf("%-*o", 20, 511) == Printf.@sprintf("%-20o", 511) @test Printf.@sprintf("%-*o", 20, UInt(4294966785)) == Printf.@sprintf("%-20o", UInt(4294966785)) @test Printf.@sprintf("%-*x", 20, 305441741) == Printf.@sprintf("%-20x", 305441741) @test Printf.@sprintf("%-*x", 20, UInt(3989525555)) == Printf.@sprintf("%-20x", UInt(3989525555)) @test Printf.@sprintf("%-*X", 20, 305441741) == Printf.@sprintf("%-20X", 305441741) @test Printf.@sprintf("%-*X", 20, UInt(3989525555)) == Printf.@sprintf("%-20X", UInt(3989525555)) @test Printf.@sprintf("%0*d", 20, 1024) == Printf.@sprintf("%020d", 1024) @test Printf.@sprintf("%0*d", 20, -1024) == Printf.@sprintf("%020d", -1024) @test Printf.@sprintf("%0*i", 20, 1024) == Printf.@sprintf("%020i", 1024) @test Printf.@sprintf("%0*i", 20, -1024) == Printf.@sprintf("%020i", -1024) @test Printf.@sprintf("%0*u", 20, 1024) == Printf.@sprintf("%020u", 1024) @test Printf.@sprintf("%0*u", 20, UInt(4294966272)) == Printf.@sprintf("%020u", UInt(4294966272)) @test Printf.@sprintf("%0*o", 20, 511) == Printf.@sprintf("%020o", 511) @test Printf.@sprintf("%0*o", 20, UInt(4294966785)) == Printf.@sprintf("%020o", UInt(4294966785)) @test Printf.@sprintf("%0*x", 20, 305441741) == Printf.@sprintf("%020x", 305441741) @test Printf.@sprintf("%0*x", 20, UInt(3989525555)) == Printf.@sprintf("%020x", UInt(3989525555)) @test Printf.@sprintf("%0*X", 20, 305441741) == Printf.@sprintf("%020X", 305441741) @test Printf.@sprintf("%0*X", 20, UInt(3989525555)) == Printf.@sprintf("%020X", UInt(3989525555)) @test Printf.@sprintf("%#*o", 20, 511) == Printf.@sprintf("%#20o", 511) @test Printf.@sprintf("%#*o", 20, UInt(4294966785)) == Printf.@sprintf("%#20o", UInt(4294966785)) @test Printf.@sprintf("%#*x", 20, 305441741) == Printf.@sprintf("%#20x", 305441741) @test Printf.@sprintf("%#*x", 20, UInt(3989525555)) == Printf.@sprintf("%#20x", UInt(3989525555)) @test Printf.@sprintf("%#*X", 20, 305441741) == Printf.@sprintf("%#20X", 305441741) @test Printf.@sprintf("%#*X", 20, UInt(3989525555)) == Printf.@sprintf("%#20X", UInt(3989525555)) @test Printf.@sprintf("%#0*o", 20, 511) == Printf.@sprintf("%#020o", 511) @test Printf.@sprintf("%#0*o", 20, UInt(4294966785)) == Printf.@sprintf("%#020o", UInt(4294966785)) @test Printf.@sprintf("%#0*x", 20, 305441741) == Printf.@sprintf("%#020x", 305441741) @test Printf.@sprintf("%#0*x", 20, UInt(3989525555)) == Printf.@sprintf("%#020x", UInt(3989525555)) @test Printf.@sprintf("%#0*X", 20, 305441741) == Printf.@sprintf("%#020X", 305441741) @test Printf.@sprintf("%#0*X", 20, UInt(3989525555)) == Printf.@sprintf("%#020X", UInt(3989525555)) @test Printf.@sprintf("%0-*d", 20, 1024) == Printf.@sprintf("%0-20d", 1024) @test Printf.@sprintf("%0-*d", 20, -1024) == Printf.@sprintf("%0-20d", -1024) @test Printf.@sprintf("%0-*i", 20, 1024) == Printf.@sprintf("%0-20i", 1024) @test Printf.@sprintf("%0-*i", 20, -1024) == Printf.@sprintf("%0-20i", -1024) @test Printf.@sprintf("%0-*u", 20, 1024) == Printf.@sprintf("%0-20u", 1024) @test Printf.@sprintf("%0-*u", 20, UInt(4294966272)) == Printf.@sprintf("%0-20u", UInt(4294966272)) @test Printf.@sprintf("%-0*o", 20, 511) == Printf.@sprintf("%-020o", 511) @test Printf.@sprintf("%-0*o", 20, UInt(4294966785)) == Printf.@sprintf("%-020o", UInt(4294966785)) @test Printf.@sprintf("%-0*x", 20, 305441741) == Printf.@sprintf("%-020x", 305441741) @test Printf.@sprintf("%-0*x", 20, UInt(3989525555)) == Printf.@sprintf("%-020x", UInt(3989525555)) @test Printf.@sprintf("%-0*X", 20, 305441741) == Printf.@sprintf("%-020X", 305441741) @test Printf.@sprintf("%-0*X", 20, UInt(3989525555)) == Printf.@sprintf("%-020X", UInt(3989525555)) @test Printf.@sprintf("%.*d", 20, 1024) == Printf.@sprintf("%.20d", 1024) @test Printf.@sprintf("%.*d", 20, -1024) == Printf.@sprintf("%.20d", -1024) @test Printf.@sprintf("%.*i", 20, 1024) == Printf.@sprintf("%.20i", 1024) @test Printf.@sprintf("%.*i", 20, -1024) == Printf.@sprintf("%.20i", -1024) @test Printf.@sprintf("%.*u", 20, 1024) == Printf.@sprintf("%.20u", 1024) @test Printf.@sprintf("%.*u", 20, UInt(4294966272)) == Printf.@sprintf("%.20u", UInt(4294966272)) @test Printf.@sprintf("%.*o", 20, 511) == Printf.@sprintf("%.20o", 511) @test Printf.@sprintf("%.*o", 20, UInt(4294966785)) == Printf.@sprintf("%.20o", UInt(4294966785)) @test Printf.@sprintf("%.*x", 20, 305441741) == Printf.@sprintf("%.20x", 305441741) @test Printf.@sprintf("%.*x", 20, UInt(3989525555)) == Printf.@sprintf("%.20x", UInt(3989525555)) @test Printf.@sprintf("%.*X", 20, 305441741) == Printf.@sprintf("%.20X", 305441741) @test Printf.@sprintf("%.*X", 20, UInt(3989525555)) == Printf.@sprintf("%.20X", UInt(3989525555)) @test Printf.@sprintf("%*.*d", 20, 5, 1024) == Printf.@sprintf("%20.5d", 1024) @test Printf.@sprintf("%*.*d", 20, 5, -1024) == Printf.@sprintf("%20.5d", -1024) @test Printf.@sprintf("%*.*i", 20, 5, 1024) == Printf.@sprintf("%20.5i", 1024) @test Printf.@sprintf("%*.*i", 20, 5, -1024) == Printf.@sprintf("%20.5i", -1024) @test Printf.@sprintf("%*.*u", 20, 5, 1024) == Printf.@sprintf("%20.5u", 1024) @test Printf.@sprintf("%*.*u", 20, 5, UInt(4294966272)) == Printf.@sprintf("%20.5u", UInt(4294966272)) @test Printf.@sprintf("%*.*o", 20, 5, 511) == Printf.@sprintf("%20.5o", 511) @test Printf.@sprintf("%*.*o", 20, 5, UInt(4294966785)) == Printf.@sprintf("%20.5o", UInt(4294966785)) @test Printf.@sprintf("%*.*x", 20, 5, 305441741) == Printf.@sprintf("%20.5x", 305441741) @test Printf.@sprintf("%*.*x", 20, 10, UInt(3989525555)) == Printf.@sprintf("%20.10x", UInt(3989525555)) @test Printf.@sprintf("%*.*X", 20, 5, 305441741) == Printf.@sprintf("%20.5X", 305441741) @test Printf.@sprintf("%*.*X", 20, 10, UInt(3989525555)) == Printf.@sprintf("%20.10X", UInt(3989525555)) @test Printf.@sprintf("%0*.*d", 20, 5, 1024) == Printf.@sprintf("%020.5d", 1024) @test Printf.@sprintf("%0*.*d", 20, 5, -1024) == Printf.@sprintf("%020.5d", -1024) @test Printf.@sprintf("%0*.*i", 20, 5, 1024) == Printf.@sprintf("%020.5i", 1024) @test Printf.@sprintf("%0*.*i", 20, 5, -1024) == Printf.@sprintf("%020.5i", -1024) @test Printf.@sprintf("%0*.*u", 20, 5, 1024) == Printf.@sprintf("%020.5u", 1024) @test Printf.@sprintf("%0*.*u", 20, 5, UInt(4294966272)) == Printf.@sprintf("%020.5u", UInt(4294966272)) @test Printf.@sprintf("%0*.*o", 20, 5, 511) == Printf.@sprintf("%020.5o", 511) @test Printf.@sprintf("%0*.*o", 20, 5, UInt(4294966785)) == Printf.@sprintf("%020.5o", UInt(4294966785)) @test Printf.@sprintf("%0*.*x", 20, 5, 305441741) == Printf.@sprintf("%020.5x", 305441741) @test Printf.@sprintf("%0*.*x", 20, 10, UInt(3989525555)) == Printf.@sprintf("%020.10x", UInt(3989525555)) @test Printf.@sprintf("%0*.*X", 20, 5, 305441741) == Printf.@sprintf("%020.5X", 305441741) @test Printf.@sprintf("%0*.*X", 20, 10, UInt(3989525555)) == Printf.@sprintf("%020.10X", UInt(3989525555)) @test Printf.@sprintf("%*.0d", 20, 1024) == Printf.@sprintf("%20.0d", 1024) @test Printf.@sprintf("%*.d", 20, -1024) == Printf.@sprintf("%20.d", -1024) @test Printf.@sprintf("%*.d", 20, 0) == Printf.@sprintf("%20.d", 0) @test Printf.@sprintf("%*.0i", 20, 1024) == Printf.@sprintf("%20.0i", 1024) @test Printf.@sprintf("%*.i", 20, -1024) == Printf.@sprintf("%20.i", -1024) @test Printf.@sprintf("%*.i", 20, 0) == Printf.@sprintf("%20.i", 0) @test Printf.@sprintf("%*.u", 20, 1024) == Printf.@sprintf("%20.u", 1024) @test Printf.@sprintf("%*.0u", 20, UInt(4294966272)) == Printf.@sprintf("%20.0u", UInt(4294966272)) @test Printf.@sprintf("%*.u", 20, UInt(0)) == Printf.@sprintf("%20.u", UInt(0)) @test Printf.@sprintf("%*.o", 20, 511) == Printf.@sprintf("%20.o", 511) @test Printf.@sprintf("%*.0o", 20, UInt(4294966785)) == Printf.@sprintf("%20.0o", UInt(4294966785)) @test Printf.@sprintf("%*.o", 20, UInt(0)) == Printf.@sprintf("%20.o", UInt(0)) @test Printf.@sprintf("%*.x", 20, 305441741) == Printf.@sprintf("%20.x", 305441741) @test Printf.@sprintf("%*.0x", 20, UInt(3989525555)) == Printf.@sprintf("%20.0x", UInt(3989525555)) @test Printf.@sprintf("%*.x", 20, UInt(0)) == Printf.@sprintf("%20.x", UInt(0)) @test Printf.@sprintf("%*.X", 20, 305441741) == Printf.@sprintf("%20.X", 305441741) @test Printf.@sprintf("%*.0X", 20, UInt(3989525555)) == Printf.@sprintf("%20.0X", UInt(3989525555)) @test Printf.@sprintf("%*.X", 20, UInt(0)) == Printf.@sprintf("%20.X", UInt(0)) x = Ref{Int}() y = Ref{Int}() @test begin Printf.@sprintf "%10s%n" "😉" x Printf.@sprintf "%*s%n" 10 "😉" y x[] == y[] end @test begin Printf.@sprintf "%10s%n" "1234" x Printf.@sprintf "%*s%n" 10 "1234" y x[] == y[] end end @testset "length modifiers" begin @test_throws Printf.InvalidFormatStringError Printf.Format("%h") @test_throws Printf.InvalidFormatStringError Printf.Format("%hh") @test_throws Printf.InvalidFormatStringError Printf.Format("%z") end @testset "Docstrings" begin @test isempty(Docs.undocumented_names(Printf)) end @test @sprintf("%.160g", 1.38e-23) == "1.380000000000000060010582465734078799297660966782642624395399644741944111814291318296454846858978271484375e-23" end @testset "Printf" begin @testset "%p" begin if Sys.WORD_SIZE == 64 @test Printf.@sprintf("%20p", 0) == " 0x0000000000000000" @test Printf.@sprintf("%-20p", 0) == "0x0000000000000000 " @test Printf.@sprintf("%20p", C_NULL) == " 0x0000000000000000" @test @sprintf("%-20p", C_NULL) == "0x0000000000000000 " elseif Sys.WORD_SIZE == 32 @test Printf.@sprintf("%20p", 0) == " 0x00000000" @test Printf.@sprintf("%-20p", 0) == "0x00000000 " @test @sprintf("%20p", C_NULL) == " 0x00000000" @test @sprintf("%-20p", C_NULL) == "0x00000000 " end @test @sprintf("%p", 0xfffffffffffe0000) == "0xfffffffffffe0000" end @testset "%a" begin @test Printf.@sprintf("%a", 0.0) == "0x0p+0" @test Printf.@sprintf("%a", -0.0) == "-0x0p+0" @test Printf.@sprintf("%.3a", 0.0) == "0x0.000p+0" @test Printf.@sprintf("%a", 1.5) == "0x1.8p+0" @test Printf.@sprintf("%a", 1.5f0) == "0x1.8p+0" @test Printf.@sprintf("%a", 1.5) == "0x1.8p+0" @test Printf.@sprintf("%#.0a", 1.5) == "0x2.p+0" @test Printf.@sprintf("%+30a", 1 / 3) == " +0x1.5555555555555p-2" @test Printf.@sprintf("%a", 1.5) == "0x1.8p+0" @test Printf.@sprintf("%a", 3.14) == "0x1.91eb851eb851fp+1" @test Printf.@sprintf("%.0a", 3.14) == "0x2p+1" @test Printf.@sprintf("%.1a", 3.14) == "0x1.9p+1" @test Printf.@sprintf("%.2a", 3.14) == "0x1.92p+1" @test Printf.@sprintf("%#a", 3.14) == "0x1.91eb851eb851fp+1" @test Printf.@sprintf("%#.0a", 3.14) == "0x2.p+1" @test Printf.@sprintf("%#.1a", 3.14) == "0x1.9p+1" @test Printf.@sprintf("%#.2a", 3.14) == "0x1.92p+1" @test Printf.@sprintf("%.6a", 1.5) == "0x1.800000p+0" end @testset "%g" begin for (val, res) = ((1.2345678e7, "1.23457e+07"), (1.2345678e6, "1.23457e+06"), (123456.78, "123457"), (12345.678, "12345.7"), (1.234e7, "1.234e+07")) @test Printf.@sprintf("%.6g", val) == res end for (val, res) = ((1.2345678e7, "1.23457e+07"), (1.234567799999999999999999999999999999999999999999999999999999999999999999999993e6, "1.23457e+06"), (123456.7800000000000000000000000000000000000000000000000000000000000000000000004, "123457"), (12345.67800000000000000000000000000000000000000000000000000000000000000000000007, "12345.7")) @test Printf.@sprintf("%.6g", val) == res end for (fmt, val) = (("%10.5g", " 123.4"), ("%+10.5g", " +123.4"), ("% 10.5g", " 123.4"), ("%#10.5g", " 123.40"), ("%-10.5g", "123.4 "), ("%-+10.5g", "+123.4 "), ("%010.5g", "00000123.4")), num = (123.4, 123.4000000000000000000000000000000000000000000000000000000000000000000000000002) @test Printf.format(Printf.Format(fmt), num) == val end @test Printf.@sprintf("%10.5g", -123.4) == " -123.4" @test Printf.@sprintf("%010.5g", -123.4) == "-0000123.4" @test Printf.@sprintf("%.6g", 1.234e7) == "1.234e+07" @test Printf.@sprintf("%#.6g", 1.234e7) == "1.23400e+07" @test Printf.@sprintf("%10.5g", -123.4000000000000000000000000000000000000000000000000000000000000000000000000002) == " -123.4" @test Printf.@sprintf("%010.5g", -123.4000000000000000000000000000000000000000000000000000000000000000000000000002) == "-0000123.4" @test Printf.@sprintf("%.6g", 1.234e7) == "1.234e+07" @test Printf.@sprintf("%#.6g", 1.234e7) == "1.23400e+07" @test Printf.@sprintf("%.5g", 42) == "42" @test Printf.@sprintf("%#.2g", 42) == "42." @test Printf.@sprintf("%#.5g", 42) == "42.000" @test Printf.@sprintf("%g", 0.00012) == "0.00012" @test Printf.@sprintf("%g", 1.2e-5) == "1.2e-05" @test Printf.@sprintf("%g", 123456.7) == "123457" @test Printf.@sprintf("%g", 1.2345678e6) == "1.23457e+06" for (val, res) = ((Inf, "Inf"), (-Inf, "-Inf"), (NaN, "NaN"), (-NaN, "NaN")) @test Printf.@sprintf("%g", val) == res @test Printf.@sprintf("%G", val) == res end @test Printf.@sprintf("%.15g", 0) == "0" @test Printf.@sprintf("%#.15g", 0) == "0.00000000000000" end @testset "%f" begin @test Printf.@sprintf("%f", Inf) == "Inf" @test Printf.@sprintf("%+f", Inf) == "+Inf" @test Printf.@sprintf("% f", Inf) == " Inf" @test Printf.@sprintf("% #f", Inf) == " Inf" @test Printf.@sprintf("%07f", Inf) == " Inf" @test Printf.@sprintf("%f", -Inf) == "-Inf" @test Printf.@sprintf("%+f", -Inf) == "-Inf" @test Printf.@sprintf("%07f", -Inf) == " -Inf" @test Printf.@sprintf("%f", NaN) == "NaN" @test Printf.@sprintf("%+f", NaN) == "+NaN" @test Printf.@sprintf("% f", NaN) == " NaN" @test Printf.@sprintf("% #f", NaN) == " NaN" @test Printf.@sprintf("%07f", NaN) == " NaN" @test Printf.@sprintf("%e", Inf) == "Inf" @test Printf.@sprintf("%e", NaN) == "NaN" @test Printf.@sprintf("%.0f", 3.0e142) == "29999999999999997463140672961703247153805615792184250659629251954072073858354858644285983761764971823910371920726635399393477049701891710124032" @test Printf.@sprintf("%f", 1.234) == "1.234000" @test Printf.@sprintf("%F", 1.234) == "1.234000" @test Printf.@sprintf("%+f", 1.234) == "+1.234000" @test Printf.@sprintf("% f", 1.234) == " 1.234000" @test Printf.@sprintf("%f", -1.234) == "-1.234000" @test Printf.@sprintf("%+f", -1.234) == "-1.234000" @test Printf.@sprintf("% f", -1.234) == "-1.234000" @test Printf.@sprintf("%#f", 1.234) == "1.234000" @test Printf.@sprintf("%.2f", 1.234) == "1.23" @test Printf.@sprintf("%.2f", 1.235) == "1.24" @test Printf.@sprintf("%.2f", 0.235) == "0.23" @test Printf.@sprintf("%4.1f", 1.234) == " 1.2" @test Printf.@sprintf("%8.1f", 1.234) == " 1.2" @test Printf.@sprintf("%+8.1f", 1.234) == " +1.2" @test Printf.@sprintf("% 8.1f", 1.234) == " 1.2" @test Printf.@sprintf("% 7.1f", 1.234) == " 1.2" @test Printf.@sprintf("% 08.1f", 1.234) == " 00001.2" @test Printf.@sprintf("%08.1f", 1.234) == "000001.2" @test Printf.@sprintf("%-08.1f", 1.234) == "1.2 " @test Printf.@sprintf("%-8.1f", 1.234) == "1.2 " @test Printf.@sprintf("%08.1f", -1.234) == "-00001.2" @test Printf.@sprintf("%09.1f", -1.234) == "-000001.2" @test Printf.@sprintf("%09.1f", 1.234) == "0000001.2" @test Printf.@sprintf("%+09.1f", 1.234) == "+000001.2" @test Printf.@sprintf("% 09.1f", 1.234) == " 000001.2" @test Printf.@sprintf("%+ 09.1f", 1.234) == "+000001.2" @test Printf.@sprintf("%+ 09.1f", 1.234) == "+000001.2" @test Printf.@sprintf("%+ 09.0f", 1.234) == "+00000001" @test Printf.@sprintf("%+ #09.0f", 1.234) == "+0000001." @test Printf.@sprintf("%+7.1f", 9.96) == " +10.0" @test Printf.@sprintf("% 7.1f", 9.96) == " 10.0" end @testset "%e" begin @test Printf.@sprintf("%e", Inf) == "Inf" @test Printf.@sprintf("%+e", Inf) == "+Inf" @test Printf.@sprintf("% e", Inf) == " Inf" @test Printf.@sprintf("% #e", Inf) == " Inf" @test Printf.@sprintf("%07e", Inf) == " Inf" @test Printf.@sprintf("%e", -Inf) == "-Inf" @test Printf.@sprintf("%+e", -Inf) == "-Inf" @test Printf.@sprintf("%07e", -Inf) == " -Inf" @test Printf.@sprintf("%e", NaN) == "NaN" @test Printf.@sprintf("%+e", NaN) == "+NaN" @test Printf.@sprintf("% e", NaN) == " NaN" @test Printf.@sprintf("% #e", NaN) == " NaN" @test Printf.@sprintf("%07e", NaN) == " NaN" PkgEval terminated after 210.49s: test log exceeded the size limit