Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(interface): show load code errors #145

Merged
merged 3 commits into from
Apr 3, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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