History

Lua 1.1

Lua Team committed 32 years ago

Commit 6a0a9ef1 parent 8fa4b5556 files · +6975 −3402Browse files

Showing the changes to src (16 of 56 files). Show all

Unified · Split

16 files
  1. src/Makefile +24 −0
  2. src/hash.c +347 −0
  3. src/hash.h +32 −0
  4. src/inout.c +177 −0
  5. src/inout.h +21 −0
  6. src/lex.c +238 −0
  7. src/opcode.c +1021 −0
  8. src/opcode.h +164 −0
  9. src/table.c +337 −0
  10. src/table.h +42 −0
  11. src/y.tab.c +1811 −0
  12. src/y.tab.h +37 −0
  13. src/yacc/Makefile +27 −0
  14. src/yacc/exscript +3 −0
  15. src/yacc/lua.lex +85 −0
  16. src/yacc/lua.stx +953 −0
src/Makefile+24−0
@@ -0,0 +1,24 @@
1# makefile for lua
2
3LIB= $(LUA)/lib
4INC= $(LUA)/include
5
6CC= gcc
7CFLAGS= -g -Wall -O2 -I$(INC) $(DEFS)
8DEFS= -DMAXCODE=64000 -DMAXCONSTANT=1024 -DMAXSYMBOL=1024 -DMAXARRAY=1024
9
10OBJS= hash.o inout.o lex.o opcode.o table.o y.tab.o
11SLIB= $(LIB)/liblua.a
12DLIB= $(LIB)/liblua.so.1.1
13
14libs: $(SLIB) $(DLIB)
15
16$(SLIB): $(OBJS)
17 ar ruvl $@ $(OBJS)
18 ranlib $(SLIB)
19
20$(DLIB): $(OBJS)
21 ld -o $@ $(OBJS)
22
23clean:
24 rm -f $(OBJS) $(SLIB) $(DLIB)
src/hash.c+347−0
@@ -0,0 +1,347 @@
1/*
2** hash.c
3** hash manager for lua
4** Luiz Henrique de Figueiredo - 17 Aug 90
5*/
6
7char *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
38typedef struct ArrayList
39{
40 Hash *array;
41 struct ArrayList *next;
42} ArrayList;
43
44static ArrayList *listhead = NULL;
45
46static 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
68static 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
94static 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*/
107static 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*/
129static 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*/
142void 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*/
164void 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*/
193Hash *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*/
223Object *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*/
254static 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}
286void 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}
src/hash.h+32−0
@@ -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
11typedef struct node
12{
13 Object ref;
14 Object val;
15 struct node *next;
16} Node;
17
18typedef struct Hash
19{
20 char mark;
21 unsigned int nhash;
22 Node **list;
23} Hash;
24
25
26Hash *lua_createarray (int nhash);
27void lua_hashmark (Hash *h);
28void lua_hashcollector (void);
29Object *lua_hashdefine (Hash *t, Object *ref);
30void lua_next (void);
31
32#endif
src/inout.c+177−0
@@ -0,0 +1,177 @@
1/*
2** inout.c
3** Provide function to realise the input/output function and debugger
4** facilities.
5*/
6
7char *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 */
18int lua_linenumber;
19int lua_debug;
20int lua_debugline;
21
22/* Internal variables */
23#ifndef MAXFUNCSTACK
24#define MAXFUNCSTACK 32
25#endif
26static struct { int file; int function; } funcstack[MAXFUNCSTACK];
27static int nfuncstack=0;
28
29static FILE *fp;
30static char *st;
31static void (*usererror) (char *s);
32
33/*
34** Function to set user function to handle errors.
35*/
36void 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*/
44static 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*/
53static 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*/
63int 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*/
76void 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*/
89int 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*/
105void 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*/
114void 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*/
124int 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*/
141void lua_popfunction (void)
142{
143 nfuncstack--;
144}
145
146/*
147** Report bug building a message and sending it to lua_error function.
148*/
149void 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
src/inout.h+21−0
@@ -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
9extern int lua_linenumber;
10extern int lua_debug;
11extern int lua_debugline;
12
13int lua_openfile (char *fn);
14void lua_closefile (void);
15int lua_openstring (char *s);
16void lua_closestring (void);
17int lua_pushfunction (int file, int function);
18void lua_popfunction (void);
19void lua_reportbug (char *s);
20
21#endif
src/lex.c+238−0
@@ -0,0 +1,238 @@
1char *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
33static int current;
34static char yytext[256];
35static char *yytextLast;
36
37static Input input;
38
39void lua_setinput (Input fn)
40{
41 current = ' ';
42 input = fn;
43}
44
45char *lua_lasttext (void)
46{
47 *yytextLast = 0;
48 return yytext;
49}
50
51
52static 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
77int 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
96int 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();
218fraction: 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
src/opcode.c+1021−0
@@ -0,0 +1,1021 @@
1/*
2** opcode.c
3** TecCGraf - PUC-Rio
4*/
5
6char *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 */
13extern 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
29static Object stack[MAXSTACK] = {{T_MARK, {NULL}}};
30static 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*/
37static 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*/
53char *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*/
69static 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*/
91static 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*/
118static 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*/
141int 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*/
608void 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*/
619int 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*/
631int 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*/
642int 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*/
660Object *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*/
669real 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*/
679char *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*/
689char *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*/
699lua_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*/
709void *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*/
720Object *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*/
738Object *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*/
755Object *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*/
765Object *lua_pop (void)
766{
767 if (top <= base) return NULL;
768 top--;
769 return top;
770}
771
772/*
773** Push a nil object
774*/
775int 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*/
789int 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*/
803int 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*/
818int 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*/
832int 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*/
846int 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*/
861int 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*/
873int 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*/
894int 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*/
915int 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*/
923int 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*/
931int 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*/
939int 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*/
947int 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*/
955int lua_isuserdata (Object *object)
956{
957 return (object != NULL && tag(object) == T_USERDATA);
958}
959
960/*
961** Internal function: return an object type.
962*/
963void 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*/
972void 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*/
981void 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*/
1000void 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*/
1012void 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
src/opcode.h+164−0
@@ -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
19typedef unsigned char Byte;
20
21typedef unsigned short Word;
22
23typedef union
24{
25 struct {char c1; char c2;} m;
26 Word w;
27} CodeWord;
28
29typedef union
30{
31 struct {char c1; char c2; char c3; char c4;} m;
32 float f;
33} CodeFloat;
34
35typedef 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
86typedef 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
98typedef void (*Cfunction) (void);
99typedef int (*Input) (void);
100
101typedef union
102{
103 Cfunction f;
104 real n;
105 char *s;
106 Byte *b;
107 struct Hash *a;
108 void *u;
109} Value;
110
111typedef struct Object
112{
113 Type tag;
114 Value value;
115} Object;
116
117typedef 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 */
150int lua_execute (Byte *pc);
151void lua_markstack (void);
152char *lua_strdup (char *l);
153
154void lua_setinput (Input fn); /* from "lex.c" module */
155char *lua_lasttext (void); /* from "lex.c" module */
156int lua_parse (void); /* from "lua.stx" module */
157void lua_type (void);
158void lua_obj2number (void);
159void lua_print (void);
160void lua_internaldofile (void);
161void lua_internaldostring (void);
162void lua_travstack (void (*fn)(Object *));
163
164#endif
src/table.c+337−0
@@ -0,0 +1,337 @@
1/*
2** table.c
3** Module to control static tables
4*/
5
6char *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
24static 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 };
33Symbol *lua_table=tablebuffer;
34Word lua_ntable=7;
35
36struct List
37{
38 Symbol *s;
39 struct List *next;
40};
41
42static struct List o6={ tablebuffer+6, 0};
43static struct List o5={ tablebuffer+5, &o6 };
44static struct List o4={ tablebuffer+4, &o5 };
45static struct List o3={ tablebuffer+3, &o4 };
46static struct List o2={ tablebuffer+2, &o3 };
47static struct List o1={ tablebuffer+1, &o2 };
48static struct List o0={ tablebuffer+0, &o1 };
49static struct List *searchlist=&o0;
50
51#ifndef MAXCONSTANT
52#define MAXCONSTANT 256
53#endif
54/* pre-defined constants need garbage collection extra byte */
55static char tm[] = " mark";
56static char ti[] = " nil";
57static char tn[] = " number";
58static char ts[] = " string";
59static char tt[] = " table";
60static char tf[] = " function";
61static char tc[] = " cfunction";
62static char tu[] = " userdata";
63static char *constantbuffer[MAXCONSTANT] = {tm+1, ti+1,
64 tn+1, ts+1,
65 tt+1, tf+1,
66 tc+1, tu+1
67 };
68char **lua_constant = constantbuffer;
69Word lua_nconstant=T_USERDATA+1;
70
71#ifndef MAXSTRING
72#define MAXSTRING 512
73#endif
74static char *stringbuffer[MAXSTRING];
75char **lua_string = stringbuffer;
76Word lua_nstring=0;
77
78#define MAXFILE 20
79char *lua_file[MAXFILE];
80int lua_nfile;
81
82
83#define markstring(s) (*((s)-1))
84
85
86/* Variables to controll garbage collection */
87Word lua_block=10; /* to check when garbage collector will be called */
88Word 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*/
96int 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*/
142int 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*/
165void 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*/
176void 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*/
189void 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*/
207void 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*/
228char *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*/
259int 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*/
277int lua_delfile (void)
278{
279 lua_nfile--;
280 return 1;
281}
282
283/*
284** Return the last file name set.
285*/
286char *lua_filename (void)
287{
288 return lua_file[lua_nfile-1];
289}
290
291/*
292** Internal function: return next global variable
293*/
294void 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}
src/table.h+42−0
@@ -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
10extern Symbol *lua_table;
11extern Word lua_ntable;
12
13extern char **lua_constant;
14extern Word lua_nconstant;
15
16extern char **lua_string;
17extern Word lua_nstring;
18
19extern Hash **lua_array;
20extern Word lua_narray;
21
22extern char *lua_file[];
23extern int lua_nfile;
24
25extern Word lua_block;
26extern Word lua_nentity;
27
28
29
30int lua_findsymbol (char *s);
31int lua_findconstant (char *s);
32void lua_travsymbol (void (*fn)(Object *));
33void lua_markobject (Object *o);
34void lua_pack (void);
35void lua_stringcollector (void);
36char *lua_createstring (char *s);
37int lua_addfile (char *fn);
38int lua_delfile (void);
39char *lua_filename (void);
40void lua_nextvar (void);
41
42#endif
src/y.tab.c+1811−0
@@ -0,0 +1,1811 @@
1
2# line 2 "lua.stx"
3
4char *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
23static Word maxcode;
24static Word maxmain;
25static Word maxcurr ;
26static Byte *code = NULL;
27static Byte *initcode;
28static Byte *basepc;
29static Word maincode;
30static Word pc;
31
32#define MAXVAR 32
33static long varbuffer[MAXVAR]; /* variables in an assignment list;
34 it's long to store negative Word values */
35static int nvarbuffer=0; /* number of variables at a list */
36
37static Word localvar[STACKGAP]; /* store local variable names */
38static int nlocalvar=0; /* number of local variables */
39
40#define MAXFIELDS FIELDS_PER_FLUSH*2
41static Word fields[MAXFIELDS]; /* fieldnames to be flushed */
42static int nfields=0;
43static int ntemp; /* number of temporary var into stack */
44static int err; /* flag to indicate error */
45
46/* Internal functions */
47
48static 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
63static 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
71static 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
81static 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
89static 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
100static 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
111static 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
125static 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
136static 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
147static 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
158static 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"
184typedef 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
221extern int yychar;
222extern int yyerrflag;
223#ifndef YYMAXDEPTH
224#define YYMAXDEPTH 150
225#endif
226YYSTYPE 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*/
235static 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*/
248static 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
274static void lua_codeadjust (int n)
275{
276 code_byte(ADJUST);
277 code_byte(n + nlocalvar);
278}
279
280static 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
315void 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
324int 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*/
334int 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
359static 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
562int 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
623int 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 };
662int 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 };
682int 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 };
689int 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 };
702int 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 };
715int 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 };
735int 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 };
755typedef 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
762yytoktype 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
800char * 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*/
940int 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*/
950static YYSTYPE *yyv; /* value stack */
951static int *yys; /* state stack */
952
953static YYSTYPE *yypv; /* top of value stack */
954static int *yyps; /* top of state stack */
955
956static int yystate; /* current state */
957static int yytmp; /* extra var (lasts between blocks) */
958
959int yynerrs; /* number of errors */
960
961int yyerrflag; /* error recovery flag */
962int yychar; /* current input token number */
963
964
965/*
966** yyparse - return 0 if worked, 1 if syntax error not recovered from
967*/
968int
969yyparse()
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
1347case 2:
1348# line 227 "lua.stx"
1349{
1350 pc=maincode; basepc=initcode; maxcurr=maxmain;
1351 nlocalvar=0;
1352 } break;
1353case 3:
1354# line 232 "lua.stx"
1355{
1356 maincode=pc; initcode=basepc; maxmain=maxcurr;
1357 } break;
1358case 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;
1375case 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;
1386case 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
1401PrintCode(code,code+pc);
1402#endif
1403 } break;
1404case 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;
1413case 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;
1432case 16:
1433# line 320 "lua.stx"
1434{yyval.vWord=pc;} break;
1435case 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;
1444case 18:
1445# line 330 "lua.stx"
1446{yyval.vWord=pc;} break;
1447case 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;
1453case 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;
1466case 21:
1467# line 350 "lua.stx"
1468{ lua_codeadjust (0); } break;
1469case 22:
1470# line 351 "lua.stx"
1471{ lua_codeadjust (0); } break;
1472case 23:
1473# line 352 "lua.stx"
1474{ add_nlocalvar(yypvt[-1].vInt); lua_codeadjust (0); } break;
1475case 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;
1494case 27:
1495# line 377 "lua.stx"
1496{yyval.vInt = nlocalvar;} break;
1497case 28:
1498# line 377 "lua.stx"
1499{ntemp = 0;} break;
1500case 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;
1509case 31:
1510# line 388 "lua.stx"
1511{ if (lua_debug){code_byte(SETLINE);code_word(lua_linenumber);}} break;
1512case 32:
1513# line 390 "lua.stx"
1514{
1515 if (lua_debug) code_byte(RESET);
1516 code_byte(RETCODE); code_byte(nlocalvar);
1517 } break;
1518case 33:
1519# line 397 "lua.stx"
1520{
1521 yyval.vWord = pc;
1522 code_byte(0); /* open space */
1523 code_word (0);
1524 } break;
1525case 34:
1526# line 403 "lua.stx"
1527{ if (yypvt[-0].vInt == 0) {lua_codeadjust (ntemp+1); incr_ntemp();}} break;
1528case 35:
1529# line 406 "lua.stx"
1530{ yyval.vInt = yypvt[-1].vInt; } break;
1531case 36:
1532# line 407 "lua.stx"
1533{ code_byte(EQOP); yyval.vInt = 1; ntemp--;} break;
1534case 37:
1535# line 408 "lua.stx"
1536{ code_byte(LTOP); yyval.vInt = 1; ntemp--;} break;
1537case 38:
1538# line 409 "lua.stx"
1539{ code_byte(LEOP); code_byte(NOTOP); yyval.vInt = 1; ntemp--;} break;
1540case 39:
1541# line 410 "lua.stx"
1542{ code_byte(EQOP); code_byte(NOTOP); yyval.vInt = 1; ntemp--;} break;
1543case 40:
1544# line 411 "lua.stx"
1545{ code_byte(LEOP); yyval.vInt = 1; ntemp--;} break;
1546case 41:
1547# line 412 "lua.stx"
1548{ code_byte(LTOP); code_byte(NOTOP); yyval.vInt = 1; ntemp--;} break;
1549case 42:
1550# line 413 "lua.stx"
1551{ code_byte(ADDOP); yyval.vInt = 1; ntemp--;} break;
1552case 43:
1553# line 414 "lua.stx"
1554{ code_byte(SUBOP); yyval.vInt = 1; ntemp--;} break;
1555case 44:
1556# line 415 "lua.stx"
1557{ code_byte(MULTOP); yyval.vInt = 1; ntemp--;} break;
1558case 45:
1559# line 416 "lua.stx"
1560{ code_byte(DIVOP); yyval.vInt = 1; ntemp--;} break;
1561case 46:
1562# line 417 "lua.stx"
1563{ code_byte(CONCOP); yyval.vInt = 1; ntemp--;} break;
1564case 47:
1565# line 418 "lua.stx"
1566{ yyval.vInt = 1; } break;
1567case 48:
1568# line 419 "lua.stx"
1569{ code_byte(MINUSOP); yyval.vInt = 1;} break;
1570case 49:
1571# line 420 "lua.stx"
1572{ yyval.vInt = yypvt[-0].vInt; } break;
1573case 50:
1574# line 422 "lua.stx"
1575{
1576 code_byte(CREATEARRAY);
1577 yyval.vInt = 1;
1578 } break;
1579case 51:
1580# line 426 "lua.stx"
1581{ lua_pushvar (yypvt[-0].vLong); yyval.vInt = 1;} break;
1582case 52:
1583# line 427 "lua.stx"
1584{ code_number(yypvt[-0].vFloat); yyval.vInt = 1; } break;
1585case 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;
1593case 54:
1594# line 435 "lua.stx"
1595{code_byte(PUSHNIL); yyval.vInt = 1; incr_ntemp();} break;
1596case 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;
1605case 56:
1606# line 444 "lua.stx"
1607{ code_byte(NOTOP); yyval.vInt = 1;} break;
1608case 57:
1609# line 445 "lua.stx"
1610{code_byte(POP); ntemp--;} break;
1611case 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;
1618case 59:
1619# line 451 "lua.stx"
1620{code_byte(POP); ntemp--;} break;
1621case 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;
1628case 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;
1636case 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;
1660case 63:
1661# line 491 "lua.stx"
1662{ code_byte(PUSHNIL); incr_ntemp();} break;
1663case 65:
1664# line 495 "lua.stx"
1665{code_byte(PUSHMARK); yyval.vInt = ntemp; incr_ntemp();} break;
1666case 66:
1667# line 496 "lua.stx"
1668{ code_byte(CALLFUNC); ntemp = yypvt[-3].vInt-1;} break;
1669case 67:
1670# line 498 "lua.stx"
1671{lua_pushvar (yypvt[-0].vLong); } break;
1672case 68:
1673# line 501 "lua.stx"
1674{ yyval.vInt = 1; } break;
1675case 69:
1676# line 502 "lua.stx"
1677{ yyval.vInt = yypvt[-0].vInt; } break;
1678case 70:
1679# line 505 "lua.stx"
1680{ yyval.vInt = yypvt[-0].vInt; } break;
1681case 71:
1682# line 506 "lua.stx"
1683{if (!yypvt[-1].vInt){lua_codeadjust (ntemp+1); incr_ntemp();}} break;
1684case 72:
1685# line 507 "lua.stx"
1686{yyval.vInt = yypvt[-0].vInt;} break;
1687case 75:
1688# line 515 "lua.stx"
1689{
1690 localvar[nlocalvar]=lua_findsymbol(yypvt[-0].pChar);
1691 add_nlocalvar(1);
1692 } break;
1693case 76:
1694# line 520 "lua.stx"
1695{
1696 localvar[nlocalvar]=lua_findsymbol(yypvt[-0].pChar);
1697 add_nlocalvar(1);
1698 } break;
1699case 77:
1700# line 526 "lua.stx"
1701{yyval.vLong=-1;} break;
1702case 78:
1703# line 527 "lua.stx"
1704{yyval.vLong=lua_findsymbol(yypvt[-0].pChar);} break;
1705case 79:
1706# line 531 "lua.stx"
1707{
1708 flush_record(yypvt[-1].vInt%FIELDS_PER_FLUSH);
1709 yyval.vInt = yypvt[-1].vInt;
1710 } break;
1711case 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;
1717case 81:
1718# line 542 "lua.stx"
1719{ yyval.vInt = 0; } break;
1720case 82:
1721# line 543 "lua.stx"
1722{ yyval.vInt = yypvt[-0].vInt; } break;
1723case 83:
1724# line 546 "lua.stx"
1725{yyval.vInt=1;} break;
1726case 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;
1732case 85:
1733# line 554 "lua.stx"
1734{yyval.vWord = lua_findconstant(yypvt[-0].pChar);} break;
1735case 86:
1736# line 555 "lua.stx"
1737{
1738 push_field(yypvt[-2].vWord);
1739 } break;
1740case 87:
1741# line 560 "lua.stx"
1742{ yyval.vInt = 0; } break;
1743case 88:
1744# line 561 "lua.stx"
1745{ yyval.vInt = yypvt[-0].vInt; } break;
1746case 89:
1747# line 564 "lua.stx"
1748{yyval.vInt=1;} break;
1749case 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;
1756case 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;
1763case 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;
1769case 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;
1779case 94:
1780# line 596 "lua.stx"
1781{lua_pushvar (yypvt[-0].vLong);} break;
1782case 95:
1783# line 597 "lua.stx"
1784{
1785 yyval.vLong = 0; /* indexed variable */
1786 } break;
1787case 96:
1788# line 600 "lua.stx"
1789{lua_pushvar (yypvt[-0].vLong);} break;
1790case 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;
1797case 98:
1798# line 608 "lua.stx"
1799{localvar[nlocalvar]=lua_findsymbol(yypvt[-0].pChar); yyval.vInt = 1;} break;
1800case 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;
1806case 102:
1807# line 620 "lua.stx"
1808{lua_debug = yypvt[-0].vInt;} break;
1809 }
1810 goto yystack; /* reset registers in driver code */
1811}
src/y.tab.h+37−0
@@ -0,0 +1,37 @@
1
2typedef union
3{
4 int vInt;
5 long vLong;
6 float vFloat;
7 char *pChar;
8 Word vWord;
9 Byte *pByte;
10} YYSTYPE;
11extern 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
src/yacc/Makefile+27−0
@@ -0,0 +1,27 @@
1# makefile for lua
2
3LIB= $(LUA)/lib
4INC= $(LUA)/inc
5
6CC= gcc
7CFLAGS= -g -Wall -O2 -I$(INC) $(DEFS)
8DEFS= -DMAXCODE=64000 -DMAXCONSTANT=1024 -DMAXSYMBOL=1024 -DMAXARRAY=1024
9
10OBJS= hash.o inout.o lex.o opcode.o table.o y.tab.o
11SLIB= $(LIB)/lua.a
12DLIB= $(LIB)/liblua.so.1.1
13
14libs: $(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
23y.tab.c: lua.stx exscript
24 yacc -d lua.stx ; ex y.tab.c <exscript
25
26clean:
27 rm -f $(OBJS) $(SLIB) $(DLIB)
src/yacc/exscript+3−0
@@ -0,0 +1,3 @@
11d
2x
3
src/yacc/lua.lex+85−0
@@ -0,0 +1,85 @@
1%{
2
3char *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
17static Input input;
18static Unput unput;
19
20void lua_setinput (Input fn)
21{
22 input = fn;
23}
24
25void lua_setunput (Unput fn)
26{
27 unput = fn;
28}
29
30char *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
src/yacc/lua.stx+953−0
@@ -0,0 +1,953 @@
1%{
2
3char *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
22static Word maxcode;
23static Word maxmain;
24static Word maxcurr ;
25static Byte *code = NULL;
26static Byte *initcode;
27static Byte *basepc;
28static Word maincode;
29static Word pc;
30
31#define MAXVAR 32
32static long varbuffer[MAXVAR]; /* variables in an assignment list;
33 it's long to store negative Word values */
34static int nvarbuffer=0; /* number of variables at a list */
35
36static Word localvar[STACKGAP]; /* store local variable names */
37static int nlocalvar=0; /* number of local variables */
38
39#define MAXFIELDS FIELDS_PER_FLUSH*2
40static Word fields[MAXFIELDS]; /* fieldnames to be flushed */
41static int nfields=0;
42static int ntemp; /* number of temporary var into stack */
43static int err; /* flag to indicate error */
44
45/* Internal functions */
46
47static 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
62static 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
70static 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
80static 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
88static 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
99static 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
110static 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
124static 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
135static 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
146static 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
157static 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
225functionlist : /* 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
239function : 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
280PrintCode(code,code+pc);
281#endif
282 }
283 ;
284
285statlist : /* empty */
286 | statlist stat sc
287 ;
288
289stat : {
290 ntemp = 0;
291 if (lua_debug)
292 {
293 code_byte(SETLINE); code_word(lua_linenumber);
294 }
295 }
296 stat1
297
298sc : /* empty */ | ';' ;
299
300
301stat1 : 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
355elsepart : /* 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
377block : {$<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
387ret : /* 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
396PrepJump : /* empty */
397 {
398 $$ = pc;
399 code_byte(0); /* open space */
400 code_word (0);
401 }
402
403expr1 : expr { if ($1 == 0) {lua_codeadjust (ntemp+1); incr_ntemp();}}
404 ;
405
406expr : '(' 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
459typeconstructor: '@'
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
491dimension : /* empty */ { code_byte(PUSHNIL); incr_ntemp();}
492 | expr1
493 ;
494
495functioncall : functionvalue {code_byte(PUSHMARK); $<vInt>$ = ntemp; incr_ntemp();}
496 '(' exprlist ')' { code_byte(CALLFUNC); ntemp = $<vInt>2-1;}
497
498functionvalue : var {lua_pushvar ($1); }
499 ;
500
501exprlist : /* empty */ { $$ = 1; }
502 | exprlist1 { $$ = $1; }
503 ;
504
505exprlist1 : expr { $$ = $1; }
506 | exprlist1 ',' {if (!$1){lua_codeadjust (ntemp+1); incr_ntemp();}}
507 expr {$$ = $4;}
508 ;
509
510parlist : /* empty */
511 | parlist1
512 ;
513
514parlist1 : 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
526objectname : /* empty */ {$$=-1;}
527 | NAME {$$=lua_findsymbol($1);}
528 ;
529
530fieldlist : '{' 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
542ffieldlist : /* empty */ { $$ = 0; }
543 | ffieldlist1 { $$ = $1; }
544 ;
545
546ffieldlist1 : ffield {$$=1;}
547 | ffieldlist1 ',' ffield
548 {
549 $$=$1+1;
550 if ($$%FIELDS_PER_FLUSH == 0) flush_record(FIELDS_PER_FLUSH);
551 }
552 ;
553
554ffield : NAME {$<vWord>$ = lua_findconstant($1);} '=' expr1
555 {
556 push_field($<vWord>2);
557 }
558 ;
559
560lfieldlist : /* empty */ { $$ = 0; }
561 | lfieldlist1 { $$ = $1; }
562 ;
563
564lfieldlist1 : 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
573varlist1 : 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
586var : 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
608localdeclist : NAME {localvar[nlocalvar]=lua_findsymbol($1); $$ = 1;}
609 | localdeclist ',' NAME
610 {
611 localvar[nlocalvar+$1]=lua_findsymbol($3);
612 $$ = $1+1;
613 }
614 ;
615
616decinit : /* empty */
617 | '=' exprlist1
618 ;
619
620setdebug : 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*/
627static 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*/
640static 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
666static void lua_codeadjust (int n)
667{
668 code_byte(ADJUST);
669 code_byte(n + nlocalvar);
670}
671
672static 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
707void 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
716int 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*/
726int 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
751static 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

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t