скачать рефераты
  RSS    

Меню

Быстрый поиск

скачать рефераты

скачать рефератыКурсовая работа: Интерактивный интерпретатор

Но, пожалуй, наиболее важным из методов класса Facade является ExecuteCommand() – выполнить команду. Он вызывается в обработчике события GetCommand элемента ConsoleBox на главной форме. В нем в отдельном потоке запускается на выполнение частный метод ThrStart(), в котором введенная с консоли команда сначала «компилируется» методом LineCompiler.CompileCommand(), затем  выполняется, по окончании чего генерируется событие Facade.Done(), в обработчике которого консоль переводится в состояние ожидания следующей команды методом ConsoleBox.Prompt(). И «компиляция» и выполнение команды производятся в блоках try, в случае возникновения исключения на консоль выдается соответствующее сообщение об ошибке.

Необходимость выполнять команды в отдельном потоке связана с тем, что только в этом случае можно прервать зациклившуюся или долго работающую пользовательскую функцию без аварийного завершения интерпретатора. Для перезапуска интерпретатора, возможно, с прерыванием работы пользовательской функции, предназначен метод Facade.Restart(). В нем в отдельном потоке запускается метод DoRestart(), в котором выполняются следующие действия. Во-первых, если в данный момент времени выполняется команда, то вызывается статический метод Subroutine.Moment.Break().В нем с помощью метода Interlocked.Exchange() (безопасное при параллельном выполнении присваивание) статическому полю Subroutine.Moment.s_break присваивается значение 1. На каждой итерации цикла в методе Subroutine.Moment.Run(), помимо выполнения очередного оператора функции, проверяется значение этого поля. Если оно равно единице, то генерируется исключение CalcException, то есть выполнение команды завершается с ошибкой времени выполнения. После вызова Subroutine.Moment.Break() в методе DoRestart() следует цикл без тела, который выполняется до тех пор, пока выполнение команды не будет завершено, чего, конечно же, не приходится долго ждать. После того, как выполнение будет прервано, производится повторная инициализация, аналогичная происходящей при запуске интерпретатора.

Для реализации многопоточности используется стандартный класс System.Threading.Thread. Его конструктору передается один параметр типа делегата System.Threading.ThreadStart (процедура без параметров). Метод, на который указывает этот делегат, начинает выполняться в отдельном потоке при вызове метода Start() объекта потока. Когда метод, запущенный в потоке, возвращается, выполнение потока завершается. Повторное использование того же объекта класса Thread невозможно, его нужно создавать заново. При использовании многопоточности следует принимать ряд мер предосторожности для обеспечения безопасного доступа к общим данным. Например, присваивание значений переменным, используемым несколькими потоками, по возможности следует производить с помощью метода Interlocked.Exchange, который гарантирует атомарность операции, то есть то, что ее выполнение не будет прервано до полного завершения для передачи управления другому потоку. Также обращаться к методам и свойствам элементов графического интерфейса пользователя  напрямую можно только из того же потока, в котором они были созданы. Если необходимо воздействовать на графический интерфейс пользователя из других потоков, то это следует делать в методе (процедуре без параметров), вызываемом с помощью делегата System.Windows.Forms.MethodInvoker. В языке C# имеются и другие средства синхронизации работы потоков, которые не используются в данном интерпретаторе.


Заключение

Мною выполнен интерпретатор несложного языка программирования. Интерпретатор работает в интерактивном режиме, выполняя команды, вводимые с консоли, которые могут содержать вызовы пользовательских функций (подпрограмм). Пользовательские функции могут содержать структурные конструкции – циклы, ветвления, вызовы других функций (возможна и рекурсия). Возможна работа с числовыми и строковыми данными, а также с одномерными массивами. Имеется достаточно большое число встроенных математических и других функций. Предварительного объявления переменных не требуется, синтаксис математический выражений – традиционный для языков высокого уровня. Это делает интерпретатор удобным в использовании. Данный интерпретатор может применяться как в учебных целях, например, для обучения школьников основам программирования, так и качестве «программируемого микрокалькулятора» для практических расчетов, сложность которых не требует применения специфического программного обеспечения.


Приложение. Исходный текст (сокращенно).

Ввиду большого объема исходного кода, приведены лишь наиболее важные его фрагменты.

1. Класс VarBase.

using System;

using System.IO;

namespace interpr.logic.vartypes {

         public abstract class VarBase : ICloneable , IComputable {

                   public bool IsArray() {

                            return (this is ArrayVar);

                   }

                   public bool IsNum() {

                            return (this is NumVar);

                   }

                   public bool IsString() {

                            return (this is StringVar);

                   }

                   public bool IsInt() {

                            return (this is IntVar);

                   }

                   public bool IsReal() {

                            return (this is RealVar);

                   }

                   public bool IsSingle() {

                            return (this is SingleVar);

                   }

                   public virtual VarBase Compute() {

                            return this.Clone() as VarBase;

                   }

                   public abstract System.Object Clone();

                   public override abstract string ToString();

                   public abstract void Serialise(BinaryWriter bw);

         }

}

2. Класс ArrayVar.

using System.Collections;

using System.IO;

namespace interpr.logic.vartypes {

         public class ArrayVar : VarBase {

                   public virtual IntVar Size {

                            get { return new IntVar(m_list.Count); }

                   }

                   private ArrayList m_list;

                   public ArrayVar() {

                            m_list = new ArrayList();

                   }

                   public int GetSize() {

                            return m_list.Count;

                   }

