org.pshdl.model.simulation.codegenerator.DartCodeGenerator.java Source code

Java tutorial

Introduction

Here is the source code for org.pshdl.model.simulation.codegenerator.DartCodeGenerator.java

Source

/**
 * PSHDL is a library and (trans-)compiler for PSHDL input. It generates
 *     output suitable for implementation or simulation of it.
 * 
 *     Copyright (C) 2014 Karsten Becker (feedback (at) pshdl (dot) org)
 * 
 *     This program is free software: you can redistribute it and/or modify
 *     it under the terms of the GNU General Public License as published by
 *     the Free Software Foundation, either version 3 of the License, or
 *     (at your option) any later version.
 * 
 *     This program is distributed in the hope that it will be useful,
 *     but WITHOUT ANY WARRANTY; without even the implied warranty of
 *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *     GNU General Public License for more details.
 * 
 *     You should have received a copy of the GNU General Public License
 *     along with this program.  If not, see <http://www.gnu.org/licenses/>.
 * 
 *     This License does not grant permission to use the trade names, trademarks,
 *     service marks, or product names of the Licensor, except as required for
 *     reasonable and customary use in describing the origin of the Work.
 * 
 * Contributors:
 *     Karsten Becker - initial API and implementation
 */
package org.pshdl.model.simulation.codegenerator;

import com.google.common.base.Objects;
import com.google.common.collect.Iterables;
import com.google.common.collect.Lists;
import com.google.common.io.Files;
import java.io.File;
import java.io.InputStream;
import java.io.OutputStream;
import java.math.BigInteger;
import java.nio.charset.StandardCharsets;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.EnumSet;
import java.util.List;
import java.util.Set;
import org.apache.commons.cli.CommandLine;
import org.apache.commons.cli.Options;
import org.eclipse.xtend2.lib.StringConcatenation;
import org.eclipse.xtext.xbase.lib.Conversions;
import org.eclipse.xtext.xbase.lib.Exceptions;
import org.eclipse.xtext.xbase.lib.Functions.Function1;
import org.eclipse.xtext.xbase.lib.IterableExtensions;
import org.pshdl.interpreter.ExecutableModel;
import org.pshdl.interpreter.Frame;
import org.pshdl.interpreter.IHDLInterpreterFactory;
import org.pshdl.interpreter.InternalInformation;
import org.pshdl.interpreter.NativeRunner;
import org.pshdl.interpreter.VariableInformation;
import org.pshdl.interpreter.utils.Instruction;
import org.pshdl.model.simulation.ITypeOuptutProvider;
import org.pshdl.model.simulation.codegenerator.CommonCodeGenerator;
import org.pshdl.model.simulation.codegenerator.DartCodeGeneratorParameter;
import org.pshdl.model.utils.PSAbstractCompiler;
import org.pshdl.model.utils.services.AuxiliaryContent;
import org.pshdl.model.utils.services.IOutputProvider;
import org.pshdl.model.validation.Problem;

@SuppressWarnings("all")
public class DartCodeGenerator extends CommonCodeGenerator implements ITypeOuptutProvider {
    private String unitName;

    private String library;

    private boolean usePackageImport;

    private final static int epsWidth = 16;

    public static String TESTRUNNER_DIR = "/Users/karstenbecker/GDrive/DartTestRunner/";

    public static String DART_EXEC = "/Applications/dart/dart-sdk/bin/dart";

    public DartCodeGenerator() {
    }

    public DartCodeGenerator(final DartCodeGeneratorParameter parameter) {
        super(parameter);
        this.unitName = parameter.unitName;
        this.library = parameter.library;
        this.usePackageImport = (!parameter.useLocalImport);
    }

    public IHDLInterpreterFactory<NativeRunner> createInterpreter(final File tempDir) {
        try {
            IHDLInterpreterFactory<NativeRunner> _xblockexpression = null;
            {
                final String dartCode = this.generateMainCode();
                final File binDir = new File(tempDir, "bin");
                boolean _mkdirs = binDir.mkdirs();
                boolean _not = (!_mkdirs);
                if (_not) {
                    throw new IllegalArgumentException(("Failed to create Directory " + binDir));
                }
                File _file = new File(binDir, "dut.dart");
                Files.write(dartCode, _file, StandardCharsets.UTF_8);
                final File testRunnerDir = new File(DartCodeGenerator.TESTRUNNER_DIR);
                final File testRunner = new File(testRunnerDir, "bin/darttestrunner.dart");
                String _name = testRunner.getName();
                File _file_1 = new File(binDir, _name);
                Files.copy(testRunner, _file_1);
                final File yaml = new File(testRunnerDir, "pubspec.yaml");
                String _name_1 = yaml.getName();
                File _file_2 = new File(tempDir, _name_1);
                Files.copy(yaml, _file_2);
                File _file_3 = new File(binDir, "packages");
                Path _path = _file_3.toPath();
                File _file_4 = new File(testRunnerDir, "packages");
                Path _path_1 = _file_4.toPath();
                java.nio.file.Files.createSymbolicLink(_path, _path_1);
                File _file_5 = new File(tempDir, "packages");
                Path _path_2 = _file_5.toPath();
                File _file_6 = new File(testRunnerDir, "packages");
                Path _path_3 = _file_6.toPath();
                java.nio.file.Files.createSymbolicLink(_path_2, _path_3);
                _xblockexpression = new IHDLInterpreterFactory<NativeRunner>() {
                    public NativeRunner newInstance() {
                        try {
                            String _name = testRunner.getName();
                            String _plus = ("bin/" + _name);
                            ProcessBuilder _processBuilder = new ProcessBuilder(DartCodeGenerator.DART_EXEC, _plus,
                                    DartCodeGenerator.this.unitName, DartCodeGenerator.this.library);
                            ProcessBuilder _directory = _processBuilder.directory(tempDir);
                            ProcessBuilder _redirectErrorStream = _directory.redirectErrorStream(true);
                            final Process dartRunner = _redirectErrorStream.start();
                            InputStream _inputStream = dartRunner.getInputStream();
                            OutputStream _outputStream = dartRunner.getOutputStream();
                            return new NativeRunner(_inputStream, _outputStream, DartCodeGenerator.this.em,
                                    dartRunner, 5, ((("Dart " + DartCodeGenerator.this.library) + ".")
                                            + DartCodeGenerator.this.unitName));
                        } catch (Throwable _e) {
                            throw Exceptions.sneakyThrow(_e);
                        }
                    }
                };
            }
            return _xblockexpression;
        } catch (Throwable _e) {
            throw Exceptions.sneakyThrow(_e);
        }
    }

