There are a few ways how you could accomplish this.
Using the c preprocessor
You can use the c preprocessor on other file types, so you could create a compile setup for your javascript code.
Example:
foo.js:
#include "macros.js"
function foo() {
repeat(10) {
console.log(i);
}
}
macros.js:
#pragma once
#define repeat(x) for(let i = 0; i < x; i++)
and then you can compile it with cpp:
cpp -nostdinc -CC -P -undef -I. foo.js -o foo.compiled.js
This would result in a foo.compiled.js file that looks like this:
function foo() {
for(let i = 0; i < 10; i++) {
console.log(i);
}
}
You can easily set this up for an entire project with a Makefile or similar, like you would for a c++ project.
using babel
Babel is often used in javascript projects to be able to use newer javascript features without having to think about compatiblity. (it compiles the code down and inserts polyfills as needed)
With a few plugins you can achieve something similar to what you want.
For example babel-plugin-macros that allows you to write macros that will be inlined in the calling function.
There's however one big downside to this - your code must be valid javascript, so your repeat example would not work as-is.
Why this is a bad idea
While i can see the benefit for having to type less with those kinds of macros, you should also think about the maintainability of your code.
Think about it from the perspective of someone who has never seen your code and then gets presented with c++ code like this:
numero foo fonction
debut
si i > 0 alors
sortie(i)
revenir(i)
sinon
inverser(i)
sortie(i)
revenir(i)
finsi
fin
Sure this is valid c++ code - but can you tell what it does without knowing each one of those macros?
Maybe with the help of the macro definitions?
#define debut {
#define fin }
#define si if(
#define alors ){
#define sinon }else{
#define finsi }
#define numero int
#define fonction (int i)
#define sortie(v) std::cout << v << std::endl;
#define revenir(v) return v;
#define inverser(v) v = -v;
As you can see this quickly gets into a deep rabbit hole - you basically have to lookup each macro definition, memorize what they replace with and piece the actual code together in your mind to actually be able to understand what it does.
In comparison to that horrible example try to read it in plain c++:
int foo(int value) {
if(value > 0) {
std::cout << value << std::endl;
return value;
} else {
value = -value;
std::cout << value << std::endl;
return value;
}
}
while that might be a bit more to type, everybody will be able to quickly understand what that function does, since its just standard c++ that everyone should be familiar with.
A few more helpful links