Compare commits
12 commits
Author | SHA1 | Date | |
---|---|---|---|
|
14833d64b1 | ||
|
dee1d42924 | ||
|
40c104f2fe | ||
|
66afdf9085 | ||
|
a00f27aa25 | ||
|
0d5382a71d | ||
|
8b9b7a9290 | ||
|
86ad6dad28 | ||
|
aa3c372d54 | ||
|
d139a45548 | ||
|
8fe59115c4 | ||
|
45703d743e |
16 changed files with 130 additions and 37 deletions
22
.gitignore
vendored
22
.gitignore
vendored
|
@ -1,3 +1,4 @@
|
|||
.vscode
|
||||
.gradle
|
||||
**/build/
|
||||
!src/**/build/
|
||||
|
@ -19,3 +20,24 @@ gradle-app.setting
|
|||
.project
|
||||
# JDT-specific (Eclipse Java Development Tools)
|
||||
.classpath
|
||||
|
||||
# Compiled class file
|
||||
*.class
|
||||
|
||||
# Log file
|
||||
*.log
|
||||
|
||||
# Package Files #
|
||||
*.jar
|
||||
*.war
|
||||
*.nar
|
||||
*.ear
|
||||
*.zip
|
||||
*.tar.gz
|
||||
*.rar
|
||||
|
||||
*.minisig
|
||||
|
||||
# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
|
||||
hs_err_pid*
|
||||
replay_pid*
|
||||
|
|
12
README.md
12
README.md
|
@ -52,14 +52,17 @@ classDiagram
|
|||
Computer --> ProgramCounter
|
||||
Program <-- ArrayList
|
||||
Program : +toString()
|
||||
Memory <|-- LongMemory
|
||||
Word <|-- LongWord
|
||||
Memory --|> LongMemory
|
||||
Word --|> LongWord
|
||||
|
||||
|
||||
```
|
||||
|
||||
```mermaid
|
||||
classDiagram
|
||||
class Operand {
|
||||
+ Word getValue()
|
||||
}
|
||||
class Instruction {
|
||||
+ void execute(Memory memory, ProgramCounter pc)
|
||||
# String opcode()
|
||||
|
@ -73,8 +76,9 @@ classDiagram
|
|||
class JumpEq
|
||||
class Mul
|
||||
class Print
|
||||
Instruction --|> Word
|
||||
Instruction --|> Address
|
||||
Instruction *-- Operand
|
||||
Operand <|-- Word
|
||||
Operand <|-- Address
|
||||
Add --|> Instruction
|
||||
Copy --|> Instruction
|
||||
Halt --|> Instruction
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
package hatelace;
|
||||
|
||||
public class Address {
|
||||
public class Address implements Operand {
|
||||
int address;
|
||||
|
||||
public Address(int address) {
|
||||
|
@ -14,4 +14,8 @@ public class Address {
|
|||
public String toString() {
|
||||
return Integer.toString(address);
|
||||
}
|
||||
|
||||
public Word getWord(Memory memory) {
|
||||
return memory.read(this);
|
||||
}
|
||||
}
|
||||
|
|
5
app/src/main/java/hatelace/Operand.java
Normal file
5
app/src/main/java/hatelace/Operand.java
Normal file
|
@ -0,0 +1,5 @@
|
|||
package hatelace;
|
||||
|
||||
public interface Operand {
|
||||
Word getWord(Memory memory);
|
||||
}
|
|
@ -1,6 +1,6 @@
|
|||
package hatelace;
|
||||
|
||||
public abstract class Word {
|
||||
public abstract class Word implements Operand {
|
||||
public abstract <T> T getValue();
|
||||
public abstract Word add(Word other);
|
||||
public abstract Word subtract(Word other);
|
||||
|
|
|
@ -3,19 +3,18 @@ package hatelace.instructions;
|
|||
import hatelace.*;
|
||||
|
||||
public class Add extends Instruction {
|
||||
private Address src;
|
||||
private Word imm;
|
||||
private Address dest;
|
||||
private Operand o1, o2;
|
||||
|
||||
/** Add immediate value to memory address. */
|
||||
public Add(Address src, Word imm, Address dest) {
|
||||
this.src = src;
|
||||
this.imm = imm;
|
||||
public Add(Operand o1, Operand o2, Address dest) {
|
||||
this.o1 = o1;
|
||||
this.o2 = o2;
|
||||
this.dest = dest;
|
||||
}
|
||||
|
||||
public void execute(Memory memory, ProgramCounter PC) {
|
||||
memory.write(this.dest, memory.read(this.src).add(this.imm));
|
||||
memory.write(this.dest, this.o1.getWord(memory).add(this.o2.getWord(memory)));
|
||||
PC.incPC();
|
||||
}
|
||||
|
||||
|
@ -24,10 +23,10 @@ public class Add extends Instruction {
|
|||
}
|
||||
|
||||
public String toString() {
|
||||
return String.format("%s [%s] %s [%s]", this.opcode(), this.src, this.imm, this.dest);
|
||||
return String.format("%s [%s] %s [%s]", this.opcode(), this.o1, this.o2, this.dest);
|
||||
}
|
||||
|
||||
protected Object[] operands() {
|
||||
return new Object[] { this.src, this.imm, this.dest };
|
||||
return new Object[] { this.o1, this.o2, this.dest };
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,17 +3,17 @@ package hatelace.instructions;
|
|||
import hatelace.*;
|
||||
|
||||
public class Copy extends Instruction {
|
||||
private Word imm;
|
||||
private Operand src;
|
||||
private Address dest;
|
||||
|
||||
/** Copy immediate value to memory address. */
|
||||
public Copy(Word imm, Address dest) {
|
||||
this.imm = imm;
|
||||
public Copy(Operand src, Address dest) {
|
||||
this.src = src;
|
||||
this.dest = dest;
|
||||
}
|
||||
|
||||
public void execute(Memory memory, ProgramCounter PC) {
|
||||
memory.write(this.dest, this.imm);
|
||||
memory.write(this.dest, this.src.getWord(memory));
|
||||
PC.incPC();
|
||||
}
|
||||
|
||||
|
@ -22,10 +22,10 @@ public class Copy extends Instruction {
|
|||
}
|
||||
|
||||
protected Object[] operands() {
|
||||
return new Object[] {this.imm, this.dest};
|
||||
return new Object[] {this.src, this.dest};
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return String.format("%s %s [%s]", this.opcode(), this.imm, this.dest);
|
||||
return String.format("%s %s [%s]", this.opcode(), this.src, this.dest);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,18 +4,18 @@ import hatelace.*;
|
|||
|
||||
public class JumpEq extends Instruction {
|
||||
private int index;
|
||||
private Address src;
|
||||
private Word imm;
|
||||
private Operand o1;
|
||||
private Operand o2;
|
||||
|
||||
/** Conditional jump */
|
||||
public JumpEq(int index, Address src, Word imm) {
|
||||
public JumpEq(int index, Operand o1, Operand o2) {
|
||||
this.index = index;
|
||||
this.src = src;
|
||||
this.imm = imm;
|
||||
this.o1 = o1;
|
||||
this.o2 = o2;
|
||||
}
|
||||
|
||||
public void execute(Memory memory, ProgramCounter PC) {
|
||||
if (this.imm.equals(memory.read(this.src))) {
|
||||
if (this.o1.getWord(memory).equals(this.o2.getWord(memory))) {
|
||||
PC.setPC(this.index);
|
||||
} else {
|
||||
PC.incPC();
|
||||
|
@ -27,10 +27,10 @@ public class JumpEq extends Instruction {
|
|||
}
|
||||
|
||||
protected Object[] operands() {
|
||||
return new Object[] {this.index, this.src, this.imm};
|
||||
return new Object[] {this.index, this.o1, this.o2};
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return String.format("%s %s [%s] %s", this.opcode(), this.index, this.src, this.imm);
|
||||
return String.format("%s %s [%s] %s", this.opcode(), this.index, this.o1, this.o2);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,19 +3,19 @@ package hatelace.instructions;
|
|||
import hatelace.*;
|
||||
|
||||
public class Mul extends Instruction {
|
||||
private Address src1;
|
||||
private Address src2;
|
||||
private Operand o1;
|
||||
private Operand o2;
|
||||
private Address dest;
|
||||
|
||||
/** Multiply contents of two addresses and store the result in a third memory address. */
|
||||
public Mul(Address src1, Address src2, Address dest) {
|
||||
this.src1 = src1;
|
||||
this.src2 = src2;
|
||||
public Mul(Operand o1, Operand o2, Address dest) {
|
||||
this.o1 = o1;
|
||||
this.o2 = o2;
|
||||
this.dest = dest;
|
||||
}
|
||||
|
||||
public void execute(Memory memory, ProgramCounter PC) {
|
||||
memory.write(this.dest, memory.read(this.src1).multiply(memory.read(this.src2)));
|
||||
memory.write(this.dest, this.o1.getWord(memory).multiply(this.o2.getWord(memory)));
|
||||
PC.incPC();
|
||||
}
|
||||
|
||||
|
@ -24,10 +24,10 @@ public class Mul extends Instruction {
|
|||
}
|
||||
|
||||
protected Object[] operands() {
|
||||
return new Object[] { this.src1, this.src2, this.dest };
|
||||
return new Object[] { this.o1, this.o2, this.dest };
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return String.format("%s [%s] [%s] [%s]", this.opcode(), this.src1, this.src2, this.dest);
|
||||
return String.format("%s [%s] [%s] [%s]", this.opcode(), this.o1, this.o2, this.dest);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
package hatelace.memtypes;
|
||||
|
||||
import hatelace.Memory;
|
||||
import hatelace.Word;
|
||||
|
||||
public class IntWord extends Word {
|
||||
|
@ -15,6 +16,11 @@ public class IntWord extends Word {
|
|||
return value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Word getWord(Memory memory) {
|
||||
return this;
|
||||
}
|
||||
|
||||
public Word add(Word other) {
|
||||
return new IntWord(value + (Integer) other.getValue());
|
||||
}
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
package hatelace.memtypes;
|
||||
|
||||
import hatelace.Memory;
|
||||
import hatelace.Word;
|
||||
|
||||
public class LongWord extends Word {
|
||||
|
@ -15,6 +16,11 @@ public class LongWord extends Word {
|
|||
return value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Word getWord(Memory memory) {
|
||||
return this;
|
||||
}
|
||||
|
||||
public Word add(Word other) {
|
||||
return new LongWord(value + (Long) other.getValue());
|
||||
}
|
||||
|
|
15
doc/answers.md
Normal file
15
doc/answers.md
Normal file
|
@ -0,0 +1,15 @@
|
|||
1. En interface som alla typer av instruktioner kan ha gemensam borde inte vara helt fel. Vilket i sin tur betyder en klass för varje instruktion där ett instruktions interface implementeras.
|
||||
|
||||
2. Man ärver lämplig collection, ex arraylist. Detta är kass design, då komposition är tydligare.
|
||||
|
||||
3. "Program" och självaste "datorn" borde vara olika paket, paketet "program" rör program som skall köra på datorn, "datorn" har de klasser som är datorn som t.ex. memory och programCounter osv.
|
||||
|
||||
4. Varje instruktion skulle kunna representeras som ett kommando, och datorn skulle utföra dessa kommandon utan att behöva veta exakt vad varje instruktion innebär. På så sätt separeras ansvar, och det blir enklare att lägga till eller ändra instruktioner i framtiden.
|
||||
|
||||
5. Designmönstret Template Method kan vara användbart för att undvika duplicerad kod i likartade klasser, särskilt för de instruktionsklasser som ingår i programmet (t.ex. Copy, JumpEq, Mul, Add, Print, Halt). Eftersom dessa instruktionsklasser kan ha vissa gemensamma delar i hur de utför sin uppgift, kan ett template method-mönster användas för att abstrahera och återanvända gemensam kod.
|
||||
|
||||
6. För att hantera olika sorters operander på ett enhetligt sätt med hjälp av Strategy-mönstret i en datormodell skulle man kunna implementera olika strategier för hur operander ska hanteras. Operander kan vara antingen konstanter eller adresser, och olika instruktioner kräver olika typer av operander.
|
||||
|
||||
7. Additionen bör nog utföras i LongWord.
|
||||
|
||||
8.
|
1
doc/image1.svg
Normal file
1
doc/image1.svg
Normal file
File diff suppressed because one or more lines are too long
After Width: | Height: | Size: 24 KiB |
1
doc/image2.svg
Normal file
1
doc/image2.svg
Normal file
File diff suppressed because one or more lines are too long
After Width: | Height: | Size: 20 KiB |
1
doc/image3.svg
Normal file
1
doc/image3.svg
Normal file
File diff suppressed because one or more lines are too long
After Width: | Height: | Size: 25 KiB |
31
makefile
31
makefile
|
@ -1,3 +1,8 @@
|
|||
GITHASH := $(shell git rev-parse --short HEAD)$(shell git diff-index --quiet HEAD || echo "-dirty")
|
||||
|
||||
TARNAME := hatelace-imbus_$(GITHASH).tar.gz
|
||||
DIRNAME := hatelace
|
||||
|
||||
run:
|
||||
./gradlew run
|
||||
|
||||
|
@ -6,11 +11,35 @@ watch:
|
|||
|
||||
build:
|
||||
./gradlew build
|
||||
ls -lh app/build/libs/*.jar
|
||||
|
||||
clean:
|
||||
./gradlew clean
|
||||
rm -f *.tar.gz *.tar.gz.minisig *.zip *.jpg
|
||||
|
||||
test:
|
||||
./gradlew test
|
||||
|
||||
.PHONY: run build clean
|
||||
$(TARNAME):
|
||||
git archive --format=tar --prefix=$(DIRNAME)/ HEAD > intermediate.tar
|
||||
tar -f intermediate.tar --delete $(DIRNAME)/doc
|
||||
gzip -9 -c intermediate.tar > $(TARNAME)
|
||||
rm intermediate.tar
|
||||
|
||||
$(TARNAME).minisig: $(TARNAME)
|
||||
minisign -Sm $(TARNAME)
|
||||
|
||||
tar: $(TARNAME)
|
||||
tar -tvf $(TARNAME)
|
||||
|
||||
sign: $(TARNAME).minisig
|
||||
|
||||
publish: $(TARNAME) $(TARNAME).minisig
|
||||
@git diff-index --quiet HEAD || (echo "git is dirty, commit changes first"; exit 1)
|
||||
ssh server mkdir -p /public/$(DIRNAME)
|
||||
rsync -avz $(TARNAME).minisig server:/public/$(DIRNAME)/$(TARNAME).minisig
|
||||
rsync -avz $(TARNAME) server:/public/$(DIRNAME)/$(TARNAME)
|
||||
ssh server ln -sf /public/$(DIRNAME)/$(TARNAME).minisig /public/$(DIRNAME)/latest.tar.gz.minisig
|
||||
ssh server ln -sf /public/$(DIRNAME)/$(TARNAME) /public/$(DIRNAME)/latest.tar.gz
|
||||
|
||||
.PHONY: run watch build clean test archive sign publish
|
||||
|
|
Loading…
Reference in a new issue