How can I simulate macros in JavaScript? - javascript

I know that JavaScript doesn't support macros (Lisp-style ones) but I was wondering if anyone had a solution to maybe simulate macros? I Googled it, and one of the solutions suggested using eval(), but as he said, would be quite costly.
They don't really have to be very fancy. I just want to do simple stuff with them. And it shouldn't make debugging significantly harder :)

You could use parenscript. That'll give you macros for Javascript.

A library by Mozilla (called SweetJS) is designed to simulate macros in JavaScript. For example, you can use SweetJS to replace the function keyword with def.

One can also now use ClojureScript to compile clojure to javascript and get macros that way. Note ClojureScript uses Google Closure.

I've written a gameboy emulator in javascript and I simulate macros for cpu emulation this way:
macro code (the function returns a string with the macro code):
function CPU_CP_A(R,C) { // this function simulates the CP instruction,
return ''+ // sets CPU flags and stores in CCC the number
'FZ=(RA=='+R+');'+ // of cpu cycles needed
'FN=1;'+
'FC=RA<'+R+';'+
'FH=(RA&0x0F)<('+R+'&0x0F);'+
'ICC='+C+';';
}
Using the "macro", so the code is generated "on the fly" and we don't need to make function calls to it or write lots of repeated code for each istruction...
OP[0xB8]=new Function(CPU_CP_A('RB',4)); // CP B
OP[0xB9]=new Function(CPU_CP_A('RC',4)); // CP C
OP[0xBA]=new Function(CPU_CP_A('RD',4)); // CP D
OP[0xBB]=new Function(CPU_CP_A('RE',4)); // CP E
OP[0xBC]=new Function('T1=HL>>8;'+CPU_CP_A('T1',4)); // CP H
OP[0xBD]=new Function('T1=HL&0xFF;'+CPU_CP_A('T1',4)); // CP L
OP[0xBE]=new Function('T1=MEM[HL];'+CPU_CP_A('T1',8)); // CP (HL)
OP[0xBF]=new Function(CPU_CP_A('RA',4)); // CP A
Now we can execute emulated code like this:
OP[MEM[PC]](); // MEM is an array of bytes and PC the program counter
Hope it helps...

function unless(condition,body) {
return 'if(! '+condition.toSource()+'() ) {' + body.toSource()+'(); }';
}
eval(unless( function() {
return false;
}, function() {
alert("OK");
}));

LispyScript is the latest language that compiles to Javascript, that supports macros. It has a Lisp like tree syntax, but also maintains the same Javascript semantics.
Disclaimer: I am the author of LispyScript.

Check out the Linux/Unix/GNU M4 processor. It is a generic and powerful macro processor for any language. It is especially oriented towards Algol-style languages of which JavaScript is a member.

Javascript is interpreted. Eval isn't any more costly that anything else in Javascript.

Related

Assert simple conditions in Javascript without using eval

I'm trying to build a Javascript program that can interpret simple conditions :
let condition = '5 + 6 > 10';
if( assert(condition) ){
//... do something
} else {
// ... do other thing
}
A simple but unsecure way to implement assert is to simply use eval. It works, but opens a security hole. How could I work around this ?
I need support for addition and substraction, string and numbers comparisons, and parenthesis management.
There are several options:
you can write a tokenizer and parser for your expressions by hand. For a simple grammar like this, this isn't complicated and is actually a very good exercise in programming. Look up "shunting yard algorithm" or "recursive descent parser".
alternatively, you can use a parser generator like peg or nearley. With a generator, you write your grammar in their specific language and let the generator create a parsing function for you. Check out their examples: https://pegjs.org/online , https://github.com/kach/nearley/tree/master/examples/calculator
finally, you can use a full-blown Javascript parser like esprima or acorn. This way you'll get a complete javascript AST, which you can walk and perform calculations as you go. This method is far more complicated that the others, but gives you the full power of javascript in your expressions, e.g. functions, regexes etc.
If the interpreter supports toString() on functions, you can do this for example:
function test (f) {
let source = f.toString().replace(/^\(\) => /,'');
if (f()) {
console.log(source+" succeeded");
} else {
console.log(source+" failed");
}
}
let condition = () => 5 + 6 > 10;
test(condition)
test(() => 5 + 4 > 10)

