Showing the changes to src (16 of 56 files). Show all
Unified · Split
| @@ -0,0 +1,24 @@ | ||
| 1 | +# makefile for lua | |
| 2 | + | |
| 3 | +LIB= $(LUA)/lib | |
| 4 | +INC= $(LUA)/include | |
| 5 | + | |
| 6 | +CC= gcc | |
| 7 | +CFLAGS= -g -Wall -O2 -I$(INC) $(DEFS) | |
| 8 | +DEFS= -DMAXCODE=64000 -DMAXCONSTANT=1024 -DMAXSYMBOL=1024 -DMAXARRAY=1024 | |
| 9 | + | |
| 10 | +OBJS= hash.o inout.o lex.o opcode.o table.o y.tab.o | |
| 11 | +SLIB= $(LIB)/liblua.a | |
| 12 | +DLIB= $(LIB)/liblua.so.1.1 | |
| 13 | + | |
| 14 | +libs: $(SLIB) $(DLIB) | |
| 15 | + | |
| 16 | +$(SLIB): $(OBJS) | |
| 17 | + ar ruvl $@ $(OBJS) | |
| 18 | + ranlib $(SLIB) | |
| 19 | + | |
| 20 | +$(DLIB): $(OBJS) | |
| 21 | + ld -o $@ $(OBJS) | |
| 22 | + | |
| 23 | +clean: | |
| 24 | + rm -f $(OBJS) $(SLIB) $(DLIB) | |
| @@ -0,0 +1,347 @@ | ||
| 1 | +/* | |
| 2 | +** hash.c | |
| 3 | +** hash manager for lua | |
| 4 | +** Luiz Henrique de Figueiredo - 17 Aug 90 | |
| 5 | +*/ | |
| 6 | + | |
| 7 | +char *rcs_hash="$Id: hash.c,v 2.1 1994/04/20 22:07:57 celes Exp $"; | |
| 8 | + | |
| 9 | +#include <string.h> | |
| 10 | +#include <stdlib.h> | |
| 11 | + | |
| 12 | +#include "mm.h" | |
| 13 | + | |
| 14 | +#include "opcode.h" | |
| 15 | +#include "hash.h" | |
| 16 | +#include "inout.h" | |
| 17 | +#include "table.h" | |
| 18 | +#include "lua.h" | |
| 19 | + | |
| 20 | +#define streq(s1,s2) (strcmp(s1,s2)==0) | |
| 21 | +#define strneq(s1,s2) (strcmp(s1,s2)!=0) | |
| 22 | + | |
| 23 | +#define new(s) ((s *)malloc(sizeof(s))) | |
| 24 | +#define newvector(n,s) ((s *)calloc(n,sizeof(s))) | |
| 25 | + | |
| 26 | +#define nhash(t) ((t)->nhash) | |
| 27 | +#define nodelist(t) ((t)->list) | |
| 28 | +#define list(t,i) ((t)->list[i]) | |
| 29 | +#define markarray(t) ((t)->mark) | |
| 30 | +#define ref_tag(n) (tag(&(n)->ref)) | |
| 31 | +#define ref_nvalue(n) (nvalue(&(n)->ref)) | |
| 32 | +#define ref_svalue(n) (svalue(&(n)->ref)) | |
| 33 | + | |
| 34 | +#ifndef ARRAYBLOCK | |
| 35 | +#define ARRAYBLOCK 50 | |
| 36 | +#endif | |
| 37 | + | |
| 38 | +typedef struct ArrayList | |
| 39 | +{ | |
| 40 | + Hash *array; | |
| 41 | + struct ArrayList *next; | |
| 42 | +} ArrayList; | |
| 43 | + | |
| 44 | +static ArrayList *listhead = NULL; | |
| 45 | + | |
| 46 | +static int head (Hash *t, Object *ref) /* hash function */ | |
| 47 | +{ | |
| 48 | + if (tag(ref) == T_NUMBER) return (((int)nvalue(ref))%nhash(t)); | |
| 49 | + else if (tag(ref) == T_STRING) | |
| 50 | + { | |
| 51 | + int h; | |
| 52 | + char *name = svalue(ref); | |
| 53 | + for (h=0; *name!=0; name++) /* interpret name as binary number */ | |
| 54 | + { | |
| 55 | + h <<= 8; | |
| 56 | + h += (unsigned char) *name; /* avoid sign extension */ | |
| 57 | + h %= nhash(t); /* make it a valid index */ | |
| 58 | + } | |
| 59 | + return h; | |
| 60 | + } | |
| 61 | + else | |
| 62 | + { | |
| 63 | + lua_reportbug ("unexpected type to index table"); | |
| 64 | + return -1; | |
| 65 | + } | |
| 66 | +} | |
| 67 | + | |
| 68 | +static Node *present(Hash *t, Object *ref, int h) | |
| 69 | +{ | |
| 70 | + Node *n=NULL, *p; | |
| 71 | + if (tag(ref) == T_NUMBER) | |
| 72 | + { | |
| 73 | + for (p=NULL,n=list(t,h); n!=NULL; p=n, n=n->next) | |
| 74 | + if (ref_tag(n) == T_NUMBER && nvalue(ref) == ref_nvalue(n)) break; | |
| 75 | + } | |
| 76 | + else if (tag(ref) == T_STRING) | |
| 77 | + { | |
| 78 | + for (p=NULL,n=list(t,h); n!=NULL; p=n, n=n->next) | |
| 79 | + if (ref_tag(n) == T_STRING && streq(svalue(ref),ref_svalue(n))) break; | |
| 80 | + } | |
| 81 | + if (n==NULL) /* name not present */ | |
| 82 | + return NULL; | |
| 83 | +#if 0 | |
| 84 | + if (p!=NULL) /* name present but not first */ | |
| 85 | + { | |
| 86 | + p->next=n->next; /* move-to-front self-organization */ | |
| 87 | + n->next=list(t,h); | |
| 88 | + list(t,h)=n; | |
| 89 | + } | |
| 90 | +#endif | |
| 91 | + return n; | |
| 92 | +} | |
| 93 | + | |
| 94 | +static void freelist (Node *n) | |
| 95 | +{ | |
| 96 | + while (n) | |
| 97 | + { | |
| 98 | + Node *next = n->next; | |
| 99 | + free (n); | |
| 100 | + n = next; | |
| 101 | + } | |
| 102 | +} | |
| 103 | + | |
| 104 | +/* | |
| 105 | +** Create a new hash. Return the hash pointer or NULL on error. | |
| 106 | +*/ | |
| 107 | +static Hash *hashcreate (unsigned int nhash) | |
| 108 | +{ | |
| 109 | + Hash *t = new (Hash); | |
| 110 | + if (t == NULL) | |
| 111 | + { | |
| 112 | + lua_error ("not enough memory"); | |
| 113 | + return NULL; | |
| 114 | + } | |
| 115 | + nhash(t) = nhash; | |
| 116 | + markarray(t) = 0; | |
| 117 | + nodelist(t) = newvector (nhash, Node*); | |
| 118 | + if (nodelist(t) == NULL) | |
| 119 | + { | |
| 120 | + lua_error ("not enough memory"); | |
| 121 | + return NULL; | |
| 122 | + } | |
| 123 | + return t; | |
| 124 | +} | |
| 125 | + | |
| 126 | +/* | |
| 127 | +** Delete a hash | |
| 128 | +*/ | |
| 129 | +static void hashdelete (Hash *h) | |
| 130 | +{ | |
| 131 | + int i; | |
| 132 | + for (i=0; i<nhash(h); i++) | |
| 133 | + freelist (list(h,i)); | |
| 134 | + free (nodelist(h)); | |
| 135 | + free(h); | |
| 136 | +} | |
| 137 | + | |
| 138 | + | |
| 139 | +/* | |
| 140 | +** Mark a hash and check its elements | |
| 141 | +*/ | |
| 142 | +void lua_hashmark (Hash *h) | |
| 143 | +{ | |
| 144 | + if (markarray(h) == 0) | |
| 145 | + { | |
| 146 | + int i; | |
| 147 | + markarray(h) = 1; | |
| 148 | + for (i=0; i<nhash(h); i++) | |
| 149 | + { | |
| 150 | + Node *n; | |
| 151 | + for (n = list(h,i); n != NULL; n = n->next) | |
| 152 | + { | |
| 153 | + lua_markobject(&n->ref); | |
| 154 | + lua_markobject(&n->val); | |
| 155 | + } | |
| 156 | + } | |
| 157 | + } | |
| 158 | +} | |
| 159 | + | |
| 160 | +/* | |
| 161 | +** Garbage collection to arrays | |
| 162 | +** Delete all unmarked arrays. | |
| 163 | +*/ | |
| 164 | +void lua_hashcollector (void) | |
| 165 | +{ | |
| 166 | + ArrayList *curr = listhead, *prev = NULL; | |
| 167 | + while (curr != NULL) | |
| 168 | + { | |
| 169 | + ArrayList *next = curr->next; | |
| 170 | + if (markarray(curr->array) != 1) | |
| 171 | + { | |
| 172 | + if (prev == NULL) listhead = next; | |
| 173 | + else prev->next = next; | |
| 174 | + hashdelete(curr->array); | |
| 175 | + free(curr); | |
| 176 | + } | |
| 177 | + else | |
| 178 | + { | |
| 179 | + markarray(curr->array) = 0; | |
| 180 | + prev = curr; | |
| 181 | + } | |
| 182 | + curr = next; | |
| 183 | + } | |
| 184 | +} | |
| 185 | + | |
| 186 | + | |
| 187 | +/* | |
| 188 | +** Create a new array | |
| 189 | +** This function insert the new array at array list. It also | |
| 190 | +** execute garbage collection if the number of array created | |
| 191 | +** exceed a pre-defined range. | |
| 192 | +*/ | |
| 193 | +Hash *lua_createarray (int nhash) | |
| 194 | +{ | |
| 195 | + ArrayList *new = new(ArrayList); | |
| 196 | + if (new == NULL) | |
| 197 | + { | |
| 198 | + lua_error ("not enough memory"); | |
| 199 | + return NULL; | |
| 200 | + } | |
| 201 | + new->array = hashcreate(nhash); | |
| 202 | + if (new->array == NULL) | |
| 203 | + { | |
| 204 | + lua_error ("not enough memory"); | |
| 205 | + return NULL; | |
| 206 | + } | |
| 207 | + | |
| 208 | + if (lua_nentity == lua_block) | |
| 209 | + lua_pack(); | |
| 210 | + | |
| 211 | + lua_nentity++; | |
| 212 | + new->next = listhead; | |
| 213 | + listhead = new; | |
| 214 | + return new->array; | |
| 215 | +} | |
| 216 | + | |
| 217 | + | |
| 218 | +/* | |
| 219 | +** If the hash node is present, return its pointer, otherwise create a new | |
| 220 | +** node for the given reference and also return its pointer. | |
| 221 | +** On error, return NULL. | |
| 222 | +*/ | |
| 223 | +Object *lua_hashdefine (Hash *t, Object *ref) | |
| 224 | +{ | |
| 225 | + int h; | |
| 226 | + Node *n; | |
| 227 | + h = head (t, ref); | |
| 228 | + if (h < 0) return NULL; | |
| 229 | + | |
| 230 | + n = present(t, ref, h); | |
| 231 | + if (n == NULL) | |
| 232 | + { | |
| 233 | + n = new(Node); | |
| 234 | + if (n == NULL) | |
| 235 | + { | |
| 236 | + lua_error ("not enough memory"); | |
| 237 | + return NULL; | |
| 238 | + } | |
| 239 | + n->ref = *ref; | |
| 240 | + tag(&n->val) = T_NIL; | |
| 241 | + n->next = list(t,h); /* link node to head of list */ | |
| 242 | + list(t,h) = n; | |
| 243 | + } | |
| 244 | + return (&n->val); | |
| 245 | +} | |
| 246 | + | |
| 247 | + | |
| 248 | +/* | |
| 249 | +** Internal function to manipulate arrays. | |
| 250 | +** Given an array object and a reference value, return the next element | |
| 251 | +** in the hash. | |
| 252 | +** This function pushs the element value and its reference to the stack. | |
| 253 | +*/ | |
| 254 | +static void firstnode (Hash *a, int h) | |
| 255 | +{ | |
| 256 | + if (h < nhash(a)) | |
| 257 | + { | |
| 258 | + int i; | |
| 259 | + for (i=h; i<nhash(a); i++) | |
| 260 | + { | |
| 261 | + if (list(a,i) != NULL) | |
| 262 | + { | |
| 263 | + if (tag(&list(a,i)->val) != T_NIL) | |
| 264 | + { | |
| 265 | + lua_pushobject (&list(a,i)->ref); | |
| 266 | + lua_pushobject (&list(a,i)->val); | |
| 267 | + return; | |
| 268 | + } | |
| 269 | + else | |
| 270 | + { | |
| 271 | + Node *next = list(a,i)->next; | |
| 272 | + while (next != NULL && tag(&next->val) == T_NIL) next = next->next; | |
| 273 | + if (next != NULL) | |
| 274 | + { | |
| 275 | + lua_pushobject (&next->ref); | |
| 276 | + lua_pushobject (&next->val); | |
| 277 | + return; | |
| 278 | + } | |
| 279 | + } | |
| 280 | + } | |
| 281 | + } | |
| 282 | + } | |
| 283 | + lua_pushnil(); | |
| 284 | + lua_pushnil(); | |
| 285 | +} | |
| 286 | +void lua_next (void) | |
| 287 | +{ | |
| 288 | + Hash *a; | |
| 289 | + Object *o = lua_getparam (1); | |
| 290 | + Object *r = lua_getparam (2); | |
| 291 | + if (o == NULL || r == NULL) | |
| 292 | + { lua_error ("too few arguments to function `next'"); return; } | |
| 293 | + if (lua_getparam (3) != NULL) | |
| 294 | + { lua_error ("too many arguments to function `next'"); return; } | |
| 295 | + if (tag(o) != T_ARRAY) | |
| 296 | + { lua_error ("first argument of function `next' is not a table"); return; } | |
| 297 | + a = avalue(o); | |
| 298 | + if (tag(r) == T_NIL) | |
| 299 | + { | |
| 300 | + firstnode (a, 0); | |
| 301 | + return; | |
| 302 | + } | |
| 303 | + else | |
| 304 | + { | |
| 305 | + int h = head (a, r); | |
| 306 | + if (h >= 0) | |
| 307 | + { | |
| 308 | + Node *n = list(a,h); | |
| 309 | + while (n) | |
| 310 | + { | |
| 311 | + if (memcmp(&n->ref,r,sizeof(Object)) == 0) | |
| 312 | + { | |
| 313 | + if (n->next == NULL) | |
| 314 | + { | |
| 315 | + firstnode (a, h+1); | |
| 316 | + return; | |
| 317 | + } | |
| 318 | + else if (tag(&n->next->val) != T_NIL) | |
| 319 | + { | |
| 320 | + lua_pushobject (&n->next->ref); | |
| 321 | + lua_pushobject (&n->next->val); | |
| 322 | + return; | |
| 323 | + } | |
| 324 | + else | |
| 325 | + { | |
| 326 | + Node *next = n->next->next; | |
| 327 | + while (next != NULL && tag(&next->val) == T_NIL) next = next->next; | |
| 328 | + if (next == NULL) | |
| 329 | + { | |
| 330 | + firstnode (a, h+1); | |
| 331 | + return; | |
| 332 | + } | |
| 333 | + else | |
| 334 | + { | |
| 335 | + lua_pushobject (&next->ref); | |
| 336 | + lua_pushobject (&next->val); | |
| 337 | + } | |
| 338 | + return; | |
| 339 | + } | |
| 340 | + } | |
| 341 | + n = n->next; | |
| 342 | + } | |
| 343 | + if (n == NULL) | |
| 344 | + lua_error ("error in function 'next': reference not found"); | |
| 345 | + } | |
| 346 | + } | |
| 347 | +} | |
| @@ -0,0 +1,32 @@ | ||
| 1 | +/* | |
| 2 | +** hash.h | |
| 3 | +** hash manager for lua | |
| 4 | +** Luiz Henrique de Figueiredo - 17 Aug 90 | |
| 5 | +** $Id: hash.h,v 2.1 1994/04/20 22:07:57 celes Exp $ | |
| 6 | +*/ | |
| 7 | + | |
| 8 | +#ifndef hash_h | |
| 9 | +#define hash_h | |
| 10 | + | |
| 11 | +typedef struct node | |
| 12 | +{ | |
| 13 | + Object ref; | |
| 14 | + Object val; | |
| 15 | + struct node *next; | |
| 16 | +} Node; | |
| 17 | + | |
| 18 | +typedef struct Hash | |
| 19 | +{ | |
| 20 | + char mark; | |
| 21 | + unsigned int nhash; | |
| 22 | + Node **list; | |
| 23 | +} Hash; | |
| 24 | + | |
| 25 | + | |
| 26 | +Hash *lua_createarray (int nhash); | |
| 27 | +void lua_hashmark (Hash *h); | |
| 28 | +void lua_hashcollector (void); | |
| 29 | +Object *lua_hashdefine (Hash *t, Object *ref); | |
| 30 | +void lua_next (void); | |
| 31 | + | |
| 32 | +#endif | |
| @@ -0,0 +1,177 @@ | ||
| 1 | +/* | |
| 2 | +** inout.c | |
| 3 | +** Provide function to realise the input/output function and debugger | |
| 4 | +** facilities. | |
| 5 | +*/ | |
| 6 | + | |
| 7 | +char *rcs_inout="$Id: inout.c,v 1.2 1993/12/22 21:15:16 roberto Exp $"; | |
| 8 | + | |
| 9 | +#include <stdio.h> | |
| 10 | +#include <string.h> | |
| 11 | + | |
| 12 | +#include "opcode.h" | |
| 13 | +#include "hash.h" | |
| 14 | +#include "inout.h" | |
| 15 | +#include "table.h" | |
| 16 | + | |
| 17 | +/* Exported variables */ | |
| 18 | +int lua_linenumber; | |
| 19 | +int lua_debug; | |
| 20 | +int lua_debugline; | |
| 21 | + | |
| 22 | +/* Internal variables */ | |
| 23 | +#ifndef MAXFUNCSTACK | |
| 24 | +#define MAXFUNCSTACK 32 | |
| 25 | +#endif | |
| 26 | +static struct { int file; int function; } funcstack[MAXFUNCSTACK]; | |
| 27 | +static int nfuncstack=0; | |
| 28 | + | |
| 29 | +static FILE *fp; | |
| 30 | +static char *st; | |
| 31 | +static void (*usererror) (char *s); | |
| 32 | + | |
| 33 | +/* | |
| 34 | +** Function to set user function to handle errors. | |
| 35 | +*/ | |
| 36 | +void lua_errorfunction (void (*fn) (char *s)) | |
| 37 | +{ | |
| 38 | + usererror = fn; | |
| 39 | +} | |
| 40 | + | |
| 41 | +/* | |
| 42 | +** Function to get the next character from the input file | |
| 43 | +*/ | |
| 44 | +static int fileinput (void) | |
| 45 | +{ | |
| 46 | + int c = fgetc (fp); | |
| 47 | + return (c == EOF ? 0 : c); | |
| 48 | +} | |
| 49 | + | |
| 50 | +/* | |
| 51 | +** Function to get the next character from the input string | |
| 52 | +*/ | |
| 53 | +static int stringinput (void) | |
| 54 | +{ | |
| 55 | + st++; | |
| 56 | + return (*(st-1)); | |
| 57 | +} | |
| 58 | + | |
| 59 | +/* | |
| 60 | +** Function to open a file to be input unit. | |
| 61 | +** Return 0 on success or 1 on error. | |
| 62 | +*/ | |
| 63 | +int lua_openfile (char *fn) | |
| 64 | +{ | |
| 65 | + lua_linenumber = 1; | |
| 66 | + lua_setinput (fileinput); | |
| 67 | + fp = fopen (fn, "r"); | |
| 68 | + if (fp == NULL) return 1; | |
| 69 | + if (lua_addfile (fn)) return 1; | |
| 70 | + return 0; | |
| 71 | +} | |
| 72 | + | |
| 73 | +/* | |
| 74 | +** Function to close an opened file | |
| 75 | +*/ | |
| 76 | +void lua_closefile (void) | |
| 77 | +{ | |
| 78 | + if (fp != NULL) | |
| 79 | + { | |
| 80 | + lua_delfile(); | |
| 81 | + fclose (fp); | |
| 82 | + fp = NULL; | |
| 83 | + } | |
| 84 | +} | |
| 85 | + | |
| 86 | +/* | |
| 87 | +** Function to open a string to be input unit | |
| 88 | +*/ | |
| 89 | +int lua_openstring (char *s) | |
| 90 | +{ | |
| 91 | + lua_linenumber = 1; | |
| 92 | + lua_setinput (stringinput); | |
| 93 | + st = s; | |
| 94 | + { | |
| 95 | + char sn[64]; | |
| 96 | + sprintf (sn, "String: %10.10s...", s); | |
| 97 | + if (lua_addfile (sn)) return 1; | |
| 98 | + } | |
| 99 | + return 0; | |
| 100 | +} | |
| 101 | + | |
| 102 | +/* | |
| 103 | +** Function to close an opened string | |
| 104 | +*/ | |
| 105 | +void lua_closestring (void) | |
| 106 | +{ | |
| 107 | + lua_delfile(); | |
| 108 | +} | |
| 109 | + | |
| 110 | +/* | |
| 111 | +** Call user function to handle error messages, if registred. Or report error | |
| 112 | +** using standard function (fprintf). | |
| 113 | +*/ | |
| 114 | +void lua_error (char *s) | |
| 115 | +{ | |
| 116 | + if (usererror != NULL) usererror (s); | |
| 117 | + else fprintf (stderr, "lua: %s\n", s); | |
| 118 | +} | |
| 119 | + | |
| 120 | +/* | |
| 121 | +** Called to execute SETFUNCTION opcode, this function pushs a function into | |
| 122 | +** function stack. Return 0 on success or 1 on error. | |
| 123 | +*/ | |
| 124 | +int lua_pushfunction (int file, int function) | |
| 125 | +{ | |
| 126 | + if (nfuncstack >= MAXFUNCSTACK-1) | |
| 127 | + { | |
| 128 | + lua_error ("function stack overflow"); | |
| 129 | + return 1; | |
| 130 | + } | |
| 131 | + funcstack[nfuncstack].file = file; | |
| 132 | + funcstack[nfuncstack].function = function; | |
| 133 | + nfuncstack++; | |
| 134 | + return 0; | |
| 135 | +} | |
| 136 | + | |
| 137 | +/* | |
| 138 | +** Called to execute RESET opcode, this function pops a function from | |
| 139 | +** function stack. | |
| 140 | +*/ | |
| 141 | +void lua_popfunction (void) | |
| 142 | +{ | |
| 143 | + nfuncstack--; | |
| 144 | +} | |
| 145 | + | |
| 146 | +/* | |
| 147 | +** Report bug building a message and sending it to lua_error function. | |
| 148 | +*/ | |
| 149 | +void lua_reportbug (char *s) | |
| 150 | +{ | |
| 151 | + char msg[1024]; | |
| 152 | + strcpy (msg, s); | |
| 153 | + if (lua_debugline != 0) | |
| 154 | + { | |
| 155 | + int i; | |
| 156 | + if (nfuncstack > 0) | |
| 157 | + { | |
| 158 | + sprintf (strchr(msg,0), | |
| 159 | + "\n\tin statement begining at line %d in function \"%s\" of file \"%s\"", | |
| 160 | + lua_debugline, s_name(funcstack[nfuncstack-1].function), | |
| 161 | + lua_file[funcstack[nfuncstack-1].file]); | |
| 162 | + sprintf (strchr(msg,0), "\n\tactive stack\n"); | |
| 163 | + for (i=nfuncstack-1; i>=0; i--) | |
| 164 | + sprintf (strchr(msg,0), "\t-> function \"%s\" of file \"%s\"\n", | |
| 165 | + s_name(funcstack[i].function), | |
| 166 | + lua_file[funcstack[i].file]); | |
| 167 | + } | |
| 168 | + else | |
| 169 | + { | |
| 170 | + sprintf (strchr(msg,0), | |
| 171 | + "\n\tin statement begining at line %d of file \"%s\"", | |
| 172 | + lua_debugline, lua_filename()); | |
| 173 | + } | |
| 174 | + } | |
| 175 | + lua_error (msg); | |
| 176 | +} | |
| 177 | + | |
| @@ -0,0 +1,21 @@ | ||
| 1 | +/* | |
| 2 | +** $Id: inout.h,v 1.1 1993/12/17 18:41:19 celes Exp $ | |
| 3 | +*/ | |
| 4 | + | |
| 5 | + | |
| 6 | +#ifndef inout_h | |
| 7 | +#define inout_h | |
| 8 | + | |
| 9 | +extern int lua_linenumber; | |
| 10 | +extern int lua_debug; | |
| 11 | +extern int lua_debugline; | |
| 12 | + | |
| 13 | +int lua_openfile (char *fn); | |
| 14 | +void lua_closefile (void); | |
| 15 | +int lua_openstring (char *s); | |
| 16 | +void lua_closestring (void); | |
| 17 | +int lua_pushfunction (int file, int function); | |
| 18 | +void lua_popfunction (void); | |
| 19 | +void lua_reportbug (char *s); | |
| 20 | + | |
| 21 | +#endif | |
| @@ -0,0 +1,238 @@ | ||
| 1 | +char *rcs_lex = "$Id: lex.c,v 2.1 1994/04/15 19:00:28 celes Exp $"; | |
| 2 | +/*$Log: lex.c,v $ | |
| 3 | + * Revision 2.1 1994/04/15 19:00:28 celes | |
| 4 | + * Retirar chamada da funcao lua_findsymbol associada a cada | |
| 5 | + * token NAME. A decisao de chamar lua_findsymbol ou lua_findconstant | |
| 6 | + * fica a cargo do modulo "lua.stx". | |
| 7 | + * | |
| 8 | + * Revision 1.3 1993/12/28 16:42:29 roberto | |
| 9 | + * "include"s de string.h e stdlib.h para evitar warnings | |
| 10 | + * | |
| 11 | + * Revision 1.2 1993/12/22 21:39:15 celes | |
| 12 | + * Tratamento do token $debug e $nodebug | |
| 13 | + * | |
| 14 | + * Revision 1.1 1993/12/22 21:15:16 roberto | |
| 15 | + * Initial revision | |
| 16 | + **/ | |
| 17 | + | |
| 18 | +#include <ctype.h> | |
| 19 | +#include <math.h> | |
| 20 | +#include <stdlib.h> | |
| 21 | +#include <string.h> | |
| 22 | + | |
| 23 | +#include "opcode.h" | |
| 24 | +#include "hash.h" | |
| 25 | +#include "inout.h" | |
| 26 | +#include "table.h" | |
| 27 | +#include "y.tab.h" | |
| 28 | + | |
| 29 | +#define next() { current = input(); } | |
| 30 | +#define save(x) { *yytextLast++ = (x); } | |
| 31 | +#define save_and_next() { save(current); next(); } | |
| 32 | + | |
| 33 | +static int current; | |
| 34 | +static char yytext[256]; | |
| 35 | +static char *yytextLast; | |
| 36 | + | |
| 37 | +static Input input; | |
| 38 | + | |
| 39 | +void lua_setinput (Input fn) | |
| 40 | +{ | |
| 41 | + current = ' '; | |
| 42 | + input = fn; | |
| 43 | +} | |
| 44 | + | |
| 45 | +char *lua_lasttext (void) | |
| 46 | +{ | |
| 47 | + *yytextLast = 0; | |
| 48 | + return yytext; | |
| 49 | +} | |
| 50 | + | |
| 51 | + | |
| 52 | +static struct | |
| 53 | + { | |
| 54 | + char *name; | |
| 55 | + int token; | |
| 56 | + } reserved [] = { | |
| 57 | + {"and", AND}, | |
| 58 | + {"do", DO}, | |
| 59 | + {"else", ELSE}, | |
| 60 | + {"elseif", ELSEIF}, | |
| 61 | + {"end", END}, | |
| 62 | + {"function", FUNCTION}, | |
| 63 | + {"if", IF}, | |
| 64 | + {"local", LOCAL}, | |
| 65 | + {"nil", NIL}, | |
| 66 | + {"not", NOT}, | |
| 67 | + {"or", OR}, | |
| 68 | + {"repeat", REPEAT}, | |
| 69 | + {"return", RETURN}, | |
| 70 | + {"then", THEN}, | |
| 71 | + {"until", UNTIL}, | |
| 72 | + {"while", WHILE} }; | |
| 73 | + | |
| 74 | +#define RESERVEDSIZE (sizeof(reserved)/sizeof(reserved[0])) | |
| 75 | + | |
| 76 | + | |
| 77 | +int findReserved (char *name) | |
| 78 | +{ | |
| 79 | + int l = 0; | |
| 80 | + int h = RESERVEDSIZE - 1; | |
| 81 | + while (l <= h) | |
| 82 | + { | |
| 83 | + int m = (l+h)/2; | |
| 84 | + int comp = strcmp(name, reserved[m].name); | |
| 85 | + if (comp < 0) | |
| 86 | + h = m-1; | |
| 87 | + else if (comp == 0) | |
| 88 | + return reserved[m].token; | |
| 89 | + else | |
| 90 | + l = m+1; | |
| 91 | + } | |
| 92 | + return 0; | |
| 93 | +} | |
| 94 | + | |
| 95 | + | |
| 96 | +int yylex () | |
| 97 | +{ | |
| 98 | + while (1) | |
| 99 | + { | |
| 100 | + yytextLast = yytext; | |
| 101 | + switch (current) | |
| 102 | + { | |
| 103 | + case '\n': lua_linenumber++; | |
| 104 | + case ' ': | |
| 105 | + case '\t': | |
| 106 | + next(); | |
| 107 | + continue; | |
| 108 | + | |
| 109 | + case '$': | |
| 110 | + next(); | |
| 111 | + while (isalnum(current) || current == '_') | |
| 112 | + save_and_next(); | |
| 113 | + *yytextLast = 0; | |
| 114 | + if (strcmp(yytext, "debug") == 0) | |
| 115 | + { | |
| 116 | + yylval.vInt = 1; | |
| 117 | + return DEBUG; | |
| 118 | + } | |
| 119 | + else if (strcmp(yytext, "nodebug") == 0) | |
| 120 | + { | |
| 121 | + yylval.vInt = 0; | |
| 122 | + return DEBUG; | |
| 123 | + } | |
| 124 | + return WRONGTOKEN; | |
| 125 | + | |
| 126 | + case '-': | |
| 127 | + save_and_next(); | |
| 128 | + if (current != '-') return '-'; | |
| 129 | + do { next(); } while (current != '\n' && current != 0); | |
| 130 | + continue; | |
| 131 | + | |
| 132 | + case '<': | |
| 133 | + save_and_next(); | |
| 134 | + if (current != '=') return '<'; | |
| 135 | + else { save_and_next(); return LE; } | |
| 136 | + | |
| 137 | + case '>': | |
| 138 | + save_and_next(); | |
| 139 | + if (current != '=') return '>'; | |
| 140 | + else { save_and_next(); return GE; } | |
| 141 | + | |
| 142 | + case '~': | |
| 143 | + save_and_next(); | |
| 144 | + if (current != '=') return '~'; | |
| 145 | + else { save_and_next(); return NE; } | |
| 146 | + | |
| 147 | + case '"': | |
| 148 | + case '\'': | |
| 149 | + { | |
| 150 | + int del = current; | |
| 151 | + next(); /* skip the delimiter */ | |
| 152 | + while (current != del) | |
| 153 | + { | |
| 154 | + switch (current) | |
| 155 | + { | |
| 156 | + case 0: | |
| 157 | + case '\n': | |
| 158 | + return WRONGTOKEN; | |
| 159 | + case '\\': | |
| 160 | + next(); /* do not save the '\' */ | |
| 161 | + switch (current) | |
| 162 | + { | |
| 163 | + case 'n': save('\n'); next(); break; | |
| 164 | + case 't': save('\t'); next(); break; | |
| 165 | + case 'r': save('\r'); next(); break; | |
| 166 | + default : save('\\'); break; | |
| 167 | + } | |
| 168 | + break; | |
| 169 | + default: | |
| 170 | + save_and_next(); | |
| 171 | + } | |
| 172 | + } | |
| 173 | + next(); /* skip the delimiter */ | |
| 174 | + *yytextLast = 0; | |
| 175 | + yylval.vWord = lua_findconstant (yytext); | |
| 176 | + return STRING; | |
| 177 | + } | |
| 178 | + | |
| 179 | + case 'a': case 'b': case 'c': case 'd': case 'e': | |
| 180 | + case 'f': case 'g': case 'h': case 'i': case 'j': | |
| 181 | + case 'k': case 'l': case 'm': case 'n': case 'o': | |
| 182 | + case 'p': case 'q': case 'r': case 's': case 't': | |
| 183 | + case 'u': case 'v': case 'w': case 'x': case 'y': | |
| 184 | + case 'z': | |
| 185 | + case 'A': case 'B': case 'C': case 'D': case 'E': | |
| 186 | + case 'F': case 'G': case 'H': case 'I': case 'J': | |
| 187 | + case 'K': case 'L': case 'M': case 'N': case 'O': | |
| 188 | + case 'P': case 'Q': case 'R': case 'S': case 'T': | |
| 189 | + case 'U': case 'V': case 'W': case 'X': case 'Y': | |
| 190 | + case 'Z': | |
| 191 | + case '_': | |
| 192 | + { | |
| 193 | + int res; | |
| 194 | + do { save_and_next(); } while (isalnum(current) || current == '_'); | |
| 195 | + *yytextLast = 0; | |
| 196 | + res = findReserved(yytext); | |
| 197 | + if (res) return res; | |
| 198 | + yylval.pChar = yytext; | |
| 199 | + return NAME; | |
| 200 | + } | |
| 201 | + | |
| 202 | + case '.': | |
| 203 | + save_and_next(); | |
| 204 | + if (current == '.') | |
| 205 | + { | |
| 206 | + save_and_next(); | |
| 207 | + return CONC; | |
| 208 | + } | |
| 209 | + else if (!isdigit(current)) return '.'; | |
| 210 | + /* current is a digit: goes through to number */ | |
| 211 | + goto fraction; | |
| 212 | + | |
| 213 | + case '0': case '1': case '2': case '3': case '4': | |
| 214 | + case '5': case '6': case '7': case '8': case '9': | |
| 215 | + | |
| 216 | + do { save_and_next(); } while (isdigit(current)); | |
| 217 | + if (current == '.') save_and_next(); | |
| 218 | +fraction: while (isdigit(current)) save_and_next(); | |
| 219 | + if (current == 'e' || current == 'E') | |
| 220 | + { | |
| 221 | + save_and_next(); | |
| 222 | + if (current == '+' || current == '-') save_and_next(); | |
| 223 | + if (!isdigit(current)) return WRONGTOKEN; | |
| 224 | + do { save_and_next(); } while (isdigit(current)); | |
| 225 | + } | |
| 226 | + *yytextLast = 0; | |
| 227 | + yylval.vFloat = atof(yytext); | |
| 228 | + return NUMBER; | |
| 229 | + | |
| 230 | + default: /* also end of file */ | |
| 231 | + { | |
| 232 | + save_and_next(); | |
| 233 | + return *yytext; | |
| 234 | + } | |
| 235 | + } | |
| 236 | + } | |
| 237 | +} | |
| 238 | + | |
| @@ -0,0 +1,1021 @@ | ||
| 1 | +/* | |
| 2 | +** opcode.c | |
| 3 | +** TecCGraf - PUC-Rio | |
| 4 | +*/ | |
| 5 | + | |
| 6 | +char *rcs_opcode="$Id: opcode.c,v 2.1 1994/04/20 22:07:57 celes Exp $"; | |
| 7 | + | |
| 8 | +#include <stdio.h> | |
| 9 | +#include <stdlib.h> | |
| 10 | +#include <string.h> | |
| 11 | + | |
| 12 | +/* stdlib.h does not have this in SunOS */ | |
| 13 | +extern double strtod(const char *, char **); | |
| 14 | + | |
| 15 | +#include "mm.h" | |
| 16 | + | |
| 17 | +#include "opcode.h" | |
| 18 | +#include "hash.h" | |
| 19 | +#include "inout.h" | |
| 20 | +#include "table.h" | |
| 21 | +#include "lua.h" | |
| 22 | + | |
| 23 | +#define tonumber(o) ((tag(o) != T_NUMBER) && (lua_tonumber(o) != 0)) | |
| 24 | +#define tostring(o) ((tag(o) != T_STRING) && (lua_tostring(o) != 0)) | |
| 25 | + | |
| 26 | +#ifndef MAXSTACK | |
| 27 | +#define MAXSTACK 256 | |
| 28 | +#endif | |
| 29 | +static Object stack[MAXSTACK] = {{T_MARK, {NULL}}}; | |
| 30 | +static Object *top=stack+1, *base=stack+1; | |
| 31 | + | |
| 32 | + | |
| 33 | +/* | |
| 34 | +** Concatenate two given string, creating a mark space at the beginning. | |
| 35 | +** Return the new string pointer. | |
| 36 | +*/ | |
| 37 | +static char *lua_strconc (char *l, char *r) | |
| 38 | +{ | |
| 39 | + char *s = calloc (strlen(l)+strlen(r)+2, sizeof(char)); | |
| 40 | + if (s == NULL) | |
| 41 | + { | |
| 42 | + lua_error ("not enough memory"); | |
| 43 | + return NULL; | |
| 44 | + } | |
| 45 | + *s++ = 0; /* create mark space */ | |
| 46 | + return strcat(strcpy(s,l),r); | |
| 47 | +} | |
| 48 | + | |
| 49 | +/* | |
| 50 | +** Duplicate a string, creating a mark space at the beginning. | |
| 51 | +** Return the new string pointer. | |
| 52 | +*/ | |
| 53 | +char *lua_strdup (char *l) | |
| 54 | +{ | |
| 55 | + char *s = calloc (strlen(l)+2, sizeof(char)); | |
| 56 | + if (s == NULL) | |
| 57 | + { | |
| 58 | + lua_error ("not enough memory"); | |
| 59 | + return NULL; | |
| 60 | + } | |
| 61 | + *s++ = 0; /* create mark space */ | |
| 62 | + return strcpy(s,l); | |
| 63 | +} | |
| 64 | + | |
| 65 | +/* | |
| 66 | +** Convert, if possible, to a number tag. | |
| 67 | +** Return 0 in success or not 0 on error. | |
| 68 | +*/ | |
| 69 | +static int lua_tonumber (Object *obj) | |
| 70 | +{ | |
| 71 | + char *ptr; | |
| 72 | + if (tag(obj) != T_STRING) | |
| 73 | + { | |
| 74 | + lua_reportbug ("unexpected type at conversion to number"); | |
| 75 | + return 1; | |
| 76 | + } | |
| 77 | + nvalue(obj) = strtod(svalue(obj), &ptr); | |
| 78 | + if (*ptr) | |
| 79 | + { | |
| 80 | + lua_reportbug ("string to number convertion failed"); | |
| 81 | + return 2; | |
| 82 | + } | |
| 83 | + tag(obj) = T_NUMBER; | |
| 84 | + return 0; | |
| 85 | +} | |
| 86 | + | |
| 87 | +/* | |
| 88 | +** Test if is possible to convert an object to a number one. | |
| 89 | +** If possible, return the converted object, otherwise return nil object. | |
| 90 | +*/ | |
| 91 | +static Object *lua_convtonumber (Object *obj) | |
| 92 | +{ | |
| 93 | + static Object cvt; | |
| 94 | + | |
| 95 | + if (tag(obj) == T_NUMBER) | |
| 96 | + { | |
| 97 | + cvt = *obj; | |
| 98 | + return &cvt; | |
| 99 | + } | |
| 100 | + | |
| 101 | + tag(&cvt) = T_NIL; | |
| 102 | + if (tag(obj) == T_STRING) | |
| 103 | + { | |
| 104 | + char *ptr; | |
| 105 | + nvalue(&cvt) = strtod(svalue(obj), &ptr); | |
| 106 | + if (*ptr == 0) | |
| 107 | + tag(&cvt) = T_NUMBER; | |
| 108 | + } | |
| 109 | + return &cvt; | |
| 110 | +} | |
| 111 | + | |
| 112 | + | |
| 113 | + | |
| 114 | +/* | |
| 115 | +** Convert, if possible, to a string tag | |
| 116 | +** Return 0 in success or not 0 on error. | |
| 117 | +*/ | |
| 118 | +static int lua_tostring (Object *obj) | |
| 119 | +{ | |
| 120 | + static char s[256]; | |
| 121 | + if (tag(obj) != T_NUMBER) | |
| 122 | + { | |
| 123 | + lua_reportbug ("unexpected type at conversion to string"); | |
| 124 | + return 1; | |
| 125 | + } | |
| 126 | + if ((int) nvalue(obj) == nvalue(obj)) | |
| 127 | + sprintf (s, "%d", (int) nvalue(obj)); | |
| 128 | + else | |
| 129 | + sprintf (s, "%g", nvalue(obj)); | |
| 130 | + svalue(obj) = lua_createstring(lua_strdup(s)); | |
| 131 | + if (svalue(obj) == NULL) | |
| 132 | + return 1; | |
| 133 | + tag(obj) = T_STRING; | |
| 134 | + return 0; | |
| 135 | +} | |
| 136 | + | |
| 137 | + | |
| 138 | +/* | |
| 139 | +** Execute the given opcode. Return 0 in success or 1 on error. | |
| 140 | +*/ | |
| 141 | +int lua_execute (Byte *pc) | |
| 142 | +{ | |
| 143 | + Object *oldbase = base; | |
| 144 | + base = top; | |
| 145 | + while (1) | |
| 146 | + { | |
| 147 | + OpCode opcode; | |
| 148 | + switch (opcode = (OpCode)*pc++) | |
| 149 | + { | |
| 150 | + case PUSHNIL: tag(top++) = T_NIL; break; | |
| 151 | + | |
| 152 | + case PUSH0: tag(top) = T_NUMBER; nvalue(top++) = 0; break; | |
| 153 | + case PUSH1: tag(top) = T_NUMBER; nvalue(top++) = 1; break; | |
| 154 | + case PUSH2: tag(top) = T_NUMBER; nvalue(top++) = 2; break; | |
| 155 | + | |
| 156 | + case PUSHBYTE: tag(top) = T_NUMBER; nvalue(top++) = *pc++; break; | |
| 157 | + | |
| 158 | + case PUSHWORD: | |
| 159 | + { | |
| 160 | + CodeWord code; | |
| 161 | + get_word(code,pc); | |
| 162 | + tag(top) = T_NUMBER; nvalue(top++) = code.w; | |
| 163 | + } | |
| 164 | + break; | |
| 165 | + | |
| 166 | + case PUSHFLOAT: | |
| 167 | + { | |
| 168 | + CodeFloat code; | |
| 169 | + get_float(code,pc); | |
| 170 | + tag(top) = T_NUMBER; nvalue(top++) = code.f; | |
| 171 | + } | |
| 172 | + break; | |
| 173 | + | |
| 174 | + case PUSHSTRING: | |
| 175 | + { | |
| 176 | + CodeWord code; | |
| 177 | + get_word(code,pc); | |
| 178 | + tag(top) = T_STRING; svalue(top++) = lua_constant[code.w]; | |
| 179 | + } | |
| 180 | + break; | |
| 181 | + | |
| 182 | + case PUSHLOCAL0: case PUSHLOCAL1: case PUSHLOCAL2: | |
| 183 | + case PUSHLOCAL3: case PUSHLOCAL4: case PUSHLOCAL5: | |
| 184 | + case PUSHLOCAL6: case PUSHLOCAL7: case PUSHLOCAL8: | |
| 185 | + case PUSHLOCAL9: *top++ = *(base + (int)(opcode-PUSHLOCAL0)); break; | |
| 186 | + | |
| 187 | + case PUSHLOCAL: *top++ = *(base + (*pc++)); break; | |
| 188 | + | |
| 189 | + case PUSHGLOBAL: | |
| 190 | + { | |
| 191 | + CodeWord code; | |
| 192 | + get_word(code,pc); | |
| 193 | + *top++ = s_object(code.w); | |
| 194 | + } | |
| 195 | + break; | |
| 196 | + | |
| 197 | + case PUSHINDEXED: | |
| 198 | + --top; | |
| 199 | + if (tag(top-1) != T_ARRAY) | |
| 200 | + { | |
| 201 | + lua_reportbug ("indexed expression not a table"); | |
| 202 | + return 1; | |
| 203 | + } | |
| 204 | + { | |
| 205 | + Object *h = lua_hashdefine (avalue(top-1), top); | |
| 206 | + if (h == NULL) return 1; | |
| 207 | + *(top-1) = *h; | |
| 208 | + } | |
| 209 | + break; | |
| 210 | + | |
| 211 | + case PUSHMARK: tag(top++) = T_MARK; break; | |
| 212 | + | |
| 213 | + case PUSHOBJECT: *top = *(top-3); top++; break; | |
| 214 | + | |
| 215 | + case STORELOCAL0: case STORELOCAL1: case STORELOCAL2: | |
| 216 | + case STORELOCAL3: case STORELOCAL4: case STORELOCAL5: | |
| 217 | + case STORELOCAL6: case STORELOCAL7: case STORELOCAL8: | |
| 218 | + case STORELOCAL9: *(base + (int)(opcode-STORELOCAL0)) = *(--top); break; | |
| 219 | + | |
| 220 | + case STORELOCAL: *(base + (*pc++)) = *(--top); break; | |
| 221 | + | |
| 222 | + case STOREGLOBAL: | |
| 223 | + { | |
| 224 | + CodeWord code; | |
| 225 | + get_word(code,pc); | |
| 226 | + s_object(code.w) = *(--top); | |
| 227 | + } | |
| 228 | + break; | |
| 229 | + | |
| 230 | + case STOREINDEXED0: | |
| 231 | + if (tag(top-3) != T_ARRAY) | |
| 232 | + { | |
| 233 | + lua_reportbug ("indexed expression not a table"); | |
| 234 | + return 1; | |
| 235 | + } | |
| 236 | + { | |
| 237 | + Object *h = lua_hashdefine (avalue(top-3), top-2); | |
| 238 | + if (h == NULL) return 1; | |
| 239 | + *h = *(top-1); | |
| 240 | + } | |
| 241 | + top -= 3; | |
| 242 | + break; | |
| 243 | + | |
| 244 | + case STOREINDEXED: | |
| 245 | + { | |
| 246 | + int n = *pc++; | |
| 247 | + if (tag(top-3-n) != T_ARRAY) | |
| 248 | + { | |
| 249 | + lua_reportbug ("indexed expression not a table"); | |
| 250 | + return 1; | |
| 251 | + } | |
| 252 | + { | |
| 253 | + Object *h = lua_hashdefine (avalue(top-3-n), top-2-n); | |
| 254 | + if (h == NULL) return 1; | |
| 255 | + *h = *(top-1); | |
| 256 | + } | |
| 257 | + top--; | |
| 258 | + } | |
| 259 | + break; | |
| 260 | + | |
| 261 | + case STORELIST0: | |
| 262 | + case STORELIST: | |
| 263 | + { | |
| 264 | + int m, n; | |
| 265 | + Object *arr; | |
| 266 | + if (opcode == STORELIST0) m = 0; | |
| 267 | + else m = *(pc++) * FIELDS_PER_FLUSH; | |
| 268 | + n = *(pc++); | |
| 269 | + arr = top-n-1; | |
| 270 | + if (tag(arr) != T_ARRAY) | |
| 271 | + { | |
| 272 | + lua_reportbug ("internal error - table expected"); | |
| 273 | + return 1; | |
| 274 | + } | |
| 275 | + while (n) | |
| 276 | + { | |
| 277 | + tag(top) = T_NUMBER; nvalue(top) = n+m; | |
| 278 | + *(lua_hashdefine (avalue(arr), top)) = *(top-1); | |
| 279 | + top--; | |
| 280 | + n--; | |
| 281 | + } | |
| 282 | + } | |
| 283 | + break; | |
| 284 | + | |
| 285 | + case STORERECORD: | |
| 286 | + { | |
| 287 | + int n = *(pc++); | |
| 288 | + Object *arr = top-n-1; | |
| 289 | + if (tag(arr) != T_ARRAY) | |
| 290 | + { | |
| 291 | + lua_reportbug ("internal error - table expected"); | |
| 292 | + return 1; | |
| 293 | + } | |
| 294 | + while (n) | |
| 295 | + { | |
| 296 | + CodeWord code; | |
| 297 | + get_word(code,pc); | |
| 298 | + tag(top) = T_STRING; svalue(top) = lua_constant[code.w]; | |
| 299 | + *(lua_hashdefine (avalue(arr), top)) = *(top-1); | |
| 300 | + top--; | |
| 301 | + n--; | |
| 302 | + } | |
| 303 | + } | |
| 304 | + break; | |
| 305 | + | |
| 306 | + case ADJUST: | |
| 307 | + { | |
| 308 | + Object *newtop = base + *(pc++); | |
| 309 | + while (top < newtop) tag(top++) = T_NIL; | |
| 310 | + top = newtop; /* top could be bigger than newtop */ | |
| 311 | + } | |
| 312 | + break; | |
| 313 | + | |
| 314 | + case CREATEARRAY: | |
| 315 | + if (tag(top-1) == T_NIL) | |
| 316 | + nvalue(top-1) = 101; | |
| 317 | + else | |
| 318 | + { | |
| 319 | + if (tonumber(top-1)) return 1; | |
| 320 | + if (nvalue(top-1) <= 0) nvalue(top-1) = 101; | |
| 321 | + } | |
| 322 | + avalue(top-1) = lua_createarray(nvalue(top-1)); | |
| 323 | + if (avalue(top-1) == NULL) | |
| 324 | + return 1; | |
| 325 | + tag(top-1) = T_ARRAY; | |
| 326 | + break; | |
| 327 | + | |
| 328 | + case EQOP: | |
| 329 | + { | |
| 330 | + Object *l = top-2; | |
| 331 | + Object *r = top-1; | |
| 332 | + --top; | |
| 333 | + if (tag(l) != tag(r)) | |
| 334 | + tag(top-1) = T_NIL; | |
| 335 | + else | |
| 336 | + { | |
| 337 | + switch (tag(l)) | |
| 338 | + { | |
| 339 | + case T_NIL: tag(top-1) = T_NUMBER; break; | |
| 340 | + case T_NUMBER: tag(top-1) = (nvalue(l) == nvalue(r)) ? T_NUMBER : T_NIL; break; | |
| 341 | + case T_ARRAY: tag(top-1) = (avalue(l) == avalue(r)) ? T_NUMBER : T_NIL; break; | |
| 342 | + case T_FUNCTION: tag(top-1) = (bvalue(l) == bvalue(r)) ? T_NUMBER : T_NIL; break; | |
| 343 | + case T_CFUNCTION: tag(top-1) = (fvalue(l) == fvalue(r)) ? T_NUMBER : T_NIL; break; | |
| 344 | + case T_USERDATA: tag(top-1) = (uvalue(l) == uvalue(r)) ? T_NUMBER : T_NIL; break; | |
| 345 | + case T_STRING: tag(top-1) = (strcmp (svalue(l), svalue(r)) == 0) ? T_NUMBER : T_NIL; break; | |
| 346 | + case T_MARK: return 1; | |
| 347 | + } | |
| 348 | + } | |
| 349 | + nvalue(top-1) = 1; | |
| 350 | + } | |
| 351 | + break; | |
| 352 | + | |
| 353 | + case LTOP: | |
| 354 | + { | |
| 355 | + Object *l = top-2; | |
| 356 | + Object *r = top-1; | |
| 357 | + --top; | |
| 358 | + if (tag(l) == T_NUMBER && tag(r) == T_NUMBER) | |
| 359 | + tag(top-1) = (nvalue(l) < nvalue(r)) ? T_NUMBER : T_NIL; | |
| 360 | + else | |
| 361 | + { | |
| 362 | + if (tostring(l) || tostring(r)) | |
| 363 | + return 1; | |
| 364 | + tag(top-1) = (strcmp (svalue(l), svalue(r)) < 0) ? T_NUMBER : T_NIL; | |
| 365 | + } | |
| 366 | + nvalue(top-1) = 1; | |
| 367 | + } | |
| 368 | + break; | |
| 369 | + | |
| 370 | + case LEOP: | |
| 371 | + { | |
| 372 | + Object *l = top-2; | |
| 373 | + Object *r = top-1; | |
| 374 | + --top; | |
| 375 | + if (tag(l) == T_NUMBER && tag(r) == T_NUMBER) | |
| 376 | + tag(top-1) = (nvalue(l) <= nvalue(r)) ? T_NUMBER : T_NIL; | |
| 377 | + else | |
| 378 | + { | |
| 379 | + if (tostring(l) || tostring(r)) | |
| 380 | + return 1; | |
| 381 | + tag(top-1) = (strcmp (svalue(l), svalue(r)) <= 0) ? T_NUMBER : T_NIL; | |
| 382 | + } | |
| 383 | + nvalue(top-1) = 1; | |
| 384 | + } | |
| 385 | + break; | |
| 386 | + | |
| 387 | + case ADDOP: | |
| 388 | + { | |
| 389 | + Object *l = top-2; | |
| 390 | + Object *r = top-1; | |
| 391 | + if (tonumber(r) || tonumber(l)) | |
| 392 | + return 1; | |
| 393 | + nvalue(l) += nvalue(r); | |
| 394 | + --top; | |
| 395 | + } | |
| 396 | + break; | |
| 397 | + | |
| 398 | + case SUBOP: | |
| 399 | + { | |
| 400 | + Object *l = top-2; | |
| 401 | + Object *r = top-1; | |
| 402 | + if (tonumber(r) || tonumber(l)) | |
| 403 | + return 1; | |
| 404 | + nvalue(l) -= nvalue(r); | |
| 405 | + --top; | |
| 406 | + } | |
| 407 | + break; | |
| 408 | + | |
| 409 | + case MULTOP: | |
| 410 | + { | |
| 411 | + Object *l = top-2; | |
| 412 | + Object *r = top-1; | |
| 413 | + if (tonumber(r) || tonumber(l)) | |
| 414 | + return 1; | |
| 415 | + nvalue(l) *= nvalue(r); | |
| 416 | + --top; | |
| 417 | + } | |
| 418 | + break; | |
| 419 | + | |
| 420 | + case DIVOP: | |
| 421 | + { | |
| 422 | + Object *l = top-2; | |
| 423 | + Object *r = top-1; | |
| 424 | + if (tonumber(r) || tonumber(l)) | |
| 425 | + return 1; | |
| 426 | + nvalue(l) /= nvalue(r); | |
| 427 | + --top; | |
| 428 | + } | |
| 429 | + break; | |
| 430 | + | |
| 431 | + case CONCOP: | |
| 432 | + { | |
| 433 | + Object *l = top-2; | |
| 434 | + Object *r = top-1; | |
| 435 | + if (tostring(r) || tostring(l)) | |
| 436 | + return 1; | |
| 437 | + svalue(l) = lua_createstring (lua_strconc(svalue(l),svalue(r))); | |
| 438 | + if (svalue(l) == NULL) | |
| 439 | + return 1; | |
| 440 | + --top; | |
| 441 | + } | |
| 442 | + break; | |
| 443 | + | |
| 444 | + case MINUSOP: | |
| 445 | + if (tonumber(top-1)) | |
| 446 | + return 1; | |
| 447 | + nvalue(top-1) = - nvalue(top-1); | |
| 448 | + break; | |
| 449 | + | |
| 450 | + case NOTOP: | |
| 451 | + tag(top-1) = tag(top-1) == T_NIL ? T_NUMBER : T_NIL; | |
| 452 | + break; | |
| 453 | + | |
| 454 | + case ONTJMP: | |
| 455 | + { | |
| 456 | + CodeWord code; | |
| 457 | + get_word(code,pc); | |
| 458 | + if (tag(top-1) != T_NIL) pc += code.w; | |
| 459 | + } | |
| 460 | + break; | |
| 461 | + | |
| 462 | + case ONFJMP: | |
| 463 | + { | |
| 464 | + CodeWord code; | |
| 465 | + get_word(code,pc); | |
| 466 | + if (tag(top-1) == T_NIL) pc += code.w; | |
| 467 | + } | |
| 468 | + break; | |
| 469 | + | |
| 470 | + case JMP: | |
| 471 | + { | |
| 472 | + CodeWord code; | |
| 473 | + get_word(code,pc); | |
| 474 | + pc += code.w; | |
| 475 | + } | |
| 476 | + break; | |
| 477 | + | |
| 478 | + case UPJMP: | |
| 479 | + { | |
| 480 | + CodeWord code; | |
| 481 | + get_word(code,pc); | |
| 482 | + pc -= code.w; | |
| 483 | + } | |
| 484 | + break; | |
| 485 | + | |
| 486 | + case IFFJMP: | |
| 487 | + { | |
| 488 | + CodeWord code; | |
| 489 | + get_word(code,pc); | |
| 490 | + top--; | |
| 491 | + if (tag(top) == T_NIL) pc += code.w; | |
| 492 | + } | |
| 493 | + break; | |
| 494 | + | |
| 495 | + case IFFUPJMP: | |
| 496 | + { | |
| 497 | + CodeWord code; | |
| 498 | + get_word(code,pc); | |
| 499 | + top--; | |
| 500 | + if (tag(top) == T_NIL) pc -= code.w; | |
| 501 | + } | |
| 502 | + break; | |
| 503 | + | |
| 504 | + case POP: --top; break; | |
| 505 | + | |
| 506 | + case CALLFUNC: | |
| 507 | + { | |
| 508 | + Byte *newpc; | |
| 509 | + Object *b = top-1; | |
| 510 | + while (tag(b) != T_MARK) b--; | |
| 511 | + if (tag(b-1) == T_FUNCTION) | |
| 512 | + { | |
| 513 | + lua_debugline = 0; /* always reset debug flag */ | |
| 514 | + newpc = bvalue(b-1); | |
| 515 | + bvalue(b-1) = pc; /* store return code */ | |
| 516 | + nvalue(b) = (base-stack); /* store base value */ | |
| 517 | + base = b+1; | |
| 518 | + pc = newpc; | |
| 519 | + if (MAXSTACK-(base-stack) < STACKGAP) | |
| 520 | + { | |
| 521 | + lua_error ("stack overflow"); | |
| 522 | + return 1; | |
| 523 | + } | |
| 524 | + } | |
| 525 | + else if (tag(b-1) == T_CFUNCTION) | |
| 526 | + { | |
| 527 | + int nparam; | |
| 528 | + lua_debugline = 0; /* always reset debug flag */ | |
| 529 | + nvalue(b) = (base-stack); /* store base value */ | |
| 530 | + base = b+1; | |
| 531 | + nparam = top-base; /* number of parameters */ | |
| 532 | + (fvalue(b-1))(); /* call C function */ | |
| 533 | + | |
| 534 | + /* shift returned values */ | |
| 535 | + { | |
| 536 | + int i; | |
| 537 | + int nretval = top - base - nparam; | |
| 538 | + top = base - 2; | |
| 539 | + base = stack + (int) nvalue(base-1); | |
| 540 | + for (i=0; i<nretval; i++) | |
| 541 | + { | |
| 542 | + *top = *(top+nparam+2); | |
| 543 | + ++top; | |
| 544 | + } | |
| 545 | + } | |
| 546 | + } | |
| 547 | + else | |
| 548 | + { | |
| 549 | + lua_reportbug ("call expression not a function"); | |
| 550 | + return 1; | |
| 551 | + } | |
| 552 | + } | |
| 553 | + break; | |
| 554 | + | |
| 555 | + case RETCODE: | |
| 556 | + { | |
| 557 | + int i; | |
| 558 | + int shift = *pc++; | |
| 559 | + int nretval = top - base - shift; | |
| 560 | + top = base - 2; | |
| 561 | + pc = bvalue(base-2); | |
| 562 | + base = stack + (int) nvalue(base-1); | |
| 563 | + for (i=0; i<nretval; i++) | |
| 564 | + { | |
| 565 | + *top = *(top+shift+2); | |
| 566 | + ++top; | |
| 567 | + } | |
| 568 | + } | |
| 569 | + break; | |
| 570 | + | |
| 571 | + case HALT: | |
| 572 | + base = oldbase; | |
| 573 | + return 0; /* success */ | |
| 574 | + | |
| 575 | + case SETFUNCTION: | |
| 576 | + { | |
| 577 | + CodeWord file, func; | |
| 578 | + get_word(file,pc); | |
| 579 | + get_word(func,pc); | |
| 580 | + if (lua_pushfunction (file.w, func.w)) | |
| 581 | + return 1; | |
| 582 | + } | |
| 583 | + break; | |
| 584 | + | |
| 585 | + case SETLINE: | |
| 586 | + { | |
| 587 | + CodeWord code; | |
| 588 | + get_word(code,pc); | |
| 589 | + lua_debugline = code.w; | |
| 590 | + } | |
| 591 | + break; | |
| 592 | + | |
| 593 | + case RESET: | |
| 594 | + lua_popfunction (); | |
| 595 | + break; | |
| 596 | + | |
| 597 | + default: | |
| 598 | + lua_error ("internal error - opcode didn't match"); | |
| 599 | + return 1; | |
| 600 | + } | |
| 601 | + } | |
| 602 | +} | |
| 603 | + | |
| 604 | + | |
| 605 | +/* | |
| 606 | +** Traverse all objects on stack | |
| 607 | +*/ | |
| 608 | +void lua_travstack (void (*fn)(Object *)) | |
| 609 | +{ | |
| 610 | + Object *o; | |
| 611 | + for (o = top-1; o >= stack; o--) | |
| 612 | + fn (o); | |
| 613 | +} | |
| 614 | + | |
| 615 | +/* | |
| 616 | +** Open file, generate opcode and execute global statement. Return 0 on | |
| 617 | +** success or 1 on error. | |
| 618 | +*/ | |
| 619 | +int lua_dofile (char *filename) | |
| 620 | +{ | |
| 621 | + if (lua_openfile (filename)) return 1; | |
| 622 | + if (lua_parse ()) { lua_closefile (); return 1; } | |
| 623 | + lua_closefile (); | |
| 624 | + return 0; | |
| 625 | +} | |
| 626 | + | |
| 627 | +/* | |
| 628 | +** Generate opcode stored on string and execute global statement. Return 0 on | |
| 629 | +** success or 1 on error. | |
| 630 | +*/ | |
| 631 | +int lua_dostring (char *string) | |
| 632 | +{ | |
| 633 | + if (lua_openstring (string)) return 1; | |
| 634 | + if (lua_parse ()) return 1; | |
| 635 | + lua_closestring(); | |
| 636 | + return 0; | |
| 637 | +} | |
| 638 | + | |
| 639 | +/* | |
| 640 | +** Execute the given function. Return 0 on success or 1 on error. | |
| 641 | +*/ | |
| 642 | +int lua_call (char *functionname, int nparam) | |
| 643 | +{ | |
| 644 | + static Byte startcode[] = {CALLFUNC, HALT}; | |
| 645 | + int i; | |
| 646 | + Object func = s_object(lua_findsymbol(functionname)); | |
| 647 | + if (tag(&func) != T_FUNCTION) return 1; | |
| 648 | + for (i=1; i<=nparam; i++) | |
| 649 | + *(top-i+2) = *(top-i); | |
| 650 | + top += 2; | |
| 651 | + tag(top-nparam-1) = T_MARK; | |
| 652 | + *(top-nparam-2) = func; | |
| 653 | + return (lua_execute (startcode)); | |
| 654 | +} | |
| 655 | + | |
| 656 | +/* | |
| 657 | +** Get a parameter, returning the object handle or NULL on error. | |
| 658 | +** 'number' must be 1 to get the first parameter. | |
| 659 | +*/ | |
| 660 | +Object *lua_getparam (int number) | |
| 661 | +{ | |
| 662 | + if (number <= 0 || number > top-base) return NULL; | |
| 663 | + return (base+number-1); | |
| 664 | +} | |
| 665 | + | |
| 666 | +/* | |
| 667 | +** Given an object handle, return its number value. On error, return 0.0. | |
| 668 | +*/ | |
| 669 | +real lua_getnumber (Object *object) | |
| 670 | +{ | |
| 671 | + if (object == NULL || tag(object) == T_NIL) return 0.0; | |
| 672 | + if (tonumber (object)) return 0.0; | |
| 673 | + else return (nvalue(object)); | |
| 674 | +} | |
| 675 | + | |
| 676 | +/* | |
| 677 | +** Given an object handle, return its string pointer. On error, return NULL. | |
| 678 | +*/ | |
| 679 | +char *lua_getstring (Object *object) | |
| 680 | +{ | |
| 681 | + if (object == NULL || tag(object) == T_NIL) return NULL; | |
| 682 | + if (tostring (object)) return NULL; | |
| 683 | + else return (svalue(object)); | |
| 684 | +} | |
| 685 | + | |
| 686 | +/* | |
| 687 | +** Given an object handle, return a copy of its string. On error, return NULL. | |
| 688 | +*/ | |
| 689 | +char *lua_copystring (Object *object) | |
| 690 | +{ | |
| 691 | + if (object == NULL || tag(object) == T_NIL) return NULL; | |
| 692 | + if (tostring (object)) return NULL; | |
| 693 | + else return (strdup(svalue(object))); | |
| 694 | +} | |
| 695 | + | |
| 696 | +/* | |
| 697 | +** Given an object handle, return its cfuntion pointer. On error, return NULL. | |
| 698 | +*/ | |
| 699 | +lua_CFunction lua_getcfunction (Object *object) | |
| 700 | +{ | |
| 701 | + if (object == NULL) return NULL; | |
| 702 | + if (tag(object) != T_CFUNCTION) return NULL; | |
| 703 | + else return (fvalue(object)); | |
| 704 | +} | |
| 705 | + | |
| 706 | +/* | |
| 707 | +** Given an object handle, return its user data. On error, return NULL. | |
| 708 | +*/ | |
| 709 | +void *lua_getuserdata (Object *object) | |
| 710 | +{ | |
| 711 | + if (object == NULL) return NULL; | |
| 712 | + if (tag(object) != T_USERDATA) return NULL; | |
| 713 | + else return (uvalue(object)); | |
| 714 | +} | |
| 715 | + | |
| 716 | +/* | |
| 717 | +** Given an object handle and a field name, return its field object. | |
| 718 | +** On error, return NULL. | |
| 719 | +*/ | |
| 720 | +Object *lua_getfield (Object *object, char *field) | |
| 721 | +{ | |
| 722 | + if (object == NULL) return NULL; | |
| 723 | + if (tag(object) != T_ARRAY) | |
| 724 | + return NULL; | |
| 725 | + else | |
| 726 | + { | |
| 727 | + Object ref; | |
| 728 | + tag(&ref) = T_STRING; | |
| 729 | + svalue(&ref) = lua_createstring(lua_strdup(field)); | |
| 730 | + return (lua_hashdefine(avalue(object), &ref)); | |
| 731 | + } | |
| 732 | +} | |
| 733 | + | |
| 734 | +/* | |
| 735 | +** Given an object handle and an index, return its indexed object. | |
| 736 | +** On error, return NULL. | |
| 737 | +*/ | |
| 738 | +Object *lua_getindexed (Object *object, float index) | |
| 739 | +{ | |
| 740 | + if (object == NULL) return NULL; | |
| 741 | + if (tag(object) != T_ARRAY) | |
| 742 | + return NULL; | |
| 743 | + else | |
| 744 | + { | |
| 745 | + Object ref; | |
| 746 | + tag(&ref) = T_NUMBER; | |
| 747 | + nvalue(&ref) = index; | |
| 748 | + return (lua_hashdefine(avalue(object), &ref)); | |
| 749 | + } | |
| 750 | +} | |
| 751 | + | |
| 752 | +/* | |
| 753 | +** Get a global object. Return the object handle or NULL on error. | |
| 754 | +*/ | |
| 755 | +Object *lua_getglobal (char *name) | |
| 756 | +{ | |
| 757 | + int n = lua_findsymbol(name); | |
| 758 | + if (n < 0) return NULL; | |
| 759 | + return &s_object(n); | |
| 760 | +} | |
| 761 | + | |
| 762 | +/* | |
| 763 | +** Pop and return an object | |
| 764 | +*/ | |
| 765 | +Object *lua_pop (void) | |
| 766 | +{ | |
| 767 | + if (top <= base) return NULL; | |
| 768 | + top--; | |
| 769 | + return top; | |
| 770 | +} | |
| 771 | + | |
| 772 | +/* | |
| 773 | +** Push a nil object | |
| 774 | +*/ | |
| 775 | +int lua_pushnil (void) | |
| 776 | +{ | |
| 777 | + if ((top-stack) >= MAXSTACK-1) | |
| 778 | + { | |
| 779 | + lua_error ("stack overflow"); | |
| 780 | + return 1; | |
| 781 | + } | |
| 782 | + tag(top) = T_NIL; | |
| 783 | + return 0; | |
| 784 | +} | |
| 785 | + | |
| 786 | +/* | |
| 787 | +** Push an object (tag=number) to stack. Return 0 on success or 1 on error. | |
| 788 | +*/ | |
| 789 | +int lua_pushnumber (real n) | |
| 790 | +{ | |
| 791 | + if ((top-stack) >= MAXSTACK-1) | |
| 792 | + { | |
| 793 | + lua_error ("stack overflow"); | |
| 794 | + return 1; | |
| 795 | + } | |
| 796 | + tag(top) = T_NUMBER; nvalue(top++) = n; | |
| 797 | + return 0; | |
| 798 | +} | |
| 799 | + | |
| 800 | +/* | |
| 801 | +** Push an object (tag=string) to stack. Return 0 on success or 1 on error. | |
| 802 | +*/ | |
| 803 | +int lua_pushstring (char *s) | |
| 804 | +{ | |
| 805 | + if ((top-stack) >= MAXSTACK-1) | |
| 806 | + { | |
| 807 | + lua_error ("stack overflow"); | |
| 808 | + return 1; | |
| 809 | + } | |
| 810 | + tag(top) = T_STRING; | |
| 811 | + svalue(top++) = lua_createstring(lua_strdup(s)); | |
| 812 | + return 0; | |
| 813 | +} | |
| 814 | + | |
| 815 | +/* | |
| 816 | +** Push an object (tag=cfunction) to stack. Return 0 on success or 1 on error. | |
| 817 | +*/ | |
| 818 | +int lua_pushcfunction (lua_CFunction fn) | |
| 819 | +{ | |
| 820 | + if ((top-stack) >= MAXSTACK-1) | |
| 821 | + { | |
| 822 | + lua_error ("stack overflow"); | |
| 823 | + return 1; | |
| 824 | + } | |
| 825 | + tag(top) = T_CFUNCTION; fvalue(top++) = fn; | |
| 826 | + return 0; | |
| 827 | +} | |
| 828 | + | |
| 829 | +/* | |
| 830 | +** Push an object (tag=userdata) to stack. Return 0 on success or 1 on error. | |
| 831 | +*/ | |
| 832 | +int lua_pushuserdata (void *u) | |
| 833 | +{ | |
| 834 | + if ((top-stack) >= MAXSTACK-1) | |
| 835 | + { | |
| 836 | + lua_error ("stack overflow"); | |
| 837 | + return 1; | |
| 838 | + } | |
| 839 | + tag(top) = T_USERDATA; uvalue(top++) = u; | |
| 840 | + return 0; | |
| 841 | +} | |
| 842 | + | |
| 843 | +/* | |
| 844 | +** Push an object to stack. | |
| 845 | +*/ | |
| 846 | +int lua_pushobject (Object *o) | |
| 847 | +{ | |
| 848 | + if ((top-stack) >= MAXSTACK-1) | |
| 849 | + { | |
| 850 | + lua_error ("stack overflow"); | |
| 851 | + return 1; | |
| 852 | + } | |
| 853 | + *top++ = *o; | |
| 854 | + return 0; | |
| 855 | +} | |
| 856 | + | |
| 857 | +/* | |
| 858 | +** Store top of the stack at a global variable array field. | |
| 859 | +** Return 1 on error, 0 on success. | |
| 860 | +*/ | |
| 861 | +int lua_storeglobal (char *name) | |
| 862 | +{ | |
| 863 | + int n = lua_findsymbol (name); | |
| 864 | + if (n < 0) return 1; | |
| 865 | + if (tag(top-1) == T_MARK) return 1; | |
| 866 | + s_object(n) = *(--top); | |
| 867 | + return 0; | |
| 868 | +} | |
| 869 | + | |
| 870 | +/* | |
| 871 | +** Store top of the stack at an array field. Return 1 on error, 0 on success. | |
| 872 | +*/ | |
| 873 | +int lua_storefield (lua_Object object, char *field) | |
| 874 | +{ | |
| 875 | + if (tag(object) != T_ARRAY) | |
| 876 | + return 1; | |
| 877 | + else | |
| 878 | + { | |
| 879 | + Object ref, *h; | |
| 880 | + tag(&ref) = T_STRING; | |
| 881 | + svalue(&ref) = lua_createstring(lua_strdup(field)); | |
| 882 | + h = lua_hashdefine(avalue(object), &ref); | |
| 883 | + if (h == NULL) return 1; | |
| 884 | + if (tag(top-1) == T_MARK) return 1; | |
| 885 | + *h = *(--top); | |
| 886 | + } | |
| 887 | + return 0; | |
| 888 | +} | |
| 889 | + | |
| 890 | + | |
| 891 | +/* | |
| 892 | +** Store top of the stack at an array index. Return 1 on error, 0 on success. | |
| 893 | +*/ | |
| 894 | +int lua_storeindexed (lua_Object object, float index) | |
| 895 | +{ | |
| 896 | + if (tag(object) != T_ARRAY) | |
| 897 | + return 1; | |
| 898 | + else | |
| 899 | + { | |
| 900 | + Object ref, *h; | |
| 901 | + tag(&ref) = T_NUMBER; | |
| 902 | + nvalue(&ref) = index; | |
| 903 | + h = lua_hashdefine(avalue(object), &ref); | |
| 904 | + if (h == NULL) return 1; | |
| 905 | + if (tag(top-1) == T_MARK) return 1; | |
| 906 | + *h = *(--top); | |
| 907 | + } | |
| 908 | + return 0; | |
| 909 | +} | |
| 910 | + | |
| 911 | + | |
| 912 | +/* | |
| 913 | +** Given an object handle, return if it is nil. | |
| 914 | +*/ | |
| 915 | +int lua_isnil (Object *object) | |
| 916 | +{ | |
| 917 | + return (object != NULL && tag(object) == T_NIL); | |
| 918 | +} | |
| 919 | + | |
| 920 | +/* | |
| 921 | +** Given an object handle, return if it is a number one. | |
| 922 | +*/ | |
| 923 | +int lua_isnumber (Object *object) | |
| 924 | +{ | |
| 925 | + return (object != NULL && tag(object) == T_NUMBER); | |
| 926 | +} | |
| 927 | + | |
| 928 | +/* | |
| 929 | +** Given an object handle, return if it is a string one. | |
| 930 | +*/ | |
| 931 | +int lua_isstring (Object *object) | |
| 932 | +{ | |
| 933 | + return (object != NULL && tag(object) == T_STRING); | |
| 934 | +} | |
| 935 | + | |
| 936 | +/* | |
| 937 | +** Given an object handle, return if it is an array one. | |
| 938 | +*/ | |
| 939 | +int lua_istable (Object *object) | |
| 940 | +{ | |
| 941 | + return (object != NULL && tag(object) == T_ARRAY); | |
| 942 | +} | |
| 943 | + | |
| 944 | +/* | |
| 945 | +** Given an object handle, return if it is a cfunction one. | |
| 946 | +*/ | |
| 947 | +int lua_iscfunction (Object *object) | |
| 948 | +{ | |
| 949 | + return (object != NULL && tag(object) == T_CFUNCTION); | |
| 950 | +} | |
| 951 | + | |
| 952 | +/* | |
| 953 | +** Given an object handle, return if it is an user data one. | |
| 954 | +*/ | |
| 955 | +int lua_isuserdata (Object *object) | |
| 956 | +{ | |
| 957 | + return (object != NULL && tag(object) == T_USERDATA); | |
| 958 | +} | |
| 959 | + | |
| 960 | +/* | |
| 961 | +** Internal function: return an object type. | |
| 962 | +*/ | |
| 963 | +void lua_type (void) | |
| 964 | +{ | |
| 965 | + Object *o = lua_getparam(1); | |
| 966 | + lua_pushstring (lua_constant[tag(o)]); | |
| 967 | +} | |
| 968 | + | |
| 969 | +/* | |
| 970 | +** Internal function: convert an object to a number | |
| 971 | +*/ | |
| 972 | +void lua_obj2number (void) | |
| 973 | +{ | |
| 974 | + Object *o = lua_getparam(1); | |
| 975 | + lua_pushobject (lua_convtonumber(o)); | |
| 976 | +} | |
| 977 | + | |
| 978 | +/* | |
| 979 | +** Internal function: print object values | |
| 980 | +*/ | |
| 981 | +void lua_print (void) | |
| 982 | +{ | |
| 983 | + int i=1; | |
| 984 | + void *obj; | |
| 985 | + while ((obj=lua_getparam (i++)) != NULL) | |
| 986 | + { | |
| 987 | + if (lua_isnumber(obj)) printf("%g\n",lua_getnumber (obj)); | |
| 988 | + else if (lua_isstring(obj)) printf("%s\n",lua_getstring (obj)); | |
| 989 | + else if (lua_iscfunction(obj)) printf("cfunction: %p\n",lua_getcfunction (obj)); | |
| 990 | + else if (lua_isuserdata(obj)) printf("userdata: %p\n",lua_getuserdata (obj)); | |
| 991 | + else if (lua_istable(obj)) printf("table: %p\n",obj); | |
| 992 | + else if (lua_isnil(obj)) printf("nil\n"); | |
| 993 | + else printf("invalid value to print\n"); | |
| 994 | + } | |
| 995 | +} | |
| 996 | + | |
| 997 | +/* | |
| 998 | +** Internal function: do a file | |
| 999 | +*/ | |
| 1000 | +void lua_internaldofile (void) | |
| 1001 | +{ | |
| 1002 | + lua_Object obj = lua_getparam (1); | |
| 1003 | + if (lua_isstring(obj) && !lua_dofile(lua_getstring(obj))) | |
| 1004 | + lua_pushnumber(1); | |
| 1005 | + else | |
| 1006 | + lua_pushnil(); | |
| 1007 | +} | |
| 1008 | + | |
| 1009 | +/* | |
| 1010 | +** Internal function: do a string | |
| 1011 | +*/ | |
| 1012 | +void lua_internaldostring (void) | |
| 1013 | +{ | |
| 1014 | + lua_Object obj = lua_getparam (1); | |
| 1015 | + if (lua_isstring(obj) && !lua_dostring(lua_getstring(obj))) | |
| 1016 | + lua_pushnumber(1); | |
| 1017 | + else | |
| 1018 | + lua_pushnil(); | |
| 1019 | +} | |
| 1020 | + | |
| 1021 | + | |
| @@ -0,0 +1,164 @@ | ||
| 1 | +/* | |
| 2 | +** TeCGraf - PUC-Rio | |
| 3 | +** $Id: opcode.h,v 2.1 1994/04/20 22:07:57 celes Exp $ | |
| 4 | +*/ | |
| 5 | + | |
| 6 | +#ifndef opcode_h | |
| 7 | +#define opcode_h | |
| 8 | + | |
| 9 | +#ifndef STACKGAP | |
| 10 | +#define STACKGAP 128 | |
| 11 | +#endif | |
| 12 | + | |
| 13 | +#ifndef real | |
| 14 | +#define real float | |
| 15 | +#endif | |
| 16 | + | |
| 17 | +#define FIELDS_PER_FLUSH 40 | |
| 18 | + | |
| 19 | +typedef unsigned char Byte; | |
| 20 | + | |
| 21 | +typedef unsigned short Word; | |
| 22 | + | |
| 23 | +typedef union | |
| 24 | +{ | |
| 25 | + struct {char c1; char c2;} m; | |
| 26 | + Word w; | |
| 27 | +} CodeWord; | |
| 28 | + | |
| 29 | +typedef union | |
| 30 | +{ | |
| 31 | + struct {char c1; char c2; char c3; char c4;} m; | |
| 32 | + float f; | |
| 33 | +} CodeFloat; | |
| 34 | + | |
| 35 | +typedef enum | |
| 36 | +{ | |
| 37 | + PUSHNIL, | |
| 38 | + PUSH0, PUSH1, PUSH2, | |
| 39 | + PUSHBYTE, | |
| 40 | + PUSHWORD, | |
| 41 | + PUSHFLOAT, | |
| 42 | + PUSHSTRING, | |
| 43 | + PUSHLOCAL0, PUSHLOCAL1, PUSHLOCAL2, PUSHLOCAL3, PUSHLOCAL4, | |
| 44 | + PUSHLOCAL5, PUSHLOCAL6, PUSHLOCAL7, PUSHLOCAL8, PUSHLOCAL9, | |
| 45 | + PUSHLOCAL, | |
| 46 | + PUSHGLOBAL, | |
| 47 | + PUSHINDEXED, | |
| 48 | + PUSHMARK, | |
| 49 | + PUSHOBJECT, | |
| 50 | + STORELOCAL0, STORELOCAL1, STORELOCAL2, STORELOCAL3, STORELOCAL4, | |
| 51 | + STORELOCAL5, STORELOCAL6, STORELOCAL7, STORELOCAL8, STORELOCAL9, | |
| 52 | + STORELOCAL, | |
| 53 | + STOREGLOBAL, | |
| 54 | + STOREINDEXED0, | |
| 55 | + STOREINDEXED, | |
| 56 | + STORELIST0, | |
| 57 | + STORELIST, | |
| 58 | + STORERECORD, | |
| 59 | + ADJUST, | |
| 60 | + CREATEARRAY, | |
| 61 | + EQOP, | |
| 62 | + LTOP, | |
| 63 | + LEOP, | |
| 64 | + ADDOP, | |
| 65 | + SUBOP, | |
| 66 | + MULTOP, | |
| 67 | + DIVOP, | |
| 68 | + CONCOP, | |
| 69 | + MINUSOP, | |
| 70 | + NOTOP, | |
| 71 | + ONTJMP, | |
| 72 | + ONFJMP, | |
| 73 | + JMP, | |
| 74 | + UPJMP, | |
| 75 | + IFFJMP, | |
| 76 | + IFFUPJMP, | |
| 77 | + POP, | |
| 78 | + CALLFUNC, | |
| 79 | + RETCODE, | |
| 80 | + HALT, | |
| 81 | + SETFUNCTION, | |
| 82 | + SETLINE, | |
| 83 | + RESET | |
| 84 | +} OpCode; | |
| 85 | + | |
| 86 | +typedef enum | |
| 87 | +{ | |
| 88 | + T_MARK, | |
| 89 | + T_NIL, | |
| 90 | + T_NUMBER, | |
| 91 | + T_STRING, | |
| 92 | + T_ARRAY, | |
| 93 | + T_FUNCTION, | |
| 94 | + T_CFUNCTION, | |
| 95 | + T_USERDATA | |
| 96 | +} Type; | |
| 97 | + | |
| 98 | +typedef void (*Cfunction) (void); | |
| 99 | +typedef int (*Input) (void); | |
| 100 | + | |
| 101 | +typedef union | |
| 102 | +{ | |
| 103 | + Cfunction f; | |
| 104 | + real n; | |
| 105 | + char *s; | |
| 106 | + Byte *b; | |
| 107 | + struct Hash *a; | |
| 108 | + void *u; | |
| 109 | +} Value; | |
| 110 | + | |
| 111 | +typedef struct Object | |
| 112 | +{ | |
| 113 | + Type tag; | |
| 114 | + Value value; | |
| 115 | +} Object; | |
| 116 | + | |
| 117 | +typedef struct | |
| 118 | +{ | |
| 119 | + char *name; | |
| 120 | + Object object; | |
| 121 | +} Symbol; | |
| 122 | + | |
| 123 | +/* Macros to access structure members */ | |
| 124 | +#define tag(o) ((o)->tag) | |
| 125 | +#define nvalue(o) ((o)->value.n) | |
| 126 | +#define svalue(o) ((o)->value.s) | |
| 127 | +#define bvalue(o) ((o)->value.b) | |
| 128 | +#define avalue(o) ((o)->value.a) | |
| 129 | +#define fvalue(o) ((o)->value.f) | |
| 130 | +#define uvalue(o) ((o)->value.u) | |
| 131 | + | |
| 132 | +/* Macros to access symbol table */ | |
| 133 | +#define s_name(i) (lua_table[i].name) | |
| 134 | +#define s_object(i) (lua_table[i].object) | |
| 135 | +#define s_tag(i) (tag(&s_object(i))) | |
| 136 | +#define s_nvalue(i) (nvalue(&s_object(i))) | |
| 137 | +#define s_svalue(i) (svalue(&s_object(i))) | |
| 138 | +#define s_bvalue(i) (bvalue(&s_object(i))) | |
| 139 | +#define s_avalue(i) (avalue(&s_object(i))) | |
| 140 | +#define s_fvalue(i) (fvalue(&s_object(i))) | |
| 141 | +#define s_uvalue(i) (uvalue(&s_object(i))) | |
| 142 | + | |
| 143 | +#define get_word(code,pc) {code.m.c1 = *pc++; code.m.c2 = *pc++;} | |
| 144 | +#define get_float(code,pc) {code.m.c1 = *pc++; code.m.c2 = *pc++;\ | |
| 145 | + code.m.c3 = *pc++; code.m.c4 = *pc++;} | |
| 146 | + | |
| 147 | + | |
| 148 | + | |
| 149 | +/* Exported functions */ | |
| 150 | +int lua_execute (Byte *pc); | |
| 151 | +void lua_markstack (void); | |
| 152 | +char *lua_strdup (char *l); | |
| 153 | + | |
| 154 | +void lua_setinput (Input fn); /* from "lex.c" module */ | |
| 155 | +char *lua_lasttext (void); /* from "lex.c" module */ | |
| 156 | +int lua_parse (void); /* from "lua.stx" module */ | |
| 157 | +void lua_type (void); | |
| 158 | +void lua_obj2number (void); | |
| 159 | +void lua_print (void); | |
| 160 | +void lua_internaldofile (void); | |
| 161 | +void lua_internaldostring (void); | |
| 162 | +void lua_travstack (void (*fn)(Object *)); | |
| 163 | + | |
| 164 | +#endif | |
| @@ -0,0 +1,337 @@ | ||
| 1 | +/* | |
| 2 | +** table.c | |
| 3 | +** Module to control static tables | |
| 4 | +*/ | |
| 5 | + | |
| 6 | +char *rcs_table="$Id: table.c,v 2.1 1994/04/20 22:07:57 celes Exp $"; | |
| 7 | + | |
| 8 | +#include <stdlib.h> | |
| 9 | +#include <string.h> | |
| 10 | + | |
| 11 | +#include "mm.h" | |
| 12 | + | |
| 13 | +#include "opcode.h" | |
| 14 | +#include "hash.h" | |
| 15 | +#include "inout.h" | |
| 16 | +#include "table.h" | |
| 17 | +#include "lua.h" | |
| 18 | + | |
| 19 | +#define streq(s1,s2) (s1[0]==s2[0]&&strcmp(s1+1,s2+1)==0) | |
| 20 | + | |
| 21 | +#ifndef MAXSYMBOL | |
| 22 | +#define MAXSYMBOL 512 | |
| 23 | +#endif | |
| 24 | +static Symbol tablebuffer[MAXSYMBOL] = { | |
| 25 | + {"type",{T_CFUNCTION,{lua_type}}}, | |
| 26 | + {"tonumber",{T_CFUNCTION,{lua_obj2number}}}, | |
| 27 | + {"next",{T_CFUNCTION,{lua_next}}}, | |
| 28 | + {"nextvar",{T_CFUNCTION,{lua_nextvar}}}, | |
| 29 | + {"print",{T_CFUNCTION,{lua_print}}}, | |
| 30 | + {"dofile",{T_CFUNCTION,{lua_internaldofile}}}, | |
| 31 | + {"dostring",{T_CFUNCTION,{lua_internaldostring}}} | |
| 32 | + }; | |
| 33 | +Symbol *lua_table=tablebuffer; | |
| 34 | +Word lua_ntable=7; | |
| 35 | + | |
| 36 | +struct List | |
| 37 | +{ | |
| 38 | + Symbol *s; | |
| 39 | + struct List *next; | |
| 40 | +}; | |
| 41 | + | |
| 42 | +static struct List o6={ tablebuffer+6, 0}; | |
| 43 | +static struct List o5={ tablebuffer+5, &o6 }; | |
| 44 | +static struct List o4={ tablebuffer+4, &o5 }; | |
| 45 | +static struct List o3={ tablebuffer+3, &o4 }; | |
| 46 | +static struct List o2={ tablebuffer+2, &o3 }; | |
| 47 | +static struct List o1={ tablebuffer+1, &o2 }; | |
| 48 | +static struct List o0={ tablebuffer+0, &o1 }; | |
| 49 | +static struct List *searchlist=&o0; | |
| 50 | + | |
| 51 | +#ifndef MAXCONSTANT | |
| 52 | +#define MAXCONSTANT 256 | |
| 53 | +#endif | |
| 54 | +/* pre-defined constants need garbage collection extra byte */ | |
| 55 | +static char tm[] = " mark"; | |
| 56 | +static char ti[] = " nil"; | |
| 57 | +static char tn[] = " number"; | |
| 58 | +static char ts[] = " string"; | |
| 59 | +static char tt[] = " table"; | |
| 60 | +static char tf[] = " function"; | |
| 61 | +static char tc[] = " cfunction"; | |
| 62 | +static char tu[] = " userdata"; | |
| 63 | +static char *constantbuffer[MAXCONSTANT] = {tm+1, ti+1, | |
| 64 | + tn+1, ts+1, | |
| 65 | + tt+1, tf+1, | |
| 66 | + tc+1, tu+1 | |
| 67 | + }; | |
| 68 | +char **lua_constant = constantbuffer; | |
| 69 | +Word lua_nconstant=T_USERDATA+1; | |
| 70 | + | |
| 71 | +#ifndef MAXSTRING | |
| 72 | +#define MAXSTRING 512 | |
| 73 | +#endif | |
| 74 | +static char *stringbuffer[MAXSTRING]; | |
| 75 | +char **lua_string = stringbuffer; | |
| 76 | +Word lua_nstring=0; | |
| 77 | + | |
| 78 | +#define MAXFILE 20 | |
| 79 | +char *lua_file[MAXFILE]; | |
| 80 | +int lua_nfile; | |
| 81 | + | |
| 82 | + | |
| 83 | +#define markstring(s) (*((s)-1)) | |
| 84 | + | |
| 85 | + | |
| 86 | +/* Variables to controll garbage collection */ | |
| 87 | +Word lua_block=10; /* to check when garbage collector will be called */ | |
| 88 | +Word lua_nentity; /* counter of new entities (strings and arrays) */ | |
| 89 | + | |
| 90 | + | |
| 91 | +/* | |
| 92 | +** Given a name, search it at symbol table and return its index. If not | |
| 93 | +** found, allocate at end of table, checking oveflow and return its index. | |
| 94 | +** On error, return -1. | |
| 95 | +*/ | |
| 96 | +int lua_findsymbol (char *s) | |
| 97 | +{ | |
| 98 | + struct List *l, *p; | |
| 99 | + for (p=NULL, l=searchlist; l!=NULL; p=l, l=l->next) | |
| 100 | + if (streq(s,l->s->name)) | |
| 101 | + { | |
| 102 | + if (p!=NULL) | |
| 103 | + { | |
| 104 | + p->next = l->next; | |
| 105 | + l->next = searchlist; | |
| 106 | + searchlist = l; | |
| 107 | + } | |
| 108 | + return (l->s-lua_table); | |
| 109 | + } | |
| 110 | + | |
| 111 | + if (lua_ntable >= MAXSYMBOL-1) | |
| 112 | + { | |
| 113 | + lua_error ("symbol table overflow"); | |
| 114 | + return -1; | |
| 115 | + } | |
| 116 | + s_name(lua_ntable) = strdup(s); | |
| 117 | + if (s_name(lua_ntable) == NULL) | |
| 118 | + { | |
| 119 | + lua_error ("not enough memory"); | |
| 120 | + return -1; | |
| 121 | + } | |
| 122 | + s_tag(lua_ntable) = T_NIL; | |
| 123 | + p = malloc(sizeof(*p)); | |
| 124 | + p->s = lua_table+lua_ntable; | |
| 125 | + p->next = searchlist; | |
| 126 | + searchlist = p; | |
| 127 | + | |
| 128 | + return lua_ntable++; | |
| 129 | +} | |
| 130 | + | |
| 131 | +/* | |
| 132 | +** Given a constant string, search it at constant table and return its index. | |
| 133 | +** If not found, allocate at end of the table, checking oveflow and return | |
| 134 | +** its index. | |
| 135 | +** | |
| 136 | +** For each allocation, the function allocate a extra char to be used to | |
| 137 | +** mark used string (it's necessary to deal with constant and string | |
| 138 | +** uniformily). The function store at the table the second position allocated, | |
| 139 | +** that represents the beginning of the real string. On error, return -1. | |
| 140 | +** | |
| 141 | +*/ | |
| 142 | +int lua_findconstant (char *s) | |
| 143 | +{ | |
| 144 | + int i; | |
| 145 | + for (i=0; i<lua_nconstant; i++) | |
| 146 | + if (streq(s,lua_constant[i])) | |
| 147 | + return i; | |
| 148 | + if (lua_nconstant >= MAXCONSTANT-1) | |
| 149 | + { | |
| 150 | + lua_error ("lua: constant string table overflow"); | |
| 151 | + return -1; | |
| 152 | + } | |
| 153 | + { | |
| 154 | + char *c = calloc(strlen(s)+2,sizeof(char)); | |
| 155 | + c++; /* create mark space */ | |
| 156 | + lua_constant[lua_nconstant++] = strcpy(c,s); | |
| 157 | + } | |
| 158 | + return (lua_nconstant-1); | |
| 159 | +} | |
| 160 | + | |
| 161 | + | |
| 162 | +/* | |
| 163 | +** Traverse symbol table objects | |
| 164 | +*/ | |
| 165 | +void lua_travsymbol (void (*fn)(Object *)) | |
| 166 | +{ | |
| 167 | + int i; | |
| 168 | + for (i=0; i<lua_ntable; i++) | |
| 169 | + fn(&s_object(i)); | |
| 170 | +} | |
| 171 | + | |
| 172 | + | |
| 173 | +/* | |
| 174 | +** Mark an object if it is a string or a unmarked array. | |
| 175 | +*/ | |
| 176 | +void lua_markobject (Object *o) | |
| 177 | +{ | |
| 178 | + if (tag(o) == T_STRING) | |
| 179 | + markstring (svalue(o)) = 1; | |
| 180 | + else if (tag(o) == T_ARRAY) | |
| 181 | + lua_hashmark (avalue(o)); | |
| 182 | +} | |
| 183 | + | |
| 184 | + | |
| 185 | +/* | |
| 186 | +** Garbage collection. | |
| 187 | +** Delete all unused strings and arrays. | |
| 188 | +*/ | |
| 189 | +void lua_pack (void) | |
| 190 | +{ | |
| 191 | + /* mark stack strings */ | |
| 192 | + lua_travstack(lua_markobject); | |
| 193 | + | |
| 194 | + /* mark symbol table strings */ | |
| 195 | + lua_travsymbol(lua_markobject); | |
| 196 | + | |
| 197 | + lua_stringcollector(); | |
| 198 | + lua_hashcollector(); | |
| 199 | + | |
| 200 | + lua_nentity = 0; /* reset counter */ | |
| 201 | +} | |
| 202 | + | |
| 203 | +/* | |
| 204 | +** Garbage collection to atrings. | |
| 205 | +** Delete all unmarked strings | |
| 206 | +*/ | |
| 207 | +void lua_stringcollector (void) | |
| 208 | +{ | |
| 209 | + int i, j; | |
| 210 | + for (i=j=0; i<lua_nstring; i++) | |
| 211 | + if (markstring(lua_string[i]) == 1) | |
| 212 | + { | |
| 213 | + lua_string[j++] = lua_string[i]; | |
| 214 | + markstring(lua_string[i]) = 0; | |
| 215 | + } | |
| 216 | + else | |
| 217 | + { | |
| 218 | + free (lua_string[i]-1); | |
| 219 | + } | |
| 220 | + lua_nstring = j; | |
| 221 | +} | |
| 222 | + | |
| 223 | +/* | |
| 224 | +** Allocate a new string at string table. The given string is already | |
| 225 | +** allocated with mark space and the function puts it at the end of the | |
| 226 | +** table, checking overflow, and returns its own pointer, or NULL on error. | |
| 227 | +*/ | |
| 228 | +char *lua_createstring (char *s) | |
| 229 | +{ | |
| 230 | + int i; | |
| 231 | + if (s == NULL) return NULL; | |
| 232 | + | |
| 233 | + for (i=0; i<lua_nstring; i++) | |
| 234 | + if (streq(s,lua_string[i])) | |
| 235 | + { | |
| 236 | + free(s-1); | |
| 237 | + return lua_string[i]; | |
| 238 | + } | |
| 239 | + | |
| 240 | + if (lua_nentity == lua_block || lua_nstring >= MAXSTRING-1) | |
| 241 | + { | |
| 242 | + lua_pack (); | |
| 243 | + if (lua_nstring >= MAXSTRING-1) | |
| 244 | + { | |
| 245 | + lua_error ("string table overflow"); | |
| 246 | + return NULL; | |
| 247 | + } | |
| 248 | + } | |
| 249 | + lua_string[lua_nstring++] = s; | |
| 250 | + lua_nentity++; | |
| 251 | + return s; | |
| 252 | +} | |
| 253 | + | |
| 254 | +/* | |
| 255 | +** Add a file name at file table, checking overflow. This function also set | |
| 256 | +** the external variable "lua_filename" with the function filename set. | |
| 257 | +** Return 0 on success or 1 on error. | |
| 258 | +*/ | |
| 259 | +int lua_addfile (char *fn) | |
| 260 | +{ | |
| 261 | + if (lua_nfile >= MAXFILE-1) | |
| 262 | + { | |
| 263 | + lua_error ("too many files"); | |
| 264 | + return 1; | |
| 265 | + } | |
| 266 | + if ((lua_file[lua_nfile++] = strdup (fn)) == NULL) | |
| 267 | + { | |
| 268 | + lua_error ("not enough memory"); | |
| 269 | + return 1; | |
| 270 | + } | |
| 271 | + return 0; | |
| 272 | +} | |
| 273 | + | |
| 274 | +/* | |
| 275 | +** Delete a file from file stack | |
| 276 | +*/ | |
| 277 | +int lua_delfile (void) | |
| 278 | +{ | |
| 279 | + lua_nfile--; | |
| 280 | + return 1; | |
| 281 | +} | |
| 282 | + | |
| 283 | +/* | |
| 284 | +** Return the last file name set. | |
| 285 | +*/ | |
| 286 | +char *lua_filename (void) | |
| 287 | +{ | |
| 288 | + return lua_file[lua_nfile-1]; | |
| 289 | +} | |
| 290 | + | |
| 291 | +/* | |
| 292 | +** Internal function: return next global variable | |
| 293 | +*/ | |
| 294 | +void lua_nextvar (void) | |
| 295 | +{ | |
| 296 | + int index; | |
| 297 | + Object *o = lua_getparam (1); | |
| 298 | + if (o == NULL) | |
| 299 | + { lua_error ("too few arguments to function `nextvar'"); return; } | |
| 300 | + if (lua_getparam (2) != NULL) | |
| 301 | + { lua_error ("too many arguments to function `nextvar'"); return; } | |
| 302 | + if (tag(o) == T_NIL) | |
| 303 | + { | |
| 304 | + index = 0; | |
| 305 | + } | |
| 306 | + else if (tag(o) != T_STRING) | |
| 307 | + { | |
| 308 | + lua_error ("incorrect argument to function `nextvar'"); | |
| 309 | + return; | |
| 310 | + } | |
| 311 | + else | |
| 312 | + { | |
| 313 | + for (index=0; index<lua_ntable; index++) | |
| 314 | + if (streq(s_name(index),svalue(o))) break; | |
| 315 | + if (index == lua_ntable) | |
| 316 | + { | |
| 317 | + lua_error ("name not found in function `nextvar'"); | |
| 318 | + return; | |
| 319 | + } | |
| 320 | + index++; | |
| 321 | + while (index < lua_ntable && tag(&s_object(index)) == T_NIL) index++; | |
| 322 | + | |
| 323 | + if (index == lua_ntable) | |
| 324 | + { | |
| 325 | + lua_pushnil(); | |
| 326 | + lua_pushnil(); | |
| 327 | + return; | |
| 328 | + } | |
| 329 | + } | |
| 330 | + { | |
| 331 | + Object name; | |
| 332 | + tag(&name) = T_STRING; | |
| 333 | + svalue(&name) = lua_createstring(lua_strdup(s_name(index))); | |
| 334 | + if (lua_pushobject (&name)) return; | |
| 335 | + if (lua_pushobject (&s_object(index))) return; | |
| 336 | + } | |
| 337 | +} | |
| @@ -0,0 +1,42 @@ | ||
| 1 | +/* | |
| 2 | +** Module to control static tables | |
| 3 | +** TeCGraf - PUC-Rio | |
| 4 | +** $Id: table.h,v 2.1 1994/04/20 22:07:57 celes Exp $ | |
| 5 | +*/ | |
| 6 | + | |
| 7 | +#ifndef table_h | |
| 8 | +#define table_h | |
| 9 | + | |
| 10 | +extern Symbol *lua_table; | |
| 11 | +extern Word lua_ntable; | |
| 12 | + | |
| 13 | +extern char **lua_constant; | |
| 14 | +extern Word lua_nconstant; | |
| 15 | + | |
| 16 | +extern char **lua_string; | |
| 17 | +extern Word lua_nstring; | |
| 18 | + | |
| 19 | +extern Hash **lua_array; | |
| 20 | +extern Word lua_narray; | |
| 21 | + | |
| 22 | +extern char *lua_file[]; | |
| 23 | +extern int lua_nfile; | |
| 24 | + | |
| 25 | +extern Word lua_block; | |
| 26 | +extern Word lua_nentity; | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | +int lua_findsymbol (char *s); | |
| 31 | +int lua_findconstant (char *s); | |
| 32 | +void lua_travsymbol (void (*fn)(Object *)); | |
| 33 | +void lua_markobject (Object *o); | |
| 34 | +void lua_pack (void); | |
| 35 | +void lua_stringcollector (void); | |
| 36 | +char *lua_createstring (char *s); | |
| 37 | +int lua_addfile (char *fn); | |
| 38 | +int lua_delfile (void); | |
| 39 | +char *lua_filename (void); | |
| 40 | +void lua_nextvar (void); | |
| 41 | + | |
| 42 | +#endif | |
| @@ -0,0 +1,1811 @@ | ||
| 1 | + | |
| 2 | +# line 2 "lua.stx" | |
| 3 | + | |
| 4 | +char *rcs_luastx = "$Id: lua.stx,v 2.4 1994/04/20 16:22:21 celes Exp $"; | |
| 5 | + | |
| 6 | +#include <stdio.h> | |
| 7 | +#include <stdlib.h> | |
| 8 | +#include <string.h> | |
| 9 | + | |
| 10 | +#include "mm.h" | |
| 11 | + | |
| 12 | +#include "opcode.h" | |
| 13 | +#include "hash.h" | |
| 14 | +#include "inout.h" | |
| 15 | +#include "table.h" | |
| 16 | +#include "lua.h" | |
| 17 | + | |
| 18 | +#define LISTING 0 | |
| 19 | + | |
| 20 | +#ifndef GAPCODE | |
| 21 | +#define GAPCODE 50 | |
| 22 | +#endif | |
| 23 | +static Word maxcode; | |
| 24 | +static Word maxmain; | |
| 25 | +static Word maxcurr ; | |
| 26 | +static Byte *code = NULL; | |
| 27 | +static Byte *initcode; | |
| 28 | +static Byte *basepc; | |
| 29 | +static Word maincode; | |
| 30 | +static Word pc; | |
| 31 | + | |
| 32 | +#define MAXVAR 32 | |
| 33 | +static long varbuffer[MAXVAR]; /* variables in an assignment list; | |
| 34 | + it's long to store negative Word values */ | |
| 35 | +static int nvarbuffer=0; /* number of variables at a list */ | |
| 36 | + | |
| 37 | +static Word localvar[STACKGAP]; /* store local variable names */ | |
| 38 | +static int nlocalvar=0; /* number of local variables */ | |
| 39 | + | |
| 40 | +#define MAXFIELDS FIELDS_PER_FLUSH*2 | |
| 41 | +static Word fields[MAXFIELDS]; /* fieldnames to be flushed */ | |
| 42 | +static int nfields=0; | |
| 43 | +static int ntemp; /* number of temporary var into stack */ | |
| 44 | +static int err; /* flag to indicate error */ | |
| 45 | + | |
| 46 | +/* Internal functions */ | |
| 47 | + | |
| 48 | +static void code_byte (Byte c) | |
| 49 | +{ | |
| 50 | + if (pc>maxcurr-2) /* 1 byte free to code HALT of main code */ | |
| 51 | + { | |
| 52 | + maxcurr += GAPCODE; | |
| 53 | + basepc = (Byte *)realloc(basepc, maxcurr*sizeof(Byte)); | |
| 54 | + if (basepc == NULL) | |
| 55 | + { | |
| 56 | + lua_error ("not enough memory"); | |
| 57 | + err = 1; | |
| 58 | + } | |
| 59 | + } | |
| 60 | + basepc[pc++] = c; | |
| 61 | +} | |
| 62 | + | |
| 63 | +static void code_word (Word n) | |
| 64 | +{ | |
| 65 | + CodeWord code; | |
| 66 | + code.w = n; | |
| 67 | + code_byte(code.m.c1); | |
| 68 | + code_byte(code.m.c2); | |
| 69 | +} | |
| 70 | + | |
| 71 | +static void code_float (float n) | |
| 72 | +{ | |
| 73 | + CodeFloat code; | |
| 74 | + code.f = n; | |
| 75 | + code_byte(code.m.c1); | |
| 76 | + code_byte(code.m.c2); | |
| 77 | + code_byte(code.m.c3); | |
| 78 | + code_byte(code.m.c4); | |
| 79 | +} | |
| 80 | + | |
| 81 | +static void code_word_at (Byte *p, Word n) | |
| 82 | +{ | |
| 83 | + CodeWord code; | |
| 84 | + code.w = n; | |
| 85 | + *p++ = code.m.c1; | |
| 86 | + *p++ = code.m.c2; | |
| 87 | +} | |
| 88 | + | |
| 89 | +static void push_field (Word name) | |
| 90 | +{ | |
| 91 | + if (nfields < STACKGAP-1) | |
| 92 | + fields[nfields++] = name; | |
| 93 | + else | |
| 94 | + { | |
| 95 | + lua_error ("too many fields in a constructor"); | |
| 96 | + err = 1; | |
| 97 | + } | |
| 98 | +} | |
| 99 | + | |
| 100 | +static void flush_record (int n) | |
| 101 | +{ | |
| 102 | + int i; | |
| 103 | + if (n == 0) return; | |
| 104 | + code_byte(STORERECORD); | |
| 105 | + code_byte(n); | |
| 106 | + for (i=0; i<n; i++) | |
| 107 | + code_word(fields[--nfields]); | |
| 108 | + ntemp -= n; | |
| 109 | +} | |
| 110 | + | |
| 111 | +static void flush_list (int m, int n) | |
| 112 | +{ | |
| 113 | + if (n == 0) return; | |
| 114 | + if (m == 0) | |
| 115 | + code_byte(STORELIST0); | |
| 116 | + else | |
| 117 | + { | |
| 118 | + code_byte(STORELIST); | |
| 119 | + code_byte(m); | |
| 120 | + } | |
| 121 | + code_byte(n); | |
| 122 | + ntemp-=n; | |
| 123 | +} | |
| 124 | + | |
| 125 | +static void incr_ntemp (void) | |
| 126 | +{ | |
| 127 | + if (ntemp+nlocalvar+MAXVAR+1 < STACKGAP) | |
| 128 | + ntemp++; | |
| 129 | + else | |
| 130 | + { | |
| 131 | + lua_error ("stack overflow"); | |
| 132 | + err = 1; | |
| 133 | + } | |
| 134 | +} | |
| 135 | + | |
| 136 | +static void add_nlocalvar (int n) | |
| 137 | +{ | |
| 138 | + if (ntemp+nlocalvar+MAXVAR+n < STACKGAP) | |
| 139 | + nlocalvar += n; | |
| 140 | + else | |
| 141 | + { | |
| 142 | + lua_error ("too many local variables or expression too complicate"); | |
| 143 | + err = 1; | |
| 144 | + } | |
| 145 | +} | |
| 146 | + | |
| 147 | +static void incr_nvarbuffer (void) | |
| 148 | +{ | |
| 149 | + if (nvarbuffer < MAXVAR-1) | |
| 150 | + nvarbuffer++; | |
| 151 | + else | |
| 152 | + { | |
| 153 | + lua_error ("variable buffer overflow"); | |
| 154 | + err = 1; | |
| 155 | + } | |
| 156 | +} | |
| 157 | + | |
| 158 | +static void code_number (float f) | |
| 159 | +{ Word i = (Word)f; | |
| 160 | + if (f == (float)i) /* f has an (short) integer value */ | |
| 161 | + { | |
| 162 | + if (i <= 2) code_byte(PUSH0 + i); | |
| 163 | + else if (i <= 255) | |
| 164 | + { | |
| 165 | + code_byte(PUSHBYTE); | |
| 166 | + code_byte(i); | |
| 167 | + } | |
| 168 | + else | |
| 169 | + { | |
| 170 | + code_byte(PUSHWORD); | |
| 171 | + code_word(i); | |
| 172 | + } | |
| 173 | + } | |
| 174 | + else | |
| 175 | + { | |
| 176 | + code_byte(PUSHFLOAT); | |
| 177 | + code_float(f); | |
| 178 | + } | |
| 179 | + incr_ntemp(); | |
| 180 | +} | |
| 181 | + | |
| 182 | + | |
| 183 | +# line 184 "lua.stx" | |
| 184 | +typedef union | |
| 185 | +{ | |
| 186 | + int vInt; | |
| 187 | + long vLong; | |
| 188 | + float vFloat; | |
| 189 | + char *pChar; | |
| 190 | + Word vWord; | |
| 191 | + Byte *pByte; | |
| 192 | +} YYSTYPE; | |
| 193 | +# define WRONGTOKEN 257 | |
| 194 | +# define NIL 258 | |
| 195 | +# define IF 259 | |
| 196 | +# define THEN 260 | |
| 197 | +# define ELSE 261 | |
| 198 | +# define ELSEIF 262 | |
| 199 | +# define WHILE 263 | |
| 200 | +# define DO 264 | |
| 201 | +# define REPEAT 265 | |
| 202 | +# define UNTIL 266 | |
| 203 | +# define END 267 | |
| 204 | +# define RETURN 268 | |
| 205 | +# define LOCAL 269 | |
| 206 | +# define NUMBER 270 | |
| 207 | +# define FUNCTION 271 | |
| 208 | +# define STRING 272 | |
| 209 | +# define NAME 273 | |
| 210 | +# define DEBUG 274 | |
| 211 | +# define AND 275 | |
| 212 | +# define OR 276 | |
| 213 | +# define NE 277 | |
| 214 | +# define LE 278 | |
| 215 | +# define GE 279 | |
| 216 | +# define CONC 280 | |
| 217 | +# define UNARY 281 | |
| 218 | +# define NOT 282 | |
| 219 | +#define yyclearin yychar = -1 | |
| 220 | +#define yyerrok yyerrflag = 0 | |
| 221 | +extern int yychar; | |
| 222 | +extern int yyerrflag; | |
| 223 | +#ifndef YYMAXDEPTH | |
| 224 | +#define YYMAXDEPTH 150 | |
| 225 | +#endif | |
| 226 | +YYSTYPE yylval, yyval; | |
| 227 | +# define YYERRCODE 256 | |
| 228 | + | |
| 229 | +# line 622 "lua.stx" | |
| 230 | + | |
| 231 | + | |
| 232 | +/* | |
| 233 | +** Search a local name and if find return its index. If do not find return -1 | |
| 234 | +*/ | |
| 235 | +static int lua_localname (Word n) | |
| 236 | +{ | |
| 237 | + int i; | |
| 238 | + for (i=nlocalvar-1; i >= 0; i--) | |
| 239 | + if (n == localvar[i]) return i; /* local var */ | |
| 240 | + return -1; /* global var */ | |
| 241 | +} | |
| 242 | + | |
| 243 | +/* | |
| 244 | +** Push a variable given a number. If number is positive, push global variable | |
| 245 | +** indexed by (number -1). If negative, push local indexed by ABS(number)-1. | |
| 246 | +** Otherwise, if zero, push indexed variable (record). | |
| 247 | +*/ | |
| 248 | +static void lua_pushvar (long number) | |
| 249 | +{ | |
| 250 | + if (number > 0) /* global var */ | |
| 251 | + { | |
| 252 | + code_byte(PUSHGLOBAL); | |
| 253 | + code_word(number-1); | |
| 254 | + incr_ntemp(); | |
| 255 | + } | |
| 256 | + else if (number < 0) /* local var */ | |
| 257 | + { | |
| 258 | + number = (-number) - 1; | |
| 259 | + if (number < 10) code_byte(PUSHLOCAL0 + number); | |
| 260 | + else | |
| 261 | + { | |
| 262 | + code_byte(PUSHLOCAL); | |
| 263 | + code_byte(number); | |
| 264 | + } | |
| 265 | + incr_ntemp(); | |
| 266 | + } | |
| 267 | + else | |
| 268 | + { | |
| 269 | + code_byte(PUSHINDEXED); | |
| 270 | + ntemp--; | |
| 271 | + } | |
| 272 | +} | |
| 273 | + | |
| 274 | +static void lua_codeadjust (int n) | |
| 275 | +{ | |
| 276 | + code_byte(ADJUST); | |
| 277 | + code_byte(n + nlocalvar); | |
| 278 | +} | |
| 279 | + | |
| 280 | +static void lua_codestore (int i) | |
| 281 | +{ | |
| 282 | + if (varbuffer[i] > 0) /* global var */ | |
| 283 | + { | |
| 284 | + code_byte(STOREGLOBAL); | |
| 285 | + code_word(varbuffer[i]-1); | |
| 286 | + } | |
| 287 | + else if (varbuffer[i] < 0) /* local var */ | |
| 288 | + { | |
| 289 | + int number = (-varbuffer[i]) - 1; | |
| 290 | + if (number < 10) code_byte(STORELOCAL0 + number); | |
| 291 | + else | |
| 292 | + { | |
| 293 | + code_byte(STORELOCAL); | |
| 294 | + code_byte(number); | |
| 295 | + } | |
| 296 | + } | |
| 297 | + else /* indexed var */ | |
| 298 | + { | |
| 299 | + int j; | |
| 300 | + int upper=0; /* number of indexed variables upper */ | |
| 301 | + int param; /* number of itens until indexed expression */ | |
| 302 | + for (j=i+1; j <nvarbuffer; j++) | |
| 303 | + if (varbuffer[j] == 0) upper++; | |
| 304 | + param = upper*2 + i; | |
| 305 | + if (param == 0) | |
| 306 | + code_byte(STOREINDEXED0); | |
| 307 | + else | |
| 308 | + { | |
| 309 | + code_byte(STOREINDEXED); | |
| 310 | + code_byte(param); | |
| 311 | + } | |
| 312 | + } | |
| 313 | +} | |
| 314 | + | |
| 315 | +void yyerror (char *s) | |
| 316 | +{ | |
| 317 | + static char msg[256]; | |
| 318 | + sprintf (msg,"%s near \"%s\" at line %d in file \"%s\"", | |
| 319 | + s, lua_lasttext (), lua_linenumber, lua_filename()); | |
| 320 | + lua_error (msg); | |
| 321 | + err = 1; | |
| 322 | +} | |
| 323 | + | |
| 324 | +int yywrap (void) | |
| 325 | +{ | |
| 326 | + return 1; | |
| 327 | +} | |
| 328 | + | |
| 329 | + | |
| 330 | +/* | |
| 331 | +** Parse LUA code and execute global statement. | |
| 332 | +** Return 0 on success or 1 on error. | |
| 333 | +*/ | |
| 334 | +int lua_parse (void) | |
| 335 | +{ | |
| 336 | + Byte *init = initcode = (Byte *) calloc(GAPCODE, sizeof(Byte)); | |
| 337 | + maincode = 0; | |
| 338 | + maxmain = GAPCODE; | |
| 339 | + if (init == NULL) | |
| 340 | + { | |
| 341 | + lua_error("not enough memory"); | |
| 342 | + return 1; | |
| 343 | + } | |
| 344 | + err = 0; | |
| 345 | + if (yyparse () || (err==1)) return 1; | |
| 346 | + initcode[maincode++] = HALT; | |
| 347 | + init = initcode; | |
| 348 | +#if LISTING | |
| 349 | + PrintCode(init,init+maincode); | |
| 350 | +#endif | |
| 351 | + if (lua_execute (init)) return 1; | |
| 352 | + free(init); | |
| 353 | + return 0; | |
| 354 | +} | |
| 355 | + | |
| 356 | + | |
| 357 | +#if LISTING | |
| 358 | + | |
| 359 | +static void PrintCode (Byte *code, Byte *end) | |
| 360 | +{ | |
| 361 | + Byte *p = code; | |
| 362 | + printf ("\n\nCODE\n"); | |
| 363 | + while (p != end) | |
| 364 | + { | |
| 365 | + switch ((OpCode)*p) | |
| 366 | + { | |
| 367 | + case PUSHNIL: printf ("%d PUSHNIL\n", (p++)-code); break; | |
| 368 | + case PUSH0: case PUSH1: case PUSH2: | |
| 369 | + printf ("%d PUSH%c\n", p-code, *p-PUSH0+'0'); | |
| 370 | + p++; | |
| 371 | + break; | |
| 372 | + case PUSHBYTE: | |
| 373 | + printf ("%d PUSHBYTE %d\n", p-code, *(++p)); | |
| 374 | + p++; | |
| 375 | + break; | |
| 376 | + case PUSHWORD: | |
| 377 | + { | |
| 378 | + CodeWord c; | |
| 379 | + int n = p-code; | |
| 380 | + p++; | |
| 381 | + get_word(c,p); | |
| 382 | + printf ("%d PUSHWORD %d\n", n, c.w); | |
| 383 | + } | |
| 384 | + break; | |
| 385 | + case PUSHFLOAT: | |
| 386 | + { | |
| 387 | + CodeFloat c; | |
| 388 | + int n = p-code; | |
| 389 | + p++; | |
| 390 | + get_float(c,p); | |
| 391 | + printf ("%d PUSHFLOAT %f\n", n, c.f); | |
| 392 | + } | |
| 393 | + break; | |
| 394 | + case PUSHSTRING: | |
| 395 | + { | |
| 396 | + CodeWord c; | |
| 397 | + int n = p-code; | |
| 398 | + p++; | |
| 399 | + get_word(c,p); | |
| 400 | + printf ("%d PUSHSTRING %d\n", n, c.w); | |
| 401 | + } | |
| 402 | + break; | |
| 403 | + case PUSHLOCAL0: case PUSHLOCAL1: case PUSHLOCAL2: case PUSHLOCAL3: | |
| 404 | + case PUSHLOCAL4: case PUSHLOCAL5: case PUSHLOCAL6: case PUSHLOCAL7: | |
| 405 | + case PUSHLOCAL8: case PUSHLOCAL9: | |
| 406 | + printf ("%d PUSHLOCAL%c\n", p-code, *p-PUSHLOCAL0+'0'); | |
| 407 | + p++; | |
| 408 | + break; | |
| 409 | + case PUSHLOCAL: printf ("%d PUSHLOCAL %d\n", p-code, *(++p)); | |
| 410 | + p++; | |
| 411 | + break; | |
| 412 | + case PUSHGLOBAL: | |
| 413 | + { | |
| 414 | + CodeWord c; | |
| 415 | + int n = p-code; | |
| 416 | + p++; | |
| 417 | + get_word(c,p); | |
| 418 | + printf ("%d PUSHGLOBAL %d\n", n, c.w); | |
| 419 | + } | |
| 420 | + break; | |
| 421 | + case PUSHINDEXED: printf ("%d PUSHINDEXED\n", (p++)-code); break; | |
| 422 | + case PUSHMARK: printf ("%d PUSHMARK\n", (p++)-code); break; | |
| 423 | + case PUSHOBJECT: printf ("%d PUSHOBJECT\n", (p++)-code); break; | |
| 424 | + case STORELOCAL0: case STORELOCAL1: case STORELOCAL2: case STORELOCAL3: | |
| 425 | + case STORELOCAL4: case STORELOCAL5: case STORELOCAL6: case STORELOCAL7: | |
| 426 | + case STORELOCAL8: case STORELOCAL9: | |
| 427 | + printf ("%d STORELOCAL%c\n", p-code, *p-STORELOCAL0+'0'); | |
| 428 | + p++; | |
| 429 | + break; | |
| 430 | + case STORELOCAL: | |
| 431 | + printf ("%d STORELOCAL %d\n", p-code, *(++p)); | |
| 432 | + p++; | |
| 433 | + break; | |
| 434 | + case STOREGLOBAL: | |
| 435 | + { | |
| 436 | + CodeWord c; | |
| 437 | + int n = p-code; | |
| 438 | + p++; | |
| 439 | + get_word(c,p); | |
| 440 | + printf ("%d STOREGLOBAL %d\n", n, c.w); | |
| 441 | + } | |
| 442 | + break; | |
| 443 | + case STOREINDEXED0: printf ("%d STOREINDEXED0\n", (p++)-code); break; | |
| 444 | + case STOREINDEXED: printf ("%d STOREINDEXED %d\n", p-code, *(++p)); | |
| 445 | + p++; | |
| 446 | + break; | |
| 447 | + case STORELIST0: | |
| 448 | + printf("%d STORELIST0 %d\n", p-code, *(++p)); | |
| 449 | + p++; | |
| 450 | + break; | |
| 451 | + case STORELIST: | |
| 452 | + printf("%d STORELIST %d %d\n", p-code, *(p+1), *(p+2)); | |
| 453 | + p+=3; | |
| 454 | + break; | |
| 455 | + case STORERECORD: | |
| 456 | + printf("%d STORERECORD %d\n", p-code, *(++p)); | |
| 457 | + p += *p*sizeof(Word) + 1; | |
| 458 | + break; | |
| 459 | + case ADJUST: | |
| 460 | + printf ("%d ADJUST %d\n", p-code, *(++p)); | |
| 461 | + p++; | |
| 462 | + break; | |
| 463 | + case CREATEARRAY: printf ("%d CREATEARRAY\n", (p++)-code); break; | |
| 464 | + case EQOP: printf ("%d EQOP\n", (p++)-code); break; | |
| 465 | + case LTOP: printf ("%d LTOP\n", (p++)-code); break; | |
| 466 | + case LEOP: printf ("%d LEOP\n", (p++)-code); break; | |
| 467 | + case ADDOP: printf ("%d ADDOP\n", (p++)-code); break; | |
| 468 | + case SUBOP: printf ("%d SUBOP\n", (p++)-code); break; | |
| 469 | + case MULTOP: printf ("%d MULTOP\n", (p++)-code); break; | |
| 470 | + case DIVOP: printf ("%d DIVOP\n", (p++)-code); break; | |
| 471 | + case CONCOP: printf ("%d CONCOP\n", (p++)-code); break; | |
| 472 | + case MINUSOP: printf ("%d MINUSOP\n", (p++)-code); break; | |
| 473 | + case NOTOP: printf ("%d NOTOP\n", (p++)-code); break; | |
| 474 | + case ONTJMP: | |
| 475 | + { | |
| 476 | + CodeWord c; | |
| 477 | + int n = p-code; | |
| 478 | + p++; | |
| 479 | + get_word(c,p); | |
| 480 | + printf ("%d ONTJMP %d\n", n, c.w); | |
| 481 | + } | |
| 482 | + break; | |
| 483 | + case ONFJMP: | |
| 484 | + { | |
| 485 | + CodeWord c; | |
| 486 | + int n = p-code; | |
| 487 | + p++; | |
| 488 | + get_word(c,p); | |
| 489 | + printf ("%d ONFJMP %d\n", n, c.w); | |
| 490 | + } | |
| 491 | + break; | |
| 492 | + case JMP: | |
| 493 | + { | |
| 494 | + CodeWord c; | |
| 495 | + int n = p-code; | |
| 496 | + p++; | |
| 497 | + get_word(c,p); | |
| 498 | + printf ("%d JMP %d\n", n, c.w); | |
| 499 | + } | |
| 500 | + break; | |
| 501 | + case UPJMP: | |
| 502 | + { | |
| 503 | + CodeWord c; | |
| 504 | + int n = p-code; | |
| 505 | + p++; | |
| 506 | + get_word(c,p); | |
| 507 | + printf ("%d UPJMP %d\n", n, c.w); | |
| 508 | + } | |
| 509 | + break; | |
| 510 | + case IFFJMP: | |
| 511 | + { | |
| 512 | + CodeWord c; | |
| 513 | + int n = p-code; | |
| 514 | + p++; | |
| 515 | + get_word(c,p); | |
| 516 | + printf ("%d IFFJMP %d\n", n, c.w); | |
| 517 | + } | |
| 518 | + break; | |
| 519 | + case IFFUPJMP: | |
| 520 | + { | |
| 521 | + CodeWord c; | |
| 522 | + int n = p-code; | |
| 523 | + p++; | |
| 524 | + get_word(c,p); | |
| 525 | + printf ("%d IFFUPJMP %d\n", n, c.w); | |
| 526 | + } | |
| 527 | + break; | |
| 528 | + case POP: printf ("%d POP\n", (p++)-code); break; | |
| 529 | + case CALLFUNC: printf ("%d CALLFUNC\n", (p++)-code); break; | |
| 530 | + case RETCODE: | |
| 531 | + printf ("%d RETCODE %d\n", p-code, *(++p)); | |
| 532 | + p++; | |
| 533 | + break; | |
| 534 | + case HALT: printf ("%d HALT\n", (p++)-code); break; | |
| 535 | + case SETFUNCTION: | |
| 536 | + { | |
| 537 | + CodeWord c1, c2; | |
| 538 | + int n = p-code; | |
| 539 | + p++; | |
| 540 | + get_word(c1,p); | |
| 541 | + get_word(c2,p); | |
| 542 | + printf ("%d SETFUNCTION %d %d\n", n, c1.w, c2.w); | |
| 543 | + } | |
| 544 | + break; | |
| 545 | + case SETLINE: | |
| 546 | + { | |
| 547 | + CodeWord c; | |
| 548 | + int n = p-code; | |
| 549 | + p++; | |
| 550 | + get_word(c,p); | |
| 551 | + printf ("%d SETLINE %d\n", n, c.w); | |
| 552 | + } | |
| 553 | + break; | |
| 554 | + | |
| 555 | + case RESET: printf ("%d RESET\n", (p++)-code); break; | |
| 556 | + default: printf ("%d Cannot happen: code %d\n", (p++)-code, *(p-1)); break; | |
| 557 | + } | |
| 558 | + } | |
| 559 | +} | |
| 560 | +#endif | |
| 561 | + | |
| 562 | +int yyexca[] ={ | |
| 563 | +-1, 1, | |
| 564 | + 0, -1, | |
| 565 | + -2, 2, | |
| 566 | +-1, 20, | |
| 567 | + 40, 67, | |
| 568 | + 91, 94, | |
| 569 | + 46, 96, | |
| 570 | + -2, 91, | |
| 571 | +-1, 32, | |
| 572 | + 40, 67, | |
| 573 | + 91, 94, | |
| 574 | + 46, 96, | |
| 575 | + -2, 51, | |
| 576 | +-1, 73, | |
| 577 | + 275, 34, | |
| 578 | + 276, 34, | |
| 579 | + 61, 34, | |
| 580 | + 277, 34, | |
| 581 | + 62, 34, | |
| 582 | + 60, 34, | |
| 583 | + 278, 34, | |
| 584 | + 279, 34, | |
| 585 | + 280, 34, | |
| 586 | + 43, 34, | |
| 587 | + 45, 34, | |
| 588 | + 42, 34, | |
| 589 | + 47, 34, | |
| 590 | + -2, 70, | |
| 591 | +-1, 74, | |
| 592 | + 91, 94, | |
| 593 | + 46, 96, | |
| 594 | + -2, 92, | |
| 595 | +-1, 105, | |
| 596 | + 261, 28, | |
| 597 | + 262, 28, | |
| 598 | + 266, 28, | |
| 599 | + 267, 28, | |
| 600 | + 268, 28, | |
| 601 | + -2, 11, | |
| 602 | +-1, 125, | |
| 603 | + 268, 31, | |
| 604 | + -2, 30, | |
| 605 | +-1, 146, | |
| 606 | + 275, 34, | |
| 607 | + 276, 34, | |
| 608 | + 61, 34, | |
| 609 | + 277, 34, | |
| 610 | + 62, 34, | |
| 611 | + 60, 34, | |
| 612 | + 278, 34, | |
| 613 | + 279, 34, | |
| 614 | + 280, 34, | |
| 615 | + 43, 34, | |
| 616 | + 45, 34, | |
| 617 | + 42, 34, | |
| 618 | + 47, 34, | |
| 619 | + -2, 72, | |
| 620 | + }; | |
| 621 | +# define YYNPROD 103 | |
| 622 | +# define YYLAST 364 | |
| 623 | +int yyact[]={ | |
| 624 | + | |
| 625 | + 58, 56, 22, 57, 132, 59, 58, 56, 137, 57, | |
| 626 | + 110, 59, 58, 56, 107, 57, 85, 59, 51, 50, | |
| 627 | + 52, 82, 23, 43, 51, 50, 52, 58, 56, 9, | |
| 628 | + 57, 157, 59, 58, 56, 165, 57, 5, 59, 162, | |
| 629 | + 6, 161, 104, 154, 155, 51, 50, 52, 64, 153, | |
| 630 | + 70, 51, 50, 52, 26, 58, 56, 127, 57, 10, | |
| 631 | + 59, 111, 25, 78, 27, 58, 56, 28, 57, 29, | |
| 632 | + 59, 131, 147, 51, 50, 52, 7, 65, 66, 115, | |
| 633 | + 150, 112, 63, 51, 50, 52, 68, 69, 31, 159, | |
| 634 | + 11, 79, 58, 76, 128, 73, 41, 59, 151, 87, | |
| 635 | + 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, | |
| 636 | + 77, 114, 148, 40, 58, 56, 102, 57, 106, 59, | |
| 637 | + 117, 32, 72, 121, 116, 100, 80, 109, 67, 48, | |
| 638 | + 20, 36, 73, 30, 45, 73, 44, 118, 149, 84, | |
| 639 | + 17, 126, 18, 46, 21, 47, 120, 119, 101, 145, | |
| 640 | + 144, 125, 71, 123, 75, 39, 38, 12, 8, 108, | |
| 641 | + 105, 136, 83, 74, 135, 24, 4, 3, 139, 140, | |
| 642 | + 2, 81, 134, 141, 133, 130, 129, 42, 113, 16, | |
| 643 | + 1, 146, 124, 0, 143, 0, 0, 152, 0, 0, | |
| 644 | + 0, 86, 0, 0, 0, 0, 0, 13, 0, 0, | |
| 645 | + 160, 14, 0, 15, 164, 163, 0, 19, 167, 0, | |
| 646 | + 0, 23, 73, 0, 0, 0, 0, 0, 168, 166, | |
| 647 | + 158, 171, 173, 0, 0, 0, 169, 0, 0, 0, | |
| 648 | + 0, 0, 0, 61, 62, 53, 54, 55, 60, 61, | |
| 649 | + 62, 53, 54, 55, 60, 0, 0, 0, 0, 103, | |
| 650 | + 60, 49, 0, 98, 99, 0, 0, 0, 0, 0, | |
| 651 | + 61, 62, 53, 54, 55, 60, 61, 62, 53, 54, | |
| 652 | + 55, 60, 0, 0, 0, 0, 0, 0, 0, 0, | |
| 653 | + 0, 0, 35, 0, 0, 0, 0, 0, 61, 62, | |
| 654 | + 53, 54, 55, 60, 33, 122, 34, 23, 0, 0, | |
| 655 | + 53, 54, 55, 60, 0, 0, 37, 0, 0, 0, | |
| 656 | + 138, 0, 0, 0, 0, 142, 0, 0, 0, 0, | |
| 657 | + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | |
| 658 | + 0, 0, 0, 156, 0, 0, 0, 0, 0, 0, | |
| 659 | + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | |
| 660 | + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | |
| 661 | + 170, 0, 0, 172 }; | |
| 662 | +int yypact[]={ | |
| 663 | + | |
| 664 | + -1000, -234, -1000, -1000, -1000, -244, -1000, 31, -62, -1000, | |
| 665 | + -1000, -1000, -1000, 24, -1000, -1000, 52, -1000, -1000, -250, | |
| 666 | + -1000, -1000, -1000, -1000, 89, -9, -1000, 24, 24, 24, | |
| 667 | + -1000, 88, -1000, -1000, -1000, -1000, -1000, 24, 24, -1000, | |
| 668 | + 24, -251, 49, -1000, -28, 45, 86, -252, -257, -1000, | |
| 669 | + 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, | |
| 670 | + 24, -1000, -1000, 84, 13, -1000, -1000, 24, -1000, -15, | |
| 671 | + -224, -1000, 74, -1000, -1000, -1000, -259, 24, 24, -263, | |
| 672 | + 24, -12, -1000, 83, 76, -1000, -1000, -30, -30, -30, | |
| 673 | + -30, -30, -30, 50, 50, -1000, -1000, 72, -1000, -1000, | |
| 674 | + -1000, 82, 13, -1000, 24, -1000, -1000, -1000, 74, -36, | |
| 675 | + -1000, 53, 74, -1000, -269, 24, -1000, -265, -1000, 24, | |
| 676 | + 24, -1000, -1000, 13, 31, -1000, 24, -1000, -1000, -53, | |
| 677 | + 68, -1000, -1000, -13, 54, 13, -1000, -1000, -218, 23, | |
| 678 | + 23, -1000, -1000, -1000, -1000, -237, -1000, -1000, -269, 28, | |
| 679 | + -1000, 24, -226, -228, -1000, 24, -232, 24, -1000, 24, | |
| 680 | + 13, -1000, -1000, -1000, -42, -1000, 31, 13, -1000, -1000, | |
| 681 | + -1000, -1000, -218, -1000 }; | |
| 682 | +int yypgo[]={ | |
| 683 | + | |
| 684 | + 0, 180, 191, 54, 61, 81, 179, 133, 178, 177, | |
| 685 | + 176, 175, 174, 172, 121, 171, 170, 76, 59, 167, | |
| 686 | + 166, 165, 162, 161, 50, 160, 158, 157, 48, 49, | |
| 687 | + 156, 155, 131, 154, 152, 151, 150, 149, 148, 147, | |
| 688 | + 146, 145, 144, 143, 141, 139, 71, 138, 136, 134 }; | |
| 689 | +int yyr1[]={ | |
| 690 | + | |
| 691 | + 0, 1, 16, 1, 1, 1, 21, 23, 19, 25, | |
| 692 | + 25, 26, 17, 18, 18, 27, 30, 27, 31, 27, | |
| 693 | + 27, 27, 27, 27, 29, 29, 29, 34, 35, 24, | |
| 694 | + 36, 37, 36, 2, 28, 3, 3, 3, 3, 3, | |
| 695 | + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, | |
| 696 | + 3, 3, 3, 3, 3, 3, 3, 39, 3, 40, | |
| 697 | + 3, 41, 7, 38, 38, 43, 32, 42, 4, 4, | |
| 698 | + 5, 44, 5, 22, 22, 45, 45, 15, 15, 8, | |
| 699 | + 8, 10, 10, 11, 11, 47, 46, 12, 12, 13, | |
| 700 | + 13, 6, 6, 14, 48, 14, 49, 14, 9, 9, | |
| 701 | + 33, 33, 20 }; | |
| 702 | +int yyr2[]={ | |
| 703 | + | |
| 704 | + 0, 0, 1, 9, 4, 4, 1, 1, 19, 0, | |
| 705 | + 6, 1, 4, 0, 2, 17, 1, 17, 1, 13, | |
| 706 | + 7, 3, 3, 7, 0, 4, 15, 1, 1, 9, | |
| 707 | + 0, 1, 9, 1, 3, 7, 7, 7, 7, 7, | |
| 708 | + 7, 7, 7, 7, 7, 7, 7, 5, 5, 3, | |
| 709 | + 9, 3, 3, 3, 3, 3, 5, 1, 11, 1, | |
| 710 | + 11, 1, 9, 1, 2, 1, 11, 3, 1, 3, | |
| 711 | + 3, 1, 9, 0, 2, 3, 7, 1, 3, 7, | |
| 712 | + 7, 1, 3, 3, 7, 1, 9, 1, 3, 3, | |
| 713 | + 7, 3, 7, 3, 1, 11, 1, 9, 3, 7, | |
| 714 | + 0, 4, 3 }; | |
| 715 | +int yychk[]={ | |
| 716 | + | |
| 717 | + -1000, -1, -16, -19, -20, 271, 274, -17, -26, 273, | |
| 718 | + -18, 59, -27, 259, 263, 265, -6, -32, -7, 269, | |
| 719 | + -14, -42, 64, 273, -21, -28, -3, 40, 43, 45, | |
| 720 | + -7, 64, -14, 270, 272, 258, -32, 282, -30, -31, | |
| 721 | + 61, 44, -9, 273, -48, -49, -43, -41, 40, 260, | |
| 722 | + 61, 60, 62, 277, 278, 279, 43, 45, 42, 47, | |
| 723 | + 280, 275, 276, -3, -28, -28, -28, 40, -28, -28, | |
| 724 | + -24, -34, -5, -3, -14, -33, 44, 61, 91, 46, | |
| 725 | + 40, -15, 273, -22, -45, 273, -2, -28, -28, -28, | |
| 726 | + -28, -28, -28, -28, -28, -28, -28, -28, -2, -2, | |
| 727 | + 41, -38, -28, 264, 266, -25, 44, 273, -5, -28, | |
| 728 | + 273, -4, -5, -8, 123, 91, 41, 44, -24, -39, | |
| 729 | + -40, 41, -2, -28, -17, -35, -44, 93, 41, -10, | |
| 730 | + -11, -46, 273, -12, -13, -28, -23, 273, -2, -28, | |
| 731 | + -28, -24, -2, -18, -36, -37, -3, 125, 44, -47, | |
| 732 | + 93, 44, -24, -29, 261, 262, -2, 268, -46, 61, | |
| 733 | + -28, 267, 267, -24, -28, 267, -4, -28, 260, -18, | |
| 734 | + -2, -24, -2, -29 }; | |
| 735 | +int yydef[]={ | |
| 736 | + | |
| 737 | + 1, -2, 11, 4, 5, 0, 102, 13, 0, 6, | |
| 738 | + 3, 14, 12, 0, 16, 18, 0, 21, 22, 0, | |
| 739 | + -2, 65, 61, 93, 0, 0, 34, 0, 0, 0, | |
| 740 | + 49, 61, -2, 52, 53, 54, 55, 0, 0, 27, | |
| 741 | + 0, 0, 100, 98, 0, 0, 0, 77, 73, 33, | |
| 742 | + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | |
| 743 | + 0, 33, 33, 34, 0, 47, 48, 63, 56, 0, | |
| 744 | + 0, 9, 20, -2, -2, 23, 0, 0, 0, 0, | |
| 745 | + 68, 0, 78, 0, 74, 75, 27, 36, 37, 38, | |
| 746 | + 39, 40, 41, 42, 43, 44, 45, 46, 57, 59, | |
| 747 | + 35, 0, 64, 33, 0, -2, 71, 99, 101, 0, | |
| 748 | + 97, 0, 69, 62, 81, 87, 7, 0, 33, 0, | |
| 749 | + 0, 50, 27, 33, 13, -2, 0, 95, 66, 0, | |
| 750 | + 82, 83, 85, 0, 88, 89, 27, 76, 24, 58, | |
| 751 | + 60, 33, 19, 10, 29, 0, -2, 79, 0, 0, | |
| 752 | + 80, 0, 0, 0, 27, 0, 0, 68, 84, 0, | |
| 753 | + 90, 8, 15, 25, 0, 17, 13, 86, 33, 32, | |
| 754 | + 27, 33, 24, 26 }; | |
| 755 | +typedef struct { char *t_name; int t_val; } yytoktype; | |
| 756 | +#ifndef YYDEBUG | |
| 757 | +# define YYDEBUG 0 /* don't allow debugging */ | |
| 758 | +#endif | |
| 759 | + | |
| 760 | +#if YYDEBUG | |
| 761 | + | |
| 762 | +yytoktype yytoks[] = | |
| 763 | +{ | |
| 764 | + "WRONGTOKEN", 257, | |
| 765 | + "NIL", 258, | |
| 766 | + "IF", 259, | |
| 767 | + "THEN", 260, | |
| 768 | + "ELSE", 261, | |
| 769 | + "ELSEIF", 262, | |
| 770 | + "WHILE", 263, | |
| 771 | + "DO", 264, | |
| 772 | + "REPEAT", 265, | |
| 773 | + "UNTIL", 266, | |
| 774 | + "END", 267, | |
| 775 | + "RETURN", 268, | |
| 776 | + "LOCAL", 269, | |
| 777 | + "NUMBER", 270, | |
| 778 | + "FUNCTION", 271, | |
| 779 | + "STRING", 272, | |
| 780 | + "NAME", 273, | |
| 781 | + "DEBUG", 274, | |
| 782 | + "AND", 275, | |
| 783 | + "OR", 276, | |
| 784 | + "=", 61, | |
| 785 | + "NE", 277, | |
| 786 | + ">", 62, | |
| 787 | + "<", 60, | |
| 788 | + "LE", 278, | |
| 789 | + "GE", 279, | |
| 790 | + "CONC", 280, | |
| 791 | + "+", 43, | |
| 792 | + "-", 45, | |
| 793 | + "*", 42, | |
| 794 | + "/", 47, | |
| 795 | + "UNARY", 281, | |
| 796 | + "NOT", 282, | |
| 797 | + "-unknown-", -1 /* ends search */ | |
| 798 | +}; | |
| 799 | + | |
| 800 | +char * yyreds[] = | |
| 801 | +{ | |
| 802 | + "-no such reduction-", | |
| 803 | + "functionlist : /* empty */", | |
| 804 | + "functionlist : functionlist", | |
| 805 | + "functionlist : functionlist stat sc", | |
| 806 | + "functionlist : functionlist function", | |
| 807 | + "functionlist : functionlist setdebug", | |
| 808 | + "function : FUNCTION NAME", | |
| 809 | + "function : FUNCTION NAME '(' parlist ')'", | |
| 810 | + "function : FUNCTION NAME '(' parlist ')' block END", | |
| 811 | + "statlist : /* empty */", | |
| 812 | + "statlist : statlist stat sc", | |
| 813 | + "stat : /* empty */", | |
| 814 | + "stat : stat1", | |
| 815 | + "sc : /* empty */", | |
| 816 | + "sc : ';'", | |
| 817 | + "stat1 : IF expr1 THEN PrepJump block PrepJump elsepart END", | |
| 818 | + "stat1 : WHILE", | |
| 819 | + "stat1 : WHILE expr1 DO PrepJump block PrepJump END", | |
| 820 | + "stat1 : REPEAT", | |
| 821 | + "stat1 : REPEAT block UNTIL expr1 PrepJump", | |
| 822 | + "stat1 : varlist1 '=' exprlist1", | |
| 823 | + "stat1 : functioncall", | |
| 824 | + "stat1 : typeconstructor", | |
| 825 | + "stat1 : LOCAL localdeclist decinit", | |
| 826 | + "elsepart : /* empty */", | |
| 827 | + "elsepart : ELSE block", | |
| 828 | + "elsepart : ELSEIF expr1 THEN PrepJump block PrepJump elsepart", | |
| 829 | + "block : /* empty */", | |
| 830 | + "block : statlist", | |
| 831 | + "block : statlist ret", | |
| 832 | + "ret : /* empty */", | |
| 833 | + "ret : /* empty */", | |
| 834 | + "ret : RETURN exprlist sc", | |
| 835 | + "PrepJump : /* empty */", | |
| 836 | + "expr1 : expr", | |
| 837 | + "expr : '(' expr ')'", | |
| 838 | + "expr : expr1 '=' expr1", | |
| 839 | + "expr : expr1 '<' expr1", | |
| 840 | + "expr : expr1 '>' expr1", | |
| 841 | + "expr : expr1 NE expr1", | |
| 842 | + "expr : expr1 LE expr1", | |
| 843 | + "expr : expr1 GE expr1", | |
| 844 | + "expr : expr1 '+' expr1", | |
| 845 | + "expr : expr1 '-' expr1", | |
| 846 | + "expr : expr1 '*' expr1", | |
| 847 | + "expr : expr1 '/' expr1", | |
| 848 | + "expr : expr1 CONC expr1", | |
| 849 | + "expr : '+' expr1", | |
| 850 | + "expr : '-' expr1", | |
| 851 | + "expr : typeconstructor", | |
| 852 | + "expr : '@' '(' dimension ')'", | |
| 853 | + "expr : var", | |
| 854 | + "expr : NUMBER", | |
| 855 | + "expr : STRING", | |
| 856 | + "expr : NIL", | |
| 857 | + "expr : functioncall", | |
| 858 | + "expr : NOT expr1", | |
| 859 | + "expr : expr1 AND PrepJump", | |
| 860 | + "expr : expr1 AND PrepJump expr1", | |
| 861 | + "expr : expr1 OR PrepJump", | |
| 862 | + "expr : expr1 OR PrepJump expr1", | |
| 863 | + "typeconstructor : '@'", | |
| 864 | + "typeconstructor : '@' objectname fieldlist", | |
| 865 | + "dimension : /* empty */", | |
| 866 | + "dimension : expr1", | |
| 867 | + "functioncall : functionvalue", | |
| 868 | + "functioncall : functionvalue '(' exprlist ')'", | |
| 869 | + "functionvalue : var", | |
| 870 | + "exprlist : /* empty */", | |
| 871 | + "exprlist : exprlist1", | |
| 872 | + "exprlist1 : expr", | |
| 873 | + "exprlist1 : exprlist1 ','", | |
| 874 | + "exprlist1 : exprlist1 ',' expr", | |
| 875 | + "parlist : /* empty */", | |
| 876 | + "parlist : parlist1", | |
| 877 | + "parlist1 : NAME", | |
| 878 | + "parlist1 : parlist1 ',' NAME", | |
| 879 | + "objectname : /* empty */", | |
| 880 | + "objectname : NAME", | |
| 881 | + "fieldlist : '{' ffieldlist '}'", | |
| 882 | + "fieldlist : '[' lfieldlist ']'", | |
| 883 | + "ffieldlist : /* empty */", | |
| 884 | + "ffieldlist : ffieldlist1", | |
| 885 | + "ffieldlist1 : ffield", | |
| 886 | + "ffieldlist1 : ffieldlist1 ',' ffield", | |
| 887 | + "ffield : NAME", | |
| 888 | + "ffield : NAME '=' expr1", | |
| 889 | + "lfieldlist : /* empty */", | |
| 890 | + "lfieldlist : lfieldlist1", | |
| 891 | + "lfieldlist1 : expr1", | |
| 892 | + "lfieldlist1 : lfieldlist1 ',' expr1", | |
| 893 | + "varlist1 : var", | |
| 894 | + "varlist1 : varlist1 ',' var", | |
| 895 | + "var : NAME", | |
| 896 | + "var : var", | |
| 897 | + "var : var '[' expr1 ']'", | |
| 898 | + "var : var", | |
| 899 | + "var : var '.' NAME", | |
| 900 | + "localdeclist : NAME", | |
| 901 | + "localdeclist : localdeclist ',' NAME", | |
| 902 | + "decinit : /* empty */", | |
| 903 | + "decinit : '=' exprlist1", | |
| 904 | + "setdebug : DEBUG", | |
| 905 | +}; | |
| 906 | +#endif /* YYDEBUG */ | |
| 907 | +#line 1 "/usr/lib/yaccpar" | |
| 908 | +/* @(#)yaccpar 1.10 89/04/04 SMI; from S5R3 1.10 */ | |
| 909 | + | |
| 910 | +/* | |
| 911 | +** Skeleton parser driver for yacc output | |
| 912 | +*/ | |
| 913 | + | |
| 914 | +/* | |
| 915 | +** yacc user known macros and defines | |
| 916 | +*/ | |
| 917 | +#define YYERROR goto yyerrlab | |
| 918 | +#define YYACCEPT { free(yys); free(yyv); return(0); } | |
| 919 | +#define YYABORT { free(yys); free(yyv); return(1); } | |
| 920 | +#define YYBACKUP( newtoken, newvalue )\ | |
| 921 | +{\ | |
| 922 | + if ( yychar >= 0 || ( yyr2[ yytmp ] >> 1 ) != 1 )\ | |
| 923 | + {\ | |
| 924 | + yyerror( "syntax error - cannot backup" );\ | |
| 925 | + goto yyerrlab;\ | |
| 926 | + }\ | |
| 927 | + yychar = newtoken;\ | |
| 928 | + yystate = *yyps;\ | |
| 929 | + yylval = newvalue;\ | |
| 930 | + goto yynewstate;\ | |
| 931 | +} | |
| 932 | +#define YYRECOVERING() (!!yyerrflag) | |
| 933 | +#ifndef YYDEBUG | |
| 934 | +# define YYDEBUG 1 /* make debugging available */ | |
| 935 | +#endif | |
| 936 | + | |
| 937 | +/* | |
| 938 | +** user known globals | |
| 939 | +*/ | |
| 940 | +int yydebug; /* set to 1 to get debugging */ | |
| 941 | + | |
| 942 | +/* | |
| 943 | +** driver internal defines | |
| 944 | +*/ | |
| 945 | +#define YYFLAG (-1000) | |
| 946 | + | |
| 947 | +/* | |
| 948 | +** static variables used by the parser | |
| 949 | +*/ | |
| 950 | +static YYSTYPE *yyv; /* value stack */ | |
| 951 | +static int *yys; /* state stack */ | |
| 952 | + | |
| 953 | +static YYSTYPE *yypv; /* top of value stack */ | |
| 954 | +static int *yyps; /* top of state stack */ | |
| 955 | + | |
| 956 | +static int yystate; /* current state */ | |
| 957 | +static int yytmp; /* extra var (lasts between blocks) */ | |
| 958 | + | |
| 959 | +int yynerrs; /* number of errors */ | |
| 960 | + | |
| 961 | +int yyerrflag; /* error recovery flag */ | |
| 962 | +int yychar; /* current input token number */ | |
| 963 | + | |
| 964 | + | |
| 965 | +/* | |
| 966 | +** yyparse - return 0 if worked, 1 if syntax error not recovered from | |
| 967 | +*/ | |
| 968 | +int | |
| 969 | +yyparse() | |
| 970 | +{ | |
| 971 | + register YYSTYPE *yypvt; /* top of value stack for $vars */ | |
| 972 | + unsigned yymaxdepth = YYMAXDEPTH; | |
| 973 | + | |
| 974 | + /* | |
| 975 | + ** Initialize externals - yyparse may be called more than once | |
| 976 | + */ | |
| 977 | + yyv = (YYSTYPE*)malloc(yymaxdepth*sizeof(YYSTYPE)); | |
| 978 | + yys = (int*)malloc(yymaxdepth*sizeof(int)); | |
| 979 | + if (!yyv || !yys) | |
| 980 | + { | |
| 981 | + yyerror( "out of memory" ); | |
| 982 | + return(1); | |
| 983 | + } | |
| 984 | + yypv = &yyv[-1]; | |
| 985 | + yyps = &yys[-1]; | |
| 986 | + yystate = 0; | |
| 987 | + yytmp = 0; | |
| 988 | + yynerrs = 0; | |
| 989 | + yyerrflag = 0; | |
| 990 | + yychar = -1; | |
| 991 | + | |
| 992 | + goto yystack; | |
| 993 | + { | |
| 994 | + register YYSTYPE *yy_pv; /* top of value stack */ | |
| 995 | + register int *yy_ps; /* top of state stack */ | |
| 996 | + register int yy_state; /* current state */ | |
| 997 | + register int yy_n; /* internal state number info */ | |
| 998 | + | |
| 999 | + /* | |
| 1000 | + ** get globals into registers. | |
| 1001 | + ** branch to here only if YYBACKUP was called. | |
| 1002 | + */ | |
| 1003 | + yynewstate: | |
| 1004 | + yy_pv = yypv; | |
| 1005 | + yy_ps = yyps; | |
| 1006 | + yy_state = yystate; | |
| 1007 | + goto yy_newstate; | |
| 1008 | + | |
| 1009 | + /* | |
| 1010 | + ** get globals into registers. | |
| 1011 | + ** either we just started, or we just finished a reduction | |
| 1012 | + */ | |
| 1013 | + yystack: | |
| 1014 | + yy_pv = yypv; | |
| 1015 | + yy_ps = yyps; | |
| 1016 | + yy_state = yystate; | |
| 1017 | + | |
| 1018 | + /* | |
| 1019 | + ** top of for (;;) loop while no reductions done | |
| 1020 | + */ | |
| 1021 | + yy_stack: | |
| 1022 | + /* | |
| 1023 | + ** put a state and value onto the stacks | |
| 1024 | + */ | |
| 1025 | +#if YYDEBUG | |
| 1026 | + /* | |
| 1027 | + ** if debugging, look up token value in list of value vs. | |
| 1028 | + ** name pairs. 0 and negative (-1) are special values. | |
| 1029 | + ** Note: linear search is used since time is not a real | |
| 1030 | + ** consideration while debugging. | |
| 1031 | + */ | |
| 1032 | + if ( yydebug ) | |
| 1033 | + { | |
| 1034 | + register int yy_i; | |
| 1035 | + | |
| 1036 | + (void)printf( "State %d, token ", yy_state ); | |
| 1037 | + if ( yychar == 0 ) | |
| 1038 | + (void)printf( "end-of-file\n" ); | |
| 1039 | + else if ( yychar < 0 ) | |
| 1040 | + (void)printf( "-none-\n" ); | |
| 1041 | + else | |
| 1042 | + { | |
| 1043 | + for ( yy_i = 0; yytoks[yy_i].t_val >= 0; | |
| 1044 | + yy_i++ ) | |
| 1045 | + { | |
| 1046 | + if ( yytoks[yy_i].t_val == yychar ) | |
| 1047 | + break; | |
| 1048 | + } | |
| 1049 | + (void)printf( "%s\n", yytoks[yy_i].t_name ); | |
| 1050 | + } | |
| 1051 | + } | |
| 1052 | +#endif /* YYDEBUG */ | |
| 1053 | + if ( ++yy_ps >= &yys[ yymaxdepth ] ) /* room on stack? */ | |
| 1054 | + { | |
| 1055 | + /* | |
| 1056 | + ** reallocate and recover. Note that pointers | |
| 1057 | + ** have to be reset, or bad things will happen | |
| 1058 | + */ | |
| 1059 | + int yyps_index = (yy_ps - yys); | |
| 1060 | + int yypv_index = (yy_pv - yyv); | |
| 1061 | + int yypvt_index = (yypvt - yyv); | |
| 1062 | + yymaxdepth += YYMAXDEPTH; | |
| 1063 | + yyv = (YYSTYPE*)realloc((char*)yyv, | |
| 1064 | + yymaxdepth * sizeof(YYSTYPE)); | |
| 1065 | + yys = (int*)realloc((char*)yys, | |
| 1066 | + yymaxdepth * sizeof(int)); | |
| 1067 | + if (!yyv || !yys) | |
| 1068 | + { | |
| 1069 | + yyerror( "yacc stack overflow" ); | |
| 1070 | + return(1); | |
| 1071 | + } | |
| 1072 | + yy_ps = yys + yyps_index; | |
| 1073 | + yy_pv = yyv + yypv_index; | |
| 1074 | + yypvt = yyv + yypvt_index; | |
| 1075 | + } | |
| 1076 | + *yy_ps = yy_state; | |
| 1077 | + *++yy_pv = yyval; | |
| 1078 | + | |
| 1079 | + /* | |
| 1080 | + ** we have a new state - find out what to do | |
| 1081 | + */ | |
| 1082 | + yy_newstate: | |
| 1083 | + if ( ( yy_n = yypact[ yy_state ] ) <= YYFLAG ) | |
| 1084 | + goto yydefault; /* simple state */ | |
| 1085 | +#if YYDEBUG | |
| 1086 | + /* | |
| 1087 | + ** if debugging, need to mark whether new token grabbed | |
| 1088 | + */ | |
| 1089 | + yytmp = yychar < 0; | |
| 1090 | +#endif | |
| 1091 | + if ( ( yychar < 0 ) && ( ( yychar = yylex() ) < 0 ) ) | |
| 1092 | + yychar = 0; /* reached EOF */ | |
| 1093 | +#if YYDEBUG | |
| 1094 | + if ( yydebug && yytmp ) | |
| 1095 | + { | |
| 1096 | + register int yy_i; | |
| 1097 | + | |
| 1098 | + (void)printf( "Received token " ); | |
| 1099 | + if ( yychar == 0 ) | |
| 1100 | + (void)printf( "end-of-file\n" ); | |
| 1101 | + else if ( yychar < 0 ) | |
| 1102 | + (void)printf( "-none-\n" ); | |
| 1103 | + else | |
| 1104 | + { | |
| 1105 | + for ( yy_i = 0; yytoks[yy_i].t_val >= 0; | |
| 1106 | + yy_i++ ) | |
| 1107 | + { | |
| 1108 | + if ( yytoks[yy_i].t_val == yychar ) | |
| 1109 | + break; | |
| 1110 | + } | |
| 1111 | + (void)printf( "%s\n", yytoks[yy_i].t_name ); | |
| 1112 | + } | |
| 1113 | + } | |
| 1114 | +#endif /* YYDEBUG */ | |
| 1115 | + if ( ( ( yy_n += yychar ) < 0 ) || ( yy_n >= YYLAST ) ) | |
| 1116 | + goto yydefault; | |
| 1117 | + if ( yychk[ yy_n = yyact[ yy_n ] ] == yychar ) /*valid shift*/ | |
| 1118 | + { | |
| 1119 | + yychar = -1; | |
| 1120 | + yyval = yylval; | |
| 1121 | + yy_state = yy_n; | |
| 1122 | + if ( yyerrflag > 0 ) | |
| 1123 | + yyerrflag--; | |
| 1124 | + goto yy_stack; | |
| 1125 | + } | |
| 1126 | + | |
| 1127 | + yydefault: | |
| 1128 | + if ( ( yy_n = yydef[ yy_state ] ) == -2 ) | |
| 1129 | + { | |
| 1130 | +#if YYDEBUG | |
| 1131 | + yytmp = yychar < 0; | |
| 1132 | +#endif | |
| 1133 | + if ( ( yychar < 0 ) && ( ( yychar = yylex() ) < 0 ) ) | |
| 1134 | + yychar = 0; /* reached EOF */ | |
| 1135 | +#if YYDEBUG | |
| 1136 | + if ( yydebug && yytmp ) | |
| 1137 | + { | |
| 1138 | + register int yy_i; | |
| 1139 | + | |
| 1140 | + (void)printf( "Received token " ); | |
| 1141 | + if ( yychar == 0 ) | |
| 1142 | + (void)printf( "end-of-file\n" ); | |
| 1143 | + else if ( yychar < 0 ) | |
| 1144 | + (void)printf( "-none-\n" ); | |
| 1145 | + else | |
| 1146 | + { | |
| 1147 | + for ( yy_i = 0; | |
| 1148 | + yytoks[yy_i].t_val >= 0; | |
| 1149 | + yy_i++ ) | |
| 1150 | + { | |
| 1151 | + if ( yytoks[yy_i].t_val | |
| 1152 | + == yychar ) | |
| 1153 | + { | |
| 1154 | + break; | |
| 1155 | + } | |
| 1156 | + } | |
| 1157 | + (void)printf( "%s\n", yytoks[yy_i].t_name ); | |
| 1158 | + } | |
| 1159 | + } | |
| 1160 | +#endif /* YYDEBUG */ | |
| 1161 | + /* | |
| 1162 | + ** look through exception table | |
| 1163 | + */ | |
| 1164 | + { | |
| 1165 | + register int *yyxi = yyexca; | |
| 1166 | + | |
| 1167 | + while ( ( *yyxi != -1 ) || | |
| 1168 | + ( yyxi[1] != yy_state ) ) | |
| 1169 | + { | |
| 1170 | + yyxi += 2; | |
| 1171 | + } | |
| 1172 | + while ( ( *(yyxi += 2) >= 0 ) && | |
| 1173 | + ( *yyxi != yychar ) ) | |
| 1174 | + ; | |
| 1175 | + if ( ( yy_n = yyxi[1] ) < 0 ) | |
| 1176 | + YYACCEPT; | |
| 1177 | + } | |
| 1178 | + } | |
| 1179 | + | |
| 1180 | + /* | |
| 1181 | + ** check for syntax error | |
| 1182 | + */ | |
| 1183 | + if ( yy_n == 0 ) /* have an error */ | |
| 1184 | + { | |
| 1185 | + /* no worry about speed here! */ | |
| 1186 | + switch ( yyerrflag ) | |
| 1187 | + { | |
| 1188 | + case 0: /* new error */ | |
| 1189 | + yyerror( "syntax error" ); | |
| 1190 | + goto skip_init; | |
| 1191 | + yyerrlab: | |
| 1192 | + /* | |
| 1193 | + ** get globals into registers. | |
| 1194 | + ** we have a user generated syntax type error | |
| 1195 | + */ | |
| 1196 | + yy_pv = yypv; | |
| 1197 | + yy_ps = yyps; | |
| 1198 | + yy_state = yystate; | |
| 1199 | + yynerrs++; | |
| 1200 | + skip_init: | |
| 1201 | + case 1: | |
| 1202 | + case 2: /* incompletely recovered error */ | |
| 1203 | + /* try again... */ | |
| 1204 | + yyerrflag = 3; | |
| 1205 | + /* | |
| 1206 | + ** find state where "error" is a legal | |
| 1207 | + ** shift action | |
| 1208 | + */ | |
| 1209 | + while ( yy_ps >= yys ) | |
| 1210 | + { | |
| 1211 | + yy_n = yypact[ *yy_ps ] + YYERRCODE; | |
| 1212 | + if ( yy_n >= 0 && yy_n < YYLAST && | |
| 1213 | + yychk[yyact[yy_n]] == YYERRCODE) { | |
| 1214 | + /* | |
| 1215 | + ** simulate shift of "error" | |
| 1216 | + */ | |
| 1217 | + yy_state = yyact[ yy_n ]; | |
| 1218 | + goto yy_stack; | |
| 1219 | + } | |
| 1220 | + /* | |
| 1221 | + ** current state has no shift on | |
| 1222 | + ** "error", pop stack | |
| 1223 | + */ | |
| 1224 | +#if YYDEBUG | |
| 1225 | +# define _POP_ "Error recovery pops state %d, uncovers state %d\n" | |
| 1226 | + if ( yydebug ) | |
| 1227 | + (void)printf( _POP_, *yy_ps, | |
| 1228 | + yy_ps[-1] ); | |
| 1229 | +# undef _POP_ | |
| 1230 | +#endif | |
| 1231 | + yy_ps--; | |
| 1232 | + yy_pv--; | |
| 1233 | + } | |
| 1234 | + /* | |
| 1235 | + ** there is no state on stack with "error" as | |
| 1236 | + ** a valid shift. give up. | |
| 1237 | + */ | |
| 1238 | + YYABORT; | |
| 1239 | + case 3: /* no shift yet; eat a token */ | |
| 1240 | +#if YYDEBUG | |
| 1241 | + /* | |
| 1242 | + ** if debugging, look up token in list of | |
| 1243 | + ** pairs. 0 and negative shouldn't occur, | |
| 1244 | + ** but since timing doesn't matter when | |
| 1245 | + ** debugging, it doesn't hurt to leave the | |
| 1246 | + ** tests here. | |
| 1247 | + */ | |
| 1248 | + if ( yydebug ) | |
| 1249 | + { | |
| 1250 | + register int yy_i; | |
| 1251 | + | |
| 1252 | + (void)printf( "Error recovery discards " ); | |
| 1253 | + if ( yychar == 0 ) | |
| 1254 | + (void)printf( "token end-of-file\n" ); | |
| 1255 | + else if ( yychar < 0 ) | |
| 1256 | + (void)printf( "token -none-\n" ); | |
| 1257 | + else | |
| 1258 | + { | |
| 1259 | + for ( yy_i = 0; | |
| 1260 | + yytoks[yy_i].t_val >= 0; | |
| 1261 | + yy_i++ ) | |
| 1262 | + { | |
| 1263 | + if ( yytoks[yy_i].t_val | |
| 1264 | + == yychar ) | |
| 1265 | + { | |
| 1266 | + break; | |
| 1267 | + } | |
| 1268 | + } | |
| 1269 | + (void)printf( "token %s\n", | |
| 1270 | + yytoks[yy_i].t_name ); | |
| 1271 | + } | |
| 1272 | + } | |
| 1273 | +#endif /* YYDEBUG */ | |
| 1274 | + if ( yychar == 0 ) /* reached EOF. quit */ | |
| 1275 | + YYABORT; | |
| 1276 | + yychar = -1; | |
| 1277 | + goto yy_newstate; | |
| 1278 | + } | |
| 1279 | + }/* end if ( yy_n == 0 ) */ | |
| 1280 | + /* | |
| 1281 | + ** reduction by production yy_n | |
| 1282 | + ** put stack tops, etc. so things right after switch | |
| 1283 | + */ | |
| 1284 | +#if YYDEBUG | |
| 1285 | + /* | |
| 1286 | + ** if debugging, print the string that is the user's | |
| 1287 | + ** specification of the reduction which is just about | |
| 1288 | + ** to be done. | |
| 1289 | + */ | |
| 1290 | + if ( yydebug ) | |
| 1291 | + (void)printf( "Reduce by (%d) \"%s\"\n", | |
| 1292 | + yy_n, yyreds[ yy_n ] ); | |
| 1293 | +#endif | |
| 1294 | + yytmp = yy_n; /* value to switch over */ | |
| 1295 | + yypvt = yy_pv; /* $vars top of value stack */ | |
| 1296 | + /* | |
| 1297 | + ** Look in goto table for next state | |
| 1298 | + ** Sorry about using yy_state here as temporary | |
| 1299 | + ** register variable, but why not, if it works... | |
| 1300 | + ** If yyr2[ yy_n ] doesn't have the low order bit | |
| 1301 | + ** set, then there is no action to be done for | |
| 1302 | + ** this reduction. So, no saving & unsaving of | |
| 1303 | + ** registers done. The only difference between the | |
| 1304 | + ** code just after the if and the body of the if is | |
| 1305 | + ** the goto yy_stack in the body. This way the test | |
| 1306 | + ** can be made before the choice of what to do is needed. | |
| 1307 | + */ | |
| 1308 | + { | |
| 1309 | + /* length of production doubled with extra bit */ | |
| 1310 | + register int yy_len = yyr2[ yy_n ]; | |
| 1311 | + | |
| 1312 | + if ( !( yy_len & 01 ) ) | |
| 1313 | + { | |
| 1314 | + yy_len >>= 1; | |
| 1315 | + yyval = ( yy_pv -= yy_len )[1]; /* $$ = $1 */ | |
| 1316 | + yy_state = yypgo[ yy_n = yyr1[ yy_n ] ] + | |
| 1317 | + *( yy_ps -= yy_len ) + 1; | |
| 1318 | + if ( yy_state >= YYLAST || | |
| 1319 | + yychk[ yy_state = | |
| 1320 | + yyact[ yy_state ] ] != -yy_n ) | |
| 1321 | + { | |
| 1322 | + yy_state = yyact[ yypgo[ yy_n ] ]; | |
| 1323 | + } | |
| 1324 | + goto yy_stack; | |
| 1325 | + } | |
| 1326 | + yy_len >>= 1; | |
| 1327 | + yyval = ( yy_pv -= yy_len )[1]; /* $$ = $1 */ | |
| 1328 | + yy_state = yypgo[ yy_n = yyr1[ yy_n ] ] + | |
| 1329 | + *( yy_ps -= yy_len ) + 1; | |
| 1330 | + if ( yy_state >= YYLAST || | |
| 1331 | + yychk[ yy_state = yyact[ yy_state ] ] != -yy_n ) | |
| 1332 | + { | |
| 1333 | + yy_state = yyact[ yypgo[ yy_n ] ]; | |
| 1334 | + } | |
| 1335 | + } | |
| 1336 | + /* save until reenter driver code */ | |
| 1337 | + yystate = yy_state; | |
| 1338 | + yyps = yy_ps; | |
| 1339 | + yypv = yy_pv; | |
| 1340 | + } | |
| 1341 | + /* | |
| 1342 | + ** code supplied by user is placed in this switch | |
| 1343 | + */ | |
| 1344 | + switch( yytmp ) | |
| 1345 | + { | |
| 1346 | + | |
| 1347 | +case 2: | |
| 1348 | +# line 227 "lua.stx" | |
| 1349 | +{ | |
| 1350 | + pc=maincode; basepc=initcode; maxcurr=maxmain; | |
| 1351 | + nlocalvar=0; | |
| 1352 | + } break; | |
| 1353 | +case 3: | |
| 1354 | +# line 232 "lua.stx" | |
| 1355 | +{ | |
| 1356 | + maincode=pc; initcode=basepc; maxmain=maxcurr; | |
| 1357 | + } break; | |
| 1358 | +case 6: | |
| 1359 | +# line 240 "lua.stx" | |
| 1360 | +{ | |
| 1361 | + if (code == NULL) /* first function */ | |
| 1362 | + { | |
| 1363 | + code = (Byte *) calloc(GAPCODE, sizeof(Byte)); | |
| 1364 | + if (code == NULL) | |
| 1365 | + { | |
| 1366 | + lua_error("not enough memory"); | |
| 1367 | + err = 1; | |
| 1368 | + } | |
| 1369 | + maxcode = GAPCODE; | |
| 1370 | + } | |
| 1371 | + pc=0; basepc=code; maxcurr=maxcode; | |
| 1372 | + nlocalvar=0; | |
| 1373 | + yyval.vWord = lua_findsymbol(yypvt[-0].pChar); | |
| 1374 | + } break; | |
| 1375 | +case 7: | |
| 1376 | +# line 256 "lua.stx" | |
| 1377 | +{ | |
| 1378 | + if (lua_debug) | |
| 1379 | + { | |
| 1380 | + code_byte(SETFUNCTION); | |
| 1381 | + code_word(lua_nfile-1); | |
| 1382 | + code_word(yypvt[-3].vWord); | |
| 1383 | + } | |
| 1384 | + lua_codeadjust (0); | |
| 1385 | + } break; | |
| 1386 | +case 8: | |
| 1387 | +# line 267 "lua.stx" | |
| 1388 | +{ | |
| 1389 | + if (lua_debug) code_byte(RESET); | |
| 1390 | + code_byte(RETCODE); code_byte(nlocalvar); | |
| 1391 | + s_tag(yypvt[-6].vWord) = T_FUNCTION; | |
| 1392 | + s_bvalue(yypvt[-6].vWord) = calloc (pc, sizeof(Byte)); | |
| 1393 | + if (s_bvalue(yypvt[-6].vWord) == NULL) | |
| 1394 | + { | |
| 1395 | + lua_error("not enough memory"); | |
| 1396 | + err = 1; | |
| 1397 | + } | |
| 1398 | + memcpy (s_bvalue(yypvt[-6].vWord), basepc, pc*sizeof(Byte)); | |
| 1399 | + code = basepc; maxcode=maxcurr; | |
| 1400 | +#if LISTING | |
| 1401 | +PrintCode(code,code+pc); | |
| 1402 | +#endif | |
| 1403 | + } break; | |
| 1404 | +case 11: | |
| 1405 | +# line 289 "lua.stx" | |
| 1406 | +{ | |
| 1407 | + ntemp = 0; | |
| 1408 | + if (lua_debug) | |
| 1409 | + { | |
| 1410 | + code_byte(SETLINE); code_word(lua_linenumber); | |
| 1411 | + } | |
| 1412 | + } break; | |
| 1413 | +case 15: | |
| 1414 | +# line 302 "lua.stx" | |
| 1415 | +{ | |
| 1416 | + { | |
| 1417 | + Word elseinit = yypvt[-2].vWord+sizeof(Word)+1; | |
| 1418 | + if (pc - elseinit == 0) /* no else */ | |
| 1419 | + { | |
| 1420 | + pc -= sizeof(Word)+1; | |
| 1421 | + elseinit = pc; | |
| 1422 | + } | |
| 1423 | + else | |
| 1424 | + { | |
| 1425 | + basepc[yypvt[-2].vWord] = JMP; | |
| 1426 | + code_word_at(basepc+yypvt[-2].vWord+1, pc - elseinit); | |
| 1427 | + } | |
| 1428 | + basepc[yypvt[-4].vWord] = IFFJMP; | |
| 1429 | + code_word_at(basepc+yypvt[-4].vWord+1,elseinit-(yypvt[-4].vWord+sizeof(Word)+1)); | |
| 1430 | + } | |
| 1431 | + } break; | |
| 1432 | +case 16: | |
| 1433 | +# line 320 "lua.stx" | |
| 1434 | +{yyval.vWord=pc;} break; | |
| 1435 | +case 17: | |
| 1436 | +# line 322 "lua.stx" | |
| 1437 | +{ | |
| 1438 | + basepc[yypvt[-3].vWord] = IFFJMP; | |
| 1439 | + code_word_at(basepc+yypvt[-3].vWord+1, pc - (yypvt[-3].vWord + sizeof(Word)+1)); | |
| 1440 | + | |
| 1441 | + basepc[yypvt[-1].vWord] = UPJMP; | |
| 1442 | + code_word_at(basepc+yypvt[-1].vWord+1, pc - (yypvt[-6].vWord)); | |
| 1443 | + } break; | |
| 1444 | +case 18: | |
| 1445 | +# line 330 "lua.stx" | |
| 1446 | +{yyval.vWord=pc;} break; | |
| 1447 | +case 19: | |
| 1448 | +# line 332 "lua.stx" | |
| 1449 | +{ | |
| 1450 | + basepc[yypvt[-0].vWord] = IFFUPJMP; | |
| 1451 | + code_word_at(basepc+yypvt[-0].vWord+1, pc - (yypvt[-4].vWord)); | |
| 1452 | + } break; | |
| 1453 | +case 20: | |
| 1454 | +# line 339 "lua.stx" | |
| 1455 | +{ | |
| 1456 | + { | |
| 1457 | + int i; | |
| 1458 | + if (yypvt[-0].vInt == 0 || nvarbuffer != ntemp - yypvt[-2].vInt * 2) | |
| 1459 | + lua_codeadjust (yypvt[-2].vInt * 2 + nvarbuffer); | |
| 1460 | + for (i=nvarbuffer-1; i>=0; i--) | |
| 1461 | + lua_codestore (i); | |
| 1462 | + if (yypvt[-2].vInt > 1 || (yypvt[-2].vInt == 1 && varbuffer[0] != 0)) | |
| 1463 | + lua_codeadjust (0); | |
| 1464 | + } | |
| 1465 | + } break; | |
| 1466 | +case 21: | |
| 1467 | +# line 350 "lua.stx" | |
| 1468 | +{ lua_codeadjust (0); } break; | |
| 1469 | +case 22: | |
| 1470 | +# line 351 "lua.stx" | |
| 1471 | +{ lua_codeadjust (0); } break; | |
| 1472 | +case 23: | |
| 1473 | +# line 352 "lua.stx" | |
| 1474 | +{ add_nlocalvar(yypvt[-1].vInt); lua_codeadjust (0); } break; | |
| 1475 | +case 26: | |
| 1476 | +# line 358 "lua.stx" | |
| 1477 | +{ | |
| 1478 | + { | |
| 1479 | + Word elseinit = yypvt[-1].vWord+sizeof(Word)+1; | |
| 1480 | + if (pc - elseinit == 0) /* no else */ | |
| 1481 | + { | |
| 1482 | + pc -= sizeof(Word)+1; | |
| 1483 | + elseinit = pc; | |
| 1484 | + } | |
| 1485 | + else | |
| 1486 | + { | |
| 1487 | + basepc[yypvt[-1].vWord] = JMP; | |
| 1488 | + code_word_at(basepc+yypvt[-1].vWord+1, pc - elseinit); | |
| 1489 | + } | |
| 1490 | + basepc[yypvt[-3].vWord] = IFFJMP; | |
| 1491 | + code_word_at(basepc+yypvt[-3].vWord+1, elseinit - (yypvt[-3].vWord + sizeof(Word)+1)); | |
| 1492 | + } | |
| 1493 | + } break; | |
| 1494 | +case 27: | |
| 1495 | +# line 377 "lua.stx" | |
| 1496 | +{yyval.vInt = nlocalvar;} break; | |
| 1497 | +case 28: | |
| 1498 | +# line 377 "lua.stx" | |
| 1499 | +{ntemp = 0;} break; | |
| 1500 | +case 29: | |
| 1501 | +# line 378 "lua.stx" | |
| 1502 | +{ | |
| 1503 | + if (nlocalvar != yypvt[-3].vInt) | |
| 1504 | + { | |
| 1505 | + nlocalvar = yypvt[-3].vInt; | |
| 1506 | + lua_codeadjust (0); | |
| 1507 | + } | |
| 1508 | + } break; | |
| 1509 | +case 31: | |
| 1510 | +# line 388 "lua.stx" | |
| 1511 | +{ if (lua_debug){code_byte(SETLINE);code_word(lua_linenumber);}} break; | |
| 1512 | +case 32: | |
| 1513 | +# line 390 "lua.stx" | |
| 1514 | +{ | |
| 1515 | + if (lua_debug) code_byte(RESET); | |
| 1516 | + code_byte(RETCODE); code_byte(nlocalvar); | |
| 1517 | + } break; | |
| 1518 | +case 33: | |
| 1519 | +# line 397 "lua.stx" | |
| 1520 | +{ | |
| 1521 | + yyval.vWord = pc; | |
| 1522 | + code_byte(0); /* open space */ | |
| 1523 | + code_word (0); | |
| 1524 | + } break; | |
| 1525 | +case 34: | |
| 1526 | +# line 403 "lua.stx" | |
| 1527 | +{ if (yypvt[-0].vInt == 0) {lua_codeadjust (ntemp+1); incr_ntemp();}} break; | |
| 1528 | +case 35: | |
| 1529 | +# line 406 "lua.stx" | |
| 1530 | +{ yyval.vInt = yypvt[-1].vInt; } break; | |
| 1531 | +case 36: | |
| 1532 | +# line 407 "lua.stx" | |
| 1533 | +{ code_byte(EQOP); yyval.vInt = 1; ntemp--;} break; | |
| 1534 | +case 37: | |
| 1535 | +# line 408 "lua.stx" | |
| 1536 | +{ code_byte(LTOP); yyval.vInt = 1; ntemp--;} break; | |
| 1537 | +case 38: | |
| 1538 | +# line 409 "lua.stx" | |
| 1539 | +{ code_byte(LEOP); code_byte(NOTOP); yyval.vInt = 1; ntemp--;} break; | |
| 1540 | +case 39: | |
| 1541 | +# line 410 "lua.stx" | |
| 1542 | +{ code_byte(EQOP); code_byte(NOTOP); yyval.vInt = 1; ntemp--;} break; | |
| 1543 | +case 40: | |
| 1544 | +# line 411 "lua.stx" | |
| 1545 | +{ code_byte(LEOP); yyval.vInt = 1; ntemp--;} break; | |
| 1546 | +case 41: | |
| 1547 | +# line 412 "lua.stx" | |
| 1548 | +{ code_byte(LTOP); code_byte(NOTOP); yyval.vInt = 1; ntemp--;} break; | |
| 1549 | +case 42: | |
| 1550 | +# line 413 "lua.stx" | |
| 1551 | +{ code_byte(ADDOP); yyval.vInt = 1; ntemp--;} break; | |
| 1552 | +case 43: | |
| 1553 | +# line 414 "lua.stx" | |
| 1554 | +{ code_byte(SUBOP); yyval.vInt = 1; ntemp--;} break; | |
| 1555 | +case 44: | |
| 1556 | +# line 415 "lua.stx" | |
| 1557 | +{ code_byte(MULTOP); yyval.vInt = 1; ntemp--;} break; | |
| 1558 | +case 45: | |
| 1559 | +# line 416 "lua.stx" | |
| 1560 | +{ code_byte(DIVOP); yyval.vInt = 1; ntemp--;} break; | |
| 1561 | +case 46: | |
| 1562 | +# line 417 "lua.stx" | |
| 1563 | +{ code_byte(CONCOP); yyval.vInt = 1; ntemp--;} break; | |
| 1564 | +case 47: | |
| 1565 | +# line 418 "lua.stx" | |
| 1566 | +{ yyval.vInt = 1; } break; | |
| 1567 | +case 48: | |
| 1568 | +# line 419 "lua.stx" | |
| 1569 | +{ code_byte(MINUSOP); yyval.vInt = 1;} break; | |
| 1570 | +case 49: | |
| 1571 | +# line 420 "lua.stx" | |
| 1572 | +{ yyval.vInt = yypvt[-0].vInt; } break; | |
| 1573 | +case 50: | |
| 1574 | +# line 422 "lua.stx" | |
| 1575 | +{ | |
| 1576 | + code_byte(CREATEARRAY); | |
| 1577 | + yyval.vInt = 1; | |
| 1578 | + } break; | |
| 1579 | +case 51: | |
| 1580 | +# line 426 "lua.stx" | |
| 1581 | +{ lua_pushvar (yypvt[-0].vLong); yyval.vInt = 1;} break; | |
| 1582 | +case 52: | |
| 1583 | +# line 427 "lua.stx" | |
| 1584 | +{ code_number(yypvt[-0].vFloat); yyval.vInt = 1; } break; | |
| 1585 | +case 53: | |
| 1586 | +# line 429 "lua.stx" | |
| 1587 | +{ | |
| 1588 | + code_byte(PUSHSTRING); | |
| 1589 | + code_word(yypvt[-0].vWord); | |
| 1590 | + yyval.vInt = 1; | |
| 1591 | + incr_ntemp(); | |
| 1592 | + } break; | |
| 1593 | +case 54: | |
| 1594 | +# line 435 "lua.stx" | |
| 1595 | +{code_byte(PUSHNIL); yyval.vInt = 1; incr_ntemp();} break; | |
| 1596 | +case 55: | |
| 1597 | +# line 437 "lua.stx" | |
| 1598 | +{ | |
| 1599 | + yyval.vInt = 0; | |
| 1600 | + if (lua_debug) | |
| 1601 | + { | |
| 1602 | + code_byte(SETLINE); code_word(lua_linenumber); | |
| 1603 | + } | |
| 1604 | + } break; | |
| 1605 | +case 56: | |
| 1606 | +# line 444 "lua.stx" | |
| 1607 | +{ code_byte(NOTOP); yyval.vInt = 1;} break; | |
| 1608 | +case 57: | |
| 1609 | +# line 445 "lua.stx" | |
| 1610 | +{code_byte(POP); ntemp--;} break; | |
| 1611 | +case 58: | |
| 1612 | +# line 446 "lua.stx" | |
| 1613 | +{ | |
| 1614 | + basepc[yypvt[-2].vWord] = ONFJMP; | |
| 1615 | + code_word_at(basepc+yypvt[-2].vWord+1, pc - (yypvt[-2].vWord + sizeof(Word)+1)); | |
| 1616 | + yyval.vInt = 1; | |
| 1617 | + } break; | |
| 1618 | +case 59: | |
| 1619 | +# line 451 "lua.stx" | |
| 1620 | +{code_byte(POP); ntemp--;} break; | |
| 1621 | +case 60: | |
| 1622 | +# line 452 "lua.stx" | |
| 1623 | +{ | |
| 1624 | + basepc[yypvt[-2].vWord] = ONTJMP; | |
| 1625 | + code_word_at(basepc+yypvt[-2].vWord+1, pc - (yypvt[-2].vWord + sizeof(Word)+1)); | |
| 1626 | + yyval.vInt = 1; | |
| 1627 | + } break; | |
| 1628 | +case 61: | |
| 1629 | +# line 460 "lua.stx" | |
| 1630 | +{ | |
| 1631 | + code_byte(PUSHBYTE); | |
| 1632 | + yyval.vWord = pc; code_byte(0); | |
| 1633 | + incr_ntemp(); | |
| 1634 | + code_byte(CREATEARRAY); | |
| 1635 | + } break; | |
| 1636 | +case 62: | |
| 1637 | +# line 467 "lua.stx" | |
| 1638 | +{ | |
| 1639 | + basepc[yypvt[-2].vWord] = yypvt[-0].vInt; | |
| 1640 | + if (yypvt[-1].vLong < 0) /* there is no function to be called */ | |
| 1641 | + { | |
| 1642 | + yyval.vInt = 1; | |
| 1643 | + } | |
| 1644 | + else | |
| 1645 | + { | |
| 1646 | + lua_pushvar (yypvt[-1].vLong+1); | |
| 1647 | + code_byte(PUSHMARK); | |
| 1648 | + incr_ntemp(); | |
| 1649 | + code_byte(PUSHOBJECT); | |
| 1650 | + incr_ntemp(); | |
| 1651 | + code_byte(CALLFUNC); | |
| 1652 | + ntemp -= 4; | |
| 1653 | + yyval.vInt = 0; | |
| 1654 | + if (lua_debug) | |
| 1655 | + { | |
| 1656 | + code_byte(SETLINE); code_word(lua_linenumber); | |
| 1657 | + } | |
| 1658 | + } | |
| 1659 | + } break; | |
| 1660 | +case 63: | |
| 1661 | +# line 491 "lua.stx" | |
| 1662 | +{ code_byte(PUSHNIL); incr_ntemp();} break; | |
| 1663 | +case 65: | |
| 1664 | +# line 495 "lua.stx" | |
| 1665 | +{code_byte(PUSHMARK); yyval.vInt = ntemp; incr_ntemp();} break; | |
| 1666 | +case 66: | |
| 1667 | +# line 496 "lua.stx" | |
| 1668 | +{ code_byte(CALLFUNC); ntemp = yypvt[-3].vInt-1;} break; | |
| 1669 | +case 67: | |
| 1670 | +# line 498 "lua.stx" | |
| 1671 | +{lua_pushvar (yypvt[-0].vLong); } break; | |
| 1672 | +case 68: | |
| 1673 | +# line 501 "lua.stx" | |
| 1674 | +{ yyval.vInt = 1; } break; | |
| 1675 | +case 69: | |
| 1676 | +# line 502 "lua.stx" | |
| 1677 | +{ yyval.vInt = yypvt[-0].vInt; } break; | |
| 1678 | +case 70: | |
| 1679 | +# line 505 "lua.stx" | |
| 1680 | +{ yyval.vInt = yypvt[-0].vInt; } break; | |
| 1681 | +case 71: | |
| 1682 | +# line 506 "lua.stx" | |
| 1683 | +{if (!yypvt[-1].vInt){lua_codeadjust (ntemp+1); incr_ntemp();}} break; | |
| 1684 | +case 72: | |
| 1685 | +# line 507 "lua.stx" | |
| 1686 | +{yyval.vInt = yypvt[-0].vInt;} break; | |
| 1687 | +case 75: | |
| 1688 | +# line 515 "lua.stx" | |
| 1689 | +{ | |
| 1690 | + localvar[nlocalvar]=lua_findsymbol(yypvt[-0].pChar); | |
| 1691 | + add_nlocalvar(1); | |
| 1692 | + } break; | |
| 1693 | +case 76: | |
| 1694 | +# line 520 "lua.stx" | |
| 1695 | +{ | |
| 1696 | + localvar[nlocalvar]=lua_findsymbol(yypvt[-0].pChar); | |
| 1697 | + add_nlocalvar(1); | |
| 1698 | + } break; | |
| 1699 | +case 77: | |
| 1700 | +# line 526 "lua.stx" | |
| 1701 | +{yyval.vLong=-1;} break; | |
| 1702 | +case 78: | |
| 1703 | +# line 527 "lua.stx" | |
| 1704 | +{yyval.vLong=lua_findsymbol(yypvt[-0].pChar);} break; | |
| 1705 | +case 79: | |
| 1706 | +# line 531 "lua.stx" | |
| 1707 | +{ | |
| 1708 | + flush_record(yypvt[-1].vInt%FIELDS_PER_FLUSH); | |
| 1709 | + yyval.vInt = yypvt[-1].vInt; | |
| 1710 | + } break; | |
| 1711 | +case 80: | |
| 1712 | +# line 536 "lua.stx" | |
| 1713 | +{ | |
| 1714 | + flush_list(yypvt[-1].vInt/FIELDS_PER_FLUSH, yypvt[-1].vInt%FIELDS_PER_FLUSH); | |
| 1715 | + yyval.vInt = yypvt[-1].vInt; | |
| 1716 | + } break; | |
| 1717 | +case 81: | |
| 1718 | +# line 542 "lua.stx" | |
| 1719 | +{ yyval.vInt = 0; } break; | |
| 1720 | +case 82: | |
| 1721 | +# line 543 "lua.stx" | |
| 1722 | +{ yyval.vInt = yypvt[-0].vInt; } break; | |
| 1723 | +case 83: | |
| 1724 | +# line 546 "lua.stx" | |
| 1725 | +{yyval.vInt=1;} break; | |
| 1726 | +case 84: | |
| 1727 | +# line 548 "lua.stx" | |
| 1728 | +{ | |
| 1729 | + yyval.vInt=yypvt[-2].vInt+1; | |
| 1730 | + if (yyval.vInt%FIELDS_PER_FLUSH == 0) flush_record(FIELDS_PER_FLUSH); | |
| 1731 | + } break; | |
| 1732 | +case 85: | |
| 1733 | +# line 554 "lua.stx" | |
| 1734 | +{yyval.vWord = lua_findconstant(yypvt[-0].pChar);} break; | |
| 1735 | +case 86: | |
| 1736 | +# line 555 "lua.stx" | |
| 1737 | +{ | |
| 1738 | + push_field(yypvt[-2].vWord); | |
| 1739 | + } break; | |
| 1740 | +case 87: | |
| 1741 | +# line 560 "lua.stx" | |
| 1742 | +{ yyval.vInt = 0; } break; | |
| 1743 | +case 88: | |
| 1744 | +# line 561 "lua.stx" | |
| 1745 | +{ yyval.vInt = yypvt[-0].vInt; } break; | |
| 1746 | +case 89: | |
| 1747 | +# line 564 "lua.stx" | |
| 1748 | +{yyval.vInt=1;} break; | |
| 1749 | +case 90: | |
| 1750 | +# line 566 "lua.stx" | |
| 1751 | +{ | |
| 1752 | + yyval.vInt=yypvt[-2].vInt+1; | |
| 1753 | + if (yyval.vInt%FIELDS_PER_FLUSH == 0) | |
| 1754 | + flush_list(yyval.vInt/FIELDS_PER_FLUSH - 1, FIELDS_PER_FLUSH); | |
| 1755 | + } break; | |
| 1756 | +case 91: | |
| 1757 | +# line 574 "lua.stx" | |
| 1758 | +{ | |
| 1759 | + nvarbuffer = 0; | |
| 1760 | + varbuffer[nvarbuffer] = yypvt[-0].vLong; incr_nvarbuffer(); | |
| 1761 | + yyval.vInt = (yypvt[-0].vLong == 0) ? 1 : 0; | |
| 1762 | + } break; | |
| 1763 | +case 92: | |
| 1764 | +# line 580 "lua.stx" | |
| 1765 | +{ | |
| 1766 | + varbuffer[nvarbuffer] = yypvt[-0].vLong; incr_nvarbuffer(); | |
| 1767 | + yyval.vInt = (yypvt[-0].vLong == 0) ? yypvt[-2].vInt + 1 : yypvt[-2].vInt; | |
| 1768 | + } break; | |
| 1769 | +case 93: | |
| 1770 | +# line 587 "lua.stx" | |
| 1771 | +{ | |
| 1772 | + Word s = lua_findsymbol(yypvt[-0].pChar); | |
| 1773 | + int local = lua_localname (s); | |
| 1774 | + if (local == -1) /* global var */ | |
| 1775 | + yyval.vLong = s + 1; /* return positive value */ | |
| 1776 | + else | |
| 1777 | + yyval.vLong = -(local+1); /* return negative value */ | |
| 1778 | + } break; | |
| 1779 | +case 94: | |
| 1780 | +# line 596 "lua.stx" | |
| 1781 | +{lua_pushvar (yypvt[-0].vLong);} break; | |
| 1782 | +case 95: | |
| 1783 | +# line 597 "lua.stx" | |
| 1784 | +{ | |
| 1785 | + yyval.vLong = 0; /* indexed variable */ | |
| 1786 | + } break; | |
| 1787 | +case 96: | |
| 1788 | +# line 600 "lua.stx" | |
| 1789 | +{lua_pushvar (yypvt[-0].vLong);} break; | |
| 1790 | +case 97: | |
| 1791 | +# line 601 "lua.stx" | |
| 1792 | +{ | |
| 1793 | + code_byte(PUSHSTRING); | |
| 1794 | + code_word(lua_findconstant(yypvt[-0].pChar)); incr_ntemp(); | |
| 1795 | + yyval.vLong = 0; /* indexed variable */ | |
| 1796 | + } break; | |
| 1797 | +case 98: | |
| 1798 | +# line 608 "lua.stx" | |
| 1799 | +{localvar[nlocalvar]=lua_findsymbol(yypvt[-0].pChar); yyval.vInt = 1;} break; | |
| 1800 | +case 99: | |
| 1801 | +# line 610 "lua.stx" | |
| 1802 | +{ | |
| 1803 | + localvar[nlocalvar+yypvt[-2].vInt]=lua_findsymbol(yypvt[-0].pChar); | |
| 1804 | + yyval.vInt = yypvt[-2].vInt+1; | |
| 1805 | + } break; | |
| 1806 | +case 102: | |
| 1807 | +# line 620 "lua.stx" | |
| 1808 | +{lua_debug = yypvt[-0].vInt;} break; | |
| 1809 | + } | |
| 1810 | + goto yystack; /* reset registers in driver code */ | |
| 1811 | +} | |
| @@ -0,0 +1,37 @@ | ||
| 1 | + | |
| 2 | +typedef union | |
| 3 | +{ | |
| 4 | + int vInt; | |
| 5 | + long vLong; | |
| 6 | + float vFloat; | |
| 7 | + char *pChar; | |
| 8 | + Word vWord; | |
| 9 | + Byte *pByte; | |
| 10 | +} YYSTYPE; | |
| 11 | +extern YYSTYPE yylval; | |
| 12 | +# define WRONGTOKEN 257 | |
| 13 | +# define NIL 258 | |
| 14 | +# define IF 259 | |
| 15 | +# define THEN 260 | |
| 16 | +# define ELSE 261 | |
| 17 | +# define ELSEIF 262 | |
| 18 | +# define WHILE 263 | |
| 19 | +# define DO 264 | |
| 20 | +# define REPEAT 265 | |
| 21 | +# define UNTIL 266 | |
| 22 | +# define END 267 | |
| 23 | +# define RETURN 268 | |
| 24 | +# define LOCAL 269 | |
| 25 | +# define NUMBER 270 | |
| 26 | +# define FUNCTION 271 | |
| 27 | +# define STRING 272 | |
| 28 | +# define NAME 273 | |
| 29 | +# define DEBUG 274 | |
| 30 | +# define AND 275 | |
| 31 | +# define OR 276 | |
| 32 | +# define NE 277 | |
| 33 | +# define LE 278 | |
| 34 | +# define GE 279 | |
| 35 | +# define CONC 280 | |
| 36 | +# define UNARY 281 | |
| 37 | +# define NOT 282 | |
| @@ -0,0 +1,27 @@ | ||
| 1 | +# makefile for lua | |
| 2 | + | |
| 3 | +LIB= $(LUA)/lib | |
| 4 | +INC= $(LUA)/inc | |
| 5 | + | |
| 6 | +CC= gcc | |
| 7 | +CFLAGS= -g -Wall -O2 -I$(INC) $(DEFS) | |
| 8 | +DEFS= -DMAXCODE=64000 -DMAXCONSTANT=1024 -DMAXSYMBOL=1024 -DMAXARRAY=1024 | |
| 9 | + | |
| 10 | +OBJS= hash.o inout.o lex.o opcode.o table.o y.tab.o | |
| 11 | +SLIB= $(LIB)/lua.a | |
| 12 | +DLIB= $(LIB)/liblua.so.1.1 | |
| 13 | + | |
| 14 | +libs: $(SLIB) $(DLIB) | |
| 15 | + | |
| 16 | +$(SLIB): y.tab.c $(OBJS) | |
| 17 | + ar ruvl $@ $(OBJS) | |
| 18 | + ranlib $(SLIB) | |
| 19 | + | |
| 20 | +$(DLIB): $(OBJS) | |
| 21 | + ld -o $@ $(OBJS) | |
| 22 | + | |
| 23 | +y.tab.c: lua.stx exscript | |
| 24 | + yacc -d lua.stx ; ex y.tab.c <exscript | |
| 25 | + | |
| 26 | +clean: | |
| 27 | + rm -f $(OBJS) $(SLIB) $(DLIB) | |
| @@ -0,0 +1,3 @@ | ||
| 1 | +1d | |
| 2 | +x | |
| 3 | + | |
| @@ -0,0 +1,85 @@ | ||
| 1 | +%{ | |
| 2 | + | |
| 3 | +char *rcs_lualex = "$Id: lua.lex,v 1.1 1993/12/17 18:53:41 celes Exp $"; | |
| 4 | + | |
| 5 | +#include <stdlib.h> | |
| 6 | +#include <string.h> | |
| 7 | + | |
| 8 | +#include "opcode.h" | |
| 9 | +#include "hash.h" | |
| 10 | +#include "inout.h" | |
| 11 | +#include "table.h" | |
| 12 | +#include "y.tab.h" | |
| 13 | + | |
| 14 | +#undef input | |
| 15 | +#undef unput | |
| 16 | + | |
| 17 | +static Input input; | |
| 18 | +static Unput unput; | |
| 19 | + | |
| 20 | +void lua_setinput (Input fn) | |
| 21 | +{ | |
| 22 | + input = fn; | |
| 23 | +} | |
| 24 | + | |
| 25 | +void lua_setunput (Unput fn) | |
| 26 | +{ | |
| 27 | + unput = fn; | |
| 28 | +} | |
| 29 | + | |
| 30 | +char *lua_lasttext (void) | |
| 31 | +{ | |
| 32 | + return yytext; | |
| 33 | +} | |
| 34 | + | |
| 35 | +%} | |
| 36 | + | |
| 37 | + | |
| 38 | +%% | |
| 39 | +[ \t]* ; | |
| 40 | +^"$debug" {yylval.vInt = 1; return DEBUG;} | |
| 41 | +^"$nodebug" {yylval.vInt = 0; return DEBUG;} | |
| 42 | +\n lua_linenumber++; | |
| 43 | +"--".* ; | |
| 44 | +"local" return LOCAL; | |
| 45 | +"if" return IF; | |
| 46 | +"then" return THEN; | |
| 47 | +"else" return ELSE; | |
| 48 | +"elseif" return ELSEIF; | |
| 49 | +"while" return WHILE; | |
| 50 | +"do" return DO; | |
| 51 | +"repeat" return REPEAT; | |
| 52 | +"until" return UNTIL; | |
| 53 | +"function" { | |
| 54 | + yylval.vWord = lua_nfile-1; | |
| 55 | + return FUNCTION; | |
| 56 | + } | |
| 57 | +"end" return END; | |
| 58 | +"return" return RETURN; | |
| 59 | +"local" return LOCAL; | |
| 60 | +"nil" return NIL; | |
| 61 | +"and" return AND; | |
| 62 | +"or" return OR; | |
| 63 | +"not" return NOT; | |
| 64 | +"~=" return NE; | |
| 65 | +"<=" return LE; | |
| 66 | +">=" return GE; | |
| 67 | +".." return CONC; | |
| 68 | +\"[^\"]*\" | | |
| 69 | +\'[^\']*\' { | |
| 70 | + yylval.vWord = lua_findenclosedconstant (yytext); | |
| 71 | + return STRING; | |
| 72 | + } | |
| 73 | +[0-9]+("."[0-9]*)? | | |
| 74 | +([0-9]+)?"."[0-9]+ | | |
| 75 | +[0-9]+("."[0-9]*)?[dDeEgG][+-]?[0-9]+ | | |
| 76 | +([0-9]+)?"."[0-9]+[dDeEgG][+-]?[0-9]+ { | |
| 77 | + yylval.vFloat = atof(yytext); | |
| 78 | + return NUMBER; | |
| 79 | + } | |
| 80 | +[a-zA-Z_][a-zA-Z0-9_]* { | |
| 81 | + yylval.vWord = lua_findsymbol (yytext); | |
| 82 | + return NAME; | |
| 83 | + } | |
| 84 | +. return *yytext; | |
| 85 | + | |
| @@ -0,0 +1,953 @@ | ||
| 1 | +%{ | |
| 2 | + | |
| 3 | +char *rcs_luastx = "$Id: lua.stx,v 2.4 1994/04/20 16:22:21 celes Exp $"; | |
| 4 | + | |
| 5 | +#include <stdio.h> | |
| 6 | +#include <stdlib.h> | |
| 7 | +#include <string.h> | |
| 8 | + | |
| 9 | +#include "mm.h" | |
| 10 | + | |
| 11 | +#include "opcode.h" | |
| 12 | +#include "hash.h" | |
| 13 | +#include "inout.h" | |
| 14 | +#include "table.h" | |
| 15 | +#include "lua.h" | |
| 16 | + | |
| 17 | +#define LISTING 0 | |
| 18 | + | |
| 19 | +#ifndef GAPCODE | |
| 20 | +#define GAPCODE 50 | |
| 21 | +#endif | |
| 22 | +static Word maxcode; | |
| 23 | +static Word maxmain; | |
| 24 | +static Word maxcurr ; | |
| 25 | +static Byte *code = NULL; | |
| 26 | +static Byte *initcode; | |
| 27 | +static Byte *basepc; | |
| 28 | +static Word maincode; | |
| 29 | +static Word pc; | |
| 30 | + | |
| 31 | +#define MAXVAR 32 | |
| 32 | +static long varbuffer[MAXVAR]; /* variables in an assignment list; | |
| 33 | + it's long to store negative Word values */ | |
| 34 | +static int nvarbuffer=0; /* number of variables at a list */ | |
| 35 | + | |
| 36 | +static Word localvar[STACKGAP]; /* store local variable names */ | |
| 37 | +static int nlocalvar=0; /* number of local variables */ | |
| 38 | + | |
| 39 | +#define MAXFIELDS FIELDS_PER_FLUSH*2 | |
| 40 | +static Word fields[MAXFIELDS]; /* fieldnames to be flushed */ | |
| 41 | +static int nfields=0; | |
| 42 | +static int ntemp; /* number of temporary var into stack */ | |
| 43 | +static int err; /* flag to indicate error */ | |
| 44 | + | |
| 45 | +/* Internal functions */ | |
| 46 | + | |
| 47 | +static void code_byte (Byte c) | |
| 48 | +{ | |
| 49 | + if (pc>maxcurr-2) /* 1 byte free to code HALT of main code */ | |
| 50 | + { | |
| 51 | + maxcurr += GAPCODE; | |
| 52 | + basepc = (Byte *)realloc(basepc, maxcurr*sizeof(Byte)); | |
| 53 | + if (basepc == NULL) | |
| 54 | + { | |
| 55 | + lua_error ("not enough memory"); | |
| 56 | + err = 1; | |
| 57 | + } | |
| 58 | + } | |
| 59 | + basepc[pc++] = c; | |
| 60 | +} | |
| 61 | + | |
| 62 | +static void code_word (Word n) | |
| 63 | +{ | |
| 64 | + CodeWord code; | |
| 65 | + code.w = n; | |
| 66 | + code_byte(code.m.c1); | |
| 67 | + code_byte(code.m.c2); | |
| 68 | +} | |
| 69 | + | |
| 70 | +static void code_float (float n) | |
| 71 | +{ | |
| 72 | + CodeFloat code; | |
| 73 | + code.f = n; | |
| 74 | + code_byte(code.m.c1); | |
| 75 | + code_byte(code.m.c2); | |
| 76 | + code_byte(code.m.c3); | |
| 77 | + code_byte(code.m.c4); | |
| 78 | +} | |
| 79 | + | |
| 80 | +static void code_word_at (Byte *p, Word n) | |
| 81 | +{ | |
| 82 | + CodeWord code; | |
| 83 | + code.w = n; | |
| 84 | + *p++ = code.m.c1; | |
| 85 | + *p++ = code.m.c2; | |
| 86 | +} | |
| 87 | + | |
| 88 | +static void push_field (Word name) | |
| 89 | +{ | |
| 90 | + if (nfields < STACKGAP-1) | |
| 91 | + fields[nfields++] = name; | |
| 92 | + else | |
| 93 | + { | |
| 94 | + lua_error ("too many fields in a constructor"); | |
| 95 | + err = 1; | |
| 96 | + } | |
| 97 | +} | |
| 98 | + | |
| 99 | +static void flush_record (int n) | |
| 100 | +{ | |
| 101 | + int i; | |
| 102 | + if (n == 0) return; | |
| 103 | + code_byte(STORERECORD); | |
| 104 | + code_byte(n); | |
| 105 | + for (i=0; i<n; i++) | |
| 106 | + code_word(fields[--nfields]); | |
| 107 | + ntemp -= n; | |
| 108 | +} | |
| 109 | + | |
| 110 | +static void flush_list (int m, int n) | |
| 111 | +{ | |
| 112 | + if (n == 0) return; | |
| 113 | + if (m == 0) | |
| 114 | + code_byte(STORELIST0); | |
| 115 | + else | |
| 116 | + { | |
| 117 | + code_byte(STORELIST); | |
| 118 | + code_byte(m); | |
| 119 | + } | |
| 120 | + code_byte(n); | |
| 121 | + ntemp-=n; | |
| 122 | +} | |
| 123 | + | |
| 124 | +static void incr_ntemp (void) | |
| 125 | +{ | |
| 126 | + if (ntemp+nlocalvar+MAXVAR+1 < STACKGAP) | |
| 127 | + ntemp++; | |
| 128 | + else | |
| 129 | + { | |
| 130 | + lua_error ("stack overflow"); | |
| 131 | + err = 1; | |
| 132 | + } | |
| 133 | +} | |
| 134 | + | |
| 135 | +static void add_nlocalvar (int n) | |
| 136 | +{ | |
| 137 | + if (ntemp+nlocalvar+MAXVAR+n < STACKGAP) | |
| 138 | + nlocalvar += n; | |
| 139 | + else | |
| 140 | + { | |
| 141 | + lua_error ("too many local variables or expression too complicate"); | |
| 142 | + err = 1; | |
| 143 | + } | |
| 144 | +} | |
| 145 | + | |
| 146 | +static void incr_nvarbuffer (void) | |
| 147 | +{ | |
| 148 | + if (nvarbuffer < MAXVAR-1) | |
| 149 | + nvarbuffer++; | |
| 150 | + else | |
| 151 | + { | |
| 152 | + lua_error ("variable buffer overflow"); | |
| 153 | + err = 1; | |
| 154 | + } | |
| 155 | +} | |
| 156 | + | |
| 157 | +static void code_number (float f) | |
| 158 | +{ Word i = (Word)f; | |
| 159 | + if (f == (float)i) /* f has an (short) integer value */ | |
| 160 | + { | |
| 161 | + if (i <= 2) code_byte(PUSH0 + i); | |
| 162 | + else if (i <= 255) | |
| 163 | + { | |
| 164 | + code_byte(PUSHBYTE); | |
| 165 | + code_byte(i); | |
| 166 | + } | |
| 167 | + else | |
| 168 | + { | |
| 169 | + code_byte(PUSHWORD); | |
| 170 | + code_word(i); | |
| 171 | + } | |
| 172 | + } | |
| 173 | + else | |
| 174 | + { | |
| 175 | + code_byte(PUSHFLOAT); | |
| 176 | + code_float(f); | |
| 177 | + } | |
| 178 | + incr_ntemp(); | |
| 179 | +} | |
| 180 | + | |
| 181 | +%} | |
| 182 | + | |
| 183 | + | |
| 184 | +%union | |
| 185 | +{ | |
| 186 | + int vInt; | |
| 187 | + long vLong; | |
| 188 | + float vFloat; | |
| 189 | + char *pChar; | |
| 190 | + Word vWord; | |
| 191 | + Byte *pByte; | |
| 192 | +} | |
| 193 | + | |
| 194 | +%start functionlist | |
| 195 | + | |
| 196 | +%token WRONGTOKEN | |
| 197 | +%token NIL | |
| 198 | +%token IF THEN ELSE ELSEIF WHILE DO REPEAT UNTIL END | |
| 199 | +%token RETURN | |
| 200 | +%token LOCAL | |
| 201 | +%token <vFloat> NUMBER | |
| 202 | +%token <vWord> FUNCTION STRING | |
| 203 | +%token <pChar> NAME | |
| 204 | +%token <vInt> DEBUG | |
| 205 | + | |
| 206 | +%type <vWord> PrepJump | |
| 207 | +%type <vInt> expr, exprlist, exprlist1, varlist1, typeconstructor | |
| 208 | +%type <vInt> fieldlist, localdeclist | |
| 209 | +%type <vInt> ffieldlist, ffieldlist1 | |
| 210 | +%type <vInt> lfieldlist, lfieldlist1 | |
| 211 | +%type <vLong> var, objectname | |
| 212 | + | |
| 213 | + | |
| 214 | +%left AND OR | |
| 215 | +%left '=' NE '>' '<' LE GE | |
| 216 | +%left CONC | |
| 217 | +%left '+' '-' | |
| 218 | +%left '*' '/' | |
| 219 | +%left UNARY NOT | |
| 220 | + | |
| 221 | + | |
| 222 | +%% /* beginning of rules section */ | |
| 223 | + | |
| 224 | + | |
| 225 | +functionlist : /* empty */ | |
| 226 | + | functionlist | |
| 227 | + { | |
| 228 | + pc=maincode; basepc=initcode; maxcurr=maxmain; | |
| 229 | + nlocalvar=0; | |
| 230 | + } | |
| 231 | + stat sc | |
| 232 | + { | |
| 233 | + maincode=pc; initcode=basepc; maxmain=maxcurr; | |
| 234 | + } | |
| 235 | + | functionlist function | |
| 236 | + | functionlist setdebug | |
| 237 | + ; | |
| 238 | + | |
| 239 | +function : FUNCTION NAME | |
| 240 | + { | |
| 241 | + if (code == NULL) /* first function */ | |
| 242 | + { | |
| 243 | + code = (Byte *) calloc(GAPCODE, sizeof(Byte)); | |
| 244 | + if (code == NULL) | |
| 245 | + { | |
| 246 | + lua_error("not enough memory"); | |
| 247 | + err = 1; | |
| 248 | + } | |
| 249 | + maxcode = GAPCODE; | |
| 250 | + } | |
| 251 | + pc=0; basepc=code; maxcurr=maxcode; | |
| 252 | + nlocalvar=0; | |
| 253 | + $<vWord>$ = lua_findsymbol($2); | |
| 254 | + } | |
| 255 | + '(' parlist ')' | |
| 256 | + { | |
| 257 | + if (lua_debug) | |
| 258 | + { | |
| 259 | + code_byte(SETFUNCTION); | |
| 260 | + code_word(lua_nfile-1); | |
| 261 | + code_word($<vWord>3); | |
| 262 | + } | |
| 263 | + lua_codeadjust (0); | |
| 264 | + } | |
| 265 | + block | |
| 266 | + END | |
| 267 | + { | |
| 268 | + if (lua_debug) code_byte(RESET); | |
| 269 | + code_byte(RETCODE); code_byte(nlocalvar); | |
| 270 | + s_tag($<vWord>3) = T_FUNCTION; | |
| 271 | + s_bvalue($<vWord>3) = calloc (pc, sizeof(Byte)); | |
| 272 | + if (s_bvalue($<vWord>3) == NULL) | |
| 273 | + { | |
| 274 | + lua_error("not enough memory"); | |
| 275 | + err = 1; | |
| 276 | + } | |
| 277 | + memcpy (s_bvalue($<vWord>3), basepc, pc*sizeof(Byte)); | |
| 278 | + code = basepc; maxcode=maxcurr; | |
| 279 | +#if LISTING | |
| 280 | +PrintCode(code,code+pc); | |
| 281 | +#endif | |
| 282 | + } | |
| 283 | + ; | |
| 284 | + | |
| 285 | +statlist : /* empty */ | |
| 286 | + | statlist stat sc | |
| 287 | + ; | |
| 288 | + | |
| 289 | +stat : { | |
| 290 | + ntemp = 0; | |
| 291 | + if (lua_debug) | |
| 292 | + { | |
| 293 | + code_byte(SETLINE); code_word(lua_linenumber); | |
| 294 | + } | |
| 295 | + } | |
| 296 | + stat1 | |
| 297 | + | |
| 298 | +sc : /* empty */ | ';' ; | |
| 299 | + | |
| 300 | + | |
| 301 | +stat1 : IF expr1 THEN PrepJump block PrepJump elsepart END | |
| 302 | + { | |
| 303 | + { | |
| 304 | + Word elseinit = $6+sizeof(Word)+1; | |
| 305 | + if (pc - elseinit == 0) /* no else */ | |
| 306 | + { | |
| 307 | + pc -= sizeof(Word)+1; | |
| 308 | + elseinit = pc; | |
| 309 | + } | |
| 310 | + else | |
| 311 | + { | |
| 312 | + basepc[$6] = JMP; | |
| 313 | + code_word_at(basepc+$6+1, pc - elseinit); | |
| 314 | + } | |
| 315 | + basepc[$4] = IFFJMP; | |
| 316 | + code_word_at(basepc+$4+1,elseinit-($4+sizeof(Word)+1)); | |
| 317 | + } | |
| 318 | + } | |
| 319 | + | |
| 320 | + | WHILE {$<vWord>$=pc;} expr1 DO PrepJump block PrepJump END | |
| 321 | + | |
| 322 | + { | |
| 323 | + basepc[$5] = IFFJMP; | |
| 324 | + code_word_at(basepc+$5+1, pc - ($5 + sizeof(Word)+1)); | |
| 325 | + | |
| 326 | + basepc[$7] = UPJMP; | |
| 327 | + code_word_at(basepc+$7+1, pc - ($<vWord>2)); | |
| 328 | + } | |
| 329 | + | |
| 330 | + | REPEAT {$<vWord>$=pc;} block UNTIL expr1 PrepJump | |
| 331 | + | |
| 332 | + { | |
| 333 | + basepc[$6] = IFFUPJMP; | |
| 334 | + code_word_at(basepc+$6+1, pc - ($<vWord>2)); | |
| 335 | + } | |
| 336 | + | |
| 337 | + | |
| 338 | + | varlist1 '=' exprlist1 | |
| 339 | + { | |
| 340 | + { | |
| 341 | + int i; | |
| 342 | + if ($3 == 0 || nvarbuffer != ntemp - $1 * 2) | |
| 343 | + lua_codeadjust ($1 * 2 + nvarbuffer); | |
| 344 | + for (i=nvarbuffer-1; i>=0; i--) | |
| 345 | + lua_codestore (i); | |
| 346 | + if ($1 > 1 || ($1 == 1 && varbuffer[0] != 0)) | |
| 347 | + lua_codeadjust (0); | |
| 348 | + } | |
| 349 | + } | |
| 350 | + | functioncall { lua_codeadjust (0); } | |
| 351 | + | typeconstructor { lua_codeadjust (0); } | |
| 352 | + | LOCAL localdeclist decinit { add_nlocalvar($2); lua_codeadjust (0); } | |
| 353 | + ; | |
| 354 | + | |
| 355 | +elsepart : /* empty */ | |
| 356 | + | ELSE block | |
| 357 | + | ELSEIF expr1 THEN PrepJump block PrepJump elsepart | |
| 358 | + { | |
| 359 | + { | |
| 360 | + Word elseinit = $6+sizeof(Word)+1; | |
| 361 | + if (pc - elseinit == 0) /* no else */ | |
| 362 | + { | |
| 363 | + pc -= sizeof(Word)+1; | |
| 364 | + elseinit = pc; | |
| 365 | + } | |
| 366 | + else | |
| 367 | + { | |
| 368 | + basepc[$6] = JMP; | |
| 369 | + code_word_at(basepc+$6+1, pc - elseinit); | |
| 370 | + } | |
| 371 | + basepc[$4] = IFFJMP; | |
| 372 | + code_word_at(basepc+$4+1, elseinit - ($4 + sizeof(Word)+1)); | |
| 373 | + } | |
| 374 | + } | |
| 375 | + ; | |
| 376 | + | |
| 377 | +block : {$<vInt>$ = nlocalvar;} statlist {ntemp = 0;} ret | |
| 378 | + { | |
| 379 | + if (nlocalvar != $<vInt>1) | |
| 380 | + { | |
| 381 | + nlocalvar = $<vInt>1; | |
| 382 | + lua_codeadjust (0); | |
| 383 | + } | |
| 384 | + } | |
| 385 | + ; | |
| 386 | + | |
| 387 | +ret : /* empty */ | |
| 388 | + | { if (lua_debug){code_byte(SETLINE);code_word(lua_linenumber);}} | |
| 389 | + RETURN exprlist sc | |
| 390 | + { | |
| 391 | + if (lua_debug) code_byte(RESET); | |
| 392 | + code_byte(RETCODE); code_byte(nlocalvar); | |
| 393 | + } | |
| 394 | + ; | |
| 395 | + | |
| 396 | +PrepJump : /* empty */ | |
| 397 | + { | |
| 398 | + $$ = pc; | |
| 399 | + code_byte(0); /* open space */ | |
| 400 | + code_word (0); | |
| 401 | + } | |
| 402 | + | |
| 403 | +expr1 : expr { if ($1 == 0) {lua_codeadjust (ntemp+1); incr_ntemp();}} | |
| 404 | + ; | |
| 405 | + | |
| 406 | +expr : '(' expr ')' { $$ = $2; } | |
| 407 | + | expr1 '=' expr1 { code_byte(EQOP); $$ = 1; ntemp--;} | |
| 408 | + | expr1 '<' expr1 { code_byte(LTOP); $$ = 1; ntemp--;} | |
| 409 | + | expr1 '>' expr1 { code_byte(LEOP); code_byte(NOTOP); $$ = 1; ntemp--;} | |
| 410 | + | expr1 NE expr1 { code_byte(EQOP); code_byte(NOTOP); $$ = 1; ntemp--;} | |
| 411 | + | expr1 LE expr1 { code_byte(LEOP); $$ = 1; ntemp--;} | |
| 412 | + | expr1 GE expr1 { code_byte(LTOP); code_byte(NOTOP); $$ = 1; ntemp--;} | |
| 413 | + | expr1 '+' expr1 { code_byte(ADDOP); $$ = 1; ntemp--;} | |
| 414 | + | expr1 '-' expr1 { code_byte(SUBOP); $$ = 1; ntemp--;} | |
| 415 | + | expr1 '*' expr1 { code_byte(MULTOP); $$ = 1; ntemp--;} | |
| 416 | + | expr1 '/' expr1 { code_byte(DIVOP); $$ = 1; ntemp--;} | |
| 417 | + | expr1 CONC expr1 { code_byte(CONCOP); $$ = 1; ntemp--;} | |
| 418 | + | '+' expr1 %prec UNARY { $$ = 1; } | |
| 419 | + | '-' expr1 %prec UNARY { code_byte(MINUSOP); $$ = 1;} | |
| 420 | + | typeconstructor { $$ = $1; } | |
| 421 | + | '@' '(' dimension ')' | |
| 422 | + { | |
| 423 | + code_byte(CREATEARRAY); | |
| 424 | + $$ = 1; | |
| 425 | + } | |
| 426 | + | var { lua_pushvar ($1); $$ = 1;} | |
| 427 | + | NUMBER { code_number($1); $$ = 1; } | |
| 428 | + | STRING | |
| 429 | + { | |
| 430 | + code_byte(PUSHSTRING); | |
| 431 | + code_word($1); | |
| 432 | + $$ = 1; | |
| 433 | + incr_ntemp(); | |
| 434 | + } | |
| 435 | + | NIL {code_byte(PUSHNIL); $$ = 1; incr_ntemp();} | |
| 436 | + | functioncall | |
| 437 | + { | |
| 438 | + $$ = 0; | |
| 439 | + if (lua_debug) | |
| 440 | + { | |
| 441 | + code_byte(SETLINE); code_word(lua_linenumber); | |
| 442 | + } | |
| 443 | + } | |
| 444 | + | NOT expr1 { code_byte(NOTOP); $$ = 1;} | |
| 445 | + | expr1 AND PrepJump {code_byte(POP); ntemp--;} expr1 | |
| 446 | + { | |
| 447 | + basepc[$3] = ONFJMP; | |
| 448 | + code_word_at(basepc+$3+1, pc - ($3 + sizeof(Word)+1)); | |
| 449 | + $$ = 1; | |
| 450 | + } | |
| 451 | + | expr1 OR PrepJump {code_byte(POP); ntemp--;} expr1 | |
| 452 | + { | |
| 453 | + basepc[$3] = ONTJMP; | |
| 454 | + code_word_at(basepc+$3+1, pc - ($3 + sizeof(Word)+1)); | |
| 455 | + $$ = 1; | |
| 456 | + } | |
| 457 | + ; | |
| 458 | + | |
| 459 | +typeconstructor: '@' | |
| 460 | + { | |
| 461 | + code_byte(PUSHBYTE); | |
| 462 | + $<vWord>$ = pc; code_byte(0); | |
| 463 | + incr_ntemp(); | |
| 464 | + code_byte(CREATEARRAY); | |
| 465 | + } | |
| 466 | + objectname fieldlist | |
| 467 | + { | |
| 468 | + basepc[$<vWord>2] = $4; | |
| 469 | + if ($3 < 0) /* there is no function to be called */ | |
| 470 | + { | |
| 471 | + $$ = 1; | |
| 472 | + } | |
| 473 | + else | |
| 474 | + { | |
| 475 | + lua_pushvar ($3+1); | |
| 476 | + code_byte(PUSHMARK); | |
| 477 | + incr_ntemp(); | |
| 478 | + code_byte(PUSHOBJECT); | |
| 479 | + incr_ntemp(); | |
| 480 | + code_byte(CALLFUNC); | |
| 481 | + ntemp -= 4; | |
| 482 | + $$ = 0; | |
| 483 | + if (lua_debug) | |
| 484 | + { | |
| 485 | + code_byte(SETLINE); code_word(lua_linenumber); | |
| 486 | + } | |
| 487 | + } | |
| 488 | + } | |
| 489 | + ; | |
| 490 | + | |
| 491 | +dimension : /* empty */ { code_byte(PUSHNIL); incr_ntemp();} | |
| 492 | + | expr1 | |
| 493 | + ; | |
| 494 | + | |
| 495 | +functioncall : functionvalue {code_byte(PUSHMARK); $<vInt>$ = ntemp; incr_ntemp();} | |
| 496 | + '(' exprlist ')' { code_byte(CALLFUNC); ntemp = $<vInt>2-1;} | |
| 497 | + | |
| 498 | +functionvalue : var {lua_pushvar ($1); } | |
| 499 | + ; | |
| 500 | + | |
| 501 | +exprlist : /* empty */ { $$ = 1; } | |
| 502 | + | exprlist1 { $$ = $1; } | |
| 503 | + ; | |
| 504 | + | |
| 505 | +exprlist1 : expr { $$ = $1; } | |
| 506 | + | exprlist1 ',' {if (!$1){lua_codeadjust (ntemp+1); incr_ntemp();}} | |
| 507 | + expr {$$ = $4;} | |
| 508 | + ; | |
| 509 | + | |
| 510 | +parlist : /* empty */ | |
| 511 | + | parlist1 | |
| 512 | + ; | |
| 513 | + | |
| 514 | +parlist1 : NAME | |
| 515 | + { | |
| 516 | + localvar[nlocalvar]=lua_findsymbol($1); | |
| 517 | + add_nlocalvar(1); | |
| 518 | + } | |
| 519 | + | parlist1 ',' NAME | |
| 520 | + { | |
| 521 | + localvar[nlocalvar]=lua_findsymbol($3); | |
| 522 | + add_nlocalvar(1); | |
| 523 | + } | |
| 524 | + ; | |
| 525 | + | |
| 526 | +objectname : /* empty */ {$$=-1;} | |
| 527 | + | NAME {$$=lua_findsymbol($1);} | |
| 528 | + ; | |
| 529 | + | |
| 530 | +fieldlist : '{' ffieldlist '}' | |
| 531 | + { | |
| 532 | + flush_record($2%FIELDS_PER_FLUSH); | |
| 533 | + $$ = $2; | |
| 534 | + } | |
| 535 | + | '[' lfieldlist ']' | |
| 536 | + { | |
| 537 | + flush_list($2/FIELDS_PER_FLUSH, $2%FIELDS_PER_FLUSH); | |
| 538 | + $$ = $2; | |
| 539 | + } | |
| 540 | + ; | |
| 541 | + | |
| 542 | +ffieldlist : /* empty */ { $$ = 0; } | |
| 543 | + | ffieldlist1 { $$ = $1; } | |
| 544 | + ; | |
| 545 | + | |
| 546 | +ffieldlist1 : ffield {$$=1;} | |
| 547 | + | ffieldlist1 ',' ffield | |
| 548 | + { | |
| 549 | + $$=$1+1; | |
| 550 | + if ($$%FIELDS_PER_FLUSH == 0) flush_record(FIELDS_PER_FLUSH); | |
| 551 | + } | |
| 552 | + ; | |
| 553 | + | |
| 554 | +ffield : NAME {$<vWord>$ = lua_findconstant($1);} '=' expr1 | |
| 555 | + { | |
| 556 | + push_field($<vWord>2); | |
| 557 | + } | |
| 558 | + ; | |
| 559 | + | |
| 560 | +lfieldlist : /* empty */ { $$ = 0; } | |
| 561 | + | lfieldlist1 { $$ = $1; } | |
| 562 | + ; | |
| 563 | + | |
| 564 | +lfieldlist1 : expr1 {$$=1;} | |
| 565 | + | lfieldlist1 ',' expr1 | |
| 566 | + { | |
| 567 | + $$=$1+1; | |
| 568 | + if ($$%FIELDS_PER_FLUSH == 0) | |
| 569 | + flush_list($$/FIELDS_PER_FLUSH - 1, FIELDS_PER_FLUSH); | |
| 570 | + } | |
| 571 | + ; | |
| 572 | + | |
| 573 | +varlist1 : var | |
| 574 | + { | |
| 575 | + nvarbuffer = 0; | |
| 576 | + varbuffer[nvarbuffer] = $1; incr_nvarbuffer(); | |
| 577 | + $$ = ($1 == 0) ? 1 : 0; | |
| 578 | + } | |
| 579 | + | varlist1 ',' var | |
| 580 | + { | |
| 581 | + varbuffer[nvarbuffer] = $3; incr_nvarbuffer(); | |
| 582 | + $$ = ($3 == 0) ? $1 + 1 : $1; | |
| 583 | + } | |
| 584 | + ; | |
| 585 | + | |
| 586 | +var : NAME | |
| 587 | + { | |
| 588 | + Word s = lua_findsymbol($1); | |
| 589 | + int local = lua_localname (s); | |
| 590 | + if (local == -1) /* global var */ | |
| 591 | + $$ = s + 1; /* return positive value */ | |
| 592 | + else | |
| 593 | + $$ = -(local+1); /* return negative value */ | |
| 594 | + } | |
| 595 | + | |
| 596 | + | var {lua_pushvar ($1);} '[' expr1 ']' | |
| 597 | + { | |
| 598 | + $$ = 0; /* indexed variable */ | |
| 599 | + } | |
| 600 | + | var {lua_pushvar ($1);} '.' NAME | |
| 601 | + { | |
| 602 | + code_byte(PUSHSTRING); | |
| 603 | + code_word(lua_findconstant($4)); incr_ntemp(); | |
| 604 | + $$ = 0; /* indexed variable */ | |
| 605 | + } | |
| 606 | + ; | |
| 607 | + | |
| 608 | +localdeclist : NAME {localvar[nlocalvar]=lua_findsymbol($1); $$ = 1;} | |
| 609 | + | localdeclist ',' NAME | |
| 610 | + { | |
| 611 | + localvar[nlocalvar+$1]=lua_findsymbol($3); | |
| 612 | + $$ = $1+1; | |
| 613 | + } | |
| 614 | + ; | |
| 615 | + | |
| 616 | +decinit : /* empty */ | |
| 617 | + | '=' exprlist1 | |
| 618 | + ; | |
| 619 | + | |
| 620 | +setdebug : DEBUG {lua_debug = $1;} | |
| 621 | + | |
| 622 | +%% | |
| 623 | + | |
| 624 | +/* | |
| 625 | +** Search a local name and if find return its index. If do not find return -1 | |
| 626 | +*/ | |
| 627 | +static int lua_localname (Word n) | |
| 628 | +{ | |
| 629 | + int i; | |
| 630 | + for (i=nlocalvar-1; i >= 0; i--) | |
| 631 | + if (n == localvar[i]) return i; /* local var */ | |
| 632 | + return -1; /* global var */ | |
| 633 | +} | |
| 634 | + | |
| 635 | +/* | |
| 636 | +** Push a variable given a number. If number is positive, push global variable | |
| 637 | +** indexed by (number -1). If negative, push local indexed by ABS(number)-1. | |
| 638 | +** Otherwise, if zero, push indexed variable (record). | |
| 639 | +*/ | |
| 640 | +static void lua_pushvar (long number) | |
| 641 | +{ | |
| 642 | + if (number > 0) /* global var */ | |
| 643 | + { | |
| 644 | + code_byte(PUSHGLOBAL); | |
| 645 | + code_word(number-1); | |
| 646 | + incr_ntemp(); | |
| 647 | + } | |
| 648 | + else if (number < 0) /* local var */ | |
| 649 | + { | |
| 650 | + number = (-number) - 1; | |
| 651 | + if (number < 10) code_byte(PUSHLOCAL0 + number); | |
| 652 | + else | |
| 653 | + { | |
| 654 | + code_byte(PUSHLOCAL); | |
| 655 | + code_byte(number); | |
| 656 | + } | |
| 657 | + incr_ntemp(); | |
| 658 | + } | |
| 659 | + else | |
| 660 | + { | |
| 661 | + code_byte(PUSHINDEXED); | |
| 662 | + ntemp--; | |
| 663 | + } | |
| 664 | +} | |
| 665 | + | |
| 666 | +static void lua_codeadjust (int n) | |
| 667 | +{ | |
| 668 | + code_byte(ADJUST); | |
| 669 | + code_byte(n + nlocalvar); | |
| 670 | +} | |
| 671 | + | |
| 672 | +static void lua_codestore (int i) | |
| 673 | +{ | |
| 674 | + if (varbuffer[i] > 0) /* global var */ | |
| 675 | + { | |
| 676 | + code_byte(STOREGLOBAL); | |
| 677 | + code_word(varbuffer[i]-1); | |
| 678 | + } | |
| 679 | + else if (varbuffer[i] < 0) /* local var */ | |
| 680 | + { | |
| 681 | + int number = (-varbuffer[i]) - 1; | |
| 682 | + if (number < 10) code_byte(STORELOCAL0 + number); | |
| 683 | + else | |
| 684 | + { | |
| 685 | + code_byte(STORELOCAL); | |
| 686 | + code_byte(number); | |
| 687 | + } | |
| 688 | + } | |
| 689 | + else /* indexed var */ | |
| 690 | + { | |
| 691 | + int j; | |
| 692 | + int upper=0; /* number of indexed variables upper */ | |
| 693 | + int param; /* number of itens until indexed expression */ | |
| 694 | + for (j=i+1; j <nvarbuffer; j++) | |
| 695 | + if (varbuffer[j] == 0) upper++; | |
| 696 | + param = upper*2 + i; | |
| 697 | + if (param == 0) | |
| 698 | + code_byte(STOREINDEXED0); | |
| 699 | + else | |
| 700 | + { | |
| 701 | + code_byte(STOREINDEXED); | |
| 702 | + code_byte(param); | |
| 703 | + } | |
| 704 | + } | |
| 705 | +} | |
| 706 | + | |
| 707 | +void yyerror (char *s) | |
| 708 | +{ | |
| 709 | + static char msg[256]; | |
| 710 | + sprintf (msg,"%s near \"%s\" at line %d in file \"%s\"", | |
| 711 | + s, lua_lasttext (), lua_linenumber, lua_filename()); | |
| 712 | + lua_error (msg); | |
| 713 | + err = 1; | |
| 714 | +} | |
| 715 | + | |
| 716 | +int yywrap (void) | |
| 717 | +{ | |
| 718 | + return 1; | |
| 719 | +} | |
| 720 | + | |
| 721 | + | |
| 722 | +/* | |
| 723 | +** Parse LUA code and execute global statement. | |
| 724 | +** Return 0 on success or 1 on error. | |
| 725 | +*/ | |
| 726 | +int lua_parse (void) | |
| 727 | +{ | |
| 728 | + Byte *init = initcode = (Byte *) calloc(GAPCODE, sizeof(Byte)); | |
| 729 | + maincode = 0; | |
| 730 | + maxmain = GAPCODE; | |
| 731 | + if (init == NULL) | |
| 732 | + { | |
| 733 | + lua_error("not enough memory"); | |
| 734 | + return 1; | |
| 735 | + } | |
| 736 | + err = 0; | |
| 737 | + if (yyparse () || (err==1)) return 1; | |
| 738 | + initcode[maincode++] = HALT; | |
| 739 | + init = initcode; | |
| 740 | +#if LISTING | |
| 741 | + PrintCode(init,init+maincode); | |
| 742 | +#endif | |
| 743 | + if (lua_execute (init)) return 1; | |
| 744 | + free(init); | |
| 745 | + return 0; | |
| 746 | +} | |
| 747 | + | |
| 748 | + | |
| 749 | +#if LISTING | |
| 750 | + | |
| 751 | +static void PrintCode (Byte *code, Byte *end) | |
| 752 | +{ | |
| 753 | + Byte *p = code; | |
| 754 | + printf ("\n\nCODE\n"); | |
| 755 | + while (p != end) | |
| 756 | + { | |
| 757 | + switch ((OpCode)*p) | |
| 758 | + { | |
| 759 | + case PUSHNIL: printf ("%d PUSHNIL\n", (p++)-code); break; | |
| 760 | + case PUSH0: case PUSH1: case PUSH2: | |
| 761 | + printf ("%d PUSH%c\n", p-code, *p-PUSH0+'0'); | |
| 762 | + p++; | |
| 763 | + break; | |
| 764 | + case PUSHBYTE: | |
| 765 | + printf ("%d PUSHBYTE %d\n", p-code, *(++p)); | |
| 766 | + p++; | |
| 767 | + break; | |
| 768 | + case PUSHWORD: | |
| 769 | + { | |
| 770 | + CodeWord c; | |
| 771 | + int n = p-code; | |
| 772 | + p++; | |
| 773 | + get_word(c,p); | |
| 774 | + printf ("%d PUSHWORD %d\n", n, c.w); | |
| 775 | + } | |
| 776 | + break; | |
| 777 | + case PUSHFLOAT: | |
| 778 | + { | |
| 779 | + CodeFloat c; | |
| 780 | + int n = p-code; | |
| 781 | + p++; | |
| 782 | + get_float(c,p); | |
| 783 | + printf ("%d PUSHFLOAT %f\n", n, c.f); | |
| 784 | + } | |
| 785 | + break; | |
| 786 | + case PUSHSTRING: | |
| 787 | + { | |
| 788 | + CodeWord c; | |
| 789 | + int n = p-code; | |
| 790 | + p++; | |
| 791 | + get_word(c,p); | |
| 792 | + printf ("%d PUSHSTRING %d\n", n, c.w); | |
| 793 | + } | |
| 794 | + break; | |
| 795 | + case PUSHLOCAL0: case PUSHLOCAL1: case PUSHLOCAL2: case PUSHLOCAL3: | |
| 796 | + case PUSHLOCAL4: case PUSHLOCAL5: case PUSHLOCAL6: case PUSHLOCAL7: | |
| 797 | + case PUSHLOCAL8: case PUSHLOCAL9: | |
| 798 | + printf ("%d PUSHLOCAL%c\n", p-code, *p-PUSHLOCAL0+'0'); | |
| 799 | + p++; | |
| 800 | + break; | |
| 801 | + case PUSHLOCAL: printf ("%d PUSHLOCAL %d\n", p-code, *(++p)); | |
| 802 | + p++; | |
| 803 | + break; | |
| 804 | + case PUSHGLOBAL: | |
| 805 | + { | |
| 806 | + CodeWord c; | |
| 807 | + int n = p-code; | |
| 808 | + p++; | |
| 809 | + get_word(c,p); | |
| 810 | + printf ("%d PUSHGLOBAL %d\n", n, c.w); | |
| 811 | + } | |
| 812 | + break; | |
| 813 | + case PUSHINDEXED: printf ("%d PUSHINDEXED\n", (p++)-code); break; | |
| 814 | + case PUSHMARK: printf ("%d PUSHMARK\n", (p++)-code); break; | |
| 815 | + case PUSHOBJECT: printf ("%d PUSHOBJECT\n", (p++)-code); break; | |
| 816 | + case STORELOCAL0: case STORELOCAL1: case STORELOCAL2: case STORELOCAL3: | |
| 817 | + case STORELOCAL4: case STORELOCAL5: case STORELOCAL6: case STORELOCAL7: | |
| 818 | + case STORELOCAL8: case STORELOCAL9: | |
| 819 | + printf ("%d STORELOCAL%c\n", p-code, *p-STORELOCAL0+'0'); | |
| 820 | + p++; | |
| 821 | + break; | |
| 822 | + case STORELOCAL: | |
| 823 | + printf ("%d STORELOCAL %d\n", p-code, *(++p)); | |
| 824 | + p++; | |
| 825 | + break; | |
| 826 | + case STOREGLOBAL: | |
| 827 | + { | |
| 828 | + CodeWord c; | |
| 829 | + int n = p-code; | |
| 830 | + p++; | |
| 831 | + get_word(c,p); | |
| 832 | + printf ("%d STOREGLOBAL %d\n", n, c.w); | |
| 833 | + } | |
| 834 | + break; | |
| 835 | + case STOREINDEXED0: printf ("%d STOREINDEXED0\n", (p++)-code); break; | |
| 836 | + case STOREINDEXED: printf ("%d STOREINDEXED %d\n", p-code, *(++p)); | |
| 837 | + p++; | |
| 838 | + break; | |
| 839 | + case STORELIST0: | |
| 840 | + printf("%d STORELIST0 %d\n", p-code, *(++p)); | |
| 841 | + p++; | |
| 842 | + break; | |
| 843 | + case STORELIST: | |
| 844 | + printf("%d STORELIST %d %d\n", p-code, *(p+1), *(p+2)); | |
| 845 | + p+=3; | |
| 846 | + break; | |
| 847 | + case STORERECORD: | |
| 848 | + printf("%d STORERECORD %d\n", p-code, *(++p)); | |
| 849 | + p += *p*sizeof(Word) + 1; | |
| 850 | + break; | |
| 851 | + case ADJUST: | |
| 852 | + printf ("%d ADJUST %d\n", p-code, *(++p)); | |
| 853 | + p++; | |
| 854 | + break; | |
| 855 | + case CREATEARRAY: printf ("%d CREATEARRAY\n", (p++)-code); break; | |
| 856 | + case EQOP: printf ("%d EQOP\n", (p++)-code); break; | |
| 857 | + case LTOP: printf ("%d LTOP\n", (p++)-code); break; | |
| 858 | + case LEOP: printf ("%d LEOP\n", (p++)-code); break; | |
| 859 | + case ADDOP: printf ("%d ADDOP\n", (p++)-code); break; | |
| 860 | + case SUBOP: printf ("%d SUBOP\n", (p++)-code); break; | |
| 861 | + case MULTOP: printf ("%d MULTOP\n", (p++)-code); break; | |
| 862 | + case DIVOP: printf ("%d DIVOP\n", (p++)-code); break; | |
| 863 | + case CONCOP: printf ("%d CONCOP\n", (p++)-code); break; | |
| 864 | + case MINUSOP: printf ("%d MINUSOP\n", (p++)-code); break; | |
| 865 | + case NOTOP: printf ("%d NOTOP\n", (p++)-code); break; | |
| 866 | + case ONTJMP: | |
| 867 | + { | |
| 868 | + CodeWord c; | |
| 869 | + int n = p-code; | |
| 870 | + p++; | |
| 871 | + get_word(c,p); | |
| 872 | + printf ("%d ONTJMP %d\n", n, c.w); | |
| 873 | + } | |
| 874 | + break; | |
| 875 | + case ONFJMP: | |
| 876 | + { | |
| 877 | + CodeWord c; | |
| 878 | + int n = p-code; | |
| 879 | + p++; | |
| 880 | + get_word(c,p); | |
| 881 | + printf ("%d ONFJMP %d\n", n, c.w); | |
| 882 | + } | |
| 883 | + break; | |
| 884 | + case JMP: | |
| 885 | + { | |
| 886 | + CodeWord c; | |
| 887 | + int n = p-code; | |
| 888 | + p++; | |
| 889 | + get_word(c,p); | |
| 890 | + printf ("%d JMP %d\n", n, c.w); | |
| 891 | + } | |
| 892 | + break; | |
| 893 | + case UPJMP: | |
| 894 | + { | |
| 895 | + CodeWord c; | |
| 896 | + int n = p-code; | |
| 897 | + p++; | |
| 898 | + get_word(c,p); | |
| 899 | + printf ("%d UPJMP %d\n", n, c.w); | |
| 900 | + } | |
| 901 | + break; | |
| 902 | + case IFFJMP: | |
| 903 | + { | |
| 904 | + CodeWord c; | |
| 905 | + int n = p-code; | |
| 906 | + p++; | |
| 907 | + get_word(c,p); | |
| 908 | + printf ("%d IFFJMP %d\n", n, c.w); | |
| 909 | + } | |
| 910 | + break; | |
| 911 | + case IFFUPJMP: | |
| 912 | + { | |
| 913 | + CodeWord c; | |
| 914 | + int n = p-code; | |
| 915 | + p++; | |
| 916 | + get_word(c,p); | |
| 917 | + printf ("%d IFFUPJMP %d\n", n, c.w); | |
| 918 | + } | |
| 919 | + break; | |
| 920 | + case POP: printf ("%d POP\n", (p++)-code); break; | |
| 921 | + case CALLFUNC: printf ("%d CALLFUNC\n", (p++)-code); break; | |
| 922 | + case RETCODE: | |
| 923 | + printf ("%d RETCODE %d\n", p-code, *(++p)); | |
| 924 | + p++; | |
| 925 | + break; | |
| 926 | + case HALT: printf ("%d HALT\n", (p++)-code); break; | |
| 927 | + case SETFUNCTION: | |
| 928 | + { | |
| 929 | + CodeWord c1, c2; | |
| 930 | + int n = p-code; | |
| 931 | + p++; | |
| 932 | + get_word(c1,p); | |
| 933 | + get_word(c2,p); | |
| 934 | + printf ("%d SETFUNCTION %d %d\n", n, c1.w, c2.w); | |
| 935 | + } | |
| 936 | + break; | |
| 937 | + case SETLINE: | |
| 938 | + { | |
| 939 | + CodeWord c; | |
| 940 | + int n = p-code; | |
| 941 | + p++; | |
| 942 | + get_word(c,p); | |
| 943 | + printf ("%d SETLINE %d\n", n, c.w); | |
| 944 | + } | |
| 945 | + break; | |
| 946 | + | |
| 947 | + case RESET: printf ("%d RESET\n", (p++)-code); break; | |
| 948 | + default: printf ("%d Cannot happen: code %d\n", (p++)-code, *(p-1)); break; | |
| 949 | + } | |
| 950 | + } | |
| 951 | +} | |
| 952 | +#endif | |
| 953 | + | |