From 989295578f75d0455ab211ddcc5fa72d7dd47c18 Mon Sep 17 00:00:00 2001 From: jacquej96 <32223123+jacquej96@users.noreply.github.com> Date: Wed, 16 Oct 2019 09:42:59 -0400 Subject: [PATCH 1/5] Create produceError function --- Server/src/main/resources/static/js/editor.js | 72 +++++-------------- 1 file changed, 18 insertions(+), 54 deletions(-) diff --git a/Server/src/main/resources/static/js/editor.js b/Server/src/main/resources/static/js/editor.js index d4f6d13..bcd18eb 100644 --- a/Server/src/main/resources/static/js/editor.js +++ b/Server/src/main/resources/static/js/editor.js @@ -260,6 +260,15 @@ function getOperandType(text, result) { } +function produceError(result, currentLine, errorString) { + result.annotations.push({ + row: currentLine, + column: 0, + text: errorString, + type: "error" + }); +} + function parseInstruction(line, result, currentLine) { line = removeComment(line); line = removeLabel(line); @@ -287,12 +296,7 @@ function parseInstruction(line, result, currentLine) { //Validate operand number if (!new RegExp('\\b(?:mov|add|sub|and|or|test|cmp|shl|shr|xor|rol|ror|sal|sar|rcl|xchg|rcr)\\b').test(mnemonic.toLowerCase())) { - result.annotations.push({ - row: currentLine, - column: 0, - text: mnemonic + " instruction with 2 operands is illegal", - type: "error" - }); + produceError(result, currentLine, mnemonic + " instruction with 2 operands is illegal"); return; } @@ -300,32 +304,17 @@ function parseInstruction(line, result, currentLine) { var o1Type = getOperandType(strO1, result); var o2Type = getOperandType(strO2, result); if (o1Type === OPERAND_INVALID) { - result.annotations.push({ - row: currentLine, - column: 0, - text: "Invalid operand: " + strO1, - type: "error" - }); + produceError(result, currentLine, "Invalid operand: " + strO1); return; } if (o2Type === OPERAND_INVALID) { - result.annotations.push({ - row: currentLine, - column: 0, - text: "Invalid operand: " + strO2, - type: "error" - }); + produceError(result, currentLine, "Invalid operand: " + strO2); return; } //Check for illegal operand combos: if (o1Type === OPERAND_IMM) { - result.annotations.push({ - row: currentLine, - column: 0, - text: "Destination operand can't be an immediate value", - type: "error" - }); + produceError(result, currentLine, "Destination operand can't be an immediate value"); } @@ -335,33 +324,18 @@ function parseInstruction(line, result, currentLine) { //Validate operand number if (!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|inc|dec|ja|jna|seta|setnbe|setae|setnb|setnc|setbe|setna|setb|setc|setnae|sete|setz|setne|setnz|setg|setnle|setge|setnl|setle|setng|setl|setnge|seto|setno|sets|setns)\\b').test(mnemonic.toLowerCase())) { - result.annotations.push({ - row: currentLine, - column: 0, - text: mnemonic + " instruction with 1 operand is illegal", - type: "error" - }); + produceError(result, currentLine, mnemonic + " instruction with 1 operand is illegal"); return; } //Validate operand type if (getOperandType(strO1, result) === OPERAND_INVALID) { - result.annotations.push({ - row: currentLine, - column: 0, - text: "Invalid operand: " + strO1, - type: "error" - }); + produceError(result, currentLine, "Invalid operand: " + strO1); } if (new RegExp('\\b(?:seta|setnbe|setae|setnb|setnc|setbe|setna|setb|setc|setnae|sete|setz|setne|setnz|setg|setnle|setge|setnl|setle|setng|setl|setnge|seto|setno|sets|setns)\\b').test(mnemonic.toLowerCase())) { if (getOperandType(strO1, result) === OPERAND_IMM) { - result.annotations.push({ - row: currentLine, - column: 0, - text: "Invalid operand type: " + strO1, - type: "error" - }); + produceError(result, currentLine, "Invalid operand type: " + strO1); } } @@ -370,23 +344,13 @@ function parseInstruction(line, result, currentLine) { if (!new RegExp('\\b(?:ret|brk|nop|pushf|popf)\\b').test(mnemonic.toLowerCase())) { //Validate operand number - result.annotations.push({ - row: currentLine, - column: 0, - text: mnemonic + " instruction with no operand is illegal", - type: "error" - }); + produceError(result, currentLine, mnemonic + " instruction with no operand is illegal"); } } } else { - result.annotations.push({ - row: currentLine, - column: 0, - text: "Unknown mnemonic: " + mnemonic, - type: "error" - }); + produceError(result, currentLine, "Unknown mnemonic: " + mnemonic); } } From 9efb79118f6726da8d75b386248e1ba6b454855a Mon Sep 17 00:00:00 2001 From: jacquej96 <32223123+jacquej96@users.noreply.github.com> Date: Wed, 16 Oct 2019 10:33:49 -0400 Subject: [PATCH 2/5] Create helper functions for clarity --- Server/src/main/resources/static/js/editor.js | 46 ++++++++++++------- 1 file changed, 29 insertions(+), 17 deletions(-) diff --git a/Server/src/main/resources/static/js/editor.js b/Server/src/main/resources/static/js/editor.js index bcd18eb..4d07294 100644 --- a/Server/src/main/resources/static/js/editor.js +++ b/Server/src/main/resources/static/js/editor.js @@ -269,6 +269,25 @@ function produceError(result, currentLine, errorString) { }); } +function isValidMnemonic(mnemonic) { + return isDoubleOpMnemonic(mnemonic) || isSingleOpMnemonic(mnemonic) || isZeroOpMnemonic(mnemonic); +} + +function isDoubleOpMnemonic(mnemonic) { + return new RegExp('\\b(?:mov|add|sub|and|or|test|cmp|shl|shr|xor|rol|ror|sal|sar|rcl|xchg|rcr)\\b').test(mnemonic.toLowerCase()); +} + +function isSingleOpMnemonic(mnemonic) { + return 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|inc|dec|ja|jna|seta|setnbe|setae|setnb|setnc|setbe|setna|setb|setc|' + + 'setnae|sete|setz|setne|setnz|setg|setnle|setge|setnl|setle|setng|setl|setnge|seto|' + + 'setno|sets|setns)\\b').test(mnemonic.toLowerCase()); +} + +function isZeroOpMnemonic(mnemonic) { + return new RegExp('\\b(?:ret|brk|nop|pushf|popf)\\b').test(mnemonic.toLowerCase()); +} + function parseInstruction(line, result, currentLine) { line = removeComment(line); line = removeLabel(line); @@ -283,22 +302,18 @@ function parseInstruction(line, result, currentLine) { if (!parseDWInstruction(line, result, currentLine)) { - if (new RegExp('\\b(?:mov|add|sub|and|or|test|cmp|shl|shr|mul|push|pop|div|xor|hwi|hwq|nop|neg|' + - 'seta|setnbe|setae|setnb|setnc|setbe|setna|setb|setc|setnae|sete|setz|setne|setnz|setg|setnle|setge|setnl|setle|setng|setl|setnge|seto|setno|sets|setns|' + - 'call|ret|jmp|jnz|jg|jl|jge|jle|int|jz|js|jns|brk|not|jc|jnc|ror|rol|sal|sar|jo|jno|inc|dec|rcl|xchg|rcr|pushf|popf|ja|jna)\\b').test(mnemonic.toLowerCase())) { + if (isValidMnemonic(mnemonic)) { if (line.indexOf(",") !== -1) { //2 Operands - var strO1 = line.substring(line.indexOf(mnemonic) + mnemonic.length, line.indexOf(',')); - var strO2 = line.substring(line.indexOf(',') + 1).trim(); - - - //Validate operand number - if (!new RegExp('\\b(?:mov|add|sub|and|or|test|cmp|shl|shr|xor|rol|ror|sal|sar|rcl|xchg|rcr)\\b').test(mnemonic.toLowerCase())) { + if (!isDoubleOpMnemonic(mnemonic)) { produceError(result, currentLine, mnemonic + " instruction with 2 operands is illegal"); return; } + + var strO1 = line.substring(line.indexOf(mnemonic) + mnemonic.length, line.indexOf(',')); + var strO2 = line.substring(line.indexOf(',') + 1).trim(); //Validate operand type var o1Type = getOperandType(strO1, result); @@ -320,13 +335,12 @@ function parseInstruction(line, result, currentLine) { } else if (tokens.length > 1) { //1 Operand - strO1 = line.substring(line.indexOf(mnemonic) + mnemonic.length).trim(); - - //Validate operand number - if (!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|inc|dec|ja|jna|seta|setnbe|setae|setnb|setnc|setbe|setna|setb|setc|setnae|sete|setz|setne|setnz|setg|setnle|setge|setnl|setle|setng|setl|setnge|seto|setno|sets|setns)\\b').test(mnemonic.toLowerCase())) { + if (!isSingleOpMnemonic(mnemonic)) { produceError(result, currentLine, mnemonic + " instruction with 1 operand is illegal"); return; } + + strO1 = line.substring(line.indexOf(mnemonic) + mnemonic.length).trim(); //Validate operand type if (getOperandType(strO1, result) === OPERAND_INVALID) { @@ -340,10 +354,8 @@ function parseInstruction(line, result, currentLine) { } } else { - //No operand - if (!new RegExp('\\b(?:ret|brk|nop|pushf|popf)\\b').test(mnemonic.toLowerCase())) { - - //Validate operand number + //No Operand + if (!isZeroOpMnemonic(mnemonic)) { produceError(result, currentLine, mnemonic + " instruction with no operand is illegal"); } } From 51527ae95bdb04c4660630c206e1147d0cc00e4d Mon Sep 17 00:00:00 2001 From: jacquej96 <32223123+jacquej96@users.noreply.github.com> Date: Wed, 16 Oct 2019 13:55:12 -0400 Subject: [PATCH 3/5] Reuse error function throughout file --- Server/src/main/resources/static/js/editor.js | 31 +++---------------- 1 file changed, 4 insertions(+), 27 deletions(-) diff --git a/Server/src/main/resources/static/js/editor.js b/Server/src/main/resources/static/js/editor.js index 4d07294..1b374a0 100644 --- a/Server/src/main/resources/static/js/editor.js +++ b/Server/src/main/resources/static/js/editor.js @@ -54,12 +54,7 @@ function checkForEQUInstruction(line, result, currentLine) { result.labels.push(tokens[0]); return true; } else { - result.annotations.push({ - row: currentLine, - column: 0, - text: "Usage: constant_name EQU immediate_value", - type: "error" - }); + produceError(result, currentLine, "Usage: constant_name EQU immediate_value"); return true; } } else { @@ -102,12 +97,7 @@ function checkForORGInstruction(line, result, currentLine) { if (!isNaN(num) && num === Math.floor(num)) { return true; } else { - result.annotations.push({ - row: currentLine, - column: 0, - text: "Invalid operand: " + tokens[1], - type: "error" - }); + produceError(result, currentLine, "Invalid operand: " + tokens[1]); return true } } @@ -140,13 +130,7 @@ function parseDWInstruction(line, result, currentLine) { var strText = values[i].substr(1, values[i].length - 2); if (strText.match(MALFORMED_UTF16_RE) != null) { - - result.annotations.push({ - row: currentLine, - column: 0, - text: "Malformed UTF-16 escape sequence", - type: "error" - }); + produceError(result, currentLine, "Malformed UTF-16 escape sequence"); return true; } @@ -157,15 +141,8 @@ function parseDWInstruction(line, result, currentLine) { // console.log("is Imm " + values[i]); } else { - - result.annotations.push({ - row: currentLine, - column: 0, - text: "Usage: DW IMM, IMM ...", - type: "error" - }); + produceError(result, currentLine, "Usage: DW IMM, IMM ..."); return true; - } } From 8cbf2b45c3ccf8ca28e4f7912df10d7c844554c6 Mon Sep 17 00:00:00 2001 From: jacquej96 <32223123+jacquej96@users.noreply.github.com> Date: Wed, 16 Oct 2019 14:09:58 -0400 Subject: [PATCH 4/5] Rename vars --- Server/src/main/resources/static/js/editor.js | 32 +++++++++---------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/Server/src/main/resources/static/js/editor.js b/Server/src/main/resources/static/js/editor.js index 1b374a0..4656af6 100644 --- a/Server/src/main/resources/static/js/editor.js +++ b/Server/src/main/resources/static/js/editor.js @@ -237,11 +237,11 @@ function getOperandType(text, result) { } -function produceError(result, currentLine, errorString) { +function produceError(result, currentLine, explanation) { result.annotations.push({ row: currentLine, column: 0, - text: errorString, + text: explanation, type: "error" }); } @@ -289,23 +289,23 @@ function parseInstruction(line, result, currentLine) { return; } - var strO1 = line.substring(line.indexOf(mnemonic) + mnemonic.length, line.indexOf(',')); - var strO2 = line.substring(line.indexOf(',') + 1).trim(); + var op1 = line.substring(line.indexOf(mnemonic) + mnemonic.length, line.indexOf(',')); + var op2 = line.substring(line.indexOf(',') + 1).trim(); //Validate operand type - var o1Type = getOperandType(strO1, result); - var o2Type = getOperandType(strO2, result); - if (o1Type === OPERAND_INVALID) { - produceError(result, currentLine, "Invalid operand: " + strO1); + var op1Type = getOperandType(op1, result); + var op2Type = getOperandType(op2, result); + if (op1Type === OPERAND_INVALID) { + produceError(result, currentLine, "Invalid operand: " + op1); return; } - if (o2Type === OPERAND_INVALID) { - produceError(result, currentLine, "Invalid operand: " + strO2); + if (op2Type === OPERAND_INVALID) { + produceError(result, currentLine, "Invalid operand: " + op2); return; } //Check for illegal operand combos: - if (o1Type === OPERAND_IMM) { + if (op1Type === OPERAND_IMM) { produceError(result, currentLine, "Destination operand can't be an immediate value"); } @@ -317,16 +317,16 @@ function parseInstruction(line, result, currentLine) { return; } - strO1 = line.substring(line.indexOf(mnemonic) + mnemonic.length).trim(); + var op1 = line.substring(line.indexOf(mnemonic) + mnemonic.length).trim(); //Validate operand type - if (getOperandType(strO1, result) === OPERAND_INVALID) { - produceError(result, currentLine, "Invalid operand: " + strO1); + if (getOperandType(op1, result) === OPERAND_INVALID) { + produceError(result, currentLine, "Invalid operand: " + op1); } if (new RegExp('\\b(?:seta|setnbe|setae|setnb|setnc|setbe|setna|setb|setc|setnae|sete|setz|setne|setnz|setg|setnle|setge|setnl|setle|setng|setl|setnge|seto|setno|sets|setns)\\b').test(mnemonic.toLowerCase())) { - if (getOperandType(strO1, result) === OPERAND_IMM) { - produceError(result, currentLine, "Invalid operand type: " + strO1); + if (getOperandType(op1, result) === OPERAND_IMM) { + produceError(result, currentLine, "Invalid operand type: " + op1); } } From e19dc81b437c991d1560e5c27f06adc60cbc2ce5 Mon Sep 17 00:00:00 2001 From: jacquej96 <32223123+jacquej96@users.noreply.github.com> Date: Mon, 21 Oct 2019 14:20:58 -0400 Subject: [PATCH 5/5] Move Set mnemonics to function --- Server/src/main/resources/static/js/editor.js | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/Server/src/main/resources/static/js/editor.js b/Server/src/main/resources/static/js/editor.js index 4656af6..eac1551 100644 --- a/Server/src/main/resources/static/js/editor.js +++ b/Server/src/main/resources/static/js/editor.js @@ -256,15 +256,19 @@ function isDoubleOpMnemonic(mnemonic) { function isSingleOpMnemonic(mnemonic) { return 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|inc|dec|ja|jna|seta|setnbe|setae|setnb|setnc|setbe|setna|setb|setc|' + - 'setnae|sete|setz|setne|setnz|setg|setnle|setge|setnl|setle|setng|setl|setnge|seto|' + - 'setno|sets|setns)\\b').test(mnemonic.toLowerCase()); + 'jc|jnc|jo|jno|inc|dec|ja|jna)\\b').test(mnemonic.toLowerCase()) || + isSetMnemonic(mnemonic); } function isZeroOpMnemonic(mnemonic) { return new RegExp('\\b(?:ret|brk|nop|pushf|popf)\\b').test(mnemonic.toLowerCase()); } +function isSetMnemonic(mnemonic) { + return new RegExp('\\b(?:seta|setnbe|setae|setnb|setnc|setbe|setna|setb|setc|setnae|sete|setz|setne|' + + 'setnz|setg|setnle|setge|setnl|setle|setng|setl|setnge|seto|setno|sets|setns)\\b').test(mnemonic.toLowerCase()); +} + function parseInstruction(line, result, currentLine) { line = removeComment(line); line = removeLabel(line); @@ -276,7 +280,6 @@ function parseInstruction(line, result, currentLine) { return; //Line is empty } - if (!parseDWInstruction(line, result, currentLine)) { if (isValidMnemonic(mnemonic)) { @@ -324,7 +327,7 @@ function parseInstruction(line, result, currentLine) { produceError(result, currentLine, "Invalid operand: " + op1); } - if (new RegExp('\\b(?:seta|setnbe|setae|setnb|setnc|setbe|setna|setb|setc|setnae|sete|setz|setne|setnz|setg|setnle|setge|setnl|setle|setng|setl|setnge|seto|setno|sets|setns)\\b').test(mnemonic.toLowerCase())) { + if (isSetMnemonic(mnemonic)) { if (getOperandType(op1, result) === OPERAND_IMM) { produceError(result, currentLine, "Invalid operand type: " + op1); } @@ -341,7 +344,6 @@ function parseInstruction(line, result, currentLine) { } else { produceError(result, currentLine, "Unknown mnemonic: " + mnemonic); } - } }