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 | |||