*** empty log message ***

This commit is contained in:
hyung-hwan 2006-04-05 15:56:20 +00:00
parent 2aadae710a
commit abc5ea4502
4 changed files with 97 additions and 27 deletions

View File

@ -1,5 +1,5 @@
/* /*
* $Id: awk.h,v 1.41 2006-04-04 16:03:14 bacon Exp $ * $Id: awk.h,v 1.42 2006-04-05 15:56:20 bacon Exp $
*/ */
#ifndef _XP_AWK_AWK_H_ #ifndef _XP_AWK_AWK_H_
@ -63,7 +63,10 @@ enum
XP_AWK_EDUPVAR, /* duplicate variable name */ XP_AWK_EDUPVAR, /* duplicate variable name */
XP_AWK_EDUPNAME, /* duplicate name - function, variable, etc */ XP_AWK_EDUPNAME, /* duplicate name - function, variable, etc */
XP_AWK_EUNDEF, /* undefined identifier */ XP_AWK_EUNDEF, /* undefined identifier */
XP_AWK_ELVALUE /* l-value required */ XP_AWK_ELVALUE, /* l-value required */
/* run time error */
XP_AWK_EDIVBYZERO /* divide by zero */
}; };
#ifdef __cplusplus #ifdef __cplusplus

View File

