Skip to content

Instantly share code, notes, and snippets.

@chuntaro
Last active December 15, 2021 09:41
Show Gist options
  • Select an option

  • Save chuntaro/b425e270a3553344e3c3a3cddd89df80 to your computer and use it in GitHub Desktop.

Select an option

Save chuntaro/b425e270a3553344e3c3a3cddd89df80 to your computer and use it in GitHub Desktop.
C で多値を返す関数の実験コード
//
// C で多値を返す関数の実験コード
//
// Lisp -> C へのトランスレータを実装する時に多値をどう実装すればいいかを確認する実験コード
//
// 基本的に values() の呼び出しは values1 が呼ばれる
// 多値が必要な時は multiple-value-bind の第2引数で呼ばれた時のみで、
// レキシカルに判断出来るので、この方法で問題無い(はず…)
#include <stdio.h>
#include <stdarg.h>
#include <stdint.h>
////////////////////////////////////////////////////////////////
typedef int Object;
// _Thread_local
Object __multiple_values__[128];
Object values1(int n, Object a, ...)
{
(void)n;
return a;
}
Object valuesn(int n, Object a, ...)
{
va_list va_args;
va_start(va_args, a);
for (int i = 0; i < n - 1; ++i) {
__multiple_values__[i] = va_arg(va_args, Object);
}
va_end(va_args);
return a;
}
// _Thread_local
Object (*values)(int, Object, ...) = values1;
#define MULTIPLE_VALUE_BIND2(var1, var2, form, body) \
{ \
Object var1, var2; \
values = valuesn; \
var1 = form; \
var2 = __multiple_values__[0]; \
values = values1; \
body; \
}
#define MULTIPLE_VALUE_BIND3(var1, var2, var3, form, body) \
{ \
Object var1, var2, var3; \
values = valuesn; \
var1 = form; \
var2 = __multiple_values__[0]; \
var3 = __multiple_values__[1]; \
values = values1; \
body; \
}
////////////////////////////////////////////////////////////////
Object my_func(Object n)
{
return values(3, n, 30 * n, 90 * n);
}
int main(void)
{
printf("-> %d\n", my_func(3)); // -> 3
MULTIPLE_VALUE_BIND3(a, b, c, my_func(5), {
printf("-> %d\n", my_func(9)); // -> 9
printf("a -> %d, b -> %d, c -> %d\n", a, b, c); // a -> 5, b -> 150, c -> 450
MULTIPLE_VALUE_BIND2(d, e, my_func(7), {
printf("d -> %d, e -> %d\n", d, e); // d -> 7, e -> 210
});
});
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment