<commit_before>import Hal/[Display, Panic], Printf

include stdbool, stdint, c_types
include ./array

/**
 * objects
 */
Object: abstract class {

    class: Class

    /// Instance initializer: set default values for a new instance of this class
    __defaults__: func {}

    /// Finalizer: cleans up any objects belonging to this instance
    __destroy__: func {}

    /** return true if *class* is a subclass of *T*. */
    instanceOf: final func (T: Class) -> Bool {
        if(!this) return false
        class inheritsFrom(T)
    }

    toString: func -> String {
        "%s@%08p" format(class name, this)
    }
}

Class: abstract class {

    /// Number of octets to allocate for a new instance of this class
    instanceSize: SizeT

    /**
     * Number of octets to allocate to hold an instance of this class
     * it's different because for classes, instanceSize may greatly
     * vary, but size will always be equal to the size of a Pointer.
     * for basic types (e.g. Int, Char, Pointer), size == instanceSize
     */
    size: SizeT

    /// Human readable representation of the name of this class
    name: String

    /// Pointer to instance of super-class
    super: const Class

    /// Create a new instance of the object of type defined by this class
    alloc: final func ~_class -> Object {
        object := gc_malloc(instanceSize) as Object
        if(object) {
            object class = this
        }
        return object
    }

    inheritsFrom: final func ~_class (T: Class) -> Bool {
        if(this == T) return true
        return (super ? super inheritsFrom(T) : false)
    }

}

Array: cover from _lang_array__Array {
    length: extern Int
    data: extern Pointer
}

/**
 * Pointer type
 */
Void: cover from void
Pointer: cover from void* {
    toString: func -> String { "%p" format(this) }
}

NULL: unmangled Pointer = 0

/**
 * character and pointer types
 */
//__char: extern(char) Void
__char_ary: extern(__CHAR_ARY) Void
Char: cover from char {
    println: func {
        Display printChar(this)
        Display printChar('\n')
    }

    print: func {
        Display printChar(this)
    }

    /// check for an alphanumeric character
    isAlphaNumeric: func -> Bool {
        isAlpha() || isDigit()
    }

    /// check for an alphabetic character
    isAlpha: func -> Bool {
        isLower() || isUpper()
    }

    /// check for a lowercase alphabetic character
    isLower: func -> Bool {
        this >= 'a' && this <= 'z'
    }

    /// check for an uppercase alphabetic character
    isUpper: func -> Bool {
        this >= 'A' && this <= 'Z'
    }

    /// check for a decimal digit (0 through 9)
    isDigit: func -> Bool {
        this >= '0' && this <= '9'
    }

    /// check for a hexadecimal digit (0 1 2 3 4 5 6 7 8 9 a b c d e f A B C D E F)
    isHexDigit: func -> Bool {
        isDigit() ||
        (this >= 'A' && this <= 'F') ||
        (this >= 'a' && this <= 'f')
    }

    /// check for a control character
    isControl: func -> Bool {
        (this >= 0 && this <= 31) || this == 127
    }

    /// check for any printable character except space
    isGraph: func -> Bool {
        isPrintable() && this != ' '
    }

    /// check for any printable character including space
    isPrintable: func -> Bool {
        this >= 32 && this <= 126
    }

    /// check for any printable character which is not a space or an alphanumeric character
    isPunctuation: func -> Bool {
        isPrintable() && !isAlphaNumeric() && this != ' '
    }

    /** check for white-space characters: space, form-feed ('\f'), newline ('\n'),
        carriage return ('\r'), horizontal tab ('\t'), and vertical tab ('\v') */
    isWhitespace: func -> Bool {
        this == ' '  ||
        this == '\f' ||
        this == '\n' ||
        this == '\r' ||
        this == '\t' ||
        this == '\v'
    }

    /// check for a blank character; that is, a space or a tab
    isBlank: func -> Bool {
        this == ' ' || this == '\t'
    }
    
    /// convert to an integer. This only works for digits, otherwise -1 is returned
    toInt: func -> Int {
        if (isDigit()) {
            return (this - '0')
        }
        return -1
    }
}

UChar: cover from unsigned char extends Char

