Representing Code 5
This commit is contained in:
parent
074fde11ea
commit
192b8d1c27
1 changed files with 84 additions and 0 deletions
84
src/expr.d
Normal file
84
src/expr.d
Normal file
|
|
@ -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));
|
||||
}
|
||||
|
||||
Loading…
Add table
Add a link
Reference in a new issue