diff --git a/ls8/cpu.py b/ls8/cpu.py index 9a307496e..8aac2589b 100644 --- a/ls8/cpu.py +++ b/ls8/cpu.py @@ -2,44 +2,108 @@ import sys + class CPU: """Main CPU class.""" +# Step 1: Add the constructor to cpu.py def __init__(self): """Construct a new CPU.""" - pass + # RAM + # create 256 bytes of RAM + self.ram = [0] * 256 + # create 8 registrars + self.reg = [0] * 8 # 8 general-purpose registers, like variables, R0, R1, R2 .. R7 + # internal registers + # set the program counter to 0 + self.pc = 0 # Program Counter, index of the current instruction + self.halted = False + self.ir = 0 + self.reg[7] = 0xF4 + self.sp = self.reg[7] + # self.branch_table = { + # self.ldi = 0b10000010, + # self.prn = 0b01000111, + # ADD: self.alu, + # DIV: self.alu, + # SUB: self.alu, + # AND: self.alu, + # OR: self.alu + # } - def load(self): - """Load a program into memory.""" +# Step 2: Add RAM functions + def ram_read(self, address): + """ + This reads a value at its designated address of RAM + """ + return self.ram[address] - address = 0 + def ram_write(self, value, address): + """ + This writes a value to RAM at its designated address + """ + self.ram[address] = value # For now, we've just hardcoded a program: - program = [ - # From print8.ls8 - 0b10000010, # LDI R0,8 - 0b00000000, - 0b00001000, - 0b01000111, # PRN R0 - 0b00000000, - 0b00000001, # HLT - ] - - for instruction in program: - self.ram[address] = instruction - address += 1 +# Step 7: Un-hardcode the machine code + # program = [ + # # From print8.ls8 + # 0b10000010, # LDI R0,8 + # 0b00000000, #registrar 0 + # 0b00001000, # value 8 + # 0b01000111, # PRN R0 + # 0b00000000, #print value in first registrar + # 0b00000001, # HLT + # ] + # for instruction in program: + # self.ram[address] = instruction + # address += 1 + def load(self, filename): + """Load a program into memory.""" + address = 0 + # -- Load program --- + with open(filename, ) as f: + for line in f: + # print(line) + line = line.split("#") + line = line[0].strip() + # except ValueError: + # Our command needs to be casted and set to base 2 + if line == '': + continue + # print('value is: ' + str(value)) + # will assign are converted value into the next entry in our RAM + self.ram[address] = int(line, 2) + # after it is entered into RAM, it will increment the address value by 1 + address += 1 def alu(self, op, reg_a, reg_b): """ALU operations.""" if op == "ADD": self.reg[reg_a] += self.reg[reg_b] - #elif op == "SUB": etc + # elif op == "SUB": + # self.reg[reg_a] -= self.reg[reg_b] + elif op == "MUL": + self.reg[reg_a] *= self.reg[reg_b] + # elif op == " DIV": + # self.reg[reg_a] //= self.reg[reg_b] + # elif op == "AND": + # self.reg[reg_a] &= self.reg[reg_b] + # elif op == "OR": + # self.reg[reg_a] |= self.reg[reg_b] + else: raise Exception("Unsupported ALU operation") + # if op == "ADD": + # self.reg[reg_a] += self.reg[reg_b] + # # elif op == "SUB": etc + # else: + # raise Exception("Unsupported ALU operation") + def trace(self): """ Handy function to print out the CPU state. You might want to call this @@ -48,8 +112,8 @@ def trace(self): print(f"TRACE: %02X | %02X %02X %02X |" % ( self.pc, - #self.fl, - #self.ie, + # self.fl, + # self.ie, self.ram_read(self.pc), self.ram_read(self.pc + 1), self.ram_read(self.pc + 2) @@ -61,5 +125,149 @@ def trace(self): print() def run(self): - """Run the CPU.""" - pass + """ + Run the CPU: + The core running of our built CPU + """ + # Step 4: Implement the HLT instruction handler + HLT = 0b00000001 # Instruction handler + # Step 5: Add the LDI instruction + LDI = 0b10000010 # instruction + # Step 6: Add the PRN instruction + PRN = 0b01000111 # PRN instruction + + ADD = 0b10100000 + SUB = 0b10100001 + MUL = 0b10100010 + DIV = 0b10100011 + + AND = 0b10101000 + OR = 0b10101010 + PUSH = 0b01000101 + POP = 0b01000110 + CALL = 0b01010000 + RET = 0b00010001 + # kept in a while loop to continue working through passed in commands. + running = True + # Step 9: Beautify your run() loop + while running == True: + # print(f"PC:{self.pc}") + """ + Lets load our function now. This will write our pre-written commands in the program variable to our RAM. + + The instructions will loaded and cycle through our RAM. + """ + instruction = self.ram[self.pc] + + # Halt our CPU and exit + if instruction == HLT: + running = False + self.pc += 1 + # checking if instruction is to set registrar to integer: + # From Spec: + # `LDI register immediate` + # Will set the value of a register to an integer. + # The first value sets which registrar will assign the integer + # The second value determines what that value is + # The PC (program counter) goes one forward to see the value + elif instruction == LDI: + # one RAM entries out determines which registrar is loaded: + reg_slot = self.ram_read(self.pc + 1) + # two RAM entries out determines what value is loaded + int_value = self.ram_read(self.pc + 2) + + # The registrar at slot reg_slot is being assigned the int_value both + # determined from RAM above + self.reg[reg_slot] = int_value + # the program counter is set 3 entries ahead + # one for the current instruction + # one for the integer value + # one for the registrar slot + # 3 bit operation + self.pc += 3 + # Writing logic for if the Print function is called + elif instruction == PRN: + # import pdb; pdb.set_trace() + # loading which registrar slot should be preinted + # print(self.reg[reg_num1]) # print our stored value + reg_slot = self.ram_read(self.pc + 1) + # prints the value at that registrar slot + print(self.reg[reg_slot]) + # print("RAM: ", self.ram) + # print("REG: ", self.reg) + # print("Value", value) + # inriments by two + # one for the current instruction + # one for the reg_slot + self.pc += 2 + elif instruction == MUL: + # if MUL is called, it will grab the next two values in our program counter + # Step 8: Implement a Multiply and Print the Result + # to find out what values in the registrar are going to be multiplied: + reg_num1 = self.ram[self.pc+1] # register + reg_num2 = self.ram[self.pc+2] # value + self.alu('MUL', reg_num1, reg_num2) + # 3 bit operation + self.pc += 3 + # if ADD is called: + elif instruction == ADD: + # This will grab the next values in our program counter. + # and will know which values in our registrar will be added + reg_num1 = self.ram[self.pc+1] # register + reg_num2 = self.ram[self.pc+2] # value + self.alu('ADD', reg_num1, reg_num2) + # 3 bit operation + self.pc += 3 + + # Step 10: Implement System Stack + # PUSH + elif instruction == PUSH: + # This will determine which registrar is pushing their value to the stack: + reg_slot = self.ram[self.pc+1] + val = self.reg[reg_slot] + # decriment the stack pointer + self.sp -= 1 + # now we will push the value pulled from our registar to the stack: + self.ram[self.sp] = val + # 2 bit operation + self.pc += 2 + # POP + elif instruction == POP: + # This will determine which registrar will get popped from the stack: + reg_slot = self.ram[self.pc+1] + # now the value of the registrar is updated + # at the reg_slot with its assigned value: + value = self.ram[self.sp] + self.reg[reg_slot] = value + # now will incriment the stack pointer: + self.sp += 1 + # 2 bit operation + self.pc += 2 + # CALL + elif instruction == CALL: + # Since the CALL spec has the address after the CALL instruction. + # We will designate the + return_address = self.pc + 2 + # now will decriment the stack pointer by 1 + self.sp -= 1 + # will assign the new top of the stack value of our returned address: + self.ram[self.sp] = return_address + # with the return addres now stored. + # We need to determine which registar slot is now used for our called function + reg_slot = self.ram[self.pc+1] + # Step 11: Implement Subroutine Calls + # The subroutine location is the value at that designated reg_slot: + subroutine_location = self.reg[reg_slot] + # Our program counter is now set to the location of that subroutine + self.pc = subroutine_location + elif instruction == RET: + return_address = self.ram[self.sp] + # now will incriment the stack pointer: + self.sp += 1 + # return our address: + self.pc = return_address + else: + print(f"unknown instruction {instruction} at address {IR}") + print(f"Our program counter value is: {self.pc}") + print(f"The command issued was: {self.ram_read(self.pc)}") + sys.exit(1) diff --git a/ls8/ls8.py b/ls8/ls8.py index 74128d36b..0bddf9dfe 100755 --- a/ls8/ls8.py +++ b/ls8/ls8.py @@ -7,5 +7,5 @@ cpu = CPU() -cpu.load() -cpu.run() \ No newline at end of file +cpu.load(sys.argv[1]) +cpu.run() diff --git a/notebooks/+bf.py b/notebooks/+bf.py new file mode 100644 index 000000000..4f9e73773 --- /dev/null +++ b/notebooks/+bf.py @@ -0,0 +1,12 @@ +def foo(): + print("foo") + + +bar = foo +baz = foo +frotz = bar + +foo() +bar() +baz() +frotz() diff --git a/notebooks/+bf00.py b/notebooks/+bf00.py new file mode 100644 index 000000000..7af2e7491 --- /dev/null +++ b/notebooks/+bf00.py @@ -0,0 +1,52 @@ +# Branch Tables +# (AKA) Dispatch Tables) + +# def function1(): + + +def function1(x, y): + # print("function1") + print(f"function1 {x} {y}") + + +def function2(x, y): + # print("function2") + print(f"function2 {x} {y}") + + +def function3(x, y): + # print("function3") + print(f"function3 {x} {y}") + + +def function4(x, y): + # print("function4") + print(f"function4 {x} {y}") + + +def call_function(n, x=None, y=None): + branch_table = { + 1: function1, + 2: function2, + 3: function3, + 4: function4, + # writen as a lambda function: + 5: lambda x, y: print(f"lambda {x} {y}") + # if n == 1: + # function1() + # elif n == 2: + # function2() + # elif n == 3: + # function3() + # elif n == 4: + # function4() + + } + # f = branch_table[n] + # f(x, y) + branch_table[n](x, y) + + +call_function(2, 99, 100) +call_function(3, 2, 3) +call_function(5, 33, 44) diff --git a/notebooks/bitwise notes b/notebooks/bitwise notes new file mode 100644 index 000000000..cbea22d28 --- /dev/null +++ b/notebooks/bitwise notes @@ -0,0 +1,108 @@ +Bitwise Operations +------------------ + +Review: Boolean + +if x < 10 or x > 2: + print("foo") + +x = 0 + +if False: + print("foo") + +A B A and B +---------------- +F F F +T F F +F T F +T T T + +A B A or B +---------------- +F F F +T F T +F T T +T T T + +Bitwise: + +A B A & B Bitwise AND +---------------- +0 0 0 +1 0 0 +0 1 0 +1 1 1 + +A B A | B Bitwise OR +---------------- +0 0 0 +1 0 1 +0 1 1 +1 1 1 + + 11001100 +& 11110000 AND Mask +---------- + 11000000 + +In general: + +* You can use AND to clear (set to 0) bits +* You can use OR to set (set to 1) bits + +Shifting +-------- + +Moving all bits in a number left or right. + + 111001 + 011100 + 001110 + 000111 + 000011 + +Base 10, Decimal analogy: + + vv + 12345678 + 23456780 + 34567800 + 03456780 + 00345678 + 00034567 + 00003456 + 00000345 + 00000034 + ^^ + + vv + 12345678 + d& 00990000 First AND + ----------- + 00340000 Then shift + 00034000 + 00003400 + 00000340 + 00000034 + + + vv +ir = 0b10000010 + + vv + 10000010 + & 11000000 + ---------- + 10000000 + ^^ + 00000010 + ^^ + +num_operands = (ir & 0b11000000) >> 6 + +how_far_to_move_pc = num_operands + 1 + +pc += how_far_to_move_pc + +LDI R1,R2 diff --git a/notebooks/branch_table.py b/notebooks/branch_table.py new file mode 100644 index 000000000..fe69c82eb --- /dev/null +++ b/notebooks/branch_table.py @@ -0,0 +1,48 @@ +# Branch Tables +# (AKA Dispatch Tables) + + +def fun1(x, y): + print(f"fun1 {x} {y}") + + +def fun2(x, y): + print(f"fun2 {x} {y}") + + +def fun3(x, y): + print(f"fun3 {x} {y}") + + +def fun4(x, y): + print(f"fun4 {x} {y}") + + +def call_fun(n, x=None, y=None): + """ + if n == 1: + fun1(x, y) + elif n == 2: + fun2(x, y) + elif n == 3: + fun3(x, y) + elif n == 4: + fun4(x, y) + """ + + branch_table = { + 1: fun1, + 2: fun2, + 3: fun3, + 4: fun4, + 5: lambda x, y: print(f"lambda {x} {y}") + } + + #f = branch_table[n] + #f(x, y) + branch_table[n](x, y) + + +call_fun(2, 99, 100) +call_fun(3, 2, 3) +call_fun(5, 33, 44) diff --git a/notebooks/comp.py b/notebooks/comp.py new file mode 100644 index 000000000..436de6eaa --- /dev/null +++ b/notebooks/comp.py @@ -0,0 +1,76 @@ +""" +Beej Computer Emulator + +Software that pretends to be hardware + +Turing Complete--it can solve any problem for which there is an algorithm. +""" + +""" +Memory--like a big array + +"Index into the memory array" == "address" == "pointer" +""" + + +# memory = [0] * 256 # RAM + +import sys +PRINT_BEEJ = 1 +HALT = 2 +SAVE_REG = 3 # SAVE_REG R1,37 register[1] = 37 +PRINT_REG = 4 # PRINT_REG R1 print(register[1]) +ADD = 5 + +memory = [ + SAVE_REG, # SAVE_REG R1,37 + 1, # <-- index into the register array + 99, # <-- value that we want to store there + SAVE_REG, + 2, # <-- index into the register array + 11, # <-- value that we want to store there + ADD, # ADD R1, R2 register[1] += register[2] + 1, + 2, + PRINT_REG, + 1, + PRINT_BEEJ, + HALT, +] + +register = [0] * 8 # 8 general-purpose registers, like variables, R0, R1, R2 .. R7 + +pc = 0 # Program Counter, index of the current instruction +running = True + +while running: + ir = memory[pc] # Instruction register + + if ir == PRINT_BEEJ: + print("Beej!") + pc += 1 + + elif ir == SAVE_REG: + reg_num = memory[pc + 1] + value = memory[pc + 2] + register[reg_num] = value + pc += 3 + + elif ir == PRINT_REG: + reg_num = memory[pc + 1] + print(register[reg_num]) + pc += 2 + + elif ir == ADD: + reg_num1 = memory[pc + 1] + reg_num2 = memory[pc + 2] + register[reg_num1] += register[reg_num2] + pc += 3 + + elif ir == HALT: + running = False + pc += 1 + + else: + print(f'Unknown instruction {ir} at address {pc}') + sys.exit(1) diff --git a/notebooks/comp00.py b/notebooks/comp00.py new file mode 100644 index 000000000..0cdff05b6 --- /dev/null +++ b/notebooks/comp00.py @@ -0,0 +1,80 @@ +""" +Computer emulator + +Software that pretends to be hardware + +Turing Complete -- it can solve any problem for which there is an algorithm. + +256bytes in total + +Write a program that can run any program. +- add this to your resume. +""" + +# Memory = an array +# Index in the array and value that is stored there +""" +Memory --like a big array +Index into the memory array" =="address" == "pointer" +""" + +# a = [1, 2, 3] +# +# print(a[0]) +# a[0] = 99 + +# memory = [0] * 256 #RAM + +import sys +PRINT_JORGE = 1 +HALT = 2 +SAVE_REG = 3 # SAVE_REG R1, 37 +PRINT_REG = 4 # PRINT_REG R1 + +# running instructions +memory = [ + PRINT_JORGE, # < ---- PC + # PRINT_JORGE, + # PRINT_JORGE, + # SAVE_REG R1, 37 + 1, + # 37, + 99, + SAVE_REG, + 2, + 11, + ADD, # ADD R1, R2 register[1] += register[2] + 1, + 2, + PRINT_REG, + 1, + PRINT_JORGE, + HALT, +] + +register = [0] * 8 # 8 registers, like variables. We have 8 here, RO, R1, R2 .. R7 +pc = 0 # Program Counter, index of the current instruction +running = True + +# for v in memory: +while running: + ir = memory[pc] # Instruction register = ir + # if v == PRINT_JORGE: + if ir == PRINT_JORGE: + print("Jorge !") + pc += 1 + # elif v == HALT: + # elif ir == HALT: + elif ir == SAVE_REG: + reg_num = memory[pc + 1] # grab it out of memory + reg_num = memory[pc + 2] + register[reg_num] = value + # break + running = False + pc += 3 + elif ir == HALT + running = False + pc += 1 + else: + print(f"Unkown instruction {ir} at address {pc}") + sys.exit diff --git a/notebooks/comp01.py b/notebooks/comp01.py new file mode 100644 index 000000000..1988802c2 --- /dev/null +++ b/notebooks/comp01.py @@ -0,0 +1,87 @@ +""" +Beej Computer Emulator + +Software that pretends to be hardware + +Turing Complete--it can solve any problem for which there is an algorithm. +""" + +""" +Memory--like a big array + +"Index into the memory array" == "address" == "pointer" +""" + + +# memory = [0] * 256 # RAM + +import sys +PRINT_BEEJ = 1 +HALT = 2 +SAVE_REG = 3 # SAVE_REG R1,37 register[1] = 37 +PRINT_REG = 4 # PRINT_REG R1 print(register[1]) +ADD = 5 + +memory = [0] * 256 +register = [0] * 8 # 8 general-purpose registers, like variables, R0, R1, R2 .. R7 + +# -- Load program -- +filename = sys.argv[1] +# hardcoded +with open(filename) as f: + # with open("prog1") as f: + # itteration looking at one line at a time + for address, line in enumerate(f): + # for line in f: + # print(line) + line = line.split("#") + + try: + v = int(line[0]) + except ValueError: + continue + # print(v) + + memory[address] = v + address += 1 + print(memory[:15]) + print(sys.argv) # embedded into our sys + +sys.exit(0) + +# -- Run loop -- + +pc = 0 # Program Counter, index of the current instruction +running = True + +while running: + ir = memory[pc] # Instruction register + + if ir == PRINT_BEEJ: + print("Beej!") + pc += 1 + + elif ir == SAVE_REG: + reg_num = memory[pc + 1] + value = memory[pc + 2] + register[reg_num] = value + pc += 3 + + elif ir == PRINT_REG: + reg_num = memory[pc + 1] + print(register[reg_num]) + pc += 2 + + elif ir == ADD: + reg_num1 = memory[pc + 1] + reg_num2 = memory[pc4 + 2] + register[reg_num1] += register[reg_num2] + pc += 3 + + elif ir == HALT: + running = False + pc += 1 + + else: + print(f'Unknown instruction {ir} at address {pc}') + sys.exit(1) diff --git a/notebooks/comp02.py b/notebooks/comp02.py new file mode 100644 index 000000000..4f9c85aee --- /dev/null +++ b/notebooks/comp02.py @@ -0,0 +1,79 @@ +""" +Beej Computer Emulator + +Software that pretends to be hardware + +Turing Complete--it can solve any problem for which there is an algorithm. +""" + +""" +Memory--like a big array + +"Index into the memory array" == "address" == "pointer" +""" + + +import sys +PRINT_BEEJ = 1 +HALT = 2 +SAVE_REG = 3 # SAVE_REG R1,37 register[1] = 37 +PRINT_REG = 4 # PRINT_REG R1 print(register[1]) +ADD = 5 + +memory = [0] * 256 + +register = [0] * 8 # 8 general-purpose registers, like variables, R0, R1, R2 .. R7 + +# -- Load program -- +filename = sys.argv[1] + +# TODO: error checking on sys.argv + +with open(filename) as f: + for address, line in enumerate(f): + + line = line.split("#") + + try: + v = int(line[0], 10) + except ValueError: + continue + + memory[address] = v + +# -- Run loop -- + +pc = 0 # Program Counter, index of the current instruction +running = True + +while running: + ir = memory[pc] # Instruction register + + if ir == PRINT_BEEJ: + print("Beej!") + pc += 1 + + elif ir == SAVE_REG: + reg_num = memory[pc + 1] + value = memory[pc + 2] + register[reg_num] = value + pc += 3 + + elif ir == PRINT_REG: + reg_num = memory[pc + 1] + print(register[reg_num]) + pc += 2 + + elif ir == ADD: + reg_num1 = memory[pc + 1] + reg_num2 = memory[pc + 2] + register[reg_num1] += register[reg_num2] + pc += 3 + + elif ir == HALT: + running = False + pc += 1 + + else: + print(f'Unknown instruction {ir} at address {pc}') + sys.exit(1) diff --git a/notebooks/comp03.py b/notebooks/comp03.py new file mode 100644 index 000000000..ba321f687 --- /dev/null +++ b/notebooks/comp03.py @@ -0,0 +1,92 @@ +""" +Beej Computer Emulator + +Software that pretends to be hardware + +Turing Complete--it can solve any problem for which there is an algorithm. +""" + +""" +Memory--like a big array + +"Index into the memory array" == "address" == "pointer" +""" + + +import sys +PRINT_BEEJ = 1 +HALT = 2 +SAVE_REG = 3 # SAVE_REG R1,37 register[1] = 37 +PRINT_REG = 4 # PRINT_REG R1 print(register[1]) +ADD = 5 + +memory = [0] * 256 + +register = [0] * 8 # 8 general-purpose registers, like variables, R0, R1, R2 .. R7 + +# -- Load program -- + +# TODO: error checking on sys.argv + +with open(filename) as f: + for address, line in enumerate(f): + + line = line.split("#") + + try: + v = int(line[0], 10) + except ValueError: + continue + + memory[address] = v + +# -- Run loop -- + +pc = 0 # Program Counter, index of the current instruction +SP = 7 # Register 7 +register[7] = 0xf4 # our stack pointer +running = True + +while running: + ir = memory[pc] # Instruction register + + if ir == PRINT_BEEJ: + print("Beej!") + pc += 1 + + elif ir == SAVE_REG: + reg_num = memory[pc + 1] + value = memory[pc + 2] + register[reg_num] = value + pc += 3 + + elif ir == PRINT_REG: + reg_num = memory[pc + 1] + print(register[reg_num]) + pc += 2 + + elif ir == ADD: + reg_num1 = memory[pc + 1] + reg_num2 = memory[pc + 2] + register[reg_num1] += register[reg_num2] + pc += 3 + + elif ir == PUSH: # pc push # Push register 2 + # decrement stack pointer + register[SP] -= 1 + # Get the value we want to store from the register + register_num = memory[pc + 1] + value = register[register_num] + # Figure out where to store it + top_of_stack_address = register[SP] + # Store it + memory[top_of_stack_address] = value + pc += 2 + + elif ir == HALT: + running = False + pc += 1 + + else: + print(f'Unknown instruction {ir} at address {pc}') + sys.exit(1) diff --git a/notebooks/comp04.py b/notebooks/comp04.py new file mode 100644 index 000000000..ca8e0cc0e --- /dev/null +++ b/notebooks/comp04.py @@ -0,0 +1,110 @@ +""" +Beej Computer Emulator + +Software that pretends to be hardware + +Turing Complete--it can solve any problem for which there is an algorithm. +""" + +""" +Memory--like a big array + +"Index into the memory array" == "address" == "pointer" +""" + +import sys + +PRINT_BEEJ = 1 +HALT = 2 +SAVE_REG = 3 # SAVE_REG R1,37 register[1] = 37 +PRINT_REG = 4 # PRINT_REG R1 print(register[1]) +ADD = 5 +PUSH = 6 +POP = 7 + +memory = [0] * 256 + +register = [0] * 8 # 8 general-purpose registers, like variables, R0, R1, R2 .. R7 + +# -- Load program -- +filename = sys.argv[1] + +# TODO: error checking on sys.argv + +with open(filename) as f: + address = 0 + + for line in f: + + line = line.split("#") + + try: + v = int(line[0], 10) + except ValueError: + continue + + memory[address] = v + + address += 1 + +# -- Run loop -- + +SP = 7 + +pc = 0 # Program Counter, index of the current instruction +register[SP] = 0xf4 + +running = True + +while running: + ir = memory[pc] # Instruction register + + if ir == PRINT_BEEJ: + print("Beej!") + pc += 1 + + elif ir == SAVE_REG: + reg_num = memory[pc + 1] + value = memory[pc + 2] + register[reg_num] = value + pc += 3 + + elif ir == PRINT_REG: + reg_num = memory[pc + 1] + print(register[reg_num]) + pc += 2 + + elif ir == ADD: + reg_num1 = memory[pc + 1] + reg_num2 = memory[pc + 2] + register[reg_num1] += register[reg_num2] + pc += 3 + + elif ir == PUSH: + # decrement SP + register[SP] -= 1 + + # Get the value we want to store from the register + reg_num = memory[pc + 1] + value = register[reg_num] # <-- this is the value that we want to push + + # Figure out where to store it + top_of_stack_addr = register[SP] + + # Store it + memory[top_of_stack_addr] = value + + pc += 2 + + elif ir == POP: + # TODO + pass + + elif ir == HALT: + running = False + pc += 1 + + else: + print(f'Unknown instruction {ir} at address {pc}') + sys.exit(1) + diff --git a/notebooks/practice.py b/notebooks/practice.py new file mode 100644 index 000000000..411146977 --- /dev/null +++ b/notebooks/practice.py @@ -0,0 +1,31 @@ +""" +Print out all of the strings in the following array in alphabetical order, each on a separate line. +['Waltz', 'Tango', 'Viennese Waltz', 'Foxtrot', 'Cha Cha', 'Samba', 'Rumba', 'Paso Doble', 'Jive'] +The expected output is: +'Cha Cha' +'Foxtrot' +'Jive' +'Paso Doble' +'Rumba' +'Samba' +'Tango' +'Viennese Waltz' +'Waltz' +You may use whatever programming language you'd like. +Verbalize your thought process as much as possible before writing any code. Run through the UPER problem solving framework while going through your thought process. + +""" + + +line = ['Waltz', 'Tango', 'Viennese Waltz', 'Foxtrot', + 'Cha Cha', 'Samba', 'Rumba', 'Paso Doble', 'Jive'] + +line.sort() # (n log(n)) +# Python timsort +# use the built in function +# always (n log(n)) +# Bubble Sort 0(n^2) +# Mergesort +# 2-3 challenges. +for i in line: + print(i) diff --git a/notebooks/prog00 b/notebooks/prog00 new file mode 100644 index 000000000..e69de29bb diff --git a/notebooks/prog1.txt b/notebooks/prog1.txt new file mode 100644 index 000000000..6f6a10b29 --- /dev/null +++ b/notebooks/prog1.txt @@ -0,0 +1,13 @@ +3 # SAVE_REG R1,99 +1 +99 +3 # SAVE_REG R2,11 +2 +11 +5 # ADD R1,R2 +1 +2 +4 # PRINT_REG +1 +1 # PRINT_BEEJ +2 # HALT diff --git a/notebooks/prog2 b/notebooks/prog2 new file mode 100644 index 000000000..6f6a10b29 --- /dev/null +++ b/notebooks/prog2 @@ -0,0 +1,13 @@ +3 # SAVE_REG R1,99 +1 +99 +3 # SAVE_REG R2,11 +2 +11 +5 # ADD R1,R2 +1 +2 +4 # PRINT_REG +1 +1 # PRINT_BEEJ +2 # HALT