Skip to content

Commit

Permalink
Move program code input to edit mode
Browse files Browse the repository at this point in the history
  • Loading branch information
wkwiatek committed Dec 9, 2024
1 parent f9b10f9 commit b298c54
Show file tree
Hide file tree
Showing 8 changed files with 97 additions and 90 deletions.
53 changes: 42 additions & 11 deletions src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,13 +21,19 @@ import { MobileRegisters } from "./components/MobileRegisters";
import { MobileKnowledgeBase } from "./components/KnowledgeBase/Mobile";
import { Assembly } from "./components/ProgramLoader/Assembly";
import { useAppDispatch, useAppSelector } from "@/store/hooks.ts";
import { setClickedInstruction, setInstructionMode, setIsProgramEditMode } from "@/store/debugger/debuggerSlice.ts";
import {
setClickedInstruction,
setInstructionMode,
setIsProgramEditMode,
setIsProgramInvalid,
} from "@/store/debugger/debuggerSlice.ts";
import { MemoryPreview } from "@/components/MemoryPreview";
import { DebuggerControlls } from "./components/DebuggerControlls";
import { useDebuggerActions } from "./hooks/useDebuggerActions";
import { Loader } from "./components/ProgramLoader/Loader";
import classNames from "classnames";
import { DebuggerSettings } from "./components/DebuggerSettings";
import { ProgramTextLoader } from "@/components/ProgramTextLoader";

