#include "StdAfx.h" #include "MainForm.h" #include "inp.h" #include "out.h" #include "lex.h" #include "code1.h" #include "expr1.h" #include "stat1.h" using namespace System::IO; using namespace System::Windows; Prekl::MainForm ^ getMainForm () { return Prekl::MainForm::win; } namespace Prekl { ref class CompilerException: System::Exception { public: CompilerException (String ^ txt) : Exception (txt) { } }; std::string SysToStd (String ^ txt) { int len = txt->Length; char * p = new char [len+1]; for (int i = 0; i < len; i ++) p[i] = char (txt[i]); p[len] = 0; std::string s (p); delete [] p; return s; } String ^ StdToSys (std::string s) { String ^ txt = gcnew String (s.c_str ()); return txt; } String ^ IntToStr (int n) { return "" + n; } /* Source Text */ std::string MainForm::GetInpLine (int line_num) { String ^ txt = ""; if (line_num <= inputArea->Lines->Length) txt = inputArea->Lines [line_num-1]; else txt = "\0"; return SysToStd (txt); } std::string MainForm::GetInpText () { String ^ txt = inputArea->Text; return SysToStd (txt); } /* Output Text */ void MainForm::ClearOutLines () { outputArea->Clear (); } void MainForm::ShowOutLine (std::string txt) { txt = txt; outputArea->AppendText (StdToSys (txt) + "\r\n"); } /* Status Bar */ void MainForm::SetStatus (String ^txt) { statusLabel->Text = txt; } /* Show Error */ void MainForm::ShowError (std::string txt) { CloseInp (); /* uzavri vstup a vystup */ CloseOut (); String ^ s = StdToSys (txt); SetStatus ("Line: " + IntToStr (InpLineNum) + " " + "Col: " + IntToStr (InpColNum) + " " + "Error: " + s); inputArea->SelectionStart = InpPos; /* pozice kurzoru ve vstupnim okenku */ inputArea->SelectionLength = 1; MessageBox::Show ( s, "Error", MessageBoxButtons::OK, MessageBoxIcon::Error ); throw gcnew CompilerException (s); /* skok zpet do funkce Compile */ } /* Compile */ static bool IsIdent (char * id) { return sy==IDENT && strcmp (IdentVal, id) == 0; } static void CheckIdent (char * id) { if (IsIdent (id)) NextSymbol (); else { char msg [200] = "Identier expected: "; stradd (msg, sizeof (msg), id); Error (msg); } } using namespace std; void PutString (string txt) { PutStr ((char *)txt.c_str ()); } static string ReadString () { char * result = ""; if (sy == STR) { result = StrVal; NextSymbol (); } else Error ("String expected"); return result; } static string ReadIdent () { char * result = ""; if (sy == IDENT) { result = IdentVal; NextSymbol (); } else Error ("Identifier expected"); return result; } static string ReadNumber () { char * result = ""; if (sy == NUM) { result = NumVal; NextSymbol (); } else Error ("(Integer) number expected"); return result; } void expr (); void simple_expr () { Indent (); if (sy == IDENT) { PutString (ReadIdent ()); PutEol (); } else if (sy == NUM) { PutString (ReadNumber ()); PutEol (); } else if (sy == LPAR) { // PutStr ("("); PutEol (); NextSymbol (); /* preskoc ( */ expr (); CheckSymbol (RPAR); /* ) */ // PutStr (")"); PutEol (); } else Error ("Simple expression expected"); Unindent (); } /* void mul_expr () { Indent (); simple_expr (); while (sy == ASTERISK || sy == SLASH) { if (sy == ASTERISK) PutStr ("*"); else PutStr ("/"); PutEol (); NextSymbol (); simple_expr (); } Unindent (); } */ void mul_expr () { Indent (); simple_expr (); if (sy == ASTERISK || sy == SLASH) { if (sy == ASTERISK) PutStr ("*"); else PutStr ("/"); PutEol (); NextSymbol (); mul_expr (); } Unindent (); } void expr () { Indent (); mul_expr (); while (sy == PLUS || sy == MINUS) { if (sy == PLUS) PutStr ("+"); else PutStr ("/"); PutEol (); NextSymbol (); mul_expr (); } Unindent (); } void let () { CheckIdent ("LET"); string name = ReadIdent (); CheckSymbol (ASSIGN); PutString ("LET " + name + " = "); PutEol (); expr (); CheckSymbol (SEMICOLON); PutEol (); } void item () { CheckIdent ("ITEM"); string item_name = ReadString (); string command_name = ""; if (IsIdent ("COMMAND")) { NextSymbol (); command_name = ReadIdent (); } PutStr ("item "); PutString (item_name); PutStr (" with command "); PutString (command_name); PutEol (); CheckSymbol (SEMICOLON); } void menu () { CheckIdent ("MENU"); string name = ""; if (sy == IDENT) name = ReadIdent (); else if (sy == STR) name = ReadString (); PutStr ("menu "); PutString (name); PutEol (); Indent (); CheckSymbol (LBRACE); while (sy!=RBRACE) { if (IsIdent ("MENU")) menu (); else if (IsIdent ("ITEM")) item (); else Error ("Unknown menu item"); } CheckSymbol (RBRACE); Unindent (); PutStr ("end of menu"); PutEol (); } void MainForm::Compile () { try { OpenInp (); /* otevri vstupni a vystupni text */ OpenOut (); InitLex (); /* inicializace modulu Lex, precteni prvniho symbolu */ init_labels (); while (sy!=EOS) { if (IsIdent ("MENU")) menu (); else if (IsIdent ("LET")) let (); else Error ("Unknown statement"); } CloseInp (); /* uzavri vstupni a vystupni text */ CloseOut (); SetStatus ("O.K."); /* stavova radka */ outputArea->SelectionStart = 0; /* zobraz zacatek textu */ outputArea->SelectionLength = 1; outputArea->ScrollToCaret (); } catch (CompilerException ^ e) { /* nic - informace o chybe jiz zobrazila funkce ShowError */ } } /* Read File */ void MainForm::Read (String ^ file_name) { try { StreamReader ^ f = gcnew StreamReader (file_name); inputArea->Text = f->ReadToEnd (); f->Close (); } catch (FileNotFoundException ^ e) { SetStatus (e->Message); } inputArea->DeselectAll (); } /* Open File */ void MainForm::openMenuItem_Click (System::Object^ sender, System::EventArgs^ e) { if (openFileDialog->ShowDialog () == System::Windows::Forms::DialogResult::OK) { StreamReader ^ f = gcnew StreamReader (openFileDialog->FileName); inputArea->Text = f->ReadToEnd (); f->Close (); inputArea->DeselectAll (); } } /* Save File */ void MainForm::saveMenuItem_Click (System::Object^ sender, System::EventArgs^ e) { if (saveFileDialog->ShowDialog () == Forms::DialogResult::OK) { StreamWriter ^ f = gcnew StreamWriter (saveFileDialog->FileName); f->Write (inputArea->Text); f->Close (); } } /* Change Font */ void MainForm::fontMenuItem_Click(System::Object^ sender, System::EventArgs^ e) { fontDialog->Font = inputArea->Font; if (fontDialog->ShowDialog () == Forms::DialogResult::OK) { inputArea->Font = fontDialog->Font; outputArea->Font = fontDialog->Font; } } } // end of namespace