    protected String constantSuffix() {
        return "";
    }

    protected String fieldPrefix() {
        return "_";
    }

    protected void postBody() {
        this.indent--;
    }

    protected void preBody() {
        this.indent++;
    }

    protected CharSequence applyRegUpdates() {
        return "_updateRegs();";
    }

    protected CharSequence checkRegupdates() {
        return "!_regUpdates.isEmpty";
    }

    protected CharSequence clearRegUpdates() {
        StringConcatenation _builder = new StringConcatenation();
        _builder.append("_regUpdates.clear();");
        _builder.newLine();
        return _builder;
    }

    protected CharSequence arrayInit(final VariableInformation varInfo, final BigInteger initValue,
            final EnumSet<CommonCodeGenerator.Attributes> attributes) {
        StringConcatenation _builder = new StringConcatenation();
        _builder.append("new ");
        CharSequence _fieldType = this.fieldType(varInfo, attributes);
        _builder.append(_fieldType, "");
        _builder.append("(");
        int _arraySize = this.getArraySize(varInfo);
        _builder.append(_arraySize, "");
        _builder.append(")");
        return _builder;
    }

    protected CharSequence functionFooter(final Frame frame) {
        StringConcatenation _builder = new StringConcatenation();
        _builder.append("}");
        _builder.newLine();
        return _builder;
    }

    protected CharSequence functionHeader(final Frame frame) {
        StringConcatenation _builder = new StringConcatenation();
        _builder.append("void _");
        CharSequence _frameName = this.getFrameName(frame);
        _builder.append(_frameName, "");
        _builder.append("() {");
        _builder.newLineIfNotEmpty();
        return _builder;
    }

    protected CharSequence scheduleShadowReg(final InternalInformation outputInternal, final CharSequence last,
            final CharSequence cpyName, final CharSequence offset, final boolean forceRegUpdate,
            final CharSequence fillValue) {
        StringConcatenation _builder = new StringConcatenation();
        {
            if ((!forceRegUpdate)) {
                _builder.append("if (");
                _builder.append(cpyName, "");
                _builder.append("!=");
                _builder.append(last, "");
                _builder.append(")");
                _builder.newLineIfNotEmpty();
                CharSequence _indent = this.indent();
                _builder.append(_indent, "");
                _builder.append("\t");
            }
        }
        _builder.append("_regUpdates.add(new RegUpdate(");
        int _varIdx = this.getVarIdx(outputInternal);
        _builder.append(_varIdx, "");
        _builder.append(", ");
        _builder.append(offset, "");
        _builder.append(", ");
        _builder.append(fillValue, "");
        _builder.append("));");
        return _builder;
    }

    protected CharSequence runMethodsHeader(final boolean constant) {
        StringConcatenation _builder = new StringConcatenation();
        _builder.append("void ");
        {
            if ((!constant)) {
                _builder.append("run");
            } else {
                _builder.append("initConstants");
            }
        }
        _builder.append("() {");
        _builder.newLineIfNotEmpty();
        return _builder;
    }

    protected CharSequence runMethodsFooter(final boolean constant) {
        StringConcatenation _builder = new StringConcatenation();
        _builder.append("}");
        _builder.newLine();
        return _builder;
    }

    protected CharSequence callStage(final int stage, final boolean constant) {
        StringConcatenation _builder = new StringConcatenation();
        _builder.append("_");
        CharSequence _stageMethodName = this.stageMethodName(stage, constant);
        _builder.append(_stageMethodName, "");
        _builder.append("();");
        _builder.newLineIfNotEmpty();
        return _builder;
    }

    protected CharSequence stageMethodsFooter(final int stage, final int stageCosts, final boolean constant) {
        StringConcatenation _builder = new StringConcatenation();
        _builder.append("}");
        _builder.newLine();
        return _builder;
    }

    protected CharSequence copyArray(final VariableInformation varInfo) {
        final CharSequence type = this.fieldType(varInfo, CommonCodeGenerator.NONE);
        StringConcatenation _builder = new StringConcatenation();
        EnumSet<CommonCodeGenerator.Attributes> _of = EnumSet.<CommonCodeGenerator.Attributes>of(
                CommonCodeGenerator.Attributes.isPrev);
        CharSequence _idName = this.idName(varInfo, true, _of);
        _builder.append(_idName, "");
        _builder.append(" = new ");
        _builder.append(type, "");
        _builder.append(".from");
        {
            boolean _notEquals = (!Objects.equal(type, "List< "));
            if (_notEquals) {
                _builder.append("List");
            }
        }
        _builder.append("(");
        CharSequence _idName_1 = this.idName(varInfo, true, CommonCodeGenerator.NONE);
        _builder.append(_idName_1, "");
        _builder.append(");");
        return _builder;
    }

