/*
 * milktea : lib/string.js
 * copyright (c) 2015 Susisu
 */

"use strict";

function end_module() {
    module.exports = Object.freeze({
        "__String__proto__": __String__proto__,
        "__String__"       : __String__
    });
}

var core      = require("../core.js"),
    Value     = core.Value,
    DataType  = core.DataType;

var utils         = require("./utils.js"),
    assertType    = utils.assertType,
    createObject  = utils.createObject,
    readProperty  = utils.readProperty,
    writeProperty = utils.writeProperty;

var __module__object__ = require("./object.js");

var __String__proto__ = createObject(__module__object__.__Object__proto__);
__String__proto__.data["toString"] =
    new Value(
        DataType.FUNCTION,
        function (obj) {
            assertType(obj, DataType.OBJECT);
            var str = readProperty(obj, "value");
            assertType(str, DataType.STRING);
            return new Value(
                DataType.STRING,
                str.toString()
            );
        }
    );
__String__proto__.data["length"] =
    new Value(
        DataType.FUNCTION,
        function (obj) {
            assertType(obj, DataType.OBJECT);
            var str = readProperty(obj, "value");
            assertType(str, DataType.STRING);
            return new Value(
                DataType.NUMBER,
                str.data.length
            );
        }
    );

var __String__ = createObject(__module__object__.__Class__proto__);
__String__.data["proto"] = __String__proto__;
__String__.data["ctor"] =
    new Value(
        DataType.FUNCTION,
        function (obj) {
            assertType(obj, DataType.OBJECT);
            return new Value(
                DataType.FUNCTION,
                function (value) {
                    assertType(value, DataType.STRING);
                    writeProperty(obj, "value", value);
                    return obj;
                }
            );
        }
    );

end_module();

@@ -220,16 +220,226 @@
 String__
+,%0A        %22__length__%22       : __length__,%0A        %22__charAt__%22       : __charAt__,%0A        %22__charCodeAt__%22   : __charCodeAt__,%0A        %22__reverse__%22      : __reverse__,%0A        %22__concat__%22       : __concat__
 %0A    %7D);
@@ -2162,16 +2162,2420 @@
     );%0A%0A
+var __length__ =%0A    new Value(%0A        DataType.FUNCTION,%0A        function (str) %7B%0A            assertType(str, DataType.STRING);%0A            return new Value(%0A                DataType.NUMBER,%0A                str.data.length%0A            );%0A        %7D%0A    );%0A%0Avar __charAt__ =%0A    new Value(%0A        DataType.FUNCTION,%0A        function (str) %7B%0A            assertType(str, DataType.STRING);%0A            return new Value(%0A                DataType.FUNCTION,%0A                function (index) %7B%0A                    assertType(index, DataType.NUMBER);%0A                    var len = str.data.length;%0A                    if (index.data %3C 0 %7C%7C index.data %3E= len) %7B%0A                        throw errors.outOfRangeError(undefined, index.data);%0A                    %7D%0A                    return new Value(%0A                        DataType.STRING,%0A                        str.data.charAt(index)%0A                    );%0A                %7D%0A            );%0A        %7D%0A    );%0A%0Avar __charCodeAt__ =%0A    new Value(%0A        DataType.FUNCTION,%0A        function (str) %7B%0A            assertType(str, DataType.STRING);%0A            return new Value(%0A                DataType.FUNCTION,%0A                function (index) %7B%0A                    assertType(index, DataType.NUMBER);%0A                    var len = str.data.length;%0A                    if (index.data %3C 0 %7C%7C index.data %3E= len) %7B%0A                        throw errors.outOfRangeError(undefined, index.data);%0A                    %7D%0A                    return new Value(%0A                        DataType.NUMBER,%0A                        str.data.charCodeAt(index)%0A                    );%0A                %7D%0A            );%0A        %7D%0A    );%0A%0Avar __reverse__ =%0A    new Value(%0A        DataType.FUNCTION,%0A        function (str) %7B%0A            assertType(str, DataType.STRING);%0A            return new Value(%0A                DataType.NUMBER,%0A                str.data.split(%22%22).reverse().join(%22%22)%0A            );%0A        %7D%0A    );%0A%0Avar __concat__ =%0A    new Value(%0A        DataType.FUNCTION,%0A        function (x) %7B%0A            assertType(x, DataType.STRING);%0A            return new Value(%0A                DataType.FUNCTION,%0A                function (y) %7B%0A                    assertType(y, DataType.STRING);%0A                    return new Value(%0A                        DataType.STRING,%0A                        x.data + y.data%0A                    );%0A                %7D%0A            );%0A        %7D%0A    );%0A%0A
 end_modu

Add some string functions