// 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/String.jack /** * Represents character strings. In addition for constructing and disposing * strings, the class features methods for getting and setting individual * characters of the string, for erasing the string's last character, * for appending a character to the string's end, and more typical * string-oriented operations. */ class String { field Array arr; field int lng, maxLng; /** constructs a new empty string with a maximum length of maxLength * and initial length of 0. */ constructor String new(int maxLength) { if(maxLength < 1) { let arr = null; } else { let arr = Array.new(maxLength); } let lng = 0; let maxLng = maxLength; return this; } /** Disposes this string. */ method void dispose() { if(maxLng > 0) { do arr.dispose(); } return; } /** Returns the current length of this string. */ method int length() { return lng; } /** Returns the character at the j-th location of this string. */ method char charAt(int j) { var int tmpLng; let tmpLng = j - 1; if(maxLng < tmpLng) { //配列サイズより大きい要素を参照しようとした do Sys.error(13); } return arr[j]; } /** Sets the character at the j-th location of this string to c. */ method void setCharAt(int j, char c) { var int tmpLng; let tmpLng = j - 1; if(maxLng < tmpLng) { //配列サイズより大きい要素に代入しようとした do Sys.error(12); } let arr[j] = c; return; } /** Appends c to this string's end and returns this string. */ method String appendChar(char c) { var int tmpLng; let tmpLng = lng - 1; if(maxLng < tmpLng) { //配列サイズより大きい文字列にしようとした do Sys.error(11); } let arr[lng] = c; let lng = lng + 1; return this; } /** Erases the last character from this string. */ method void eraseLastChar() { if(lng > 0) { let lng = lng - 1; } return; } /** Returns the integer value of this string, * until a non-digit character is detected. */ method int intValue() { var int v, i, d; var boolean mFlg; let v = 0; let i = 0; let mFlg = false; while(i < lng) { if((i = 0) & (arr[i] = 45)) { let mFlg = true; } else { let d = arr[i] - 48; if((d < 0) | (d > 9)) { //数値に直せない文字コードを指定した do Sys.error(16); } let v = v * 10 + d; } let i = i + 1; } if(mFlg) { let v = -v; } return v; } /** Sets this string to hold a representation of the given value. */ method void setInt(int val) { //文字列を初期化する let lng = 0; do setIntRec(val); return; } method void setIntRec(int val) { var int c, lastDigit, cpVal; var boolean mFlg; if(val < 0) { let mFlg = true; do appendChar(45); } else { let mFlg = false; } let cpVal = Math.abs(val); //下一桁(modを出すため。もしかしてjackに余りを出す関数や式があったかもしれないが分からないので...) let lastDigit = cpVal - (cpVal / 10 * 10); let c = lastDigit + 48; if(cpVal > 9) { do setIntRec(cpVal / 10); } do appendChar(c); return; } /** Returns the new line character. */ function char newLine() { //return 10; return 128; } /** Returns the backspace character. */ function char backSpace() { //return 8; return 129; } /** Returns the double quote (") character. */ function char doubleQuote() { return 34; } }