enhanced error handling for shorter code in some functions of qse_awk_t

This commit is contained in:
hyung-hwan 2011-07-26 02:25:13 +00:00
parent 6ac70e5958
commit f43799a68c

View File

@ -1,5 +1,5 @@
/* /*
* $Id: parse.c 520 2011-07-25 07:32:49Z hyunghwan.chung $ * $Id: parse.c 521 2011-07-25 08:25:13Z hyunghwan.chung $
* *
Copyright 2006-2011 Chung, Hyung-Hwan. Copyright 2006-2011 Chung, Hyung-Hwan.
This file is part of QSE. This file is part of QSE.
@ -2055,10 +2055,10 @@ static qse_awk_t* collect_locals (
static qse_awk_nde_t* parse_if (qse_awk_t* awk, const qse_awk_loc_t* xloc) static qse_awk_nde_t* parse_if (qse_awk_t* awk, const qse_awk_loc_t* xloc)
{ {
qse_awk_nde_t* test; qse_awk_nde_t* test = QSE_NULL;
qse_awk_nde_t* then_part; qse_awk_nde_t* then_part = QSE_NULL;
qse_awk_nde_t* else_part; qse_awk_nde_t* else_part = QSE_NULL;
qse_awk_nde_if_t* nde; qse_awk_nde_if_t* nde_if;
qse_awk_loc_t eloc, tloc; qse_awk_loc_t eloc, tloc;
if (!MATCH(awk,TOK_LPAREN)) if (!MATCH(awk,TOK_LPAREN))
@ -2070,81 +2070,59 @@ static qse_awk_nde_t* parse_if (qse_awk_t* awk, const qse_awk_loc_t* xloc)
eloc = awk->tok.loc; eloc = awk->tok.loc;
test = parse_expr_dc (awk, &eloc); test = parse_expr_dc (awk, &eloc);
if (test == QSE_NULL) return QSE_NULL; if (test == QSE_NULL) goto oops;
if (!MATCH(awk,TOK_RPAREN)) if (!MATCH(awk,TOK_RPAREN))
{ {
qse_awk_clrpt (awk, test);
SETERR_TOK (awk, QSE_AWK_ERPAREN); SETERR_TOK (awk, QSE_AWK_ERPAREN);
return QSE_NULL; goto oops;
} }
if (get_token(awk) <= -1) if (get_token(awk) <= -1) goto oops;
{
qse_awk_clrpt (awk, test);
return QSE_NULL;
}
tloc = awk->tok.loc; tloc = awk->tok.loc;
then_part = parse_statement (awk, &tloc); then_part = parse_statement (awk, &tloc);
if (then_part == QSE_NULL) if (then_part == QSE_NULL) goto oops;
{
qse_awk_clrpt (awk, test);
return QSE_NULL;
}
/* skip any new lines before the else block */ /* skip any new lines before the else block */
while (MATCH(awk,TOK_NEWLINE)) while (MATCH(awk,TOK_NEWLINE))
{ {
if (get_token(awk) <= -1) if (get_token(awk) <= -1) goto oops;
{
qse_awk_clrpt (awk, then_part);
qse_awk_clrpt (awk, test);
return QSE_NULL;
}
} }
if (MATCH(awk,TOK_ELSE)) if (MATCH(awk,TOK_ELSE))
{ {
if (get_token(awk) <= -1) if (get_token(awk) <= -1) goto oops;
{
qse_awk_clrpt (awk, then_part);
qse_awk_clrpt (awk, test);
return QSE_NULL;
}
{ {
qse_awk_loc_t eloc = awk->tok.loc; qse_awk_loc_t eloc = awk->tok.loc;
else_part = parse_statement (awk, &eloc); else_part = parse_statement (awk, &eloc);
} if (else_part == QSE_NULL) goto oops;
if (else_part == QSE_NULL)
{
qse_awk_clrpt (awk, then_part);
qse_awk_clrpt (awk, test);
return QSE_NULL;
} }
} }
else else_part = QSE_NULL;
nde = (qse_awk_nde_if_t*) nde_if = (qse_awk_nde_if_t*)
QSE_AWK_ALLOC (awk, QSE_SIZEOF(qse_awk_nde_if_t)); QSE_AWK_ALLOC (awk, QSE_SIZEOF(*nde_if));
if (nde == QSE_NULL) if (nde_if == QSE_NULL)
{ {
qse_awk_clrpt (awk, else_part);
qse_awk_clrpt (awk, then_part);
qse_awk_clrpt (awk, test);
SETERR_LOC (awk, QSE_AWK_ENOMEM, xloc); SETERR_LOC (awk, QSE_AWK_ENOMEM, xloc);
return QSE_NULL; goto oops;
} }
nde->type = QSE_AWK_NDE_IF; nde_if->type = QSE_AWK_NDE_IF;
nde->loc = *xloc; nde_if->loc = *xloc;
nde->next = QSE_NULL; nde_if->next = QSE_NULL;
nde->test = test; nde_if->test = test;
nde->then_part = then_part; nde_if->then_part = then_part;
nde->else_part = else_part; nde_if->else_part = else_part;
return (qse_awk_nde_t*)nde; return (qse_awk_nde_t*)nde_if;
oops:
if (else_part) qse_awk_clrpt (awk, else_part);
if (then_part) qse_awk_clrpt (awk, then_part);
if (test) qse_awk_clrpt (awk, test);
return QSE_NULL;
} }
static qse_awk_nde_t* parse_while (qse_awk_t* awk, const qse_awk_loc_t* xloc) static qse_awk_nde_t* parse_while (qse_awk_t* awk, const qse_awk_loc_t* xloc)
@ -2209,9 +2187,10 @@ static qse_awk_nde_t* parse_while (qse_awk_t* awk, const qse_awk_loc_t* xloc)
static qse_awk_nde_t* parse_for (qse_awk_t* awk, const qse_awk_loc_t* xloc) static qse_awk_nde_t* parse_for (qse_awk_t* awk, const qse_awk_loc_t* xloc)
{ {
qse_awk_nde_t* init, * test, * incr, * body; qse_awk_nde_t* init = QSE_NULL, * test = QSE_NULL;
qse_awk_nde_for_t* nde; qse_awk_nde_t* incr = QSE_NULL, * body = QSE_NULL;
qse_awk_nde_foreach_t* nde2; qse_awk_nde_for_t* nde_for;
qse_awk_nde_foreach_t* nde_foreach;
if (!MATCH(awk,TOK_LPAREN)) if (!MATCH(awk,TOK_LPAREN))
{ {
@ -2220,8 +2199,7 @@ static qse_awk_nde_t* parse_for (qse_awk_t* awk, const qse_awk_loc_t* xloc)
} }
if (get_token(awk) <= -1) return QSE_NULL; if (get_token(awk) <= -1) return QSE_NULL;
if (MATCH(awk,TOK_SEMICOLON)) init = QSE_NULL; if (!MATCH(awk,TOK_SEMICOLON))
else
{ {
/* this line is very ugly. it checks the entire next /* this line is very ugly. it checks the entire next
* expression or the first element in the expression * expression or the first element in the expression
@ -2231,8 +2209,8 @@ static qse_awk_nde_t* parse_for (qse_awk_t* awk, const qse_awk_loc_t* xloc)
{ {
qse_awk_loc_t eloc = awk->tok.loc; qse_awk_loc_t eloc = awk->tok.loc;
init = parse_expr_dc (awk, &eloc); init = parse_expr_dc (awk, &eloc);
if (init == QSE_NULL) goto oops;
} }
if (init == QSE_NULL) return QSE_NULL;
if (!no_foreach && init->type == QSE_AWK_NDE_EXP_BIN && if (!no_foreach && init->type == QSE_AWK_NDE_EXP_BIN &&
((qse_awk_nde_exp_t*)init)->opcode == QSE_AWK_BINOP_IN && ((qse_awk_nde_exp_t*)init)->opcode == QSE_AWK_BINOP_IN &&
@ -2242,168 +2220,118 @@ static qse_awk_nde_t* parse_for (qse_awk_t* awk, const qse_awk_loc_t* xloc)
if (!MATCH(awk,TOK_RPAREN)) if (!MATCH(awk,TOK_RPAREN))
{ {
qse_awk_clrpt (awk, init);
SETERR_TOK (awk, QSE_AWK_ERPAREN); SETERR_TOK (awk, QSE_AWK_ERPAREN);
return QSE_NULL; goto oops;
} }
if (get_token(awk) <= -1) if (get_token(awk) <= -1) goto oops;
{
qse_awk_clrpt (awk, init);
return QSE_NULL;
}
{ {
qse_awk_loc_t floc = awk->tok.loc; qse_awk_loc_t floc = awk->tok.loc;
body = parse_statement (awk, &floc); body = parse_statement (awk, &floc);
} if (body == QSE_NULL) goto oops;
if (body == QSE_NULL)
{
qse_awk_clrpt (awk, init);
return QSE_NULL;
} }
nde2 = (qse_awk_nde_foreach_t*) QSE_AWK_ALLOC ( nde_foreach = (qse_awk_nde_foreach_t*) QSE_AWK_ALLOC (
awk, QSE_SIZEOF(qse_awk_nde_foreach_t)); awk, QSE_SIZEOF(*nde_foreach));
if (nde2 == QSE_NULL) if (nde_foreach == QSE_NULL)
{ {
qse_awk_clrpt (awk, init);
qse_awk_clrpt (awk, body);
SETERR_LOC (awk, QSE_AWK_ENOMEM, xloc); SETERR_LOC (awk, QSE_AWK_ENOMEM, xloc);
return QSE_NULL; goto oops;
} }
nde2->type = QSE_AWK_NDE_FOREACH; nde_foreach->type = QSE_AWK_NDE_FOREACH;
nde2->loc = *xloc; nde_foreach->loc = *xloc;
nde2->next = QSE_NULL; nde_foreach->next = QSE_NULL;
nde2->test = init; nde_foreach->test = init;
nde2->body = body; nde_foreach->body = body;
return (qse_awk_nde_t*)nde2; return (qse_awk_nde_t*)nde_foreach;
} }
if (!MATCH(awk,TOK_SEMICOLON)) if (!MATCH(awk,TOK_SEMICOLON))
{ {
qse_awk_clrpt (awk, init);
SETERR_TOK (awk, QSE_AWK_ESCOLON); SETERR_TOK (awk, QSE_AWK_ESCOLON);
return QSE_NULL; goto oops;
} }
} }
do do
{ {
if (get_token(awk) <= -1) if (get_token(awk) <= -1) goto oops;
{
qse_awk_clrpt (awk, init);
return QSE_NULL;
}
/* skip new lines after the first semicolon */ /* skip new lines after the first semicolon */
} }
while (MATCH(awk,TOK_NEWLINE)); while (MATCH(awk,TOK_NEWLINE));
if (MATCH(awk,TOK_SEMICOLON)) test = QSE_NULL; if (!MATCH(awk,TOK_SEMICOLON))
else
{ {
{ {
qse_awk_loc_t eloc = awk->tok.loc; qse_awk_loc_t eloc = awk->tok.loc;
test = parse_expr_dc (awk, &eloc); test = parse_expr_dc (awk, &eloc);
} if (test == QSE_NULL) goto oops;
if (test == QSE_NULL)
{
qse_awk_clrpt (awk, init);
return QSE_NULL;
} }
if (!MATCH(awk,TOK_SEMICOLON)) if (!MATCH(awk,TOK_SEMICOLON))
{ {
qse_awk_clrpt (awk, init);
qse_awk_clrpt (awk, test);
SETERR_TOK (awk, QSE_AWK_ESCOLON); SETERR_TOK (awk, QSE_AWK_ESCOLON);
return QSE_NULL; goto oops;
} }
} }
do do
{ {
if (get_token(awk) <= -1) if (get_token(awk) <= -1) goto oops;
{
qse_awk_clrpt (awk, init);
qse_awk_clrpt (awk, test);
return QSE_NULL;
}
/* skip new lines after the second semicolon */ /* skip new lines after the second semicolon */
} }
while (MATCH(awk,TOK_NEWLINE)); while (MATCH(awk,TOK_NEWLINE));
if (MATCH(awk,TOK_RPAREN)) incr = QSE_NULL; if (!MATCH(awk,TOK_RPAREN))
else
{ {
{ {
qse_awk_loc_t eloc = awk->tok.loc; qse_awk_loc_t eloc = awk->tok.loc;
incr = parse_expr_dc (awk, &eloc); incr = parse_expr_dc (awk, &eloc);
} if (incr == QSE_NULL) goto oops;
if (incr == QSE_NULL)
{
qse_awk_clrpt (awk, init);
qse_awk_clrpt (awk, test);
return QSE_NULL;
} }
if (!MATCH(awk,TOK_RPAREN)) if (!MATCH(awk,TOK_RPAREN))
{ {
qse_awk_clrpt (awk, init);
qse_awk_clrpt (awk, test);
qse_awk_clrpt (awk, incr);
SETERR_TOK (awk, QSE_AWK_ERPAREN); SETERR_TOK (awk, QSE_AWK_ERPAREN);
return QSE_NULL; goto oops;
} }
} }
if (get_token(awk) <= -1) if (get_token(awk) <= -1) goto oops;
{
qse_awk_clrpt (awk, init);
qse_awk_clrpt (awk, test);
qse_awk_clrpt (awk, incr);
return QSE_NULL;
}
{ {
qse_awk_loc_t floc = awk->tok.loc; qse_awk_loc_t floc = awk->tok.loc;
body = parse_statement (awk, &floc); body = parse_statement (awk, &floc);
} if (body == QSE_NULL) goto oops;
if (body == QSE_NULL)
{
qse_awk_clrpt (awk, init);
qse_awk_clrpt (awk, test);
qse_awk_clrpt (awk, incr);
return QSE_NULL;
} }
nde = (qse_awk_nde_for_t*) nde_for = (qse_awk_nde_for_t*)
QSE_AWK_ALLOC (awk, QSE_SIZEOF(qse_awk_nde_for_t)); QSE_AWK_ALLOC (awk, QSE_SIZEOF(*nde_for));
if (nde == QSE_NULL) if (nde_for == QSE_NULL)
{ {
qse_awk_clrpt (awk, init);
qse_awk_clrpt (awk, test);
qse_awk_clrpt (awk, incr);
qse_awk_clrpt (awk, body);
SETERR_LOC (awk, QSE_AWK_ENOMEM, xloc); SETERR_LOC (awk, QSE_AWK_ENOMEM, xloc);
return QSE_NULL; goto oops;
} }
nde->type = QSE_AWK_NDE_FOR; nde_for->type = QSE_AWK_NDE_FOR;
nde->loc = *xloc; nde_for->loc = *xloc;
nde->next = QSE_NULL; nde_for->next = QSE_NULL;
nde->init = init; nde_for->init = init;
nde->test = test; nde_for->test = test;
nde->incr = incr; nde_for->incr = incr;
nde->body = body; nde_for->body = body;
return (qse_awk_nde_t*)nde; return (qse_awk_nde_t*)nde_for;
oops:
if (init) qse_awk_clrpt (awk, init);
if (test) qse_awk_clrpt (awk, test);
if (incr) qse_awk_clrpt (awk, incr);
if (body) qse_awk_clrpt (awk, body);
return QSE_NULL;
} }
static qse_awk_nde_t* parse_dowhile (qse_awk_t* awk, const qse_awk_loc_t* xloc) static qse_awk_nde_t* parse_dowhile (qse_awk_t* awk, const qse_awk_loc_t* xloc)
@ -2989,7 +2917,6 @@ static qse_awk_nde_t* parse_statement_nb (
return nde; return nde;
} }
/* keywords that require a terminating semicolon */ /* keywords that require a terminating semicolon */
if (MATCH(awk,TOK_DO)) if (MATCH(awk,TOK_DO))
{ {
@ -3530,13 +3457,35 @@ static int fold_constants_for_binop (
return fold; return fold;
} }
static qse_awk_nde_t* new_exp_bin_node (
qse_awk_t* awk, const qse_awk_loc_t* loc,
int opcode, qse_awk_nde_t* left, qse_awk_nde_t* right)
{
qse_awk_nde_exp_t* tmp;
tmp = (qse_awk_nde_exp_t*) QSE_AWK_ALLOC (awk, QSE_SIZEOF(*tmp));
if (tmp == QSE_NULL)
{
SETERR_LOC (awk, QSE_AWK_ENOMEM, loc);
return QSE_NULL;
}
tmp->type = QSE_AWK_NDE_EXP_BIN;
tmp->loc = *loc;
tmp->next = QSE_NULL;
tmp->opcode = opcode;
tmp->left = left;
tmp->right = right;
return (qse_awk_nde_t*)tmp;
}
static qse_awk_nde_t* new_int_node ( static qse_awk_nde_t* new_int_node (
qse_awk_t* awk, qse_long_t lv, const qse_awk_loc_t* loc) qse_awk_t* awk, qse_long_t lv, const qse_awk_loc_t* loc)
{ {
qse_awk_nde_int_t* tmp; qse_awk_nde_int_t* tmp;
tmp = (qse_awk_nde_int_t*) QSE_AWK_ALLOC ( tmp = (qse_awk_nde_int_t*) QSE_AWK_ALLOC (awk, QSE_SIZEOF(*tmp));
awk, QSE_SIZEOF(qse_awk_nde_int_t));
if (tmp == QSE_NULL) if (tmp == QSE_NULL)
{ {
SETERR_LOC (awk, QSE_AWK_ENOMEM, loc); SETERR_LOC (awk, QSE_AWK_ENOMEM, loc);
@ -3556,8 +3505,7 @@ static qse_awk_nde_t* new_real_node (
{ {
qse_awk_nde_real_t* tmp; qse_awk_nde_real_t* tmp;
tmp = (qse_awk_nde_real_t*) QSE_AWK_ALLOC ( tmp = (qse_awk_nde_real_t*) QSE_AWK_ALLOC (awk, QSE_SIZEOF(*tmp));
awk, QSE_SIZEOF(qse_awk_nde_real_t));
if (tmp == QSE_NULL) if (tmp == QSE_NULL)
{ {
SETERR_LOC (awk, QSE_AWK_ENOMEM, loc); SETERR_LOC (awk, QSE_AWK_ENOMEM, loc);
@ -3601,19 +3549,19 @@ static qse_awk_nde_t* parse_binary (
int skipnl, const binmap_t* binmap, int skipnl, const binmap_t* binmap,
qse_awk_nde_t*(*next_level_func)(qse_awk_t*,const qse_awk_loc_t*)) qse_awk_nde_t*(*next_level_func)(qse_awk_t*,const qse_awk_loc_t*))
{ {
qse_awk_nde_t* left, * right; qse_awk_nde_t* left = QSE_NULL;
int opcode; qse_awk_nde_t* right = QSE_NULL;
int fold;
folded_t folded;
left = next_level_func (awk, xloc); left = next_level_func (awk, xloc);
if (left == QSE_NULL) return QSE_NULL; if (left == QSE_NULL) goto oops;
do do
{ {
qse_awk_loc_t rloc; qse_awk_loc_t rloc;
const binmap_t* p = binmap; const binmap_t* p = binmap;
qse_bool_t matched = QSE_FALSE; qse_bool_t matched = QSE_FALSE;
int opcode, fold;
folded_t folded;
while (p->token != TOK_EOF) while (p->token != TOK_EOF)
{ {
@ -3629,21 +3577,13 @@ static qse_awk_nde_t* parse_binary (
do do
{ {
if (get_token(awk) <= -1) if (get_token(awk) <= -1) goto oops;
{
qse_awk_clrpt (awk, left);
return QSE_NULL;
}
} }
while (skipnl && MATCH(awk,TOK_NEWLINE)); while (skipnl && MATCH(awk,TOK_NEWLINE));
rloc = awk->tok.loc; rloc = awk->tok.loc;
right = next_level_func (awk, &rloc); right = next_level_func (awk, &rloc);
if (right == QSE_NULL) if (right == QSE_NULL) goto oops;
{
qse_awk_clrpt (awk, left);
return QSE_NULL;
}
fold = fold_constants_for_binop (awk, left, right, opcode, &folded); fold = fold_constants_for_binop (awk, left, right, opcode, &folded);
switch (fold) switch (fold)
@ -3651,7 +3591,8 @@ static qse_awk_nde_t* parse_binary (
case QSE_AWK_NDE_INT: case QSE_AWK_NDE_INT:
if (fold == left->type) if (fold == left->type)
{ {
qse_awk_clrpt (awk, right); qse_awk_clrpt (awk, right);
right = QSE_NULL;
update_int_node (awk, (qse_awk_nde_int_t*)left, folded.l); update_int_node (awk, (qse_awk_nde_int_t*)left, folded.l);
} }
else if (fold == right->type) else if (fold == right->type)
@ -3659,14 +3600,15 @@ static qse_awk_nde_t* parse_binary (
qse_awk_clrpt (awk, left); qse_awk_clrpt (awk, left);
update_int_node (awk, (qse_awk_nde_int_t*)right, folded.l); update_int_node (awk, (qse_awk_nde_int_t*)right, folded.l);
left = right; left = right;
right = QSE_NULL;
} }
else else
{ {
qse_awk_clrpt (awk, right); qse_awk_clrpt (awk, right); right = QSE_NULL;
qse_awk_clrpt (awk, left); qse_awk_clrpt (awk, left); left = QSE_NULL;
left = new_int_node (awk, folded.l, xloc); left = new_int_node (awk, folded.l, xloc);
if (left == QSE_NULL) return QSE_NULL; if (left == QSE_NULL) goto oops;
} }
break; break;
@ -3675,47 +3617,35 @@ static qse_awk_nde_t* parse_binary (
if (fold == left->type) if (fold == left->type)
{ {
qse_awk_clrpt (awk, right); qse_awk_clrpt (awk, right);
right = QSE_NULL;
update_real_node (awk, (qse_awk_nde_real_t*)left, folded.r); update_real_node (awk, (qse_awk_nde_real_t*)left, folded.r);
} }
else if (fold == right->type) else if (fold == right->type)
{ {
qse_awk_clrpt (awk, left); qse_awk_clrpt (awk, left);
update_real_node (awk, (qse_awk_nde_real_t*)right, folded.r); update_real_node (awk, (qse_awk_nde_real_t*)right, folded.r);
left = right; left = right;
right = QSE_NULL;
} }
else else
{ {
qse_awk_clrpt (awk, right); qse_awk_clrpt (awk, right); right = QSE_NULL;
qse_awk_clrpt (awk, left); qse_awk_clrpt (awk, left); left = QSE_NULL;
left = new_real_node (awk, folded.r, xloc); left = new_real_node (awk, folded.r, xloc);
if (left == QSE_NULL) return QSE_NULL; if (left == QSE_NULL) goto oops;
} }
break; break;
default: default:
{ {
qse_awk_nde_exp_t* nde; qse_awk_nde_t* tmp;
nde = (qse_awk_nde_exp_t*) QSE_AWK_ALLOC ( tmp = new_exp_bin_node (awk, xloc, opcode, left, right);
awk, QSE_SIZEOF(qse_awk_nde_exp_t)); if (tmp == QSE_NULL) goto oops;
if (nde == QSE_NULL) left = tmp;
{ right = QSE_NULL;
qse_awk_clrpt (awk, right);
qse_awk_clrpt (awk, left);
SETERR_LOC (awk, QSE_AWK_ENOMEM, xloc);
return QSE_NULL;
}
nde->type = QSE_AWK_NDE_EXP_BIN;
nde->loc = *xloc;
nde->next = QSE_NULL;
nde->opcode = opcode;
nde->left = left;
nde->right = right;
left = (qse_awk_nde_t*)nde;
break; break;
} }
} }
@ -3723,6 +3653,11 @@ static qse_awk_nde_t* parse_binary (
while (1); while (1);
return left; return left;
oops:
if (right) qse_awk_clrpt (awk, right);
if (left) qse_awk_clrpt (awk, left);
return QSE_NULL;
} }
static qse_awk_nde_t* parse_logical_or ( static qse_awk_nde_t* parse_logical_or (
@ -3762,60 +3697,46 @@ static qse_awk_nde_t* parse_in (
return parse_binary (awk, xloc, 0, map, parse_regex_match); return parse_binary (awk, xloc, 0, map, parse_regex_match);
*/ */
qse_awk_nde_exp_t* nde; qse_awk_nde_t* left = QSE_NULL;
qse_awk_nde_t* left, * right; qse_awk_nde_t* right = QSE_NULL;
qse_awk_loc_t rloc; qse_awk_loc_t rloc;
left = parse_regex_match (awk, xloc); left = parse_regex_match (awk, xloc);
if (left == QSE_NULL) return QSE_NULL; if (left == QSE_NULL) goto oops;
while (1) do
{ {
qse_awk_nde_t* tmp;
if (!MATCH(awk,TOK_IN)) break; if (!MATCH(awk,TOK_IN)) break;
if (get_token(awk) <= -1) if (get_token(awk) <= -1) goto oops;
{
qse_awk_clrpt (awk, left);
return QSE_NULL;
}
rloc = awk->tok.loc; rloc = awk->tok.loc;
right = parse_regex_match (awk, &rloc); right = parse_regex_match (awk, &rloc);
if (right == QSE_NULL) if (right == QSE_NULL) goto oops;
{
qse_awk_clrpt (awk, left);
return QSE_NULL;
}
if (!is_plain_var(right)) if (!is_plain_var(right))
{ {
qse_awk_clrpt (awk, right);
qse_awk_clrpt (awk, left);
SETERR_LOC (awk, QSE_AWK_ENOTVAR, &rloc); SETERR_LOC (awk, QSE_AWK_ENOTVAR, &rloc);
return QSE_NULL; goto oops;
} }
nde = (qse_awk_nde_exp_t*) QSE_AWK_ALLOC ( tmp = new_exp_bin_node (
awk, QSE_SIZEOF(qse_awk_nde_exp_t)); awk, xloc, QSE_AWK_BINOP_IN, left, right);
if (nde == QSE_NULL) if (left == QSE_NULL) goto oops;
{
qse_awk_clrpt (awk, right);
qse_awk_clrpt (awk, left);
SETERR_LOC (awk, QSE_AWK_ENOMEM, xloc);
return QSE_NULL;
}
nde->type = QSE_AWK_NDE_EXP_BIN; left = tmp;
nde->loc = *xloc; right = QSE_NULL;
nde->next = QSE_NULL;
nde->opcode = QSE_AWK_BINOP_IN;
nde->left = left;
nde->right = right;
left = (qse_awk_nde_t*)nde;
} }
while (1);
return left; return left;
oops:
if (right) qse_awk_clrpt (awk, right);
if (left) qse_awk_clrpt (awk, left);
return QSE_NULL;
} }
static qse_awk_nde_t* parse_regex_match ( static qse_awk_nde_t* parse_regex_match (
@ -3912,24 +3833,21 @@ static qse_awk_nde_t* parse_shift (
static qse_awk_nde_t* parse_concat ( static qse_awk_nde_t* parse_concat (
qse_awk_t* awk, const qse_awk_loc_t* xloc) qse_awk_t* awk, const qse_awk_loc_t* xloc)
{ {
qse_awk_nde_exp_t* nde; qse_awk_nde_t* left = QSE_NULL;
qse_awk_nde_t* left, * right; qse_awk_nde_t* right = QSE_NULL;
left = parse_additive (awk, xloc); left = parse_additive (awk, xloc);
if (left == QSE_NULL) return QSE_NULL; if (left == QSE_NULL) goto oops;
while (1) do
{ {
qse_awk_nde_t* tmp;
qse_awk_loc_t rloc; qse_awk_loc_t rloc;
if (MATCH(awk,TOK_PERIOD)) if (MATCH(awk,TOK_PERIOD))
{ {
if (!(awk->option & QSE_AWK_EXPLICIT)) break; if (!(awk->option & QSE_AWK_EXPLICIT)) break;
if (get_token(awk) <= -1) if (get_token(awk) <= -1) goto oops;
{
qse_awk_clrpt (awk, left);
return QSE_NULL;
}
} }
else if (MATCH(awk,TOK_LPAREN) || else if (MATCH(awk,TOK_LPAREN) ||
MATCH(awk,TOK_DOLLAR) || MATCH(awk,TOK_DOLLAR) ||
@ -3947,33 +3865,22 @@ static qse_awk_nde_t* parse_concat (
rloc = awk->tok.loc; rloc = awk->tok.loc;
right = parse_additive (awk, &rloc); right = parse_additive (awk, &rloc);
if (right == QSE_NULL) if (right == QSE_NULL) goto oops;
{
qse_awk_clrpt (awk, left);
return QSE_NULL;
}
nde = (qse_awk_nde_exp_t*) QSE_AWK_ALLOC ( tmp = new_exp_bin_node (
awk, QSE_SIZEOF(qse_awk_nde_exp_t)); awk, xloc, QSE_AWK_BINOP_CONCAT, left, right);
if (nde == QSE_NULL) if (left == QSE_NULL) goto oops;
{ left = tmp;
qse_awk_clrpt (awk, right); right = QSE_NULL;
qse_awk_clrpt (awk, left);
SETERR_LOC (awk, QSE_AWK_ENOMEM, xloc);
return QSE_NULL;
}
nde->type = QSE_AWK_NDE_EXP_BIN;
nde->loc = *xloc;
nde->next = QSE_NULL;
nde->opcode = QSE_AWK_BINOP_CONCAT;
nde->left = left;
nde->right = right;
left = (qse_awk_nde_t*)nde;
} }
while (1);
return left; return left;
oops:
if (right) qse_awk_clrpt (awk, right);
if (left) qse_awk_clrpt (awk, left);
return QSE_NULL;
} }
static qse_awk_nde_t* parse_additive ( static qse_awk_nde_t* parse_additive (
@ -4303,6 +4210,7 @@ static qse_awk_nde_t* parse_primary_nogetline (
{ {
qse_awk_nde_int_t* nde; qse_awk_nde_int_t* nde;
/* create the node for the literal */
nde = (qse_awk_nde_int_t*)new_int_node ( nde = (qse_awk_nde_int_t*)new_int_node (
awk, awk,
qse_awk_strxtolong (awk, qse_awk_strxtolong (awk,
@ -4314,6 +4222,7 @@ static qse_awk_nde_t* parse_primary_nogetline (
); );
if (nde == QSE_NULL) return QSE_NULL; if (nde == QSE_NULL) return QSE_NULL;
/* remember the literal in the original form */
nde->str = QSE_AWK_STRXDUP (awk, nde->str = QSE_AWK_STRXDUP (awk,
QSE_STR_PTR(awk->tok.name), QSE_STR_PTR(awk->tok.name),
QSE_STR_LEN(awk->tok.name)); QSE_STR_LEN(awk->tok.name));
@ -4341,6 +4250,7 @@ static qse_awk_nde_t* parse_primary_nogetline (
{ {
qse_awk_nde_real_t* nde; qse_awk_nde_real_t* nde;
/* create the node for the literal */
nde = (qse_awk_nde_real_t*) new_real_node ( nde = (qse_awk_nde_real_t*) new_real_node (
awk, awk,
qse_awk_strxtoreal (awk, qse_awk_strxtoreal (awk,
@ -4352,6 +4262,7 @@ static qse_awk_nde_t* parse_primary_nogetline (
); );
if (nde == QSE_NULL) return QSE_NULL; if (nde == QSE_NULL) return QSE_NULL;
/* remember the literal in the original form */
nde->str = QSE_AWK_STRXDUP (awk, nde->str = QSE_AWK_STRXDUP (awk,
QSE_STR_PTR(awk->tok.name), QSE_STR_PTR(awk->tok.name),
QSE_STR_LEN(awk->tok.name)); QSE_STR_LEN(awk->tok.name));