    protected CharSequence fieldType(final VariableInformation information,
            final EnumSet<CommonCodeGenerator.Attributes> attributes) {
        String jt = "int";
        boolean _isBoolean = this.isBoolean(information, attributes);
        if (_isBoolean) {
            jt = "bool";
        }
        boolean _and = false;
        boolean _isArray = this.isArray(information);
        if (!_isArray) {
            _and = false;
        } else {
            boolean _contains = attributes.contains(CommonCodeGenerator.Attributes.baseType);
            boolean _not = (!_contains);
            _and = _not;
        }
        if (_and) {
            boolean _equals = Objects.equal(jt, "bool");
            if (_equals) {
                StringConcatenation _builder = new StringConcatenation();
                _builder.append("List<");
                _builder.append(jt, "");
                _builder.append(">");
                return _builder;
            }
            boolean _and_1 = false;
            if (!(information.width <= 8)) {
                _and_1 = false;
            } else {
                boolean _tripleEquals = (information.type == VariableInformation.Type.INT);
                _and_1 = _tripleEquals;
            }
            if (_and_1) {
                StringConcatenation _builder_1 = new StringConcatenation();
                _builder_1.append("Int8List");
                return _builder_1;
            }
            if ((information.width <= 8)) {
                StringConcatenation _builder_2 = new StringConcatenation();
                _builder_2.append("Uint8List");
                return _builder_2;
            }
            boolean _and_2 = false;
            if (!(information.width <= 16)) {
                _and_2 = false;
            } else {
                boolean _tripleEquals_1 = (information.type == VariableInformation.Type.INT);
                _and_2 = _tripleEquals_1;
            }
            if (_and_2) {
                StringConcatenation _builder_3 = new StringConcatenation();
                _builder_3.append("Int16List");
                return _builder_3;
            }
            if ((information.width <= 16)) {
                StringConcatenation _builder_4 = new StringConcatenation();
                _builder_4.append("Uint16List");
                return _builder_4;
            }
            boolean _and_3 = false;
            if (!(information.width <= 32)) {
                _and_3 = false;
            } else {
                boolean _tripleEquals_2 = (information.type == VariableInformation.Type.INT);
                _and_3 = _tripleEquals_2;
            }
            if (_and_3) {
                StringConcatenation _builder_5 = new StringConcatenation();
                _builder_5.append("Int32List");
                return _builder_5;
            }
            if ((information.width <= 32)) {
                StringConcatenation _builder_6 = new StringConcatenation();
                _builder_6.append("Uint32List");
                return _builder_6;
            }
            boolean _and_4 = false;
            if (!(information.width <= 64)) {
                _and_4 = false;
            } else {
                boolean _tripleEquals_3 = (information.type == VariableInformation.Type.INT);
                _and_4 = _tripleEquals_3;
            }
            if (_and_4) {
                StringConcatenation _builder_7 = new StringConcatenation();
                _builder_7.append("Int64List");
                return _builder_7;
            }
            if ((information.width <= 64)) {
                StringConcatenation _builder_8 = new StringConcatenation();
                _builder_8.append("Uint64List");
                return _builder_8;
            }
            StringConcatenation _builder_9 = new StringConcatenation();
            _builder_9.append("List<");
            _builder_9.append(jt, "");
            _builder_9.append(">");
            return _builder_9;
        }
        return jt;
    }

    protected CharSequence calculateVariableAccessIndexArr(final VariableInformation varInfo) {
        return "offset";
    }

