1 /************************************************************************
2  *
3  * Copyright 2010-2012 Jakob Leben (jakob.leben@gmail.com)
4  *
5  * This file is part of SuperCollider Qt GUI.
6  *
7  * This program is free software: you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation, either version 2 of the License, or
10  * (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
19  *
20  ************************************************************************/
21 
22 #include <PyrPrimitive.h>
23 #include <VMGlobals.h>
24 #include <PyrSlot.h>
25 
26 #include <QList>
27 
28 #include <cstring>
29 
30 namespace QtCollider {
31 
32 template <typename T> struct LangPrimitive {};
33 
34 class LangPrimitiveDefiner {
35 public:
LangPrimitiveDefiner()36     LangPrimitiveDefiner(): _base(nextPrimitiveIndex()), _index(0) {}
37 
define()38     template <typename T> void define() { LangPrimitive<T>::define(_base, _index++); }
39 
40 private:
41     int _base;
42     int _index;
43 };
44 
45 
46 } // namespace
47 
48 #define QC_LANG_PRIMITIVE(NAME, ARGC, RECEIVER, ARGS, GLOBAL)                                                          \
49     struct NAME {};                                                                                                    \
50     template <> struct LangPrimitive<NAME> {                                                                           \
51         static int implementation(RECEIVER, ARGS, GLOBAL);                                                             \
52         static int mediate(VMGlobals* g, int i) {                                                                      \
53             PyrSlot* stack = g->sp - i + 1;                                                                            \
54             return implementation(stack, i > 1 ? stack + 1 : 0, g);                                                    \
55         }                                                                                                              \
56         static void define(int base, int index) { definePrimitive(base, index, "_" #NAME, &mediate, ARGC + 1, 0); }    \
57     };                                                                                                                 \
58     int LangPrimitive<NAME>::implementation(RECEIVER, ARGS, GLOBAL)
59 
60 #if 0
61 #    define QC_LANG_PRIMITIVE(name, argc, receiver, args, global)                                                      \
62         int name(receiver, args, global);                                                                              \
63         static QtCollider::LangPrimitive<&name> p_##name("_" #name, argc);                                             \
64         int name(receiver, args, global)
65 #endif