What is a JavaScript Macro?

Recently I have seen people talk about the using of macros in JavaScript. I have no idea what that means and after looking up documentation on MDN I came up without any answer. So that leads me to my question …
What are JavaScript macros?
How/why are they used?
Is it a form of meta-programming?
Answers with examples and example code would be appreciated greatly.
As has been posted in comments it's a macro system for javascript.
It's a way of defining text replacements in the "pre-processing phase". So you would define a macro and use it in your code, then run them both through sweet.js and the output would be code with text replacements.
example:
macro swap {
rule { ($a, $b) } => {
var tmp = $a;
$a = $b;
$b = tmp;
}
}
var a = 10;
var b = 20;
swap (a, b)
After running this through sweet.js we get the expanded code:
var a$1 = 10;
var b$2 = 20;
var tmp$3 = a$1;
a$1 = b$2;
b$2 = tmp$3;
I think the use case for this is more centered around frameworks and the likes. It's a more flexible way of saving lines of code than a function.
In JS, a function can basically either
Mathematically calculate something based off of it's inputs
Perform some kind of side effect on another variable within the scope of the function
But Macros are more flexible, it's like code that just takes in inputs and actually equates to text that can be compiled as regular code. It's a common feature in languages that prioritize code prettiness over code-traceability. A couple of notable examples are Ruby, Rust, and Elixir.
Here's an example of a ruby macro and what the equivalent code would look like in js.
In ruby you can do this to tell a class to have certain relationship methods in it's ORM
class Movie < ActiveRecord::Base
has_many :reviews
end
In this case, saying has_many :reviews dumps a bunch of methods onto the Movie class. So because of that line you can call movie.reviews.
In TypeORM right now you could do something like
class Movie {
#OneToMany(() => Review, review => review.movie)
reviews: Review[];
}
If macros made it into js, you could clean this up to look more like
class Movie {
oneToMany(Review, "reviews", "movie")
}
My guess is that this won't happen any time soon. IMO one of the things you lose with macros, is that it becomes less clear what your code actually does, I also have to imagine it would be a pretty big change for linters and type checkers. There's also other ways of dumping a bunch of functionality into an object or function.
For example in react hook form you can accomplish something similar using closures and spreading.
<input {...register("firstName")} placeholder="Bill" />

Javascript in LESS appears hobbled: workaround?

