}
public Moment(Subroutine sub) {
m_sub = sub;
m_pos = 1;
s_break = 0;
}
public void GoTo(int to) {
m_pos = to;
}
public void Next() {
m_pos++;
}
public void Run() {
while (m_pos < m_sub.m_count) {
if (s_break == 1)
throw new CalcException("Прервано пользователем");
(m_sub.m_operators[m_pos] as IOperator).Execute(this);
}
}
public void Return() {
m_pos = m_sub.m_count;
}
public IOperator Current {
get { return m_sub.m_operators[m_pos] as IOperator; }
}
}
}
}
using System.Threading;
using interpr.logic;
using interpr.logic.operators;
namespace interpr {
public class Facade {
private static Facade s_instance = null;
public static void Create(IConsole console) {
if (s_instance == null)
s_instance = new Facade(console);
}
public static Facade Instance {
get { return s_instance; }
}
private IConsole m_console;
private InterprEnvironment m_env;
private string m_cmd;
private bool m_doing = false;
private Facade(IConsole console) {
m_console = console;
m_env = InterprEnvironment.Instance;
m_env.CurrentConsole = m_console;
}
public delegate void CommandDoneHandler();
public event CommandDoneHandler Done;
private void ThrStart() {
m_doing = true;
Command cmd;
do {
try {
cmd = LineCompiler.CompileCommand(m_cmd);
}
catch (SyntaxErrorException ex) {
m_env.CurrentConsole.PrintLn("Ошибка : " + ex.Message);
break;
}
try {
cmd.Execute();
}
catch (CalcException ex) {
m_env.CurrentConsole.PrintLn("Ошибка : " + ex.Message);
m_env.CurrentNamespace = m_env.ConsoleNamespace;
break;
}
} while (false);
Done();
m_doing = false;
}
public void ExecuteCommand(string cmd) {
if (m_doing)
throw new OtherException("Error in Bridge.ExecuteCommand()");
m_cmd = cmd;
new Thread(new ThreadStart(ThrStart)).Start();
}
private void DoRestart() {
if (m_doing)
Subroutine.Moment.Break();
while (m_doing) {}
InterprEnvironment.Reset();
m_env = InterprEnvironment.Instance;
m_env.CurrentConsole = m_console;
m_env.LoadSubs();
}
public void Restart() {
new Thread(new ThreadStart(DoRestart)).Start();
}
public bool Busy {
get { return m_doing; }
}
public void SaveVariables() {
m_env.SaveVars();
}
public void LoadSubs() {
m_env.LoadSubs();
}
public ConsoleNamespace.VariableReport[] GetVariables() {
return m_env.GetGlobalVarsList();
}
public string[] GetSubs() {
return m_env.LoadedSubs;
}
public void DeleteVariable(string name) {
m_env.ConsoleNamespace.Remove(name);
}
public bool LoadSub(string name) {
return m_env.LoadSub(name);
}
public void UnloadSub(string name) {
m_env.UnloadSub(name);
}
public bool NotRestored {
get {
return m_env.NotRestored;
}
}
}
}
using System;
using System.ComponentModel;
using System.Drawing;
using System.Windows.Forms;
namespace interpr {
public class SourceBox : UserControl {
private RichTextBox m_tb;
private TextBox m_tb_2;
....................................................................
private int m_curline = 0;//текущаястрока
private int m_lincount = 0;//общеечислострок
private HighlightParser m_hp = new HighlightParser();
private static Font s_nfont =
new Font("Lucida Console", 10, FontStyle.Regular);
private static Font s_cfont =
new Font("Lucida Console", 12, FontStyle.Bold);
private int GetCurrentLine() {
return m_tb.GetLineFromCharIndex(m_tb.SelectionStart);
}
private int GetLinesCount() {
return m_tb.Lines.Length;
}
private String GetLine(int index) {
return m_tb.Lines[index];
}
private void m_tb_KeyPress(object sender, KeyPressEventArgs e) {
if (e.KeyChar == '\r') {
string txt = m_tb.Text;
int i = m_tb.SelectionStart - 2;
int j;
while (i >= 0) {
if (txt[i] == '\n')
return;
else if (txt[i] == '\t') {
j = 0;
while ((i >= 0) && (txt[i] == '\t')) {
j++;
i--;
}
if ((i < 0) || (txt[i] == '\n')) {
m_tb.SelectedText = new String('\t', j);
return;
}
}
i--;
}
}
}
private bool GetLinePos(int index, out int beg, out int len) {
if ((index < 0) || (index >= GetLinesCount())) {
beg = len = 0;
return false;
}
int i;
string[] ls = m_tb.Lines;
beg = 0;
for (i = 0; i < index; i++)
beg += ls[i].Length + 1;
len = ls[index].Length;
return true;
}
private void SelectLine(int index) {
int beg, len;
if (!GetLinePos(index, out beg, out len))
throw new IndexOutOfRangeException();
m_tb.SelectionStart = beg;
m_tb.SelectionLength = len;
}
private void HighlightLine(int index) {
int beg, len;
int curbeg = m_tb.SelectionStart;
int curlen = m_tb.SelectionLength;
GetLinePos(index, out beg, out len);
string str = m_tb.Lines[index];
m_hp.Reset(str);
while (m_hp.HasMore()) {
int tbeg, tlen;
HighlightParser.TokenType type;
m_hp.GetNext(out tbeg, out tlen, out type);
m_tb.SelectionStart = beg + tbeg;
m_tb.SelectionLength = tlen;
switch (type) {
case HighlightParser.TokenType.Comment:
{
m_tb.SelectionColor = Color.DarkGreen;
break;
}
case HighlightParser.TokenType.Identifier:
{
m_tb.SelectionColor = Color.Purple;
break;
}
case HighlightParser.TokenType.Keyword:
{
m_tb.SelectionColor = Color.Blue;
break;
}
case HighlightParser.TokenType.Number:
{
m_tb.SelectionColor = Color.Red;
break;
}
case HighlightParser.TokenType.String:
{
m_tb.SelectionColor = Color.Brown;
break;
}
case HighlightParser.TokenType.Other:
{
m_tb.SelectionColor = Color.Black;
break;
}
}
}
m_tb.SelectionStart = curbeg;
m_tb.SelectionLength = curlen;
}
public enum LineState {
ErrorLine,
CurrentLine,
NormalLine
}
private void ColorLine(int index, LineState state) {
int curbeg = m_tb.SelectionStart;
int curlen = m_tb.SelectionLength;
SelectLine(index);
switch (state) {
case LineState.ErrorLine:
{
m_tb.SelectionColor = Color.Red;
break;
}
case LineState.CurrentLine:
{
m_tb.SelectionFont = s_cfont;
break;
}
case LineState.NormalLine:
{
m_tb.SelectionFont = s_nfont;
HighlightLine(index);
break;
}
}
m_tb.SelectionStart = curbeg;
m_tb.SelectionLength = curlen;
}
private void HighlightText(bool anyway) {
int l = GetCurrentLine();
int lc = GetLinesCount();
if ((l != m_curline) || (lc != m_lincount) || anyway) {
m_tb_2.Focus();
m_curline = l;
m_lincount = lc;
int bi = m_tb.GetCharIndexFromPosition(new Point(0, 0));
int ei = m_tb.GetCharIndexFromPosition(new Point(m_tb.Size));
int bl = m_tb.GetLineFromCharIndex(bi);
int el = m_tb.GetLineFromCharIndex(ei);
if (bl > 0) bl--;
if (el < lc) el++;
for (int i = bl; i < el; i++)
HighlightLine(i);
m_tb.Focus();
}
}
private void m_tb_KeyUp(object sender, KeyEventArgs e) {
HighlightText(false);
}
private void m_tb_MouseUp(object sender, MouseEventArgs e) {
if (e.Button == MouseButtons.Left)
HighlightText(true);
}
public string[] Lines {
get { return (string[]) m_tb.Lines.Clone(); }
}
public bool LoadFile(string filename) {
try {
m_tb.LoadFile(filename, RichTextBoxStreamType.PlainText);
HighlightText(true);
return true;
}
catch {
return false;
}
}
public bool SaveFile(string filename) {
try {
m_tb.SaveFile(filename, RichTextBoxStreamType.PlainText);
return true;
}
catch {
return false;
}
}
public int CurrentLine {
get { return m_tb.GetLineFromCharIndex(m_tb.SelectionStart); }
}
private class HighlightParser {
private char[] m_a;
private int m_len;
private int m_cur;
public enum TokenType {
String,
Number,
Keyword,
Comment,
Identifier,
Other
}
public void Reset(string str) {
m_a = str.ToCharArray();
m_len = str.Length;
m_cur = 0;
while ((m_cur < m_len) && Char.IsWhiteSpace(m_a[m_cur]))
m_cur++;
}
public bool HasMore() {
return m_cur < m_len;
}
private bool IsKeyword(string str) {
return
(str == "if") ||
(str == "else") ||
(str == "elseif") ||
(str == "endif") ||
(str == "while") ||
(str == "loop") ||
(str == "return") ||
(str == "result") ||
(str == "call") ||
(str == "print") ||
(str == "println") ||
(str == "readln") ||
(str == "clear") ||
(str == "for") ||
(str == "next") ||
(str == "error");
}
public void GetNext(out int beg, out int len, out TokenType type) {
if (m_cur >= m_len)
throw new IndexOutOfRangeException();
beg = m_cur;
if (m_a[m_cur] == '\"') {
m_cur++;
while ((m_cur < m_len) && (m_a[m_cur] != '\"'))
m_cur++;
if (m_cur < m_len)
m_cur++;
len = m_cur - beg;
type = TokenType.String;
}
else if (isL(m_a[m_cur])) {
m_cur++;
while ((m_cur < m_len) && isLD(m_a[m_cur]))
m_cur++;
len = m_cur - beg;
if (IsKeyword(new string(m_a, beg, len)))
type = TokenType.Keyword;
else
type = TokenType.Identifier;
}
else if (m_a[m_cur] == '#') {
len = m_len - m_cur;
m_cur = m_len;
type = TokenType.Comment;
}
else if (m_a[m_cur] == '.') {
if (GetNumber()) {
len = m_cur - beg;
type = TokenType.Number;
}
else {
m_cur = beg + 1;
len = 1;
type = TokenType.Other;
}
}
else if (char.IsDigit(m_a[m_cur])) {
GetNumber();
len = m_cur - beg;
type = TokenType.Number;
}
else {
m_cur++;
len = 1;
type = TokenType.Other;
}
while ((m_cur < m_len) && Char.IsWhiteSpace(m_a[m_cur]))
m_cur++;
}
private bool GetNumber() {
if (!((m_a[m_cur] == '.') || char.IsDigit(m_a[m_cur])))
return false;
while ((m_cur < m_len) && char.IsDigit(m_a[m_cur]))
m_cur++;
if (m_cur == m_len)
return true;
else if (m_a[m_cur] == '.') {
m_cur++;
while ((m_cur < m_len) && char.IsDigit(m_a[m_cur]))
m_cur++;
if (m_cur == m_len)
return true;
else if ((m_a[m_cur] == 'e') || (m_a[m_cur] == 'E')) {
int p1 = m_cur;
m_cur++;
if (m_cur == m_len) {
m_cur = p1;
return true;
}
else if ((m_a[m_cur] == '-') || (m_a[m_cur] == '+')) {
m_cur++;
if ((m_cur == m_len) || !char.IsDigit(m_a[m_cur])) {
m_cur = p1;
return true;
}
while ((m_cur < m_len) && char.IsDigit(m_a[m_cur]))
m_cur++;
return true;
}
else if (char.IsDigit(m_a[m_cur])) {
while ((m_cur < m_len) && char.IsDigit(m_a[m_cur]))
m_cur++;
return true;
}
else {
m_cur = p1;
return true;
}
}
else
return true;
}
else if ((m_a[m_cur] == 'e') || (m_a[m_cur] == 'E')) {
int p1 = m_cur;
m_cur++;
if (m_cur == m_len) {
m_cur = p1;
return true;
}
else if ((m_a[m_cur] == '-') || (m_a[m_cur] == '+')) {
m_cur++;
if ((m_cur == m_len) || !char.IsDigit(m_a[m_cur])) {
m_cur = p1;
return true;
}
while ((m_cur < m_len) && char.IsDigit(m_a[m_cur]))
m_cur++;
return true;
}
else if (char.IsDigit(m_a[m_cur])) {
while ((m_cur < m_len) && char.IsDigit(m_a[m_cur]))
m_cur++;
return true;
}
else {
m_cur = p1;
return true;
}
}
else
return true;
}
private static bool isLD(char c) {
return ((c >= 'a') && (c <= 'z')) || ((c >= 'A') && (c <= 'Z')) || (c == '0')
|| ((c >= '1') && (c <= '9')) || (c == '_');
}
private static bool isL(char c) {
return ((c >= 'a') && (c <= 'z')) || ((c >= 'A') && (c <= 'Z')) || (c == '_');
}
}
}
}
using System;
using System.ComponentModel;
using System.Windows.Forms;
namespace interpr {
public class Form1 : Form {
private Panel panel1;
private Button button1;
private Button button2;
private Button button3;
private Button button4;
private Button button5;
private ConsoleBox consoleBox1;
private Facade m_fasade;
private void Form1_Load(object sender, EventArgs e) {
Facade.Create(consoleBox1);
m_fasade = Facade.Instance;
if (m_fasade.NotRestored) {
MessageBox.Show("Ошибка! Переменные не были успешно восстановлены.");
}
m_fasade.Done += new Facade.CommandDoneHandler(EndExec);
m_fasade.LoadSubs();
consoleBox1.Prompt();
}
private void EndExec() {
consoleBox1.Prompt();
}
private void button1_Click(object sender, EventArgs e) {
if (m_fasade.Busy) {
MessageBox.Show("Не могу открыть окно функций во время выполнения комманды!");
return;
}
FunctionsForm ff = new FunctionsForm(m_fasade);
ff.ShowDialog();
EditorForm ef = ff.LastOpenedEditorForm;
if (ef != null) {
ef.Activate();
ff.SetLastEditorFormNull();
}
else
consoleBox1.Focus();
}
private void button2_Click(object sender, EventArgs e) {
if (m_fasade.Busy) {
MessageBox.Show("Не могу открыть окно переменных во время выполнения комманды!");
return;
}
VariablesForm vf = new VariablesForm(m_fasade);
vf.ShowDialog();
consoleBox1.Focus();
}
private void consoleBox1_GetCommand(object sender, ConsoleBoxGetCommandEventArgs e) {
if (e.Command.Length > 0)
m_fasade.ExecuteCommand(e.Command);
else
consoleBox1.Prompt();
}
private void button3_Click(object sender, EventArgs e) {
m_fasade.Restart();
if (m_fasade.NotRestored) {
MessageBox.Show("Ошибка! Переменные не были успешно восстановлены.");
}
consoleBox1.Focus();
}
private void button5_Click(object sender, EventArgs e) {
if (m_fasade.Busy) {
MessageBox.Show("Не могу сохранить переменные во время выполнения программы");
return;
}
m_fasade.SaveVariables();
consoleBox1.Focus();
}
private void Form1_Closing(object sender, CancelEventArgs e) {
if (EditorForm.ThereAreOpened()) {
MessageBox.Show("Сначалазакройтевсеокнаредакторакода.");
e.Cancel = true;
return;
}
m_fasade.SaveVariables();
}
private void button4_Click(object sender, EventArgs e) {
this.Close();
}
}
}
1. А. Ахо, Дж. Хопкрофт, Д. Ульман. Структуры данных и алгоритмы – М. «Вильямс», 2003.
2. Э. Гамма, Р. Хелм, Р. Джонсон, Дж. Влиссидес. Приемы объектно-ориентированного проектирования: паттерны проектирования – СПб., «Питер», 2001.
3. Д. Грис. Конструирование компиляторов для цифровых вычислительных машин – М. «Мир», 1975.
4. Г. Корнелл, Дж. Моррисон. Программирование на VB.NET. Учебный курс – СПб., «Питер», 2002.
5. Э. Троелсен. C# и платформа .NET – СПб., «Питер», 2004.
6. MSDN Library – April 2003.