public ComplexElement Layout(MineDefineAST ast)
 {
     var symbolTable = DefaultSymbolsTable();
     var rootDef = new ComplexElement();
     Plan(ast.Statements, symbolTable, Transform.Identity, rootDef);
     return rootDef;
 }
 public string ItDeterminesBoundaries(string input)
 {
     var cmplx = new ComplexElement();
     input.Split('|')
         .Select(x => x.Split(';'))
         .Select(x => new {
             Dimension = Dimension.Parse(x[0]),
             Location = Location.Parse(x[1]),
             Element = new StubElement() {
                 Width = int.Parse(x[2]),
                 Depth = int.Parse(x[3]),
                 Height = int.Parse(x[4]),
             }
         })
         .ToList()
         .ForEach(x => cmplx.AddBuildInstruction(new BuildInstruction(BuildShape.Box, x.Dimension, x.Location, x.Element)));
     return string.Join(";", new[] {cmplx.Width, cmplx.Depth, cmplx.Height});
 }
 private void Plan(IEnumerable<IStatement> statements, SymbolTable symbolTable, Transform transform, ComplexElement def)
 {
     foreach (var statement in statements)
     {
         if (statement is ElementDefinition) {
             var anotherDef = (ElementDefinition) statement;
             var ele = new ComplexElement();
             Plan(anotherDef.Statements, symbolTable.Push(), Transform.Identity, ele);
             symbolTable = symbolTable.AddSymbol(anotherDef.Name, ele);
         }
         else if (statement is BuildByIdentifier)
         {
             var build = (BuildByIdentifier) statement;
             var ele = symbolTable[build.Identifier];
             var buildInst = new BuildInstruction(build.Shape, build.Dimension, transform.Adjust(build.Location), ele);
             def.AddBuildInstruction(buildInst);
         }
         else if (statement is BuildByStatements)
         {
             var build = (BuildByStatements) statement;
             var ele = new ComplexElement();
             Plan(build.Statements, symbolTable, Transform.Identity, ele);
             var buildInst = new BuildInstruction(build.Shape, build.Dimension, transform.Adjust(build.Location), ele);
             def.AddBuildInstruction(buildInst);
         }
         else if (statement is OriginTransformStatement)
         {
             var transStatement = (OriginTransformStatement) statement;
             if (transStatement.Instructions is AbsoluteTransformInstructions)
             {
                 var absInstr = (AbsoluteTransformInstructions) transStatement.Instructions;
                 var newTrans = transform.Adjust(absInstr.Direction, absInstr.Degree);
                 Plan(transStatement.Statements,symbolTable,newTrans,def);
             }
             else
             {
                 var absInstr = (RelativeTransformInstructions) transStatement.Instructions;
                 var newTrans = transform.Adjust(absInstr.Direction, def);
                 Plan(transStatement.Statements,symbolTable,newTrans,def);
             }
         }
     }
 }
 public MineDefineExecutable(MineDefineAST ast, ComplexElement layout)
 {
     _ast = ast;
     _layout = layout;
 }