summaryrefslogblamecommitdiff
path: root/projects/12/StringTest/String.jack
blob: 3ef40b2bd57fd31321fd734827af90271ac3f3fa (plain) (tree)















































































































































































                                                                                     
// 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 int maxLen;
    field int len;
    field Array s;

    /** constructs a new empty string with a maximum length of maxLength
     *  and initial length of 0. */
    constructor String new(int maxLength) {
        if (maxLength > 0) {
            let s = Array.new(maxLength);
        }
        let maxLen = maxLength;
        let len = 0;
        return this;
    }

    /** Disposes this string. */
    method void dispose() {
        if (maxLen > 0) {
            do s.dispose();
        }
        do Memory.deAlloc(this);
        return;
    }

    /** Returns the current length of this string. */
    method int length() {
        return len;
    }

    /** Returns the character at the j-th location of this string. */
    method char charAt(int j) {
        if ((j < 0) | (j + 1 > len)){
            do Output.printString("String.charAt: index out of range!");
            do Sys.error(5);
        }
        return s[j];
    }

    /** Sets the character at the j-th location of this string to c. */
    method void setCharAt(int j, char c) {
        if ((j < 0) | (j + 1 > len)){
            do Output.printString("String.setCharAt: index out of range!");
            do Sys.error(5);
        }
        let s[j] = c;
        return;
    }

    /** Appends c to this string's end and returns this string. */
    method String appendChar(char c) {
        if (len = maxLen) {
            do Output.printString("String.appendChar: reached max length!");
            do Sys.error(5);
        }
        let s[len] = c;
        let len = len + 1;
        return this;
    }

    /** Erases the last character from this string. */
    method void eraseLastChar() {
        if (len = 0){
            do Output.printString("String.eraseLastChar: string is already empty!");
            do Sys.error(5);
        }
        let len = len - 1;
        return;
    }

    /** Returns the integer value of this string, 
     *  until a non-digit character is detected. */
    method int intValue() {
        var int n, i;
        var char c;
        var boolean neg, done;
        let n = 0;
        if (s[0] = 45) {
            let i = 1;
            let neg = true;
        } else {
            let i = 0;
            let neg = false;
        }
        let c = s[i];
        if ((c < 48) | (c > 57)) {
            do Sys.error(3);
            do Output.printString("String.intValue: the input data is not number!");
        }
        let done = false;
        while ((~done) & (i < len)) {
            let c = s[i];
            if ((c > 47) & (c < 58)) {
                let n = n * 10 + (c - 48);
            } else {
                let done = true;
            }
            let i = i + 1;
        }
        if (neg) {
            return -n;
        } else {
            return n;
        }

    }

    /** Sets this string to hold a representation of the given value. */
    method void setInt(int val) {           //change Output.printInt after this
        var int x, i, y;
        var boolean neg;
        if (val < 0) { 
            let neg = true; 
            let len = 2;
        } else {
            let neg = false;
            let len = 1;
        }
        let x = Math.abs(val);
        if (x > 9999) {
            let len = len + 4;
        } else { if (x > 999) {
            let len = len + 3;
        } else { if (x > 99) {
            let len = len + 2;
        } else { if (x > 9) {
            let len = len + 1;
        }}}}
        if (len > maxLen) {
            do Output.printString("String.setInt: val is too big for the string!");
            do Sys.error(5);
        }
        if (x = 0) {
            do setCharAt(0, 48);
            return;
        }
        if (neg) {
            do setCharAt(0, 45);
        }
        let i = len - 1;
        while (x > 0) {
            let y = x / 10;
            do setCharAt(i, x - (y * 10) + 48);
            let x = y;
            let i = i - 1;
        }
        return;
    }

    /** Returns the new line character. */
    function char newLine() {
        return 128;
    }

    /** Returns the backspace character. */
    function char backSpace() {
        return 129;
    }

    /** Returns the double quote (") character. */
    function char doubleQuote() {
        return 34;
    }
}