commit 673eb4d0566aa07e305be93020de39d5e30d2313 Author: Ed_ Date: Sun May 4 10:45:43 2025 -0400 initial commit diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..1ca209f --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +build +.vscode diff --git a/build.ps1 b/build.ps1 new file mode 100644 index 0000000..5eec485 --- /dev/null +++ b/build.ps1 @@ -0,0 +1,142 @@ +$devshell = join-path $PSScriptRoot 'devshell.ps1' + +if ($IsWindows) { + & $devshell -arch amd64 +} + +# https://learn.microsoft.com/en-us/cpp/build/reference/compiler-options-listed-by-category?view=msvc-170 +$flag_all_c = '/TC' +$flag_c11 = '/std:c11' +$flag_all_cpp = '/TP' +$flag_compile = '/c' +$flag_debug = '/Zi' +$flag_define = '/D' +$flag_exceptions_disabled = '/EHsc-' +$flag_RTTI_disabled = '/GR-' +$flag_include = '/I' +$flag_full_src_path = '/FC' +$flag_nologo = '/nologo' +$flag_dll = '/LD' +$flag_dll_debug = '/LDd' +$flag_linker = '/link' +# $flag_link_lib = '/lib' +$flag_link_dll = '/DLL' +$flag_link_no_incremental = '/INCREMENTAL:NO' +$flag_link_mapfile = '/MAP:' +$flag_link_optimize_references = '/OPT:REF' +$flag_link_win_debug = '/DEBUG' +$flag_link_win_pdb = '/PDB:' +$flag_link_win_machine_32 = '/MACHINE:X86' +$flag_link_win_machine_64 = '/MACHINE:X64' +$flag_link_win_path_output = '/OUT:' +$flag_link_win_rt_dll = '/MD' +$flag_link_win_rt_dll_debug = '/MDd' +$flag_link_win_rt_static = '/MT' +$flag_link_win_rt_static_debug = '/MTd' +$flag_link_win_subsystem_console = '/SUBSYSTEM:CONSOLE' +$flag_link_win_subsystem_windows = '/SUBSYSTEM:WINDOWS' +$flag_no_optimization = '/Od' +$flag_optimize_fast = '/O2' +$flag_optimize_size = '/O1' +$flag_optimize_intrinsics = '/Oi' +$flag_optimized_debug_forceinline = '/d2Obforceinline' +$flag_optimized_debug = '/Zo' +$flag_preprocess_to_file = '/P' +$flag_preprocess_preserve_comments = '/C' +# $flag_out_name = '/OUT:' +$flag_path_interm = '/Fo' +$flag_path_debug = '/Fd' +$flag_path_output = '/Fe' +$flag_preprocess_conform = '/Zc:preprocessor' +$flag_updated_cpp_macro = "/Zc:__cplusplus" +$flag_set_stack_size = '/F' +$flag_syntax_only = '/Zs' +$flag_wall = '/Wall' +$flag_warnings_as_errors = '/WX' +$flag_lib_list = '/LIST' + +$archiver = 'lib' +$compiler = 'cl' +$linker = 'link' + +$path_build = join-path $PSScriptRoot 'build' +if ( -not(test-path -Path $path_build) ) { + new-item -ItemType Directory -Path $path_build +} + +push-location $path_build + +$compiler_args = @() +$compiler_args += $flag_nologo + +# Constraints on interpeting all files as C code +$compiler_args += $flag_all_c +# Constraints on C program code-gen +$compiler_args += $flag_exceptions_disabled +$compiler_args += $flag_RTTI_disabled +$compiler_args += $flag_preprocess_conform + +# Dump preprocess file +if ($false) { + $compiler_args += $flag_preprocess_to_file + $compiler_args += $flag_preprocess_preserve_comments +} + +# Diagnostic loggign +$compiler_args += $flag_full_src_path + +# Specifing output pathing +$compiler_args += ( $flag_path_interm + $path_build + '\' ) +$compiler_args += ( $flag_path_output + $path_build + '\' ) + +$compiler_args += $flag_no_optimization + +# Debug setup +$compiler_args += $flag_debug +$compiler_args += ( $flag_path_debug + $path_build + '\' ) +$compiler_args += $flag_link_win_rt_static_debug + +# Include setup +$compiler_args += ($flag_include + $PSScriptRoot) + +# Specify unit to compile +$unit = join-path $PSScriptRoot 'demo.str_cache.c' +$compiler_args += $flag_compile, $unit + +# Diagnoistc print for the args +$compiler_args | ForEach-Object { Write-Host $_ } +write-host + +# $compiler_args += ( $flag_define + "DEMO_STR_SLICE" ) +# $compiler_args += ( $flag_define + "DEMO_STR_SLICE" ) + +# Compile the unit +& $compiler $compiler_args + +$binary = join-path $path_build 'demo.str_cache.exe' +$object = join-path $path_build 'demo.str_cache.obj' + +$pdb = join-path $path_build 'demo.str_cache.pdb' +$map = join-path $path_build 'demo.str_cache.map' + +if ($true) { + $linker_args = @() + $linker_args += $flag_nologo + $linker_args += $flag_link_win_machine_64 + $linker_args += $flag_link_no_incremental + $linker_args += ($flag_link_win_path_output + $binary) + + $linker_args += $flag_link_win_debug + $linker_args += $flag_link_win_pdb + $pdb + $linker_args += $flag_link_mapfile + $map + + $linker_args += $object + + # Diagnoistc print for the args + $linker_args | ForEach-Object { Write-Host $_ } + write-host + + & $linker $linker_args +} + +Pop-Location diff --git a/demo.str_cache.c b/demo.str_cache.c new file mode 100644 index 0000000..6e4745a --- /dev/null +++ b/demo.str_cache.c @@ -0,0 +1,193 @@ +/* +A introduction to C11 with a str cache demo. +Attempting to showcase better conventions and constructs in C; Discovered to me as of 2025 from scouring the internet. +*/ + +/* +The below will be implemented within this single file. +Because of this, definitions will be kept on a need-to-have basis to target only one vendor target and toolchain. +We will not use nearly any libraries and will be targeting only Windows 11 x64 using MSVC. +Even so the constructs defined and their dependencies can be properly abstracted into a ergonomic library for multiple targets with enough time and pain. + +AI prompting will be used as a search engine I'll be provding the prompts used to gather specific vendor API information thats not-memorized. +If the prompt fails it will be noted and I'll fallback to traditional search engines to derive a reference to a specific vendor API document. +*/ +#if 0 +int main() +{ + VArena cache_arena; varena_init(cache_arena); + StrCache cache = strcache_init(varena_ainfo(cache)); + + VArena file_arena; varena_init(file_arena); + Str path_text = lit("../demo.strcache.c"); + FileContent text_file = file_read_contents(varena_ainfo(file_arena), path_text); + + Arena ast_arena; arena_init(ast_arena); + + WATL_ParseOps ops = { .str_cache = &cache, .node_backing = arena_ainfo(ast_arena) } + WATL_ParsedInfo parsed = watl_parse(text_file.content, ops); + + watl_dbg_dump(parsed.root); + strcache_dbg_listing(cache); + return 0; +} +#endif + +/* +The above makes use of the following core concepts to achieve its net result: +* Slices +* Arenas +* Generic Runtime Allocator Interface +* Hashing + +Secondarily for the purposes of using the above sufficiently the following are also utilized: +* Virtual Address Space +* Read/Write Files +* Lexing & Parsing +* Debug printing + +TODO(Ed): Do we introduce gencpp in this? +*/ + +/* +First thing we'll problably want is a way to deal with text effectively. +So we'll setup the the minimum for that when dealing with immutable constructs. +*/ + +// We'll need some minimum set of dependencies to adequately define the constructs. +// ASSUMING MODERN MSVC TOOLCHAIN. + +#include +#include + +#include +#include +#include + +#include +#include + +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 size_t USIZE; +typedef ptrdiff_t SSIZE; + +// Functional style cast +#define cast(type, data) ((type)(data)) + +// Enforces size querying uses SSIZE type. +#define size_of(data) cast(SSIZE, data) + +/* +The first construct we'll utilize is a String Slice. +In modern programming with the memory sizes utilized, it is more ergonomic to track the length of strings with their pointer. +Most strings are not stored in some immutable table tracked statically, performance loss in doing so is negligble on modern hardware constraints. +*/ + +typedef struct Str8 Str8; +struct Str8 { + char const* ptr; + SSIZE len; +}; + +// String iterals in C include null-terminators, we aren't interested in preserving that. +#define lit(string_literal) (Str8){ string_literal, size_of(string_literal) - 1 }; + +// For now this string can visualized using a debugger. +// #define DEMO__STR_SLICE +#ifdef DEMO__STR_SLICE +int main() +{ + Str8 first = lit("Our first string as a slice"); + return 0; +} +#endif DEMO__STR_SLICE + +/* +We now want to be able to read a file. This will be a heavy rabbit-hole as we'll need to setup a basic file interface +and related definitions for handling the memory. + +For the purposes of the initial definition we'll introduced fixed-sized memory handling statically allocated onto the stack. +*/ + +/* +First off we need to find out how to aquire the contents of a file on Windows. + +We'll be wrapping the operation in a procedure called file_read_contents. We'll have it take a path and optional arguments (Opts__read_file_contents). +It will return a result in a composite struct: FileOpResult; which may be expanded as needed in the future. +*/ + +typedef struct FileOpResult FileOpResult; +typedef struct Opts__read_file_contents Opts__read_file_contents; +void file__read_contents(FileOpResult* result, Str8 path, Opts__read_file_contents* opts); +FileOpResult file_read_contents ( Str8 path, Opts__read_file_contents* opts); + +/* +The above is a pattern that can be provided so that whether or not the result is formatted and provided to the user via the stack is entirely optional. +*/ + +// Now for our "Version 1" + +#define DEMO__FILE_READ_CONTENTS_V1 +#ifdef DEMO__FILE_READ_CONTENTS_V1 + +/* +The file contents will be returned in bytes. +To view or manage any slice of bytes we'll be utilizing a byte slice. +*/ +typedef struct SliceByte SliceByte; +struct SliceByte { + U8* ptr; + SSIZE len; +}; + +/* +To address memory we'll use a memory slice. +*/ +typedef struct SliceMem SliceMem; +struct SliceMem { + void* ptr; + SSIZE len; +}; + +struct FileOpResult +{ + // For now we'll just have the content + SliceByte content; +}; + +struct Opts__read_file_contents +{ + // For now we'll just have the backing memory provided as a slice. + SliceMem backing; +}; + +// We'll utilize the ReadFile procedure within the WinAPI: https://learn.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-readfile +#include "fileapi.h" + + +#endif DEMO__FILE_READ_CONTENTS_V1 + + + +#define KILOBTYES(n) (cast(SSIZE, n) << 10) +#define MEGABYTES(n) (cast(SSIZE, n) << 20) +#define GIGABYTES(n) (cast(SSIZE, n) << 30) +#define TERABYTES(n) (cast(SSIZE, n) << 40) + +/* +We'll be defining here Fixed-sized memory blocks using typedefs on-demand + +They will having the following format: +typedef U8 FMem_KB [ ]; +*/ + +typedef U8 FMem_1KB [ KILOBTYES(1) ]; + diff --git a/devshell.ps1 b/devshell.ps1 new file mode 100644 index 0000000..33ca0ce --- /dev/null +++ b/devshell.ps1 @@ -0,0 +1,28 @@ +if ($env:VCINSTALLDIR) { + return +} + +$ErrorActionPreference = "Stop" + +# Use vswhere to find the latest Visual Studio installation +$vswhere_out = & "C:\Program Files (x86)\Microsoft Visual Studio\Installer\vswhere.exe" -latest -property installationPath +if ($null -eq $vswhere_out) { + Write-Host "ERROR: Visual Studio installation not found" + exit 1 +} + +# Find Launch-VsDevShell.ps1 in the Visual Studio installation +$vs_path = $vswhere_out +$vs_devshell = Join-Path $vs_path "\Common7\Tools\Launch-VsDevShell.ps1" + +if ( -not (Test-Path $vs_devshell) ) { + Write-Host "ERROR: Launch-VsDevShell.ps1 not found in Visual Studio installation" + Write-Host Tested path: $vs_devshell + exit 1 +} + +# Launch the Visual Studio Developer Shell +Push-Location +write-host @args +& $vs_devshell @args +Pop-Location diff --git a/intro.c b/intro.c new file mode 100644 index 0000000..d570d7a --- /dev/null +++ b/intro.c @@ -0,0 +1,8 @@ +#include "stdio.h" + + + +int main() +{ + printf("Hello world!"); +}