Skip to content

Commit

Permalink
fix(interface): show load code errors (#145)
Browse files Browse the repository at this point in the history
* fix(interface): Show load code errors

* style: enhance load modal layout and errors

* test: update error message in unit tests

---------

Co-authored-by: Óscar Carrasco <me@oxca.be>
  • Loading branch information
endes0 and oxcabe authored Apr 3, 2024
1 parent 8e072fa commit b9010f8
Show file tree
Hide file tree
Showing 5 changed files with 81 additions and 59 deletions.
2 changes: 1 addition & 1 deletion src/core/Common/CodeParser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,7 @@ const opcodeParser = apply(
if (opcode !== -1) {
return { opcode: opcode, pos: opcodeTok.pos };
}
throw new TokenError(opcodeTok.pos, `Unknown opcode ${opcodeTok.text}`);
throw new TokenError(opcodeTok.pos, `Unknown opcode "${opcodeTok.text}".`);
},
);

Expand Down
128 changes: 76 additions & 52 deletions src/interface/components/Superescalar/modal/LoadModalComponent.tsx
Original file line number Diff line number Diff line change
@@ -1,17 +1,44 @@
import { toggleLoadModal } from "@/interface/actions/modals";
import FileReaderInput from "@/interface/components/Common/FileReaderInput";
import { Button, Modal } from "react-bootstrap";
import { Alert, Button, Form, Modal, Stack } from "react-bootstrap";
import { useTranslation } from "react-i18next";
import { connect } from "react-redux";
import { bindActionCreators } from "redux";

import { Code } from "@/core/Common/Code";
import SuperescalarIntegration from "@/integration/superescalar-integration";
import { useState } from "react";

const DEFAULT_MODAL_CODE = `
ADDI R2 R0 #50
ADDI R3 R0 #70
ADDI R4 R0 #40
LF F0 (R4)
ADDI R5 R2 #16
// Setup Code
LF F1 (R2)
ADDF F2 F1 F0
LF F1 1(R2)
ADDI R2 R2 #2
LOOP:
SF F2 (R3)
ADDF F2 F1 F0
LF F1 (R2)
ADDI R2 R2 #1
ADDI R3 R3 #1
BNE R2 R5 LOOP
// Ending Code
SF F2 (R3)
ADDF F2 F1 F0
SF F2 1(R3)
`.trim();

const mapStateToProps = (state) => {
return {
isLoadModalOpen: state.Ui.isLoadModalOpen,
error: "",
};
};

Expand All @@ -24,90 +51,87 @@ export type LoadModalComponentProps = ReturnType<typeof mapStateToProps> &

