*** empty log message ***

This commit is contained in:
hyung-hwan 2006-04-07 04:23:11 +00:00
parent 11c34a6b0e
commit 3acfc556bd
6 changed files with 143 additions and 82 deletions

View File

@ -1,5 +1,5 @@
/* /*
* $Id: awk.h,v 1.43 2006-04-06 16:25:37 bacon Exp $ * $Id: awk.h,v 1.44 2006-04-07 04:23:11 bacon Exp $
*/ */
#ifndef _XP_AWK_AWK_H_ #ifndef _XP_AWK_AWK_H_
@ -28,7 +28,8 @@ enum
XP_AWK_EXPLICIT = (1 << 1), /* variable requires explicit declaration */ XP_AWK_EXPLICIT = (1 << 1), /* variable requires explicit declaration */
XP_AWK_UNIQUE = (1 << 2), /* a function name should not coincide to be a variable name */ XP_AWK_UNIQUE = (1 << 2), /* a function name should not coincide to be a variable name */
XP_AWK_SHADING = (1 << 3), /* allow variable shading */ XP_AWK_SHADING = (1 << 3), /* allow variable shading */
XP_AWK_SHIFT = (1 << 4) /* support shift operators */ XP_AWK_SHIFT = (1 << 4), /* support shift operators */
XP_AWK_HASHSIGN = (1 << 5) /* support comments by a hash sign */
}; };
/* error code */ /* error code */
@ -45,6 +46,7 @@ enum
XP_AWK_ELXUNG, /* lexer failed to unget a character */ XP_AWK_ELXUNG, /* lexer failed to unget a character */
XP_AWK_EENDSRC, /* unexpected end of source */ XP_AWK_EENDSRC, /* unexpected end of source */
XP_AWK_EENDSTR, /* unexpected end of a string */
XP_AWK_ELBRACE, /* left brace expected */ XP_AWK_ELBRACE, /* left brace expected */
XP_AWK_ELPAREN, /* left parenthesis expected */ XP_AWK_ELPAREN, /* left parenthesis expected */
XP_AWK_ERPAREN, /* right parenthesis expected */ XP_AWK_ERPAREN, /* right parenthesis expected */

View File

@ -1,5 +1,5 @@
/* /*
* $Id: err.c,v 1.5 2006-04-06 16:25:37 bacon Exp $ * $Id: err.c,v 1.6 2006-04-07 04:23:11 bacon Exp $
*/ */
#include <xp/awk/awk_i.h> #include <xp/awk/awk_i.h>
@ -20,7 +20,9 @@ const xp_char_t* xp_awk_geterrstr (xp_awk_t* awk)
XP_TEXT("cannot read source"), XP_TEXT("cannot read source"),
XP_TEXT("invalid character"), XP_TEXT("invalid character"),
XP_TEXT("cannot unget character"), XP_TEXT("cannot unget character"),
XP_TEXT("unexpected end of source"), XP_TEXT("unexpected end of source"),
XP_TEXT("unexpected end of a string"),
XP_TEXT("left brace expected"), XP_TEXT("left brace expected"),
XP_TEXT("left parenthesis expected"), XP_TEXT("left parenthesis expected"),
XP_TEXT("right parenthesis expected"), XP_TEXT("right parenthesis expected"),

View File

