Updated stream API.

This commit is contained in:
Christoffer Lerno
2023-09-02 19:48:51 +02:00
committed by Christoffer Lerno
parent a6cff5c2a5
commit 9a6d83f526
44 changed files with 837 additions and 952 deletions

View File

@@ -378,7 +378,7 @@ fn void DString.reserve(&self, usz addition)
*self = (DString)realloc(data, StringData.sizeof + new_capacity, .using = data.allocator);
}
fn usz! DString.read_from_stream(&self, Stream reader)
fn usz! DString.read_from_stream(&self, Stream* reader)
{
if (reader.supports_available())
{

View File

@@ -3,17 +3,11 @@ import std::io;
struct CsvReader
{
Stream stream;
Stream* stream;
String separator;
}
fn void CsvReader.init_file(&self, File* file, String separator = ",")
{
self.stream = file.as_stream();
self.separator = separator;
}
fn void CsvReader.init(&self, Stream stream, String separator = ",")
fn void CsvReader.init(&self, Stream* stream, String separator = ",")
{
self.stream = stream;
self.separator = separator;
@@ -42,7 +36,7 @@ fn void! CsvReader.skip_row(self) @maydiscard
macro CsvReader.@each_row(self, int rows = int.max; @body(String[] row))
{
Stream stream = self.stream;
Stream* stream = self.stream;
String sep = self.separator;
while (rows--)
{

View File

@@ -15,7 +15,7 @@ fault JsonParsingError
INVALID_NUMBER,
}
fn Object*! parse(Stream s, Allocator* using = mem::heap())
fn Object*! parse(Stream* s, Allocator* using = mem::heap())
{
JsonContext context = { .last_string = dstring::new_with_capacity(64, using), .stream = s, .allocator = using };
defer context.last_string.free();
@@ -44,7 +44,7 @@ enum JsonTokenType @local
struct JsonContext @local
{
uint line;
Stream stream;
Stream* stream;
Allocator* allocator;
JsonTokenType token;
DString last_string;

View File

@@ -6,6 +6,7 @@ import libc;
struct File
{
inline Stream stream;
CFile file;
}
@@ -95,19 +96,25 @@ fn void putchar(char c) @inline
libc::putchar(c);
}
fn File stdout()
fn File* stdout()
{
return { libc::stdout() };
static File file;
if (!file.fns) file = file::from_handle(libc::stdout());
return &file;
}
fn File stderr()
fn File* stderr()
{
return { libc::stderr() };
static File file;
if (!file.fns) file = file::from_handle(libc::stderr());
return &file;
}
fn File stdin()
fn File* stdin()
{
return { libc::stdin() };
static File file;
if (!file.fns) file = file::from_handle(libc::stdin());
return &file;
}
module std::io @if(!env::LIBC);

View File

@@ -3,20 +3,21 @@ import libc;
fn File! open(String filename, String mode)
{
return { .file = os::native_fopen(filename, mode) };
return from_handle(os::native_fopen(filename, mode));
}
fn File! open_path(Path path, String mode)
{
return from_handle(os::native_fopen(path.as_str(), mode));
}
fn File from_handle(CFile file)
{
return { .stream.fns = &FILESTREAM_INTERFACE, .file = file };
}
fn void! delete(String filename) => os::native_remove(filename) @inline;
fn File! open_path(Path path, String mode)
{
return { .file = os::native_fopen(path.as_str(), mode) };
}
fn File from_libc(CFile file)
{
return { .file = file };
}
/**
* @require self.file != null
@@ -29,7 +30,7 @@ fn void! File.reopen(&self, String filename, String mode)
/**
* @require self.file != null
**/
fn usz! File.seek(self, isz offset, Seek seek_mode = Seek.SET)
fn usz! File.seek(&self, isz offset, Seek seek_mode = Seek.SET)
{
os::native_fseek(self.file, offset, seek_mode)!;
return os::native_ftell(self.file);
@@ -55,7 +56,7 @@ fn void! File.memopen(File* file, char[] data, String mode)
/**
* @require self.file != null
*/
fn void! File.putc(self, char c)
fn void! File.write_byte(&self, char c)
{
if (!libc::fputc(c, self.file)) return IoError.EOF?;
}
@@ -89,7 +90,7 @@ fn void! File.close(&self) @inline
/**
* @require self.file
*/
fn bool File.eof(self) @inline
fn bool File.eof(&self) @inline
{
return libc::feof(self.file) != 0;
}
@@ -97,44 +98,24 @@ fn bool File.eof(self) @inline
/**
* @param [in] buffer
*/
fn usz! File.read(self, char[] buffer)
fn usz! File.read(&self, char[] buffer)
{
return os::native_fread(self.file, buffer);
}
/**
* @param ref "the object to read into."
* @require ref.ptr != null
* @ensure return == ref.type.sizeof
*/
fn usz! File.read_any(self, any ref)
{
return self.read(ref.ptr[:ref.type.sizeof]);
}
/**
* @param [out] buffer
* @require self.file `File must be initialized`
*/
fn usz! File.write(self, char[] buffer)
fn usz! File.write(&self, char[] buffer)
{
return os::native_fwrite(self.file, buffer);
}
/**
* @param ref "the object to write."
* @require ref.ptr != null
* @ensure return == ref.type.sizeof
*/
fn usz! File.write_any(self, any ref)
{
return self.write(ref.ptr[:ref.type.sizeof]);
}
/**
* @require self.file `File must be initialized`
*/
fn usz! File.printn(self, String string = "")
fn usz! File.printn(&self, String string = "")
{
usz len = self.print(string)!;
if (!libc::putc('\n', self.file)) return IoError.UNKNOWN_ERROR?;
@@ -144,39 +125,14 @@ fn usz! File.printn(self, String string = "")
/**
* @require self.file `File must be initialized`
*/
fn usz! File.print(self, String string)
fn usz! File.print(&self, String string)
{
usz len = string.len;
if (len != self.write((char[])string)!) return IoError.UNKNOWN_ERROR?;
return len;
}
/**
* @require self.file `File must be initialized`
*/
fn DString File.getline(self, Allocator* using = mem::heap())
{
DString s = dstring::new_with_capacity(120, using);
while (!self.eof())
{
int c = libc::fgetc(self.file);
if (c == -1) break;
if (c == '\n') break;
s.append_char((char)c);
}
return s;
}
/**
* @require self.file `File must be initialized`
* @return "a zero terminated String (the pointer may be safely cast into a ZString)"
*/
fn String File.tgetline(self)
{
return self.getline(mem::temp()).zstr().as_str();
}
fn char! File.getc(self)
fn char! File.read_byte(&self)
{
int c = libc::fgetc(self.file);
if (c == -1) return IoError.EOF?;
@@ -186,7 +142,17 @@ fn char! File.getc(self)
/**
* @require self.file `File must be initialized`
*/
fn void File.flush(self)
fn void File.flush(&self)
{
libc::fflush(self.file);
}
const StreamInterface FILESTREAM_INTERFACE = {
.close_fn = (CloseStreamFn)&File.close,
.seek_fn = (SeekStreamFn)&File.seek,
.read_fn = (ReadStreamFn)&File.read,
.read_byte_fn = (ReadByteStreamFn)&File.read_byte,
.write_fn = (WriteStreamFn)&File.write,
.write_byte_fn = (WriteByteStreamFn)&File.write_byte,
.flush_fn = (FlushStreamFn)&File.flush
};

View File

@@ -64,7 +64,7 @@ fn usz! File.printfn(self, String format, args...) @maydiscard
Formatter formatter;
formatter.init(&out_fputchar_fn, &self);
usz len = formatter.vprintf(format, args)!;
self.putc('\n')!;
self.write_byte('\n')!;
self.flush();
return len + 1;
}
@@ -280,7 +280,7 @@ fn void! out_putchar_fn(char c, void* data @unused) @private
fn void! out_fputchar_fn(char c, void* data) @private
{
File* f = data;
f.putc(c)!;
f.write_byte(c)!;
}
struct BufferData @private

View File

@@ -1,18 +1,18 @@
module std::io;
def CloseStreamFn = fn void!(Stream);
def FlushStreamFn = fn void!(Stream);
def SeekStreamFn = fn usz!(Stream, isz offset, Seek seek);
def LenStreamFn = fn usz(Stream);
def AvailableStreamFn = fn usz!(Stream);
def ReadStreamFn = fn usz!(Stream, char[] bytes);
def ReadFromStreamFn = fn usz!(Stream, Stream);
def ReadByteStreamFn = fn char!(Stream);
def PushbackByteStreamFn = fn void!(Stream);
def WriteStreamFn = fn usz!(Stream, char[] bytes);
def WriteToStreamFn = fn usz!(Stream, Stream out);
def WriteByteStreamFn = fn void!(Stream, char c);
def DestroyStreamFn = fn void!(Stream);
def CloseStreamFn = fn void!(Stream*);
def FlushStreamFn = fn void!(Stream*);
def SeekStreamFn = fn usz!(Stream*, isz offset, Seek seek);
def LenStreamFn = fn usz(Stream*);
def AvailableStreamFn = fn usz!(Stream*);
def ReadStreamFn = fn usz!(Stream*, char[] bytes);
def ReadFromStreamFn = fn usz!(Stream*, Stream*);
def ReadByteStreamFn = fn char!(Stream*);
def PushbackByteStreamFn = fn void!(Stream*);
def WriteStreamFn = fn usz!(Stream*, char[] bytes);
def WriteToStreamFn = fn usz!(Stream*, Stream* out);
def WriteByteStreamFn = fn void!(Stream*, char c);
def DestroyStreamFn = fn void!(Stream*);
struct StreamInterface
{
@@ -33,40 +33,45 @@ struct StreamInterface
struct Stream
{
StreamInterface *fns;
StreamInterface* fns;
}
struct StreamWrapper
{
inline Stream stream;
void* data;
}
fn bool Stream.supports_flush(s) @inline => (bool)s.fns.flush_fn;
fn bool Stream.supports_seek(s) @inline => (bool)s.fns.seek_fn;
fn bool Stream.supports_available(s) @inline => s.fns.available_fn || s.fns.seek_fn;
fn bool Stream.supports_len(s) @inline => s.fns.len_fn || s.fns.seek_fn;
fn bool Stream.supports_read(s) @inline => s.fns.read_fn || s.fns.read_byte_fn;
fn bool Stream.supports_read_from(s) @inline => (bool)s.fns.read_stream_fn;
fn bool Stream.supports_write_to(s) @inline => (bool)s.fns.write_stream_fn;
fn bool Stream.supports_pushback_byte(s) @inline => s.fns.pushback_byte_fn || s.fns.seek_fn;
fn bool Stream.supports_write(s) @inline => s.fns.write_fn || s.fns.write_byte_fn;
fn bool Stream.supports_read_byte(s) @inline => (bool)s.fns.read_byte_fn;
fn bool Stream.supports_write_byte(s) @inline => (bool)s.fns.write_byte_fn;
fn bool Stream.supports_flush(&s) @inline => (bool)s.fns.flush_fn;
fn bool Stream.supports_seek(&s) @inline => (bool)s.fns.seek_fn;
fn bool Stream.supports_available(&s) @inline => s.fns.available_fn || s.fns.seek_fn;
fn bool Stream.supports_len(&s) @inline => s.fns.len_fn || s.fns.seek_fn;
fn bool Stream.supports_read(&s) @inline => s.fns.read_fn || s.fns.read_byte_fn;
fn bool Stream.supports_read_from(&s) @inline => (bool)s.fns.read_stream_fn;
fn bool Stream.supports_write_to(&s) @inline => (bool)s.fns.write_stream_fn;
fn bool Stream.supports_pushback_byte(&s) @inline => s.fns.pushback_byte_fn || s.fns.seek_fn;
fn bool Stream.supports_write(&s) @inline => s.fns.write_fn || s.fns.write_byte_fn;
fn bool Stream.supports_read_byte(&s) @inline => (bool)s.fns.read_byte_fn;
fn bool Stream.supports_write_byte(&s) @inline => (bool)s.fns.write_byte_fn;
fn void! Stream.destroy(self) @inline @maydiscard
fn void! Stream.destroy(&self) @inline @maydiscard
{
if (self.fns.destroy_fn) return self.fns.destroy_fn(self);
return self.close();
}
fn void! Stream.close(self) @inline @maydiscard
fn void! Stream.close(&self) @inline @maydiscard
{
if (CloseStreamFn func = self.fns.close_fn) return func(self);
}
fn usz! Stream.seek(self, isz offset, Seek seek) @inline
fn usz! Stream.seek(&self, isz offset, Seek seek) @inline
{
if (SeekStreamFn func = self.fns.seek_fn) return func(self, offset, seek);
return IoError.NOT_SEEKABLE?;
}
fn usz! Stream.available(self) @inline
fn usz! Stream.available(&self) @inline
{
if (AvailableStreamFn func = self.fns.available_fn) return func(self);
if (SeekStreamFn func = self.fns.seek_fn)
@@ -79,9 +84,9 @@ fn usz! Stream.available(self) @inline
return IoError.NOT_SEEKABLE?;
}
fn usz! Stream.read_any(self, any ref)
fn usz! Stream.read_any(&self, any ref)
{
return self.read(ref.ptr[:ref.type.sizeof]);
return self.read_all(ref.ptr[:ref.type.sizeof]);
}
/**
@@ -89,13 +94,12 @@ fn usz! Stream.read_any(self, any ref)
* @require ref.ptr != null
* @ensure return == ref.type.sizeof
*/
fn usz! Stream.write_any(self, any ref)
fn usz! Stream.write_any(&self, any ref)
{
return self.write(ref.ptr[:ref.type.sizeof]);
return self.write_all(ref.ptr[:ref.type.sizeof]);
}
fn usz! Stream.read(self, char[] buffer)
fn usz! Stream.read(&self, char[] buffer)
{
if (ReadStreamFn func = self.fns.read_fn) return func(self, buffer);
if (ReadByteStreamFn func = self.fns.read_byte_fn)
@@ -116,56 +120,94 @@ fn usz! Stream.read(self, char[] buffer)
return IoError.UNSUPPORTED_OPERATION?;
}
fn char! Stream.read_byte(self) @inline
fn char! Stream.read_byte(&self) @inline
{
if (ReadByteStreamFn func = self.fns.read_byte_fn) return func(self);
if (ReadStreamFn func = self.fns.read_fn)
{
char[1] buffer;
usz read = func(self, &buffer)!;
if (read != 1) return IoError.EOF?;
return buffer[0];
}
return IoError.UNSUPPORTED_OPERATION?;
}
fn usz! Stream.read_all(self, char[] buffer) @inline
fn usz! Stream.read_all(&self, char[] buffer) @inline
{
usz n = self.read(buffer)!;
if (n != buffer.len) return IoError.UNEXPECTED_EOF?;
return n;
}
fn usz! Stream.write_all(self, char[] buffer) @inline
fn usz! Stream.write_all(&self, char[] buffer) @inline
{
usz n = self.write(buffer)!;
if (n != buffer.len) return IoError.INCOMPLETE_WRITE?;
return n;
}
fn String! Stream.treadline(self) => self.readline(mem::temp()) @inline;
fn String! Stream.readline(self, Allocator* using = mem::heap())
fn String! Stream.treadline(&self) => self.readline(mem::temp()) @inline;
fn String! Stream.readline(&self, Allocator* using = mem::heap())
{
ReadByteStreamFn func;
if (func = self.fns.read_byte_fn, !func) return IoError.UNSUPPORTED_OPERATION?;
bool read = false;
char val = func(self)!;
if (val == '\n') return "";
@pool(using)
if (ReadByteStreamFn func = self.fns.read_byte_fn)
{
DString str = dstring::tnew_with_capacity(256);
if (val != '\r') str.append(val);
while (1)
{
char! c = func(self);
if (catch err = c)
{
if (err == IoError.EOF) break;
return err?;
}
if (c == '\r') continue;
if (c == '\n') break;
str.append_char(c);
}
return str.copy_str(using);
};
char val = func(self)!;
if (val == '\n') return "";
@pool(using)
{
DString str = dstring::tnew_with_capacity(256);
if (val != '\r') str.append(val);
while (1)
{
char! c = func(self);
if (catch err = c)
{
if (err == IoError.EOF) break;
return err?;
}
if (c == '\r') continue;
if (c == '\n') break;
str.append_char(c);
}
return str.copy_str(using);
};
}
if (ReadStreamFn func = self.fns.read_fn)
{
char[1] buff;
if (func(self, &buff)! == 0) return IoError.EOF?;
char val = buff[0];
if (val == '\n') return "";
@pool(using)
{
DString str = dstring::tnew_with_capacity(256);
if (val != '\r') str.append(val);
while (1)
{
usz! read = func(self, &buff);
if (catch err = read)
{
if (err == IoError.EOF) break;
return err?;
}
if (!read) break;
char c = buff[0];
if (c == '\r') continue;
if (c == '\n') break;
str.append_char(c);
}
return str.copy_str(using);
};
}
return IoError.UNSUPPORTED_OPERATION?;
}
fn usz! Stream.write(self, char[] bytes) @inline
fn usz! Stream.write(&self, char[] bytes) @inline
{
if (WriteStreamFn func = self.fns.write_fn) return func(self, bytes);
if (WriteByteStreamFn func = self.fns.write_byte_fn)
@@ -176,31 +218,31 @@ fn usz! Stream.write(self, char[] bytes) @inline
return IoError.UNSUPPORTED_OPERATION?;
}
fn void! Stream.write_byte(self, char b) @inline
fn void! Stream.write_byte(&self, char b) @inline
{
if (WriteByteStreamFn func = self.fns.write_byte_fn) return func(self, b);
return IoError.UNSUPPORTED_OPERATION?;
}
fn usz! Stream.write_to(self, Stream to) @inline
fn usz! Stream.write_to(&self, Stream* to) @inline
{
if (WriteToStreamFn func = self.fns.write_stream_fn) return func(self, to);
return IoError.UNSUPPORTED_OPERATION?;
}
fn usz! Stream.read_from(self, Stream from) @inline
fn usz! Stream.read_from(&self, Stream* from) @inline
{
if (ReadFromStreamFn func = self.fns.read_stream_fn) return func(self, from);
return IoError.UNSUPPORTED_OPERATION?;
}
fn void! Stream.flush(self) @inline @maydiscard
fn void! Stream.flush(&self) @inline @maydiscard
{
if (FlushStreamFn func = self.fns.flush_fn) return func(self);
return IoError.UNSUPPORTED_OPERATION?;
}
fn usz! Stream.len(self) @inline
fn usz! Stream.len(&self) @inline
{
if (LenStreamFn func = self.fns.len_fn) return func(self);
if (SeekStreamFn func = self.fns.seek_fn)
@@ -213,7 +255,7 @@ fn usz! Stream.len(self) @inline
return IoError.NOT_SEEKABLE?;
}
fn void! Stream.pushback_byte(self) @inline
fn void! Stream.pushback_byte(&self) @inline
{
if (PushbackByteStreamFn func = self.fns.pushback_byte_fn) return func(self);
if (SeekStreamFn func = self.fns.seek_fn)
@@ -224,13 +266,13 @@ fn void! Stream.pushback_byte(self) @inline
return IoError.UNSUPPORTED_OPERATION?;
}
fn void! Stream.write_string(self, String str) @inline => (void)(self.write((char[])str)!);
fn void! Stream.write_string(&self, String str) @inline => (void)(self.write((char[])str)!);
fn usz! Stream.copy_to(self, Stream dst, char[] buffer = {})
fn usz! Stream.copy_to(&self, Stream* dst, char[] buffer = {})
{
if (buffer.len) return copy_through_buffer(self, dst, buffer);
if (WriteToStreamFn func = self.fns.write_stream_fn) return func(self, dst);
if (ReadFromStreamFn func = dst.fns.read_stream_fn) return func(dst, self);
if (ReadFromStreamFn func = self.fns.read_stream_fn) return func(dst, self);
$switch (env::MEMORY_ENV)
$case NORMAL:
@pool()
@@ -248,7 +290,7 @@ fn usz! Stream.copy_to(self, Stream dst, char[] buffer = {})
$endswitch
}
macro usz! copy_through_buffer(self, Stream dst, char[] buffer) @local
macro usz! copy_through_buffer(Stream *self, Stream* dst, char[] buffer) @local
{
usz total_copied;
while (true)

View File

@@ -2,7 +2,8 @@ module std::io;
struct ReadBuffer
{
Stream stream;
inline Stream stream;
Stream* wrapped_stream;
char[] bytes;
usz read_idx;
usz write_idx;
@@ -14,19 +15,16 @@ struct ReadBuffer
* @require bytes.len > 0
* @require self.bytes.len == 0 "Init may not run on already initialized data"
**/
fn void ReadBuffer.init(&self, Stream stream, char[] bytes)
fn ReadBuffer* ReadBuffer.init(&self, Stream* wrapped_stream, char[] bytes)
{
*self = { .stream = stream, .bytes = bytes };
*self = { .stream.fns = &READBUFFER_INTERFACE, .wrapped_stream = wrapped_stream, .bytes = bytes };
return self;
}
fn Stream ReadBuffer.as_stream(&self)
{
return { .fns = &readbuffer_interface, .data = self };
}
StreamInterface readbuffer_interface = {
.read_fn = fn(s, char[] bytes) => ((ReadBuffer*)s.data).read(bytes),
.read_byte_fn = fn(s) => ((ReadBuffer*)s.data).read_byte(),
const StreamInterface READBUFFER_INTERFACE = {
.read_fn = (ReadStreamFn)&ReadBuffer.read,
.read_byte_fn = (ReadByteStreamFn)&ReadBuffer.read_byte,
};
fn String ReadBuffer.as_str(&self) @inline
@@ -41,7 +39,7 @@ fn usz! ReadBuffer.read(&self, char[] bytes)
if (self.read_idx == 0 && bytes.len >= self.bytes.len)
{
// Read directly into the input buffer.
return self.stream.read(bytes)!;
return self.wrapped_stream.read(bytes)!;
}
self.refill()!;
}
@@ -63,12 +61,13 @@ fn char! ReadBuffer.read_byte(&self)
fn void! ReadBuffer.refill(&self) @local @inline
{
self.read_idx = 0;
self.write_idx = self.stream.read(self.bytes)!;
self.write_idx = self.wrapped_stream.read(self.bytes)!;
}
struct WriteBuffer
{
Stream stream;
inline Stream stream;
Stream* wrapped_stream;
char[] bytes;
usz index;
}
@@ -79,20 +78,16 @@ struct WriteBuffer
* @require bytes.len > 0 "Non-empty buffer required"
* @require self.bytes.len == 0 "Init may not run on already initialized data"
**/
fn void WriteBuffer.init(&self, Stream stream, char[] bytes)
fn WriteBuffer* WriteBuffer.init(&self, Stream* wrapped_stream, char[] bytes)
{
*self = { .stream = stream, .bytes = bytes };
*self = { .stream.fns = &WRITEBUFFER_INTERFACE, .wrapped_stream = wrapped_stream, .bytes = bytes };
return self;
}
fn Stream WriteBuffer.as_stream(&self)
{
return { .fns = &writebuffer_interface, .data = self };
}
StreamInterface writebuffer_interface = {
.flush_fn = fn(s) => ((WriteBuffer*)s.data).flush(),
.write_fn = fn(s, char[] bytes) => ((WriteBuffer*)s.data).write(bytes),
.write_byte_fn = fn(s, char c) => ((WriteBuffer*)s.data).write_byte(c),
const StreamInterface WRITEBUFFER_INTERFACE = {
.flush_fn = (FlushStreamFn)&WriteBuffer.flush,
.write_fn = (WriteStreamFn)&WriteBuffer.write,
.write_byte_fn = (WriteByteStreamFn)&WriteBuffer.write_byte,
};
fn String WriteBuffer.as_str(&self) @inline
@@ -103,7 +98,7 @@ fn String WriteBuffer.as_str(&self) @inline
fn void! WriteBuffer.flush(&self)
{
self.write_pending()!;
if (self.stream.supports_flush()) self.stream.flush()!;
if (self.wrapped_stream.supports_flush()) self.wrapped_stream.flush()!;
}
fn usz! WriteBuffer.write(&self, char[] bytes)
@@ -120,7 +115,7 @@ fn usz! WriteBuffer.write(&self, char[] bytes)
if (bytes.len >= self.bytes.len)
{
// Write directly to the stream.
return self.stream.write(bytes);
return self.wrapped_stream.write(bytes);
}
// Buffer the data.
self.bytes[:bytes.len] = bytes[..];
@@ -138,6 +133,6 @@ fn void! WriteBuffer.write_byte(&self, char c)
fn void! WriteBuffer.write_pending(&self) @local
{
self.index -= self.stream.write(self.bytes[:self.index])!;
self.index -= self.wrapped_stream.write(self.bytes[:self.index])!;
if (self.index != 0) return IoError.INCOMPLETE_WRITE?;
}

View File

@@ -3,6 +3,7 @@ import std::math;
struct ByteBuffer
{
inline Stream stream;
Allocator* allocator;
usz max_read;
char[] bytes;
@@ -16,16 +17,17 @@ struct ByteBuffer
* max_read defines how many bytes might be kept before its internal buffer is shrinked.
* @require self.bytes.len == 0 "Buffer already initialized."
**/
fn void! ByteBuffer.init(&self, usz max_read, usz initial_capacity = 16, Allocator* using = mem::heap())
fn ByteBuffer*! ByteBuffer.init(&self, usz max_read, usz initial_capacity = 16, Allocator* using = mem::heap())
{
*self = { .allocator = using, .max_read = max_read };
*self = { .stream.fns = &BYTEBUFFER_INTERFACE, .allocator = using, .max_read = max_read };
initial_capacity = max(initial_capacity, 16);
self.grow(initial_capacity)!;
return self;
}
fn void! ByteBuffer.tinit(&self, usz max_read, usz initial_capacity = 16)
fn ByteBuffer*! ByteBuffer.tinit(&self, usz max_read, usz initial_capacity = 16)
{
self.init(max_read, initial_capacity, mem::temp())!;
return self.init(max_read, initial_capacity, mem::temp())!;
}
fn void! ByteBuffer.free(&self)
@@ -34,18 +36,13 @@ fn void! ByteBuffer.free(&self)
*self = {};
}
fn Stream ByteBuffer.as_stream(&self)
{
return { .fns = &bytebuffer_interface, .data = self };
}
StreamInterface bytebuffer_interface = {
.write_fn = fn(s, char[] bytes) => ((ByteBuffer*)s.data).write(bytes),
.write_byte_fn = fn(s, c) => ((ByteBuffer*)s.data).write_byte(c),
.read_fn = fn(s, char[] bytes) => ((ByteBuffer*)s.data).read(bytes),
.read_byte_fn = fn(s) => ((ByteBuffer*)s.data).read_byte(),
.pushback_byte_fn = fn(s) => ((ByteBuffer*)s.data).pushback_byte(),
.available_fn = fn(s) => ((ByteBuffer*)s.data).available(),
const StreamInterface BYTEBUFFER_INTERFACE = {
.write_fn = (WriteStreamFn)&ByteBuffer.write,
.write_byte_fn = (WriteByteStreamFn)&ByteBuffer.write_byte,
.read_fn = (ReadStreamFn)&ByteBuffer.read,
.read_byte_fn = (ReadByteStreamFn)&ByteBuffer.read_byte,
.pushback_byte_fn = (PushbackByteStreamFn)&ByteBuffer.pushback_byte,
.available_fn = (AvailableStreamFn)&ByteBuffer.available
};
fn usz! ByteBuffer.write(&self, char[] bytes)

View File

@@ -2,18 +2,15 @@ module std::io;
struct ByteReader
{
inline Stream stream;
char[] bytes;
usz index;
}
fn void ByteReader.init(&self, char[] bytes)
fn ByteReader* ByteReader.init(&self, char[] bytes)
{
*self = { .bytes = bytes };
}
fn Stream ByteReader.as_stream(&self)
{
return { .fns = &bytereader_interface, .data = self };
*self = { .stream = { &BYTEREADER_INTERFACE }, .bytes = bytes };
return self;
}
fn usz! ByteReader.read(&self, char[] bytes)
@@ -52,7 +49,7 @@ fn usz! ByteReader.seek(&self, isz offset, Seek seek)
return new_index;
}
fn usz! ByteReader.write_stream(&self, Stream writer)
fn usz! ByteReader.write_stream(&self, Stream* writer)
{
if (self.index >= self.bytes.len) return 0;
usz written = writer.write(self.bytes[self.index..])!;
@@ -66,14 +63,14 @@ fn usz ByteReader.available(&self) @inline
return max(0, self.bytes.len - self.index);
}
StreamInterface bytereader_interface = {
.len_fn = fn (s) => ((ByteReader*)s.data).bytes.len,
.read_fn = fn (s, char[] bytes) => ((ByteReader*)s.data).read(bytes) @inline,
.read_byte_fn = fn (s) => ((ByteReader*)s.data).read_byte() @inline,
.pushback_byte_fn = fn (s) => ((ByteReader*)s.data).pushback_byte() @inline,
.seek_fn = fn (s, offset, seek) => ((ByteReader*)s.data).seek(offset, seek) @inline,
.write_stream_fn = fn (s, writer) => ((ByteReader*)s.data).write_stream(writer) @inline,
.available_fn = fn (s) => ((ByteReader*)s.data).available() @inline,
const StreamInterface BYTEREADER_INTERFACE = {
.len_fn = fn (Stream* self) => ((ByteReader*)self).bytes.len,
.read_fn = (ReadStreamFn)&ByteReader.read,
.read_byte_fn = (ReadByteStreamFn)&ByteReader.read_byte,
.pushback_byte_fn = (PushbackByteStreamFn)&ByteReader.pushback_byte,
.seek_fn = (SeekStreamFn)&ByteReader.seek,
.write_stream_fn = (WriteToStreamFn)&ByteReader.write_stream,
.available_fn = fn (Stream* self) => ((ByteReader*)self).available(),
};

View File

@@ -2,6 +2,7 @@ module std::io;
struct ByteWriter
{
inline Stream stream;
char[] bytes;
usz index;
Allocator* allocator;
@@ -11,30 +12,27 @@ struct ByteWriter
* @param [&inout] self
* @param [&in] using
* @require self.bytes.len == 0 "Init may not run on on already initialized data"
* @ensure using != null, index == 0
* @ensure using != null, self.index == 0
**/
fn void ByteWriter.init(&self, Allocator* using = mem::heap())
fn ByteWriter* ByteWriter.init(&self, Allocator* using = mem::heap())
{
*self = { .bytes = {}, .allocator = using };
*self = { .stream.fns = &BYTEWRITER_INTERFACE, .bytes = {}, .allocator = using };
return self;
}
fn void ByteWriter.init_buffer(&self, char[] data)
fn ByteWriter* ByteWriter.init_buffer(&self, char[] data)
{
*self = { .bytes = data, .allocator = null };
*self = { .stream.fns = &BYTEWRITER_INTERFACE, .bytes = data, .allocator = null };
return self;
}
/**
* @param [&inout] self
* @require self.bytes.len == 0 "Init may not run on on already initialized data"
**/
fn void ByteWriter.tinit(&self)
fn ByteWriter* ByteWriter.tinit(&self)
{
*self = { .bytes = {}, .allocator = mem::temp() };
}
fn Stream ByteWriter.as_stream(&self)
{
return { .fns = &bytewriter_interface, .data = self };
return self.init(mem::temp());
}
fn void ByteWriter.destroy(&self)
@@ -77,7 +75,7 @@ fn void! ByteWriter.write_byte(&self, char c)
* @param [&inout] self
* @param reader
**/
fn usz! ByteWriter.read_from(&self, Stream reader)
fn usz! ByteWriter.read_from(&self, Stream* reader)
{
usz start_index = self.index;
if (reader.supports_available())
@@ -113,10 +111,10 @@ fn usz! ByteWriter.read_from(&self, Stream reader)
}
}
StreamInterface bytewriter_interface = {
.destroy_fn = fn (s) => ((ByteWriter*)s.data).destroy(),
.len_fn = fn (s) => ((ByteWriter*)s.data).bytes.len,
.write_fn = fn (s, char[] bytes) => ((ByteWriter*)s.data).write(bytes),
.write_byte_fn = fn (s, char c) => ((ByteWriter*)s.data).write_byte(c),
.read_stream_fn = fn (s, reader) => ((ByteWriter*)s.data).read_from(reader),
const StreamInterface BYTEWRITER_INTERFACE = {
.destroy_fn = fn (s) => ((ByteWriter*)s).destroy(),
.len_fn = fn (s) => ((ByteWriter*)s).bytes.len,
.write_fn = (WriteStreamFn)&ByteWriter.write,
.write_byte_fn = (WriteByteStreamFn)&ByteWriter.write_byte,
.read_stream_fn = (ReadFromStreamFn)&ByteWriter.read_from,
};

View File

@@ -1,14 +1,38 @@
module std::io;
fn Stream DString.as_stream(&self)
struct DStringStream
{
return { .fns = &dstring_interface, .data = self };
inline Stream stream;
DString* wrapped_string;
}
StreamInterface dstring_interface = {
.destroy_fn = fn (s) => ((DString*)s.data).free(),
.len_fn = fn (s) => ((DString*)s.data).len(),
.write_fn = fn (s, char[] bytes) { ((DString*)s.data).append_chars((String)bytes); return bytes.len; },
.write_byte_fn = fn (s, char c) => ((DString*)s.data).append_char(c),
.read_stream_fn = fn (s, reader) => ((DString*)s.data).read_from_stream(reader),
fn DStringStream* DStringStream.init(&self, DString* wrapped_string)
{
*self = { .stream.fns = &DSTRINGSTREAM_INTERFACE, .wrapped_string = wrapped_string };
return self;
}
fn usz DStringStream.len(&self) => self.wrapped_string.len();
fn usz! DStringStream.write(&self, char[] bytes)
{
self.wrapped_string.append_chars((String)bytes);
return bytes.len;
}
fn void! DStringStream.write_byte(&self, char c)
{
self.wrapped_string.append_char(c);
}
fn usz! DStringStream.read_from_stream(&self, Stream* reader)
{
return self.wrapped_string.read_from_stream(reader);
}
const StreamInterface DSTRINGSTREAM_INTERFACE = {
.len_fn = (LenStreamFn)&DStringStream.len,
.write_fn = (WriteStreamFn)&DStringStream.write,
.write_byte_fn = (WriteByteStreamFn)&DStringStream.write_byte,
.read_stream_fn = (ReadFromStreamFn)&DStringStream.read_from_stream,
};

View File

@@ -1,18 +0,0 @@
module std::io;
fn Stream File.as_stream(&self)
{
return { .fns = &filestream_interface, .data = self };
}
StreamInterface filestream_interface = {
.close_fn = fn (s) => ((File*)s.data).close(),
.seek_fn = fn (s, offset, seek) => ((File*)s.data).seek(offset, seek) @inline,
.read_fn = fn (s, char[] bytes) => ((File*)s.data).read(bytes) @inline,
.write_fn = fn (s, char[] bytes) => ((File*)s.data).write(bytes) @inline,
.write_byte_fn = fn (s, char c) => ((File*)s.data).putc(c) @inline,
.read_byte_fn = fn (s) => ((File*)s.data).getc() @inline,
.flush_fn = fn (s) => ((File*)s.data).flush() @inline,
};

View File

@@ -2,27 +2,35 @@ module std::io::stream;
struct LimitReader
{
Stream reader;
inline Stream stream;
Stream* wrapped_stream;
usz limit;
}
fn void LimitReader.init(&self, Stream reader, usz limit)
/**
* @param [&inout] wrapped_stream "The stream to read from"
* @param limit "The max limit to read"
**/
fn LimitReader* LimitReader.init(&self, Stream* wrapped_stream, usz limit)
{
*self = { .reader = reader, .limit = limit };
*self = { .stream.fns = &LIMITREADER_INTERFACE, .wrapped_stream = wrapped_stream, .limit = limit };
return self;
}
fn usz! LimitReader.read(&self, char[] bytes)
{
if (self.limit == 0) return IoError.EOF?;
usz m = min(bytes.len, self.limit);
usz n = self.reader.read(bytes[:m])!;
usz n = self.wrapped_stream.read(bytes[:m])!;
self.limit -= n;
return n;
}
fn Stream LimitReader.as_stream(&self)
fn char! LimitReader.read_byte(&self)
{
return { .fns = &limitreader_interface, .data = self };
if (self.limit == 0) return IoError.EOF?;
defer try self.limit--;
return self.wrapped_stream.read_byte();
}
fn usz LimitReader.available(&self) @inline
@@ -30,7 +38,8 @@ fn usz LimitReader.available(&self) @inline
return self.limit;
}
StreamInterface limitreader_interface = {
.read_fn = fn(s, char[] bytes) => ((LimitReader*)s.data).read(bytes),
.available_fn = fn(s) => ((LimitReader*)s.data).available(),
const StreamInterface LIMITREADER_INTERFACE = {
.read_fn = (ReadStreamFn)&LimitReader.read,
.read_byte_fn = (ReadByteStreamFn)&LimitReader.read_byte,
.available_fn = fn(s) => ((LimitReader*)s).available(),
};

View File

@@ -2,7 +2,7 @@ module std::io;
struct Scanner
{
Stream reader;
Stream* stream;
char[] buf;
usz pattern_idx;
usz read_idx;
@@ -12,11 +12,15 @@ struct Scanner
* Scanner provides a way to read delimited data (with newlines as the default).
* The supplied buffer must be at least as large as the expected data length
* including its pattern.
*
* @param [&in] stream "The stream to read data from."
* @require buffer.len > 0 "Non-empty buffer required."
* @require stream.supports_read() "The stream must support read."
*
**/
fn void Scanner.init(&self, Stream reader, char[] buffer)
fn void Scanner.init(&self, Stream* stream, char[] buffer)
{
*self = { .reader = reader, .buf = buffer };
*self = { .stream = stream, .buf = buffer };
}
/**
@@ -81,7 +85,7 @@ macro usz! Scanner.find(&self, buf, pattern) @private
macro usz! Scanner.refill(&self, buf) @private
{
usz! n = self.reader.read(buf);
usz! n = self.stream.read(buf);
if (catch err = n)
{
case IoError.EOF:

View File

@@ -4,6 +4,7 @@ import libc;
struct Socket
{
inline Stream stream;
NativeSocket sock;
Socklen_t ai_addrlen;
// TODO proper way to get the size of sockaddr_storage
@@ -24,9 +25,9 @@ macro void @loop_over_ai(AddrInfo* ai; @body(NativeSocket fd, AddrInfo* ai))
}
}
macro Socket network_socket(fd, ai)
macro Socket new_socket(fd, ai)
{
Socket sock = { .sock = fd, .ai_addrlen = ai.ai_addrlen };
Socket sock = { .stream.fns = &SOCKETSTREAM_INTERFACE, .sock = fd, .ai_addrlen = ai.ai_addrlen };
assert(sock.ai_addr_storage.len >= ai.ai_addrlen, "storage %d < addrlen %d", sock.ai_addr_storage.len, ai.ai_addrlen);
mem::copy(&sock.ai_addr_storage, (void*)ai.ai_addr, ai.ai_addrlen);
return sock;
@@ -42,15 +43,10 @@ enum SocketOption : char (CInt value)
DONTROUTE (os::SO_DONTROUTE),
}
fn Stream Socket.as_stream(&self)
{
return { .fns = &socketstream_interface, .data = self };
}
StreamInterface socketstream_interface = {
.read_fn = fn(s, char[] bytes) => ((Socket*)s.data).read(bytes) @inline,
.write_fn = fn(s, char[] bytes) => ((Socket*)s.data).write(bytes) @inline,
.close_fn = fn(s) => ((Socket*)s.data).close(),
const StreamInterface SOCKETSTREAM_INTERFACE = {
.read_fn = (ReadStreamFn)&Socket.read,
.write_fn = (WriteStreamFn)&Socket.write,
.close_fn = (CloseStreamFn)&Socket.close,
};
fn bool! Socket.get_broadcast(&self) => self.get_option(BROADCAST);

View File

@@ -14,7 +14,7 @@ fn Socket! connect_from_addrinfo(AddrInfo* addrinfo, SocketOption[] options) @pr
apply_sockoptions(sockfd, options)!;
int errcode = os::connect(sockfd, ai.ai_addr, ai.ai_addrlen);
// Keep the first successful connection.
if (!errcode) return network_socket(sockfd, ai);
if (!errcode) return new_socket(sockfd, ai);
};
return os::socket_error()?;
}
@@ -44,7 +44,7 @@ fn Socket! connect_async_from_addrinfo(AddrInfo* addrinfo, SocketOption[] option
if (!errcode || last_error_is_delayed_connect())
{
// Keep the first successful connection.
return network_socket(sockfd, ai);
return new_socket(sockfd, ai);
}
};
return os::socket_error()?;

View File

@@ -50,7 +50,7 @@ fn TcpServerSocket! listen_to(AddrInfo* ai, uint backlog, SocketOption... option
{
net::apply_sockoptions(sockfd, options)!;
bool err = os::bind(sockfd, ai_candidate.ai_addr, ai_candidate.ai_addrlen) || os::listen(sockfd, backlog);
if (!err) return (TcpServerSocket)net::network_socket(sockfd, ai_candidate);
if (!err) return (TcpServerSocket)net::new_socket(sockfd, ai_candidate);
};
return os::socket_error()?;
}

View File

@@ -351,7 +351,7 @@ fn CInt! SubProcess.join(&self) @if(env::POSIX)
fn File SubProcess.stdout(&self)
{
return file::from_libc(self.stdout_file);
return file::from_handle(self.stdout_file);
}
fn CInt! SubProcess.join(&self) @if(env::WIN32)

View File

@@ -38,7 +38,7 @@ fn void! brainf(String program)
io::putchar(memory[mem]);
io::stdout().flush();
case ',':
memory[mem] = io::stdin().getc()!!;
memory[mem] = io::stdin().read_byte()!!;
case '[':
usz indent = 1;
if (memory[mem]) continue;

View File

@@ -19,7 +19,7 @@ struct StringData @private
char[*] chars;
}
fn void Summary.print(Summary *s, File out)
fn void Summary.print(Summary *s, File* out)
{
String title = s.title ? s.title.as_str() : "missing";
out.printf("Summary({ .title = %s, .ok = %s})", title, s.ok);

View File

@@ -6,6 +6,6 @@ fn void! main()
defer f.close()!!;
while (!f.eof())
{
@pool() { io::printn(f.tgetline()); };
@pool() { io::printn(f.treadline()!); };
}
}

View File

@@ -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(String[] args)
fn void! main(String[] args)
{
// Grab a string from stdin
DString s = io::stdin().getline();
String s = io::stdin().readline()!;
// Delete it at scope end [defer]
defer s.free();
// Grab the string as a slice.
String numbers = s.as_str();
// Copy the slice, which doesn't change the underlying data.
String numbers = s;
// Track our current value
int val = 0;

View File

@@ -7,7 +7,7 @@ fn void! main()
String command = env::WIN32 ? "dir" : "ls";
SubProcess x = process::create({ command }, { .search_user_path = true })!!;
x.join()!;
Stream stream = x.stdout().as_stream();
Stream* stream = &&x.stdout();
while (try char b = stream.read_byte())
{
io::printf("%c", b);

View File

@@ -486,6 +486,8 @@ CHECK_ACCESS:
switch (decl->var.kind)
{
case VARDECL_LOCAL:
if (decl->var.is_static) return true;
FALLTHROUGH;
case VARDECL_PARAM:
break;
default:

View File

@@ -90,116 +90,110 @@ loop.body: ; preds = %loop.cond
loop.exit: ; preds = %loop.cond
%22 = call ptr @std.io.stdout()
store ptr %22, ptr %result, align 8
%23 = load ptr, ptr %result, align 8
%24 = call i64 @std.io.File.printn(ptr %retparam4, ptr %23, ptr null, i64 0)
%25 = load ptr, ptr %z, align 8
store ptr %25, ptr %.anon5, align 8
%23 = call i64 @std.io.File.printn(ptr %retparam4, ptr %22, ptr null, i64 0)
%24 = load ptr, ptr %z, align 8
store ptr %24, ptr %.anon5, align 8
store i64 0, ptr %.anon6, align 8
br label %loop.cond7
loop.cond7: ; preds = %loop.body9, %loop.exit
%26 = load i64, ptr %.anon6, align 8
%gt8 = icmp ugt i64 4, %26
%25 = load i64, ptr %.anon6, align 8
%gt8 = icmp ugt i64 4, %25
br i1 %gt8, label %loop.body9, label %loop.exit14
loop.body9: ; preds = %loop.cond7
%27 = load ptr, ptr %.anon5, align 8
%28 = load i64, ptr %.anon6, align 8
%29 = getelementptr inbounds [4 x i8], ptr %27, i64 0, i64 %28
%30 = load i8, ptr %29, align 1
store i8 %30, ptr %d10, align 1
%31 = insertvalue %any undef, ptr %d10, 0
%32 = insertvalue %any %31, i64 ptrtoint (ptr @"$ct.char" to i64), 1
%33 = getelementptr inbounds [1 x %any], ptr %varargslots12, i64 0, i64 0
store %any %32, ptr %33, align 16
%34 = call i64 @std.io.printf(ptr %retparam11, ptr @.str.2, i64 3, ptr %varargslots12, i64 1)
%35 = load i64, ptr %.anon6, align 8
%add13 = add i64 %35, 1
%26 = load ptr, ptr %.anon5, align 8
%27 = load i64, ptr %.anon6, align 8
%28 = getelementptr inbounds [4 x i8], ptr %26, i64 0, i64 %27
%29 = load i8, ptr %28, align 1
store i8 %29, ptr %d10, align 1
%30 = insertvalue %any undef, ptr %d10, 0
%31 = insertvalue %any %30, i64 ptrtoint (ptr @"$ct.char" to i64), 1
%32 = getelementptr inbounds [1 x %any], ptr %varargslots12, i64 0, i64 0
store %any %31, ptr %32, align 16
%33 = call i64 @std.io.printf(ptr %retparam11, ptr @.str.2, i64 3, ptr %varargslots12, i64 1)
%34 = load i64, ptr %.anon6, align 8
%add13 = add i64 %34, 1
store i64 %add13, ptr %.anon6, align 8
br label %loop.cond7
loop.exit14: ; preds = %loop.cond7
%36 = call ptr @std.io.stdout()
store ptr %36, ptr %result16, align 8
%37 = load ptr, ptr %result16, align 8
%38 = call i64 @std.io.File.printn(ptr %retparam15, ptr %37, ptr null, i64 0)
%39 = load i32, ptr %abc, align 4
%40 = call i32 @llvm.bswap.i32(i32 %39)
%41 = and i32 65535, %40
%trunc = trunc i32 %41 to i16
store i16 %trunc, ptr %taddr19, align 2
%42 = insertvalue %any undef, ptr %taddr19, 0
%43 = insertvalue %any %42, i64 ptrtoint (ptr @"$ct.ushort" to i64), 1
%44 = getelementptr inbounds [1 x %any], ptr %varargslots18, i64 0, i64 0
store %any %43, ptr %44, align 16
%45 = call i64 @std.io.printfn(ptr %retparam17, ptr @.str.3, i64 10, ptr %varargslots18, i64 1)
%46 = load i32, ptr %abc, align 4
%47 = call i32 @llvm.bswap.i32(i32 %46)
%48 = and i32 %47, -65536
%49 = or i32 %48, 4660
%35 = call ptr @std.io.stdout()
%36 = call i64 @std.io.File.printn(ptr %retparam15, ptr %35, ptr null, i64 0)
%37 = load i32, ptr %abc, align 4
%38 = call i32 @llvm.bswap.i32(i32 %37)
%39 = and i32 65535, %38
%trunc = trunc i32 %39 to i16
store i16 %trunc, ptr %taddr18, align 2
%40 = insertvalue %any undef, ptr %taddr18, 0
%41 = insertvalue %any %40, i64 ptrtoint (ptr @"$ct.ushort" to i64), 1
%42 = getelementptr inbounds [1 x %any], ptr %varargslots17, i64 0, i64 0
store %any %41, ptr %42, align 16
%43 = call i64 @std.io.printfn(ptr %retparam16, ptr @.str.3, i64 10, ptr %varargslots17, i64 1)
%44 = load i32, ptr %abc, align 4
%45 = call i32 @llvm.bswap.i32(i32 %44)
%46 = and i32 %45, -65536
%47 = or i32 %46, 4660
%48 = call i32 @llvm.bswap.i32(i32 %47)
store i32 %48, ptr %abc, align 4
%49 = load i32, ptr %abc, align 4
%50 = call i32 @llvm.bswap.i32(i32 %49)
store i32 %50, ptr %abc, align 4
%51 = load i32, ptr %abc, align 4
%52 = call i32 @llvm.bswap.i32(i32 %51)
%53 = and i32 %52, 65535
%54 = or i32 %53, 1450704896
%51 = and i32 %50, 65535
%52 = or i32 %51, 1450704896
%53 = call i32 @llvm.bswap.i32(i32 %52)
store i32 %53, ptr %abc, align 4
%54 = load i32, ptr %abc, align 4
%55 = call i32 @llvm.bswap.i32(i32 %54)
store i32 %55, ptr %abc, align 4
%56 = load i32, ptr %abc, align 4
%57 = call i32 @llvm.bswap.i32(i32 %56)
%58 = and i32 65535, %57
%trunc22 = trunc i32 %58 to i16
store i16 %trunc22, ptr %taddr23, align 2
%59 = insertvalue %any undef, ptr %taddr23, 0
%60 = insertvalue %any %59, i64 ptrtoint (ptr @"$ct.ushort" to i64), 1
%61 = getelementptr inbounds [1 x %any], ptr %varargslots21, i64 0, i64 0
store %any %60, ptr %61, align 16
%62 = call i64 @std.io.printfn(ptr %retparam20, ptr @.str.4, i64 12, ptr %varargslots21, i64 1)
%63 = load ptr, ptr %z, align 8
store ptr %63, ptr %.anon24, align 8
store i64 0, ptr %.anon25, align 8
br label %loop.cond26
%56 = and i32 65535, %55
%trunc21 = trunc i32 %56 to i16
store i16 %trunc21, ptr %taddr22, align 2
%57 = insertvalue %any undef, ptr %taddr22, 0
%58 = insertvalue %any %57, i64 ptrtoint (ptr @"$ct.ushort" to i64), 1
%59 = getelementptr inbounds [1 x %any], ptr %varargslots20, i64 0, i64 0
store %any %58, ptr %59, align 16
%60 = call i64 @std.io.printfn(ptr %retparam19, ptr @.str.4, i64 12, ptr %varargslots20, i64 1)
%61 = load ptr, ptr %z, align 8
store ptr %61, ptr %.anon23, align 8
store i64 0, ptr %.anon24, align 8
br label %loop.cond25
loop.cond26: ; preds = %loop.body28, %loop.exit14
%64 = load i64, ptr %.anon25, align 8
%gt27 = icmp ugt i64 4, %64
br i1 %gt27, label %loop.body28, label %loop.exit33
loop.cond25: ; preds = %loop.body27, %loop.exit14
%62 = load i64, ptr %.anon24, align 8
%gt26 = icmp ugt i64 4, %62
br i1 %gt26, label %loop.body27, label %loop.exit32
loop.body28: ; preds = %loop.cond26
%65 = load ptr, ptr %.anon24, align 8
%66 = load i64, ptr %.anon25, align 8
%67 = getelementptr inbounds [4 x i8], ptr %65, i64 0, i64 %66
%68 = load i8, ptr %67, align 1
store i8 %68, ptr %d29, align 1
%69 = insertvalue %any undef, ptr %d29, 0
%70 = insertvalue %any %69, i64 ptrtoint (ptr @"$ct.char" to i64), 1
%71 = getelementptr inbounds [1 x %any], ptr %varargslots31, i64 0, i64 0
store %any %70, ptr %71, align 16
%72 = call i64 @std.io.printf(ptr %retparam30, ptr @.str.5, i64 3, ptr %varargslots31, i64 1)
%73 = load i64, ptr %.anon25, align 8
%add32 = add i64 %73, 1
store i64 %add32, ptr %.anon25, align 8
br label %loop.cond26
loop.body27: ; preds = %loop.cond25
%63 = load ptr, ptr %.anon23, align 8
%64 = load i64, ptr %.anon24, align 8
%65 = getelementptr inbounds [4 x i8], ptr %63, i64 0, i64 %64
%66 = load i8, ptr %65, align 1
store i8 %66, ptr %d28, align 1
%67 = insertvalue %any undef, ptr %d28, 0
%68 = insertvalue %any %67, i64 ptrtoint (ptr @"$ct.char" to i64), 1
%69 = getelementptr inbounds [1 x %any], ptr %varargslots30, i64 0, i64 0
store %any %68, ptr %69, align 16
%70 = call i64 @std.io.printf(ptr %retparam29, ptr @.str.5, i64 3, ptr %varargslots30, i64 1)
%71 = load i64, ptr %.anon24, align 8
%add31 = add i64 %71, 1
store i64 %add31, ptr %.anon24, align 8
br label %loop.cond25
loop.exit33: ; preds = %loop.cond26
%74 = call ptr @std.io.stdout()
store ptr %74, ptr %result35, align 8
%75 = load ptr, ptr %result35, align 8
%76 = call i64 @std.io.File.printn(ptr %retparam34, ptr %75, ptr null, i64 0)
loop.exit32: ; preds = %loop.cond25
%72 = call ptr @std.io.stdout()
%73 = call i64 @std.io.File.printn(ptr %retparam33, ptr %72, ptr null, i64 0)
store i32 0, ptr %y, align 4
%77 = load i32, ptr %y, align 4
%74 = load i32, ptr %y, align 4
store i32 123, ptr %y, align 4
%78 = insertvalue %any undef, ptr %y, 0
%79 = insertvalue %any %78, i64 ptrtoint (ptr @"$ct.int" to i64), 1
%80 = getelementptr inbounds [2 x %any], ptr %varargslots37, i64 0, i64 0
store %any %79, ptr %80, align 16
%81 = load i32, ptr %y, align 4
store i32 %81, ptr %taddr38, align 4
%82 = insertvalue %any undef, ptr %taddr38, 0
%83 = insertvalue %any %82, i64 ptrtoint (ptr @"$ct.int" to i64), 1
%84 = getelementptr inbounds [2 x %any], ptr %varargslots37, i64 0, i64 1
store %any %83, ptr %84, align 16
%85 = call i64 @std.io.printf(ptr %retparam36, ptr @.str.6, i64 18, ptr %varargslots37, i64 2)
%75 = insertvalue %any undef, ptr %y, 0
%76 = insertvalue %any %75, i64 ptrtoint (ptr @"$ct.int" to i64), 1
%77 = getelementptr inbounds [2 x %any], ptr %varargslots35, i64 0, i64 0
store %any %76, ptr %77, align 16
%78 = load i32, ptr %y, align 4
store i32 %78, ptr %taddr36, align 4
%79 = insertvalue %any undef, ptr %taddr36, 0
%80 = insertvalue %any %79, i64 ptrtoint (ptr @"$ct.int" to i64), 1
%81 = getelementptr inbounds [2 x %any], ptr %varargslots35, i64 0, i64 1
store %any %80, ptr %81, align 16
%82 = call i64 @std.io.printf(ptr %retparam34, ptr @.str.6, i64 18, ptr %varargslots35, i64 2)
ret void
}

View File

@@ -32,19 +32,15 @@ entry:
%varargslots = alloca [1 x %any], align 16
%taddr = alloca i32, align 4
%retparam1 = alloca i64, align 8
%result = alloca %File, align 8
%retparam2 = alloca i64, align 8
%result3 = alloca %File, align 8
%retparam4 = alloca i64, align 8
%varargslots5 = alloca [1 x %any], align 16
%taddr6 = alloca i64, align 8
%retparam7 = alloca i64, align 8
%varargslots8 = alloca [1 x %any], align 16
%taddr9 = alloca i64, align 8
%retparam3 = alloca i64, align 8
%varargslots4 = alloca [1 x %any], align 16
%taddr5 = alloca i64, align 8
%retparam6 = alloca i64, align 8
%varargslots7 = alloca [1 x %any], align 16
%taddr8 = alloca i64, align 8
%retparam9 = alloca i64, align 8
%retparam10 = alloca i64, align 8
%result11 = alloca %File, align 8
%retparam12 = alloca i64, align 8
%result13 = alloca %File, align 8
store i32 %0, ptr %taddr, align 4
%1 = insertvalue %any undef, ptr %taddr, 0
%2 = insertvalue %any %1, i64 ptrtoint (ptr @"$ct.int" to i64), 1
@@ -53,44 +49,33 @@ entry:
%4 = call i64 @std.io.printfn(ptr %retparam, ptr @.str, i64 2, ptr %varargslots, i64 1)
%gt = icmp sgt i32 %0, 0
br i1 %gt, label %if.then, label %if.exit
if.then: ; preds = %entry
%sub = sub i32 %0, 1
call void @test.test(i32 %sub)
br label %if.exit
if.exit: ; preds = %if.then, %entry
%5 = call ptr @std.io.stdout()
store ptr %5, ptr %result, align 8
%6 = load ptr, ptr %result, align 8
%7 = call i64 @std.io.File.printn(ptr %retparam1, ptr %6, ptr @.str.1, i64 8)
%8 = call ptr @std.io.stdout()
store ptr %8, ptr %result3, align 8
%9 = load ptr, ptr %result3, align 8
%10 = call i64 @std.io.File.printn(ptr %retparam2, ptr %9, ptr @.str.2, i64 10)
store i64 14, ptr %taddr6, align 8
%11 = insertvalue %any undef, ptr %taddr6, 0
%12 = insertvalue %any %11, i64 ptrtoint (ptr @"$ct.long" to i64), 1
%13 = getelementptr inbounds [1 x %any], ptr %varargslots5, i64 0, i64 0
store %any %12, ptr %13, align 16
%14 = call i64 @std.io.printfn(ptr %retparam4, ptr @.str.3, i64 2, ptr %varargslots5, i64 1)
store i64 6, ptr %taddr9, align 8
%15 = insertvalue %any undef, ptr %taddr9, 0
%16 = insertvalue %any %15, i64 ptrtoint (ptr @"$ct.long" to i64), 1
%17 = getelementptr inbounds [1 x %any], ptr %varargslots8, i64 0, i64 0
store %any %16, ptr %17, align 16
%18 = call i64 @std.io.printfn(ptr %retparam7, ptr @.str.4, i64 2, ptr %varargslots8, i64 1)
%6 = call i64 @std.io.File.printn(ptr %retparam1, ptr %5, ptr @.str.1, i64 8)
%7 = call ptr @std.io.stdout()
%8 = call i64 @std.io.File.printn(ptr %retparam2, ptr %7, ptr @.str.2, i64 10)
store i64 14, ptr %taddr5, align 8
%9 = insertvalue %any undef, ptr %taddr5, 0
%10 = insertvalue %any %9, i64 ptrtoint (ptr @"$ct.long" to i64), 1
%11 = getelementptr inbounds [1 x %any], ptr %varargslots4, i64 0, i64 0
store %any %10, ptr %11, align 16
%12 = call i64 @std.io.printfn(ptr %retparam3, ptr @.str.3, i64 2, ptr %varargslots4, i64 1)
store i64 6, ptr %taddr8, align 8
%13 = insertvalue %any undef, ptr %taddr8, 0
%14 = insertvalue %any %13, i64 ptrtoint (ptr @"$ct.long" to i64), 1
%15 = getelementptr inbounds [1 x %any], ptr %varargslots7, i64 0, i64 0
store %any %14, ptr %15, align 16
%16 = call i64 @std.io.printfn(ptr %retparam6, ptr @.str.4, i64 2, ptr %varargslots7, i64 1)
%17 = call ptr @std.io.stdout()
%18 = call i64 @std.io.File.printn(ptr %retparam9, ptr %17, ptr @.str.5, i64 23)
%19 = call ptr @std.io.stdout()
store ptr %19, ptr %result11, align 8
%20 = load ptr, ptr %result11, align 8
%21 = call i64 @std.io.File.printn(ptr %retparam10, ptr %20, ptr @.str.5, i64 23)
%22 = call ptr @std.io.stdout()
store ptr %22, ptr %result13, align 8
%23 = load ptr, ptr %result13, align 8
%24 = call i64 @std.io.File.printn(ptr %retparam12, ptr %23, ptr @.str.6, i64 4)
%20 = call i64 @std.io.File.printn(ptr %retparam10, ptr %19, ptr @.str.6, i64 4)
ret void
}
; Function Attrs: nounwind
define void @test.main() #0 {
entry:

View File

@@ -113,232 +113,209 @@ entry:
store i64 %5, ptr %ptroffset1, align 8
ret void
}
; Function Attrs: nounwind
define void @test.test(i32 %0) #0 {
entry:
%retparam = alloca i64, align 8
%result = alloca %File, align 8
%retparam1 = alloca i64, align 8
%result2 = alloca %File, align 8
%retparam2 = alloca i64, align 8
%retparam3 = alloca i64, align 8
%result4 = alloca %File, align 8
%retparam4 = alloca i64, align 8
%retparam5 = alloca i64, align 8
%result6 = alloca %File, align 8
%retparam6 = alloca i64, align 8
%retparam7 = alloca i64, align 8
%result8 = alloca %File, align 8
%retparam9 = alloca i64, align 8
%result10 = alloca %File, align 8
%retparam11 = alloca i64, align 8
%result12 = alloca %File, align 8
%retparam13 = alloca i64, align 8
%varargslots = alloca [1 x %any], align 16
%taddr = alloca %"char[]", align 8
%retparam14 = alloca i64, align 8
%varargslots15 = alloca [2 x %any], align 16
%taddr16 = alloca %"char[]", align 8
%taddr17 = alloca %"char[]", align 8
%retparam18 = alloca i64, align 8
%varargslots19 = alloca [2 x %any], align 16
%taddr20 = alloca %"char[]", align 8
%taddr21 = alloca %"char[]", align 8
%retparam22 = alloca i64, align 8
%varargslots23 = alloca [2 x %any], align 16
%taddr24 = alloca %"char[]", align 8
%taddr25 = alloca %"char[]", align 8
%retparam26 = alloca i64, align 8
%varargslots27 = alloca [2 x %any], align 16
%taddr28 = alloca %"char[]", align 8
%retparam8 = alloca i64, align 8
%varargslots9 = alloca [2 x %any], align 16
%taddr10 = alloca %"char[]", align 8
%taddr11 = alloca %"char[]", align 8
%retparam12 = alloca i64, align 8
%varargslots13 = alloca [2 x %any], align 16
%taddr14 = alloca %"char[]", align 8
%taddr15 = alloca %"char[]", align 8
%retparam16 = alloca i64, align 8
%varargslots17 = alloca [2 x %any], align 16
%taddr18 = alloca %"char[]", align 8
%taddr19 = alloca %"char[]", align 8
%retparam20 = alloca i64, align 8
%varargslots21 = alloca [2 x %any], align 16
%taddr22 = alloca %"char[]", align 8
%taddr23 = alloca %"char[]", align 8
%retparam24 = alloca i64, align 8
%varargslots25 = alloca [1 x %any], align 16
%taddr26 = alloca %"char[]", align 8
%retparam27 = alloca i64, align 8
%varargslots28 = alloca [2 x %any], align 16
%taddr29 = alloca %"char[]", align 8
%retparam30 = alloca i64, align 8
%varargslots31 = alloca [1 x %any], align 16
%taddr32 = alloca %"char[]", align 8
%retparam33 = alloca i64, align 8
%varargslots34 = alloca [2 x %any], align 16
%taddr35 = alloca %"char[]", align 8
%taddr36 = alloca %"char[]", align 8
%retparam37 = alloca i64, align 8
%varargslots38 = alloca [2 x %any], align 16
%taddr39 = alloca %"char[]", align 8
%taddr40 = alloca %"char[]", align 8
%retparam41 = alloca i64, align 8
%varargslots42 = alloca [2 x %any], align 16
%taddr43 = alloca %"char[]", align 8
%taddr44 = alloca %"char[]", align 8
%retparam45 = alloca i64, align 8
%varargslots46 = alloca [2 x %any], align 16
%taddr47 = alloca %"char[]", align 8
%taddr30 = alloca %"char[]", align 8
%retparam31 = alloca i64, align 8
%varargslots32 = alloca [2 x %any], align 16
%taddr33 = alloca %"char[]", align 8
%taddr34 = alloca %"char[]", align 8
%retparam35 = alloca i64, align 8
%varargslots36 = alloca [2 x %any], align 16
%taddr37 = alloca %"char[]", align 8
%taddr38 = alloca %"char[]", align 8
%retparam39 = alloca i64, align 8
%varargslots40 = alloca [2 x %any], align 16
%taddr41 = alloca %"char[]", align 8
%taddr42 = alloca %"char[]", align 8
%retparam43 = alloca i64, align 8
%varargslots44 = alloca [1 x %any], align 16
%taddr45 = alloca %"char[]", align 8
%retparam46 = alloca i64, align 8
%varargslots47 = alloca [2 x %any], align 16
%taddr48 = alloca %"char[]", align 8
%retparam49 = alloca i64, align 8
%varargslots50 = alloca [1 x %any], align 16
%taddr51 = alloca %"char[]", align 8
%retparam52 = alloca i64, align 8
%varargslots53 = alloca [2 x %any], align 16
%taddr54 = alloca %"char[]", align 8
%taddr55 = alloca %"char[]", align 8
%retparam56 = alloca i64, align 8
%varargslots57 = alloca [2 x %any], align 16
%taddr58 = alloca %"char[]", align 8
%taddr59 = alloca %"char[]", align 8
%taddr49 = alloca %"char[]", align 8
%retparam50 = alloca i64, align 8
%varargslots51 = alloca [2 x %any], align 16
%taddr52 = alloca %"char[]", align 8
%taddr53 = alloca %"char[]", align 8
%1 = call ptr @std.io.stdout()
store ptr %1, ptr %result, align 8
%2 = load ptr, ptr %result, align 8
%3 = call i64 @std.io.File.printn(ptr %retparam, ptr %2, ptr @.str, i64 3)
%4 = call ptr @std.io.stdout()
store ptr %4, ptr %result2, align 8
%5 = load ptr, ptr %result2, align 8
%6 = call i64 @std.io.File.printn(ptr %retparam1, ptr %5, ptr @.str.10, i64 3)
%2 = call i64 @std.io.File.printn(ptr %retparam, ptr %1, ptr @.str, i64 3)
%3 = call ptr @std.io.stdout()
%4 = call i64 @std.io.File.printn(ptr %retparam1, ptr %3, ptr @.str.10, i64 3)
%5 = call ptr @std.io.stdout()
%6 = call i64 @std.io.File.printn(ptr %retparam2, ptr %5, ptr @.str.11, i64 6)
%7 = call ptr @std.io.stdout()
store ptr %7, ptr %result4, align 8
%8 = load ptr, ptr %result4, align 8
%9 = call i64 @std.io.File.printn(ptr %retparam3, ptr %8, ptr @.str.11, i64 6)
%10 = call ptr @std.io.stdout()
store ptr %10, ptr %result6, align 8
%11 = load ptr, ptr %result6, align 8
%12 = call i64 @std.io.File.printn(ptr %retparam5, ptr %11, ptr @.str.12, i64 6)
%8 = call i64 @std.io.File.printn(ptr %retparam3, ptr %7, ptr @.str.12, i64 6)
%9 = call ptr @std.io.stdout()
%10 = call i64 @std.io.File.printn(ptr %retparam4, ptr %9, ptr @.str.13, i64 5)
%11 = call ptr @std.io.stdout()
%12 = call i64 @std.io.File.printn(ptr %retparam5, ptr %11, ptr @.str.14, i64 4)
%13 = call ptr @std.io.stdout()
store ptr %13, ptr %result8, align 8
%14 = load ptr, ptr %result8, align 8
%15 = call i64 @std.io.File.printn(ptr %retparam7, ptr %14, ptr @.str.13, i64 5)
%16 = call ptr @std.io.stdout()
store ptr %16, ptr %result10, align 8
%17 = load ptr, ptr %result10, align 8
%18 = call i64 @std.io.File.printn(ptr %retparam9, ptr %17, ptr @.str.14, i64 4)
%19 = call ptr @std.io.stdout()
store ptr %19, ptr %result12, align 8
%20 = load ptr, ptr %result12, align 8
%21 = call i64 @std.io.File.printn(ptr %retparam11, ptr %20, ptr @.str.15, i64 3)
%14 = call i64 @std.io.File.printn(ptr %retparam6, ptr %13, ptr @.str.15, i64 3)
store %"char[]" { ptr @.str.17, i64 3 }, ptr %taddr, align 8
%22 = insertvalue %any undef, ptr %taddr, 0
%15 = insertvalue %any undef, ptr %taddr, 0
%16 = insertvalue %any %15, i64 ptrtoint (ptr @"$ct.String" to i64), 1
%17 = getelementptr inbounds [1 x %any], ptr %varargslots, i64 0, i64 0
store %any %16, ptr %17, align 16
%18 = call i64 @std.io.printfn(ptr %retparam7, ptr @.str.16, i64 8, ptr %varargslots, i64 1)
store %"char[]" { ptr @.str.19, i64 1 }, ptr %taddr10, align 8
%19 = insertvalue %any undef, ptr %taddr10, 0
%20 = insertvalue %any %19, i64 ptrtoint (ptr @"$ct.String" to i64), 1
%21 = getelementptr inbounds [2 x %any], ptr %varargslots9, i64 0, i64 0
store %any %20, ptr %21, align 16
store %"char[]" { ptr @.str.20, i64 3 }, ptr %taddr11, align 8
%22 = insertvalue %any undef, ptr %taddr11, 0
%23 = insertvalue %any %22, i64 ptrtoint (ptr @"$ct.String" to i64), 1
%24 = getelementptr inbounds [1 x %any], ptr %varargslots, i64 0, i64 0
%24 = getelementptr inbounds [2 x %any], ptr %varargslots9, i64 0, i64 1
store %any %23, ptr %24, align 16
%25 = call i64 @std.io.printfn(ptr %retparam13, ptr @.str.16, i64 8, ptr %varargslots, i64 1)
store %"char[]" { ptr @.str.19, i64 1 }, ptr %taddr16, align 8
%26 = insertvalue %any undef, ptr %taddr16, 0
%25 = call i64 @std.io.printfn(ptr %retparam8, ptr @.str.18, i64 6, ptr %varargslots9, i64 2)
store %"char[]" { ptr @.str.22, i64 4 }, ptr %taddr14, align 8
%26 = insertvalue %any undef, ptr %taddr14, 0
%27 = insertvalue %any %26, i64 ptrtoint (ptr @"$ct.String" to i64), 1
%28 = getelementptr inbounds [2 x %any], ptr %varargslots15, i64 0, i64 0
%28 = getelementptr inbounds [2 x %any], ptr %varargslots13, i64 0, i64 0
store %any %27, ptr %28, align 16
store %"char[]" { ptr @.str.20, i64 3 }, ptr %taddr17, align 8
%29 = insertvalue %any undef, ptr %taddr17, 0
store %"char[]" { ptr @.str.23, i64 4 }, ptr %taddr15, align 8
%29 = insertvalue %any undef, ptr %taddr15, 0
%30 = insertvalue %any %29, i64 ptrtoint (ptr @"$ct.String" to i64), 1
%31 = getelementptr inbounds [2 x %any], ptr %varargslots15, i64 0, i64 1
%31 = getelementptr inbounds [2 x %any], ptr %varargslots13, i64 0, i64 1
store %any %30, ptr %31, align 16
%32 = call i64 @std.io.printfn(ptr %retparam14, ptr @.str.18, i64 6, ptr %varargslots15, i64 2)
store %"char[]" { ptr @.str.22, i64 4 }, ptr %taddr20, align 8
%33 = insertvalue %any undef, ptr %taddr20, 0
%32 = call i64 @std.io.printfn(ptr %retparam12, ptr @.str.21, i64 6, ptr %varargslots13, i64 2)
store %"char[]" zeroinitializer, ptr %taddr18, align 8
%33 = insertvalue %any undef, ptr %taddr18, 0
%34 = insertvalue %any %33, i64 ptrtoint (ptr @"$ct.String" to i64), 1
%35 = getelementptr inbounds [2 x %any], ptr %varargslots19, i64 0, i64 0
%35 = getelementptr inbounds [2 x %any], ptr %varargslots17, i64 0, i64 0
store %any %34, ptr %35, align 16
store %"char[]" { ptr @.str.23, i64 4 }, ptr %taddr21, align 8
%36 = insertvalue %any undef, ptr %taddr21, 0
store %"char[]" { ptr @.str.25, i64 5 }, ptr %taddr19, align 8
%36 = insertvalue %any undef, ptr %taddr19, 0
%37 = insertvalue %any %36, i64 ptrtoint (ptr @"$ct.String" to i64), 1
%38 = getelementptr inbounds [2 x %any], ptr %varargslots19, i64 0, i64 1
%38 = getelementptr inbounds [2 x %any], ptr %varargslots17, i64 0, i64 1
store %any %37, ptr %38, align 16
%39 = call i64 @std.io.printfn(ptr %retparam18, ptr @.str.21, i64 6, ptr %varargslots19, i64 2)
store %"char[]" zeroinitializer, ptr %taddr24, align 8
%40 = insertvalue %any undef, ptr %taddr24, 0
%39 = call i64 @std.io.printfn(ptr %retparam16, ptr @.str.24, i64 6, ptr %varargslots17, i64 2)
store %"char[]" { ptr @.str.27, i64 1 }, ptr %taddr22, align 8
%40 = insertvalue %any undef, ptr %taddr22, 0
%41 = insertvalue %any %40, i64 ptrtoint (ptr @"$ct.String" to i64), 1
%42 = getelementptr inbounds [2 x %any], ptr %varargslots23, i64 0, i64 0
%42 = getelementptr inbounds [2 x %any], ptr %varargslots21, i64 0, i64 0
store %any %41, ptr %42, align 16
store %"char[]" { ptr @.str.25, i64 5 }, ptr %taddr25, align 8
%43 = insertvalue %any undef, ptr %taddr25, 0
store %"char[]" { ptr @.str.28, i64 6 }, ptr %taddr23, align 8
%43 = insertvalue %any undef, ptr %taddr23, 0
%44 = insertvalue %any %43, i64 ptrtoint (ptr @"$ct.String" to i64), 1
%45 = getelementptr inbounds [2 x %any], ptr %varargslots23, i64 0, i64 1
%45 = getelementptr inbounds [2 x %any], ptr %varargslots21, i64 0, i64 1
store %any %44, ptr %45, align 16
%46 = call i64 @std.io.printfn(ptr %retparam22, ptr @.str.24, i64 6, ptr %varargslots23, i64 2)
store %"char[]" { ptr @.str.27, i64 1 }, ptr %taddr28, align 8
%47 = insertvalue %any undef, ptr %taddr28, 0
%46 = call i64 @std.io.printfn(ptr %retparam20, ptr @.str.26, i64 6, ptr %varargslots21, i64 2)
store %"char[]" { ptr @.str.30, i64 3 }, ptr %taddr26, align 8
%47 = insertvalue %any undef, ptr %taddr26, 0
%48 = insertvalue %any %47, i64 ptrtoint (ptr @"$ct.String" to i64), 1
%49 = getelementptr inbounds [2 x %any], ptr %varargslots27, i64 0, i64 0
%49 = getelementptr inbounds [1 x %any], ptr %varargslots25, i64 0, i64 0
store %any %48, ptr %49, align 16
store %"char[]" { ptr @.str.28, i64 6 }, ptr %taddr29, align 8
%50 = insertvalue %any undef, ptr %taddr29, 0
%51 = insertvalue %any %50, i64 ptrtoint (ptr @"$ct.String" to i64), 1
%52 = getelementptr inbounds [2 x %any], ptr %varargslots27, i64 0, i64 1
store %any %51, ptr %52, align 16
%53 = call i64 @std.io.printfn(ptr %retparam26, ptr @.str.26, i64 6, ptr %varargslots27, i64 2)
store %"char[]" { ptr @.str.30, i64 3 }, ptr %taddr32, align 8
%54 = insertvalue %any undef, ptr %taddr32, 0
%50 = call i64 @std.io.printfn(ptr %retparam24, ptr @.str.29, i64 8, ptr %varargslots25, i64 1)
store %"char[]" { ptr @.str.32, i64 1 }, ptr %taddr29, align 8
%51 = insertvalue %any undef, ptr %taddr29, 0
%52 = insertvalue %any %51, i64 ptrtoint (ptr @"$ct.String" to i64), 1
%53 = getelementptr inbounds [2 x %any], ptr %varargslots28, i64 0, i64 0
store %any %52, ptr %53, align 16
store %"char[]" { ptr @.str.33, i64 4 }, ptr %taddr30, align 8
%54 = insertvalue %any undef, ptr %taddr30, 0
%55 = insertvalue %any %54, i64 ptrtoint (ptr @"$ct.String" to i64), 1
%56 = getelementptr inbounds [1 x %any], ptr %varargslots31, i64 0, i64 0
%56 = getelementptr inbounds [2 x %any], ptr %varargslots28, i64 0, i64 1
store %any %55, ptr %56, align 16
%57 = call i64 @std.io.printfn(ptr %retparam30, ptr @.str.29, i64 8, ptr %varargslots31, i64 1)
store %"char[]" { ptr @.str.32, i64 1 }, ptr %taddr35, align 8
%58 = insertvalue %any undef, ptr %taddr35, 0
%57 = call i64 @std.io.printfn(ptr %retparam27, ptr @.str.31, i64 6, ptr %varargslots28, i64 2)
store %"char[]" { ptr @.str.35, i64 1 }, ptr %taddr33, align 8
%58 = insertvalue %any undef, ptr %taddr33, 0
%59 = insertvalue %any %58, i64 ptrtoint (ptr @"$ct.String" to i64), 1
%60 = getelementptr inbounds [2 x %any], ptr %varargslots34, i64 0, i64 0
%60 = getelementptr inbounds [2 x %any], ptr %varargslots32, i64 0, i64 0
store %any %59, ptr %60, align 16
store %"char[]" { ptr @.str.33, i64 4 }, ptr %taddr36, align 8
%61 = insertvalue %any undef, ptr %taddr36, 0
store %"char[]" { ptr @.str.36, i64 5 }, ptr %taddr34, align 8
%61 = insertvalue %any undef, ptr %taddr34, 0
%62 = insertvalue %any %61, i64 ptrtoint (ptr @"$ct.String" to i64), 1
%63 = getelementptr inbounds [2 x %any], ptr %varargslots34, i64 0, i64 1
%63 = getelementptr inbounds [2 x %any], ptr %varargslots32, i64 0, i64 1
store %any %62, ptr %63, align 16
%64 = call i64 @std.io.printfn(ptr %retparam33, ptr @.str.31, i64 6, ptr %varargslots34, i64 2)
store %"char[]" { ptr @.str.35, i64 1 }, ptr %taddr39, align 8
%65 = insertvalue %any undef, ptr %taddr39, 0
%64 = call i64 @std.io.printfn(ptr %retparam31, ptr @.str.34, i64 6, ptr %varargslots32, i64 2)
store %"char[]" zeroinitializer, ptr %taddr37, align 8
%65 = insertvalue %any undef, ptr %taddr37, 0
%66 = insertvalue %any %65, i64 ptrtoint (ptr @"$ct.String" to i64), 1
%67 = getelementptr inbounds [2 x %any], ptr %varargslots38, i64 0, i64 0
%67 = getelementptr inbounds [2 x %any], ptr %varargslots36, i64 0, i64 0
store %any %66, ptr %67, align 16
store %"char[]" { ptr @.str.36, i64 5 }, ptr %taddr40, align 8
%68 = insertvalue %any undef, ptr %taddr40, 0
store %"char[]" { ptr @.str.38, i64 5 }, ptr %taddr38, align 8
%68 = insertvalue %any undef, ptr %taddr38, 0
%69 = insertvalue %any %68, i64 ptrtoint (ptr @"$ct.String" to i64), 1
%70 = getelementptr inbounds [2 x %any], ptr %varargslots38, i64 0, i64 1
%70 = getelementptr inbounds [2 x %any], ptr %varargslots36, i64 0, i64 1
store %any %69, ptr %70, align 16
%71 = call i64 @std.io.printfn(ptr %retparam37, ptr @.str.34, i64 6, ptr %varargslots38, i64 2)
store %"char[]" zeroinitializer, ptr %taddr43, align 8
%72 = insertvalue %any undef, ptr %taddr43, 0
%71 = call i64 @std.io.printfn(ptr %retparam35, ptr @.str.37, i64 6, ptr %varargslots36, i64 2)
store %"char[]" { ptr @.str.40, i64 3 }, ptr %taddr41, align 8
%72 = insertvalue %any undef, ptr %taddr41, 0
%73 = insertvalue %any %72, i64 ptrtoint (ptr @"$ct.String" to i64), 1
%74 = getelementptr inbounds [2 x %any], ptr %varargslots42, i64 0, i64 0
%74 = getelementptr inbounds [2 x %any], ptr %varargslots40, i64 0, i64 0
store %any %73, ptr %74, align 16
store %"char[]" { ptr @.str.38, i64 5 }, ptr %taddr44, align 8
%75 = insertvalue %any undef, ptr %taddr44, 0
store %"char[]" { ptr @.str.41, i64 3 }, ptr %taddr42, align 8
%75 = insertvalue %any undef, ptr %taddr42, 0
%76 = insertvalue %any %75, i64 ptrtoint (ptr @"$ct.String" to i64), 1
%77 = getelementptr inbounds [2 x %any], ptr %varargslots42, i64 0, i64 1
%77 = getelementptr inbounds [2 x %any], ptr %varargslots40, i64 0, i64 1
store %any %76, ptr %77, align 16
%78 = call i64 @std.io.printfn(ptr %retparam41, ptr @.str.37, i64 6, ptr %varargslots42, i64 2)
store %"char[]" { ptr @.str.40, i64 3 }, ptr %taddr47, align 8
%79 = insertvalue %any undef, ptr %taddr47, 0
%78 = call i64 @std.io.printfn(ptr %retparam39, ptr @.str.39, i64 6, ptr %varargslots40, i64 2)
store %"char[]" { ptr @.str.43, i64 4 }, ptr %taddr45, align 8
%79 = insertvalue %any undef, ptr %taddr45, 0
%80 = insertvalue %any %79, i64 ptrtoint (ptr @"$ct.String" to i64), 1
%81 = getelementptr inbounds [2 x %any], ptr %varargslots46, i64 0, i64 0
%81 = getelementptr inbounds [1 x %any], ptr %varargslots44, i64 0, i64 0
store %any %80, ptr %81, align 16
store %"char[]" { ptr @.str.41, i64 3 }, ptr %taddr48, align 8
%82 = insertvalue %any undef, ptr %taddr48, 0
%83 = insertvalue %any %82, i64 ptrtoint (ptr @"$ct.String" to i64), 1
%84 = getelementptr inbounds [2 x %any], ptr %varargslots46, i64 0, i64 1
store %any %83, ptr %84, align 16
%85 = call i64 @std.io.printfn(ptr %retparam45, ptr @.str.39, i64 6, ptr %varargslots46, i64 2)
store %"char[]" { ptr @.str.43, i64 4 }, ptr %taddr51, align 8
%86 = insertvalue %any undef, ptr %taddr51, 0
%82 = call i64 @std.io.printfn(ptr %retparam43, ptr @.str.42, i64 8, ptr %varargslots44, i64 1)
store %"char[]" { ptr @.str.45, i64 1 }, ptr %taddr48, align 8
%83 = insertvalue %any undef, ptr %taddr48, 0
%84 = insertvalue %any %83, i64 ptrtoint (ptr @"$ct.String" to i64), 1
%85 = getelementptr inbounds [2 x %any], ptr %varargslots47, i64 0, i64 0
store %any %84, ptr %85, align 16
store %"char[]" { ptr @.str.46, i64 3 }, ptr %taddr49, align 8
%86 = insertvalue %any undef, ptr %taddr49, 0
%87 = insertvalue %any %86, i64 ptrtoint (ptr @"$ct.String" to i64), 1
%88 = getelementptr inbounds [1 x %any], ptr %varargslots50, i64 0, i64 0
%88 = getelementptr inbounds [2 x %any], ptr %varargslots47, i64 0, i64 1
store %any %87, ptr %88, align 16
%89 = call i64 @std.io.printfn(ptr %retparam49, ptr @.str.42, i64 8, ptr %varargslots50, i64 1)
store %"char[]" { ptr @.str.45, i64 1 }, ptr %taddr54, align 8
%90 = insertvalue %any undef, ptr %taddr54, 0
%89 = call i64 @std.io.printfn(ptr %retparam46, ptr @.str.44, i64 6, ptr %varargslots47, i64 2)
store %"char[]" { ptr @.str.48, i64 1 }, ptr %taddr52, align 8
%90 = insertvalue %any undef, ptr %taddr52, 0
%91 = insertvalue %any %90, i64 ptrtoint (ptr @"$ct.String" to i64), 1
%92 = getelementptr inbounds [2 x %any], ptr %varargslots53, i64 0, i64 0
%92 = getelementptr inbounds [2 x %any], ptr %varargslots51, i64 0, i64 0
store %any %91, ptr %92, align 16
store %"char[]" { ptr @.str.46, i64 3 }, ptr %taddr55, align 8
%93 = insertvalue %any undef, ptr %taddr55, 0
store %"char[]" { ptr @.str.49, i64 5 }, ptr %taddr53, align 8
%93 = insertvalue %any undef, ptr %taddr53, 0
%94 = insertvalue %any %93, i64 ptrtoint (ptr @"$ct.String" to i64), 1
%95 = getelementptr inbounds [2 x %any], ptr %varargslots53, i64 0, i64 1
%95 = getelementptr inbounds [2 x %any], ptr %varargslots51, i64 0, i64 1
store %any %94, ptr %95, align 16
%96 = call i64 @std.io.printfn(ptr %retparam52, ptr @.str.44, i64 6, ptr %varargslots53, i64 2)
store %"char[]" { ptr @.str.48, i64 1 }, ptr %taddr58, align 8
%97 = insertvalue %any undef, ptr %taddr58, 0
%98 = insertvalue %any %97, i64 ptrtoint (ptr @"$ct.String" to i64), 1
%99 = getelementptr inbounds [2 x %any], ptr %varargslots57, i64 0, i64 0
store %any %98, ptr %99, align 16
store %"char[]" { ptr @.str.49, i64 5 }, ptr %taddr59, align 8
%100 = insertvalue %any undef, ptr %taddr59, 0
%101 = insertvalue %any %100, i64 ptrtoint (ptr @"$ct.String" to i64), 1
%102 = getelementptr inbounds [2 x %any], ptr %varargslots57, i64 0, i64 1
store %any %101, ptr %102, align 16
%103 = call i64 @std.io.printfn(ptr %retparam56, ptr @.str.47, i64 6, ptr %varargslots57, i64 2)
%96 = call i64 @std.io.printfn(ptr %retparam50, ptr @.str.47, i64 6, ptr %varargslots51, i64 2)
ret void
}
; Function Attrs: nounwind
define void @test.main() #0 {
entry:

View File

@@ -75,11 +75,8 @@ fn void main()
define void @foo.Foo.hello(ptr %0) #0 {
entry:
%retparam = alloca i64, align 8
%result = alloca %File, align 8
%1 = call ptr @std.io.stdout()
store ptr %1, ptr %result, align 8
%2 = load ptr, ptr %result, align 8
%3 = call i64 @std.io.File.printn(ptr %retparam, ptr %2, ptr @.str.12, i64 14)
%2 = call i64 @std.io.File.printn(ptr %retparam, ptr %1, ptr @.str.12, i64 14)
ret void
}
@@ -87,11 +84,8 @@ entry:
define void @foo.Bar.hello(ptr %0) #0 {
entry:
%retparam = alloca i64, align 8
%result = alloca %File, align 8
%1 = call ptr @std.io.stdout()
store ptr %1, ptr %result, align 8
%2 = load ptr, ptr %result, align 8
%3 = call i64 @std.io.File.printn(ptr %retparam, ptr %2, ptr @.str.13, i64 14)
%2 = call i64 @std.io.File.printn(ptr %retparam, ptr %1, ptr @.str.13, i64 14)
ret void
}
@@ -99,11 +93,8 @@ entry:
define void @foo.MyEnum.hello(ptr %0) #0 {
entry:
%retparam = alloca i64, align 8
%result = alloca %File, align 8
%1 = call ptr @std.io.stdout()
store ptr %1, ptr %result, align 8
%2 = load ptr, ptr %result, align 8
%3 = call i64 @std.io.File.printn(ptr %retparam, ptr %2, ptr @.str.14, i64 17)
%2 = call i64 @std.io.File.printn(ptr %retparam, ptr %1, ptr @.str.14, i64 17)
ret void
}

View File

@@ -55,7 +55,6 @@ entry:
%temp_err = alloca i64, align 8
%retparam27 = alloca i32, align 4
%retparam38 = alloca i64, align 8
%result = alloca %File, align 8
%err42 = alloca i64, align 8
%retparam44 = alloca i32, align 4
%retparam55 = alloca i64, align 8
@@ -182,35 +181,33 @@ end_block35: ; preds = %after_check34, %ass
if.then37: ; preds = %end_block35
%23 = call ptr @std.io.stdout()
store ptr %23, ptr %result, align 8
%24 = load ptr, ptr %result, align 8
%25 = call i64 @std.io.File.printn(ptr %retparam38, ptr %24, ptr @.str.5, i64 4)
%24 = call i64 @std.io.File.printn(ptr %retparam38, ptr %23, ptr @.str.5, i64 4)
br label %if.exit41
if.exit41: ; preds = %if.then37, %end_block35
br label %testblock43
testblock43: ; preds = %if.exit41
%26 = call i64 @demo1.hello(ptr %retparam44, i32 0)
%not_err45 = icmp eq i64 %26, 0
%27 = call i1 @llvm.expect.i1(i1 %not_err45, i1 true)
br i1 %27, label %after_check47, label %assign_optional46
%25 = call i64 @demo1.hello(ptr %retparam44, i32 0)
%not_err45 = icmp eq i64 %25, 0
%26 = call i1 @llvm.expect.i1(i1 %not_err45, i1 true)
br i1 %26, label %after_check47, label %assign_optional46
assign_optional46: ; preds = %testblock43
store i64 %26, ptr %err42, align 8
store i64 %25, ptr %err42, align 8
br label %end_block52
after_check47: ; preds = %testblock43
br label %testblock48
testblock48: ; preds = %after_check47
%28 = call i64 @demo1.bye()
%not_err49 = icmp eq i64 %28, 0
%29 = call i1 @llvm.expect.i1(i1 %not_err49, i1 true)
br i1 %29, label %after_check51, label %assign_optional50
%27 = call i64 @demo1.bye()
%not_err49 = icmp eq i64 %27, 0
%28 = call i1 @llvm.expect.i1(i1 %not_err49, i1 true)
br i1 %28, label %after_check51, label %assign_optional50
assign_optional50: ; preds = %testblock48
store i64 %28, ptr %err42, align 8
store i64 %27, ptr %err42, align 8
br label %end_block52
after_check51: ; preds = %testblock48
@@ -218,16 +215,16 @@ after_check51: ; preds = %testblock48
br label %end_block52
end_block52: ; preds = %after_check51, %assign_optional50, %assign_optional46
%30 = load i64, ptr %err42, align 8
%neq53 = icmp ne i64 %30, 0
%29 = load i64, ptr %err42, align 8
%neq53 = icmp ne i64 %29, 0
br i1 %neq53, label %if.then54, label %if.exit59
if.then54: ; preds = %end_block52
%31 = insertvalue %any undef, ptr %err42, 0
%32 = insertvalue %any %31, i64 ptrtoint (ptr @"$ct.anyfault" to i64), 1
%33 = getelementptr inbounds [1 x %any], ptr %varargslots56, i64 0, i64 0
store %any %32, ptr %33, align 16
%34 = call i64 @std.io.printfn(ptr %retparam55, ptr @.str.6, i64 8, ptr %varargslots56, i64 1)
%30 = insertvalue %any undef, ptr %err42, 0
%31 = insertvalue %any %30, i64 ptrtoint (ptr @"$ct.anyfault" to i64), 1
%32 = getelementptr inbounds [1 x %any], ptr %varargslots56, i64 0, i64 0
store %any %31, ptr %32, align 16
%33 = call i64 @std.io.printfn(ptr %retparam55, ptr @.str.6, i64 8, ptr %varargslots56, i64 1)
br label %if.exit59
if.exit59: ; preds = %if.then54, %end_block52

View File

@@ -47,15 +47,11 @@ entry:
%error_var = alloca i64, align 8
%blockret = alloca i32, align 4
%retparam1 = alloca i64, align 8
%result = alloca %File, align 8
%retparam2 = alloca i64, align 8
%result3 = alloca %File, align 8
%error_var4 = alloca i64, align 8
%blockret5 = alloca i32, align 4
%retparam9 = alloca i64, align 8
%result10 = alloca %File, align 8
%retparam12 = alloca i64, align 8
%result13 = alloca %File, align 8
%error_var3 = alloca i64, align 8
%blockret4 = alloca i32, align 4
%retparam8 = alloca i64, align 8
%retparam10 = alloca i64, align 8
store i32 %0, ptr %taddr, align 4
%1 = insertvalue %any undef, ptr %taddr, 0
%2 = insertvalue %any %1, i64 ptrtoint (ptr @"$ct.int" to i64), 1
@@ -82,32 +78,26 @@ or.phi: ; preds = %entry
if.then: ; preds = %or.phi
%6 = call ptr @std.io.stdout()
store ptr %6, ptr %result, align 8
%7 = load ptr, ptr %result, align 8
%8 = call i64 @std.io.File.printn(ptr %retparam1, ptr %7, ptr @.str.2, i64 3)
%7 = call i64 @std.io.File.printn(ptr %retparam1, ptr %6, ptr @.str.2, i64 3)
br label %if.exit
if.exit: ; preds = %if.then
%9 = call ptr @std.io.stdout()
store ptr %9, ptr %result3, align 8
%10 = load ptr, ptr %result3, align 8
%11 = call i64 @std.io.File.printn(ptr %retparam2, ptr %10, ptr @.str.3, i64 9)
store i64 ptrtoint (ptr @"foo.Foo$ABC" to i64), ptr %error_var4, align 8
br label %opt_block_cleanup6
%8 = call ptr @std.io.stdout()
%9 = call i64 @std.io.File.printn(ptr %retparam2, ptr %8, ptr @.str.3, i64 9)
store i64 ptrtoint (ptr @"foo.Foo$ABC" to i64), ptr %error_var3, align 8
br label %opt_block_cleanup5
opt_block_cleanup6: ; preds = %if.exit
opt_block_cleanup5: ; preds = %if.exit
call void @foo.blurb()
br label %guard_block7
br label %guard_block6
guard_block7: ; preds = %opt_block_cleanup6
%12 = load i64, ptr %error_var4, align 8
ret i64 %12
guard_block6: ; preds = %opt_block_cleanup5
%10 = load i64, ptr %error_var3, align 8
ret i64 %10
if.exit11: ; No predecessors!
%13 = call ptr @std.io.stdout()
store ptr %13, ptr %result13, align 8
%14 = load ptr, ptr %result13, align 8
%15 = call i64 @std.io.File.printn(ptr %retparam12, ptr %14, ptr @.str.5, i64 7)
if.exit9: ; No predecessors!
%11 = call ptr @std.io.stdout()
%12 = call i64 @std.io.File.printn(ptr %retparam10, ptr %11, ptr @.str.5, i64 7)
ret i64 0
}
@@ -120,11 +110,9 @@ entry:
%error_var = alloca i64, align 8
%blockret = alloca i32, align 4
%retparam1 = alloca i64, align 8
%result = alloca %File, align 8
%error_var2 = alloca i64, align 8
%blockret3 = alloca i32, align 4
%retparam7 = alloca i64, align 8
%result8 = alloca %File, align 8
store i32 %0, ptr %taddr, align 4
%1 = insertvalue %any undef, ptr %taddr, 0
%2 = insertvalue %any %1, i64 ptrtoint (ptr @"$ct.int" to i64), 1
@@ -151,9 +139,7 @@ and.phi: ; preds = %entry
if.exit: ; preds = %and.phi
%6 = call ptr @std.io.stdout()
store ptr %6, ptr %result, align 8
%7 = load ptr, ptr %result, align 8
%8 = call i64 @std.io.File.printn(ptr %retparam1, ptr %7, ptr @.str.7, i64 9)
%7 = call i64 @std.io.File.printn(ptr %retparam1, ptr %6, ptr @.str.7, i64 9)
store i64 ptrtoint (ptr @"foo.Foo$ABC" to i64), ptr %error_var2, align 8
br label %opt_block_cleanup4
@@ -162,14 +148,12 @@ opt_block_cleanup4: ; preds = %if.exit
br label %guard_block5
guard_block5: ; preds = %opt_block_cleanup4
%9 = load i64, ptr %error_var2, align 8
ret i64 %9
%8 = load i64, ptr %error_var2, align 8
ret i64 %8
if.exit6: ; No predecessors!
%10 = call ptr @std.io.stdout()
store ptr %10, ptr %result8, align 8
%11 = load ptr, ptr %result8, align 8
%12 = call i64 @std.io.File.printn(ptr %retparam7, ptr %11, ptr @.str.8, i64 7)
%9 = call ptr @std.io.stdout()
%10 = call i64 @std.io.File.printn(ptr %retparam7, ptr %9, ptr @.str.8, i64 7)
ret i64 0
}

View File

@@ -10,5 +10,5 @@ macro char[] read(src, allocator, n)
fn void main()
{
ByteReader br;
read(br.as_stream(), mem::temp(), 10);
read(&br, mem::temp(), 10);
}

View File

@@ -29,48 +29,30 @@ entry:
br i1 %eq, label %if.then, label %if.exit
if.then: ; preds = %entry
%1 = call ptr @std.io.stdout()
store ptr %1, ptr %result, align 8
%2 = load ptr, ptr %result, align 8
%3 = call i64 @std.io.File.print(ptr %retparam, ptr %2, ptr @.str, i64 1)
%4 = call ptr @std.io.stdout()
store ptr %4, ptr %result2, align 8
%5 = load ptr, ptr %result2, align 8
%6 = call i64 @std.io.File.printn(ptr %retparam1, ptr %5, ptr null, i64 0)
%2 = call i64 @std.io.File.print(ptr %retparam, ptr %1, ptr @.str, i64 1)
%3 = call ptr @std.io.stdout()
%4 = call i64 @std.io.File.printn(ptr %retparam1, ptr %3, ptr null, i64 0)
ret void
if.exit: ; preds = %entry
%eq3 = icmp eq i32 %0, 0
br i1 %eq3, label %if.then4, label %if.exit11
if.then4: ; preds = %if.exit
%eq2 = icmp eq i32 %0, 0
br i1 %eq2, label %if.then3, label %if.exit7
if.then3: ; preds = %if.exit
%5 = call ptr @std.io.stdout()
%6 = call i64 @std.io.File.print(ptr %retparam4, ptr %5, ptr @.str.1, i64 1)
%7 = call ptr @std.io.stdout()
store ptr %7, ptr %result6, align 8
%8 = load ptr, ptr %result6, align 8
%9 = call i64 @std.io.File.print(ptr %retparam5, ptr %8, ptr @.str.1, i64 1)
%10 = call ptr @std.io.stdout()
store ptr %10, ptr %result8, align 8
%11 = load ptr, ptr %result8, align 8
%12 = call i64 @std.io.File.print(ptr %retparam7, ptr %11, ptr @.str.2, i64 1)
%13 = call ptr @std.io.stdout()
store ptr %13, ptr %result10, align 8
%14 = load ptr, ptr %result10, align 8
%15 = call i64 @std.io.File.printn(ptr %retparam9, ptr %14, ptr null, i64 0)
%8 = call i64 @std.io.File.print(ptr %retparam5, ptr %7, ptr @.str.2, i64 1)
%9 = call ptr @std.io.stdout()
%10 = call i64 @std.io.File.printn(ptr %retparam6, ptr %9, ptr null, i64 0)
ret void
if.exit11: ; preds = %if.exit
%16 = call ptr @std.io.stdout()
store ptr %16, ptr %result13, align 8
%17 = load ptr, ptr %result13, align 8
%18 = call i64 @std.io.File.print(ptr %retparam12, ptr %17, ptr @.str.3, i64 1)
%19 = call ptr @std.io.stdout()
store ptr %19, ptr %result15, align 8
%20 = load ptr, ptr %result15, align 8
%21 = call i64 @std.io.File.print(ptr %retparam14, ptr %20, ptr @.str.4, i64 1)
%22 = call ptr @std.io.stdout()
store ptr %22, ptr %result17, align 8
%23 = load ptr, ptr %result17, align 8
%24 = call i64 @std.io.File.print(ptr %retparam16, ptr %23, ptr @.str.5, i64 1)
%25 = call ptr @std.io.stdout()
store ptr %25, ptr %result19, align 8
%26 = load ptr, ptr %result19, align 8
%27 = call i64 @std.io.File.printn(ptr %retparam18, ptr %26, ptr null, i64 0)
if.exit7: ; preds = %if.exit
%11 = call ptr @std.io.stdout()
%12 = call i64 @std.io.File.print(ptr %retparam8, ptr %11, ptr @.str.3, i64 1)
%13 = call ptr @std.io.stdout()
%14 = call i64 @std.io.File.print(ptr %retparam9, ptr %13, ptr @.str.4, i64 1)
%15 = call ptr @std.io.stdout()
%16 = call i64 @std.io.File.print(ptr %retparam10, ptr %15, ptr @.str.5, i64 1)
%17 = call ptr @std.io.stdout()
%18 = call i64 @std.io.File.printn(ptr %retparam11, ptr %17, ptr null, i64 0)
ret void
}
; Function Attrs: nounwind

View File

@@ -115,27 +115,19 @@ define void @examples.demo_enum(i32 %0) #0 {
entry:
%switch = alloca i32, align 4
%retparam = alloca i64, align 8
%result = alloca %File, align 8
%retparam2 = alloca i64, align 8
%result3 = alloca %File, align 8
%switch4 = alloca i32, align 4
%retparam7 = alloca i64, align 8
%result8 = alloca %File, align 8
%retparam10 = alloca i64, align 8
%result11 = alloca %File, align 8
%switch13 = alloca i32, align 4
%retparam17 = alloca i64, align 8
%result18 = alloca %File, align 8
%switch3 = alloca i32, align 4
%retparam6 = alloca i64, align 8
%retparam8 = alloca i64, align 8
%switch10 = alloca i32, align 4
%retparam14 = alloca i64, align 8
%switch17 = alloca i32, align 4
%switch21 = alloca i32, align 4
%switch25 = alloca i32, align 4
%a = alloca i32, align 4
%retparam28 = alloca i64, align 8
%result29 = alloca %File, align 8
%a31 = alloca i32, align 4
%retparam32 = alloca i64, align 8
%result33 = alloca %File, align 8
%retparam35 = alloca i64, align 8
%result36 = alloca %File, align 8
%retparam24 = alloca i64, align 8
%a26 = alloca i32, align 4
%retparam27 = alloca i64, align 8
%retparam29 = alloca i64, align 8
store i32 %0, ptr %switch, align 4
br label %switch.entry
switch.entry: ; preds = %entry
@@ -147,102 +139,86 @@ switch.entry: ; preds = %entry
]
switch.case: ; preds = %switch.entry, %switch.entry
%2 = call ptr @std.io.stdout()
store ptr %2, ptr %result, align 8
%3 = load ptr, ptr %result, align 8
%4 = call i64 @std.io.File.printn(ptr %retparam, ptr %3, ptr @.str.1, i64 8)
%3 = call i64 @std.io.File.printn(ptr %retparam, ptr %2, ptr @.str.1, i64 8)
br label %switch.exit
switch.case1: ; preds = %switch.entry
%5 = call ptr @std.io.stdout()
store ptr %5, ptr %result3, align 8
%6 = load ptr, ptr %result3, align 8
%7 = call i64 @std.io.File.printn(ptr %retparam2, ptr %6, ptr @.str.2, i64 4)
%4 = call ptr @std.io.stdout()
%5 = call i64 @std.io.File.printn(ptr %retparam2, ptr %4, ptr @.str.2, i64 4)
br label %switch.exit
switch.exit: ; preds = %switch.case1, %switch.case, %switch.entry
store i32 %0, ptr %switch4, align 4
br label %switch.entry5
switch.entry5: ; preds = %switch.exit
%8 = load i32, ptr %switch4, align 4
switch i32 %8, label %switch.exit12 [
i32 0, label %switch.case6
i32 1, label %switch.case6
i32 2, label %switch.case9
store i32 %0, ptr %switch3, align 4
br label %switch.entry4
switch.entry4: ; preds = %switch.exit
%6 = load i32, ptr %switch3, align 4
switch i32 %6, label %switch.exit9 [
i32 0, label %switch.case5
i32 1, label %switch.case5
i32 2, label %switch.case7
]
switch.case6: ; preds = %switch.entry5, %switch.entry5
switch.case5: ; preds = %switch.entry4, %switch.entry4
%7 = call ptr @std.io.stdout()
%8 = call i64 @std.io.File.printn(ptr %retparam6, ptr %7, ptr @.str.3, i64 8)
br label %switch.exit9
switch.case7: ; preds = %switch.entry4
%9 = call ptr @std.io.stdout()
store ptr %9, ptr %result8, align 8
%10 = load ptr, ptr %result8, align 8
%11 = call i64 @std.io.File.printn(ptr %retparam7, ptr %10, ptr @.str.3, i64 8)
br label %switch.exit12
switch.case9: ; preds = %switch.entry5
%10 = call i64 @std.io.File.printn(ptr %retparam8, ptr %9, ptr @.str.4, i64 4)
br label %switch.exit9
switch.exit9: ; preds = %switch.case7, %switch.case5, %switch.entry4
store i32 %0, ptr %switch10, align 4
br label %switch.entry11
switch.entry11: ; preds = %switch.exit9
%11 = load i32, ptr %switch10, align 4
switch i32 %11, label %switch.exit16 [
i32 0, label %switch.case12
i32 1, label %switch.case13
i32 2, label %switch.case15
]
switch.case12: ; preds = %switch.entry11
br label %switch.exit16
switch.case13: ; preds = %switch.entry11
%12 = call ptr @std.io.stdout()
store ptr %12, ptr %result11, align 8
%13 = load ptr, ptr %result11, align 8
%14 = call i64 @std.io.File.printn(ptr %retparam10, ptr %13, ptr @.str.4, i64 4)
br label %switch.exit12
switch.exit12: ; preds = %switch.case9, %switch.case6, %switch.entry5
store i32 %0, ptr %switch13, align 4
br label %switch.entry14
switch.entry14: ; preds = %switch.exit12
%15 = load i32, ptr %switch13, align 4
switch i32 %15, label %switch.exit20 [
i32 0, label %switch.case15
i32 1, label %switch.case16
%13 = call i64 @std.io.File.printn(ptr %retparam14, ptr %12, ptr @.str.5, i64 6)
br label %switch.exit16
switch.case15: ; preds = %switch.entry11
br label %switch.exit16
switch.exit16: ; preds = %switch.case15, %switch.case13, %switch.case12, %switch.entry11
store i32 %0, ptr %switch17, align 4
br label %switch.entry18
switch.entry18: ; preds = %switch.exit16
%14 = load i32, ptr %switch17, align 4
switch i32 %14, label %switch.default [
i32 0, label %switch.case19
i32 1, label %switch.case19
i32 2, label %switch.case19
]
switch.case15: ; preds = %switch.entry14
switch.case19: ; preds = %switch.entry18, %switch.entry18, %switch.entry18
br label %switch.exit20
switch.case16: ; preds = %switch.entry14
%16 = call ptr @std.io.stdout()
store ptr %16, ptr %result18, align 8
%17 = load ptr, ptr %result18, align 8
%18 = call i64 @std.io.File.printn(ptr %retparam17, ptr %17, ptr @.str.5, i64 6)
switch.default: ; preds = %switch.entry18
br label %switch.exit20
switch.case19: ; preds = %switch.entry14
br label %switch.exit20
switch.exit20: ; preds = %switch.case19, %switch.case16, %switch.case15, %switch.entry14
switch.exit20: ; preds = %switch.default, %switch.case19
store i32 %0, ptr %switch21, align 4
br label %switch.entry22
switch.entry22: ; preds = %switch.exit20
%19 = load i32, ptr %switch21, align 4
switch i32 %19, label %switch.default [
%15 = load i32, ptr %switch21, align 4
switch i32 %15, label %switch.exit30 [
i32 0, label %switch.case23
i32 1, label %switch.case23
i32 2, label %switch.case23
i32 1, label %switch.case25
i32 2, label %switch.case28
]
switch.case23: ; preds = %switch.entry22, %switch.entry22, %switch.entry22
br label %switch.exit24
switch.default: ; preds = %switch.entry22
br label %switch.exit24
switch.exit24: ; preds = %switch.default, %switch.case23
store i32 %0, ptr %switch25, align 4
br label %switch.entry26
switch.entry26: ; preds = %switch.exit24
%20 = load i32, ptr %switch25, align 4
switch i32 %20, label %switch.exit37 [
i32 0, label %switch.case27
i32 1, label %switch.case30
i32 2, label %switch.case34
]
switch.case27: ; preds = %switch.entry26
switch.case23: ; preds = %switch.entry22
store i32 1, ptr %a, align 4
%21 = call ptr @std.io.stdout()
store ptr %21, ptr %result29, align 8
%22 = load ptr, ptr %result29, align 8
%23 = call i64 @std.io.File.printn(ptr %retparam28, ptr %22, ptr @.str.6, i64 1)
br label %switch.case30
switch.case30: ; preds = %switch.entry26, %switch.case27
store i32 2, ptr %a31, align 4
%24 = call ptr @std.io.stdout()
store ptr %24, ptr %result33, align 8
%25 = load ptr, ptr %result33, align 8
%26 = call i64 @std.io.File.printn(ptr %retparam32, ptr %25, ptr @.str.7, i64 1)
br label %switch.case34
switch.case34: ; preds = %switch.entry26, %switch.case30
%27 = call ptr @std.io.stdout()
store ptr %27, ptr %result36, align 8
%28 = load ptr, ptr %result36, align 8
%29 = call i64 @std.io.File.printn(ptr %retparam35, ptr %28, ptr @.str.8, i64 1)
br label %switch.exit37
switch.exit37: ; preds = %switch.case34, %switch.entry26
%16 = call ptr @std.io.stdout()
%17 = call i64 @std.io.File.printn(ptr %retparam24, ptr %16, ptr @.str.6, i64 1)
br label %switch.case25
switch.case25: ; preds = %switch.entry22, %switch.case23
store i32 2, ptr %a26, align 4
%18 = call ptr @std.io.stdout()
%19 = call i64 @std.io.File.printn(ptr %retparam27, ptr %18, ptr @.str.7, i64 1)
br label %switch.case28
switch.case28: ; preds = %switch.entry22, %switch.case25
%20 = call ptr @std.io.stdout()
%21 = call i64 @std.io.File.printn(ptr %retparam29, ptr %20, ptr @.str.8, i64 1)
br label %switch.exit30
switch.exit30: ; preds = %switch.case28, %switch.entry22
ret void
}

View File

@@ -102,16 +102,16 @@ fn void! TextTemplate.free(&self)
*self = {};
}
fn Stream TextTemplate.as_stream(&self)
fn StreamWrapper TextTemplate.as_stream(&self)
{
return { .fns = &texttemplate_interface, .data = self };
return { .stream.fns = &texttemplate_interface, .data = self };
}
StreamInterface texttemplate_interface @private = {
.write_stream_fn = fn (s, out) => ((TextTemplate*)s.data).write_to(out),
.write_stream_fn = fn (s, out) => ((TextTemplate*)(((StreamWrapper*)s).data)).write_to(out),
};
fn usz! TextTemplate.write_to(&self, Stream writer)
fn usz! TextTemplate.write_to(&self, Stream* writer)
{
usz n;
usz pos;
@@ -125,7 +125,7 @@ fn usz! TextTemplate.write_to(&self, Stream writer)
return n;
}
fn usz! TextTag.write(&self, Stream writer)
fn usz! TextTag.write(&self, Stream* writer)
{
switch (self.kind)
{

View File

@@ -48,9 +48,7 @@ fn int main()
%Bar = type { i32, i32 }
%"Bar[]" = type { ptr, i64 }
%"int[]" = type { ptr, i64 }
%File = type { ptr }
%Baz = type { double }
@"$ct.subarrays.Baz" = linkonce global %.introspect { i8 11, i64 0, ptr null, i64 8, i64 0, i64 2, [0 x i64] zeroinitializer }, align 8
@"$ct.subarrays.Bar" = linkonce global %.introspect { i8 10, i64 0, ptr null, i64 8, i64 0, i64 2, [0 x i64] zeroinitializer }, align 8
@.taddr = private global [2 x %Bar] [%Bar { i32 3, i32 4 }, %Bar { i32 8, i32 9 }], align 8
@@ -66,7 +64,6 @@ fn int main()
@.str.9 = private unnamed_addr constant [25 x i8] c"Fofeo second element %d\0A\00", align 1
@.__const.10 = private unnamed_addr constant { i32, [4 x i8] } { i32 1, [4 x i8] undef }, align 8
@.str.12 = private unnamed_addr constant [3 x i8] c"Ok\00", align 1
; Function Attrs: nounwind
define i32 @main() #0 {
entry:
@@ -76,13 +73,11 @@ entry:
%y = alloca ptr, align 8
%literal2 = alloca [3 x i32], align 4
%retparam = alloca i64, align 8
%result = alloca %File, align 8
%ffe = alloca %Baz, align 8
%azz = alloca [1 x i32], align 4
%xy = alloca i8, align 1
%literal6 = alloca [3 x i32], align 4
%retparam8 = alloca i64, align 8
%result9 = alloca %File, align 8
%b = alloca %Bar, align 4
%z = alloca %Baz, align 8
%sub = alloca %"int[]", align 8
@@ -103,52 +98,46 @@ entry:
call void @llvm.memcpy.p0.p0.i32(ptr align 4 %literal2, ptr align 4 @.__const.5, i32 12, i1 false)
store ptr %literal2, ptr %y, align 8
%7 = call ptr @std.io.stdout()
store ptr %7, ptr %result, align 8
%8 = load ptr, ptr %result, align 8
%9 = call i64 @std.io.File.printn(ptr %retparam, ptr %8, ptr @.str.6, i64 6)
%10 = getelementptr inbounds %"int[]", ptr %x, i32 0, i32 1
%11 = load i64, ptr %10, align 8
%trunc = trunc i64 %11 to i32
%12 = getelementptr inbounds %"int[]", ptr %x, i32 0, i32 0
%13 = load ptr, ptr %12, align 8
%ptroffset3 = getelementptr inbounds i32, ptr %13, i64 1
%14 = load i32, ptr %ptroffset3, align 4
%15 = call i32 (ptr, ...) @printf(ptr @.str.7, i32 %trunc, i32 %14)
%16 = load ptr, ptr %y, align 8
%ptroffset4 = getelementptr inbounds i32, ptr %16, i64 1
%17 = load i32, ptr %ptroffset4, align 4
%18 = call i32 (ptr, ...) @printf(ptr @.str.8, i32 %17)
%19 = load ptr, ptr @subarrays.fofeo, align 8
%ptroffset5 = getelementptr inbounds i32, ptr %19, i64 1
%20 = load i32, ptr %ptroffset5, align 4
%21 = call i32 (ptr, ...) @printf(ptr @.str.9, i32 %20)
%8 = call i64 @std.io.File.printn(ptr %retparam, ptr %7, ptr @.str.6, i64 6)
%9 = getelementptr inbounds %"int[]", ptr %x, i32 0, i32 1
%10 = load i64, ptr %9, align 8
%trunc = trunc i64 %10 to i32
%11 = getelementptr inbounds %"int[]", ptr %x, i32 0, i32 0
%12 = load ptr, ptr %11, align 8
%ptroffset3 = getelementptr inbounds i32, ptr %12, i64 1
%13 = load i32, ptr %ptroffset3, align 4
%14 = call i32 (ptr, ...) @printf(ptr @.str.7, i32 %trunc, i32 %13)
%15 = load ptr, ptr %y, align 8
%ptroffset4 = getelementptr inbounds i32, ptr %15, i64 1
%16 = load i32, ptr %ptroffset4, align 4
%17 = call i32 (ptr, ...) @printf(ptr @.str.8, i32 %16)
%18 = load ptr, ptr @subarrays.fofeo, align 8
%ptroffset5 = getelementptr inbounds i32, ptr %18, i64 1
%19 = load i32, ptr %ptroffset5, align 4
%20 = call i32 (ptr, ...) @printf(ptr @.str.9, i32 %19)
call void @llvm.memcpy.p0.p0.i32(ptr align 8 %ffe, ptr align 8 @.__const.10, i32 8, i1 false)
%22 = getelementptr inbounds [1 x i32], ptr %azz, i64 0, i64 0
store i32 0, ptr %22, align 4
%21 = getelementptr inbounds [1 x i32], ptr %azz, i64 0, i64 0
store i32 0, ptr %21, align 4
call void @llvm.memcpy.p0.p0.i32(ptr align 4 %literal6, ptr align 4 @.__const.11, i32 12, i1 false)
%23 = insertvalue %"int[]" undef, ptr %literal6, 0
%24 = insertvalue %"int[]" %23, i64 3, 1
%25 = extractvalue %"int[]" %24, 1
%not = icmp eq i64 %25, 0
%26 = zext i1 %not to i8
store i8 %26, ptr %xy, align 1
%27 = load i8, ptr %xy, align 1
%28 = trunc i8 %27 to i1
%not7 = xor i1 %28, true
%22 = insertvalue %"int[]" undef, ptr %literal6, 0
%23 = insertvalue %"int[]" %22, i64 3, 1
%24 = extractvalue %"int[]" %23, 1
%not = icmp eq i64 %24, 0
%25 = zext i1 %not to i8
store i8 %25, ptr %xy, align 1
%26 = load i8, ptr %xy, align 1
%27 = trunc i8 %26 to i1
%not7 = xor i1 %27, true
br i1 %not7, label %if.then, label %if.exit
if.then: ; preds = %entry
%29 = call ptr @std.io.stdout()
store ptr %29, ptr %result9, align 8
%30 = load ptr, ptr %result9, align 8
%31 = call i64 @std.io.File.printn(ptr %retparam8, ptr %30, ptr @.str.12, i64 2)
%28 = call ptr @std.io.stdout()
%29 = call i64 @std.io.File.printn(ptr %retparam8, ptr %28, ptr @.str.12, i64 2)
br label %if.exit
if.exit: ; preds = %if.then, %entry
%32 = getelementptr inbounds %Bar, ptr %b, i32 0, i32 0
store i32 0, ptr %32, align 4
%33 = getelementptr inbounds %Bar, ptr %b, i32 0, i32 1
store i32 0, ptr %33, align 4
%30 = getelementptr inbounds %Bar, ptr %b, i32 0, i32 0
store i32 0, ptr %30, align 4
%31 = getelementptr inbounds %Bar, ptr %b, i32 0, i32 1
store i32 0, ptr %31, align 4
call void @llvm.memset.p0.i64(ptr align 8 %z, i8 0, i64 8, i1 false)
store %"int[]" zeroinitializer, ptr %sub, align 8
store %"Bar[]" zeroinitializer, ptr %foo, align 8

View File

@@ -47,33 +47,24 @@ fn int main()
define void @foo.Foo.hello(ptr %0) #0 {
entry:
%retparam = alloca i64, align 8
%result = alloca %File, align 8
%1 = call ptr @std.io.stdout()
store ptr %1, ptr %result, align 8
%2 = load ptr, ptr %result, align 8
%3 = call i64 @std.io.File.printn(ptr %retparam, ptr %2, ptr @.str, i64 14)
%2 = call i64 @std.io.File.printn(ptr %retparam, ptr %1, ptr @.str, i64 14)
ret void
}
; Function Attrs: nounwind
define void @foo.Bar.hello(ptr %0) #0 {
entry:
%retparam = alloca i64, align 8
%result = alloca %File, align 8
%1 = call ptr @std.io.stdout()
store ptr %1, ptr %result, align 8
%2 = load ptr, ptr %result, align 8
%3 = call i64 @std.io.File.printn(ptr %retparam, ptr %2, ptr @.str.1, i64 14)
%2 = call i64 @std.io.File.printn(ptr %retparam, ptr %1, ptr @.str.1, i64 14)
ret void
}
; Function Attrs: nounwind
define void @foo.MyEnum.hello(ptr %0) #0 {
entry:
%retparam = alloca i64, align 8
%result = alloca %File, align 8
%1 = call ptr @std.io.stdout()
store ptr %1, ptr %result, align 8
%2 = load ptr, ptr %result, align 8
%3 = call i64 @std.io.File.printn(ptr %retparam, ptr %2, ptr @.str.2, i64 17)
%2 = call i64 @std.io.File.printn(ptr %retparam, ptr %1, ptr @.str.2, i64 17)
ret void
}
; Function Attrs: nounwind

View File

@@ -33,7 +33,7 @@ def Ident = fn bool (usz index, char c);
struct Lexer
{
Allocator* allocator;
Stream reader;
Stream* reader;
char[] buf;
TokenTrie tokens;
Ident ident;
@@ -50,7 +50,7 @@ struct Lexer
}
}
fn void! Lexer.init(&self, Stream reader, Ident ident, Allocator* using = mem::heap())
fn void! Lexer.init(&self, Stream* reader, Ident ident, Allocator* using = mem::heap())
{
TokenTrie trie;
ushort max_token;
@@ -447,9 +447,8 @@ fn void! lex_uint()
foreach (tc : tcases)
{
ByteReader br;
br.init((char[])tc.in);
Lexer lex;
lex.init(br.as_stream(), &is_ident_char)!;
lex.init(br.init((char[])tc.in), &is_ident_char)!;
Kind kind = lex.next()!;
assert(kind == UINT, "got %s; want %s", kind, Kind.UINT);
@@ -681,39 +680,65 @@ fn void test()
/* #expect: lexer_test.ll
; ModuleID = 'lexer_test'
source_filename = "lexer_test"
target datalayout = "e-m:o-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128"
target triple = "x86_64-apple-darwin"
%.introspect = type { i8, i64, ptr, i64, i64, i64, [0 x i64] }
%"char[]" = type { ptr, i64 }
%"UintTest[]" = type { ptr, i64 }
%UintTest = type { %"char[]", i64 }
%ByteReader = type { %Stream, %"char[]", i64 }
%Stream = type { ptr }
%Lexer = type { ptr, ptr, %"char[]", %Trie, ptr, i8, i8, i32, i32, i32, %.anon }
%Trie = type { %List }
%List = type { i64, i64, ptr, ptr }
%.anon = type { %"char[]" }
@"$ct.lexer_test.UintTest" = linkonce global %.introspect { i8 10, i64 0, ptr null, i64 24, i64 0, i64 2, [0 x i64] zeroinitializer }, align 8
@.enum.KEYWORD1 = internal constant [9 x i8] c"KEYWORD1\00", align 1
@.enum.KEYWORD2 = internal constant [9 x i8] c"KEYWORD2\00", align 1
@.enum.SINGLE = internal constant [7 x i8] c"SINGLE\00", align 1
@.enum.MULTI = internal constant [6 x i8] c"MULTI\00", align 1
@"$ct.char" = linkonce global %.introspect { i8 3, i64 0, ptr null, i64 1, i64 0, i64 0, [0 x i64] zeroinitializer }, align 8
@"$ct.lexer_test.Token" = linkonce global { i8, i64, ptr, i64, i64, i64, [4 x %"char[]"] } { i8 8, i64 0, ptr null, i64 1, i64 ptrtoint (ptr @"$ct.char" to i64), i64 4, [4 x %"char[]"] [%"char[]" { ptr @.enum.KEYWORD1, i64 8 }, %"char[]" { ptr @.enum.KEYWORD2, i64 8 }, %"char[]" { ptr @.enum.SINGLE, i64 6 }, %"char[]" { ptr @.enum.MULTI, i64 5 }] }, align 8
@.str = private unnamed_addr constant [8 x i8] c"keword1\00", align 1
@.str.1 = private unnamed_addr constant [9 x i8] c"keyword2\00", align 1
@.str.2 = private unnamed_addr constant [3 x i8] c"//\00", align 1
@.str.3 = private unnamed_addr constant [3 x i8] c"/*\00", align 1
@"lexer_test.Token$token" = linkonce constant [4 x %"char[]"] [%"char[]" { ptr @.str, i64 7 }, %"char[]" { ptr @.str.1, i64 8 }, %"char[]" { ptr @.str.2, i64 2 }, %"char[]" { ptr @.str.3, i64 2 }], align 8
@"$ct.lexer_test.Comment" = linkonce global { i8, i64, ptr, i64, i64, i64, [2 x %"char[]"] } { i8 8, i64 0, ptr null, i64 1, i64 ptrtoint (ptr @"$ct.char" to i64), i64 2, [2 x %"char[]"] [%"char[]" { ptr @.enum.SINGLE, i64 6 }, %"char[]" { ptr @.enum.MULTI, i64 5 }] }, align 8
@"lexer_test.Comment$start" = linkonce constant [2 x i8] c"\02\03", align 1
@.str.4 = private unnamed_addr constant [2 x i8] c"\0A\00", align 1
@.str.5 = private unnamed_addr constant [3 x i8] c"*/\00", align 1
@"lexer_test.Comment$end" = linkonce constant [2 x %"char[]"] [%"char[]" { ptr @.str.4, i64 1 }, %"char[]" { ptr @.str.5, i64 2 }], align 8
@std.core.mem.thread_allocator = external thread_local global ptr, align 8
; Function Attrs: nounwind
define zeroext i8 @lexer_test.is_ident_char(i64 %0, i8 zeroext %1) #0 {
entry:
%eq = icmp eq i64 0, %0
br i1 %eq, label %and.rhs, label %and.phi
and.rhs: ; preds = %entry
%2 = call i8 @char.is_alpha(i8 zeroext %1)
%3 = trunc i8 %2 to i1
br label %and.phi
and.phi: ; preds = %and.rhs, %entry
%val = phi i1 [ false, %entry ], [ %3, %and.rhs ]
br i1 %val, label %or.phi, label %or.rhs
or.rhs: ; preds = %and.phi
%lt = icmp ult i64 0, %0
br i1 %lt, label %and.rhs1, label %and.phi2
and.rhs1: ; preds = %or.rhs
%4 = call i8 @char.is_alnum(i8 zeroext %1)
%5 = trunc i8 %4 to i1
br label %and.phi2
and.phi2: ; preds = %and.rhs1, %or.rhs
%val3 = phi i1 [ false, %or.rhs ], [ %5, %and.rhs1 ]
br label %or.phi
or.phi: ; preds = %and.phi2, %and.phi
%val4 = phi i1 [ true, %and.phi ], [ %val3, %and.phi2 ]
%6 = zext i1 %val4 to i8
ret i8 %6
}
; Function Attrs: nounwind
define i64 @lexer_test.lex_uint() #0 {
entry:
@@ -724,9 +749,8 @@ entry:
%br = alloca %ByteReader, align 8
%lex = alloca %Lexer, align 8
%error_var = alloca i64, align 8
%result = alloca %Stream, align 8
%kind = alloca i8, align 1
%error_var4 = alloca i64, align 8
%error_var2 = alloca i64, align 8
%retparam = alloca i8, align 1
store %"UintTest[]" zeroinitializer, ptr %tcases, align 8
%0 = getelementptr inbounds %"UintTest[]", ptr %tcases, i32 0, i32 1
@@ -734,78 +758,61 @@ entry:
store i64 %1, ptr %.anon, align 8
store i64 0, ptr %.anon1, align 8
br label %loop.cond
loop.cond: ; preds = %noerr_block9, %entry
loop.cond: ; preds = %noerr_block7, %entry
%2 = load i64, ptr %.anon1, align 8
%3 = load i64, ptr %.anon, align 8
%lt = icmp ult i64 %2, %3
br i1 %lt, label %loop.body, label %loop.exit
loop.body: ; preds = %loop.cond
%4 = getelementptr inbounds %"UintTest[]", ptr %tcases, i32 0, i32 0
%5 = load ptr, ptr %4, align 8
%6 = load i64, ptr %.anon1, align 8
%ptroffset = getelementptr inbounds %UintTest, ptr %5, i64 %6
call void @llvm.memcpy.p0.p0.i32(ptr align 8 %tc, ptr align 8 %ptroffset, i32 24, i1 false)
call void @llvm.memset.p0.i64(ptr align 8 %br, i8 0, i64 24, i1 false)
call void @llvm.memset.p0.i64(ptr align 8 %br, i8 0, i64 32, i1 false)
call void @llvm.memset.p0.i64(ptr align 8 %lex, i8 0, i64 104, i1 false)
%7 = getelementptr inbounds %UintTest, ptr %tc, i32 0, i32 0
%8 = getelementptr inbounds %"char[]", ptr %7, i32 0, i32 0
%lo = load ptr, ptr %8, align 8
%9 = getelementptr inbounds %"char[]", ptr %7, i32 0, i32 1
%hi = load i64, ptr %9, align 8
call void @std.io.ByteReader.init(ptr %br, ptr %lo, i64 %hi)
call void @llvm.memset.p0.i64(ptr align 8 %lex, i8 0, i64 112, i1 false)
%10 = call { ptr, ptr } @std.io.ByteReader.as_stream(ptr %br)
store { ptr, ptr } %10, ptr %result, align 8
%11 = getelementptr inbounds %Stream, ptr %result, i32 0, i32 0
%lo2 = load ptr, ptr %11, align 8
%12 = getelementptr inbounds %Stream, ptr %result, i32 0, i32 1
%hi3 = load ptr, ptr %12, align 8
%13 = load ptr, ptr @std.core.mem.thread_allocator, align 8
%14 = call i64 @"lexer$lexer_test.Token$lexer_test.Comment$.Lexer.init"(ptr %lex, ptr %lo2, ptr %hi3, ptr @lexer_test.is_ident_char, ptr %13)
%not_err = icmp eq i64 %14, 0
%15 = call i1 @llvm.expect.i1(i1 %not_err, i1 true)
br i1 %15, label %after_check, label %assign_optional
%10 = call ptr @std.io.ByteReader.init(ptr %br, ptr %lo, i64 %hi)
%11 = load ptr, ptr @std.core.mem.thread_allocator, align 8
%12 = call i64 @"lexer$lexer_test.Token$lexer_test.Comment$.Lexer.init"(ptr %lex, ptr %10, ptr @lexer_test.is_ident_char, ptr %11)
%not_err = icmp eq i64 %12, 0
%13 = call i1 @llvm.expect.i1(i1 %not_err, i1 true)
br i1 %13, label %after_check, label %assign_optional
assign_optional: ; preds = %loop.body
store i64 %14, ptr %error_var, align 8
store i64 %12, ptr %error_var, align 8
br label %guard_block
after_check: ; preds = %loop.body
br label %noerr_block
guard_block: ; preds = %assign_optional
%16 = load i64, ptr %error_var, align 8
ret i64 %16
%14 = load i64, ptr %error_var, align 8
ret i64 %14
noerr_block: ; preds = %after_check
%17 = call i64 @"lexer$lexer_test.Token$lexer_test.Comment$.Lexer.next"(ptr %retparam, ptr %lex)
%not_err5 = icmp eq i64 %17, 0
%18 = call i1 @llvm.expect.i1(i1 %not_err5, i1 true)
br i1 %18, label %after_check7, label %assign_optional6
assign_optional6: ; preds = %noerr_block
store i64 %17, ptr %error_var4, align 8
br label %guard_block8
after_check7: ; preds = %noerr_block
br label %noerr_block9
guard_block8: ; preds = %assign_optional6
%19 = load i64, ptr %error_var4, align 8
ret i64 %19
noerr_block9: ; preds = %after_check7
%20 = load i8, ptr %retparam, align 1
store i8 %20, ptr %kind, align 1
%21 = load i8, ptr %kind, align 1
%eq = icmp eq i8 %21, 1
%15 = call i64 @"lexer$lexer_test.Token$lexer_test.Comment$.Lexer.next"(ptr %retparam, ptr %lex)
%not_err3 = icmp eq i64 %15, 0
%16 = call i1 @llvm.expect.i1(i1 %not_err3, i1 true)
br i1 %16, label %after_check5, label %assign_optional4
assign_optional4: ; preds = %noerr_block
store i64 %15, ptr %error_var2, align 8
br label %guard_block6
after_check5: ; preds = %noerr_block
br label %noerr_block7
guard_block6: ; preds = %assign_optional4
%17 = load i64, ptr %error_var2, align 8
ret i64 %17
noerr_block7: ; preds = %after_check5
%18 = load i8, ptr %retparam, align 1
store i8 %18, ptr %kind, align 1
%19 = load i8, ptr %kind, align 1
%eq = icmp eq i8 %19, 1
call void @llvm.assume(i1 %eq)
%22 = load i64, ptr %.anon1, align 8
%add = add i64 %22, 1
%20 = load i64, ptr %.anon1, align 8
%add = add i64 %20, 1
store i64 %add, ptr %.anon1, align 8
br label %loop.cond
loop.exit: ; preds = %loop.cond
ret i64 0
}

View File

@@ -7,7 +7,7 @@ fn void! simple_test()
{
ByteReader reader;
reader.init(`{ "b": 123, "c": [ { "d": 66 }, null, "hello", false, { "id": "xyz" } ] }`);
Object* o = json::parse(reader.as_stream())!;
Object* o = json::parse(&reader)!;
assert(o.get_int("b")! == 123);
assert(o.get("c").get_len()! == 5);
assert(o.get("c").get_at(0).get_int("d")! == 66);

View File

@@ -8,7 +8,7 @@ fn void! readbuffer_large()
src.init(DATA);
char[DATA.len] buf;
ReadBuffer reader_buf;
reader_buf.init(src.as_stream(), buf[..]);
reader_buf.init(&src, buf[..]);
char[DATA.len] bytes;
usz n = reader_buf.read(bytes[..])!;
@@ -24,12 +24,12 @@ fn void! readbuffer()
src.init(DATA);
char[3] buf;
ReadBuffer reader_buf;
reader_buf.init(src.as_stream(), buf[..]);
reader_buf.init(&src, buf[..]);
ByteWriter bw;
bw.tinit();
usz n = reader_buf.as_stream().copy_to(bw.as_stream())!;
usz n = reader_buf.copy_to(&bw)!;
assert(n == DATA.len, "got %d; want %d", n, DATA.len);
String got = bw.as_str();
@@ -42,7 +42,7 @@ fn void! writebuffer_large()
out.tinit();
char[16] buf;
WriteBuffer write_buf;
write_buf.init(out.as_stream(), buf[..]);
write_buf.init(&out, buf[..]);
usz n = write_buf.write(DATA)!;
@@ -59,9 +59,9 @@ fn void! writebuffer()
out.tinit();
char[3] buf;
WriteBuffer write_buf;
write_buf.init(out.as_stream(), buf[..]);
write_buf.init(&out, buf[..]);
usz n = br.as_stream().copy_to(write_buf.as_stream())!;
usz n = br.copy_to(&write_buf)!;
assert(n == DATA.len, "got %d; want %d", n, DATA.len);
String got = out.as_str();

View File

@@ -4,7 +4,7 @@ fn void! bytestream()
{
ByteReader r;
r.init("abc");
Stream s = r.as_stream();
Stream* s = &r;
assert(s.len()! == 3);
char[5] buffer;
assert('a' == s.read_byte()!);
@@ -13,7 +13,7 @@ fn void! bytestream()
assert((String)buffer[:len] == "abc");
ByteWriter w;
w.init();
Stream ws = w.as_stream();
Stream* ws = &w;
ws.write("helloworld")!;
assert(w.as_str() == "helloworld");
s.seek(0, SET)!;
@@ -28,7 +28,7 @@ fn void! bytewriter_buffer()
ByteWriter writer;
char[8] z;
writer.init_buffer(&z);
Stream s = writer.as_stream();
Stream* s = &writer;
s.write("hello")!!;
s.write_byte(0)!!;
String o = ((ZString)&z).as_str();
@@ -40,7 +40,7 @@ fn void! bytewriter_read_from()
{
char[] data = "Lorem ipsum dolor sit amet biam.";
TestReader r = { .bytes = data };
Stream s = r.as_stream();
Stream* s = &&r.as_stream();
ByteWriter bw;
bw.tinit();
@@ -58,9 +58,9 @@ struct TestReader
usz index;
}
fn Stream TestReader.as_stream(TestReader *r)
fn StreamWrapper TestReader.as_stream(TestReader *r)
{
return { .fns = &testReader_interface, .data = r };
return { .stream = { &testReader_interface }, .data = r };
}
fn usz! TestReader.read(TestReader *r, char[] bytes)
@@ -74,5 +74,5 @@ fn usz! TestReader.read(TestReader *r, char[] bytes)
}
StreamInterface testReader_interface = {
.read_fn = fn(s, char[] bytes) => ((TestReader*)s.data).read(bytes),
.read_fn = fn(s, char[] bytes) => ((TestReader*)((StreamWrapper*)s).data).read(bytes),
};

View File

@@ -4,14 +4,13 @@ fn void! test_writing()
{
DString foo;
foo.init();
Stream s = foo.as_stream();
Stream* s = DStringStream{}.init(&foo);
s.write("hello")!!;
s.write_byte('-')!!;
s.write("what?")!!;
s.write("what?-------------------------------------------------------")!!;
ByteReader r;
String test_str = "2134";
r.init(test_str);
s.read_from(r.as_stream())!;
s.read_from(r.init(test_str))!;
String o = foo.as_str();
assert(o == "hello-what?2134");
assert(o == "hello-what?-------------------------------------------------------2134");
}

View File

@@ -8,7 +8,7 @@ fn void! limitreader()
src.init(DATA);
const LIMIT = 5;
LimitReader lmr;
lmr.init(src.as_stream(), LIMIT);
lmr.init(&src, LIMIT);
char[DATA.len] bytes;
usz n = lmr.read(bytes[..])!;

View File

@@ -25,7 +25,7 @@ fn void! test_scanner()
br.init(tc.in);
Scanner sc;
char[4] buffer; // max match (2) + pattern length (2)
sc.init(br.as_stream(), buffer[..]);
sc.init(&br, buffer[..]);
Results results;
while LOOP: (true)