]> git.lizzy.rs Git - uwu-lang.git/commitdiff
Add :ref module and refactor type handling
authorElias Fleckenstein <eliasfleckenstein@web.de>
Thu, 30 Dec 2021 15:53:37 +0000 (16:53 +0100)
committerElias Fleckenstein <eliasfleckenstein@web.de>
Thu, 30 Dec 2021 15:53:37 +0000 (16:53 +0100)
22 files changed:
Makefile
api/bool.c
api/bool.h
api/int.c
api/int.h
api/nil.c
api/nil.h
api/ref.c
api/ref.h
api/str.c
api/str.h
api/util.c [new file with mode: 0644]
api/util.h [new file with mode: 0644]
api/vm.c
api/vm.h
doc/std.md
src/vm.c
std/bool.c
std/int.c
std/nil.c
std/ref.c [new file with mode: 0644]
std/str.c

index 8dbf5d8a38b5817bc1ddd537a1dfa830e7c7566a..17c69223ea41687819cdc425f2ea389b1f4ea20f 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -5,7 +5,7 @@ uwu: src/*.c src/*.h
 
 .PHONY: std api
 
-std: std/bool.so std/int.so std/str.so std/nil.so
+std: std/bool.so std/int.so std/str.so std/nil.so std/ref.so
 api: api/api.so
 
 std/%.so: std/%.c
index 4cbc3f315eef00b6637f99cdad41fc999958bd85..768ae2fc14e99792148ce5221dc1c9e8307a66ae 100644 (file)
@@ -25,7 +25,7 @@ bool uwubool_get(UwUVMValue vm_value)
                return true;
 }
 
-static void *uwubool_copy(void *data)
+static void *uwubool_clone(void *data)
 {
        bool *copy = malloc(sizeof(*copy));
        *copy = *(bool *) data;
@@ -38,7 +38,7 @@ static char *uwubool_print(void *data)
 }
 
 UwUVMType uwubool_type = {
-       .copy = &uwubool_copy,
-       .delete = &free,
+       .clone = &uwubool_clone,
+       .delet = &free,
        .print = &uwubool_print,
 };
index 70dfd60e3067d739a4301db82f576c7ab166bdd0..2e43f782cbec72d5769f4fee40cb79300d2267ff 100644 (file)
@@ -5,8 +5,7 @@
 #include "vm.h"
 
 extern UwUVMType uwubool_type;
-
-UwUVMValue uwubool_create(bool value);
-bool uwubool_get(UwUVMValue vm_value);
+UwUVMValue       uwubool_create(bool value);
+bool             uwubool_get(UwUVMValue vm_value);
 
 #endif
index 0b9329d91a1a5ba06b88dfaf2213517262779801..8446d1d7c1a2c01b2caeb6451b0a672a6f681778 100644 (file)
--- a/api/int.c
+++ b/api/int.c
@@ -13,7 +13,12 @@ UwUVMValue uwuint_create(int value)
        return vm_value;
 }
 
-void *uwuint_copy(void *data)
+int uwuint_get(UwUVMValue vm_value)
+{
+       return *(int *) vm_value.data;
+}
+
+void *uwuint_clone(void *data)
 {
        int *copy = malloc(sizeof(*copy));
        *copy = *(int *) data;
@@ -26,7 +31,7 @@ char *uwuint_print(void *data)
 }
 
 UwUVMType uwuint_type = {
-       .copy = &uwuint_copy,
-       .delete = &free,
+       .clone = &uwuint_clone,
+       .delet = &free,
        .print = &uwuint_print,
 };
index e9c5798395151c7037577ddca8a291a7b7da16e0..6b5361dfc2608a361dd63dc5f8e660b59516c585 100644 (file)
--- a/api/int.h
+++ b/api/int.h
@@ -4,7 +4,7 @@
 #include "vm.h"
 
 extern UwUVMType uwuint_type;
-
-UwUVMValue uwuint_create(int value);
+UwUVMValue       uwuint_create(int value);
+int              uwuint_get(UwUVMValue vm_value);
 
 #endif
index b6304e013a9f63dc2030014c89895baadcc20c13..2c47cb60941990e71e1856d032f5558ad83b0bf0 100644 (file)
--- a/api/nil.c
+++ b/api/nil.c
@@ -9,12 +9,12 @@ UwUVMValue uwunil_create()
        };
 }
 
-static void *uwunil_copy(void *data)
+static void *uwunil_clone(void *data)
 {
        return data;
 }
 
-static void uwunil_delete(void *data)
+static void uwunil_delet(void *data)
 {
        (void) data;
 }
@@ -26,7 +26,7 @@ static char *uwunil_print(void *data)
 }
 
 UwUVMType uwunil_type = {
-       .copy = &uwunil_copy,
-       .delete = &uwunil_delete,
+       .clone = &uwunil_clone,
+       .delet = &uwunil_delet,
        .print = &uwunil_print,
 };
index 014be45c607483bca8d825a76d9d83b3f6121e90..7b2a5cfac5f354c657c7b9557f85b7d1ded5aa74 100644 (file)
--- a/api/nil.h
+++ b/api/nil.h
@@ -4,7 +4,6 @@
 #include "vm.h"
 
 extern UwUVMType uwunil_type;
-
-UwUVMValue uwunil_create();
+UwUVMValue       uwunil_create();
 
 #endif
index f66ae19e69d3f403af1d9b5905f9db04dc96e112..43eb68e4cb0b95d3bb35f7e75211a35e22ea5b5c 100644 (file)
--- a/api/ref.c
+++ b/api/ref.c
@@ -1,20 +1,25 @@
 #include "../src/util.h"
 #include "ref.h"
 
-UwUVMValue uwuref_create(UwUVMFunction *function)
+UwUVMValue uwuref_create(UwUVMFunction *value)
 {
        return (UwUVMValue) {
                .type = &uwuref_type,
-               .data = function,
+               .data = value,
        };
 }
 
-static void *uwuref_copy(void *data)
+UwUVMFunction *uwuref_get(UwUVMValue value)
+{
+       return value.data;
+}
+
+static void *uwuref_clone(void *data)
 {
        return data;
 }
 
-static void uwuref_delete(void *data)
+static void uwuref_delet(void *data)
 {
        (void) data;
 }
@@ -25,7 +30,7 @@ static char *uwuref_print(void *data)
 }
 
 UwUVMType uwuref_type = {
-       .copy = &uwuref_copy,
-       .delete = &uwuref_delete,
+       .clone = &uwuref_clone,
+       .delet = &uwuref_delet,
        .print = &uwuref_print,
 };
index 6a2fead614bb6cc7224f70708219c21b8b8f776e..4bbe017ffd49dc75545520863fc52e85b20db2d2 100644 (file)
--- a/api/ref.h
+++ b/api/ref.h
@@ -4,7 +4,7 @@
 #include "vm.h"
 
 extern UwUVMType uwuref_type;
-
-UwUVMValue uwuref_create(UwUVMFunction *function);
+UwUVMValue       uwuref_create(UwUVMFunction *value);
+UwUVMFunction   *uwuref_get(UwUVMValue vm_value);
 
 #endif
index 84d2b107047ea1cad107200fdcca40ee253824f9..eefd0d736beafcaa12e2a7dcd2df212e6948e923 100644 (file)
--- a/api/str.c
+++ b/api/str.c
@@ -12,10 +12,10 @@ UwUVMValue uwustr_create(const char *value)
 
 char *uwustr_get(UwUVMValue vm_value)
 {
-       vm_value.type->print(vm_value.data);
+       return uwuvm_print_value(vm_value);
 }
 
-static void *uwustr_copy(void *data)
+static void *uwustr_clone(void *data)
 {
        return strdup(data);
 }
@@ -26,7 +26,7 @@ static char *uwustr_print(void *data)
 }
 
 UwUVMType uwustr_type = {
-       .copy = &uwustr_copy,
-       .delete = &free,
+       .clone = &uwustr_clone,
+       .delet = &free,
        .print = &uwustr_print,
 };
index 609328e2a7255b3855adeb17bfe8662ada75fe60..d7596fc00f62769db255c26f198a5dbb2a183ec7 100644 (file)
--- a/api/str.h
+++ b/api/str.h
@@ -4,8 +4,7 @@
 #include "vm.h"
 
 extern UwUVMType uwustr_type;
-
-UwUVMValue uwustr_create(const char *value);
-char *uwustr_get(UwUVMValue vm_value);
+UwUVMValue       uwustr_create(const char *value);
+char            *uwustr_get(UwUVMValue vm_value);
 
 #endif
diff --git a/api/util.c b/api/util.c
new file mode 100644 (file)
index 0000000..c3e8a38
--- /dev/null
@@ -0,0 +1,15 @@
+#include "../src/err.h"
+#include "util.h"
+#include "bool.h"
+
+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);
+
+       for (size_t i = 0; i < args->num; i++)
+               if (uwuvm_get_arg(args, i).type != type)
+                       return uwubool_create(false);
+
+       return uwubool_create(true);
+}
diff --git a/api/util.h b/api/util.h
new file mode 100644 (file)
index 0000000..259f53a
--- /dev/null
@@ -0,0 +1,8 @@
+#ifndef _API_UTIL_H_
+#define _API_UTIL_H_
+
+#include "vm.h"
+
+UwUVMValue uwuutil_is_type(const char *fnname, UwUVMArgs *args, UwUVMType *type);
+
+#endif
index 73ec87eb92dee8cd1930f1ed50eda5706c55343d..5cab6c08465485025b5fc7cc89dd831ed2c643c9 100644 (file)
--- a/api/vm.c
+++ b/api/vm.c
@@ -6,33 +6,22 @@
 #include "ref.h"
 #include "int.h"
 
-void uwuvm_free_value(UwUVMValue value)
+UwUVMValue uwuvm_clone_value(UwUVMValue value)
 {
-       value.type->delete(value.data);
+       return (UwUVMValue) {
+               .type = value.type,
+               .data = value.type->clone(value.data),
+       };
 }
 
-void uwuvm_free_args(UwUVMArgs *args)
+void uwuvm_delet_value(UwUVMValue value)
 {
-       if (args->evaluated) {
-               for (size_t i = 0; i < args->num; i++) {
-                       UwUVMValue *value = args->evaluated[i];
-
-                       if (value) {
-                               uwuvm_free_value(*value);
-                               free(value);
-                       }
-               }
-
-               free(args->evaluated);
-       }
+       value.type->delet(value.data);
 }
 
-UwUVMValue uwuvm_copy_value(UwUVMValue value)
+char *uwuvm_print_value(UwUVMValue value)
 {
-       return (UwUVMValue) {
-               .type = value.type,
-               .data = value.type->copy(value.data),
-       };
+       return value.type->print(value.data);
 }
 
 UwUVMValue uwuvm_get_arg(UwUVMArgs *args, size_t i)
@@ -58,30 +47,53 @@ UwUVMValue uwuvm_evaluate_expression(UwUVMExpression *expression, UwUVMArgs *arg
                        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);
 
-                       return uwuvm_copy_value(uwuvm_get_arg(args, expression->value.int_value));
+                       return uwuvm_clone_value(uwuvm_get_arg(args, expression->value.int_value));
 
                case EX_FNNAME:
                        return uwuref_create(expression->value.ref_value);
 
                case EX_FNCALL:
-                       return uwuvm_run_function(expression->value.cll_value.function, (UwUVMArgs) {
-                               .num = expression->value.cll_value.num_args,
-                               .evaluated = expression->value.cll_value.num_args == 0 ? NULL : calloc(expression->value.cll_value.num_args, sizeof(UwUVMValue *)),
-                               .unevaluated = expression->value.cll_value.args,
-                               .super = args,
-                       });
+                       return uwuvm_call_function(
+                               expression->value.cll_value.function,
+                               expression->value.cll_value.num_args,
+                               expression->value.cll_value.args,
+                               args
+                       );
 
                default:
                        return (UwUVMValue) {};
        }
 }
 
-UwUVMValue uwuvm_run_function(UwUVMFunction *function, UwUVMArgs args)
+UwUVMValue uwuvm_call_function(UwUVMFunction *function, size_t num_args, UwUVMExpression *unevaluated_args, UwUVMArgs *super_args)
 {
-       UwUVMValue value = function->type == MODULE_PLAIN
+       UwUVMValue *evaluated_args[num_args];
+
+       for (size_t i = 0; i < num_args; i++)
+               evaluated_args[i] = NULL;
+
+       UwUVMArgs args = {
+               .num = num_args,
+               .evaluated = evaluated_args,
+               .unevaluated = unevaluated_args,
+               .super = super_args,
+       };
+
+       UwUVMValue return_value = function->type == MODULE_PLAIN
                ? uwuvm_evaluate_expression(function->value.plain, &args)
                : function->value.native(&args);
 
-       uwuvm_free_args(&args);
-       return value;
+       if (num_args > 0) {
+               for (size_t i = 0; i < num_args; i++) {
+                       UwUVMValue *value = evaluated_args[i];
+
+                       if (value) {
+                               uwuvm_delet_value(*value);
+                               free(value);
+                       }
+               }
+
+       }
+
+       return return_value;
 }
index 7286f63b93373578ed0bc77549fd537ba519714e..81465f83b7088792b3885e0887d6f45b7c597a9a 100644 (file)
--- a/api/vm.h
+++ b/api/vm.h
@@ -13,9 +13,9 @@ typedef enum
 
 typedef struct
 {
-       void *(*copy  )(void *data);
-       void  (*delete)(void *data);
-       char *(*print )(void *data);
+       void *(*clone)(void *data);
+       void  (*delet)(void *data);
+       char *(*print)(void *data);
 } UwUVMType;
 
 typedef struct
@@ -71,11 +71,11 @@ typedef struct
        size_t num_libraries;
 } UwUVMProgram;
 
-void uwuvm_free_value(UwUVMValue value);
-void uwuvm_free_args(UwUVMArgs *args);
-UwUVMValue uwuvm_copy_value(UwUVMValue value);
+UwUVMValue uwuvm_clone_value(UwUVMValue value);
+void       uwuvm_delet_value(UwUVMValue value);
+char      *uwuvm_print_value(UwUVMValue value);
 UwUVMValue uwuvm_get_arg(UwUVMArgs *args, size_t i);
 UwUVMValue uwuvm_evaluate_expression(UwUVMExpression *expression, UwUVMArgs *args);
-UwUVMValue uwuvm_run_function(UwUVMFunction *function, UwUVMArgs args);
+UwUVMValue uwuvm_call_function(UwUVMFunction *function, size_t num_args, UwUVMExpression *unevaluated_args, UwUVMArgs *super_args);
 
 #endif
index debf46055e83d72d9b14cc7280c08f6d3d83f433..2e7720bf4392dd2e00b369ae841bc9d8f3084a85 100644 (file)
@@ -1,50 +1,42 @@
 # Standard library
 
-## The `:nil` module
-
-- `:nil:nil`: The nil constant
-
 ## The `:bool` module
 
-- `:bool:if`: Requires exactly 3 arguments of arbitrary type. If $0 is a truthy value, evaluate and return $1. If $0 is a falsy value, evaluate and return $2. Values considered as falsy are: `:bool:false` and `:nil:nil`. Everything else is considered truey.
-
+- `:bool:if`: Requires exactly 3 arguments of arbitrary type. If $0 is a truthy value, evaluate and return $1. If $0 is a falsy value, evaluate and return $2. Values considered as falsy are: `:bool:false` and `:nil:nil`. Everything else is considered truthy.
 - `:bool:and`: Accepts an arbitrary number of arguments of arbitrary type, but at least one. Returns `:bool:true` if all of the arguments are considered truthy.
-
 - `:bool:or`: Accepts an arbitrary number of arguments of arbitrary type, but at least one. Returns `:bool:true` if at least one of the arguments is considered truthy.
-
 - `:bool:equal`: Accepts an arbitrary number of arguments of arbitrary type, but at least 2. Returns `bool:true` if either all of the arguments are considered truthy or all of the arguments are considered falsy.
-
 - `:bool:not`: Accepts exactly one argument of arbitrary type. Returns `:bool:true` if the $0 is considered falsy, returns `:bool:false` if $0 is considered truthy.
-
 - `:bool:true`: The true constant
-
 - `:bool:false`: The false constant
-
 - `:bool:is`: Accepts an arbitrary number of arguments of arbitrary type, but at least one. Returns `:bool:true` if all arguments are booleans (`:nil:nil` is NOT considered a boolean).
 
 ## The `:int` module
 
 - `:int:add`: Accepts an arbitrary number of integer arguments (or none at all) and returns the sum of all arguments, or `0` if none were given.
-
 - `:int:sub`: Accepts exactly 2 integer arguments and returns their difference.
-
 - `:int:mul`: Accepts an arbitrary number of integer arguments (or none at all) and returns the product of all arguments, or `1` if none were given.
-
 - `:int:div`: Accepts exactly 2 integer arguments and returns their quotient (rounded towards 0).
-
 - `:int:mod`: Accepts exactly 2 integer arguments and returns the reminder of their division.
-
 - `:int:smaller`: Accepts exactly 2 integer arguments and returns `:bool:true` if $0 is smaller than $1, `:boool:false` else.
-
 - `:int:greater`: Accepts exactly 2 integer arguments and returns `:bool:true` if $0 is greater than $1, `:bool:false` else.
-
 - `:int:equal`: Accepts an arbitrary number of integer arguments, but at least 2. Returns `bool:true` if all the arguments are equal.
-
 - `:int:is`: Accepts an arbitrary number of arguments of arbitrary type, but at least one. Returns `:bool:true` if all arguments are integers.
 
+## The `:nil` module
+
+- `:nil:nil`: The nil constant
+- `:nil:is`: Accepts an arbitrary number of arguments of arbitrary type, but at least one. Returns `:bool:true` if all arguments are strings.
+
+## The `:ref` module
+
+- `:ref:call`: Accepts a function reference as $0 and after that and arbitrary number of arguments of arbitrary type. Calls the function $0 with the arguments that follow and returns it's return value.
+- `:ref:is`: Accepts an arbitrary number of arguments of arbitrary type, but at least one. Returns `:bool:true` if all arguments are function references.
+
 ## The `:str` module
 
 - `:str:cat`: Accepts an arbitrary number of arguments of arbitrary type and returns the concatenation of their string representations.
+- `:str:is`: Accepts an arbitrary number of arguments of arbitrary type, but at least one. Returns `:bool:true` if all arguments are strings.
 
 ### String representations
 
index 335eb48d5b8aa261e4e89cbe72d38b7482fdc15b..8b1b13a9f38fd01ecac1f62cef012b9812406c9c 100644 (file)
--- a/src/vm.c
+++ b/src/vm.c
@@ -20,14 +20,14 @@ static void free_expression(UwUVMExpression *expr)
 void vm_run_file(const char *progname, const char *modname)
 {
        UwUVMProgram program = create_program(progname, modname);
-       UwUVMValue result = ((UwUVMValue (*)(UwUVMFunction *, UwUVMArgs args)) dlsym(program.api_library, "uwuvm_run_function"))(program.main_function, (UwUVMArgs) {.num = 0, .evaluated = NULL, .unevaluated = NULL, .super = NULL});
+       UwUVMValue result = ((UwUVMValue (*)(UwUVMFunction *, size_t, UwUVMExpression *, UwUVMArgs *)) dlsym(program.api_library, "uwuvm_call_function"))(program.main_function, 0, NULL, NULL);
 
-       char *str = ((char *(*)(UwUVMValue)) dlsym(program.api_library, "uwustr_get"))(result);
+       char *str = ((char *(*)(UwUVMValue)) dlsym(program.api_library, "uwuvm_print_value"))(result);
 
        printf("%s\n", str);
        free(str);
 
-       ((void (*)(UwUVMValue)) dlsym(program.api_library, "uwuvm_free_value"))(result);
+       ((void (*)(UwUVMValue)) dlsym(program.api_library, "uwuvm_delet_value"))(result);
 
        for (size_t i = 0; i < program.num_functions; i++) {
                UwUVMFunction *function = program.functions[i];
index 02aa8872a5d653b52ad12a6b577e8ea83e24bc6c..4386dc3fb9588b1335e026fd9b259c9879034099 100644 (file)
@@ -2,8 +2,10 @@
 #include <stdlib.h>
 #include "../src/err.h"
 #include "../api/vm.h"
+#include "../api/util.h"
 #include "../api/bool.h"
 
+
 static inline bool get_bool_arg(UwUVMArgs *args, size_t i)
 {
        return uwubool_get(uwuvm_get_arg(args, i));
@@ -14,7 +16,7 @@ UwUVMValue uwu_if(UwUVMArgs *args)
        if (args->num != 3)
                error("error: :bool:if requires exactly 3 arguments\n");
 
-       return uwuvm_copy_value(get_bool_arg(args, 0)
+       return uwuvm_clone_value(get_bool_arg(args, 0)
                ? uwuvm_get_arg(args, 1)
                : uwuvm_get_arg(args, 2)
        );
@@ -84,12 +86,5 @@ UwUVMValue uwu_false(UwUVMArgs *args)
 
 UwUVMValue uwu_is(UwUVMArgs *args)
 {
-       if (args->num < 1)
-               error("error: :bool:is requires at least 1 argument\n");
-
-       for (size_t i = 0; i < args->num; i++)
-               if (uwuvm_get_arg(args, i).type != &uwubool_type)
-                       return uwubool_create(false);
-
-       return uwubool_create(true);
+       return uwuutil_is_type(":bool:is", args, &uwubool_type);
 }
index c6c8ab7bd43ff4a545ab54289cf39f82b394fb8e..6857f26fea4dc731a7d527dad11ed3a10b22af9d 100644 (file)
--- a/std/int.c
+++ b/std/int.c
@@ -4,6 +4,7 @@
 #include "../api/vm.h"
 #include "../api/int.h"
 #include "../api/bool.h"
+#include "../api/util.h"
 
 typedef enum
 {
@@ -30,8 +31,8 @@ static int binary(const char *fnname, UwUVMArgs *args, BinaryOP op)
        if (value1.type != &uwuint_type)
                error("error: %s requires an integer as $1\n", fnname);
 
-       int a = *(int *) value0.data;
-       int b = *(int *) value1.data;
+       int a = uwuint_get(value0);
+       int b = uwuint_get(value1);
 
        switch (op) {
                case BOP_SUB: return a - b;
@@ -60,7 +61,7 @@ static int reduce(const char *fnname, UwUVMArgs *args, ReduceOP op, int result)
                if (value.type != &uwuint_type)
                        error("error: %s only accepts integers as arguments (invalid argument: $%lu)\n", fnname, i);
 
-               int this = *(int *) value.data;
+               int this = uwuint_get(value);
 
                switch (op) {
                        case ROP_ADD: result += this; break;
@@ -123,12 +124,5 @@ UwUVMValue uwu_equal(UwUVMArgs *args)
 
 UwUVMValue uwu_is(UwUVMArgs *args)
 {
-       if (args->num < 1)
-               error("error: :int:is requires at least 1 argument\n");
-
-       for (size_t i = 0; i < args->num; i++)
-               if (uwuvm_get_arg(args, i).type != &uwuint_type)
-                       return uwubool_create(false);
-
-       return uwubool_create(true);
+       return uwuutil_is_type(":int:is", args, &uwuint_type);
 }
index 33230fb498da792e8606c994087501ba6e2c8b56..599e3d42d4e91dc64f5c5cc7eb8eee9c5180f4e8 100644 (file)
--- a/std/nil.c
+++ b/std/nil.c
@@ -1,5 +1,6 @@
 #include "../src/err.h"
 #include "../api/nil.h"
+#include "../api/util.h"
 
 UwUVMValue uwu_nil(UwUVMArgs *args)
 {
@@ -8,3 +9,8 @@ UwUVMValue uwu_nil(UwUVMArgs *args)
 
        return uwunil_create();
 }
+
+UwUVMValue uwu_is(UwUVMArgs *args)
+{
+       return uwuutil_is_type(":nil:is", args, &uwunil_type);
+}
diff --git a/std/ref.c b/std/ref.c
new file mode 100644 (file)
index 0000000..f82bb50
--- /dev/null
+++ b/std/ref.c
@@ -0,0 +1,21 @@
+#include "../src/err.h"
+#include "../api/ref.h"
+#include "../api/util.h"
+
+UwUVMValue uwu_call(UwUVMArgs *args)
+{
+       if (args->num < 1)
+               error(":ref:call requires at least one argument\n");
+
+       UwUVMValue value = uwuvm_get_arg(args, 0);
+
+       if (value.type != &uwuref_type)
+               error(":ref:call requires a function reference as $0\n");
+
+       return uwuvm_call_function(value.data, args->num - 1, &args->unevaluated[1], args->super);
+}
+
+UwUVMValue uwu_is(UwUVMArgs *args)
+{
+       return uwuutil_is_type(":ref:is", args, &uwuref_type);
+}
index 16f756b4464212a46df698deefd628752f18ddd6..953e8c086ece3c07e74ee9e4ed99fa8cd4185598 100644 (file)
--- a/std/str.c
+++ b/std/str.c
@@ -2,6 +2,7 @@
 #include <stdlib.h>
 #include "../api/vm.h"
 #include "../api/str.h"
+#include "../api/util.h"
 
 UwUVMValue uwu_cat(UwUVMArgs *args)
 {
@@ -28,3 +29,8 @@ UwUVMValue uwu_cat(UwUVMArgs *args)
 
        return uwustr_create(result);
 }
+
+UwUVMValue uwu_is(UwUVMArgs *args)
+{
+       return uwuutil_is_type(":str:is", args, &uwustr_type);
+}