Child pages
  • Model Transformation with Xtend

Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

  1. Add a new plug-in project de.cau.cs.rtprak.login.compiler.ui to your workspace. This time, leave the option This plug-in will make contributions to the UI checked. Add dependencies to the two projects containing the Turing Machine metamodel and the programming language metamodel. Also add a dependency to our base plug-in that contains the transformation.
  2. Add a menu contribution that is visible if a file containing a Turing Machine model is selected in the project explorer. (this can be both, a regular Turing Machine model file or a textual representation of a Turing Machine) The previous tutorial taught you how to add menu contributions.
  3. Create a command handler that loads the turing machine model from the selected file, calls the transformation on the model, and saves the imperative program to a file with the same name, but different extension. You can use the following code as a template: (The code requires a dependency to com.google.inject to work.)

    Code Block
    languagejava
        @Override
        public Object execute(ExecutionEvent event) throws ExecutionException {
            ISelection selection = HandlerUtil.getCurrentSelection(event);
            if (selection instanceof IStructuredSelection) {
                Object element = ((IStructuredSelection) selection).getFirstElement();
                if (element instanceof IFile) {
                    IFile machineFile = (IFile) element;
                    
                    // Load Turing Machine
                    TuringMachine machine = loadTuringMachine(machineFile);
                    
                    // Call the transformation
                    Injector injector = Guice.createInjector();
                    TuringToImperativeTransformation transformation =
                            injector.getInstance(TuringToImperativeTransformation.class);
                    Program program = transformation.transformTuringToImperative(machine);
                    
                    // Save imperative program
                    IFile programFile = machineFile.getParent().getFile(
                            new Path(machineFile.getName() + ".imperative"));
                    saveImperativeProgram(programFile, program);
                    
                    // Refresh the parent folder to have the new file show up in the UI
                    try {
                        machineFile.getParent().refreshLocal(IResource.DEPTH_ONE, null);
                    } catch (CoreException e) {
                        // Ignore
                    }
                }
            }
            return null;
        }
        
        /**
         * Load the turing machine model from the given file.
         * 
         * @param turingFile the file to load the turing machine model from.
         * @return the turing machine model.
         * @throws ExecutionException if the file couldn't be opened.
         */
        private TuringMachine loadTuringMachine(IFile turingFile) throws ExecutionException {
            // TODO Implement.
        }
        
        /**
         * Saves the given imperative program in the given file.
         * 
         * @param programFile the file to save the program to.
         * @param program the program to save.
         * @throws ExecutionException if there was an error saving the file.
         */
        private void saveImperativeProgram(IFile programFile, Program program) throws ExecutionException {
            // TODO Implement
        }

    Note that replacing the ".imperative" file extension by ".pseudo", this code will generate a textual representation of the transformation's results. Even if saving the model in the ".imperative" format works, saving it in the textual format may still fail if the model is not correct. This includes things like forgetting to add a condition to a WhileStatement, or forgetting to add a statement to an IfStatement's falseStatement. Thus, generating the textual output is a good way to find problems with your transformation. You may even want to add a second menu contribution to have both output formats available at the same time without always having to change the source code. Note, however, that no errors when generating the textual output does not mean that your transformation is correct – it merely means that your model can be expressed by the grammar.