-
-
Save bitcrazed/41939974879bd5056337 to your computer and use it in GitHub Desktop.
Language Comparison: Simple AST in Clojure, F#, Ocaml, Scala, Clojure, Ruby, C++, C#, Go, Haskell and others
This file contains 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
(use '[clojure.core.match :only [match]]) | |
(defn evaluate [env [sym x y]] | |
(match [sym] | |
['Number] x | |
['Add] (+ (evaluate env x) (evaluate env y)) | |
['Multiply] (* (evaluate env x) (evaluate env y)) | |
['Variable] (env x))) | |
(def environment {"a" 3, "b" 4, "c" 5}) | |
(def expression-tree '(Add (Variable "a") (Multiply (Number 2) (Variable "b")))) | |
(def result (evaluate environment expression-tree)) |
This file contains 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
(defprotocol Expression | |
(evaluate [e env] )) | |
(deftype Number1 [x]) | |
(deftype Add [x y] ) | |
(deftype Multiply [x y]) | |
(deftype Variable [x]) | |
(extend-protocol Expression | |
Number1 (evaluate [e env] (.x e ) ) | |
Add (evaluate [e env] (+ (evaluate (.x e) env) (evaluate (.y e) env))) | |
Multiply (evaluate [e env] (* (evaluate (.x e) env) (evaluate (.y e) env))) | |
Variable (evaluate [e env] (env (.x e)))) | |
(def environment {"a" 3, "b" 4, "c" 5}) | |
(def expression-tree (Add. (Variable. "a") (Multiply. (Number1. 2) (Variable. "b")))) | |
(def result (evaluate expression-tree environment)) | |
This file contains 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
#include <string> | |
#include <iostream> | |
#include <map> | |
#include <memory> | |
typedef std::map <std::string, int> Variables; | |
struct Expr | |
{ | |
virtual ~Expr() {} | |
virtual int eval (Variables&) = 0; | |
}; | |
struct Multiply : public Expr | |
{ | |
std::unique_ptr<Expr> e1, e2; | |
Multiply (Expr* lhs, Expr* rhs) : e1 (lhs), e2 (rhs) {} | |
int eval (Variables& env) { return e1->eval (env) * e2->eval (env); } | |
}; | |
struct Add : public Expr | |
{ | |
std::unique_ptr<Expr> e1, e2; | |
Add (Expr* lhs, Expr* rhs) : e1 (lhs), e2 (rhs) {} | |
int eval (Variables& env) { return e1->eval (env) + e2->eval (env); } | |
}; | |
struct Constant : public Expr | |
{ | |
int value; | |
Constant (int val) : value (val) {} | |
int eval (Variables&) { return value; } | |
}; | |
struct Variable : public Expr | |
{ | |
std::string varName; | |
Variable (const std::string& name) : varName (name) {} | |
int eval (Variables& env) { return env [varName]; } | |
}; | |
int main (int argc, char** argv) | |
{ | |
Variables env; | |
env["a"] = 3; | |
env["b"] = 4; | |
env["c"] = 5; | |
Add tree (new Variable ("a"), | |
new Multiply (new Constant (2), | |
new Variable ("b"))); | |
std::cout << tree.eval (env) << std::endl; | |
} |
This file contains 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
using System; | |
using Env = System.Collections.Generic.Dictionary<string, int>; | |
delegate int Expr(Env e); | |
public class Program | |
{ | |
public static void Main() | |
{ | |
Func<string, Expr> Var = s => env => env[s]; | |
Func<int, Expr> Num = i => env => i; | |
Func<Expr, Expr, Expr> Add = (x, y) => env => x(env) + y(env); | |
Func<Expr, Expr, Expr> Mul = (x, y) => env => x(env) * y(env); | |
var expr = Add(Var("a"), Mul(Num(2), Var("b"))); | |
Console.WriteLine(expr(new Env { { "a", 3 }, { "b", 4 }, { "c", 5 } })); | |
} | |
} |
This file contains 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
type Expression = | |
| Number of int | |
| Add of Expression * Expression | |
| Multiply of Expression * Expression | |
| Variable of string | |
let rec Evaluate (env:Map<string,int>) exp = | |
match exp with | |
| Number n -> n | |
| Add (x, y) -> Evaluate env x + Evaluate env y | |
| Multiply (x, y) -> Evaluate env x * Evaluate env y | |
| Variable id -> env.[id] | |
let environment = Map.ofList [ "a", 1; "b", 2; "c", 3 ] | |
let expressionTree1 = Add(Variable "a", Multiply(Number 2, Variable "b")) | |
let result = Evaluate environment expressionTree1 |
This file contains 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
package main | |
import "fmt" | |
type Add struct{a, b interface{}} | |
type Mul struct{a, b interface{}} | |
func eval(env map[string]int, e interface{}) int { | |
switch v := e.(type) { | |
case int: return v | |
case string: return env[v] | |
case Add: return eval(env, v.a) + eval(env, v.b) | |
case Mul: return eval(env, v.a) * eval(env, v.b) | |
} | |
return 0 | |
} | |
func main() { | |
env := map[string]int{"a":3, "b":4, "c":5} | |
ast := Add{"a", Mul{2, "b"}} | |
fmt.Println(eval(env, ast)) | |
} |
This file contains 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
import Data.Map | |
data Expression = | |
Number Int | |
| Add Expression Expression | |
| Multiply Expression Expression | |
| Variable String | |
evaluate :: Map String Int -> Expression -> Int | |
evaluate env exp = | |
case exp of | |
Number x -> x | |
Add x y -> evaluate env x + evaluate env y | |
Multiply x y -> evaluate env x * evaluate env y | |
Variable x -> findWithDefault 0 x env | |
environment = fromList([("a",3), ("b",4), ("c",7)]) | |
expressionTree = Add (Variable "a") (Multiply (Number 2) (Variable "b")) | |
result = evaluate environment expressionTree |
This file contains 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
import Data.Map | |
data Expression = | |
Number Int | |
| Add Expression Expression | |
| Multiply Expression Expression | |
| Variable String | |
evaluate :: Map String Int -> Expression -> Int | |
evaluate env (Number x) = x | |
evaluate env (Add x y) = evaluate env x + evaluate env y | |
evaluate env (Multiply x y) = evaluate env x * evaluate env y | |
evaluate env (Variable x) = findWithDefault 0 x env | |
environment = fromList([("a",3), ("b",4), ("c",7)]) | |
expressionTree = Add (Variable "a") (Multiply (Number 2) (Variable "b")) | |
result = evaluate environment expressionTree |
This file contains 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
#pragma indent | |
using Nemerle.Extensions; | |
using System.Collections.Generic; | |
variant Ast | |
| Number { val : int } | |
| Add { left : Ast; right : Ast } | |
| Multiply { left : Ast; right : Ast } | |
| Variable { name : string } | |
def eval(env, expr) | |
match(expr) | |
| Ast.Number(val) => val | |
| Add(l, r) => eval(env, l) + eval(env, r) | |
| Multiply(l, r) => eval(env, l) * eval(env, r) | |
| Variable(name) => env[name] | |
def environment = Dictionary() <- ["a" = 3, "b" = 4, "c" = 5]; | |
def expr = Ast.Add(Ast.Variable("a"), Ast.Multiply(Ast.Number(2), Ast.Variable("b"))); | |
def result = eval(environment, expr); |
This file contains 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
type expression = | |
Number of int | |
| Add of expression * expression | |
| Multiply of expression * expression | |
| Variable of string | |
let rec evaluate env = function | |
| Number n -> n | |
| Add (x, y) -> evaluate env x + evaluate env y | |
| Multiply (x, y) -> evaluate env x * evaluate env y | |
| Variable id -> env id | |
let environment = function "a" -> 3 | "b" -> 4 | "c" -> 5 | |
let expressiontree1 = Add(Variable "a", Multiply(Number 2, Variable "b")) | |
let result = evaluate environment expressiontree1 |
This file contains 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
Number = lambda env, n: n | |
Add = lambda env, a, b: evaluate(env, a) + evaluate(env, b) | |
Multiply = lambda env, a, b: evaluate(env, a) * evaluate(env, b) | |
Variable = lambda env, x: env[x] | |
evaluate = lambda env, expr: expr[0](env, *expr[1:]) | |
expression_tree = (Add, (Variable, 'a'), | |
(Multiply, (Number, 2), | |
(Variable, 'b'))) | |
environment = {'a': 3, 'b': 4, 'c': 5} | |
print evaluate(environment, expression_tree) |
This file contains 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
def evaluate(env, exp) | |
keyword, a, b = exp | |
case keyword | |
when :number; a | |
when :variable; env[a] | |
when :add; evaluate(env, a) + evaluate(env, b) | |
when :multiply; evaluate(env, a) * evaluate(env, b) | |
end | |
end | |
ExpressionTree = [:add, [:variable, :a], [:multiply, [:number, 2], [:variable, :b]]] | |
Env = { a: 3, b: 4, c: 5 } | |
puts evaluate(Env, ExpressionTree) |
This file contains 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
Number = lambda { |env, num| num } | |
Variable = lambda { |env, var| env[var] } | |
Add = lambda { |env, a, b| evaluate(env, a) + evaluate(env, b) } | |
Multiply = lambda { |env, a, b| evaluate(env, a) * evaluate(env, b) } | |
def evaluate(env, exp) | |
op, *args = exp | |
op.(env, *args) | |
end | |
ExpressionTree = [Add, [Variable, :a], [Multiply, [Number, 2], [Variable, :b]]] | |
Env = { a: 3, b: 4, c: 5 } | |
puts evaluate(Env, ExpressionTree) |
This file contains 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
abstract class Expression | |
case class Number(i: Int) extends Expression | |
case class Add(x: Expression, y: Expression) extends Expression | |
case class Multiply(x: Expression, y: Expression) extends Expression | |
case class Variable(id: Symbol) extends Expression | |
object Maths extends App { | |
val environment = Map('a -> 1, | |
'b -> 2, | |
'c -> 3) | |
def evaluate(env: Map[Symbol, Int], exp: Expression): Int = exp match { | |
case Number(n: Int) => n | |
case Add(x, y) => evaluate(env, x) + evaluate(env, y) | |
case Multiply(x, y) => evaluate(env, x) * evaluate(env, y) | |
case Variable(id: Symbol) => env(id) | |
} | |
val expressionTree1 = Add(Variable('a), Multiply(Number(2), Variable('b))) | |
println(evaluate(environment, expressionTree1)) | |
} |
This file contains 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
import java.util.*; | |
public class Eval { | |
static int evaluate(Map env, Expression exp){ | |
if(exp instanceof Variable){ return (Integer)env.get(((Variable)exp).x); } | |
else if(exp instanceof Number){ return ((Number)exp).x; } | |
else if(exp instanceof Multiply){ return evaluate(env, ((Multiply)exp).x)*evaluate(env, ((Multiply)exp).y); } | |
else if(exp instanceof Add){ return evaluate(env, ((Add)exp).x)+evaluate(env, ((Add)exp).y); } | |
return 0; | |
} | |
public static void main(String[] args){ | |
Map env=new HashMap(); | |
env.put("a", 3); | |
env.put("b", 4); | |
env.put("c", 5); | |
Expression expressionTree=new Add(new Variable("a"), new Multiply(new Number(2), new Variable("b"))); | |
System.out.println(evaluate(env, expressionTree)); | |
} | |
} | |
abstract class Expression {} | |
class Number extends Expression{ | |
int x; | |
Number(int x){ this.x=x; } | |
} | |
class Add extends Expression{ | |
Expression x; Expression y; | |
Add(Expression x, Expression y){ this.x=x; this.y=y; } | |
} | |
class Multiply extends Add{ | |
Multiply(Expression x, Expression y){ super(x, y); } | |
} | |
class Variable extends Expression{ | |
String x; | |
Variable(String x){ this.x=x; } | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment