#include OrderIn a .c file, first include the corresponding .h file, followed by a blank line.
Then, include anything from the standard C library that is needed, followed by a blank line.
Then, include any other header files from YASL that are needed, followed by a blank line.
Each section should be alphabetical.
In a .h file, exclude the first section, but otherwise follow the same format as in a .c file.
For example, the following is the includes from list_methods.c:
#include "list_methods.h"
#include <stdio.h>
#include "list.h"
#include "VM.h"
#include "YASL_Object.h"
#include "yasl_state.h"
Whenever a floating point or integral type is used that represents a int or float within the YASL language, yasl_float or yasl_int should be used to represent it.
For example:
yasl_int val = YASL_GETINT(obj), rather than int64_t val = YASL_GETINT(obj).
typedefsDo not add any new typedefs. You may use any existing typedefs if needed.
Struct names should be in upper camel case (e.g. RefCount). Variable names should be lower case with no separator or lower snake case (e.g. refcount or ref_count). Try to match the style used in the particular file. Functions should be lower snake case (e.g. vm_pop). There are also other conventions for naming functions; e.g. all functions that operate on the VM start with vm_. This last convention must absolutely be followed.
Opening brace is always at the end of the the line. Closing brace is on a line of its own, unless the next piece of code continues
the statement (e.g. if-else or do-while).
Indent with tabs. A tab is 8 spaces.
Right-align your * for pointers, e.g. do char *s, not char* s. In casts, leave a space between the type and the asterisk(s), as in (char *)x rather than (char*)x. If there are multiple asterisks, only a space between the type and the first is needed: (char **)x.
A switch and the matching cases should be indented the same amount.
Macro names should be in ALL CAPS, unless the macro is function-like, in which case it may be named as though it were a function.
Macros containing multiple statements must be enclosed in a do-while block:
#define macrofun(a, b, c) \
do { \
if ((a) == 5) \
do_this((b), (c)); \
} while (0)
Macros that evaluate to expressions should be enclosed in parentheses. Macro arguments should be enclosed in parentheses.
Things to avoid in macros:
#define FOO(val) bar(index, val) is bad. You probably want
#define FOO(index, val) bar(index, val) instead.Enums are preferred to macros when definining many related constants. Enums should be named in ALL CAPS. Many exisiting enums use a prefix to denote what they should be used for, for example:
T_ are for token types, e.g. T_PLUS is the token for +.L_ are for lexer modes, e.g. L_NORMAL is the default lexer mode.N_ are for AST node types, e.g. N_IF is the AST node for if-statements.New enums should follow this style. The one exception is the enum for opcodes, which uses no prefix currently.