mirror of
https://github.com/c3lang/c3c.git
synced 2026-02-27 12:01:16 +00:00
Use "String" consistently for "char[]" (#694)
Use "String" consistently for "char[]". Fix win32 return value.
This commit is contained in:
committed by
GitHub
parent
5b2b4e900f
commit
43dc2d650c
@@ -56,12 +56,12 @@ macro varcast(variant v, $Type) @builtin
|
||||
struct CallstackElement
|
||||
{
|
||||
CallstackElement* prev;
|
||||
char[] function;
|
||||
char[] file;
|
||||
String function;
|
||||
String file;
|
||||
uint line;
|
||||
}
|
||||
|
||||
fn void default_panic(char[] message, char[] file, char[] function, uint line)
|
||||
fn void default_panic(String message, String file, String function, uint line)
|
||||
{
|
||||
CallstackElement* stack = $$stacktrace();
|
||||
$if ($defined(libc::stderr) && $defined(libc::fprintf)):
|
||||
@@ -88,7 +88,7 @@ fn void default_panic(char[] message, char[] file, char[] function, uint line)
|
||||
$$trap();
|
||||
}
|
||||
|
||||
define PanicFn = fn void(char[] message, char[] file, char[] function, uint line);
|
||||
define PanicFn = fn void(String message, String file, String function, uint line);
|
||||
|
||||
PanicFn panic = &default_panic;
|
||||
|
||||
@@ -110,7 +110,7 @@ macro bitcast(expr, $Type) @builtin
|
||||
/**
|
||||
* @require $Type.kindof == TypeKind.ENUM `Only enums may be used`
|
||||
**/
|
||||
macro enum_by_name($Type, char[] enum_name) @builtin
|
||||
macro enum_by_name($Type, String enum_name) @builtin
|
||||
{
|
||||
typeid x = $Type.typeid;
|
||||
foreach (i, name : x.names)
|
||||
@@ -164,4 +164,4 @@ macro uint long.hash(long i) = (uint)((i >> 32) ^ i);
|
||||
macro uint ulong.hash(ulong i) = (uint)((i >> 32) ^ i);
|
||||
macro uint bool.hash(bool b) = (uint)b;
|
||||
macro uint typeid.hash(typeid t) = (uint)(((uptr)t >> 32) ^ (uptr)t);
|
||||
macro uint char[].hash(char[] c) = (uint)fnv32a::encode(c);
|
||||
macro uint String.hash(String c) = (uint)fnv32a::encode(c);
|
||||
@@ -185,7 +185,7 @@ fn Char32! utf8_to_char32(char* ptr, usz* size)
|
||||
* @param utf8 `An UTF-8 encoded slice of bytes`
|
||||
* @return `the number of encoded code points`
|
||||
**/
|
||||
fn usz utf8_codepoints(char[] utf8)
|
||||
fn usz utf8_codepoints(String utf8)
|
||||
{
|
||||
usz len = 0;
|
||||
foreach (char c : utf8)
|
||||
@@ -257,7 +257,7 @@ fn usz utf8len_for_utf16(Char16[] utf16)
|
||||
* @param utf8 `the utf8 data to calculate from`
|
||||
* @return `the length of the resulting UTF16 array`
|
||||
**/
|
||||
fn usz utf16len_for_utf8(char[] utf8)
|
||||
fn usz utf16len_for_utf8(String utf8)
|
||||
{
|
||||
usz len = utf8.len;
|
||||
usz len16 = 0;
|
||||
@@ -297,7 +297,7 @@ fn usz utf16len_for_utf32(Char32[] utf32)
|
||||
* @param [out] utf8_buffer
|
||||
* @return `the number of bytes written.`
|
||||
**/
|
||||
fn usz! utf32to8(Char32[] utf32, char[] utf8_buffer)
|
||||
fn usz! utf32to8(Char32[] utf32, String utf8_buffer)
|
||||
{
|
||||
usz len = utf8_buffer.len;
|
||||
char* ptr = utf8_buffer.ptr;
|
||||
@@ -317,7 +317,7 @@ fn usz! utf32to8(Char32[] utf32, char[] utf8_buffer)
|
||||
* @param [out] utf32_buffer
|
||||
* @return `the number of Char32s written.`
|
||||
**/
|
||||
fn usz! utf8to32(char[] utf8, Char32[] utf32_buffer)
|
||||
fn usz! utf8to32(String utf8, Char32[] utf32_buffer)
|
||||
{
|
||||
usz len = utf8.len;
|
||||
Char32* ptr = utf32_buffer.ptr;
|
||||
@@ -361,7 +361,7 @@ fn void! utf16to8_unsafe(Char16[] utf16, char* utf8_buffer)
|
||||
* @param [in] utf8 `The UTF8 buffer containing the data to convert.`
|
||||
* @param [out] utf32_buffer `the (sufficiently large) buffer to hold the UTF8 data.`
|
||||
**/
|
||||
fn void! utf8to32_unsafe(char[] utf8, Char32* utf32_buffer)
|
||||
fn void! utf8to32_unsafe(String utf8, Char32* utf32_buffer)
|
||||
{
|
||||
usz len = utf8.len;
|
||||
for (usz i = 0; i < len;)
|
||||
@@ -381,7 +381,7 @@ fn void! utf8to32_unsafe(char[] utf8, Char32* utf32_buffer)
|
||||
* @param [in] utf8 `The UTF8 buffer containing the data to convert.`
|
||||
* @param [out] utf16_buffer `the (sufficiently large) buffer to hold the UTF8 data.`
|
||||
**/
|
||||
fn void! utf8to16_unsafe(char[] utf8, Char16* utf16_buffer)
|
||||
fn void! utf8to16_unsafe(String utf8, Char16* utf16_buffer)
|
||||
{
|
||||
usz len = utf8.len;
|
||||
for (usz i = 0; i < len;)
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
module std::core::str;
|
||||
|
||||
define ZString = distinct char*;
|
||||
define String = char[];
|
||||
define Char32 = uint;
|
||||
define Char16 = ushort;
|
||||
|
||||
@@ -18,17 +20,17 @@ fault NumberConversion
|
||||
MALFORMED_INTEGER,
|
||||
INTEGER_OVERFLOW,
|
||||
}
|
||||
fn String join(char[][] s, char[] joiner)
|
||||
fn VarString join(String[] s, String joiner)
|
||||
{
|
||||
if (!s.len) return (String)null;
|
||||
if (!s.len) return (VarString)null;
|
||||
usz total_size = joiner.len * s.len;
|
||||
foreach (char[]* &str : s)
|
||||
foreach (String* &str : s)
|
||||
{
|
||||
total_size += str.len;
|
||||
}
|
||||
String res = string::new_with_capacity(total_size);
|
||||
VarString res = string::new_with_capacity(total_size);
|
||||
res.append(s[0]);
|
||||
foreach (char[]* &str : s[1..])
|
||||
foreach (String* &str : s[1..])
|
||||
{
|
||||
res.append(joiner);
|
||||
res.append(*str);
|
||||
@@ -36,7 +38,7 @@ fn String join(char[][] s, char[] joiner)
|
||||
return res;
|
||||
}
|
||||
|
||||
macro bool char_in_set(char c, char[] set)
|
||||
macro bool char_in_set(char c, String set)
|
||||
{
|
||||
foreach (ch : set)
|
||||
{
|
||||
@@ -50,7 +52,7 @@ private macro char_is_space_tab(char c)
|
||||
return c == ' ' || c == '\t';
|
||||
}
|
||||
|
||||
private macro to_integer($Type, char[] string)
|
||||
private macro to_integer($Type, String string)
|
||||
{
|
||||
usz len = string.len;
|
||||
usz index = 0;
|
||||
@@ -121,19 +123,19 @@ private macro to_integer($Type, char[] string)
|
||||
return value;
|
||||
}
|
||||
|
||||
fn int128! to_int128(char[] string) = to_integer(int128, string);
|
||||
fn long! to_long(char[] string) = to_integer(long, string);
|
||||
fn int! to_int(char[] string) = to_integer(int, string);
|
||||
fn short! to_short(char[] string) = to_integer(short, string);
|
||||
fn ichar! to_ichar(char[] string) = to_integer(ichar, string);
|
||||
fn int128! to_int128(String string) = to_integer(int128, string);
|
||||
fn long! to_long(String string) = to_integer(long, string);
|
||||
fn int! to_int(String string) = to_integer(int, string);
|
||||
fn short! to_short(String string) = to_integer(short, string);
|
||||
fn ichar! to_ichar(String string) = to_integer(ichar, string);
|
||||
|
||||
fn uint128! to_uint128(char[] str) = to_integer(uint128, str);
|
||||
fn ulong! to_ulong(char[] str) = to_integer(ulong, str);
|
||||
fn uint! to_uint(char[] str) = to_integer(uint, str);
|
||||
fn ushort! to_ushort(char[] str) = to_integer(ushort, str);
|
||||
fn char! to_uchar(char[] str) = to_integer(char, str);
|
||||
fn uint128! to_uint128(String str) = to_integer(uint128, str);
|
||||
fn ulong! to_ulong(String str) = to_integer(ulong, str);
|
||||
fn uint! to_uint(String str) = to_integer(uint, str);
|
||||
fn ushort! to_ushort(String str) = to_integer(ushort, str);
|
||||
fn char! to_uchar(String str) = to_integer(char, str);
|
||||
|
||||
fn char[] trim(char[] string, char[] to_trim = "\t\n\r ")
|
||||
fn String trim(String string, String to_trim = "\t\n\r ")
|
||||
{
|
||||
usz start = 0;
|
||||
usz len = string.len;
|
||||
@@ -144,7 +146,7 @@ fn char[] trim(char[] string, char[] to_trim = "\t\n\r ")
|
||||
return string[start..end];
|
||||
}
|
||||
|
||||
fn bool starts_with(char[] s, char[] needle)
|
||||
fn bool starts_with(String s, String needle)
|
||||
{
|
||||
if (needle.len > s.len) return false;
|
||||
foreach (i, c : needle)
|
||||
@@ -154,17 +156,17 @@ fn bool starts_with(char[] s, char[] needle)
|
||||
return true;
|
||||
}
|
||||
|
||||
fn char[][] tsplit(char[] s, char[] needle) = split(s, needle, mem::temp_allocator()) @inline;
|
||||
fn String[] tsplit(String s, String needle) = split(s, needle, mem::temp_allocator()) @inline;
|
||||
|
||||
fn char[][] split(char[] s, char[] needle, Allocator* allocator = mem::current_allocator())
|
||||
fn String[] split(String s, String needle, Allocator* allocator = mem::current_allocator())
|
||||
{
|
||||
usz capacity = 16;
|
||||
usz i = 0;
|
||||
char[]* holder = allocator.alloc(char[].sizeof * capacity)!!;
|
||||
String* holder = allocator.alloc(String.sizeof * capacity)!!;
|
||||
while (s.len)
|
||||
{
|
||||
usz! index = index_of(s, needle);
|
||||
char[] res = void;
|
||||
String res = void;
|
||||
if (try index)
|
||||
{
|
||||
res = s[:index];
|
||||
@@ -178,14 +180,14 @@ fn char[][] split(char[] s, char[] needle, Allocator* allocator = mem::current_a
|
||||
if (i == capacity)
|
||||
{
|
||||
capacity *= 2;
|
||||
holder = allocator.realloc(holder, char[].sizeof * capacity)!!;
|
||||
holder = allocator.realloc(holder, String.sizeof * capacity)!!;
|
||||
}
|
||||
holder[i++] = res;
|
||||
}
|
||||
return holder[:i];
|
||||
}
|
||||
|
||||
fn usz! rindex_of(char[] s, char[] needle)
|
||||
fn usz! rindex_of(String s, String needle)
|
||||
{
|
||||
usz match = 0;
|
||||
usz needed = needle.len;
|
||||
@@ -211,7 +213,7 @@ fn usz! rindex_of(char[] s, char[] needle)
|
||||
return SearchResult.MISSING!;
|
||||
}
|
||||
|
||||
fn usz! index_of(char[] s, char[] needle)
|
||||
fn usz! index_of(String s, String needle)
|
||||
{
|
||||
usz match = 0;
|
||||
usz needed = needle.len;
|
||||
@@ -237,7 +239,7 @@ fn usz! index_of(char[] s, char[] needle)
|
||||
return SearchResult.MISSING!;
|
||||
}
|
||||
|
||||
fn ZString copy_zstring(char[] s, Allocator* allocator = mem::current_allocator())
|
||||
fn ZString copy_zstring(String s, Allocator* allocator = mem::current_allocator())
|
||||
{
|
||||
usz len = s.len;
|
||||
char* str = allocator.alloc(len + 1)!!;
|
||||
@@ -246,7 +248,7 @@ fn ZString copy_zstring(char[] s, Allocator* allocator = mem::current_allocator(
|
||||
return (ZString)str;
|
||||
}
|
||||
|
||||
fn char[] copyz(char[] s, Allocator* allocator = mem::current_allocator())
|
||||
fn String copyz(String s, Allocator* allocator = mem::current_allocator())
|
||||
{
|
||||
usz len = s.len;
|
||||
char* str = allocator.alloc(len + 1)!!;
|
||||
@@ -255,12 +257,12 @@ fn char[] copyz(char[] s, Allocator* allocator = mem::current_allocator())
|
||||
return str[:len];
|
||||
}
|
||||
|
||||
fn ZString tcopy_zstring(char[] s)
|
||||
fn ZString tcopy_zstring(String s)
|
||||
{
|
||||
return copy_zstring(s, mem::temp_allocator());
|
||||
}
|
||||
|
||||
fn bool compare(char[] a, char[] b)
|
||||
fn bool compare(String a, String b)
|
||||
{
|
||||
if (a.len != b.len) return false;
|
||||
foreach (i, c : a)
|
||||
@@ -276,7 +278,7 @@ fault UnicodeResult
|
||||
CONVERSION_FAILED,
|
||||
}
|
||||
|
||||
fn usz utf8_codepoints(char[] utf8)
|
||||
fn usz utf8_codepoints(String utf8)
|
||||
{
|
||||
usz len = 0;
|
||||
foreach (char c : utf8)
|
||||
@@ -286,7 +288,7 @@ fn usz utf8_codepoints(char[] utf8)
|
||||
return len;
|
||||
}
|
||||
|
||||
fn Char32[]! utf8to32(char[] utf8, Allocator* allocator = mem::current_allocator)
|
||||
fn Char32[]! utf8to32(String utf8, Allocator* allocator = mem::current_allocator)
|
||||
{
|
||||
usz codepoints = conv::utf8_codepoints(utf8);
|
||||
Char32* data = allocator.alloc(Char32.sizeof * (codepoints + 1))?;
|
||||
@@ -295,7 +297,7 @@ fn Char32[]! utf8to32(char[] utf8, Allocator* allocator = mem::current_allocator
|
||||
return data[:codepoints];
|
||||
}
|
||||
|
||||
fn char[] utf32to8(Char32[] utf32, Allocator* allocator = mem::current_allocator)
|
||||
fn String utf32to8(Char32[] utf32, Allocator* allocator = mem::current_allocator)
|
||||
{
|
||||
usz len = conv::utf8len_for_utf32(utf32);
|
||||
char* data = allocator.alloc(len + 1)!!;
|
||||
@@ -304,7 +306,7 @@ fn char[] utf32to8(Char32[] utf32, Allocator* allocator = mem::current_allocator
|
||||
return data[:len];
|
||||
}
|
||||
|
||||
fn Char16[]! utf8to16(char[] utf8, Allocator* allocator = mem::current_allocator)
|
||||
fn Char16[]! utf8to16(String utf8, Allocator* allocator = mem::current_allocator)
|
||||
{
|
||||
usz len16 = conv::utf16len_for_utf8(utf8);
|
||||
Char16* data = allocator.alloc((len16 + 1) * Char16.sizeof)?;
|
||||
@@ -314,7 +316,7 @@ fn Char16[]! utf8to16(char[] utf8, Allocator* allocator = mem::current_allocator
|
||||
}
|
||||
|
||||
|
||||
fn char[]! utf16to8(Char16[] utf16, Allocator* allocator = mem::current_allocator())
|
||||
fn String! utf16to8(Char16[] utf16, Allocator* allocator = mem::current_allocator())
|
||||
{
|
||||
usz len = conv::utf8len_for_utf16(utf16);
|
||||
char* data = allocator.alloc(len + 1)?;
|
||||
@@ -322,21 +324,21 @@ fn char[]! utf16to8(Char16[] utf16, Allocator* allocator = mem::current_allocato
|
||||
return data[:len];
|
||||
}
|
||||
|
||||
fn char[] copy(char[] s, Allocator* allocator = mem::current_allocator())
|
||||
fn String copy(String s, Allocator* allocator = mem::current_allocator())
|
||||
{
|
||||
usz len = s.len;
|
||||
ZString str_copy = copy_zstring(s, allocator) @inline;
|
||||
return str_copy[:len];
|
||||
}
|
||||
|
||||
fn char[] tcopy(char[] s)
|
||||
fn String tcopy(String s)
|
||||
{
|
||||
usz len = s.len;
|
||||
ZString str_copy = tcopy_zstring(s) @inline;
|
||||
return str_copy[:len];
|
||||
}
|
||||
|
||||
fn char[] tconcat(char[] s1, char[] s2)
|
||||
fn String tconcat(String s1, String s2)
|
||||
{
|
||||
usz full_len = s1.len + s2.len;
|
||||
char* str = tmalloc(full_len + 1);
|
||||
@@ -347,7 +349,7 @@ fn char[] tconcat(char[] s1, char[] s2)
|
||||
return str[:full_len];
|
||||
}
|
||||
|
||||
fn char[] concat(char[] s1, char[] s2)
|
||||
fn String concat(String s1, String s2)
|
||||
{
|
||||
usz full_len = s1.len + s2.len;
|
||||
char* str = malloc(full_len + 1);
|
||||
@@ -358,7 +360,7 @@ fn char[] concat(char[] s1, char[] s2)
|
||||
return str[:full_len];
|
||||
}
|
||||
|
||||
fn char[] ZString.as_str(ZString str)
|
||||
fn String ZString.as_str(ZString str)
|
||||
{
|
||||
return ((char*)str)[:str.len()];
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
module std::core::string;
|
||||
import libc;
|
||||
|
||||
define String = distinct void*;
|
||||
define VarString = distinct void*;
|
||||
|
||||
private struct StringData
|
||||
{
|
||||
@@ -13,30 +13,30 @@ private struct StringData
|
||||
|
||||
const usz MIN_CAPACITY = 16;
|
||||
|
||||
fn String new_with_capacity(usz capacity, Allocator* allocator = mem::current_allocator())
|
||||
fn VarString new_with_capacity(usz capacity, Allocator* allocator = mem::current_allocator())
|
||||
{
|
||||
if (capacity < MIN_CAPACITY) capacity = MIN_CAPACITY;
|
||||
StringData* data = allocator.alloc(StringData.sizeof + capacity)!!;
|
||||
data.allocator = allocator;
|
||||
data.len = 0;
|
||||
data.capacity = capacity;
|
||||
return (String)data;
|
||||
return (VarString)data;
|
||||
}
|
||||
|
||||
fn String new(char[] c)
|
||||
fn VarString new(String c)
|
||||
{
|
||||
usz len = c.len;
|
||||
String str = new_with_capacity(len);
|
||||
VarString str = new_with_capacity(len);
|
||||
StringData* data = str.data();
|
||||
if (len)
|
||||
{
|
||||
data.len = len;
|
||||
mem::copy(&data.chars, c.ptr, len);
|
||||
}
|
||||
return (String)data;
|
||||
return (VarString)data;
|
||||
}
|
||||
|
||||
fn ZString String.zstr(String str)
|
||||
fn ZString VarString.zstr(VarString str)
|
||||
{
|
||||
StringData* data = str.data();
|
||||
if (!data) return (ZString)"";
|
||||
@@ -52,7 +52,7 @@ fn ZString String.zstr(String str)
|
||||
return (ZString)&data.chars[0];
|
||||
}
|
||||
|
||||
fn usz String.len(String this)
|
||||
fn usz VarString.len(VarString this)
|
||||
{
|
||||
if (!this) return 0;
|
||||
return this.data().len;
|
||||
@@ -61,20 +61,20 @@ fn usz String.len(String this)
|
||||
/**
|
||||
* @require new_size <= this.len()
|
||||
*/
|
||||
fn void String.chop(String this, usz new_size)
|
||||
fn void VarString.chop(VarString this, usz new_size)
|
||||
{
|
||||
if (!this) return;
|
||||
this.data().len = new_size;
|
||||
}
|
||||
|
||||
fn char[] String.str(String str)
|
||||
fn String VarString.str(VarString str)
|
||||
{
|
||||
StringData* data = (StringData*)str;
|
||||
if (!data) return char[] {};
|
||||
return data.chars[:data.len];
|
||||
if (!data) return String {};
|
||||
return (String)data.chars[:data.len];
|
||||
}
|
||||
|
||||
fn void String.append_utf32(String* str, Char32[] chars)
|
||||
fn void VarString.append_utf32(VarString* str, Char32[] chars)
|
||||
{
|
||||
str.reserve(chars.len);
|
||||
foreach (Char32 c : chars)
|
||||
@@ -86,12 +86,12 @@ fn void String.append_utf32(String* str, Char32[] chars)
|
||||
/**
|
||||
* @require index < str.len()
|
||||
**/
|
||||
fn void String.set(String str, usz index, char c)
|
||||
fn void VarString.set(VarString str, usz index, char c)
|
||||
{
|
||||
str.data().chars[index] = c;
|
||||
}
|
||||
|
||||
fn void String.append_repeat(String* str, char c, usz times)
|
||||
fn void VarString.append_repeat(VarString* str, char c, usz times)
|
||||
{
|
||||
if (times == 0) return;
|
||||
str.reserve(times);
|
||||
@@ -105,7 +105,7 @@ fn void String.append_repeat(String* str, char c, usz times)
|
||||
/**
|
||||
* @require c < 0x10ffff
|
||||
*/
|
||||
fn void String.append_char32(String* str, Char32 c)
|
||||
fn void VarString.append_char32(VarString* str, Char32 c)
|
||||
{
|
||||
if (c < 0x7f)
|
||||
{
|
||||
@@ -139,23 +139,23 @@ fn void String.append_char32(String* str, Char32 c)
|
||||
data.chars[data.len++] = (char)(0x80 | (c & 0x3F));
|
||||
}
|
||||
|
||||
fn String String.tcopy(String* str) = str.copy(mem::temp_allocator());
|
||||
fn VarString VarString.tcopy(VarString* str) = str.copy(mem::temp_allocator());
|
||||
|
||||
fn String String.copy(String* str, Allocator* allocator = null)
|
||||
fn VarString VarString.copy(VarString* str, Allocator* allocator = null)
|
||||
{
|
||||
if (!str)
|
||||
{
|
||||
if (allocator) return new_with_capacity(0, allocator);
|
||||
return (String)null;
|
||||
return (VarString)null;
|
||||
}
|
||||
if (!allocator) allocator = mem::current_allocator();
|
||||
StringData* data = str.data();
|
||||
String new_string = new_with_capacity(data.capacity, allocator);
|
||||
VarString new_string = new_with_capacity(data.capacity, allocator);
|
||||
mem::copy((char*)new_string.data(), (char*)data, StringData.sizeof + data.len);
|
||||
return new_string;
|
||||
}
|
||||
|
||||
fn ZString String.copy_zstr(String* str, Allocator* allocator = mem::current_allocator())
|
||||
fn ZString VarString.copy_zstr(VarString* str, Allocator* allocator = mem::current_allocator())
|
||||
{
|
||||
usz str_len = str.len();
|
||||
if (!str_len)
|
||||
@@ -169,14 +169,14 @@ fn ZString String.copy_zstr(String* str, Allocator* allocator = mem::current_all
|
||||
return (ZString)zstr;
|
||||
}
|
||||
|
||||
fn char[] String.copy_str(String* str, Allocator* allocator = mem::current_allocator())
|
||||
fn String VarString.copy_str(VarString* str, Allocator* allocator = mem::current_allocator())
|
||||
{
|
||||
return str.copy_zstr(allocator)[:str.len()];
|
||||
return (String)str.copy_zstr(allocator)[:str.len()];
|
||||
}
|
||||
|
||||
fn char[] String.tcopy_str(String* str) = str.copy_str(mem::temp_allocator()) @inline;
|
||||
fn String VarString.tcopy_str(VarString* str) = str.copy_str(mem::temp_allocator()) @inline;
|
||||
|
||||
fn bool String.equals(String str, String other_string)
|
||||
fn bool VarString.equals(VarString str, VarString other_string)
|
||||
{
|
||||
StringData *str1 = str.data();
|
||||
StringData *str2 = other_string.data();
|
||||
@@ -192,16 +192,16 @@ fn bool String.equals(String str, String other_string)
|
||||
return true;
|
||||
}
|
||||
|
||||
fn void String.destroy(String* str)
|
||||
fn void VarString.destroy(VarString* str)
|
||||
{
|
||||
if (!*str) return;
|
||||
StringData* data = str.data();
|
||||
if (!data) return;
|
||||
data.allocator.free(data)!!;
|
||||
*str = (String)null;
|
||||
*str = (VarString)null;
|
||||
}
|
||||
|
||||
fn bool String.less(String str, String other_string)
|
||||
fn bool VarString.less(VarString str, VarString other_string)
|
||||
{
|
||||
StringData* str1 = str.data();
|
||||
StringData* str2 = other_string.data();
|
||||
@@ -218,7 +218,7 @@ fn bool String.less(String str, String other_string)
|
||||
return true;
|
||||
}
|
||||
|
||||
fn void String.append_chars(String* this, char[] str)
|
||||
fn void VarString.append_chars(VarString* this, String str)
|
||||
{
|
||||
usz other_len = str.len;
|
||||
if (!other_len) return;
|
||||
@@ -233,19 +233,19 @@ fn void String.append_chars(String* this, char[] str)
|
||||
data.len += other_len;
|
||||
}
|
||||
|
||||
fn Char32[] String.copy_utf32(String* this, Allocator* allocator = mem::current_allocator())
|
||||
fn Char32[] VarString.copy_utf32(VarString* this, Allocator* allocator = mem::current_allocator())
|
||||
{
|
||||
return str::utf8to32(this.str(), allocator) @inline!!;
|
||||
}
|
||||
|
||||
fn void String.append_string(String* this, String str)
|
||||
fn void VarString.append_string(VarString* this, VarString str)
|
||||
{
|
||||
StringData* other = (StringData*)str;
|
||||
if (!other) return;
|
||||
this.append(str.str());
|
||||
}
|
||||
|
||||
fn void String.append_char(String* str, char c)
|
||||
fn void VarString.append_char(VarString* str, char c)
|
||||
{
|
||||
if (!*str)
|
||||
{
|
||||
@@ -257,23 +257,23 @@ fn void String.append_char(String* str, char c)
|
||||
}
|
||||
|
||||
|
||||
macro void String.append(String* str, value)
|
||||
macro void VarString.append(VarString* str, value)
|
||||
{
|
||||
var $Type = $typeof(value);
|
||||
$switch ($Type):
|
||||
$case char:
|
||||
$case ichar:
|
||||
str.append_char(value);
|
||||
$case String:
|
||||
$case VarString:
|
||||
str.append_string(value);
|
||||
$case char[]:
|
||||
$case String:
|
||||
str.append_chars(value);
|
||||
$case Char32:
|
||||
str.append_char32(value);
|
||||
$default:
|
||||
$if (@convertible($Type, Char32)):
|
||||
str.append_char32(value);
|
||||
$elif (@convertible($Type, char[])):
|
||||
$elif (@convertible($Type, String)):
|
||||
str.append_chars(value);
|
||||
$else:
|
||||
$assert("Unsupported type for appending");
|
||||
@@ -282,12 +282,12 @@ macro void String.append(String* str, value)
|
||||
}
|
||||
|
||||
|
||||
private fn StringData* String.data(String str) @inline
|
||||
private fn StringData* VarString.data(VarString str) @inline
|
||||
{
|
||||
return (StringData*)str;
|
||||
}
|
||||
|
||||
private fn void String.reserve(String* str, usz addition)
|
||||
private fn void VarString.reserve(VarString* str, usz addition)
|
||||
{
|
||||
StringData* data = str.data();
|
||||
if (!data)
|
||||
@@ -299,12 +299,12 @@ private fn void String.reserve(String* str, usz addition)
|
||||
if (data.capacity >= len) return;
|
||||
usz new_capacity = data.capacity *= 2;
|
||||
if (new_capacity < MIN_CAPACITY) new_capacity = MIN_CAPACITY;
|
||||
*str = (String)data.allocator.realloc(data, StringData.sizeof + new_capacity)!!;
|
||||
*str = (VarString)data.allocator.realloc(data, StringData.sizeof + new_capacity)!!;
|
||||
}
|
||||
|
||||
fn String String.new_concat(String a, String b, Allocator* allocator = mem::current_allocator())
|
||||
fn VarString VarString.new_concat(VarString a, VarString b, Allocator* allocator = mem::current_allocator())
|
||||
{
|
||||
String string = new_with_capacity(a.len() + b.len(), allocator);
|
||||
VarString string = new_with_capacity(a.len() + b.len(), allocator);
|
||||
string.append(a);
|
||||
string.append(b);
|
||||
return string;
|
||||
|
||||
@@ -2,7 +2,7 @@ module std::core::string::iterator;
|
||||
|
||||
struct StringIterator
|
||||
{
|
||||
char[] utf8;
|
||||
String utf8;
|
||||
usz current;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
module std::io::dir;
|
||||
import std::io::os;
|
||||
// In progress.
|
||||
define Path = distinct char[];
|
||||
define Path = distinct String;
|
||||
|
||||
const PREFERRED_SEPARATOR = USE_WIN32_FILESYSTEM ? '\\' : '/';
|
||||
private const USE_WIN32_FILESYSTEM = env::OS_TYPE != OsType.WIN32;
|
||||
@@ -11,12 +11,12 @@ fault PathResult
|
||||
INVALID_PATH
|
||||
}
|
||||
|
||||
fn char[]! getcwd(Allocator* allocator = mem::default_allocator())
|
||||
fn String! getcwd(Allocator* allocator = mem::default_allocator())
|
||||
{
|
||||
return os::getcwd(allocator);
|
||||
}
|
||||
|
||||
fn char[]! tgetcwd()
|
||||
fn String! tgetcwd()
|
||||
{
|
||||
return getcwd(mem::temp_allocator()) @inline;
|
||||
}
|
||||
@@ -56,7 +56,7 @@ $else:
|
||||
$endif;
|
||||
}
|
||||
|
||||
private fn usz! root_name_len(char[] path)
|
||||
private fn usz! root_name_len(String path)
|
||||
{
|
||||
usz len = path.len;
|
||||
if (!len) return 0;
|
||||
@@ -83,9 +83,9 @@ private fn usz! root_name_len(char[] path)
|
||||
return 0;
|
||||
}
|
||||
|
||||
private fn void! normalize_path(char[]* path_ref)
|
||||
private fn void! normalize_path(String* path_ref)
|
||||
{
|
||||
char[] path = *path_ref;
|
||||
String path = *path_ref;
|
||||
if (!path.len) return;
|
||||
usz path_start = root_name_len(path)?;
|
||||
usz len = path_start;
|
||||
@@ -137,16 +137,16 @@ private fn void! normalize_path(char[]* path_ref)
|
||||
*path_ref = path[:len];
|
||||
}
|
||||
|
||||
fn Path new_path(char[] path)
|
||||
fn Path new_path(String path)
|
||||
{
|
||||
char[] copy = str::copy(path);
|
||||
String copy = str::copy(path);
|
||||
normalize_path(©)!!;
|
||||
return (Path)copy;
|
||||
}
|
||||
|
||||
fn Path Path.root_name(Path path)
|
||||
{
|
||||
char[] path_str = (char[])path;
|
||||
String path_str = (String)path;
|
||||
usz len = root_name_len(path_str)!!;
|
||||
if (!len) return (Path)"";
|
||||
return (Path)path_str[0:len];
|
||||
@@ -154,7 +154,7 @@ fn Path Path.root_name(Path path)
|
||||
|
||||
fn Path Path.root_directory(Path path)
|
||||
{
|
||||
char[] path_str = (char[])path;
|
||||
String path_str = (String)path;
|
||||
usz len = path_str.len;
|
||||
if (!len) return (Path)"";
|
||||
$if (USE_WIN32_FILESYSTEM):
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
module std::io;
|
||||
import libc;
|
||||
|
||||
fn void! File.open(File* file, char[] filename, char[] mode)
|
||||
fn void! File.open(File* file, String filename, String mode)
|
||||
{
|
||||
@pool()
|
||||
{
|
||||
@@ -102,7 +102,7 @@ fn usz File.write(File* file, void* buffer, usz items, usz element_size = 1)
|
||||
* @param [&in] file
|
||||
* @require file.file `File must be initialized`
|
||||
*/
|
||||
fn usz! File.println(File* file, char[] string)
|
||||
fn usz! File.println(File* file, String string)
|
||||
{
|
||||
usz len = string.len;
|
||||
if (len != libc::fwrite(string.ptr, 1, len, file.file)) return IoError.UNKNOWN_ERROR!;
|
||||
@@ -114,9 +114,9 @@ fn usz! File.println(File* file, char[] string)
|
||||
* @param [&in] file
|
||||
* @require file.file `File must be initialized`
|
||||
*/
|
||||
fn String File.getline(File* file, Allocator* allocator = mem::current_allocator())
|
||||
fn VarString File.getline(File* file, Allocator* allocator = mem::current_allocator())
|
||||
{
|
||||
String s = string::new_with_capacity(120, allocator);
|
||||
VarString s = string::new_with_capacity(120, allocator);
|
||||
while (!file.eof())
|
||||
{
|
||||
int c = libc::fgetc(file.file);
|
||||
@@ -130,12 +130,12 @@ fn String File.getline(File* file, Allocator* allocator = mem::current_allocator
|
||||
/**
|
||||
* @param [&in] file
|
||||
* @require file.file `File must be initialized`
|
||||
* @return "a zero terminated char[] (the pointer may be safely cast into a ZString)"
|
||||
* @return "a zero terminated String (the pointer may be safely cast into a ZString)"
|
||||
*/
|
||||
fn char[] File.tgetline(File* file)
|
||||
fn String File.tgetline(File* file)
|
||||
{
|
||||
|
||||
String s = file.getline(mem::temp_allocator());
|
||||
VarString s = file.getline(mem::temp_allocator());
|
||||
ZString z = s.zstr();
|
||||
return z[:s.len()];
|
||||
}
|
||||
|
||||
@@ -43,7 +43,7 @@ fn void! FileInfo.read(FileInfo* info, Path path)
|
||||
@pool()
|
||||
{
|
||||
Darwin64Stat stat;
|
||||
int res = _stat(str::tcopy_zstring((char[])path), &stat);
|
||||
int res = _stat(str::tcopy_zstring((String)path), &stat);
|
||||
if (res != 0)
|
||||
{
|
||||
switch (libc::errno())
|
||||
|
||||
@@ -131,7 +131,7 @@ private fn uint simple_atoi(char* buf, usz maxlen, usz* len_ptr) @inline
|
||||
}
|
||||
|
||||
|
||||
private fn void! Formatter.out_substr(Formatter *this, char[] str)
|
||||
private fn void! Formatter.out_substr(Formatter *this, String str)
|
||||
{
|
||||
usz l = conv::utf8_codepoints(str);
|
||||
uint prec = this.prec;
|
||||
@@ -415,7 +415,7 @@ private fn void! Formatter.ntoa(Formatter* this, uint128 value, bool negative, u
|
||||
return this.ntoa_format(buf[:PRINTF_NTOA_BUFFER_SIZE], len, negative, base);
|
||||
}
|
||||
|
||||
private fn void! Formatter.ntoa_format(Formatter* this, char[] buf, usz len, bool negative, uint base)
|
||||
private fn void! Formatter.ntoa_format(Formatter* this, String buf, usz len, bool negative, uint base)
|
||||
{
|
||||
// pad leading zeros
|
||||
if (!this.flags.left)
|
||||
@@ -511,7 +511,7 @@ private fn void! Formatter.out_char(Formatter* this, variant arg)
|
||||
}
|
||||
|
||||
|
||||
private fn void! Formatter.out_reverse(Formatter* this, char[] buf)
|
||||
private fn void! Formatter.out_reverse(Formatter* this, String buf)
|
||||
{
|
||||
usz buffer_start_idx = this.idx;
|
||||
usz len = buf.len;
|
||||
|
||||
@@ -17,7 +17,7 @@ fault PrintFault
|
||||
|
||||
|
||||
define OutputFn = fn void!(char c, void* buffer);
|
||||
define ToStringFunction = fn char[](void* value, Allocator *allocator);
|
||||
define ToStringFunction = fn String(void* value, Allocator *allocator);
|
||||
define ToFormatFunction = fn void!(void* value, Formatter* formatter);
|
||||
define FloatType = double;
|
||||
|
||||
@@ -163,9 +163,9 @@ private fn void! Formatter.out_str(Formatter* this, variant arg)
|
||||
unreachable();
|
||||
case DISTINCT:
|
||||
if (this.print_with_function(arg)?) return;
|
||||
if (arg.type == String.typeid)
|
||||
if (arg.type == VarString.typeid)
|
||||
{
|
||||
return this.out_substr(((String*)arg).str());
|
||||
return this.out_substr(((VarString*)arg).str());
|
||||
}
|
||||
return this.out_str(variant { arg.ptr, arg.type.inner });
|
||||
case POINTER:
|
||||
@@ -188,7 +188,7 @@ private fn void! Formatter.out_str(Formatter* this, variant arg)
|
||||
typeid inner = arg.type.inner;
|
||||
usz size = inner.sizeof;
|
||||
usz len = arg.type.len;
|
||||
// Pretend this is a char[]
|
||||
// Pretend this is a String
|
||||
void* ptr = (void*)arg.ptr;
|
||||
this.out('[')?;
|
||||
for (usz i = 0; i < len; i++)
|
||||
@@ -204,7 +204,7 @@ private fn void! Formatter.out_str(Formatter* this, variant arg)
|
||||
typeid inner = arg.type.inner;
|
||||
usz size = inner.sizeof;
|
||||
usz len = arg.type.len;
|
||||
// Pretend this is a char[]
|
||||
// Pretend this is a String
|
||||
void* ptr = (void*)arg.ptr;
|
||||
this.out_substr("[<")?;
|
||||
for (usz i = 0; i < len; i++)
|
||||
@@ -220,11 +220,11 @@ private fn void! Formatter.out_str(Formatter* this, variant arg)
|
||||
typeid inner = arg.type.inner;
|
||||
if (inner == char.typeid)
|
||||
{
|
||||
return this.out_substr(*(char[]*)arg);
|
||||
return this.out_substr(*(String*)arg);
|
||||
}
|
||||
usz size = inner.sizeof;
|
||||
// Pretend this is a char[]
|
||||
char[]* temp = (void*)arg.ptr;
|
||||
// Pretend this is a String
|
||||
String* temp = (void*)arg.ptr;
|
||||
void* ptr = (void*)temp.ptr;
|
||||
usz len = temp.len;
|
||||
this.out('[')?;
|
||||
@@ -283,18 +283,18 @@ private fn void! out_fputchar_fn(char c, void* data)
|
||||
|
||||
private fn void! out_string_append_fn(char c, void* data)
|
||||
{
|
||||
String* s = data;
|
||||
VarString* s = data;
|
||||
s.append_char(c);
|
||||
}
|
||||
|
||||
fn usz! printf(char[] format, args...) @maydiscard
|
||||
fn usz! printf(String format, args...) @maydiscard
|
||||
{
|
||||
Formatter formatter;
|
||||
formatter.init(&out_putchar_fn);
|
||||
return formatter.vprintf(format, args);
|
||||
}
|
||||
|
||||
fn usz! printfln(char[] format, args...) @maydiscard
|
||||
fn usz! printfln(String format, args...) @maydiscard
|
||||
{
|
||||
Formatter formatter;
|
||||
formatter.init(&out_putchar_fn);
|
||||
@@ -303,14 +303,14 @@ fn usz! printfln(char[] format, args...) @maydiscard
|
||||
return len + 1;
|
||||
}
|
||||
|
||||
fn usz! String.printf(String* str, char[] format, args...) @maydiscard
|
||||
fn usz! VarString.printf(VarString* str, String format, args...) @maydiscard
|
||||
{
|
||||
Formatter formatter;
|
||||
formatter.init(&out_string_append_fn, str);
|
||||
return formatter.vprintf(format, args);
|
||||
}
|
||||
|
||||
fn usz! String.printfln(String* str, char[] format, args...) @maydiscard
|
||||
fn usz! VarString.printfln(VarString* str, String format, args...) @maydiscard
|
||||
{
|
||||
Formatter formatter;
|
||||
formatter.init(&out_string_append_fn, str);
|
||||
@@ -325,7 +325,7 @@ private struct BufferData
|
||||
usz written;
|
||||
}
|
||||
|
||||
fn char[]! bprintf(char[] buffer, char[] format, args...) @maydiscard
|
||||
fn char[]! bprintf(char[] buffer, String format, args...) @maydiscard
|
||||
{
|
||||
Formatter formatter;
|
||||
BufferData data = { .buffer = buffer };
|
||||
@@ -334,14 +334,14 @@ fn char[]! bprintf(char[] buffer, char[] format, args...) @maydiscard
|
||||
return buffer[:size];
|
||||
}
|
||||
|
||||
fn usz! File.printf(File file, char[] format, args...) @maydiscard
|
||||
fn usz! File.printf(File file, String format, args...) @maydiscard
|
||||
{
|
||||
Formatter formatter;
|
||||
formatter.init(&out_putchar_fn, &file);
|
||||
return formatter.vprintf(format, args)?;
|
||||
}
|
||||
|
||||
fn usz! File.printfln(File file, char[] format, args...) @maydiscard
|
||||
fn usz! File.printfln(File file, String format, args...) @maydiscard
|
||||
{
|
||||
Formatter formatter;
|
||||
formatter.init(&out_putchar_fn, &file);
|
||||
@@ -351,12 +351,12 @@ fn usz! File.printfln(File file, char[] format, args...) @maydiscard
|
||||
return len + 1;
|
||||
}
|
||||
|
||||
fn usz! Formatter.printf(Formatter* this, char[] format, args...)
|
||||
fn usz! Formatter.printf(Formatter* this, String format, args...)
|
||||
{
|
||||
return this.vprintf(format, args) @inline;
|
||||
}
|
||||
|
||||
fn usz! Formatter.vprintf(Formatter* this, char[] format, variant[] variants)
|
||||
fn usz! Formatter.vprintf(Formatter* this, String format, variant[] variants)
|
||||
{
|
||||
if (!this.out_fn)
|
||||
{
|
||||
|
||||
@@ -6,7 +6,7 @@ $if (env::OS_TYPE == OsType.WIN32):
|
||||
extern fn Char16* _wgetcwd(Char16* buffer, int maxlen);
|
||||
extern fn usz wcslen(Char16* str);
|
||||
|
||||
macro char[]! getcwd(Allocator* allocator = mem::default_allocator())
|
||||
macro String! getcwd(Allocator* allocator = mem::default_allocator())
|
||||
{
|
||||
const DEFAULT_BUFFER = 256;
|
||||
Char16[DEFAULT_BUFFER] buffer;
|
||||
@@ -26,7 +26,7 @@ macro char[]! getcwd(Allocator* allocator = mem::default_allocator())
|
||||
$else:
|
||||
|
||||
extern fn ZString _getcwd(char* pwd, usz len) @extname("getcwd");
|
||||
macro char[]! getcwd(Allocator* allocator = mem::default_allocator())
|
||||
macro String! getcwd(Allocator* allocator = mem::default_allocator())
|
||||
{
|
||||
const usz DEFAULT_BUFFER = 256;
|
||||
char[DEFAULT_BUFFER] buffer;
|
||||
@@ -40,7 +40,7 @@ macro char[]! getcwd(Allocator* allocator = mem::default_allocator())
|
||||
free = true;
|
||||
}
|
||||
defer if (free) libc::free((void*)res);
|
||||
char[] copy = str::copyz(res.as_str(), allocator);
|
||||
String copy = str::copyz(res.as_str(), allocator);
|
||||
return copy;
|
||||
}
|
||||
|
||||
|
||||
@@ -32,7 +32,7 @@ define TestFn = fn void!();
|
||||
|
||||
struct TestRunner
|
||||
{
|
||||
char[][] test_names;
|
||||
String[] test_names;
|
||||
TestFn[] test_fns;
|
||||
JmpBuf buf;
|
||||
}
|
||||
@@ -48,7 +48,7 @@ fn TestRunner test_runner_create()
|
||||
import libc;
|
||||
|
||||
private TestRunner* current_runner;
|
||||
fn void test_panic(char[] message, char[] file, char[] function, uint line)
|
||||
fn void test_panic(String message, String file, String function, uint line)
|
||||
{
|
||||
io::println("[error]");
|
||||
io::printfln("\n Error: %s", message);
|
||||
@@ -65,7 +65,7 @@ fn bool TestRunner.run(TestRunner* runner)
|
||||
int tests_passed = 0;
|
||||
int tests = runner.test_names.len;
|
||||
io::println("----- TESTS -----");
|
||||
foreach(i, char[] name : runner.test_names)
|
||||
foreach(i, String name : runner.test_names)
|
||||
{
|
||||
io::printf("Testing %s ... ", name);
|
||||
if (libc::setjmp(&runner.buf) == 0)
|
||||
|
||||
@@ -42,7 +42,7 @@ const char PAD = '=';
|
||||
const char FIRST = '+';
|
||||
const char LAST = 'z';
|
||||
|
||||
fn void encode(char[] in, char *out)
|
||||
fn void encode(String in, char *out)
|
||||
{
|
||||
int j = 0;
|
||||
char c = LUT_ENC[1];
|
||||
@@ -76,7 +76,7 @@ fn void encode(char[] in, char *out)
|
||||
}
|
||||
|
||||
|
||||
fn int! decode(char[] in, char* out, int* invalid_char_index = null)
|
||||
fn int! decode(String in, char* out, int* invalid_char_index = null)
|
||||
{
|
||||
int j = 0;
|
||||
|
||||
|
||||
@@ -5,16 +5,16 @@ fn void main()
|
||||
{
|
||||
for (int i = 0; i < 20; i++)
|
||||
{
|
||||
String s = bin(i);
|
||||
VarString s = bin(i);
|
||||
defer s.destroy();
|
||||
io::printf("%s\n", s);
|
||||
}
|
||||
}
|
||||
|
||||
fn String bin(int x)
|
||||
fn VarString bin(int x)
|
||||
{
|
||||
int bits = 1 + (int)(x == 0 ? 0 : math::log10((double)(x)) / math::log10(2));
|
||||
String str;
|
||||
VarString str;
|
||||
str.append_repeat('0', bits);
|
||||
for (int i = 0; i < bits; i++)
|
||||
{
|
||||
|
||||
@@ -10,13 +10,13 @@ fault InterpretError
|
||||
INTEPRET_FAILED
|
||||
}
|
||||
|
||||
fn void! print_error(usz pos, char[] err)
|
||||
fn void! print_error(usz pos, String err)
|
||||
{
|
||||
io::printfln("Error at %s: %s", pos, err);
|
||||
return InterpretError.INTEPRET_FAILED!;
|
||||
}
|
||||
|
||||
fn void! brainf(char[] program)
|
||||
fn void! brainf(String program)
|
||||
{
|
||||
usz sp = 0;
|
||||
usz mem = 0;
|
||||
@@ -76,7 +76,7 @@ fn void! brainf(char[] program)
|
||||
}
|
||||
fn void! main()
|
||||
{
|
||||
char[] program = `
|
||||
String program = `
|
||||
++++[>+++++<-]>[<+++++>-]+<+[
|
||||
>[>+>+<<-]++>>[<<+>>-]>>>[-]++>[-]+
|
||||
>>>+[[-]++++++>>>]<<<[[<++++++++<++>>-]+<.<[>----<-]<]
|
||||
|
||||
@@ -3,11 +3,11 @@ import libc;
|
||||
import std::io;
|
||||
|
||||
struct Doc { Head *head; }
|
||||
struct Head { String* title; }
|
||||
struct Head { VarString* title; }
|
||||
|
||||
struct Summary
|
||||
{
|
||||
String* title;
|
||||
VarString* title;
|
||||
bool ok;
|
||||
}
|
||||
|
||||
@@ -21,11 +21,11 @@ private struct StringData
|
||||
|
||||
fn void Summary.print(Summary *s, File out)
|
||||
{
|
||||
char[] title = s.title ? s.title.str() : "missing";
|
||||
String title = s.title ? s.title.str() : "missing";
|
||||
out.printf("Summary({ .title = %s, .ok = %s})", title, s.ok);
|
||||
}
|
||||
|
||||
fn bool contains(char[] haystack, char[] needle)
|
||||
fn bool contains(String haystack, String needle)
|
||||
{
|
||||
usz len = haystack.len;
|
||||
usz needle_len = needle.len;
|
||||
@@ -54,13 +54,13 @@ fault ReadError
|
||||
BAD_READ,
|
||||
}
|
||||
|
||||
fn Doc! readDoc(char[] url)
|
||||
fn Doc! readDoc(String url)
|
||||
{
|
||||
if (contains(url, "fail")) return ReadError.BAD_READ!;
|
||||
if (contains(url, "head-missing")) return { .head = null };
|
||||
if (contains(url, "title-missing")) return { @dupe(Head { .title = null }) };
|
||||
if (contains(url, "title-empty")) return { @dupe(Head { .title = @dupe((String)null) }) };
|
||||
String str;
|
||||
if (contains(url, "title-empty")) return { @dupe(Head { .title = @dupe((VarString)null) }) };
|
||||
VarString str;
|
||||
str.printf("Title of %s", url);
|
||||
return { @dupe(Head { .title = @dupe(str) }) };
|
||||
}
|
||||
@@ -73,7 +73,7 @@ fn Summary buildSummary(Doc doc)
|
||||
};
|
||||
}
|
||||
|
||||
fn Summary readAndBuildSummary(char[] url)
|
||||
fn Summary readAndBuildSummary(String url)
|
||||
{
|
||||
return buildSummary(readDoc(url)) ?? Summary { .title = null, .ok = false };
|
||||
/*
|
||||
@@ -97,18 +97,18 @@ fault TitleResult
|
||||
fn bool! isTitleNonEmpty(Doc doc)
|
||||
{
|
||||
if (!doc.head) return TitleResult.TITLE_MISSING!;
|
||||
String* head = doc.head.title;
|
||||
VarString* head = doc.head.title;
|
||||
if (!head) return TitleResult.TITLE_MISSING!;
|
||||
return head.len() > 0;
|
||||
}
|
||||
|
||||
|
||||
fn bool! readWhetherTitleNonEmpty(char[] url)
|
||||
fn bool! readWhetherTitleNonEmpty(String url)
|
||||
{
|
||||
return isTitleNonEmpty(readDoc(url));
|
||||
}
|
||||
|
||||
fn char[] bool_to_string(bool b)
|
||||
fn String bool_to_string(bool b)
|
||||
{
|
||||
return b ? "true" : "false";
|
||||
}
|
||||
@@ -116,10 +116,10 @@ fn char[] bool_to_string(bool b)
|
||||
|
||||
fn void main()
|
||||
{
|
||||
const char[][] URLS = { "good", "title-empty", "title-missing", "head-missing", "fail" };
|
||||
const String[] URLS = { "good", "title-empty", "title-missing", "head-missing", "fail" };
|
||||
DynamicArenaAllocator dynamic_arena;
|
||||
dynamic_arena.init(1024);
|
||||
foreach (char[] url : URLS)
|
||||
foreach (String url : URLS)
|
||||
{
|
||||
mem::@scoped(&dynamic_arena)
|
||||
{
|
||||
@@ -128,7 +128,7 @@ fn void main()
|
||||
io::printf(" Summary: ");
|
||||
summary.print(io::stdout());
|
||||
io::println("");
|
||||
char[] title_sure = summary.title ? summary.title.str() : "";
|
||||
String title_sure = summary.title ? summary.title.str() : "";
|
||||
io::printf(" Title: %s\n", title_sure);
|
||||
bool! has_title = readWhetherTitleNonEmpty(url);
|
||||
// This looks a bit less than elegant, but as you see it's mostly due to having to
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
module foo;
|
||||
import std::io;
|
||||
|
||||
tlocal char[] context_user = "safe";
|
||||
tlocal String context_user = "safe";
|
||||
|
||||
macro long reallyPerform(task)
|
||||
{
|
||||
@@ -14,7 +14,7 @@ macro long perform(task)
|
||||
return reallyPerform(task);
|
||||
}
|
||||
|
||||
macro @with_mode(char[] user, #action, ...)
|
||||
macro @with_mode(String user, #action, ...)
|
||||
{
|
||||
@scope(context_user)
|
||||
{
|
||||
@@ -27,6 +27,6 @@ fn void main()
|
||||
{
|
||||
long val1 = perform("something");
|
||||
long val2 = @with_mode("faster", perform, "reliable");
|
||||
long val3 = perform(char[][] {"something"});
|
||||
long val3 = perform(String[] {"something"});
|
||||
io::printfln("%d %d %d", val1, val2, val3);
|
||||
}
|
||||
|
||||
@@ -23,14 +23,14 @@ int err_count = 0;
|
||||
fn int! askGuess(int high)
|
||||
{
|
||||
libc::printf("Guess a number between 1 and %d: ", high);
|
||||
char[] text = readLine()?;
|
||||
String text = readLine()?;
|
||||
char* end = null;
|
||||
int value = (int)libc::strtol(text.ptr, &end, 10);
|
||||
if (end && end[0] >= ' ') return InputResult.NOT_AN_INT!;
|
||||
return value;
|
||||
}
|
||||
|
||||
fn char[]! readLine()
|
||||
fn String! readLine()
|
||||
{
|
||||
char* chars = tmalloc(1024)?;
|
||||
isz loaded = getline(&chars, &&(usz)1023, libc::stdin());
|
||||
@@ -67,7 +67,7 @@ fn void! Game.play(Game *game)
|
||||
|
||||
fn void Game.report(Game *game, int guess)
|
||||
{
|
||||
char[] desc = {|
|
||||
String desc = {|
|
||||
if (guess < game.answer) return "too low";
|
||||
if (guess > game.answer) return "too high";
|
||||
return "the answer";
|
||||
|
||||
@@ -9,7 +9,7 @@ fn void main()
|
||||
And a nested comment.
|
||||
*/
|
||||
*/
|
||||
char[] text = `
|
||||
String text = `
|
||||
function hello() {
|
||||
console.log("name`"\t"`age");
|
||||
}
|
||||
|
||||
@@ -15,7 +15,7 @@ fn float fasta_rand(float max_val)
|
||||
return max_val * seed / IM;
|
||||
}
|
||||
|
||||
private char[] alu =
|
||||
private String alu =
|
||||
"GGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTGG"
|
||||
"GAGGCCGAGGCGGGCGGATCACCTGAGGTCAGGAGTTCGAGA"
|
||||
"CCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACTAAAAAT"
|
||||
@@ -25,7 +25,7 @@ private char[] alu =
|
||||
"AGCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAA";
|
||||
|
||||
|
||||
char[] iub = "acgtBDHKMNRSVWY";
|
||||
String iub = "acgtBDHKMNRSVWY";
|
||||
double[] iub_p = {
|
||||
0.27,
|
||||
0.12,
|
||||
@@ -43,7 +43,7 @@ double[] iub_p = {
|
||||
0.02,
|
||||
0.02 };
|
||||
|
||||
char[] homosapiens = "acgt";
|
||||
String homosapiens = "acgt";
|
||||
double[] homosapiens_p = {
|
||||
0.3029549426680,
|
||||
0.1979883004921,
|
||||
@@ -54,7 +54,7 @@ double[] homosapiens_p = {
|
||||
const LINELEN = 60;
|
||||
|
||||
// slowest character-at-a-time output
|
||||
fn void repeat_fasta(char[] seq, int n)
|
||||
fn void repeat_fasta(String seq, int n)
|
||||
{
|
||||
usz len = seq.len;
|
||||
int i = void;
|
||||
@@ -66,7 +66,7 @@ fn void repeat_fasta(char[] seq, int n)
|
||||
if (i % LINELEN != 0) io::putchar('\n');
|
||||
}
|
||||
|
||||
fn void random_fasta(char[] symb, double[] probability, int n)
|
||||
fn void random_fasta(String symb, double[] probability, int n)
|
||||
{
|
||||
assert(symb.len == probability.len);
|
||||
int len = probability.len;
|
||||
|
||||
@@ -7,7 +7,7 @@ import libc;
|
||||
|
||||
fn void main()
|
||||
{
|
||||
char[] y = "Hello World!";
|
||||
String y = "Hello World!";
|
||||
libc::printf("Adler32 of %s is %x, expected 1c49043e\n", (char*)(y), adler32(y));
|
||||
libc::printf("CRC32B of %s is %x, expected 1c291ca3\n", (char*)(y), crc32(y));
|
||||
libc::printf("CRC64 of %s is %llx, expected fad9a77c67077205\n", (char*)(y), crc64(y));
|
||||
|
||||
@@ -2,7 +2,7 @@ import std::io;
|
||||
|
||||
fn void main()
|
||||
{
|
||||
char[][] greetings = {
|
||||
String[] greetings = {
|
||||
"Hello, world!",
|
||||
"¡Hola Mundo!",
|
||||
"Γειά σου Κόσμε!",
|
||||
|
||||
@@ -2,7 +2,7 @@ module levenshtein;
|
||||
import std::math;
|
||||
|
||||
// This levenshtein exercises C3 subarrays.
|
||||
fn int levenshtein(char[] s, char[] t)
|
||||
fn int levenshtein(String s, String t)
|
||||
{
|
||||
// if either string is empty, difference is inserting all chars
|
||||
// from the other
|
||||
|
||||
@@ -142,7 +142,7 @@ fn void scale_bodies(Planet[] bodies, double scale)
|
||||
}
|
||||
|
||||
|
||||
fn void main(char[][] args)
|
||||
fn void main(String[] args)
|
||||
{
|
||||
int n = args.len < 2 ? 50000000 : str::to_int(args[1])!!;
|
||||
|
||||
|
||||
@@ -4,10 +4,10 @@ import regex, stdio;
|
||||
fn void main()
|
||||
{
|
||||
println("Enter a story template, terminated by an empty line:");
|
||||
String story = "";
|
||||
VarString story = "";
|
||||
while (1)
|
||||
{
|
||||
String line = stdin.readln().strip() else break;
|
||||
VarString line = stdin.readln().strip() else break;
|
||||
story = story.append(line);
|
||||
story = story.append("\n");
|
||||
}
|
||||
@@ -19,7 +19,7 @@ fn void main()
|
||||
|
||||
foreach (RegexMatch* match : r.match(story))
|
||||
{
|
||||
String s = match.string;
|
||||
VarString s = match.string;
|
||||
printf("Enter a value for '%s': ", s[1..^2]);
|
||||
string word = stdin.readln().strip() else return;
|
||||
story = story.replace(s, word);
|
||||
|
||||
@@ -7,7 +7,7 @@ import stdlib;
|
||||
|
||||
const uint MaxText = 1024;
|
||||
|
||||
enum TokenKind : char (String name)
|
||||
enum TokenKind : char (VarString name)
|
||||
{
|
||||
WORD("word"),
|
||||
TEXT("text"),
|
||||
|
||||
@@ -10,15 +10,15 @@ fault TokenResult
|
||||
|
||||
// While we could have written this with libc
|
||||
// the C way, let's showcase some features added to C3.
|
||||
fn void main(char[][] args)
|
||||
fn void main(String[] args)
|
||||
{
|
||||
// Grab a string from stdin
|
||||
String s = io::stdin().getline();
|
||||
VarString s = io::stdin().getline();
|
||||
// Delete it at scope end [defer]
|
||||
defer s.destroy();
|
||||
|
||||
// Grab the string as a slice.
|
||||
char[] numbers = s.str();
|
||||
String numbers = s.str();
|
||||
|
||||
// Track our current value
|
||||
int val = 0;
|
||||
@@ -26,7 +26,7 @@ fn void main(char[][] args)
|
||||
// Is the current state an add?
|
||||
bool add = true;
|
||||
|
||||
while (try char[] token = read_next(&numbers))
|
||||
while (try String token = read_next(&numbers))
|
||||
{
|
||||
// We're assuming well formed input here
|
||||
// so just use atoi.
|
||||
@@ -36,7 +36,7 @@ fn void main(char[][] args)
|
||||
val = add ? val + i : val - i;
|
||||
|
||||
// Read an optional token.
|
||||
char[]! op = read_next(&numbers);
|
||||
String! op = read_next(&numbers);
|
||||
|
||||
// If it's an error, then we're done.
|
||||
if (catch op) break;
|
||||
@@ -56,7 +56,7 @@ fn void main(char[][] args)
|
||||
io::printfln("%d", val);
|
||||
}
|
||||
|
||||
fn char[]! read_next(char[]* remaining)
|
||||
fn String! read_next(String* remaining)
|
||||
{
|
||||
while (remaining.len > 0 && (*remaining)[0] == ' ')
|
||||
{
|
||||
|
||||
@@ -42,7 +42,7 @@ fn void eval_AtA_times_u(double[] u, double[] atau, double[] x)
|
||||
eval_At_times_u(temparr, atau, x);
|
||||
}
|
||||
|
||||
fn void main(char[][] args)
|
||||
fn void main(String[] args)
|
||||
{
|
||||
int n = args.len == 2 ? str::to_int(args[1])!! : 2000;
|
||||
temparr = array::alloc(double, n);
|
||||
|
||||
@@ -12,7 +12,7 @@ fn void print_pages()
|
||||
mem::temp_allocator().print_pages(io::stdout());
|
||||
}
|
||||
|
||||
fn void setstring(char* dst, char[] str)
|
||||
fn void setstring(char* dst, String str)
|
||||
{
|
||||
foreach (char c : str)
|
||||
{
|
||||
|
||||
@@ -143,7 +143,7 @@ $else
|
||||
|
||||
generic boofer2(i, g, eok)
|
||||
{
|
||||
case int, char[], type($eoo):
|
||||
case int, String, type($eoo):
|
||||
return "Helo";
|
||||
default:
|
||||
return 1000;
|
||||
|
||||
@@ -2,7 +2,7 @@ module tmem;
|
||||
import std::mem;
|
||||
import std::io;
|
||||
|
||||
struct String
|
||||
struct VarString
|
||||
{
|
||||
Allocator allocator;
|
||||
usz len;
|
||||
@@ -10,7 +10,7 @@ struct String
|
||||
char* ptr;
|
||||
}
|
||||
|
||||
fn void String.init(String *s, char[] c)
|
||||
fn void VarString.init(VarString *s, String c)
|
||||
{
|
||||
s.capacity = c.len + 16;
|
||||
s.ptr = malloc(s.capacity);
|
||||
@@ -18,7 +18,7 @@ fn void String.init(String *s, char[] c)
|
||||
mem::copy(s.ptr, (char*)(c), c.len);
|
||||
}
|
||||
|
||||
fn char* String.zstr(String *s)
|
||||
fn char* VarString.zstr(VarString *s)
|
||||
{
|
||||
char* c = malloc(s.len + 1);
|
||||
mem::copy(c, s.ptr, s.len);
|
||||
@@ -26,7 +26,7 @@ fn char* String.zstr(String *s)
|
||||
return c;
|
||||
}
|
||||
|
||||
fn void String.appendc(String *s, char c)
|
||||
fn void VarString.appendc(VarString *s, char c)
|
||||
{
|
||||
if (s.capacity == s.len)
|
||||
{
|
||||
@@ -38,7 +38,7 @@ fn void String.appendc(String *s, char c)
|
||||
s.ptr[s.len++] = c;
|
||||
}
|
||||
|
||||
fn void String.append(String *s, char[] other_string)
|
||||
fn void VarString.append(VarString *s, String other_string)
|
||||
{
|
||||
if (s.capacity < s.len + other_string.len)
|
||||
{
|
||||
@@ -55,7 +55,7 @@ fn void String.append(String *s, char[] other_string)
|
||||
s.len += other_string.len;
|
||||
}
|
||||
|
||||
fn void String.concat(String *s, String* other_string)
|
||||
fn void VarString.concat(VarString *s, VarString* other_string)
|
||||
{
|
||||
if (s.capacity < s.len + other_string.len)
|
||||
{
|
||||
@@ -74,12 +74,12 @@ fn void String.concat(String *s, String* other_string)
|
||||
|
||||
fn void main()
|
||||
{
|
||||
String s;
|
||||
VarString s;
|
||||
s.init("Hello");
|
||||
s.appendc(' ');
|
||||
s.appendc('W');
|
||||
s.append("orld!");
|
||||
String w;
|
||||
VarString w;
|
||||
w.init("Yo man!");
|
||||
s.concat(&w);
|
||||
libc::printf("Message was: %s\n", s.zstr());
|
||||
|
||||
@@ -27,7 +27,6 @@
|
||||
"hello_world_win32": {
|
||||
"type": "executable",
|
||||
"c-sources-override": [
|
||||
"./csource/**"
|
||||
]
|
||||
},
|
||||
"hello_world_lib": {
|
||||
|
||||
@@ -750,6 +750,7 @@ void compile()
|
||||
}
|
||||
global_context.sources = active_target.sources;
|
||||
global_context.main = NULL;
|
||||
global_context.string_type = NULL;
|
||||
asm_target.initialized = false;
|
||||
target_setup(&active_target);
|
||||
resolve_libraries();
|
||||
|
||||
@@ -1666,12 +1666,13 @@ typedef struct
|
||||
DeclTable symbols;
|
||||
DeclTable generic_symbols;
|
||||
Path std_module_path;
|
||||
Type *string_type;
|
||||
Decl *panic_var;
|
||||
Decl *main;
|
||||
Decl *test_func;
|
||||
Decl *decl_stack[MAX_GLOBAL_DECL_STACK];
|
||||
Decl** decl_stack_bottom;
|
||||
Decl** decl_stack_top;
|
||||
Decl **decl_stack_bottom;
|
||||
Decl **decl_stack_top;
|
||||
} GlobalContext;
|
||||
|
||||
|
||||
@@ -2259,6 +2260,7 @@ void decltable_set(DeclTable *table, Decl *decl);
|
||||
|
||||
const char *scratch_buffer_interned(void);
|
||||
|
||||
const char *symtab_preset(const char *data, TokenType type);
|
||||
const char *symtab_add(const char *symbol, uint32_t len, uint32_t fnv1hash, TokenType *type);
|
||||
const char *symtab_find(const char *symbol, uint32_t len, uint32_t fnv1hash, TokenType *type);
|
||||
void *llvm_target_machine_create(void);
|
||||
|
||||
@@ -1065,10 +1065,10 @@ INLINE GenContext *llvm_gen_tests(Module** modules, unsigned module_count, LLVMC
|
||||
unsigned test_count = vec_size(decls);
|
||||
LLVMValueRef name_ref;
|
||||
LLVMValueRef decl_ref;
|
||||
LLVMTypeRef chars_type = llvm_get_type(c, type_chars);
|
||||
|
||||
if (test_count)
|
||||
{
|
||||
LLVMValueRef array_of_names = LLVMConstArray(chars_type, names, test_count);
|
||||
LLVMValueRef array_of_names = LLVMConstArray(c->chars_type, names, test_count);
|
||||
LLVMValueRef array_of_decls = LLVMConstArray(LLVMPointerType(opt_test, 0), decls, test_count);
|
||||
LLVMTypeRef arr_type = LLVMTypeOf(array_of_names);
|
||||
name_ref = llvm_add_global_raw(c, ".test_names", arr_type, 0);
|
||||
|
||||
@@ -27,7 +27,7 @@ static inline LLVMTypeRef create_fault_type(GenContext *c)
|
||||
{
|
||||
LLVMTypeRef type = LLVMStructCreateNamed(c->context, ".fault");
|
||||
LLVMTypeRef typeid_type = llvm_get_type(c, type_typeid);
|
||||
LLVMTypeRef chars_type = llvm_get_type(c, type_chars);
|
||||
LLVMTypeRef chars_type = c->chars_type;
|
||||
LLVMTypeRef fault_type[] = {
|
||||
[0] = typeid_type,
|
||||
[1] = chars_type,
|
||||
@@ -123,11 +123,11 @@ void gencontext_begin_module(GenContext *c)
|
||||
}
|
||||
c->bool_type = LLVMInt1TypeInContext(c->context);
|
||||
c->byte_type = LLVMInt8TypeInContext(c->context);
|
||||
c->chars_type = llvm_get_type(c, type_chars);
|
||||
c->introspect_type = create_introspection_type(c);
|
||||
c->fault_type = create_fault_type(c);
|
||||
c->size_type = llvm_get_type(c, type_usize);
|
||||
c->char_ptr_type = LLVMPointerType(c->byte_type, 0);
|
||||
c->chars_type = llvm_get_type(c, type_chars);
|
||||
if (c->panic_var) c->panic_var->backend_ref = NULL;
|
||||
|
||||
if (active_target.debug_info != DEBUG_INFO_NONE)
|
||||
|
||||
@@ -1245,13 +1245,13 @@ LLVMValueRef llvm_emit_string_const(GenContext *c, const char *str, const char *
|
||||
if (!len) return llvm_emit_empty_string_const(c);
|
||||
LLVMValueRef val = llvm_emit_zstring_named(c, str, extname);
|
||||
LLVMValueRef data[2] = { val, llvm_const_int(c, type_usize, strlen(str)) };
|
||||
return llvm_get_struct_named(llvm_get_type(c, type_chars), data, 2);
|
||||
return llvm_get_struct_named(c->chars_type, data, 2);
|
||||
}
|
||||
|
||||
LLVMValueRef llvm_emit_empty_string_const(GenContext *c)
|
||||
{
|
||||
LLVMValueRef data[2] = { LLVMConstNull(c->char_ptr_type), llvm_const_int(c, type_usize, 0) };
|
||||
return llvm_get_struct_named(llvm_get_type(c, type_chars), data, 2);
|
||||
return llvm_get_struct_named(c->chars_type, data, 2);
|
||||
}
|
||||
|
||||
LLVMValueRef llvm_emit_zstring(GenContext *c, const char *str)
|
||||
|
||||
@@ -556,7 +556,6 @@ static LLVMValueRef llvm_get_introspection_for_enum(GenContext *c, Type *type)
|
||||
|
||||
if (!is_dynamic) is_external = false;
|
||||
|
||||
LLVMTypeRef subarray = llvm_get_type(c, type_chars);
|
||||
LLVMValueRef *values = elements ? malloc_arena(elements * sizeof(LLVMValueRef)) : NULL;
|
||||
|
||||
bool obfuscate = decl->obfuscate;
|
||||
@@ -574,7 +573,7 @@ static LLVMValueRef llvm_get_introspection_for_enum(GenContext *c, Type *type)
|
||||
}
|
||||
values[i] = llvm_emit_string_const(c, name, scratch_buffer_to_string());
|
||||
}
|
||||
LLVMValueRef names = llvm_get_array(subarray, values, elements);
|
||||
LLVMValueRef names = llvm_get_array(c->chars_type, values, elements);
|
||||
|
||||
LLVMValueRef val = llvm_generate_introspection_global(c, NULL, type, INTROSPECT_TYPE_ENUM, type_flatten(type), elements, names, is_external);
|
||||
LLVMTypeRef val_type;
|
||||
|
||||
@@ -516,7 +516,7 @@ static bool cast_may_explicit(Type *from_type, Type *to_type, bool is_const)
|
||||
// Allow conversion float -> float/int/bool/enum
|
||||
return type_is_integer(to_type) || type_is_float(to_type) || to_type == type_bool || to_kind == TYPE_ENUM;
|
||||
case TYPE_POINTER:
|
||||
UNREACHABLE
|
||||
return type_is_pointer_sized_or_more(to_type) || to_type == type_bool;
|
||||
case TYPE_ANY:
|
||||
return to_kind == TYPE_POINTER;
|
||||
case TYPE_FAULTTYPE:
|
||||
|
||||
@@ -2736,7 +2736,7 @@ static inline void sema_expr_replace_with_enum_name_array(Expr *enum_array_expr,
|
||||
initializer->initializer_list = element_values;
|
||||
enum_array_expr->expr_kind = EXPR_COMPOUND_LITERAL;
|
||||
enum_array_expr->expr_compound_literal.initializer = initializer;
|
||||
enum_array_expr->expr_compound_literal.type_info = type_info_new_base(type_get_subarray(type_chars), span);
|
||||
enum_array_expr->expr_compound_literal.type_info = type_info_new_base(type_get_subarray(global_context_string_type()), span);
|
||||
enum_array_expr->resolve_status = RESOLVE_NOT_DONE;
|
||||
}
|
||||
|
||||
@@ -3210,7 +3210,7 @@ static bool sema_expr_rewrite_to_typeid_property(SemaContext *context, Expr *exp
|
||||
sema_expr_rewrite_typeid_kind(expr, typeid);
|
||||
return true;
|
||||
case TYPE_PROPERTY_NAMES:
|
||||
return sema_expr_rewrite_typeid_call(expr, typeid, TYPEID_INFO_NAMES, type_get_subarray(type_chars));
|
||||
return sema_expr_rewrite_typeid_call(expr, typeid, TYPEID_INFO_NAMES, type_get_subarray(global_context_string_type()));
|
||||
case TYPE_PROPERTY_ALIGNOF:
|
||||
case TYPE_PROPERTY_INF:
|
||||
case TYPE_PROPERTY_MIN:
|
||||
@@ -3516,7 +3516,7 @@ CHECK_DEEPER:
|
||||
}
|
||||
else
|
||||
{
|
||||
expr_rewrite_to_builtin_access(expr, current_parent, ACCESS_ENUMNAME, type_chars);
|
||||
expr_rewrite_to_builtin_access(expr, current_parent, ACCESS_ENUMNAME, global_context_string_type());
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -3527,7 +3527,7 @@ CHECK_DEEPER:
|
||||
expr_rewrite_to_string(expr, current_parent->const_expr.enum_err_val->name);
|
||||
return true;
|
||||
}
|
||||
expr_rewrite_to_builtin_access(expr, current_parent, ACCESS_FAULTNAME, type_chars);
|
||||
expr_rewrite_to_builtin_access(expr, current_parent, ACCESS_FAULTNAME, global_context_string_type());
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -6004,10 +6004,10 @@ static inline bool sema_expr_analyse_compiler_const(SemaContext *context, Expr *
|
||||
expr->expr_kind = EXPR_CONST;
|
||||
ConstInitializer *init = expr->const_expr.initializer = CALLOCS(ConstInitializer);
|
||||
init->kind = CONST_INIT_ZERO;
|
||||
init->type = expr->type = type_get_subarray(type_chars);
|
||||
init->type = expr->type = type_get_subarray(global_context_string_type());
|
||||
return true;
|
||||
}
|
||||
expr->type = type_get_subarray(type_chars);
|
||||
expr->type = type_get_subarray(global_context_string_type());
|
||||
expr->test_hook_expr = BUILTIN_DEF_TEST_NAMES;
|
||||
expr->expr_kind = EXPR_TEST_HOOK;
|
||||
return true;
|
||||
@@ -6802,7 +6802,7 @@ static inline bool sema_analyse_expr_dispatch(SemaContext *context, Expr *expr)
|
||||
if (!sema_expr_analyse_ct_stringify(context, expr)) return false;
|
||||
return true;
|
||||
case EXPR_ARGV_TO_SUBARRAY:
|
||||
expr->type = type_get_subarray(type_chars);
|
||||
expr->type = type_get_subarray(global_context_string_type());
|
||||
return true;
|
||||
case EXPR_DECL:
|
||||
if (!sema_analyse_var_decl(context, expr->decl_expr, true)) return false;
|
||||
|
||||
@@ -48,6 +48,7 @@ extern const char *ct_eval_error;
|
||||
|
||||
Decl **global_context_acquire_locals_list(void);
|
||||
void generic_context_release_locals_list(Decl **);
|
||||
Type *global_context_string_type(void);
|
||||
|
||||
AstId context_get_defers(SemaContext *context, AstId defer_top, AstId defer_bottom);
|
||||
void context_pop_defers(SemaContext *context, AstId *next);
|
||||
|
||||
@@ -224,6 +224,20 @@ static void sema_analyze_to_stage(AnalysisStage stage)
|
||||
halt_on_error();
|
||||
}
|
||||
|
||||
Type *global_context_string_type(void)
|
||||
{
|
||||
if (global_context.string_type) return global_context.string_type;
|
||||
DeclId type = decltable_get(&global_context.symbols, symtab_preset("String", TOKEN_TYPE_IDENT));
|
||||
if (!type) error_exit("Missing definition of 'String' type.");
|
||||
Decl *decl = declptr(type);
|
||||
if (decl->decl_kind == DECL_TYPEDEF || decl->decl_kind == DECL_DISTINCT)
|
||||
{
|
||||
if (type_flatten(decl->type) == type_chars) return global_context.string_type = decl->type;
|
||||
|
||||
}
|
||||
error_exit("Invalid definition of String, expected a type with an underlying char[]");
|
||||
}
|
||||
|
||||
/**
|
||||
* Perform the entire semantic analysis.
|
||||
*/
|
||||
@@ -266,7 +280,6 @@ void sema_analysis_run(void)
|
||||
// Set a maximum of symbols in the std_module and test module
|
||||
htable_init(&global_context.std_module.symbols, 0x10000);
|
||||
|
||||
|
||||
// Setup the func prototype hash map
|
||||
type_func_prototype_init(0x10000);
|
||||
|
||||
@@ -312,9 +325,10 @@ void sema_analysis_run(void)
|
||||
{
|
||||
error_exit("'%s::%s' is not a function pointer.", path->module, ident);
|
||||
}
|
||||
if (!type_func_match(panic_fn_type, type_void, 4, type_chars, type_chars, type_chars, type_uint))
|
||||
Type *string = global_context_string_type();
|
||||
if (!type_func_match(panic_fn_type, type_void, 4, string, string, string, type_uint))
|
||||
{
|
||||
error_exit("Expected panic function to have the signature fn void(char[], char[], char[], uint).");
|
||||
error_exit("Expected panic function to have the signature fn void(String, String, String, uint).");
|
||||
}
|
||||
global_context.panic_var = decl;
|
||||
}
|
||||
|
||||
@@ -336,6 +336,15 @@ const char *symtab_find(const char *symbol, uint32_t len, uint32_t fnv1hash, Tok
|
||||
return NULL;
|
||||
}
|
||||
|
||||
const char *symtab_preset(const char *data, TokenType type)
|
||||
{
|
||||
uint32_t len = (uint32_t)strlen(data);
|
||||
TokenType result = type;
|
||||
const char *res = symtab_add(data, len, fnv1a(data, len), &result);
|
||||
assert(result == type);
|
||||
return res;
|
||||
}
|
||||
|
||||
const char *symtab_add(const char *data, uint32_t len, uint32_t fnv1hash, TokenType *type)
|
||||
{
|
||||
size_t pos = fnv1hash & symtab.bucket_mask;
|
||||
|
||||
@@ -8,9 +8,9 @@ static Type *flatten_raw_function_type(Type *type);
|
||||
|
||||
static struct
|
||||
{
|
||||
Type u0, u1, i8, i16, i32, i64, i128, ixx;
|
||||
Type u0, u1, i8, i16, i32, i64, i128;
|
||||
Type u8, u16, u32, u64, u128;
|
||||
Type f16, f32, f64, f128, fxx;
|
||||
Type f16, f32, f64, f128;
|
||||
Type usz, isz, usize, isize, uptr, iptr;
|
||||
Type voidstar, typeid, anyerr, member, typeinfo, untyped_list;
|
||||
Type any, anyfail;
|
||||
|
||||
@@ -99,7 +99,7 @@ int wmain(int argc, const uint16_t *argv[])
|
||||
{
|
||||
args[i] = win_utf16to8(argv[i]);
|
||||
}
|
||||
main_real(argc, (const char **)args);
|
||||
return main_real(argc, (const char **)args);
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
@@ -1 +1 @@
|
||||
#define COMPILER_VERSION "0.4.6"
|
||||
#define COMPILER_VERSION "0.4.7"
|
||||
@@ -8,7 +8,7 @@ fn int test(int baz)
|
||||
}
|
||||
|
||||
extern fn void printf(char*, ...);
|
||||
fn void main(char[][] args)
|
||||
fn void main(String[] args)
|
||||
{
|
||||
test(1022);
|
||||
printf("Hello\n");
|
||||
|
||||
@@ -12,6 +12,6 @@ import private foo;
|
||||
define intHello = foo::@hello<int>; // #error: cannot be aliased
|
||||
define @intHello = foo::hello<int>; // #error: cannot use
|
||||
|
||||
fn void main(char[][] args) {
|
||||
fn void main(String[] args) {
|
||||
@intHello(42);
|
||||
}
|
||||
@@ -11,6 +11,6 @@ import private foo;
|
||||
|
||||
define @intHello = foo::@hello<int>;
|
||||
|
||||
fn void main(char[][] args) {
|
||||
fn void main(String[] args) {
|
||||
@intHello(42);
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
// TODO string str = "hello";
|
||||
char* str2 = "hello";
|
||||
char[] str3 = "hello";
|
||||
String str3 = "hello";
|
||||
|
||||
|
||||
int[2] a1 = { 1, 2 };
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
fn void test()
|
||||
{
|
||||
char* hello = "123";
|
||||
char[] a = { '1', '2', '3' };
|
||||
String a = { '1', '2', '3' };
|
||||
char[*] b = { '1', '2', '3' };
|
||||
char[3] c = { '1', '2', '3' };
|
||||
char* d = { '1', '2', '3' }; // #error: Pointers cannot be initialized using an initializer list, instead you need to take the address of an array
|
||||
|
||||
@@ -10,7 +10,7 @@ fn void IntArray.someFunc(IntArray *this, usz param) {
|
||||
this.push((int)param);
|
||||
}
|
||||
|
||||
fn int main(char[][] argv)
|
||||
fn int main(String[] argv)
|
||||
{
|
||||
IntArray stk;
|
||||
stk.someFunc(256);
|
||||
|
||||
@@ -11,7 +11,7 @@ define IntDoubleMap = std::map::HashMap<int, double>;
|
||||
|
||||
fn char[] Foo.to_string(Foo* foo, Allocator* allocator = mem::current_allocator())
|
||||
{
|
||||
String s = string::new_with_capacity(128, allocator);
|
||||
VarString s = string::new_with_capacity(128, allocator);
|
||||
s.printf("{%s, %p}", foo.x, foo.bar);
|
||||
return s.str();
|
||||
}
|
||||
@@ -109,7 +109,7 @@ entry:
|
||||
%lo = load i8*, i8** %17, align 8
|
||||
%18 = getelementptr inbounds { i8*, i64 }, { i8*, i64 }* %16, i32 0, i32 1
|
||||
%hi = load i64, i64* %18, align 8
|
||||
%19 = call i64 @std_core_string_String_printf(i64* %retparam, i8** %s, i8* getelementptr inbounds ([9 x i8], [9 x i8]* @.str.12, i32 0, i32 0), i64 8, i8* %lo, i64 %hi)
|
||||
%19 = call i64 @std_core_string_VarString_printf(i64* %retparam, i8** %s, i8* getelementptr inbounds ([9 x i8], [9 x i8]* @.str.12, i32 0, i32 0), i64 8, i8* %lo, i64 %hi)
|
||||
%not_err = icmp eq i64 %19, 0
|
||||
br i1 %not_err, label %after_check, label %voiderr
|
||||
|
||||
@@ -118,7 +118,7 @@ after_check: ; preds = %entry
|
||||
|
||||
voiderr: ; preds = %after_check, %entry
|
||||
%20 = load i8*, i8** %s, align 8
|
||||
%21 = call { i8*, i64 } @std_core_string_String_str(i8* %20)
|
||||
%21 = call { i8*, i64 } @std_core_string_VarString_str(i8* %20)
|
||||
%22 = bitcast %"char[]"* %result to { i8*, i64 }*
|
||||
store { i8*, i64 } %21, { i8*, i64 }* %22, align 8
|
||||
%23 = bitcast %"char[]"* %result to { i8*, i64 }*
|
||||
|
||||
@@ -8,7 +8,7 @@ fn int test(int baz)
|
||||
}
|
||||
|
||||
extern fn void printf(char*, ...);
|
||||
fn void main(char[][] args)
|
||||
fn void main(String[] args)
|
||||
{
|
||||
test(1022);
|
||||
printf("Hello\n");
|
||||
|
||||
@@ -12,6 +12,6 @@ import private foo;
|
||||
define intHello = foo::@hello<int>; // #error: cannot be aliased
|
||||
define @intHello = foo::hello<int>; // #error: cannot use
|
||||
|
||||
fn void main(char[][] args) {
|
||||
fn void main(String[] args) {
|
||||
@intHello(42);
|
||||
}
|
||||
@@ -11,6 +11,6 @@ import private foo;
|
||||
|
||||
define @intHello = foo::@hello<int>;
|
||||
|
||||
fn void main(char[][] args) {
|
||||
fn void main(String[] args) {
|
||||
@intHello(42);
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
// TODO string str = "hello";
|
||||
char* str2 = "hello";
|
||||
char[] str3 = "hello";
|
||||
String str3 = "hello";
|
||||
|
||||
|
||||
int[2] a1 = { 1, 2 };
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
fn void test()
|
||||
{
|
||||
char* hello = "123";
|
||||
char[] a = { '1', '2', '3' };
|
||||
String a = { '1', '2', '3' };
|
||||
char[*] b = { '1', '2', '3' };
|
||||
char[3] c = { '1', '2', '3' };
|
||||
char* d = { '1', '2', '3' }; // #error: Pointers cannot be initialized using an initializer list, instead you need to take the address of an array
|
||||
|
||||
@@ -10,7 +10,7 @@ fn void IntArray.someFunc(IntArray *this, usz param) {
|
||||
this.push((int)param);
|
||||
}
|
||||
|
||||
fn int main(char[][] argv)
|
||||
fn int main(String[] argv)
|
||||
{
|
||||
IntArray stk;
|
||||
stk.someFunc(256);
|
||||
|
||||
@@ -11,7 +11,7 @@ define IntDoubleMap = std::map::HashMap<int, double>;
|
||||
|
||||
fn char[] Foo.to_string(Foo* foo, Allocator* allocator = mem::current_allocator())
|
||||
{
|
||||
String s = string::new_with_capacity(128, allocator);
|
||||
VarString s = string::new_with_capacity(128, allocator);
|
||||
s.printf("{%s, %p}", foo.x, foo.bar);
|
||||
return s.str();
|
||||
}
|
||||
@@ -91,7 +91,7 @@ entry:
|
||||
%9 = insertvalue %variant %8, i64 ptrtoint (ptr @"ct$p$void" to i64), 1
|
||||
%10 = getelementptr inbounds [2 x %variant], ptr %varargslots, i64 0, i64 1
|
||||
store %variant %9, ptr %10, align 16
|
||||
%11 = call i64 @std_core_string_String_printf(ptr %retparam, ptr %s, ptr @.str.12, i64 8, ptr %varargslots, i64 2)
|
||||
%11 = call i64 @std_core_string_VarString_printf(ptr %retparam, ptr %s, ptr @.str.12, i64 8, ptr %varargslots, i64 2)
|
||||
%not_err = icmp eq i64 %11, 0
|
||||
br i1 %not_err, label %after_check, label %voiderr
|
||||
|
||||
@@ -100,7 +100,7 @@ after_check: ; preds = %entry
|
||||
|
||||
voiderr: ; preds = %after_check, %entry
|
||||
%12 = load ptr, ptr %s, align 8
|
||||
%13 = call { ptr, i64 } @std_core_string_String_str(ptr %12)
|
||||
%13 = call { ptr, i64 } @std_core_string_VarString_str(ptr %12)
|
||||
store { ptr, i64 } %13, ptr %result, align 8
|
||||
%14 = load { ptr, i64 }, ptr %result, align 8
|
||||
ret { ptr, i64 } %14
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
module conv_tests;
|
||||
import std::io;
|
||||
|
||||
fn void! comparison_helper_32_to_8(Char32 c32, char[] expected_output)
|
||||
fn void! comparison_helper_32_to_8(Char32 c32, String expected_output)
|
||||
{
|
||||
char[8] out;
|
||||
usz len = conv::char32_to_utf8(c32, &out, 4)?;
|
||||
@@ -12,7 +12,7 @@ fn void! comparison_helper_32_to_8(Char32 c32, char[] expected_output)
|
||||
}
|
||||
}
|
||||
|
||||
fn void! comparison_helper_8_to_32(char[] in, Char32 c32)
|
||||
fn void! comparison_helper_8_to_32(String in, Char32 c32)
|
||||
{
|
||||
usz len = in.len;
|
||||
Char32 res = conv::utf8_to_char32(in.ptr, &len)?;
|
||||
@@ -20,7 +20,7 @@ fn void! comparison_helper_8_to_32(char[] in, Char32 c32)
|
||||
assert(res == c32, "Expected character match.");
|
||||
}
|
||||
|
||||
fn void assert_utf8_is_error(char[] in)
|
||||
fn void assert_utf8_is_error(String in)
|
||||
{
|
||||
usz len = in.len;
|
||||
assert(catch(conv::utf8_to_char32(in.ptr, &len)), "Expected error");
|
||||
|
||||
@@ -6,7 +6,7 @@ fn void! rc_crypt() @test
|
||||
Rc4 rc;
|
||||
rc.init(&&x"63727970746969");
|
||||
char[200] x;
|
||||
char[] text = "The quick brown fox jumps over the lazy dog.";
|
||||
String text = "The quick brown fox jumps over the lazy dog.";
|
||||
rc.crypt(text, &x);
|
||||
char[*] res = x"2ac2fecdd8fbb84638e3a4
|
||||
820eb205cc8e29c28b9d5d
|
||||
|
||||
Reference in New Issue
Block a user