Skip to content

Commit 0a147ed

Browse files
authored
Merge pull request #1 from tcorzo/develop
Develop
2 parents 23e0d45 + 1fada66 commit 0a147ed

File tree

10 files changed

+120
-45
lines changed

10 files changed

+120
-45
lines changed

.pre-commit-config.yaml

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
# fail_fast: true
2+
repos:
3+
- repo: https://github.com/pre-commit/pre-commit-hooks
4+
rev: v3.2.0
5+
hooks:
6+
- id: mixed-line-ending
7+
args: [--fix, lf]
8+
- id: no-commit-to-branch
9+
args: [--branch, master]
10+
- id: trailing-whitespace
11+
- id: end-of-file-fixer
12+
- id: check-yaml
13+
- id: check-added-large-files
14+
15+
- repo: https://github.com/executablebooks/mdformat
16+
rev: 0.7.18
17+
hooks:
18+
- id: mdformat
19+
additional_dependencies:
20+
- "mdformat-mkdocs[recommended]>=2.1.0"
21+
- mdformat-admon
22+
23+
- repo: https://github.com/igorshubovych/markdownlint-cli
24+
rev: v0.42.0
25+
hooks:
26+
- id: markdownlint
27+
28+
- repo: https://github.com/crate-ci/typos
29+
rev: v1.26.0
30+
hooks:
31+
- id: typos
32+
33+
- repo: https://github.com/pre-commit/mirrors-prettier
34+
rev: v4.0.0-alpha.8
35+
hooks:
36+
- id: prettier
37+
types: [yaml]

README.md

Lines changed: 21 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -6,27 +6,30 @@ Deno.
66
## Setup Development Environment
77

