]> git.lizzy.rs Git - uwu-lang.git/blob - api/vm.c
Argument counting starts at 1 now
[uwu-lang.git] / api / vm.c
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include "common/err.h"
4 #include "vm.h"
5 #include "str.h"
6 #include "ref.h"
7 #include "int.h"
8
9 UwUVMValue uwuvm_clone_value(UwUVMValue value)
10 {
11         return (UwUVMValue) {
12                 .type = value.type,
13                 .data = value.type->clone(value.data),
14         };
15 }
16
17 void uwuvm_delet_value(UwUVMValue value)
18 {
19         value.type->delet(value.data);
20 }
21
22 char *uwuvm_print_value(UwUVMValue value)
23 {
24         return value.type->print(value.data);
25 }
26
27 UwUVMValue uwuvm_get_arg(UwUVMArgs *args, size_t i)
28 {
29         if (! args->evaluated[i]) {
30                 args->evaluated[i] = malloc(sizeof(UwUVMValue));
31                 *(args->evaluated[i]) = uwuvm_evaluate_expression(&args->unevaluated[i], args->super);
32         }
33
34         return *(args->evaluated[i]);
35 }
36
37 UwUVMValue uwuvm_evaluate_expression(UwUVMExpression *expression, UwUVMArgs *args)
38 {
39         switch (expression->type) {
40                 case EX_INTLIT:
41                         return uwuint_create(expression->value.int_value);
42
43                 case EX_STRLIT:
44                         return uwustr_create(expression->value.str_value);
45
46                 case EX_ARGNUM:
47                         if (expression->value.int_value == 0)
48                                 error("type error: trying to access argument $0\n");
49                         if ((size_t) expression->value.int_value > args->num)
50                                 error("type error: trying to access argument $%d, but only %lu arguments were passed)\n", expression->value.int_value, args->num);
51
52                         return uwuvm_clone_value(uwuvm_get_arg(args, expression->value.int_value - 1));
53
54                 case EX_FNNAME:
55                         return uwuref_create(expression->value.ref_value);
56
57                 case EX_FNCALL:
58                         return uwuvm_call_function(
59                                 expression->value.cll_value.function,
60                                 expression->value.cll_value.num_args,
61                                 expression->value.cll_value.args,
62                                 args
63                         );
64
65                 default:
66                         return (UwUVMValue) {};
67         }
68 }
69
70 UwUVMValue uwuvm_call_function(UwUVMFunction *function, size_t num_args, UwUVMExpression *unevaluated_args, UwUVMArgs *super_args)
71 {
72         UwUVMValue *evaluated_args[num_args];
73
74         for (size_t i = 0; i < num_args; i++)
75                 evaluated_args[i] = NULL;
76
77         UwUVMArgs args = {
78                 .num = num_args,
79                 .evaluated = evaluated_args,
80                 .unevaluated = unevaluated_args,
81                 .super = super_args,
82         };
83
84         UwUVMValue return_value = function->type == MODULE_PLAIN
85                 ? uwuvm_evaluate_expression(function->value.plain, &args)
86                 : function->value.native(&args);
87
88         if (num_args > 0) {
89                 for (size_t i = 0; i < num_args; i++) {
90                         UwUVMValue *value = evaluated_args[i];
91
92                         if (value) {
93                                 uwuvm_delet_value(*value);
94                                 free(value);
95                         }
96                 }
97
98         }
99
100         return return_value;
101 }