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