@ -1,5 +1,5 @@
/* /*
* $Id: err.c,v 1.3 2006-04-02 12:41:14 bacon Exp $ * $Id: err.c,v 1.4 2006-04-05 15:56:20 bacon Exp $
*/ */
#include <xp/awk/awk_i.h> #include <xp/awk/awk_i.h>
@ -38,7 +38,9 @@ const xp_char_t* xp_awk_geterrstr (xp_awk_t* awk)
XP_TEXT("duplicate variable name"), XP_TEXT("duplicate variable name"),
XP_TEXT("duplicate name"), XP_TEXT("duplicate name"),
XP_TEXT("undefined identifier"), XP_TEXT("undefined identifier"),
XP_TEXT("l-value required") XP_TEXT("l-value required"),
XP_TEXT("divide by zero")
}; };
if (awk->errnum >= 0 && awk->errnum < xp_countof(__errstr)) { if (awk->errnum >= 0 && awk->errnum < xp_countof(__errstr)) {

View File

@ -1,5 +1,5 @@
/* /*
* $Id: parse.c,v 1.71 2006-04-04 16:22:01 bacon Exp $ * $Id: parse.c,v 1.72 2006-04-05 15:56:20 bacon Exp $
*/ */
#include <xp/awk/awk_i.h> #include <xp/awk/awk_i.h>
@ -738,7 +738,7 @@ static xp_awk_nde_t* __parse_block (xp_awk_t* awk, xp_bool_t is_top)
block->next = XP_NULL; block->next = XP_NULL;
block->body = head; block->body = head;
/* TODO: not only local variables but also etsted blocks, /* TODO: not only local variables but also nested blocks,
unless it is part of other constructs such as if, can be promoted unless it is part of other constructs such as if, can be promoted
and merged to top-level block */ and merged to top-level block */
@ -840,7 +840,8 @@ static xp_awk_t* __collect_locals (xp_awk_t* awk, xp_size_t nlocals)
/* check if it conflicts with other local variable names */ /* check if it conflicts with other local variable names */
if (xp_awk_tab_find(&awk->parse.locals, local, if (xp_awk_tab_find(&awk->parse.locals, local,
((awk->opt.parse & XP_AWK_SHADING)? nlocals: 0)) != (xp_size_t)-1) { ((awk->opt.parse & XP_AWK_SHADING)? nlocals: 0)) != (xp_size_t)-1)
{
PANIC (awk, XP_AWK_EDUPVAR); PANIC (awk, XP_AWK_EDUPVAR);
} }
@ -1103,24 +1104,34 @@ static xp_awk_nde_t* __parse_binary_expr (
if (opcode == XP_AWK_BINOP_PLUS) l += r; if (opcode == XP_AWK_BINOP_PLUS) l += r;
else if (opcode == XP_AWK_BINOP_MINUS) l -= r; else if (opcode == XP_AWK_BINOP_MINUS) l -= r;
else if (opcode == XP_AWK_BINOP_MUL) l *= r; else if (opcode == XP_AWK_BINOP_MUL) l *= r;
else if (opcode == XP_AWK_BINOP_DIV) l /= r; else if (opcode == XP_AWK_BINOP_DIV && r != 0) l /= r;
else if (opcode == XP_AWK_BINOP_MOD) l %= r; else if (opcode == XP_AWK_BINOP_MOD && r != 0) l %= r;
else goto skip_constant_folding; else goto skip_constant_folding;
xp_awk_clrpt (right); xp_awk_clrpt (right);
((xp_awk_nde_int_t*)left)->val = l; ((xp_awk_nde_int_t*)left)->val = l;
continue; continue;
} }
/* TODO:
else if (left->type == XP_AWK_NDE_REAL && else if (left->type == XP_AWK_NDE_REAL &&
right->type == XP_AWK_NDE_REAL) right->type == XP_AWK_NDE_REAL)
{ {
xp_real_t l, r;
l = ((xp_awk_nde_real_t*)left)->val;
r = ((xp_awk_nde_real_t*)right)->val;
/* TODO: more operators */
if (opcode == XP_AWK_BINOP_PLUS) l += r;
else if (opcode == XP_AWK_BINOP_MINUS) l -= r;
else if (opcode == XP_AWK_BINOP_MUL) l *= r;
else if (opcode == XP_AWK_BINOP_DIV) l /= r;
else goto skip_constant_folding;
xp_awk_clrpt (right);
((xp_awk_nde_real_t*)left)->val = l;
continue;
} }
else if (left->type == XP_AWK_NDE_STR && // TODO: enhance constant folding more...
right->type == XP_AWK_NDE_STR)
{
// TODO: string concatenation operator....
} */
skip_constant_folding: skip_constant_folding:
nde = (xp_awk_nde_exp_t*)xp_malloc(xp_sizeof(xp_awk_nde_exp_t)); nde = (xp_awk_nde_exp_t*)xp_malloc(xp_sizeof(xp_awk_nde_exp_t));
@ -1362,7 +1373,8 @@ static xp_awk_nde_t* __parse_increment (xp_awk_t* awk)
static xp_awk_nde_t* __parse_primary (xp_awk_t* awk) static xp_awk_nde_t* __parse_primary (xp_awk_t* awk)
{ {
if (MATCH(awk,TOKEN_IDENT)) { if (MATCH(awk,TOKEN_IDENT))
{
xp_char_t* name_dup; xp_char_t* name_dup;
name_dup = (xp_char_t*)xp_strdup(XP_STR_BUF(&awk->token.name)); name_dup = (xp_char_t*)xp_strdup(XP_STR_BUF(&awk->token.name));
@ -1480,7 +1492,8 @@ 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_REAL)) { else if (MATCH(awk,TOKEN_REAL))
{
xp_awk_nde_real_t* nde; xp_awk_nde_real_t* nde;
nde = (xp_awk_nde_real_t*) nde = (xp_awk_nde_real_t*)
@ -1503,7 +1516,8 @@ 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_STRING))
{
xp_awk_nde_str_t* nde; xp_awk_nde_str_t* nde;
nde = (xp_awk_nde_str_t*)xp_malloc(xp_sizeof(xp_awk_nde_str_t)); nde = (xp_awk_nde_str_t*)xp_malloc(xp_sizeof(xp_awk_nde_str_t));
@ -2476,11 +2490,11 @@ static int __get_number (xp_awk_t* awk)
else if (c != '.') else if (c != '.')
{ {
/* octal number */ /* octal number */
do while (c >= XP_CHAR('0') && c <= XP_CHAR('7'))
{ {
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('7')); }
return 0; return 0;
} }

View File

@ -1,5 +1,5 @@
/* /*
* $Id: run.c,v 1.34 2006-04-04 06:26:56 bacon Exp $ * $Id: run.c,v 1.35 2006-04-05 15:56:20 bacon Exp $
*/ */
#include <xp/awk/awk_i.h> #include <xp/awk/awk_i.h>
@ -26,6 +26,9 @@
#define EXIT_FUNCTION 3 #define EXIT_FUNCTION 3
#define EXIT_GLOBAL 4 #define EXIT_GLOBAL 4
#define PANIC(awk,code) \
do { (awk)->errnum = (code); return XP_NULL; } while (0)
static int __run_block (xp_awk_t* awk, xp_awk_nde_blk_t* nde); static int __run_block (xp_awk_t* awk, xp_awk_nde_blk_t* nde);
static int __run_statement (xp_awk_t* awk, xp_awk_nde_t* nde); static int __run_statement (xp_awk_t* awk, xp_awk_nde_t* nde);
static int __run_if_statement (xp_awk_t* awk, xp_awk_nde_if_t* nde); static int __run_if_statement (xp_awk_t* awk, xp_awk_nde_if_t* nde);
@ -1067,12 +1070,50 @@ static xp_awk_val_t* __eval_binop_div (
if (left->type == XP_AWK_VAL_INT && if (left->type == XP_AWK_VAL_INT &&
right->type == XP_AWK_VAL_INT) right->type == XP_AWK_VAL_INT)
{ {
xp_long_t r = xp_long_t r;
((xp_awk_val_int_t*)left)->val /
((xp_awk_val_int_t*)right)->val; if (((xp_awk_val_int_t*)right)->val == 0)
{
PANIC (awk, XP_AWK_EDIVBYZERO);
}
r = ((xp_awk_val_int_t*)left)->val /
((xp_awk_val_int_t*)right)->val;
res = xp_awk_makeintval (awk, r); res = xp_awk_makeintval (awk, r);
// TOOD: error handling // TOOD: error handling
} }
else if (left->type == XP_AWK_VAL_REAL &&
right->type == XP_AWK_VAL_REAL)
{
xp_real_t r;
r = ((xp_awk_val_real_t*)left)->val /
((xp_awk_val_real_t*)right)->val;
res = xp_awk_makerealval (awk, r);
// TOOD: error handling
}
else if (left->type == XP_AWK_VAL_INT &&
right->type == XP_AWK_VAL_REAL)
{
xp_real_t r;
r = ((xp_awk_val_int_t*)left)->val /
((xp_awk_val_real_t*)right)->val;
res = xp_awk_makerealval (awk, r);
}
else if (left->type == XP_AWK_VAL_REAL &&
right->type == XP_AWK_VAL_INT)
{
xp_real_t r;
r = ((xp_awk_val_real_t*)left)->val /
((xp_awk_val_int_t*)right)->val;
res = xp_awk_makerealval (awk, r);
}
else
{
// TODO: invalid operands for div
}
return res; return res;
} }
@ -1085,12 +1126,22 @@ static xp_awk_val_t* __eval_binop_mod (
if (left->type == XP_AWK_VAL_INT && if (left->type == XP_AWK_VAL_INT &&
right->type == XP_AWK_VAL_INT) right->type == XP_AWK_VAL_INT)
{ {
xp_long_t r = xp_long_t r;
((xp_awk_val_int_t*)left)->val %
((xp_awk_val_int_t*)right)->val; if (((xp_awk_val_int_t*)right)->val == 0)
{
PANIC (awk, XP_AWK_EDIVBYZERO);
}
r = ((xp_awk_val_int_t*)left)->val %
((xp_awk_val_int_t*)right)->val;
res = xp_awk_makeintval (awk, r); res = xp_awk_makeintval (awk, r);
// TOOD: error handling // TOOD: error handling
} }
else
{
// TODO: mod is only for integers
}
return res; return res;
} }