We are currently working on new rules for what content should and shouldn't be allowed on this website, and are looking for feedback! See Esolang:2026 topicality proposal to view and give feedback on the current draft.
Preproc
Preproc is an esolang invented by User:None1 that resembles C/C++ preprocessors.
Basic syntax
This esolang is case-sensitive. Comments are the same as that of C/C++.
Macros
Like C/C++ preprocessors, Preproc uses macros (simple text replacements). However, macros can be recursive: Expanding a macro that causes infinite recursion is valid, but it results in an infinite loop.
Macro expansion
Macro expansion only happens under certain circumstances in Preproc. In this article, these circumstances are explicitly mentioned.
# and ## operator
Like C/C++ preprocessors, there's ## operator in Preproc, which joins two tokens, and # operator, which just adds a double quote before and after the token.
_: The special macro
_ is a special macro in this esolang that allows it to read input: Whenever control reaches a line with this macro, it reads a line from user input and replaces the _ with the result (before executing that line). If there are multiple _'s in one line, they're processed in the order they appear. Note that this does not change the line itself, so if the line is executed again, it reads input again as well. This feature makes code injection possible.
Examples:
#define A _ // If you input "B" (Without quotes), then this line will be the same as #define A B #define _ A // If you input "B", then this line will be the same as #define B A #define _ _ // If you input "A<LF>B", then this line will be the same as #define A B
Preprocessors
#define
Defines a macro.
#define MACRO text or empty
If this macro already exists, then its content is overwritten.
#undef
Deletes a macro.
#undef MACRO
If this macro is non-existent, do nothing.
#warning and #error
#warning expression #error expression
They do macro expansion on expression and outputs the results plus a line feed. Implementations can choose to display real warning/error messages or just output normally. #error terminates the program after printing but #warning doesn't.
#include
#include "filename"
or:
#include<filename>
Includes a virtual "file" (it won't include a real file on a disk even if it exists) named filename. "filename" can't be replaced by macros. A file can be included multiple times.
- include can be nested, and there's no limit on the nesting depth.
#file
This preprocessor doesn't exist in C/C++, but exists in Preproc. It's used to define virtual "file"s.
#file "filename"
Makes the lines before another #file preprocessor belong to the "file" filename. Multiple #file preprocessors must not have the same file name. Lines before any #file preprocessor belong to a "file" named main (and main can't be used as a file name in the #file preprocessor either).
#ifdef/#ifndef/#else/#endif
These macros are the same as that of C/C++.
#if
This macro allows comparison between two macros.
Usage:
#if expression // If expression doesn't expand to an empty string. #if expression1==/!=expression2 // If the expansion of expression1 and expression2 are the same/not the same
Examples
Hello, world!
#warning Hello, world!
Or:
#error Hello, world!
Cat
#warning _ #include "main"
Never terminates.
Truth Machine
#if _!=0 #include "1" #else #include "0" #endif #file "1" #warning 1 #include "1" #file "0" #warning 0
Unary A+B
#warning _##_
Computational class
PDA, because the macro system is an FSA even though recursion is allowed while file inclusion can be seen as a stack.