]> git.lizzy.rs Git - uwu-lang.git/blob - api/vm.c
Allow passing arguments to program, refactor directory structure
[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 ((size_t) expression->value.int_value >= args->num)
48                                 error("error: not enough arguments (accessed argument $%d, but only %lu arguments were passed)\n", expression->value.int_value, args->num);
49
50                         return uwuvm_clone_value(uwuvm_get_arg(args, expression->value.int_value));
51
52                 case EX_FNNAME:
53                         return uwuref_create(expression->value.ref_value);
54
55                 case EX_FNCALL:
56                         return uwuvm_call_function(
57                                 expression->value.cll_value.function,
58                                 expression->value.cll_value.num_args,
59                                 expression->value.cll_value.args,
60                                 args
61                         );
62
63                 default:
64                         return (UwUVMValue) {};
65         }
66 }
67
68 UwUVMValue uwuvm_call_function(UwUVMFunction *function, size_t num_args, UwUVMExpression *unevaluated_args, UwUVMArgs *super_args)
69 {
70         UwUVMValue *evaluated_args[num_args];
71
72         for (size_t i = 0; i < num_args; i++)
73                 evaluated_args[i] = NULL;
74
75         UwUVMArgs args = {
76                 .num = num_args,
77                 .evaluated = evaluated_args,
78                 .unevaluated = unevaluated_args,
79                 .super = super_args,
80         };
81
82         UwUVMValue return_value = function->type == MODULE_PLAIN
83                 ? uwuvm_evaluate_expression(function->value.plain, &args)
84                 : function->value.native(&args);
85
86         if (num_args > 0) {
87                 for (size_t i = 0; i < num_args; i++) {
88                         UwUVMValue *value = evaluated_args[i];
89
90                         if (value) {
91                                 uwuvm_delet_value(*value);
92                                 free(value);
93                         }
94                 }
95
96         }
97
98         return return_value;
99 }