    protected CharSequence footer() {
        StringConcatenation _builder = new StringConcatenation();
        _builder.append("\t");
        _builder.append("void setVar(int idx, dynamic value, {int offset}) {");
        _builder.newLine();
        _builder.append("\t\t");
        _builder.append("switch (idx) {");
        _builder.newLine();
        _builder.append("\t\t\t");
        EnumSet<CommonCodeGenerator.Attributes> _of = EnumSet.<CommonCodeGenerator.Attributes>of(
                CommonCodeGenerator.Attributes.useArrayOffset);
        CharSequence _setInputCases = this.setInputCases("value", null, _of);
        _builder.append(_setInputCases, "\t\t\t");
        _builder.newLineIfNotEmpty();
        _builder.append("\t\t\t");
        _builder.append("default:");
        _builder.newLine();
        _builder.append("\t\t\t\t");
        _builder.append("throw new ArgumentError(\"Not a valid index: $idx\");");
        _builder.newLine();
        _builder.append("\t\t");
        _builder.append("}");
        _builder.newLine();
        _builder.append("\t");
        _builder.append("}");
        _builder.newLine();
        _builder.append("\t");
        _builder.newLine();
        _builder.append("\t");
        _builder.append("int getIndex(String name) {");
        _builder.newLine();
        _builder.append("\t\t");
        _builder.append("return _varIdx[name];");
        _builder.newLine();
        _builder.append("\t");
        _builder.append("}");
        _builder.newLine();
        _builder.append("\t");
        _builder.newLine();
        _builder.append("\t");
        _builder.append("String getName(int idx) {");
        _builder.newLine();
        _builder.append("\t\t");
        _builder.append("switch (idx) {");
        _builder.newLine();
        {
            for (final VariableInformation v : this.em.variables) {
                _builder.append("\t\t\t");
                _builder.append("case ");
                int _varIdx = this.getVarIdx(v, false);
                _builder.append(_varIdx, "\t\t\t");
                _builder.append(": return \"");
                String _replaceAll = v.name.replaceAll("[\\$]", "\\\\\\$");
                _builder.append(_replaceAll, "\t\t\t");
                _builder.append("\";");
                _builder.newLineIfNotEmpty();
            }
        }
        _builder.append("\t\t\t");
        _builder.append("default:");
        _builder.newLine();
        _builder.append("\t\t\t\t");
        _builder.append("throw new ArgumentError(\"Not a valid index: $idx\");");
        _builder.newLine();
        _builder.append("\t\t");
        _builder.append("}");
        _builder.newLine();
        _builder.append("\t");
        _builder.append("}");
        _builder.newLine();
        _builder.append("\t");
        _builder.newLine();
        _builder.append("\t");
        _builder.append("dynamic getVar(int idx, {int offset}) {");
        _builder.newLine();
        _builder.append("\t\t");
        _builder.append("switch (idx) {");
        _builder.newLine();
        _builder.append("\t\t\t");
        EnumSet<CommonCodeGenerator.Attributes> _of_1 = EnumSet.<CommonCodeGenerator.Attributes>of(
                CommonCodeGenerator.Attributes.useArrayOffset);
        CharSequence _outputCases = this.getOutputCases(null, _of_1);
        _builder.append(_outputCases, "\t\t\t");
        _builder.newLineIfNotEmpty();
        _builder.append("\t\t\t");
        _builder.append("default:");
        _builder.newLine();
        _builder.append("\t\t\t\t");
        _builder.append("throw new ArgumentError(\"Not a valid index: $idx\");");
        _builder.newLine();
        _builder.append("\t\t");
        _builder.append("}");
        _builder.newLine();
        _builder.append("\t");
        _builder.append("}");
        _builder.newLine();
        _builder.append("\t");
        _builder.newLine();
        _builder.append("\t");
        _builder.append("int get deltaCycle =>_deltaCycle;");
        _builder.newLine();
        _builder.append("\t");
        _builder.newLine();
        _builder.append("\t");
        _builder.append("int get varNum => ");
        int _size = this.varIdx.size();
        _builder.append(_size, "\t");
        _builder.append(";");
        _builder.newLineIfNotEmpty();
        _builder.append("\t");
        _builder.newLine();
        _builder.append("\t");
        _builder.append("bool get ");
        _builder.append(CommonCodeGenerator.DISABLE_EDGES.name, "\t");
        _builder.append(" => ");
        CharSequence _idName = this.idName(CommonCodeGenerator.DISABLE_EDGES, true, CommonCodeGenerator.NONE);
        _builder.append(_idName, "\t");
        _builder.append(";");
        _builder.newLineIfNotEmpty();
        _builder.append("\t");
        _builder.append("set ");
        _builder.append(CommonCodeGenerator.DISABLE_EDGES.name, "\t");
        _builder.append("(bool newVal) => ");
        CharSequence _idName_1 = this.idName(CommonCodeGenerator.DISABLE_EDGES, true, CommonCodeGenerator.NONE);
        _builder.append(_idName_1, "\t");
        _builder.append("=newVal;");
        _builder.newLineIfNotEmpty();
        _builder.append("\t");
        _builder.append("bool get ");
        _builder.append(CommonCodeGenerator.DISABLE_REG_OUTPUTLOGIC.name, "\t");
        _builder.append(" => ");
        CharSequence _idName_2 = this.idName(CommonCodeGenerator.DISABLE_REG_OUTPUTLOGIC, true,
                CommonCodeGenerator.NONE);
        _builder.append(_idName_2, "\t");
        _builder.append(";");
        _builder.newLineIfNotEmpty();
        _builder.append("\t");
        _builder.append("set ");
        _builder.append(CommonCodeGenerator.DISABLE_REG_OUTPUTLOGIC.name, "\t");
        _builder.append("(bool newVal) => ");
        CharSequence _idName_3 = this.idName(CommonCodeGenerator.DISABLE_REG_OUTPUTLOGIC, true,
                CommonCodeGenerator.NONE);
        _builder.append(_idName_3, "\t");
        _builder.append("=newVal;");
        _builder.newLineIfNotEmpty();
        _builder.append("\t");
        _builder.newLine();
        {
            for (final VariableInformation vi : this.em.variables) {
                _builder.append("\t");
                _builder.append("int get ");
                CharSequence _idName_4 = this.idName(vi.name, false, CommonCodeGenerator.NONE);
                _builder.append(_idName_4, "\t");
                _builder.append(" => ");
                CharSequence _idName_5 = this.idName(vi.name, true, CommonCodeGenerator.NONE);
                _builder.append(_idName_5, "\t");
                _builder.append(";");
                _builder.newLineIfNotEmpty();
                _builder.append("\t");
                _builder.append("set ");
                CharSequence _idName_6 = this.idName(vi.name, false, CommonCodeGenerator.NONE);
                _builder.append(_idName_6, "\t");
                _builder.append("(int newVal) => ");
                CharSequence _idName_7 = this.idName(vi.name, true, CommonCodeGenerator.NONE);
                _builder.append(_idName_7, "\t");
                _builder.append("=newVal;");
                _builder.newLineIfNotEmpty();
            }
        }
        _builder.append("\t");
        _builder.newLine();
        _builder.append("\t");
        CharSequence _description = this.getDescription();
        _builder.append(_description, "\t");
        _builder.newLineIfNotEmpty();
        _builder.append("}");
        _builder.newLine();
        return _builder;
    }

