/*
Magic IDE
Copyright (C) 2003 Michael Bebenita
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 2
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, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Data;
using Crownwood.Magic;
using Crownwood.Magic.Docking;
using Crownwood.Magic.Common;
using UtilityLibrary.Menus;
using UtilityLibrary.CommandBars;
using UtilityLibrary.WinControls;
using UtilityLibrary.General;
using UtilityLibrary.Win32;
using UtilityLibrary.Collections;
using System.Diagnostics;
using System.IO;
using ICSharpCode.TextEditor;
using System.Runtime.InteropServices;
using Core;
using Core.Compilation;
namespace Magic_IDE
{
public enum IconIndex
{
Project_Explorer = 51,
Object_Explorer = 53,
Parse_Tree = 4,
New_Project = 65,
New_File = 85,
Open_Project = 84,
Open_File = 35,
Save_File = 0,
Save_Files = 1,
Output = 52,
Build = 31,
File = 88,
Project = 51,
Terminal = 7,
NonTerminal = 6,
Module = 6,
Structure = 8,
Function = 12,
Variable = 16,
Expression = 41,
Body = 47
}
/// <summary>
/// Summary description for Form1.
/// </summary>
public class IDE : System.Windows.Forms.Form
{
[DllImport("User32.Dll")]
private static extern int SendMessage(IntPtr hWnd,int Msg,int wParam,int lParam);
private System.ComponentModel.IContainer components;
public IDE()
{
//
// Required for Windows Form Designer support
//
InitializeComponent();
InitializeImageLists();
InitializeDockingSystem();
InitializeMenu();
InitializeCompiler();
UpdateUIState();
}
/// <summary>
/// Clean up any resources being used.
/// </summary>
protected override void Dispose( bool disposing )
{
if( disposing )
{
if (components != null)
{
components.Dispose();
}
}
base.Dispose( disposing );
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
//
// IDE
//
this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);
this.ClientSize = new System.Drawing.Size(688, 422);
this.Name = "IDE";
this.Text = "Sharp IDE";
this.Closing += new System.ComponentModel.CancelEventHandler(this.IDE_Closing);
}
#endregion
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main()
{
//Application.Run(new Test());
Application.Run(new IDE());
}
private DockingManager m_Docker = null;
private TreeView m_tvProjectExplorer = null;
private TreeView m_tvObjectExplorer = null;
private TreeView m_tvParseTree = null;
private TreeView m_tvSyntaxTree = null;
private RichTextBox m_Output = null;
private Crownwood.Magic.Controls.TabControl m_Files = null;
private StatusBar m_Status = null;
private ImageList m_ImageList = null;
private Language m_Language = null;
private void InitializeCompiler()
{
m_Language = Language.FromFile("Sharp.cgt");
}
private void InitializeImageLists()
{
Bitmap strip = (Bitmap)Bitmap.FromFile("Images.bmp");
m_ImageList = new ImageList();
m_ImageList.ImageSize = new Size(16,16);
m_ImageList.TransparentColor = Color.FromArgb(0,255,0);
m_ImageList.Images.AddStrip(strip);
}
Content m_OutputContent = null;
Content m_ProjectExplorerContent = null;
Content m_ObjectExplorerContent = null;
Content m_ParseTreeContent = null;
Content m_SyntaxTreeContent = null;
private void InitializeDockingSystem()
{
//
// Setup File Tabs
//
m_Files = new Crownwood.Magic.Controls.TabControl();
m_Files.Appearance = Crownwood.Magic.Controls.TabControl.VisualAppearance.MultiDocument;
m_Files.Dock = DockStyle.Fill;
m_Files.Style = Crownwood.Magic.Common.VisualStyle.IDE;
m_Files.IDEPixelBorder = true;
m_Files.ClosePressed += new EventHandler(OnFilesClosed);
m_Files.PageGotFocus += new EventHandler(OnPageGotFocus);
Controls.Add(m_Files);
m_Docker = new DockingManager(this, Crownwood.Magic.Common.VisualStyle.IDE);
//
// Setup Output
//
m_Output = new RichTextBox();
m_Output.WordWrap = false;
m_Output.ScrollBars = RichTextBoxScrollBars.Both;
m_Output.Font = new Font("Courier New",8);
m_Output.BackColor = Color.Black;
m_Output.ForeColor = Color.GreenYellow;
m_OutputContent = m_Docker.Contents.Add(
m_Output, "Output");
m_OutputContent.ImageList = m_ImageList;
m_OutputContent.ImageIndex = (int)IconIndex.Output;
WindowContent bottomWindow = m_Docker.AddContentWithState(
m_OutputContent, Crownwood.Magic.Docking.State.DockBottom) as WindowContent;
//
// Setup Project and Object explorers.
//
// Project Explorer
m_tvProjectExplorer = new TreeView();
m_tvProjectExplorer.ImageList = m_ImageList;
m_tvProjectExplorer.DoubleClick += new EventHandler(OnProjectExplorerDoubleClick);
m_ProjectExplorerContent = m_Docker.Contents.Add(
m_tvProjectExplorer, "Project Explorer");
m_ProjectExplorerContent.ImageList = m_ImageList;
m_ProjectExplorerContent.ImageIndex = (int)IconIndex.Project_Explorer;
WindowContent leftWindow = m_Docker.AddContentWithState(
m_ProjectExplorerContent, Crownwood.Magic.Docking.State.DockLeft) as WindowContent;
// Object Explorer
m_tvObjectExplorer = new TreeView();
m_tvObjectExplorer.ImageList = m_ImageList;
m_ObjectExplorerContent = m_Docker.Contents.Add(
m_tvObjectExplorer, "Object Explorer");
m_ObjectExplorerContent.ImageList = m_ImageList;
m_ObjectExplorerContent.ImageIndex = (int)IconIndex.Object_Explorer;
m_Docker.AddContentToWindowContent(m_ObjectExplorerContent, leftWindow);
// Parse Tree
m_tvParseTree = new TreeView();
m_tvParseTree.ImageList = m_ImageList;
m_ParseTreeContent = m_Docker.Contents.Add(m_tvParseTree,"Parse Tree");
m_ParseTreeContent.ImageList = m_ImageList;
m_ParseTreeContent.ImageIndex = (int)IconIndex.Parse_Tree;
m_Docker.AddContentToWindowContent(m_ParseTreeContent, leftWindow);
// Syntax Tree
m_tvSyntaxTree = new TreeView();
m_tvSyntaxTree.ImageList = m_ImageList;
m_SyntaxTreeContent = m_Docker.Contents.Add(m_tvSyntaxTree,"Syntax Tree");
m_SyntaxTreeContent.ImageList = m_ImageList;
m_SyntaxTreeContent.ImageIndex = (int)IconIndex.Parse_Tree;
m_Docker.AddContentToWindowContent(m_SyntaxTreeContent, leftWindow);
m_Status = new StatusBar();
m_Status.Dock = DockStyle.Bottom;
Controls.Add(m_Status);
m_Docker.InnerControl = m_Files;
m_Docker.OuterControl = m_Status;
m_Docker.HideAllContents();
m_Docker.ShowAllContents();
m_Docker.LoadConfigFromFile("Config.dck");
}
private ReBar m_Toolbars = null;
private ToolBarEx m_Menu = null;
private ToolBarItem m_FileMenu = null;
private MenuItemEx m_New = null;
private MenuItemEx m_NewProject = null;
private MenuItemEx m_NewFile = null;
private MenuItemEx m_OpenProject = null;
private MenuItemEx m_CloseProject = null;
private MenuItemEx m_SaveFile = null;
private MenuItemEx m_SaveAllFiles = null;
private MenuItemEx m_Exit = null;
private ToolBarItem m_ProjectMenu = null;
private MenuItemEx m_AddNewFile = null;
private MenuItemEx m_RemoveFile = null;
private MenuItemEx m_DeleteFile = null;
private ToolBarItem m_ViewMenu = null;
private MenuItemEx m_ViewProjectExplorer = null;
private MenuItemEx m_ViewObjectExplorer = null;
private MenuItemEx m_ViewOutput = null;
private ToolBarItem m_ToolsMenu = null;
private MenuItemEx m_BuildParseTree = null;
private MenuItemEx m_BuildSyntaxTree = null;
private ToolBarEx m_Tools = null;
private ToolBarItem m_NewTool = null;
private MenuItemEx m_NewProjectTool = null;
private MenuItemEx m_NewFileTool = null;
private ToolBarItem m_AddNewFileTool = null;
private ToolBarItem m_SaveFileTool = null;
private ToolBarItem m_SaveAllFilesTool = null;
private ToolBarItem m_BuildTool = null;
private ToolBarEx m_FullScreenTools = null;
private ToolBarItem m_FullScreenTool = null;
private void InitializeMenu()
{
//
// Menu
//
ToolBarEx m_Menu = new ToolBarEx(BarType.MenuBar);
m_Menu.ImageList = m_ImageList;
m_FileMenu = new ToolBarItem("&File");
m_New = new MenuItemEx("&New",null);
m_NewProject = new MenuItemEx("&Project",m_ImageList,(int)IconIndex.New_Project,Shortcut.CtrlShiftN,new EventHandler(OnNewProject));
m_NewFile = new MenuItemEx("&File",m_ImageList,(int)IconIndex.New_File,Shortcut.CtrlN,new EventHandler(OnNewFile));
m_New.MenuItems.Add(m_NewProject);
m_New.MenuItems.Add(m_NewFile);
m_OpenProject = new MenuItemEx("&Open Project",m_ImageList,(int)IconIndex.Open_Project,Shortcut.CtrlO,new EventHandler(OnOpenProject));
m_CloseProject = new MenuItemEx("&Close Project",new EventHandler(OnCloseProject));
m_SaveFile = new MenuItemEx("&Save File",m_ImageList,(int)IconIndex.Save_File,Shortcut.CtrlS ,new EventHandler(OnSaveFile));
m_SaveAllFiles = new MenuItemEx("&Save All",m_ImageList,(int)IconIndex.Save_Files,Shortcut.CtrlShiftS,new EventHandler(OnSaveAllFiles));
m_Exit = new MenuItemEx("&Exit",new EventHandler(OnExit));
m_FileMenu.MenuItems.Add(m_New);
m_FileMenu.MenuItems.Add(m_OpenProject);
m_FileMenu.MenuItems.Add(m_CloseProject);
m_FileMenu.MenuItems.Add(new MenuItemEx("-",null));
m_FileMenu.MenuItems.Add(m_SaveFile);
m_FileMenu.MenuItems.Add(m_SaveAllFiles);
m_FileMenu.MenuItems.Add(new MenuItemEx("-",null));
m_FileMenu.MenuItems.Add(m_Exit);
m_ViewMenu = new ToolBarItem("&View");
m_ViewProjectExplorer = new MenuItemEx("&Project Explorer",m_ImageList,(int)IconIndex.Project_Explorer,Shortcut.CtrlShiftP,new EventHandler(OnView));
m_ViewObjectExplorer = new MenuItemEx("&Object Explorer",m_ImageList,(int)IconIndex.Object_Explorer,Shortcut.CtrlShiftB,new EventHandler(OnView));
m_ViewOutput = new MenuItemEx("&Output",m_ImageList,(int)IconIndex.Output,Shortcut.CtrlShiftO,new EventHandler(OnView));
m_ViewMenu.MenuItems.Add(m_ViewProjectExplorer);
m_ViewMenu.MenuItems.Add(m_ViewObjectExplorer);
m_ViewMenu.MenuItems.Add(m_ViewOutput);
m_ProjectMenu = new ToolBarItem("&Project");
m_ProjectMenu.DropDown += new EventHandler(OnProjectMenuDropDown);
m_AddNewFile = new MenuItemEx("&Add Exisiting File",m_ImageList,(int)IconIndex.New_File,Shortcut.None,new EventHandler(OnAddFile));
m_RemoveFile = new MenuItemEx("&Remove File",new EventHandler(OnRemoveFile),Shortcut.CtrlR);
m_DeleteFile = new MenuItemEx("&Delete File",new EventHandler(OnDeleteFile),Shortcut.CtrlD);
m_ProjectMenu.MenuItems.Add(m_AddNewFile);
m_ProjectMenu.MenuItems.Add(m_RemoveFile);
m_ProjectMenu.MenuItems.Add(m_DeleteFile);
m_ToolsMenu = new ToolBarItem("&Tools");
m_ToolsMenu.DropDown += new EventHandler(OnToolsMenuDropDown);
m_BuildParseTree = new MenuItemEx("Build &Parse Tree",m_ImageList,(int)IconIndex.Parse_Tree,Shortcut.CtrlP,new EventHandler(OnBuildParseTree));
m_BuildSyntaxTree = new MenuItemEx("Build &Syntax Tree",m_ImageList,(int)IconIndex.Parse_Tree,Shortcut.CtrlS,new EventHandler(OnBuildSyntaxTree));
m_ToolsMenu.MenuItems.Add(m_BuildParseTree);
m_ToolsMenu.MenuItems.Add(m_BuildSyntaxTree);
m_Menu.Items.Add(m_FileMenu);
m_Menu.Items.Add(m_ViewMenu);
m_Menu.Items.Add(m_ProjectMenu);
m_Menu.Items.Add(m_ToolsMenu);
//
// Toolbar
//
m_Tools = new ToolBarEx();
m_Tools.ImageList = m_ImageList;
m_NewTool = new ToolBarItem();
m_NewTool.ImageListIndex = (int)IconIndex.New_Project;
m_NewTool.Style = ToolBarItemStyle.DropDownButton;
m_NewTool.DropDown += new EventHandler(OnToolbarDropDown);
m_NewTool.Text = "New";
m_NewProjectTool = new MenuItemEx("&Project",m_ImageList,(int)IconIndex.New_Project,Shortcut.None,new EventHandler(OnNewProject));
m_NewFileTool = new MenuItemEx("&File",m_ImageList,(int)IconIndex.New_File,Shortcut.None,new EventHandler(OnNewFile));
m_Tools.Items.Add(m_NewTool);
m_AddNewFileTool = new ToolBarItem();
m_AddNewFileTool.ImageListIndex = (int)IconIndex.New_File;
m_AddNewFileTool.Style = ToolBarItemStyle.PushButton;
m_AddNewFileTool.Text = "Add Existing File";
m_AddNewFileTool.Click += new EventHandler(OnAddFile);
m_Tools.Items.Add(m_AddNewFileTool);
m_SaveFileTool = new ToolBarItem();
m_SaveFileTool.ImageListIndex = (int)IconIndex.Save_File;
m_SaveFileTool.Style = ToolBarItemStyle.PushButton;
m_SaveFileTool.Text = "Save File";
m_SaveFileTool.Click += new EventHandler(OnSaveFile);
m_Tools.Items.Add(m_SaveFileTool);
m_SaveAllFilesTool = new ToolBarItem();
m_SaveAllFilesTool.ImageListIndex = (int)IconIndex.Save_Files;
m_SaveAllFilesTool.Style = ToolBarItemStyle.PushButton;
m_SaveAllFilesTool.Text = "Save All";
m_SaveAllFilesTool.Click += new EventHandler(OnSaveAllFiles);
m_Tools.Items.Add(m_SaveAllFilesTool);
ToolBarItem separator = new ToolBarItem();
separator.Style = ToolBarItemStyle.Separator;
m_Tools.Items.Add(separator);
m_BuildTool = new ToolBarItem();
m_BuildTool.ImageListIndex = (int)IconIndex.Build;
m_BuildTool.Style = ToolBarItemStyle.PushButton;
m_BuildTool.Click += new EventHandler(OnBuild);
m_BuildTool.Text = "Build";
m_Tools.Items.Add(m_BuildTool);
//
// Full Screen Tools
//
m_FullScreenTools = new ToolBarEx();
m_FullScreenTools.ImageList = m_ImageList;
m_FullScreenTool = new ToolBarItem();
m_FullScreenTool.Style = ToolBarItemStyle.PushButton;
m_FullScreenTool.Text = "Full Screen";
m_FullScreenTool.Click += new EventHandler(OnFullScreenTool);
m_FullScreenTools.Items.Add(m_FullScreenTool);
// ////////////////////////////
m_Toolbars = new ReBar();
m_Toolbars.Bands.Add(m_Menu);
m_Toolbars.Bands.Add(m_Tools);
m_Toolbars.Bands.Add(m_FullScreenTools);
m_Toolbars.Dock = DockStyle.Top;
Controls.Add(m_Toolbars);
}
private void IDE_Closing(object sender, System.ComponentModel.CancelEventArgs e)
{
m_Docker.SaveConfigToFile("Config.dck");
CloseProject();
}
public bool m_bFullScreen = false;
public Content [] m_VisibleContent = null;
private void OnFullScreenTool(object sender, EventArgs e)
{
if(m_bFullScreen)
{
foreach(Content c in m_VisibleContent)
m_Docker.ShowContent(c);
m_bFullScreen = false;
}
else
{
int visible = 0;
foreach(Content c in m_Docker.Contents)
visible = c.Visible ? visible + 1: visible;
m_VisibleContent = new Content [visible];
int index = 0;
foreach(Content c in m_Docker.Contents)
{
if(c.Visible)
{
m_VisibleContent[index] = c;
index ++;
}
}
m_Docker.HideAllContents();
m_bFullScreen = true;
}
}
private void OnView(object sender, EventArgs e)
{
if(sender == m_ViewObjectExplorer)
{
m_Docker.ShowContent(m_ObjectExplorerContent);
}
else if(sender == m_ViewProjectExplorer)
{
m_Docker.ShowContent(m_ProjectExplorerContent);
}
else if(sender == m_ViewOutput)
{
m_Docker.ShowContent(m_OutputContent);
}
}
private void OnToolbarDropDown(object sender, EventArgs e)
{
ToolBarItem item = (ToolBarItem)sender;
ContextMenu cm = new ContextMenu(new MenuItemEx[] {m_NewProjectTool,m_NewFileTool});
Rectangle rc = item.ItemRectangle;
Point pos = new Point(rc.Left, rc.Bottom);
cm.Show(m_Tools, pos);
}
private void WriteAndScroll(RichTextBox textbox, string message)
{
textbox.AppendText(message + "\n");
SendMessage(textbox.Handle,0xB6, 0, 1);
}
// ///////////////////////////////
// ///////////////////////////////
/// <summary>
/// Load project.
/// </summary>
/// <param name="project"></param>
private void LoadProject(Project project)
{
m_Project = project;
//
// Load project in project explorer.
//
m_tvProjectExplorer.HideSelection = false;
m_tvProjectExplorer.Nodes.Clear();
if(m_Project == null)
return;
TreeNode tnProject = new TreeNode(m_Project.Name,(int)IconIndex.Project,(int)IconIndex.Project );
tnProject.Tag = m_Project;
m_Project.Node = tnProject;
foreach(ProjectFile file in m_Project.ProjectFiles)
{
TreeNode tnFile = new TreeNode(System.IO.Path.GetFileName(file.Path),(int)IconIndex.File,(int)IconIndex.File);
tnFile.Tag = file;
file.Node = tnFile;
tnProject.Nodes.Add(tnFile);
}
m_tvProjectExplorer.Nodes.Add(tnProject);
m_tvProjectExplorer.ExpandAll();
m_Project.ProjectFiles.Added += new ProjectFileEventHandler(OnProjectFileAdded);
m_Project.ProjectFiles.Removed += new ProjectFileEventHandler(OnProjectFileRemoved);
//
// TODO: Open opened files.
//
m_ProjectFiles = new ProjectFileCollection();
m_ProjectFiles.Added += new ProjectFileEventHandler(OnProjectFileOpened);
m_ProjectFiles.Removed += new ProjectFileEventHandler(OnProjectFileClosed);
}
/// <summary>
/// Close loaded project.
/// </summary>
private void CloseProject()
{
if(m_Project == null)
return;
//
// Clear project explorer.
//
m_tvProjectExplorer.Nodes.Clear();
m_Project.Save();
m_Project = null;
//
// TODO: Clear opened files.
//
}
private void UpdateUIState()
{
m_AddNewFileTool.Enabled = (m_Project != null);
m_CloseProject.Enabled = (m_Project != null);
m_NewFile.Enabled = m_NewFileTool.Enabled = (m_Project != null);
m_SaveFile.Enabled = m_SaveFileTool.Enabled = (m_ProjectFile != null);
if(m_ProjectFile != null)
m_SaveFile.Text = "S&ave " + m_ProjectFile.Name;
else
m_SaveFile.Text = "S&ave File";
if(m_ProjectFile != null)
m_SaveAllFiles.Enabled = m_SaveAllFilesTool.Enabled = (m_ProjectFiles.Count > 0);
else
m_SaveAllFiles.Enabled = m_SaveAllFilesTool.Enabled = false;
}
// ///////////////////////////////
/// <summary>
/// Currently opened project.
/// </summary>
private Project m_Project = null;
/// <summary>
/// Opened project files.
/// </summary>
private ProjectFileCollection m_ProjectFiles = null;
/// <summary>
/// Currently opened project file.
/// </summary>
private ProjectFile m_ProjectFile = null;
//
// UI Commands
//
/// <summary>
/// UI command to build source program.
/// </summary>
private void OnBuild(object sender, EventArgs e)
{
if(m_ProjectFile == null)
return;
m_ProjectFile.Source.SaveFile(m_ProjectFile.Path);
m_ProjectFile.IsChanged = false;
try
{
m_Output.Clear();
Scanner scanner = new Scanner(m_ProjectFile.Path,m_Language);
Parser parser = new Parser(scanner,m_Language);
parser.Error += new ParserEventHandler(OnParserError);
Module module = parser.CreateSyntaxTree();
Generator generator = new Generator(module);
string path = Path.GetDirectoryName(m_Project.Path) + "\\" + module.Name + ".exe";
if(File.Exists(path))
File.Delete(path);
generator.Compile(path);
//
// Use ildasm to decompile executable.
//
/*
if(File.Exists("il.txt"))
File.Delete("il.txt");
Process ildasm = new Process();
ildasm.StartInfo.FileName = "ildasm.exe";
ildasm.StartInfo.Arguments = "/OUT=il.txt " + path;
ildasm.Start();
ildasm.WaitForExit();
StreamReader il = File.OpenText("il.txt");
WriteAndScroll(m_Output, il.ReadToEnd());
il.Close();
*/
Process child = new Process();
child.StartInfo.FileName = path;
child.Start();
}
catch(Exception x)
{
WriteAndScroll(m_Output,x.Message);
}
}
private void OnParserError(Core.Token token, string message)
{
WriteAndScroll(m_Output,message);
}
/// <summary>
/// UI command to exit IDE.
/// </summary>
private void OnExit(object sender, EventArgs e)
{
Close();
}
/// <summary>
/// UI command to create new project.
/// </summary>
private void OnNewProject(object sender, EventArgs e)
{
NewProjectWizard wizard = new NewProjectWizard();
if(wizard.ShowDialog() != DialogResult.OK)
return;
LoadProject(Project.Create(wizard.ProjectPath + "\\" + wizard.ProjectName + ".shp",wizard.ProjectName));
UpdateUIState();
}
/// <summary>
/// UI command to open a project.
/// </summary>
private void OnOpenProject(object sender, EventArgs e)
{
OpenFileDialog browser = new OpenFileDialog();
browser.Filter = "Sharp Project|*.shp";
browser.CheckFileExists = true;
if(browser.ShowDialog() != DialogResult.OK)
return;
LoadProject(Project.Open(browser.FileName));
UpdateUIState();
}
/// <summary>
/// UI command to close opened project.
/// </summary>
private void OnCloseProject(object sender, EventArgs e)
{
CloseProject();
UpdateUIState();
}
/// <summary>
/// UI command to add a existing file to the opened project.
/// </summary>
private void OnAddFile(object sender, EventArgs e)
{
OpenFileDialog browser = new OpenFileDialog();
browser.Filter = "Sharp Source File|*.sh";
browser.CheckFileExists = true;
if(browser.ShowDialog() != DialogResult.OK)
return;
foreach(ProjectFile file in m_Project.ProjectFiles)
{
if(file.Path == browser.FileName)
{
MessageBox.Show("File is already part of the project.");
return;
}
}
m_Project.ProjectFiles.Add(new ProjectFile(m_Project,browser.FileName));
UpdateUIState();
}
/// <summary>
/// UI command to create a new file and add it to the opened project.
/// </summary>
private void OnNewFile(object sender, EventArgs e)
{
NewFileWizard wizard = new NewFileWizard(m_Project);
if(wizard.ShowDialog() != DialogResult.OK)
return;
m_Project.ProjectFiles.Add(wizard.ProjectFile);
UpdateUIState();
}
/// <summary>
/// UI command to drop down the tools menu.
/// </summary>
private void OnToolsMenuDropDown(object sender, EventArgs e)
{
m_BuildParseTree.Enabled = m_BuildSyntaxTree.Enabled = (m_ProjectFile != null);
}
/// <summary>
/// UI command to drop down the project menu.
/// </summary>
private void OnProjectMenuDropDown(object sender, EventArgs e)
{
TreeNode selected = m_tvProjectExplorer.SelectedNode;
if(selected == null)
return;
Debug.Assert(selected.Tag != null,"Tree node has no tag value.");
if(selected.Tag.GetType() == typeof(ProjectFile))
{
ProjectFile file = selected.Tag as ProjectFile;
m_RemoveFile.Enabled = m_DeleteFile.Enabled = true;
m_RemoveFile.Text = "&Remove " + file.Name;
m_DeleteFile.Text = "&Delete " + file.Name;
}
else
{
m_RemoveFile.Enabled = m_DeleteFile.Enabled = false;
m_RemoveFile.Text = "&Remove File";
m_DeleteFile.Text = "&Delete File";
}
}
/// <summary>
/// UI command to remove a file from the opened project.
/// </summary>
private void OnRemoveFile(object sender, EventArgs e)
{
TreeNode selected = m_tvProjectExplorer.SelectedNode;
if(selected == null)
return;
Debug.Assert(selected.Tag != null,"Tree node has no tag value.");
if(selected.Tag.GetType() == typeof(ProjectFile))
{
ProjectFile file = selected.Tag as ProjectFile;
m_Project.ProjectFiles.Remove(file);
if(m_ProjectFiles.Contains(file))
m_ProjectFiles.Remove(file);
}
}
/// <summary>
/// UI command to remove and delete a file from the opened project.
/// </summary>
private void OnDeleteFile(object sender, EventArgs e)
{
TreeNode selected = m_tvProjectExplorer.SelectedNode;
if(selected == null)
return;
Debug.Assert(selected.Tag != null,"Tree node has no tag value.");
if(selected.Tag.GetType() == typeof(ProjectFile))
{
ProjectFile file = selected.Tag as ProjectFile;
m_Project.ProjectFiles.Remove(file);
if(m_ProjectFiles.Contains(file))
{
m_ProjectFiles.Remove(file);
File.Delete(file.Path);
file = null;
}
}
}
/// <summary>
/// UI command to save current file.
/// </summary>
private void OnSaveFile(object sender, EventArgs e)
{
m_ProjectFile.Source.SaveFile(m_ProjectFile.Path);
m_ProjectFile.IsChanged = false;
}
/// <summary>
/// UI command to save all opened files.
/// </summary>
private void OnSaveAllFiles(object sender, EventArgs e)
{
foreach(ProjectFile file in m_ProjectFiles)
{
file.Source.SaveFile(file.Path);
file.IsChanged = false;
}
}
/// <summary>
/// UI command to open a project file for editing.
/// </summary>
private void OnProjectExplorerDoubleClick(object sender, EventArgs e)
{
TreeNode selected = m_tvProjectExplorer.SelectedNode;
if(selected == null)
return;
Debug.Assert(selected.Tag != null,"Tree node has no tag value.");
if(selected.Tag.GetType() == typeof(ProjectFile))
{
ProjectFile file = selected.Tag as ProjectFile;
if(!m_ProjectFiles.Contains(file))
m_ProjectFiles.Add(file);
else
{
Crownwood.Magic.Controls.TabPage tabPage = file.Tab;
m_Files.SelectedTab = tabPage;
}
}
}
/// <summary>
/// UI command to close a file.
/// </summary>
private void OnFilesClosed(object sender, EventArgs e)
{
if(m_Files.TabPages.Count == 0)
return;
m_ProjectFiles.Remove(m_Files.SelectedTab.Tag as ProjectFile);
}
/// <summary>
/// UI command that modified the source code of a file.
/// </summary>
private void OnProjectFileTextChanged(object sender, EventArgs e)
{
ProjectFile file = ((TextAreaControl)sender).Tag as ProjectFile;
file.IsChanged = true;
}
/// <summary>
/// UI command that displayed a new source tab page.
/// </summary>
private void OnPageGotFocus(object sender, EventArgs e)
{
m_ProjectFile = m_Files.SelectedTab.Tag as ProjectFile;
UpdateUIState();
}
/// <summary>
/// UI command to build the parse tree for the current file.
/// </summary>
private void OnBuildParseTree(object sender, EventArgs e)
{
if(m_ProjectFile == null)
return;
m_ProjectFile.Source.SaveFile(m_ProjectFile.Path);
m_ProjectFile.IsChanged = false;
Scanner scanner = new Scanner(m_ProjectFile.Path,m_Language);
Parser parser = new Parser(scanner,m_Language);
ParseTreeNode root = parser.CreateParseTree ();
if(root == null)
{
UI.Error("Cannot build parse tree from file [" + m_ProjectFile.Name + "] because its not grammatical");
return;
}
//
// Show parse tree
//
m_tvParseTree.Nodes.Clear();
TreeNode rootNode = new TreeNode(root.Name,(int)IconIndex.NonTerminal,(int)IconIndex.NonTerminal);
BuildParseTreeNode(rootNode,root.Children);
m_tvParseTree.Nodes.Add(rootNode);
}
private void BuildParseTreeNode(TreeNode parent, ParseTreeNode [] children)
{
if(children == null)
return;
foreach(ParseTreeNode child in children)
{
TreeNode node = new TreeNode(child.Name);
node.SelectedImageIndex = node.ImageIndex = child.Children == null ? (int)IconIndex.Terminal : (int)IconIndex.NonTerminal;
if(child.Children != null)
BuildParseTreeNode(node,child.Children);
parent.Nodes.Add(node);
}
}
/// <summary>
/// UI command to build the parse tree for the current file.
/// </summary>
private void OnBuildSyntaxTree(object sender, EventArgs e)
{
if(m_ProjectFile == null)
return;
m_ProjectFile.Source.SaveFile(m_ProjectFile.Path);
m_ProjectFile.IsChanged = false;
Scanner scanner = new Scanner(m_ProjectFile.Path,m_Language);
Parser parser = new Parser(scanner,m_Language);
parser.Error += new ParserEventHandler(OnError);
Module module = parser.CreateSyntaxTree();
if(module == null)
{
UI.Error("Cannot build syntax tree from file [" + m_ProjectFile.Name + "] because its not grammatical");
return;
}
//
// Show parse tree
//
m_tvSyntaxTree.Nodes.Clear();
TreeNode rootNode = new TreeNode("Syntax Tree",(int)IconIndex.Parse_Tree,(int)IconIndex.Parse_Tree);
BuildSyntaxTreeNode(rootNode,module);
m_tvSyntaxTree.Nodes.Add(rootNode);
}
private void BuildSyntaxTreeNode(TreeNode parent, object node)
{
if(node == null)
return;
if(node.GetType() == typeof(Module))
{
Module module = (Module)node;
TreeNode moduleNode = new TreeNode("Module : " + module.Name,(int)IconIndex.Module,(int)IconIndex.Module);
BuildSyntaxTreeNode(moduleNode,module.Body);
parent.Nodes.Add(moduleNode);
}
else if(node.GetType() == typeof(Body))
{
Body body = (Body)node;
TreeNode bodyNode = new TreeNode("Body",(int)IconIndex.Body,(int)IconIndex.Body);
if(body.Structures != null)
foreach(Structure structure in body.Structures)
BuildSyntaxTreeNode(bodyNode,structure);
if(body.Functions != null)
foreach(Function function in body.Functions)
BuildSyntaxTreeNode(bodyNode,function);
if(body.Statements != null)
foreach(Statement statement in body.Statements)
BuildSyntaxTreeNode(bodyNode,statement);
parent.Nodes.Add(bodyNode);
}
else if(node.GetType() == typeof(Function))
{
Function function = (Function)node;
TreeNode functionNode = new TreeNode("Function : " + function.Name,(int)IconIndex.Function,(int)IconIndex.Function);
BuildSyntaxTreeNode(functionNode,function.Type);
TreeNode parametersNode = new TreeNode("Parameters",(int)IconIndex.Expression,(int)IconIndex.Expression);
if(function.Parameters != null)
foreach(Parameter parameter in function.Parameters)
BuildSyntaxTreeNode(parametersNode,parameter);
functionNode.Nodes.Add(parametersNode);
BuildSyntaxTreeNode(functionNode,function.Body);
parent.Nodes.Add(functionNode);
}
else if(node.GetType() == typeof(Variable))
{
Variable variable = (Variable)node;
TreeNode variableNode = new TreeNode("Variable : " + variable.Name,(int)IconIndex.Variable,(int)IconIndex.Variable);
BuildSyntaxTreeNode(variableNode,variable.Type);
TreeNode valueNode = new TreeNode("Value",7,7);
BuildSyntaxTreeNode(valueNode,variable.Value);
variableNode.Nodes.Add(valueNode);
parent.Nodes.Add(variableNode);
}
else if(node.GetType() == typeof(Structure))
{
Structure structure = (Structure)node;
TreeNode structureNode = new TreeNode("Structure : " + structure.Name,(int)IconIndex.Structure,(int)IconIndex.Structure);
TreeNode variablesNode = new TreeNode("Variables",7,7);
if(structure.Variables != null)
foreach(Variable variable in structure.Variables)
BuildSyntaxTreeNode(variablesNode,variable);
structureNode.Nodes.Add(variablesNode);
parent.Nodes.Add(structureNode);
}
else if(node.GetType() == typeof(Core.Type))
{
Core.Type type = (Core.Type)node;
TreeNode typeNode = new TreeNode("Type",7,7);
typeNode.Nodes.Add(new TreeNode("Primitive Type : " + type.PrimitiveType.ToString(),7,7));
typeNode.Nodes.Add(new TreeNode("Variable Type : " + type.VariableType.ToString(),7,7));
parent.Nodes.Add(typeNode);
}
else if(node.GetType() == typeof(Parameter))
{
Parameter parameter = (Parameter)node;
TreeNode parameterNode = new TreeNode("Parameter : " + parameter.Name,7,7);
BuildSyntaxTreeNode(parameterNode,parameter.Type);
parameterNode.Nodes.Add(new TreeNode("Pass Method : " + parameter.PassMethod.ToString(),7,7));
parent.Nodes.Add(parameterNode);
}
else if(node.GetType() == typeof(Assignment))
{
Assignment assignment = (Assignment)node;
TreeNode assignmentNode = new TreeNode("Assignment : " + assignment.Name,(int)IconIndex.Expression,(int)IconIndex.Expression);
TreeNode val = new TreeNode("Value",(int)IconIndex.Expression,(int)IconIndex.Expression);
BuildSyntaxTreeNode(val,assignment.Value);
assignmentNode.Nodes.Add(val);
parent.Nodes.Add(assignmentNode);
}
else if(node.GetType() == typeof(If))
{
If ifStatement = (If)node;
TreeNode ifNode = new TreeNode("if",7,7);
TreeNode condition = new TreeNode("Condition",(int)IconIndex.Expression,(int)IconIndex.Expression);
BuildSyntaxTreeNode(condition,ifStatement.Condition);
TreeNode ifBody = new TreeNode("If Body",(int)IconIndex.Body,(int)IconIndex.Body);
BuildSyntaxTreeNode(ifBody,ifStatement.IfBody);
TreeNode elseBody = new TreeNode("Else Body",(int)IconIndex.Body,(int)IconIndex.Body);
BuildSyntaxTreeNode(elseBody,ifStatement.ElseBody);
ifNode.Nodes.Add(condition);
ifNode.Nodes.Add(ifBody);
ifNode.Nodes.Add(elseBody);
parent.Nodes.Add(ifNode);
}
else if(node.GetType() == typeof(While))
{
While whileStatement = (While)node;
TreeNode whileNode = new TreeNode("while",7,7);
TreeNode condition = new TreeNode("Condition",(int)IconIndex.Expression,(int)IconIndex.Expression);
BuildSyntaxTreeNode(condition,whileStatement.Condition);
whileNode.Nodes.Add(condition);
BuildSyntaxTreeNode(whileNode,whileStatement.Body);
parent.Nodes.Add(whileNode);
}
else if(node.GetType() == typeof(Do))
{
Do doStatement = (Do)node;
TreeNode doNode = new TreeNode("do",7,7);
TreeNode condition = new TreeNode("Condition",(int)IconIndex.Expression,(int)IconIndex.Expression);
BuildSyntaxTreeNode(condition,doStatement.Condition);
doNode.Nodes.Add(condition);
BuildSyntaxTreeNode(doNode,doStatement.Body);
parent.Nodes.Add(doNode);
}
else if(node.GetType() == typeof(For))
{
For forStatement = (For)node;
TreeNode forNode = new TreeNode("for",7,7);
TreeNode initializer = new TreeNode("Initializer",(int)IconIndex.Expression,(int)IconIndex.Expression);
BuildSyntaxTreeNode(initializer,forStatement.Initializer);
forNode.Nodes.Add(initializer);
TreeNode condition = new TreeNode("Condition",(int)IconIndex.Expression,(int)IconIndex.Expression);
BuildSyntaxTreeNode(condition,forStatement.Condition);
forNode.Nodes.Add(condition);
TreeNode counter = new TreeNode("Counter",(int)IconIndex.Expression,(int)IconIndex.Expression);
BuildSyntaxTreeNode(counter,forStatement.Counter);
forNode.Nodes.Add(counter);
BuildSyntaxTreeNode(forNode,forStatement.Body);
parent.Nodes.Add(forNode);
}
else if(node.GetType() == typeof(BinaryExpression))
{
BinaryExpression binaryExpression = (BinaryExpression)node;
TreeNode binaryExpressionNode = new TreeNode("Binary Expression : " + binaryExpression.BinaryOperatorType.ToString(),7,7);
TreeNode left = new TreeNode("Left",(int)IconIndex.Expression,(int)IconIndex.Expression);
BuildSyntaxTreeNode(left,binaryExpression.Left);
TreeNode right = new TreeNode("Right",(int)IconIndex.Expression,(int)IconIndex.Expression);
BuildSyntaxTreeNode(right,binaryExpression.Right);
binaryExpressionNode.Nodes.Add(left);
binaryExpressionNode.Nodes.Add(right);
parent.Nodes.Add(binaryExpressionNode);
}
else if(node.GetType() == typeof(UnaryExpression))
{
UnaryExpression unaryExpression = (UnaryExpression)node;
TreeNode unaryExpressionNode = new TreeNode("Unary Expression : " + unaryExpression.UnaryOperatorType.ToString(),7,7);
TreeNode val = new TreeNode("Value",(int)IconIndex.Expression,(int)IconIndex.Expression);
BuildSyntaxTreeNode(val,unaryExpression.Value);
TreeNode indexer = new TreeNode("Indexer",(int)IconIndex.Expression,(int)IconIndex.Expression);
BuildSyntaxTreeNode(indexer,unaryExpression.Indexer);
unaryExpressionNode.Nodes.Add(val);
unaryExpressionNode.Nodes.Add(indexer);
parent.Nodes.Add(unaryExpressionNode);
}
else if(node.GetType() == typeof(Literal))
{
Literal literal = (Literal)node;
TreeNode literalNode = new TreeNode("Literal : " + literal.Value,(int)IconIndex.Expression,(int)IconIndex.Expression);
TreeNode literalTypeNode = new TreeNode("Literal Type : " + literal.LiteralType.ToString(),7,7);
literalNode.Nodes.Add(literalTypeNode);
parent.Nodes.Add(literalNode);
}
else if(node.GetType() == typeof(Call))
{
Call call = (Call)node;
TreeNode callNode = new TreeNode("Call : " + call.Name,(int)IconIndex.Function,(int)IconIndex.Function);
TreeNode argumentsNode = new TreeNode("Arguments",7,7);
if(call.Arguments != null)
foreach(Argument argument in call.Arguments)
BuildSyntaxTreeNode(argumentsNode,argument);
callNode.Nodes.Add(argumentsNode);
parent.Nodes.Add(callNode);
}
else if(node.GetType() == typeof(Name))
{
Name name = (Name)node;
TreeNode nameNode = new TreeNode("Name : " + name.Value,(int)IconIndex.Expression,(int)IconIndex.Expression);
parent.Nodes.Add(nameNode);
}
else if(node.GetType() == typeof(Argument))
{
Argument argument = (Argument)node;
TreeNode argumentNode = new TreeNode("Argument",7,7);
TreeNode valueNode = new TreeNode("Value",7,7);
BuildSyntaxTreeNode(valueNode,argument.Value);
argumentNode.Nodes.Add(valueNode);
argumentNode.Nodes.Add(new TreeNode("Pass Method : " + argument.PassMethod.ToString(),7,7));
parent.Nodes.Add(argumentNode);
}
}
void OnError(Token token, string message)
{
WriteAndScroll(m_Output,"[" + token.Line + "," + token.Column + "] " + message + " : '" + token.Text + "'\n");
}
void OnWarning(Token token, string message)
{
}
//
// Events generated by the project.
//
/// <summary>
/// Modify UI elements for the changed file.
/// </summary>
private void OnProjectFileChanged(ProjectFile file)
{
Crownwood.Magic.Controls.TabPage tabPage = file.Tab;
if(file.IsChanged)
tabPage.Title = file.Name + " *";
else
tabPage.Title = file.Name;
}
/// <summary>
/// Add UI elements for the added file.
/// </summary>
private void OnProjectFileAdded(ProjectFile file)
{
TreeNode tnProject = (TreeNode)file.Project.Node;
TreeNode tnFile = new TreeNode(Path.GetFileName(file.Path),(int)IconIndex.File,(int)IconIndex.File);
tnFile.Tag = file;
file.Node = tnFile;
tnProject.Nodes.Add(tnFile);
tnProject.Expand();
}
/// <summary>
/// Remove UI elements for the removed file.
/// </summary>
private void OnProjectFileRemoved(ProjectFile file)
{
TreeNode tnFile = file.Node;
tnFile.Remove();
}
/// <summary>
/// Add UI elements for the file to be opened for editing.
/// </summary>
private void OnProjectFileOpened(ProjectFile file)
{
if(!File.Exists(file.Path))
{
MessageBox.Show("File not found.");
return;
}
Crownwood.Magic.Controls.TabPage tabPage = new Crownwood.Magic.Controls.TabPage(file.Name);
TextAreaControl editor = new ICSharpCode.TextEditor.TextAreaControl();
editor.Tag = file;
editor.LoadFile(file.Path);
editor.Changed += new EventHandler(OnProjectFileTextChanged);
tabPage.Control = editor;
tabPage.Tag = file;
tabPage.ImageList = m_ImageList;
tabPage.ImageIndex = (int)IconIndex.File;
file.Tab = tabPage;
file.Source = editor;
file.Changed += new ProjectFileEventHandler(OnProjectFileChanged);
m_Files.TabPages.Add(tabPage);
m_Files.SelectedTab = tabPage;
file.IsChanged = false;
}
/// <summary>
/// Remove UI elements for the file to be closed.
/// </summary>
private void OnProjectFileClosed(ProjectFile file)
{
m_Files.TabPages.Remove(file.Tab);
file.Source = null;
file.Tab = null;
if(m_Files.SelectedTab != null)
m_ProjectFile = m_Files.SelectedTab.Tag as ProjectFile;
else
m_ProjectFile = null;
UpdateUIState();
}
}
}