diff --git a/.gitignore b/.gitignore index efd51d8..9ca72da 100644 --- a/.gitignore +++ b/.gitignore @@ -235,3 +235,12 @@ cython_debug/ # PyPI configuration file .pypirc +# ============================ +# NUMBRELLA BUILD DIRECTORIES +# ============================ +# Root umbrella build +.build/ + +# Per-project standalone builds +build/ + diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000..2c9ca1e --- /dev/null +++ b/.gitmodules @@ -0,0 +1,18 @@ +[submodule "Foreign/SDL"] + path = Foreign/SDL + url = https://github.com/libsdl-org/SDL.git +[submodule "Foreign/SDL_mixer"] + path = Foreign/SDL_mixer + url = https://github.com/libsdl-org/SDL_mixer.git +[submodule "Foreign/SDL_image"] + path = Foreign/SDL_image + url = https://github.com/libsdl-org/SDL_image.git +[submodule "Foreign/SDL_ttf"] + path = Foreign/SDL_ttf + url = https://github.com/libsdl-org/SDL_ttf.git +[submodule "Foreign/SDL_net"] + path = Foreign/SDL_net + url = https://github.com/libsdl-org/SDL_net.git +[submodule "Foreign/fonts"] + path = Foreign/fonts + url = https://github.com/google/fonts.git diff --git a/Documentation/FOREIGN_SYNTAX.txt b/Documentation/FOREIGN_SYNTAX.txt new file mode 100644 index 0000000..2eb7a46 --- /dev/null +++ b/Documentation/FOREIGN_SYNTAX.txt @@ -0,0 +1,1344 @@ +=============================================================================== + THE NUMBRELLA PROJECT — Syntax Guide +=============================================================================== + + Copyright (C) 2026 Sixten Björling + All rights reserved. + + A syntax reference for the three primary languages used in the Numbrella + ecosystem: Python (≥ 3.10), Go, and C/C++ with LLVM/Clang/Clang++. + +=============================================================================== + TABLE OF CONTENTS +=============================================================================== + PART I — PYTHON (≥ 3.10) + PART II — GO + PART III — C / C++ (C17 / C++20) with Clang/Clang++ & LLVM + +=============================================================================== + PART I — PYTHON (≥ 3.10) +=============================================================================== + +--- 1.1 Basic Structure ------------------------------------------------ + + #!/usr/bin/env python3 + # -*- coding: utf-8 -*- + + """Module docstring.""" + + import sys + from pathlib import Path + from typing import Any + + CONSTANT = 42 + + def main() -> None: + """Entry point.""" + print("Hello, Numbrella.") + + if __name__ == "__main__": + main() + +--- 1.2 Variables & Types ---------------------------------------------- + + x: int = 42 # Integer + y: float = 3.14 # Float + z: complex = 1 + 2j # Complex + name: str = "Numbrella" # String + flag: bool = True # Boolean + nothing: None = None # None + + # F-strings (Python ≥ 3.6) + s = f"Value: {x}, Name: {name}" + + # Triple-quoted strings + multiline = """Line 1 + Line 2""" + +--- 1.3 Collections ---------------------------------------------------- + + # List (mutable, ordered) + items: list[int] = [1, 2, 3] + items.append(4) + items.pop() + first = items[0] + + # Tuple (immutable, ordered) + coords: tuple[int, int] = (10, 20) + x, y = coords # Unpacking + + # Set (mutable, unordered, unique) + tags: set[str] = {"audio", "dsp"} + tags.add("midi") + + # Dictionary (mutable, key-value) + config: dict[str, Any] = {"host": "localhost", "port": 8080} + config["debug"] = True + value = config.get("missing", "default") + + # Comprehensions + squares = [n ** 2 for n in range(10) if n % 2 == 0] + mapping = {k: k.upper() for k in ["a", "b", "c"]} + +--- 1.4 Control Flow --------------------------------------------------- + + # If / elif / else + if x > 0: + result = "positive" + elif x < 0: + result = "negative" + else: + result = "zero" + + # Match / case (Python ≥ 3.10) + match value: + case 0: + print("Zero") + case 1 | 2: + print("One or two") + case str(s): + print(f"String: {s}") + case [first, *rest]: + print(f"List starting with {first}") + case {"type": "audio", "rate": r}: + print(f"Audio at {r} Hz") + case _: + print("Unknown") + + # While + while condition: + do_work() + if done: + break + + # For + for item in items: + process(item) + + for i, item in enumerate(items): + print(f"{i}: {item}") + + for key, val in config.items(): + print(f"{key} = {val}") + +--- 1.5 Functions ------------------------------------------------------- + + def add(a: int, b: int) -> int: + """Add two integers.""" + return a + b + + # Default arguments + def greet(name: str = "World") -> str: + return f"Hello, {name}." + + # Variadic arguments + def log(*messages: str, **kwargs: Any) -> None: + level = kwargs.get("level", "INFO") + for msg in messages: + print(f"[{level}] {msg}") + + # Lambda + square = lambda n: n * n + + # Decorator + from functools import wraps + + def timer(func): + @wraps(func) + def wrapper(*args, **kwargs): + import time + start = time.perf_counter() + result = func(*args, **kwargs) + elapsed = time.perf_counter() - start + print(f"{func.__name__} took {elapsed:.4f}s") + return result + return wrapper + + @timer + def heavy_computation() -> int: + return sum(range(1_000_000)) + +--- 1.6 Classes --------------------------------------------------------- + + from dataclasses import dataclass + + @dataclass + class AudioClip: + path: str + sample_rate: int = 44100 + channels: int = 2 + + def duration_ms(self) -> float: + """Read from file and compute duration.""" + ... + + # Traditional class + class Buffer: + def __init__(self, size: int) -> None: + self._size = size + self._data = bytearray(size) + + def __len__(self) -> int: + return self._size + + def __getitem__(self, index: int) -> int: + return self._data[index] + + def __enter__(self): + return self + + def __exit__(self, *args): + self._data.clear() + +--- 1.7 Exceptions ------------------------------------------------------ + + try: + risky_operation() + except ValueError as e: + print(f"Bad value: {e}") + except (IOError, OSError): + print("I/O failure") + else: + print("No exception raised") # Runs only on success + finally: + cleanup() # Always runs + + # Raise + raise RuntimeError("Something went wrong") + + # Custom exception + class NumbrellaError(Exception): + """Base exception for Numbrella.""" + +--- 1.8 Context Managers ------------------------------------------------ + + with open("file.txt", "r") as f: + data = f.read() + + from contextlib import contextmanager + + @contextmanager + def temporary_path(base: Path): + path = base / "temp" + path.mkdir(exist_ok=True) + try: + yield path + finally: + import shutil + shutil.rmtree(path) + +--- 1.9 Async / Await --------------------------------------------------- + + import asyncio + + async def fetch_data(url: str) -> str: + async with aiohttp.ClientSession() as session: + async with session.get(url) as resp: + return await resp.text() + + async def main() -> None: + tasks = [fetch_data(u) for u in urls] + results = await asyncio.gather(*tasks) + + asyncio.run(main()) + +--- 1.10 Modules & Packages ---------------------------------------------- + + # Relative imports (inside a package) + from . import sibling + from .sibling import SomeClass + from ..parent_pkg import util + + # Conditional import + try: + import orjson as json + except ImportError: + import json + +--- 1.11 Type Hints (Advanced) ------------------------------------------- + + from typing import Generic, TypeVar, Protocol, Literal, Final + + T = TypeVar("T") + + class Stack(Generic[T]): + def push(self, item: T) -> None: ... + def pop(self) -> T: ... + + class Renderable(Protocol): + def render(self) -> str: ... + + Mode = Literal["read", "write", "append"] + MAX_CONNECTIONS: Final = 256 + +=============================================================================== + PART II — GO +=============================================================================== + +--- 2.1 Basic Structure ------------------------------------------------ + + // +build !wasm ← build constraint (old) + //go:build !wasm ← build constraint (Go ≥ 1.17) + + package main + + import ( + "fmt" + "os" + ) + + func main() { + fmt.Println("Hello, Numbrella.") + os.Exit(0) + } + +--- 2.2 Variables & Types ---------------------------------------------- + + var name string = "Numbrella" + var version = "0.1.0" // Type inferred + var x, y int = 10, 20 // Multiple + + // Short declaration (inside functions only) + count := 0 + message := fmt.Sprintf("Count: %d", count) + + // Blanks + _, err := doThing() + + // Constants + const MaxRetries = 3 + const ( + StatusOK = 200 + StatusError = 500 + ) + + // Iota enumerator + const ( + LevelDebug = iota // 0 + LevelInfo // 1 + LevelWarn // 2 + LevelError // 3 + ) + + // Basic types + var ( + i int = 42 + u uint = 100 + f64 float64 = 3.1415 + f32 float32 = 2.718 + b bool = true + s string = "hello" + r rune = '✓' // Unicode code point (int32) + by byte = 255 // uint8 + ) + +--- 2.3 Composite Types ------------------------------------------------ + + // Array (fixed size, value type) + var arr [4]int = [4]int{1, 2, 3, 4} + arr[0] = 10 + + // Slice (dynamic, reference type) + items := []int{1, 2, 3} + items = append(items, 4, 5) + sub := items[1:3] // [2, 3] + copied := make([]int, len(items)) + copy(copied, items) + + // Map + config := map[string]any{ + "host": "localhost", + "port": 8080, + } + config["debug"] = true + val, ok := config["missing"] // ok == false if key absent + delete(config, "debug") + + // Struct + type AudioClip struct { + Path string + SampleRate int + Channels int + _ struct{} // Prevent unkeyed literals + } + + clip := AudioClip{ + Path: "/assets/sound.wav", + SampleRate: 44100, + Channels: 2, + } + + // Pointer + ptr := &clip + ptr.SampleRate = 48000 // Auto-dereferenced + + // Interface + type Renderer interface { + Render() string + } + + func RenderAll(renderers []Renderer) { + for _, r := range renderers { + fmt.Println(r.Render()) + } + } + +--- 2.4 Control Flow --------------------------------------------------- + + // If (with optional init statement) + if val, ok := config["port"]; ok { + fmt.Printf("Port: %v\n", val) + } else if cfg := loadDefault(); cfg != nil { + fmt.Println("Using defaults") + } else { + fmt.Println("No config available") + } + + // Switch (no fallthrough by default) + switch level := getLevel(); level { + case LevelDebug: + fmt.Println("Debug") + case LevelInfo, LevelWarn: // Multiple cases + fmt.Println("Info/Warn") + default: + fmt.Printf("Unknown: %d\n", level) + } + + // Switch without expression = if/else chain + switch { + case x < 0: + fmt.Println("negative") + case x == 0: + fmt.Println("zero") + default: + fmt.Println("positive") + } + + // Type switch + switch v := data.(type) { + case string: + fmt.Printf("string: %s\n", v) + case int: + fmt.Printf("int: %d\n", v) + case nil: + fmt.Println("nil") + } + + // For (Go's only loop construct) + for i := 0; i < 10; i++ { // C-style + ... + } + for condition { // While + ... + } + for { // Infinite + if done() { break } + } + for idx, item := range items { // Range over slice + ... + } + for key, val := range config { // Range over map + ... + } + +--- 2.5 Functions ------------------------------------------------------- + + func add(a, b int) int { + return a + b + } + + // Multiple return values + func divide(a, b float64) (float64, error) { + if b == 0 { + return 0, fmt.Errorf("division by zero") + } + return a / b, nil + } + + // Named return values (naked return) + func parse(s string) (result int, err error) { + result, err = strconv.Atoi(s) + return // Naked return + } + + // Variadic + func log(level string, messages ...string) { + for _, msg := range messages { + fmt.Printf("[%s] %s\n", level, msg) + } + } + + // Defer (LIFO, runs on function exit) + func readFile(path string) ([]byte, error) { + f, err := os.Open(path) + if err != nil { + return nil, err + } + defer f.Close() + return io.ReadAll(f) + } + + // Closures + counter := func() func() int { + n := 0 + return func() int { + n++ + return n + } + }() + +--- 2.6 Methods & Interfaces ------------------------------------------- + + type Buffer struct { + data []byte + } + + // Value receiver (read-only, copied) + func (b Buffer) Len() int { + return len(b.data) + } + + // Pointer receiver (can mutate) + func (b *Buffer) Write(p []byte) (int, error) { + b.data = append(b.data, p...) + return len(p), nil + } + + // Interface compliance is implicit (structural typing) + var w io.Writer = &Buffer{} + + // Interface composition + type ReadWriteCloser interface { + io.Reader + io.Writer + io.Closer + } + + // Empty interface = any type + var anything any = 42 // (any is an alias for interface{} in Go ≥ 1.18) + +--- 2.7 Generics (Go ≥ 1.18) -------------------------------------------- + + // Generic function + func Map[T, U any](items []T, fn func(T) U) []U { + result := make([]U, len(items)) + for i, item := range items { + result[i] = fn(item) + } + return result + } + + // Generic type with constraint + type Number interface { + ~int | ~int64 | ~float64 + } + + func Sum[N Number](values []N) N { + var total N + for _, v := range values { + total += v + } + return total + } + + // Generic struct + type Stack[T any] struct { + items []T + } + func (s *Stack[T]) Push(item T) { s.items = append(s.items, item) } + func (s *Stack[T]) Pop() T { + item := s.items[len(s.items)-1] + s.items = s.items[:len(s.items)-1] + return item + } + +--- 2.8 Goroutines & Channels ------------------------------------------ + + // Goroutine + go func() { + doWork() + }() + + // Channel (unbuffered) + ch := make(chan int) + go func() { ch <- 42 }() + val := <-ch + + // Buffered channel + ch := make(chan string, 10) + + // Select (multiplex channels) + select { + case msg := <-ch: + fmt.Println(msg) + case ch2 <- data: + fmt.Println("sent") + case <-time.After(5 * time.Second): + fmt.Println("timeout") + default: + fmt.Println("no activity") + } + + // Directional channels + func producer(out chan<- int) { out <- 1 } + func consumer(in <-chan int) { _ = <-in } + + // Close + range + close(ch) + for item := range ch { ... } + + // sync.WaitGroup + var wg sync.WaitGroup + for i := 0; i < 5; i++ { + wg.Add(1) + go func(n int) { + defer wg.Done() + process(n) + }(i) + } + wg.Wait() + +--- 2.9 Error Handling ------------------------------------------------- + + // Sentinel errors + if errors.Is(err, io.EOF) { ... } + + // Error wrapping (Go ≥ 1.13) + if err != nil { + return fmt.Errorf("open config: %w", err) + } + var configErr *ConfigError + if errors.As(err, &configErr) { ... } + +--- 2.10 Embedding ------------------------------------------------------- + + type Logger struct{} + + func (l Logger) Log(msg string) { fmt.Println(msg) } + + type Service struct { + Logger // Embedding → Service.Log() promoted + Name string + } + + // Interface embedding + type FileSystem interface { + fs.FS + fs.ReadDirFS + } + +--- 2.11 Package Layout -------------------------------------------------- + + myservice/ + ├── main.go // package main + ├── internal/ // Not importable outside the module + │ ├── db/ + │ └── auth/ + ├── pkg/ // Public API (consumable by other modules) + │ └── client/ + ├── cmd/ // Sub-commands + │ ├── serve/ + │ └── migrate/ + ├── go.mod + └── go.sum + +--- 2.12 cgo (C Interop) ------------------------------------------------- + + /* + #cgo CFLAGS: -I${SRCDIR}/../../Libraries + #cgo LDFLAGS: -L${SRCDIR}/../../Libraries/FilesLib -lFilesLib + #include "FilesLib/header.h" + #include + */ + import "C" + import "unsafe" + + func CallC() { + cs := C.CString("data from Go") + defer C.free(unsafe.Pointer(cs)) + C.process_data(cs) + } + +=============================================================================== + PART III — C / C++ (C17 / C++20) WITH CLANG/CLANG++ & LLVM +=============================================================================== + +--- 3.1 Compiler Invocation (Clang / Clang++) -------------------------- + + # C (C17) + clang -std=c17 -Wall -Wextra -Wpedantic -O2 -c source.c -o source.o + + # C++ (C++20) + clang++ -std=c++20 -Wall -Wextra -Wpedantic -O2 -c source.cpp -o source.o + + # Linking + clang++ source.o -lSDL3 -lSDL3_image -o myapp + + # Full build pipeline + clang++ -std=c++20 -O2 main.cpp app.cpp -o app + + # LLVM IR output (intermediate representation) + clang++ -std=c++20 -S -emit-llvm source.cpp -o source.ll + + # LLVM bitcode + clang++ -std=c++20 -c -emit-llvm source.cpp -o source.bc + + # Assembly output + clang++ -std=c++20 -S source.cpp -o source.s + + # Preprocessor output + clang++ -std=c++20 -E source.cpp -o source.i + + # Sanitizers + clang++ -std=c++20 -fsanitize=address -g source.cpp # AddressSanitizer + clang++ -std=c++20 -fsanitize=undefined -g source.cpp # UBSan + clang++ -std=c++20 -fsanitize=memory -g source.cpp # MemorySanitizer + + # LTO (Link-Time Optimization) + clang++ -std=c++20 -flto=thin -O2 source.cpp -o app # ThinLTO + clang++ -std=c++20 -flto=full -O2 source.cpp -o app # Full LTO + + # Profiling + clang++ -std=c++20 -fprofile-instr-generate source.cpp -o app + ./app # Produces default.profraw + llvm-profdata merge default.profraw -o default.profdata + clang++ -std=c++20 -fprofile-instr-use=default.profdata -O2 source.cpp + + # Modules (C++20) + clang++ -std=c++20 -fmodules -fbuiltin-module-map source.cpp + +--- 3.2 Basic Structure ------------------------------------------------- + + // ===== C ===== + #include + #include "mylib.h" + + #define BUFFER_SIZE 256 + + int main(int argc, char *argv[]) { + printf("Hello, Numbrella.\n"); + return 0; + } + + // ===== C++ ===== + #include // C++23; use or for C++20 + #include "mylib.h" + + constexpr size_t BUFFER_SIZE = 256; + + auto main(int argc, char *argv[]) -> int { + std::println("Hello, Numbrella."); + return 0; + } + +--- 3.3 Preprocessor (C / C++ Shared) ----------------------------------- + + // Include guards (C; prefer #pragma once in this project) + #ifndef MYLIB_H + #define MYLIB_H + // ... declarations ... + #endif + + // #pragma once (C / C++, supported by all modern compilers) + #pragma once + + // Conditional compilation + #ifdef _WIN32 + #define PLATFORM "windows" + #elif defined(__APPLE__) + #define PLATFORM "macos" + #elif defined(__linux__) + #define PLATFORM "linux" + #endif + + // Macros + #define SQUARE(x) ((x) * (x)) + #define STRINGIFY(s) #s + #define CONCAT(a, b) a ## b + + // Diagnostic pragmas (Clang/GCC) + #pragma clang diagnostic push + #pragma clang diagnostic ignored "-Wunused-variable" + int unused = 0; + #pragma clang diagnostic pop + +--- 3.4 C Syntax (C17) -------------------------------------------------- + + // ---- Types ---- + _Bool flag = 1; // Boolean (stdbool.h → bool) + char ch = 'A'; + int n = 42; + long ln = 1000000L; + long long lln = 99999999999LL; + float f = 3.14f; + double d = 2.7182818; + size_t sz = sizeof(int); + + // Fixed-width (stdint.h) + #include + int8_t i8 = -128; + uint32_t u32 = 0xDEADBEEF; + + // ---- Arrays ---- + int arr[4] = {1, 2, 3, 4}; + int arr2[] = {1, 2, 3}; // Size deduced: 3 + int matrix[2][3] = {{1,2,3}, {4,5,6}}; + + // ---- Strings ---- + char str[] = "Numbrella"; // Mutable + const char *msg = "immutable"; // String literal + + // ---- Structs ---- + struct Point { + int x; + int y; + }; + struct Point p = {.x = 10, .y = 20}; // Designated initializer (C99) + + // Typedef + typedef struct { + float real; + float imag; + } Complex; + + // ---- Unions ---- + union Value { + int i; + float f; + char c; + }; + + // ---- Enums ---- + enum Status { STATUS_OK = 200, STATUS_NOT_FOUND = 404 }; + + // ---- Pointers ---- + int a = 42; + int *p = &a; + *p = 100; + + void *vp = p; // Void pointer (type-erased) + int *ip = (int *)vp; // Cast back + + // Function pointer + typedef int (*operation)(int, int); + int add(int a, int b) { return a + b; } + operation op = add; + int result = op(3, 4); // result == 7 + + // ---- Dynamic Allocation ---- + int *data = malloc(100 * sizeof(int)); + if (data == NULL) { /* handle */ } + free(data); + + // ---- Control Flow ---- + if (x > 0) { + ... + } else if (x < 0) { + ... + } else { + ... + } + + switch (n) { + case 0: + handle_zero(); + break; // Fallthrough only with explicit break + case 1: + case 2: + handle_one_or_two(); + break; + default: + handle_other(); + } + + for (int i = 0; i < 10; i++) { ... } + while (condition) { ... } + do { ... } while (condition); + + // ---- C11/C17 Features ---- + // _Generic (type-generic macro) + #define ABS(x) _Generic((x), \ + int: abs, \ + long: labs, \ + float: fabsf \ + )(x) + + // _Alignas / _Alignof (C11) + _Alignas(16) char aligned_buffer[64]; + + // _Static_assert (C11) + _Static_assert(sizeof(int) >= 4, "int must be at least 4 bytes"); + + // _Noreturn (C11) + _Noreturn void fatal_error(const char *msg); + + // _Thread_local (C11) + _Thread_local int thread_counter = 0; + +--- 3.5 C++ Syntax (C++20) ---------------------------------------------- + + // ---- auto & Type Deduction ---- + auto x = 42; // int + auto y = 3.14; // double + auto z = std::vector{1, 2, 3}; // std::vector + + // ---- constexpr / consteval / constinit ---- + constexpr int factorial(int n) { + return n <= 1 ? 1 : n * factorial(n - 1); + } + constexpr int f5 = factorial(5); // Computed at compile time + + consteval int square(int n) { // C++20: must be compile-time + return n * n; + } + + constinit static int counter = 0; // C++20: zero-init at compile time, mutable + + // ---- Initialization (Uniform / Brace) ---- + int a{42}; + std::vector v{1, 2, 3, 4}; + struct Point { int x; int y; }; + Point p{.x = 10, .y = 20}; // Designated initializer (C++20) + + // ---- References ---- + int original = 10; + int& ref = original; // L-value reference + int&& rref = 42; // R-value reference + + // ---- Range-based for ---- + for (const auto& item : v) { + std::println("{}", item); + } + + // ---- Lambdas ---- + auto square = [](int n) -> int { return n * n; }; + + // Capture by value, mutable + auto counter = [count = 0]() mutable { return ++count; }; + + // Capture by reference + int total = 0; + std::for_each(v.begin(), v.end(), [&total](int n) { total += n; }); + + // Generic lambda (C++14) + auto generic = [](const auto& a, const auto& b) { return a + b; }; + + // Template lambda (C++20) + auto templ = [](const std::vector& vec) -> size_t { + return vec.size(); + }; + + // ---- Classes ---- + class AudioClip { + public: + AudioClip(std::string path, int rate = 44100) + : m_path(std::move(path)), m_sampleRate(rate) {} + + auto duration() const -> std::chrono::milliseconds; + + // Defaulted / deleted + AudioClip(const AudioClip&) = default; + AudioClip& operator=(const AudioClip&) = delete; + + // Spaceship operator (C++20) + auto operator<=>(const AudioClip&) const = default; + + private: + std::string m_path; + int m_sampleRate; + }; + + // ---- Inheritance & Virtual ---- + class Shape { + public: + virtual ~Shape() = default; + virtual auto area() const -> double = 0; // Pure virtual + }; + + class Circle final : public Shape { + public: + explicit Circle(double r) : m_radius(r) {} + auto area() const -> double override { return 3.14159 * m_radius * m_radius; } + private: + double m_radius; + }; + + // ---- Templates ---- + template + concept Numeric = std::is_arithmetic_v; // C++20 concept + + template + [[nodiscard]] auto sum(const std::vector& values) -> T { + T total{}; + for (const auto& v : values) total += v; + return total; + } + + // Variadic templates + template + void log(Args&&... args) { + (std::println("{}", std::forward(args)), ...); // Fold expression (C++17) + } + + // Template specialization + template struct TypeName { static const char* get() { return "unknown"; } }; + template <> struct TypeName { static const char* get() { return "int"; } }; + template <> struct TypeName { static const char* get() { return "double"; } }; + + // ---- Modules (C++20) ---- + // mymodule.ixx / mymodule.cppm + export module mymodule; + + export auto greet() -> std::string { return "Hello from module"; } + + // Consumer: + import mymodule; + + // ---- Coroutines (C++20) ---- + #include + #include // std::generator (C++23; implement manually for C++20) + + // ---- Ranges (C++20) ---- + #include + + auto even_squares(const std::vector& v) { + return v + | std::views::filter([](int n) { return n % 2 == 0; }) + | std::views::transform([](int n) { return n * n; }); + } + + // ---- std::format / std::print (C++20/23) ---- + #include + auto msg = std::format("Value: {}, Name: {}", 42, "Numbrella"); + std::print("Hello, {}.\n", "World"); + + // ---- Span (C++20) ---- + void process(std::span data) { + for (int n : data) { ... } + } + std::vector v{1,2,3}; + process(v); // Works with vector, array, C-array + + // ---- Expected (C++23; or tl::expected / boost::outcome for C++20) ---- + #include // C++23 + auto divide(double a, double b) -> std::expected { + if (b == 0) return std::unexpected("division by zero"); + return a / b; + } + + // ---- Attributes ---- + [[nodiscard]] int important_result(); // Warn if return value discarded + [[maybe_unused]] int x = 0; // Suppress unused warning + [[likely]] if (fast_path) { ... } // Branch prediction hint (C++20) + [[unlikely]] if (error_path) { ... } // Branch prediction hint (C++20) + [[noreturn]] void fatal(); // Function never returns + + // ---- Three-way comparison (C++20) ---- + struct Version { + int major, minor, patch; + auto operator<=>(const Version&) const = default; // auto-generates ==, !=, <, <=, >, >= + }; + +--- 3.6 STL Quick Reference (C++20) ------------------------------------ + + // Containers + #include // Dynamic array + #include // Fixed-size array + #include // String (std::string) + #include // Non-owning string view + #include // Ordered key-value (red-black tree) + #include // Hash map + #include // Ordered set + #include // Hash set + #include // Double-ended queue + #include // Doubly-linked list + #include // Singly-linked list + #include // LIFO + #include // FIFO + #include // Heap + #include // Non-owning view of contiguous data (C++20) + #include // Maybe value + #include // Type-safe union + #include // Type-erased value + #include // Heterogeneous tuple + #include // Bit array + + // Algorithms + #include // sort, find, copy, transform, etc. + #include // accumulate, iota, gcd, lcm + #include // Range adaptors (C++20) + + // Utilities + #include // unique_ptr, shared_ptr, make_unique, make_shared + #include // Time utilities + #include // Threading + #include // Mutex, lock_guard, scoped_lock + #include // File system operations + #include // std::function, std::bind + + // I/O + #include // cin, cout, cerr + #include // File I/O + #include // String streams + #include // std::print, std::println (C++23) + #include // std::format (C++20) + +--- 3.7 Smart Pointers & RAII ------------------------------------------- + + // Unique ownership + auto p1 = std::make_unique("sound.wav"); + auto p2 = std::move(p1); // Transfer ownership; p1 == nullptr + + // Shared ownership + auto s1 = std::make_shared(100); + auto s2 = s1; // Reference count = 2 + + // Weak reference (breaks cycles) + std::weak_ptr weak = s1; + if (auto locked = weak.lock()) { + locked->use(); + } + + // RAII guard + { + std::lock_guard lock(m_mutex); // Auto-locks, auto-unlocks + shared_data.modify(); + } + + // Custom deleter + auto file = std::unique_ptr( + fopen("data.bin", "rb"), fclose + ); + + // Scope guard (manual implementation or library) + template + class ScopeGuard { + F m_func; bool m_active = true; + public: + explicit ScopeGuard(F f) : m_func(std::move(f)) {} + ~ScopeGuard() { if (m_active) m_func(); } + void dismiss() { m_active = false; } + ScopeGuard(const ScopeGuard&) = delete; + ScopeGuard& operator=(const ScopeGuard&) = delete; + ScopeGuard(ScopeGuard&&) = default; + ScopeGuard& operator=(ScopeGuard&&) = default; + }; + // Usage: auto guard = ScopeGuard([] { cleanup(); }); + +--- 3.8 Threading & Atomics --------------------------------------------- + + // Threads + #include + std::thread t([] { doWork(); }); + t.join(); // Wait for completion + // Or t.detach() for fire-and-forget + + // Mutex & condition variable + std::mutex m; + std::condition_variable cv; + bool ready = false; + + // Producer + { + std::lock_guard lk(m); + ready = true; + } + cv.notify_one(); + + // Consumer + std::unique_lock lk(m); + cv.wait(lk, [] { return ready; }); // Wait + check predicate + + // Atomic + #include + std::atomic counter{0}; + counter.fetch_add(1, std::memory_order_relaxed); + + // Async / Future + #include + auto fut = std::async(std::launch::async, [] { return compute(); }); + auto result = fut.get(); // Blocks until ready + + // jthread (C++20: auto-joining thread) + std::jthread jt([](std::stop_token token) { + while (!token.stop_requested()) { + doWork(); + } + }); + // jthread auto-joins on destruction; request_stop() cooperatively stops it + + // Latch / Barrier (C++20) + #include + std::latch done{3}; // Wait for 3 countdowns + done.count_down(); + done.wait(); + +--- 3.9 Move Semantics -------------------------------------------------- + + class Buffer { + public: + Buffer(size_t size) : m_data(std::make_unique(size)), m_size(size) {} + + // Move constructor + Buffer(Buffer&& other) noexcept + : m_data(std::move(other.m_data)), m_size(other.m_size) { + other.m_size = 0; + } + + // Move assignment + Buffer& operator=(Buffer&& other) noexcept { + if (this != &other) { + m_data = std::move(other.m_data); + m_size = other.m_size; + other.m_size = 0; + } + return *this; + } + + // Delete copy (move-only type) + Buffer(const Buffer&) = delete; + Buffer& operator=(const Buffer&) = delete; + + private: + std::unique_ptr m_data; + size_t m_size = 0; + }; + + Buffer create() { + Buffer b{1024}; + return b; // NRVO / move (compiler-elided or moved) + } + Buffer sink = create(); // Move or copy elision + +--- 3.10 LLVM IR Basics -------------------------------------------------- + + // ---- What is LLVM IR? ---- + // LLVM Intermediate Representation is a low-level, platform-independent, + // Static Single Assignment (SSA) language used between the Clang frontend + // and the LLVM backend optimizer/code-generator. + + // ---- Generating IR ---- + // clang++ -std=c++20 -S -emit-llvm source.cpp -o source.ll (text) + // clang++ -std=c++20 -c -emit-llvm source.cpp -o source.bc (bitcode) + + // ---- Minimal .ll Example (hand-written equivalent of a C function) ---- + + ; Module-level + target triple = "x86_64-unknown-linux-gnu" + + ; @.str = private unnamed_addr constant [14 x i8] c"Hello, %d!\0A\00" + + declare i32 @printf(i8*, ...) + + ; define i32 @main() #0 { + ; entry: + ; %call = call i32 (i8*, ...) @printf(i8* getelementptr (...), i32 42) + ; ret i32 0 + ; } + + // ---- Key LLVM IR Concepts ---- + // + // SSA (Static Single Assignment): + // Every virtual register is assigned exactly once. + // %result = add i32 %a, %b ← %result can never be re-assigned. + // + // Basic Blocks: + // A straight-line sequence of instructions ending with a terminator + // (br, ret, switch, etc.). Labels mark block entry points. + // + // PHI Nodes: + // Merge SSA values from different predecessor blocks. + // %val = phi i32 [ %then_val, %then_block ], [ %else_val, %else_block ] + // + // Types: + // i1, i8, i16, i32, i64 ← Integer types + // float, double ← FP types + // ptr ← Opaque pointer (LLVM ≥ 15) + // [N x T] ← Array + // { T1, T2, ... } ← Struct + // ← Vector + + // ---- LLVM Toolchain ---- + // + // llc — Compile .ll/.bc to native assembly + // lli — JIT-execute .ll/.bc directly + // opt — LLVM optimizer (run passes on IR) + // llvm-link — Link multiple .bc files into one + // llvm-dis — Disassemble .bc → .ll (human-readable) + // llvm-as — Assemble .ll → .bc + // llvm-ar — Archive .bc files + // llvm-nm — List symbols in .bc files + // llvm-objdump — Dump object information + // clang — Frontend (C → IR, C++ → IR, IR → native) + + // ---- Optimization Pipeline (opt) ---- + // opt -O2 input.ll -o output.ll + // opt -passes="default" input.ll -o output.ll (new PM syntax) + + // ---- Linking IR ---- + // llvm-link a.bc b.bc -o combined.bc + // clang++ combined.bc -o program + + // ---- LTO with Clang ---- + // Compile: clang++ -flto=thin -c a.cpp b.cpp → a.o, b.o (contain bitcode) + // Link: clang++ -flto=thin a.o b.o -o program + + // ---- Writing a simple LLVM pass (skeleton) ---- + // #include "llvm/Pass.h" + // #include "llvm/IR/Function.h" + // struct MyPass : public llvm::FunctionPass { + // static char ID; + // MyPass() : FunctionPass(ID) {} + // bool runOnFunction(Function &F) override { + // // Inspect/transform F + // return false; // true if modified + // } + // }; + // char MyPass::ID = 0; + // static RegisterPass X("mypass", "My Analysis Pass"); + + // ---- Clang Attributes for LLVM IR Control ---- + [[gnu::noinline]] void dont_inline_me(); // Suppress inlining + [[gnu::always_inline]] inline void must_inline_me(); + __attribute__((optnone)) void debug_me(); // Disable optimization for this function + + // ---- Clang Builtins for low-level access ---- + __builtin_expect(cond, 0); // Branch prediction hint + __builtin_prefetch(ptr); // Prefetch hint + __builtin_assume(cond); // Optimization assumption + __builtin_unreachable(); // Mark unreachable code + + // ---- Compiler Explorer pattern ---- + // https://godbolt.org — paste code, see generated LLVM IR / assembly + // Useful flags: -std=c++20 -O2 -march=native + +--- 3.11 Common Clang Attributes & Pragmas ------------------------------- + + // ---- Function attributes ---- + [[nodiscard]] int compute(); // C++17: warn if result unused + [[deprecated("Use newAPI() instead")]] void oldAPI(); + [[noreturn]] void fatal_exit(); + + // ---- Clang-specific attributes ---- + __attribute__((constructor)) void on_load(); // Run before main() + __attribute__((destructor)) void on_unload(); // Run after main() / atexit + __attribute__((used)) void keep_symbol(); // Prevent removal even if unused + __attribute__((visibility("default"))) void exported_func(); + __attribute__((visibility("hidden"))) void internal_func(); + __attribute__((aligned(16))) char buffer[64]; + __attribute__((packed)) struct Compact { char a; int b; }; + + // ---- Compiler barriers ---- + asm volatile("" ::: "memory"); // Full compiler barrier + __sync_synchronize(); // Full memory fence + + // ---- SIMD pragmas ---- + #pragma clang loop vectorize(enable) + for (int i = 0; i < N; i++) { ... } + + #pragma clang loop unroll(enable) + for (int i = 0; i < 4; i++) { ... } + +=============================================================================== + END OF SYNTAX GUIDE +=============================================================================== \ No newline at end of file diff --git a/Documentation/PRESENTATION.txt b/Documentation/PRESENTATION.txt new file mode 100644 index 0000000..d3ca506 --- /dev/null +++ b/Documentation/PRESENTATION.txt @@ -0,0 +1,11 @@ +Copyright (C) 2026 Sixten Björling + +"The Numbrella Project" + +Welcome! This is where "The Numbrella Project" is developed and maintained. + +The project aims to please the resulting developer and user with a comfortable, +and simple approach with high performance rates and broad cross-platform functionality. + +It was founded by @sibjor in the summer of 2026. + diff --git a/Documentation/WALKTHROUGH.txt b/Documentation/WALKTHROUGH.txt new file mode 100644 index 0000000..12e7fb6 --- /dev/null +++ b/Documentation/WALKTHROUGH.txt @@ -0,0 +1,376 @@ +=============================================================================== + THE NUMBRELLA PROJECT — Developer Walkthrough +=============================================================================== + + Copyright (C) 2026 Sixten Björling + All rights reserved. + + This document explains how to set up, build, and contribute to the Numbrella + ecosystem using Python, C/C++ (Clang, Clang++), and Go. + +=============================================================================== + TABLE OF CONTENTS +=============================================================================== + 1. Prerequisites + 2. Cloning & First-Time Setup + 3. Project Layout + 4. Building (C / C++) + 5. Working with Go + 6. Working with Python + 7. Adding a New Library + 8. Adding a New Application + 9. Adding a New Tool +10. Coding Conventions +11. Troubleshooting +12. Quick Reference + +=============================================================================== + 1. PREREQUISITES +=============================================================================== + + Required: + • CMake ≥ 3.20 + • Clang / Clang++ (any version supporting C17 / C++20) + • Ninja (or Make, but Ninja is recommended) + • Go ≥ 1.21 + • Python ≥ 3.10 + • Git (with submodule support) + + Optional but recommended: + • ccache (speeds up recompilation) + • clang-format (consistent code style) + • clang-tidy (static analysis) + + Platform support: + • Windows (MSVC or Clang-cl; Ninja is strongly preferred) + • macOS (Clang via Xcode CLT) + • Linux (Clang via system package manager) + +=============================================================================== + 2. CLONING & FIRST-TIME SETUP +=============================================================================== + + # Clone with submodules + git clone --recurse-submodules Numbrella + cd Numbrella + + # If you already cloned without --recurse-submodules: + git submodule update --init --recursive + + # Verify everything is in place: + ls Libraries/ # Should show FilesLib, PathsLib, MathsLib, etc. + ls Foreign/ # Should show SDL, SDL_image, SDL_ttf, SDL_mixer, fonts + ls Software/ # Should show AuthSide, DevIO, NetBud, etc. + +=============================================================================== + 3. PROJECT LAYOUT +=============================================================================== + + Numbrella/ + ├── CMakeLists.txt ← Root build definition + ├── cmake/ ← CMake modules + │ ├── Foreign.cmake ← SDL3 submodule inclusion + │ ├── Libraries.cmake ← Auto-discovers Libraries/ + │ └── Project.cmake ← Auto-discovers Software/ & Tools/ + ├── Libraries/ ← Static libraries (C / C++) + │ ├── FilesLib/ + │ ├── PathsLib/ + │ ├── MathsLib/ + │ ├── MidsLib/ + │ ├── NetsLib/ + │ └── LangsLib/ ← Language bindings (C/, Go/, Python/) + ├── Software/ ← Application executables + │ ├── AuthSide/ + │ ├── DevIO/ + │ ├── FileSync/ + │ ├── InterLingo/ + │ ├── Kompis/ + │ ├── NetBud/ + │ ├── NuCLI/ + │ └── Nudel/ + ├── Tools/ ← Utility executables + ├── Foreign/ ← Git submodules (SDL3, fonts) + ├── Assets/ ← Audio, Graphic, Shaders + ├── Development/ ← Out-of-source build tree (gitignored) + ├── Documentation/ ← You are here + ├── Rules/ ← Project rules & allowed tech + └── Project/ ← Planning & tracking documents + +=============================================================================== + 4. BUILDING (C / C++) +=============================================================================== + + The project uses out-of-source builds inside the Development/ directory. + All build artifacts stay there; compiled binaries are exported back to + their respective source directories. + + ---- Configure (do this once) ---- + cd Development + cmake .. -G Ninja -DCMAKE_BUILD_TYPE=Debug + + # Release build: + cmake .. -G Ninja -DCMAKE_BUILD_TYPE=Release + + # Use ccache (faster rebuilds): + cmake .. -G Ninja -DCMAKE_BUILD_TYPE=Debug \ + -DCMAKE_C_COMPILER_LAUNCHER=ccache \ + -DCMAKE_CXX_COMPILER_LAUNCHER=ccache + + ---- Build everything ---- + cmake --build . + + # Or build a single target: + cmake --build . --target FilesLib + cmake --build . --target AuthSide + cmake --build . --target NetBud + + ---- Output locations ---- + Static libraries: Libraries//lib.a + Applications: Software//[.exe] + Tools: Tools//[.exe] + + ---- Clean ---- + cmake --build . --target clean + # Or nuke everything: + rm -rf Development/* + +=============================================================================== + 5. WORKING WITH GO +=============================================================================== + + Go modules inside the project are self-contained. They import Numbrella + C libraries via cgo when needed. + + ---- Initialize a new Go module inside a Software/ or Tools/ directory ---- + cd Software/MyService + go mod init numbrella/myservice + + ---- Build ---- + go build -o MyService . + # Or for a binary placed in the project root toolchain: + go build -o ../../Software/MyService/MyService . + + ---- Using cgo to call Numbrella C libraries ---- + /* + #cgo CFLAGS: -I${SRCDIR}/../../Libraries + #cgo LDFLAGS: -L${SRCDIR}/../../Libraries/FilesLib -lFilesLib + #include "FilesLib/some_header.h" + */ + import "C" + + ---- Recommended Go layout inside a Software/ directory ---- + Software/MyService/ + ├── main.go + ├── go.mod + ├── go.sum + ├── internal/ ← Private packages + └── cmd/ ← Sub-commands (if CLI) + + ---- Testing ---- + go test ./... + +=============================================================================== + 6. WORKING WITH PYTHON +=============================================================================== + + Python scripts live alongside other source or inside Tools/. + No virtual environment is enforced, but using one is recommended + for isolation. + + ---- Quick script layout ---- + Tools/MyTool/ + ├── __init__.py + ├── __main__.py ← Entry point (python -m MyTool) + ├── mytool.py + └── requirements.txt ← Dependencies (if any) + + ---- Running a Python tool ---- + cd Tools/MyTool + python -m MyTool + + # Or directly: + python mytool.py + + ---- Calling Numbrella binaries from Python ---- + Use subprocess to invoke compiled C/Go executables: + + import subprocess + result = subprocess.run( + ["../../Software/SomeService/SomeService", "--flag"], + capture_output=True, text=True + ) + + ---- LangsLib Python bindings ---- + Libraries/LangsLib/Python/ contains shared Python utilities. + Add the Libraries path to PYTHONPATH when using them: + + export PYTHONPATH="${PYTHONPATH}:$(pwd)/Libraries" + python -m LangsLib.Python.some_module + +=============================================================================== + 7. ADDING A NEW LIBRARY +=============================================================================== + + C/C++ static libraries are auto-discovered. Just create the directory. + + mkdir Libraries/MyNewLib + # Add your .cpp, .c, and .h files inside. + # The build system picks them up automatically on next configure. + + Libraries/MyNewLib/ + ├── MyNewLib.h + ├── MyNewLib.cpp + └── internal/ + └── helpers.h + + # Re-configure to register the new target: + cd Development + cmake .. + + # Build just your library: + cmake --build . --target MyNewLib + + The library target name = directory name (MyNewLib). + Other targets can use #include "MyNewLib/MyNewLib.h" via the + global Libraries/ include path. + +=============================================================================== + 8. ADDING A NEW APPLICATION +=============================================================================== + + Applications live under Software/. Same auto-discovery principle. + + mkdir Software/MyApp + # Add sources (.cpp, .c, .h). + + Software/MyApp/ + ├── main.cpp + ├── App.h + └── App.cpp + + # Re-configure and build: + cd Development + cmake .. + cmake --build . --target MyApp + + # Run: + ../Software/MyApp/MyApp + + Every Software/ application automatically links against: + • All Numbrella libraries + • SDL3, SDL3_image, SDL3_ttf, SDL3_mixer + +=============================================================================== + 9. ADDING A NEW TOOL +=============================================================================== + + Tools follow the same pattern as Software/. The only difference is + the output directory (Tools/ instead of Software/). + + mkdir Tools/MyTool + # Add sources. + + cd Development + cmake .. + cmake --build . --target MyTool + + # Run: + ../Tools/MyTool/MyTool + +=============================================================================== +10. CODING CONVENTIONS +=============================================================================== + + ---- C / C++ ---- + • Standard: C17 & C++20 + • Compiler: Clang / Clang++ + • Style: Keep it clean; prefer readability over cleverness. + • Headers: Use #pragma once. + • Warnings: -Wall -Wextra -Wpedantic (treat warnings as errors in CI). + • Naming: PascalCase for types, camelCase for functions/variables. + • Includes: Use quotes for project headers, angle brackets for system. + + ---- Go ---- + • Standard: Latest stable Go. + • Style: gofmt (mandatory). + • Linting: golangci-lint. + • Modules: One go.mod per Software/ subdirectory. + • Naming: Standard Go conventions (MixedCaps, not underscores). + + ---- Python ---- + • Standard: Python ≥ 3.10. + • Style: PEP 8. + • Formatting: black or ruff. + • Typing: Use type hints everywhere. + • Docstrings: Google or NumPy style. + + ---- General ---- + • Cross-platform code only (no platform-specific #ifdefs unless necessary). + • Prefer standard libraries over third-party dependencies. + • Document public APIs. + • Write tests. + +=============================================================================== +11. TROUBLESHOOTING +=============================================================================== + + Q: "CMake can't find SDL3" + A: Did you clone with --recurse-submodules? Run: + git submodule update --init --recursive + + Q: "No targets found in Libraries/" + A: The directories exist but are empty. Add source files. + + Q: "My new directory is not picked up" + A: After creating the directory, re-run cmake .. inside Development/. + + Q: "compile_commands.json is missing" + A: Set CMAKE_EXPORT_COMPILE_COMMANDS=ON (it is on by default). + Check Development/compile_commands.json. Symlink it to root: + ln -s Development/compile_commands.json . + + Q: "clangd doesn't recognize my headers" + A: Ensure compile_commands.json is symlinked to the project root. + + Q: "Build is slow" + A: Install ccache and pass the launcher flags shown in Section 4. + Also, build only the target you need: cmake --build . --target MyApp + +=============================================================================== +12. QUICK REFERENCE +=============================================================================== + + Clone: + git clone --recurse-submodules && cd Numbrella + + Configure: + cd Development + cmake .. -G Ninja -DCMAKE_BUILD_TYPE=Debug + + Build all: + cmake --build . + + Build one target: + cmake --build . --target + + Re-configure (pick up new directories): + cmake .. + + Clean: + rm -rf Development/* + + Add a library: + mkdir Libraries/ # Add .cpp/.c/.h + cd Development && cmake .. && cmake --build . --target + + Add an app: + mkdir Software/ # Add .cpp/.c/.h + cd Development && cmake .. && cmake --build . --target + + Add a tool: + mkdir Tools/ # Add .cpp/.c/.h + cd Development && cmake .. && cmake --build . --target + +=============================================================================== + END OF WALKTHROUGH +=============================================================================== \ No newline at end of file diff --git a/Foreign/SDL b/Foreign/SDL new file mode 160000 index 0000000..855cbec --- /dev/null +++ b/Foreign/SDL @@ -0,0 +1 @@ +Subproject commit 855cbec702f246661ff00a0bce9e0683012840c2 diff --git a/Foreign/SDL_image b/Foreign/SDL_image new file mode 160000 index 0000000..0ee698e --- /dev/null +++ b/Foreign/SDL_image @@ -0,0 +1 @@ +Subproject commit 0ee698ef02cf38026c476e28157c182685861d18 diff --git a/Foreign/SDL_mixer b/Foreign/SDL_mixer new file mode 160000 index 0000000..4cc1fb5 --- /dev/null +++ b/Foreign/SDL_mixer @@ -0,0 +1 @@ +Subproject commit 4cc1fb51ae00ffdf970f64db61af8842b4db0a3a diff --git a/Foreign/SDL_net b/Foreign/SDL_net new file mode 160000 index 0000000..4dd9d84 --- /dev/null +++ b/Foreign/SDL_net @@ -0,0 +1 @@ +Subproject commit 4dd9d8418e9781d10481fd6177e3a1064ca201fe diff --git a/Foreign/SDL_ttf b/Foreign/SDL_ttf new file mode 160000 index 0000000..a42434b --- /dev/null +++ b/Foreign/SDL_ttf @@ -0,0 +1 @@ +Subproject commit a42434b8c96daaf7650dbd0befe480c090d1c2eb diff --git a/Foreign/fonts b/Foreign/fonts new file mode 160000 index 0000000..7ff85c8 --- /dev/null +++ b/Foreign/fonts @@ -0,0 +1 @@ +Subproject commit 7ff85c87f93ea6cca5f41c69f2e4edcb90240f26 diff --git a/Project/PLAN.numl b/Project/PLAN.numl new file mode 100644 index 0000000..e76d4f0 --- /dev/null +++ b/Project/PLAN.numl @@ -0,0 +1,101 @@ +@sibjor +{ + [x] Project Directories + - Core directory structure established: Project/, Libraries/, Foreign/, Rules/, Documentation/, Software/ + - Modular CMake layout active via cmake/*.cmake + - SDL3 submodules integrated + + [ ] FilesLib Prototype + - Unified file abstraction layer + - Memory-mapped IO support + - File hashing (SHA-256) + - Metadata handling (timestamps, permissions) + - Integration point for FileWorks + + [ ] PathsLib Prototype + - Virtual path system + - Path normalization and canonicalization + - Sandboxed directory handling + - Namespace-based path resolution + - Integration with FilesLib + + [ ] MidsLib Prototype + - Middleware for data transformation + - Serialization formats (binary, JSON, NUML) + - Data schema validation + - Message passing between modules + + [ ] NetsLib Prototype + - Unified networking abstraction + - TCP/UDP sockets + - HTTP/HTTPS client and server + - SSH/SFTP support + - WebSocket handling + - Integration with NetBud + + [ ] MathsLib Prototype + - Vector and matrix math + - DSP utilities (psytrance experiments) + - Randomness, noise, distributions + - Geometry and collision primitives + + [ ] FileWorks Prototype (Sync, Versioning) + - Local file synchronization engine + - Remote sync via NetBud + - Versioning system (snapshots, diffs) + - Conflict resolution + - Integration with FilesLib and PathsLib + + [ ] AuthSide Prototype (Auth & Registration Service, invite-only) + - Invite-token registration flow + - Passwordless login (email, SSH keys) + - Session management + - Integration with Kompis and NetBud + + [ ] Kompis Prototype (E-Mail, Chat, VideoChat, VoiceChat, ScreenShare) + - Email client/server (SMTP/IMAP) + - Real-time chat (WebSocket) + - Voice/video communication (WebRTC or custom stack) + - Screen sharing (SDL3 capture) + - Integration with AuthSide + + [ ] NetBud Prototype (WebServer, HTTP, HTTPS, SSH, TCP, UDP, FTP, SFTP) + - Unified server framework + - Routing system + - TLS termination + - SSH subsystem + - FTP/SFTP module + - Integration with NetsLib + + [ ] InterLingo Prototype (LLVM-like IR, Spoken Languages & Syntax) + - Custom IR for language translation + - Grammar and syntax specification + - Tokenizer and parser + - Semantic analysis + - Integration with NuCLI and DevIO + + [ ] NuCLI Prototype (Desktop CLI, Packages, Runs the Projects Stated Above) + - Unified CLI for all Numbrella tools + - Package management + - Plugin loader + - System-level commands + - Integration with InterLingo + + [ ] Nudel (App Store with GUI) + - GUI frontend for NuCLI + - Application browsing, installation, updates + - User authentication (AuthSide) + - Integration with NetBud + + [ ] DevIO Prototype (IDE with GUI & Extension Support) + - Editor core (SDL3) + - Syntax highlighting via InterLingo + - Extension system + - Build system integration (CMake) + - Integration with NuCLI and Nudel + + [ ] OMDaw Prototype (Digital AUdio Workstation) + - Engine Core (SDL3) + - Flowchart GUI Nodes (similar to Blueprint) + - Music Composition with Text +} diff --git a/Project/SPECS.numl b/Project/SPECS.numl new file mode 100644 index 0000000..fd39d86 --- /dev/null +++ b/Project/SPECS.numl @@ -0,0 +1,6 @@ +@sibjor +{ + PROJECT_TYPE: Umbrella Project + PROJECT_NAME: The Numbrella Project + PROJECT_DIRECTORY: ../../Numbrella +} \ No newline at end of file diff --git a/Project/TODO.numl b/Project/TODO.numl new file mode 100644 index 0000000..ff26cc8 --- /dev/null +++ b/Project/TODO.numl @@ -0,0 +1,18 @@ +@sibjor +{ + [x] Project Directories + [ ] FilesLib Prototype + [ ] PathsLib Prototype + [ ] MidsLib Prototype + [ ] NetsLib Prototype + [ ] MathsLib Prototype + [ ] FileWorks Prototype (Sync, Versioning) + [ ] AuthSide Prototype (Auth & Registration Service, invite-only) + [ ] Kompis Prototype (E-Mail, Chat, VideoChat, VoiceChat, ScreenShare) + [ ] NetBud Prototype (WebServer, HTTP, HTTPS, SSH, TCP, UDP, FTP, SFTP) + [ ] InterLingo Prototype (LLVM Similar IR, Spoken Languages & Syntax) + [ ] NuCLI Prototype (Desktop CLI, Packages, Runs the Projects Stated Above) + [ ] Nudel (App Store with GUI) + [ ] DevIO Prototype (IDE with GUI & Extension Support) + [ ] OMDaw Prototype (DAW) +} \ No newline at end of file diff --git a/Rules/ALLOWED.numl b/Rules/ALLOWED.numl new file mode 100644 index 0000000..3a42af7 --- /dev/null +++ b/Rules/ALLOWED.numl @@ -0,0 +1,25 @@ +@sibjor +{ + Allowed: + Languages: + 1. English + 2. Swedish + 3. Norwiegan + 4. Icelandic + 5. Danish + 6. Finnish + Foreign Material: + 1. C (Clang) + 2. C++ (Clang++) + 3. LLVM + 4. Python + 5. Go + 6. SDL3 + 7. SDL3_image + 8. SDL3_mixer + 9. SDL3_ttf + 10. Google Fonts + +} + + \ No newline at end of file