From 4ffeada3c7e8e79f70d7abd5775c34bc84a1e622 Mon Sep 17 00:00:00 2001 From: Christoffer Lerno Date: Sun, 12 Mar 2023 00:22:17 +0100 Subject: [PATCH] Updated stdlib. Prefer file::open. Fix to slice assign with distinct types. --- lib/std/core/string.c3 | 2 +- lib/std/io/io.c3 | 2 +- lib/std/io/io_file.c3 | 10 +++-- lib/std/io/io_fileinfo.c3 | 2 + lib/std/io/io_path.c3 | 37 +++---------------- lib/std/io/os/file.c3 | 26 ++++++------- lib/std/io/os/fileinfo_other.c3 | 17 +++++---- lib/std/io/os/fileinfo_win32.c3 | 7 ++-- resources/examples/load_world.c3 | 3 +- src/compiler/sema_expr.c | 2 +- src/version.h | 2 +- .../methods/enum_distinct_err_methods.c3t | 24 +++++------- 12 files changed, 54 insertions(+), 80 deletions(-) diff --git a/lib/std/core/string.c3 b/lib/std/core/string.c3 index 71829568f..6e7c3d077 100644 --- a/lib/std/core/string.c3 +++ b/lib/std/core/string.c3 @@ -158,7 +158,7 @@ fn String[] String.split(String s, String needle, usz max = 0, Allocator* using * @param [in] needle * @param max "Max number of elements, 0 means no limit, defaults to 0" **/ -fn String[] tsplit(String s, String needle, usz max = 0) +fn String[] String.tsplit(String s, String needle, usz max = 0) { return s.split(needle, max, mem::temp()) @inline; } diff --git a/lib/std/io/io.c3 b/lib/std/io/io.c3 index da9328ba8..0a09ac671 100644 --- a/lib/std/io/io.c3 +++ b/lib/std/io/io.c3 @@ -92,7 +92,7 @@ macro void printn(x = "") $endswitch; } -macro void println(x = "") => printn(x); +macro void println(x = "") @deprecated => printn(x); fn File stdout() { diff --git a/lib/std/io/io_file.c3 b/lib/std/io/io_file.c3 index 910ddb60a..3d8f67c2f 100644 --- a/lib/std/io/io_file.c3 +++ b/lib/std/io/io_file.c3 @@ -1,8 +1,12 @@ -module std::io; +module std::io::file; import libc; +fn File! open(String filename, String mode) +{ + return { .file = os::native_fopen(filename, mode) }; +} -fn void! File.open(File* file, String filename, String mode) +fn void! File.open(File* file, String filename, String mode) @deprecated { file.file = os::native_fopen(filename, mode)?; } @@ -123,7 +127,7 @@ fn usz! File.print(File file, String string) return len; } -fn usz! File.println(File file, String string) => file.printn(string); +fn usz! File.println(File file, String string) @deprecated => file.printn(string); /** * @param [&in] file diff --git a/lib/std/io/io_fileinfo.c3 b/lib/std/io/io_fileinfo.c3 index 644298d8e..3294017f5 100644 --- a/lib/std/io/io_fileinfo.c3 +++ b/lib/std/io/io_fileinfo.c3 @@ -1,6 +1,8 @@ module std::io::file; import libc; + + fn bool is_file(String path) { return os::native_is_file(path); diff --git a/lib/std/io/io_path.c3 b/lib/std/io/io_path.c3 index e65313613..c047d710d 100644 --- a/lib/std/io/io_path.c3 +++ b/lib/std/io/io_path.c3 @@ -35,15 +35,12 @@ fn Path! getcwd(Allocator* using = mem::heap()) }; } -fn Path! tgetcwd() -{ - return getcwd(mem::temp()) @inline; -} - -fn bool is_dir(String path) -{ - return os::native_is_dir(path); -} +fn bool is_dir(Path path) => os::native_is_dir(path.as_str()); +fn bool is_file(Path path) => os::native_is_file(path.as_str()); +fn usz! file_size(Path path) => os::native_file_size(path.as_str()); +fn bool exists(Path path) => os::native_file_or_dir_exists(path.as_str()); +fn Path! tgetcwd() => getcwd(mem::temp()) @inline; +fn Path! temp_directory(Allocator* using = mem::heap()) => os::native_temp_directory(using); macro bool is_separator(char c, PathEnv path_env = DEFAULT_PATH_ENV) { @@ -105,10 +102,6 @@ fn Path! Path.append(Path path, String filename, Allocator* using = mem::heap()) fn Path! Path.tappend(Path path, String filename) => path.append(filename, mem::temp()); -fn Path! temp_directory(Allocator* using = mem::heap()) -{ - return os::native_temp_directory(using); -} fn String Path.volume_name(Path path) { @@ -287,36 +280,18 @@ fn String Path.root_directory(Path path) return path_str; } -fn usz! Path.file_size(Path path) -{ - return os::native_file_size(path.as_str()); -} fn String Path.as_str(Path path) { return path.path_string; } -fn bool Path.file_or_dir_exists(Path path) -{ - return os::native_file_or_dir_exists(path.as_str()); -} - -fn bool Path.is_dir(Path path) -{ - return os::native_is_dir(path.as_str()); -} fn bool Path.has_suffix(Path path, String str) { return path.as_str().ends_with(str); } -fn bool Path.is_file(Path path) -{ - return os::native_is_file(path.as_str()); -} - fn void Path.free(Path path) { diff --git a/lib/std/io/os/file.c3 b/lib/std/io/os/file.c3 index 91429fc5c..3cfaa561b 100644 --- a/lib/std/io/os/file.c3 +++ b/lib/std/io/os/file.c3 @@ -1,13 +1,13 @@ module std::io::os; import libc; -define FopenFn = fn CFile!(String, String); -define FreopenFn = fn CFile!(CFile, String, String); -define FcloseFn = fn void!(CFile); -define FseekFn = fn void!(CFile, isz, Seek); -define FtellFn = fn usz!(CFile); -define FwriteFn = fn usz!(CFile, char[] buffer); -define FreadFn = fn usz!(CFile, char[] buffer); +define FopenFn = fn void*!(String, String); +define FreopenFn = fn void*!(void*, String, String); +define FcloseFn = fn void!(void*); +define FseekFn = fn void!(void*, isz, Seek); +define FtellFn = fn usz!(void*); +define FwriteFn = fn usz!(void*, char[] buffer); +define FreadFn = fn usz!(void*, char[] buffer); $if (!$defined(native_fopen_fn)): FopenFn native_fopen_fn @weak; @@ -36,7 +36,7 @@ $endif; * @require mode.len > 0 * @require filename.len > 0 **/ -fn CFile! native_fopen(String filename, String mode) @inline +fn void*! native_fopen(String filename, String mode) @inline { $if (!env::COMPILER_LIBC_AVAILABLE): if (native_fopen_fn) return native_fopen_fn(filename, mode); @@ -45,9 +45,9 @@ $else: @pool() { $if (env::os_is_win32()): - CFile file = (CFile)_wfopen(filename.to_temp_utf16(), filename.to_temp_utf16())?; + void* file = (CFile)_wfopen(filename.to_temp_utf16(), filename.to_temp_utf16())?; $else: - CFile file = libc::fopen(filename.zstr_tcopy(), mode.zstr_tcopy()); + void* file = libc::fopen(filename.zstr_tcopy(), mode.zstr_tcopy()); $endif; return file ?: file_open_errno()!; }; @@ -58,7 +58,7 @@ $endif; * @require mode.len > 0 * @require filename.len > 0 **/ -fn CFile! native_freopen(CFile file, String filename, String mode) @inline +fn void*! native_freopen(void* file, String filename, String mode) @inline { $if (!env::COMPILER_LIBC_AVAILABLE): if (native_freopen_fn) return native_freopen_fn(file, filename, mode); @@ -67,7 +67,7 @@ $else: @pool() { $if (env::os_is_win32()): - file = (CFile)_wfreopen(filename.to_temp_utf16(), mode.to_temp_utf16(), file)?; + file = _wfreopen(filename.to_temp_utf16(), mode.to_temp_utf16(), file)?; $else: file = libc::freopen(filename.zstr_tcopy(), mode.zstr_tcopy(), file); $endif; @@ -76,7 +76,7 @@ $else: $endif; } -fn void! native_fseek(CFile file, isz offset, Seek seek_mode) @inline +fn void! native_fseek(void* file, isz offset, Seek seek_mode) @inline { $if (!env::COMPILER_LIBC_AVAILABLE): if (native_fseek_fn) return native_fseek_fn(file, offset, seek_mode); diff --git a/lib/std/io/os/fileinfo_other.c3 b/lib/std/io/os/fileinfo_other.c3 index aa25d88ac..419ccc1c0 100644 --- a/lib/std/io/os/fileinfo_other.c3 +++ b/lib/std/io/os/fileinfo_other.c3 @@ -28,11 +28,13 @@ const DT_LNK = 10; const DT_SOCK = 12; const DT_WHT = 14; -fn void! native_readdir(PathList* list, Path dir, bool no_dirs, bool no_symlinks, String mask, Allocator* using) +fn PathList! native_readdir(Path dir, bool no_dirs, bool no_symlinks, String mask, Allocator* using) { + PathList list; + list.init(.using = using); void* directory = opendir(dir.as_str() ? dir.as_zstr() : (ZString)"."); defer if (directory) closedir(directory); - if (!directory) return (dir.is_dir() ? IoError.CANNOT_READ_DIR : IoError.FILE_NOT_DIR)!; + if (!directory) return (path::is_dir(dir) ? IoError.CANNOT_READ_DIR : IoError.FILE_NOT_DIR)!; NativeDirentry* entry; while ((entry = readdir(directory))) { @@ -43,6 +45,7 @@ fn void! native_readdir(PathList* list, Path dir, bool no_dirs, bool no_symlinks Path path = path::new(name.copy(using), using)!!; list.append(path); } + return list; } $endif; @@ -53,8 +56,7 @@ $if (!env::os_is_darwin() && !env::os_is_win32()): fn usz! native_file_size(String path) { - File f; - f.open(path, "r")?; + File f = file::open(path, "r")?; defer (void)f.close(); return f.seek(0, Seek.END)?; } @@ -71,10 +73,9 @@ fn bool native_file_or_dir_exists(String path) fn bool native_is_file(String path) { - File f; - if (catch(f.open(path, "r"))) return false; - (void)f.close(); - return true; + File! f = file::open(path, "r"); + defer (void)f.close(); + return try(f); } fn bool native_is_dir(String path) diff --git a/lib/std/io/os/fileinfo_win32.c3 b/lib/std/io/os/fileinfo_win32.c3 index b79a633a7..0671261fb 100644 --- a/lib/std/io/os/fileinfo_win32.c3 +++ b/lib/std/io/os/fileinfo_win32.c3 @@ -28,10 +28,9 @@ fn bool native_file_or_dir_exists(String path) fn bool native_is_file(String path) { - File f; - if (catch(f.open(path, "r"))) return false; - (void)f.close(); - return true; + File! f = file::open(path, "r"); + defer (void)f.close(); + return try(f); } fn bool native_is_dir(String path) diff --git a/resources/examples/load_world.c3 b/resources/examples/load_world.c3 index 1768a3615..ef269c188 100644 --- a/resources/examples/load_world.c3 +++ b/resources/examples/load_world.c3 @@ -2,8 +2,7 @@ module load_world; import std::io; fn void! main() { - File f; - f.open("examples/hello_world.txt", "rb")?; + File f = file::open("examples/hello_world.txt", "rb")?; defer f.close()!!; while (!f.eof()) { diff --git a/src/compiler/sema_expr.c b/src/compiler/sema_expr.c index 332d3d4c9..8728c1559 100644 --- a/src/compiler/sema_expr.c +++ b/src/compiler/sema_expr.c @@ -3993,7 +3993,7 @@ static inline IndexDiff range_const_len(Range *range) static bool sema_expr_analyse_slice_assign(SemaContext *context, Expr *expr, Type *left_type, Expr *right, bool is_unwrapped) { Expr *left = exprptr(expr->binary_expr.left); - Type *base = left_type->array.base; + Type *base = type_flatten(left_type)->array.base; if (right->expr_kind == EXPR_SLICE) { Range *left_range = &left->subscript_expr.range; diff --git a/src/version.h b/src/version.h index debd08296..c734d6925 100644 --- a/src/version.h +++ b/src/version.h @@ -1 +1 @@ -#define COMPILER_VERSION "0.4.106" \ No newline at end of file +#define COMPILER_VERSION "0.4.107" \ No newline at end of file diff --git a/test/test_suite/methods/enum_distinct_err_methods.c3t b/test/test_suite/methods/enum_distinct_err_methods.c3t index c8d1022c4..933524f6c 100644 --- a/test/test_suite/methods/enum_distinct_err_methods.c3t +++ b/test/test_suite/methods/enum_distinct_err_methods.c3t @@ -18,17 +18,17 @@ enum MyEnum fn void Foo.hello(Foo *f) { - io::println("Hello from Foo"); + io::printn("Hello from Foo"); } fn void Bar.hello(Bar *b) { - io::println("Hello from Bar"); + io::printn("Hello from Bar"); } fn void MyEnum.hello(MyEnum *myenum) { - io::println("Hello from MyEnum"); + io::printn("Hello from MyEnum"); } fn int main() { @@ -47,17 +47,15 @@ fn int main() define void @foo.Foo.hello(ptr %0) #0 { entry: %x = alloca %"char[]", align 8 - %x1 = alloca %"char[]", align 8 %retparam = alloca i64, align 8 %result = alloca %File, align 8 store %"char[]" { ptr @.str, i64 14 }, ptr %x, align 8 - call void @llvm.memcpy.p0.p0.i32(ptr align 8 %x1, ptr align 8 %x, i32 16, i1 false) %1 = call ptr @std.io.stdout() store ptr %1, ptr %result, align 8 %2 = load ptr, ptr %result, align 8 - %3 = getelementptr inbounds %"char[]", ptr %x1, i32 0, i32 0 + %3 = getelementptr inbounds %"char[]", ptr %x, i32 0, i32 0 %lo = load ptr, ptr %3, align 8 - %4 = getelementptr inbounds %"char[]", ptr %x1, i32 0, i32 1 + %4 = getelementptr inbounds %"char[]", ptr %x, i32 0, i32 1 %hi = load i64, ptr %4, align 8 %5 = call i64 @std.io.File.printn(ptr %retparam, ptr %2, ptr %lo, i64 %hi) ret void @@ -66,17 +64,15 @@ entry: define void @foo.Bar.hello(ptr %0) #0 { entry: %x = alloca %"char[]", align 8 - %x1 = alloca %"char[]", align 8 %retparam = alloca i64, align 8 %result = alloca %File, align 8 store %"char[]" { ptr @.str.1, i64 14 }, ptr %x, align 8 - call void @llvm.memcpy.p0.p0.i32(ptr align 8 %x1, ptr align 8 %x, i32 16, i1 false) %1 = call ptr @std.io.stdout() store ptr %1, ptr %result, align 8 %2 = load ptr, ptr %result, align 8 - %3 = getelementptr inbounds %"char[]", ptr %x1, i32 0, i32 0 + %3 = getelementptr inbounds %"char[]", ptr %x, i32 0, i32 0 %lo = load ptr, ptr %3, align 8 - %4 = getelementptr inbounds %"char[]", ptr %x1, i32 0, i32 1 + %4 = getelementptr inbounds %"char[]", ptr %x, i32 0, i32 1 %hi = load i64, ptr %4, align 8 %5 = call i64 @std.io.File.printn(ptr %retparam, ptr %2, ptr %lo, i64 %hi) ret void @@ -85,17 +81,15 @@ entry: define void @foo.MyEnum.hello(ptr %0) #0 { entry: %x = alloca %"char[]", align 8 - %x1 = alloca %"char[]", align 8 %retparam = alloca i64, align 8 %result = alloca %File, align 8 store %"char[]" { ptr @.str.2, i64 17 }, ptr %x, align 8 - call void @llvm.memcpy.p0.p0.i32(ptr align 8 %x1, ptr align 8 %x, i32 16, i1 false) %1 = call ptr @std.io.stdout() store ptr %1, ptr %result, align 8 %2 = load ptr, ptr %result, align 8 - %3 = getelementptr inbounds %"char[]", ptr %x1, i32 0, i32 0 + %3 = getelementptr inbounds %"char[]", ptr %x, i32 0, i32 0 %lo = load ptr, ptr %3, align 8 - %4 = getelementptr inbounds %"char[]", ptr %x1, i32 0, i32 1 + %4 = getelementptr inbounds %"char[]", ptr %x, i32 0, i32 1 %hi = load i64, ptr %4, align 8 %5 = call i64 @std.io.File.printn(ptr %retparam, ptr %2, ptr %lo, i64 %hi) ret void