// This file is part of www.nand2tetris.org // and the book "The Elements of Computing Systems" // by Nisan and Schocken, MIT Press. // File name: projects/12/Keyboard.jack /** * A library for handling user input from the keyboard. */ class Keyboard { /** Initializes the keyboard. */ function void init() { return; } /** * Returns the character of the currently pressed key on the keyboard; * if no key is currently pressed, returns 0. * * Recognizes all ASCII characters, as well as the following keys: * new line = 128 = String.newline() * backspace = 129 = String.backspace() * left arrow = 130 * up arrow = 131 * right arrow = 132 * down arrow = 133 * home = 134 * End = 135 * page up = 136 * page down = 137 * insert = 138 * delete = 139 * ESC = 140 * F1 - F12 = 141 - 152 */ function char keyPressed() { var char value; let value = Memory.peek(24576); if (value = 128) { return String.newLine(); } if (value = 129) { return String.backSpace(); } return value; } /** * Waits until a key is pressed on the keyboard and released, * then echoes the key to the screen, and returns the character * of the pressed key. */ function char readChar() { var char key, result; while (Keyboard.keyPressed() = 0) {} let key = Keyboard.keyPressed(); while (~(Keyboard.keyPressed() = 0)) {} if (key = String.newLine()) { return key; } if (key = String.backSpace()) { return key; } do Output.printChar(key); return key; } /** * Displays the message on the screen, reads from the keyboard the entered * text until a newline character is detected, echoes the text to the screen, * and returns its value. Also handles user backspaces. */ function String readLine(String message) { var String s; var char key, newline, backspace; var int i; let newline = String.newLine(); let backspace = String.backSpace(); let s = String.new(128); let key = 0; do Output.printString(message); let i = 0; while (~(key = newline)) { let key = Keyboard.readChar(); if (key = newline) { do Output.println(); return s; } else { if (key = backspace) { if (i > 0) { do s.eraseLastChar(); do Output.backSpace(); let i = i - 1; } } else { do s.appendChar(key); let i = i + 1; } } // Prevent out of bound error. if (i = 128) { return s; } } return s; } function int textToInt(String s) { var int result, i, length, multiplier; var char c; var boolean isNegative, continue; let isNegative = false; let length = s.length(); let i = 0; let result = 0; let multiplier = 1; if (length = 0) { return 0; } if (s.charAt(0) = 45) { let isNegative = true; } let i = length; while (true) { let i = i - 1; let c = s.charAt(i); if ((s.charAt(i) > 47) & (s.charAt(i) < 58)) { let result = result + ((s.charAt(i) - 48) * multiplier); let multiplier = multiplier * 10; } else { // could raise exception here; } if (isNegative) { if (i = 1) { return -result; } } else { if (i = 0) { return result; } } } return 0; } /** * Displays the message on the screen, reads from the keyboard the entered * text until a newline character is detected, echoes the text to the screen, * and returns its integer value (until the first non-digit character in the * entered text is detected). Also handles user backspaces. */ function int readInt(String message) { var String s; var char key, newline, backspace; var int i; let newline = String.newLine(); let backspace = String.backSpace(); let s = String.new(128); let key = 0; do Output.printString(message); let i = 0; while (~(key = newline)) { let key = Keyboard.readChar(); if (key = newline) { do Output.println(); } else { if (key = backspace) { if (i > 0) { do s.eraseLastChar(); do Output.backSpace(); let i = i - 1; } } else { do s.appendChar(key); let i = i + 1; } } // Prevent out of bound error. if (i = 128) { return s; } } let i = Keyboard.textToInt(s); do s.dispose(); return i; } }