export const LoadModalComponent = ({
isLoadModalOpen,
error: modalError,
actions,
}: LoadModalComponentProps) => {
const [modalError, setModalError] = useState("");
const [modalCode, setModalCode] = useState(DEFAULT_MODAL_CODE);
const [t] = useTranslation();

const close = () => {
actions.toggleLoadModal(false);
};

const handleInputFileChange = (_, results) => {
for (const result of results) {
const [e, file] = result;
const a = document.getElementById("codeInput") as HTMLInputElement;
a.value = e.target.result;
}
const loadCodeFromFile = ([[fileContent]]) => {
setModalCode(fileContent.target.result);
};

const loadCode = () => {
const code = new Code();

try {
const code = new Code();
code.load(
(document.getElementById("codeInput") as HTMLInputElement).value,
);
modalError = "";
code.load(modalCode);
SuperescalarIntegration.loadCode(code);

setModalError("");
close();
} catch (error) {
// Check if error has the property position. Checking instance of TokenError not working
modalError = error.pos
? `[${error.pos?.rowBegin}:${error.pos?.columnBegin}]: ${error.errorMessage}`
const errorMessage = error.pos
? `Syntax error at line ${error.pos?.rowBegin}, column ${error.pos?.columnBegin}:
${error.errorMessage}`
: error.message;

setModalError(errorMessage);
}
};

return (
<Modal className="smd-load_modal" show={isLoadModalOpen} onHide={close}>
<Modal show={isLoadModalOpen} onHide={close}>
<Modal.Header closeButton>
<Modal.Title>{t("loadModal.title")}</Modal.Title>
</Modal.Header>
<Modal.Body>
<textarea
id="codeInput"
defaultValue={` ADDI R2 R0 #50
ADDI R3 R0 #70
ADDI R4 R0 #40
LF F0 (R4)
ADDI R5 R2 #16
// Setup Code
LF F1 (R2)
ADDF F2 F1 F0
LF F1 1(R2)
ADDI R2 R2 #2
LOOP:
SF F2 (R3)
ADDF F2 F1 F0
LF F1 (R2)
ADDI R2 R2 #1
ADDI R3 R3 #1
BNE R2 R5 LOOP
// Ending Code
SF F2 (R3)
ADDF F2 F1 F0
SF F2 1(R3)`}
/>
<div className="smd-load_modal-errors">
{modalError && <div className="smd-forms_error">{modalError}</div>}
</div>
<Stack gap={0}>
<Form>
<Form.Control
as="textarea"
style={{ resize: "none" }}
className={`smd-monospace mx-0 ${
modalError
? "border-bottom-0 rounded-bottom-0 border-danger-subtle"
: ""
}`}
value={modalCode}
onChange={(event) => {
setModalCode(event.target.value);
}}
/>
</Form>
<div>
{modalError && (
<Alert className="border-top-0 rounded-top-0" variant={"danger"}>
{modalError}
</Alert>
)}
</div>
</Stack>
</Modal.Body>

<Modal.Footer className="smd-load_modal-footer">
<div className="smd-load_modal-file_input">
<Modal.Footer>
<div>
<FileReaderInput
as="text"
onChange={handleInputFileChange}
onChange={(_, files) => {
loadCodeFromFile(files);
}}
accept=".pla"
>
<Button className="btn btn-primary">
{t("commonButtons.loadFromFile")}
</Button>
<Button>{t("commonButtons.loadFromFile")}</Button>
</FileReaderInput>
</div>
<div className="smd-load_modal-actions">
<div>
<Button onClick={close}>{t("commonButtons.close")}</Button>
<Button className="btn btn-primary" onClick={loadCode}>
<Button className="ml-2" onClick={loadCode}>
{t("loadModal.load")}
</Button>
</div>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,7 @@
height: 70vh;
margin: auto 10px;

font-size: 1rem;
font-family: Arial;
font-family: 'Courier New', Courier, monospace;
}

.btn.btn-primary {
Expand Down
3 changes: 1 addition & 2 deletions src/interface/styles/components/LoadModalComponent.scss
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,7 @@
width: 100%;
height: 70vh;

font-size: .875rem;
font-family: Arial;
font-family: 'Courier New', Courier, monospace;
}

.btn.btn-primary {
Expand Down
4 changes: 2 additions & 2 deletions src/test/unit/core/Common/Code.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ test("Parsing opcodes errors are being thrown", (t) => {
`;
const code: Code = new Code();
expect(() => code.load(input)).toThrowError(
'{"index":31,"rowBegin":4,"columnBegin":5,"rowEnd":4,"columnEnd":8}: Unknown opcode ADF',
'{"index":31,"rowBegin":4,"columnBegin":5,"rowEnd":4,"columnEnd":8}: Unknown opcode "ADF"',
);
});

Expand Down Expand Up @@ -130,7 +130,7 @@ test("Parsing strange inmediates throws errors", (t) => {
const code: Code = new Code();

expect(() => code.load(input)).toThrowError(
'{"index":16,"rowBegin":2,"columnBegin":15,"rowEnd":2,"columnEnd":17}: Unknown opcode x0',
'{"index":16,"rowBegin":2,"columnBegin":15,"rowEnd":2,"columnEnd":17}: Unknown opcode "x0"',
);
expect(() => code.load(inpu2)).toThrowError(
'{"index":16,"rowBegin":2,"columnBegin":15,"rowEnd":2,"columnEnd":15}: Unable to tokenize the rest of the input: .0',
Expand Down

0 comments on commit b9010f8

Please sign in to comment.