qse/ase/lsp/read.c

568 lines
11 KiB
C
Raw Normal View History

2005-02-04 15:39:11 +00:00
/*
2007-03-06 15:01:50 +00:00
* $Id: read.c,v 1.33 2007-03-06 14:58:00 bacon Exp $
2007-02-03 10:52:36 +00:00
*
* {License}
2005-02-04 15:39:11 +00:00
*/
2006-10-25 13:42:31 +00:00
#include <ase/lsp/lsp_i.h>
2005-02-04 15:39:11 +00:00
#define IS_IDENT(c) \
2006-10-24 04:22:40 +00:00
((c) == ASE_T('+') || (c) == ASE_T('-') || \
(c) == ASE_T('*') || (c) == ASE_T('/') || \
(c) == ASE_T('%') || (c) == ASE_T('&') || \
(c) == ASE_T('<') || (c) == ASE_T('>') || \
(c) == ASE_T('=') || (c) == ASE_T('_') || \
(c) == ASE_T('?'))
2006-10-29 13:00:39 +00:00
#define TOKEN_CLEAR(lsp) ase_lsp_name_clear (&(lsp)->token.name)
#define TOKEN_TYPE(lsp) (lsp)->token.type
#define TOKEN_IVAL(lsp) (lsp)->token.ival
#define TOKEN_RVAL(lsp) (lsp)->token.rval
2007-02-11 07:36:55 +00:00
#define TOKEN_SPTR(lsp) (lsp)->token.name.buf
2006-10-29 13:00:39 +00:00
#define TOKEN_SLEN(lsp) (lsp)->token.name.size
2005-11-18 17:58:47 +00:00
2007-02-11 07:36:55 +00:00
#define TOKEN_ADD_CHAR(lsp,ch) \
do { \
if (ase_lsp_name_addc(&(lsp)->token.name, ch) == -1) { \
ase_lsp_seterror (lsp, ASE_LSP_ENOMEM, ASE_NULL, 0); \
return -1; \
} \
} while (0)
2005-11-18 17:58:47 +00:00
2007-02-11 07:36:55 +00:00
#define TOKEN_COMPARE(lsp,str) \
ase_lsp_name_compare (&(lsp)->token.name, str)
2005-02-04 15:39:11 +00:00
#define TOKEN_END 0
#define TOKEN_INT 1
2005-09-20 11:19:15 +00:00
#define TOKEN_REAL 2
2005-02-04 15:39:11 +00:00
#define TOKEN_STRING 3
#define TOKEN_LPAREN 4
#define TOKEN_RPAREN 5
#define TOKEN_IDENT 6
#define TOKEN_QUOTE 7
#define TOKEN_DOT 8
#define TOKEN_INVALID 50
#define TOKEN_UNTERM_STRING 51
#define NEXT_CHAR(lsp) \
2005-09-18 13:06:43 +00:00
do { if (read_char(lsp) == -1) return -1;} while (0)
2005-02-04 15:39:11 +00:00
2007-02-10 13:52:41 +00:00
#define NEXT_CHAR_TO(lsp,c) \
do { \
if (read_char(lsp) == -1) return -1;\
c = (lsp)->curc; \
} while (0)
2005-02-04 15:39:11 +00:00
#define NEXT_TOKEN(lsp) \
2006-10-24 04:22:40 +00:00
do { if (read_token(lsp) == -1) return ASE_NULL; } while (0)
2005-02-04 15:39:11 +00:00
2006-10-24 04:22:40 +00:00
static ase_lsp_obj_t* read_obj (ase_lsp_t* lsp);
static ase_lsp_obj_t* read_list (ase_lsp_t* lsp);
static ase_lsp_obj_t* read_quote (ase_lsp_t* lsp);
2005-09-18 12:20:43 +00:00
2006-10-24 04:22:40 +00:00
static int read_char (ase_lsp_t* lsp);
static int read_token (ase_lsp_t* lsp);
static int read_number (ase_lsp_t* lsp, int negative);
static int read_ident (ase_lsp_t* lsp);
static int read_string (ase_lsp_t* lsp);
2005-09-18 12:20:43 +00:00
2006-10-24 04:22:40 +00:00
ase_lsp_obj_t* ase_lsp_read (ase_lsp_t* lsp)
2005-02-04 15:39:11 +00:00
{
2006-10-25 13:42:31 +00:00
if (lsp->curc == ASE_CHAR_EOF &&
2006-10-24 04:22:40 +00:00
read_char(lsp) == -1) return ASE_NULL;
2005-02-04 15:39:11 +00:00
NEXT_TOKEN (lsp);
2006-11-02 10:12:01 +00:00
lsp->mem->read = read_obj (lsp);
if (lsp->mem->read != ASE_NULL)
ase_lsp_deepunlockobj (lsp, lsp->mem->read);
return lsp->mem->read;
2005-02-04 15:39:11 +00:00
}
2006-10-24 04:22:40 +00:00
static ase_lsp_obj_t* read_obj (ase_lsp_t* lsp)
2005-02-04 15:39:11 +00:00
{
2006-10-24 04:22:40 +00:00
ase_lsp_obj_t* obj;
2005-02-04 15:39:11 +00:00
2006-10-26 08:17:38 +00:00
switch (TOKEN_TYPE(lsp))
{
2006-10-29 13:00:39 +00:00
case TOKEN_END:
2007-02-11 07:36:55 +00:00
ase_lsp_seterror (lsp, ASE_LSP_EEND, ASE_NULL, 0);
2006-10-29 13:00:39 +00:00
return ASE_NULL;
case TOKEN_LPAREN:
NEXT_TOKEN (lsp);
return read_list (lsp);
case TOKEN_QUOTE:
NEXT_TOKEN (lsp);
return read_quote (lsp);
case TOKEN_INT:
obj = ase_lsp_makeintobj (lsp->mem, TOKEN_IVAL(lsp));
2007-02-11 07:36:55 +00:00
if (obj == ASE_NULL) return ASE_NULL;
2006-10-25 13:42:31 +00:00
ase_lsp_lockobj (lsp, obj);
2006-10-29 13:00:39 +00:00
return obj;
case TOKEN_REAL:
obj = ase_lsp_makerealobj (lsp->mem, TOKEN_RVAL(lsp));
2007-02-11 07:36:55 +00:00
if (obj == ASE_NULL) return ASE_NULL;
2006-10-29 13:00:39 +00:00
ase_lsp_lockobj (lsp, obj);
return obj;
case TOKEN_STRING:
2006-11-02 10:12:01 +00:00
obj = ase_lsp_makestr (
2007-02-11 07:36:55 +00:00
lsp->mem, TOKEN_SPTR(lsp), TOKEN_SLEN(lsp));
if (obj == ASE_NULL) return ASE_NULL;
2006-10-29 13:00:39 +00:00
ase_lsp_lockobj (lsp, obj);
return obj;
case TOKEN_IDENT:
2007-03-06 15:01:50 +00:00
ASE_ASSERT (
2007-02-11 07:36:55 +00:00
lsp->mem->nil != ASE_NULL &&
lsp->mem->t != ASE_NULL);
2006-11-02 10:12:01 +00:00
if (TOKEN_COMPARE(lsp,ASE_T("nil")) == 0)
{
obj = lsp->mem->nil;
}
else if (TOKEN_COMPARE(lsp,ASE_T("t")) == 0)
{
obj = lsp->mem->t;
}
2006-10-29 13:00:39 +00:00
else
{
2006-11-02 10:12:01 +00:00
obj = ase_lsp_makesym (
2007-02-11 07:36:55 +00:00
lsp->mem,
TOKEN_SPTR(lsp),
TOKEN_SLEN(lsp));
if (obj == ASE_NULL) return ASE_NULL;
ase_lsp_lockobj (lsp, obj);
2006-10-29 13:00:39 +00:00
}
2007-02-11 07:36:55 +00:00
2006-10-29 13:00:39 +00:00
return obj;
2005-02-04 15:39:11 +00:00
}
2007-02-11 07:36:55 +00:00
ase_lsp_seterror (lsp, ASE_LSP_ESYNTAX, ASE_NULL, 0);
2006-10-24 04:22:40 +00:00
return ASE_NULL;
2005-02-04 15:39:11 +00:00
}
2006-10-24 04:22:40 +00:00
static ase_lsp_obj_t* read_list (ase_lsp_t* lsp)
2005-02-04 15:39:11 +00:00
{
2006-10-24 04:22:40 +00:00
ase_lsp_obj_t* obj;
ase_lsp_obj_cons_t* p, * first = ASE_NULL, * prev = ASE_NULL;
2005-02-04 15:39:11 +00:00
2006-10-26 08:17:38 +00:00
while (TOKEN_TYPE(lsp) != TOKEN_RPAREN)
{
if (TOKEN_TYPE(lsp) == TOKEN_END)
{
2007-02-03 10:52:36 +00:00
/* unexpected end of input */
2007-02-11 07:36:55 +00:00
ase_lsp_seterror (lsp, ASE_LSP_ESYNTAX, ASE_NULL, 0);
2006-10-24 04:22:40 +00:00
return ASE_NULL;
2005-02-04 15:39:11 +00:00
}
2006-10-26 08:17:38 +00:00
if (TOKEN_TYPE(lsp) == TOKEN_DOT)
{
2006-11-02 06:46:31 +00:00
if (prev == ASE_NULL)
{
2007-02-03 10:52:36 +00:00
/* unexpected dot */
2007-02-11 07:36:55 +00:00
ase_lsp_seterror (lsp, ASE_LSP_ESYNTAX, ASE_NULL, 0);
2006-10-24 04:22:40 +00:00
return ASE_NULL;
2005-02-04 15:39:11 +00:00
}
NEXT_TOKEN (lsp);
obj = read_obj (lsp);
2006-10-26 08:17:38 +00:00
if (obj == ASE_NULL)
{
2007-02-03 10:52:36 +00:00
if (lsp->errnum == ASE_LSP_EEND)
2006-10-26 08:17:38 +00:00
{
2006-11-02 06:46:31 +00:00
/* unexpected end of input */
2007-02-11 07:36:55 +00:00
ase_lsp_seterror (lsp, ASE_LSP_ESYNTAX, ASE_NULL, 0);
2005-02-04 15:39:11 +00:00
}
2006-10-24 04:22:40 +00:00
return ASE_NULL;
2005-02-04 15:39:11 +00:00
}
prev->cdr = obj;
NEXT_TOKEN (lsp);
2006-10-26 08:17:38 +00:00
if (TOKEN_TYPE(lsp) != TOKEN_RPAREN)
{
2007-02-03 10:52:36 +00:00
/* ) expected */
2007-02-11 07:36:55 +00:00
ase_lsp_seterror (lsp, ASE_LSP_ERPAREN, ASE_NULL, 0);
2006-10-24 04:22:40 +00:00
return ASE_NULL;
2005-02-04 15:39:11 +00:00
}
break;
}
obj = read_obj (lsp);
2006-10-25 13:42:31 +00:00
if (obj == ASE_NULL)
{
2007-02-03 10:52:36 +00:00
if (lsp->errnum == ASE_LSP_EEND)
2006-10-25 13:42:31 +00:00
{
2006-11-02 10:12:01 +00:00
/* unexpected end of input */
2007-02-11 07:36:55 +00:00
ase_lsp_seterror (lsp, ASE_LSP_ESYNTAX, ASE_NULL, 0);
2005-02-04 15:39:11 +00:00
}
2006-10-24 04:22:40 +00:00
return ASE_NULL;
2005-02-04 15:39:11 +00:00
}
2006-10-25 13:42:31 +00:00
p = (ase_lsp_obj_cons_t*)ase_lsp_makecons (
2005-02-04 15:39:11 +00:00
lsp->mem, lsp->mem->nil, lsp->mem->nil);
2007-02-11 07:36:55 +00:00
if (p == ASE_NULL) return ASE_NULL;
2006-10-25 13:42:31 +00:00
ase_lsp_lockobj (lsp, (ase_lsp_obj_t*)p);
2005-02-04 15:39:11 +00:00
2006-10-24 04:22:40 +00:00
if (first == ASE_NULL) first = p;
if (prev != ASE_NULL) prev->cdr = (ase_lsp_obj_t*)p;
2005-02-04 15:39:11 +00:00
p->car = obj;
prev = p;
NEXT_TOKEN (lsp);
}
2006-10-24 04:22:40 +00:00
return (first == ASE_NULL)? lsp->mem->nil: (ase_lsp_obj_t*)first;
2005-02-04 15:39:11 +00:00
}
2006-10-24 04:22:40 +00:00
static ase_lsp_obj_t* read_quote (ase_lsp_t* lsp)
2005-02-04 15:39:11 +00:00
{
2006-10-24 04:22:40 +00:00
ase_lsp_obj_t* cons, * tmp;
2005-02-04 15:39:11 +00:00
tmp = read_obj (lsp);
2006-10-25 13:42:31 +00:00
if (tmp == ASE_NULL)
{
2007-02-03 10:52:36 +00:00
if (lsp->errnum == ASE_LSP_EEND)
2006-10-25 13:42:31 +00:00
{
2007-02-03 10:52:36 +00:00
/* unexpected end of input */
2007-02-11 07:36:55 +00:00
ase_lsp_seterror (lsp, ASE_LSP_ESYNTAX, ASE_NULL, 0);
2005-02-04 15:39:11 +00:00
}
2006-10-24 04:22:40 +00:00
return ASE_NULL;
2005-02-04 15:39:11 +00:00
}
2006-10-25 13:42:31 +00:00
cons = ase_lsp_makecons (lsp->mem, tmp, lsp->mem->nil);
2007-02-11 07:36:55 +00:00
if (cons == ASE_NULL) return ASE_NULL;
2006-10-25 13:42:31 +00:00
ase_lsp_lockobj (lsp, cons);
2005-02-04 15:39:11 +00:00
2006-10-25 13:42:31 +00:00
cons = ase_lsp_makecons (lsp->mem, lsp->mem->quote, cons);
2007-02-11 07:36:55 +00:00
if (cons == ASE_NULL) return ASE_NULL;
2006-11-02 10:12:01 +00:00
ase_lsp_lockobj (lsp, cons);
2005-02-04 15:39:11 +00:00
return cons;
}
2006-10-24 04:22:40 +00:00
static int read_char (ase_lsp_t* lsp)
2005-09-18 13:06:43 +00:00
{
2006-10-24 04:22:40 +00:00
ase_ssize_t n;
2006-10-29 13:00:39 +00:00
ase_char_t c;
2005-09-18 13:06:43 +00:00
2006-10-25 13:42:31 +00:00
if (lsp->input_func == ASE_NULL)
{
2007-02-11 07:36:55 +00:00
ase_lsp_seterror (lsp, ASE_LSP_ENOINP, ASE_NULL, 0);
2005-09-18 13:06:43 +00:00
return -1;
}
2006-10-29 13:00:39 +00:00
n = lsp->input_func(ASE_LSP_IO_READ, lsp->input_arg, &c, 1);
2006-10-25 13:42:31 +00:00
if (n == -1)
{
2007-02-11 07:36:55 +00:00
ase_lsp_seterror (lsp, ASE_LSP_EINPUT, ASE_NULL, 0);
2005-09-18 13:06:43 +00:00
return -1;
}
2006-10-25 13:42:31 +00:00
if (n == 0) lsp->curc = ASE_CHAR_EOF;
2006-10-29 13:00:39 +00:00
else lsp->curc = c;
2005-09-18 13:06:43 +00:00
return 0;
}
2006-10-24 04:22:40 +00:00
static int read_token (ase_lsp_t* lsp)
2005-02-04 15:39:11 +00:00
{
2007-03-06 15:01:50 +00:00
ASE_ASSERT (lsp->input_func != ASE_NULL);
2005-02-04 15:39:11 +00:00
TOKEN_CLEAR (lsp);
2006-10-25 13:42:31 +00:00
while (1)
{
2007-02-03 10:52:36 +00:00
/* skip white spaces */
2006-10-26 08:17:38 +00:00
while (ASE_LSP_ISSPACE(lsp, lsp->curc)) NEXT_CHAR (lsp);
2005-02-04 15:39:11 +00:00
2007-02-03 10:52:36 +00:00
/* skip the comments here */
2006-10-25 13:42:31 +00:00
if (lsp->curc == ASE_T(';'))
{
do
{
2005-02-04 15:39:11 +00:00
NEXT_CHAR (lsp);
2006-10-25 13:42:31 +00:00
}
2006-10-26 08:17:38 +00:00
while (lsp->curc != ASE_T('\n') &&
lsp->curc != ASE_CHAR_EOF);
2005-02-04 15:39:11 +00:00
}
else break;
}
2006-10-25 13:42:31 +00:00
if (lsp->curc == ASE_CHAR_EOF)
{
2005-02-04 15:39:11 +00:00
TOKEN_TYPE(lsp) = TOKEN_END;
return 0;
}
2006-10-25 13:42:31 +00:00
else if (lsp->curc == ASE_T('('))
{
2005-02-04 15:39:11 +00:00
TOKEN_ADD_CHAR (lsp, lsp->curc);
TOKEN_TYPE(lsp) = TOKEN_LPAREN;
NEXT_CHAR (lsp);
return 0;
}
2006-10-25 13:42:31 +00:00
else if (lsp->curc == ASE_T(')'))
{
2005-02-04 15:39:11 +00:00
TOKEN_ADD_CHAR (lsp, lsp->curc);
TOKEN_TYPE(lsp) = TOKEN_RPAREN;
NEXT_CHAR (lsp);
return 0;
}
2006-10-25 13:42:31 +00:00
else if (lsp->curc == ASE_T('\''))
{
2005-02-04 15:39:11 +00:00
TOKEN_ADD_CHAR (lsp, lsp->curc);
TOKEN_TYPE(lsp) = TOKEN_QUOTE;
NEXT_CHAR (lsp);
return 0;
}
2006-10-25 13:42:31 +00:00
else if (lsp->curc == ASE_T('.'))
{
2005-02-04 15:39:11 +00:00
TOKEN_ADD_CHAR (lsp, lsp->curc);
TOKEN_TYPE(lsp) = TOKEN_DOT;
NEXT_CHAR (lsp);
return 0;
}
2006-10-25 13:42:31 +00:00
else if (lsp->curc == ASE_T('-'))
{
2005-02-04 15:39:11 +00:00
TOKEN_ADD_CHAR (lsp, lsp->curc);
NEXT_CHAR (lsp);
2006-10-26 08:17:38 +00:00
if (ASE_LSP_ISDIGIT(lsp,lsp->curc))
2006-10-25 13:42:31 +00:00
{
2005-09-20 08:05:32 +00:00
return read_number (lsp, 1);
}
2006-10-25 13:42:31 +00:00
else if (IS_IDENT(lsp->curc))
{
2005-09-20 08:05:32 +00:00
return read_ident (lsp);
}
2006-10-25 13:42:31 +00:00
else
{
2005-09-20 08:05:32 +00:00
TOKEN_TYPE(lsp) = TOKEN_IDENT;
return 0;
}
2005-02-04 15:39:11 +00:00
}
2006-10-26 08:17:38 +00:00
else if (ASE_LSP_ISDIGIT(lsp,lsp->curc))
2006-10-25 13:42:31 +00:00
{
2005-02-04 15:39:11 +00:00
return read_number (lsp, 0);
}
2006-10-26 08:17:38 +00:00
else if (ASE_LSP_ISALPHA(lsp,lsp->curc) || IS_IDENT(lsp->curc))
2006-10-25 13:42:31 +00:00
{
2005-02-04 15:39:11 +00:00
return read_ident (lsp);
}
2006-10-25 13:42:31 +00:00
else if (lsp->curc == ASE_T('\"'))
{
2005-02-04 15:39:11 +00:00
return read_string (lsp);
}
TOKEN_TYPE(lsp) = TOKEN_INVALID;
2007-02-03 10:52:36 +00:00
NEXT_CHAR (lsp); /* consume */
2005-02-04 15:39:11 +00:00
return 0;
}
2006-10-24 04:22:40 +00:00
static int read_number (ase_lsp_t* lsp, int negative)
2005-02-04 15:39:11 +00:00
{
2006-10-29 13:00:39 +00:00
ase_long_t ival = 0;
2007-02-10 13:52:41 +00:00
ase_real_t rval = .0;
2005-02-14 14:37:50 +00:00
2006-10-25 13:42:31 +00:00
do
{
2006-10-29 13:00:39 +00:00
ival = ival * 10 + (lsp->curc - ASE_T('0'));
2005-02-04 15:39:11 +00:00
TOKEN_ADD_CHAR (lsp, lsp->curc);
NEXT_CHAR (lsp);
2006-10-25 13:42:31 +00:00
}
2007-02-10 13:52:41 +00:00
while (ASE_LSP_ISDIGIT(lsp, lsp->curc));
2005-02-04 15:39:11 +00:00
2005-09-20 11:19:15 +00:00
/* TODO: extend parsing floating point number */
2006-10-25 13:42:31 +00:00
if (lsp->curc == ASE_T('.'))
{
ase_real_t fraction = 0.1;
2005-02-14 14:37:50 +00:00
2005-09-20 11:19:15 +00:00
NEXT_CHAR (lsp);
2006-10-29 13:00:39 +00:00
rval = (ase_real_t)ival;
2005-09-20 11:19:15 +00:00
2006-10-26 08:17:38 +00:00
while (ASE_LSP_ISDIGIT(lsp, lsp->curc))
2006-10-25 13:42:31 +00:00
{
2006-10-29 13:00:39 +00:00
rval += (ase_real_t)(lsp->curc - ASE_T('0')) * fraction;
2005-09-20 11:19:15 +00:00
fraction *= 0.1;
NEXT_CHAR (lsp);
}
2005-02-04 15:39:11 +00:00
2006-10-29 13:00:39 +00:00
TOKEN_RVAL(lsp) = rval;
2005-09-20 11:19:15 +00:00
TOKEN_TYPE(lsp) = TOKEN_REAL;
2006-10-29 13:00:39 +00:00
if (negative) rval *= -1;
2005-09-20 11:19:15 +00:00
}
2007-02-10 13:52:41 +00:00
else
{
2006-10-29 13:00:39 +00:00
TOKEN_IVAL(lsp) = ival;
2005-09-20 11:19:15 +00:00
TOKEN_TYPE(lsp) = TOKEN_INT;
2006-10-29 13:00:39 +00:00
if (negative) ival *= -1;
2005-09-20 11:19:15 +00:00
}
2005-02-04 15:39:11 +00:00
return 0;
}
2006-10-26 14:22:01 +00:00
2006-10-24 04:22:40 +00:00
static int read_ident (ase_lsp_t* lsp)
2005-02-04 15:39:11 +00:00
{
2006-10-26 08:17:38 +00:00
do
{
2005-02-04 15:39:11 +00:00
TOKEN_ADD_CHAR (lsp, lsp->curc);
NEXT_CHAR (lsp);
2006-10-26 08:17:38 +00:00
}
while (ASE_LSP_ISALNUM(lsp,lsp->curc) || IS_IDENT(lsp->curc));
2005-02-04 15:39:11 +00:00
TOKEN_TYPE(lsp) = TOKEN_IDENT;
return 0;
}
2006-10-24 04:22:40 +00:00
static int read_string (ase_lsp_t* lsp)
2005-02-04 15:39:11 +00:00
{
2007-02-10 13:52:41 +00:00
ase_cint_t c;
2005-02-04 15:39:11 +00:00
int escaped = 0;
2007-02-10 13:52:41 +00:00
int digit_count = 0;
ase_cint_t c_acc = 0;
2005-02-04 15:39:11 +00:00
2007-02-10 13:52:41 +00:00
while (1)
2006-10-26 08:17:38 +00:00
{
2007-02-10 13:52:41 +00:00
NEXT_CHAR_TO (lsp, c);
2005-02-04 15:39:11 +00:00
2007-02-10 13:52:41 +00:00
if (c == ASE_CHAR_EOF)
2006-10-26 08:17:38 +00:00
{
2007-02-11 07:36:55 +00:00
ase_lsp_seterror (lsp, ASE_LSP_EENDSTR, ASE_NULL, 0);
2007-02-10 13:52:41 +00:00
return -1;
2005-02-04 15:39:11 +00:00
}
2007-02-10 13:52:41 +00:00
if (escaped == 3)
2006-10-26 08:17:38 +00:00
{
2007-02-10 13:52:41 +00:00
if (c >= ASE_T('0') && c <= ASE_T('7'))
{
c_acc = c_acc * 8 + c - ASE_T('0');
digit_count++;
if (digit_count >= escaped)
{
TOKEN_ADD_CHAR (lsp, c_acc);
escaped = 0;
}
continue;
}
else
{
TOKEN_ADD_CHAR (lsp, c_acc);
escaped = 0;
}
2005-02-04 15:39:11 +00:00
}
2007-02-10 13:52:41 +00:00
else if (escaped == 2 || escaped == 4 || escaped == 8)
2006-10-26 08:17:38 +00:00
{
2007-02-10 13:52:41 +00:00
if (c >= ASE_T('0') && c <= ASE_T('9'))
2006-10-26 08:17:38 +00:00
{
2007-02-10 13:52:41 +00:00
c_acc = c_acc * 16 + c - ASE_T('0');
digit_count++;
if (digit_count >= escaped)
{
TOKEN_ADD_CHAR (lsp, c_acc);
escaped = 0;
}
2005-02-04 15:39:11 +00:00
continue;
}
2007-02-10 13:52:41 +00:00
else if (c >= ASE_T('A') && c <= ASE_T('F'))
2006-10-26 08:17:38 +00:00
{
2007-02-10 13:52:41 +00:00
c_acc = c_acc * 16 + c - ASE_T('A') + 10;
digit_count++;
if (digit_count >= escaped)
{
TOKEN_ADD_CHAR (lsp, c_acc);
escaped = 0;
}
continue;
}
else if (c >= ASE_T('a') && c <= ASE_T('f'))
{
c_acc = c_acc * 16 + c - ASE_T('a') + 10;
digit_count++;
if (digit_count >= escaped)
{
TOKEN_ADD_CHAR (lsp, c_acc);
escaped = 0;
}
2005-02-04 15:39:11 +00:00
continue;
}
2007-02-10 13:52:41 +00:00
else
{
ase_char_t rc;
rc = (escaped == 2)? ASE_T('x'):
(escaped == 4)? ASE_T('u'): ASE_T('U');
if (digit_count == 0) TOKEN_ADD_CHAR (lsp, rc);
else TOKEN_ADD_CHAR (lsp, c_acc);
escaped = 0;
}
}
if (escaped == 0 && c == ASE_T('\"'))
{
/* terminating quote */
/*NEXT_CHAR_TO (lsp, c);*/
NEXT_CHAR (lsp);
break;
2005-02-04 15:39:11 +00:00
}
2007-02-10 13:52:41 +00:00
if (escaped == 0 && c == ASE_T('\\'))
2006-10-26 08:17:38 +00:00
{
2005-02-04 15:39:11 +00:00
escaped = 1;
continue;
}
2007-02-10 13:52:41 +00:00
if (escaped == 1)
{
if (c == ASE_T('n')) c = ASE_T('\n');
else if (c == ASE_T('r')) c = ASE_T('\r');
else if (c == ASE_T('t')) c = ASE_T('\t');
else if (c == ASE_T('f')) c = ASE_T('\f');
else if (c == ASE_T('b')) c = ASE_T('\b');
else if (c == ASE_T('v')) c = ASE_T('\v');
else if (c == ASE_T('a')) c = ASE_T('\a');
else if (c >= ASE_T('0') && c <= ASE_T('7'))
{
escaped = 3;
digit_count = 1;
c_acc = c - ASE_T('0');
continue;
}
else if (c == ASE_T('x'))
{
escaped = 2;
digit_count = 0;
c_acc = 0;
continue;
}
#ifdef ASE_CHAR_IS_WCHAR
else if (c == ASE_T('u') && ASE_SIZEOF(ase_char_t) >= 2)
{
escaped = 4;
digit_count = 0;
c_acc = 0;
continue;
}
else if (c == ASE_T('U') && ASE_SIZEOF(ase_char_t) >= 4)
{
escaped = 8;
digit_count = 0;
c_acc = 0;
continue;
}
#endif
2005-02-04 15:39:11 +00:00
2007-02-10 13:52:41 +00:00
escaped = 0;
}
2005-02-04 15:39:11 +00:00
2007-02-10 13:52:41 +00:00
TOKEN_ADD_CHAR (lsp, c);
}
TOKEN_TYPE(lsp) = TOKEN_STRING;
2005-02-04 15:39:11 +00:00
return 0;
}