UwUVMValue uwuutil_is_type(const char *fnname, UwUVMArgs *args, UwUVMType *type)
{
- if (args->num < 1)
- error("error: %s requires at least one argument\n", fnname);
+ uwuutil_require_min(fnname, args, 1);
for (size_t i = 0; i < args->num; i++)
if (uwuvm_get_arg(args, i).type != type)
return uwubool_create(true);
}
+
+void uwuutil_require_min(const char *fnname, UwUVMArgs *args, size_t n)
+{
+ if (args->num < n) {
+ if (n == 1)
+ error("type error: %s requires at least one optional argument, but none were given\n", fnname);
+ else
+ error("type error: %s requires at least %d arguments, but only %d were given\n", fnname, n, args->num);
+ }
+}
+
+void uwuutil_require_max(const char *fnname, UwUVMArgs *args, size_t n)
+{
+ if (args->num > n) {
+ if (n == 1)
+ error("type error: %s accepts one optional argument, but %d were given\n", fnname, args->num);
+ else
+ error("type error: %s does not take more than %d arguments, but %d were given\n", fnname, args->num);
+ }
+}
+
+void uwuutil_require_exact(const char *fnname, UwUVMArgs *args, size_t n)
+{
+ if (args->num != n) {
+ if (n == 0)
+ error("type error: %s does not take any arguments, but %d were given\n", fnname, args->num);
+ else if (n == 1)
+ error("type error: %s requires exactly one argument, but %d were given\n", fnname, args->num);
+ else
+ error("type error: %s requires exactly %d arguments, but %d were given\n", fnname, n, args->num);
+ }
+}
#include "vm.h"
UwUVMValue uwuutil_is_type(const char *fnname, UwUVMArgs *args, UwUVMType *type);
+void uwuutil_require_min (const char *fnname, UwUVMArgs *args, size_t n);
+void uwuutil_require_max (const char *fnname, UwUVMArgs *args, size_t n);
+void uwuutil_require_exact(const char *fnname, UwUVMArgs *args, size_t n);
+void uwuutil_require_none (const char *fnname, UwUVMArgs *args);
#endif
case EX_ARGNUM:
if ((size_t) expression->value.int_value >= args->num)
- error("error: not enough arguments (accessed argument $%d, but only %lu arguments were passed)\n", expression->value.int_value, args->num);
+ error("type error: not enough arguments (accessed argument $%d, but only %lu arguments were passed)\n", expression->value.int_value, args->num);
return uwuvm_clone_value(uwuvm_get_arg(args, expression->value.int_value));
exit(1);
}
+static inline void syserror(const char *call, FILE *file)
+{
+ perror(call);
+
+ if (file)
+ fclose(file);
+
+ exit(1);
+}
+
#endif
--- /dev/null
+#ifndef _COMMON_PERR_H_
+#define _COMMON_PERR_H_
+
+
+
+
+
+#endif
char *filename = get_filename(module_path);
if (! filename)
- error("error: module %s not found\n", module_path);
+ error("module error: module %s not found\n", module_path);
size_t filename_len = strlen(filename);
UwUVMModuleType type = (filename_len >= 3 && strcmp(filename + filename_len - 3, ".so") == 0) ? MODULE_NATIVE : MODULE_PLAIN;
fnname++;
if (*fnname == '\0')
- error("error: empty function name\n");
+ error("module error: empty function name referenced/called by module %s\n", caller_module->filename);
Module *callee_module;
*function = NULL;
} else {
- error("error: no function %s in module %s\n", link->name, module->filename);
+ error("module error: no function %s in module %s\n", link->name, module->filename);
}
} else {
char *symbol = asprintf_wrapper("uwu_%s", link->name);
FILE *f = fopen(filename, "r");
if (! f)
- error("%s: unable to open\n", filename);
+ syserror("fopen", f);
#if DEBUG
printf("[File %s]\n[Line %d]\n", filename, lines);
break;
if (ferror(f))
- error("%s: I/O error\n", filename);
+ syserror("getc", f);
if (c == '\n')
++lines;
#endif
if (! parse_character(&state, c))
- error("%s: syntax error in line %d\n", filename, lines);
+ error("syntax error: in file %s, line %d\n", filename, lines);
}
if (state.buffer || state.expression)
- error("%s: syntax error at end of file\n", filename);
+ error("syntax error: at end of file %s\n", filename);
fclose(f);
UwUVMValue uwu_if(UwUVMArgs *args)
{
- if (args->num != 3)
- error("error: :bool:if requires exactly 3 arguments\n");
+ uwuutil_require_exact(":bool:if", args, 3);
return uwuvm_clone_value(get_bool_arg(args, 0)
? uwuvm_get_arg(args, 1)
UwUVMValue uwu_and(UwUVMArgs *args)
{
- if (args->num < 1)
- error("error: :bool:and requires at least one argument\n");
+ uwuutil_require_min(":bool:and", args, 1);
for (size_t i = 0; i < args->num; i++)
if (! get_bool_arg(args, i))
UwUVMValue uwu_or(UwUVMArgs *args)
{
- if (args->num < 1)
- error("error: :bool:or requires at least one argument\n");
+ uwuutil_require_min(":bool:or", args, 1);
for (size_t i = 0; i < args->num; i++)
if (get_bool_arg(args, i))
UwUVMValue uwu_equal(UwUVMArgs *args)
{
- if (args->num < 2)
- error("error: :bool:equal requires at least 2 arguments\n");
+ uwuutil_require_min(":bool:equal", args, 2);
bool value = get_bool_arg(args, 0);
UwUVMValue uwu_not(UwUVMArgs *args)
{
- if (args->num != 1)
- error("error: :bool:not requires exactly 1 argument\n");
-
+ uwuutil_require_exact(":bool:not", args, 1);
return uwubool_create(! get_bool_arg(args, 0));
}
UwUVMValue uwu_true(UwUVMArgs *args)
{
- if (args->num != 0)
- error("error: :bool:true does not take any arguments\n");
-
+ uwuutil_require_exact(":bool:true", args, 0);
return uwubool_create(true);
}
UwUVMValue uwu_false(UwUVMArgs *args)
{
- if (args->num != 0)
- error("error: :bool:false does not take any arguments\n");
-
+ uwuutil_require_exact(":bool:false", args, 0);
return uwubool_create(false);
}
static int binary(const char *fnname, UwUVMArgs *args, BinaryOP op)
{
- if (args->num != 2)
- error("error: %s requires exactly 2 arguments\n", fnname);
+ uwuutil_require_exact(fnname, args, 2);
UwUVMValue value0 = uwuvm_get_arg(args, 0);
if (value0.type != &uwuint_type)
- error("error: %s requires an integer as $0\n", fnname);
+ error("type error: %s requires an integer as $0\n", fnname);
UwUVMValue value1 = uwuvm_get_arg(args, 1);
if (value1.type != &uwuint_type)
- error("error: %s requires an integer as $1\n", fnname);
+ error("type error: %s requires an integer as $1\n", fnname);
int a = uwuint_get(value0);
int b = uwuint_get(value1);
UwUVMValue value = uwuvm_get_arg(args, i);
if (value.type != &uwuint_type)
- error("error: %s only accepts integers as arguments (invalid argument: $%lu)\n", fnname, i);
+ error("type error: %s only accepts integers as arguments (invalid argument: $%lu)\n", fnname, i);
int this = uwuint_get(value);
UwUVMValue uwu_equal(UwUVMArgs *args)
{
- if (args->num < 2)
- error("error: :int:equal requires at least 2 arguments\n");
-
+ uwuutil_require_min(":int:equal", args, 2);
return uwubool_create(reduce(":int:equal", args, ROP_EQU, 1) == 1);
}
UwUVMValue uwu_nil(UwUVMArgs *args)
{
- if (args->num != 0)
- error(":nil:nil does not accept any arguments\n");
-
+ uwuutil_require_exact(":nil:nil", args, 0);
return uwunil_create();
}
UwUVMValue uwu_call(UwUVMArgs *args)
{
- if (args->num < 1)
- error(":ref:call requires at least one argument\n");
+ uwuutil_require_min(":ref:call", args, 1);
UwUVMValue value = uwuvm_get_arg(args, 0);