I am finding that LESS has a hobbled JavaScript evaluator, at least the way I am using it, which is to compile *.less files into *.css on a client before uploading them to the web server.
I'm aware that compilation may be more often done server-side, but for performance & simplicity we only want CSS files on the server. I'm compiling the LESS files on Fedora Linux with the lessc ruby gem installed into Node Package Manager as in these instructions.
The compiler is working perfectly, but as far as I can tell the JavaScript expression evaluation is sorely limited. I believe this also applies to server-side JavaScript expression evaluation based on this posting which suggests uncertainty about how the JavaScript engine is plugged into the LESS environment.
All I can use are simple, comma-separated expressions, like the following:
#bar: `
"ignored-string-expression"
,
5
`;
div.test-thing { content: ~"#{bar}"; }
which compiles into:
div.test-thing {
content: 5;
}
When I try to define a function, the compiler barfs (whether or not the semicolon in the expression is backslash-escaped):
[719] anjaneya% cat testfunc.less
#bar: `function foo() {return 5}; foo()`;
div.test-thing { content: ~"#{bar}"; }
[720] anjaneya% lessc testfunc.less
SyntaxError: JavaScript evaluation error: `function foo() {return 5}; foo()` ...
There also doesn't seem to be any way of looping, even if you try to trick it into evaluating a loop as you would the "ignored-string-expression" above, like:
#foo: `x = 0,
for (var n = 0; n <= 10; n++) { x++; },
x
`;
div.test-thing { content: ~"#{bar}"; }
which says:
ParseError: Syntax Error on line 1 ...
Why bother? To be able to compile this LESS:
#svgSource: '<svg xmlns="http://www.w3.org/2000/svg" width="100%" height="100%"><linearGradient id="g" x1="0" y1="0" x2="0" y2="1"><stop offset="0" stop-color="#{start}" /><stop offset="1" stop-color="#{end}" /></linearGradient><rect x="0" y="0" width="100%" height="100%" fill="url(#g)" /></svg>';
into this CSS:
background: url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiPjxsaW5lYXJHcmFkaWVudCBpZD0iZyIgeDE9IjAiIHkxPSIwIiB4Mj0iMCIgeTI9IjEiPjxzdG9wIG9mZnNldD0iMCIgc3RvcC1jb2xvcj0iIzU3OWRkYiIgLz48c3RvcCBvZmZzZXQ9IjEiIHN0b3AtY29sb3I9IiMwMDAwMjIiIC8+PC9saW5lYXJHcmFkaWVudD48cmVjdCB4PSIwIiB5PSIwIiB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiBmaWxsPSJ1cmwoI2cpIiAvPjwvc3ZnPg==);
using a program like this, whether the algorithm is implemented in JavaScript, PHP, Perl, UNIX shell, or anything else. This processing might be done without function definitions but not without looping, and without functions you can't even have recursion.
Given that both functions and looping are compound statements that probably aren't evaluated as expressions (it's not LISP), that is probably the basis for the failure... it's not really a full JavaScript interpreter. So I'm hoping someone who really knows the LESS compiler will:
clarify the limitation above, so I can use JavaScript & LESS portably for this task
say how this problem can be worked around (e.g., with a "shell escape" or any evaluation environment that can process strings iteratively) and/or
say how to extend the LESS compiler with such text processing capabilities, like a "real" JavaScript engine.
The data-uri() function is now built into LESS:
http://lesscss.org/functions/#misc-functions-data-uri
Will that help?
I think what you're looking for is both a mixture of a BUNCH of little frustrating things about using javascript in LESS.
All javascript has to be on one line. (I... don't even.. whatever.)
All javascript has to return something or you get the completely useless error "Cannot read property 'value' of undefined"
All javascript must be one statement. This comes from the original use case where they were thinking you would do something like #foo: ~'something.javascript.is.good.at({#bar});'
Number 1 is formatting, 2 just means you need to return something even if you don't use it, but number 3 catches a lot of people off guard. To get around it, just make you "one thing" a self-executing anonymous function.
Eg:
(function(){
do.some.cool.stuff();
other.cool.things();
return('Fry');
})();
So the LESS parser sees that (make sure it's all in one line instead of how I wrote it!), bundles it off to javascript land as a single execution, reads the return value, and calls it a day.
If you want to see it in action, I recently wrote LESS mixin to make RGBA 1x1 pixels for background fills, etc. that uses all of this madness.
Hope that helps!
I know this post is a couple of years old but javascript embedded in LESS can be very handy so I though I would post some tips:
//All javascript must
// a. be on the rhs of an assignment e.g. #x:` var x = #{val}+7`;
// b. must evaluate to a value
// c. cannot be terminated by a ';'
//
// To get around this, multiline code can be packed into an IIFE......
#val:7;
#loop:`(function(val){
var sum=0;
for(var i=0; i<val; i++){sum+=i;}
return sum;
} )(#{val})`;
.test{
content:#loop; // content: 21;
}
// console.log writes directly to the beginning of the output file
#x:`console.log('/*...... loop = #{loop}.......*/')`; // /*...... loop = 21.......*/
// you can use the global variable. Here we attach a library module to it.....
#x:`global.myLib={}`;
// Then add a method to the module..............
#btoa:`myLib.btoa=function(str){
var buffer = new Buffer((str).toString(), 'binary');
return buffer.toString('base64');
}`;
// And invoke the method to encode some text............................
#sometext:'LESS is more (more or less)';
.test2{
content:`myLib.btoa(#{sometext})`;// content: "TEVTUyBpcyBtb3JlIChtb3JlIG9yIGxlc3Mp";
}

Are there any one-way hashing functions available in native JavaScript?

