@@ -86,9 +86,26 @@ class PlaygroundInstance {
8686 return this . getDiagnosticsAndFree ( pg ) ;
8787 }
8888
89+ compile ( program : string ) : GraphAlgDiagnostic [ ] {
90+ const ga_new = this . bindings . ga_new ;
91+ const ga_parse = this . bindings . ga_parse ;
92+ const ga_desugar = this . bindings . ga_desugar ;
93+
94+ const pg = ga_new ( ) ;
95+
96+ if ( ! ga_parse ( pg , program ) ) {
97+ return this . getDiagnosticsAndFree ( pg ) ;
98+ }
99+
100+ if ( ! ga_desugar ( pg ) ) {
101+ return this . getDiagnosticsAndFree ( pg ) ;
102+ }
103+
104+ return [ ] ;
105+ }
106+
89107 run ( program : string , func : string , args : GraphAlgMatrix [ ] ) : RunResults {
90108 const ga_new = this . bindings . ga_new ;
91- const ga_free = this . bindings . ga_free ;
92109 const ga_parse = this . bindings . ga_parse ;
93110 const ga_desugar = this . bindings . ga_desugar ;
94111 const ga_add_arg = this . bindings . ga_add_arg ;
@@ -692,6 +709,24 @@ function buildErrorNote(diagnostics: GraphAlgDiagnostic[]): HTMLQuoteElement {
692709 return quote ;
693710}
694711
712+ function buildCompileSuccessNote ( ) : HTMLQuoteElement {
713+ const quote = document . createElement ( "blockquote" ) ;
714+ quote . setAttribute ( 'class' , 'success-title' ) ;
715+ const messages = [
716+ "Compiled successfully" ,
717+ "Parser: OK, syntax is valid" ,
718+ "Type checker: OK, types are valid" ,
719+ ] ;
720+
721+ for ( let msg of messages ) {
722+ const pelem = document . createElement ( "p" ) ;
723+ pelem . textContent = msg ;
724+ quote . appendChild ( pelem ) ;
725+ }
726+
727+ return quote ;
728+ }
729+
695730function run ( editor : GraphAlgEditor , inst : PlaygroundInstance ) {
696731 const program = editor . editorView ?. state . doc . toString ( ) ;
697732 if ( ! program ) {
@@ -719,25 +754,57 @@ function run(editor: GraphAlgEditor, inst: PlaygroundInstance) {
719754 editor . outputContainer . replaceChildren ( details ) ;
720755}
721756
757+ function compile ( editor : GraphAlgEditor , inst : PlaygroundInstance ) {
758+ const program = editor . editorView ?. state . doc . toString ( ) ;
759+ if ( ! program ) {
760+ throw new Error ( "No program to compile" ) ;
761+ }
762+
763+ const diagnostics = inst . compile ( program ) ;
764+ let resultElem ;
765+ if ( diagnostics . length > 0 ) {
766+ resultElem = buildErrorNote ( diagnostics ) ;
767+ } else {
768+ // TODO: Build success note
769+ resultElem = buildCompileSuccessNote ( ) ;
770+ }
771+
772+ // Place output in a default-open accordion
773+ const details = document . createElement ( "details" ) ;
774+ details . setAttribute ( 'open' , 'true' ) ;
775+ const summary = document . createElement ( "summary" ) ;
776+ summary . textContent = "Output" ;
777+ details . append ( summary , resultElem ) ;
778+ editor . outputContainer . replaceChildren ( details ) ;
779+ }
780+
722781// Add run buttons
723782playgroundWasmBindings . onLoaded ( ( bindings : any ) => {
724783 const instance = new PlaygroundInstance ( bindings ) ;
725784
726785 for ( let editor of editors ) {
727- if ( ! editor . functionName ) {
728- // No function to run
729- continue ;
786+ if ( editor . functionName ) {
787+ const runButton = document . createElement ( "button" ) ;
788+ runButton . setAttribute ( 'type' , 'button' ) ;
789+ runButton . setAttribute ( 'name' , 'run' ) ;
790+ runButton . setAttribute ( 'class' , 'btn' ) ;
791+ runButton . textContent = `Run '${ editor . functionName } '` ;
792+ runButton . addEventListener ( 'click' , ( ) => {
793+ run ( editor , instance ) ;
794+ } ) ;
795+ editor . toolbar . appendChild ( runButton ) ;
796+ } else {
797+ // No function to run, compile only
798+ const compileButton = document . createElement ( "button" ) ;
799+ compileButton . setAttribute ( 'type' , 'button' ) ;
800+ compileButton . setAttribute ( 'name' , 'compile' ) ;
801+ compileButton . setAttribute ( 'class' , 'btn' ) ;
802+ compileButton . textContent = "Compile" ;
803+ compileButton . addEventListener ( 'click' , ( ) => {
804+ compile ( editor , instance ) ;
805+ } ) ;
806+ editor . toolbar . appendChild ( compileButton ) ;
730807 }
731-
732- const runButton = document . createElement ( "button" ) ;
733- runButton . setAttribute ( 'type' , 'button' ) ;
734- runButton . setAttribute ( 'name' , 'run' ) ;
735- runButton . setAttribute ( 'class' , 'btn' ) ;
736- runButton . textContent = `Run '${ editor . functionName } '` ;
737- runButton . addEventListener ( 'click' , ( ) => {
738- run ( editor , instance ) ;
739- } ) ;
740- editor . toolbar . appendChild ( runButton ) ;
741808 }
742809} ) ;
743810
0 commit comments