mirror of
https://github.com/simon987/Much-Assembly-Required-Frontend.git
synced 2025-04-20 19:06:46 +00:00
1 line
5.3 KiB
JavaScript
1 line
5.3 KiB
JavaScript
function removeComment(e){return e.indexOf(";")!==-1?e.substring(0,e.indexOf(";")):e}function checkForLabel(e,t){e=removeComment(e);var r;null!==(r=/\b\w*\b:/.exec(e))&&t.labels.push(r[0].substring(0,r[0].length-1))}function checkForSegmentDeclaration(e){var t=getTokens(e);return void 0!==t[0]&&(".data"===t[0].toLowerCase()||".text"===t[0].toLowerCase())}function checkForEQUInstruction(e,t,r){var n=getTokens(e);if(e.toLowerCase().indexOf(" equ ")!==-1||void 0!==n[1]&&"equ"===n[1].toLowerCase()){var o=Number(n[2]);return isNaN(o)||o!==Math.floor(o)?(t.annotations.push({row:r,column:0,text:"Usage: constant_name EQU immediate_value",type:"error"}),!0):(t.labels.push(n[0]),!0)}return!1}function getTokens(e){for(var t=e.split(/\s+/),r=0;r<t.length;r++)""===t[r]&&t.splice(r,1);return t}function removeLabel(e){return e.replace(/\b\w*\b:/,"")}function checkForORGInstruction(e,t,r){e=removeComment(e),e=removeLabel(e);var n=getTokens(e),o=n[0];if(void 0===o||"org"!==o.toLowerCase())return!1;if(console.log(n),n.length>1){var s=Number(n[1]);return!isNaN(s)&&s===Math.floor(s)||(t.annotations.push({row:r,column:0,text:"Invalid operand: "+n[1],type:"error"}),!0)}}function parseDWInstruction(e,t,r){if(e=e.trim(),"dw"===e.substr(0,2).toLowerCase()){for(var n=e.substr(2,e.length).split(/,(?=(?:[^"]*"[^"]*")*[^"]*$)/,-1),o=0;o<n.length;o++){n[o]=n[o].trim();var s=getTokens(n[o]);if(2===s.length&&getOperandType(s[0],t)===OPERAND_IMM&&s[1].toLowerCase().startsWith("dup(")&&s[1].endsWith(")")&&getOperandType(s[1].substring(4,s[1].indexOf(")")),t)===OPERAND_IMM);else if(n[o].startsWith('"')&&n[o].endsWith('"'));else if(getOperandType(n[o],t)!==OPERAND_IMM)return t.annotations.push({row:r,column:0,text:"Usage: DW IMM, IMM ...",type:"error"}),!0}return!0}return!1}function getOperandType(e,t){if(e=e.trim(),""===e)return OPERAND_INVALID;if(!isNaN(Number(e))&&Number(e)===Math.floor(Number(e))&&e.indexOf("o")===-1&&e.indexOf("e")===-1)return OPERAND_IMM;if(new RegExp("^(a|b|c|d|x|y|bp|sp)$").test(e.toLowerCase()))return OPERAND_REG;for(r=0;r<t.labels.length;r++)if(e===t.labels[r])return OPERAND_IMM;if(e.startsWith("[")&&e.endsWith("]")){if(e=e.replace("[","").replace("]",""),!isNaN(Number(e))&&Number(e)===Math.floor(Number(e)))return OPERAND_MEM_IMM;for(var r=0;r<t.labels.length;r++)if(e===t.labels[r])return OPERAND_MEM_IMM;var n="";if(new RegExp("^(bp|sp)$").test(e.toLowerCase().substring(0,2).toLowerCase()))n=e.substring(2);else{if(!new RegExp("^(a|b|c|d|x|y)$").test(e.toLowerCase().substring(0,1).toLowerCase()))return OPERAND_INVALID;n=e.substring(1)}if(""===n.replace(/\s+/g,""))return OPERAND_MEM_REG;for(n=n.replace(/\s+/g,""),r=0;r<t.labels.length;r++)if(n.substring(1)===t.labels[r])return OPERAND_MEM_REG;if(!isNaN(Number(n))&&Number(n)===Math.floor(Number(n)))return OPERAND_MEM_REG}return OPERAND_INVALID}function parseInstruction(e,t,r){e=removeComment(e),e=removeLabel(e);var n=getTokens(e),o=n[0];if(void 0!==o&&""!==o&&!parseDWInstruction(e,t,r))if(new RegExp("\\b(?:mov|add|sub|and|or|test|cmp|shl|shr|mul|push|pop|div|xor|hwi|hwq|nop|neg|call|ret|jmp|jnz|jg|jl|jge|jle|int|jz|js|jns|brk|not|jc|jnc|ror|rol|sal|sar|jo|jno|pushf|popf)\\b").test(o.toLowerCase()))if(e.indexOf(",")!==-1){var s=e.substring(e.indexOf(o)+o.length,e.indexOf(",")),i=e.substring(e.indexOf(",")+1).trim();if(!new RegExp("\\b(?:mov|add|sub|and|or|test|cmp|shl|shr|xor|rol|ror|sal|sar)\\b").test(o.toLowerCase()))return void t.annotations.push({row:r,column:0,text:o+" instruction with 2 operands is illegal",type:"error"});var a=getOperandType(s,t),u=getOperandType(i,t);if(a===OPERAND_INVALID)return void t.annotations.push({row:r,column:0,text:"Invalid operand: "+s,type:"error"});if(u===OPERAND_INVALID)return void t.annotations.push({row:r,column:0,text:"Invalid operand: "+i,type:"error"});a===OPERAND_IMM&&t.annotations.push({row:r,column:0,text:"Destination operand can't be an immediate value",type:"error"})}else if(n.length>1){if(s=e.substring(e.indexOf(o)+o.length).trim(),!new RegExp("\\b(?:push|mul|pop|div|neg|call|jnz|jg|jl|jge|jle|hwi|hwq|jz|js|jns|ret|jmp|not|jc|jnc|jo|jno)\\b").test(o.toLowerCase()))return void t.annotations.push({row:r,column:0,text:o+" instruction with 1 operand is illegal",type:"error"});getOperandType(s,t)===OPERAND_INVALID&&t.annotations.push({row:r,column:0,text:"Invalid operand: "+s,type:"error"})}else new RegExp("\\b(?:ret|brk|nop|pushf|popf)\\b").test(o.toLowerCase())||t.annotations.push({row:r,column:0,text:o+" instruction with no operand is illegal",type:"error"});else t.annotations.push({row:r,column:0,text:"Unknown mnemonic: "+o,type:"error"})}function parse(){for(var e=ace.edit("editor").getValue(),t=e.split("\n"),r={labels:[],annotations:[]},n=0;n<t.length;n++)checkForLabel(t[n],r);for(n=0;n<t.length;n++)checkForSegmentDeclaration(t[n])||checkForEQUInstruction(t[n],r,n)||checkForORGInstruction(t[n],r,n)||parseInstruction(t[n],r,n);editor.getSession().setAnnotations(r.annotations)}function gameClick(){document.getElementById("editorBtns").setAttribute("style","display: none"),document.getElementById("gameBtns").setAttribute("style","")}function editorClick(){document.getElementById("editorBtns").setAttribute("style",""),document.getElementById("gameBtns").setAttribute("style","display: none")}OPERAND_INVALID=-1,OPERAND_REG=0,OPERAND_MEM_IMM=1,OPERAND_MEM_REG=2,OPERAND_IMM=3,editor=ace.edit("editor"),editor.session.setOption("useWorker",!1),editor.$blockScrolling=1/0,editor.on("change",parse); |