1 | using System;
|
---|
2 | using System.Collections.Generic;
|
---|
3 | using HeuristicLab.Algorithms.PushGP.Expressions.Boolean;
|
---|
4 | using HeuristicLab.Algorithms.PushGP.Expressions.Code;
|
---|
5 | using HeuristicLab.Algorithms.PushGP.Expressions.Exec;
|
---|
6 | using HeuristicLab.Algorithms.PushGP.Expressions.Float;
|
---|
7 | using HeuristicLab.Algorithms.PushGP.Expressions.Integer;
|
---|
8 | using HeuristicLab.Algorithms.PushGP.Expressions.Templates;
|
---|
9 | using HeuristicLab.Algorithms.PushGP.Interpreter;
|
---|
10 | using HeuristicLab.Algorithms.PushGP.Stack;
|
---|
11 |
|
---|
12 | namespace HeuristicLab.Algorithms.PushGP.Expressions
|
---|
13 | {
|
---|
14 | public static class ExpressionFactory
|
---|
15 | {
|
---|
16 | private static Func<IInterpreter, IStack<Expression>> execStackProvider = interpreter => interpreter.ExecStack;
|
---|
17 | private static Func<IInterpreter, IStack<Expression>> codeStackProvider = interpreter => interpreter.CodeStack;
|
---|
18 | private static Func<IInterpreter, IStack<string>> nameStackProvider = interpreter => interpreter.NameStack;
|
---|
19 | private static Func<IInterpreter, IStack<long>> integerStackProvider = interpreter => interpreter.IntegerStack;
|
---|
20 | private static Func<IInterpreter, IStack<double>> floatStackProvider = interpreter => interpreter.FloatStack;
|
---|
21 | private static Func<IInterpreter, IStack<bool>> booleanStackProvider = interpreter => interpreter.BooleanStack;
|
---|
22 |
|
---|
23 | private static IDictionary<OpCode, Expression> expressions = new Dictionary<OpCode, Expression>()
|
---|
24 | {
|
---|
25 | #region Exec
|
---|
26 | { OpCode.ExecPop, new PopExpressionTemplate<Expression>(Symbols.ExecPop, execStackProvider) },
|
---|
27 | { OpCode.ExecDuplicate, new DuplicateExpressionTemplate<Expression>(Symbols.ExecDuplicate, execStackProvider) },
|
---|
28 | { OpCode.ExecDefine, new ExecDefineExpression() },
|
---|
29 | { OpCode.ExecDoXRange, new ExecDoRangeExpression() },
|
---|
30 | { OpCode.ExecY, new ExecYExpression() },
|
---|
31 | { OpCode.ExecIf, new ExecIfExpression() },
|
---|
32 | #endregion Exec
|
---|
33 |
|
---|
34 | #region Code
|
---|
35 | { OpCode.CodeDuplicate, new DuplicateExpressionTemplate<Expression>(Symbols.CodeDuplicate, codeStackProvider, true) },
|
---|
36 | { OpCode.CodeDefine, new CodeDefineExpression() },
|
---|
37 | { OpCode.CodeQuote, new CodeQuoteExpression() },
|
---|
38 | { OpCode.CodeDo, new CodeDoExpression() },
|
---|
39 | { OpCode.CodeIf, new CodeIfExpression() },
|
---|
40 | { OpCode.CodeNoop, new CodeNoopExpression() },
|
---|
41 | #endregion Code
|
---|
42 |
|
---|
43 | #region Name
|
---|
44 | { OpCode.NamePop, new PopExpressionTemplate<string>(Symbols.NamePop, nameStackProvider) },
|
---|
45 | { OpCode.NameDuplicate, new DuplicateExpressionTemplate<string>(Symbols.NameDuplicate, nameStackProvider) },
|
---|
46 | #endregion Name
|
---|
47 |
|
---|
48 | #region Boolean
|
---|
49 | { OpCode.BooleanPop, new PopExpressionTemplate<bool>(Symbols.BooleanPop, booleanStackProvider) },
|
---|
50 | { OpCode.BooleanDuplicate, new DuplicateExpressionTemplate<bool>(Symbols.BooleanDuplicate, booleanStackProvider) },
|
---|
51 | { OpCode.BooleanDefine, new DefineExpressionTemplate<bool>(Symbols.BooleanDefine, booleanStackProvider, v => new BooleanPushExpression(v)) },
|
---|
52 | { OpCode.BooleanOr, new PushResultExpressionTemplate<bool, bool>(Symbols.BooleanOr, booleanStackProvider, booleanStackProvider, v => v[0] || v[1]) },
|
---|
53 | { OpCode.BooleanAnd, new PushResultExpressionTemplate<bool, bool>(Symbols.BooleanAnd, booleanStackProvider, booleanStackProvider, v => v[0] && v[1]) },
|
---|
54 | #endregion Boolean
|
---|
55 |
|
---|
56 | #region Float
|
---|
57 | { OpCode.IntegerPop, new PopExpressionTemplate<long>(Symbols.IntegerPop, integerStackProvider) },
|
---|
58 | { OpCode.IntegerDuplicate, new DuplicateExpressionTemplate<long>(Symbols.IntegerDuplicate, integerStackProvider) },
|
---|
59 | { OpCode.IntegerDefine, new DefineExpressionTemplate<long>(Symbols.IntegerDefine, integerStackProvider, v => new IntegerPushExpression(v)) },
|
---|
60 | { OpCode.IntegerAdd, new PushResultExpressionTemplate<long, long>(Symbols.IntegerAdd, integerStackProvider, integerStackProvider, v => v[0] + v[1]) },
|
---|
61 | { OpCode.IntegerSubtract, new PushResultExpressionTemplate<long, long>(Symbols.IntegerSubtract, integerStackProvider, integerStackProvider, v => v[0] - v[1]) },
|
---|
62 | { OpCode.IntegerMultiply, new PushResultExpressionTemplate<long, long>(Symbols.IntegerMultiply, integerStackProvider, integerStackProvider, v => v[0] * v[1]) },
|
---|
63 | { OpCode.IntegerDivide, new PushResultExpressionTemplate<long, long>(Symbols.IntegerDivide, integerStackProvider, integerStackProvider, v => v[0] / v[1]) },
|
---|
64 | { OpCode.IntegerMin, new PushResultExpressionTemplate<long, long>(Symbols.IntegerMin, integerStackProvider, integerStackProvider, v => Math.Min(v[0], v[1])) },
|
---|
65 | { OpCode.IntegerMax, new PushResultExpressionTemplate<long, long>(Symbols.IntegerMax, integerStackProvider, integerStackProvider, v => Math.Max(v[0], v[1])) },
|
---|
66 | { OpCode.IntegerSmallerThan, new PushResultExpressionTemplate<long, bool>(Symbols.IntegerSmallerThan, integerStackProvider, booleanStackProvider, v => v[0] < v[1]) },
|
---|
67 | { OpCode.IntegerGreaterThan, new PushResultExpressionTemplate<long, bool>(Symbols.IntegerGreaterThan, integerStackProvider, booleanStackProvider, v => v[0] > v[1]) },
|
---|
68 | { OpCode.IntegerEquals, new PushResultExpressionTemplate<long, bool>(Symbols.IntegerEquals, integerStackProvider, booleanStackProvider, v => v[0] == v[1]) },
|
---|
69 | #endregion Float
|
---|
70 |
|
---|
71 | #region Float
|
---|
72 | { OpCode.FloatPop, new PopExpressionTemplate<double>(Symbols.FloatPop, floatStackProvider) },
|
---|
73 | { OpCode.FloatDuplicate, new DuplicateExpressionTemplate<double>(Symbols.FloatDuplicate, floatStackProvider) },
|
---|
74 | { OpCode.FloatDefine, new DefineExpressionTemplate<double>(Symbols.FloatDefine, floatStackProvider, v => new FloatPushExpression(v)) },
|
---|
75 | { OpCode.FloatAdd, new PushResultExpressionTemplate<double, double>(Symbols.FloatAdd, floatStackProvider, floatStackProvider, v => v[0] + v[1]) },
|
---|
76 | { OpCode.FloatSubtract, new PushResultExpressionTemplate<double, double>(Symbols.FloatSubtract, floatStackProvider, floatStackProvider, v => v[0] - v[1]) },
|
---|
77 | { OpCode.FloatMultiply, new PushResultExpressionTemplate<double, double>(Symbols.FloatMultiply, floatStackProvider, floatStackProvider, v => v[0] * v[1]) },
|
---|
78 | { OpCode.FloatDivide, new PushResultExpressionTemplate<double, double>(Symbols.FloatDivide, floatStackProvider, floatStackProvider, v => v[0] / v[1]) },
|
---|
79 | { OpCode.FloatMin, new PushResultExpressionTemplate<double, double>(Symbols.FloatMin, floatStackProvider, floatStackProvider, v => Math.Min(v[0], v[1])) },
|
---|
80 | { OpCode.FloatMax, new PushResultExpressionTemplate<double, double>(Symbols.FloatMax, floatStackProvider, floatStackProvider, v => Math.Max(v[0], v[1])) },
|
---|
81 | { OpCode.FloatSmallerThan, new PushResultExpressionTemplate<double, bool>(Symbols.FloatSmallerThan, floatStackProvider, booleanStackProvider, v => v[0] < v[1]) },
|
---|
82 | { OpCode.FloatGreaterThan, new PushResultExpressionTemplate<double, bool>(Symbols.FloatGreaterThan, floatStackProvider, booleanStackProvider, v => v[0] > v[1]) },
|
---|
83 | { OpCode.FloatEquals, new PushResultExpressionTemplate<double, bool>(Symbols.FloatEquals, floatStackProvider, booleanStackProvider, v => v[0] == v[1]) },
|
---|
84 | #endregion Float
|
---|
85 | };
|
---|
86 |
|
---|
87 | public static Expression Create(OpCode opCode)
|
---|
88 | {
|
---|
89 | Expression expression;
|
---|
90 | return expressions.TryGetValue(opCode, out expression)
|
---|
91 | ? expression
|
---|
92 | : expressions[OpCode.CodeNoop];
|
---|
93 | }
|
---|
94 | }
|
---|
95 | }
|
---|