Package com.ardublock.translator

Source Code of com.ardublock.translator.Translator

package com.ardublock.translator;

import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedHashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;

import javax.swing.JOptionPane;

import com.ardublock.translator.adaptor.BlockAdaptor;
import com.ardublock.translator.adaptor.OpenBlocksAdaptor;
import com.ardublock.translator.block.TranslatorBlock;
import com.ardublock.translator.block.TranslatorBlockFactory;
import com.ardublock.translator.block.exception.BlockException;
import com.ardublock.translator.block.exception.SocketNullException;
import com.ardublock.translator.block.exception.SubroutineNameDuplicatedException;
import com.ardublock.translator.block.exception.SubroutineNotDeclaredException;

import edu.mit.blocks.codeblocks.Block;
import edu.mit.blocks.renderable.RenderableBlock;
import edu.mit.blocks.workspace.Workspace;

public class Translator
{
  private static final String variablePrefix = "_ABVAR_";

  private Set<String> headerFileSet;
  private Set<String> definitionSet;
  private List<String> setupCommand;
  private Set<String> functionNameSet;
  private Set<TranslatorBlock> bodyTranslatreFinishCallbackSet;
  private BlockAdaptor blockAdaptor;
 
  private Set<String> inputPinSet;
  private Set<String> outputPinSet;
 
  private Map<String, String> numberVariableSet;
  private Map<String, String> booleanVariableSet;
  private Map<String, String> stringVariableSet;
  private Map<String, Object> internalData;
 
  private Workspace workspace;
 
  private String rootBlockName;
 
  private int variableCnt;
  private boolean isScoopProgram;

  public Translator(Workspace ws)
  {
    workspace = ws;
    reset();
  }
 
  public String genreateHeaderCommand()
  {
    StringBuilder headerCommand = new StringBuilder();
   
    if (!headerFileSet.isEmpty())
    {
      for (String file:headerFileSet)
      {
        headerCommand.append("#include <" + file + ">\n");
      }
      headerCommand.append("\n");
    }
   
    if (!definitionSet.isEmpty())
    {
      for (String command:definitionSet)
      {
        headerCommand.append(command + "\n");
      }
      headerCommand.append("\n");
    }
   
    if (!functionNameSet.isEmpty())
    {
      for (String functionName:functionNameSet)
      {
        headerCommand.append("void " + functionName + "();\n");
      }
      headerCommand.append("\n");
    }
   
    return headerCommand.toString() + generateSetupFunction();
  }
 
  public String generateSetupFunction()
  {
    StringBuilder setupFunction = new StringBuilder();
    setupFunction.append("void setup()\n{\n");
   
    if (!inputPinSet.isEmpty())
    {
      for (String pinNumber:inputPinSet)
      {
        setupFunction.append("pinMode( " + pinNumber + " , INPUT);\n");
      }
    }
    if (!outputPinSet.isEmpty())
    {
      for (String pinNumber:outputPinSet)
      {
        setupFunction.append("pinMode( " + pinNumber + " , OUTPUT);\n");
      }
    }
   
    if (!setupCommand.isEmpty())
    {
      for (String command:setupCommand)
      {
        setupFunction.append(command + "\n");
      }
    }
   
    setupFunction.append("}\n\n");
   
    return setupFunction.toString();
  }
 
  public String translate(Long blockId) throws SocketNullException, SubroutineNotDeclaredException, BlockException
  {
    TranslatorBlockFactory translatorBlockFactory = new TranslatorBlockFactory();
    Block block = workspace.getEnv().getBlock(blockId);
    TranslatorBlock rootTranslatorBlock = translatorBlockFactory.buildTranslatorBlock(this, blockId, block.getGenusName(), "", "", block.getBlockLabel());
    return rootTranslatorBlock.toCode();
  }
 
  public BlockAdaptor getBlockAdaptor()
  {
    return blockAdaptor;
  }
 
  public void reset()
  {
    headerFileSet = new LinkedHashSet<String>();
    definitionSet = new LinkedHashSet<String>();
    setupCommand = new LinkedList<String>();
    functionNameSet = new HashSet<String>();
    inputPinSet = new HashSet<String>();
    outputPinSet = new HashSet<String>();
    bodyTranslatreFinishCallbackSet = new HashSet<TranslatorBlock>();
   
    numberVariableSet = new HashMap<String, String>();
    booleanVariableSet = new HashMap<String, String>();
    stringVariableSet = new HashMap<String, String>();
   
    internalData =  new HashMap<String, Object>();
    blockAdaptor = buildOpenBlocksAdaptor();
   
    variableCnt = 0;
   
    rootBlockName = null;
    isScoopProgram = false;
  }
 
  private BlockAdaptor buildOpenBlocksAdaptor()
  {
    return new OpenBlocksAdaptor();
  }
 
  public void addHeaderFile(String headerFile)
  {
    if (!headerFileSet.contains(headerFile))
    {
      headerFileSet.add(headerFile);
    }
  }
 
  public void addSetupCommand(String command)
  {
    if (!setupCommand.contains(command))
    {
      setupCommand.add(command);
    }
  }
 
  public void addSetupCommandForced(String command)
  {
    setupCommand.add(command);
  }
 
  public void addDefinitionCommand(String command)
  {
    definitionSet.add(command);
  }
 
  public void addInputPin(String pinNumber)
  {
    inputPinSet.add(pinNumber);
  }
 
  public void addOutputPin(String pinNumber)
  {
    outputPinSet.add(pinNumber);
  }
 
  public String getNumberVariable(String userVarName)
  {
    return numberVariableSet.get(userVarName);
  }
 
