*** empty log message ***

This commit is contained in:
hyung-hwan 2006-12-04 06:04:07 +00:00
parent f3b9755c3c
commit a38e6e5ba8
7 changed files with 120 additions and 84 deletions

View File

@ -1,5 +1,5 @@
/* /*
* $Id: awk.h,v 1.158 2006-12-02 16:26:03 bacon Exp $ * $Id: awk.h,v 1.159 2006-12-04 06:04:05 bacon Exp $
*/ */
#ifndef _ASE_AWK_AWK_H_ #ifndef _ASE_AWK_AWK_H_
@ -151,11 +151,11 @@ enum
/* support shift operators */ /* support shift operators */
ASE_AWK_SHIFT = (1 << 4), ASE_AWK_SHIFT = (1 << 4),
/* support comments by a hash sign */ /* enable the idiv operator (double slashes) */
ASE_AWK_HASHSIGN = (1 << 5), ASE_AWK_IDIV = (1 << 5),
/* support comments by double slashes */ /* support comments by a hash sign */
ASE_AWK_DBLSLASHES = (1 << 6), ASE_AWK_HASHSIGN = (1 << 6),
/* support string concatenation in tokenization. /* support string concatenation in tokenization.
* this option can change the behavior of a certain construct. * this option can change the behavior of a certain construct.

View File

@ -1,5 +1,5 @@
/* /*
* $Id: jni.c,v 1.35 2006-12-02 16:26:03 bacon Exp $ * $Id: jni.c,v 1.36 2006-12-04 06:04:06 bacon Exp $
*/ */
#include <ase/awk/jni.h> #include <ase/awk/jni.h>
@ -234,8 +234,8 @@ JNIEXPORT void JNICALL Java_ase_awk_Awk_open (JNIEnv* env, jobject obj)
(*env)->SetLongField (env, obj, fid_handle, (jlong)awk); (*env)->SetLongField (env, obj, fid_handle, (jlong)awk);
opt = ASE_AWK_EXPLICIT | ASE_AWK_UNIQUEAFN | ASE_AWK_DBLSLASHES | opt = ASE_AWK_EXPLICIT | ASE_AWK_UNIQUEAFN | ASE_AWK_SHADING |
ASE_AWK_SHADING | ASE_AWK_IMPLICIT | ASE_AWK_SHIFT | ASE_AWK_IMPLICIT | ASE_AWK_SHIFT | ASE_AWK_IDIV |
ASE_AWK_EXTIO | ASE_AWK_BLOCKLESS | ASE_AWK_HASHSIGN | ASE_AWK_EXTIO | ASE_AWK_BLOCKLESS | ASE_AWK_HASHSIGN |
ASE_AWK_NEXTOFILE; ASE_AWK_NEXTOFILE;
ase_awk_setopt (awk, opt); ase_awk_setopt (awk, opt);

View File