    public CharSequence getDescription() {
        StringConcatenation _builder = new StringConcatenation();
        _builder.append("Description get description=>new Description(");
        _builder.newLine();
        _builder.append("[");
        _builder.newLine();
        {
            final Function1<VariableInformation, Boolean> _function = new Function1<VariableInformation, Boolean>() {
                public Boolean apply(final VariableInformation it) {
                    return Boolean.valueOf((it.dir == VariableInformation.Direction.IN));
                }
            };
            Iterable<VariableInformation> _filter = IterableExtensions.<VariableInformation>filter(
                    ((Iterable<VariableInformation>) Conversions.doWrapArray(this.em.variables)), _function);
            boolean _hasElements = false;
            for (final VariableInformation v : _filter) {
                if (!_hasElements) {
                    _hasElements = true;
                } else {
                    _builder.appendImmediate(",", "");
                }
                CharSequence _asPort = this.asPort(v);
                _builder.append(_asPort, "");
                _builder.newLineIfNotEmpty();
            }
        }
        _builder.append("],");
        _builder.newLine();
        _builder.append("[");
        _builder.newLine();
        {
            final Function1<VariableInformation, Boolean> _function_1 = new Function1<VariableInformation, Boolean>() {
                public Boolean apply(final VariableInformation it) {
                    return Boolean.valueOf((it.dir == VariableInformation.Direction.INOUT));
                }
            };
            Iterable<VariableInformation> _filter_1 = IterableExtensions.<VariableInformation>filter(
                    ((Iterable<VariableInformation>) Conversions.doWrapArray(this.em.variables)), _function_1);
            boolean _hasElements_1 = false;
            for (final VariableInformation v_1 : _filter_1) {
                if (!_hasElements_1) {
                    _hasElements_1 = true;
                } else {
                    _builder.appendImmediate(",", "");
                }
                CharSequence _asPort_1 = this.asPort(v_1);
                _builder.append(_asPort_1, "");
                _builder.newLineIfNotEmpty();
            }
        }
        _builder.append("],");
        _builder.newLine();
        _builder.append("[");
        _builder.newLine();
        {
            final Function1<VariableInformation, Boolean> _function_2 = new Function1<VariableInformation, Boolean>() {
                public Boolean apply(final VariableInformation it) {
                    return Boolean.valueOf((it.dir == VariableInformation.Direction.OUT));
                }
            };
            Iterable<VariableInformation> _filter_2 = IterableExtensions.<VariableInformation>filter(
                    ((Iterable<VariableInformation>) Conversions.doWrapArray(this.em.variables)), _function_2);
            boolean _hasElements_2 = false;
            for (final VariableInformation v_2 : _filter_2) {
                if (!_hasElements_2) {
                    _hasElements_2 = true;
                } else {
                    _builder.appendImmediate(",", "");
                }
                CharSequence _asPort_2 = this.asPort(v_2);
                _builder.append(_asPort_2, "");
                _builder.newLineIfNotEmpty();
            }
        }
        _builder.append("],");
        _builder.newLine();
        _builder.append("[");
        _builder.newLine();
        {
            final Function1<VariableInformation, Boolean> _function_3 = new Function1<VariableInformation, Boolean>() {
                public Boolean apply(final VariableInformation it) {
                    return Boolean.valueOf((it.dir == VariableInformation.Direction.INTERNAL));
                }
            };
            Iterable<VariableInformation> _filter_3 = IterableExtensions.<VariableInformation>filter(
                    ((Iterable<VariableInformation>) Conversions.doWrapArray(this.em.variables)), _function_3);
            boolean _hasElements_3 = false;
            for (final VariableInformation v_3 : _filter_3) {
                if (!_hasElements_3) {
                    _hasElements_3 = true;
                } else {
                    _builder.appendImmediate(",", "");
                }
                CharSequence _asPort_3 = this.asPort(v_3);
                _builder.append(_asPort_3, "");
                _builder.newLineIfNotEmpty();
            }
        }
        _builder.append("], _varIdx, \"");
        _builder.append(this.em.moduleName, "");
        _builder.append("\");");
        _builder.newLineIfNotEmpty();
        return _builder;
    }

    public CharSequence asPort(final VariableInformation v) {
        CharSequence _xblockexpression = null;
        {
            String dims = "";
            boolean _isArray = this.isArray(v);
            if (_isArray) {
                StringConcatenation _builder = new StringConcatenation();
                _builder.append(", dimensions: [");
                {
                    boolean _hasElements = false;
                    for (final int i : v.dimensions) {
                        if (!_hasElements) {
                            _hasElements = true;
                        } else {
                            _builder.appendImmediate(",", "");
                        }
                        _builder.append(i, "");
                    }
                }
                _builder.append("]");
                dims = _builder.toString();
            }
            String _xifexpression = null;
            if (v.isClock) {
                _xifexpression = ", clock:true";
            } else {
                _xifexpression = "";
            }
            final String clock = _xifexpression;
            String _xifexpression_1 = null;
            if (v.isReset) {
                _xifexpression_1 = ", reset:true";
            } else {
                _xifexpression_1 = "";
            }
            final String reset = _xifexpression_1;
            String type = "INVALID";
            final VariableInformation.Type _switchValue = v.type;
            if (_switchValue != null) {
                switch (_switchValue) {
                case BIT:
                    type = "Port.TYPE_BIT";
                    break;
                case INT:
                    type = "Port.TYPE_INT";
                    break;
                case UINT:
                    type = "Port.TYPE_UINT";
                    break;
                case BOOL:
                    type = "Port.TYPE_BOOL";
                    break;
                case STRING:
                    type = "Port.TYPE_STRING";
                    break;
                case ENUM:
                    type = "Port.TYPE_ENUM";
                    break;
                default:
                    break;
                }
            }
            StringConcatenation _builder_1 = new StringConcatenation();
            _builder_1.append("new Port(");
            Integer _get = this.varIdx.get(v.name);
            _builder_1.append(_get, "");
            _builder_1.append(", \"");
            String _replaceAll = v.name.replaceAll("[\\$]", "\\\\\\$");
            _builder_1.append(_replaceAll, "");
            _builder_1.append("\", ");
            _builder_1.append(v.width, "");
            _builder_1.append(", ");
            _builder_1.append(type, "");
            _builder_1.append(dims, "");
            _builder_1.append(clock, "");
            _builder_1.append(reset, "");
            _builder_1.append(")");
            _xblockexpression = _builder_1;
        }
        return _xblockexpression;
    }

