@Override
 public String trace() {
   String s = "";
   for (int i = 0; i < functions.size(); i++) {
     s += functions.getValue(i).trace();
   }
   return s;
 }
 @Override
 public void compile() {
   Debugger debugContext = DinaCompiler.getDebugger();
   int variablesWithValue = 0;
   int variablesAmount = getVariablesAmount();
   for (int variableIndex = 0; variableIndex < variablesAmount; variableIndex++) {
     Variable variable = getVariable(variableIndex);
     if (variable.getValue() != null) {
       if (constructor == null) {
         constructor = new Function(ParserConstants.CONSTRUCTOR);
         constructor.setStatement(new Block());
         constructor.getStatement().setFunction(constructor);
       }
       Assignment assignment = new Assignment(variable, variable.getValue());
       constructor.getStatement().insertNode(assignment, variablesWithValue);
       variablesWithValue++;
     }
   }
   if (constructor != null) {
     Output.writeSystemInformation(Constants.BEGIN_FUNCTION);
     constructor.compile();
     if (Debugger.DEVELOPMENT_MODE) {
       debugContext.putFunction("<constructor>", constructor.getAddress());
     }
     Output.writeSystemInformation(Constants.END_FUNCTION);
   }
   int functionsAmount = functions.size();
   for (int functionIndex = 0; functionIndex < functionsAmount; functionIndex++) {
     Function function = functions.getValue(functionIndex);
     Output.writeSystemInformation(Constants.BEGIN_FUNCTION);
     function.compile();
     if (Debugger.DEVELOPMENT_MODE) {
       debugContext.putFunction(
           function.getSignatureLabel() + function.getNodeType().getSignature(),
           function.getAddress());
     }
     Output.writeSystemInformation(Constants.END_FUNCTION);
   }
   if (destructor != null) {
     Output.writeSystemInformation(Constants.BEGIN_FUNCTION);
     destructor.compile();
     if (Debugger.DEVELOPMENT_MODE) {
       debugContext.putFunction("<destructor>", destructor.getAddress());
     }
     Output.writeSystemInformation(Constants.END_FUNCTION);
   }
 }
 public void addFunction(Function function) {
   String functionSignature = function.getSignatureLabel();
   if (functions.getValue(functionSignature) != null) {
     throw new DinaException(
         "Функция '" + function.getSignature().toString() + "' уже существует",
         DinaException.COMPILATION_ERROR);
   }
   if (Function.getNativeFunctionsTable().getValue(functionSignature) != null) {
     error(function);
   }
   InternalFunctionContainer functionContainer =
       InternalFunctions.getFunctionContainer(function.getName());
   if (functionContainer != null) {
     if (functionContainer.check(function.getArguments())) {
       error(function);
     }
   }
   functions.put(functionSignature, function);
 }
 public void checkFunctions() {
   Enumeration<Function> en = functions.elements();
   while (en.hasMoreElements()) {
     Function function = (Function) en.nextElement();
     if (function.isForward()) {
       if (!function.isCompleted()) {
         throw new DinaException(
             "Неопределенная функция '" + function.getSignature() + "'",
             DinaException.COMPILATION_ERROR);
       }
     }
   }
 }
 public int getFunctionsAmount() {
   int value = functions.size();
   value += constructor == null ? 0 : 1;
   value += destructor == null ? 0 : 1;
   return value;
 }
 public Function getFunction(String signature) {
   return functions.getValue(signature);
 }