-
Notifications
You must be signed in to change notification settings - Fork 0
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)