@ -1,5 +1,5 @@
/* /*
* $Id: parse.c,v 1.214 2006-11-29 02:54:15 bacon Exp $ * $Id: parse.c,v 1.215 2006-12-04 06:04:06 bacon Exp $
*/ */
#include <ase/awk/awk_i.h> #include <ase/awk/awk_i.h>
@ -16,6 +16,7 @@ enum
TOKEN_MINUS_ASSIGN, TOKEN_MINUS_ASSIGN,
TOKEN_MUL_ASSIGN, TOKEN_MUL_ASSIGN,
TOKEN_DIV_ASSIGN, TOKEN_DIV_ASSIGN,
TOKEN_IDIV_ASSIGN,
TOKEN_MOD_ASSIGN, TOKEN_MOD_ASSIGN,
TOKEN_EXP_ASSIGN, TOKEN_EXP_ASSIGN,
@ -33,6 +34,7 @@ enum
TOKEN_MINUSMINUS, TOKEN_MINUSMINUS,
TOKEN_MUL, TOKEN_MUL,
TOKEN_DIV, TOKEN_DIV,
TOKEN_IDIV,
TOKEN_MOD, TOKEN_MOD,
TOKEN_LOR, TOKEN_LOR,
TOKEN_LAND, TOKEN_LAND,
@ -1540,68 +1542,6 @@ static ase_awk_nde_t* __parse_binary_expr (
return ASE_NULL; return ASE_NULL;
} }
#if 0
/* TODO: enhance constant folding. do it in a better way */
/* TODO: differentiate different types of numbers ... */
if (left->type == ASE_AWK_NDE_INT &&
right->type == ASE_AWK_NDE_INT)
{
ase_long_t l, r;
l = ((ase_awk_nde_int_t*)left)->val;
r = ((ase_awk_nde_int_t*)right)->val;
/* TODO: more operators */
if (opcode == ASE_AWK_BINOP_PLUS) l += r;
else if (opcode == ASE_AWK_BINOP_MINUS) l -= r;
else if (opcode == ASE_AWK_BINOP_MUL) l *= r;
else if (opcode == ASE_AWK_BINOP_DIV && r != 0) l /= r;
else if (opcode == ASE_AWK_BINOP_MOD && r != 0) l %= r;
else goto skip_constant_folding;
ase_awk_clrpt (awk, right);
((ase_awk_nde_int_t*)left)->val = l;
if (((ase_awk_nde_int_t*)left)->str != ASE_NULL)
{
ASE_AWK_FREE (awk, ((ase_awk_nde_int_t*)left)->str);
((ase_awk_nde_int_t*)left)->str = ASE_NULL;
((ase_awk_nde_int_t*)left)->len = 0;
}
continue;
}
else if (left->type == ASE_AWK_NDE_REAL &&
right->type == ASE_AWK_NDE_REAL)
{
ase_real_t l, r;
l = ((ase_awk_nde_real_t*)left)->val;
r = ((ase_awk_nde_real_t*)right)->val;
/* TODO: more operators */
if (opcode == ASE_AWK_BINOP_PLUS) l += r;
else if (opcode == ASE_AWK_BINOP_MINUS) l -= r;
else if (opcode == ASE_AWK_BINOP_MUL) l *= r;
else if (opcode == ASE_AWK_BINOP_DIV) l /= r;
else goto skip_constant_folding;
ase_awk_clrpt (awk, right);
((ase_awk_nde_real_t*)left)->val = l;
if (((ase_awk_nde_real_t*)left)->str != ASE_NULL)
{
ASE_AWK_FREE (awk, ((ase_awk_nde_real_t*)left)->str);
((ase_awk_nde_real_t*)left)->str = ASE_NULL;
((ase_awk_nde_real_t*)left)->len = 0;
}
continue;
}
/* TODO: enhance constant folding more... */
skip_constant_folding:
#endif
nde = (ase_awk_nde_exp_t*) ASE_AWK_MALLOC ( nde = (ase_awk_nde_exp_t*) ASE_AWK_MALLOC (
awk, ASE_SIZEOF(ase_awk_nde_exp_t)); awk, ASE_SIZEOF(ase_awk_nde_exp_t));
if (nde == ASE_NULL) if (nde == ASE_NULL)
@ -1962,9 +1902,10 @@ static ase_awk_nde_t* __parse_multiplicative (ase_awk_t* awk)
{ {
static __binmap_t map[] = static __binmap_t map[] =
{ {
{ TOKEN_MUL, ASE_AWK_BINOP_MUL }, { TOKEN_MUL, ASE_AWK_BINOP_MUL },
{ TOKEN_DIV, ASE_AWK_BINOP_DIV }, { TOKEN_DIV, ASE_AWK_BINOP_DIV },
{ TOKEN_MOD, ASE_AWK_BINOP_MOD }, { TOKEN_IDIV, ASE_AWK_BINOP_IDIV },
{ TOKEN_MOD, ASE_AWK_BINOP_MOD },
/* { TOKEN_EXP, ASE_AWK_BINOP_EXP }, */ /* { TOKEN_EXP, ASE_AWK_BINOP_EXP }, */
{ TOKEN_EOF, 0 } { TOKEN_EOF, 0 }
}; };
@ -3781,11 +3722,46 @@ static int __get_token (ase_awk_t* awk)
ADD_TOKEN_CHAR (awk, c); ADD_TOKEN_CHAR (awk, c);
GET_CHAR (awk); GET_CHAR (awk);
} }
else if ((awk->option & ASE_AWK_IDIV) && c == ASE_T('/'))
{
ADD_TOKEN_CHAR (awk, c);
GET_CHAR_TO (awk, c);
if (c == ASE_T('='))
{
SET_TOKEN_TYPE (awk, TOKEN_IDIV_ASSIGN);
ADD_TOKEN_CHAR (awk, c);
GET_CHAR (awk);
}
else
{
SET_TOKEN_TYPE (awk, TOKEN_IDIV);
}
}
else else
{ {
SET_TOKEN_TYPE (awk, TOKEN_DIV); SET_TOKEN_TYPE (awk, TOKEN_DIV);
} }
} }
#if 0
/* TODO: is it a good idea to use a back-slash for
* the idiv operator like BASIC? */
else if ((awk->option & ASE_AWK_IDIV) && c == ASE_T('\\'))
{
ADD_TOKEN_CHAR (awk, c);
GET_CHAR_TO (awk, c);
if (c == ASE_T('='))
{
SET_TOKEN_TYPE (awk, TOKEN_IDIV_ASSIGN);
ADD_TOKEN_CHAR (awk, c);
GET_CHAR (awk);
}
else
{
SET_TOKEN_TYPE (awk, TOKEN_IDIV);
}
}
#endif
else if (c == ASE_T('%')) else if (c == ASE_T('%'))
{ {
ADD_TOKEN_CHAR (awk, c); ADD_TOKEN_CHAR (awk, c);
@ -4254,6 +4230,7 @@ static int __skip_comment (ase_awk_t* awk)
if (c != ASE_T('/')) return 0; /* not a comment */ if (c != ASE_T('/')) return 0; /* not a comment */
GET_CHAR_TO (awk, c); GET_CHAR_TO (awk, c);
#if 0
if ((awk->option & ASE_AWK_DBLSLASHES) && c == ASE_T('/')) if ((awk->option & ASE_AWK_DBLSLASHES) && c == ASE_T('/'))
{ {
do do
@ -4265,7 +4242,9 @@ static int __skip_comment (ase_awk_t* awk)
GET_CHAR (awk); GET_CHAR (awk);
return 1; /* comment by // */ return 1; /* comment by // */
} }
else if (c == ASE_T('*')) else
#endif
if (c == ASE_T('*'))
{ {
do do
{ {
@ -4332,6 +4311,7 @@ static int __assign_to_opcode (ase_awk_t* awk)
ASE_AWK_ASSOP_MINUS, ASE_AWK_ASSOP_MINUS,
ASE_AWK_ASSOP_MUL, ASE_AWK_ASSOP_MUL,
ASE_AWK_ASSOP_DIV, ASE_AWK_ASSOP_DIV,
ASE_AWK_ASSOP_IDIV,
ASE_AWK_ASSOP_MOD, ASE_AWK_ASSOP_MOD,
ASE_AWK_ASSOP_EXP ASE_AWK_ASSOP_EXP
}; };

View File

@ -1,5 +1,5 @@
/* /*
* $Id: run.c,v 1.289 2006-12-03 15:05:01 bacon Exp $ * $Id: run.c,v 1.290 2006-12-04 06:04:07 bacon Exp $
*/ */
#include <ase/awk/awk_i.h> #include <ase/awk/awk_i.h>
@ -141,6 +141,8 @@ static ase_awk_val_t* __eval_binop_mul (
ase_awk_run_t* run, ase_awk_val_t* left, ase_awk_val_t* right); ase_awk_run_t* run, ase_awk_val_t* left, ase_awk_val_t* right);
static ase_awk_val_t* __eval_binop_div ( static ase_awk_val_t* __eval_binop_div (
ase_awk_run_t* run, ase_awk_val_t* left, ase_awk_val_t* right); ase_awk_run_t* run, ase_awk_val_t* left, ase_awk_val_t* right);
static ase_awk_val_t* __eval_binop_idiv (
ase_awk_run_t* run, ase_awk_val_t* left, ase_awk_val_t* right);
static ase_awk_val_t* __eval_binop_mod ( static ase_awk_val_t* __eval_binop_mod (
ase_awk_run_t* run, ase_awk_val_t* left, ase_awk_val_t* right); ase_awk_run_t* run, ase_awk_val_t* left, ase_awk_val_t* right);
static ase_awk_val_t* __eval_binop_exp ( static ase_awk_val_t* __eval_binop_exp (
@ -2719,6 +2721,10 @@ static ase_awk_val_t* __eval_assignment (ase_awk_run_t* run, ase_awk_nde_t* nde)
{ {
tmp = __eval_binop_div (run, val2, val); tmp = __eval_binop_div (run, val2, val);
} }
else if (ass->opcode == ASE_AWK_ASSOP_IDIV)
{
tmp = __eval_binop_idiv (run, val2, val);
}
else if (ass->opcode == ASE_AWK_ASSOP_MOD) else if (ass->opcode == ASE_AWK_ASSOP_MOD)
{ {
tmp = __eval_binop_mod (run, val2, val); tmp = __eval_binop_mod (run, val2, val);
@ -3029,6 +3035,7 @@ static ase_awk_val_t* __eval_binary (ase_awk_run_t* run, ase_awk_nde_t* nde)
__eval_binop_minus, __eval_binop_minus,
__eval_binop_mul, __eval_binop_mul,
__eval_binop_div, __eval_binop_div,
__eval_binop_idiv,
__eval_binop_mod, __eval_binop_mod,
__eval_binop_exp, __eval_binop_exp,
@ -3808,16 +3815,61 @@ static ase_awk_val_t* __eval_binop_div (
} }
else if (n3 == 1) else if (n3 == 1)
{ {
res = ase_awk_makerealval (run, (ase_real_t)r1 / (ase_real_t)l2); res = ase_awk_makerealval (
run, (ase_real_t)r1 / (ase_real_t)l2);
} }
else if (n3 == 2) else if (n3 == 2)
{ {
res = ase_awk_makerealval (run, (ase_real_t)l1 / (ase_real_t)r2); res = ase_awk_makerealval (
run, (ase_real_t)l1 / (ase_real_t)r2);
} }
else else
{ {
ASE_AWK_ASSERT (run->awk, n3 == 3); ASE_AWK_ASSERT (run->awk, n3 == 3);
res = ase_awk_makerealval (run, (ase_real_t)r1 / (ase_real_t)r2); res = ase_awk_makerealval (
run, (ase_real_t)r1 / (ase_real_t)r2);
}
if (res == ASE_NULL) PANIC (run, ASE_AWK_ENOMEM);
return res;
}
static ase_awk_val_t* __eval_binop_idiv (
ase_awk_run_t* run, ase_awk_val_t* left, ase_awk_val_t* right)
{
int n1, n2, n3;
ase_long_t l1, l2;
ase_real_t r1, r2, quo;
ase_awk_val_t* res;
n1 = ase_awk_valtonum (run, left, &l1, &r1);
n2 = ase_awk_valtonum (run, right, &l2, &r2);
if (n1 == -1 || n2 == -1) PANIC (run, ASE_AWK_EOPERAND);
n3 = n1 + (n2 << 1);
if (n3 == 0)
{
if (l2 == 0) PANIC (run, ASE_AWK_EDIVBYZERO);
res = ase_awk_makeintval (
run, (ase_long_t)l1 / (ase_long_t)l2);
}
else if (n3 == 1)
{
quo = (ase_real_t)r1 / (ase_real_t)l2;
res = ase_awk_makeintval (run, (ase_long_t)quo);
}
else if (n3 == 2)
{
quo = (ase_real_t)l1 / (ase_real_t)r2;
res = ase_awk_makeintval (run, (ase_long_t)quo);
}
else
{
ASE_AWK_ASSERT (run->awk, n3 == 3);
quo = (ase_real_t)r1 / (ase_real_t)r2;
res = ase_awk_makeintval (run, (ase_long_t)quo);
} }
if (res == ASE_NULL) PANIC (run, ASE_AWK_ENOMEM); if (res == ASE_NULL) PANIC (run, ASE_AWK_ENOMEM);
@ -3841,7 +3893,8 @@ static ase_awk_val_t* __eval_binop_mod (
if (n3 == 0) if (n3 == 0)
{ {
if (l2 == 0) PANIC (run, ASE_AWK_EDIVBYZERO); if (l2 == 0) PANIC (run, ASE_AWK_EDIVBYZERO);
res = ase_awk_makeintval (run, (ase_long_t)l1 % (ase_long_t)l2); res = ase_awk_makeintval (
run, (ase_long_t)l1 % (ase_long_t)l2);
} }
else PANIC (run, ASE_AWK_EOPERAND); else PANIC (run, ASE_AWK_EOPERAND);

View File

@ -1,5 +1,5 @@
/* /*
* $Id: run.h,v 1.28 2006-11-24 13:20:49 bacon Exp $ * $Id: run.h,v 1.29 2006-12-04 06:04:07 bacon Exp $
*/ */
#ifndef _ASE_AWK_RUN_H_ #ifndef _ASE_AWK_RUN_H_
@ -17,6 +17,7 @@ enum ase_awk_assop_type_t
ASE_AWK_ASSOP_MINUS, /* -= */ ASE_AWK_ASSOP_MINUS, /* -= */
ASE_AWK_ASSOP_MUL, /* *= */ ASE_AWK_ASSOP_MUL, /* *= */
ASE_AWK_ASSOP_DIV, /* /= */ ASE_AWK_ASSOP_DIV, /* /= */
ASE_AWK_ASSOP_IDIV, /* //= */
ASE_AWK_ASSOP_MOD, /* %= */ ASE_AWK_ASSOP_MOD, /* %= */
ASE_AWK_ASSOP_EXP /* **= */ ASE_AWK_ASSOP_EXP /* **= */
}; };
@ -47,6 +48,7 @@ enum ase_awk_binop_type_t
ASE_AWK_BINOP_MINUS, ASE_AWK_BINOP_MINUS,
ASE_AWK_BINOP_MUL, ASE_AWK_BINOP_MUL,
ASE_AWK_BINOP_DIV, ASE_AWK_BINOP_DIV,
ASE_AWK_BINOP_IDIV,
ASE_AWK_BINOP_MOD, ASE_AWK_BINOP_MOD,
ASE_AWK_BINOP_EXP, ASE_AWK_BINOP_EXP,

View File

@ -1,5 +1,5 @@
/* /*
* $Id: tree.c,v 1.92 2006-11-29 02:54:16 bacon Exp $ * $Id: tree.c,v 1.93 2006-12-04 06:04:07 bacon Exp $
*/ */
#include <ase/awk/awk_i.h> #include <ase/awk/awk_i.h>
@ -11,6 +11,7 @@ static const ase_char_t* __assop_str[] =
ASE_T("-="), ASE_T("-="),
ASE_T("*="), ASE_T("*="),
ASE_T("/="), ASE_T("/="),
ASE_T("//="),
ASE_T("%="), ASE_T("%="),
ASE_T("**=") ASE_T("**=")
}; };

View File

@ -1,5 +1,5 @@
/* /*
* $Id: awk.c,v 1.133 2006-11-30 10:40:40 bacon Exp $ * $Id: awk.c,v 1.134 2006-12-04 06:04:07 bacon Exp $
*/ */
#include <ase/awk/awk.h> #include <ase/awk/awk.h>
@ -755,7 +755,7 @@ static int __main (int argc, ase_char_t* argv[])
ASE_AWK_EXPLICIT | ASE_AWK_EXPLICIT |
ASE_AWK_UNIQUEAFN | ASE_AWK_UNIQUEAFN |
ASE_AWK_HASHSIGN | ASE_AWK_HASHSIGN |
/*ASE_AWK_DBLSLASHES |*/ ASE_AWK_IDIV |
ASE_AWK_SHADING | ASE_AWK_SHADING |
ASE_AWK_SHIFT | ASE_AWK_SHIFT |
ASE_AWK_EXTIO | ASE_AWK_EXTIO |