step : i32 = 1;
}
+@Deprecated
vararg :: #type ^struct {
data: rawptr;
count: i32;
}
+@Deprecated
vararg_get :: #match {
(va: vararg, ret: ^$T) -> bool {
if va.count <= 0 do return false;
// CLEANUP: Does this really need to be limited to a non-custom runtime?
#if runtime.Runtime != runtime.Runtime_Custom {
- new :: ($T: type_expr, allocator := context.allocator, initialize := true) -> ^T {
- res := cast(^T) raw_alloc(allocator, sizeof T);
-
- // @Robustness: This should be a '#if' when those are added in procedures because
- // otherwise the __initialize intrinsic is going to be generated no matter what.
- // This could be a problem if the type is not something that can be initialized.
- //
- // Static ifs in procedures are added now, however, much like nested procedures,
- // static ifs cannot "see" polymorphic variables. They are only evaluated once
- // NOT in the context of the polymorphic procedure they are instatiated in.
- // This will be changed eventually. 'make' can be used for the time being or
- // for forever.
+ new :: ($T: type_expr, allocator := context.allocator) -> ^T {
use package core.intrinsics.onyx { __initialize }
- if initialize do __initialize(res);
+
+ res := cast(^T) raw_alloc(allocator, sizeof T);
+ __initialize(res);
return res;
}
wasi.fd_datasync(file.fd);
}
-get_size :: (file: File) -> u64 {
+file_get_size :: (file: File) -> u64 {
fs: FileStat;
if wasi.fd_filestat_get(file.fd, ^fs) != Errno.Success do return 0;
}
get_contents_from_file :: (file: File) -> str {
- size := cast(u32) get_size(file);
+ size := cast(u32) file_get_size(file);
data := cast(^u8) raw_alloc(context.allocator, size);
if !success do return .NotFound, fs;
fs.file = file;
- fs.vtable = ^file_stream_vtable;
+ fs.vtable = ^wasi_file_stream_vtable;
return .None, fs;
}
file.stream.vtable = null;
}
+with_file :: (path: str, mode := OpenMode.Read) -> Iterator(^FileStream) {
+ Context :: struct {
+ valid_file_stream := false;
+
+ file_stream: FileStream;
+ }
+
+ c := new(Context);
+ if err, file_stream := open(path, mode); err == .None {
+ c.file_stream = file_stream;
+ c.valid_file_stream = true;
+ }
+
+ next :: (use c: ^Context) -> (^FileStream, bool) {
+ if !valid_file_stream do return null, false;
+
+ defer valid_file_stream = false;
+ return ^file_stream, true;
+ }
+
+ close_context :: (use c: ^Context) {
+ close(^file_stream);
+ cfree(c);
+ }
+
+ return .{ c, next, close_context };
+}
+
#package
-file_stream_vtable := Stream_Vtable.{
+wasi_file_stream_vtable := Stream_Vtable.{
seek = (use fs: ^FileStream, to: i32, whence: SeekFrom) -> Error {
// Currently, the new offset is just ignored.
newoffset : wasi.Filesize;
--- /dev/null
+The following things are defined in the `builtin` package, which is implicitly
+used in every file. Therefore, these things are effectively like "globals". Also,
+you can add your own things to the `builtin` package to define your own "globals"
+for your project.
+
+- `str` -
+This is the builtin string type, which is just a slice of bytes.
+
+- `cstr` -
+This is the builtin cstring type, used in every program as the type of the command line arguments given to main.
+
+- `range` -
+This is the type of a range literal, i.e. 1 .. 5. You can also use this type in a for-loop to iterate over the values.
+
+- `vararg` -
+This is a deprecated type used when you have an untyped variadic procedure, i.e. x :: (va: ...). This is deprecated because of the 'any' type.
+
+- `vararg_get` -
+This is also deprecated but it allowed you get values out of a `vararg` type.
+
+- `null_proc` -
+This is a special procedure that always matches any procedure type, regardless of whether the types actually match. This allows you to use it as a placeholder or "null" value when a procedure is expected.
+
+- `null` -
+Much like every other systems-ish programming language, Onyx has a "null" type. In Onyx, it is nothing more than a 0 value casted to a `rawptr`.
+
+- `null_str` -
+A helpful constant that is a string with the data being null and the count being 0. Useful if you want to have a blank string value. It is different from "", because the latter will still be assigned a data location, even through there will not be any data there.
+
+- `OnyxContext` -
+The builtin type of the `context`, described below. In theory, this type could exist at file scope in builtin.onyx, but I decided to leave it exposed.
+
+- `context` -
+This is a thread-local variable that stores the active allocators, loggers, and assert_handler for the current thread.
+
+- `assert` -
+A function that asserts a certain condition is true; if not, it calls the assert handler on the `context`.
+
+- `Logger` -
+The type used for the logger on the `context`.
+
+- `log` -
+Logs a message to the `context.logger`. Currently, this does not support formatted arguments, but that is planned in the near future.
+
+- `AllocationAction` -
+A simple enum that represent what action is to be taken when calling an allocator_proc.
+
+- `Allocator` -
+This type represents something that can allocate memory. It has two members, `data` and `func`. The `func` is an `allocator_proc`, which takes the data, the allocation action, size, alignment and old pointer. Not all of these values are used for every action, but the allocator procedure must consume all of them.
+
+- `raw_alloc` `raw_resize` `raw_free` -
+These functions are simply wrappers provided to invoke an `Allocator` with a specific action.
+
+- `calloc` `cresize` `cfree` -
+These functions simply call `raw_alloc`, `raw_resize` and `raw_free` using `context.allocator` as the allocator. These are effectively the equivalent of `malloc`, `realloc`, and `free` in C.
+
+- `new` -
+This function allocates enough space for the given type from the given allocator, which by default is the context's allocator. It also initializes the resulting memory, which uses the `__initialize` intrinsic that initializes all types, but most importantly it evalutes the default values for struct members.
+
+- `make` -
+This function is like new, except it does not initialize the memory.
+
+- `Iterator` -
+This type represents a custom iterator that can be iterated over using a `for` loop. It has three members. `data`, a simple pointer passed to the other functions. `next` which provides the next value for the iterator, and a continuation boolean. If the boolean is false, the iterator is done and the value given is garbage. And finally `close`, which is optional and allows you to run code when the iterator is done being used. When using a `for` loop, `close` is called automatically for you when the loop exits in any way.
+
+- `CallSite` -
+This type represents the value given by the `#callsite` expression. In practice, you will never use this type because you will just do something like: `f :: (site := #callsite)`
+
+- `any` -
+This type represents any value. It does this by using a data pointer and a type expression. Using the `builtin.type_info` package, you can introspect that type expression to retrieve data about the type, and from there reconstruct how to use the data pointer. See `conv.onyx` for how this works with `printf`.
+
+- `Code` -
+This is a dummy type that represents the type of a `#code {}` block. It is used when passing code around to macros or procedures, i.e. `f :: macro (body: Code)`
\ No newline at end of file