turtlecompile.lpr 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245
  1. program turtlecompile;
  2. {$mode objfpc}
  3. uses
  4. Math, Classes, SysUtils, browserapp, Web, webfilecache, pas2jswebcompiler;
  5. Type
  6. { TWebCompilerDemo }
  7. TWebCompilerDemo = Class(TBrowserApplication)
  8. Private
  9. btnCloseNotification,
  10. BRun : TJSHTMLButtonElement;
  11. MSource : TJSHTMLTextAreaElement;
  12. MLog: TJSHTMLElement;
  13. pnlLog : TJSHTMLElement;
  14. RFrame : TJSHTMLIFrameElement;
  15. FCompiler : TPas2JSWebCompiler;
  16. procedure ClearResult;
  17. procedure DoLog(Sender: TObject; const Msg: String);
  18. function HideNotification(aEvent: TJSMouseEvent): boolean;
  19. procedure LogError(const aMsg: string);
  20. procedure OnUnitsLoaded(Sender: TObject; aFileName: String; aError: string);
  21. function Prepare(aSource: string): string;
  22. function RunClick(aEvent: TJSMouseEvent): boolean;
  23. procedure RunResult;
  24. Protected
  25. function CompileClick(aEvent: TJSMouseEvent): boolean;
  26. Procedure LinkElements;
  27. Property Compiler : TPas2JSWebCompiler Read FCompiler;
  28. Public
  29. Constructor Create(aOwner : TComponent); override;
  30. Procedure Execute;
  31. end;
  32. Const
  33. // Default run HTML page, shown in IFrame.
  34. SHTMLHead =
  35. '<HTML>'+LineEnding+
  36. '<head>'+LineEnding+
  37. ' <meta charset="UTF-8">'+LineEnding+
  38. ' <Title>Pas2JS Turtle graphics program output</Title>'+LineEnding+
  39. ' <script type="application/javascript">'+LineEnding;
  40. SHTMLTail =
  41. ' </script>'+LineEnding+
  42. ' <link href="bulma.min.css" rel="stylesheet">'+LineEnding+
  43. '</head>'+LineEnding+
  44. '<body>'+LineEnding+
  45. ' <div class="container is-fluid">'+LineEnding+
  46. ' <div class="box">'+LineEnding+
  47. ' <h1 class="is-title">Run program output</h1>'+LineEnding+
  48. ' <div class="block" style="min-height: 75hv;">'+LineEnding+
  49. ' <canvas id="cnvTurtle" style="width: 100%; height: 100%;"></canvas>'+LineEnding+
  50. ' </div> <!-- .block --> '+LineEnding+
  51. ' </div> <!-- .box -->'+LineEnding+
  52. ' </div> <!-- .container -->'+LineEnding+
  53. '<script>'+LineEnding+
  54. ' rtl.run();'+LineEnding+
  55. '</script>'+LineEnding+
  56. '</body>'+LineEnding+
  57. '</HTML>';
  58. { TWebCompilerDemo }
  59. procedure TWebCompilerDemo.LogError(const aMsg : string);
  60. begin
  61. MLog.InnerText:=aMsg;
  62. pnlLog.classList.remove('is-hidden');
  63. end;
  64. procedure TWebCompilerDemo.OnUnitsLoaded(Sender: TObject; aFileName: String; aError: string);
  65. begin
  66. BRun.classList.remove('is-loading');
  67. if aError='' then
  68. BRun.disabled:=False
  69. else
  70. begin
  71. LogError('Error Loading "'+aFileName+'": '+AError);
  72. end;
  73. end;
  74. procedure TWebCompilerDemo.LinkElements;
  75. begin
  76. BRun:=TJSHTMLButtonElement(GetHTMLElement('btnRun'));
  77. BRun.onClick:=@CompileClick;
  78. btnCloseNotification:=TJSHTMLButtonElement(GetHTMLElement('btnCloseNotification'));
  79. btnCloseNotification.onClick:=@HideNotification;
  80. MSource:=TJSHTMLTextAreaElement(GetHTMLElement('memSource'));
  81. MLog:=GetHTMLElement('lblCompilerOutput');
  82. pnlLog:=GetHTMLElement('pnlLog');
  83. RFrame:=TJSHTMLIFrameElement(Document.getElementById('runarea'));
  84. end;
  85. constructor TWebCompilerDemo.Create(aOwner : TComponent);
  86. begin
  87. Inherited;
  88. FCompiler:=TPas2JSWebCompiler.Create;
  89. Compiler.Log.OnLog:=@DoLog;
  90. end;
  91. function TWebCompilerDemo.RunClick(aEvent: TJSMouseEvent): boolean;
  92. Var
  93. Src : String;
  94. begin
  95. Result:=True;
  96. end;
  97. procedure TWebCompilerDemo.DoLog(Sender: TObject; const Msg: String);
  98. begin
  99. MLog.InnerHTML:=MLog.InnerHTML+'<BR>'+Msg;
  100. end;
  101. function TWebCompilerDemo.HideNotification(aEvent: TJSMouseEvent): boolean;
  102. begin
  103. pnlLog.classList.Add('is-hidden');
  104. end;
  105. Procedure TWebCompilerDemo.ClearResult;
  106. begin
  107. end;
  108. function TWebCompilerDemo.Prepare(aSource : string) : string;
  109. var
  110. Src,un : String;
  111. p, pu, pp, ps : Integer;
  112. doinsert,withcomma : boolean;
  113. begin
  114. Result:=aSource;
  115. Src:=LowerCase(aSource);
  116. p:=pos('begin',Src);
  117. p:=Min(P,pos('function ',Src));
  118. p:=Min(P,pos('procedure ',Src));
  119. doinsert:=true;
  120. withcomma:=false;
  121. pu:=Pos('uses',Src);
  122. // No uses
  123. if (pu=0) then
  124. begin
  125. pp:=pos('program',src);
  126. if pp=0 then
  127. pu:=1
  128. else
  129. pu:=pos(';',Src,pp+6)+1;
  130. System.Insert(#10'uses ;',result,pu);
  131. pu:=pu+6;
  132. end
  133. else
  134. begin
  135. pu:=pu+5;
  136. ps:=pos(';',Src,pu);
  137. if pos('turtlegraphics',Src,pu)<ps then
  138. doinsert:=False;
  139. withcomma:=true;
  140. end;
  141. if doInsert then
  142. begin
  143. un:=' turtlegraphics';
  144. if Withcomma then
  145. un:=un+', ';
  146. System.insert(un,result,pu);
  147. end;
  148. Writeln('Final code : ',Result);
  149. end;
  150. Procedure TWebCompilerDemo.RunResult;
  151. var
  152. Src : String;
  153. begin
  154. Src:=Compiler.WebFS.GetFileContent('main.js');
  155. if Src='' then
  156. begin
  157. Window.Alert('No source available');
  158. exit;
  159. end;
  160. Src:=SHTMLHead+Src+LineEnding+SHTMLTail;
  161. RFrame['srcdoc']:=Src;
  162. end;
  163. function TWebCompilerDemo.CompileClick(aEvent: TJSMouseEvent): boolean;
  164. Procedure ShowResult(success : boolean);
  165. begin
  166. ClearResult;
  167. BRun.classList.remove('is-loading');
  168. if not Success then
  169. pnlLog.classList.remove('is-hidden');
  170. BRun.Disabled:=False;
  171. end;
  172. Var
  173. args : TStrings;
  174. Res : Boolean;
  175. begin
  176. Result:=False;
  177. BRun.classList.add('is-loading');
  178. // BRun.disabled:=True;
  179. ClearResult;
  180. MLog.InnerHTML:='';
  181. Compiler.WebFS.SetFileContent('main.pp',Prepare(MSource.value));
  182. args:=TStringList.Create;
  183. try
  184. Args.Add('-Tbrowser');
  185. Args.Add('-Jc');
  186. Args.Add('-Jirtl.js');
  187. Args.Add('main.pp');
  188. RFrame.Src:='run.html';
  189. Compiler.Run('','',Args,True);
  190. Res:=Compiler.ExitCode=0;
  191. ShowResult(Res);
  192. if Res then
  193. RunResult;
  194. finally
  195. Args.Free;
  196. end;
  197. end;
  198. procedure TWebCompilerDemo.Execute;
  199. begin
  200. LinkElements;
  201. Compiler.WebFS.LoadBaseURL:='sources';
  202. BRun.classList.add('is-loading');
  203. Compiler.WebFS.LoadFiles(['rtl.js','system.pas','p2jsres.pas','sysutils.pas','types.pas','typinfo.pas','classes.pas','rtlconsts.pas','js.pas','simplelinkedlist.pas','web.pas','weborworker.pas','browserconsole.pas','turtlegraphics.pas'],@OnUnitsLoaded);
  204. end;
  205. begin
  206. With TWebCompilerDemo.Create(Nil) do
  207. Execute;
  208. end.