String: cover from Char* {
    new: static func~withLength (length: Int) -> This {
        result := gc_malloc(length + 1) as This
        result[length] = '\0'
        result
    }
<commit_msg>Added toLower, toUpper, toString to Char.<commit_after>import Hal/[Display, Panic], Printf

include stdbool, stdint, c_types
include ./array

/**
 * objects
 */
Object: abstract class {

    class: Class

    /// Instance initializer: set default values for a new instance of this class
    __defaults__: func {}

    /// Finalizer: cleans up any objects belonging to this instance
    __destroy__: func {}

    /** return true if *class* is a subclass of *T*. */
    instanceOf: final func (T: Class) -> Bool {
        if(!this) return false
        class inheritsFrom(T)
    }

    toString: func -> String {
        "%s@%08p" format(class name, this)
    }
}

Class: abstract class {

    /// Number of octets to allocate for a new instance of this class
    instanceSize: SizeT

    /**
     * Number of octets to allocate to hold an instance of this class
     * it's different because for classes, instanceSize may greatly
     * vary, but size will always be equal to the size of a Pointer.
     * for basic types (e.g. Int, Char, Pointer), size == instanceSize
     */
    size: SizeT

    /// Human readable representation of the name of this class
    name: String

    /// Pointer to instance of super-class
    super: const Class

    /// Create a new instance of the object of type defined by this class
    alloc: final func ~_class -> Object {
        object := gc_malloc(instanceSize) as Object
        if(object) {
            object class = this
        }
        return object
    }

    inheritsFrom: final func ~_class (T: Class) -> Bool {
        if(this == T) return true
        return (super ? super inheritsFrom(T) : false)
    }

}

Array: cover from _lang_array__Array {
    length: extern Int
    data: extern Pointer
}

/**
 * Pointer type
 */
Void: cover from void
Pointer: cover from void* {
    toString: func -> String { "%p" format(this) }
}

NULL: unmangled Pointer = 0

/**
 * character and pointer types
 */
//__char: extern(char) Void
__char_ary: extern(__CHAR_ARY) Void
Char: cover from char {
    /// check for an alphanumeric character
    isAlphaNumeric: func -> Bool {
        isAlpha() || isDigit()
    }

    /// check for an alphabetic character
    isAlpha: func -> Bool {
        isLower() || isUpper()
    }

    /// check for a lowercase alphabetic character
    isLower: func -> Bool {
        this >= 'a' && this <= 'z'
    }

    /// check for an uppercase alphabetic character
    isUpper: func -> Bool {
        this >= 'A' && this <= 'Z'
    }

    /// check for a decimal digit (0 through 9)
    isDigit: func -> Bool {
        this >= '0' && this <= '9'
    }

    /// check for a hexadecimal digit (0 1 2 3 4 5 6 7 8 9 a b c d e f A B C D E F)
    isHexDigit: func -> Bool {
        isDigit() ||
        (this >= 'A' && this <= 'F') ||
        (this >= 'a' && this <= 'f')
    }

    /// check for a control character
    isControl: func -> Bool {
        (this >= 0 && this <= 31) || this == 127
    }

    /// check for any printable character except space
    isGraph: func -> Bool {
        isPrintable() && this != ' '
    }

    /// check for any printable character including space
    isPrintable: func -> Bool {
        this >= 32 && this <= 126
    }

    /// check for any printable character which is not a space or an alphanumeric character
    isPunctuation: func -> Bool {
        isPrintable() && !isAlphaNumeric() && this != ' '
    }

    /** check for white-space characters: space, form-feed ('\f'), newline ('\n'),
        carriage return ('\r'), horizontal tab ('\t'), and vertical tab ('\v') */
    isWhitespace: func -> Bool {
        this == ' '  ||
        this == '\f' ||
        this == '\n' ||
        this == '\r' ||
        this == '\t' ||
        this == '\v'
    }

    /// check for a blank character; that is, a space or a tab
    isBlank: func -> Bool {
        this == ' ' || this == '\t'
    }
    
    /// convert to an integer. This only works for digits, otherwise -1 is returned
    toInt: func -> Int {
        if (isDigit()) {
            return (this - '0')
        }
        return -1
    }

    /// return the lowered charater
    toLower: func -> This {
        if(this isUpper()) {
            return this - 'A' + 'a'
            // or this + 32 ?
        }
        return this
    }

    /// return the capitalized character
    toUpper: func -> This {
        if(this isLower()) {
            return this - 'a' + 'A'
            // or this - 32 ?
        }
        return this
    }

    /// return a one-character string containing this character
    toString: func -> String {
        String new(this)
    }

    /// print this character without a following newline
    print: func {
        Display printChar(this)
    }

    /// print this character with a following newline
    println: func {
        Display printChar(this)
        Display printChar('\n')
    }
}

SChar: cover from signed char extends Char
UChar: cover from unsigned char extends Char

operator as (chr: Char) -> String {
    chr toString()
}

String: cover from Char* {
    /** Create a new string exactly *length* characters long (without the nullbyte).
        The contents of the string are undefined. */
    new: static func~withLength (length: Int) -> This {
        result := gc_malloc(length + 1) as This
        result[length] = '\0'
        result
    }

    /// Create a new string of the length 1 containing only the character *c*
    new: static func~withChar (c: Char) -> This {
        result := This new~withLength(1)
        result[0] = c
        result
    }
    
    /// return the string's length, excluding the null byte.
{'fraction_non_alphanumeric': 0.12137753076617705, 'fraction_numerical': 0.007244938467645891, 'mean_word_length': 1.9743211334120425, 'pattern_counts': {'":': 0, '<': 17, '<?xml version=': 0, '>': 60, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 6, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1649241', 'n_tokens_mistral': 3066, 'n_tokens_neox': 2922, 'n_words': 1140}