    protected CharSequence header() {
        StringConcatenation _builder = new StringConcatenation();
        {
            boolean _tripleNotEquals = (this.library != null);
            if (_tripleNotEquals) {
                _builder.append("library ");
                _builder.append(this.library, "");
                _builder.append(";");
            }
        }
        _builder.newLineIfNotEmpty();
        CharSequence _imports = this.getImports(this.usePackageImport);
        _builder.append(_imports, "");
        _builder.newLineIfNotEmpty();
        _builder.append("void main(List<String> args, SendPort replyTo){");
        _builder.newLine();
        _builder.append("  \t");
        _builder.append("handleReceive((e,l) => new ");
        _builder.append(this.unitName, "  \t");
        _builder.append("(e,l), replyTo);");
        _builder.newLineIfNotEmpty();
        _builder.append("}");
        _builder.newLine();
        {
            if (this.hasClock) {
                _builder.append("class RegUpdate {");
                _builder.newLine();
                _builder.append("\t");
                _builder.append("final int internalID;");
                _builder.newLine();
                _builder.append("\t");
                _builder.append("final int offset;");
                _builder.newLine();
                _builder.append("\t");
                _builder.append("final int fillValue;");
                _builder.newLine();
                _builder.append("\t");
                _builder.newLine();
                _builder.append("\t");
                _builder.append("RegUpdate(this.internalID, this.offset, this.fillValue);");
                _builder.newLine();
                _builder.append("\t");
                _builder.newLine();
                _builder.append("\t");
                _builder.append("int get hashCode {");
                _builder.newLine();
                _builder.append("\t\t");
                _builder.append("final int prime = 31;");
                _builder.newLine();
                _builder.append("\t\t");
                _builder.append("int result = 1;");
                _builder.newLine();
                _builder.append("\t\t");
                _builder.append("result = (prime * result) + internalID;");
                _builder.newLine();
                _builder.append("\t\t");
                _builder.append("result = (prime * result) + offset;");
                _builder.newLine();
                _builder.append("\t\t");
                _builder.append("result = (prime * result) + fillValue;");
                _builder.newLine();
                _builder.append("\t\t");
                _builder.append("return result;");
                _builder.newLine();
                _builder.append("\t");
                _builder.append("}");
                _builder.newLine();
                _builder.append("\t");
                _builder.newLine();
                _builder.append("\t");
                _builder.append("operator ==(RegUpdate other) {");
                _builder.newLine();
                _builder.append("\t\t");
                _builder.append("if (identical(this, other))");
                _builder.newLine();
                _builder.append("\t\t\t");
                _builder.append("return true;");
                _builder.newLine();
                _builder.append("\t\t");
                _builder.append("if (other == null)");
                _builder.newLine();
                _builder.append("\t\t\t");
                _builder.append("return false;");
                _builder.newLine();
                _builder.append("\t\t");
                _builder.append("if (internalID != other.internalID)");
                _builder.newLine();
                _builder.append("\t\t\t");
                _builder.append("return false;");
                _builder.newLine();
                _builder.append("\t\t");
                _builder.append("if (offset != other.offset)");
                _builder.newLine();
                _builder.append("\t\t\t");
                _builder.append("return false;");
                _builder.newLine();
                _builder.append("\t\t");
                _builder.append("if (fillValue != other.fillValue)");
                _builder.newLine();
                _builder.append("\t\t\t");
                _builder.append("return false;");
                _builder.newLine();
                _builder.append("\t\t");
                _builder.append("return true;");
                _builder.newLine();
                _builder.append("\t");
                _builder.append("}");
                _builder.newLine();
                _builder.append("}");
                _builder.newLine();
                _builder.newLine();
            }
        }
        _builder.append("class ");
        _builder.append(this.unitName, "");
        _builder.append(" extends DartInterpreter{");
        _builder.newLineIfNotEmpty();
        {
            if (this.hasClock) {
                _builder.append("\t");
                _builder.append("List<RegUpdate> _regUpdates=[];");
                _builder.newLine();
            }
        }
        _builder.append("\t");
        _builder.newLine();
        _builder.append("\t");
        _builder.append("Map<String, int> _varIdx={");
        _builder.newLine();
        {
            boolean _hasElements = false;
            for (final VariableInformation v : this.em.variables) {
                if (!_hasElements) {
                    _hasElements = true;
                } else {
                    _builder.appendImmediate(",", "\t\t");
                }
                _builder.append("\t\t");
                _builder.append("\"");
                String _replaceAll = v.name.replaceAll("[\\$]", "\\\\\\$");
                _builder.append(_replaceAll, "\t\t");
                _builder.append("\": ");
                int _varIdx = this.getVarIdx(v, this.purgeAliases);
                _builder.append(_varIdx, "\t\t");
                _builder.newLineIfNotEmpty();
            }
        }
        _builder.append("\t");
        _builder.append("};");
        _builder.newLine();
        _builder.append("\t");
        _builder.newLine();
        _builder.append("\t");
        _builder.append("List<String> get names=>_varIdx.keys.toList();");
        _builder.newLine();
        _builder.append("\t");
        _builder.newLine();
        {
            if (this.hasClock) {
                _builder.append("\t");
                _builder.append(this.unitName, "\t");
                _builder.append("(this._");
                _builder.append(CommonCodeGenerator.DISABLE_EDGES.name, "\t");
                _builder.append(", this._");
                _builder.append(CommonCodeGenerator.DISABLE_REG_OUTPUTLOGIC.name, "\t");
                _builder.append(");");
                _builder.newLineIfNotEmpty();
            } else {
                _builder.append("\t");
                _builder.append(this.unitName, "\t");
                _builder.append("(bool disableEdges, bool disabledRegOutputlogic) {}");
                _builder.newLineIfNotEmpty();
            }
        }
        {
            if (this.hasClock) {
                _builder.append("\t");
                _builder.append("bool _skipEdge(int local) {");
                _builder.newLine();
                _builder.append("\t");
                _builder.append("\t");
                _builder.append("int dc = local >> ");
                _builder.append(DartCodeGenerator.epsWidth, "\t\t");
                _builder.append(";");
                _builder.newLineIfNotEmpty();
                _builder.append("\t");
                _builder.append("\t");
                _builder.append("// Register was updated in previous delta cylce, that is ok");
                _builder.newLine();
                _builder.append("\t");
                _builder.append("\t");
                _builder.append("if (dc < deltaCycle)");
                _builder.newLine();
                _builder.append("\t");
                _builder.append("\t\t");
                _builder.append("return false;");
                _builder.newLine();
                _builder.append("\t");
                _builder.append("\t");
                _builder.append("// Register was updated in this delta cycle but it is the same eps,");
                _builder.newLine();
                _builder.append("\t");
                _builder.append("\t");
                _builder.append("// that is ok as well");
                _builder.newLine();
                _builder.append("\t");
                _builder.append("\t");
                _builder.append("if ((dc == _deltaCycle) && ((local & ");
                BigInteger _calcMask = this.calcMask(DartCodeGenerator.epsWidth);
                CharSequence _constant = this.constant(_calcMask, true);
                _builder.append(_constant, "\t\t");
                _builder.append(") == _epsCycle))");
                _builder.newLineIfNotEmpty();
                _builder.append("\t");
                _builder.append("\t\t");
                _builder.append("return false;");
                _builder.newLine();
                _builder.append("\t");
                _builder.append("\t");
                _builder.append("// Don\'t update");
                _builder.newLine();
                _builder.append("\t");
                _builder.append("\t");
                _builder.append("return true;");
                _builder.newLine();
                _builder.append("\t");
                _builder.append("}");
                _builder.newLine();
                _builder.append("\t");
                _builder.append("void _updateRegs() {");
                _builder.newLine();
                _builder.append("\t");
                _builder.append("\t");
                _builder.append("for (RegUpdate reg in _regUpdates) {");
                _builder.newLine();
                _builder.append("\t");
                _builder.append("\t\t");
                _builder.append("switch (reg.internalID) {");
                _builder.newLine();
                _builder.append("\t");
                _builder.append("\t\t\t");
                CharSequence _updateRegCases = this.updateRegCases();
                _builder.append(_updateRegCases, "\t\t\t\t");
                _builder.newLineIfNotEmpty();
                _builder.append("\t");
                _builder.append("\t\t");
                _builder.append("}");
                _builder.newLine();
                _builder.append("\t");
                _builder.append("\t");
                _builder.append("}");
                _builder.newLine();
                _builder.append("\t");
                _builder.append("}");
                _builder.newLine();
            }
        }
        _builder.append("\t");
        _builder.append("int _srl(int val, int shiftBy, int width){");
        _builder.newLine();
        _builder.append("\t  ");
        _builder.append("if (val>=0)");
        _builder.newLine();
        _builder.append("\t    ");
        _builder.append("return val>>shiftBy;");
        _builder.newLine();
        _builder.append("\t  ");
        _builder.append("int opener=1<<(width);");
        _builder.newLine();
        _builder.append("\t  ");
        _builder.append("int opened=(val - opener) & (opener - 1);");
        _builder.newLine();
        _builder.append("\t  ");
        _builder.append("return (opened>>shiftBy);");
        _builder.newLine();
        _builder.append("\t");
        _builder.append("}");
        _builder.newLine();
        _builder.append("\t");
        _builder.append("int _signExtend(int val, int width) {");
        _builder.newLine();
        _builder.append("\t  ");
        _builder.append("var msb=(1<<(width-1));");
        _builder.newLine();
        _builder.append("\t  ");
        _builder.append("var mask=(1<<width)-1;");
        _builder.newLine();
        _builder.append("\t  ");
        _builder.append("var twoComplement = -val;");
        _builder.newLine();
        _builder.append("\t  ");
        _builder.append("if ((val&msb)==0){");
        _builder.newLine();
        _builder.append("\t    ");
        _builder.append("//The MSB is not set, but the stored sign is negative");
        _builder.newLine();
        _builder.append("\t    ");
        _builder.append("if (val>=0)");
        _builder.newLine();
        _builder.append("\t      ");
        _builder.append("return val;");
        _builder.newLine();
        _builder.append("\t    ");
        _builder.append("return twoComplement&mask;");
        _builder.newLine();
        _builder.append("\t  ");
        _builder.append("}");
        _builder.newLine();
        _builder.append("\t  ");
        _builder.append("if (val<0)");
        _builder.newLine();
        _builder.append("\t    ");
        _builder.append("return val;");
        _builder.newLine();
        _builder.append("\t  ");
        _builder.append("return -(twoComplement&mask);");
        _builder.newLine();
        _builder.append("\t");
        _builder.append("}");
        _builder.newLine();
        return _builder;
    }

