From 192b8d1c273900dad8e2a9d70c06f381a9e7fe78 Mon Sep 17 00:00:00 2001 From: nazrin Date: Wed, 28 May 2025 20:44:45 +0000 Subject: [PATCH] Representing Code 5 --- src/expr.d | 84 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 84 insertions(+) create mode 100644 src/expr.d diff --git a/src/expr.d b/src/expr.d new file mode 100644 index 0000000..408129b --- /dev/null +++ b/src/expr.d @@ -0,0 +1,84 @@ +import std.conv; +import std.stdio; + +import taggedalgebraic; + +import token; +import tokentype; + +abstract class Expr{ + interface Visitor(R){ + R visit(Binary expr); + R visit(Grouping expr); + R visit(Literal expr); + R visit(Unary expr); + } + abstract string accept(Visitor!string visitor); + private template defCtorAndAccept(){ + this(Args...)(auto ref Args args){ + static foreach(i, a; args) + this.tupleof[i] = a; + } + override string accept(Visitor!string visitor) => visitor.visit(this); + } + + static class Binary : Expr{ + Expr left; + Token operator; + Expr right; + mixin defCtorAndAccept; + } + static class Grouping : Expr{ + Expr expression; + mixin defCtorAndAccept; + } + static class Literal : Expr{ + TTokenValue value; + mixin defCtorAndAccept; + } + static class Unary : Expr{ + Token operator; + Expr right; + mixin defCtorAndAccept; + } +} + +class AstPrinter : Expr.Visitor!string{ + string print(Expr expr){ + return expr.accept(this); + } + string parenthesize(Args...)(string name, Args args){ + string s = "(" ~ name; + static foreach(expr; args){ + s ~= " "; + s ~= expr.accept(this); + } + return s ~ ")"; + } + string visit(Expr.Binary expr){ + return parenthesize(expr.operator.lexeme, expr.left, expr.right); + } + string visit(Expr.Grouping expr){ + return parenthesize("group", expr.expression); + } + string visit(Expr.Literal expr){ + if(expr.value.isNil) + return "nil"; + return expr.value.to!string; + } + string visit(Expr.Unary expr){ + return parenthesize(expr.operator.lexeme, expr.right); + } +} + +unittest{ + auto expression = new Expr.Binary( + new Expr.Unary( + new Token(TokenType.MINUS, "-", TTokenValue.nil(0), 1), + new Expr.Literal(123)), + new Token(TokenType.STAR, "*", TTokenValue.nil(0), 1), + new Expr.Grouping( + new Expr.Literal(45.67))); + assert(new AstPrinter().print(expression)); +} +