source: trunk/sources/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.3/SymbolicExpressionTreeCompiler.cs @ 3376

Last change on this file since 3376 was 3376, checked in by swagner, 11 years ago

Moved interfaces and classes for deep cloning from HeuristicLab.Core to HeuristicLab.Common (#975).

File size: 3.4 KB
Line 
1#region License Information
2/* HeuristicLab
3 * Copyright (C) 2002-2010 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
4 *
5 * This file is part of HeuristicLab.
6 *
7 * HeuristicLab is free software: you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation, either version 3 of the License, or
10 * (at your option) any later version.
11 *
12 * HeuristicLab is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
19 */
20#endregion
21
22using System;
23using System.Linq;
24using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
25using HeuristicLab.Common;
26using HeuristicLab.Core;
27using System.Collections.Generic;
28using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding;
29using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding.GeneralSymbols;
30
31namespace HeuristicLab.Encodings.SymbolicExpressionTreeEncoding {
32  public class SymbolicExpressionTreeCompiler {
33    private Dictionary<Type, CodeSymbol> codeSymbol = new Dictionary<Type, CodeSymbol>() {
34      {typeof(Addition), CodeSymbol.Add},
35      {typeof(Subtraction), CodeSymbol.Sub},
36      {typeof(Multiplication), CodeSymbol.Mul},
37      {typeof(Division), CodeSymbol.Div},
38      {typeof(InvokeFunction), CodeSymbol.Call},
39      //{typeof(Values), CodeSymbol.Values}
40    };
41    private Dictionary<string, short> entryPoint = new Dictionary<string, short>();
42
43    public Instruction[] Compile(SymbolicExpressionTree tree) {
44      List<Instruction> code = new List<Instruction>();
45      entryPoint.Clear();
46      // compile main body
47      code.AddRange(Compile(tree.ResultProducingExpression));
48      // compile branches
49      var functionBranches = from node in tree.IterateNodesPrefix()
50                             where node.Symbol is Defun
51                             select node;
52      foreach (DefunTreeNode branch in functionBranches) {
53        entryPoint[branch.FunctionName] = (short)code.Count;
54        code.AddRange(Compile(branch));
55      }
56      return code.ToArray();
57    }
58
59    private IEnumerable<Instruction> Compile(SymbolicExpressionTreeNode branch) {
60      foreach (var node in IteratePrefix(branch)) {
61        Instruction instr = new Instruction();
62        if (node.SubTrees.Count > 255) throw new ArgumentException();
63        instr.nArguments = (byte)node.SubTrees.Count;
64        if (codeSymbol.ContainsKey(node.Symbol.GetType())) {
65          instr.symbol = codeSymbol[node.Symbol.GetType()];
66          if (instr.symbol == CodeSymbol.Call) {
67            var invokeNode = (InvokeFunctionTreeNode)node;
68            instr.iArg0 = entryPoint[invokeNode.Symbol.FunctionName];
69          }
70        } else {
71          instr.symbol = CodeSymbol.Dynamic;
72          instr.dynamicNode = node;
73        }
74        yield return instr;
75      }
76    }
77
78    private IEnumerable<SymbolicExpressionTreeNode> IteratePrefix(SymbolicExpressionTreeNode branch) {
79      yield return branch;
80      foreach (var subtree in branch.SubTrees) {
81        foreach (var node in IteratePrefix(subtree))
82          yield return node;
83      }
84    }
85  }
86}
Note: See TracBrowser for help on using the repository browser.