Compare commits

..

3 Commits

Author SHA1 Message Date
Ed_
e49fc3964f Improved str8__fmt_kt1l (watl.v0.msvc.c), need to propogate change to other versions 2025-10-10 21:29:21 -04:00
Ed_
2bf18e8241 Making adjustments to C versions, update readme 2025-10-10 20:47:38 -04:00
Ed_
7949d2ba5f Remove gencpp_c11 for now (not using yet, maybe I'll do a truncated version)
Prepparing to explore Lottes's C-- more, also how crufty it looks in odin.
2025-10-10 19:28:36 -04:00
8 changed files with 222 additions and 29314 deletions

File diff suppressed because it is too large Load Diff

61
C/watl.v0.llvm.lottes.c Normal file
View File

@@ -0,0 +1,61 @@
/*
WATL Exercise
Version: 0 (From Scratch, 1-Stage Compilation, LLVM & WinAPI Only, Win CRT Multi-threaded Static Linkage)
Host: Windows 11 (x86-64)
Toolchain: LLVM (2025-08-30), C-Stanard: 11
Following strictly: Neokineogfx - Fixing C
https://youtu.be/RrL7121MOeA
*/
#pragma clang diagnostic ignored "-Wunused-const-variable"
#pragma clang diagnostic ignored "-Wunused-but-set-variable"
#pragma clang diagnostic ignored "-Wswitch"
#pragma clang diagnostic ignored "-Wunused-variable"
#pragma clang diagnostic ignored "-Wunknown-pragmas"
#pragma clang diagnostic ignored "-Wvarargs"
#pragma clang diagnostic ignored "-Wunused-function"
#pragma clang diagnostic ignored "-Wbraced-scalar-init"
#pragma clang diagnostic ignored "-W#pragma-messages"
#pragma clang diagnostic ignored "-Wstatic-in-inline"
#pragma clang diagnostic ignored "-Wkeyword-macro"
#pragma clang diagnostic ignored "-Wc23-compat"
#pragma clang diagnostic ignored "-Wreserved-identifier"
#pragma clang diagnostic ignored "-Wpre-c11-compat"
#pragma clang diagnostic ignored "-Wc23-extensions"
#pragma clang diagnostic ignored "-Wunused-macros"
#pragma clang diagnostic ignored "-Wdeclaration-after-statement"
#pragma clang diagnostic ignored "-Wunsafe-buffer-usage"
#pragma clang diagnostic ignored "-Wc++-keyword"
#pragma clang diagnostic ignored "-Wimplicit-function-declaration"
#pragma clang diagnostic ignored "-Wcast-align"
#pragma clang diagnostic ignored "-Wunused-parameter"
#pragma clang diagnostic ignored "-Wswitch-default"
#pragma clang diagnostic ignored "-Wmissing-field-initializers"
#pragma clang diagnostic ignored "-Wgnu-zero-variadic-macro-arguments"
#pragma clang diagnostic ignored "-Wpointer-sign"
#pragma region Header
#pragma region DSL
#define A_(x) __attribute__((aligned (x)))
#define E_(x,y) __builtin_expect(x,y)
#define S_ static
#define I_ static inline __attribute__((always_inline))
#define N_ static __attribute__((noinline))
#define R_ __restrict
#define V_ volatile
#define W_ __attribute((__stdcall__)) __attribute__((__force_align_arg_pointer__))
#pragma endregion DSL
#pragma endregion Header
#pragma region Implementation
#pragma endregion Implementation
int main(void)
{
return 0;
}
#pragma clang diagnostic pop

View File

@@ -4,7 +4,7 @@ Version: 0 (From Scratch, 1-Stage Compilation, LLVM & WinAPI Only, Win CRT Mul
Host: Windows 11 (x86-64)
Toolchain: LLVM (2025-08-30), C-Stanard: 11
Based on: Neokineogfx - Fixing C
Based on: Neokineogfx - Fixing C, personalized to include typeinfo more readily.
https://youtu.be/RrL7121MOeA
*/
@@ -39,21 +39,6 @@ https://youtu.be/RrL7121MOeA
#pragma region Header
#pragma region DSL
#if 0
// Original macros
#define A_(x) __attribute__((aligned (x)))
#define E_(x,y) __builtin_expect(x,y)
#define S_ static
#define I_ static inline __attribute__((always_inline))
#define N_ static __attribute__((noinline))
#define R_ __restrict
#define V_ volatile
#define W_ __attribute((__stdcall__)) __attribute__((__force_align_arg_pointer__))
#endif
// Ones I'm deciding to use..
#define align_(value) __attribute__((aligned (value))) // for easy alignment
#define expect_(x, y) __builtin_expect(x, y) // so compiler knows the common path
#define finline static inline __attribute__((always_inline)) // force inline
@@ -130,6 +115,9 @@ enum { false = 0, true = 1, true_overflow, };
#define offset_of(type, member) cast(U8, & (((type*) 0)->member))
#define size_of(data) cast(U8, sizeof(data))
#define r_(ptr) cast(typeof_ptr(ptr)*R_, ptr)
#define v_(ptr) cast(typeof_ptr(ptr)*V_, ptr)
#define kilo(n) (cast(U8, n) << 10)
#define mega(n) (cast(U8, n) << 20)
#define giga(n) (cast(U8, n) << 30)
@@ -158,17 +146,17 @@ def_signed_ops(ge, >=) def_signed_ops(le, <=)
#define ge_s(a,b) def_generic_sop(ge, a,b)
#define le_s(a,b) def_generic_sop(le, a,b)
finline U4 AtmAdd_u4 (U4_R a, U4 v){__asm__ volatile("lock xaddl %0,%1":"=r"(v),"=m"(*a):"0"(v),"m"(*a):"memory","cc");return v;}
finline U8 AtmAdd_u8 (U8_R a, U8 v){__asm__ volatile("lock xaddq %0,%1":"=r"(v),"=m"(*a):"0"(v),"m"(*a):"memory","cc");return v;}
finline U4 AtmSwap_u4(U4_R a, U4 v){__asm__ volatile("lock xchgl %0,%1":"=r"(v),"=m"(*a):"0"(v),"m"(*a):"memory","cc");return v;}
finline U8 AtmSwap_u8(U8_R a, U8 v){__asm__ volatile("lock xchgq %0,%1":"=r"(v),"=m"(*a):"0"(v),"m"(*a):"memory","cc");return v;}
finline U4 atm_add_u4 (U4_R a, U4 v){__asm__ volatile("lock xaddl %0,%1":"=r"(v),"=m"(*a):"0"(v),"m"(*a):"memory","cc");return v;}
finline U8 atm_add_u8 (U8_R a, U8 v){__asm__ volatile("lock xaddq %0,%1":"=r"(v),"=m"(*a):"0"(v),"m"(*a):"memory","cc");return v;}
finline U4 atm_swap_u4(U4_R a, U4 v){__asm__ volatile("lock xchgl %0,%1":"=r"(v),"=m"(*a):"0"(v),"m"(*a):"memory","cc");return v;}
finline U8 atm_swap_u8(U8_R a, U8 v){__asm__ volatile("lock xchgq %0,%1":"=r"(v),"=m"(*a):"0"(v),"m"(*a):"memory","cc");return v;}
#pragma endregion DSL
#pragma region Strings
typedef unsigned char def_tset(UTF8);
typedef def_struct(Str8) { UTF8*R_ ptr; U8 len; }; typedef Str8 def_tset(Slice_UTF8);
typedef def_struct(Slice_Str8) { Str8*R_ ptr; U8 len; };
#define lit(string_literal) (Str8){ (UTF8*R_) string_literal, size_of(string_literal) - 1 }
typedef def_struct(Str8) { UTF8* ptr; U8 len; }; typedef Str8 def_tset(Slice_UTF8);
typedef def_struct(Slice_Str8) { Str8* ptr; U8 len; };
#define lit(string_literal) (Str8){ (UTF8*) string_literal, size_of(string_literal) - 1 }
#pragma endregion Strings
#pragma region Debug
@@ -217,10 +205,10 @@ U8 mem_copy (U8 dest, U8 src, U8 length);
U8 mem_copy_overlapping(U8 dest, U8 src, U8 length);
B4 mem_zero (U8 dest, U8 length);
finline void BarC(void){__asm__ volatile("::""memory");} // Compiler Barrier
finline void BarM(void){__builtin_ia32_mfence();} // Memory Barrier
finline void BarR(void){__builtin_ia32_lfence();} // Read Barrier
finline void BarW(void){__builtin_ia32_sfence();} // Write Barrier
finline void barrier_compiler(void){__asm__ volatile("::""memory");} // Compiler Barrier
finline void barrier_memory (void){__builtin_ia32_mfence();} // Memory Barrier
finline void barrier_read (void){__builtin_ia32_lfence();} // Read Barrier
finline void barrier_write (void){__builtin_ia32_sfence();} // Write Barrier
#define check_nil(nil, p) ((p) == 0 || (p) == nil)
#define set_nil(nil, p) ((p) = nil)
@@ -241,7 +229,7 @@ finline void BarW(void){__builtin_ia32_sfence();} // Write Barrier
)
#define sll_queue_push_n(f, l, n, next) sll_queue_push_nz(0, f, l, n, next)
#define def_Slice(type) def_struct(tmpl(Slice,type)) { type*R_ ptr; U8 len; }; typedef def_ptr_set(tmpl(Slice,type))
#define def_Slice(type) def_struct(tmpl(Slice,type)) { type* ptr; U8 len; }; typedef def_ptr_set(tmpl(Slice,type))
#define slice_assert(slice) do { assert((slice).ptr != 0); assert((slice).len > 0); } while(0)
#define slice_end(slice) ((slice).ptr + (slice).len)
#define size_of_slice_type(slice) size_of( (slice).ptr[0] )
@@ -252,7 +240,7 @@ typedef def_struct(Slice_Mem) { U8 ptr; U8 len; };
typedef def_Slice(void);
typedef def_Slice(B1);
#define slice_byte(slice) ((Slice_B1){cast(B1_R, (slice).ptr), (slice).len * size_of_slice_type(slice)})
#define slice_byte(slice) ((Slice_B1){cast(B1*, (slice).ptr), (slice).len * size_of_slice_type(slice)})
#define slice_fmem(mem) slice_mem(u8_(mem), size_of(mem))
finline void slice__copy(Slice_B1 dest, U8 dest_typewidth, Slice_B1 src, U8 src_typewidth);
@@ -386,8 +374,8 @@ finline Slice_Mem mem__shrink(AllocatorInfo ainfo, Slice_Mem mem, U8 size, Opts_
#define mem_resize(ainfo, mem, size, ...) mem__resize(ainfo, mem, size, opt_args(Opts_mem_resize, __VA_ARGS__))
#define mem_shrink(ainfo, mem, size, ...) mem__shrink(ainfo, mem, size, opt_args(Opts_mem_shrink, __VA_ARGS__))
#define alloc_type(ainfo, type, ...) (type*R_) mem__alloc(ainfo, size_of(type), opt_args(Opts_mem_alloc, __VA_ARGS__)).ptr
#define alloc_slice(ainfo, type, num, ...) (tmpl(Slice,type)){ (type*R_)mem__alloc(ainfo, size_of(type) * num, opt_args(Opts_mem_alloc, __VA_ARGS__)).ptr, num }
#define alloc_type(ainfo, type, ...) (type*) mem__alloc(ainfo, size_of(type), opt_args(Opts_mem_alloc, __VA_ARGS__)).ptr
#define alloc_slice(ainfo, type, num, ...) (tmpl(Slice,type)){ (type*)mem__alloc(ainfo, size_of(type) * num, opt_args(Opts_mem_alloc, __VA_ARGS__)).ptr, num }
#pragma endregion Allocator Interface
#pragma region FArena (Fixed-Sized Arena)
@@ -420,8 +408,8 @@ cast(type*R_, farena__push(arena, size_of(type), 1, opt_args(Opts_farena, lit(st
#pragma endregion FArena
#pragma region OS
finline U8 Clk (void){U8 aa,dd;__asm__ volatile("rdtsc":"=a"(aa),"=d"(dd));return aa;}
finline void Pause(void){__asm__ volatile("pause":::"memory");}
finline U8 clock(void){U8 aa,dd;__asm__ volatile("rdtsc":"=a"(aa),"=d"(dd));return aa;}
finline void pause(void){__asm__ volatile("pause":::"memory");}
typedef def_struct(OS_SystemInfo) {
U8 target_page_size;
@@ -463,7 +451,7 @@ typedef def_struct(Opts_varena_make) {
VArenaFlags flags;
A4_B1 _PAD_;
};
VArena_R varena__make(Opts_varena_make*R_ opts);
VArena* varena__make(Opts_varena_make*R_ opts);
#define varena_make(...) varena__make(opt_args(Opts_varena_make, __VA_ARGS__))
Slice_Mem varena__push (VArena_R arena, U8 amount, U8 type_width, Opts_varena*R_ opts);
@@ -479,7 +467,7 @@ void varena_allocator_proc(AllocatorProc_In in, AllocatorProc_Out_R out);
#define varena_push_mem(arena, amount, ...) varena__push(arena, amount, 1, opt_args(Opts_varena, lit(stringify(B1)), __VA_ARGS__))
#define varena_push(arena, type, ...) \
cast(type*R_, varena__push(arena, 1, size_of(type), opt_args(Opts_varena, lit(stringify(type)), __VA_ARGS__) ).ptr)
cast(type*, varena__push(arena, 1, size_of(type), opt_args(Opts_varena, lit(stringify(type)), __VA_ARGS__) ).ptr)
#define varena_push_array(arena, type, amount, ...) \
(tmpl(Slice,type)){ varena__push(arena, size_of(type), amount, opt_args(Opts_varena, lit(stringify(type)), __VA_ARGS__)).ptr, amount }
@@ -492,16 +480,16 @@ typedef def_enum(U4, ArenaFlags) {
ArenaFlag_NoChain = (1 << 1),
};
typedef def_struct(Arena) {
VArena_R backing;
Arena_R prev;
Arena_R current;
VArena* backing;
Arena* prev;
Arena* current;
U8 base_pos;
U8 pos;
ArenaFlags flags;
A4_B1 _PAD_;
};
typedef Opts_varena_make Opts_arena_make;
Arena_R arena__make (Opts_arena_make*R_ opts);
Arena* arena__make (Opts_arena_make*R_ opts);
Slice_Mem arena__push (Arena_R arena, U8 amount, U8 type_width, Opts_arena*R_ opts);
finline void arena_release(Arena_R arena);
finline void arena_reset (Arena_R arena);
@@ -580,7 +568,7 @@ def_struct(tmpl(KT1CX_Slot,type)) { \
#define def_KT1CX_Cell(type, depth) \
def_struct(tmpl(KT1CX_Cell,type)) { \
tmpl(KT1CX_Slot,type) slots[depth]; \
tmpl(KT1CX_Slot,type)*R_ next; \
tmpl(KT1CX_Slot,type)* next; \
}
#define def_KT1CX(type) \
def_struct(tmpl(KT1CX,type)) { \
@@ -651,7 +639,7 @@ typedef def_Slice(A2_Str8);
typedef def_KT1L_Slot(Str8);
typedef def_KT1L(Str8);
finline Str8 str8__fmt_backed(AllocatorInfo tbl_backing, AllocatorInfo buf_backing, Str8 fmt_template, Slice_A2_Str8* entries);
finline Str8 str8__fmt_backed(AllocatorInfo tbl_backing, AllocatorInfo buf_backing, Str8 fmt_template, Slice_A2_Str8*R_ entries);
#define str8_fmt_backed(tbl_backing, buf_backing, fmt_template, ...) \
str8__fmt_backed(tbl_backing, buf_backing, lit(fmt_template), slice_arg_from_array(A2_Str8, __VA_ARGS__))
@@ -692,7 +680,7 @@ finline Str8 cache_str8(Str8Cache_R cache, Str8 str);
typedef def_struct(Str8Gen) {
AllocatorInfo backing;
UTF8_R ptr;
UTF8* ptr;
U8 len;
U8 cap;
};
@@ -722,7 +710,7 @@ void api_file_read_contents(FileOpInfo_R result, Str8 path, Opts_read_file_conte
void file_write_str8 (Str8 path, Str8 content);
finline FileOpInfo file__read_contents(Str8 path, Opts_read_file_contents*R_ opts);
#define file_read_contents(path, ...) file__read_contents(path, &(Opts_read_file_contents){__VA_ARGS__})
#define file_read_contents(path, ...) file__read_contents(path, opt_args(Opts_read_file_contents, __VA_ARGS__))
#pragma endregion File System
#pragma region WATL
@@ -743,13 +731,13 @@ typedef def_struct(WATL_Pos) {
S4 column;
};
typedef def_struct(WATL_LexMsg) {
WATL_LexMsg_R next;
WATL_LexMsg* next;
Str8 content;
WATL_Tok_R tok;
WATL_Tok* tok;
WATL_Pos pos;
};
typedef def_struct(WATL_LexInfo) {
WATL_LexMsg_R msgs;
WATL_LexMsg* msgs;
Slice_WATL_Tok toks;
WATL_LexStatus signal;
A4_B1 _PAD_;
@@ -764,17 +752,17 @@ typedef def_struct(Opts_watl_lex) {
};
void api_watl_lex(WATL_LexInfo_R info, Str8 source, Opts_watl_lex*R_ opts);
WATL_LexInfo watl__lex ( Str8 source, Opts_watl_lex*R_ opts);
#define watl_lex(source, ...) watl__lex(source, &(Opts_watl_lex){__VA_ARGS__})
#define watl_lex(source, ...) watl__lex(source, opt_args(Opts_watl_lex, __VA_ARGS__))
typedef Str8 WATL_Node; typedef def_ptr_set(WATL_Node);
typedef def_Slice(WATL_Node);
typedef Slice_WATL_Node def_tset(WATL_Line);
typedef def_Slice(WATL_Line);
typedef def_struct(WATL_ParseMsg) {
WATL_ParseMsg_R next;
WATL_ParseMsg* next;
Str8 content;
WATL_Line_R line;
WATL_Tok_R tok;
WATL_Line* line;
WATL_Tok* tok;
WATL_Pos pos;
};
typedef def_enum(U4, WATL_ParseStatus) {
@@ -782,7 +770,7 @@ typedef def_enum(U4, WATL_ParseStatus) {
};
typedef def_struct(WATL_ParseInfo) {
Slice_WATL_Line lines;
WATL_ParseMsg_R msgs;
WATL_ParseMsg* msgs;
WATL_ParseStatus signal;
A4_B1 _PAD_;
};
@@ -790,13 +778,13 @@ typedef def_struct(Opts_watl_parse) {
AllocatorInfo ainfo_msgs;
AllocatorInfo ainfo_nodes;
AllocatorInfo ainfo_lines;
Str8Cache_R str_cache;
Str8Cache* str_cache;
B4 failon_slice_constraint_fail;
A4_B1 _PAD_;
};
void api_watl_parse(WATL_ParseInfo_R info, Slice_WATL_Tok tokens, Opts_watl_parse*R_ opts);
WATL_ParseInfo watl__parse ( Slice_WATL_Tok tokens, Opts_watl_parse*R_ opts);
#define watl_parse(tokens, ...) watl__parse(tokens, &(Opts_watl_parse){__VA_ARGS__})
#define watl_parse(tokens, ...) watl__parse(tokens, opt_args(Opts_watl_parse, __VA_ARGS__))
Str8 watl_dump_listing(AllocatorInfo buffer, Slice_WATL_Line lines);
#pragma endregion WATL
@@ -1148,7 +1136,7 @@ inline void os_vmem_release(U8 vm, U8 size) { VirtualFree(cast(MS_LPVOID, vm),
#pragma region VArena (Virutal Address Space Arena)
inline
VArena_R varena__make(Opts_varena_make*R_ opts) {
VArena* varena__make(Opts_varena_make*R_ opts) {
assert(opts != nullptr);
if (opts->reserve_size == 0) { opts->reserve_size = mega(64); }
if (opts->commit_size == 0) { opts->commit_size = mega(64); }
@@ -1159,8 +1147,8 @@ VArena_R varena__make(Opts_varena_make*R_ opts) {
assert(base != 0);
os_vmem_commit(base, commit_size, .no_large_pages = no_large_pages);
U8 header_size = align_pow2(size_of(VArena), MEMORY_ALIGNMENT_DEFAULT);
VArena_R vm = cast(VArena_R, base);
vm[0] = (VArena){
VArena* vm = cast(VArena*, base);
r_(vm)[0] = (VArena){
.reserve_start = base + header_size,
.reserve = reserve_size,
.commit_size = commit_size,
@@ -1294,13 +1282,13 @@ void varena_allocator_proc(AllocatorProc_In in, AllocatorProc_Out* out)
#pragma region Arena (Chained Arena)
inline
Arena_R arena__make(Opts_arena_make*R_ opts) {
Arena* arena__make(Opts_arena_make*R_ opts) {
assert(opts != nullptr);
U8 header_size = align_pow2(size_of(Arena), MEMORY_ALIGNMENT_DEFAULT);
VArena_R current = varena__make(opts);
assert(current != nullptr);
Arena_R arena = varena_push(current, Arena);
arena[0] = (Arena){
Arena* arena = varena_push(current, Arena);
r_(arena)[0] = (Arena){
.backing = current,
.prev = nullptr,
.current = arena,

View File

@@ -16,78 +16,62 @@ Toolchain: MSVC 19.43, C-Stanard: 11
#pragma region Header
#pragma region DSL
typedef unsigned __int8 U8;
typedef signed __int8 S8;
typedef unsigned __int16 U16;
typedef signed __int16 S16;
typedef unsigned __int32 U32;
typedef signed __int32 S32;
typedef unsigned __int64 U64;
typedef signed __int64 S64;
typedef unsigned char Byte;
typedef unsigned __int64 USIZE;
typedef __int64 SSIZE;
typedef S8 B8;
typedef S16 B16;
typedef S32 B32;
enum {
false = 0,
true = 1,
true_overflow,
};
#define glue_impl(A, B) A ## B
#define glue(A, B) glue_impl(A, B)
#define stringify_impl(S) #S
#define stringify(S) stringify_impl(S)
#define tmpl(prefix, type) prefix ## _ ## type
#define local_persist static
#define global static
#define internal static
#define static_assert _Static_assert
#define typeof __typeof__
#define typeof_ptr(ptr) typeof(ptr[0])
#define typeof_same(a, b) _Generic((a), typeof((b)): 1, default: 0)
typedef unsigned __int8 U8; typedef unsigned __int16 U16; typedef unsigned __int32 U32; typedef unsigned __int64 U64;
typedef signed __int8 S8; typedef signed __int16 S16; typedef signed __int32 S32; typedef signed __int64 S64;
typedef unsigned char Byte; typedef S8 B8; typedef S16 B16; typedef S32 B32;
typedef unsigned __int64 USIZE; typedef __int64 SSIZE;
typedef float F32; typedef double F64;
enum { false = 0, true = 1, true_overflow, };
#define farray_len(array) (SSIZE)sizeof(array) / size_of( typeof((array)[0]))
#define farray_init(type, ...) (type[]){__VA_ARGS__}
#define alignas _Alignas
#define alignof _Alignof
#define byte_pad(amount, ...) Byte glue(_PAD_, __VA_ARGS__) [amount]
#define farray_len(array) (SSIZE)sizeof(array) / size_of( typeof((array)[0]))
#define farray_init(type, ...) (type[]){__VA_ARGS__}
#define def_farray(type, len) type A ## len ## _ ## type[len]
#define def_enum(underlying_type, symbol) underlying_type symbol; enum symbol
#define def_struct(symbol) struct symbol symbol; struct symbol
#define def_union(symbol) union symbol symbol; union symbol
#define def_proc(symbol) symbol
#define opt_args(symbol, ...) &(symbol){__VA_ARGS__}
#define ret_type(type) type
#define local_persist static
#define global static
#define offset_of(type, member) cast(SSIZE, & (((type*) 0)->member))
#define static_assert _Static_assert
#define typeof __typeof__
#define typeof_ptr(ptr) typeof(ptr[0])
#define typeof_same(a, b) _Generic((a), typeof((b)): 1, default: 0)
#define cast(type, data) ((type)(data))
#define pcast(type, data) * cast(type*, & (data))
#define nullptr cast(void*, 0)
#define offset_of(type, member) cast(SSIZE, & (((type*) 0)->member))
#define size_of(data) cast(SSIZE, sizeof(data))
#define kilo(n) (cast(SSIZE, n) << 10)
#define mega(n) (cast(SSIZE, n) << 20)
#define giga(n) (cast(SSIZE, n) << 30)
#define tera(n) (cast(SSIZE, n) << 40)
#define span_iter(type, iter, m_begin, op, m_end) \
tmpl(Iter_Span,type) iter = { \
.r = {(m_begin), (m_end)}, \
.cursor = (m_begin) }; \
iter.cursor op iter.r.end; \
++ iter.cursor
#define def_span(type) \
def_struct(tmpl( Span,type)) { type begin; type end; }; \
typedef def_struct(tmpl(Iter_Span,type)) { tmpl(Span,type) r; type cursor; }
typedef def_span(S32);
typedef def_span(U32);
typedef def_span(SSIZE);
typedef void def_proc(VoidFn) (void);
#pragma endregion DSL
#pragma region Strings
typedef unsigned char UTF8;
typedef def_struct(Str8) { UTF8* ptr; SSIZE len; }; typedef Str8 Slice_UTF8;
typedef def_struct(Slice_Str8) { Str8* ptr; SSIZE len; };
#define lit(string_literal) (Str8){ (UTF8*) string_literal, size_of(string_literal) - 1 }
#pragma endregion Strings
#pragma region Debug
#if !defined(BUILD_DEBUG)
#define debug_trap()
@@ -133,6 +117,25 @@ void* memory_copy (void* restrict dest, void const* restrict src, USI
void* memory_copy_overlapping(void* restrict dest, void const* restrict src, USIZE length);
B32 memory_zero (void* dest, USIZE length);
#define check_nil(nil, p) ((p) == 0 || (p) == nil)
#define set_nil(nil, p) ((p) = nil)
#define sll_stack_push_n(f, n, next) do { (n)->next = (f); (f) = (n); } while(0)
#define sll_queue_push_nz(nil, f, l, n, next) \
( \
check_nil(nil, f) ? ( \
(f) = (l) = (n), \
set_nil(nil, (n)->next) \
) \
: ( \
(l)->next=(n), \
(l) = (n), \
set_nil(nil,(n)->next) \
) \
)
#define sll_queue_push_n(f, l, n, next) sll_queue_push_nz(0, f, l, n, next)
#define def_Slice(type) \
def_struct(tmpl(Slice,type)) { \
type* ptr; \
@@ -164,24 +167,20 @@ void slice__zero(Slice_Byte mem, SSIZE typewidth);
.len = farray_len( farray_init(type, __VA_ARGS__)) \
}
#define check_nil(nil, p) ((p) == 0 || (p) == nil)
#define set_nil(nil, p) ((p) = nil)
#define span_iter(type, iter, m_begin, op, m_end) \
tmpl(Iter_Span,type) iter = { \
.r = {(m_begin), (m_end)}, \
.cursor = (m_begin) }; \
iter.cursor op iter.r.end; \
++ iter.cursor
#define sll_stack_push_n(f, n, next) do { (n)->next = (f); (f) = (n); } while(0)
#define def_span(type) \
def_struct(tmpl( Span,type)) { type begin; type end; }; \
typedef def_struct(tmpl(Iter_Span,type)) { tmpl(Span,type) r; type cursor; }
#define sll_queue_push_nz(nil, f, l, n, next) \
( \
check_nil(nil, f) ? ( \
(f) = (l) = (n), \
set_nil(nil, (n)->next) \
) \
: ( \
(l)->next=(n), \
(l) = (n), \
set_nil(nil,(n)->next) \
) \
)
#define sll_queue_push_n(f, l, n, next) sll_queue_push_nz(0, f, l, n, next)
typedef def_span(S32);
typedef def_span(U32);
typedef def_span(SSIZE);
#pragma endregion Memory
#pragma region Math
@@ -190,14 +189,6 @@ void slice__zero(Slice_Byte mem, SSIZE typewidth);
#define clamp_bot(X, B) max(X, B)
#pragma endregion Math
#pragma region Strings
typedef unsigned char UTF8;
typedef def_Slice(UTF8);
typedef Slice_UTF8 Str8;
typedef def_Slice(Str8);
#define lit(string_literal) (Str8){ (UTF8*) string_literal, size_of(string_literal) - 1 }
#pragma endregion Strings
#pragma region Allocator Interface
typedef def_enum(U32, AllocatorOp) {
AllocatorOp_Alloc_NoZero = 0, // If Alloc exist, so must No_Zero
@@ -604,16 +595,16 @@ void str8gen__append_fmt(Str8Gen* gen, Str8 fmt_template, Slice_A2_Str8* tokens)
typedef def_struct(FileOpInfo) {
Slice_Byte content;
};
typedef def_struct(Opts_read_file_contents) {
typedef def_struct(Opts_file_read_contents) {
AllocatorInfo backing;
B32 zero_backing;
byte_pad(4);
};
void api_file_read_contents(FileOpInfo* result, Str8 path, Opts_read_file_contents opts);
void api_file_read_contents(FileOpInfo* result, Str8 path, Opts_file_read_contents opts);
void file_write_str8 (Str8 path, Str8 content);
FileOpInfo file__read_contents(Str8 path, Opts_read_file_contents* opts);
#define file_read_contents(path, ...) file__read_contents(path, &(Opts_read_file_contents){__VA_ARGS__})
FileOpInfo file__read_contents(Str8 path, Opts_file_read_contents* opts);
#define file_read_contents(path, ...) file__read_contents(path, opt_args(Opts_file_read_contents, __VA_ARGS__))
#pragma endregion File System
#pragma region WATL
@@ -655,7 +646,7 @@ typedef def_struct(Opts_watl_lex) {
};
void api_watl_lex(WATL_LexInfo* info, Str8 source, Opts_watl_lex* opts);
WATL_LexInfo watl__lex ( Str8 source, Opts_watl_lex* opts);
#define watl_lex(source, ...) watl__lex(source, &(Opts_watl_lex){__VA_ARGS__})
#define watl_lex(source, ...) watl__lex(source, opt_args(Opts_watl_lex, __VA_ARGS__))
typedef Str8 WATL_Node;
typedef def_Slice(WATL_Node);
@@ -687,7 +678,7 @@ typedef def_struct(Opts_watl_parse) {
};
void api_watl_parse(WATL_ParseInfo* info, Slice_WATL_Tok tokens, Opts_watl_parse* opts);
WATL_ParseInfo watl__parse ( Slice_WATL_Tok tokens, Opts_watl_parse* opts);
#define watl_parse(tokens, ...) watl__parse(tokens, &(Opts_watl_parse){__VA_ARGS__})
#define watl_parse(tokens, ...) watl__parse(tokens, opt_args(Opts_watl_parse, __VA_ARGS__))
Str8 watl_dump_listing(AllocatorInfo buffer, Slice_WATL_Line lines);
#pragma endregion WATL
@@ -1398,10 +1389,8 @@ void kt1cx_init(KT1CX_Info info, KT1CX_InfoMeta m, KT1CX_Byte* result) {
assert(m.cell_pool_size >= kilo(4));
assert(m.table_size >= kilo(4));
assert(m.type_width > 0);
result->table = mem_alloc(info.backing_table, m.table_size * m.cell_size);
slice_assert(result->table);
result->cell_pool = mem_alloc(info.backing_cells, m.cell_size * m.cell_pool_size);
slice_assert(result->cell_pool);
result->table = mem_alloc(info.backing_table, m.table_size * m.cell_size); slice_assert(result->table);
result->cell_pool = mem_alloc(info.backing_cells, m.cell_size * m.cell_pool_size); slice_assert(result->cell_pool);
result->table.len = m.table_size; // Setting to the table number of elements instead of byte length.
}
void kt1cx_clear(KT1CX_Byte kt, KT1CX_ByteMeta m) {
@@ -1590,38 +1579,38 @@ Str8 str8__fmt_kt1l(AllocatorInfo ainfo, Slice_Byte* _buffer, KT1L_Str8 table, S
UTF8* cursor_buffer = buffer.ptr;
SSIZE buffer_remaining = buffer.len;
char curr_code = * fmt_template.ptr;
UTF8* cursor_fmt = fmt_template.ptr;
SSIZE left_fmt = fmt_template.len;
while (left_fmt && buffer_remaining)
{
SSIZE copy_offset = 0;
// Forward until we hit the delimiter '<' or the template's contents are exhausted.
while (curr_code && curr_code != '<' && cursor_fmt != slice_end(fmt_template)) {
* cursor_buffer = * cursor_fmt;
++ cursor_buffer;
++ cursor_fmt;
-- buffer_remaining;
-- left_fmt;
curr_code = * cursor_fmt;
while (cursor_fmt[copy_offset] != cast(UTF8, '<') && (cursor_fmt + copy_offset) != slice_end(fmt_template)) {
++ copy_offset;
}
if (curr_code == '<')
memory_copy(cursor_buffer, cursor_fmt, copy_offset);
buffer_remaining -= copy_offset;
left_fmt -= copy_offset;
cursor_buffer += copy_offset;
cursor_fmt += copy_offset;
if (cursor_fmt[0] == '<')
{
UTF8* cursor_potential_token = cursor_fmt + 1;
SSIZE potential_token_length = 0;
UTF8* potential_token_cursor = cursor_fmt + 1;
SSIZE potential_token_len = 0;
B32 fmt_overflow = false;
for (;;) {
UTF8* cursor = cursor_potential_token + potential_token_length;
UTF8* cursor = potential_token_cursor + potential_token_len;
fmt_overflow = cursor >= slice_end(fmt_template);
B32 found_terminator = * (cursor_potential_token + potential_token_length) == '>';
B32 found_terminator = * (potential_token_cursor + potential_token_len) == '>';
if (fmt_overflow || found_terminator) { break; }
++ potential_token_length;
++ potential_token_len;
}
if (fmt_overflow) continue;
// Hashing the potential token and cross checking it with our token table
U64 key = 0; hash64_djb8(& key, (Slice_Byte){ cast(Byte*, cursor_potential_token), potential_token_length});
U64 key = 0; hash64_djb8(& key, (Slice_Byte){ cast(Byte*, potential_token_cursor), potential_token_len});
Str8* value = nullptr;
for (slice_iter(table, token))
{
for (slice_iter(table, token)) {
// We do a linear iteration instead of a hash table lookup because the user should be never substiuting with more than 100 unqiue tokens..
if (token->key == key) {
value = & token->value;
@@ -1631,32 +1620,26 @@ Str8 str8__fmt_kt1l(AllocatorInfo ainfo, Slice_Byte* _buffer, KT1L_Str8 table, S
if (value)
{
// We're going to appending the string, make sure we have enough space in our buffer.
if (ainfo.proc != nullptr && (buffer_remaining - potential_token_length) <= 0) {
buffer = mem_grow(ainfo, buffer, buffer.len + potential_token_length);
buffer_remaining += potential_token_length;
}
SSIZE left = value->len;
U8* cursor_value = value->ptr;
while (left && buffer_remaining) {
* cursor_buffer = * cursor_value;
++ cursor_buffer;
++ cursor_value;
-- buffer_remaining;
-- left;
if (ainfo.proc != nullptr && (buffer_remaining - potential_token_len) <= 0) {
buffer = mem_grow(ainfo, buffer, buffer.len + potential_token_len);
buffer_remaining += potential_token_len;
}
assert((buffer_remaining - potential_token_len) > 0);
memory_copy(cursor_buffer, value->ptr, value->len);
// Sync cursor format to after the processed token
cursor_fmt = cursor_potential_token + potential_token_length + 1;
curr_code = * cursor_fmt;
left_fmt -= potential_token_length + 2; // The 2 here are the '<' & '>' delimiters being omitted.
cursor_buffer += value->len;
buffer_remaining -= value->len;
cursor_fmt = potential_token_cursor + potential_token_len + 1;
left_fmt -= potential_token_len + 2; // The 2 here are the '<' & '>' delimiters being omitted.
continue;
}
// If not a value, we do a single copy for the '<' and continue.
* cursor_buffer = * cursor_fmt;
++ cursor_buffer;
++ cursor_fmt;
-- buffer_remaining;
-- left_fmt;
curr_code = * cursor_fmt;
continue;
}
}
* _buffer = buffer;
@@ -1838,12 +1821,12 @@ __declspec(dllimport) MS_BOOL __stdcall GetFileSizeEx(MS_HANDLE hFile, MS_LARGE_
__declspec(dllimport) MS_DWORD __stdcall GetLastError(void);
inline
FileOpInfo file__read_contents(Str8 path, Opts_read_file_contents* opts) {
FileOpInfo file__read_contents(Str8 path, Opts_file_read_contents* opts) {
assert(opts != nullptr);
FileOpInfo result = {0}; api_file_read_contents(& result, path, * opts);
return result;
}
void api_file_read_contents(FileOpInfo* result, Str8 path, Opts_read_file_contents opts)
void api_file_read_contents(FileOpInfo* result, Str8 path, Opts_file_read_contents opts)
{
assert(result != nullptr);
slice_assert(path);

View File

View File

View File

@@ -1,12 +1,9 @@
# WATL Exercise
An exercise on making the "Whitespace Aware Text Layout" parser with different languages or conventions. It simply gets a structural idea of the lines and chunks (visbile and whitespace) for a text file.
The purpose of this exercise is convey succiently many core pragmatic concepts for code in a small program.
The intent was to use this as a working set of samples for my code visualizing and editing prototyping.
The code conveys a convention for doing "systems" programming I've synthesized after studying how several people in the "handmade" community have written their exposed libraries or codebases.
The goal of the exercise is always the following:
The goal of is always the following:
```odin
start:
@@ -19,6 +16,8 @@ start:
end
```
The exercise is done in several conventions but are generally pragmatic and relatively low abstraction. Favoring composition to construct anything. It succiently conveys many core pragmatic concepts for code in a small source file.
There are plans for multiple versions of the program:
* V0: Attempt todo a single-threaded example with as little support from the toolchain as possible within the domain of the language. With a single compilation stage.
@@ -33,6 +32,8 @@ Embeddable scripting languages will be embedded as they should be.
## TODOs
* Fix large-pages not working (at least on my system).
* [x] Single-threaded C example
* [] Multi-threaded C example
* [] Add basic timing benchmark to C examples

View File

@@ -131,7 +131,7 @@ $compiler_args += $flag_link_win_rt_static_debug
# Include setup
$compiler_args += ($flag_include + $path_root)
$unit_name = "watl.v0.lottes"
$unit_name = "watl.v0.llvm.lottes_hybrid"
# Specify unit to compile
$unit = join-path $path_root "C\$unit_name.c"