#pragma once // ------------------------------------------------------------------------ // Standard library #include #include #include #include #include #include #include #include #include #include // ---------------------------------------------------------------------------- // Dynamic array. typedef struct bufHdr { vlong len; vlong cap; byte buf[]; } bufHdr; #define _bufHdr(s) ((bufHdr*)((uint8*)(s)-offsetof(bufHdr, buf))) #define buflen(s) ((s) ? (_bufHdr(s)->len) : 0) #define bufcap(s) ((s) ? (_bufHdr(s)->cap) : 0) #define bufend(s) ((s) + buflen(s)) #define bufsize(s) ((s) ? (buflen(s) * sizeof((s)[0])) : 0) #define buffree(s) ((s) ? (free(_bufHdr(s)), (s) = nil) : 0) #define buffit(s, n) ((n) <= bufcap(s) ? 0 : ((s) = bufgrow((s), (n), sizeof(*(s))))) #define bufresize(s, n) \ do { \ (buffit(s, n)); \ ((_bufHdr(s)->len) = (n)); \ } while (0) #define bufpush(s, ...) (buffit((s), 1 + buflen(s)), (s)[_bufHdr(s)->len++] = (__VA_ARGS__)) #define bufpop(s, i) (_bufpop((s), (i), sizeof(*(s))), (s)[_bufHdr(s)->len]) void* bufgrow(void*, vlong, vlong); void _bufpop(void*, int, vlong); // ----------------------------------------------------------------------------- // Memory allocation typedef struct mem·Allocator { void *(*alloc)(ulong size); void *(*realloc)(void *ptr, ulong size); void (*free)(void *ptr); } mem·Allocator; static mem·Allocator mem·sys = { .alloc = &malloc, .realloc = &realloc, .free = &free }; typedef struct mem·Arena mem·Arena; mem·Arena *mem·newarena(mem·Allocator from); void *mem·arenaalloc(mem·Arena *A, ulong size); void mem·freearena(mem·Arena *A); // ----------------------------------------------------------------------------- // Co-routines typedef struct Coro Coro; Coro* coro·new(uintptr stk, uintptr (*func)(Coro*, uintptr)); uintptr coro·yield(Coro *c, uintptr arg); error coro·free(Coro *c); // ----------------------------------------------------------------------------- // Strings // TODO(nnoll): Move here? #include ".include/str.h" // ----------------------------------------------------------------------------- // Maps or dictionaries #include ".include/map.h" // ----------------------------------------------------------------------------- // I/O typedef FILE Stream; enum SeekPos { seek·CUR = SEEK_CUR, seek·SET = SEEK_SET, seek·END = SEEK_END }; Stream *io·open(byte *name, byte *mode); error io·close(Stream *s); byte io·getbyte(Stream *s); error io·ungetbyte(Stream *s, byte c); vlong io·read(Stream *s, int sz, int n, void *buf); int io·readln(Stream *s, int n, byte* buf); error io·putbyte(Stream *s, byte c); int io·putstring(Stream *s, string str); vlong io·write(Stream *s, int sz, int n, void *buf); int io·flush(Stream *s); int io·seek(Stream *s, long off, enum SeekPos origin); // ----------------------------------------------------------------------------- // Buffered I/O // ----------------------------------------------------------------------------- // Error handling functions. void errorf(const byte* fmt, ...); #define panicf(...) (errorf(__VA_ARGS__), assert(0))