00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042 #include <dev/board.h>
00043 #include <sys/version.h>
00044 #include <sys/heap.h>
00045 #include <sys/timer.h>
00046 #include <sys/confnet.h>
00047 #include <sys/thread.h>
00048
00049 #include <gorp/edline.h>
00050
00051 #include <arpa/inet.h>
00052 #include <pro/dhcp.h>
00053
00054 #include <stdio.h>
00055 #include <io.h>
00056 #include <string.h>
00057
00058 #define lua_c
00059
00060 #include <lua/lua.h>
00061
00062 #include <lua/lauxlib.h>
00063 #include <lua/lualib.h>
00064
00065 #ifndef NUTLUA_PARSER_EXCLUDED
00066
00067 #ifdef __AVR__
00068 #define THREAD_LUASTACK 2048
00069 #else
00070 #define THREAD_LUASTACK 8192
00071 #endif
00072
00073 static char lua_line_buffer[LUA_MAXINPUT];
00074 static EDLINE *lua_line_edit;
00075
00076
00077
00078
00079 static void report(lua_State * L)
00080 {
00081 if (!lua_isnil(L, -1)) {
00082 const char *msg = lua_tostring(L, -1);
00083
00084 if (msg == NULL)
00085 msg = "(error object is not a string)";
00086 fputs(msg, stderr);
00087 fputc('\n', stderr);
00088 fflush(stderr);
00089 lua_pop(L, 1);
00090 }
00091 }
00092
00093
00094
00095
00096 static int traceback(lua_State * L)
00097 {
00098 if (!lua_isstring(L, 1))
00099 return 1;
00100 lua_getfield(L, LUA_GLOBALSINDEX, "debug");
00101 if (!lua_istable(L, -1)) {
00102 lua_pop(L, 1);
00103 return 1;
00104 }
00105 lua_getfield(L, -1, "traceback");
00106 if (!lua_isfunction(L, -1)) {
00107 lua_pop(L, 2);
00108 return 1;
00109 }
00110 lua_pushvalue(L, 1);
00111 lua_pushinteger(L, 2);
00112 lua_call(L, 2, 1);
00113 return 1;
00114 }
00115
00116
00117
00118
00119 static int docall(lua_State * L)
00120 {
00121 int status;
00122 int base;
00123
00124
00125
00126 base = lua_gettop(L);
00127 lua_pushcfunction(L, traceback);
00128 lua_insert(L, base);
00129
00130 status = lua_pcall(L, 0, LUA_MULTRET, base);
00131
00132
00133 lua_remove(L, base);
00134
00135
00136 if (status)
00137 lua_gc(L, LUA_GCCOLLECT, 0);
00138
00139 return status;
00140 }
00141
00142
00143
00144
00145 static const char *get_prompt(lua_State * L, int firstline)
00146 {
00147 const char *p;
00148
00149
00150 lua_getfield(L, LUA_GLOBALSINDEX, firstline ? "_PROMPT" : "_PROMPT2");
00151 p = lua_tostring(L, -1);
00152 if (p == NULL)
00153 p = (firstline ? LUA_PROMPT : LUA_PROMPT2);
00154 lua_pop(L, 1);
00155
00156 return p;
00157 }
00158
00159
00160
00161
00162 static int is_complete(lua_State * L, int status)
00163 {
00164 if (status == LUA_ERRSYNTAX) {
00165 size_t lmsg;
00166 const char *msg = lua_tolstring(L, -1, &lmsg);
00167 const char *tp = msg + lmsg - (sizeof(LUA_QL("<eof>")) - 1);
00168
00169 if (strstr(msg, LUA_QL("<eof>")) == tp) {
00170 lua_pop(L, 1);
00171 return 0;
00172 }
00173 }
00174 return 1;
00175 }
00176
00177
00178
00179
00180 static int pushline(lua_State * L, int firstline)
00181 {
00182 int l;
00183 const char *prmt;
00184
00185
00186 prmt = get_prompt(L, firstline);
00187 fputs(prmt, stdout);
00188 fflush(stdout);
00189
00190
00191 lua_line_buffer[0] = '\0';
00192 l = EdLineRead(lua_line_edit, lua_line_buffer, LUA_MAXINPUT);
00193
00194 if (l >= 0) {
00195
00196 if (firstline && lua_line_buffer[0] == '=')
00197 lua_pushfstring(L, "return %s", &lua_line_buffer[1]);
00198 else
00199 lua_pushstring(L, lua_line_buffer);
00200 }
00201 return l;
00202 }
00203
00204
00205
00206
00207 static int loadchunk(lua_State * L)
00208 {
00209 int status = -1;
00210
00211
00212 lua_settop(L, 0);
00213
00214 if (pushline(L, 1) >= 0) {
00215
00216 for (;;) {
00217 status = luaL_loadbuffer(L, lua_tostring(L, 1), lua_strlen(L, 1), "=stdin");
00218
00219 if (is_complete(L, status))
00220 break;
00221
00222 if (pushline(L, 0) < 0)
00223 return -1;
00224
00225 lua_pushliteral(L, "\n");
00226 lua_insert(L, -2);
00227 lua_concat(L, 3);
00228 }
00229 lua_saveline(L, 1);
00230 lua_remove(L, 1);
00231 }
00232 return status;
00233 }
00234
00235
00236
00237
00238 static int pmain(lua_State * L)
00239 {
00240 int status;
00241
00242
00243 lua_gc(L, LUA_GCSTOP, 0);
00244 luaL_openlibs(L);
00245 lua_gc(L, LUA_GCRESTART, 0);
00246
00247
00248
00249
00250 while ((status = loadchunk(L)) != -1) {
00251
00252 if (status == 0)
00253 status = docall(L);
00254
00255 if (status) {
00256 report(L);
00257 }
00258
00259 else if (lua_gettop(L) > 0) {
00260 lua_getglobal(L, "print");
00261 lua_insert(L, 1);
00262 if (lua_pcall(L, lua_gettop(L) - 1, 0, 0) != 0) {
00263 fprintf(stderr, lua_pushfstring(L, "error calling "
00264 LUA_QL("print") " (%s)", lua_tostring(L, -1)));
00265 fputc('\n', stderr);
00266 fflush(stderr);
00267 }
00268 }
00269 }
00270
00271 lua_settop(L, 0);
00272
00273 fputc('\n', stdout);
00274 fflush(stdout);
00275
00276 return 0;
00277 }
00278
00279
00280
00281
00282 THREAD(LuaThread, arg)
00283 {
00284 lua_State *L;
00285
00286 for (;;) {
00287
00288
00289 printf("Running on Nut/OS %s - %ld bytes free\n", NutVersionString(), (long)NutHeapAvailable());
00290
00291
00292 lua_line_edit = EdLineOpen(EDIT_MODE_ECHO | EDIT_MODE_HISTORY);
00293 if (lua_line_edit) {
00294
00295
00296 EdLineRegisterKeymap(lua_line_edit, EdLineKeyMapVt100);
00297
00298
00299 L = lua_open();
00300 if (L) {
00301 if (lua_cpcall(L, &pmain, NULL)) {
00302 report(L);
00303 }
00304
00305 lua_close(L);
00306 }
00307
00308 EdLineClose(lua_line_edit);
00309 }
00310 }
00311 }
00312
00313 #endif
00314
00315
00316
00317
00318 int main(void)
00319 {
00320 unsigned long baud = 115200;
00321
00322
00323 NutRegisterDevice(&DEV_CONSOLE, 0, 0);
00324 freopen(DEV_CONSOLE_NAME, "w", stdout);
00325 freopen(DEV_CONSOLE_NAME, "w", stderr);
00326 freopen(DEV_CONSOLE_NAME, "r", stdin);
00327 _ioctl(_fileno(stdin), UART_SETSPEED, &baud);
00328
00329
00330 puts("\n" LUA_RELEASE " " LUA_COPYRIGHT);
00331
00332 #ifdef NUTLUA_PARSER_EXCLUDED
00333 puts("Error: Stand-alone interpreter requires parser");
00334 #else
00335 #ifdef NUTLUA_IOLIB_TCP
00336 NutRegisterDevice(&DEV_ETHER, 0, 0);
00337 if (NutDhcpIfConfig(DEV_ETHER_NAME, 0, 60000)) {
00338 uint8_t mac[6] = { 0x00, 0x06, 0x98, 0x00, 0x00, 0x00 };
00339 if (NutDhcpIfConfig("eth0", mac, 60000)) {
00340 uint32_t ip_addr = inet_addr("192.168.192.100");
00341 uint32_t ip_mask = inet_addr("255.255.255.0");
00342 NutNetIfConfig("eth0", mac, ip_addr, ip_mask);
00343 }
00344 }
00345 printf("Network interface %s\n", inet_ntoa(confnet.cdn_ip_addr));
00346 #endif
00347
00348
00349
00350
00351 NutThreadCreate("lua", LuaThread, NULL, THREAD_LUASTACK * NUT_THREAD_STACK_MULT + NUT_THREAD_STACK_ADD);
00352 #endif
00353
00354 for(;;) {
00355 NutSleep(1000);
00356 }
00357 return 0;
00358 }