module jlox.expr; import std.conv; import std.stdio; import std.meta : AliasSeq; import jlox.token; import jlox.tokentype; import common.util; abstract class Expr{ interface Visitor(R){ R visit(Assign expr); R visit(Binary expr); R visit(Call expr); R visit(Get expr); R visit(Grouping expr); R visit(Literal expr); R visit(Logical expr); R visit(Set expr); R visit(Super expr); R visit(This expr); R visit(Unary expr); R visit(Variable expr); } private alias rTypes = AliasSeq!(string, LoxValue, void); static foreach(T; rTypes) abstract T accept(Visitor!T visitor); private template defCtorAndAccept(){ mixin defaultCtor; static foreach(T; rTypes) override T accept(Visitor!T visitor) => visitor.visit(this); } static class Assign : typeof(this){ Token name; Expr value; mixin defCtorAndAccept; } static class Binary : typeof(this){ Expr left; Token operator; Expr right; mixin defCtorAndAccept; } static class Call : typeof(this){ Expr callee; Token paren; Expr[] arguments; mixin defCtorAndAccept; } static class Get : typeof(this){ Expr object; Token name; mixin defCtorAndAccept; } static class Grouping : typeof(this){ Expr expression; mixin defCtorAndAccept; } static class Literal : typeof(this){ LoxValue value; mixin defCtorAndAccept; } static class Logical : typeof(this){ Expr left; Token operator; Expr right; mixin defCtorAndAccept; } static class Set : typeof(this){ Expr object; Token name; Expr value; mixin defCtorAndAccept; } static class Super : typeof(this){ Token keyword; Token method; mixin defCtorAndAccept; } static class This : typeof(this){ Token keyword; mixin defCtorAndAccept; } static class Unary : typeof(this){ Token operator; Expr right; mixin defCtorAndAccept; } static class Variable : typeof(this){ Token name; mixin defCtorAndAccept; } }