1 #include "nebu_scripting.h"
2 
3 #include "lua.h"
4 #include "lualib.h"
5 
6 #include <stdarg.h>
7 #include <stdio.h>
8 #include <stdlib.h>
9 #include <string.h>
10 
11 // static lua_State *L;
12 lua_State *L;
13 
14 extern void init_c_interface(lua_State *L);
15 
scripting_Init()16 void scripting_Init() {
17   L = lua_open(0);
18   lua_baselibopen(L);
19   lua_strlibopen(L);
20   lua_iolibopen(L);
21 
22   // init_c_interface(L);
23 }
24 
scripting_Quit()25 void scripting_Quit() {
26   lua_close(L);
27 }
28 
29 
showStack()30 void showStack() {
31 	int i;
32 	printf("dumping stack with %d elements\n", lua_gettop(L));
33 	for(i = 0; i < lua_gettop(L); i++) {
34 		int type = lua_type(L, - (i+1));
35 		switch(type) {
36 		case LUA_TNIL: printf("nil\n"); break;
37 		case LUA_TNUMBER: printf("number\n"); break;
38 		case LUA_TSTRING: printf("string\n"); break;
39 		case LUA_TTABLE: printf("table\n"); break;
40 		case LUA_TFUNCTION: printf("function\n"); break;
41 		case LUA_TUSERDATA: printf("userdata\n"); break;
42 		}
43 	}
44 }
45 
scripting_IsNilResult()46 int scripting_IsNilResult() {
47 	int result = lua_isnil(L, -1);
48 	lua_pop(L, 1);
49 	return result;
50 }
51 
getGlobal(const char * s,va_list ap)52 int getGlobal(const char *s, va_list ap) {
53 	int top = lua_gettop(L);
54 	int count = 0;
55 	while(s) {
56 		lua_pushstring(L, s);
57 		lua_gettable(L, -2);
58 		count++;
59 		s = va_arg(ap, char *);
60 	}
61 	lua_insert(L, top); /* move result to bottom */
62 	lua_pop(L, count); /* restore stack */
63 	return 0;
64 }
65 
scripting_GetGlobal(const char * global,const char * s,...)66 int scripting_GetGlobal(const char *global, const char *s, ...) {
67 	lua_getglobal(L, global);
68 	if(s) {
69 		va_list ap;
70 		va_start(ap, s);
71 		getGlobal(s, ap);
72 		va_end(ap);
73 	}
74 	return 0;
75 }
76 
scripting_SetFloat(float f,const char * name,const char * global,const char * s,...)77 int scripting_SetFloat(float f, const char *name, const char *global, const char *s, ...) {
78 	va_list ap;
79 
80 	if(global == NULL) {
81 		lua_pushnumber(L, f);
82 		lua_setglobal(L, global);
83 		return 0;
84 	}
85 
86 	lua_getglobal(L, global);
87 
88 	if(s) {
89 		va_start(ap, s);
90 		getGlobal(s, ap);
91 		va_end(ap);
92 	}
93 
94 	lua_pushstring(L, name);
95 	lua_pushnumber(L, f);
96 	lua_settable(L, -3);
97 	lua_pop(L, 1);
98 
99 	return 0;
100 }
101 
scripting_GetFloatResult(float * f)102 int scripting_GetFloatResult(float *f) {
103 	if(lua_isnumber(L, -1)) {
104     *f = lua_tonumber(L, -1);
105 		lua_pop(L, 1); /* restore stack */
106 		return 0;
107 	} else {
108 		showStack();
109     return 1;
110 	}
111 }
112 
scripting_GetIntegerResult(int * i)113 int scripting_GetIntegerResult(int *i) {
114 	if(lua_isnumber(L, -1)) {
115     *i = (int)lua_tonumber(L, -1);
116 		lua_pop(L, 1); /* restore stack */
117 		return 0;
118 	} else {
119 		showStack();
120 		return 1;
121 	}
122 }
123 
scripting_GetFloatArrayResult(float * f,int n)124 void scripting_GetFloatArrayResult(float *f, int n) {
125   int i;
126 
127   for(i = 0; i < n; i++) {
128     lua_rawgeti(L, -1, i + 1);
129     if(lua_isnumber(L, -1)) {
130       *(f + i) = (float)lua_tonumber(L, 2);
131     } else {
132       fprintf(stderr, "element %d is not number!\n", i);
133     }
134     lua_pop(L, 1); /* remove number from stack */
135   }
136 
137 	lua_pop(L, 1); /* remove table from stack */
138 }
139 
scripting_GetStringResult(char ** s)140 int scripting_GetStringResult(char **s) {
141   int status;
142   if(lua_isstring(L, -1)) {
143     int size;
144     status = 0;
145     size = lua_strlen(L, -1) + 1;
146     *s = malloc( size );
147     memcpy( *s, lua_tostring(L, -1), size );
148     /* printf("allocated string '%s' of size %d\n", *s, size); */
149   } else
150     status = 1;
151 
152   lua_pop(L, 1);
153   return status;
154 }
155 
scripting_CopyStringResult(char * s,int len)156 int scripting_CopyStringResult(char *s, int len) {
157   int status;
158   if(lua_isstring(L, -1)) {
159     int size, copy;
160     status = 0;
161     size = lua_strlen(L, -1) + 1;
162     if(size > len) { copy = len; status = 2; }
163     else copy = size;
164     memcpy( s, lua_tostring(L, -1), size );
165   } else
166     status = 1;
167 
168   lua_pop(L, 1);
169   return status;
170 }
171 
scripting_RunFile(const char * name)172 void scripting_RunFile(const char *name) {
173   lua_dofile(L, name);
174 }
175 
scripting_Run(const char * command)176 void scripting_Run(const char *command) {
177   /* fprintf(stderr, "[command] %s\n", command); */
178   lua_dostring(L, command);
179 }
180 
scripting_RunFormat(const char * format,...)181 void scripting_RunFormat(const char *format, ... ) {
182   char buf[4096];
183   va_list ap;
184   va_start(ap, format);
185   vsprintf(buf, format, ap);
186   va_end(ap);
187   scripting_Run(buf);
188 }
189 
scripting_RunGC()190 void scripting_RunGC() {
191   lua_setgcthreshold(L, 0);
192 }
193 
Scripting_Idle()194 void Scripting_Idle() {
195 	scripting_RunGC();
196 }
197 
scripting_Register(const char * name,int (* func)(lua_State * L))198 void scripting_Register(const char *name, int(*func) (lua_State *L)) {
199 	lua_register(L, name, func);
200 }
201