/** * VMNative: string_length( workshop ) * Accepts one number argument: the string workshop instance */ static bool vmn_str_length(VM * vm, VMArg * arg, int argc) { VMLibData * data; /* check for proper number of arguments */ if(argc != 1) { vm_set_err(vm, VMERR_INCORRECT_NUMARGS); return false; } /* check argument major type */ if(vmarg_type(arg[0]) != TYPE_LIBDATA) { vm_set_err(vm, VMERR_INVALID_TYPE_ARGUMENT); return false; } /* extract the libdata from the argument */ data = vmarg_libdata(arg[0]); /* check libdata type */ if(!vmlibdata_is_type(data, LIBSTR_STRING_TYPE, LIBSTR_STRING_TYPE_LEN)) { vm_set_err(vm, VMERR_INVALID_TYPE_ARGUMENT); return false; } /* push string length */ vmarg_push_number(vm, libstr_string_length(data)); /* this function does return a value */ return true; }
/** * VMNative: char_to_string( char ) * Accepts one number argument: the char to convert * Returns the desired char as a VM String. */ static bool vmn_char_to_str(VM * vm, VMArg * arg, int argc) { VMLibData * newStrData; char character[2] = ""; /* check for proper number of arguments */ if(argc != 1) { vm_set_err(vm, VMERR_INCORRECT_NUMARGS); return false; } /* check argument major type */ if(vmarg_type(arg[0]) != TYPE_NUMBER) { vm_set_err(vm, VMERR_INVALID_TYPE_ARGUMENT); return false; } character[0] = (char) vmarg_number(arg[0], NULL); /* check if value is out of range for char */ if(character[0] > CHAR_MAX || character[0] < CHAR_MIN) { vm_set_err(vm, VMERR_ARGUMENT_OUT_OF_RANGE); return false; } newStrData = vmarg_new_string(character, 1); /* push char as a number */ if(newStrData == NULL || !vmarg_push_libdata(vm, newStrData)) { vm_set_err(vm, VMERR_ALLOC_FAILED); return false; } /* this function does return a value */ return true; }
/** * VMNative: string_prealloc( workshop , newsize ) * Accepts a workshop argument and a number. The newsize is the size to * reallocate the workshop buffer to. Preallocate buffer for best performance. */ static bool vmn_str_prealloc(VM * vm, VMArg * arg, int argc) { VMLibData * data; Buffer * buffer; int newSize; /* check for proper number of arguments */ if(argc != 2) { vm_set_err(vm, VMERR_INCORRECT_NUMARGS); return false; } /* check argument 1 major type */ if(vmarg_type(arg[0]) != TYPE_LIBDATA) { vm_set_err(vm, VMERR_INVALID_TYPE_ARGUMENT); return false; } /* extract the libdata from the argument */ data = vmarg_libdata(arg[0]); /* check libdata type */ if(!vmlibdata_is_type(data, LIBSTR_STRING_TYPE, LIBSTR_STRING_TYPE_LEN)) { vm_set_err(vm, VMERR_INVALID_TYPE_ARGUMENT); return false; } /* check argument 2 type */ if(vmarg_type(arg[1]) != TYPE_NUMBER) { vm_set_err(vm, VMERR_INVALID_TYPE_ARGUMENT); return false; } newSize = (int)vmarg_number(arg[1], NULL); /* check buffer size range */ if(newSize < 1) { vm_set_err(vm, VMERR_ARGUMENT_OUT_OF_RANGE); return false; } /* extract the workshop */ buffer = vmlibdata_data(data); /* can't make it smaller, only bigger */ buffer_resize(buffer, newSize >= buffer_size(buffer) ? newSize : buffer_size(buffer)); /* push null result */ vmarg_push_null(vm); /* this function does return a value */ return true; }
/** * VMNative: string_append( workshop , string ) * Accepts a workshop argument and a string. The string will be allocated * onto the buffer. */ static bool vmn_str_append(VM * vm, VMArg * arg, int argc) { VMLibData * data; Buffer * buffer; char * appendStr; /* check for proper number of arguments */ if(argc != 2) { vm_set_err(vm, VMERR_INCORRECT_NUMARGS); return false; } /* check argument 1 major type */ if(vmarg_type(arg[0]) != TYPE_LIBDATA) { vm_set_err(vm, VMERR_INVALID_TYPE_ARGUMENT); return false; } /* extract the libdata from the argument */ data = vmarg_libdata(arg[0]); /* check libdata type */ if(!vmlibdata_is_type(data, LIBSTR_STRING_TYPE, LIBSTR_STRING_TYPE_LEN)) { vm_set_err(vm, VMERR_INVALID_TYPE_ARGUMENT); return false; } /* check argument 2 type */ if(!vmarg_is_string(arg[1])) { vm_set_err(vm, VMERR_INVALID_TYPE_ARGUMENT); return false; } /* extract the buffer */ buffer = vmlibdata_data(data); appendStr = vmarg_string(arg[1]); /* append the string to the buffer * TODO: perhaps make it so this doesn't have to use strlen */ if(!buffer_append_string(buffer, appendStr, strlen(appendStr))) { vm_set_err(vm, VMERR_ALLOC_FAILED); return false; } /* push null result */ vmarg_push_null(vm); /* this function does return a value */ return true; }
/** * VMNative: string_char_at( workshop, index ) * Accepts one number argument: the string workshop instance * Returns the desired char as a TYPE_NUMBER. */ static bool vmn_str_char_at(VM * vm, VMArg * arg, int argc) { VMLibData * data; Buffer * buffer; int index; /* check for proper number of arguments */ if(argc != 2) { vm_set_err(vm, VMERR_INCORRECT_NUMARGS); return false; } /* check argument major type */ if(vmarg_type(arg[0]) != TYPE_LIBDATA || vmarg_type(arg[1]) != TYPE_NUMBER) { vm_set_err(vm, VMERR_INVALID_TYPE_ARGUMENT); return false; } /* extract the libdata from the argument */ data = vmarg_libdata(arg[0]); /* check libdata type */ if(!vmlibdata_is_type(data, LIBSTR_STRING_TYPE, LIBSTR_STRING_TYPE_LEN)) { vm_set_err(vm, VMERR_INVALID_TYPE_ARGUMENT); return false; } /* extract the buffer */ buffer = vmlibdata_data(data); /* extract the index */ index = vmarg_number(arg[1], NULL); /* check buffer size range */ if(index < 0 || index >= buffer_size(buffer)) { vm_set_err(vm, VMERR_ARGUMENT_OUT_OF_RANGE); return false; } /* push char as a number */ if(!vmarg_push_number(vm, buffer_get_buffer(buffer)[index] )) { vm_set_err(vm, VMERR_ALLOC_FAILED); return false; } /* this function does return a value */ return true; }
/** * VMNative: math_sqrt( value ) * Accepts one number argument. Returns its square root. */ static bool vmn_math_sqrt(VM * vm, VMArg * arg, int argc) { /* check for proper number of arguments */ if(argc != 1) { vm_set_err(vm, VMERR_INCORRECT_NUMARGS); return false; } /* check argument type */ if(vmarg_type(arg[0]) != TYPE_NUMBER) { vm_set_err(vm, VMERR_INVALID_TYPE_ARGUMENT); return false; } /* push result */ vmarg_push_number(vm, sqrt(vmarg_number(arg[0], NULL))); /* this function does return a value */ return true; }
/** * VMNative: string_equals( string1, string2 ) * Accepts two string arguments. Returns true if they are the same, and false if * not. */ static bool vmn_str_equals(VM * vm, VMArg * arg, int argc) { /* check for proper number of arguments */ if(argc != 2) { vm_set_err(vm, VMERR_INCORRECT_NUMARGS); return false; } /* check argument type */ if(!vmarg_is_string(arg[0]) || !vmarg_is_string(arg[1])) { vm_set_err(vm, VMERR_INVALID_TYPE_ARGUMENT); return false; } /* push result */ vmarg_push_boolean(vm, strcmp(vmarg_string(arg[0]), vmarg_string(arg[1])) == 0); /* this function does return a value */ return true; }
/** * VMNative: math_round( value, precision ) * Accepts one number argument. Returns value rounded to precision decimal places. */ static bool vmn_math_round(VM * vm, VMArg * arg, int argc) { switch(argc) { case 1: /* If user did not specify precision, assume round to int */ /* check argument type */ if(vmarg_type(arg[0]) != TYPE_NUMBER) { vm_set_err(vm, VMERR_INVALID_TYPE_ARGUMENT); return false; } /* push result */ vmarg_push_number(vm, round(vmarg_number(arg[0], NULL))); /* this function does return a value */ return true; case 2: /* if user specified precision */ /* check argument type */ if(vmarg_type(arg[0]) != TYPE_NUMBER || vmarg_type(arg[1]) != TYPE_NUMBER) { vm_set_err(vm, VMERR_INVALID_TYPE_ARGUMENT); return false; } /* push result */ vmarg_push_number(vm, round(vmarg_number(arg[0], NULL) * pow(10, vmarg_number(arg[1], NULL))) / pow(10, vmarg_number(arg[1], NULL))); /* this function does return a value */ return true; } vm_set_err(vm, VMERR_INCORRECT_NUMARGS); return false; }
/** * VMNative: string ( buffersize ) * Accepts one number argument: the size of the string buffer. */ static bool vmn_str(VM * vm, VMArg * arg, int argc) { VMLibData * data; int bufferSize; /* check for proper number of arguments */ if(argc != 1) { vm_set_err(vm, VMERR_INCORRECT_NUMARGS); return false; } /* check argument type */ if(vmarg_type(arg[0]) != TYPE_NUMBER) { vm_set_err(vm, VMERR_INVALID_TYPE_ARGUMENT); return false; } bufferSize = (int)vmarg_number(arg[0], NULL); /* check buffer size range */ if(bufferSize < 1) { vm_set_err(vm, VMERR_ARGUMENT_OUT_OF_RANGE); return false; } /* allocate string workshop */ data = libstr_string_new(bufferSize); if(data == NULL) { vm_set_err(vm, VMERR_ALLOC_FAILED); return false; } /* push result */ vmarg_push_libdata(vm, data); /* this function does return a value */ return true; }