/** * VMNative: string_set_char_at( string, index, value ) * Accepts one number argument: the string workshop instance * Returns NULL. */ static bool vmn_str_set_char_at(VM * vm, VMArg * arg, int argc) { VMLibData * data; Buffer * buffer; int index; char value; /* check for proper number of arguments */ if(argc != 3) { 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 || 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); value = (char) vmarg_number(arg[2], NULL); /* check buffer size range */ if(index < 0) { vm_set_err(vm, VMERR_ARGUMENT_OUT_OF_RANGE); return false; } /* check char value */ if(value > CHAR_MAX || value < CHAR_MIN) { vm_set_err(vm, VMERR_ARGUMENT_OUT_OF_RANGE); return false; } /* push char as a number */ if(!buffer_set_char(buffer, value, index)) { vm_set_err(vm, VMERR_ALLOC_FAILED); return false; } /* this function does not return a value */ return false; }
/** * 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: math_pow( base, power ) * Accepts one number argument. Returns base^power. */ static bool vmn_math_pow(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_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, pow(vmarg_number(arg[0], NULL), vmarg_number(arg[1], NULL))); /* 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: 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; }