aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRoberto Ierusalimschy <roberto@inf.puc-rio.br>1998-12-27 18:25:20 -0200
committerRoberto Ierusalimschy <roberto@inf.puc-rio.br>1998-12-27 18:25:20 -0200
commit4c94d8cc2cbeac74ae3618b1322c3f3d3ec166ea (patch)
treefd95bdb49c335389a222547b072b60d04d23043f
parentd2de2d5eda5779832a6e6ce4de1f1d8aa4f01047 (diff)
downloadlua-4c94d8cc2cbeac74ae3618b1322c3f3d3ec166ea.tar.gz
lua-4c94d8cc2cbeac74ae3618b1322c3f3d3ec166ea.tar.bz2
lua-4c94d8cc2cbeac74ae3618b1322c3f3d3ec166ea.zip
new function "luaO_str2d" to convert strings to numbers, because
old "lex" algorithm had aproximation errors, but strtod (and atof and scanf) are too slow.
-rw-r--r--llex.c67
-rw-r--r--lobject.c70
-rw-r--r--lobject.h4
-rw-r--r--lvm.c43
4 files changed, 108 insertions, 76 deletions
diff --git a/llex.c b/llex.c
index 3c3cf430..941e6b8a 100644
--- a/llex.c
+++ b/llex.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: llex.c,v 1.24 1998/07/24 18:02:38 roberto Exp roberto $ 2** $Id: llex.c,v 1.25 1998/12/03 15:45:15 roberto Exp $
3** Lexical Analizer 3** Lexical Analizer
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -46,7 +46,7 @@ void luaX_init (void)
46 46
47 47
48void luaX_syntaxerror (LexState *ls, char *s, char *token) { 48void luaX_syntaxerror (LexState *ls, char *s, char *token) {
49 if (token[0] == 0) 49 if (token[0] == '\0')
50 token = "<eof>"; 50 token = "<eof>";
51 luaL_verror("%.100s;\n last token read: `%.50s' at line %d in chunk `%.50s'", 51 luaL_verror("%.100s;\n last token read: `%.50s' at line %d in chunk `%.50s'",
52 s, token, ls->linenumber, zname(ls->lex_z)); 52 s, token, ls->linenumber, zname(ls->lex_z));
@@ -54,7 +54,7 @@ void luaX_syntaxerror (LexState *ls, char *s, char *token) {
54 54
55 55
56void luaX_error (LexState *ls, char *s) { 56void luaX_error (LexState *ls, char *s) {
57 save(0); 57 save('\0');
58 luaX_syntaxerror(ls, s, luaL_buffer()); 58 luaX_syntaxerror(ls, s, luaL_buffer());
59} 59}
60 60
@@ -62,7 +62,7 @@ void luaX_error (LexState *ls, char *s) {
62void luaX_token2str (int token, char *s) { 62void luaX_token2str (int token, char *s) {
63 if (token < 255) { 63 if (token < 255) {
64 s[0] = token; 64 s[0] = token;
65 s[1] = 0; 65 s[1] = '\0';
66 } 66 }
67 else 67 else
68 strcpy(s, reserved[token-FIRST_RESERVED]); 68 strcpy(s, reserved[token-FIRST_RESERVED]);
@@ -221,6 +221,7 @@ static void inclinenumber (LexState *LS)
221} 221}
222 222
223 223
224
224/* 225/*
225** ======================================================= 226** =======================================================
226** LEXICAL ANALIZER 227** LEXICAL ANALIZER
@@ -229,10 +230,7 @@ static void inclinenumber (LexState *LS)
229 230
230 231
231 232
232 233static int read_long_string (LexState *LS) {
233
234static int read_long_string (LexState *LS)
235{
236 int cont = 0; 234 int cont = 0;
237 for (;;) { 235 for (;;) {
238 switch (LS->current) { 236 switch (LS->current) {
@@ -262,7 +260,7 @@ static int read_long_string (LexState *LS)
262 save_and_next(LS); 260 save_and_next(LS);
263 } 261 }
264 } endloop: 262 } endloop:
265 save_and_next(LS); /* pass the second ']' */ 263 save_and_next(LS); /* skip the second ']' */
266 LS->seminfo.ts = luaS_newlstr(L->Mbuffbase+2, 264 LS->seminfo.ts = luaS_newlstr(L->Mbuffbase+2,
267 L->Mbuffnext-(L->Mbuffbase-L->Mbuffer)-4); 265 L->Mbuffnext-(L->Mbuffbase-L->Mbuffer)-4);
268 return STRING; 266 return STRING;
@@ -270,7 +268,6 @@ static int read_long_string (LexState *LS)
270 268
271 269
272int luaX_lex (LexState *LS) { 270int luaX_lex (LexState *LS) {
273 double a;
274 luaL_resetbuffer(); 271 luaL_resetbuffer();
275 for (;;) { 272 for (;;) {
276 switch (LS->current) { 273 switch (LS->current) {
@@ -347,7 +344,7 @@ int luaX_lex (LexState *LS) {
347 c = 10*c + (LS->current-'0'); 344 c = 10*c + (LS->current-'0');
348 next(LS); 345 next(LS);
349 } while (++i<3 && isdigit(LS->current)); 346 } while (++i<3 && isdigit(LS->current));
350 if (c >= 256) 347 if (c > (unsigned char)c)
351 luaX_error(LS, "escape sequence too large"); 348 luaX_error(LS, "escape sequence too large");
352 save(c); 349 save(c);
353 } 350 }
@@ -382,15 +379,11 @@ int luaX_lex (LexState *LS) {
382 else return CONC; /* .. */ 379 else return CONC; /* .. */
383 } 380 }
384 else if (!isdigit(LS->current)) return '.'; 381 else if (!isdigit(LS->current)) return '.';
385 /* LS->current is a digit: goes through to number */ 382 goto fraction; /* LS->current is a digit: goes through to number */
386 a=0.0;
387 goto fraction;
388 383
389 case '0': case '1': case '2': case '3': case '4': 384 case '0': case '1': case '2': case '3': case '4':
390 case '5': case '6': case '7': case '8': case '9': 385 case '5': case '6': case '7': case '8': case '9':
391 a=0.0;
392 do { 386 do {
393 a = 10.0*a + (LS->current-'0');
394 save_and_next(LS); 387 save_and_next(LS);
395 } while (isdigit(LS->current)); 388 } while (isdigit(LS->current));
396 if (LS->current == '.') { 389 if (LS->current == '.') {
@@ -402,35 +395,19 @@ int luaX_lex (LexState *LS) {
402 } 395 }
403 } 396 }
404 fraction: 397 fraction:
405 { double da=0.1; 398 while (isdigit(LS->current))
406 while (isdigit(LS->current)) 399 save_and_next(LS);
407 { 400 if (toupper(LS->current) == 'E') {
408 a += (LS->current-'0')*da; 401 save_and_next(LS); /* read 'E' */
409 da /= 10.0; 402 save_and_next(LS); /* read '+', '-' or first digit */
410 save_and_next(LS); 403 while (isdigit(LS->current))
411 }
412 if (toupper(LS->current) == 'E') {
413 int e = 0;
414 int neg;
415 double ea;
416 save_and_next(LS); 404 save_and_next(LS);
417 neg = (LS->current=='-');
418 if (LS->current == '+' || LS->current == '-') save_and_next(LS);
419 if (!isdigit(LS->current))
420 luaX_error(LS, "invalid numeral format");
421 do {
422 e = 10*e + (LS->current-'0');
423 save_and_next(LS);
424 } while (isdigit(LS->current));
425 for (ea=neg?0.1:10.0; e>0; e>>=1)
426 {
427 if (e & 1) a *= ea;
428 ea *= ea;
429 }
430 }
431 LS->seminfo.r = a;
432 return NUMBER;
433 } 405 }
406 save('\0');
407 LS->seminfo.r = luaO_str2d(L->Mbuffbase);
408 if (LS->seminfo.r < 0)
409 luaX_error(LS, "invalid numeric format");
410 return NUMBER;
434 411
435 case EOZ: 412 case EOZ:
436 if (LS->iflevel > 0) 413 if (LS->iflevel > 0)
@@ -450,9 +427,9 @@ int luaX_lex (LexState *LS) {
450 do { 427 do {
451 save_and_next(LS); 428 save_and_next(LS);
452 } while (isalnum(LS->current) || LS->current == '_'); 429 } while (isalnum(LS->current) || LS->current == '_');
453 save(0); 430 save('\0');
454 ts = luaS_new(L->Mbuffbase); 431 ts = luaS_new(L->Mbuffbase);
455 if (ts->head.marked >= 'A') 432 if (ts->head.marked >= FIRST_RESERVED)
456 return ts->head.marked; /* reserved word */ 433 return ts->head.marked; /* reserved word */
457 LS->seminfo.ts = ts; 434 LS->seminfo.ts = ts;
458 return NAME; 435 return NAME;
diff --git a/lobject.c b/lobject.c
index 8e1742dd..5c0e3dd8 100644
--- a/lobject.c
+++ b/lobject.c
@@ -1,9 +1,10 @@
1/* 1/*
2** $Id: lobject.c,v 1.12 1998/06/18 16:57:03 roberto Exp roberto $ 2** $Id: lobject.c,v 1.13 1998/06/19 16:14:09 roberto Exp $
3** Some generic functions over Lua objects 3** Some generic functions over Lua objects
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
6 6
7#include <ctype.h>
7#include <stdlib.h> 8#include <stdlib.h>
8 9
9#include "lobject.h" 10#include "lobject.h"
@@ -64,20 +65,67 @@ void luaO_insertlist (GCnode *root, GCnode *node)
64 node->marked = 0; 65 node->marked = 0;
65} 66}
66 67
68
67#ifdef OLD_ANSI 69#ifdef OLD_ANSI
68void luaO_memup (void *dest, void *src, int size) 70void luaO_memup (void *dest, void *src, int size) {
69{ 71 while (size--)
70 char *d = dest; 72 ((char *)dest)[size]=((char *)src)[size];
71 char *s = src;
72 while (size--) d[size]=s[size];
73} 73}
74 74
75void luaO_memdown (void *dest, void *src, int size) 75void luaO_memdown (void *dest, void *src, int size) {
76{
77 char *d = dest;
78 char *s = src;
79 int i; 76 int i;
80 for (i=0; i<size; i++) d[i]=s[i]; 77 for (i=0; i<size; i++)
78 ((char *)dest)[i]=((char *)src)[i];
81} 79}
82#endif 80#endif
83 81
82
83
84static double expten (unsigned int e) {
85 double exp = 10.0;
86 double res = 1.0;
87 for (; e; e>>=1) {
88 if (e & 1) res *= exp;
89 exp *= exp;
90 }
91 return res;
92}
93
94
95double luaO_str2d (char *s) {
96 double a = 0.0;
97 int point = 0;
98 if (!isdigit((unsigned char)*s) && !isdigit((unsigned char)*(s+1)))
99 return -1; /* no digit before or after decimal point */
100 while (isdigit((unsigned char)*s)) {
101 a = 10.0*a + (*(s++)-'0');
102 }
103 if (*s == '.') s++;
104 while (isdigit((unsigned char)*s)) {
105 a = 10.0*a + (*(s++)-'0');
106 point++;
107 }
108 if (toupper((unsigned char)*s) == 'E') {
109 int e = 0;
110 int sig = 1;
111 s++;
112 if (*s == '+') s++;
113 else if (*s == '-') {
114 s++;
115 sig = -1;
116 }
117 if (!isdigit((unsigned char)*s)) return -1; /* no digit in expoent part? */
118 do {
119 e = 10*e + (*(s++)-'0');
120 } while (isdigit((unsigned char)*s));
121 point -= sig*e;
122 }
123 while (isspace((unsigned char)*s)) s++;
124 if (*s != '\0') return -1; /* invalid trailing characters? */
125 if (point > 0)
126 a /= expten(point);
127 else if (point < 0)
128 a *= expten(-point);
129 return a;
130}
131
diff --git a/lobject.h b/lobject.h
index 0fe44329..1266a825 100644
--- a/lobject.h
+++ b/lobject.h
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lobject.h,v 1.22 1998/07/12 16:11:55 roberto Exp roberto $ 2** $Id: lobject.h,v 1.23 1998/12/01 19:09:47 roberto Exp $
3** Type definitions for Lua objects 3** Type definitions for Lua objects
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -30,7 +30,6 @@
30*/ 30*/
31#ifndef LUA_NUM_TYPE 31#ifndef LUA_NUM_TYPE
32#define LUA_NUM_TYPE double 32#define LUA_NUM_TYPE double
33#define NUMBER_FMT "%g"
34#endif 33#endif
35 34
36 35
@@ -197,6 +196,7 @@ extern TObject luaO_nilobject;
197int luaO_equalObj (TObject *t1, TObject *t2); 196int luaO_equalObj (TObject *t1, TObject *t2);
198int luaO_redimension (int oldsize); 197int luaO_redimension (int oldsize);
199void luaO_insertlist (GCnode *root, GCnode *node); 198void luaO_insertlist (GCnode *root, GCnode *node);
199double luaO_str2d (char *s);
200 200
201#ifdef OLD_ANSI 201#ifdef OLD_ANSI
202void luaO_memup (void *dest, void *src, int size); 202void luaO_memup (void *dest, void *src, int size);
diff --git a/lvm.c b/lvm.c
index 9fd7c5d0..d84752a3 100644
--- a/lvm.c
+++ b/lvm.c
@@ -1,11 +1,12 @@
1/* 1/*
2** $Id: lvm.c,v 1.32 1998/12/03 15:45:15 roberto Exp roberto $ 2** $Id: lvm.c,v 1.33 1998/12/24 14:57:23 roberto Exp $
3** Lua virtual machine 3** Lua virtual machine
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
6 6
7 7
8#include <ctype.h> 8#include <ctype.h>
9#include <limits.h>
9#include <stdio.h> 10#include <stdio.h>
10#include <stdlib.h> 11#include <stdlib.h>
11#include <string.h> 12#include <string.h>
@@ -15,6 +16,7 @@
15#include "lfunc.h" 16#include "lfunc.h"
16#include "lgc.h" 17#include "lgc.h"
17#include "lmem.h" 18#include "lmem.h"
19#include "lobject.h"
18#include "lopcodes.h" 20#include "lopcodes.h"
19#include "lstate.h" 21#include "lstate.h"
20#include "lstring.h" 22#include "lstring.h"
@@ -26,7 +28,6 @@
26 28
27#ifdef OLD_ANSI 29#ifdef OLD_ANSI
28#define strcoll(a,b) strcmp(a,b) 30#define strcoll(a,b) strcmp(a,b)
29double strtod();
30#endif 31#endif
31 32
32 33
@@ -40,11 +41,10 @@ double strtod();
40 41
41 42
42 43
43static TaggedString *strconc (TaggedString *l, TaggedString *r) 44static TaggedString *strconc (TaggedString *l, TaggedString *r) {
44{ 45 long nl = l->u.s.len;
45 size_t nl = l->u.s.len; 46 long nr = r->u.s.len;
46 size_t nr = r->u.s.len; 47 char *buffer = luaL_openspace(nl+nr);
47 char *buffer = luaL_openspace(nl+nr+1);
48 memcpy(buffer, l->str, nl); 48 memcpy(buffer, l->str, nl);
49 memcpy(buffer+nl, r->str, nr); 49 memcpy(buffer+nl, r->str, nr);
50 return luaS_newlstr(buffer, nl+nr); 50 return luaS_newlstr(buffer, nl+nr);
@@ -56,29 +56,36 @@ int luaV_tonumber (TObject *obj) {
56 if (ttype(obj) != LUA_T_STRING) 56 if (ttype(obj) != LUA_T_STRING)
57 return 1; 57 return 1;
58 else { 58 else {
59 char *e; 59 double t;
60 double t = strtod(svalue(obj), &e); 60 char *e = svalue(obj);
61 while (isspace(*e)) e++; 61 int sig = 1;
62 if (*e != '\0') return 2; 62 while (isspace((unsigned char)*e)) e++;
63 nvalue(obj) = (real)t; 63 if (*e == '+') e++;
64 else if (*e == '-') {
65 e++;
66 sig = -1;
67 }
68 t = luaO_str2d(e);
69 if (t<0) return 2;
70 nvalue(obj) = (real)t*sig;
64 ttype(obj) = LUA_T_NUMBER; 71 ttype(obj) = LUA_T_NUMBER;
65 return 0; 72 return 0;
66 } 73 }
67} 74}
68 75
69 76
70int luaV_tostring (TObject *obj) 77int luaV_tostring (TObject *obj) {
71{ /* LUA_NUMBER */ 78 /* LUA_NUMBER */
72 if (ttype(obj) != LUA_T_NUMBER) 79 if (ttype(obj) != LUA_T_NUMBER)
73 return 1; 80 return 1;
74 else { 81 else {
75 char s[60]; 82 char s[60];
76 real f = nvalue(obj); 83 real f = nvalue(obj);
77 int i; 84 long i;
78 if ((real)(-MAX_INT) <= f && f <= (real)MAX_INT && (real)(i=(int)f) == f) 85 if ((real)LONG_MIN <= f && f <= (real)LONG_MAX && (real)(i=(long)f) == f)
79 sprintf (s, "%d", i); 86 sprintf(s, "%ld", i);
80 else 87 else
81 sprintf (s, NUMBER_FMT, nvalue(obj)); 88 sprintf(s, "%g", (double)nvalue(obj));
82 tsvalue(obj) = luaS_new(s); 89 tsvalue(obj) = luaS_new(s);
83 ttype(obj) = LUA_T_STRING; 90 ttype(obj) = LUA_T_STRING;
84 return 0; 91 return 0;