const DebuggerContent = () => {
const dispatch = useAppDispatch();
Expand All @@ -36,7 +42,7 @@ const DebuggerContent = () => {
program,
initialState,
isProgramEditMode,
isAsmError,
isProgramInvalid,
programPreviewResult,
clickedInstruction,
instructionMode,
Expand Down Expand Up @@ -79,11 +85,37 @@ const DebuggerContent = () => {
<>
{isProgramEditMode && (
<div className="border-2 rounded-md h-full p-2 pt-8">
<Assembly
program={program}
onProgramLoad={debuggerActions.handleProgramLoad}
initialState={initialState}
/>
{instructionMode === InstructionMode.ASM ? (
<Assembly
program={program}
onProgramLoad={debuggerActions.handleProgramLoad}
initialState={initialState}
/>
) : (
<ProgramTextLoader
program={program}
setProgram={(program, error) => {
if (error) {
dispatch(setIsProgramInvalid(true));
}

if (!error && program) {
debuggerActions.handleProgramLoad({
initial: initialState,
program: program || [],
name: "custom",
});
}
// onProgramLoad({ initial: initialState, program, name: "custom" }, error);
// if (program) {
// setTempProgram(program);
// onProgramLoad({ initial, program, name: "custom" }, error);
// } else {
// onProgramLoad(undefined, error);
// }
}}
/>
)}
</div>
)}

Expand Down Expand Up @@ -144,7 +176,6 @@ const DebuggerContent = () => {
<div className={`flex items-center space-x-2 ${!program.length ? "invisible" : "visible"}`}>
<Label htmlFor="instruction-mode">ASM</Label>
<Switch
disabled={isProgramEditMode}
id="instruction-mode"
checked={instructionMode === InstructionMode.BYTECODE}
onCheckedChange={(checked) =>
Expand All @@ -158,7 +189,7 @@ const DebuggerContent = () => {
variant="link"
size="icon"
className={!program.length ? "invisible" : "visible"}
disabled={!program.length || isAsmError}
disabled={!program.length || isProgramInvalid}
title="Edit the code"
onClick={() => {
if (isProgramEditMode) {
Expand All @@ -180,7 +211,7 @@ const DebuggerContent = () => {
};

function App() {
const { pvmInitialized, initialState, program } = useAppSelector((state) => state.debugger);
const { pvmInitialized } = useAppSelector((state) => state.debugger);

return (
<>
Expand Down Expand Up @@ -210,7 +241,7 @@ function App() {
) : (
<div className="col-span-12 flex justify-center h-[50vh] align-middle">
<div className="min-w-[50vw] max-md:w-[100%] min-h-[500px] h-[75vh] flex flex-col">
<Loader initialState={initialState} program={program} />
<Loader />
</div>
</div>
)}
Expand Down
2 changes: 1 addition & 1 deletion src/components/ProgramLoader/BinaryFileUpload.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ export const BinaryFileUpload = ({

return (
<div className="block">
<p className="mt-10 mb-3">or upload program as a binary file</p>
<p className="mb-3">Upload program as a binary file</p>
<Input
className="my-6 mr-3"
id="test-file"
Expand Down
40 changes: 0 additions & 40 deletions src/components/ProgramLoader/Bytecode.tsx
Original file line number Diff line number Diff line change
@@ -1,57 +1,17 @@
import { ProgramTextLoader } from "../ProgramTextLoader";
import { ProgramUploadFileOutput } from "./types";
import { BinaryFileUpload } from "@/components/ProgramLoader/BinaryFileUpload.tsx";
import { useState } from "react";

const initial = {
regs: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] as [
number,
number,
number,
number,
number,
number,
number,
number,
number,
number,
number,
number,
number,
],
pc: 0,
pageMap: [],
memory: [],
gas: 10000n,
};

export const Bytecode = ({
onProgramLoad,
program,
}: {
onProgramLoad: (val?: ProgramUploadFileOutput, error?: string) => void;
program: number[];
}) => {
const [tempProgram, setTempProgram] = useState<number[] | undefined>(program);
const handleFileUpload = (val: ProgramUploadFileOutput) => {
setTempProgram(val.program);
onProgramLoad(val);
};

return (
<div className="h-full flex flex-col">
<p className="mb-3">Edit program code bytes</p>
<ProgramTextLoader
program={tempProgram}
setProgram={(program, error) => {
if (program) {
setTempProgram(program);
onProgramLoad({ initial, program, name: "custom" }, error);
} else {
onProgramLoad(undefined, error);
}
}}
/>
<BinaryFileUpload onFileUpload={handleFileUpload} />
</div>
);
Expand Down
28 changes: 28 additions & 0 deletions src/components/ProgramLoader/Examples.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,28 @@ const programs: {
memory: [],
gas: 10000n,
},
empty: {
program: [0, 0, 0],
regs: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] as [
number,
number,
number,
number,
number,
number,
number,
number,
number,
number,
number,
number,
number,
],
pc: 0,
pageMap: [],
memory: [],
gas: 10000n,
},
};

export const Examples = ({ onProgramLoad }: { onProgramLoad: (val: ProgramUploadFileOutput) => void }) => {
Expand Down Expand Up @@ -131,6 +153,12 @@ export const Examples = ({ onProgramLoad }: { onProgramLoad: (val: ProgramUpload
Store U16 instruction
</Label>
</div>
<div className="flex items-center space-x-2">
<RadioGroupItem value="empty" id="option-empty" />
<Label htmlFor="option-empty" className="cursor-pointer">
Empty
</Label>
</div>
</RadioGroup>
</div>
);
Expand Down
24 changes: 1 addition & 23 deletions src/components/ProgramLoader/Loader.tsx
Original file line number Diff line number Diff line change
@@ -1,27 +1,17 @@
import { Tabs, TabsList, TabsTrigger, TabsContent } from "@/components/ui/tabs";
import { Button } from "../ui/button";
import { Assembly } from "./Assembly";
import { Bytecode } from "./Bytecode";
import { Examples } from "./Examples";
import { TextFileUpload } from "./TextFileUpload";
import { useState, useCallback, useEffect } from "react";
import { ProgramUploadFileOutput } from "./types";
import { InitialState } from "@/types/pvm";
import { useDebuggerActions } from "@/hooks/useDebuggerActions";
import { useAppDispatch, useAppSelector } from "@/store/hooks.ts";
import { setIsProgramEditMode } from "@/store/debugger/debuggerSlice.ts";
import { selectIsAnyWorkerLoading } from "@/store/workers/workersSlice";
import { isSerializedError } from "@/store/utils";

export const Loader = ({
initialState,
program,
setIsDialogOpen,
}: {
initialState: InitialState;
program: number[];
setIsDialogOpen?: (val: boolean) => void;
}) => {
export const Loader = ({ setIsDialogOpen }: { setIsDialogOpen?: (val: boolean) => void }) => {
const dispatch = useAppDispatch();
const [programLoad, setProgramLoad] = useState<ProgramUploadFileOutput>();
const [error, setError] = useState<string>();
Expand Down Expand Up @@ -57,7 +47,6 @@ export const Loader = ({
<TabsTrigger value="upload">JSON tests</TabsTrigger>
<TabsTrigger value="examples">Examples</TabsTrigger>
<TabsTrigger value="bytecode">RAW bytecode</TabsTrigger>
<TabsTrigger value="assembly">Assembly</TabsTrigger>
</TabsList>
<div className="border-2 rounded p-4 flex-1 flex flex-col w-full h-full overflow-auto md:px-5">
<TabsContent value="upload">
Expand All @@ -83,17 +72,6 @@ export const Loader = ({
setIsSubmitted(false);
setError(error);
}}
program={program}
/>
</TabsContent>
<TabsContent value="assembly">
<Assembly
onProgramLoad={(val) => {
setProgramLoad(val);
setIsSubmitted(false);
}}
program={program}
initialState={initialState}
/>
</TabsContent>
{error && isSubmitted && <p className="text-red-500">{error}</p>}
Expand Down
22 changes: 16 additions & 6 deletions src/components/ProgramTextLoader/index.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
import { Textarea } from "@/components/ui/textarea.tsx";
import React, { useEffect, useState } from "react";
import React, { useMemo, useState } from "react";
import classNames from "classnames";
import { bytes } from "@typeberry/block";
import { logger } from "@/utils/loggerService";
import { useAppSelector } from "@/store/hooks.ts";
import { selectIsProgramInvalid } from "@/store/debugger/debuggerSlice.ts";

export const ProgramTextLoader = ({
program,
Expand All @@ -11,11 +13,13 @@ export const ProgramTextLoader = ({
program?: number[];
setProgram: (val?: number[], error?: string) => void;
}) => {
const [programInput, setProgramInput] = useState(program?.length ? JSON.stringify(program) : "");
useEffect(() => {
setProgramInput(program?.length ? JSON.stringify(program) : "");
const defaultProgram = useMemo(() => {
return program;
}, [program]);

const [programInput, setProgramInput] = useState(defaultProgram?.length ? JSON.stringify(defaultProgram) : "");
const isProgramInvalid = useAppSelector(selectIsProgramInvalid);

const handleOnChange = (e: React.ChangeEvent<HTMLTextAreaElement>) => {
const newInput = e.target.value.trim();
setProgramInput(newInput);
Expand All @@ -41,15 +45,21 @@ export const ProgramTextLoader = ({

return (
<div className="h-full">
<div className={classNames("h-full flex-auto flex gap-1 flex-col border-2 rounded-md ")}>
<div className={classNames("h-full flex-auto flex gap-1 flex-col")}>
<p className="pb-2 mb-1">
<small>Edit program code bytes</small>
</p>
<Textarea
autoFocus
className={classNames("w-full flex-auto font-mono border-0 text-base")}
className={classNames("w-full flex-auto font-mono text-base border-2 rounded-md", {
"focus-visible:ring-3 focus-visible:outline-none active:outline-none border-red-500": isProgramInvalid,
})}
id="program"
placeholder="Paste the program as an array of numbers or hex string"
value={programInput}
onChange={handleOnChange}
/>
{isProgramInvalid && <span className="text-red-500">Program is not valid</span>}
</div>
</div>
);
Expand Down
6 changes: 3 additions & 3 deletions src/hooks/useDebuggerActions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import {
setBreakpointAddresses,
setClickedInstruction,
setInitialState,
setIsAsmError,
setIsProgramInvalid,
setIsDebugFinished,
setIsRunMode,
setProgram,
Expand Down Expand Up @@ -82,9 +82,9 @@ export const useDebuggerActions = () => {
if (data) {
await startProgram({ ...data.initial, status: Status.OK }, data.program);

dispatch(setIsAsmError(false));
dispatch(setIsProgramInvalid(false));
} else {
dispatch(setIsAsmError(true));
dispatch(setIsProgramInvalid(true));
}
},
[startProgram, dispatch],
Expand Down
12 changes: 6 additions & 6 deletions src/store/debugger/debuggerSlice.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ export interface DebuggerState {
program: number[];
initialState: ExpectedState;
isProgramEditMode: boolean;
isAsmError: boolean;
isProgramInvalid: boolean;
isRunMode: boolean;
isStepMode: boolean;
programPreviewResult: CurrentInstruction[];
Expand All @@ -29,7 +29,7 @@ const initialState: DebuggerState = {
gas: 10000n,
},
isProgramEditMode: false,
isAsmError: false,
isProgramInvalid: false,
isRunMode: false,
isStepMode: false,
programPreviewResult: [],
Expand All @@ -54,8 +54,8 @@ const debuggerSlice = createSlice({
setIsProgramEditMode(state, action) {
state.isProgramEditMode = action.payload;
},
setIsAsmError(state, action) {
state.isAsmError = action.payload;
setIsProgramInvalid(state, action) {
state.isProgramInvalid = action.payload;
},
setIsRunMode(state, action) {
state.isRunMode = action.payload;
Expand Down Expand Up @@ -91,7 +91,7 @@ export const {
setProgram,
setInitialState,
setIsProgramEditMode,
setIsAsmError,
setIsProgramInvalid,
setIsRunMode,
setIsStepMode,
setProgramPreviewResult,
Expand All @@ -106,7 +106,7 @@ export const {
export const selectProgram = (state: RootState) => state.debugger.program;
export const selectInitialState = (state: RootState) => state.debugger.initialState;
export const selectIsProgramEditMode = (state: RootState) => state.debugger.isProgramEditMode;
export const selectIsAsmError = (state: RootState) => state.debugger.isAsmError;
export const selectIsProgramInvalid = (state: RootState) => state.debugger.isProgramInvalid;
export const selectIsRunMode = (state: RootState) => state.debugger.isRunMode;
export const selectProgramPreviewResult = (state: RootState) => state.debugger.programPreviewResult;
export const selectBreakpointAddresses = (state: RootState) => state.debugger.breakpointAddresses;
Expand Down

0 comments on commit b298c54

Please sign in to comment.