                   public void setAt(int index, SingleVar var) {

                            if (var == null) {

                                      throw new CalcException("Ошибка");

                            }

                            if (index < 0)

                                      throw new CalcException("Индекс не может быть отрицательным");

                            for (int ind = index, s = m_list.Count; ind >= s; ind--)

                                      m_list.Add(null);

                            m_list[index] = var.Clone();

                   }

                   public SingleVar getAt(int index) {

                            if (index < 0)

                                      throw new CalcException("Индекс не может быть отрицательным");

                            if (index >= m_list.Count)

                                      throw new CalcException("Выход за пределы массива");

                            else

                                      return (SingleVar) m_list[index];

                   }

                   public SingleVar this[int index] {

                            get { return getAt(index); }

                            set { setAt(index, value); }

                   }

                   public IntVar IsElementDefined(int index) {

                            bool result = index>=0;

                            result = result&&(index<m_list.Count);

                            result = result&&(m_list[index]!=null);

                            return new IntVar(result);

                   }

                   public override System.Object Clone() {

                            ArrayVar res = new ArrayVar();

                            int li = 0;

                            SingleVar e = null;

                            while (li < m_list.Count) {

                                      e = (SingleVar) m_list[li++];

                                      if (e != null)

                                               res.m_list.Add(e.Clone());

                                      else

                                               res.m_list.Add(null);

                            }

                            return res;

                   }

                   public override void Serialise(BinaryWriter bw) {

                            bw.Write('a');

                            int size = m_list.Count;

                            bw.Write(size);

                            for (int i = 0; i < size; i++) {

                                      if (m_list[i] == null)

                                               bw.Write('n');

                                      else

                                               (m_list[i] as VarBase).Serialise(bw);

                            }

                  }

                   public override System.String ToString() {

                            System.String res = "[";

                            int li = 0;

                            SingleVar e = null;

                            if (li < m_list.Count) {

                                      e = (SingleVar) m_list[li++];

                                      if (e != null) {

                                               res += e.ToString();

                                      }

                                      else

                                               res += "-";

                            }

                            while (li < m_list.Count) {

                                      e = (SingleVar) m_list[li++];

                                      if (e != null) {

                                               res += ", " + e.ToString();

                                      }

                                      else

                                               res += ", -";

                            }

                            return res + "]";

                   }

         }

}

3. Класс InterprEnvironment.

using System;

using System.Collections;

using System.IO;

namespace interpr.logic {

         public class InterprEnvironment {

                   private SubroutinesManager m_subsman = null;

                   private ConsoleNamespace m_console_vars;

                   private bool m_not_restored = false;

                   public bool NotRestored {

                            get { return m_not_restored; }

                   }

                   public ConsoleNamespace ConsoleNamespace {

                            get { return m_console_vars; }

                   }

                   public ConsoleNamespace.VariableReport[] GetGlobalVarsList() {

                            return m_console_vars.GetVariableList();

                   }

                   private InterprEnvironment() {

                            m_current_namespace = new ConsoleNamespace();

                            m_console_vars = m_current_namespace as ConsoleNamespace;

                            m_not_restored = false;

                            try {

                                      m_console_vars.Restore();

                            } catch {

                                      m_not_restored = true;

                                      m_console_vars = new ConsoleNamespace();

                                      m_current_namespace = m_console_vars;

                            }

                   }

                   public void LoadSubs() {

                            if (m_current_console == null)

                                      throw new OtherException("Error in Environment.LoadSubs()");

                            s_instance.m_subsman = SubroutinesManager.GetInstance();

                            s_instance.m_subsman.ReloadAll();

                   }

                   private static InterprEnvironment s_instance = null;

                   public static InterprEnvironment Instance {

                            get {

                                      if (s_instance == null)

                                               s_instance = new InterprEnvironment();

                                      return s_instance;

                            }

                   }

                   public static void Reset() {

                            s_instance = new InterprEnvironment();

                   }

                   public void SaveVars() {

                            m_console_vars.Save();

                   }

                   public bool LoadSub(string name) {

                            return m_subsman.Load(name);

                   }

                   private Namespace m_current_namespace = null;

                   public Namespace CurrentNamespace {

                            get { return m_current_namespace; }

                            set { m_current_namespace = value; }

                   }

                   private IConsole m_current_console = null;

                   public IConsole CurrentConsole {

                            get { return m_current_console; }

                            set { m_current_console = value; }

                   }

                   public Operation GetFunction(string name) {

                            if (name == "abs")

                                      return Operation.ABS;

                                    

                            ...........................

                            if (name == "size")

                                      return Operation.SIZE;

                            return new SubName(name);

                   }

                   public string[] LoadedSubs {

                            get { return m_subsman.SubroutineNames; }

                   }

                   private class SubroutinesManager {

                            private ArrayList m_subs = new ArrayList();

                            private ArrayList m_names = new ArrayList();

                            private SubroutinesManager() {

                                      DirectoryInfo di =

                                               new DirectoryInfo(Directory.GetCurrentDirectory() + @"\subroutines");

                                      if (!di.Exists) {

                                               di.Create();

                                      }

                            }

                            public bool Load(string name) {

                                      FileInfo fi = new FileInfo(Directory.GetCurrentDirectory() + @"\subroutines\" + name);

                                      if (!fi.Exists)

                                               throw new OtherException("Error in SubroutinesManager.Load()");

                                      return LoadFile(fi);

                            }

Страницы: 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14


Новости

Быстрый поиск

Группа вКонтакте: новости

Пока нет

Новости в Twitter и Facebook

  скачать рефераты              скачать рефераты

Новости

скачать рефераты

© 2010.