diff --git a/qse/ac/au/config.guess b/qse/ac/au/config.guess index da833146..e3a2116a 100755 --- a/qse/ac/au/config.guess +++ b/qse/ac/au/config.guess @@ -1,10 +1,10 @@ #! /bin/sh # Attempt to guess a canonical system name. # Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, -# 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 +# 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 # Free Software Foundation, Inc. -timestamp='2009-04-27' +timestamp='2009-06-10' # This file is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by @@ -170,7 +170,7 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in arm*|i386|m68k|ns32k|sh3*|sparc|vax) eval $set_cc_for_build if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \ - | grep __ELF__ >/dev/null + | grep -q __ELF__ then # Once all utilities can be ECOFF (netbsdecoff) or a.out (netbsdaout). # Return netbsd for either. FIX? @@ -656,7 +656,7 @@ EOF # => hppa64-hp-hpux11.23 if echo __LP64__ | (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | - grep __LP64__ >/dev/null + grep -q __LP64__ then HP_ARCH="hppa2.0w" else @@ -822,6 +822,9 @@ EOF [345]86:Windows_95:* | [345]86:Windows_98:* | [345]86:Windows_NT:*) echo i${UNAME_MACHINE}-pc-mks exit ;; + 8664:Windows_NT:*) + echo x86_64-pc-mks + exit ;; i*:Windows_NT*:* | Pentium*:Windows_NT*:*) # How do we know it's Interix rather than the generic POSIX subsystem? # It also conflicts with pre-2.0 versions of AT&T UWIN. Should we @@ -882,40 +885,17 @@ EOF m68*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-gnu exit ;; - mips:Linux:*:*) + mips:Linux:*:* | mips64:Linux:*:*) eval $set_cc_for_build sed 's/^ //' << EOF >$dummy.c #undef CPU - #undef mips - #undef mipsel + #undef ${UNAME_MACHINE} + #undef ${UNAME_MACHINE}el #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL) - CPU=mipsel + CPU=${UNAME_MACHINE}el #else #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB) - CPU=mips - #else - CPU= - #endif - #endif -EOF - eval "`$CC_FOR_BUILD -E $dummy.c 2>/dev/null | sed -n ' - /^CPU/{ - s: ::g - p - }'`" - test x"${CPU}" != x && { echo "${CPU}-unknown-linux-gnu"; exit; } - ;; - mips64:Linux:*:*) - eval $set_cc_for_build - sed 's/^ //' << EOF >$dummy.c - #undef CPU - #undef mips64 - #undef mips64el - #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL) - CPU=mips64el - #else - #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB) - CPU=mips64 + CPU=${UNAME_MACHINE} #else CPU= #endif @@ -947,7 +927,7 @@ EOF EV67) UNAME_MACHINE=alphaev67 ;; EV68*) UNAME_MACHINE=alphaev68 ;; esac - objdump --private-headers /bin/sh | grep ld.so.1 >/dev/null + objdump --private-headers /bin/sh | grep -q ld.so.1 if test "$?" = 0 ; then LIBC="libc1" ; else LIBC="" ; fi echo ${UNAME_MACHINE}-unknown-linux-gnu${LIBC} exit ;; @@ -1001,14 +981,6 @@ EOF elf32-i386) TENTATIVE="${UNAME_MACHINE}-pc-linux-gnu" ;; - a.out-i386-linux) - echo "${UNAME_MACHINE}-pc-linux-gnuaout" - exit ;; - "") - # Either a pre-BFD a.out linker (linux-gnuoldld) or - # one that does not give us useful --help. - echo "${UNAME_MACHINE}-pc-linux-gnuoldld" - exit ;; esac # Determine whether the default compiler is a.out or elf eval $set_cc_for_build @@ -1074,7 +1046,7 @@ EOF i*86:syllable:*:*) echo ${UNAME_MACHINE}-pc-syllable exit ;; - i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.0*:*) + i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.[02]*:*) echo i386-unknown-lynxos${UNAME_RELEASE} exit ;; i*86:*DOS:*:*) @@ -1182,7 +1154,7 @@ EOF rs6000:LynxOS:2.*:*) echo rs6000-unknown-lynxos${UNAME_RELEASE} exit ;; - PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.0*:*) + PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.[02]*:*) echo powerpc-unknown-lynxos${UNAME_RELEASE} exit ;; SM[BE]S:UNIX_SV:*:*) diff --git a/qse/ac/au/config.sub b/qse/ac/au/config.sub index a39437d0..eb0389a6 100755 --- a/qse/ac/au/config.sub +++ b/qse/ac/au/config.sub @@ -1,10 +1,10 @@ #! /bin/sh # Configuration validation subroutine script. # Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, -# 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 +# 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 # Free Software Foundation, Inc. -timestamp='2009-04-17' +timestamp='2009-06-11' # This file is (in principle) common to ALL GNU software. # The presence of a machine in this file suggests that SOME GNU software @@ -153,6 +153,9 @@ case $os in os= basic_machine=$1 ;; + -bluegene*) + os=-cnk + ;; -sim | -cisco | -oki | -wec | -winbond) os= basic_machine=$1 @@ -467,6 +470,10 @@ case $basic_machine in basic_machine=bfin-`echo $basic_machine | sed 's/^[^-]*-//'` os=-linux ;; + bluegene*) + basic_machine=powerpc-ibm + os=-cnk + ;; c90) basic_machine=c90-cray os=-unicos @@ -1260,7 +1267,7 @@ case $os in # Each alternative MUST END IN A *, to match a version number. # -sysv* is not here because it comes later, after sysvr4. -gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \ - | -*vms* | -sco* | -esix* | -isc* | -aix* | -sunos | -sunos[34]*\ + | -*vms* | -sco* | -esix* | -isc* | -aix* | -cnk* | -sunos | -sunos[34]*\ | -hpux* | -unos* | -osf* | -luna* | -dgux* | -solaris* | -sym* \ | -kopensolaris* \ | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \ @@ -1613,7 +1620,7 @@ case $basic_machine in -sunos*) vendor=sun ;; - -aix*) + -cnk*|-aix*) vendor=ibm ;; -beos*) diff --git a/qse/ac/au/ltmain.sh b/qse/ac/au/ltmain.sh index 3506ead3..7ed280bc 100755 --- a/qse/ac/au/ltmain.sh +++ b/qse/ac/au/ltmain.sh @@ -1,6 +1,6 @@ # Generated from ltmain.m4sh. -# ltmain.sh (GNU libtool) 2.2.6 +# ltmain.sh (GNU libtool) 2.2.6b # Written by Gordon Matzigkeit , 1996 # Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005, 2006, 2007 2008 Free Software Foundation, Inc. @@ -65,7 +65,7 @@ # compiler: $LTCC # compiler flags: $LTCFLAGS # linker: $LD (gnu? $with_gnu_ld) -# $progname: (GNU libtool) 2.2.6 Debian-2.2.6a-4 +# $progname: (GNU libtool) 2.2.6b Debian-2.2.6b-2ubuntu1 # automake: $automake_version # autoconf: $autoconf_version # @@ -73,9 +73,9 @@ PROGRAM=ltmain.sh PACKAGE=libtool -VERSION="2.2.6 Debian-2.2.6a-4" +VERSION="2.2.6b Debian-2.2.6b-2ubuntu1" TIMESTAMP="" -package_revision=1.3012 +package_revision=1.3017 # Be Bourne compatible if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then diff --git a/qse/ac/m4/libtool.m4 b/qse/ac/m4/libtool.m4 index 1e7ea47c..a3fee536 100644 --- a/qse/ac/m4/libtool.m4 +++ b/qse/ac/m4/libtool.m4 @@ -2445,7 +2445,7 @@ linux*oldld* | linux*aout* | linux*coff*) ;; # This must be Linux ELF. -linux* | k*bsd*-gnu) +linux* | k*bsd*-gnu | kopensolaris*-gnu) version_type=linux need_lib_prefix=no need_version=no @@ -3084,7 +3084,7 @@ irix5* | irix6* | nonstopux*) ;; # This must be Linux ELF. -linux* | k*bsd*-gnu) +linux* | k*bsd*-gnu | kopensolaris*-gnu) lt_cv_deplibs_check_method=pass_all ;; @@ -3705,7 +3705,7 @@ m4_if([$1], [CXX], [ ;; esac ;; - linux* | k*bsd*-gnu) + linux* | k*bsd*-gnu | kopensolaris*-gnu) case $cc_basename in KCC*) # KAI C++ Compiler @@ -3989,7 +3989,7 @@ m4_if([$1], [CXX], [ _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' ;; - linux* | k*bsd*-gnu) + linux* | k*bsd*-gnu | kopensolaris*-gnu) case $cc_basename in # old Intel for x86_64 which still supported -KPIC. ecc*) @@ -4285,6 +4285,7 @@ dnl Note also adjust exclude_expsyms for C++ above. fi supports_anon_versioning=no case `$LD -v 2>&1` in + *GNU\ gold*) supports_anon_versioning=yes ;; *\ [[01]].* | *\ 2.[[0-9]].* | *\ 2.10.*) ;; # catch versions < 2.11 *\ 2.11.93.0.2\ *) supports_anon_versioning=yes ;; # RH7.3 ... *\ 2.11.92.0.12\ *) supports_anon_versioning=yes ;; # Mandrake 8.2 ... @@ -4376,7 +4377,7 @@ _LT_EOF _LT_TAGVAR(archive_expsym_cmds, $1)='sed "s,^,_," $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--retain-symbols-file,$output_objdir/$soname.expsym ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' ;; - gnu* | linux* | tpf* | k*bsd*-gnu) + gnu* | linux* | tpf* | k*bsd*-gnu | kopensolaris*-gnu) tmp_diet=no if test "$host_os" = linux-dietlibc; then case $cc_basename in @@ -5860,7 +5861,7 @@ if test "$_lt_caught_CXX_error" != yes; then _LT_TAGVAR(inherit_rpath, $1)=yes ;; - linux* | k*bsd*-gnu) + linux* | k*bsd*-gnu | kopensolaris*-gnu) case $cc_basename in KCC*) # Kuck and Associates, Inc. (KAI) C++ Compiler diff --git a/qse/ac/m4/ltversion.m4 b/qse/ac/m4/ltversion.m4 index b8e154fe..f3c53098 100644 --- a/qse/ac/m4/ltversion.m4 +++ b/qse/ac/m4/ltversion.m4 @@ -9,15 +9,15 @@ # Generated from ltversion.in. -# serial 3012 ltversion.m4 +# serial 3017 ltversion.m4 # This file is part of GNU Libtool -m4_define([LT_PACKAGE_VERSION], [2.2.6]) -m4_define([LT_PACKAGE_REVISION], [1.3012]) +m4_define([LT_PACKAGE_VERSION], [2.2.6b]) +m4_define([LT_PACKAGE_REVISION], [1.3017]) AC_DEFUN([LTVERSION_VERSION], -[macro_version='2.2.6' -macro_revision='1.3012' +[macro_version='2.2.6b' +macro_revision='1.3017' _LT_DECL(, macro_version, 0, [Which release of libtool.m4 was used?]) _LT_DECL(, macro_revision, 0) ]) diff --git a/qse/cmd/awk/awk.c b/qse/cmd/awk/awk.c index b0efe937..b774c180 100644 --- a/qse/cmd/awk/awk.c +++ b/qse/cmd/awk/awk.c @@ -1,5 +1,5 @@ /* - * $Id: awk.c 343 2010-08-05 07:31:17Z hyunghwan.chung $ + * $Id: awk.c 344 2010-08-17 13:15:14Z hyunghwan.chung $ * Copyright 2006-2009 Chung, Hyung-Hwan. This file is part of QSE. @@ -270,7 +270,7 @@ static void dprint_return (qse_awk_rtx_t* rtx, qse_awk_val_t* ret) static void on_statement ( qse_awk_rtx_t* rtx, qse_awk_nde_t* nde, void* data) { - dprint (L"running %d at line %d\n", (int)nde->type, (int)nde->loc.lin); + dprint (L"running %d at line %d\n", (int)nde->type, (int)nde->loc.line); } #endif @@ -659,11 +659,11 @@ static void print_awkerr (qse_awk_t* awk) print_err ( QSE_T("CODE %d LINE %u COLUMN %u %s%s%s- %s\n"), qse_awk_geterrnum(awk), - (unsigned int)loc->lin, - (unsigned int)loc->col, - ((loc->fil == QSE_NULL)? QSE_T(""): QSE_T("FILE ")), - ((loc->fil == QSE_NULL)? QSE_T(""): loc->fil), - ((loc->fil == QSE_NULL)? QSE_T(""): QSE_T(" ")), + (unsigned int)loc->line, + (unsigned int)loc->colm, + ((loc->file == QSE_NULL)? QSE_T(""): QSE_T("FILE ")), + ((loc->file == QSE_NULL)? QSE_T(""): loc->file), + ((loc->file == QSE_NULL)? QSE_T(""): QSE_T(" ")), qse_awk_geterrmsg(awk) ); } @@ -675,11 +675,11 @@ static void print_rtxerr (qse_awk_rtx_t* rtx) print_err ( QSE_T("CODE %d LINE %u COLUMN %u %s%s%s- %s\n"), qse_awk_rtx_geterrnum(rtx), - (unsigned int)loc->lin, - (unsigned int)loc->col, - ((loc->fil == QSE_NULL)? QSE_T(""): QSE_T("FILE ")), - ((loc->fil == QSE_NULL)? QSE_T(""): loc->fil), - ((loc->fil == QSE_NULL)? QSE_T(""): QSE_T(" ")), + (unsigned int)loc->line, + (unsigned int)loc->colm, + ((loc->file == QSE_NULL)? QSE_T(""): QSE_T("FILE ")), + ((loc->file == QSE_NULL)? QSE_T(""): loc->file), + ((loc->file == QSE_NULL)? QSE_T(""): QSE_T(" ")), qse_awk_rtx_geterrmsg(rtx) ); } diff --git a/qse/cmd/lsp/lsp.c b/qse/cmd/lsp/lsp.c index 4d9acab1..c5a2b609 100644 --- a/qse/cmd/lsp/lsp.c +++ b/qse/cmd/lsp/lsp.c @@ -15,118 +15,66 @@ #include #include -#ifdef _WIN32 -#include -#include -#endif - -#if defined(_WIN32) && defined(_MSC_VER) && defined(_DEBUG) -#define _CRTDBG_MAP_ALLOC -#include -#endif - -#if defined(__linux) && defined(_DEBUG) -#include -#endif - static qse_ssize_t get_input ( - int cmd, void* arg, qse_char_t* data, qse_size_t size) + qse_lsp_t* lsp, qse_lsp_io_cmd_t cmd, + qse_lsp_io_arg_t* arg, qse_char_t* data, qse_size_t size) { switch (cmd) { case QSE_LSP_IO_OPEN: + arg->handle = stdin; + return 1; + case QSE_LSP_IO_CLOSE: return 0; case QSE_LSP_IO_READ: { - /* - if (qse_fgets (data, size, stdin) == QSE_NULL) - { - if (ferror(stdin)) return -1; - return 0; - } - return qse_lsp_strlen(data); - */ - qse_cint_t c; if (size <= 0) return -1; - c = qse_fgetc (stdin); + c = qse_fgetc ((FILE*)arg->handle); if (c == QSE_CHAR_EOF) { - if (ferror(stdin)) return -1; + if (ferror((FILE*)arg->handle)) return -1; return 0; } data[0] = c; return 1; } - } - return -1; + default: + return -1; + } } static qse_ssize_t put_output ( - int cmd, void* arg, qse_char_t* data, qse_size_t size) + qse_lsp_t* lsp, qse_lsp_io_cmd_t cmd, + qse_lsp_io_arg_t* arg, qse_char_t* data, qse_size_t size) { switch (cmd) { case QSE_LSP_IO_OPEN: + arg->handle = stdout; + return 1; + case QSE_LSP_IO_CLOSE: return 0; case QSE_LSP_IO_WRITE: { int n = qse_fprintf ( - stdout, QSE_T("%.*s"), size, data); + (FILE*)arg->handle, QSE_T("%.*s"), size, data); if (n < 0) return -1; return size; } + + default: + return -1; } - - return -1; -} - -#ifdef _WIN32 -typedef struct prmfns_data_t prmfns_data_t; -struct prmfns_data_t -{ - HANDLE heap; -}; -#endif - -static void* custom_lsp_malloc (void* custom, qse_size_t n) -{ -#ifdef _WIN32 - return HeapAlloc (((prmfns_data_t*)custom)->heap, 0, n); -#else - return malloc (n); -#endif -} - -static void* custom_lsp_realloc (void* custom, void* ptr, qse_size_t n) -{ -#ifdef _WIN32 - /* HeapReAlloc behaves differently from realloc */ - if (ptr == NULL) - return HeapAlloc (((prmfns_data_t*)custom)->heap, 0, n); - else - return HeapReAlloc (((prmfns_data_t*)custom)->heap, 0, ptr, n); -#else - return realloc (ptr, n); -#endif -} - -static void custom_lsp_free (void* custom, void* ptr) -{ -#ifdef _WIN32 - HeapFree (((prmfns_data_t*)custom)->heap, 0, ptr); -#else - free (ptr); -#endif } static int custom_lsp_sprintf ( @@ -143,15 +91,6 @@ static int custom_lsp_sprintf ( return n; } - -static void custom_lsp_dprintf (void* custom, const qse_char_t* fmt, ...) -{ - va_list ap; - va_start (ap, fmt); - qse_vfprintf (stderr, fmt, ap); - va_end (ap); -} - static int opt_memsize = 1000; static int opt_meminc = 1000; @@ -222,69 +161,49 @@ int lsp_main (int argc, qse_char_t* argv[]) { qse_lsp_t* lsp; qse_lsp_obj_t* obj; - qse_lsp_prmfns_t prmfns; -#ifdef _WIN32 - prmfns_data_t prmfns_data; -#endif + qse_lsp_prm_t prm; if (handle_args (argc, argv) == -1) return -1; - qse_memset (&prmfns, 0, QSE_SIZEOF(prmfns)); + prm.sprintf = custom_lsp_sprintf; + prm.udd = QSE_NULL; - prmfns.mmgr.alloc = custom_lsp_malloc; - prmfns.mmgr.realloc = custom_lsp_realloc; - prmfns.mmgr.free = custom_lsp_free; -#ifdef _WIN32 - prmfns_data.heap = HeapCreate (0, 1000000, 1000000); - if (prmfns_data.heap == NULL) - { - qse_printf (QSE_T("Error: cannot create an lsp heap\n")); - return -1; - } - - prmfns.mmgr.udd = &prmfns_data; -#else - prmfns.mmgr.udd = QSE_NULL; -#endif - - prmfns.misc.sprintf = custom_lsp_sprintf; - prmfns.misc.dprintf = custom_lsp_dprintf; - prmfns.misc.udd = QSE_NULL; - - lsp = qse_lsp_open (&prmfns, opt_memsize, opt_meminc); + lsp = qse_lsp_open (QSE_NULL, 0, &prm, opt_memsize, opt_meminc); if (lsp == QSE_NULL) { -#ifdef _WIN32 - HeapDestroy (prmfns_data.heap); -#endif qse_printf (QSE_T("Error: cannot create a lsp instance\n")); return -1; } - qse_printf (QSE_T("ASELSP 0.0001\n")); + qse_printf (QSE_T("QSELSP 0.0001\n")); - qse_lsp_attinput (lsp, get_input, QSE_NULL); - qse_lsp_attoutput (lsp, put_output, QSE_NULL); + { + qse_lsp_io_t io = { get_input, put_output }; + qse_lsp_attachio (lsp, &io); + } while (1) { - qse_printf (QSE_T("ASELSP $ ")); + qse_printf (QSE_T("QSELSP $ ")); qse_fflush (stdout); +qse_lsp_gc (lsp); + obj = qse_lsp_read (lsp); if (obj == QSE_NULL) { - int errnum; + qse_lsp_errnum_t errnum; + qse_lsp_loc_t errloc; const qse_char_t* errmsg; - qse_lsp_geterror (lsp, &errnum, &errmsg); + qse_lsp_geterror (lsp, &errnum, &errmsg, &errloc); if (errnum != QSE_LSP_EEND && errnum != QSE_LSP_EEXIT) { qse_printf ( - QSE_T("error in read: [%d] %s\n"), - errnum, errmsg); + QSE_T("error in read: [%d] %s at line %d column %d\n"), + errnum, errmsg, (int)errloc.line, (int)errloc.colm); } /* TODO: change the following check */ @@ -299,44 +218,25 @@ int lsp_main (int argc, qse_char_t* argv[]) } else { - int errnum; + qse_lsp_errnum_t errnum; + qse_lsp_loc_t errloc; const qse_char_t* errmsg; - qse_lsp_geterror (lsp, &errnum, &errmsg); + qse_lsp_geterror (lsp, &errnum, &errmsg, &errloc); if (errnum == QSE_LSP_EEXIT) break; qse_printf ( - QSE_T("error in eval: [%d] %s\n"), - errnum, errmsg); + QSE_T("error in eval: [%d] %s at line %d column %d\n"), + errnum, errmsg, (int)errloc.line, (int)errloc.colm); } } qse_lsp_close (lsp); -#ifdef _WIN32 - HeapDestroy (prmfns_data.heap); -#endif return 0; } int qse_main (int argc, qse_achar_t* argv[]) { - int n; - -#if defined(__linux) && defined(_DEBUG) - mtrace (); -#endif - - n = qse_runmain (argc, argv, lsp_main); - -#if defined(__linux) && defined(_DEBUG) - muntrace (); -#endif -#if defined(_WIN32) && defined(_MSC_VER) && defined(_DEBUG) - _CrtDumpMemoryLeaks (); - wprintf (L"Press ENTER to quit\n"); - getchar (); -#endif - - return n; + return qse_runmain (argc, argv, lsp_main); } diff --git a/qse/cmd/sed/sed.c b/qse/cmd/sed/sed.c index c77c9ebf..ea378ae3 100644 --- a/qse/cmd/sed/sed.c +++ b/qse/cmd/sed/sed.c @@ -308,13 +308,13 @@ int sed_main (int argc, qse_char_t* argv[]) if (qse_sed_comp (sed, g_script, qse_strlen(g_script)) == -1) { const qse_sed_loc_t* errloc = qse_sed_geterrloc(sed); - if (errloc->lin > 0 || errloc->col > 0) + if (errloc->line > 0 || errloc->colm > 0) { qse_fprintf (QSE_STDERR, QSE_T("cannot compile - %s at line %lu column %lu\n"), qse_sed_geterrmsg(sed), - (unsigned long)errloc->lin, - (unsigned long)errloc->col + (unsigned long)errloc->line, + (unsigned long)errloc->colm ); } else @@ -330,13 +330,13 @@ int sed_main (int argc, qse_char_t* argv[]) if (qse_sed_exec (sed, in, out) == -1) { const qse_sed_loc_t* errloc = qse_sed_geterrloc(sed); - if (errloc->lin > 0 || errloc->col > 0) + if (errloc->line > 0 || errloc->colm > 0) { qse_fprintf (QSE_STDERR, QSE_T("cannot execute - %s at line %lu column %lu\n"), qse_sed_geterrmsg(sed), - (unsigned long)errloc->lin, - (unsigned long)errloc->col + (unsigned long)errloc->line, + (unsigned long)errloc->colm ); } else @@ -359,7 +359,7 @@ oops: return ret; } -int qse_main (int argc, char* argv[]) +int qse_main (int argc, qse_achar_t* argv[]) { return qse_runmain (argc, argv, sed_main); } diff --git a/qse/configure b/qse/configure index d5c1ae1b..08a109d7 100755 --- a/qse/configure +++ b/qse/configure @@ -5929,8 +5929,8 @@ esac -macro_version='2.2.6' -macro_revision='1.3012' +macro_version='2.2.6b' +macro_revision='1.3017' @@ -7073,7 +7073,7 @@ irix5* | irix6* | nonstopux*) ;; # This must be Linux ELF. -linux* | k*bsd*-gnu) +linux* | k*bsd*-gnu | kopensolaris*-gnu) lt_cv_deplibs_check_method=pass_all ;; @@ -10039,7 +10039,7 @@ $as_echo_n "checking for $compiler option to produce PIC... " >&6; } lt_prog_compiler_static='-non_shared' ;; - linux* | k*bsd*-gnu) + linux* | k*bsd*-gnu | kopensolaris*-gnu) case $cc_basename in # old Intel for x86_64 which still supported -KPIC. ecc*) @@ -10512,6 +10512,7 @@ $as_echo_n "checking whether the $compiler linker ($LD) supports shared librarie fi supports_anon_versioning=no case `$LD -v 2>&1` in + *GNU\ gold*) supports_anon_versioning=yes ;; *\ [01].* | *\ 2.[0-9].* | *\ 2.10.*) ;; # catch versions < 2.11 *\ 2.11.93.0.2\ *) supports_anon_versioning=yes ;; # RH7.3 ... *\ 2.11.92.0.12\ *) supports_anon_versioning=yes ;; # Mandrake 8.2 ... @@ -10603,7 +10604,7 @@ _LT_EOF archive_expsym_cmds='sed "s,^,_," $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--retain-symbols-file,$output_objdir/$soname.expsym ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' ;; - gnu* | linux* | tpf* | k*bsd*-gnu) + gnu* | linux* | tpf* | k*bsd*-gnu | kopensolaris*-gnu) tmp_diet=no if test "$host_os" = linux-dietlibc; then case $cc_basename in @@ -12065,7 +12066,7 @@ linux*oldld* | linux*aout* | linux*coff*) ;; # This must be Linux ELF. -linux* | k*bsd*-gnu) +linux* | k*bsd*-gnu | kopensolaris*-gnu) version_type=linux need_lib_prefix=no need_version=no @@ -12752,7 +12753,7 @@ else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext <<_LT_EOF -#line 12755 "configure" +#line 12756 "configure" #include "confdefs.h" #if HAVE_DLFCN_H @@ -12848,7 +12849,7 @@ else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext <<_LT_EOF -#line 12851 "configure" +#line 12852 "configure" #include "confdefs.h" #if HAVE_DLFCN_H @@ -13788,7 +13789,7 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi inherit_rpath_CXX=yes ;; - linux* | k*bsd*-gnu) + linux* | k*bsd*-gnu | kopensolaris*-gnu) case $cc_basename in KCC*) # Kuck and Associates, Inc. (KAI) C++ Compiler @@ -14616,7 +14617,7 @@ $as_echo_n "checking for $compiler option to produce PIC... " >&6; } ;; esac ;; - linux* | k*bsd*-gnu) + linux* | k*bsd*-gnu | kopensolaris*-gnu) case $cc_basename in KCC*) # KAI C++ Compiler @@ -14804,11 +14805,11 @@ else -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:14807: $lt_compile\"" >&5) + (eval echo "\"\$as_me:14808: $lt_compile\"" >&5) (eval "$lt_compile" 2>conftest.err) ac_status=$? cat conftest.err >&5 - echo "$as_me:14811: \$? = $ac_status" >&5 + echo "$as_me:14812: \$? = $ac_status" >&5 if (exit $ac_status) && test -s "$ac_outfile"; then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings other than the usual output. @@ -14903,11 +14904,11 @@ else -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:14906: $lt_compile\"" >&5) + (eval echo "\"\$as_me:14907: $lt_compile\"" >&5) (eval "$lt_compile" 2>out/conftest.err) ac_status=$? cat out/conftest.err >&5 - echo "$as_me:14910: \$? = $ac_status" >&5 + echo "$as_me:14911: \$? = $ac_status" >&5 if (exit $ac_status) && test -s out/conftest2.$ac_objext then # The compiler can only warn and ignore the option if not recognized @@ -14955,11 +14956,11 @@ else -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:14958: $lt_compile\"" >&5) + (eval echo "\"\$as_me:14959: $lt_compile\"" >&5) (eval "$lt_compile" 2>out/conftest.err) ac_status=$? cat out/conftest.err >&5 - echo "$as_me:14962: \$? = $ac_status" >&5 + echo "$as_me:14963: \$? = $ac_status" >&5 if (exit $ac_status) && test -s out/conftest2.$ac_objext then # The compiler can only warn and ignore the option if not recognized @@ -15533,7 +15534,7 @@ linux*oldld* | linux*aout* | linux*coff*) ;; # This must be Linux ELF. -linux* | k*bsd*-gnu) +linux* | k*bsd*-gnu | kopensolaris*-gnu) version_type=linux need_lib_prefix=no need_version=no diff --git a/qse/include/qse/awk/awk.h b/qse/include/qse/awk/awk.h index 5be0e58f..0e3c0818 100644 --- a/qse/include/qse/awk/awk.h +++ b/qse/include/qse/awk/awk.h @@ -1,5 +1,5 @@ /* - * $Id: awk.h 343 2010-08-05 07:31:17Z hyunghwan.chung $ + * $Id: awk.h 344 2010-08-17 13:15:14Z hyunghwan.chung $ * Copyright 2006-2009 Chung, Hyung-Hwan. This file is part of QSE. @@ -119,9 +119,9 @@ typedef struct qse_awk_rtx_t qse_awk_rtx_t; */ struct qse_awk_loc_t { - const qse_char_t* fil; /**< file */ - qse_size_t lin; /**< line */ - qse_size_t col; /**< column */ + const qse_char_t* file; /**< file */ + qse_size_t line; /**< line */ + qse_size_t colm; /**< column */ }; typedef struct qse_awk_loc_t qse_awk_loc_t; @@ -376,10 +376,10 @@ typedef enum qse_awk_sio_cmd_t qse_awk_sio_cmd_t; */ struct qse_awk_sio_lxc_t { - qse_cint_t c; /**< character */ - qse_size_t lin; /**< line */ - qse_size_t col; /**< column */ - const qse_char_t* fil; /**< file */ + qse_cint_t c; /**< character */ + qse_size_t line; /**< line */ + qse_size_t colm; /**< column */ + const qse_char_t* file; /**< file */ }; typedef struct qse_awk_sio_lxc_t qse_awk_sio_lxc_t; @@ -396,8 +396,8 @@ struct qse_awk_sio_arg_t qse_size_t len; } b; - qse_size_t lin; - qse_size_t col; + qse_size_t line; + qse_size_t colm; qse_awk_sio_lxc_t last; struct qse_awk_sio_arg_t* next; @@ -615,9 +615,9 @@ typedef struct qse_awk_rio_t qse_awk_rio_t; * statement. */ typedef void (*qse_awk_rcb_stm_t) ( - qse_awk_rtx_t* rtx, /**< runtime context */ - const qse_awk_nde_t* nde, /**< node */ - void* udd /**< user-defined data */ + qse_awk_rtx_t* rtx, /**< runtime context */ + qse_awk_nde_t* nde, /**< node */ + void* udd /**< user-defined data */ ); /** diff --git a/qse/include/qse/cut/cut.h b/qse/include/qse/cut/cut.h index ed3b3552..e9c0e4b2 100644 --- a/qse/include/qse/cut/cut.h +++ b/qse/include/qse/cut/cut.h @@ -62,7 +62,7 @@ typedef enum qse_cut_errnum_t qse_cut_errnum_t; * editor with the qse_cut_seterrstr() function to customize an error string. */ typedef const qse_char_t* (*qse_cut_errstr_t) ( - qse_cut_t* sed, /**< text cutter */ + qse_cut_t* cut, /**< text cutter */ qse_cut_errnum_t num /**< an error number */ ); @@ -119,8 +119,8 @@ typedef struct qse_cut_io_arg_t qse_cut_io_arg_t; * I/O handlers to read from and write to a text stream. */ typedef qse_ssize_t (*qse_cut_io_fun_t) ( - qse_cut_t* sed, - qse_cut_io_cmd_t cmd, + qse_cut_t* cut, + qse_cut_io_cmd_t cmd, qse_cut_io_arg_t* arg, qse_char_t* data, qse_size_t count @@ -223,9 +223,9 @@ void qse_cut_seterrnum ( * message for a given error number. */ void qse_cut_seterrmsg ( - qse_cut_t* cut, /**< text cutter */ + qse_cut_t* cut, /**< text cutter */ qse_cut_errnum_t errnum, /**< error number */ - const qse_char_t* errmsg /**< error message */ + const qse_char_t* errmsg /**< error message */ ); /** diff --git a/qse/include/qse/lsp/lsp.h b/qse/include/qse/lsp/lsp.h index 23da8c4d..38d36c77 100644 --- a/qse/include/qse/lsp/lsp.h +++ b/qse/include/qse/lsp/lsp.h @@ -24,50 +24,78 @@ #include #include -/****o* LISP/LISP Interpreter - * DESCRIPTION - * The library includes a LISP interpreter that can be embedded into other - * applications or can run stand-alone. - * - * #include - ****** +/** @file + * The file provides interface to a LISP interpreter. */ typedef struct qse_lsp_t qse_lsp_t; typedef struct qse_lsp_obj_t qse_lsp_obj_t; -typedef struct qse_lsp_prmfns_t qse_lsp_prmfns_t; +typedef struct qse_lsp_prm_t qse_lsp_prm_t; -typedef qse_ssize_t (*qse_lsp_io_t) ( - int cmd, void* arg, qse_char_t* data, qse_size_t count); +/** + * The qse_lsp_loc_t defines a structure to store location information. + */ +struct qse_lsp_loc_t +{ + const qse_char_t* file; /**< file */ + qse_size_t line; /**< line */ + qse_size_t colm; /**< column */ +}; +typedef struct qse_lsp_loc_t qse_lsp_loc_t; -typedef qse_real_t (*qse_lsp_pow_t) ( - void* data, qse_real_t x, qse_real_t y); typedef int (*qse_lsp_sprintf_t) ( void* data, qse_char_t* buf, qse_size_t size, const qse_char_t* fmt, ...); -typedef void (*qse_lsp_dprintf_t) (void* data, const qse_char_t* fmt, ...); -struct qse_lsp_prmfns_t +struct qse_lsp_prm_t { - qse_mmgr_t mmgr; - - /* utilities */ - struct - { - qse_lsp_sprintf_t sprintf; - qse_lsp_dprintf_t dprintf; - void* udd; - } misc; + qse_lsp_sprintf_t sprintf; + void* udd; }; -/* io function commands */ -enum +/** + * The qse_lsp_io_cmd_t type defines I/O commands. + */ +enum qse_lsp_io_cmd_t { QSE_LSP_IO_OPEN = 0, QSE_LSP_IO_CLOSE = 1, QSE_LSP_IO_READ = 2, QSE_LSP_IO_WRITE = 3 }; +typedef enum qse_lsp_io_cmd_t qse_lsp_io_cmd_t; + +/** + * The qse_lsp_io_arg_t type defines a data structure for an I/O handler. + */ +struct qse_lsp_io_arg_t +{ + void* handle; + const qse_char_t* path; +}; +typedef struct qse_lsp_io_arg_t qse_lsp_io_arg_t; + +/** + * The qse_lsp_io_fun_t type defines an I/O handler function. + */ +typedef qse_ssize_t (*qse_lsp_io_fun_t) ( + qse_lsp_t* lsp, + qse_lsp_io_cmd_t cmd, + qse_lsp_io_arg_t* arg, + qse_char_t* data, + qse_size_t count +); + +/** + * The qse_lsp_io_t type defines a I/O handler set. + */ +struct qse_lsp_io_t +{ + qse_lsp_io_fun_t in; + qse_lsp_io_fun_t out; +}; +typedef struct qse_lsp_io_t qse_lsp_io_t; + /* option code */ enum @@ -75,8 +103,10 @@ enum QSE_LSP_UNDEFSYMBOL = (1 << 0) }; -/* error code */ -enum +/** + * The qse_lsp_errnum_t type defines error numbers. + */ +enum qse_lsp_errnum_t { QSE_LSP_ENOERR, QSE_LSP_ENOMEM, @@ -89,7 +119,9 @@ enum QSE_LSP_ENOOUTP, QSE_LSP_EOUTPUT, + QSE_LSP_EINTERN, QSE_LSP_ESYNTAX, + QSE_LSP_ELSTDEEP, QSE_LSP_ERPAREN, QSE_LSP_EARGBAD, QSE_LSP_EARGFEW, @@ -103,47 +135,116 @@ enum QSE_LSP_EVALBAD, QSE_LSP_EDIVBY0 }; +typedef enum qse_lsp_errnum_t qse_lsp_errnum_t; -typedef qse_lsp_obj_t* (*qse_lsp_prim_t) (qse_lsp_t* lsp, qse_lsp_obj_t* obj); +typedef const qse_char_t* (*qse_lsp_errstr_t) ( + qse_lsp_t* lsp, /**< lisp */ + qse_lsp_errnum_t num /**< error number */ +); + +typedef qse_lsp_obj_t* (*qse_lsp_prim_t) ( + qse_lsp_t* lsp, + qse_lsp_obj_t* obj +); #ifdef __cplusplus extern "C" { #endif +QSE_DEFINE_COMMON_FUNCTIONS (lsp) + qse_lsp_t* qse_lsp_open ( - const qse_lsp_prmfns_t* prmfns, - qse_size_t mem_ubound, qse_size_t mem_ubound_inc); + qse_mmgr_t* mmgr, + qse_size_t xtnsize, + const qse_lsp_prm_t* prm, + qse_size_t mem_ubound, + qse_size_t mem_ubound_inc +); -void qse_lsp_close (qse_lsp_t* lsp); +void qse_lsp_close ( + qse_lsp_t* lsp /**< lisp */ +); -/** - * @function qse_lsp_setassocdata - * @brief ssociats the user-specified data with an interpreter - */ -void qse_lsp_setassocdata (qse_lsp_t* lsp, void* data); -/** - * @function qse_lsp_getassocdata - * @brief returns the user-specified data associated with an interpreter - */ -void* qse_lsp_getassocdata (qse_lsp_t* lsp); +qse_lsp_errstr_t qse_lsp_geterrstr ( + qse_lsp_t* lsp /**< lisp */ +); + +void qse_lsp_seterrstr ( + qse_lsp_t* lsp, /**< lisp */ + qse_lsp_errstr_t errstr /**< an error string getter */ +); + +qse_lsp_errnum_t qse_lsp_geterrnum ( + qse_lsp_t* lsp /**< lisp */ +); + +const qse_lsp_loc_t* qse_lsp_geterrloc ( + qse_lsp_t* lsp /**< lisp */ +); + +const qse_char_t* qse_lsp_geterrmsg ( + qse_lsp_t* lsp /**< lisp */ +); void qse_lsp_geterror ( - qse_lsp_t* lsp, int* errnum, const qse_char_t** errmsg); + qse_lsp_t* lsp, /**< lisp */ + qse_lsp_errnum_t* errnum, /**< error number */ + const qse_char_t** errmsg, /**< error message */ + qse_lsp_loc_t* errloc /**< error location */ +); + +void qse_lsp_seterrnum ( + qse_lsp_t* lsp, /**< lisp */ + qse_lsp_errnum_t errnum, /**< error number */ + const qse_cstr_t* errarg /**< argument for formatting error message */ +); + +void qse_lsp_seterrmsg ( + qse_lsp_t* lsp, /**< lisp */ + qse_lsp_errnum_t errnum, /**< error number */ + const qse_char_t* errmsg, /**< error message */ + const qse_lsp_loc_t* errloc /**< error location */ +); void qse_lsp_seterror ( - qse_lsp_t* lsp, int errnum, - const qse_char_t** errarg, qse_size_t argcnt); + qse_lsp_t* lsp, /**< lisp */ + qse_lsp_errnum_t errnum, /**< error number */ + const qse_cstr_t* errarg, /**< array of arguments for formatting + * an error message */ + const qse_lsp_loc_t* errloc /**< error location */ +); -int qse_lsp_attinput (qse_lsp_t* lsp, qse_lsp_io_t input, void* arg); -int qse_lsp_detinput (qse_lsp_t* lsp); +/** + * The qse_lsp_attachio() function attaches I/O handlers. + * Upon attachment, it opens input and output streams by calling + * the I/O handlers with the #QSE_LSP_IO_OPEN command. + */ +int qse_lsp_attachio ( + qse_lsp_t* lsp, /**< lisp */ + qse_lsp_io_t* io /**< I/O handler set */ +); -int qse_lsp_attoutput (qse_lsp_t* lsp, qse_lsp_io_t output, void* arg); -int qse_lsp_detoutput (qse_lsp_t* lsp); +/** + * The qse_lsp_detachio() function detaches I/O handlers. + * It closes the streams for both input and output by calling the I/O handlers + * with the #QSE_LSP_IO_CLOSE command. + */ +void qse_lsp_detachio ( + qse_lsp_t* lsp /**< lisp */ +); qse_lsp_obj_t* qse_lsp_read (qse_lsp_t* lsp); qse_lsp_obj_t* qse_lsp_eval (qse_lsp_t* lsp, qse_lsp_obj_t* obj); int qse_lsp_print (qse_lsp_t* lsp, const qse_lsp_obj_t* obj); + +/** + * The qse_lsp_gc() function invokes the garbage collector + */ +void qse_lsp_gc ( + qse_lsp_t* lsp /**< lisp */ +); + int qse_lsp_addprim ( qse_lsp_t* lsp, const qse_char_t* name, qse_size_t name_len, qse_lsp_prim_t prim, qse_size_t min_args, qse_size_t max_args); diff --git a/qse/include/qse/sed/sed.h b/qse/include/qse/sed/sed.h index c76df04e..56728db3 100644 --- a/qse/include/qse/sed/sed.h +++ b/qse/include/qse/sed/sed.h @@ -1,5 +1,5 @@ /* - * $Id: sed.h 340 2010-08-01 13:13:38Z hyunghwan.chung $ + * $Id: sed.h 344 2010-08-17 13:15:14Z hyunghwan.chung $ * Copyright 2006-2009 Chung, Hyung-Hwan. This file is part of QSE. @@ -65,8 +65,8 @@ typedef struct qse_sed_t qse_sed_t; */ struct qse_sed_loc_t { - qse_size_t lin; /**< line */ - qse_size_t col; /**< column */ + qse_size_t line; /**< line */ + qse_size_t colm; /**< column */ }; typedef struct qse_sed_loc_t qse_sed_loc_t; @@ -108,14 +108,14 @@ enum qse_sed_errnum_t typedef enum qse_sed_errnum_t qse_sed_errnum_t; /** - * The qse_sed_errstr_t type defines a error string getter. It should return + * The qse_sed_errstr_t type defines an error string getter. It should return * an error formatting string for an error number requested. A new string * should contain the same number of positional parameters (${X}) as in the * default error formatting string. You can set a new getter into a stream * editor with the qse_sed_seterrstr() function to customize an error string. */ typedef const qse_char_t* (*qse_sed_errstr_t) ( - qse_sed_t* sed, /**< stream editor */ + qse_sed_t* sed, /**< stream editor */ qse_sed_errnum_t num /**< an error number */ ); diff --git a/qse/lib/Makefile.am b/qse/lib/Makefile.am index 04984175..4cc6ae50 100644 --- a/qse/lib/Makefile.am +++ b/qse/lib/Makefile.am @@ -1,2 +1,2 @@ -SUBDIRS = cmn sed awk cut lsp utl +SUBDIRS = cmn sed awk cut utl DIST_SUBDIRS = $(SUBDIRS) diff --git a/qse/lib/Makefile.in b/qse/lib/Makefile.in index 446d5273..77e6bd0c 100644 --- a/qse/lib/Makefile.in +++ b/qse/lib/Makefile.in @@ -228,7 +228,7 @@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ -SUBDIRS = cmn sed awk cut lsp utl +SUBDIRS = cmn sed awk cut utl DIST_SUBDIRS = $(SUBDIRS) all: all-recursive diff --git a/qse/lib/awk/awk.c b/qse/lib/awk/awk.c index 7939a1ce..934c26a2 100644 --- a/qse/lib/awk/awk.c +++ b/qse/lib/awk/awk.c @@ -1,5 +1,5 @@ /* - * $Id: awk.c 328 2010-07-08 06:58:44Z hyunghwan.chung $ + * $Id: awk.c 344 2010-08-17 13:15:14Z hyunghwan.chung $ * Copyright 2006-2009 Chung, Hyung-Hwan. This file is part of QSE. @@ -47,9 +47,9 @@ static int init_token (qse_mmgr_t* mmgr, qse_awk_tok_t* tok) if (tok->name == QSE_NULL) return -1; tok->type = 0; - tok->loc.fil = QSE_NULL; - tok->loc.lin = 0; - tok->loc.col = 0; + tok->loc.file = QSE_NULL; + tok->loc.line = 0; + tok->loc.colm = 0; return 0; } @@ -67,9 +67,9 @@ static void clear_token (qse_awk_tok_t* tok) { if (tok->name != QSE_NULL) qse_str_clear (tok->name); tok->type = 0; - tok->loc.fil = QSE_NULL; - tok->loc.lin = 0; - tok->loc.col = 0; + tok->loc.file = QSE_NULL; + tok->loc.line = 0; + tok->loc.colm = 0; } qse_awk_t* qse_awk_open (qse_mmgr_t* mmgr, qse_size_t xtn, qse_awk_prm_t* prm) @@ -180,9 +180,9 @@ qse_awk_t* qse_awk_open (qse_mmgr_t* mmgr, qse_size_t xtn, qse_awk_prm_t* prm) awk->option = QSE_AWK_CLASSIC; awk->errinf.num = QSE_AWK_ENOERR; - awk->errinf.loc.lin = 0; - awk->errinf.loc.col = 0; - awk->errinf.loc.fil = QSE_NULL; + awk->errinf.loc.line = 0; + awk->errinf.loc.colm = 0; + awk->errinf.loc.file = QSE_NULL; awk->errstr = qse_awk_dflerrstr; awk->stopall = QSE_FALSE; @@ -328,13 +328,13 @@ int qse_awk_clear (qse_awk_t* awk) */ awk->sio.last.c = QSE_CHAR_EOF; - awk->sio.last.lin = 0; - awk->sio.last.col = 0; - awk->sio.last.fil = QSE_NULL; + awk->sio.last.line = 0; + awk->sio.last.colm = 0; + awk->sio.last.file = QSE_NULL; awk->sio.nungots = 0; - awk->sio.arg.lin = 1; - awk->sio.arg.col = 1; + awk->sio.arg.line = 1; + awk->sio.arg.colm = 1; awk->sio.arg.b.pos = 0; awk->sio.arg.b.len = 0; diff --git a/qse/lib/awk/parse.c b/qse/lib/awk/parse.c index 0614d5d9..415bfc6c 100644 --- a/qse/lib/awk/parse.c +++ b/qse/lib/awk/parse.c @@ -1,5 +1,5 @@ /* - * $Id: parse.c 343 2010-08-05 07:31:17Z hyunghwan.chung $ + * $Id: parse.c 344 2010-08-17 13:15:14Z hyunghwan.chung $ * Copyright 2006-2009 Chung, Hyung-Hwan. This file is part of QSE. @@ -446,9 +446,9 @@ static int get_char (qse_awk_t* awk) if (n == 0) { awk->sio.last.c = QSE_CHAR_EOF; - awk->sio.last.lin = awk->sio.inp->lin; - awk->sio.last.col = awk->sio.inp->col; - awk->sio.last.fil = awk->sio.inp->name; + awk->sio.last.line = awk->sio.inp->line; + awk->sio.last.colm = awk->sio.inp->colm; + awk->sio.last.file = awk->sio.inp->name; return 0; } @@ -463,14 +463,14 @@ static int get_char (qse_awk_t* awk) * incrementing it line number here instead of * updating inp->last causes the line number for * TOK_EOF to be the same line as the last newline. */ - awk->sio.inp->lin++; - awk->sio.inp->col = 1; + awk->sio.inp->line++; + awk->sio.inp->colm = 1; } awk->sio.inp->last.c = awk->sio.inp->b.buf[awk->sio.inp->b.pos++]; - awk->sio.inp->last.lin = awk->sio.inp->lin; - awk->sio.inp->last.col = awk->sio.inp->col++; - awk->sio.inp->last.fil = awk->sio.inp->name; + awk->sio.inp->last.line = awk->sio.inp->line; + awk->sio.inp->last.colm = awk->sio.inp->colm++; + awk->sio.inp->last.file = awk->sio.inp->name; awk->sio.last = awk->sio.inp->last; return 0; @@ -742,8 +742,8 @@ static int begin_include (qse_awk_t* awk) awk->sio.inp = arg; awk->parse.depth.cur.incl++; - awk->sio.inp->lin = 1; - awk->sio.inp->col = 1; + awk->sio.inp->line = 1; + awk->sio.inp->colm = 1; return 0; @@ -4676,8 +4676,8 @@ static qse_awk_nde_t* parse_primary_ident ( else if (awk->option & QSE_AWK_IMPLICIT) { if (MATCH(awk,TOK_LPAREN) && - awk->tok.loc.lin == xloc->lin && - awk->tok.loc.col == xloc->col + namelen) + awk->tok.loc.line == xloc->line && + awk->tok.loc.colm == xloc->colm + namelen) { qse_awk_nde_t* nde; @@ -5440,9 +5440,9 @@ static int skip_comment (qse_awk_t* awk) if (c == QSE_CHAR_EOF) { qse_awk_loc_t loc; - loc.lin = awk->sio.inp->lin; - loc.col = awk->sio.inp->col; - loc.fil = awk->sio.inp->name; + loc.line = awk->sio.inp->line; + loc.colm = awk->sio.inp->colm; + loc.file = awk->sio.inp->name; SETERR_LOC (awk, QSE_AWK_ECMTNC, &loc); return -1; } @@ -5453,9 +5453,9 @@ static int skip_comment (qse_awk_t* awk) if (c == QSE_CHAR_EOF) { qse_awk_loc_t loc; - loc.lin = awk->sio.inp->lin; - loc.col = awk->sio.inp->col; - loc.fil = awk->sio.inp->name; + loc.line = awk->sio.inp->line; + loc.colm = awk->sio.inp->colm; + loc.file = awk->sio.inp->name; SETERR_LOC (awk, QSE_AWK_ECMTNC, &loc); return -1; } @@ -5593,9 +5593,9 @@ retry: while (n >= 1); qse_str_clear (tok->name); - tok->loc.fil = awk->sio.last.fil; - tok->loc.lin = awk->sio.last.lin; - tok->loc.col = awk->sio.last.col; + tok->loc.file = awk->sio.last.file; + tok->loc.line = awk->sio.last.line; + tok->loc.colm = awk->sio.last.colm; c = awk->sio.last.c; @@ -5695,17 +5695,17 @@ retry: static int get_token (qse_awk_t* awk) { awk->ptok.type = awk->tok.type; - awk->ptok.loc.fil = awk->tok.loc.fil; - awk->ptok.loc.lin = awk->tok.loc.lin; - awk->ptok.loc.col = awk->tok.loc.col; + awk->ptok.loc.file = awk->tok.loc.file; + awk->ptok.loc.line = awk->tok.loc.line; + awk->ptok.loc.colm = awk->tok.loc.colm; qse_str_swap (awk->ptok.name, awk->tok.name); if (QSE_STR_LEN(awk->ntok.name) > 0) { awk->tok.type = awk->ntok.type; - awk->tok.loc.fil = awk->ntok.loc.fil; - awk->tok.loc.lin = awk->ntok.loc.lin; - awk->tok.loc.col = awk->ntok.loc.col; + awk->tok.loc.file = awk->ntok.loc.file; + awk->tok.loc.line = awk->ntok.loc.line; + awk->tok.loc.colm = awk->ntok.loc.colm; qse_str_swap (awk->tok.name, awk->ntok.name); qse_str_clear (awk->ntok.name); diff --git a/qse/lib/lsp/Makefile.am b/qse/lib/lsp/Makefile.am index 20ef0bd4..84624e8f 100644 --- a/qse/lib/lsp/Makefile.am +++ b/qse/lib/lsp/Makefile.am @@ -5,6 +5,6 @@ AM_CPPFLAGS = -I$(top_srcdir)/include lib_LTLIBRARIES = libqselsp.la -libqselsp_la_SOURCES = lsp.c err.c env.c eval.c mem.c mem.h misc.c name.c prim.c prim_compar.c prim.h prim_let.c prim_math.c prim_prog.c print.c read.c lsp.h env.h misc.h name.h obj.h +libqselsp_la_SOURCES = lsp.c err.c env.c eval.c mem.c mem.h misc.c prim.c prim_compar.c prim.h prim_let.c prim_math.c prim_prog.c print.c read.c lsp.h env.h misc.h obj.h libqselsp_la_LDFLAGS = -L../cmn -version-info 1:0:0 -no-undefined libqselsp_la_LIBADD = -lqsecmn diff --git a/qse/lib/lsp/Makefile.in b/qse/lib/lsp/Makefile.in index 69a22220..f3710f69 100644 --- a/qse/lib/lsp/Makefile.in +++ b/qse/lib/lsp/Makefile.in @@ -73,8 +73,8 @@ am__installdirs = "$(DESTDIR)$(libdir)" LTLIBRARIES = $(lib_LTLIBRARIES) libqselsp_la_DEPENDENCIES = am_libqselsp_la_OBJECTS = lsp.lo err.lo env.lo eval.lo mem.lo misc.lo \ - name.lo prim.lo prim_compar.lo prim_let.lo prim_math.lo \ - prim_prog.lo print.lo read.lo + prim.lo prim_compar.lo prim_let.lo prim_math.lo prim_prog.lo \ + print.lo read.lo libqselsp_la_OBJECTS = $(am_libqselsp_la_OBJECTS) libqselsp_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ @@ -239,7 +239,7 @@ top_srcdir = @top_srcdir@ AUTOMAKE_OPTIONS = nostdinc AM_CPPFLAGS = -I$(top_srcdir)/include lib_LTLIBRARIES = libqselsp.la -libqselsp_la_SOURCES = lsp.c err.c env.c eval.c mem.c mem.h misc.c name.c prim.c prim_compar.c prim.h prim_let.c prim_math.c prim_prog.c print.c read.c lsp.h env.h misc.h name.h obj.h +libqselsp_la_SOURCES = lsp.c err.c env.c eval.c mem.c mem.h misc.c prim.c prim_compar.c prim.h prim_let.c prim_math.c prim_prog.c print.c read.c lsp.h env.h misc.h obj.h libqselsp_la_LDFLAGS = -L../cmn -version-info 1:0:0 -no-undefined libqselsp_la_LIBADD = -lqsecmn all: all-am @@ -322,7 +322,6 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lsp.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mem.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/misc.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/name.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/prim.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/prim_compar.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/prim_let.Plo@am__quote@ diff --git a/qse/lib/lsp/env.c b/qse/lib/lsp/env.c index 640af4aa..706adcd2 100644 --- a/qse/lib/lsp/env.c +++ b/qse/lib/lsp/env.c @@ -1,7 +1,21 @@ /* * $Id: env.c 337 2008-08-20 09:17:25Z baconevi $ * - * {License} + Copyright 2006-2009 Chung, Hyung-Hwan. + This file is part of QSE. + + QSE is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as + published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. + + QSE is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with QSE. If not, see . */ #include "lsp.h" diff --git a/qse/lib/lsp/env.h b/qse/lib/lsp/env.h index 8fafa9d7..ecdfbe37 100644 --- a/qse/lib/lsp/env.h +++ b/qse/lib/lsp/env.h @@ -1,11 +1,25 @@ /* * $Id: env.h 117 2008-03-03 11:20:05Z baconevi $ * - * {License} + Copyright 2006-2009 Chung, Hyung-Hwan. + This file is part of QSE. + + QSE is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as + published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. + + QSE is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with QSE. If not, see . */ -#ifndef _QSE_LSP_ENV_H_ -#define _QSE_LSP_ENV_H_ +#ifndef _QSE_LIB_LSP_ENV_H_ +#define _QSE_LIB_LSP_ENV_H_ #ifndef _QSE_LSP_LSP_H_ #error Never include this file directly. Include instead diff --git a/qse/lib/lsp/err.c b/qse/lib/lsp/err.c index 05d70473..1db5e198 100644 --- a/qse/lib/lsp/err.c +++ b/qse/lib/lsp/err.c @@ -1,14 +1,28 @@ /* * $Id: err.c 337 2008-08-20 09:17:25Z baconevi $ * - * {License} + Copyright 2006-2009 Chung, Hyung-Hwan. + This file is part of QSE. + + QSE is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as + published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. + + QSE is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with QSE. If not, see . */ #include "lsp.h" -static const qse_char_t* __geterrstr (int errnum) +const qse_char_t* qse_lsp_dflerrstr (qse_lsp_t* lsp, qse_lsp_errnum_t errnum) { - static const qse_char_t* __errstr[] = + static const qse_char_t* errstr[] = { QSE_T("no error"), QSE_T("out of memory"), @@ -19,112 +33,97 @@ static const qse_char_t* __geterrstr (int errnum) QSE_T("input"), QSE_T("output not attached"), QSE_T("output"), + + QSE_T("internal error"), QSE_T("syntax"), + QSE_T("list too deep"), QSE_T("right parenthesis expected"), QSE_T("bad arguments"), QSE_T("too few arguments"), QSE_T("too many arguments"), - QSE_T("undefined function '%s'"), + QSE_T("undefined function '${0}'"), QSE_T("bad function"), QSE_T("duplicate formal"), QSE_T("bad symbol"), - QSE_T("undefined symbol '%s'"), + QSE_T("undefined symbol '${0}'"), QSE_T("empty body"), QSE_T("bad value"), QSE_T("divide by zero") }; - if (errnum >= 0 && errnum < QSE_COUNTOF(__errstr)) - { - return __errstr[errnum]; - } + return (errnum >= 0 && errnum < QSE_COUNTOF(errstr))? + errstr[errnum]: QSE_T("unknown error"); +} - return QSE_T("unknown error"); +qse_lsp_errstr_t qse_lsp_geterrstr (qse_lsp_t* lsp) +{ + return lsp->errstr; +} + +void qse_lsp_seterrstr (qse_lsp_t* lsp, qse_lsp_errstr_t errstr) +{ + lsp->errstr = errstr; +} + +qse_lsp_errnum_t qse_lsp_geterrnum (qse_lsp_t* lsp) +{ + return lsp->errnum; +} + +const qse_lsp_loc_t* qse_lsp_geterrloc (qse_lsp_t* lsp) +{ + return &lsp->errloc; +} + +const qse_char_t* qse_lsp_geterrmsg (qse_lsp_t* lsp) +{ + return (lsp->errmsg[0] == QSE_T('\0'))? + qse_lsp_geterrstr(lsp)(lsp,lsp->errnum): lsp->errmsg; } void qse_lsp_geterror ( - qse_lsp_t* lsp, int* errnum, const qse_char_t** errmsg) + qse_lsp_t* lsp, qse_lsp_errnum_t* errnum, + const qse_char_t** errmsg, qse_lsp_loc_t* errloc) { if (errnum != QSE_NULL) *errnum = lsp->errnum; - if (errmsg != QSE_NULL) *errmsg = lsp->errmsg; + if (errmsg != QSE_NULL) + { + *errmsg = (lsp->errmsg[0] == QSE_T('\0'))? + qse_lsp_geterrstr(lsp)(lsp,lsp->errnum): + lsp->errmsg; + } + if (errloc != QSE_NULL) *errloc = lsp->errloc; +} + +void qse_lsp_seterrnum ( + qse_lsp_t* lsp, qse_lsp_errnum_t errnum, const qse_cstr_t* errarg) +{ + qse_lsp_seterror (lsp, errnum, errarg, QSE_NULL); +} + +void qse_lsp_seterrmsg ( + qse_lsp_t* lsp, qse_lsp_errnum_t errnum, + const qse_char_t* errmsg, const qse_lsp_loc_t* errloc) +{ + lsp->errnum = errnum; + qse_strxcpy (lsp->errmsg, QSE_COUNTOF(lsp->errmsg), errmsg); + if (errloc != QSE_NULL) lsp->errloc = *errloc; + else QSE_MEMSET (&lsp->errloc, 0, QSE_SIZEOF(lsp->errloc)); } void qse_lsp_seterror ( - qse_lsp_t* lsp, int errnum, - const qse_char_t** errarg, qse_size_t argcnt) + qse_lsp_t* lsp, qse_lsp_errnum_t errnum, + const qse_cstr_t* errarg, const qse_lsp_loc_t* errloc) { const qse_char_t* errfmt; - QSE_ASSERT (argcnt <= 5); - lsp->errnum = errnum; - errfmt = __geterrstr (errnum); - switch (argcnt) - { - case 0: - lsp->prmfns.misc.sprintf ( - lsp->prmfns.misc.udd, - lsp->errmsg, - QSE_COUNTOF(lsp->errmsg), - errfmt); - return; + errfmt = qse_lsp_geterrstr(lsp)(lsp,lsp->errnum); + QSE_ASSERT (errfmt != QSE_NULL); + qse_strxfncpy (lsp->errmsg, QSE_COUNTOF(lsp->errmsg), errfmt, errarg); - case 1: - lsp->prmfns.misc.sprintf ( - lsp->prmfns.misc.udd, - lsp->errmsg, - QSE_COUNTOF(lsp->errmsg), - errfmt, - errarg[0]); - return; - - case 2: - lsp->prmfns.misc.sprintf ( - lsp->prmfns.misc.udd, - lsp->errmsg, - QSE_COUNTOF(lsp->errmsg), - errfmt, - errarg[0], - errarg[1]); - return; - - case 3: - lsp->prmfns.misc.sprintf ( - lsp->prmfns.misc.udd, - lsp->errmsg, - QSE_COUNTOF(lsp->errmsg), - errfmt, - errarg[0], - errarg[1], - errarg[2]); - return; - - case 4: - lsp->prmfns.misc.sprintf ( - lsp->prmfns.misc.udd, - lsp->errmsg, - QSE_COUNTOF(lsp->errmsg), - errfmt, - errarg[0], - errarg[1], - errarg[2], - errarg[3]); - return; - - case 5: - lsp->prmfns.misc.sprintf ( - lsp->prmfns.misc.udd, - lsp->errmsg, - QSE_COUNTOF(lsp->errmsg), - errfmt, - errarg[0], - errarg[1], - errarg[2], - errarg[3], - errarg[4]); - return; - } + if (errloc != QSE_NULL) lsp->errloc = *errloc; + else QSE_MEMSET (&lsp->errloc, 0, QSE_SIZEOF(lsp->errloc)); } - diff --git a/qse/lib/lsp/eval.c b/qse/lib/lsp/eval.c index 50bdab23..254da26a 100644 --- a/qse/lib/lsp/eval.c +++ b/qse/lib/lsp/eval.c @@ -1,7 +1,21 @@ /* * $Id: eval.c 337 2008-08-20 09:17:25Z baconevi $ * - * {License} + Copyright 2006-2009 Chung, Hyung-Hwan. + This file is part of QSE. + + QSE is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as + published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. + + QSE is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with QSE. If not, see . */ #include "lsp.h" @@ -44,13 +58,12 @@ qse_lsp_obj_t* qse_lsp_eval (qse_lsp_t* lsp, qse_lsp_obj_t* obj) { if (lsp->opt_undef_symbol) { - const qse_char_t* arg[1]; + qse_cstr_t errarg; - arg[0] = QSE_LSP_SYMPTR(obj); + errarg.len = QSE_LSP_SYMLEN(obj); + errarg.ptr = QSE_LSP_SYMPTR(obj); - qse_lsp_seterror ( - lsp, QSE_LSP_EUNDEFSYM, - arg, QSE_COUNTOF(arg)); + qse_lsp_seterror (lsp, QSE_LSP_EUNDEFSYM, &errarg, QSE_NULL); return QSE_NULL; } return lsp->mem->nil; @@ -68,13 +81,13 @@ static qse_lsp_obj_t* makefn (qse_lsp_t* lsp, qse_lsp_obj_t* cdr, int is_macro) if (cdr == lsp->mem->nil) { - qse_lsp_seterror (lsp, QSE_LSP_EARGFEW, QSE_NULL, 0); + qse_lsp_seterror (lsp, QSE_LSP_EARGFEW, QSE_NULL, QSE_NULL); return QSE_NULL; } if (QSE_LSP_TYPE(cdr) != QSE_LSP_OBJ_CONS) { - qse_lsp_seterror (lsp, QSE_LSP_EARGBAD, QSE_NULL, 0); + qse_lsp_seterror (lsp, QSE_LSP_EARGBAD, QSE_NULL, QSE_NULL); return QSE_NULL; } @@ -83,7 +96,7 @@ static qse_lsp_obj_t* makefn (qse_lsp_t* lsp, qse_lsp_obj_t* cdr, int is_macro) if (body == lsp->mem->nil) { - qse_lsp_seterror (lsp, QSE_LSP_EEMPBDY, QSE_NULL, 0); + qse_lsp_seterror (lsp, QSE_LSP_EEMPBDY, QSE_NULL, QSE_NULL); return QSE_NULL; } @@ -95,7 +108,7 @@ static qse_lsp_obj_t* makefn (qse_lsp_t* lsp, qse_lsp_obj_t* cdr, int is_macro) if (p != lsp->mem->nil) { /* like in (lambda (x) (+ x 10) . 4) */ - qse_lsp_seterror (lsp, QSE_LSP_EARGBAD, QSE_NULL, 0); + qse_lsp_seterror (lsp, QSE_LSP_EARGBAD, QSE_NULL, QSE_NULL); return QSE_NULL; } @@ -137,13 +150,12 @@ static qse_lsp_obj_t* eval_cons (qse_lsp_t* lsp, qse_lsp_obj_t* cons) if (func == QSE_NULL) { /* the symbol's function definition is void */ - const qse_char_t* arg[1]; + qse_cstr_t errarg; - arg[0] = QSE_LSP_SYMPTR(car); - qse_lsp_seterror ( - lsp, QSE_LSP_EUNDEFFN, - arg, QSE_COUNTOF(arg)); + errarg.len = QSE_LSP_SYMLEN(car); + errarg.ptr = QSE_LSP_SYMPTR(car); + qse_lsp_seterror (lsp, QSE_LSP_EUNDEFFN, &errarg, QSE_NULL); return QSE_NULL; } @@ -159,25 +171,23 @@ static qse_lsp_obj_t* eval_cons (qse_lsp_t* lsp, qse_lsp_obj_t* cons) } else { - const qse_char_t* arg[1]; + qse_cstr_t errarg; - arg[0] = QSE_LSP_SYMPTR(car); - qse_lsp_seterror ( - lsp, QSE_LSP_EUNDEFFN, - arg, QSE_COUNTOF(arg)); + errarg.len = QSE_LSP_SYMLEN(car); + errarg.ptr = QSE_LSP_SYMPTR(car); + qse_lsp_seterror (lsp, QSE_LSP_EUNDEFFN, &errarg, QSE_NULL); return QSE_NULL; } } else { - const qse_char_t* arg[1]; + qse_cstr_t errarg; - arg[0] = QSE_LSP_SYMPTR(car); - qse_lsp_seterror ( - lsp, QSE_LSP_EUNDEFFN, - arg, QSE_COUNTOF(arg)); + errarg.len = QSE_LSP_SYMLEN(car); + errarg.ptr = QSE_LSP_SYMPTR(car); + qse_lsp_seterror (lsp, QSE_LSP_EUNDEFFN, &errarg, QSE_NULL); return QSE_NULL; } } @@ -204,7 +214,7 @@ static qse_lsp_obj_t* eval_cons (qse_lsp_t* lsp, qse_lsp_obj_t* cons) } } - qse_lsp_seterror (lsp, QSE_LSP_EBADFN, QSE_NULL, 0); + qse_lsp_seterror (lsp, QSE_LSP_EBADFN, QSE_NULL, QSE_NULL); return QSE_NULL; } @@ -252,7 +262,7 @@ static qse_lsp_obj_t* apply ( mem->brooding_frame = frame->link; qse_lsp_freeframe (lsp, frame); - qse_lsp_seterror (lsp, QSE_LSP_EARGFEW, QSE_NULL, 0); + qse_lsp_seterror (lsp, QSE_LSP_EARGFEW, QSE_NULL, QSE_NULL); return QSE_NULL; } @@ -275,7 +285,7 @@ static qse_lsp_obj_t* apply ( mem->brooding_frame = frame->link; qse_lsp_freeframe (lsp, frame); - qse_lsp_seterror (lsp, QSE_LSP_EDUPFML, QSE_NULL, 0); + qse_lsp_seterror (lsp, QSE_LSP_EDUPFML, QSE_NULL, QSE_NULL); return QSE_NULL; } @@ -296,7 +306,7 @@ static qse_lsp_obj_t* apply ( mem->brooding_frame = frame->link; qse_lsp_freeframe (lsp, frame); - qse_lsp_seterror (lsp, QSE_LSP_EARGMANY, QSE_NULL, 0); + qse_lsp_seterror (lsp, QSE_LSP_EARGMANY, QSE_NULL, QSE_NULL); return QSE_NULL; } else if (actual != mem->nil) @@ -304,7 +314,7 @@ static qse_lsp_obj_t* apply ( mem->brooding_frame = frame->link; qse_lsp_freeframe (lsp, frame); - qse_lsp_seterror (lsp, QSE_LSP_EARGBAD, QSE_NULL, 0); + qse_lsp_seterror (lsp, QSE_LSP_EARGBAD, QSE_NULL, QSE_NULL); return QSE_NULL; } @@ -359,19 +369,19 @@ static qse_lsp_obj_t* apply_to_prim ( } if (obj != lsp->mem->nil) { - qse_lsp_seterror (lsp, QSE_LSP_EARGBAD, QSE_NULL, 0); + qse_lsp_seterror (lsp, QSE_LSP_EARGBAD, QSE_NULL, QSE_NULL); return QSE_NULL; } if (count < QSE_LSP_PMINARGS(func)) { - qse_lsp_seterror (lsp, QSE_LSP_EARGFEW, QSE_NULL, 0); + qse_lsp_seterror (lsp, QSE_LSP_EARGFEW, QSE_NULL, QSE_NULL); return QSE_NULL; } if (count > QSE_LSP_PMAXARGS(func)) { - qse_lsp_seterror (lsp, QSE_LSP_EARGMANY, QSE_NULL, 0); + qse_lsp_seterror (lsp, QSE_LSP_EARGMANY, QSE_NULL, QSE_NULL); return QSE_NULL; } diff --git a/qse/lib/lsp/lsp.c b/qse/lib/lsp/lsp.c index 272b5c30..ba4ae271 100644 --- a/qse/lib/lsp/lsp.c +++ b/qse/lib/lsp/lsp.c @@ -1,50 +1,79 @@ /* * $Id: lsp.c 337 2008-08-20 09:17:25Z baconevi $ * - * {License} + Copyright 2006-2009 Chung, Hyung-Hwan. + This file is part of QSE. + + QSE is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as + published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. + + QSE is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with QSE. If not, see . */ -#if defined(__BORLANDC__) -#pragma hdrstop -#define Library -#endif - #include "lsp.h" +QSE_IMPLEMENT_COMMON_FUNCTIONS (lsp) + +static qse_lsp_t* qse_lsp_init ( + qse_lsp_t* lsp, qse_mmgr_t* mmgr, const qse_lsp_prm_t* prm, + qse_size_t mem_ubound, qse_size_t mem_ubound_inc); +static void qse_lsp_fini (qse_lsp_t* lsp); + static int __add_builtin_prims (qse_lsp_t* lsp); qse_lsp_t* qse_lsp_open ( - const qse_lsp_prmfns_t* prmfns, + qse_mmgr_t* mmgr, qse_size_t xtnsize, const qse_lsp_prm_t* prm, qse_size_t mem_ubound, qse_size_t mem_ubound_inc) { qse_lsp_t* lsp; - if (prmfns == QSE_NULL) return QSE_NULL; + if (mmgr == QSE_NULL) + { + mmgr = QSE_MMGR_GETDFL(); -/* - if (prmfns->mmgr.malloc == QSE_NULL || - prmfns->mmgr.realloc == QSE_NULL || - prmfns->mmgr.free == QSE_NULL) return QSE_NULL; -*/ + QSE_ASSERTX (mmgr != QSE_NULL, + "Set the memory manager with QSE_MMGR_SETDFL()"); - if (prmfns->misc.sprintf == QSE_NULL || - prmfns->misc.dprintf == QSE_NULL) return QSE_NULL; + if (mmgr == QSE_NULL) return QSE_NULL; + } -#if defined(_WIN32) && defined(_MSC_VER) && defined(_DEBUG) - lsp = (qse_lsp_t*) malloc (QSE_SIZEOF(qse_lsp_t)); -#else - lsp = (qse_lsp_t*) prmfns->mmgr.alloc ( - prmfns->mmgr.udd, QSE_SIZEOF(qse_lsp_t)); -#endif + lsp = (qse_lsp_t*) QSE_MMGR_ALLOC (mmgr, QSE_SIZEOF(qse_lsp_t) + xtnsize); if (lsp == QSE_NULL) return QSE_NULL; - /* it uses the built-in qse_lsp_memset because lsp is not - * fully initialized yet */ - QSE_MEMSET (lsp, 0, QSE_SIZEOF(qse_lsp_t)); - QSE_MEMCPY (&lsp->prmfns, prmfns, QSE_SIZEOF(lsp->prmfns)); - lsp->assoc_data = QSE_NULL; + if (qse_lsp_init (lsp, mmgr, prm, mem_ubound, mem_ubound_inc) == QSE_NULL) + { + QSE_MMGR_FREE (lsp->mmgr, lsp); + return QSE_NULL; + } - if (qse_lsp_name_open(&lsp->token.name, 0, lsp) == QSE_NULL) + return lsp; +} + +void qse_lsp_close (qse_lsp_t* lsp) +{ + qse_lsp_fini (lsp); + QSE_LSP_FREE (lsp, lsp); +} + +static qse_lsp_t* qse_lsp_init ( + qse_lsp_t* lsp, qse_mmgr_t* mmgr, const qse_lsp_prm_t* prm, + qse_size_t mem_ubound, qse_size_t mem_ubound_inc) +{ + QSE_MEMSET (lsp, 0, QSE_SIZEOF(*lsp)); + + lsp->mmgr = mmgr; + lsp->errstr = qse_lsp_dflerrstr; + lsp->prm = *prm; + + if (qse_str_init(&lsp->token.name, mmgr, 256) == QSE_NULL) { QSE_LSP_FREE (lsp, lsp); return QSE_NULL; @@ -56,15 +85,13 @@ qse_lsp_t* qse_lsp_open ( /*lsp->opt_undef_symbol = 0;*/ lsp->curc = QSE_CHAR_EOF; - lsp->input_func = QSE_NULL; - lsp->output_func = QSE_NULL; - lsp->input_arg = QSE_NULL; - lsp->output_arg = QSE_NULL; + lsp->curloc.line = 1; + lsp->curloc.colm = 0; lsp->mem = qse_lsp_openmem (lsp, mem_ubound, mem_ubound_inc); if (lsp->mem == QSE_NULL) { - qse_lsp_name_close (&lsp->token.name); + qse_str_fini (&lsp->token.name); QSE_LSP_FREE (lsp, lsp); return QSE_NULL; } @@ -72,7 +99,7 @@ qse_lsp_t* qse_lsp_open ( if (__add_builtin_prims(lsp) == -1) { qse_lsp_closemem (lsp->mem); - qse_lsp_name_close (&lsp->token.name); + qse_str_fini (&lsp->token.name); QSE_LSP_FREE (lsp, lsp); return QSE_NULL; } @@ -83,88 +110,51 @@ qse_lsp_t* qse_lsp_open ( return lsp; } -void qse_lsp_close (qse_lsp_t* lsp) +static void qse_lsp_fini (qse_lsp_t* lsp) { qse_lsp_closemem (lsp->mem); - qse_lsp_name_close (&lsp->token.name); - QSE_LSP_FREE (lsp, lsp); + qse_str_fini (&lsp->token.name); } -void qse_lsp_setassocdata (qse_lsp_t* lsp, void* data) +void qse_lsp_detachio (qse_lsp_t* lsp) { - lsp->assoc_data = data; -} - -void* qse_lsp_getassocdata (qse_lsp_t* lsp) -{ - return lsp->assoc_data; -} - -int qse_lsp_attinput (qse_lsp_t* lsp, qse_lsp_io_t input, void* arg) -{ - if (qse_lsp_detinput(lsp) == -1) return -1; - - QSE_ASSERT (lsp->input_func == QSE_NULL); - - if (input(QSE_LSP_IO_OPEN, arg, QSE_NULL, 0) == -1) + if (lsp->io.fns.out) { - /* TODO: set error number */ + lsp->io.fns.out (lsp, QSE_LSP_IO_CLOSE, &lsp->io.arg.out, QSE_NULL, 0); + lsp->io.fns.out = QSE_NULL; + } + if (lsp->io.fns.in) + { + lsp->io.fns.in (lsp, QSE_LSP_IO_CLOSE, &lsp->io.arg.in, QSE_NULL, 0); + lsp->io.fns.in = QSE_NULL; + lsp->curc = QSE_CHAR_EOF; /* TODO: needed??? */ + } +} + +int qse_lsp_attachio (qse_lsp_t* lsp, qse_lsp_io_t* io) +{ + qse_lsp_detachio(lsp); + + QSE_ASSERT (lsp->io.fns.in == QSE_NULL); + QSE_ASSERT (lsp->io.fns.out == QSE_NULL); + + if (io->in (lsp, QSE_LSP_IO_OPEN, &lsp->io.arg.in, QSE_NULL, 0) <= -1) + { + /* TODO: error code if error not set... */ return -1; } - lsp->input_func = input; - lsp->input_arg = arg; + if (io->out (lsp, QSE_LSP_IO_OPEN, &lsp->io.arg.out, QSE_NULL, 0) <= -1) + { + /* TODO: error code if error not set... */ + io->in (lsp, QSE_LSP_IO_CLOSE, &lsp->io.arg.in, QSE_NULL, 0); + return -1; + } + + lsp->io.fns = *io; lsp->curc = QSE_CHAR_EOF; - return 0; -} - -int qse_lsp_detinput (qse_lsp_t* lsp) -{ - if (lsp->input_func != QSE_NULL) - { - if (lsp->input_func ( - QSE_LSP_IO_CLOSE, lsp->input_arg, QSE_NULL, 0) == -1) - { - /* TODO: set error number */ - return -1; - } - lsp->input_func = QSE_NULL; - lsp->input_arg = QSE_NULL; - lsp->curc = QSE_CHAR_EOF; - } - - return 0; -} - -int qse_lsp_attoutput (qse_lsp_t* lsp, qse_lsp_io_t output, void* arg) -{ - if (qse_lsp_detoutput(lsp) == -1) return -1; - - QSE_ASSERT (lsp->output_func == QSE_NULL); - - if (output(QSE_LSP_IO_OPEN, arg, QSE_NULL, 0) == -1) - { - /* TODO: set error number */ - return -1; - } - lsp->output_func = output; - lsp->output_arg = arg; - return 0; -} - -int qse_lsp_detoutput (qse_lsp_t* lsp) -{ - if (lsp->output_func != QSE_NULL) - { - if (lsp->output_func ( - QSE_LSP_IO_CLOSE, lsp->output_arg, QSE_NULL, 0) == -1) - { - /* TODO: set error number */ - return -1; - } - lsp->output_func = QSE_NULL; - lsp->output_arg = QSE_NULL; - } + lsp->curloc.line = 1; + lsp->curloc.colm = 0; return 0; } @@ -195,7 +185,7 @@ static int __add_builtin_prims (qse_lsp_t* lsp) ADD_PRIM (lsp, QSE_T("setq"), 4, qse_lsp_prim_setq, 1, MAX_ARGS); ADD_PRIM (lsp, QSE_T("quote"), 5, qse_lsp_prim_quote, 1, 1); ADD_PRIM (lsp, QSE_T("defun"), 5, qse_lsp_prim_defun, 3, MAX_ARGS); - ADD_PRIM (lsp, QSE_T("demac"), 5, qse_lsp_prim_demac, 3, MAX_ARGS); + ADD_PRIM (lsp, QSE_T("macro"), 5, qse_lsp_prim_demac, 3, MAX_ARGS); ADD_PRIM (lsp, QSE_T("let"), 3, qse_lsp_prim_let, 1, MAX_ARGS); ADD_PRIM (lsp, QSE_T("let*"), 4, qse_lsp_prim_letx, 1, MAX_ARGS); /*ADD_PRIM (lsp, QSE_T("or"), 2, qse_lsp_prim_or, 2, MAX_ARGS);*/ diff --git a/qse/lib/lsp/lsp.h b/qse/lib/lsp/lsp.h index 43171a6b..c7353aba 100644 --- a/qse/lib/lsp/lsp.h +++ b/qse/lib/lsp/lsp.h @@ -1,7 +1,21 @@ /* - * $Id: lsp_i.h 332 2008-08-18 11:21:48Z baconevi $ + * $Id: lsp.h 332 2008-08-18 11:21:48Z baconevi $ * - * {License} + Copyright 2006-2009 Chung, Hyung-Hwan. + This file is part of QSE. + + QSE is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as + published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. + + QSE is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with QSE. If not, see . */ #ifndef _QSE_LIB_LSP_LSP_H_ @@ -17,15 +31,14 @@ #include "mem.h" #include "misc.h" #include "prim.h" -#include "name.h" #ifdef _MSC_VER #pragma warning (disable: 4996) #endif -#define QSE_LSP_ALLOC(lsp,size) QSE_MMGR_ALLOC(&(lsp)->prmfns.mmgr,size) -#define QSE_LSP_REALLOC(lsp,ptr,size) QSE_MMGR_REALLOC(&(lsp)->prmfns.mmgr,ptr,size) -#define QSE_LSP_FREE(lsp,ptr) QSE_MMGR_FREE(&(lsp)->prmfns.mmgr,ptr) +#define QSE_LSP_ALLOC(lsp,size) QSE_MMGR_ALLOC((lsp)->mmgr,size) +#define QSE_LSP_REALLOC(lsp,ptr,size) QSE_MMGR_REALLOC((lsp)->mmgr,ptr,size) +#define QSE_LSP_FREE(lsp,ptr) QSE_MMGR_FREE((lsp)->mmgr,ptr) #define QSE_LSP_ISUPPER(lsp,c) QSE_ISUPPER(c) #define QSE_LSP_ISLOWER(lsp,c) QSE_ISLOWER(c) @@ -43,32 +56,42 @@ struct qse_lsp_t { - qse_lsp_prmfns_t prmfns; - /* user-specified data */ - void* assoc_data; + QSE_DEFINE_COMMON_FIELDS (lsp) - /* error */ - int errnum; - qse_char_t errmsg[256]; + qse_lsp_prm_t prm; + + qse_lsp_errstr_t errstr; /**< error string getter */ + qse_lsp_errnum_t errnum; /**< stores an error number */ + qse_char_t errmsg[128]; /**< error message holder */ + qse_lsp_loc_t errloc; /**< location of the last error */ /* options */ int opt_undef_symbol; /* for read */ - qse_cint_t curc; + qse_cint_t curc; + qse_lsp_loc_t curloc; + struct { - int type; - qse_long_t ival; - qse_real_t rval; - qse_lsp_name_t name; + int type; + qse_lsp_loc_t loc; + qse_long_t ival; + qse_real_t rval; + qse_str_t name; } token; - /* io functions */ - qse_lsp_io_t input_func; - qse_lsp_io_t output_func; - void* input_arg; - void* output_arg; + /* io function */ + struct + { + qse_lsp_io_t fns; + + struct + { + qse_lsp_io_arg_t in; + qse_lsp_io_arg_t out; + } arg; + } io; /* security options */ qse_size_t max_eval_depth; @@ -78,4 +101,13 @@ struct qse_lsp_t qse_lsp_mem_t* mem; }; +#ifdef __cplusplus +extern "C" { +#endif + +const qse_char_t* qse_lsp_dflerrstr (qse_lsp_t* lsp, qse_lsp_errnum_t errnum); + +#ifdef __cplusplus +} +#endif #endif diff --git a/qse/lib/lsp/mem.c b/qse/lib/lsp/mem.c index 728027a3..14329fac 100644 --- a/qse/lib/lsp/mem.c +++ b/qse/lib/lsp/mem.c @@ -1,16 +1,35 @@ /* * $Id: mem.c 337 2008-08-20 09:17:25Z baconevi $ * - * {License} + Copyright 2006-2009 Chung, Hyung-Hwan. + This file is part of QSE. + + QSE is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as + published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. + + QSE is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with QSE. If not, see . */ #include "lsp.h" +static qse_lsp_obj_t* makeint (qse_lsp_mem_t* mem, qse_long_t value); +static QSE_INLINE_ALWAYS void collect_garbage (qse_lsp_mem_t* mem); +static void dispose_all (qse_lsp_mem_t* mem); + qse_lsp_mem_t* qse_lsp_openmem ( qse_lsp_t* lsp, qse_size_t ubound, qse_size_t ubound_inc) { qse_lsp_mem_t* mem; qse_size_t i; + int fail = 0; /* allocate memory */ mem = (qse_lsp_mem_t*) QSE_LSP_ALLOC (lsp, QSE_SIZEOF(qse_lsp_mem_t)); @@ -40,7 +59,11 @@ qse_lsp_mem_t* qse_lsp_openmem ( mem->used[i] = QSE_NULL; mem->free[i] = QSE_NULL; } - mem->read = QSE_NULL; + + /* initialize read registers */ + mem->r.obj = QSE_NULL; + mem->r.tmp = QSE_NULL; + mem->r.stack = QSE_NULL; /* when "ubound" is too small, the garbage collection can * be performed while making the common objects. */ @@ -49,21 +72,35 @@ qse_lsp_mem_t* qse_lsp_openmem ( mem->quote = QSE_NULL; mem->lambda = QSE_NULL; mem->macro = QSE_NULL; + for (i = 0; i < QSE_COUNTOF(mem->num); i++) mem->num[i] = QSE_NULL; /* initialize common object pointers */ - mem->nil = qse_lsp_makenil (mem); - mem->t = qse_lsp_maketrue (mem); - mem->quote = qse_lsp_makesym (mem, QSE_T("quote"), 5); - mem->lambda = qse_lsp_makesym (mem, QSE_T("lambda"), 6); - mem->macro = qse_lsp_makesym (mem, QSE_T("macro"), 5); + mem->nil = qse_lsp_makenil (mem); + mem->t = qse_lsp_maketrue (mem); + mem->quote = qse_lsp_makesym (mem, QSE_T("quote"), 5); + mem->lambda = qse_lsp_makesym (mem, QSE_T("lambda"), 6); + mem->macro = qse_lsp_makesym (mem, QSE_T("macro"), 5); - if (mem->nil == QSE_NULL || - mem->t == QSE_NULL || - mem->quote == QSE_NULL || + if (mem->nil == QSE_NULL || + mem->t == QSE_NULL || + mem->quote == QSE_NULL || mem->lambda == QSE_NULL || - mem->macro == QSE_NULL) + mem->macro == QSE_NULL) { - qse_lsp_dispose_all (mem); + fail = 1; + } + else + { + for (i = 0; i < QSE_COUNTOF(mem->num); i++) + { + mem->num[i] = makeint (mem, i); + if (mem->num[i] == QSE_NULL) { fail = 1; break; } + } + } + + if (fail) + { + dispose_all (mem); qse_lsp_freeframe (lsp, mem->frame); QSE_LSP_FREE (lsp, mem); return QSE_NULL; @@ -74,6 +111,13 @@ qse_lsp_mem_t* qse_lsp_openmem ( QSE_LSP_PERM(mem->quote) = 1; QSE_LSP_PERM(mem->lambda) = 1; QSE_LSP_PERM(mem->macro) = 1; + for (i = 0; i < QSE_COUNTOF(mem->num); i++) + { + QSE_LSP_PERM(mem->num[i]) = 1; + } + + /* let the read stack point to nil */ + mem->r.stack = mem->nil; return mem; } @@ -81,7 +125,7 @@ qse_lsp_mem_t* qse_lsp_openmem ( void qse_lsp_closemem (qse_lsp_mem_t* mem) { /* dispose of the allocated objects */ - qse_lsp_dispose_all (mem); + dispose_all (mem); /* dispose of environment frames */ qse_lsp_freeframe (mem->lsp, mem->frame); @@ -90,14 +134,11 @@ void qse_lsp_closemem (qse_lsp_mem_t* mem) QSE_LSP_FREE (mem->lsp, mem); } -qse_lsp_obj_t* qse_lsp_alloc (qse_lsp_mem_t* mem, int type, qse_size_t size) +static qse_lsp_obj_t* allocate (qse_lsp_mem_t* mem, int type, qse_size_t size) { qse_lsp_obj_t* obj; -/* TODO: remove the following line... */ -qse_lsp_gc (mem); - - if (mem->count >= mem->ubound) qse_lsp_gc (mem); + if (mem->count >= mem->ubound) collect_garbage (mem); if (mem->count >= mem->ubound) { mem->ubound += mem->ubound_inc; @@ -107,7 +148,7 @@ qse_lsp_gc (mem); obj = (qse_lsp_obj_t*) QSE_LSP_ALLOC (mem->lsp, size); if (obj == QSE_NULL) { - qse_lsp_gc (mem); + collect_garbage (mem); obj = (qse_lsp_obj_t*) QSE_LSP_ALLOC (mem->lsp, size); if (obj == QSE_NULL) @@ -121,7 +162,6 @@ qse_lsp_gc (mem); QSE_LSP_SIZE(obj) = size; QSE_LSP_MARK(obj) = 0; QSE_LSP_PERM(obj) = 0; - QSE_LSP_LOCK(obj) = 0; /* insert the object at the head of the used list */ QSE_LSP_LINK(obj) = mem->used[type]; @@ -135,7 +175,7 @@ qse_lsp_gc (mem); return obj; } -void qse_lsp_dispose ( +static void dispose ( qse_lsp_mem_t* mem, qse_lsp_obj_t* prev, qse_lsp_obj_t* obj) { QSE_ASSERT (obj != QSE_NULL); @@ -156,7 +196,7 @@ void qse_lsp_dispose ( QSE_LSP_FREE (mem->lsp, obj); } -void qse_lsp_dispose_all (qse_lsp_mem_t* mem) +static void dispose_all (qse_lsp_mem_t* mem) { qse_lsp_obj_t* obj, * next; qse_size_t i; @@ -168,96 +208,45 @@ void qse_lsp_dispose_all (qse_lsp_mem_t* mem) while (obj != QSE_NULL) { next = QSE_LSP_LINK(obj); - qse_lsp_dispose (mem, QSE_NULL, obj); + dispose (mem, QSE_NULL, obj); obj = next; } } } -static void __mark_obj (qse_lsp_t* lsp, qse_lsp_obj_t* obj) +static void mark_obj (qse_lsp_mem_t* mem, qse_lsp_obj_t* obj) { QSE_ASSERT (obj != QSE_NULL); - /* TODO: can it be recursive? */ + /* TODO: can it be non-recursive? */ if (QSE_LSP_MARK(obj) != 0) return; QSE_LSP_MARK(obj) = 1; if (QSE_LSP_TYPE(obj) == QSE_LSP_OBJ_CONS) { - __mark_obj (lsp, QSE_LSP_CAR(obj)); - __mark_obj (lsp, QSE_LSP_CDR(obj)); + mark_obj (mem, QSE_LSP_CAR(obj)); + mark_obj (mem, QSE_LSP_CDR(obj)); } else if (QSE_LSP_TYPE(obj) == QSE_LSP_OBJ_FUNC) { - __mark_obj (lsp, QSE_LSP_FFORMAL(obj)); - __mark_obj (lsp, QSE_LSP_FBODY(obj)); + mark_obj (mem, QSE_LSP_FFORMAL(obj)); + mark_obj (mem, QSE_LSP_FBODY(obj)); } else if (QSE_LSP_TYPE(obj) == QSE_LSP_OBJ_MACRO) { - __mark_obj (lsp, QSE_LSP_MFORMAL(obj)); - __mark_obj (lsp, QSE_LSP_MBODY(obj)); + mark_obj (mem, QSE_LSP_MFORMAL(obj)); + mark_obj (mem, QSE_LSP_MBODY(obj)); } } -/* - * qse_lsp_lockobj and qse_lsp_deepunlockobj are just called by qse_lsp_read. - */ -void qse_lsp_lockobj (qse_lsp_t* lsp, qse_lsp_obj_t* obj) -{ - QSE_ASSERTX (obj != QSE_NULL, - "an object pointer should not be QSE_NULL"); - if (QSE_LSP_PERM(obj) == 0) QSE_LSP_LOCK(obj)++; -} - -void qse_lsp_unlockobj (qse_lsp_t* lsp, qse_lsp_obj_t* obj) -{ - QSE_ASSERTX (obj != QSE_NULL, - "an object pointer should not be QSE_NULL"); - - if (QSE_LSP_PERM(obj) != 0) return; - QSE_ASSERTX (QSE_LSP_LOCK(obj) > 0, - "the lock count should be greater than zero to be unlocked"); - - QSE_LSP_LOCK(obj)--; -} - -void qse_lsp_deepunlockobj (qse_lsp_t* lsp, qse_lsp_obj_t* obj) -{ - QSE_ASSERTX (obj != QSE_NULL, - "an object pointer should not be QSE_NULL"); - - if (QSE_LSP_PERM(obj) == 0) - { - QSE_ASSERTX (QSE_LSP_LOCK(obj) > 0, - "the lock count should be greater than zero to be unlocked"); - QSE_LSP_LOCK(obj)--; - } - - if (QSE_LSP_TYPE(obj) == QSE_LSP_OBJ_CONS) - { - qse_lsp_deepunlockobj (lsp, QSE_LSP_CAR(obj)); - qse_lsp_deepunlockobj (lsp, QSE_LSP_CDR(obj)); - } - else if (QSE_LSP_TYPE(obj) == QSE_LSP_OBJ_FUNC) - { - qse_lsp_deepunlockobj (lsp, QSE_LSP_FFORMAL(obj)); - qse_lsp_deepunlockobj (lsp, QSE_LSP_FBODY(obj)); - } - else if (QSE_LSP_TYPE(obj) == QSE_LSP_OBJ_MACRO) - { - qse_lsp_deepunlockobj (lsp, QSE_LSP_MFORMAL(obj)); - qse_lsp_deepunlockobj (lsp, QSE_LSP_MBODY(obj)); - } -} - -static void __mark_objs_in_use (qse_lsp_mem_t* mem) +static void mark_objs_in_use (qse_lsp_mem_t* mem) { qse_lsp_frame_t* frame; qse_lsp_assoc_t* assoc; qse_lsp_tlink_t* tlink; /*qse_lsp_arr_t* arr;*/ - /*qse_size_t i;*/ + qse_size_t i; #if 0 qse_dprint0 (QSE_T("marking environment frames\n")); @@ -269,12 +258,12 @@ static void __mark_objs_in_use (qse_lsp_mem_t* mem) assoc = frame->assoc; while (assoc != QSE_NULL) { - __mark_obj (mem->lsp, assoc->name); + mark_obj (mem, assoc->name); if (assoc->value != QSE_NULL) - __mark_obj (mem->lsp, assoc->value); + mark_obj (mem, assoc->value); if (assoc->func != QSE_NULL) - __mark_obj (mem->lsp, assoc->func); + mark_obj (mem, assoc->func); assoc = assoc->link; } @@ -293,12 +282,12 @@ static void __mark_objs_in_use (qse_lsp_mem_t* mem) assoc = frame->assoc; while (assoc != QSE_NULL) { - __mark_obj (mem->lsp, assoc->name); + mark_obj (mem, assoc->name); if (assoc->value != QSE_NULL) - __mark_obj (mem->lsp, assoc->value); + mark_obj (mem, assoc->value); if (assoc->func != QSE_NULL) - __mark_obj (mem->lsp, assoc->func); + mark_obj (mem, assoc->func); assoc = assoc->link; } @@ -306,28 +295,35 @@ static void __mark_objs_in_use (qse_lsp_mem_t* mem) frame = frame->link; } - /* qse_dprint0 (QSE_T("marking the read object\n"));*/ - if (mem->read != QSE_NULL) __mark_obj (mem->lsp, mem->read); + /*qse_dprint0 (QSE_T("marking the read object\n"));*/ + if (mem->r.obj) mark_obj (mem, mem->r.obj); + if (mem->r.tmp) mark_obj (mem, mem->r.tmp); + if (mem->r.stack) mark_obj (mem, mem->r.stack); /* qse_dprint0 (QSE_T("marking the temporary objects\n"));*/ for (tlink = mem->tlink; tlink != QSE_NULL; tlink = tlink->link) { - __mark_obj (mem->lsp, tlink->obj); + mark_obj (mem, tlink->obj); } #if 0 qse_dprint0 (QSE_T("marking builtin objects\n")); #endif /* mark common objects */ - if (mem->t != QSE_NULL) __mark_obj (mem->lsp, mem->t); - if (mem->nil != QSE_NULL) __mark_obj (mem->lsp, mem->nil); - if (mem->quote != QSE_NULL) __mark_obj (mem->lsp, mem->quote); - if (mem->lambda != QSE_NULL) __mark_obj (mem->lsp, mem->lambda); - if (mem->macro != QSE_NULL) __mark_obj (mem->lsp, mem->macro); + if (mem->t) mark_obj (mem, mem->t); + if (mem->nil) mark_obj (mem, mem->nil); + if (mem->quote) mark_obj (mem, mem->quote); + if (mem->lambda) mark_obj (mem, mem->lambda); + if (mem->macro) mark_obj (mem, mem->macro); + + for (i = 0; i < QSE_COUNTOF(mem->num); i++) + { + if (mem->num[i]) mark_obj (mem, mem->num[i]); + } } //#include -static void __sweep_unmarked_objs (qse_lsp_mem_t* mem) +static void sweep_unmarked_objs (qse_lsp_mem_t* mem) { qse_lsp_obj_t* obj, * prev, * next; qse_size_t i; @@ -345,8 +341,7 @@ static void __sweep_unmarked_objs (qse_lsp_mem_t* mem) { next = QSE_LSP_LINK(obj); - if (QSE_LSP_LOCK(obj) == 0 && - QSE_LSP_MARK(obj) == 0 && + if (QSE_LSP_MARK(obj) == 0 && QSE_LSP_PERM(obj) == 0) { /* dispose of unused objects */ @@ -362,7 +357,7 @@ qse_printf (QSE_T("disposing....%d [%s]\n"), i, QSE_LSP_STRPTR(obj)); else qse_printf (QSE_T("disposing....%d\n"), i); */ - qse_lsp_dispose (mem, prev, obj); + dispose (mem, prev, obj); } else { @@ -376,16 +371,21 @@ qse_printf (QSE_T("disposing....%d\n"), i); } } -void qse_lsp_gc (qse_lsp_mem_t* mem) +static QSE_INLINE_ALWAYS void collect_garbage (qse_lsp_mem_t* mem) { - __mark_objs_in_use (mem); - __sweep_unmarked_objs (mem); + mark_objs_in_use (mem); + sweep_unmarked_objs (mem); +} + +void qse_lsp_gc (qse_lsp_t* lsp) +{ + collect_garbage (lsp->mem); } qse_lsp_obj_t* qse_lsp_makenil (qse_lsp_mem_t* mem) { if (mem->nil != QSE_NULL) return mem->nil; - mem->nil = qse_lsp_alloc ( + mem->nil = allocate ( mem, QSE_LSP_OBJ_NIL, QSE_SIZEOF(qse_lsp_obj_nil_t)); return mem->nil; } @@ -393,16 +393,16 @@ qse_lsp_obj_t* qse_lsp_makenil (qse_lsp_mem_t* mem) qse_lsp_obj_t* qse_lsp_maketrue (qse_lsp_mem_t* mem) { if (mem->t != QSE_NULL) return mem->t; - mem->t = qse_lsp_alloc ( + mem->t = allocate ( mem, QSE_LSP_OBJ_TRUE, QSE_SIZEOF(qse_lsp_obj_true_t)); return mem->t; } -qse_lsp_obj_t* qse_lsp_makeintobj (qse_lsp_mem_t* mem, qse_long_t value) +static qse_lsp_obj_t* makeint (qse_lsp_mem_t* mem, qse_long_t value) { qse_lsp_obj_t* obj; - obj = qse_lsp_alloc (mem, + obj = allocate (mem, QSE_LSP_OBJ_INT, QSE_SIZEOF(qse_lsp_obj_int_t)); if (obj == QSE_NULL) return QSE_NULL; @@ -411,11 +411,17 @@ qse_lsp_obj_t* qse_lsp_makeintobj (qse_lsp_mem_t* mem, qse_long_t value) return obj; } -qse_lsp_obj_t* qse_lsp_makerealobj (qse_lsp_mem_t* mem, qse_real_t value) +qse_lsp_obj_t* qse_lsp_makeint (qse_lsp_mem_t* mem, qse_long_t value) +{ + if (value >= 0 && value < QSE_COUNTOF(mem->num)) return mem->num[value]; + return makeint (mem, value); +} + +qse_lsp_obj_t* qse_lsp_makereal (qse_lsp_mem_t* mem, qse_real_t value) { qse_lsp_obj_t* obj; - obj = qse_lsp_alloc (mem, + obj = allocate (mem, QSE_LSP_OBJ_REAL, QSE_SIZEOF(qse_lsp_obj_real_t)); if (obj == QSE_NULL) return QSE_NULL; @@ -429,6 +435,8 @@ qse_lsp_obj_t* qse_lsp_makesym ( { qse_lsp_obj_t* obj; +/* TODO: use rbt or htb ... */ + /* look for a sysmbol with the given name */ obj = mem->used[QSE_LSP_OBJ_SYM]; while (obj != QSE_NULL) @@ -442,7 +450,7 @@ qse_lsp_obj_t* qse_lsp_makesym ( } /* no such symbol found. create a new one */ - obj = qse_lsp_alloc (mem, QSE_LSP_OBJ_SYM, + obj = allocate (mem, QSE_LSP_OBJ_SYM, QSE_SIZEOF(qse_lsp_obj_sym_t)+(len + 1)*QSE_SIZEOF(qse_char_t)); if (obj == QSE_NULL) return QSE_NULL; @@ -458,7 +466,7 @@ qse_lsp_obj_t* qse_lsp_makestr ( qse_lsp_obj_t* obj; /* allocate memory for the string */ - obj = qse_lsp_alloc (mem, QSE_LSP_OBJ_STR, + obj = allocate (mem, QSE_LSP_OBJ_STR, QSE_SIZEOF(qse_lsp_obj_str_t)+(len + 1)*QSE_SIZEOF(qse_char_t)); if (obj == QSE_NULL) return QSE_NULL; @@ -473,7 +481,7 @@ qse_lsp_obj_t* qse_lsp_makecons ( { qse_lsp_obj_t* obj; - obj = qse_lsp_alloc (mem, + obj = allocate (mem, QSE_LSP_OBJ_CONS, QSE_SIZEOF(qse_lsp_obj_cons_t)); if (obj == QSE_NULL) return QSE_NULL; @@ -488,7 +496,7 @@ qse_lsp_obj_t* qse_lsp_makefunc ( { qse_lsp_obj_t* obj; - obj = qse_lsp_alloc (mem, + obj = allocate (mem, QSE_LSP_OBJ_FUNC, QSE_SIZEOF(qse_lsp_obj_func_t)); if (obj == QSE_NULL) return QSE_NULL; @@ -503,7 +511,7 @@ qse_lsp_obj_t* qse_lsp_makemacro ( { qse_lsp_obj_t* obj; - obj = qse_lsp_alloc (mem, + obj = allocate (mem, QSE_LSP_OBJ_MACRO, QSE_SIZEOF(qse_lsp_obj_macro_t)); if (obj == QSE_NULL) return QSE_NULL; @@ -518,7 +526,7 @@ qse_lsp_obj_t* qse_lsp_makeprim (qse_lsp_mem_t* mem, { qse_lsp_obj_t* obj; - obj = qse_lsp_alloc ( + obj = allocate ( mem, QSE_LSP_OBJ_PRIM, QSE_SIZEOF(qse_lsp_obj_prim_t)); if (obj == QSE_NULL) return QSE_NULL; diff --git a/qse/lib/lsp/mem.h b/qse/lib/lsp/mem.h index fe4ae687..51e71208 100644 --- a/qse/lib/lsp/mem.h +++ b/qse/lib/lsp/mem.h @@ -1,11 +1,25 @@ /* * $Id: mem.h 117 2008-03-03 11:20:05Z baconevi $ * - * {License} + Copyright 2006-2009 Chung, Hyung-Hwan. + This file is part of QSE. + + QSE is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as + published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. + + QSE is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with QSE. If not, see . */ -#ifndef _QSE_LSP_MEM_H_ -#define _QSE_LSP_MEM_H_ +#ifndef _QSE_LIB_LSP_MEM_H_ +#define _QSE_LIB_LSP_MEM_H_ #ifndef _QSE_LSP_LSP_H_ #error Never include this file directly. Include instead @@ -23,7 +37,13 @@ struct qse_lsp_mem_t qse_size_t count; /* the number of objects currently allocated */ qse_lsp_obj_t* used[QSE_LSP_TYPE_COUNT]; qse_lsp_obj_t* free[QSE_LSP_TYPE_COUNT]; - qse_lsp_obj_t* read; + + struct + { + qse_lsp_obj_t* obj; + qse_lsp_obj_t* tmp; /* temporary object to protect from gc in read() */ + qse_lsp_obj_t* stack; + } r; /* commonly accessed objects */ qse_lsp_obj_t* nil; /* qse_lsp_obj_nil_t */ @@ -31,6 +51,7 @@ struct qse_lsp_mem_t qse_lsp_obj_t* quote; /* qse_lsp_obj_sym_t */ qse_lsp_obj_t* lambda; /* qse_lsp_obj_sym_t */ qse_lsp_obj_t* macro; /* qse_lsp_obj_sym_t */ + qse_lsp_obj_t* num[10]; /* qse_lsp_obj_int_t */ /* run-time environment frame */ qse_lsp_frame_t* frame; @@ -52,20 +73,11 @@ qse_lsp_mem_t* qse_lsp_openmem ( qse_lsp_t* lsp, qse_size_t ubound, qse_size_t ubound_inc); void qse_lsp_closemem (qse_lsp_mem_t* mem); -qse_lsp_obj_t* qse_lsp_alloc (qse_lsp_mem_t* mem, int type, qse_size_t size); -void qse_lsp_dispose (qse_lsp_mem_t* mem, qse_lsp_obj_t* prev, qse_lsp_obj_t* obj); -void qse_lsp_dispose_all (qse_lsp_mem_t* mem); -void qse_lsp_gc (qse_lsp_mem_t* mem); - -void qse_lsp_lockobj (qse_lsp_t* lsp, qse_lsp_obj_t* obj); -void qse_lsp_unlockobj (qse_lsp_t* lsp, qse_lsp_obj_t* obj); -void qse_lsp_deepunlockobj (qse_lsp_t* lsp, qse_lsp_obj_t* obj); - /* object creation of standard types */ -qse_lsp_obj_t* qse_lsp_makenil (qse_lsp_mem_t* mem); -qse_lsp_obj_t* qse_lsp_maketrue (qse_lsp_mem_t* mem); -qse_lsp_obj_t* qse_lsp_makeintobj (qse_lsp_mem_t* mem, qse_long_t value); -qse_lsp_obj_t* qse_lsp_makerealobj (qse_lsp_mem_t* mem, qse_real_t value); +qse_lsp_obj_t* qse_lsp_makenil (qse_lsp_mem_t* mem); +qse_lsp_obj_t* qse_lsp_maketrue (qse_lsp_mem_t* mem); +qse_lsp_obj_t* qse_lsp_makeint (qse_lsp_mem_t* mem, qse_long_t value); +qse_lsp_obj_t* qse_lsp_makereal (qse_lsp_mem_t* mem, qse_real_t value); qse_lsp_obj_t* qse_lsp_makesym ( qse_lsp_mem_t* mem, const qse_char_t* str, qse_size_t len); diff --git a/qse/lib/lsp/misc.c b/qse/lib/lsp/misc.c index 0f643841..0bd713c1 100644 --- a/qse/lib/lsp/misc.c +++ b/qse/lib/lsp/misc.c @@ -1,7 +1,21 @@ /* * $Id: misc.c 337 2008-08-20 09:17:25Z baconevi $ * - * {License} + Copyright 2006-2009 Chung, Hyung-Hwan. + This file is part of QSE. + + QSE is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as + published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. + + QSE is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with QSE. If not, see . */ #include "lsp.h" diff --git a/qse/lib/lsp/misc.h b/qse/lib/lsp/misc.h index 7b40f5d7..659ac3ac 100644 --- a/qse/lib/lsp/misc.h +++ b/qse/lib/lsp/misc.h @@ -1,11 +1,25 @@ /* * $Id: misc.h 117 2008-03-03 11:20:05Z baconevi $ * - * {License} + Copyright 2006-2009 Chung, Hyung-Hwan. + This file is part of QSE. + + QSE is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as + published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. + + QSE is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with QSE. If not, see . */ -#ifndef _QSE_LSP_MISC_H_ -#define _QSE_LSP_MISC_H_ +#ifndef _QSE_LIB_LSP_MISC_H_ +#define _QSE_LIB_LSP_MISC_H_ #ifndef _QSE_LSP_LSP_H_ #error Never include this file directly. Include instead diff --git a/qse/lib/lsp/name.c b/qse/lib/lsp/name.c deleted file mode 100644 index f66945a4..00000000 --- a/qse/lib/lsp/name.c +++ /dev/null @@ -1,125 +0,0 @@ -/* - * $Id: name.c 337 2008-08-20 09:17:25Z baconevi $ - * - * {License} - */ - -#include "lsp.h" - -qse_lsp_name_t* qse_lsp_name_open ( - qse_lsp_name_t* name, qse_size_t capa, qse_lsp_t* lsp) -{ - if (capa == 0) capa = QSE_COUNTOF(name->static_buf) - 1; - - if (name == QSE_NULL) - { - name = (qse_lsp_name_t*) - QSE_LSP_ALLOC (lsp, QSE_SIZEOF(qse_lsp_name_t)); - if (name == QSE_NULL) return QSE_NULL; - name->__dynamic = QSE_TRUE; - } - else name->__dynamic = QSE_FALSE; - - if (capa < QSE_COUNTOF(name->static_buf)) - { - name->buf = name->static_buf; - } - else - { - name->buf = (qse_char_t*) - QSE_LSP_ALLOC (lsp, (capa+1)*QSE_SIZEOF(qse_char_t)); - if (name->buf == QSE_NULL) - { - if (name->__dynamic) QSE_LSP_FREE (lsp, name); - return QSE_NULL; - } - } - - name->size = 0; - name->capa = capa; - name->buf[0] = QSE_T('\0'); - name->lsp = lsp; - - return name; -} - -void qse_lsp_name_close (qse_lsp_name_t* name) -{ - if (name->capa >= QSE_COUNTOF(name->static_buf)) - { - QSE_ASSERT (name->buf != name->static_buf); - QSE_LSP_FREE (name->lsp, name->buf); - } - if (name->__dynamic) QSE_LSP_FREE (name->lsp, name); -} - -int qse_lsp_name_addc (qse_lsp_name_t* name, qse_cint_t c) -{ - if (name->size >= name->capa) - { - /* double the capacity */ - qse_size_t new_capa = name->capa * 2; - - if (new_capa >= QSE_COUNTOF(name->static_buf)) - { - qse_char_t* space; - - if (name->capa < QSE_COUNTOF(name->static_buf)) - { - space = (qse_char_t*) QSE_LSP_ALLOC ( - name->lsp, (new_capa+1)*QSE_SIZEOF(qse_char_t)); - if (space == QSE_NULL) return -1; - - /* don't need to copy up to the terminating null */ - QSE_MEMCPY (space, name->buf, name->capa*QSE_SIZEOF(qse_char_t)); - } - else - { - space = (qse_char_t*) QSE_LSP_REALLOC ( - name->lsp, name->buf, - (new_capa+1)*QSE_SIZEOF(qse_char_t)); - if (space == QSE_NULL) return -1; - } - - name->buf = space; - } - - name->capa = new_capa; - } - - name->buf[name->size++] = c; - name->buf[name->size] = QSE_T('\0'); - return 0; -} - -int qse_lsp_name_adds (qse_lsp_name_t* name, const qse_char_t* s) -{ - while (*s != QSE_T('\0')) - { - if (qse_lsp_name_addc(name, *s) == -1) return -1; - s++; - } - - return 0; -} - -void qse_lsp_name_clear (qse_lsp_name_t* name) -{ - name->size = 0; - name->buf[0] = QSE_T('\0'); -} - -int qse_lsp_name_compare (qse_lsp_name_t* name, const qse_char_t* str) -{ - qse_char_t* p = name->buf; - qse_size_t index = 0; - - while (index < name->size) - { - if (*p > *str) return 1; - if (*p < *str) return -1; - index++; p++; str++; - } - - return (*str == QSE_T('\0'))? 0: -1; -} diff --git a/qse/lib/lsp/name.h b/qse/lib/lsp/name.h deleted file mode 100644 index 9515b7d0..00000000 --- a/qse/lib/lsp/name.h +++ /dev/null @@ -1,42 +0,0 @@ -/* - * $Id: name.h 223 2008-06-26 06:44:41Z baconevi $ - * - * {License} - */ - -#ifndef _QSE_LSP_NAME_H_ -#define _QSE_LSP_NAME_H_ - -#include -#include - -struct qse_lsp_name_t -{ - qse_size_t capa; - qse_size_t size; - qse_char_t* buf; - qse_char_t static_buf[128]; - qse_lsp_t* lsp; - qse_bool_t __dynamic; -}; - -typedef struct qse_lsp_name_t qse_lsp_name_t; - -#ifdef __cplusplus -extern "C" { -#endif - -qse_lsp_name_t* qse_lsp_name_open ( - qse_lsp_name_t* name, qse_size_t capa, qse_lsp_t* lsp); -void qse_lsp_name_close (qse_lsp_name_t* name); - -int qse_lsp_name_addc (qse_lsp_name_t* name, qse_cint_t c); -int qse_lsp_name_adds (qse_lsp_name_t* name, const qse_char_t* s); -void qse_lsp_name_clear (qse_lsp_name_t* name); -int qse_lsp_name_compare (qse_lsp_name_t* name, const qse_char_t* str); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/qse/lib/lsp/obj.h b/qse/lib/lsp/obj.h index d801f3ba..1997474a 100644 --- a/qse/lib/lsp/obj.h +++ b/qse/lib/lsp/obj.h @@ -1,11 +1,25 @@ /* * $Id: obj.h 117 2008-03-03 11:20:05Z baconevi $ * - * {License} + Copyright 2006-2009 Chung, Hyung-Hwan. + This file is part of QSE. + + QSE is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as + published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. + + QSE is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with QSE. If not, see . */ -#ifndef _QSE_LSP_OBJ_H_ -#define _QSE_LSP_OBJ_H_ +#ifndef _QSE_LIB_LSP_OBJ_H_ +#define _QSE_LIB_LSP_OBJ_H_ #ifndef _QSE_LSP_LSP_H_ #error Never include this file directly. Include instead @@ -42,10 +56,9 @@ typedef struct qse_lsp_obj_prim_t qse_lsp_obj_prim_t; struct qse_lsp_objhdr_t { - qse_uint32_t type: 8; - qse_uint32_t mark: 4; - qse_uint32_t perm: 4; - qse_uint32_t lock: 16; + qse_uint16_t type: 8; + qse_uint16_t mark: 4; + qse_uint16_t perm: 4; qse_size_t size; qse_lsp_obj_t* link; }; @@ -127,7 +140,6 @@ struct qse_lsp_obj_prim_t #define QSE_LSP_SIZE(x) (((qse_lsp_obj_t*)x)->hdr.size) #define QSE_LSP_MARK(x) (((qse_lsp_obj_t*)x)->hdr.mark) #define QSE_LSP_PERM(x) (((qse_lsp_obj_t*)x)->hdr.perm) -#define QSE_LSP_LOCK(x) (((qse_lsp_obj_t*)x)->hdr.lock) #define QSE_LSP_LINK(x) (((qse_lsp_obj_t*)x)->hdr.link) /* value access */ diff --git a/qse/lib/lsp/prim.c b/qse/lib/lsp/prim.c index 77dfdafd..13b2047b 100644 --- a/qse/lib/lsp/prim.c +++ b/qse/lib/lsp/prim.c @@ -422,7 +422,7 @@ qse_lsp_obj_t* qse_lsp_prim_length (qse_lsp_t* lsp, qse_lsp_obj_t* args) } QSE_ASSERT (body == lsp->mem->nil); - return qse_lsp_makeintobj (lsp->mem, len); + return qse_lsp_makeint (lsp->mem, len); } qse_lsp_obj_t* qse_lsp_prim_set (qse_lsp_t* lsp, qse_lsp_obj_t* args) diff --git a/qse/lib/lsp/prim.h b/qse/lib/lsp/prim.h index 9f5c5a34..172e5d09 100644 --- a/qse/lib/lsp/prim.h +++ b/qse/lib/lsp/prim.h @@ -1,11 +1,25 @@ /* * $Id: prim.h 117 2008-03-03 11:20:05Z baconevi $ * - * {License} + Copyright 2006-2009 Chung, Hyung-Hwan. + This file is part of QSE. + + QSE is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as + published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. + + QSE is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with QSE. If not, see . */ -#ifndef _QSE_LSP_PRIM_H_ -#define _QSE_LSP_PRIM_H_ +#ifndef _QSE_LIB_LSP_PRIM_H_ +#define _QSE_LIB_LSP_PRIM_H_ #ifndef _QSE_LSP_LSP_H_ #error Never include this file directly. Include instead diff --git a/qse/lib/lsp/prim_math.c b/qse/lib/lsp/prim_math.c index 103c66fb..4a4da4c9 100644 --- a/qse/lib/lsp/prim_math.c +++ b/qse/lib/lsp/prim_math.c @@ -67,8 +67,8 @@ qse_lsp_obj_t* qse_lsp_prim_plus (qse_lsp_t* lsp, qse_lsp_obj_t* args) QSE_ASSERT (body == lsp->mem->nil); tmp = (realnum)? - qse_lsp_makerealobj (lsp->mem, rval): - qse_lsp_makeintobj (lsp->mem, ival); + qse_lsp_makereal (lsp->mem, rval): + qse_lsp_makeint (lsp->mem, ival); if (tmp == QSE_NULL) return QSE_NULL; return tmp; @@ -136,8 +136,8 @@ qse_lsp_obj_t* qse_lsp_prim_minus (qse_lsp_t* lsp, qse_lsp_obj_t* args) QSE_ASSERT (body == lsp->mem->nil); tmp = (realnum)? - qse_lsp_makerealobj (lsp->mem, rval): - qse_lsp_makeintobj (lsp->mem, ival); + qse_lsp_makereal (lsp->mem, rval): + qse_lsp_makeint (lsp->mem, ival); if (tmp == QSE_NULL) return QSE_NULL; return tmp; @@ -204,8 +204,8 @@ qse_lsp_obj_t* qse_lsp_prim_mul (qse_lsp_t* lsp, qse_lsp_obj_t* args) QSE_ASSERT (body == lsp->mem->nil); tmp = (realnum)? - qse_lsp_makerealobj (lsp->mem, rval): - qse_lsp_makeintobj (lsp->mem, ival); + qse_lsp_makereal (lsp->mem, rval): + qse_lsp_makeint (lsp->mem, ival); if (tmp == QSE_NULL) return QSE_NULL; return tmp; @@ -279,8 +279,8 @@ qse_lsp_obj_t* qse_lsp_prim_div (qse_lsp_t* lsp, qse_lsp_obj_t* args) QSE_ASSERT (body == lsp->mem->nil); tmp = (realnum)? - qse_lsp_makerealobj (lsp->mem, rval): - qse_lsp_makeintobj (lsp->mem, ival); + qse_lsp_makereal (lsp->mem, rval): + qse_lsp_makeint (lsp->mem, ival); if (tmp == QSE_NULL) return QSE_NULL; return tmp; @@ -344,7 +344,7 @@ qse_lsp_obj_t* qse_lsp_prim_mod (qse_lsp_t* lsp, qse_lsp_obj_t* args) QSE_ASSERT (body == lsp->mem->nil); - tmp = qse_lsp_makeintobj (lsp->mem, ival); + tmp = qse_lsp_makeint (lsp->mem, ival); if (tmp == QSE_NULL) return QSE_NULL; return tmp; diff --git a/qse/lib/lsp/print.c b/qse/lib/lsp/print.c index 5467cc48..3c4a7f5e 100644 --- a/qse/lib/lsp/print.c +++ b/qse/lib/lsp/print.c @@ -8,7 +8,7 @@ #define OUTPUT_STR(lsp,str) \ do { \ - if (lsp->output_func(QSE_LSP_IO_WRITE, lsp->output_arg, (qse_char_t*)str, qse_strlen(str)) == -1) { \ + if (lsp->io.fns.out(lsp, QSE_LSP_IO_WRITE, &lsp->io.arg.out, (qse_char_t*)str, qse_strlen(str)) == -1) { \ qse_lsp_seterror (lsp, QSE_LSP_EOUTPUT, QSE_NULL, 0); \ return -1; \ } \ @@ -16,7 +16,7 @@ #define OUTPUT_STRX(lsp,str,len) \ do { \ - if (lsp->output_func(QSE_LSP_IO_WRITE, lsp->output_arg, (qse_char_t*)str, len) == -1) { \ + if (lsp->io.fns.out(lsp, QSE_LSP_IO_WRITE, &lsp->io.arg.out, (qse_char_t*)str, qse_strlen(str)) == -1) { \ qse_lsp_seterror (lsp, QSE_LSP_EOUTPUT, QSE_NULL, 0); \ return -1; \ } \ @@ -26,7 +26,7 @@ static int __print (qse_lsp_t* lsp, const qse_lsp_obj_t* obj, qse_bool_t prt_con { qse_char_t buf[256]; - if (lsp->output_func == QSE_NULL) + if (lsp->io.fns.out == QSE_NULL) { qse_lsp_seterror (lsp, QSE_LSP_ENOOUTP, QSE_NULL, 0); return -1; @@ -44,23 +44,23 @@ static int __print (qse_lsp_t* lsp, const qse_lsp_obj_t* obj, qse_bool_t prt_con case QSE_LSP_OBJ_INT: #if QSE_SIZEOF_LONG_LONG > 0 - lsp->prmfns.misc.sprintf ( - lsp->prmfns.misc.udd, + lsp->prm.sprintf ( + lsp->prm.udd, buf, QSE_COUNTOF(buf), QSE_T("%lld"), (long long)QSE_LSP_IVAL(obj)); #elif QSE_SIZEOF___INT64 > 0 - lsp->prmfns.misc.sprintf ( - lsp->prmfns.misc.udd, + lsp->prm.sprintf ( + lsp->prm.udd, buf, QSE_COUNTOF(buf), QSE_T("%I64d"), (__int64)QSE_LSP_IVAL(obj)); #elif QSE_SIZEOF_LONG > 0 - lsp->prmfns.misc.sprintf ( - lsp->prmfns.misc.udd, + lsp->prm.sprintf ( + lsp->prm.udd, buf, QSE_COUNTOF(buf), QSE_T("%ld"), (long)QSE_LSP_IVAL(obj)); #elif QSE_SIZEOF_INT > 0 - lsp->prmfns.misc.sprintf ( - lsp->prmfns.misc.udd, + lsp->prm.sprintf ( + lsp->prm.udd, buf, QSE_COUNTOF(buf), QSE_T("%d"), (int)QSE_LSP_IVAL(obj)); #else @@ -70,8 +70,8 @@ static int __print (qse_lsp_t* lsp, const qse_lsp_obj_t* obj, qse_bool_t prt_con break; case QSE_LSP_OBJ_REAL: - lsp->prmfns.misc.sprintf ( - lsp->prmfns.misc.udd, + lsp->prm.sprintf ( + lsp->prm.udd, buf, QSE_COUNTOF(buf), QSE_T("%Lf"), #ifdef __MINGW32__ @@ -140,8 +140,8 @@ static int __print (qse_lsp_t* lsp, const qse_lsp_obj_t* obj, qse_bool_t prt_con break; default: - lsp->prmfns.misc.sprintf ( - lsp->prmfns.misc.udd, + lsp->prm.sprintf ( + lsp->prm.udd, buf, QSE_COUNTOF(buf), QSE_T("unknown object type: %d"), QSE_LSP_TYPE(obj)); OUTPUT_STR (lsp, buf); diff --git a/qse/lib/lsp/read.c b/qse/lib/lsp/read.c index 41057435..449e2e82 100644 --- a/qse/lib/lsp/read.c +++ b/qse/lib/lsp/read.c @@ -1,49 +1,70 @@ /* * $Id: read.c 337 2008-08-20 09:17:25Z baconevi $ * - * {License} + Copyright 2006-2009 Chung, Hyung-Hwan. + This file is part of QSE. + + QSE is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as + published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. + + QSE is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with QSE. If not, see . */ #include "lsp.h" -#define IS_IDENT(c) \ - ((c) == QSE_T('+') || (c) == QSE_T('-') || \ - (c) == QSE_T('*') || (c) == QSE_T('/') || \ - (c) == QSE_T('%') || (c) == QSE_T('&') || \ - (c) == QSE_T('<') || (c) == QSE_T('>') || \ - (c) == QSE_T('=') || (c) == QSE_T('_') || \ - (c) == QSE_T('?')) +enum list_flag_t +{ + QUOTED = (1 << 0), + DOTTED = (1 << 1), + CLOSED = (1 << 2) +}; -#define TOKEN_CLEAR(lsp) qse_lsp_name_clear (&(lsp)->token.name) +enum token_type_t +{ + TOKEN_END = 0, + TOKEN_INT = 1, + TOKEN_REAL = 2, + TOKEN_STRING = 3, + TOKEN_LPAREN = 4, + TOKEN_RPAREN = 5, + TOKEN_IDENT = 6, + TOKEN_QUOTE = 7, + TOKEN_DOT = 8, + TOKEN_INVALID = 50 +}; + +#define IS_SPECIAL_CHAR(c) \ + ((c) == QSE_T('(') || (c) == QSE_T(')') || \ + (c) == QSE_T('.') || (c) == QSE_T('\'') || (c) == QSE_T('\"')) + +#define IS_IDENT_CHAR(lsp,c) \ + (c != QSE_T('\0') && !IS_SPECIAL_CHAR(c) && !QSE_LSP_ISSPACE(lsp, c)) + +#define TOKEN_CLEAR(lsp) qse_str_clear (&(lsp)->token.name) #define TOKEN_TYPE(lsp) (lsp)->token.type #define TOKEN_IVAL(lsp) (lsp)->token.ival #define TOKEN_RVAL(lsp) (lsp)->token.rval -#define TOKEN_SPTR(lsp) (lsp)->token.name.buf -#define TOKEN_SLEN(lsp) (lsp)->token.name.size +#define TOKEN_STR(lsp) (lsp)->token.name +#define TOKEN_SPTR(lsp) (lsp)->token.name.ptr +#define TOKEN_SLEN(lsp) (lsp)->token.name.len +#define TOKEN_LOC(lsp) (lsp)->token.loc #define TOKEN_ADD_CHAR(lsp,ch) \ do { \ - if (qse_lsp_name_addc(&(lsp)->token.name, ch) == -1) { \ - qse_lsp_seterror (lsp, QSE_LSP_ENOMEM, QSE_NULL, 0); \ + if (qse_str_ccat(&(lsp)->token.name, ch) == -1) { \ + qse_lsp_seterror (lsp, QSE_LSP_ENOMEM, QSE_NULL, &lsp->curloc); \ return -1; \ } \ } while (0) -#define TOKEN_COMPARE(lsp,str) \ - qse_lsp_name_compare (&(lsp)->token.name, str) - -#define TOKEN_END 0 -#define TOKEN_INT 1 -#define TOKEN_REAL 2 -#define TOKEN_STRING 3 -#define TOKEN_LPAREN 4 -#define TOKEN_RPAREN 5 -#define TOKEN_IDENT 6 -#define TOKEN_QUOTE 7 -#define TOKEN_DOT 8 -#define TOKEN_INVALID 50 -#define TOKEN_UNTERM_STRING 51 - #define NEXT_CHAR(lsp) \ do { if (read_char(lsp) == -1) return -1;} while (0) @@ -57,8 +78,6 @@ do { if (read_token(lsp) == -1) return QSE_NULL; } while (0) static qse_lsp_obj_t* read_obj (qse_lsp_t* lsp); -static qse_lsp_obj_t* read_list (qse_lsp_t* lsp); -static qse_lsp_obj_t* read_quote (qse_lsp_t* lsp); static int read_char (qse_lsp_t* lsp); static int read_token (qse_lsp_t* lsp); @@ -66,213 +85,411 @@ static int read_number (qse_lsp_t* lsp, int negative); static int read_ident (qse_lsp_t* lsp); static int read_string (qse_lsp_t* lsp); +static QSE_INLINE_ALWAYS void protect (qse_lsp_t* lsp, qse_lsp_obj_t* obj) +{ + /* remember an object for temporary GC protection */ + QSE_ASSERT (lsp->mem->r.tmp == QSE_NULL); + lsp->mem->r.tmp = obj; +} + +static QSE_INLINE_ALWAYS void unprotect (qse_lsp_t* lsp, qse_lsp_obj_t* obj) +{ + /* release an object from temporary GC protection */ + QSE_ASSERT (lsp->mem->r.tmp == obj); + lsp->mem->r.tmp = QSE_NULL; +} + qse_lsp_obj_t* qse_lsp_read (qse_lsp_t* lsp) { if (lsp->curc == QSE_CHAR_EOF && - read_char(lsp) == -1) return QSE_NULL; - + read_char(lsp) <= -1) return QSE_NULL; NEXT_TOKEN (lsp); - lsp->mem->read = read_obj (lsp); - if (lsp->mem->read != QSE_NULL) - qse_lsp_deepunlockobj (lsp, lsp->mem->read); - return lsp->mem->read; + lsp->mem->r.obj = read_obj (lsp); + + /* clear the stack. + * TODO: better to clear stack elements instead of counting on GC? + */ + lsp->mem->r.stack = lsp->mem->nil; + + return lsp->mem->r.obj; +} + +static QSE_INLINE qse_lsp_obj_t* makesym (qse_lsp_t* lsp, const qse_str_t* name) +{ + QSE_ASSERT (lsp->mem->nil != QSE_NULL && lsp->mem->t != QSE_NULL); + + if (qse_strxcmp (name->ptr, name->len, QSE_T("t")) == 0) + return lsp->mem->t; + if (qse_strxcmp (name->ptr, name->len, QSE_T("nil")) == 0) + return lsp->mem->nil; + + return qse_lsp_makesym (lsp->mem, name->ptr, name->len); +} + +static QSE_INLINE qse_lsp_obj_t* push (qse_lsp_t* lsp, qse_lsp_obj_t* obj) +{ + qse_lsp_obj_t* cell; + + protect (lsp, obj); /* temporary protection */ + cell = qse_lsp_makecons (lsp->mem, obj, lsp->mem->r.stack); + unprotect (lsp, obj); /* ok to unprotected as it is already chained to the stack... */ + if (cell == QSE_NULL) return QSE_NULL; + + lsp->mem->r.stack = cell; + return cell; /* return the containing cell */ +} + +static QSE_INLINE_ALWAYS void pop (qse_lsp_t* lsp) +{ + QSE_ASSERT (lsp->mem->r.stack != lsp->mem->nil); + lsp->mem->r.stack = QSE_LSP_CDR(lsp->mem->r.stack); +} + +static QSE_INLINE qse_lsp_obj_t* enter_list (qse_lsp_t* lsp, int flagv) +{ + /* upon entering a list, it pushes three cells into a stack. + * + * r.stack -------+ + * V + * +---cons--+ + * +------ | -------+ + * car| +---------+ |cdr + * V | + * nil#1 V + * +---cons--+ + * +------ | --------+ + * car| +---------+ |cdr + * v | + * nil#2 V + * +---cons--+ + * +------ | --------+ + * car| +---------+ |cdr + * V | + * flag number V + * previous stack top + * + * nil#1 to store the first element in the list. + * nil#2 to store the last element in the list. + * both to be updated in chain_to_list() as items are added. + */ + return (push (lsp, lsp->mem->num[flagv]) == QSE_NULL || + push (lsp, lsp->mem->nil) == QSE_NULL || + push (lsp, lsp->mem->nil) == QSE_NULL)? QSE_NULL: lsp->mem->r.stack; +} + +static QSE_INLINE_ALWAYS qse_lsp_obj_t* leave_list (qse_lsp_t* lsp, int* flagv) +{ + qse_lsp_obj_t* head; + + /* the stack must not be empty */ + QSE_ASSERT (lsp->mem->r.stack != lsp->mem->nil); + + /* remember the current list head */ + head = QSE_LSP_CAR(QSE_LSP_CDR(lsp->mem->r.stack)); + + /* upon leaving a list, it pops the three cells off the stack */ + pop (lsp); + pop (lsp); + pop (lsp); + + if (lsp->mem->r.stack == lsp->mem->nil) + { + /* the stack is empty after popping. + * it is back to the top level. + * the top level can never be quoted. */ + *flagv = 0; + } + else + { + /* restore the flag for the outer returning level */ + qse_lsp_obj_t* flag = QSE_LSP_CDR(QSE_LSP_CDR(lsp->mem->r.stack)); + QSE_ASSERT (QSE_LSP_TYPE(QSE_LSP_CAR(flag)) == QSE_LSP_OBJ_INT); + *flagv = QSE_LSP_IVAL(QSE_LSP_CAR(flag)); + } + + /* return the head of the list being left */ + return head; +} + +static QSE_INLINE_ALWAYS void dot_list (qse_lsp_t* lsp) +{ + qse_lsp_obj_t* cell; + + /* mark the state that a dot has appeared in the list */ + QSE_ASSERT (lsp->mem->r.stack != lsp->mem->nil); + cell = QSE_LSP_CDR(QSE_LSP_CDR(lsp->mem->r.stack)); + QSE_LSP_CAR(cell) = lsp->mem->num[QSE_LSP_IVAL(QSE_LSP_CAR(cell)) | DOTTED]; +} + +static qse_lsp_obj_t* chain_to_list (qse_lsp_t* lsp, qse_lsp_obj_t* obj) +{ + qse_lsp_obj_t* cell, * head, * tail, *flag; + int flagv; + + /* the stack top is the cons cell pointing to the list tail */ + tail = lsp->mem->r.stack; + QSE_ASSERT (tail != lsp->mem->nil); + + /* the cons cell pointing to the list head is below the tail cell + * connected via cdr. */ + head = QSE_LSP_CDR(tail); + QSE_ASSERT (head != lsp->mem->nil); + + /* the cons cell pointing to the flag is below the head cell + * connected via cdr */ + flag = QSE_LSP_CDR(head); + + /* retrieve the numeric flag value */ + QSE_ASSERT(QSE_LSP_TYPE(QSE_LSP_CAR(flag)) == QSE_LSP_OBJ_INT); + flagv = (int)QSE_LSP_IVAL(QSE_LSP_CAR(flag)); + + if (flagv & CLOSED) + { + /* the list has already been closed. cannot add more items. */ + qse_lsp_seterror (lsp, QSE_LSP_ERPAREN, QSE_NULL, &TOKEN_LOC(lsp)); + return QSE_NULL; + } + else if (flagv & DOTTED) + { + /* the list must not be empty to have reached the dotted state */ + QSE_ASSERT (QSE_LSP_CAR(tail) != lsp->mem->nil); + + /* chain the object via 'cdr' of the tail cell */ + QSE_LSP_CDR(QSE_LSP_CAR(tail)) = obj; + + /* update the flag to CLOSED */ + QSE_LSP_CAR(flag) = lsp->mem->num[flagv | CLOSED]; + } + else + { + protect (lsp, obj); /* in case makecons() fails */ + cell = qse_lsp_makecons (lsp->mem, obj, lsp->mem->nil); + unprotect (lsp, obj); + + if (cell == QSE_NULL) return QSE_NULL; + + if (QSE_LSP_CAR(head) == lsp->mem->nil) + { + /* the list head is not set yet. it is the first + * element added to the list. let both head and tail + * point to the new cons cell */ + QSE_ASSERT (QSE_LSP_CAR(tail) == lsp->mem->nil); + QSE_LSP_CAR(head) = cell; + QSE_LSP_CAR(tail) = cell; + } + else + { + /* the new cons cell is not the first element. + * append it to the list */ + QSE_LSP_CDR(QSE_LSP_CAR(tail)) = cell; + QSE_LSP_CAR(tail) = cell; + } + } + + return obj; +} + +static QSE_INLINE_ALWAYS int is_list_empty (qse_lsp_t* lsp) +{ + /* the stack must not be empty */ + QSE_ASSERT (lsp->mem->r.stack != lsp->mem->nil); + + /* if the tail pointer is pointing to nil, the list is empty */ + return QSE_LSP_CAR(lsp->mem->r.stack) == lsp->mem->nil; } static qse_lsp_obj_t* read_obj (qse_lsp_t* lsp) { + /* this function read an s-expression non-recursively + * by manipulating its own stack. */ + + int level = 0, flag = 0; qse_lsp_obj_t* obj; - switch (TOKEN_TYPE(lsp)) + while (1) { - case TOKEN_END: - qse_lsp_seterror (lsp, QSE_LSP_EEND, QSE_NULL, 0); - return QSE_NULL; - - case TOKEN_LPAREN: - NEXT_TOKEN (lsp); - return read_list (lsp); - - case TOKEN_QUOTE: - NEXT_TOKEN (lsp); - return read_quote (lsp); - - case TOKEN_INT: - obj = qse_lsp_makeintobj (lsp->mem, TOKEN_IVAL(lsp)); - if (obj == QSE_NULL) return QSE_NULL; - qse_lsp_lockobj (lsp, obj); - return obj; - - case TOKEN_REAL: - obj = qse_lsp_makerealobj (lsp->mem, TOKEN_RVAL(lsp)); - if (obj == QSE_NULL) return QSE_NULL; - qse_lsp_lockobj (lsp, obj); - return obj; - - case TOKEN_STRING: - obj = qse_lsp_makestr ( - lsp->mem, TOKEN_SPTR(lsp), TOKEN_SLEN(lsp)); - if (obj == QSE_NULL) return QSE_NULL; - qse_lsp_lockobj (lsp, obj); - return obj; - - case TOKEN_IDENT: - QSE_ASSERT ( - lsp->mem->nil != QSE_NULL && - lsp->mem->t != QSE_NULL); - - if (TOKEN_COMPARE(lsp,QSE_T("nil")) == 0) - { - obj = lsp->mem->nil; - } - else if (TOKEN_COMPARE(lsp,QSE_T("t")) == 0) - { - obj = lsp->mem->t; - } - else - { - obj = qse_lsp_makesym ( - lsp->mem, - TOKEN_SPTR(lsp), - TOKEN_SLEN(lsp)); - if (obj == QSE_NULL) return QSE_NULL; - qse_lsp_lockobj (lsp, obj); - } - - return obj; - } - - qse_lsp_seterror (lsp, QSE_LSP_ESYNTAX, QSE_NULL, 0); - return QSE_NULL; -} - -static qse_lsp_obj_t* read_list (qse_lsp_t* lsp) -{ - qse_lsp_obj_t* obj; - qse_lsp_obj_cons_t* p, * first = QSE_NULL, * prev = QSE_NULL; - - while (TOKEN_TYPE(lsp) != TOKEN_RPAREN) - { - if (TOKEN_TYPE(lsp) == TOKEN_END) + redo: + switch (TOKEN_TYPE(lsp)) { - /* unexpected end of input */ - qse_lsp_seterror (lsp, QSE_LSP_ESYNTAX, QSE_NULL, 0); - return QSE_NULL; - } - - if (TOKEN_TYPE(lsp) == TOKEN_DOT) - { - if (prev == QSE_NULL) - { - /* unexpected dot */ - qse_lsp_seterror (lsp, QSE_LSP_ESYNTAX, QSE_NULL, 0); + default: + QSE_ASSERT (!"should never happen - invalid token type"); + qse_lsp_seterror (lsp, QSE_LSP_EINTERN, QSE_NULL, QSE_NULL); return QSE_NULL; - } - NEXT_TOKEN (lsp); - obj = read_obj (lsp); - if (obj == QSE_NULL) - { - if (lsp->errnum == QSE_LSP_EEND) + case TOKEN_INVALID: + qse_lsp_seterror (lsp, QSE_LSP_ESYNTAX, QSE_NULL, &TOKEN_LOC(lsp)); + return QSE_NULL; + + case TOKEN_END: + qse_lsp_seterror (lsp, QSE_LSP_EEND, QSE_NULL, &TOKEN_LOC(lsp)); + return QSE_NULL; + + case TOKEN_QUOTE: + if (level >= QSE_TYPE_MAX(int)) { - /* unexpected end of input */ - qse_lsp_seterror (lsp, QSE_LSP_ESYNTAX, QSE_NULL, 0); + /* the nesting level has become too deep */ + qse_lsp_seterror (lsp, QSE_LSP_ELSTDEEP, QSE_NULL, &TOKEN_LOC(lsp)); + return QSE_NULL; } - return QSE_NULL; - } - prev->cdr = obj; - NEXT_TOKEN (lsp); - if (TOKEN_TYPE(lsp) != TOKEN_RPAREN) - { - /* ) expected */ - qse_lsp_seterror (lsp, QSE_LSP_ERPAREN, QSE_NULL, 0); - return QSE_NULL; - } + /* enter a quoted string */ + flag |= QUOTED; + if (enter_list (lsp, flag) == QSE_NULL) return QSE_NULL; + level++; - break; + /* force-chain the quote symbol to the new list entered */ + if (chain_to_list (lsp, lsp->mem->quote) == QSE_NULL) return QSE_NULL; + + /* read the next token */ + NEXT_TOKEN (lsp); + goto redo; + + case TOKEN_LPAREN: + if (level >= QSE_TYPE_MAX(int)) + { + /* the nesting level has become too deep */ + qse_lsp_seterror (lsp, QSE_LSP_ELSTDEEP, QSE_NULL, &TOKEN_LOC(lsp)); + return QSE_NULL; + } + + /* enter a normal string */ + flag = 0; + if (enter_list (lsp, flag) == QSE_NULL) return QSE_NULL; + level++; + + /* read the next token */ + NEXT_TOKEN (lsp); + goto redo; + + case TOKEN_DOT: + if (level <= 0 || is_list_empty (lsp)) + { + qse_lsp_seterror (lsp, QSE_LSP_ESYNTAX, QSE_NULL, &TOKEN_LOC(lsp)); + return QSE_NULL; + } + + dot_list (lsp); + NEXT_TOKEN (lsp); + goto redo; + + case TOKEN_RPAREN: + if ((flag & QUOTED) || level <= 0) + { + /* the right parenthesis can never appear while + * 'quoted' is true. 'quoted' is set to false when + * entering a normal list. 'quoted' is set to true + * when entering a quoted list. a quoted list does + * not have an explicit right parenthesis. + * so the right parenthesis can only pair up with + * the left parenthesis for the normal list. + * + * For example, '(1 2 3 ') 5 6) + * + * this condition is triggerred when the first ) is + * met after the second quote. + * + * also it is illegal to have the right parenthesis + * with no opening(left) parenthesis, which is + * indicated by level<=0. + */ + qse_lsp_seterror (lsp, QSE_LSP_ESYNTAX, QSE_NULL, &TOKEN_LOC(lsp)); + return QSE_NULL; + } + + obj = leave_list (lsp, &flag); + + level--; + break; + + case TOKEN_INT: + obj = qse_lsp_makeint (lsp->mem, TOKEN_IVAL(lsp)); + break; + + case TOKEN_REAL: + obj = qse_lsp_makereal (lsp->mem, TOKEN_RVAL(lsp)); + break; + + case TOKEN_STRING: + obj = qse_lsp_makestr ( + lsp->mem, TOKEN_SPTR(lsp), TOKEN_SLEN(lsp)); + break; + + case TOKEN_IDENT: + obj = makesym (lsp, &TOKEN_STR(lsp)); + break; } - obj = read_obj (lsp); - if (obj == QSE_NULL) + /* check if the element is read for a quoted list */ + while (flag & QUOTED) { - if (lsp->errnum == QSE_LSP_EEND) - { - /* unexpected end of input */ - qse_lsp_seterror (lsp, QSE_LSP_ESYNTAX, QSE_NULL, 0); - } - return QSE_NULL; + QSE_ASSERT (level > 0); + + /* if so, append the element read into the quote list */ + if (chain_to_list (lsp, obj) == QSE_NULL) return QSE_NULL; + + /* exit out of the quoted list. the quoted list can have + * one element only. */ + obj = leave_list (lsp, &flag); + + /* one level up toward the top */ + level--; } - p = (qse_lsp_obj_cons_t*)qse_lsp_makecons ( - lsp->mem, lsp->mem->nil, lsp->mem->nil); - if (p == QSE_NULL) return QSE_NULL; - qse_lsp_lockobj (lsp, (qse_lsp_obj_t*)p); + /* check if we are at the top level */ + if (level <= 0) break; /* yes */ - if (first == QSE_NULL) first = p; - if (prev != QSE_NULL) prev->cdr = (qse_lsp_obj_t*)p; - - p->car = obj; - prev = p; + /* if not, append the element read into the current list. + * if we are not at the top level, we must be in a list */ + if (chain_to_list (lsp, obj) == QSE_NULL) return QSE_NULL; + /* read the next token */ NEXT_TOKEN (lsp); - } - - return (first == QSE_NULL)? lsp->mem->nil: (qse_lsp_obj_t*)first; -} - -static qse_lsp_obj_t* read_quote (qse_lsp_t* lsp) -{ - qse_lsp_obj_t* cons, * tmp; - - tmp = read_obj (lsp); - if (tmp == QSE_NULL) - { - if (lsp->errnum == QSE_LSP_EEND) - { - /* unexpected end of input */ - qse_lsp_seterror (lsp, QSE_LSP_ESYNTAX, QSE_NULL, 0); - } - return QSE_NULL; } - cons = qse_lsp_makecons (lsp->mem, tmp, lsp->mem->nil); - if (cons == QSE_NULL) return QSE_NULL; - qse_lsp_lockobj (lsp, cons); + /* upon exit, we must be at the top level */ + QSE_ASSERT (level == 0); - cons = qse_lsp_makecons (lsp->mem, lsp->mem->quote, cons); - if (cons == QSE_NULL) return QSE_NULL; - qse_lsp_lockobj (lsp, cons); - - return cons; -} + return obj; +} static int read_char (qse_lsp_t* lsp) { qse_ssize_t n; qse_char_t c; - if (lsp->input_func == QSE_NULL) + if (lsp->io.fns.in == QSE_NULL) { - qse_lsp_seterror (lsp, QSE_LSP_ENOINP, QSE_NULL, 0); + qse_lsp_seterror (lsp, QSE_LSP_ENOINP, QSE_NULL, QSE_NULL); return -1; } - n = lsp->input_func(QSE_LSP_IO_READ, lsp->input_arg, &c, 1); +/* TODO: do some bufferring.... */ + n = lsp->io.fns.in (lsp, QSE_LSP_IO_READ, &lsp->io.arg.in, &c, 1); if (n == -1) { - qse_lsp_seterror (lsp, QSE_LSP_EINPUT, QSE_NULL, 0); + qse_lsp_seterror (lsp, QSE_LSP_EINPUT, QSE_NULL, QSE_NULL); return -1; } if (n == 0) lsp->curc = QSE_CHAR_EOF; - else lsp->curc = c; + else + { + lsp->curc = c; + + if (c == QSE_T('\n')) + { + lsp->curloc.colm = 0; + lsp->curloc.line++; + } + else lsp->curloc.colm++; + } return 0; } static int read_token (qse_lsp_t* lsp) { - QSE_ASSERT (lsp->input_func != QSE_NULL); + QSE_ASSERT (lsp->io.fns.in != QSE_NULL); TOKEN_CLEAR (lsp); @@ -281,19 +498,15 @@ static int read_token (qse_lsp_t* lsp) /* skip white spaces */ while (QSE_LSP_ISSPACE(lsp, lsp->curc)) NEXT_CHAR (lsp); - /* skip the comments here */ - if (lsp->curc == QSE_T(';')) - { - do - { - NEXT_CHAR (lsp); - } - while (lsp->curc != QSE_T('\n') && - lsp->curc != QSE_CHAR_EOF); - } - else break; + if (lsp->curc != QSE_T(';')) break; + + /* skip a comment - ignore all the following text */ + do { NEXT_CHAR (lsp); } + while (lsp->curc != QSE_T('\n') && + lsp->curc != QSE_CHAR_EOF); } + TOKEN_LOC(lsp) = lsp->curloc; if (lsp->curc == QSE_CHAR_EOF) { TOKEN_TYPE(lsp) = TOKEN_END; @@ -335,7 +548,7 @@ static int read_token (qse_lsp_t* lsp) { return read_number (lsp, 1); } - else if (IS_IDENT(lsp->curc)) + else if (IS_IDENT_CHAR(lsp,lsp->curc)) { return read_ident (lsp); } @@ -349,7 +562,7 @@ static int read_token (qse_lsp_t* lsp) { return read_number (lsp, 0); } - else if (QSE_LSP_ISALPHA(lsp,lsp->curc) || IS_IDENT(lsp->curc)) + else if (IS_IDENT_CHAR(lsp,lsp->curc)) { return read_ident (lsp); } @@ -412,7 +625,7 @@ static int read_ident (qse_lsp_t* lsp) TOKEN_ADD_CHAR (lsp, lsp->curc); NEXT_CHAR (lsp); } - while (QSE_LSP_ISALNUM(lsp,lsp->curc) || IS_IDENT(lsp->curc)); + while (IS_IDENT_CHAR(lsp,lsp->curc)); TOKEN_TYPE(lsp) = TOKEN_IDENT; return 0; } @@ -430,7 +643,7 @@ static int read_string (qse_lsp_t* lsp) if (c == QSE_CHAR_EOF) { - qse_lsp_seterror (lsp, QSE_LSP_EENDSTR, QSE_NULL, 0); + qse_lsp_seterror (lsp, QSE_LSP_EENDSTR, QSE_NULL, &lsp->curloc); return -1; } @@ -565,3 +778,4 @@ static int read_string (qse_lsp_t* lsp) TOKEN_TYPE(lsp) = TOKEN_STRING; return 0; } + diff --git a/qse/lib/sed/Sed.cpp b/qse/lib/sed/Sed.cpp index d9ef45a1..3eede3cf 100644 --- a/qse/lib/sed/Sed.cpp +++ b/qse/lib/sed/Sed.cpp @@ -1,5 +1,5 @@ /* - * $Id: Sed.cpp 319 2009-12-19 03:06:28Z hyunghwan.chung $ + * $Id: Sed.cpp 344 2010-08-17 13:15:14Z hyunghwan.chung $ * Copyright 2006-2009 Chung, Hyung-Hwan. This file is part of QSE. @@ -102,7 +102,7 @@ Sed::loc_t Sed::getErrorLocation () const if (sed == QSE_NULL) { loc_t loc; - loc.lin = 0; loc.col = 0; + loc.line = 0; loc.colm = 0; return loc; } return *qse_sed_geterrloc (sed); diff --git a/qse/lib/sed/sed.c b/qse/lib/sed/sed.c index ca9fc83b..d4d1f6f5 100644 --- a/qse/lib/sed/sed.c +++ b/qse/lib/sed/sed.c @@ -1,5 +1,5 @@ /* - * $Id: sed.c 334 2010-07-14 12:54:48Z hyunghwan.chung $ + * $Id: sed.c 344 2010-08-17 13:15:14Z hyunghwan.chung $ * Copyright 2006-2009 Chung, Hyung-Hwan. This file is part of QSE. @@ -148,7 +148,6 @@ static qse_sed_t* qse_sed_init (qse_sed_t* sed, qse_mmgr_t* mmgr) return sed; } - static void qse_sed_fini (qse_sed_t* sed) { free_all_command_blocks (sed); @@ -209,10 +208,10 @@ static qse_cint_t getnextsc (qse_sed_t* sed) { if (sed->src.cc == QSE_T('\n')) { - sed->src.loc.lin++; - sed->src.loc.col = 1; + sed->src.loc.line++; + sed->src.loc.colm = 1; } - else sed->src.loc.col++; + else sed->src.loc.colm++; sed->src.cc = *sed->src.cur++; /* TODO: support different line end convension */ @@ -1236,8 +1235,8 @@ int qse_sed_comp (qse_sed_t* sed, const qse_char_t* sptr, qse_size_t slen) sed->src.ptr = sptr; sed->src.end = sptr + slen; sed->src.cur = sptr; - sed->src.loc.lin = 1; - sed->src.loc.col = 0; + sed->src.loc.line = 1; + sed->src.loc.colm = 0; sed->src.cc = QSE_CHAR_EOF; c = NXTSC (sed); diff --git a/qse/samples/awk/awk05.cpp b/qse/samples/awk/awk05.cpp index b313d199..5f1147d0 100644 --- a/qse/samples/awk/awk05.cpp +++ b/qse/samples/awk/awk05.cpp @@ -25,8 +25,8 @@ static void print_error ( const QSE::StdAwk::loc_t& loc, const QSE::StdAwk::char_t* msg) { - if (loc.lin > 0 || loc.col > 0) - qse_fprintf (QSE_STDERR, QSE_T("ERROR: %s at LINE %lu COLUMN %lu\n"), msg, loc.lin, loc.col); + if (loc.line > 0 || loc.colm > 0) + qse_fprintf (QSE_STDERR, QSE_T("ERROR: %s at LINE %lu COLUMN %lu\n"), msg, loc.line, loc.colm); else qse_fprintf (QSE_STDERR, QSE_T("ERROR: %s\n"), msg); diff --git a/qse/samples/awk/awk06.cpp b/qse/samples/awk/awk06.cpp index 2164a146..343419df 100644 --- a/qse/samples/awk/awk06.cpp +++ b/qse/samples/awk/awk06.cpp @@ -25,8 +25,8 @@ static void print_error ( const QSE::StdAwk::loc_t& loc, const QSE::StdAwk::char_t* msg) { - if (loc.lin > 0 || loc.col > 0) - qse_fprintf (QSE_STDERR, QSE_T("ERROR: %s at LINE %lu COLUMN %lu\n"), msg, loc.lin, loc.col); + if (loc.line > 0 || loc.colm > 0) + qse_fprintf (QSE_STDERR, QSE_T("ERROR: %s at LINE %lu COLUMN %lu\n"), msg, loc.line, loc.colm); else qse_fprintf (QSE_STDERR, QSE_T("ERROR: %s\n"), msg); diff --git a/qse/samples/awk/awk07.cpp b/qse/samples/awk/awk07.cpp index 67eb7dfc..d9adfcb3 100644 --- a/qse/samples/awk/awk07.cpp +++ b/qse/samples/awk/awk07.cpp @@ -25,8 +25,8 @@ static void print_error ( const QSE::StdAwk::loc_t& loc, const QSE::StdAwk::char_t* msg) { - if (loc.lin > 0 || loc.col > 0) - qse_fprintf (QSE_STDERR, QSE_T("ERROR: %s at LINE %lu COLUMN %lu\n"), msg, loc.lin, loc.col); + if (loc.line > 0 || loc.colm > 0) + qse_fprintf (QSE_STDERR, QSE_T("ERROR: %s at LINE %lu COLUMN %lu\n"), msg, loc.line, loc.colm); else qse_fprintf (QSE_STDERR, QSE_T("ERROR: %s\n"), msg); diff --git a/qse/samples/awk/awk08.cpp b/qse/samples/awk/awk08.cpp index f8d0eae9..8bd92510 100644 --- a/qse/samples/awk/awk08.cpp +++ b/qse/samples/awk/awk08.cpp @@ -179,7 +179,7 @@ static void print_error (MyAwk& awk) print_error ( QSE_T("LINE [%u] %s\n"), - (unsigned)loc.lin, + (unsigned)loc.line, awk.getErrorMessage() ); }