mirror of
https://github.com/c3lang/c3c.git
synced 2026-02-27 03:51:18 +00:00
- Added path::home_directory, path::documents_directory, path::videos_directory, path::pictures_directory, path::desktop_directory, path::screenshots_directory,
`path::public_share_directory`, `path::templates_directory`, `path::saved_games_directory`, `path::music_directory`, `path::downloads_directory`. Fix codegen bug in expressions like `foo(x()) ?? io::EOF?` causing irregular crashes.
This commit is contained in:
committed by
Christoffer Lerno
parent
cbd415881b
commit
69b3263a00
10
.github/workflows/main.yml
vendored
10
.github/workflows/main.yml
vendored
@@ -88,16 +88,16 @@ jobs:
|
||||
..\build\${{ matrix.build_type }}\c3c.exe compile --lib raylib55 --print-linking examples\raylib\raylib_snake.c3
|
||||
..\build\${{ matrix.build_type }}\c3c.exe compile --lib raylib55 --print-linking examples\raylib\raylib_tetris.c3
|
||||
|
||||
- name: run compiler tests
|
||||
run: |
|
||||
cd test
|
||||
..\build\${{ matrix.build_type }}\c3c.exe compile-run -O1 src/test_suite_runner.c3 -- ..\build\${{ matrix.build_type }}\c3c.exe test_suite/
|
||||
|
||||
- name: Compile run unit tests
|
||||
run: |
|
||||
cd test
|
||||
..\build\${{ matrix.build_type }}\c3c.exe compile-test unit -O1 -D SLOW_TESTS
|
||||
|
||||
- name: run compiler tests
|
||||
run: |
|
||||
cd test
|
||||
..\build\${{ matrix.build_type }}\c3c.exe compile-run -O1 src/test_suite_runner.c3 -- ..\build\${{ matrix.build_type }}\c3c.exe test_suite/ --no-terminal
|
||||
|
||||
- name: Test python script
|
||||
run: |
|
||||
py msvc_build_libraries.py --accept-license
|
||||
|
||||
@@ -35,6 +35,7 @@ faultdef
|
||||
NO_PERMISSION,
|
||||
OUT_OF_SPACE,
|
||||
OVERFLOW,
|
||||
PATH_COULD_NOT_BE_FOUND,
|
||||
READ_ONLY,
|
||||
SYMLINK_FAILED,
|
||||
TOO_MANY_DESCRIPTORS,
|
||||
|
||||
@@ -1,5 +1,112 @@
|
||||
module std::io::os;
|
||||
|
||||
enum NativeSystemDir
|
||||
{
|
||||
DESKTOP,
|
||||
DOCUMENTS,
|
||||
VIDEOS,
|
||||
MUSIC,
|
||||
DOWNLOADS,
|
||||
PICTURES,
|
||||
TEMPLATES,
|
||||
PUBLIC_SHARE,
|
||||
SAVED_GAMES,
|
||||
SCREENSHOTS
|
||||
}
|
||||
|
||||
module std::io::os @if(env::LIBC);
|
||||
import std::io::path, std::os;
|
||||
import std::io, std::os;
|
||||
|
||||
fn String? win32_get_known_folder_temp(Win32_REFKNOWNFOLDERID rfid) @private @if(env::WIN32)
|
||||
{
|
||||
Win32_PWSTR path;
|
||||
Win32_HRESULT res = win32::shGetKnownFolderPath(rfid, 0x00008000 /* KF_FLAG_CREATE */, null, &path);
|
||||
if (res) return io::PATH_COULD_NOT_BE_FOUND?;
|
||||
return string::from_wstring(tmem, (WString)path);
|
||||
}
|
||||
|
||||
fn Path? native_home_directory(Allocator allocator) => @pool()
|
||||
{
|
||||
$switch env::OS_TYPE:
|
||||
$case IOS:
|
||||
$case MACOS:
|
||||
$case TVOS:
|
||||
$case WATCHOS:
|
||||
$case FREEBSD:
|
||||
$case KFREEBSD:
|
||||
$case LINUX:
|
||||
$case NETBSD:
|
||||
$case OPENBSD:
|
||||
$case HAIKU:
|
||||
return path::new(allocator, env::tget_var("HOME")) ?? io::PATH_COULD_NOT_BE_FOUND?;
|
||||
$case WIN32:
|
||||
return path::new(allocator, win32_get_known_folder_temp(&win32::FOLDERID_PROFILE));
|
||||
$default:
|
||||
return io::PATH_COULD_NOT_BE_FOUND?;
|
||||
$endswitch
|
||||
}
|
||||
|
||||
fn Path? native_user_directory(Allocator allocator, NativeSystemDir dir) => @pool()
|
||||
{
|
||||
$switch env::OS_TYPE:
|
||||
$case FREEBSD:
|
||||
$case KFREEBSD:
|
||||
$case LINUX:
|
||||
$case NETBSD:
|
||||
$case OPENBSD:
|
||||
$case HAIKU:
|
||||
switch (dir)
|
||||
{
|
||||
case DESKTOP: return path::new(allocator, posix::xdg_user_dir_lookup(tmem, "DESKTOP"));
|
||||
case DOWNLOADS: return path::new(allocator, posix::xdg_user_dir_lookup(tmem, "DOWNLOAD"));
|
||||
case DOCUMENTS: return path::new(allocator, posix::xdg_user_dir_lookup(tmem, "DOCUMENTS"));
|
||||
case MUSIC: return path::new(allocator, posix::xdg_user_dir_lookup(tmem, "MUSIC"));
|
||||
case VIDEOS: return path::new(allocator, posix::xdg_user_dir_lookup(tmem, "VIDEOS"));
|
||||
case PICTURES: return path::new(allocator, posix::xdg_user_dir_lookup(tmem, "PICTURES"));
|
||||
case PUBLIC_SHARE: return path::new(allocator, posix::xdg_user_dir_lookup(tmem, "PUBLICSHARE"));
|
||||
case TEMPLATES: return path::new(allocator, posix::xdg_user_dir_lookup(tmem, "TEMPLATES"));
|
||||
case SAVED_GAMES:
|
||||
case SCREENSHOTS: nextcase;
|
||||
default: return io::PATH_COULD_NOT_BE_FOUND?;
|
||||
}
|
||||
$case IOS:
|
||||
$case MACOS:
|
||||
$case WATCHOS:
|
||||
$case TVOS:
|
||||
switch (dir)
|
||||
{
|
||||
case DESKTOP: return path::new(allocator, darwin::find_first_directory_temp(DESKTOP, USER));
|
||||
case DOWNLOADS: return path::new(allocator, darwin::find_first_directory_temp(DOWNLOADS, USER));
|
||||
case DOCUMENTS: return path::new(allocator, darwin::find_first_directory_temp(DOCUMENT, USER));
|
||||
case MUSIC: return path::new(allocator, darwin::find_first_directory_temp(MUSIC, USER));
|
||||
case VIDEOS: return path::new(allocator, darwin::find_first_directory_temp(MOVIES, USER));
|
||||
case PICTURES: return path::new(allocator, darwin::find_first_directory_temp(PICTURES, USER));
|
||||
case PUBLIC_SHARE: return path::new(allocator, darwin::find_first_directory_temp(SHARED_PUBLIC, USER));
|
||||
case SAVED_GAMES:
|
||||
case SCREENSHOTS:
|
||||
case TEMPLATES: nextcase;
|
||||
default: return io::PATH_COULD_NOT_BE_FOUND?;
|
||||
}
|
||||
$case WIN32:
|
||||
switch (dir)
|
||||
{
|
||||
case DOWNLOADS: return path::new(allocator, win32_get_known_folder_temp(&win32::FOLDERID_DOWNLOADS));
|
||||
case DOCUMENTS: return path::new(allocator, win32_get_known_folder_temp(&win32::FOLDERID_DOCUMENTS));
|
||||
case DESKTOP: return path::new(allocator, win32_get_known_folder_temp(&win32::FOLDERID_DESKTOP));
|
||||
case MUSIC: return path::new(allocator, win32_get_known_folder_temp(&win32::FOLDERID_MUSIC));
|
||||
case VIDEOS: return path::new(allocator, win32_get_known_folder_temp(&win32::FOLDERID_VIDEOS));
|
||||
case PICTURES: return path::new(allocator, win32_get_known_folder_temp(&win32::FOLDERID_PICTURES));
|
||||
case SAVED_GAMES: return path::new(allocator, win32_get_known_folder_temp(&win32::FOLDERID_SAVED_GAMES));
|
||||
case SCREENSHOTS: return path::new(allocator, win32_get_known_folder_temp(&win32::FOLDERID_SCREENSHOTS));
|
||||
case TEMPLATES: return path::new(allocator, win32_get_known_folder_temp(&win32::FOLDERID_TEMPLATES));
|
||||
case PUBLIC_SHARE: nextcase;
|
||||
default: return io::PATH_COULD_NOT_BE_FOUND?;
|
||||
}
|
||||
$default:
|
||||
return io::PATH_COULD_NOT_BE_FOUND?;
|
||||
$endswitch
|
||||
}
|
||||
|
||||
|
||||
fn Path? native_temp_directory(Allocator allocator) @if(!env::WIN32)
|
||||
{
|
||||
@@ -23,7 +130,6 @@ fn Path? native_temp_directory(Allocator allocator) @if(env::WIN32) => @pool()
|
||||
module std::io::os @if(env::NO_LIBC);
|
||||
import std::io::path;
|
||||
|
||||
macro Path? native_temp_directory(Allocator allocator)
|
||||
{
|
||||
return io::UNSUPPORTED_OPERATION?;
|
||||
}
|
||||
macro Path? native_home_directory(Allocator allocator) => io::PATH_COULD_NOT_BE_FOUND?;
|
||||
macro Path? native_temp_directory(Allocator allocator) => io::PATH_COULD_NOT_BE_FOUND?;
|
||||
fn Path? native_user_directory(Allocator allocator, NativeSystemDir dir) => io::PATH_COULD_NOT_BE_FOUND?;
|
||||
|
||||
@@ -57,6 +57,18 @@ macro void? chdir(path)
|
||||
|
||||
fn Path? temp_directory(Allocator allocator) => os::native_temp_directory(allocator);
|
||||
|
||||
fn Path? home_directory(Allocator allocator) => os::native_home_directory(allocator);
|
||||
fn Path? desktop_directory(Allocator allocator) => os::native_user_directory(allocator, DESKTOP);
|
||||
fn Path? videos_directory(Allocator allocator) => os::native_user_directory(allocator, VIDEOS);
|
||||
fn Path? music_directory(Allocator allocator) => os::native_user_directory(allocator, MUSIC);
|
||||
fn Path? documents_directory(Allocator allocator) => os::native_user_directory(allocator, DOCUMENTS);
|
||||
fn Path? screenshots_directory(Allocator allocator) => os::native_user_directory(allocator, SCREENSHOTS);
|
||||
fn Path? saved_games_directory(Allocator allocator) => os::native_user_directory(allocator, SAVED_GAMES);
|
||||
fn Path? downloads_directory(Allocator allocator) => os::native_user_directory(allocator, DOWNLOADS);
|
||||
fn Path? pictures_directory(Allocator allocator) => os::native_user_directory(allocator, PICTURES);
|
||||
fn Path? templates_directory(Allocator allocator) => os::native_user_directory(allocator, TEMPLATES);
|
||||
fn Path? public_share_directory(Allocator allocator) => os::native_user_directory(allocator, PUBLIC_SHARE);
|
||||
|
||||
fn void? delete(Path path) => os::native_remove(path.str_view()) @inline;
|
||||
|
||||
macro bool @is_pathlike(#path) @const => $typeof(#path) == String ||| $typeof(#path) == Path;
|
||||
|
||||
@@ -1,11 +1,18 @@
|
||||
module std::os::macos::cf @if(env::DARWIN) @link(env::DARWIN, "CoreFoundation.framework");
|
||||
|
||||
typedef CFArrayRef = void*;
|
||||
typedef CFArray = inline CFType;
|
||||
alias CFArrayRef = CFArray*;
|
||||
typedef CFArrayCallBacksRef = void*;
|
||||
typedef CFMutableArrayRef = void*;
|
||||
typedef CFMutableArray = inline CFArray;
|
||||
typedef CFMutableArrayRef = CFMutableArray*;
|
||||
|
||||
extern fn CFIndex CFArray.getCount(&self) @extern("CFArrayGetCount");
|
||||
extern fn void* CFArray.getValueAtIndex(&self, CFIndex i) @extern("CFArrayGetValueAtIndex");
|
||||
|
||||
extern fn CFArrayRef macos_CFArrayCreate(CFAllocatorRef allocator, void** values, CFIndex num_values, CFArrayCallBacksRef callBacks) @extern("CFArrayCreate") @builtin;
|
||||
extern fn CFArrayRef macos_CFArrayCopy(CFAllocatorRef allocator, CFArrayRef array) @extern("CFArrayCopy") @builtin;
|
||||
extern fn CFIndex macos_CFArrayGetCount(CFArrayRef array) @extern("CFArrayGetCount") @builtin;
|
||||
extern fn void macos_CFArrayAppendArray(CFMutableArrayRef theArray, CFArrayRef otherArray, CFRange otherRange) @extern("CFArrayAppendArray") @builtin;
|
||||
extern fn void CFMutableArray.appendArray(&self, CFArrayRef otherArray, CFRange otherRange) @extern("CFArrayAppendArray");
|
||||
extern fn void CFMutableArray.appendValue(&self, void *value) @extern("CFArrayAppendValue");
|
||||
|
||||
extern fn CFMutableArrayRef macos_CFArrayCreateMutable(CFAllocatorRef allocator, CFIndex capacity, CFArrayCallBacksRef callBacks) @extern("CFArrayCreateMutable") @builtin;
|
||||
extern fn void macos_CFArrayAppendValue(CFMutableArrayRef theArray, void *value) @extern("CFArrayAppendValue") @builtin;
|
||||
|
||||
|
||||
@@ -1,13 +1,42 @@
|
||||
module std::os::macos::cf @if(env::DARWIN) @link(env::DARWIN, "CoreFoundation.framework");
|
||||
|
||||
typedef CFTypeRef = void*;
|
||||
typedef CFType = void;
|
||||
typedef CFTypeRef = CFType*;
|
||||
alias CFIndex = isz;
|
||||
|
||||
typedef CFString = inline CFType;
|
||||
alias CFStringRef = CFString*;
|
||||
|
||||
struct CFRange
|
||||
{
|
||||
CFIndex location;
|
||||
CFIndex length;
|
||||
}
|
||||
|
||||
extern fn CFTypeRef macos_CFRetain(CFTypeRef cf) @extern("CFRetain") @builtin;
|
||||
extern fn void macos_CFRelease(CFTypeRef cf) @extern("CFRelease") @builtin;
|
||||
extern fn ZString CFString.getCStringPtr(&self, CFStringEncoding encoding) @extern("CFStringGetCStringPtr");
|
||||
extern fn ZString CFString.getCString(&self, char* buffer, usz len, CFStringEncoding encoding) @extern("CFStringGetCString");
|
||||
|
||||
extern fn CFTypeRef CFType.retain(&self) @extern("CFRetain");
|
||||
extern fn void CFType.release(&self) @extern("CFRelease");
|
||||
extern fn CFIndex CFType.getRetainCount(&self) @extern("CFGetRetainCount");
|
||||
|
||||
enum CFStringEncoding : const uint
|
||||
{
|
||||
INVALID_ID = 0xffffffffU,
|
||||
MAC_ROMAN = 0,
|
||||
WINDOWS_LATIN_1 = 0x0500,
|
||||
ISO_LATIM_1 = 0x0201,
|
||||
NEXT_STEP_LATIN = 0x0B01,
|
||||
ASCII = 0x0600,
|
||||
UNICODE = 0x0100,
|
||||
UTF8 = 0x08000100,
|
||||
NON_LOSSY_ASCII = 0x0BFF,
|
||||
|
||||
UTF16 = 0x0100,
|
||||
UTF16BE = 0x10000100,
|
||||
UTF16LE = 0x14000100,
|
||||
|
||||
UTF32 = 0x0c000100,
|
||||
UTF32BE = 0x18000100,
|
||||
UTF32LE = 0x1c000100
|
||||
}
|
||||
|
||||
@@ -1,2 +1,60 @@
|
||||
module std::os::darwin @if(env::DARWIN);
|
||||
module std::os::darwin @if(env::DARWIN) @link("Foundation.framework");
|
||||
import std::os::macos::cf, std::os::macos::objc, std::io;
|
||||
|
||||
enum NSSearchPathDomainMask : const NSUInteger
|
||||
{
|
||||
USER = 1,
|
||||
LOCAL = 2,
|
||||
NETWORK = 4,
|
||||
SYSTEM = 8,
|
||||
ALL = 0x0ffff
|
||||
}
|
||||
|
||||
enum NSSearchPathDirectory : const NSUInteger
|
||||
{
|
||||
APPLICATION = 1,
|
||||
DEMO_APPLICATION,
|
||||
DEVELOPER_APPLICATION,
|
||||
ADMIN_APPLICATION,
|
||||
LIBRARY,
|
||||
DEVELOPER,
|
||||
USER,
|
||||
DOCUMENTATION,
|
||||
DOCUMENT,
|
||||
CORE_SERVICE,
|
||||
AUTOSAVED_INFORMATION,
|
||||
DESKTOP = 12,
|
||||
CACHES = 13,
|
||||
APPLICATION_SUPPORT = 14,
|
||||
DOWNLOADS = 15,
|
||||
INPUT_METHODS = 16,
|
||||
MOVIES = 17,
|
||||
MUSIC = 18,
|
||||
PICTURES = 19,
|
||||
PRINTER_DESCRIPTION = 20,
|
||||
SHARED_PUBLIC = 21,
|
||||
PREFERENCE_PANES = 22,
|
||||
APPLICATION_SCRIPTS = 23,
|
||||
ITEM_REPLACEMENT = 99,
|
||||
ALL_APPLICATIONS = 100,
|
||||
ALL_LIBRARIES = 101,
|
||||
TRASH = 102,
|
||||
}
|
||||
|
||||
// real signature in Foundation
|
||||
extern fn CFArrayRef nsSearchPathForDirectoriesInDomains(NSSearchPathDirectory directory, NSSearchPathDomainMask domainMask, bool expandTilde) @extern("NSSearchPathForDirectoriesInDomains");
|
||||
|
||||
|
||||
|
||||
fn String? find_first_directory_temp(NSSearchPathDirectory directory, NSSearchPathDomainMask domainMask)
|
||||
{
|
||||
objc::@autoreleasepool()
|
||||
{
|
||||
CFArrayRef arr = nsSearchPathForDirectoriesInDomains(directory, domainMask, true);
|
||||
if (!arr.getCount()) return io::PATH_COULD_NOT_BE_FOUND?;
|
||||
CFStringRef str = (CFStringRef)arr.getValueAtIndex(0);
|
||||
char* buffer = tmalloc(2048);
|
||||
if (!str.getCString(buffer, 2048, UTF8)) return io::PATH_COULD_NOT_BE_FOUND?;
|
||||
return ((ZString)buffer).str_view();
|
||||
};
|
||||
}
|
||||
|
||||
@@ -20,6 +20,9 @@ macro bool ObjcClass.equals(ObjcClass a, ObjcClass b) => a == b;
|
||||
fn ObjcId alloc(ObjcClass cls) => objc::msg_send(cls, SendVoid, "alloc");
|
||||
fn void release(ObjcId id) => objc::msg_send(id, SendVoid, "release");
|
||||
|
||||
alias NSUInteger = $typefrom(env::ARCH_64_BIT ??? ulong : uint);
|
||||
alias NSInteger = $typefrom(env::ARCH_64_BIT ??? long : int);
|
||||
|
||||
macro ObjcClass? class_by_name(ZString c)
|
||||
{
|
||||
ObjcClass cls = objc::lookUpClass(c);
|
||||
@@ -43,6 +46,15 @@ macro msg_send(id, $FunctionType, ZString $selector, ...)
|
||||
return (($FunctionType)&msgSend)((ObjcId)id, sel_getUid($selector), $vasplat);
|
||||
}
|
||||
|
||||
macro void @autoreleasepool(;@body())
|
||||
{
|
||||
void* ctx = objc_autoreleasePoolPush();
|
||||
defer objc_autoreleasePoolPop(ctx);
|
||||
@body();
|
||||
}
|
||||
|
||||
extern fn void* objc_autoreleasePoolPush();
|
||||
extern fn void objc_autoreleasePoolPop(void* context);
|
||||
extern fn ObjcClass getClass(ZString name) @extern("objc_getClass");
|
||||
extern fn int getClassList(ObjcClass* buffer, int buffer_count) @extern("objc_getClassList");
|
||||
extern fn ObjcClass lookUpClass(ZString name) @extern("objc_lookUpClass") @builtin;
|
||||
|
||||
16
lib/std/os/win32/shell32.c3
Normal file
16
lib/std/os/win32/shell32.c3
Normal file
@@ -0,0 +1,16 @@
|
||||
module std::os::win32 @if(env::WIN32) @link("shell32");
|
||||
|
||||
typedef Win32_REFKNOWNFOLDERID = Win32_KNOWNFOLDERID*;
|
||||
typedef Win32_KNOWNFOLDERID = Win32_GUID;
|
||||
extern fn Win32_HRESULT shGetKnownFolderPath(Win32_REFKNOWNFOLDERID rfid, Win32_DWORD dwFlags, Win32_HANDLE hToken, Win32_PWSTR* ppszPath) @extern("SHGetKnownFolderPath");
|
||||
|
||||
const Win32_KNOWNFOLDERID FOLDERID_PROFILE = { 0x5E6C858F, 0x0E22, 0x4760, x"9AFEEA3317B67173" };
|
||||
const Win32_KNOWNFOLDERID FOLDERID_DESKTOP = { 0xB4BFCC3A, 0xDB2C, 0x424C, x"B0297FE99A87C641" };
|
||||
const Win32_KNOWNFOLDERID FOLDERID_DOCUMENTS = { 0xFDD39AD0, 0x238F, 0x46AF, x"ADB46C85480369C7" };
|
||||
const Win32_KNOWNFOLDERID FOLDERID_DOWNLOADS = { 0x374de290, 0x123f, 0x4565, x"916439c4925e467b" };
|
||||
const Win32_KNOWNFOLDERID FOLDERID_MUSIC = { 0x4BD8D571, 0x6D19, 0x48D3, x"BE97422220080E43" };
|
||||
const Win32_KNOWNFOLDERID FOLDERID_PICTURES = { 0x33E28130, 0x4E1E, 0x4676, x"835A98395C3BC3BB" };
|
||||
const Win32_KNOWNFOLDERID FOLDERID_SAVED_GAMES = { 0x4c5c32ff, 0xbb9d, 0x43b0, x"b5b42d72e54eaaa4" };
|
||||
const Win32_KNOWNFOLDERID FOLDERID_SCREENSHOTS = { 0xb7bede81, 0xdf94, 0x4682, x"a7d857a52620b86f" };
|
||||
const Win32_KNOWNFOLDERID FOLDERID_TEMPLATES = { 0xA63293E8, 0x664E, 0x48DB, x"A079DF759E0509F7" };
|
||||
const Win32_KNOWNFOLDERID FOLDERID_VIDEOS = { 0x18989B1D, 0x99B5, 0x455B, x"841CAB7C74E4DDFC" };
|
||||
53
lib/std/os/xdg.c3
Normal file
53
lib/std/os/xdg.c3
Normal file
@@ -0,0 +1,53 @@
|
||||
module std::os::posix @if(env::POSIX);
|
||||
import std::io, std::os::env;
|
||||
|
||||
fn String? xdg_user_dir_lookup(Allocator allocator, String type) => @pool()
|
||||
{
|
||||
String home = env::tget_var("HOME")!;
|
||||
String config_file @noinit;
|
||||
if (try String config_home = env::tget_var("XDG_CONFIG_HOME") && config_home.len)
|
||||
{
|
||||
config_file = config_home.tconcat("/user-dirs.dirs");
|
||||
}
|
||||
else
|
||||
{
|
||||
config_file = home.tconcat("/.config/user-dirs.dirs");
|
||||
}
|
||||
File f = file::open(config_file, "r")!;
|
||||
defer (void)f.close();
|
||||
while (try line = io::treadline(&f))
|
||||
{
|
||||
line = line.trim();
|
||||
if (!line.starts_with("XDG_")) continue;
|
||||
line = line[4..];
|
||||
if (!line.starts_with(type)) continue;
|
||||
line = line[type.len ..];
|
||||
if (!line.starts_with("_DIR")) continue;
|
||||
line = line[4..];
|
||||
line = line.trim();
|
||||
if (!line.starts_with("=")) continue;
|
||||
line = line[1..].trim();
|
||||
if (!line.starts_with("\"")) continue;
|
||||
line = line[1..];
|
||||
bool relative = false;
|
||||
if (line.starts_with("$HOME/"))
|
||||
{
|
||||
relative = true;
|
||||
line = line[6..];
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!line.starts_with("/")) continue;
|
||||
if (line.len < 2) continue;
|
||||
line = line[1..];
|
||||
}
|
||||
if (line.len < 1 || line[^1] != '"') continue;
|
||||
line = line[:^1];
|
||||
if (relative)
|
||||
{
|
||||
return string::format(allocator, "%s/%s", home, line);
|
||||
}
|
||||
return line.copy(allocator);
|
||||
}
|
||||
return io::PATH_COULD_NOT_BE_FOUND?;
|
||||
}
|
||||
@@ -11,9 +11,12 @@
|
||||
- Returning pointer to index of slice stored in a struct from method taking self incorrectly detected as returning pointer to local variable #2455.
|
||||
- Inlining location when accessing #foo symbols.
|
||||
- Improve inlined-at when checking generic code.
|
||||
- Fix codegen bug in expressions like `foo(x()) ?? io::EOF?` causing irregular crashes.
|
||||
|
||||
### Stdlib changes
|
||||
- Added generic `InterfaceList` to store a list of values that implement a specific interface
|
||||
- Added `path::home_directory`, `path::documents_directory`, `path::videos_directory`, `path::pictures_directory`, `path::desktop_directory`, `path::screenshots_directory`,
|
||||
`path::public_share_directory`, `path::templates_directory`, `path::saved_games_directory`, `path::music_directory`, `path::downloads_directory`.
|
||||
|
||||
## 0.7.5 Change list
|
||||
|
||||
|
||||
@@ -1,10 +1,5 @@
|
||||
module hello_world;
|
||||
import std;
|
||||
import bar;
|
||||
import clib;
|
||||
import clib2;
|
||||
import std::core::env;
|
||||
|
||||
import std, bar, clib, clib2;
|
||||
|
||||
fn int test_doubler(int x) @if(env::WIN32) => x * x;
|
||||
extern fn int test_doubler(int) @if(!env::WIN32);
|
||||
@@ -18,6 +13,10 @@ fn int main()
|
||||
printf("Author emails:");
|
||||
io::printn(env::AUTHOR_EMAILS);
|
||||
|
||||
(void)io::printfn("Home dir: %s", path::home_directory(tmem));
|
||||
(void)io::printfn("Desktop dir: %s", path::desktop_directory(tmem));
|
||||
(void)io::printfn("Documents dir: %s", path::documents_directory(tmem));
|
||||
|
||||
bar::test();
|
||||
printf("Hello double: %d\n", test_doubler(11));
|
||||
if ($feature(ABCD)) io::printn("ABCD");
|
||||
|
||||
@@ -404,10 +404,12 @@ bool decl_needs_prefix(Decl *decl)
|
||||
{
|
||||
switch (decl->decl_kind)
|
||||
{
|
||||
case DECL_VAR:
|
||||
case DECL_ALIAS:
|
||||
case DECL_FUNC:
|
||||
case DECL_MACRO:
|
||||
if (decl->func_decl.type_parent) return false;
|
||||
FALLTHROUGH;
|
||||
case DECL_VAR:
|
||||
case DECL_ALIAS:
|
||||
case DECL_FAULT:
|
||||
return !decl->is_autoimport;
|
||||
default:
|
||||
|
||||
@@ -3858,7 +3858,10 @@ static void llvm_emit_else(GenContext *c, BEValue *be_value, Expr *expr)
|
||||
|
||||
// Only jump to phi if we didn't have an immediate jump. That would
|
||||
// for example happen on "{| defer foo(); return Foo.ERR?; |} ?? 123"
|
||||
if (success_end_block) llvm_emit_br(c, phi_block);
|
||||
if (success_end_block)
|
||||
{
|
||||
if (!llvm_emit_br(c, phi_block)) success_end_block = NULL;
|
||||
}
|
||||
|
||||
// Emit else
|
||||
llvm_emit_block(c, else_block);
|
||||
@@ -3881,27 +3884,28 @@ static void llvm_emit_else(GenContext *c, BEValue *be_value, Expr *expr)
|
||||
}
|
||||
}
|
||||
|
||||
// If there wasn't a success, then we end here, even if the else was a jump.
|
||||
if (!success_end_block)
|
||||
{
|
||||
*be_value = else_value;
|
||||
return;
|
||||
}
|
||||
|
||||
LLVMBasicBlockRef else_block_exit = llvm_get_current_block_if_in_use(c);
|
||||
|
||||
// While the value may not be an optional, we may get a jump
|
||||
// from this construction: foo() ?? (bar()?)
|
||||
// In this case the else block is empty.
|
||||
if (!else_block_exit)
|
||||
if (!else_block_exit || !llvm_emit_br(c, phi_block))
|
||||
{
|
||||
llvm_emit_block(c, phi_block);
|
||||
*be_value = real_value;
|
||||
return;
|
||||
}
|
||||
|
||||
llvm_emit_br(c, phi_block);
|
||||
llvm_emit_block(c, phi_block);
|
||||
|
||||
// Was there never a success, if so the result is the be_value.
|
||||
if (!success_end_block)
|
||||
{
|
||||
*be_value = else_value;
|
||||
return;
|
||||
}
|
||||
assert(success_end_block && else_block_exit);
|
||||
|
||||
// Emit an address if the phi is was by address
|
||||
if (was_address)
|
||||
|
||||
@@ -55,11 +55,12 @@ bool llvm_emit_check_block_branch(GenContext *c)
|
||||
return true;
|
||||
}
|
||||
|
||||
void llvm_emit_br(GenContext *c, LLVMBasicBlockRef next_block)
|
||||
bool llvm_emit_br(GenContext *c, LLVMBasicBlockRef next_block)
|
||||
{
|
||||
if (!llvm_emit_check_block_branch(c)) return;
|
||||
if (!llvm_emit_check_block_branch(c)) return false;
|
||||
c->current_block = NULL;
|
||||
LLVMBuildBr(c->builder, next_block);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -424,7 +424,7 @@ INLINE LLVMValueRef llvm_get_struct_of_type(GenContext *c, Type *type, LLVMValue
|
||||
// -- Jumps --
|
||||
void llvm_emit_cond_br(GenContext *context, BEValue *value, LLVMBasicBlockRef then_block, LLVMBasicBlockRef else_block);
|
||||
void llvm_emit_cond_br_raw(GenContext *context, LLVMValueRef b, LLVMBasicBlockRef then_block, LLVMBasicBlockRef else_block);
|
||||
void llvm_emit_br(GenContext *c, LLVMBasicBlockRef next_block);
|
||||
bool llvm_emit_br(GenContext *c, LLVMBasicBlockRef next_block);
|
||||
void llvm_emit_jump_to_optional_exit(GenContext *c, LLVMValueRef opt_value);
|
||||
void llvm_emit_return_abi(GenContext *c, BEValue *return_value, BEValue *optional);
|
||||
void llvm_emit_return_implicit(GenContext *c);
|
||||
|
||||
@@ -28,9 +28,6 @@ opt_block_cleanup: ; preds = %entry
|
||||
br label %else_block
|
||||
|
||||
else_block: ; preds = %opt_block_cleanup
|
||||
br label %phi_block
|
||||
|
||||
phi_block: ; preds = %else_block
|
||||
%1 = call i32 (ptr, ...) @printf(ptr @.str, i32 2)
|
||||
%2 = call i32 (ptr, ...) @printf(ptr @.str.3)
|
||||
ret void
|
||||
|
||||
Reference in New Issue
Block a user