### Quick Start Build Essentials Source: https://github.com/jordanhubbard/nanolang/blob/main/docs/BUILDING_WSL2.md Installs necessary build tools and builds the Nanolang compiler. Run this for a basic setup. ```bash sudo apt-get update sudo apt-get install -y build-essential python3 pkg-config make build make test make modules ``` -------------------------------- ### Installation Instructions Example Source: https://github.com/jordanhubbard/nanolang/blob/main/modules/MODULE_SCHEMA.md Example of installation instructions for different platforms, including package manager commands. ```json { "macos": { "brew": "sdl2", "command": "brew install sdl2" }, "linux": { "apt": "libsdl2-dev", "command": "sudo apt install libsdl2-dev" } } ``` -------------------------------- ### Install Nanolang Source: https://github.com/jordanhubbard/nanolang/blob/main/docs/FEATURES.md Instructions for cloning the Nanolang repository and building the compiler using `make`. This is the initial setup required to start using Nanolang. ```bash git clone cd nanolang make ``` -------------------------------- ### Complete Example: Game Audio Setup Source: https://github.com/jordanhubbard/nanolang/blob/main/userguide/part3_modules/16_graphics_fundamentals/sdl_mixer.md A comprehensive example demonstrating the initialization, loading, playback, and cleanup of audio assets for a game using SDL and SDL_mixer. ```APIDOC ## Game Audio Setup Example ### Description This example illustrates a typical audio setup for a game, including initializing SDL audio, opening the audio device, allocating channels, loading sound effects and music, setting volumes, playing audio with fades, and cleaning up resources. ### Initialization - `SDL_Init(SDL_INIT_AUDIO)`: Initializes SDL's audio subsystem. - `Mix_Init(MIX_INIT_OGG)`: Initializes support for OGG audio format. - `Mix_OpenAudio(44100, MIX_DEFAULT_FORMAT, 2, 2048)`: Opens the audio device with specified parameters. - `Mix_AllocateChannels(8)`: Allocates 8 channels for sound effects. ### Asset Loading - `Mix_LoadWAV("sounds/coin.wav")`: Loads a sound effect chunk. - `Mix_LoadWAV("sounds/hit.ogg")`: Loads another sound effect chunk. - `Mix_LoadMUS("music/level1.ogg")`: Loads a music track. ### Volume Control - `Mix_Volume(-1, 96)`: Sets the volume for all channels (-1) to 90% (96/128). - `Mix_VolumeMusic(MIX_MAX_VOLUME)`: Sets the music volume to maximum. ### Playback - `Mix_FadeInMusic(music, -1, 1000)`: Starts playing the loaded music with a 1-second fade-in. - `Mix_PlayChannel(-1, sfx_coin, 0)`: Plays the coin sound effect on the first available channel. - `SDL_Delay(500)`: Pauses execution for 500 milliseconds. - `Mix_PlayChannel(-1, sfx_hit, 0)`: Plays the hit sound effect on the first available channel. ### Cleanup - `Mix_HaltChannel(-1)`: Stops all currently playing sound effects. - `Mix_HaltMusic()`: Stops the currently playing music. - `Mix_FreeChunk(sfx_coin)`: Frees the memory for the coin sound effect. - `Mix_FreeChunk(sfx_hit)`: Frees the memory for the hit sound effect. - `Mix_FreeMusic(music)`: Frees the memory for the music track. - `Mix_CloseAudio()`: Closes the audio device. - `Mix_Quit()`: Shuts down SDL_mixer. - `SDL_Quit()`: Shuts down SDL. ``` -------------------------------- ### Quick Start HTTP Server Source: https://github.com/jordanhubbard/nanolang/blob/main/userguide/part3_modules/15_web_networking/http_server.md A basic example demonstrating how to create, start, stop, and free an HTTP server. It includes a simple handler for ping requests. ```nano from "modules/http_server/http_server.nano" import create, start, stop, free_server, send_ok_json, HttpServer, HttpRequest, HttpResponse fn handle_ping(req: HttpRequest, res: HttpResponse) -> void { (send_ok_json res "{\"status\": \"ok\"}") return } fn run() -> int { let server: HttpServer = (create 8080) # Register routes here when the routing API is available let rc: int = (start server) (stop server) (free_server server) return rc } shadow run { assert true } ``` -------------------------------- ### Build Examples Browser Source: https://github.com/jordanhubbard/nanolang/blob/main/README.md Compiles the examples browser for NanoLang. This requires SDL2 to be installed. ```bash cd examples && make launcher ``` -------------------------------- ### Complete Game Audio Setup Example Source: https://github.com/jordanhubbard/nanolang/blob/main/userguide/part3_modules/16_graphics_fundamentals/sdl_mixer.md A comprehensive example demonstrating SDL and SDL_mixer initialization, loading sound effects and music, setting volumes, playing audio with fade-in, and cleaning up resources. This snippet covers the full lifecycle of audio management in a game. ```nano from "modules/sdl/sdl.nano" import SDL_Init, SDL_Quit, SDL_INIT_AUDIO, SDL_Delay from "modules/sdl_mixer/sdl_mixer.nano" import Mix_Init, Mix_Quit, Mix_OpenAudio, Mix_CloseAudio, Mix_AllocateChannels, Mix_LoadWAV, Mix_FreeChunk, Mix_LoadMUS, Mix_FreeMusic, Mix_PlayChannel, Mix_HaltChannel, Mix_PlayMusic, Mix_FadeInMusic, Mix_HaltMusic, Mix_Volume, Mix_VolumeMusic, Mix_Chunk, Mix_Music, MIX_INIT_OGG, MIX_DEFAULT_FORMAT, MIX_MAX_VOLUME fn main() -> void { (SDL_Init SDL_INIT_AUDIO) (Mix_Init MIX_INIT_OGG) (Mix_OpenAudio 44100 MIX_DEFAULT_FORMAT 2 2048) (Mix_AllocateChannels 8) # Load assets let sfx_coin: Mix_Chunk = (Mix_LoadWAV "sounds/coin.wav") let sfx_hit: Mix_Chunk = (Mix_LoadWAV "sounds/hit.ogg") let music: Mix_Music = (Mix_LoadMUS "music/level1.ogg") # Set volumes (Mix_Volume -1 96) # sound effects at 75% (Mix_VolumeMusic MIX_MAX_VOLUME) # music at max # Start music with 1s fade-in (Mix_FadeInMusic music -1 1000) # Simulate game loop events (Mix_PlayChannel -1 sfx_coin 0) # player collected a coin (SDL_Delay 500) (Mix_PlayChannel -1 sfx_hit 0) # player took damage (SDL_Delay 2000) # Cleanup (Mix_HaltChannel -1) (Mix_HaltMusic) (Mix_FreeChunk sfx_coin) (Mix_FreeChunk sfx_hit) (Mix_FreeMusic music) (Mix_CloseAudio) (Mix_Quit) (SDL_Quit) } shadow main { assert true } ``` -------------------------------- ### Complete Nanolang Project Setup and Dependency Installation Source: https://github.com/jordanhubbard/nanolang/blob/main/docs/PACKAGE_MANAGER.md Demonstrates a full workflow including project creation, dependency addition via `nano.toml`, package installation, code writing with module import, and building the project. Also shows how to commit the lockfile. ```bash # Create a new project mkdir my_project && cd my_project nanoc-pkg init # Edit nano.toml to add dependencies cat >> nano.toml << 'EOF' [dependencies] vector2d = ">=1.0.0" EOF # Install dependencies nanoc-pkg install # ✓ vector2d@1.0.0 # Write your code cat > main.nano << 'EOF' import "modules/vector2d/vector2d.nano" fn main() -> Int { let v: Vector2D = vector2d_new(3.0, 4.0) let len: Float = vector2d_length(v) print("Length: " + float_to_string(len)) return 0 } EOF # Build nanoc main.nano -o my_project # Commit the lockfile git add nano.toml nano.lock git commit -m "Add vector2d dependency" ``` -------------------------------- ### Quick Start Logging Example Source: https://github.com/jordanhubbard/nanolang/blob/main/userguide/part3_modules/13_text_processing/log.md Demonstrates basic usage of log_info and log_error with categories for processing orders. Includes assertions to test functionality. ```nano from "stdlib/log.nano" import log_info, log_warn, log_error fn process_order(order_id: int) -> bool { (log_info "orders" (+ "Processing order #" (int_to_string order_id))) if (< order_id 1) { (log_error "orders" "Invalid order ID — must be positive") return false } (log_info "orders" "Order validated successfully") return true } shadow process_order { assert (process_order 42) assert (not (process_order 0)) } ``` -------------------------------- ### Nanolang GPU Quick Start Example Source: https://github.com/jordanhubbard/nanolang/blob/main/examples/gpu/README.md Demonstrates initializing the GPU, allocating device memory, launching a PTX kernel for vector addition, synchronizing, and freeing memory. This example requires a CUDA-capable GPU to run successfully. ```nano import "modules/gpu/gpu.nano" gpu fn vector_add(a: int, b: int, c: int, n: int) -> void { let i: int = (global_id_x) if (< i n) { # ... per-element work ... return } } fn main() -> int { if (not (gpu_init)) { print "No GPU" return 1 } let d_a: int = (gpu_alloc (* n 8)) let d_b: int = (gpu_alloc (* n 8)) let d_c: int = (gpu_alloc (* n 8)) (gpu_launch "vector_add.ptx" "vector_add" blocks threads d_a d_b d_c n) (gpu_sync) (gpu_free d_a) (gpu_free d_b) (gpu_free d_c) return 0 } ``` -------------------------------- ### Install and Run Nanolang Source: https://github.com/jordanhubbard/nanolang/blob/main/docs/tutorials/README.md Quick start commands to clone the repository, build the project, and run a 'Hello, World!' program using the Nanolang compiler. ```bash # Install git clone https://github.com/jordanhubbard/nanolang.git cd nanolang && make # Hello World echo 'fn main() -> int { (println "Hello, World!") return 0 }' > hello.nano ./bin/nano hello.nano ./bin/nanoc hello.nano -o hello && ./hello # Learn by example cd examples && ls *.nano ``` -------------------------------- ### Quick Start: Hello Terminal Source: https://github.com/jordanhubbard/nanolang/blob/main/userguide/part3_modules/19_terminal_ui/ncurses.md A basic example demonstrating ncurses initialization, basic text output, and cleanup. Ensure to call endwin_wrapper to restore the terminal. ```nano from "modules/ncurses/ncurses.nano" import initscr_wrapper, endwin_wrapper, noecho_wrapper, cbreak_wrapper, getch_wrapper, refresh_wrapper, mvprintw_wrapper, clear_wrapper fn hello_terminal() -> void { (initscr_wrapper) # Enter curses mode (noecho_wrapper) # Don't echo typed characters (cbreak_wrapper) # Disable line buffering (mvprintw_wrapper 0 0 "Hello, Terminal!") (mvprintw_wrapper 1 0 "Press any key to exit...") (refresh_wrapper) (getch_wrapper) # Wait for one keystroke (endwin_wrapper) # Restore normal terminal } shadow hello_terminal { # Cannot run interactive TUI in shadow tests; just assert compile success assert true } ``` -------------------------------- ### NanoLang Game Loop with Event System Source: https://github.com/jordanhubbard/nanolang/blob/main/userguide/part3_modules/18_game_dev/event.md A quick start example demonstrating the basic setup of an event loop in NanoLang. It initializes the event base, sets up a one-shot timer, dispatches the event loop, and cleans up resources. ```nano from "modules/event/event.nano" import nl_event_base_new, nl_event_base_dispatch, nl_event_base_free, nl_evtimer_new, nl_evtimer_add_timeout, nl_event_free, nl_event_get_version fn main() -> int { # Check the libevent version at startup let ver: string = (nl_event_get_version) (println (+ "libevent version: " ver)) # Create the event loop base let base: int = (nl_event_base_new) # Create a one-shot timer, fire in 1 second let timer: int = (nl_evtimer_new base) (nl_evtimer_add_timeout timer 1) # Block until all events fire (or loopbreak/loopexit is called) (nl_event_base_dispatch base) # Cleanup (nl_event_free timer) (nl_event_base_free base) return 0 } shadow main { assert true } ``` -------------------------------- ### Auto-install Workflow Example Source: https://github.com/jordanhubbard/nanolang/blob/main/modules/MODULE_AUDIT_REPORT.md Illustrates the process of how NanoLang source code, module.json, and packages.json interact to trigger system package installation via a package manager. ```text NanoLang source module.json packages.json package manager ───────────────── ───────────── ────────────── ─────────────── unsafe module "..." ───► system_packages: ["mujoco"] ──► packages.mujoco.install.brew ──► brew install --cask mujoco .linux ─► sh modules/mujoco/install_linux.sh .apt ──► sudo apt install ... .pkg ──► sudo pkg install ... ``` -------------------------------- ### Basic HTTP Server Setup Source: https://github.com/jordanhubbard/nanolang/blob/main/userguide/part3_modules/15_web_networking/index.md Creates and starts a basic HTTP server on a specified port. The server can be stopped using `stop_server`. ```nano from "modules/http_server/http_server.nano" import create_server, start_server, stop_server fn run_server() -> int { let server: int = (create_server 8080) (start_server server) # Server runs... (stop_server server) return 0 } shadow run_server { # Would test with actual server assert true } ``` -------------------------------- ### Install Build Prerequisites on macOS Source: https://github.com/jordanhubbard/nanolang/blob/main/docs/PLATFORM_COMPATIBILITY.md Install command-line tools and Homebrew, then use Homebrew to install optional dependencies for SDL2, OpenGL, and audio libraries on macOS. This prepares the system for building nanolang and its examples. ```bash xcode-select --install # Install command-line tools # Install Homebrew if needed /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)" # Install optional dependencies brew install sdl2 sdl2_ttf glfw glew ``` -------------------------------- ### Setup New Development Environment Source: https://github.com/jordanhubbard/nanolang/blob/main/docs/MODULE_DEPENDENCIES.md A workflow for setting up a new development environment by checking dependencies, installing necessary packages, and building the project. ```bash # 1. Check what's needed make -B modules # 2. Install dependencies sudo apt-get install -y [packages from above] # 3. Build everything make build make test make examples ``` -------------------------------- ### Complete Lit Teapot Scene Example Source: https://github.com/jordanhubbard/nanolang/blob/main/userguide/part3_modules/17_opengl/glut.md A comprehensive example demonstrating the setup and display functions for a lit teapot scene using GLUT and OpenGL in NanoLang. Includes initialization, lighting, material properties, and rendering of a teapot and sphere. ```nano from "modules/glew/glew.nano" import glewInit, glClear, nlg_glClearColor, glEnable, glShadeModel, glMatrixMode, glLoadIdentity, glFrustum, glViewport, nl_glLightfv4, nl_glMaterialfv4, GL_COLOR_BUFFER_BIT, GL_DEPTH_BUFFER_BIT, GL_DEPTH_TEST, GL_LIGHTING, GL_LIGHT0, GL_SMOOTH, GL_MODELVIEW, GL_PROJECTION, GL_POSITION, GL_DIFFUSE, GL_AMBIENT from "modules/opengl/opengl.nano" import glRotatef, glTranslatef, glColor3f from "modules/glut/glut.nano" import glutInit, glutInitDisplayMode, glutInitWindowSize, glutCreateWindow, glutMainLoop, glutSwapBuffers, glutPostRedisplay, glutSolidTeapot, glutSolidSphere, GLUT_DOUBLE, GLUT_RGBA, GLUT_DEPTH fn setup() -> void { (glutInit 0 0) (glutInitDisplayMode (+ GLUT_DOUBLE (+ GLUT_RGBA GLUT_DEPTH))) (glutInitWindowSize 800 600) (glutCreateWindow "Teapot Scene") (glewInit) # OpenGL state (glEnable GL_DEPTH_TEST) (glEnable GL_LIGHTING) (glEnable GL_LIGHT0) (glShadeModel GL_SMOOTH) (nl_glLightfv4 GL_LIGHT0 GL_POSITION 5.0 10.0 5.0 1.0) (nl_glLightfv4 GL_LIGHT0 GL_DIFFUSE 1.0 0.9 0.8 1.0) (nl_glLightfv4 GL_LIGHT0 GL_AMBIENT 0.1 0.1 0.15 1.0) } # This function would be called from the GLUT display callback (via C shim) fn display(angle: float) -> void { (nlg_glClearColor 0.05 0.05 0.1 1.0) (glClear (+ GL_COLOR_BUFFER_BIT GL_DEPTH_BUFFER_BIT)) (glMatrixMode GL_PROJECTION) (glLoadIdentity) (glFrustum -1.0 1.0 -0.75 0.75 1.0 50.0) (glMatrixMode GL_MODELVIEW) (glLoadIdentity) (glTranslatef 0.0 0.0 -3.5) (glRotatef angle 0.0 1.0 0.0) # Teapot (glColor3f 0.8 0.5 0.2) (glutSolidTeapot 0.8) # Small sphere off to the side (glTranslatef 1.5 0.3 0.0) (glColor3f 0.3 0.6 1.0) (glutSolidSphere 0.25 24 24) (glutSwapBuffers) (glutPostRedisplay) } shadow setup { assert true } shadow display { assert true } ``` -------------------------------- ### Quick Start: In-Memory Database Operations Source: https://github.com/jordanhubbard/nanolang/blob/main/userguide/part3_modules/14_data_formats/sqlite.md Demonstrates opening an in-memory database, creating a table, inserting data with a prepared statement, and querying the data. This example covers basic CRUD operations. ```nano from "modules/sqlite/sqlite.nano" import open, close, exec_ok, prepare, step, finalize, bind_text, bind_int, column_text, column_int, has_row fn quick_demo() -> int { # Open an in-memory database let db: int = (open ":memory:") # Create a table (exec_ok db "CREATE TABLE people (id INTEGER PRIMARY KEY, name TEXT, age INTEGER)") # Insert using a prepared statement let stmt: int = (prepare db "INSERT INTO people (name, age) VALUES (?, ?)") (bind_text stmt 1 "Alice") (bind_int stmt 2 30) (step stmt) (finalize stmt) # Query let q: int = (prepare db "SELECT name, age FROM people") let rc: int = (step q) let mut count: int = 0 while (has_row rc) { let name: string = (column_text q 0) let age: int = (column_int q 1) (println (+ name (+ " is " (+ (int_to_string age) " years old")))) set count (+ count 1) set rc (step q) } (finalize q) (close db) return count } shadow quick_demo { assert (== (quick_demo) 1) } ``` -------------------------------- ### Run a Simple ONNX Example Source: https://github.com/jordanhubbard/nanolang/blob/main/docs/AI_ML_GUIDE.md Executes a basic ONNX model using Nanolang. This is a starting point for beginners. ```bash examples/40_onnx_simple.nano ``` -------------------------------- ### Complete API Client Example using curl Source: https://github.com/jordanhubbard/nanolang/blob/main/userguide/part3_modules/15_web_networking/index.md An example demonstrating how to build a more complete API client, including fetching user data and creating users, using both GET and POST requests with headers. It also shows JSON parsing. ```nano from "modules/curl/curl.nano" import get, post_with_headers from "modules/std/json/json.nano" import parse, get_string, Json fn fetch_user(user_id: int) -> string { let url: string = (+ "https://api.example.com/users/" (int_to_string user_id)) let response: string = (get url) let json: Json = (parse response) let name: string = (get_string json "name") return name # No free() needed - automatic GC! } fn create_user(name: string, email: string) -> bool { let data: string = (+ "{\"name\": \"" (+ name (+ "\", \"email\": \"" (+ email "\"}")))) let headers: array = ["Content-Type: application/json"] let response: string = (post_with_headers "https://api.example.com/users" data headers) return (> (str_length response) 0) } shadow create_user { assert true } ``` -------------------------------- ### Basic libuv Usage Example Source: https://github.com/jordanhubbard/nanolang/blob/main/modules/uv/README.md Demonstrates basic libuv functionalities like getting system information and timing. This snippet requires the 'modules/uv/uv.nano' import. ```nano import "modules/uv/uv.nano" fn main() -> int { # Get system information (print "libuv version: ") (println (nl_uv_version_string)) (print "CPUs: ") (println (nl_uv_cpu_count)) (print "Hostname: ") (println (nl_uv_os_gethostname)) # Create event loop let loop: int = (nl_uv_default_loop) # Get current time in milliseconds let now: int = (nl_uv_now loop) (print "Current time (ms): ") (println now) # High-resolution timer let hrtime: int = (nl_uv_hrtime) (print "High-res time (ns): ") (println hrtime) return 0 } shadow main { # Skip - uses extern functions } ``` -------------------------------- ### Build Nanolang Examples Source: https://github.com/jordanhubbard/nanolang/blob/main/README.md Command to build all example programs written in Nanolang. ```bash make examples ``` -------------------------------- ### Test Nanolang User Guide Locally Source: https://github.com/jordanhubbard/nanolang/blob/main/docs/USERGUIDE_BUILD.md Build the HTML user guide, then serve it locally using Python's http.server for testing. Visit the provided localhost URL to view the guide. ```bash # Build HTML make userguide # Test locally cd docs_html python3 -m http.server 8000 # Visit http://localhost:8000 ``` -------------------------------- ### Build Compiled Example Set Source: https://github.com/jordanhubbard/nanolang/blob/main/examples/README.md Builds the compiled example set as defined by examples/Makefile. Use this command to prepare the examples for execution. ```bash make -C examples ``` -------------------------------- ### Quick Start: Fetch JSON with simple GET Source: https://github.com/jordanhubbard/nanolang/blob/main/userguide/part3_modules/15_web_networking/curl.md A basic example demonstrating how to fetch JSON data from a URL using the `nl_curl_simple_get` function. This function handles initialization and cleanup internally. ```nano from "modules/curl/curl.nano" import nl_curl_simple_get fn fetch_json(url: string) -> string { unsafe { return (nl_curl_simple_get url) } } shadow fetch_json { assert true } ``` -------------------------------- ### start Source: https://github.com/jordanhubbard/nanolang/blob/main/userguide/api_reference/http_server.md Starts the HTTP server, making it ready to accept incoming connections. ```APIDOC ## start ### Description Starts the HTTP server, making it ready to accept incoming connections. ### Parameters #### Path Parameters - **server** (HttpServer) - Required - The HTTP server instance to start. ### Returns - **int** - An integer indicating the success or failure of starting the server. ``` -------------------------------- ### Install MuJoCo on Linux Source: https://github.com/jordanhubbard/nanolang/blob/main/modules/mujoco/README.md Installs MuJoCo from release metadata into a local directory. This is an example of the manual installation steps required if automatic installation fails or is not desired. ```bash sudo mkdir -p /opt/mujoco # unpack the release so /opt/mujoco/include/mujoco/mujoco.h exists rm -rf modules/mujoco/.build ``` -------------------------------- ### SDL Core Module Basic Window and Rendering Example Source: https://github.com/jordanhubbard/nanolang/blob/main/modules/SDL_EXTENSIONS.md Demonstrates initializing SDL, creating a window and renderer, handling quit events, clearing the screen, drawing a rectangle, and cleaning up resources. ```nano import "modules/sdl/sdl.nano" import "modules/sdl_helpers/sdl_helpers.nano" fn main() -> int { # Initialize SDL (SDL_Init SDL_INIT_VIDEO) # Create window let window: int = (SDL_CreateWindow "My App" 100 100 800 600 SDL_WINDOW_SHOWN) let renderer: int = (SDL_CreateRenderer window (- 1) SDL_RENDERER_ACCELERATED) # Main loop let mut running: bool = true while running { let quit: int = (nl_sdl_poll_event_quit) if (== quit 1) { set running false } else {} # Clear screen (SDL_SetRenderDrawColor renderer 0 0 0 255) (SDL_RenderClear renderer) # Draw something (SDL_SetRenderDrawColor renderer 255 0 0 255) (nl_sdl_render_fill_rect renderer 100 100 200 200) # Present (SDL_RenderPresent renderer) (SDL_Delay 16) } # Cleanup (SDL_DestroyRenderer renderer) (SDL_DestroyWindow window) (SDL_Quit) return 0 } ``` -------------------------------- ### Install and Run Ollama Source: https://github.com/jordanhubbard/nanolang/blob/main/modules/openai/README.md Shell commands to install Ollama, download a model (llama2), and start the Ollama server. ```bash # Install Ollama curl https://ollama.ai/install.sh | sh # Download a model ollama pull llama2 # Run (starts on port 11434) ollama serve ``` -------------------------------- ### Get Field Count Example Source: https://github.com/jordanhubbard/nanolang/blob/main/docs/REFLECTION_API.md Demonstrates how to get the total number of fields in a struct using the generated field count function. ```nano extern fn ___reflect_Point_field_count() -> int fn main() -> int { let count: int = (___reflect_Point_field_count) (println (int_to_string count)) // Output: 3 return 0 } ``` -------------------------------- ### Serve Documentation Locally Source: https://github.com/jordanhubbard/nanolang/blob/main/userguide/README.md This command starts a local server to preview the documentation. Access it via http://localhost:3000. The server behavior mirrors GitHub Pages. ```bash make -C userguide serve ``` -------------------------------- ### Install SDL2 Development Libraries on Ubuntu/Debian or macOS Source: https://github.com/jordanhubbard/nanolang/blob/main/docs/PLATFORM_COMPATIBILITY.md Install the SDL2 development libraries, necessary for Nanolang examples that use the SDL graphics library. ```bash # Ubuntu/Debian sudo apt-get install libsdl2-dev # macOS brew install sdl2 ``` -------------------------------- ### Best Practice: Starting Simple with Properties Source: https://github.com/jordanhubbard/nanolang/blob/main/docs/PROPERTY_TESTING_GUIDE.md Illustrates the practice of starting with basic properties, like commutativity for an `add` function, and then adding more complex properties, such as the identity property. ```nano # I begin with basic properties shadow add { (proptest_int_pair "commutative" 100 (fn (a: int, b: int) -> bool { return (== (add a b) (add b a)) })) } # Then I add more complex properties shadow add { (proptest_int "identity" 100 (fn (x: int) -> bool { return (== (add x 0) x) })) } ``` -------------------------------- ### CI/CD Pipeline Example Source: https://github.com/jordanhubbard/nanolang/blob/main/docs/MODULE_DEPENDENCIES.md A sample GitHub Actions workflow for a CI/CD pipeline that installs dependencies, validates modules, and builds examples in strict mode. ```yaml # GitHub Actions example - name: Install dependencies run: | sudo apt-get update sudo apt-get install -y build-essential python3 pkg-config # Add other dependencies as needed - name: Validate modules run: make -B modules - name: Build examples (strict) run: make examples ``` -------------------------------- ### Get Field Type by Name Example Source: https://github.com/jordanhubbard/nanolang/blob/main/docs/REFLECTION_API.md Shows how to get the type of a struct field by providing its name. Returns an empty string if the field is not found. ```nano extern fn ___reflect_Point_field_type_by_name(name: string) -> string fn main() -> int { let x_type: string = (___reflect_Point_field_type_by_name "x") (println x_type) // Output: int let label_type: string = (___reflect_Point_field_type_by_name "label") (println label_type) // Output: string return 0 } ``` -------------------------------- ### Build Nanolang User Guide Source: https://github.com/jordanhubbard/nanolang/blob/main/docs/USERGUIDE_BUILD.md Execute the make command to build the user guide from the project root, or run the nano script directly. ```bash # From project root make userguide # Or directly ./scripts/userguide_build_html.nano ``` -------------------------------- ### Running User Guide Snippet Tests Source: https://github.com/jordanhubbard/nanolang/blob/main/MEMORY.md Execute tests specifically for the code snippets found within the user guide. This ensures documentation examples are up-to-date. ```bash make test-docs ``` -------------------------------- ### Set Up Environment Variables Source: https://github.com/jordanhubbard/nanolang/blob/main/examples/autonomous_github_agent.README.md Copy the example configuration, edit the .env file with your specific values, and export the minimum required environment variables for the agent to function. ```bash cp autonomous_github_agent.env.example .env nano .env export GITHUB_OWNER="your-username" export GITHUB_REPO="your-repo" export GITHUB_TOKEN="ghp_xxxxxxxxxxxx" export OPENAI_API_KEY="sk-xxxxxxxxxxxx" ``` -------------------------------- ### Complete Minimal SDL Example in NanoLang Source: https://github.com/jordanhubbard/nanolang/blob/main/userguide/part3_modules/16_graphics_fundamentals/sdl.md A full example demonstrating SDL initialization, window and renderer creation, an event loop with a cycling background color, and proper cleanup. ```nano from "modules/sdl/sdl.nano" import SDL_Init, SDL_Quit, SDL_GetError, SDL_CreateWindow, SDL_DestroyWindow, SDL_CreateRenderer, SDL_DestroyRenderer, SDL_SetRenderDrawColor, SDL_RenderClear, SDL_RenderPresent, SDL_PollEvent, SDL_GetTicks, SDL_Delay, SDL_Window, SDL_Renderer, SDL_INIT_VIDEO, SDL_WINDOWPOS_CENTERED, SDL_WINDOW_SHOWN, SDL_RENDERER_ACCELERATED, SDL_RENDERER_PRESENTVSYNC fn run() -> void { let init_result: int = (SDL_Init SDL_INIT_VIDEO) if (!= init_result 0) { (print (SDL_GetError)) return } let window: SDL_Window = (SDL_CreateWindow "NanoLang SDL Demo" SDL_WINDOWPOS_CENTERED SDL_WINDOWPOS_CENTERED 640 480 SDL_WINDOW_SHOWN) let renderer: SDL_Renderer = (SDL_CreateRenderer window -1 (+ SDL_RENDERER_ACCELERATED SDL_RENDERER_PRESENTVSYNC)) let mut running: bool = true while running { # Drain events (quit detection requires a C shim in practice) let mut ev: int = (SDL_PollEvent 0) while (!= ev 0) { set ev (SDL_PollEvent 0) } # Cycle background color using time let t: int = (SDL_GetTicks) let r: int = (% t 256) let g: int = (% (+ t 85) 256) let b: int = (% (+ t 170) 256) (SDL_SetRenderDrawColor renderer r g b 255) (SDL_RenderClear renderer) (SDL_RenderPresent renderer) (SDL_Delay 16) } (SDL_DestroyRenderer renderer) (SDL_DestroyWindow window) (SDL_Quit) } shadow run { assert true } ``` -------------------------------- ### String Operation Example Source: https://github.com/jordanhubbard/nanolang/blob/main/docs/LLM_CORE_SUBSET.md Demonstrates concatenating strings and getting the length of a string. ```nano let greeting: string = (+ "Hello, " name) let len: int = (str_length greeting) ``` -------------------------------- ### Multi-File Module: Main Entry Point Source: https://github.com/jordanhubbard/nanolang/blob/main/docs/tutorials/03-modules.md Imports User and Post modules and demonstrates creating instances of User and Post, then printing their properties. This is the main entry point for the multi-file module example. ```nano import "models/user.nano" as User import "models/post.nano" as Post fn main() -> int { let user: User.User = (User.create_user "alice" "alice@example.com") let post: Post.Post = (Post.create_post "Hello" "Content" user.id) (println user.username) (println post.title) return 0 } ``` -------------------------------- ### Simple GET Request with curl Source: https://github.com/jordanhubbard/nanolang/blob/main/userguide/part3_modules/15_web_networking/index.md Performs a simple GET request to a specified URL using the curl module. No special setup is required beyond importing the function. ```nano from "modules/curl/curl.nano" import get fn fetch_webpage() -> string { let response: string = (get "https://example.com") return response } shadow fetch_webpage { # Would test with actual HTTP request assert true } ``` -------------------------------- ### Lock File Example (nano.lock) Source: https://github.com/jordanhubbard/nanolang/blob/main/planning/PACKAGE_MANAGER_DESIGN.md A TOML file used to lock specific versions of installed dependencies, ensuring reproducible builds. Typically generated by 'nano pkg install'. ```toml # Generated by nano pkg install ``` -------------------------------- ### Install Build Prerequisites on Ubuntu/Debian Source: https://github.com/jordanhubbard/nanolang/blob/main/docs/PLATFORM_COMPATIBILITY.md Install essential build tools and optional development libraries for SDL2 and OpenGL on Ubuntu/Debian systems. This is required for building nanolang and its examples from source. ```bash sudo apt-get update sudo apt-get install build-essential pkg-config # Optional: For SDL examples sudo apt-get install libsdl2-dev libsdl2_ttf-dev # Optional: For OpenGL examples sudo apt-get install libglfw3-dev libglew-dev ``` -------------------------------- ### Complete Example: User Database Source: https://github.com/jordanhubbard/nanolang/blob/main/userguide/part3_modules/14_data_formats/index.md This example demonstrates defining a User struct, setting up a SQLite database table, adding users with prepared statements to prevent SQL injection, finding users by email, and includes a shadow function to test the database operations. ```nano struct User { id: int, name: string, email: string, age: int } fn setup_users_db(db: int) -> bool { let sql: string = "CREATE TABLE IF NOT EXISTS users (id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT NOT NULL, email TEXT, age INTEGER)" unsafe { return (== (nl_sqlite3_exec db sql) 0) } } fn add_user(db: int, name: string, email: string, age: int) -> int { let sql: string = "INSERT INTO users (name, email, age) VALUES (?, ?, ?)" unsafe { let stmt: int = (nl_sqlite3_prepare db sql) if (== stmt 0) { return 0 } (nl_sqlite3_bind_text stmt 1 name) (nl_sqlite3_bind_text stmt 2 email) (nl_sqlite3_bind_int stmt 3 age) (nl_sqlite3_step stmt) (nl_sqlite3_finalize stmt) # Get last inserted row ID return (nl_sqlite3_last_insert_rowid db) } } fn find_user_by_email(db: int, email: string) -> int { let sql: string = "SELECT id, name, age FROM users WHERE email = ?" unsafe { let stmt: int = (nl_sqlite3_prepare db sql) if (== stmt 0) { return 0 } (nl_sqlite3_bind_text stmt 1 email) if (!= (nl_sqlite3_step stmt) 0) { let user_id: int = (nl_sqlite3_column_int stmt 0) (nl_sqlite3_finalize stmt) return user_id } (nl_sqlite3_finalize stmt) return 0 } } shadow find_user_by_email { let db: int = (open_database ":memory:") (setup_users_db db) let user_id: int = (add_user db "Alice" "alice@example.com" 30) assert (> user_id 0) let found_id: int = (find_user_by_email db "alice@example.com") assert (== found_id user_id) unsafe { (nl_sqlite3_close db) } } ``` -------------------------------- ### Build and Verify Examples Source: https://github.com/jordanhubbard/nanolang/blob/main/planning/archive/docs/EXAMPLES_WARNINGS_AUDIT.md Compiles all examples and verifies the presence of generated binaries. This command is used to trigger the build process and check the output. ```bash cd examples && make build ls -la ../bin/ | grep -E "sdl_nanoamp|sdl_ui_widgets" ``` -------------------------------- ### Get Array Length Source: https://github.com/jordanhubbard/nanolang/blob/main/userguide/part1_fundamentals/06_collections.md Provides examples of using `array_length` to get the number of elements in arrays of different sizes, including an empty array. The shadow block asserts the results. ```nano fn get_length(arr: array) -> int { return (array_length arr) } shadow get_length { assert (== (get_length [1, 2, 3]) 3) assert (== (get_length []) 0) assert (== (get_length [42]) 1) } ``` -------------------------------- ### Quick Start: Load and Render an Image Source: https://github.com/jordanhubbard/nanolang/blob/main/modules/sdl_image/README.md A basic NanoLang program demonstrating how to initialize SDL and SDL_image, load an image texture, render it, and handle the main loop. ```nano import "modules/sdl/sdl.nano" import "modules/sdl_image/sdl_image.nano" fn main() -> int { unsafe { (SDL_Init 32) } unsafe { (IMG_Init IMG_INIT_ALL) } let window: SDL_Window = (SDL_CreateWindow "Image Demo" 100 100 800 600 4) let renderer: SDL_Renderer = (SDL_CreateRenderer window -1 2) # Load an image let texture: int = (nl_img_load_texture renderer "icon.png") # Main loop let mut running: bool = true while running { if (== (nl_sdl_poll_event_quit) 1) { set running false } else {} unsafe { (SDL_RenderClear renderer) } (nl_img_render_texture renderer texture 100 100 200 200) unsafe { (SDL_RenderPresent renderer) } unsafe { (SDL_Delay 16) } } (nl_img_destroy_texture texture) unsafe { (IMG_Quit) } unsafe { (SDL_Quit) } return 0 } ``` -------------------------------- ### Install SDL2 and OpenGL Libraries on macOS Source: https://github.com/jordanhubbard/nanolang/blob/main/docs/PLATFORM_COMPATIBILITY.md Use Homebrew to install necessary development libraries for SDL2 and OpenGL on macOS. This ensures that examples requiring these libraries can be built and run correctly. ```bash # SDL2 and related brew install sdl2 sdl2_ttf # OpenGL development (for GLFW/GLEW examples) brew install glfw glew # Audio libraries (for MOD player example) brew install libsndfile ``` -------------------------------- ### Install Minimal Dependencies and Build Source: https://github.com/jordanhubbard/nanolang/blob/main/docs/MODULE_DEPENDENCIES.md Installs essential build tools and then builds and tests the core compiler and standard library. ```bash sudo apt-get install -y build-essential python3 make build make test ``` -------------------------------- ### Get Field Name by Index Example Source: https://github.com/jordanhubbard/nanolang/blob/main/docs/REFLECTION_API.md Shows how to retrieve the name of a struct field by its 0-based index. ```nano extern fn ___reflect_Point_field_name(index: int) -> string fn main() -> int { let name0: string = (___reflect_Point_field_name 0) (println name0) // Output: x let name1: string = (___reflect_Point_field_name 1) (println name1) // Output: y return 0 } ``` -------------------------------- ### Example: Accessing Character Source: https://github.com/jordanhubbard/nanolang/blob/main/planning/STRING_OPERATIONS_PLAN.md Demonstrates how to use char_at to get the ASCII value of a character and perform a conditional check. ```nano let source: string = "let x = 42" let c: int = (char_at source 0) # Returns 108 (ASCII 'l') if (== c 108) { print "Found 'let' keyword" } ``` -------------------------------- ### Complete Example: Load and Display Sprite Source: https://github.com/jordanhubbard/nanolang/blob/main/userguide/part3_modules/16_graphics_fundamentals/sdl_image.md A full demonstration of initializing SDL and SDL Image, loading a sprite texture, rendering it with scrolling, and cleaning up resources. ```nano from "modules/sdl/sdl.nano" import SDL_Init, SDL_Quit, SDL_CreateWindow, SDL_DestroyWindow, SDL_CreateRenderer, SDL_DestroyRenderer, SDL_SetRenderDrawColor, SDL_RenderClear, SDL_RenderPresent, SDL_PollEvent, SDL_Delay, SDL_Window, SDL_Renderer, SDL_INIT_VIDEO, SDL_WINDOWPOS_CENTERED, SDL_WINDOW_SHOWN, SDL_RENDERER_ACCELERATED, SDL_RENDERER_PRESENTVSYNC from "modules/sdl_image/sdl_image.nano" import IMG_Init, IMG_Quit, nl_img_load_texture, nl_img_destroy_texture, nl_img_render_texture, nl_img_get_texture_width, nl_img_get_texture_height, IMG_INIT_PNG fn run() -> void { (SDL_Init SDL_INIT_VIDEO) (IMG_Init IMG_INIT_PNG) let window: SDL_Window = (SDL_CreateWindow "Sprite Demo" SDL_WINDOWPOS_CENTERED SDL_WINDOWPOS_CENTERED 640 480 SDL_WINDOW_SHOWN) let renderer: SDL_Renderer = (SDL_CreateRenderer window -1 (+ SDL_RENDERER_ACCELERATED SDL_RENDERER_PRESENTVSYNC)) let sprite: int = (nl_img_load_texture renderer "assets/hero.png") let sw: int = (nl_img_get_texture_width sprite) let sh: int = (nl_img_get_texture_height sprite) let mut x: int = 0 let mut running: bool = true while running { let mut ev: int = (SDL_PollEvent 0) while (!= ev 0) { set ev (SDL_PollEvent 0) } # Scroll sprite across screen set x (% (+ x 2) 640) (SDL_SetRenderDrawColor renderer 20 20 40 255) (SDL_RenderClear renderer) (nl_img_render_texture renderer sprite x 200 sw sh) (SDL_RenderPresent renderer) (SDL_Delay 16) } (nl_img_destroy_texture sprite) (SDL_DestroyRenderer renderer) (SDL_DestroyWindow window) (IMG_Quit) (SDL_Quit) } shadow run { assert true } ``` -------------------------------- ### Checking Available Events Example Source: https://github.com/jordanhubbard/nanolang/blob/main/userguide/part3_modules/18_game_dev/event.md Shows how to check the event backend method and the number of registered events for an event base. This example demonstrates creating an event base, getting its method and event count, and then cleaning up resources. ```nano from "modules/event/event.nano" import nl_event_base_new, nl_event_base_get_num_events, nl_evtimer_new, nl_event_base_free, nl_event_free, nl_event_base_get_method fn show_event_info() -> void { let base: int = (nl_event_base_new) let method: string = (nl_event_base_get_method base) (println (+ "Backend: " method)) let t: int = (nl_evtimer_new base) let n: int = (nl_event_base_get_num_events base) (println (+ "Registered events: " (int_to_string n))) (nl_event_free t) (nl_event_base_free base) } shadow show_event_info { (show_event_info) } ``` -------------------------------- ### Example Project Structure and Imports Source: https://github.com/jordanhubbard/nanolang/blob/main/docs/MULTI_FILE_PROJECTS.md Demonstrates a typical multi-file project structure and the import statements used within each file. ```nano // types.nano - Base definitions enum Status { Ok, Error, Pending } let MAX_RETRIES: int = 3 let TIMEOUT: float = 30.0 // utils.nano - Uses types import "examples/myproject/types.nano" let retry_count = MAX_RETRIES * 2 // Constants work! // core.nano - Uses types and utils import "examples/myproject/types.nano" import "examples/myproject/utils.nano" // main.nano - Uses everything import "examples/myproject/types.nano" import "examples/myproject/utils.nano" import "examples/myproject/core.nano" ``` -------------------------------- ### Deploy Nanolang User Guide to GitHub Pages Source: https://github.com/jordanhubbard/nanolang/blob/main/docs/USERGUIDE_BUILD.md Build the user guide, commit the generated HTML files to the repository, and push the changes. Configure GitHub Pages to serve from the 'docs_html' directory. ```bash # Build make userguide # Deploy git add docs_html/ git commit -m "docs: Update user guide HTML" git push # Configure GitHub Pages to serve from /docs_html ``` -------------------------------- ### Manually Deploy Nanolang User Guide Source: https://github.com/jordanhubbard/nanolang/blob/main/docs/USERGUIDE_BUILD.md Copy the generated HTML user guide files to the web server's document root using scp. ```bash # Copy to web server scp -r docs_html/* user@server:/var/www/nanolang/ ``` -------------------------------- ### Nanolang StringBuilder Snapshot Example Source: https://github.com/jordanhubbard/nanolang/blob/main/userguide/part3_modules/13_text_processing/stringbuilder.md Demonstrates how to get snapshots of the current content of a StringBuilder at different points in time using `sb_to_string`. ```nano from "std/collections/stringbuilder.nano" import sb_new, sb_append, sb_to_string, sb_free, StringBuilder fn snapshot_example() -> bool { let mut sb: StringBuilder = (sb_new) set sb (sb_append sb "Hello") let partial: string = (sb_to_string sb) # "Hello" set sb (sb_append sb " World") let full: string = (sb_to_string sb) # "Hello World" (sb_free sb) return (and (== partial "Hello") (== full "Hello World")) } shadow snapshot_example { assert (snapshot_example) } ``` -------------------------------- ### Finding First Number in String Source: https://github.com/jordanhubbard/nanolang/blob/main/userguide/part3_modules/13_text_processing/regex.md Demonstrates using `find` to get the starting byte index of the first sequence of digits in a string. ```nano from "std/regex/regex.nano" import compile, find, Regex fn find_first_number(text: string) -> int { let re: Regex = (compile "[0-9]+") return (find re text) } shadow find_first_number { assert (== (find_first_number "abc 42 xyz") 4) assert (== (find_first_number "no digits here") -1) } ``` -------------------------------- ### NanoLang Hello World Example Source: https://github.com/jordanhubbard/nanolang/blob/main/userguide/01_getting_started.md Demonstrates a basic NanoLang function to return a string and print it to the console. Includes a shadow test for verification. ```nano fn hello_message() -> string { return "Hello, NanoLang!" } shadow hello_message { assert (== (hello_message) "Hello, NanoLang!") } fn main() -> int { (println (hello_message)) return 0 } shadow main { assert true } ``` -------------------------------- ### Pure FFI Binding Example Source: https://github.com/jordanhubbard/nanolang/blob/main/docs/MODULE_CREATION_TUTORIAL.md Demonstrates a simple external function declaration for a C function, serving as a starting point for module creation. ```nano extern fn existing_c_function(arg: int) -> int ```