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 }