Skip to content

Commit

Permalink
settings works
Browse files Browse the repository at this point in the history
  • Loading branch information
AdinAck committed Oct 3, 2022
1 parent e056259 commit fefbb3b
Show file tree
Hide file tree
Showing 8 changed files with 124 additions and 18 deletions.
4 changes: 4 additions & 0 deletions LEGv8-Simulator.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
4080D12228E3FD9D00DCA947 /* Document.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4080D12128E3FD9D00DCA947 /* Document.swift */; };
4080D12728E4081200DCA947 /* SettingsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4080D12628E4081200DCA947 /* SettingsView.swift */; };
4080D12B28E40CF400DCA947 /* AboutView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4080D12A28E40CF400DCA947 /* AboutView.swift */; };
4095520828EA6A3300697ED9 /* SettingsModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4095520728EA6A3300697ED9 /* SettingsModel.swift */; };
40D605CD28E74A2F00654D3C /* FlagView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 40D605CC28E74A2F00654D3C /* FlagView.swift */; };
40D605CF28E7520500654D3C /* RegisterView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 40D605CE28E7520500654D3C /* RegisterView.swift */; };
40D605D128E7523500654D3C /* MemoryView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 40D605D028E7523500654D3C /* MemoryView.swift */; };
Expand All @@ -42,6 +43,7 @@
4080D12128E3FD9D00DCA947 /* Document.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Document.swift; sourceTree = "<group>"; };
4080D12628E4081200DCA947 /* SettingsView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingsView.swift; sourceTree = "<group>"; };
4080D12A28E40CF400DCA947 /* AboutView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AboutView.swift; sourceTree = "<group>"; };
4095520728EA6A3300697ED9 /* SettingsModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingsModel.swift; sourceTree = "<group>"; };
40D605CC28E74A2F00654D3C /* FlagView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FlagView.swift; sourceTree = "<group>"; };
40D605CE28E7520500654D3C /* RegisterView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RegisterView.swift; sourceTree = "<group>"; };
40D605D028E7523500654D3C /* MemoryView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MemoryView.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -108,6 +110,7 @@
children = (
404364A928E0DD620052F25D /* CPUModel.swift */,
4080D12128E3FD9D00DCA947 /* Document.swift */,
4095520728EA6A3300697ED9 /* SettingsModel.swift */,
);
path = Models;
sourceTree = "<group>";
Expand Down Expand Up @@ -255,6 +258,7 @@
40D605CF28E7520500654D3C /* RegisterView.swift in Sources */,
403D871A28E1EF38002E5E4A /* ConsoleView.swift in Sources */,
40D605D128E7523500654D3C /* MemoryView.swift in Sources */,
4095520828EA6A3300697ED9 /* SettingsModel.swift in Sources */,
403D871828E125AE002E5E4A /* Interpreter.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
Expand Down
3 changes: 3 additions & 0 deletions LEGv8-Simulator/LEGv8_SimulatorApp.swift
Original file line number Diff line number Diff line change
Expand Up @@ -9,15 +9,18 @@ import SwiftUI

@main
struct LEGv8_SimulatorApp: App {
@StateObject var settings: SettingsModel = SettingsModel()

var body: some Scene {
DocumentGroup(newDocument: Document()) { file in
ContentView(document: file.$document)
.environmentObject(settings)
}

#if os(macOS)
Settings {
SettingsView()
.environmentObject(settings)
}
#endif
}
Expand Down
55 changes: 50 additions & 5 deletions LEGv8-Simulator/Models/CPUModel.swift
Original file line number Diff line number Diff line change
Expand Up @@ -455,6 +455,56 @@ class CPUModel: ObservableObject {
registers[destination] = registers[operand1]! & operand2
}

func ands(_ destination: String, _ operand1: String, _ operand2: String) throws {
// verify valid registers
try isValidRegister(destination, true)
try isValidRegister(operand1)
try isValidRegister(operand2)

touchedFlags = true

// flags
var (n, z, c, v) = (false, false, false, false)

let result = registers[operand1]! & registers[operand2]!

// check z flag
if result == 0 {
z = true
}

// TODO: more flag checks may be needed

flags = [n, z, c, v]

registers[destination] = result
}

func andis(_ destination: String, _ operand1: String, _ operand2: UInt64) throws {
// verify valid registers
try isValidRegister(destination, true)
try isValidRegister(operand1)
try isValidLiteral(operand2)

touchedFlags = true

// flags
var (n, z, c, v) = (false, false, false, false)

let result = registers[operand1]! & operand2

// check z flag
if result == 0 {
z = true
}

// TODO: more flag checks may be needed

flags = [n, z, c, v]

registers[destination] = result
}

func orr(_ destination: String, _ operand1: String, _ operand2: String) throws {
// verify valid registers
try isValidRegister(destination, true)
Expand Down Expand Up @@ -520,9 +570,4 @@ class CPUModel: ObservableObject {

registers[destination] = registers[operand1]! >> operand2
}

// conditional branch

// unconditional branch

}
13 changes: 13 additions & 0 deletions LEGv8-Simulator/Models/SettingsModel.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
//
// SettingsModel.swift
// LEGv8-Simulator
//
// Created by Adin Ackerman on 10/2/22.
//

import Foundation

class SettingsModel: ObservableObject {
@Published var executionLimit: Int = 1000
@Published var buildOnType: Bool = false
}
15 changes: 12 additions & 3 deletions LEGv8-Simulator/Utils/Interpreter.swift
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ class Interpreter: ObservableObject {
@Published var assembled: Bool = false
@Published var error: Bool = false
@Published var programCounter: Int = 0
var executionLimit: Int = 0

@Published var lastTouchedRegister: String?
@Published var lastTouchedMemory: UInt64?
Expand Down Expand Up @@ -107,6 +108,7 @@ class Interpreter: ObservableObject {
objectWillChange.send()
}

// linting helpers
private func isValidRegister(_ register: String) throws {
guard cpu.registers.keys.contains(register) else { throw AssemblerError.invalidRegister(register) }
}
Expand All @@ -125,6 +127,7 @@ class Interpreter: ObservableObject {
}
}

// branching
func b(_ label: String) throws {
// verify label exists
try isValidLabel(label)
Expand Down Expand Up @@ -223,7 +226,7 @@ class Interpreter: ObservableObject {
}

func step(mode: RunMode) {
if programCounter > 1000 {
if programCounter > executionLimit {
writeToLog("[InstructionLimitExceeded] The maximum execution count has been exceeded, this could be due to infinite recursion. You can change this limit in Preferences.", type: .error)
running = false
return
Expand Down Expand Up @@ -281,12 +284,12 @@ class Interpreter: ObservableObject {
try verifyArgumentCount(arguments.count, [2])
try isValidRegister(arguments[0])
try isValidRegister(arguments[1])
case "and", "orr", "eor":
case "and", "ands", "orr", "eor":
try verifyArgumentCount(arguments.count, [3])
try isValidRegister(arguments[0])
try isValidRegister(arguments[1])
try isValidRegister(arguments[2])
case "andi", "orri", "eori":
case "andi", "andis", "orri", "eori":
try verifyArgumentCount(arguments.count, [3])
try isValidRegister(arguments[0])
try isValidRegister(arguments[1])
Expand Down Expand Up @@ -380,6 +383,12 @@ class Interpreter: ObservableObject {
case "andi":
try cpu.andi(arguments[0], arguments[1], parseLiteral(arguments[2]))
lastTouchedRegister = arguments[0]
case "ands":
try cpu.ands(arguments[0], arguments[1], arguments[2])
lastTouchedRegister = arguments[0]
case "andis":
try cpu.andis(arguments[0], arguments[1], parseLiteral(arguments[2]))
lastTouchedRegister = arguments[0]
case "orr":
try cpu.orr(arguments[0], arguments[1], arguments[2])
lastTouchedRegister = arguments[0]
Expand Down
8 changes: 7 additions & 1 deletion LEGv8-Simulator/Utils/Lexer.swift
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,13 @@ class Lexer: ObservableObject {
var lines: [String]
@Published var cursor: Int = 0

let specialCharacters: [Character] = ["\t"]
let specialCharacters: [Character] = ["\t", "\r"]

init(text: String) {
lines = text.components(separatedBy: "\n").map { sub in String(sub)}
}

// TODO: lexer does not differentiate commas and whitespace
func parseNextLine() -> (String, [String]) {
guard cursor < lines.count else { return ("_end", []) }

Expand All @@ -27,6 +28,11 @@ class Lexer: ObservableObject {

let line: [String] = lines[cursor].map({ char in if specialCharacters.contains(char) { return " " } else { return char }}).split(separator: " ").map { sub in String(sub)}

if line.count == 0{
cursor += 1
return parseNextLine()
}

let instruction: String = line[0].filter({ char in !specialCharacters.contains(char)})
if instruction.contains("/") { // line is only comment
cursor += 1
Expand Down
18 changes: 16 additions & 2 deletions LEGv8-Simulator/Views/ContentView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,14 @@ typealias _vsplitview = VStack
#endif

struct ContentView: View {
// monaco
let syntax = SyntaxHighlight(title: "asm", fileURL: Bundle.main.url(forResource: "asm", withExtension: "js")!)
@EnvironmentObject var settings: SettingsModel

@StateObject var interpreter: Interpreter = Interpreter()
@Binding var document: Document

// monaco
let syntax = SyntaxHighlight(title: "asm", fileURL: Bundle.main.url(forResource: "asm", withExtension: "js")!)

var body: some View {
_hsplitview {
_vsplitview {
Expand Down Expand Up @@ -110,6 +112,18 @@ struct ContentView: View {
.onChange(of: document.text) { newValue in
interpreter.running = false
interpreter.assembled = false

if settings.buildOnType {
withAnimation {
interpreter.assemble(document.text)
}
}
}
.onChange(of: settings.executionLimit) { newValue in
interpreter.executionLimit = newValue
}
.onAppear {
interpreter.executionLimit = settings.executionLimit
}
}
}
Expand Down
26 changes: 19 additions & 7 deletions LEGv8-Simulator/Views/Settings/SettingsView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -8,23 +8,35 @@
import SwiftUI

struct SettingsView: View {
@State var execLimit: String = "1000"
@EnvironmentObject var model: SettingsModel
@State var execLimitString: String = ""

var body: some View {
TabView() {
List {
HStack {
Text("Execution limit:")

TextField("", text: $execLimit)
TextField("", text: $execLimitString)
.textFieldStyle(.roundedBorder)
.frame(width: 100)
.onChange(of: execLimitString) { newValue in
if let val = Int(newValue) {
model.executionLimit = val
}
}
}

Toggle("Build on type", isOn: $model.buildOnType)
.toggleStyle(.switch)
}
.frame(width: 400, height: 400)
.tabItem {
Label("Settings", systemImage: "gear")
}
.onAppear {
execLimitString = String(model.executionLimit)
}

AboutView()
.tabItem {
Expand All @@ -34,8 +46,8 @@ struct SettingsView: View {
}
}

struct SettingsView_Previews: PreviewProvider {
static var previews: some View {
SettingsView()
}
}
//struct SettingsView_Previews: PreviewProvider {
// static var previews: some View {
// SettingsView()
// }
//}

0 comments on commit fefbb3b

Please sign in to comment.