mirror of
https://github.com/c3lang/c3c.git
synced 2026-02-27 12:01:16 +00:00
0.6.0: init_new/init_temp removed. LinkedList API rewritten. List "pop" and "remove" function now return Optionals. RingBuffer API rewritten. Allocator interface changed. Deprecated Allocator, DString and mem functions removed. "identity" functions are now constants for Matrix and Complex numbers. @default implementations for interfaces removed. any* => any, same for interfaces. Emit local/private globals as "private" in LLVM, following C "static". Updated enum syntax. Add support [rgba] properties in vectors. Improved checks of aliased "void". Subarray -> slice. Fix of llvm codegen enum check. Improved alignment handling. Add --output-dir #1155. Removed List/Object append. GenericList renamed AnyList. Remove unused "unwrap". Fixes to cond. Optimize output in dead branches. Better checking of operator methods. Disallow any from implementing dynamic methods. Check for operator mismatch. Remove unnecessary bitfield. Remove numbering in --list* commands Old style enum declaration for params/type, but now the type is optional. Add note on #1086. Allow making distinct types out of "void", "typeid", "anyfault" and faults. Remove system linker build options. "Try" expressions must be simple expressions. Add optimized build to Mac tests. Register int. assert(false) only allowed in unused branches or in tests. Compile time failed asserts is a compile time error. Remove current_block_is_target. Bug when assigning an optional from an optional. Remove unused emit_zstring. Simplify phi code. Remove unnecessary unreachable blocks and remove unnecessary current_block NULL assignments. Proper handling of '.' and Win32 '//server' paths. Add "no discard" to expression blocks with a return value. Detect "unsigned >= 0" as errors. Fix issue with distinct void as a member #1147. Improve callstack debug information #1184. Fix issue with absolute output-dir paths. Lambdas were not type checked thoroughly #1185. Fix compilation warning #1187. Request jump table using @jump for switches. Path normalization - fix possible null terminator out of bounds. Improved error messages on inlined macros.
Upgrade of mingw in CI. Fix problems using reflection on interface types #1203. Improved debug information on defer. $foreach doesn't create an implicit syntactic scope. Error if `@if` depends on `@if`. Updated Linux stacktrace. Fix of default argument stacktrace. Allow linking libraries directly by file path. Improve inlining warning messages. Added `index_of_char_from`. Compiler crash using enum nameof from different module #1205. Removed unused fields in find_msvc. Use vswhere to find msvc. Update tests for LLVM 19
This commit is contained in:
@@ -31,6 +31,11 @@ fault NumberConversion
|
||||
FLOAT_OUT_OF_RANGE,
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a temporary String created using the formatting function.
|
||||
*
|
||||
* @param [in] fmt `The formatting string`
|
||||
**/
|
||||
macro String tformat(String fmt, ...)
|
||||
{
|
||||
DString str = dstring::temp_with_capacity(fmt.len + $vacount * 8);
|
||||
@@ -38,6 +43,11 @@ macro String tformat(String fmt, ...)
|
||||
return str.str_view();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a temporary ZString created using the formatting function.
|
||||
*
|
||||
* @param [in] fmt `The formatting string`
|
||||
**/
|
||||
macro ZString tformat_zstr(String fmt, ...)
|
||||
{
|
||||
DString str = dstring::temp_with_capacity(fmt.len + $vacount * 8);
|
||||
@@ -45,7 +55,13 @@ macro ZString tformat_zstr(String fmt, ...)
|
||||
return str.zstr_view();
|
||||
}
|
||||
|
||||
macro String new_format(String fmt, ..., Allocator* allocator = allocator::heap())
|
||||
/**
|
||||
* Return a new String created using the formatting function.
|
||||
*
|
||||
* @param [in] fmt `The formatting string`
|
||||
* @param [inout] allocator `The allocator to use`
|
||||
**/
|
||||
macro String new_format(String fmt, ..., Allocator allocator = allocator::heap())
|
||||
{
|
||||
@pool(allocator)
|
||||
{
|
||||
@@ -55,7 +71,13 @@ macro String new_format(String fmt, ..., Allocator* allocator = allocator::heap(
|
||||
};
|
||||
}
|
||||
|
||||
macro ZString new_format_zstr(String fmt, ..., Allocator* allocator = allocator::heap())
|
||||
/**
|
||||
* Return a new ZString created using the formatting function.
|
||||
*
|
||||
* @param [in] fmt `The formatting string`
|
||||
* @param [inout] allocator `The allocator to use`
|
||||
**/
|
||||
macro ZString new_format_zstr(String fmt, ..., Allocator allocator = allocator::heap())
|
||||
{
|
||||
@pool(allocator)
|
||||
{
|
||||
@@ -65,13 +87,21 @@ macro ZString new_format_zstr(String fmt, ..., Allocator* allocator = allocator:
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if a character is in a set.
|
||||
*
|
||||
* @param c `the character to check`
|
||||
* @param [in] set `The formatting string`
|
||||
* @pure
|
||||
* @return `True if a character is in the set`
|
||||
**/
|
||||
macro bool char_in_set(char c, String set)
|
||||
{
|
||||
foreach (ch : set) if (ch == c) return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
fn String join_new(String[] s, String joiner, Allocator* allocator = allocator::heap())
|
||||
fn String join_new(String[] s, String joiner, Allocator allocator = allocator::heap())
|
||||
{
|
||||
if (!s)
|
||||
{
|
||||
@@ -97,8 +127,12 @@ fn String join_new(String[] s, String joiner, Allocator* allocator = allocator::
|
||||
}
|
||||
|
||||
/**
|
||||
* @param [in] string
|
||||
* @param [in] to_trim
|
||||
* Remove characters from the front and end of a string.
|
||||
*
|
||||
* @param [in] string `The string to trim`
|
||||
* @param [in] to_trim `The set of characters to trim, defaults to whitespace`
|
||||
* @pure
|
||||
* @return `a substring of the string passed in`
|
||||
**/
|
||||
fn String String.trim(string, String to_trim = "\t\n\r ")
|
||||
{
|
||||
@@ -112,8 +146,12 @@ fn String String.trim(string, String to_trim = "\t\n\r ")
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the String starts with the needle.
|
||||
*
|
||||
* @param [in] string
|
||||
* @param [in] needle
|
||||
* @pure
|
||||
* @return `'true' if the string starts with the needle`
|
||||
**/
|
||||
fn bool String.starts_with(string, String needle)
|
||||
{
|
||||
@@ -123,8 +161,12 @@ fn bool String.starts_with(string, String needle)
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the String ends with the needle.
|
||||
*
|
||||
* @param [in] string
|
||||
* @param [in] needle
|
||||
* @pure
|
||||
* @return `'true' if the string ends with the needle`
|
||||
**/
|
||||
fn bool String.ends_with(string, String needle)
|
||||
{
|
||||
@@ -138,6 +180,8 @@ fn bool String.ends_with(string, String needle)
|
||||
*
|
||||
* @param [in] string
|
||||
* @param [in] needle
|
||||
* @pure
|
||||
* @return `the substring with the prefix removed`
|
||||
**/
|
||||
fn String String.strip(string, String needle)
|
||||
{
|
||||
@@ -150,6 +194,8 @@ fn String String.strip(string, String needle)
|
||||
*
|
||||
* @param [in] string
|
||||
* @param [in] needle
|
||||
* @pure
|
||||
* @return `the substring with the suffix removed`
|
||||
**/
|
||||
fn String String.strip_end(string, String needle)
|
||||
{
|
||||
@@ -169,7 +215,7 @@ fn String String.strip_end(string, String needle)
|
||||
* @require needle.len > 0 "The needle must be at least 1 character long"
|
||||
* @ensure return.len > 0
|
||||
**/
|
||||
fn String[] String.split(s, String needle, usz max = 0, Allocator* allocator = allocator::heap())
|
||||
fn String[] String.split(s, String needle, usz max = 0, Allocator allocator = allocator::heap())
|
||||
{
|
||||
usz capacity = 16;
|
||||
usz i = 0;
|
||||
@@ -212,6 +258,14 @@ fn String[] String.tsplit(s, String needle, usz max = 0)
|
||||
return s.split(needle, max, allocator::temp()) @inline;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if a substring is found in the string.
|
||||
|
||||
* @param [in] s
|
||||
* @param [in] needle "The string to look for."
|
||||
* @pure
|
||||
* @return "true if the string contains the substring, false otherwise"
|
||||
**/
|
||||
fn bool String.contains(s, String needle)
|
||||
{
|
||||
return @ok(s.index_of(needle));
|
||||
@@ -221,6 +275,7 @@ fn bool String.contains(s, String needle)
|
||||
* Find the index of the first incidence of a string.
|
||||
*
|
||||
* @param [in] s
|
||||
* @param needle "The character to look for"
|
||||
* @pure
|
||||
* @ensure return < s.len
|
||||
* @return "the index of the needle"
|
||||
@@ -236,9 +291,32 @@ fn usz! String.index_of_char(s, char needle)
|
||||
}
|
||||
|
||||
/**
|
||||
* Find the index of the first incidence of a string.
|
||||
* Find the index of the first incidence of a character.
|
||||
*
|
||||
* @param [in] s
|
||||
* @param needle "The character to look for"
|
||||
* @param start_index "The index to start with, may exceed max index."
|
||||
* @pure
|
||||
* @ensure return < s.len
|
||||
* @return "the index of the needle"
|
||||
* @return! SearchResult.MISSING "if the needle cannot be found starting from the start_index"
|
||||
**/
|
||||
fn usz! String.index_of_char_from(s, char needle, usz start_index)
|
||||
{
|
||||
usz len = s.len;
|
||||
if (len <= start_index) return SearchResult.MISSING?;
|
||||
for (usz i = start_index; i < len; i++)
|
||||
{
|
||||
if (s[i] == needle) return i;
|
||||
}
|
||||
return SearchResult.MISSING?;
|
||||
}
|
||||
|
||||
/**
|
||||
* Find the index of the first incidence of a character starting from the end.
|
||||
*
|
||||
* @param [in] s
|
||||
* @param needle "the character to find"
|
||||
* @pure
|
||||
* @ensure return < s.len
|
||||
* @return "the index of the needle"
|
||||
@@ -328,7 +406,7 @@ fn usz ZString.len(str)
|
||||
}
|
||||
|
||||
|
||||
fn ZString String.zstr_copy(s, Allocator* allocator = allocator::heap())
|
||||
fn ZString String.zstr_copy(s, Allocator allocator = allocator::heap())
|
||||
{
|
||||
usz len = s.len;
|
||||
char* str = allocator::malloc(allocator, len + 1);
|
||||
@@ -337,7 +415,7 @@ fn ZString String.zstr_copy(s, Allocator* allocator = allocator::heap())
|
||||
return (ZString)str;
|
||||
}
|
||||
|
||||
fn String String.concat(s1, String s2, Allocator* allocator = allocator::heap())
|
||||
fn String String.concat(s1, String s2, Allocator allocator = allocator::heap())
|
||||
{
|
||||
usz full_len = s1.len + s2.len;
|
||||
char* str = allocator::malloc(allocator, full_len + 1);
|
||||
@@ -353,7 +431,7 @@ fn String String.tconcat(s1, String s2) => s1.concat(s2, allocator::temp());
|
||||
|
||||
fn ZString String.zstr_tcopy(s) => s.zstr_copy(allocator::temp()) @inline;
|
||||
|
||||
fn String String.copy(s, Allocator* allocator = allocator::heap())
|
||||
fn String String.copy(s, Allocator allocator = allocator::heap())
|
||||
{
|
||||
usz len = s.len;
|
||||
char* str = allocator::malloc(allocator, len + 1);
|
||||
@@ -362,7 +440,7 @@ fn String String.copy(s, Allocator* allocator = allocator::heap())
|
||||
return (String)str[:len];
|
||||
}
|
||||
|
||||
fn void String.free(&s, Allocator* allocator = allocator::heap())
|
||||
fn void String.free(&s, Allocator allocator = allocator::heap())
|
||||
{
|
||||
if (!s.len) return;
|
||||
allocator::free(allocator, s.ptr);
|
||||
@@ -371,7 +449,7 @@ fn void String.free(&s, Allocator* allocator = allocator::heap())
|
||||
|
||||
fn String String.tcopy(s) => s.copy(allocator::temp()) @inline;
|
||||
|
||||
fn String ZString.copy(z, Allocator* allocator = allocator::temp())
|
||||
fn String ZString.copy(z, Allocator allocator = allocator::temp())
|
||||
{
|
||||
return z.str_view().copy(allocator) @inline;
|
||||
}
|
||||
@@ -387,7 +465,7 @@ fn String ZString.tcopy(z)
|
||||
* @return! UnicodeResult.INVALID_UTF8 "If the string contained an invalid UTF-8 sequence"
|
||||
* @return! AllocationFailure "If allocation of the string fails"
|
||||
**/
|
||||
fn Char16[]! String.to_new_utf16(s, Allocator* allocator = allocator::heap())
|
||||
fn Char16[]! String.to_new_utf16(s, Allocator allocator = allocator::heap())
|
||||
{
|
||||
usz len16 = conv::utf16len_for_utf8(s);
|
||||
Char16* data = allocator::alloc_array_try(allocator, Char16, len16 + 1)!;
|
||||
@@ -407,7 +485,7 @@ fn Char16[]! String.to_temp_utf16(s)
|
||||
return s.to_new_utf16(allocator::temp());
|
||||
}
|
||||
|
||||
fn WString! String.to_new_wstring(s, Allocator* allocator = allocator::heap())
|
||||
fn WString! String.to_new_wstring(s, Allocator allocator = allocator::heap())
|
||||
{
|
||||
return (WString)s.to_new_utf16(allocator).ptr;
|
||||
}
|
||||
@@ -417,7 +495,7 @@ fn WString! String.to_temp_wstring(s)
|
||||
return (WString)s.to_temp_utf16().ptr;
|
||||
}
|
||||
|
||||
fn Char32[]! String.to_new_utf32(s, Allocator* allocator = allocator::heap())
|
||||
fn Char32[]! String.to_new_utf32(s, Allocator allocator = allocator::heap())
|
||||
{
|
||||
usz codepoints = conv::utf8_codepoints(s);
|
||||
Char32* data = allocator::alloc_array_try(allocator, Char32, codepoints + 1)!;
|
||||
@@ -431,29 +509,49 @@ fn Char32[]! String.to_temp_utf32(s)
|
||||
return s.to_new_utf32(allocator::temp());
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert a string to ASCII lower case.
|
||||
*
|
||||
* @param [inout] s
|
||||
* @pure
|
||||
**/
|
||||
fn void String.convert_ascii_to_lower(s)
|
||||
{
|
||||
foreach (&c : s) if (c.is_upper()) *c += 'a' - 'A';
|
||||
foreach (&c : s) if (c.is_upper() @pure) *c += 'a' - 'A';
|
||||
}
|
||||
|
||||
fn String String.new_ascii_to_lower(s, Allocator* allocator = allocator::heap())
|
||||
fn String String.new_ascii_to_lower(s, Allocator allocator = allocator::heap())
|
||||
{
|
||||
String copy = s.copy(allocator);
|
||||
copy.convert_ascii_to_lower();
|
||||
return copy;
|
||||
}
|
||||
|
||||
fn String String.temp_ascii_to_lower(s, Allocator* allocator = allocator::heap())
|
||||
fn String String.temp_ascii_to_lower(s, Allocator allocator = allocator::heap())
|
||||
{
|
||||
return s.new_ascii_to_lower(allocator::temp());
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert a string to ASCII upper case.
|
||||
*
|
||||
* @param [inout] s
|
||||
* @pure
|
||||
**/
|
||||
fn void String.convert_ascii_to_upper(s)
|
||||
{
|
||||
foreach (&c : s) if (c.is_lower()) *c -= 'a' - 'A';
|
||||
foreach (&c : s) if (c.is_lower() @pure) *c -= 'a' - 'A';
|
||||
}
|
||||
|
||||
fn String String.new_ascii_to_upper(s, Allocator* allocator = allocator::heap())
|
||||
/**
|
||||
* Returns a string converted to ASCII upper case.
|
||||
*
|
||||
* @param [in] s
|
||||
* @param [inout] allocator
|
||||
*
|
||||
* @return `a new String converted to ASCII upper case.`
|
||||
**/
|
||||
fn String String.new_ascii_to_upper(s, Allocator allocator = allocator::heap())
|
||||
{
|
||||
String copy = s.copy(allocator);
|
||||
copy.convert_ascii_to_upper();
|
||||
@@ -465,12 +563,16 @@ fn StringIterator String.iterator(s)
|
||||
return { s, 0 };
|
||||
}
|
||||
|
||||
/**
|
||||
* @param [in] s
|
||||
* @return `a temporary String converted to ASCII upper case.`
|
||||
**/
|
||||
fn String String.temp_ascii_to_upper(s)
|
||||
{
|
||||
return s.new_ascii_to_upper(allocator::temp());
|
||||
}
|
||||
|
||||
fn String! new_from_utf32(Char32[] utf32, Allocator* allocator = allocator::heap())
|
||||
fn String! new_from_utf32(Char32[] utf32, Allocator allocator = allocator::heap())
|
||||
{
|
||||
usz len = conv::utf8len_for_utf32(utf32);
|
||||
char* data = allocator::malloc_try(allocator, len + 1)!;
|
||||
@@ -480,7 +582,7 @@ fn String! new_from_utf32(Char32[] utf32, Allocator* allocator = allocator::heap
|
||||
return (String)data[:len];
|
||||
}
|
||||
|
||||
fn String! new_from_utf16(Char16[] utf16, Allocator* allocator = allocator::heap())
|
||||
fn String! new_from_utf16(Char16[] utf16, Allocator allocator = allocator::heap())
|
||||
{
|
||||
usz len = conv::utf8len_for_utf16(utf16);
|
||||
char* data = allocator::malloc_try(allocator, len + 1)!;
|
||||
@@ -490,7 +592,7 @@ fn String! new_from_utf16(Char16[] utf16, Allocator* allocator = allocator::heap
|
||||
return (String)data[:len];
|
||||
}
|
||||
|
||||
fn String! new_from_wstring(WString wstring, Allocator* allocator = allocator::heap())
|
||||
fn String! new_from_wstring(WString wstring, Allocator allocator = allocator::heap())
|
||||
{
|
||||
usz utf16_len;
|
||||
while (wstring[utf16_len] != 0) utf16_len++;
|
||||
|
||||
Reference in New Issue
Block a user