Skip to content

Instantly share code, notes, and snippets.

@alphaKAI
Last active July 11, 2016 15:51
Show Gist options
  • Save alphaKAI/f82ea135cd5c4346654e98d0e949806f to your computer and use it in GitHub Desktop.
Save alphaKAI/f82ea135cd5c4346654e98d0e949806f to your computer and use it in GitHub Desktop.
Expression Tree in D.
enum ExprType {
Number,
Add,
Sub,
Mul,
Div,
Variable
}
alias Environment = double[string];
class Expression {
ExprType type;
double Value() { return typeof(return).init; }
double Value(Environment) { return typeof(return).init; }
string Id() { return typeof(return).init; }
}
double Evalute(Expression expr, Environment env = null) {
final switch (expr.type) {
case ExprType.Number:
return (cast(Number)expr).Value;
case ExprType.Add:
return (cast(Add)expr).Value(env);
case ExprType.Sub:
return (cast(Sub)expr).Value(env);
case ExprType.Mul:
return (cast(Mul)expr).Value(env);
case ExprType.Div:
return (cast(Div)expr).Value(env);
case ExprType.Variable:
if (env == null) {
throw new Error("Environment is null. Cannnot reference any variable.");
}
return env[(cast(Variable)expr).Id];
}
}
class Number : Expression {
double value;
this (double v) {
this.type = ExprType.Number;
this.value = v;
}
@property override double Value() { return this.value; }
}
class BinaryExpression : Expression {
Expression x,
y;
double function(double, double) expr;
this (Expression _x, Expression _y, typeof(expr) expr) {
this.x = _x;
this.y = _y;
this.expr = expr;
}
@property override double Value(Environment env) {
return expr(Evalute(x, env), Evalute(y, env));
}
}
class Add : BinaryExpression {
this (Expression _x, Expression _y) {
this.type = ExprType.Add;
super(_x, _y, (double x, double y) => x + y);
}
}
class Sub : BinaryExpression {
this (Expression _x, Expression _y) {
this.type = ExprType.Sub;
super(_x, _y, (double x, double y) => x - y);
}
}
class Mul : BinaryExpression {
this (Expression _x, Expression _y) {
this.type = ExprType.Mul;
super(_x, _y, (double x, double y) => x * y);
}
}
class Div : BinaryExpression {
this (Expression _x, Expression _y) {
this.type = ExprType.Div;
super(_x, _y, (double x, double y) => x / y);
}
}
class Variable : Expression {
string id;
this (string _id) {
this.type = ExprType.Variable;
this.id = _id;
}
@property override string Id() { return this.id; }
}
import std.stdio;
void main() {
auto ExprTree1 =
new Div(
new Add(
new Mul(
new Number(400),
new Number(500)
),
new Sub(
new Number(100),
new Variable("a")
)
),
new Variable("b")
);
writeln(Evalute(ExprTree1, ["a" : 50, "b" : 20]));
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment