Last updated: 2026-09-15
Wearing Borrowed Syntax: Java, C++, and Python-flavored PatLang
Three tiny cosmetic dialects over the same underlying language, all built from PatLang's own syntax { ... } grammar-extension feature (self_hosting/lib/syntax_dsl.patlang) -- the same source-to-source preprocessing mechanism behind the Router DSL and Dynamic Syntax demos, extended with two more primitives: Block, which captures a brace-delimited body (possibly spanning many lines) and recursively re-expands it against the same rule set, and Many, which repeats a named rule zero or more times (used here for switch/case clauses and Python-ese's elif chains). Each dialect below is a plain PatLang program with its own syntax declaration at the top -- nothing about the real lexer, parser, or compiler changed to support any of this.
None of this is a Java, C++, or Python compiler, and it isn't trying to be. Each dialect is a thin cosmetic skin: keywords and punctuation are pattern-matched and rewritten textually, not parsed against Java's, C++'s, or Python's real grammars. There is no type system, no classes or inheritance, no generics or templates, no exception handling, and expressions are captured as opaque text rather than genuinely parsed -- a header ending in ) (an if/while/for condition, a function's parameter list) can't itself contain unbalanced parentheses, and function parameters are bare, untyped names, because that is exactly the shape PatLang's own takes a, b syntax already needs, with no per-parameter type-stripping logic written. Python-ese also cheats on Python's single most recognizable feature: blocks are delimited by { }, not indentation, because the Block primitive only understands balanced braces -- a genuine indentation-sensitive capture is a different, not-yet-built primitive. Every one of these gaps is a real, fixable next step on top of the same mechanism, not a wall; none of it has been built here.
Java-ese
A function, a checked if/else, a C-style for loop, a while loop, and a switch/case block -- each header's condition or value is captured as real PatLang code (not just a data string) and spliced back in with ${...}, so i < 3 stays a genuine boolean expression rather than a quoted piece of text.
Java-ese source
# Java-flavored surface syntax over genuine PatLang, built entirely from the
# `syntax { ... }` DSL feature's Block/Many/${...} primitives
# (self_hosting/lib/syntax_dsl.patlang) -- no changes to the real lexer or
# parser. Known, deliberate scope limits (not bugs):
# - expressions are captured as opaque regex text, not parsed, so a value
# used where the delimiter is ")" (an if/while/for header, a function's
# parameter list) may not itself contain unbalanced/nested parens --
# there is no balanced-paren capture primitive, only balanced-brace
# (Block). Values terminated by ";" (declarations, return statements)
# CAN contain parens, e.g. a function call.
# - function parameters are bare, comma-separated names with no per-
# parameter type (PatLang's own `takes a, b` is exactly that shape, so
# an untyped parameter list splices straight through with no
# transformation needed).
syntax JavaEse {
trigger: Keyword("javaese");
tokens {
IntKw = "int";
ReturnKw = "return";
IfKw = "if";
ElseKw = "else";
WhileKw = "while";
ForKw = "for";
SwitchKw = "switch";
CaseKw = "case";
PrintKw = "System.out.println";
Num(n) = regex("[0-9]+", n);
Expr(e) = regex("[^;{}]+", e);
ParenExpr(e) = regex("[^;{}()]+", e);
}
rule FuncDef {
expect IntKw;
let fname = expect Identifier;
expect Symbol("(");
let params = expect ParenExpr;
expect Symbol(")");
let body = expect Block;
return make a function called ${fname} takes ${params} returns r
${body}
end;
}
rule IfElseLine {
expect IfKw;
expect Symbol("(");
let cond = expect ParenExpr;
expect Symbol(")");
let then_body = expect Block;
expect ElseKw;
let else_body = expect Block;
return if ${cond} then
${then_body}
else
${else_body}
end;
}
rule IfLine {
expect IfKw;
expect Symbol("(");
let cond = expect ParenExpr;
expect Symbol(")");
let body = expect Block;
return if ${cond} then
${body}
end;
}
rule WhileLine {
expect WhileKw;
expect Symbol("(");
let cond = expect ParenExpr;
expect Symbol(")");
let body = expect Block;
return while ${cond} do
${body}
end;
}
rule ForLine {
expect ForKw;
expect Symbol("(");
expect IntKw;
let ivar = expect Identifier;
expect Symbol("=");
let ival = expect Expr;
expect Symbol(";");
let cond = expect Expr;
expect Symbol(";");
let step = expect ParenExpr;
expect Symbol(")");
let body = expect Block;
return let ${ivar} = ${ival}
while ${cond} do
${body}
let ${step}
end;
}
rule CaseClause {
expect CaseKw;
let value = expect Num;
expect Symbol(":");
let body = expect Block;
return if switch_val == ${value} then
${body}
end;
}
rule SwitchLine {
expect SwitchKw;
expect Symbol("(");
let val = expect ParenExpr;
expect Symbol(")");
expect Symbol("{");
let cases = expect Many(CaseClause);
expect Symbol("}");
return let switch_val = ${val}
${cases};
}
rule ReturnLine {
expect ReturnKw;
let val = expect Expr;
expect Symbol(";");
return return ${val};
}
rule PrintLine {
expect PrintKw;
expect Symbol("(");
let val = expect ParenExpr;
expect Symbol(")");
expect Symbol(";");
return print(${val});
}
rule VarDecl {
expect IntKw;
let name = expect Identifier;
expect Symbol("=");
let val = expect Expr;
expect Symbol(";");
return let ${name} = ${val};
}
rule Assign {
let name = expect Identifier;
expect Symbol("=");
let val = expect Expr;
expect Symbol(";");
return let ${name} = ${val};
}
}
javaese {
int square(a, b) {
return a * b;
}
int n = 3;
int r = square(n, 4);
System.out.println(r);
if (r > 10) {
System.out.println(1);
} else {
System.out.println(0);
}
for (int i = 0; i < 3; i = i + 1) {
System.out.println(i);
}
int total = 0;
while (total < 5) {
total = total + 2;
}
System.out.println(total);
switch (n) {
case 1: {
System.out.println(100);
}
case 3: {
System.out.println(300);
}
}
}
(not run yet)
Native run on the build machine:
12 1 0 1 2 6 300
C++-ese
The same control-flow shapes as Java-ese, dressed differently: std::cout << x << std::endl in place of a print statement, and auto alongside typed declarations -- the same two primitives (Block, Many), a different skin.
C++-ese source
# C++-flavored surface syntax over genuine PatLang, same DSL mechanism and
# same scope limits as java_ese_source.patlang (see that file's header):
# expressions are opaque regex text (no nested/unbalanced parens where the
# terminator is ")"), function parameters are bare comma-separated names.
# `std::cout << x << std::endl;` is supported in its common two-operand
# form only (a single value between `<<`s, no further chaining).
syntax CppEse {
trigger: Keyword("cppese");
tokens {
IntKw = "int";
AutoKw = "auto";
ReturnKw = "return";
IfKw = "if";
ElseKw = "else";
WhileKw = "while";
ForKw = "for";
SwitchKw = "switch";
CaseKw = "case";
CoutKw = "std::cout";
EndlKw = "std::endl";
ShiftOp = "<<";
Num(n) = regex("[0-9]+", n);
Expr(e) = regex("[^;{}]+", e);
ParenExpr(e) = regex("[^;{}()]+", e);
CoutExpr(e) = regex("[^;{}<]+", e);
}
rule FuncDef {
expect IntKw;
let fname = expect Identifier;
expect Symbol("(");
let params = expect ParenExpr;
expect Symbol(")");
let body = expect Block;
return make a function called ${fname} takes ${params} returns r
${body}
end;
}
rule IfElseLine {
expect IfKw;
expect Symbol("(");
let cond = expect ParenExpr;
expect Symbol(")");
let then_body = expect Block;
expect ElseKw;
let else_body = expect Block;
return if ${cond} then
${then_body}
else
${else_body}
end;
}
rule IfLine {
expect IfKw;
expect Symbol("(");
let cond = expect ParenExpr;
expect Symbol(")");
let body = expect Block;
return if ${cond} then
${body}
end;
}
rule WhileLine {
expect WhileKw;
expect Symbol("(");
let cond = expect ParenExpr;
expect Symbol(")");
let body = expect Block;
return while ${cond} do
${body}
end;
}
rule ForLine {
expect ForKw;
expect Symbol("(");
expect IntKw;
let ivar = expect Identifier;
expect Symbol("=");
let ival = expect Expr;
expect Symbol(";");
let cond = expect Expr;
expect Symbol(";");
let step = expect ParenExpr;
expect Symbol(")");
let body = expect Block;
return let ${ivar} = ${ival}
while ${cond} do
${body}
let ${step}
end;
}
rule CaseClause {
expect CaseKw;
let value = expect Num;
expect Symbol(":");
let body = expect Block;
return if switch_val == ${value} then
${body}
end;
}
rule SwitchLine {
expect SwitchKw;
expect Symbol("(");
let val = expect ParenExpr;
expect Symbol(")");
expect Symbol("{");
let cases = expect Many(CaseClause);
expect Symbol("}");
return let switch_val = ${val}
${cases};
}
rule ReturnLine {
expect ReturnKw;
let val = expect Expr;
expect Symbol(";");
return return ${val};
}
rule CoutLine {
expect CoutKw;
expect ShiftOp;
let val = expect CoutExpr;
expect ShiftOp;
expect EndlKw;
expect Symbol(";");
return print(${val});
}
rule AutoDecl {
expect AutoKw;
let name = expect Identifier;
expect Symbol("=");
let val = expect Expr;
expect Symbol(";");
return let ${name} = ${val};
}
rule VarDecl {
expect IntKw;
let name = expect Identifier;
expect Symbol("=");
let val = expect Expr;
expect Symbol(";");
return let ${name} = ${val};
}
rule Assign {
let name = expect Identifier;
expect Symbol("=");
let val = expect Expr;
expect Symbol(";");
return let ${name} = ${val};
}
}
cppese {
int square(a, b) {
return a * b;
}
auto n = 3;
int r = square(n, 4);
std::cout << r << std::endl;
if (r > 10) {
std::cout << 1 << std::endl;
} else {
std::cout << 0 << std::endl;
}
for (int i = 0; i < 3; i = i + 1) {
std::cout << i << std::endl;
}
int total = 0;
while (total < 5) {
total = total + 2;
}
std::cout << total << std::endl;
switch (n) {
case 1: {
std::cout << 100 << std::endl;
}
case 3: {
std::cout << 300 << std::endl;
}
}
}
(not run yet)
Native run on the build machine:
12 1 0 1 2 6 300
Python-ese
No semicolons, def for functions, an if/elif/else chain (the same Many primitive Java-ese uses for case clauses, applied to a different construct), and for x in range(n) translated into a counting while loop underneath. Blocks still use { } -- see the disclaimer above.
Python-ese source
# Python-flavored surface syntax over genuine PatLang, same DSL mechanism
# and same expression-capture scope limits as java_ese_source.patlang (see
# that file's header). One deliberate deviation from real Python: this
# dialect delimits blocks with `{ }`, not indentation -- the `Block`
# primitive only understands balanced braces, and building a genuine
# indentation-sensitive capture is a separate, not-yet-built engine
# primitive. Otherwise Python-flavored: no semicolons, `def` for functions,
# `elif`, and `for x in range(n) { ... }`.
syntax Pythonic {
trigger: Keyword("pythonic");
tokens {
DefKw = "def";
ReturnKw = "return";
IfKw = "if";
ElifKw = "elif";
ElseKw = "else";
WhileKw = "while";
ForKw = "for";
InKw = "in";
RangeKw = "range";
PrintKw = "print";
Num(n) = regex("[0-9]+", n);
Expr(e) = regex("[^{}]+", e);
ParenExpr(e) = regex("[^{}()]+", e);
}
rule FuncDef {
expect DefKw;
let fname = expect Identifier;
expect Symbol("(");
let params = expect ParenExpr;
expect Symbol(")");
let body = expect Block;
return make a function called ${fname} takes ${params} returns r
${body}
end;
}
rule ElifPart {
expect ElifKw;
expect Symbol("(");
let cond = expect ParenExpr;
expect Symbol(")");
let body = expect Block;
return elif ${cond} then
${body}
;
}
rule IfElifElseLine {
expect IfKw;
expect Symbol("(");
let cond = expect ParenExpr;
expect Symbol(")");
let body = expect Block;
let elifs = expect Many(ElifPart);
expect ElseKw;
let else_body = expect Block;
return if ${cond} then
${body}
${elifs}
else
${else_body}
end;
}
rule IfElifLine {
expect IfKw;
expect Symbol("(");
let cond = expect ParenExpr;
expect Symbol(")");
let body = expect Block;
let elifs = expect Many(ElifPart);
return if ${cond} then
${body}
${elifs}
end;
}
rule WhileLine {
expect WhileKw;
expect Symbol("(");
let cond = expect ParenExpr;
expect Symbol(")");
let body = expect Block;
return while ${cond} do
${body}
end;
}
rule ForRangeLine {
expect ForKw;
let ivar = expect Identifier;
expect InKw;
expect RangeKw;
expect Symbol("(");
let n = expect ParenExpr;
expect Symbol(")");
let body = expect Block;
return let ${ivar} = 0
while ${ivar} < ${n} do
${body}
let ${ivar} = ${ivar} + 1
end;
}
rule ReturnLine {
expect ReturnKw;
let val = expect Expr;
return return ${val};
}
rule PrintLine {
expect PrintKw;
expect Symbol("(");
let val = expect ParenExpr;
expect Symbol(")");
return print(${val});
}
rule Assign {
let name = expect Identifier;
expect Symbol("=");
let val = expect Expr;
return let ${name} = ${val};
}
}
pythonic {
def square(a, b) {
return a * b
}
n = 3
r = square(n, 4)
print(r)
if (r > 20) {
print(2)
} elif (r > 10) {
print(1)
} else {
print(0)
}
for i in range(3) {
print(i)
}
total = 0
while (total < 5) {
total = total + 2
}
print(total)
}
(not run yet)
Native run on the build machine:
12 1 0 1 2 6