I'd like to be able to create unique tokens* for users based on a hashed string. I know I could, for example, use a md5() library but as the purpose is not cryptographic I was wondering if there was anything I could use "out of the box." Are there any one-way hashing functions available in native JavaScript?
*I realize these won't be strictly unique. I'm ok with a small chance of hashing collision.
In 2020, there is a native API:
SubtleCrypto.digest()
https://developer.mozilla.org/en-US/docs/Web/API/SubtleCrypto/digest
example:
crypto.subtle
.digest("SHA-256", new TextEncoder().encode("hello"))
.then(console.log);
hex string conversion:
const digest = async ({ algorithm = "SHA-256", message }) =>
Array.prototype.map
.call(
new Uint8Array(
await crypto.subtle.digest(algorithm, new TextEncoder().encode(message))
),
(x) => ("0" + x.toString(16)).slice(-2)
)
.join("");
digest({message: "hello"}).then(console.log)
JavaScript does not have native hashing, but there are many libraries.
I recommend crypto-js: https://code.google.com/p/crypto-js/
For example, to use SHA1, you simply:
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/crypto-js/3.1.2/rollups/sha1.js"></script>
<script>
var hash = CryptoJS.SHA1("Message");
</script>
Nothing is available in native JavaScript. You could use something like Murmurhash. There's a JavaScript implementation here: https://github.com/garycourt/murmurhash-js. I haven't used it though so can't vouch for it.
Update: now there are multiple Murmurhash3 implementations available in JavaScript. However, many of them have problems encoding strings to bytes and can produce different results compared to the reference C++ implementation. You can read an analysis on this here, the murmurhash3js-revisited library implements all three variants of the function and conforms to the reference.
Over the horizon, this may be possible with the currently experimental Web Crypto API
https://developer.mozilla.org/en-US/docs/Web/API/Web_Crypto_API
https://developer.mozilla.org/en-US/docs/Web/API/SubtleCrypto
Granted, at the time of this writing it is unrealistic to use in a production environment and will likely be a moving target. However, come 5 years who knows?

__LINE__ equivalent in Javascript

Is there any way to get the source line number in Javascript, like __LINE__ for C or PHP?
There is a way, although more expensive: throw an exception, catch it immediately, and dig out the first entry from its stack trace. See example here on how to parse the trace. The same trick can also be used in plain Java (if the code is compiled with debugging information turned on).
Edit: Apparently not all browsers support this. The good news is (thanks for the comment, Christoph!) that some browsers export source file name and line number directly through the fileName and lineNumber properties of the error object.
The short answer is no.
The long answer is that depending on your browser you might be able to throw & catch an exception and pull out a stack trace.
I suspect you're using this for debugging (I hope so, anyway!) so your best bet would be to use Firebug. This will give you a console object; you can call console.trace() at any point to see what your programme is doing without breaking execution.
You can try to run C preprocessor (f.e. cpp from GNU Compiler Collection) on your javascript files -- either dynamically with each request or statically, by making this operation be applied every time you change your javascript files. I think the javascript syntax is similar enough for this to work.
Then you'd have all the power of C preprocessor.
You can use this in vanilla JS:
function getLine(offset) {
var stack = new Error().stack.split('\n'),
line = stack[(offset || 1) + 1].split(':');
return parseInt(line[line.length - 2], 10);
}
Object.defineProperty(window, '__LINE__', {
get: function () {
return getLine(2);
}
});
You will now have access to the global variable __LINE__
A __LINE__ in C is expanded by a preprocessor which literally replaces it with the line number of the current input. So, when you see
printf("Line Number: %d\r\n", __LINE__);
the compiler sees:
printf("Line Number: %d\r\n", 324);
In effect the number (324 in this case) is HARDCODED into the program. It is only this two-pass mechanism that makes this possible.
I do not know how PHP achieves this (is it preprocessed also?).
I think preprocessing makes more sense, in that it adds no runtime overhead. An alternative to the C preprocessor is using perl, as in the 2 step procedure below:
1 – add “Line # 999 \n” to each line in the script that you want numbered, e.g.,
alert ( "Line # 999 \n"+request.responseText);
2 – run the perl below:
cat my_js.js | perl -ane "{ s/Line # \d+ /Line # $. /; print $_;}" > C_my_js.js; mv C_my_js.js my_js.js
There is one workaround.
Usually the __ LINE __ combined with the __ FILE __ is used for marking a locations in code and the marking is done to find that location later.
However, it is possible to achieve the same effect by using Globally Unique Identifiers (GUID-s) in stead of the __ LINE __ and __ FILE __. Details of the solution reside in the COMMENTS.txt of a BSD-licensed toolset that automates the process.

Categories