Last active
December 15, 2021 09:41
-
-
Save chuntaro/b425e270a3553344e3c3a3cddd89df80 to your computer and use it in GitHub Desktop.
C で多値を返す関数の実験コード
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| // | |
| // 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