    public CharSequence getImports(final boolean usePackageImport) {
        StringConcatenation _builder = new StringConcatenation();
        {
            if (this.hasClock) {
                _builder.append("import \'dart:collection\';");
                _builder.newLine();
            }
        }
        _builder.append("import \'dart:typed_data\';");
        _builder.newLine();
        _builder.append("import \'dart:isolate\';");
        _builder.newLine();
        {
            if (usePackageImport) {
                _builder.append("import \'package:pshdl_api/simulation_comm.dart\';");
                _builder.newLine();
            } else {
                _builder.append("import \'../simulation_comm.dart\';");
                _builder.newLine();
            }
        }
        return _builder;
    }

    protected CharSequence stageMethodsHeader(final int stage, final int stageCosts, final boolean constant) {
        StringConcatenation _builder = new StringConcatenation();
        _builder.append("void _");
        CharSequence _stageMethodName = this.stageMethodName(stage, constant);
        _builder.append(_stageMethodName, "");
        _builder.append("(){");
        _builder.newLineIfNotEmpty();
        return _builder;
    }

    protected CharSequence assignNextTime(final VariableInformation nextTime,
            final CharSequence currentProcessTime) {
        StringConcatenation _builder = new StringConcatenation();
        _builder.append(nextTime.name, "");
        _builder.append("=Math.min(");
        _builder.append(nextTime.name, "");
        _builder.append(", ");
        _builder.append(currentProcessTime, "");
        _builder.append(");");
        return _builder;
    }

    protected CharSequence callMethod(final CharSequence methodName, final CharSequence... args) {
        StringConcatenation _builder = new StringConcatenation();
        _builder.append("_");
        _builder.append(methodName, "");
        _builder.append("(");
        {
            boolean _tripleNotEquals = (args != null);
            if (_tripleNotEquals) {
                {
                    boolean _hasElements = false;
                    for (final CharSequence arg : args) {
                        if (!_hasElements) {
                            _hasElements = true;
                        } else {
                            _builder.appendImmediate(",", "");
                        }
                        _builder.append(arg, "");
                    }
                }
            }
        }
        _builder.append(")");
        return _builder;
    }

    protected CharSequence callRunMethod() {
        StringConcatenation _builder = new StringConcatenation();
        _builder.append("run();");
        _builder.newLine();
        return _builder;
    }

    protected CharSequence checkTestbenchListener() {
        StringConcatenation _builder = new StringConcatenation();
        CharSequence _indent = this.indent();
        _builder.append(_indent, "");
        _builder.append("if (listener!=null && !listener.nextStep(");
        VariableInformation _varByName = this.varByName("$time");
        CharSequence _idName = this.idName(_varByName, true, CommonCodeGenerator.NONE);
        _builder.append(_idName, "");
        _builder.append(", stepCount))");
        _builder.newLineIfNotEmpty();
        CharSequence _indent_1 = this.indent();
        _builder.append(_indent_1, "");
        _builder.append("\tbreak;");
        _builder.newLineIfNotEmpty();
        return _builder;
    }

