Last active
July 11, 2016 15:51
-
-
Save alphaKAI/f82ea135cd5c4346654e98d0e949806f to your computer and use it in GitHub Desktop.
Expression Tree in D.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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