/* * $Id$ * Copyright (c) 2014-2019 Chung, Hyung-Hwan. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include #include #include #include #include #include #include #if (defined(__unix) || defined(__linux) || defined(__ultrix) || defined(_AIX) || defined(__hpux) || defined(__sgi)) && defined(HAVE_SIGNAL_H) # include #endif static void print_syntax_error (moo_t* moo, const char* main_src_file) { moo_synerr_t synerr; moo_getsynerr (moo, &synerr); moo_logbfmt (moo, MOO_LOG_STDERR, "ERROR: "); if (synerr.loc.file) { moo_logbfmt (moo, MOO_LOG_STDERR, "%js", synerr.loc.file); } else { moo_logbfmt (moo, MOO_LOG_STDERR, "%s", main_src_file); } moo_logbfmt (moo, MOO_LOG_STDERR, "[%zu,%zu] %js", synerr.loc.line, synerr.loc.colm, (moo_geterrmsg(moo) != moo_geterrstr(moo)? moo_geterrmsg(moo): moo_geterrstr(moo)) ); if (synerr.tgt.len > 0) { moo_logbfmt (moo, MOO_LOG_STDERR, " - %.*js", synerr.tgt.len, synerr.tgt.ptr); } moo_logbfmt (moo, MOO_LOG_STDERR, "\n"); } /* ========================================================================= */ #define MIN_HEAPSIZE 2048000ul int main (int argc, char* argv[]) { static moo_ooch_t str_my_object[] = { 'M', 'y', 'O', 'b','j','e','c','t' }; /*TODO: make this an argument */ static moo_ooch_t str_main[] = { 'm', 'a', 'i', 'n' }; moo_t* moo; moo_cfgstd_t cfg; moo_errinf_t errinf; moo_oocs_t objname; moo_oocs_t mthname; moo_oow_t heapsize; int i, xret; moo_bci_t c; static moo_bopt_lng_t lopt[] = { { ":log", 'l' }, { ":heapsize", '\0' }, { ":gctype", '\0' }, { ":procstksize", '\0' }, { "large-pages", '\0' }, { ":base-charset", '\0' }, { ":input-charset", '\0' }, { ":log-charset", '\0' }, #if defined(MOO_BUILD_DEBUG) { ":debug", '\0' }, /* [NOTE] there is no short option for --debug */ #endif { MOO_NULL, '\0' } }; static moo_bopt_t opt = { "l:m:", lopt }; setlocale (LC_ALL, ""); #if !defined(macintosh) if (argc < 2) { print_usage: fprintf (stderr, "Usage: %s [options] filename ...\n", argv[0]); fprintf (stderr, " --log filename[,logopts]\n"); fprintf (stderr, " --heapsize=bytes\n"); fprintf (stderr, " --gctype=ms|ss\n"); fprintf (stderr, " --procstksize=number of oops\n"); fprintf (stderr, " --large-pages\n"); fprintf (stderr, " --base-charset=name\n"); fprintf (stderr, " --input-charset=name\n"); fprintf (stderr, " --log-charset=name\n"); #if defined(MOO_BUILD_DEBUG) fprintf (stderr, " --debug dbgopts\n"); #endif return -1; } memset (&cfg, 0, MOO_SIZEOF(cfg)); cfg.type = MOO_CFGSTD_OPTB; cfg.cmgr = moo_get_utf8_cmgr(); cfg.input_cmgr = cfg.cmgr; cfg.log_cmgr = cfg.cmgr; heapsize = MIN_HEAPSIZE; while ((c = moo_getbopt(argc, argv, &opt)) != MOO_BCI_EOF) { switch (c) { case 'l': cfg.u.optb.log = opt.arg; break; case '\0': if (moo_comp_bcstr(opt.lngopt, "heapsize") == 0) { heapsize = strtoul(opt.arg, MOO_NULL, 0); break; } else if (moo_comp_bcstr(opt.lngopt, "gctype") == 0) { if (moo_comp_bcstr(opt.arg, "ms") == 0) cfg.gc_type = MOO_GC_TYPE_MARK_SWEEP; else cfg.gc_type = MOO_GC_TYPE_SEMISPACE; break; } else if (moo_comp_bcstr(opt.lngopt, "procstksize") == 0) { cfg.proc_stk_size = strtoul(opt.arg, MOO_NULL, 0); break; } else if (moo_comp_bcstr(opt.lngopt, "large-pages") == 0) { cfg.large_pages = 1; break; } else if (moo_comp_bcstr(opt.lngopt, "base-charset") == 0) { cfg.cmgr = moo_get_cmgr_by_bcstr(opt.arg); if (!cfg.cmgr) { fprintf (stderr, "unknown base-charset name - %s\n", opt.arg); return -1; } break; } else if (moo_comp_bcstr(opt.lngopt, "input-charset") == 0) { cfg.input_cmgr = moo_get_cmgr_by_bcstr(opt.arg); if (!cfg.input_cmgr) { fprintf (stderr, "unknown input-charset name - %s\n", opt.arg); return -1; } break; } else if (moo_comp_bcstr(opt.lngopt, "log-charset") == 0) { cfg.log_cmgr = moo_get_cmgr_by_bcstr(opt.arg); if (!cfg.log_cmgr) { fprintf (stderr, "unknown log-charset name - %s\n", opt.arg); return -1; } break; } #if defined(MOO_BUILD_DEBUG) else if (moo_comp_bcstr(opt.lngopt, "debug") == 0) { cfg.u.optb.dbg = opt.arg; break; } #endif goto print_usage; case ':': if (opt.lngopt) fprintf (stderr, "bad argument for '%s'\n", opt.lngopt); else fprintf (stderr, "bad argument for '%c'\n", opt.opt); return -1; default: goto print_usage; } } if (opt.ind >= argc) goto print_usage; #endif moo = moo_openstd(0, &cfg, &errinf); if (!moo) { #if defined(MOO_OOCH_IS_BCH) fprintf (stderr, "ERROR: cannot open moo - [%d] %s\n", (int)errinf.num, errinf.msg); #elif (MOO_SIZEOF_UCH_T == MOO_SIZEOF_WCHAR_T) fprintf (stderr, "ERROR: cannot open moo - [%d] %ls\n", (int)errinf.num, errinf.msg); #else moo_bch_t bcsmsg[MOO_COUNTOF(errinf.msg) * 2]; /* error messages may get truncated */ moo_oow_t wcslen, bcslen; bcslen = MOO_COUNTOF(bcsmsg); moo_conv_ucstr_to_utf8 (errinf.msg, &wcslen, bcsmsg, &bcslen); fprintf (stderr, "ERROR: cannot open moo - [%d] %s\n", (int)errinf.num, bcsmsg); #endif return -1; } { moo_oow_t tab_size; tab_size = 5000; moo_setoption (moo, MOO_OPTION_SYMTAB_SIZE, &tab_size); tab_size = 5000; moo_setoption (moo, MOO_OPTION_SYSDIC_SIZE, &tab_size); } if (cfg.gc_type == MOO_GC_TYPE_SEMISPACE && heapsize <= MIN_HEAPSIZE) heapsize = MIN_HEAPSIZE; if (moo_ignite(moo, heapsize) <= -1) { moo_logbfmt (moo, MOO_LOG_STDERR, "ERROR: cannot ignite moo - [%d] %js\n", moo_geterrnum(moo), moo_geterrstr(moo)); moo_close (moo); return -1; } /* TODO: don't initialize debug information if debug info is not requested. * call moo_loaddbgi() if loading a compiled image... */ if (moo_initdbgi(moo, 102400) <= -1) /* TODO: set initial debug information size from a configurable value */ { moo_logbfmt (moo, MOO_LOG_STDERR, "ERROR: cannot initialize debug information - [%d] %js\n", moo_geterrnum(moo), moo_geterrstr(moo)); moo_close (moo); return -1; } /* #if defined(macintosh) i = 20; xtn->source_path = "test.moo"; goto compile; #endif */ for (i = opt.ind; i < argc; i++) { moo_iostd_t in; memset (&in, 0, MOO_SIZEOF(in)); #if 1 in.type = MOO_IOSTD_FILEB; in.u.fileb.path = argv[i]; #else moo_uch_t tmp[1000]; moo_oow_t bcslen, ucslen; ucslen = MOO_COUNTOF(tmp); moo_conv_utf8_to_ucstr(argv[i], &bcslen, tmp, &ucslen); in.type = MOO_IOSTD_FILEU; in.u.fileu.path = tmp; #endif in.cmgr = MOO_NULL; /*compile:*/ if (moo_compilestd(moo, &in, 1) <= -1) { if (moo->errnum == MOO_ESYNERR) { print_syntax_error (moo, argv[i]); } else { moo_logbfmt (moo, MOO_LOG_STDERR, "ERROR: cannot compile code - [%d] %js\n", moo_geterrnum(moo), moo_geterrmsg(moo)); } moo_close (moo); return -1; } } /*MOO_DEBUG2 (moo, "XXXXXXXXXXXXXXXXXXXXX %O %zd\n", moo_ooitoint(moo, MOO_TYPE_MIN(moo_ooi_t)), MOO_TYPE_MIN(moo_ooi_t)); MOO_DEBUG2 (moo, "XXXXXXXXXXXXXXXXXXXXX %O %jd\n", moo_intmaxtoint(moo, MOO_TYPE_MIN(moo_intmax_t)), MOO_TYPE_MIN(moo_intmax_t)); MOO_DEBUG2 (moo, "XXXXXXXXXXXXXXXXXXXXX %O %ju\n", moo_uintmaxtoint(moo, MOO_TYPE_MAX(moo_uintmax_t)), MOO_TYPE_MAX(moo_uintmax_t)); MOO_DEBUG2 (moo, "XXXXXXXXXXXXXXXXXXXXX %O %zu\n", moo_oowtoint(moo, MOO_TYPE_MAX(moo_oow_t)), MOO_TYPE_MAX(moo_oow_t));*/ MOO_DEBUG0 (moo, "COMPILE OK. STARTING EXECUTION...\n"); xret = 0; #if defined(SIGINT) && defined(HAVE_SIGNAL) /* i'd like the program to ignore the interrupt signal * before moo_catch_termreq() and after moo_uncatch_termreq() */ signal (SIGINT, SIG_IGN); signal (SIGTERM, SIG_IGN); #endif moo_catch_termreq (); moo_start_ticker (); moo_rcvtickstd (moo, 1); objname.ptr = str_my_object; objname.len = 8; mthname.ptr = str_main; mthname.len = 4; if (moo_invoke(moo, &objname, &mthname) <= -1) { moo_logbfmt (moo, MOO_LOG_STDERR, "ERROR: cannot execute code - [%d] %js\n", moo_geterrnum(moo), moo_geterrmsg(moo)); xret = -1; } moo_stop_ticker (); moo_uncatch_termreq (); /*moo_dumpsymtab(moo); moo_dumpdic(moo, moo->sysdic, "System dictionary");*/ moo_close (moo); return xret; }