- Timestamp:
- 04/21/10 15:21:34 (15 years ago)
- Location:
- trunk/sources/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.3/Compiler
- Files:
-
- 1 added
- 2 moved
Legend:
- Unmodified
- Added
- Removed
-
trunk/sources/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.3/Compiler/Instruction.cs
r3456 r3462 26 26 using System.Collections.Generic; 27 27 using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding; 28 using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding. GeneralSymbols;28 using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding.Symbols; 29 29 30 namespace HeuristicLab.Encodings.SymbolicExpressionTreeEncoding { 31 public enum CodeSymbol : byte { 32 Add, 33 Sub, 34 Mul, 35 Div, 36 Call, 37 Arg, 38 Values, 39 Dynamic 40 }; 30 namespace HeuristicLab.Encodings.SymbolicExpressionTreeEncoding.Compiler { 31 // total size of this struct should be small to improve cache access while executing the code 32 // should be aligned to 8/16/32 byte 33 // size = 4(8) + 1 + 1 + 2 = 8 (12) 41 34 public struct Instruction { 35 // the tree node can hold additional data that is necessary for the execution of this instruction 36 public SymbolicExpressionTreeNode dynamicNode; 37 // op code of the function that determines what operation should be executed 38 public byte opCode; 39 // number of arguments of the current instruction 42 40 public byte nArguments; 43 public CodeSymbol symbol; 44 public short iArg0; 45 public SymbolicExpressionTreeNode dynamicNode; 41 // an optional short value (addresses for calls, argument index for arguments) 42 public ushort iArg0; 46 43 } 47 44 } -
trunk/sources/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.3/Compiler/SymbolicExpressionTreeCompiler.cs
r3456 r3462 27 27 using System.Collections.Generic; 28 28 using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding; 29 using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding. GeneralSymbols;29 using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding.Symbols; 30 30 31 namespace HeuristicLab.Encodings.SymbolicExpressionTreeEncoding {31 namespace HeuristicLab.Encodings.SymbolicExpressionTreeEncoding.Compiler { 32 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(Argument), CodeSymbol.Arg}, 40 //{typeof(Values), CodeSymbol.Values} 41 }; 42 private Dictionary<string, short> entryPoint = new Dictionary<string, short>(); 33 private Dictionary<string, ushort> entryPoint = new Dictionary<string, ushort>(); 34 private List<Func<Instruction, Instruction>> postInstructionCompiledHooks = new List<Func<Instruction, Instruction>>(); 43 35 44 public Instruction[] Compile(SymbolicExpressionTree tree ) {36 public Instruction[] Compile(SymbolicExpressionTree tree, Func<SymbolicExpressionTreeNode, byte> opCodeMapper) { 45 37 List<Instruction> code = new List<Instruction>(); 46 38 entryPoint.Clear(); 47 39 // compile main body 48 code.AddRange(Compile(tree.Root.SubTrees[0].SubTrees[0] ));40 code.AddRange(Compile(tree.Root.SubTrees[0].SubTrees[0], opCodeMapper)); 49 41 // compile branches 50 42 var functionBranches = from node in tree.IterateNodesPrefix() … … 52 44 select node; 53 45 foreach (DefunTreeNode branch in functionBranches) { 54 entryPoint[branch.FunctionName] = (short)code.Count; 55 code.AddRange(Compile(branch.SubTrees[0])); 46 if (code.Count > ushort.MaxValue) throw new ArgumentException("Code for the tree is too long (> ushort.MaxValue)."); 47 entryPoint[branch.FunctionName] = (ushort)code.Count; 48 code.AddRange(Compile(branch.SubTrees[0], opCodeMapper)); 56 49 } 57 50 // address of all functions is fixed now … … 59 52 for (int i = 0; i < code.Count; i++) { 60 53 Instruction instr = code[i]; 61 if (instr. symbol == CodeSymbol.Call) {54 if (instr.dynamicNode.Symbol is InvokeFunction) { 62 55 var invokeNode = (InvokeFunctionTreeNode)instr.dynamicNode; 63 56 instr.iArg0 = entryPoint[invokeNode.Symbol.FunctionName]; 64 instr.dynamicNode = null;65 57 code[i] = instr; 66 58 } … … 70 62 } 71 63 72 private IEnumerable<Instruction> Compile(SymbolicExpressionTreeNode branch ) {73 foreach (var node in IteratePrefix(branch)) {64 private IEnumerable<Instruction> Compile(SymbolicExpressionTreeNode branch, Func<SymbolicExpressionTreeNode, byte> opCodeMapper) { 65 foreach (var node in branch.IterateNodesPrefix()) { 74 66 Instruction instr = new Instruction(); 75 if (node.SubTrees.Count > 255) throw new ArgumentException( );67 if (node.SubTrees.Count > 255) throw new ArgumentException("Number of subtrees is too big (>255)"); 76 68 instr.nArguments = (byte)node.SubTrees.Count; 77 if (codeSymbol.ContainsKey(node.Symbol.GetType())) { 78 instr.symbol = codeSymbol[node.Symbol.GetType()]; 79 if (instr.symbol == CodeSymbol.Arg) { 80 var argNode = (ArgumentTreeNode)node; 81 instr.iArg0 = (short)argNode.Symbol.ArgumentIndex; 82 } else if (instr.symbol == CodeSymbol.Call) { 83 instr.dynamicNode = node; // save node for fixup of jump addresses in second iteration 84 } 85 } else { 86 instr.symbol = CodeSymbol.Dynamic; 87 instr.dynamicNode = node; 69 instr.opCode = opCodeMapper(node); 70 if (branch.Symbol is Argument) { 71 var argNode = (ArgumentTreeNode)node; 72 instr.iArg0 = (ushort)argNode.Symbol.ArgumentIndex; 73 } 74 instr.dynamicNode = node; 75 foreach (var hook in postInstructionCompiledHooks) { 76 instr = hook(instr); 88 77 } 89 78 yield return instr; … … 91 80 } 92 81 93 private IEnumerable<SymbolicExpressionTreeNode> IteratePrefix(SymbolicExpressionTreeNode branch) { 94 yield return branch; 95 foreach (var subtree in branch.SubTrees) { 96 foreach (var node in IteratePrefix(subtree)) 97 yield return node; 98 } 82 /// <summary> 83 /// Adds a function that will be called every time an instruction is compiled. 84 /// The compiled will insert the instruction returned by the hook into the code. 85 /// </summary> 86 /// <param name="hook">The hook that should be called for each compiled instruction.</param> 87 public void AddInstructionPostProcessingHook(Func<Instruction, Instruction> hook) { 88 postInstructionCompiledHooks.Add(hook); 99 89 } 100 90 }
Note: See TracChangeset
for help on using the changeset viewer.