m4 crimes for metaprogramming Processing
Mon 22 Jul 2024 07:21 EDT
Back in June, I made a quick-and-dirty attempt to get the big-bang model of functional UI running in Processing 4.
Unfortunately Processing uses a dialect of Java predating introduction of Java Records (JEP395), so I, er, creatively broke out m4 as a preprocessor.
The resulting macros turn this:
_record(Rect extends Pict, {{float x, float y, float w, float h}}, {{
public void render() {
rectMode(CORNER);
rect(this.x, this.y, this.w, this.h);
}
}});
into this:
class Rect extends Pict {
public final float x;
public final float y;
public final float w;
public final float h;
public Rect(float x, float y, float w, float h) {
this.x = x;
this.y = y;
this.w = w;
this.h = h;
}
public void render() {
rectMode(CORNER);
rect(this.x, this.y, this.w, this.h);
}
};
The macros
Not yet properly factored out into a utility library or anything, just pasted straight at the top of the file. Shield your eyes!
/* -*- mode: java; c-basic-offset: 2 -*- */
changecom(`//')dnl
changequote(`{{',`}}')dnl
dnl);
define({{_record}}, {{class $1 {_record_fields($2,)
public _record_classname($1)($2) {_record_inits($2,)
}
$3dnl;
}{{}}}})dnl;
define({{_record_fields}}, {{ifelse({{$#}}, {{1}},, {{
public final $1;$0(shift($@))}})}})dnl;
define({{_record_inits}}, {{ifelse({{$#}}, {{1}},, {{
this._record_fieldname({{$1}}) = _record_fieldname({{$1}});$0(shift($@))}})}})dnl;
define({{_record_classname}}, {{regexp({{$1}}, {{^\(\w+\).*$}}, {{\1}})}})dnl;
define({{_record_fieldname}}, {{regexp({{$1}}, {{^.+\s\(\w+\)$}}, {{\1}})}})dnl;
dnl;//---------------------------------------------------------------------------