-
Notifications
You must be signed in to change notification settings - Fork 139
Coding Guidelines
The existing code has a certain style. Submissions should make a good attempt at fitting in. Avoid formatting discussions.
The unusual appearance is a side effect of writing C as concisely as possible. There are great benefits to writing code as concisely as possible. Someone familiar with the style can read and comprehend the code much faster than they would be able to with traditional code. It also creates a discipline that reduces bugs. Some of the downsides of the style are inaccessibility and a steep learning curve.
The project has good test coverage. There are several hundred tests and they automatically detect memory leaks. Build the tests into the binary by defining NDEBUG
. This can be done from the command line using cc -DNDEBUG
. You can also produce the test binary using make test
. It is not difficult to get your editor to run the test suite and drop into the interpreter with a single button press. Contributors are expected to run and pass the tests before submitting. Additional tests are always appreciated. See tests.c
for more.
A return value of 0
indicates an error. The name of the error is set in the errmsg
string using the kerr
function. Zero values should bubble up through functions. The special macros U()
and P()
exist to check that an object was allocated correctly or that a given condition was met. The M()
macro can ensure consistency when allocating multiple objects.
When a K object is created it has reference count 1. The number of references must be tracked. When a reference disappears, cd()
must be called on the object. When a reference is created, ci()
must be called on the object. When cd()
reduces the reference count to zero, the memory used by the object is returned to the K memory pool (or unmapped). The K execution loop handles reference counting for values returned from verbs. In general, if you create a K object that isn’t part of the return value of a verb, you will have to cd()
that value at some point.
Running out of memory poses a special problem.
The M()
macro can help with this. Other languages use different solutions for handling this problem, perhaps another solution would work better here.