diff --git a/ase/awk/Makefile.cl b/ase/awk/Makefile.cl index 5b15ad63..b7402daf 100644 --- a/ase/awk/Makefile.cl +++ b/ase/awk/Makefile.cl @@ -4,7 +4,7 @@ OUT = xpawk.lib CC = cl #CFLAGS = /nologo /MT /W3 /GR- /D_WIN32_WINNT=0x0400 -I../.. -CFLAGS = /nologo /MT /W3 /GR- /D_WIN32_WINNT=0x0400 -I../.. -D__STAND_ALONE +CFLAGS = /nologo /MT /W3 /GR- /D_WIN32_WINNT=0x0400 -I../.. -D__STAND_ALONE -DXP_CHAR_IS_WCHAR all: $(OBJS) link -lib @<< diff --git a/ase/awk/awk.c b/ase/awk/awk.c index c0a43905..9cab8131 100644 --- a/ase/awk/awk.c +++ b/ase/awk/awk.c @@ -1,5 +1,5 @@ /* - * $Id: awk.c,v 1.35 2006-03-28 16:33:09 bacon Exp $ + * $Id: awk.c,v 1.36 2006-03-29 16:37:31 bacon Exp $ */ #include @@ -10,6 +10,7 @@ #endif static void __free_func (xp_awk_t* awk, void* func); +static void __free_namedval (xp_awk_t* awk, void* val); xp_awk_t* xp_awk_open (xp_awk_t* awk) { @@ -56,7 +57,7 @@ xp_awk_t* xp_awk_open (xp_awk_t* awk) } // TODO: initial map size... - if (xp_awk_map_open(&awk->run.named,awk,256,xp_awk_refdownval) == XP_NULL) { + if (xp_awk_map_open(&awk->run.named,awk,256,__free_namedval) == XP_NULL) { xp_str_close (&awk->token.name); xp_awk_map_close (&awk->tree.funcs); xp_awk_tab_close (&awk->parse.globals); @@ -198,3 +199,8 @@ static void __free_func (xp_awk_t* awk, void* func) xp_awk_clrpt (f->body); xp_free (f); } + +static void __free_namedval (xp_awk_t* awk, void* val) +{ + xp_awk_refdownval (awk, val); +} diff --git a/ase/awk/parse.c b/ase/awk/parse.c index 463d2eb8..7f09c3f0 100644 --- a/ase/awk/parse.c +++ b/ase/awk/parse.c @@ -1,5 +1,5 @@ /* - * $Id: parse.c,v 1.61 2006-03-27 11:43:17 bacon Exp $ + * $Id: parse.c,v 1.62 2006-03-29 16:37:31 bacon Exp $ */ #include @@ -35,6 +35,10 @@ enum TOKEN_MOD, TOKEN_RSHIFT, TOKEN_LSHIFT, + TOKEN_LOR, + TOKEN_LAND, + TOKEN_BOR, + TOKEN_BAND, TOKEN_LPAREN, TOKEN_RPAREN, @@ -81,9 +85,9 @@ enum #endif -static xp_awk_t* __parse_progunit (xp_awk_t* awk); -static xp_awk_t* __collect_globals (xp_awk_t* awk); -static xp_awk_t* __collect_locals (xp_awk_t* awk, xp_size_t nlocals); +static xp_awk_t* __parse_progunit (xp_awk_t* awk); +static xp_awk_t* __collect_globals (xp_awk_t* awk); +static xp_awk_t* __collect_locals (xp_awk_t* awk, xp_size_t nlocals); static xp_awk_nde_t* __parse_function (xp_awk_t* awk); static xp_awk_nde_t* __parse_begin (xp_awk_t* awk); @@ -96,6 +100,11 @@ static xp_awk_nde_t* __parse_statement (xp_awk_t* awk); static xp_awk_nde_t* __parse_statement_nb (xp_awk_t* awk); static xp_awk_nde_t* __parse_expression (xp_awk_t* awk); static xp_awk_nde_t* __parse_basic_expr (xp_awk_t* awk); +static xp_awk_nde_t* __parse_conditional (xp_awk_t* awk); +static xp_awk_nde_t* __parse_logical_or (xp_awk_t* awk); +static xp_awk_nde_t* __parse_logical_and (xp_awk_t* awk); +static xp_awk_nde_t* __parse_bitwise_or (xp_awk_t* awk); +static xp_awk_nde_t* __parse_bitwise_xor (xp_awk_t* awk); static xp_awk_nde_t* __parse_equality (xp_awk_t* awk); static xp_awk_nde_t* __parse_relational (xp_awk_t* awk); static xp_awk_nde_t* __parse_shift (xp_awk_t* awk); @@ -920,7 +929,6 @@ static xp_awk_nde_t* __parse_statement_nb (xp_awk_t* awk) if (__get_token(awk) == -1) return XP_NULL; nde = __parse_exit(awk); } - /* TODO: else if (MATCH(awk,TOKEN_DELETE)) { @@ -1033,7 +1041,165 @@ static xp_awk_nde_t* __parse_basic_expr (xp_awk_t* awk) * ::= [comma ]* */ - return __parse_equality (awk); + return __parse_conditional (awk); +} + +static xp_awk_nde_t* __parse_conditional (xp_awk_t* awk) +{ + return __parse_logical_or (awk); +} + +static xp_awk_nde_t* __parse_logical_or (xp_awk_t* awk) +{ + xp_awk_nde_exp_t* nde; + xp_awk_nde_t* left, * right; + int opcode; + + left = __parse_logical_and (awk); + if (left == XP_NULL) return XP_NULL; + + while (1) + { + if (MATCH(awk,TOKEN_LOR)) opcode = XP_AWK_BINOP_LOR; + else break; + + if (__get_token(awk) == -1) + { + xp_awk_clrpt (left); + return XP_NULL; + } + + right = __parse_logical_and (awk); + if (right == XP_NULL) + { + xp_awk_clrpt (left); + return XP_NULL; + } + + // TODO: constant folding -> in other parts of the program also... + + nde = (xp_awk_nde_exp_t*)xp_malloc(xp_sizeof(xp_awk_nde_exp_t)); + if (nde == XP_NULL) + { + xp_awk_clrpt (right); + xp_awk_clrpt (left); + PANIC (awk, XP_AWK_ENOMEM); + } + + nde->type = XP_AWK_NDE_EXP_BIN; + nde->next = XP_NULL; + nde->opcode = opcode; + nde->left = left; + nde->right = right; + + left = (xp_awk_nde_t*)nde; + } + + return left; +} + +static xp_awk_nde_t* __parse_logical_and (xp_awk_t* awk) +{ + xp_awk_nde_exp_t* nde; + xp_awk_nde_t* left, * right; + int opcode; + + left = __parse_bitwise_or (awk); + if (left == XP_NULL) return XP_NULL; + + while (1) + { + if (MATCH(awk,TOKEN_LAND)) opcode = XP_AWK_BINOP_LAND; + else break; + + if (__get_token(awk) == -1) + { + xp_awk_clrpt (left); + return XP_NULL; + } + + right = __parse_bitwise_or (awk); + if (right == XP_NULL) + { + xp_awk_clrpt (left); + return XP_NULL; + } + + // TODO: constant folding -> in other parts of the program also... + + nde = (xp_awk_nde_exp_t*)xp_malloc(xp_sizeof(xp_awk_nde_exp_t)); + if (nde == XP_NULL) + { + xp_awk_clrpt (right); + xp_awk_clrpt (left); + PANIC (awk, XP_AWK_ENOMEM); + } + + nde->type = XP_AWK_NDE_EXP_BIN; + nde->next = XP_NULL; + nde->opcode = opcode; + nde->left = left; + nde->right = right; + + left = (xp_awk_nde_t*)nde; + } + + return left; +} + +static xp_awk_nde_t* __parse_bitwise_or (xp_awk_t* awk) +{ + xp_awk_nde_exp_t* nde; + xp_awk_nde_t* left, * right; + int opcode; + + left = __parse_bitwise_xor (awk); + if (left == XP_NULL) return XP_NULL; + + while (1) + { + if (MATCH(awk,TOKEN_BOR)) opcode = XP_AWK_BINOP_BOR; + else break; + + if (__get_token(awk) == -1) + { + xp_awk_clrpt (left); + return XP_NULL; + } + + right = __parse_bitwise_xor (awk); + if (right == XP_NULL) + { + xp_awk_clrpt (left); + return XP_NULL; + } + + // TODO: constant folding -> in other parts of the program also... + + nde = (xp_awk_nde_exp_t*)xp_malloc(xp_sizeof(xp_awk_nde_exp_t)); + if (nde == XP_NULL) + { + xp_awk_clrpt (right); + xp_awk_clrpt (left); + PANIC (awk, XP_AWK_ENOMEM); + } + + nde->type = XP_AWK_NDE_EXP_BIN; + nde->next = XP_NULL; + nde->opcode = opcode; + nde->left = left; + nde->right = right; + + left = (xp_awk_nde_t*)nde; + } + + return left; +} + +static xp_awk_nde_t* __parse_bitwise_xor (xp_awk_t* awk) +{ + // TODO: + return XP_NULL; } static xp_awk_nde_t* __parse_equality (xp_awk_t* awk) @@ -2208,6 +2374,36 @@ static int __get_token (xp_awk_t* awk) ADD_TOKEN_STR (awk, XP_TEXT("<")); } } + else if (c == XP_CHAR('|')) + { + GET_CHAR_TO (awk, c); + if (c == XP_CHAR('|')) + { + SET_TOKEN_TYPE (awk, TOKEN_LOR); + ADD_TOKEN_STR (awk, XP_TEXT("||")); + GET_CHAR_TO (awk, c); + } + else + { + SET_TOKEN_TYPE (awk, TOKEN_BOR); + ADD_TOKEN_STR (awk, XP_TEXT("|")); + } + } + else if (c == XP_CHAR('&')) + { + GET_CHAR_TO (awk, c); + if (c == XP_CHAR('&&')) + { + SET_TOKEN_TYPE (awk, TOKEN_LAND); + ADD_TOKEN_STR (awk, XP_TEXT("&&")); + GET_CHAR_TO (awk, c); + } + else + { + SET_TOKEN_TYPE (awk, TOKEN_BAND); + ADD_TOKEN_STR (awk, XP_TEXT("&")); + } + } else if (c == XP_CHAR('+')) { GET_CHAR_TO (awk, c); diff --git a/ase/awk/run.h b/ase/awk/run.h index c2b71ec3..38ce3289 100644 --- a/ase/awk/run.h +++ b/ase/awk/run.h @@ -1,5 +1,5 @@ /* - * $Id: run.h,v 1.1 2006-03-07 16:02:58 bacon Exp $ + * $Id: run.h,v 1.2 2006-03-29 16:37:31 bacon Exp $ */ #ifndef _XP_AWK_RUN_H_ @@ -21,6 +21,10 @@ struct xp_awk_frm_t enum { + XP_AWK_BINOP_LOR, + XP_AWK_BINOP_LAND, + XP_AWK_BINOP_BOR, + XP_AWK_BINOP_BAND, XP_AWK_BINOP_PLUS, XP_AWK_BINOP_MINUS, XP_AWK_BINOP_MUL, diff --git a/ase/awk/sa.c b/ase/awk/sa.c index d0da5869..d1898774 100644 --- a/ase/awk/sa.c +++ b/ase/awk/sa.c @@ -1,5 +1,5 @@ /* - * $Id: sa.c,v 1.10 2006-03-27 14:40:58 bacon Exp $ + * $Id: sa.c,v 1.11 2006-03-29 16:37:31 bacon Exp $ */ #include @@ -8,6 +8,13 @@ static xp_char_t* __adjust_format (const xp_char_t* format); +xp_size_t xp_strlen (const xp_char_t* str) +{ + const xp_char_t* p = str; + while (*p != XP_CHAR('\0')) p++; + return p - str; +} + xp_char_t* xp_strdup (const xp_char_t* str) { xp_char_t* tmp; @@ -31,6 +38,13 @@ xp_char_t* xp_strxdup (const xp_char_t* str, xp_size_t len) return tmp; } +xp_size_t xp_strcpy (xp_char_t* buf, const xp_char_t* str) +{ + xp_char_t* org = buf; + while ((*buf++ = *str++) != XP_CHAR('\0')); + return buf - org - 1; +} + xp_size_t xp_strxncpy ( xp_char_t* buf, xp_size_t bsz, const xp_char_t* str, xp_size_t len) { @@ -44,6 +58,15 @@ xp_size_t xp_strxncpy ( return n; } +int xp_strcmp (const xp_char_t* s1, const xp_char_t* s2) +{ + while (*s1 == *s2 && *s2 != XP_CHAR('\0')) s1++, s2++; + if (*s1 > *s2) return 1; + else if (*s1 < *s2) return -1; + return 0; +} + + xp_long_t xp_strtolong (xp_char_t* str) { xp_long_t n = 0; diff --git a/ase/awk/sa.h b/ase/awk/sa.h index e4541d7e..8208c5b6 100644 --- a/ase/awk/sa.h +++ b/ase/awk/sa.h @@ -1,5 +1,5 @@ /* - * $Id: sa.h,v 1.14 2006-03-27 11:43:17 bacon Exp $ + * $Id: sa.h,v 1.15 2006-03-29 16:37:31 bacon Exp $ */ #ifndef _XP_AWK_SA_H_ @@ -11,29 +11,45 @@ #ifdef __STAND_ALONE +#if !defined(XP_CHAR_IS_MCHAR) && !defined(XP_CHAR_IS_WCHAR) +#error Neither XP_CHAR_IS_MCHAR nor XP_CHAR_IS_WCHAR is defined. +#endif + #include -#include -#include #include #include #include #include +#ifdef XP_CHAR_IS_MCHAR +#include +#else +#include +#if !defined(__BEOS__) +#include +#endif +#endif + #define xp_malloc malloc #define xp_realloc realloc #define xp_free free #define xp_assert assert +#ifdef XP_CHAR_IS_MCHAR +#define xp_isdigit isdigit +#define xp_isalpha isalpha +#define xp_isalnum isalnum +#define xp_isspace isspace +#define xp_toupper toupper +#define xp_tolower tolower +#else #define xp_isdigit iswdigit #define xp_isalpha iswalpha #define xp_isalnum iswalnum #define xp_isspace iswspace #define xp_toupper towupper #define xp_tolower towlower - -#define xp_strcpy wcscpy -#define xp_strcmp wcscmp -#define xp_strlen wcslen +#endif #define xp_memcpy memcpy #define xp_memcmp memcmp @@ -45,10 +61,6 @@ #define xp_main main -#define XP_CHAR(c) L##c -#define XP_TEXT(c) L##c -#define XP_CHAR_EOF WEOF - #define XP_NULL NULL #define xp_sizeof(n) (sizeof(n)) @@ -58,26 +70,46 @@ #define xp_false (0 != 0) typedef unsigned char xp_byte_t; -typedef int xp_bool_t; -typedef wchar_t xp_char_t; -typedef wint_t xp_cint_t; -typedef size_t xp_size_t; +typedef int xp_bool_t; +typedef size_t xp_size_t; + +#ifdef XP_CHAR_IS_MCHAR + typedef char xp_char_t; + typedef int xp_cint_t; +#else + typedef wchar_t xp_char_t; + typedef wint_t xp_cint_t; +#endif #if defined(_WIN32) || defined(vms) || defined(__vms) -typedef long xp_ssize_t; + typedef long xp_ssize_t; #else -typedef ssize_t xp_ssize_t; + typedef ssize_t xp_ssize_t; #endif #if defined(_WIN32) -typedef __int64 xp_long_t; -typedef long double xp_real_t; + typedef __int64 xp_long_t; + typedef long double xp_real_t; #elif defined(vax) || defined(__vax) -typedef long xp_long_t; -typedef long double xp_real_t; + typedef long xp_long_t; + typedef long double xp_real_t; #else -typedef long long xp_long_t; -typedef long double xp_real_t; + typedef long long xp_long_t; + typedef long double xp_real_t; +#endif + +#ifdef XP_CHAR_IS_MCHAR + #define XP_CHAR(c) c + #define XP_TEXT(c) c + #define XP_CHAR_EOF EOF +#else + #define XP_CHAR(c) L##c + #define XP_TEXT(c) L##c + #ifdef WEOF + #define XP_CHAR_EOF WEOF + #else + #define XP_CHAR_EOF ((xp_char_t)-1) + #endif #endif #define XP_STR_LEN(x) ((x)->size) @@ -99,12 +131,15 @@ struct xp_str_t extern "C" { #endif +xp_size_t xp_strlen (const xp_char_t* str); xp_char_t* xp_strdup (const xp_char_t* str); xp_char_t* xp_strxdup (const xp_char_t* str, xp_size_t len); +xp_size_t xp_strcpy (xp_char_t* buf, const xp_char_t* str); xp_size_t xp_strxncpy ( xp_char_t* buf, xp_size_t bsz, const xp_char_t* str, xp_size_t len); +int xp_strcmp (const xp_char_t* s1, const xp_char_t* s2); xp_long_t xp_strtolong (xp_char_t* str); int xp_printf (const xp_char_t* fmt, ...); diff --git a/ase/test/awk/awk.c b/ase/test/awk/awk.c index 5f58ffb4..0d0561d2 100644 --- a/ase/test/awk/awk.c +++ b/ase/test/awk/awk.c @@ -4,7 +4,7 @@ static xp_ssize_t process_source (int cmd, void* arg, xp_char_t* data, xp_size_t size) { - wchar_t c; + xp_char_t c; switch (cmd) { case XP_AWK_IO_OPEN: @@ -13,7 +13,11 @@ static xp_ssize_t process_source (int cmd, void* arg, xp_char_t* data, xp_size_t case XP_AWK_IO_DATA: if (size <= 0) return -1; +#ifdef XP_CHAR_IS_MCHAR + c = fgetc (stdin); +#else c = fgetwc (stdin); +#endif if (c == XP_CHAR_EOF) return 0; *data = c; return 1; @@ -52,7 +56,11 @@ static xp_ssize_t process_source (int cmd, void* arg, xp_char_t* data, xp_size_t #include #endif +#ifdef _WIN32 int xp_main (int argc, xp_char_t* argv[]) +#else +int xp_main (int argc, char* argv[]) +#endif { xp_awk_t awk;