jc/STYLEGUIDE
Judah Caruso 640519a5fa .
2025-05-27 00:55:08 -06:00

196 lines
5 KiB
Text

-----------
Style Guide
-----------
This document outlines repo conventions, code style, etc.
Getting Paid
------------
To pick up tasks, find something in TODO and message me
your rate. If accepted, create a single commit moving it
from the 'UP NEXT' section to your 'IN PROGRESS' section;
the commit message should only say 'start [id]'.
Once the work is done (use as many commits as you'd like),
create another commit moving the task from your 'IN
PROGRESS' section to the 'DONE' section; the commit
message should only say 'finish [id]'.
// Final commit
commit SOME HASH
Author: Your Name <your@email>
finish 034
// Intermediate commits
commit SOME HASH
Author: Your Name <your@email>
Blah blah blah
// Starting commit
commit SOME HASH
Author: Your Name <your@email>
start 034
Communication
-------------
If direction is needed, create a single commit with an
entry in 'INBOX' under that person's section; the commit
message should roughly say 'message for [name]'.
If an immediate response is needed, opt for direct
messages instead.
Use this as a base plate to write new messages:
[ToName]
05.22.25 FromName // This is a question
Lorem ipsum dolor sit amet, consectetur
adipisicing elit, sed do eiusmod tempor
incididunt ut labore et dolore magna aliqua.
05.22.25 ToName // This is a response
Excepteur sint occaecat cupidatat non proident,
sunt in culpa qui officia deserunt mollit anim
id est laborum.
You should check your inbox *every time* you pull.
Writing Code
------------
Generally, I don't care what style of code is used. It's
more important that you stay in line with the local style
of the file you're in.
Things I actually care about:
- Don't be clever. Write code that does the job;
nothing more, nothing less.
- Comment your code. I very much disagree with the
premise that code is self-documenting. Take a step
back and write a comment (with your name) that
explains *why* you're doing *what* you're doing.
Please try to stick to this format:
@note, @todo, @temp, @allocates, @leak
- Descriptive names. In general, it's fine to use short
names for local variables. However, you should
almost always opt for longer, more descriptive names
in every other context.
Imports
-------
When importing modules that ship with the compiler, ALWAYS
namespace them. The eventual goal of this repo is to be a
standalone library that doesn't rely on compiler-shipped
modules (unless absolutely required).
basic :: #import "Basic";
When importing 'jc' modules, ALWAYS namespace them and use
absolute import paths. '#import,file' does not function
the same as '#import' and causes issues when mixed
with '#load'. '_run_all_tests.jai' is an exception to
this rule.
math :: #import "jc/math";
Modules
-------
Modules should *generally* have a small scope and not be
nested unless it allows better organization. Files within
modules are not intended to be imported directly; it is
the job of 'module.jai' to '#load' and '#scope_export'
module files.
When authoring a new module, use this as a base plate:
// Within module_name/module.jai
#module_parameters(RUN_TESTS := false); // Should be the last parameter if others are required
#load "file_a.jai";
#load "file_b.jai";
#scope_file;
#if RUN_TESTS {
test :: #import "jc/test";
}
Memory Management
-----------------
If a custom type needs dynamically allocated memory to
function, it should always assume the memory came from an
arena allocator. This means it is the responsibility of
the arena to free the memory, not the custom data type.
In other words:
Do *not* add procedures that 'free' or 'delete' the memory
allocated by the data type.
Instead, add procedures that 'reset' the data type,
allowing its memory to be reused. For examples, see
the 'reset' procedures in 'jc/kv' or 'jc/array'.
OS-Specific Code
----------------
When writing code for a specific operating system, use a
switch statement over multiple files.
// Top-level scope of file:
#if OS == {
case .WINDOWS;
case .MACOS;
case .LINUX;
case; #assert false, "unimplemented platform";
}
If multiple files are required, use these file suffixes
and conditionally '#load' them based on 'OS'.
Windows: '_win.jai'
Mac: '_mac.jai'
Linux: '_linux.jai'
WASM: '_wasm.jai'
Architecture-Specific Code
--------------------------
When writing code for a specific architecture, use
the 'jc/arch' module. NEVER create a new file unless
absolutely needed.
Bindings
--------
Binding modules should default to static linking and take
an optional '#module_parameter' to link dynamically.
Libraries should be pinned to a specific version, and all
binaries (.dll, .dylib, etc.) *must* be checked into
source control. If possible, use the release build of the
library that includes debug information.
Bindings should stay as close as possible to the original
library. To jai-ify the bindings, create a submodule
called 'wrapper' that import and wraps the api.
See: 'thirdparty/raylib' for example bindings.