Remove tscoped. Replace str_index_of with "starts_with". Updated copy_zstring/copy. Fixed utf conversion functions. Initial work on "Path". Lexer fix on \\. ABI fix using distinct types. (bool)"" now works correctly. Bug in $if with switches/loops as the first statement fixed. Version bump.

This commit is contained in:
Christoffer Lerno
2022-10-20 10:46:07 +02:00
committed by Christoffer Lerno
parent 7d58ce0dcb
commit f86ef8a743
15 changed files with 1210 additions and 1493 deletions

View File

@@ -88,7 +88,6 @@ private fn void*! temp_allocator_function(Allocator* data, usz size, usz alignme
private fn void! TempAllocator._free(TempAllocator* this, void* old_pointer)
{
// TODO fix free
assert((uptr)old_pointer >= (uptr)&this.data, "Pointer originates from a different allocator.");
usz old_size = *(usz*)(old_pointer - DEFAULT_SIZE_PREFIX);

View File

@@ -206,16 +206,6 @@ macro void @scoped(Allocator* allocator; @body())
@body();
}
macro void @tscoped(;@body())
{
Allocator* old_allocator = thread_allocator;
TempAllocator* temp = temp_allocator();
usz mark = temp.mark()!!;
thread_allocator = temp;
defer temp.reset(mark);
defer thread_allocator = old_allocator;
@body();
}
macro talloc($Type) @builtin
{

View File

@@ -29,7 +29,17 @@ fn String join(char[][] s, char[] joiner)
return res;
}
fn usz! str_index_of(char[] s, char[] needle)
fn bool starts_with(char[] s, char[] needle)
{
if (needle.len > s.len) return false;
foreach (i, c : needle)
{
if (c != s[i]) return false;
}
return true;
}
fn usz! index_of(char[] s, char[] needle)
{
usz match = 0;
usz needed = needle.len;
@@ -55,10 +65,10 @@ fn usz! str_index_of(char[] s, char[] needle)
return SearchResult.MISSING!;
}
fn ZString copy_zstring(char[] s)
fn ZString copy_zstring(char[] s, Allocator* allocator = mem::current_allocator())
{
usz len = s.len;
char* str = malloc(len + 1);
char* str = allocator.alloc(len + 1)!!;
mem::copy(str, s.ptr, len);
str[len] = 0;
return (ZString)str;
@@ -66,11 +76,7 @@ fn ZString copy_zstring(char[] s)
fn ZString tcopy_zstring(char[] s)
{
usz len = s.len;
char* str = tmalloc(len + 1);
mem::copy(str, s.ptr, len);
str[len] = 0;
return (ZString)str;
return copy_zstring(s, mem::temp_allocator());
}
fn bool compare(char[] a, char[] b)
@@ -89,8 +95,6 @@ fault UnicodeResult
CONVERSION_FAILED,
}
fn usz utf8_codepoints(char[] utf8)
{
usz len = 0;
@@ -107,7 +111,7 @@ fn Char32[]! utf8to32(char[] utf8, Allocator* allocator = mem::current_allocator
Char32* data = allocator.alloc(Char32.sizeof * (codepoints + 1))?;
conv::utf8to32_unsafe(utf8, data)?;
data[codepoints] = 0;
return data[0..codepoints - 1];
return data[:codepoints];
}
fn char[] utf32to8(Char32[] utf32, Allocator* allocator = mem::current_allocator)
@@ -116,7 +120,7 @@ fn char[] utf32to8(Char32[] utf32, Allocator* allocator = mem::current_allocator
char* data = allocator.alloc(len + 1)!!;
conv::utf32to8_unsafe(utf32, data);
data[len] = 0;
return data[0..len - 1];
return data[:len];
}
fn Char16[]! utf8to16(char[] utf8, Allocator* allocator = mem::current_allocator)
@@ -125,7 +129,7 @@ fn Char16[]! utf8to16(char[] utf8, Allocator* allocator = mem::current_allocator
Char16* data = allocator.alloc((len16 + 1) * Char16.sizeof)?;
conv::utf8to16_unsafe(utf8, data)?;
data[len16] = 0;
return data[0..len16 - 1];
return data[:len16];
}
@@ -134,21 +138,21 @@ fn char[]! utf16to8(Char16[] utf16, Allocator* allocator = mem::current_allocato
usz len = conv::utf8len_for_utf16(utf16);
char* data = allocator.alloc(len + 1)?;
conv::utf16to8_unsafe(utf16, data)?;
return data[0 .. len - 1];
return data[:len];
}
fn char[] copy(char[] s)
fn char[] copy(char[] s, Allocator* allocator = mem::current_allocator())
{
usz len = s.len;
ZString str_copy = copy_zstring(s) @inline;
return str_copy[..len];
ZString str_copy = copy_zstring(s, allocator) @inline;
return str_copy[:len];
}
fn char[] tcopy(char[] s)
{
usz len = s.len;
ZString str_copy = tcopy_zstring(s) @inline;
return str_copy[..len];
return str_copy[:len];
}
fn char[] tconcat(char[] s1, char[] s2)

View File

@@ -1,19 +1,173 @@
module std::io::dir;
struct PlatformDir
// In progress.
define Path = distinct char[];
const PREFERRED_SEPARATOR = USE_WIN32_FILESYSTEM ? '\\' : '/';
private const USE_WIN32_FILESYSTEM = env::OS_TYPE != OsType.WIN32;
fault PathResult
{
void* data;
INVALID_PATH
}
macro bool is_separator(char c)
{
$if (USE_WIN32_FILESYSTEM):
return c == '/' || c == '\\';
$else:
return c == '/';
$endif;
}
const bool[256] RESERVED_PATH_CHAR_POSIX = {
[0] = true,
['/'] = true,
};
const bool[256] RESERVED_PATH_CHAR_WIN32 = {
[0..31] = true,
['>'] = true,
['<'] = true,
[':'] = true,
['\"'] = true,
['/'] = true,
['\\'] = true,
['|'] = true,
['?'] = true,
['*'] = true,
};
macro bool is_reserved_path_char(char c)
{
$if (USE_WIN32_FILESYSTEM):
return RESERVED_PATH_CHAR_WIN32[c];
$else:
return RESERVED_PATH_CHAR_POSIX[c];
$endif;
}
private fn usz! root_name_len(char[] path)
{
usz len = path.len;
if (!len) return 0;
$if (USE_WIN32_FILESYSTEM):
switch (path[0])
{
case '\\':
if (len < 2 || path[1] != '\\') break;
if (len == 2 || is_separator(path[2])) return PathResult.INVALID_PATH!;
for (usz i = 2; i < len; i++)
{
char c = path[i];
if (is_separator(c)) return i;
if (is_reserved_path_char(c)) return PathResult.INVALID_PATH!;
}
return len;
case 'A'..'Z':
case 'a'..'z':
if (len < 2 || path[1] != ':') break;
if (len < 3 || !is_separator(path[2])) return PathResult.INVALID_PATH!;
return 2;
}
$endif;
return 0;
}
private fn void! normalize_path(char[]* path_ref)
{
char[] path = *path_ref;
if (!path.len) return;
usz path_start = root_name_len(path)?;
usz len = path_start;
bool previous_was_separator = false;
usz path_len = path.len;
for (usz i = path_start; i < path_len; i++)
{
char c = path[i];
// Fold foo///bar into foo/bar
if (is_separator(c))
{
if (previous_was_separator)
{
continue;
}
path.ptr[len++] = PREFERRED_SEPARATOR;
previous_was_separator = true;
continue;
}
// If we get . we have different things that might happen:
if (c == '.' && i < path_len - 1)
{
// Is this ./ or /./ ?
if ((previous_was_separator || i == path_start) && is_separator(path[i + 1]))
{
// Then we skip this
i += 2;
continue;
}
// Is this /../ in that case we must walk back and erase(!)
if (i < path_len - 2 && previous_was_separator && path[i + 1] == '.' && is_separator(path[i + 2]))
{
assert(len > path_start);
len--;
while (len > path_start && !is_separator(path[len - 1]))
{
len--;
}
i += 2;
continue;
}
}
if (i != len) path[len] = c;
previous_was_separator = false;
len++;
}
path.ptr[len] = 0;
*path_ref = path[:len];
}
fn Path new_path(char[] path)
{
char[] copy = str::copy(path);
normalize_path(&copy)!!;
return (Path)copy;
}
fn Path Path.root_name(Path path)
{
char[] path_str = (char[])path;
usz len = root_name_len(path_str)!!;
if (!len) return (Path)"";
return (Path)path_str[0:len];
}
fn Path Path.root_directory(Path path)
{
char[] path_str = (char[])path;
usz len = path_str.len;
if (!len) return (Path)"";
$if (USE_WIN32_FILESYSTEM):
usz root_len = root_name_len(path_str)!!;
if (root_len == len || !is_separator(path_str[root_len])) return (Path)"";
return (Path)path_str[root_len..root_len];
$else:
if (!is_separator(path_str[0])) return (Path)"";
for (usz i = 1; i < len; i++)
{
if (is_separator(path_str[i]))
{
return (Path)path_str[:i];
}
}
return path;
$endif;
}
fn void Path.destroy(Path path)
{
free(path.ptr);
}
define Dir = distinct PlatformDir*;
$if (env::OS_TYPE == OsType.WIN32):
/*
private extern ulong _win32_GetCurrentDirectoryW(ulong, Char16* buffer) @extname("GetCurrentDirectoryW");
private extern bool _win32_CreateSymbolicLinkW(Char16* symlink_file, Char16* target_file, ulong flags) @extname("CreateSymbolicLinkW");
private extern bool _win32_CreateDirectoryW(Char16* path_name, void* security_attributes) @extname("CreateDirectoryW");
private extern bool _win32_DeleteFileW(Char16* file) @extname("DeleteFileW");
private extern bool _win32_CopyFileW(Char16* from_file, Char16* to_file, bool no_overwrite) @extname("CopyFileW");
private extern ulong _win32_GetFullPathNameW(Char16* file_name, ulong buffer_len, Char16* buffer, Char16** file_part) @extname("GetFullPathNameW");
*/
$endif;

View File

@@ -15,7 +15,7 @@ struct List
/**
* @require allocator != null "A valid allocator must be provided"
**/
fn void List.init(List* list, usz initial_capacity = 16, Allocator* allocator = mem::temp_allocator())
fn void List.init(List* list, usz initial_capacity = 16, Allocator* allocator = mem::current_allocator())
{
list.allocator = allocator;
list.size = 0;
@@ -31,6 +31,10 @@ fn void List.init(List* list, usz initial_capacity = 16, Allocator* allocator =
list.capacity = initial_capacity;
}
fn void List.tinit(List* list, usz initial_capacity = 16)
{
list.init(initial_capacity, mem::temp_allocator()) @inline;
}
fn void List.push(List *list, Type element) @inline
{

View File

@@ -28,7 +28,7 @@ struct HashMap
* @require capacity < MAXIMUM_CAPACITY "Capacity cannot exceed maximum"
* @require allocator != null "The allocator must be non-null"
**/
fn void HashMap.init(HashMap* map, uint capacity = DEFAULT_INITIAL_CAPACITY, float load_factor = DEFAULT_LOAD_FACTOR, Allocator* allocator = mem::temp_allocator())
fn void HashMap.init(HashMap* map, uint capacity = DEFAULT_INITIAL_CAPACITY, float load_factor = DEFAULT_LOAD_FACTOR, Allocator* allocator = mem::current_allocator())
{
capacity = math::next_power_of_2(capacity);
map.allocator = allocator;
@@ -37,12 +37,28 @@ fn void HashMap.init(HashMap* map, uint capacity = DEFAULT_INITIAL_CAPACITY, flo
map.table = array::make(Entry*, capacity, allocator);
}
fn void HashMap.init_from_map(HashMap* map, HashMap* other_map, Allocator* allocator = mem::temp_allocator())
/**
* @require capacity > 0 "The capacity must be 1 or higher"
* @require load_factor > 0.0 "The load factor must be higher than 0"
* @require !map.allocator "Map was already initialized"
* @require capacity < MAXIMUM_CAPACITY "Capacity cannot exceed maximum"
**/
fn void HashMap.tinit(HashMap* map, uint capacity = DEFAULT_INITIAL_CAPACITY, float load_factor = DEFAULT_LOAD_FACTOR)
{
map.init(capacity, load_factor, mem::temp_allocator());
}
fn void HashMap.init_from_map(HashMap* map, HashMap* other_map, Allocator* allocator = mem::current_allocator())
{
map.init(other_map.table.len, other_map.load_factor, allocator);
map.put_all_for_create(other_map);
}
fn void HashMap.tinit_from_map(HashMap* map, HashMap* other_map)
{
map.init_from_map(other_map, mem::temp_allocator()) @inline;
}
fn bool HashMap.is_empty(HashMap* map) @inline
{
return !map.count;
@@ -138,7 +154,12 @@ fn void HashMap.destroy(HashMap* map)
map.table = Entry*[] {};
}
fn Key[] HashMap.key_list(HashMap* map, Allocator* allocator = mem::temp_allocator())
fn Key[] HashMap.key_tlist(HashMap* map)
{
return map.key_list(mem::temp_allocator()) @inline;
}
fn Key[] HashMap.key_list(HashMap* map, Allocator* allocator = mem::current_allocator())
{
if (!map.count) return Key[] {};
@@ -155,7 +176,12 @@ fn Key[] HashMap.key_list(HashMap* map, Allocator* allocator = mem::temp_allocat
return list;
}
fn Value[] HashMap.value_list(HashMap* map, Allocator* allocator = mem::temp_allocator())
fn Value[] HashMap.value_tlist(HashMap* map)
{
return map.value_list(mem::temp_allocator()) @inline;
}
fn Value[] HashMap.value_list(HashMap* map, Allocator* allocator = mem::current_allocator())
{
if (!map.count) return Value[] {};
Value[] list = array::make(Value, map.count, allocator);

View File

@@ -28,7 +28,7 @@ macro Class! class_by_name(char* c)
return cls;
}
macro Class[] class_get_list(Allocator *allocator = mem::temp_allocator())
macro Class[] class_get_list(Allocator *allocator = mem::current_allocator())
{
int num_classes = _macos_objc_getClassList(null, 0);
if (!num_classes) return {};

12
lib/std/os/win32/files.c3 Normal file
View File

@@ -0,0 +1,12 @@
module std::os::win32::files;
$if (env::OS_TYPE == OsType.WIN32):
/*
private extern ulong _win32_GetCurrentDirectoryW(ulong, Char16* buffer) @extname("GetCurrentDirectoryW");
private extern bool _win32_CreateSymbolicLinkW(Char16* symlink_file, Char16* target_file, ulong flags) @extname("CreateSymbolicLinkW");
private extern bool _win32_CreateDirectoryW(Char16* path_name, void* security_attributes) @extname("CreateDirectoryW");
private extern bool _win32_DeleteFileW(Char16* file) @extname("DeleteFileW");
private extern bool _win32_CopyFileW(Char16* from_file, Char16* to_file, bool no_overwrite) @extname("CopyFileW");
private extern ulong _win32_GetFullPathNameW(Char16* file_name, ulong buffer_len, Char16* buffer, Char16** file_part) @extname("GetFullPathNameW");
*/
$endif;

View File

@@ -931,9 +931,10 @@ static inline bool scan_string(Lexer *lexer)
current++;
break;
}
if (c == '\\' && *current == '"')
if (c == '\\')
{
current++;
c = *current;
if (c != '\n' && c != '\0') current++;
continue;
}
}

View File

@@ -332,7 +332,7 @@ LLVMValueRef llvm_coerce_int_ptr(GenContext *c, LLVMValueRef value, LLVMTypeRef
LLVMValueRef llvm_emit_coerce(GenContext *c, LLVMTypeRef coerced, BEValue *value, Type *original_type)
{
assert(original_type->canonical == value->type->canonical);
assert(type_flatten_distinct(original_type) == type_flatten_distinct(value->type));
LLVMTypeRef llvm_source_type = llvm_get_type(c, value->type);
// 1. If the types match then we're done, just load.

View File

@@ -86,11 +86,13 @@ bool pointer_to_bool(Expr *expr, Type *type)
{
if (insert_runtime_cast_unless_const(expr, CAST_PTRBOOL, type)) return true;
// Must have been a null
expr->const_expr.b = false;
expr->type = type;
expr->const_expr.narrowable = false;
expr->const_expr.is_hex = false;
if (expr->const_expr.const_kind == CONST_POINTER)
{
expr_rewrite_const_bool(expr, type, expr->const_expr.ptr != 0);
return true;
}
assert(expr->const_expr.const_kind == CONST_STRING);
expr_rewrite_const_bool(expr, type, true);
return true;
}

View File

@@ -1796,9 +1796,9 @@ static bool sema_analyse_nextcase_stmt(SemaContext *context, Ast *statement)
static inline bool sema_analyse_then_overwrite(SemaContext *context, Ast *statement, AstId replacement)
{
statement->ast_kind = AST_NOP_STMT;
if (!replacement)
{
statement->ast_kind = AST_NOP_STMT;
return true;
}
AstId current = replacement;
@@ -1814,9 +1814,9 @@ static inline bool sema_analyse_then_overwrite(SemaContext *context, Ast *statem
break;
}
}
// Overwrite but store link.
// NOP and insert after.
last->next = statement->next;
*statement = *astptr(replacement);
statement->next = replacement;
return true;
}

View File

@@ -1 +1 @@
#define COMPILER_VERSION "0.3.88"
#define COMPILER_VERSION "0.3.89"

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff