// Setup editros const grammar = ace.edit("grammar-editor"); grammar.setShowPrintMargin(false); grammar.setValue(localStorage.getItem('grammarText') || ''); grammar.moveCursorTo(0, 0); const code = ace.edit("code-editor"); code.setShowPrintMargin(false); code.setValue(localStorage.getItem('codeText') || ''); code.moveCursorTo(0, 0); const codeAst = ace.edit("code-ast"); codeAst.setShowPrintMargin(false); codeAst.setOptions({ readOnly: true, highlightActiveLine: false, highlightGutterLine: false }) codeAst.renderer.$cursorLayer.element.style.opacity=0; const codeAstOptimized = ace.edit("code-ast-optimized"); codeAstOptimized.setShowPrintMargin(false); codeAstOptimized.setOptions({ readOnly: true, highlightActiveLine: false, highlightGutterLine: false }) codeAstOptimized.renderer.$cursorLayer.element.style.opacity=0; $('#opt_mode').val(localStorage.getItem('optimazationMode') || 'all'); function escapeHtml(unsafe) { return unsafe .replace(/&/g, "&") .replace(/</g, "<") .replace(/>/g, ">") .replace(/"/g, """) .replace(/'/g, "'"); } function generateErrorListHTML(errors) { let html = '<ul>'; html += $.map(errors, function (x) { return '<li data-ln="' + x.ln + '" data-col="' + x.col + '"><span>' + x.ln + ':' + x.col + '</span> <span>' + escapeHtml(x.msg) + '</span></li>'; }).join(''); html += '<ul>'; return html; } function parse() { const $grammarValidation = $('#grammar-validation'); const $grammarInfo = $('#grammar-info'); const grammarText = grammar.getValue(); const $codeValidation = $('#code-validation'); const $codeInfo = $('#code-info'); const codeText = code.getValue(); const optimazationMode = $('#opt_mode').val(); localStorage.setItem('grammarText', grammarText); localStorage.setItem('codeText', codeText); localStorage.setItem('optimazationMode', optimazationMode); $grammarInfo.html(''); $grammarValidation.hide(); $codeInfo.html(''); $codeValidation.hide(); codeAst.setValue(''); codeAstOptimized.setValue(''); if (grammarText.length === 0) { return; } const mode = optimazationMode == 'all'; const data = JSON.parse(Module.lint(grammarText, codeText, mode)); if (data.grammar_valid) { $grammarValidation.removeClass('editor-validation-invalid').text('Valid').show(); codeAst.insert(data.ast); codeAstOptimized.insert(data.astOptimized); if (data.source_valid) { $codeValidation.removeClass('editor-validation-invalid').text('Valid').show(); } else { $codeValidation.addClass('editor-validation-invalid').text('Invalid').show(); } if (data.code.length > 0) { const html = generateErrorListHTML(data.code); $codeInfo.html(html); } } else { $grammarValidation.addClass('editor-validation-invalid').text('Invalid').show(); } if (data.grammar.length > 0) { const html = generateErrorListHTML(data.grammar); $grammarInfo.html(html); } } // Event handing for text editiing let timer; function setupTimer() { clearTimeout(timer); timer = setTimeout(parse, 750); }; grammar.getSession().on('change', setupTimer); code.getSession().on('change', setupTimer); // Event handing in the info area function makeOnClickInInfo(editor) { return function () { const el = $(this); editor.navigateTo(el.data('ln') - 1, el.data('col') - 1); editor.focus(); } }; $('#grammar-info').on('click', 'li', makeOnClickInInfo(grammar)); $('#code-info').on('click', 'li', makeOnClickInInfo(code)); // Event handing in the AST optimazation $('#opt_mode').on('change', setupTimer); // Show page $('#main').css({ 'display': 'flex', }); // WebAssembly var Module = { onRuntimeInitialized: function() { // Initial parse parse(); } };