(*
DMonkey Script Host

2003/04/09 ver0.2.0.2
    AllocConsole(オプション -c)

2002/12/26 ver0.2.0.1
  ・エンジンバージョンを0.2.0.1に
  ・help起動オプション
  ・カレントディレクトリを変更
  ・ファイルが存在しない時はダイアログを開くようにした
  ・標準出力に、コンパイル、実行時間情報を追加
  ・引数の仕様をdm.exeに合わせて変更。
  ・バージョンをエンジンと同じに
  ・argumentsにはパラメータのみ格納

2002/11/23 ver0.0.1.1
  ・DMonkey0.1.7で作り直し。
  ・標準出力をファイルに吐くようにした。
  ・ecma_guiobjectを参照しないようにした。
*)
unit dmsh;

interface

uses
  Windows, Classes, SysUtils, Forms, Dialogs, shellapi,
  DMonkey, ecma_type, ecma_misc;

type
  TDMSH = class(TObject)
  private
    FDM: TDMonkey;
    FStdout: string;
    FLogout: Boolean;
    procedure DMStdout(Sender: TObject; S: string);
    procedure DMStderr(Sender: TObject; S: string);
    function OpenFile: string;
  public
    constructor Create;
    destructor Destroy; override;
    procedure Run;
  end;

implementation

{ TDMSH }

constructor TDMSH.Create;
begin
  inherited Create;
  FDM := TDMonkey.Create(nil);
  FDM.CompiledBinary := True;
  FDM.OnStdout := DMStdout;
  FDM.OnStderr := DMStderr;
end;

destructor TDMSH.Destroy;
begin
  FDM.Free;
  inherited;
end;

procedure TDMSH.DMStdout(Sender: TObject; S: string);
begin
  FLogout := True;
  FStdout := FStdout + S;
end;

procedure TDMSH.DMStderr(Sender: TObject; S: string);
begin
  ShowDMonkeyException(Sender as TDMonkey);
end;

function TDMSH.OpenFile: string;
var
  dlg: TOpenDialog;
begin
  Result := '';
  dlg := TOpenDialog.Create(nil);
  try
    dlg.Filter := 'DMonkey Script File(*' + DMS_EXT + ')|*' + DMS_EXT +
                  '|すべてのファイル(*.*)|*.*';
    if dlg.Execute then
      Result := dlg.FileName;
  finally
    dlg.Free;
  end;
end;

procedure TDMSH.Run;
var
  prm: TJValueList;
  src,hlp: string;
  sl: TStringList;
  i,paramstart: Integer;
  cout: Boolean;
begin
  paramstart := 2;
  cout := False;
  src := ParamStr(1);
  //help起動
  if (src = '-help') or (src = '/help') or
     (src = '-h') or (src = '/h') then
  begin
    hlp := ExtractFilePath(ParamStr(0)) + 'dmsref.hlp';
    ShellExecute(0,nil,PChar(hlp),nil,nil,SW_SHOW);
    Exit;
  end
  //console出力
  else if (src = '-c') or (src = '/c') then
  begin
    src := ParamStr(2);
    cout := True;
    paramstart := 3;
  end;

  //src := 't.dms';
  if ExtractFileExt(src) = '' then
    src := src + DMS_EXT;

  if not FileExists(src) then
  begin
    src := OpenFile;
    if not FileExists(src) then Exit;
  end;

  //カレントdir変更
  SetCurrentDir(ExtractFileDir(src));

  prm := TJValueList.Create;
  try
    for i := paramstart to ParamCount do
      prm.Add(BuildString(ParamStr(i)));

    if FDM.CompileFile(src) then
      FDM.Run(prm);
  finally
    prm.Free;
  end;

  if FLogout and FileExists(src) then
  begin
    if not cout then
    begin
      sl := TStringList.Create;
      try try
        sl.Text := FStdout;
        sl.Add('---------------------');
        sl.Add('compile: ' + MSecToStr2(FDM.TookTimeToCompile));
        sl.Add('run    : ' + MSecToStr2(FDM.TookTimeToRun));
        sl.SaveToFile(ChangeFileExt(src, '.log'));
      except
        MsgBox('ログファイルを作成できません',
            PChar(Application.Title), MB_OK or MB_ICONHAND);
      end;
      finally
        sl.Free;
      end;
    end
    else begin
      Win32Check(AllocConsole);
      try
        Write(FStdout);
        Writeln('---------------------');
        Writeln('compile: ' + MSecToStr2(FDM.TookTimeToCompile));
        Writeln('run    : ' + MSecToStr2(FDM.TookTimeToRun));
        Readln;
      finally
        FreeConsole;
      end;
    end;
  end;
end;

end.