  public String getBooleanVariable(String userVarName)
  {
    return booleanVariableSet.get(userVarName);
  }
 
  public String getStringVariable(String userVarName)
  {
    return stringVariableSet.get(userVarName);
  }
 
  public void addNumberVariable(String userVarName, String internalName)
  {
    numberVariableSet.put(userVarName, internalName);
  }
 
  public void addBooleanVariable(String userVarName, String internalName)
  {
    booleanVariableSet.put(userVarName, internalName);
  }
 
  public void addStringVariable(String userVarName, String internalName)
  {
    stringVariableSet.put(userVarName, internalName);
  }
 
  public void addFunctionName(Long blockId, String functionName) throws SubroutineNameDuplicatedException
  {
    if (functionName.equals("loop") ||functionName.equals("setup") || functionNameSet.contains(functionName))
    {
      throw new SubroutineNameDuplicatedException(blockId);
    }
   
    functionNameSet.add(functionName);
  }
 
  public boolean containFunctionName(String name)
  {
    return functionNameSet.contains(name.trim());
  }
 
 
  public String buildVariableName()
  {
    return buildVariableName("");
  }
 
  public String buildVariableName(String reference)
  {
    variableCnt = variableCnt + 1;
    String varName = variablePrefix + variableCnt + "_";
    int i;
    for (i=0; i<reference.length(); ++i)
    {
      char c = reference.charAt(i);
      if (Character.isLetter(c) || Character.isDigit(c) || (c == '_'))
      {
        varName = varName + c;
      }
    }
    return varName;
  }
 
  public Workspace getWorkspace() {
    return workspace;
  }
 
  public Block getBlock(Long blockId) {
    return workspace.getEnv().getBlock(blockId);
  }
 
  public void registerBodyTranslateFinishCallback(TranslatorBlock translatorBlock)
  {
    bodyTranslatreFinishCallbackSet.add(translatorBlock);
  }

  public void beforeGenerateHeader()  throws SocketNullException, SubroutineNotDeclaredException
  {
    for (TranslatorBlock translatorBlock : bodyTranslatreFinishCallbackSet)
    {
      translatorBlock.onTranslateBodyFinished();
    }
  }

  public String getRootBlockName() {
    return rootBlockName;
  }

  public void setRootBlockName(String rootBlockName) {
    this.rootBlockName = rootBlockName;
  }

  public boolean isScoopProgram() {
    return isScoopProgram;
  }

  public void setScoopProgram(boolean isScoopProgram) {
    this.isScoopProgram = isScoopProgram;
  }
 
  public Set<RenderableBlock> findEntryBlocks()
  {
    Set<RenderableBlock> loopBlockSet = new HashSet<RenderableBlock>();
    Iterable<RenderableBlock> renderableBlocks = workspace.getRenderableBlocks();
   
    for (RenderableBlock renderableBlock:renderableBlocks)
    {
      Block block = renderableBlock.getBlock();
     
      if (!block.hasPlug() && (Block.NULL.equals(block.getBeforeBlockID())))
      {
        if(block.getGenusName().equals("loop"))
        {
          loopBlockSet.add(renderableBlock);
        }
        if(block.getGenusName().equals("loop1"))
        {
          loopBlockSet.add(renderableBlock);
        }
        if(block.getGenusName().equals("loop2"))
        {
          loopBlockSet.add(renderableBlock);
        }
        if(block.getGenusName().equals("loop3"))
        {
          loopBlockSet.add(renderableBlock);
        }
        if(block.getGenusName().equals("program"))
        {
          loopBlockSet.add(renderableBlock);
        }
        if(block.getGenusName().equals("setup"))
        {
          loopBlockSet.add(renderableBlock);
        }
      }
    }
   
    return loopBlockSet;
  }
 
  public Set<RenderableBlock> findSubroutineBlocks() throws SubroutineNameDuplicatedException
  {
    Set<RenderableBlock> subroutineBlockSet = new HashSet<RenderableBlock>();
    Iterable<RenderableBlock> renderableBlocks = workspace.getRenderableBlocks();
   
    for (RenderableBlock renderableBlock:renderableBlocks)
    {
      Block block = renderableBlock.getBlock();
     
      if (!block.hasPlug() && (Block.NULL.equals(block.getBeforeBlockID())))
      {
        if (block.getGenusName().equals("subroutine"))
        {
          String functionName = block.getBlockLabel().trim();
          this.addFunctionName(block.getBlockID(), functionName);
          subroutineBlockSet.add(renderableBlock);
        }
       
      }
    }
   
    return subroutineBlockSet;
  }
 
  public String translate(Set<RenderableBlock> loopBlocks, Set<RenderableBlock> subroutineBlocks) throws SocketNullException, SubroutineNotDeclaredException
  {
    StringBuilder code = new StringBuilder();
   
    for (RenderableBlock renderableBlock : loopBlocks)
    {
      Block loopBlock = renderableBlock.getBlock();
      code.append(translate(loopBlock.getBlockID()));
    }
   
    for (RenderableBlock renderableBlock : subroutineBlocks)
    {
      Block subroutineBlock = renderableBlock.getBlock();
      code.append(translate(subroutineBlock.getBlockID()));
    }
    beforeGenerateHeader();
    code.insert(0, genreateHeaderCommand());
   
    return code.toString();
  }
 
  public Object getInternalData(String name)
  {
    return internalData.get(name);
  }
 
  public void addInternalData(String name, Object value)
  {
    internalData.put(name, value);
  }
}
TOP

Related Classes of com.ardublock.translator.Translator

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.