88
1. Install [Deno](https://deno.land/manual/getting_started/installation)
9-
2. Clone this repository
10-
3. Install the dependencies:
11-
```bash
12-
deno install
13-
```
14-
4. Run development server:
15-
```bash
16-
deno task dev
17-
```
18-
19-
# Usage
9+
1. Clone this repository
10+
1. Install the dependencies:
11+
12+
```bash
13+
deno install
14+
```
15+
16+
1. Run development server:
17+
18+
```bash
19+
deno task dev
20+
```
21+
22+
## Usage
2023

2124
Checkout the [example_program.csv](test/fixtures/example_program.csv), use it as
2225
a template for your own programs.
2326

24-
# Roadmap
27+
## Roadmap
2528

2629
- [x] Implement basic functionality
27-
- [] Add breakpoints
28-
- [] Show errors in the UI
29-
- [] Separate Data registers from Instruction registers
30-
- [] Export program to CSV
31-
- [] Indicate current register in the UI
32-
- [] Flash register when it changes
30+
- [ ] Add breakpoints
31+
- [ ] Show errors in the UI
32+
- [ ] Separate Data registers from Instruction registers
33+
- [ ] Export program to CSV
34+
- [ ] Indicate current register in the UI
35+
- [ ] Flash register when it changes

src/abacus/abacus.ts

Lines changed: 32 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ export default class AbacusEmulator {
77
private _accumulator: string = '0000'; // 4 bytes
88
private _current_address: string = '000'; // 3 bytes for the address
99
public registers: Map<string, Register> = new Map(); // 3 bytes for the address
10+
public _breakpoints: string[] = [];
1011

1112
constructor() { }
1213

@@ -44,6 +45,24 @@ export default class AbacusEmulator {
4445
this.registers.set(address, register);
4546
}
4647

48+
public addBreakpoint(address: string): void {
49+
this._breakpoints.push(address);
50+
}
51+
52+
public hasBreakpoint(address: string): boolean {
53+
return this._breakpoints.includes(address);
54+
}
55+
56+
/**
57+
* removeBreakpoint
58+
*/
59+
public removeBreakpoint(address: string): void {
60+
const index = this._breakpoints.indexOf(address);
61+
if (index > -1)
62+
this._breakpoints.splice(index, 1);
63+
64+
}
65+
4766
public loadProgram(program: Program): void {
4867
this.program = program;
4968
this.accumulator = '0000';
@@ -64,7 +83,19 @@ export default class AbacusEmulator {
6483
throw new Error('No program loaded');
6584
}
6685

67-
while (this.current_address !== '000') {
86+
// Continue after current breakpoint
87+
if (this.hasBreakpoint(this.current_address))
88+
this.step();
89+
90+
while (true) {
91+
// End of program
92+
if (this.current_address === '000')
93+
break;
94+
95+
// Breakpoint
96+
if (this.hasBreakpoint(this.current_address))
97+
break;
98+
6899
this.step();
69100
}
70101
}

src/abacus/operation_type.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,8 @@ export interface OperationType {
66
execute: (this: AbacusEmulator) => void;
77
}
88

9-
export const INMEDIATE_LOAD: OperationType = {
10-
id: 'INMEDIATE_LOAD',
9+
export const IMMEDIATE_LOAD: OperationType = {
10+
id: 'IMMEDIATE_LOAD',
1111
name: 'Carga Inmediata',
1212
execute: function (this: AbacusEmulator) {
1313
this.accumulator = this.current_register.operand;
@@ -88,14 +88,14 @@ export const JUMP_IF_POSITIVE: OperationType = {
8888

8989
const END: OperationType = {
9090
id: 'END',
91-
name: 'Fin de Programa',
91+
name: 'Fin de Program',
9292
execute: function (this: AbacusEmulator) {
9393
this.current_address = '000';
9494
}
9595
};
9696

9797
export const OperationTypes = {
98-
INMEDIATE_LOAD,
98+
IMMEDIATE_LOAD,
9999
LOAD,
100100
STORE,
101101
ADD,

src/components/Emulator.vue

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
<script setup lang="ts">
22
import { inject, } from 'vue';
3-
import { GlobalState, stepProgram } from './../state';
3+
import { GlobalState } from './../state';
44
55
const globalState: GlobalState = inject('globalState') || {} as GlobalState;
66
const registers = Array.from(globalState.emulator.registers.values());
@@ -44,7 +44,10 @@ const registers = Array.from(globalState.emulator.registers.values());
4444
<p>{{ globalState.emulator.current_address }}</p>
4545
</div>
4646
<div>
47-
<button @click="stepProgram" :disabled="globalState.mode !== 'run'">Step</button>
47+
<button @click="globalState.emulator.step" :disabled="globalState.mode !== 'run'">Step</button>
48+
</div>
49+
<div>
50+
<button @click="globalState.emulator.run" :disabled="globalState.mode !== 'run'">Run</button>
4851
</div>
4952
</div>
5053
</template>

src/components/ProgramTable.vue

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import { GlobalState } from '../state';
44
import { ref } from 'vue';
55
import { Register } from '../abacus/program';
66
7-
const globalState: GlobalState = inject('globalState')|| {} as GlobalState;
7+
const globalState: GlobalState = inject('globalState') || {} as GlobalState;
88
const newReg = ref({ address: '', value: '', comment: '' });
99
1010
const addRegister = () => {
@@ -17,17 +17,25 @@ const addRegister = () => {
1717

1818
<template>
1919
<div>
20-
<h3>Programa</h3>
20+
<h3>Program</h3>
2121
<table>
2222
<thead>
2323
<tr>
24+
<th></th>
2425
<th>0x</th>
2526
<th>Valor</th>
2627
<th>Comentario</th>
2728
</tr>
2829
</thead>
2930
<tbody>
3031
<tr v-for="(register, index) in globalState.program.registers" :key="index">
32+
<td v-if="globalState.emulator.hasBreakpoint(register.address)">
33+
<button @click="globalState.emulator.removeBreakpoint(register.address)">🔴</button>
34+
</td>
35+
<td v-else>
36+
<button @click="globalState.emulator.addBreakpoint(register.address)"></button>
37+
</td>
38+
3139
<td>
3240
<input v-if="globalState.mode === 'edit'" v-model="register.address" />
3341
<span v-else>{{ register.address }}</span>
@@ -42,6 +50,7 @@ const addRegister = () => {
4250
</td>
4351
</tr>
4452
<tr v-if="globalState.mode === 'edit'">
53+
<td></td>
4554
<td><input v-model="newReg.address" placeholder="Address" /></td>
4655
<td><input v-model="newReg.value" placeholder="Initial Value" /></td>
4756
<td><input v-model="newReg.comment" placeholder="Description" /></td>

src/state.ts

Lines changed: 2 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ const defaultProgram: Program = {
1414
name: 'New Program',
1515
description: 'A new program',
1616
operations: [
17-
{ code: '0', operation_type: OperationTypes.INMEDIATE_LOAD },
17+
{ code: '0', operation_type: OperationTypes.IMMEDIATE_LOAD },
1818
{ code: '1', operation_type: OperationTypes.LOAD },
1919
{ code: '2', operation_type: OperationTypes.STORE },
2020
{ code: '3', operation_type: OperationTypes.ADD },
@@ -25,7 +25,7 @@ const defaultProgram: Program = {
2525
{ code: 'F', operation_type: OperationTypes.END },
2626
],
2727
aux_registers: [
28-
new Register({ address: '2F0', value: '0000', comment: 'Auxiliar 1' }),
28+
new Register({ address: '2F0', value: '0000', comment: 'Auxiliary 1' }),
2929
],
3030
registers: [
3131
new Register({ address: '100', value: '0000', comment: 'Registro 100' }),
@@ -75,15 +75,7 @@ export function toggleMode() {
7575
globalState.emulator.loadProgram(globalState.program);
7676
}
7777

78-
// Function to reset program to default
7978
export function resetProgram() {
8079
globalState.program = defaultProgram;
8180
localStorage.removeItem('abacusProgram');
8281
}
83-
84-
// New function to step through the program
85-
export function stepProgram() {
86-
if (globalState.mode === 'run') {
87-
globalState.emulator.step();
88-
}
89-
}

test/abacus.test.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ Deno.test("AbacusEmulator should load an immediate value into the accumulator",
6363
operations: [
6464
{
6565
code: 'I',
66-
operation_type: OperationTypes.INMEDIATE_LOAD
66+
operation_type: OperationTypes.IMMEDIATE_LOAD
6767
},
6868
{
6969
code: 'F',
@@ -228,7 +228,7 @@ Deno.test("AbacusEmulator should jump to a specific address if the value in the
228228
operations: [
229229
{
230230
code: 'I',
231-
operation_type: OperationTypes.INMEDIATE_LOAD
231+
operation_type: OperationTypes.IMMEDIATE_LOAD
232232
},
233233
{
234234
code: 'J',
@@ -281,7 +281,7 @@ Deno.test("AbacusEmulator should jump to a specific address if the value in the
281281
operations: [
282282
{
283283
code: 'I',
284-
operation_type: OperationTypes.INMEDIATE_LOAD
284+
operation_type: OperationTypes.IMMEDIATE_LOAD
285285
},
286286
{
287287
code: 'L',
@@ -341,7 +341,7 @@ Deno.test("AbacusEmulator should jump to a specific address if the value in the
341341
operations: [
342342
{
343343
code: 'I',
344-
operation_type: OperationTypes.INMEDIATE_LOAD
344+
operation_type: OperationTypes.IMMEDIATE_LOAD
345345
},
346346
{
347347
code: 'L',

test/fixtures/example_program.csv

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
OPERATIONS,,
22
OPCODE,OPERATION,
3-
0,INMEDIATE_LOAD,
3+
0,IMMEDIATE_LOAD,
44
1,LOAD,
55
2,STORE,
66
3,ADD,
@@ -34,6 +34,6 @@ ADDR,VALUE,COMMENT
3434
50A,32F1,Suma AUX 1
3535
50B,32F7,Suma X
3636
50C,2300,Almacena AC en 300
37-
50D,FCCC,Fin de Programa
37+
50D,FCCC,Fin de Program
3838
150,0005,Valor X
3939
250,0003,Valor Y

test/importer.test.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ Deno.test("ProgramImporter should correctly import a program from CSV", async ()
1313
expect(program.operations.length).toBe(9);
1414
expect(program.operations[0]).toEqual({
1515
code: '0',
16-
operation_type: OperationTypes.INMEDIATE_LOAD
16+
operation_type: OperationTypes.IMMEDIATE_LOAD
1717
});
1818
expect(program.operations[8]).toEqual({
1919
code: 'F',
@@ -43,6 +43,6 @@ Deno.test("ProgramImporter should correctly import a program from CSV", async ()
4343
expect(program.registers[13]).toEqual({
4444
address: '50D',
4545
value: 'FCCC',
46-
comment: 'Fin de Programa'
46+
comment: 'Fin de Program'
4747
});
4848
});

0 commit comments

Comments
 (0)