Skip to content

Hello! 👋 My name is Nathan Weir. This is a fun personal project for using AI to build a bespoke, domain-specific programming language. It is not a serious, professional project. This site and the language itself are largely generated via Claude Code. If you find yourself programming with Weir, have fun - but use at your own risk!

Package System

Weir’s package system lets you organize multi-file, multi-package projects using weir.pkg manifest files with S-expression syntax.

Package metadata lives in a weir.pkg file at the package root. The format is S-expressions — dogfooding the language syntax.

;; weir-gl/weir.pkg
(package
(name "weir-gl")
(version "0.1.0")
(sources "lib.weir")
(native
(sources "gl_helper.c")
(link "glfw" "GL" "m")))
;; demos/tetris/weir.pkg
(package
(name "tetris-gl")
(version "0.1.0")
(deps
(weir-gl (path "../../../weir-gl")))
(main "tetris.weir"))
FieldRequiredDescription
nameYesPackage name (string). Becomes the root module name for imports.
versionYesSemver string (informational for now).
sourcesNoSource files — string or list of strings. Paths relative to weir.pkg.
mainNoEntry point file (has defn main). For applications only.
depsNoDependencies. Each is (name (path "relative/or/absolute")).
nativeNoNative C code. sources = C files, link = libraries (-l flags).

File paths within a package determine module names:

PackageSource FileModule Name
weir-gllib.weirweir-gl
foobar.weirfoo.bar
foolib.weirfoo
fooutils.weirfoo.utils

Convention: lib.weir maps to the bare package name — it’s the package’s root module and default entry point for imports.

Modules import from each other using the import form:

;; Import specific symbols
(import weir-gl (gl_init gl_should_close gl_begin_frame gl_end_frame))
;; Import with alias (planned)
(import math.vec2 :as v)
;; Import everything (discouraged)
(import math.vec2 :all)

Import validation checks that:

  • The referenced module exists in a resolved dependency
  • The imported symbols actually exist in the module’s exports

Dependencies are local path-based only — no registry, no git URLs, no lock files. Packages live on the developer’s local machine.

Packages can include native C source files that are automatically compiled:

  • JIT mode (weir run): C sources are compiled into a shared library (.so) and dlopened before JIT execution
  • AOT mode (weir build): C sources are passed to the system linker via --cc-arg
(native
(sources "gl_helper.c" "audio.c")
(link "glfw" "GL" "m" "openal"))

When run, build, or dev are invoked without a file argument, the CLI discovers weir.pkg in the current directory:

Terminal window
cd demos/tetris
weir run # JIT via weir.pkg
weir build -o ../../tmp/t # AOT via weir.pkg
weir dev # dev mode via weir.pkg

Single-file mode still works when a file arg is provided:

Terminal window
weir run hello.weir # no weir.pkg needed

The OpenGL Tetris demo is structured as a two-package project:

weir-gl/ # Library package (external)
weir.pkg # name: "weir-gl"
lib.weir # extern "C" declarations
gl_helper.c # Native OpenGL/GLFW wrappers
demos/tetris/ # Application package
weir.pkg # name: "tetris-gl", deps: weir-gl
tetris.weir # Game code importing weir-gl

Build and run:

Terminal window
cd demos/tetris
weir build -o ../../tmp/tetris_gl # or: weir run

The package system replaces what would otherwise be manual --cc-arg and -l flags.