Skip to content

Commit 820bf8d

Browse files
committed
vinumc: expose args and names to external functions
1 parent b7f692d commit 820bf8d

7 files changed

Lines changed: 116 additions & 8 deletions

File tree

subprojects/vinumc/eval.c

Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -257,8 +257,37 @@ DO_CALLS_FUNC_SIGNATURE(do_calls_call) {
257257
find_symbol_on_scopes(&ctx->scopes, curr_scope, symbol_node->text);
258258

259259
// expose context to external function
260-
struct _call_ctx cctx = { .text = tmp_out.base };
260+
struct _call_ctx cctx = { .text = tmp_out.base, .status = false};
261+
261262
struct return_value call_return = symbol_info->as.func(&cctx);
263+
if (call_return.status == false) {
264+
size_t node;
265+
const struct ast_node *args_node = &VUT_VEC_AT(&ast->nodes, args_id);
266+
size_t len = cctx.args_req.len;
267+
for (size_t i = 0; i < len; i++) {
268+
node = VUT_VEC_AT(&args_node->childs, VUT_VEC_POP(&cctx.args_req));
269+
const struct ast_node *arg_node = &VUT_VEC_AT(&ast->nodes, node);
270+
if (arg_node->type == ASSIGNMENT) {
271+
node = VUT_VEC_AT(&arg_node->childs, 1);
272+
}
273+
struct vut_str arg_out = {};
274+
VUT_VEC_PUT(&arg_out, '\0');
275+
do_calls(ctx, ast, &arg_out, node, flags);
276+
VUT_VEC_PUT(&cctx.args, arg_out.base);
277+
}
278+
len = cctx.names_req.len;
279+
for (size_t i = 0; i < len; i++) {
280+
struct namespace_entry ne = *find_symbol_on_scopes(&ctx->scopes, curr_scope, VUT_VEC_POP(&cctx.names_req));
281+
node = ne.as.ast_node_id;
282+
struct vut_str name_out = {};
283+
VUT_VEC_PUT(&name_out, '\0');
284+
do_calls(ctx, ast, &name_out, node, flags);
285+
VUT_VEC_PUT(&cctx.names, name_out.base);
286+
}
287+
288+
cctx.status = true;
289+
call_return = symbol_info->as.func(&cctx);
290+
}
262291

263292
// put the extern function call return on the out str
264293

subprojects/vinumc/include/vinumc/extern_library.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,5 +24,7 @@ struct loaded_lib {
2424
};
2525

2626
struct return_value ctx_get_text(call_ctx ctx);
27+
struct return_value ctx_call(call_ctx ctx);
28+
struct return_value ctx_get_index(call_ctx ctx, int index);
2729

2830
#endif //__EXTERN_LIBRARY_H__

subprojects/vinumc/meson.build

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -51,10 +51,15 @@ install_subdir(
5151
install_dir: 'include',
5252
)
5353

54+
vutils_dep = dependency('vutils', fallback : ['vutils', 'vutils_dep'])
55+
5456
extern_library = library(
5557
'extern_library',
5658
'v_lib.c',
5759
include_directories: local_inc,
60+
dependencies: [
61+
vutils_dep,
62+
],
5863
install: true
5964
)
6065

@@ -63,8 +68,6 @@ extern_library_dep = declare_dependency(
6368
include_directories: external_inc,
6469
)
6570

66-
vutils_dep = dependency('vutils', fallback : ['vutils', 'vutils_dep'])
67-
6871
vinumc = executable(
6972
'vinumc',
7073
vinumc_srcs,

subprojects/vinumc/tests/library_test.c

Lines changed: 27 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,17 +3,39 @@
33
void test_call(struct vunit_test_ctx *ctx) {
44
char *out = NULL;
55

6-
vunit_run_vinumc_ok(ctx, "[return_arg test]\n", &out, "--with",
6+
vunit_run_vinumc_ok(ctx, "[return_text test]\n", &out, "--with",
77
"subprojects/vinumc/tests/libtestlib.so", NULL);
88

99
VUNIT_ASSERT_STREQ(ctx, out, "test");
1010
}
1111

12+
void test_arg_call(struct vunit_test_ctx *ctx) {
13+
char *out = NULL;
14+
15+
vunit_run_vinumc_ok(ctx,
16+
"[hello: world!]\n"
17+
"[return_text hello]\n"
18+
"[return_call hello]\n",
19+
&out, "--with", "subprojects/vinumc/tests/libtestlib.so", NULL);
20+
21+
VUNIT_ASSERT_STREQ(ctx, out, "helloworld!");
22+
}
23+
24+
void test_arg_by_index(struct vunit_test_ctx *ctx) {
25+
char *out = NULL;
26+
27+
vunit_run_vinumc_ok(ctx,
28+
"[invert [a:2][b:1]]\n",
29+
&out, "--with", "subprojects/vinumc/tests/libtestlib.so", NULL);
30+
31+
VUNIT_ASSERT_STREQ(ctx, out, "1 2");
32+
}
33+
1234
void test_nested_call(struct vunit_test_ctx *ctx) {
1335
char *out = NULL;
1436

1537
vunit_run_vinumc_ok(ctx,
16-
"[a: This is a [return_arg Test!]!]\n"
38+
"[a: This is a [return_text Test!]!]\n"
1739
"[a]\n",
1840
&out, "--with", "subprojects/vinumc/tests/libtestlib.so", NULL);
1941

@@ -23,7 +45,7 @@ void test_nested_call(struct vunit_test_ctx *ctx) {
2345
void test_empty_nested_call(struct vunit_test_ctx *ctx) {
2446
char *out = NULL;
2547

26-
vunit_run_vinumc_ok(ctx, "[return_arg [return_arg [return_arg]]]", &out, "--with",
48+
vunit_run_vinumc_ok(ctx, "[return_text [return_text [return_text]]]", &out, "--with",
2749
"subprojects/vinumc/tests/libtestlib.so", NULL);
2850

2951
VUNIT_ASSERT_STREQ(ctx, out, "");
@@ -40,6 +62,8 @@ void test_call_no_args(struct vunit_test_ctx *ctx) {
4062

4163
struct vunit_test tests[] = {
4264
{ .name = "Test extern library call", .test_func = test_call },
65+
{ .name = "Test extern library get by index", .test_func = test_arg_by_index },
66+
{ .name = "Test extern library call get text and get arg", .test_func = test_arg_call },
4367
{ .name = "Test extern library call inside call", .test_func = test_nested_call },
4468
{ .name = "Test nested empty library calls", .test_func = test_empty_nested_call },
4569
{

subprojects/vinumc/tests/testlib.c

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,30 @@
1+
#include <stdio.h>
12
#include <stdlib.h>
23
#include <string.h>
34

45
#include <vinumc/extern_library.h>
56

6-
struct return_value return_arg(call_ctx ctx) {
7+
struct return_value return_text(call_ctx ctx) {
78
return ctx_get_text(ctx);
89
}
910

11+
struct return_value return_call(call_ctx ctx) {
12+
return ctx_call(ctx);
13+
}
14+
15+
struct return_value invert(call_ctx ctx) {
16+
struct return_value ret = {};
17+
ret = ctx_get_index(ctx, 0);
18+
char *a = ret.ptr;
19+
ret = ctx_get_index(ctx, 1);
20+
char *b = ret.ptr;
21+
if (ret.status) {
22+
sprintf(ret.ptr ,"%s %s", b, a);
23+
24+
}
25+
return ret;
26+
}
27+
1028
struct return_value parenthesize(call_ctx ctx) {
1129
struct return_value ret = ctx_get_text(ctx);
1230
if (!ret.status) {
@@ -26,8 +44,10 @@ struct return_value parenthesize(call_ctx ctx) {
2644
}
2745

2846
struct extern_function *expose_library() {
29-
static struct extern_function lib[] = { { "return_arg", return_arg },
47+
static struct extern_function lib[] = { { "return_text", return_text },
48+
{ "return_call", return_call },
3049
{ "parenthesize", parenthesize },
50+
{ "invert", invert },
3151
{} };
3252
return lib;
3353
}

subprojects/vinumc/v_lib.c

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,3 +4,21 @@
44
struct return_value ctx_get_text(call_ctx ctx) {
55
return (struct return_value){ .ptr = ctx->text, .status = true };
66
}
7+
8+
struct return_value ctx_call(call_ctx ctx) {
9+
if (ctx->status == true) {
10+
return (struct return_value){ .ptr = VUT_VEC_POP(&ctx->names), .status = true };
11+
}
12+
struct return_value ret = { .status = false};
13+
VUT_VEC_PUT(&ctx->names_req, ctx->text);
14+
return ret;
15+
}
16+
17+
struct return_value ctx_get_index(call_ctx ctx, int index) {
18+
if (ctx->status == true) {
19+
return (struct return_value){ .ptr = VUT_VEC_POP(&ctx->args), .status = true };
20+
}
21+
struct return_value ret = { .status = false};
22+
VUT_VEC_PUT(&ctx->args_req, index);
23+
return ret;
24+
}

subprojects/vinumc/v_lib.h

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,20 @@
11
#ifndef __V_LIB_H__
22
#define __V_LIB_H__
33

4+
#include <stdbool.h>
5+
#include <vutils/vec.h>
6+
7+
struct v_str_vec VUT_VEC_DEF(char *);
8+
struct arg_vec VUT_VEC_DEF(int);
9+
struct name_vec VUT_VEC_DEF(char *);
10+
411
struct _call_ctx {
512
char *text;
13+
struct v_str_vec args;
14+
struct v_str_vec names;
15+
struct arg_vec args_req;
16+
struct name_vec names_req;
17+
bool status;
618
};
719

820
#endif //__V_LIB_H__

0 commit comments

Comments
 (0)