@ -1,5 +1,5 @@
/* /*
* $Id: parse.c,v 1.72 2006-04-05 15:56:20 bacon Exp $ * $Id: parse.c,v 1.73 2006-04-07 04:23:11 bacon Exp $
*/ */
#include <xp/awk/awk_i.h> #include <xp/awk/awk_i.h>
@ -55,7 +55,7 @@ enum
TOKEN_INT, TOKEN_INT,
TOKEN_REAL, TOKEN_REAL,
TOKEN_STRING, TOKEN_STR,
TOKEN_REGEX, TOKEN_REGEX,
TOKEN_IDENT, TOKEN_IDENT,
@ -144,6 +144,7 @@ static xp_awk_nde_t* __parse_nextfile (xp_awk_t* awk);
static int __get_token (xp_awk_t* awk); static int __get_token (xp_awk_t* awk);
static int __get_number (xp_awk_t* awk); static int __get_number (xp_awk_t* awk);
static int __get_string (xp_awk_t* awk);
static int __get_char (xp_awk_t* awk); static int __get_char (xp_awk_t* awk);
static int __unget_char (xp_awk_t* awk, xp_cint_t c); static int __unget_char (xp_awk_t* awk, xp_cint_t c);
static int __skip_spaces (xp_awk_t* awk); static int __skip_spaces (xp_awk_t* awk);
@ -1516,7 +1517,7 @@ static xp_awk_nde_t* __parse_primary (xp_awk_t* awk)
return (xp_awk_nde_t*)nde; return (xp_awk_nde_t*)nde;
} }
else if (MATCH(awk,TOKEN_STRING)) else if (MATCH(awk,TOKEN_STR))
{ {
xp_awk_nde_str_t* nde; xp_awk_nde_str_t* nde;
@ -2165,10 +2166,12 @@ static int __get_token (xp_awk_t* awk)
xp_cint_t c; xp_cint_t c;
int n; int n;
do { do
{
if (__skip_spaces(awk) == -1) return -1; if (__skip_spaces(awk) == -1) return -1;
if ((n = __skip_comment(awk)) == -1) return -1; if ((n = __skip_comment(awk)) == -1) return -1;
} while (n == 1); }
while (n == 1);
xp_str_clear (&awk->token.name); xp_str_clear (&awk->token.name);
c = awk->lex.curc; c = awk->lex.curc;
@ -2184,25 +2187,34 @@ static int __get_token (xp_awk_t* awk)
else if (xp_isalpha(c) || c == XP_CHAR('_')) else if (xp_isalpha(c) || c == XP_CHAR('_'))
{ {
/* identifier */ /* identifier */
do { do
{
ADD_TOKEN_CHAR (awk, c); ADD_TOKEN_CHAR (awk, c);
GET_CHAR_TO (awk, c); GET_CHAR_TO (awk, c);
} while (xp_isalpha(c) || c == XP_CHAR('_') || xp_isdigit(c)); }
while (xp_isalpha(c) || c == XP_CHAR('_') || xp_isdigit(c));
SET_TOKEN_TYPE (awk, __classify_ident(awk, XP_STR_BUF(&awk->token.name))); SET_TOKEN_TYPE (awk, __classify_ident(awk, XP_STR_BUF(&awk->token.name)));
} }
else if (c == XP_CHAR('\"')) else if (c == XP_CHAR('\"'))
{ {
/* string */ SET_TOKEN_TYPE (awk, TOKEN_STR);
GET_CHAR_TO (awk, c);
do {
ADD_TOKEN_CHAR (awk, c);
GET_CHAR_TO (awk, c);
} while (c != XP_CHAR('\"'));
SET_TOKEN_TYPE (awk, TOKEN_STRING); if (__get_string(awk) == -1) return -1;
GET_CHAR_TO (awk, c); while (1)
// TODO: enhance string handling including escaping {
do
{
if (__skip_spaces(awk) == -1) return -1;
if ((n = __skip_comment(awk)) == -1) return -1;
}
while (n == 1);
c = awk->lex.curc;
if (c != XP_CHAR('\"')) break;
if (__get_string(awk) == -1) return -1;
}
} }
else if (c == XP_CHAR('=')) else if (c == XP_CHAR('='))
{ {
@ -2333,10 +2345,6 @@ static int __get_token (xp_awk_t* awk)
ADD_TOKEN_STR (awk, XP_TEXT("+=")); ADD_TOKEN_STR (awk, XP_TEXT("+="));
GET_CHAR_TO (awk, c); GET_CHAR_TO (awk, c);
} }
else if (xp_isdigit(c))
{
// read_number (XP_CHAR('+'));
}
else else
{ {
SET_TOKEN_TYPE (awk, TOKEN_PLUS); SET_TOKEN_TYPE (awk, TOKEN_PLUS);
@ -2358,11 +2366,6 @@ static int __get_token (xp_awk_t* awk)
ADD_TOKEN_STR (awk, XP_TEXT("-=")); ADD_TOKEN_STR (awk, XP_TEXT("-="));
GET_CHAR_TO (awk, c); GET_CHAR_TO (awk, c);
} }
else if (xp_isdigit(c))
{
// TODO...
// read_number (XP_CHAR('-'));
}
else else
{ {
SET_TOKEN_TYPE (awk, TOKEN_MINUS); SET_TOKEN_TYPE (awk, TOKEN_MINUS);
@ -2472,7 +2475,8 @@ static int __get_number (xp_awk_t* awk)
{ {
ADD_TOKEN_CHAR (awk, c); ADD_TOKEN_CHAR (awk, c);
GET_CHAR_TO (awk, c); GET_CHAR_TO (awk, c);
} while (xp_isxdigit(c)); }
while (xp_isxdigit(c));
return 0; return 0;
} }
@ -2483,7 +2487,8 @@ static int __get_number (xp_awk_t* awk)
{ {
ADD_TOKEN_CHAR (awk, c); ADD_TOKEN_CHAR (awk, c);
GET_CHAR_TO (awk, c); GET_CHAR_TO (awk, c);
} while (c == XP_CHAR('0') || c == XP_CHAR('1')); }
while (c == XP_CHAR('0') || c == XP_CHAR('1'));
return 0; return 0;
} }
@ -2544,6 +2549,49 @@ static int __get_number (xp_awk_t* awk)
return 0; return 0;
} }
static int __get_string (xp_awk_t* awk)
{
xp_cint_t c;
xp_bool_t escaped = xp_false;
GET_CHAR_TO (awk, c);
while (1)
{
if (c == XP_CHAR_EOF)
{
awk->errnum = XP_AWK_EENDSTR;
return -1;
}
if (escaped == xp_false && c == XP_CHAR('\"'))
{
GET_CHAR_TO (awk, c);
break;
}
if (escaped == xp_false && c == XP_CHAR('\\'))
{
GET_CHAR_TO (awk, c);
escaped = xp_true;
continue;
}
if (escaped == xp_true)
{
if (c == XP_CHAR('n')) c = XP_CHAR('\n');
else if (c == XP_CHAR('r')) c = XP_CHAR('\r');
else if (c == XP_CHAR('t')) c = XP_CHAR('\t');
/* TODO: more escape characters */
escaped = xp_false;
}
ADD_TOKEN_CHAR (awk, c);
GET_CHAR_TO (awk, c);
}
return 0;
}
static int __get_char (xp_awk_t* awk) static int __get_char (xp_awk_t* awk)
{ {
xp_ssize_t n; xp_ssize_t n;
@ -2589,20 +2637,36 @@ static int __skip_comment (xp_awk_t* awk)
{ {
xp_cint_t c = awk->lex.curc; xp_cint_t c = awk->lex.curc;
if (c != XP_CHAR('/')) return 0; if ((awk->opt.parse & XP_AWK_HASHSIGN) && c == XP_CHAR('#'))
{
do
{
GET_CHAR_TO (awk, c);
}
while (c != '\n' && c != XP_CHAR_EOF);
GET_CHAR (awk);
return 1; /* comment by # */
}
if (c != XP_CHAR('/')) return 0; /* not a comment */
GET_CHAR_TO (awk, c); GET_CHAR_TO (awk, c);
if (c == XP_CHAR('/')) if (c == XP_CHAR('/'))
{ {
do { do
{
GET_CHAR_TO (awk, c); GET_CHAR_TO (awk, c);
} while (c != '\n' && c != XP_CHAR_EOF); }
while (c != '\n' && c != XP_CHAR_EOF);
GET_CHAR (awk); GET_CHAR (awk);
return 1; return 1; /* comment by // */
} }
else if (c == XP_CHAR('*')) else if (c == XP_CHAR('*'))
{ {
do { do
{
GET_CHAR_TO (awk, c); GET_CHAR_TO (awk, c);
if (c == XP_CHAR('*')) if (c == XP_CHAR('*'))
{ {
@ -2613,11 +2677,13 @@ static int __skip_comment (xp_awk_t* awk)
break; break;
} }
} }
} while (0); }
return 1; while (1);
return 1; /* c-style comment */
} }
if (__unget_char(awk, c) == -1) return -1; if (__unget_char(awk,c) == -1) return -1; /* error */
awk->lex.curc = XP_CHAR('/'); awk->lex.curc = XP_CHAR('/');
return 0; return 0;

View File

@ -1,5 +1,5 @@
/* /*
* $Id: run.c,v 1.36 2006-04-06 16:25:37 bacon Exp $ * $Id: run.c,v 1.37 2006-04-07 04:23:11 bacon Exp $
*/ */
#include <xp/awk/awk_i.h> #include <xp/awk/awk_i.h>
@ -271,7 +271,7 @@ static int __run_if_statement (xp_awk_t* awk, xp_awk_nde_if_t* nde)
if (test == XP_NULL) return -1; if (test == XP_NULL) return -1;
xp_awk_refupval (test); xp_awk_refupval (test);
if (xp_awk_isvaltrue(test)) if (xp_awk_boolval(test))
{ {
n = __run_statement (awk, nde->then_part); n = __run_statement (awk, nde->then_part);
} }
@ -297,7 +297,7 @@ static int __run_while_statement (xp_awk_t* awk, xp_awk_nde_while_t* nde)
xp_awk_refupval (test); xp_awk_refupval (test);
if (xp_awk_isvaltrue(test)) if (xp_awk_boolval(test))
{ {
// TODO: break.... continue...., global exit, return... run-time abortion... // TODO: break.... continue...., global exit, return... run-time abortion...
if (__run_statement(awk,nde->body) == -1) if (__run_statement(awk,nde->body) == -1)
@ -351,7 +351,7 @@ static int __run_while_statement (xp_awk_t* awk, xp_awk_nde_while_t* nde)
if (test == XP_NULL) return -1; if (test == XP_NULL) return -1;
xp_awk_refupval (test); xp_awk_refupval (test);
if (!xp_awk_isvaltrue(test)) if (!xp_awk_boolval(test))
{ {
xp_awk_refdownval (awk, test); xp_awk_refdownval (awk, test);
break; break;
@ -381,7 +381,7 @@ static int __run_for_statement (xp_awk_t* awk, xp_awk_nde_for_t* nde)
if (test == XP_NULL) return -1; if (test == XP_NULL) return -1;
xp_awk_refupval (test); xp_awk_refupval (test);
if (xp_awk_isvaltrue(test)) if (xp_awk_boolval(test))
{ {
if (__run_statement(awk,nde->body) == -1) if (__run_statement(awk,nde->body) == -1)
{ {
@ -576,7 +576,7 @@ static xp_awk_val_t* __eval_expression (xp_awk_t* awk, xp_awk_nde_t* nde)
default: default:
/* somthing wrong. internal error */ /* somthing wrong. internal error */
/* TODO: set the error code instead of assertion below */ /* TODO: set the error code instead of assertion below */
xp_assert (XP_TEXT("should never happen") == XP_NULL); xp_assert (!"should never happen");
return XP_NULL; return XP_NULL;
} }
@ -730,19 +730,9 @@ static xp_awk_val_t* __eval_binop_lor (
{ {
xp_awk_val_t* res = XP_NULL; xp_awk_val_t* res = XP_NULL;
if (left->type == XP_AWK_VAL_INT && res = xp_awk_makeintval (awk,
right->type == XP_AWK_VAL_INT) xp_awk_boolval(left) || xp_awk_boolval(right));
{ if (res == XP_NULL) PANIC (awk, XP_AWK_ENOMEM);
xp_long_t r =
((xp_awk_val_int_t*)left)->val ||
((xp_awk_val_int_t*)right)->val;
res = xp_awk_makeintval (awk, r);
// TOOD: error handling
}
else
{
/* TODO: trigger error */
}
return res; return res;
} }
@ -752,19 +742,9 @@ static xp_awk_val_t* __eval_binop_land (
{ {
xp_awk_val_t* res = XP_NULL; xp_awk_val_t* res = XP_NULL;
if (left->type == XP_AWK_VAL_INT && res = xp_awk_makeintval (awk,
right->type == XP_AWK_VAL_INT) xp_awk_boolval(left) && xp_awk_boolval(right));
{ if (res == XP_NULL) PANIC (awk, XP_AWK_ENOMEM);
xp_long_t r =
((xp_awk_val_int_t*)left)->val &&
((xp_awk_val_int_t*)right)->val;
res = xp_awk_makeintval (awk, r);
// TOOD: error handling
}
else
{
// TODO: trigger error
}
return res; return res;
} }
@ -781,9 +761,13 @@ static xp_awk_val_t* __eval_binop_bor (
((xp_awk_val_int_t*)left)->val | ((xp_awk_val_int_t*)left)->val |
((xp_awk_val_int_t*)right)->val; ((xp_awk_val_int_t*)right)->val;
res = xp_awk_makeintval (awk, r); res = xp_awk_makeintval (awk, r);
// TOOD: error handling }
else
{
PANIC (awk, XP_AWK_EOPERAND);
} }
if (res == XP_NULL) PANIC (awk, XP_AWK_ENOMEM);
return res; return res;
} }
@ -799,9 +783,13 @@ static xp_awk_val_t* __eval_binop_bxor (
((xp_awk_val_int_t*)left)->val ^ ((xp_awk_val_int_t*)left)->val ^
((xp_awk_val_int_t*)right)->val; ((xp_awk_val_int_t*)right)->val;
res = xp_awk_makeintval (awk, r); res = xp_awk_makeintval (awk, r);
// TOOD: error handling }
else
{
PANIC (awk, XP_AWK_EOPERAND);
} }
if (res == XP_NULL) PANIC (awk, XP_AWK_ENOMEM);
return res; return res;
} }
@ -817,9 +805,13 @@ static xp_awk_val_t* __eval_binop_band (
((xp_awk_val_int_t*)left)->val & ((xp_awk_val_int_t*)left)->val &
((xp_awk_val_int_t*)right)->val; ((xp_awk_val_int_t*)right)->val;
res = xp_awk_makeintval (awk, r); res = xp_awk_makeintval (awk, r);
// TOOD: error handling }
else
{
PANIC (awk, XP_AWK_EOPERAND);
} }
if (res == XP_NULL) PANIC (awk, XP_AWK_ENOMEM);
return res; return res;
} }

View File

@ -1,5 +1,5 @@
/* /*
* $Id: val.c,v 1.16 2006-04-06 16:25:37 bacon Exp $ * $Id: val.c,v 1.17 2006-04-07 04:23:11 bacon Exp $
*/ */
#include <xp/awk/awk_i.h> #include <xp/awk/awk_i.h>
@ -232,7 +232,7 @@ xp_awk_val_t* xp_awk_cloneval (xp_awk_t* awk, xp_awk_val_t* val)
return XP_NULL; return XP_NULL;
} }
xp_bool_t xp_awk_isvaltrue (xp_awk_val_t* val) xp_bool_t xp_awk_boolval (xp_awk_val_t* val)
{ {
if (val == XP_NULL) return xp_false; if (val == XP_NULL) return xp_false;
@ -241,15 +241,14 @@ xp_bool_t xp_awk_isvaltrue (xp_awk_val_t* val)
case XP_AWK_VAL_NIL: case XP_AWK_VAL_NIL:
return xp_false; return xp_false;
case XP_AWK_VAL_INT: case XP_AWK_VAL_INT:
return (((xp_awk_val_int_t*)val)->val == 0)? xp_false: xp_true; return ((xp_awk_val_int_t*)val)->val != 0;
case XP_AWK_VAL_REAL: case XP_AWK_VAL_REAL:
return (((xp_awk_val_real_t*)val)->val == 0.0)? xp_false: xp_true; return ((xp_awk_val_real_t*)val)->val != 0.0;
case XP_AWK_VAL_STR: case XP_AWK_VAL_STR:
/* TODO: decide what to do */ return ((xp_awk_val_str_t*)val)->len > 0;
return (((xp_awk_val_str_t*)val)->len == 0)? xp_false: xp_true;
} }
/* this should never happen */ xp_assert (!"should never happen");
return xp_false; return xp_false;
} }

View File

@ -1,5 +1,5 @@
/* /*
* $Id: val.h,v 1.13 2006-04-06 16:25:37 bacon Exp $ * $Id: val.h,v 1.14 2006-04-07 04:23:11 bacon Exp $
*/ */
#ifndef _XP_AWK_VAL_H_ #ifndef _XP_AWK_VAL_H_
@ -90,7 +90,7 @@ void xp_awk_refdownval (xp_awk_t* awk, xp_awk_val_t* val);
void xp_awk_refdownval_nofree (xp_awk_t* awk, xp_awk_val_t* val); void xp_awk_refdownval_nofree (xp_awk_t* awk, xp_awk_val_t* val);
xp_awk_val_t* xp_awk_cloneval (xp_awk_t* awk, xp_awk_val_t* val); xp_awk_val_t* xp_awk_cloneval (xp_awk_t* awk, xp_awk_val_t* val);
xp_bool_t xp_awk_isvaltrue (xp_awk_val_t* val); xp_bool_t xp_awk_boolval (xp_awk_val_t* val);
void xp_awk_printval (xp_awk_val_t* val); void xp_awk_printval (xp_awk_val_t* val);
#ifdef __cplusplus #ifdef __cplusplus