(********************************************************************)
(*                                                                  *)
(*  calc7.sd7     Calculator                                        *)
(*  Copyright (C) 1995, 2004, 2013, 2014  Thomas Mertes             *)
(*                                                                  *)
(*  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., 51 Franklin Street,             *)
(*  Fifth Floor, Boston, MA  02110-1301, USA.                       *)
(*                                                                  *)
(********************************************************************)


$ include "seed7_05.s7i";
  include "progs.s7i";
  include "keybd.s7i";
  include "console.s7i";
  include "editline.s7i";


const proc: main is func

  local
    var string: command is "";
    var program: aProgram is program.EMPTY;
    var parseError: error is parseError.value;
    var string: prompt is "calculate? ";
    var string: writelnLineStart is "      writeln(";
    var integer: columnNumber is 0;
  begin
    OUT := STD_CONSOLE;
    IN := openEditLine(KEYBOARD, OUT);
    writeln("Calc7 - Seed7 calculator");
    writeln("Copyright (C) 1995, 2004, 2013, 2014 Thomas Mertes");
    writeln("This is free software; see the source for copying conditions.  There is NO");
    writeln("warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.");
    writeln("Calc7 is written in the Seed7 programming language");
    writeln("Homepage: http://seed7.sourceforge.net");
    writeln("Write an expression to be calculated or quit or exit to leave the program.");
    writeln;
    write(prompt);
    readln(command);
    while command not in {"quit", "exit"} do
      if command <> "" then
        aProgram := parseStri("\
          \$ include \"seed7_05.s7i\";\n\
          \include \"console.s7i\";\n\
          \include \"float.s7i\";\n\
          \include \"math.s7i\";\n\
          \include \"rational.s7i\";\n\
          \include \"complex.s7i\";\n\
          \include \"mixarith.s7i\";\n\
          \include \"bigint.s7i\";\n\
          \include \"bigrat.s7i\";\n\
          \include \"bigdec.s7i\";\n\
          \include \"time.s7i\";\n\
          \include \"duration.s7i\";\n\
          \include \"bytedata.s7i\";\n\
          \include \"leb128.s7i\";\n\
          \include \"unicode.s7i\";\n\
          \include \"encoding.s7i\";\n\
          \include \"compress.s7i\";\n\
          \include \"bin32.s7i\";\n\
          \include \"bin64.s7i\";\n\
          \include \"msgdigest.s7i\";\n\
          \include \"osfiles.s7i\";\n\
          \include \"getf.s7i\";\n\
          \include \"gethttp.s7i\";\n\
          \include \"gethttps.s7i\";\n\
          \include \"ftp.s7i\";\n\
          \include \"keybd.s7i\";\n\
          \include \"keydescr.s7i\";\n\
          \include \"draw.s7i\";\n\
          \include \"json.s7i\";\n\
          \\n\
          \const proc: main is func\n\
          \  begin\n\
          \    OUT := STD_CONSOLE;\n\
          \    block\n\
          \      writeln(" & command & ");\n\
          \    exception\n\
          \      catch MEMORY_ERROR:   writeln(\"MEMORY_ERROR\");\n\
          \      catch NUMERIC_ERROR:  writeln(\"NUMERIC_ERROR\");\n\
          \      catch OVERFLOW_ERROR: writeln(\"OVERFLOW_ERROR\");\n\
          \      catch RANGE_ERROR:    writeln(\"RANGE_ERROR\");\n\
          \      catch INDEX_ERROR:    writeln(\"INDEX_ERROR\");\n\
          \      catch FILE_ERROR:     writeln(\"FILE_ERROR\");\n\
          \      catch DATABASE_ERROR: writeln(\"DATABASE_ERROR\");\n\
          \      catch GRAPHIC_ERROR:  writeln(\"GRAPHIC_ERROR\");\n\
          \      catch ILLEGAL_ACTION: writeln(\"ILLEGAL_ACTION\");\n\
          \    end block;\n\
          \  end func;\n\
          \");
        if aProgram <> program.EMPTY then
          if errorCount(aProgram) = 0 then
            execute(aProgram);
          else
            error := getError(aProgram, 1);
            if startsWith(error.errorLine, writelnLineStart) then
              if error.columnNumber > length(writelnLineStart) then
                columnNumber := length(prompt) +
                    error.columnNumber - length(writelnLineStart) - 1;
                writeln("-" mult columnNumber <& "^");
              end if;
            end if;
            writeln("*** " <& error.message);
            writeln("*** " <& errorCount(aProgram) <& " errors found");
          end if;
        end if;
      end if;
      write(prompt);
      readln(command);
    end while;
  end func;