Repository navigation
Migrating to v2
Older versions of MTSC used a C like preprocessor; however, new versions provide one more like Rust's procedural macros. This fixes several quirks*, reduces the likelihood of future bugs, and is over all more powerful and flexible.
* e.g. procedural macros do not expand in backtick strings unlike prior macros
At the most abstract level, MTSC's procedural macros are simply an identifier followed by two non-null assertions (foo!!) that act as a trigger for syntax transforms. Usually proc macros will be used in one of three ways:
- Values - This is the simplest type of procedural macro. It simply replaces the macro with some value. For example,
file!!becomes a string holding the current file name. - Functions - Functional proc macros act on the AST of their arguments and replace themselves with some expression. For example,
strc!!(1 + 1)becomes the string'1 + 1'andinclude!!('example.ts')injects the contents of the fileexample.ts. - Annotations
/*
* Many prior preprocessor directives are now proc macro functions.
*/
///#include "file.ts"
include!!('file.ts');
///#include <file.ts>
include!!('<file.ts>')
///#embed 'file.bin'
embed!!('file.bin')
///#error Error Text
error!!('Error Text')
///#warning Warning Text
warning!!('Warning Text')
/*
* _Pragma and __pragma have also been replaced by a proc macro.
*/
///#pragma ...
_Pragma("...")
__pragma(...)
pragma!!(...)
///#pragma once
pragma!!(once)
///#pragma region
pragma!!(region)
///#pragma endregion
pragma!!(endregion)
/*
* Instead of if, elif, and else directives, use compile-time expressions inside of plain if statements.
* As a special case to cexpr, when evaluating to a falsey value in an if condition, that branch is removed, and if evaluating to truthy, then the branch replaces the statement.
*/
///#if EXPR
A()
///#elif EXPR
B()
///#else
C()
///#endif
if(cexpr!!(EXPR)) {
A()
} else if(cexpr!!(EXPR)) {
B()
} else {
C()
}
/*
* The __TIME__ and __DATE__ macros can also be replaced with compile-time expressions.
* Note that the format of __DATE__ below is slightly different.
*/
console.log(__TIME__)
console.log(cexpr!!(new Date().toTimeString().split(' ')[0]))
console.log(__DATE__)
console.log(cexpr!!(new Date().toDateString().slice(4)))
/*
* __FILE__ and __LINE__ are also proc macros
*/
console.log(`${__FILE__}:__LINE__`)
console.log(`${file!!}:${line!!});define/undef
The following features have been removed since they are unneeded with proc macros or were artifacts of C:
-
///#pragma mtsc eval(arg)- no longer required since directives are now proc macros and macros can call other macros ///#include_next__has_include()-
///#ifdef,///#ifndef __NEWLINE__- C Digraphs
The following features are currently missing but will be added back later:
__BASE_FILE____INCLUDE_LEVEL____MAIN____MTSC_VERSION__defined()- Command line macros like
-DDEBUG
The following features may be readded if found to be needed:
///#pragma mtsc line(arg)///#line
The following features will be added soon:
- namespaced proc macros (
foo.bar.baz!!) - global transforms
- ability to undefine macros
env!!(name)strc!!(expr)cexpr!!(expr)