Last updated: 2026-09-15

U
Undergraduate level

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