    protected CharSequence runProcessHeader(final CommonCodeGenerator.ProcessData pd) {
        CharSequence _xblockexpression = null;
        {
            this.indent++;
            StringConcatenation _builder = new StringConcatenation();
            _builder.append("bool _");
            String _processMethodName = this.processMethodName(pd);
            _builder.append(_processMethodName, "");
            _builder.append("() {");
            _builder.newLineIfNotEmpty();
            _xblockexpression = _builder;
        }
        return _xblockexpression;
    }

    protected CharSequence runTestbenchHeader() {
        CharSequence _xblockexpression = null;
        {
            this.indent++;
            StringConcatenation _builder = new StringConcatenation();
            _builder.append("void runTestbench(int maxTime, int maxSteps, ITestbenchStepListener listener) {");
            _builder.newLine();
            _xblockexpression = _builder;
        }
        return _xblockexpression;
    }

    protected CharSequence fillArray(final VariableInformation vi, final CharSequence regFillValue) {
        StringConcatenation _builder = new StringConcatenation();
        CharSequence _idName = this.idName(vi, true, CommonCodeGenerator.NONE);
        _builder.append(_idName, "");
        _builder.append(".fillRange(0, ");
        int _arraySize = this.getArraySize(vi);
        _builder.append(_arraySize, "");
        _builder.append(", ");
        _builder.append(regFillValue, "");
        _builder.append(");");
        return _builder;
    }

    protected CharSequence signExtend(final CharSequence op, final int targetSizeWithType) {
        boolean _isSignedType = this.isSignedType(targetSizeWithType);
        if (_isSignedType) {
            StringConcatenation _builder = new StringConcatenation();
            _builder.append("_signExtend(");
            _builder.append(op, "");
            _builder.append(", ");
            _builder.append((targetSizeWithType >> 1), "");
            _builder.append(")");
            return _builder;
        }
        return op;
    }

    protected CharSequence twoOp(final Frame.FastInstruction fi, final String op, final int targetSizeWithType,
            final int pos, final int leftOperand, final int rightOperand,
            final EnumSet<CommonCodeGenerator.Attributes> attributes, final boolean doMask) {
        boolean _tripleEquals = (fi.inst == Instruction.srl);
        if (_tripleEquals) {
            StringConcatenation _builder = new StringConcatenation();
            _builder.append("_srl(");
            String _tempName = this.getTempName(leftOperand, CommonCodeGenerator.NONE);
            _builder.append(_tempName, "");
            _builder.append(", ");
            String _tempName_1 = this.getTempName(rightOperand, CommonCodeGenerator.NONE);
            _builder.append(_tempName_1, "");
            _builder.append(", ");
            _builder.append(fi.arg1, "");
            _builder.append(")");
            return this.assignTempVar(targetSizeWithType, pos, CommonCodeGenerator.NONE, _builder, true);
        }
        boolean _tripleEquals_1 = (fi.inst == Instruction.div);
        if (_tripleEquals_1) {
            CharSequence _cast = this.getCast(targetSizeWithType);
            final CharSequence assignValue = this.twoOpValue("~/", _cast, leftOperand, rightOperand,
                    targetSizeWithType, attributes);
            return this.assignTempVar(targetSizeWithType, pos, attributes, assignValue, true);
        }
        return super.twoOp(fi, op, targetSizeWithType, pos, leftOperand, rightOperand, attributes, doMask);
    }

    protected CharSequence pow(final Frame.FastInstruction fi, final String op, final int targetSizeWithType,
            final int pos, final int leftOperand, final int rightOperand,
            final EnumSet<CommonCodeGenerator.Attributes> attributes, final boolean doMask) {
        StringConcatenation _builder = new StringConcatenation();
        _builder.append("pow(");
        String _tempName = this.getTempName(leftOperand, CommonCodeGenerator.NONE);
        _builder.append(_tempName, "");
        _builder.append(", ");
        String _tempName_1 = this.getTempName(rightOperand, CommonCodeGenerator.NONE);
        _builder.append(_tempName_1, "");
        _builder.append(")");
        return this.assignTempVar(targetSizeWithType, pos, CommonCodeGenerator.NONE, _builder, true);
    }

    public String getHookName() {
        return "Dart";
    }

    public IOutputProvider.MultiOption getUsage() {
        final Options options = new Options();
        options.addOption("p", "pkg", true,
                "The package the generated source will use. If non is specified the package from the module is used");
        String _hookName = this.getHookName();
        String _plus = ("Options for the " + _hookName);
        String _plus_1 = (_plus + " type:");
        return new IOutputProvider.MultiOption(_plus_1, null, options);
    }

    public List<PSAbstractCompiler.CompileResult> invoke(final CommandLine cli, final ExecutableModel em,
            final Set<Problem> syntaxProblems) throws Exception {
        DartCodeGeneratorParameter _dartCodeGeneratorParameter = new DartCodeGeneratorParameter(em);
        return DartCodeGenerator.doCompile(syntaxProblems, _dartCodeGeneratorParameter);
    }

    public static ArrayList<PSAbstractCompiler.CompileResult> doCompile(final Set<Problem> syntaxProblems,
            final DartCodeGeneratorParameter parameter) {
        final DartCodeGenerator comp = new DartCodeGenerator(parameter);
        final String code = comp.generateMainCode();
        final ArrayList<AuxiliaryContent> sideFiles = Lists.<AuxiliaryContent>newArrayList();
        Iterable<AuxiliaryContent> _auxiliaryContent = comp.getAuxiliaryContent();
        Iterables.<AuxiliaryContent>addAll(sideFiles, _auxiliaryContent);
        String _hookName = comp.getHookName();
        PSAbstractCompiler.CompileResult _compileResult = new PSAbstractCompiler.CompileResult(syntaxProblems, code,
                parameter.em.moduleName, sideFiles, parameter.em.source, _hookName, true);
        return Lists.<PSAbstractCompiler.CompileResult>newArrayList(_compileResult);
    }
}