hawk/lib/Hawk.cpp

2891 lines
66 KiB
C++

/*
* $Id$
*
Copyright (c) 2006-2020 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 <Hawk.hpp>
#include "hawk-prv.h"
/////////////////////////////////
HAWK_BEGIN_NAMESPACE(HAWK)
/////////////////////////////////
//////////////////////////////////////////////////////////////////
// Mmged
//////////////////////////////////////////////////////////////////
Mmged::Mmged (Mmgr* mmgr)
{
if (!mmgr) mmgr = Mmgr::getDFL();
this->_mmgr = mmgr;
}
void Mmged::setMmgr (Mmgr* mmgr)
{
if (!mmgr) mmgr = Mmgr::getDFL();
this->_mmgr = mmgr;
}
//////////////////////////////////////////////////////////////////
// Mmgr
//////////////////////////////////////////////////////////////////
void* Mmgr::alloc_mem (mmgr_t* mmgr, hawk_oow_t n) HAWK_CXX_NOEXCEPT
{
return ((Mmgr*)mmgr->ctx)->allocMem (n);
}
void* Mmgr::realloc_mem (mmgr_t* mmgr, void* ptr, hawk_oow_t n) HAWK_CXX_NOEXCEPT
{
return ((Mmgr*)mmgr->ctx)->reallocMem (ptr, n);
}
void Mmgr::free_mem (mmgr_t* mmgr, void* ptr) HAWK_CXX_NOEXCEPT
{
((Mmgr*)mmgr->ctx)->freeMem (ptr);
}
void* Mmgr::callocate (hawk_oow_t n, bool raise_exception) /*HAWK_CXX_THREXCEPT1(MemoryError)*/
{
void* ptr = this->allocate(n, raise_exception);
HAWK_MEMSET (ptr, 0, n);
return ptr;
}
#if 0
#if defined(__GNUC__)
static MmgrStd __attribute__((init_priority(101))) std_dfl_mmgr; //<- this solved the problem
#else
static MmgrStd std_dfl_mmgr; //<-- has an issue for undefined initialization order
#endif
Mmgr* Mmgr::dfl_mmgr = &std_dfl_mmgr;
//Mmgr* Mmgr::dfl_mmgr = MmgrStd::getInstance(); //<--- has an issue as well
Mmgr* Mmgr::getDFL () HAWK_CXX_NOEXCEPT
{
return Mmgr::dfl_mmgr;
}
#else
// C++ initialization order across translation units are not defined.
// so it's tricky to work around this... the init_priority attribute
// can solve this problem. but it's compiler dependent.
// Mmgr::getDFL() resets dfl_mmgr to &std_dfl_mmgr if it's NULL.
Mmgr* Mmgr::dfl_mmgr = HAWK_NULL;
Mmgr* Mmgr::getDFL () HAWK_CXX_NOEXCEPT
{
static MmgrStd std_dfl_mmgr;
Mmgr* mmgr = Mmgr::dfl_mmgr;
return mmgr? mmgr: &std_dfl_mmgr;
}
#endif
void Mmgr::setDFL (Mmgr* mmgr) HAWK_CXX_NOEXCEPT
{
Mmgr::dfl_mmgr = mmgr;
}
//////////////////////////////////////////////////////////////////
// Hawk::Source
//////////////////////////////////////////////////////////////////
struct xtn_t
{
Hawk* hawk;
hawk_ecb_t ecb;
};
struct rxtn_t
{
Hawk::Run* run;
};
Hawk::NoSource Hawk::Source::NONE;
#if defined(HAWK_HAVE_INLINE)
static HAWK_INLINE xtn_t* GET_XTN(hawk_t* hawk) { return (xtn_t*)((hawk_uint8_t*)hawk_getxtn(hawk) - HAWK_SIZEOF(xtn_t)); }
static HAWK_INLINE rxtn_t* GET_RXTN(hawk_rtx_t* rtx) { return (rxtn_t*)((hawk_uint8_t*)hawk_rtx_getxtn(rtx) - HAWK_SIZEOF(rxtn_t)); }
#else
#define GET_XTN(hawk) ((xtn_t*)((hawk_uint8_t*)hawk_getxtn(hawk) - HAWK_SIZEOF(xtn_t)))
#define GET_RXTN(rtx) ((rxtn_t*)((hawk_uint8_t*)hawk_rtx_getxtn(rtx) - HAWK_SIZEOF(rxtn_t)))
#endif
//////////////////////////////////////////////////////////////////
// Hawk::Pipe
//////////////////////////////////////////////////////////////////
Hawk::Pipe::Pipe (Run* run, hawk_rio_arg_t* riod): RIOBase (run, riod)
{
}
Hawk::Pipe::Mode Hawk::Pipe::getMode () const
{
return (Mode)riod->mode;
}
Hawk::Pipe::CloseMode Hawk::Pipe::getCloseMode () const
{
return (CloseMode)riod->rwcmode;
}
//////////////////////////////////////////////////////////////////
// Hawk::File
//////////////////////////////////////////////////////////////////
Hawk::File::File (Run* run, hawk_rio_arg_t* riod): RIOBase (run, riod)
{
}
Hawk::File::Mode Hawk::File::getMode () const
{
return (Mode)riod->mode;
}
//////////////////////////////////////////////////////////////////
// Hawk::Console
//////////////////////////////////////////////////////////////////
Hawk::Console::Console (Run* run, hawk_rio_arg_t* riod):
RIOBase (run, riod), filename (HAWK_NULL)
{
}
Hawk::Console::~Console ()
{
if (filename != HAWK_NULL)
{
hawk_freemem ((hawk_t*)this, filename);
}
}
int Hawk::Console::setFileName (const hawk_ooch_t* name)
{
if (this->getMode() == READ)
{
return hawk_rtx_setfilenamewithoochars(this->run->rtx, name, hawk_count_oocstr(name));
}
else
{
return hawk_rtx_setofilenamewithoochars(this->run->rtx, name, hawk_count_oocstr(name));
}
}
int Hawk::Console::setFNR (hawk_int_t fnr)
{
hawk_val_t* tmp;
int n;
tmp = hawk_rtx_makeintval (this->run->rtx, fnr);
if (tmp == HAWK_NULL) return -1;
hawk_rtx_refupval (this->run->rtx, tmp);
n = hawk_rtx_setgbl(this->run->rtx, HAWK_GBL_FNR, tmp);
hawk_rtx_refdownval (this->run->rtx, tmp);
return n;
}
Hawk::Console::Mode Hawk::Console::getMode () const
{
return (Mode)riod->mode;
}
//////////////////////////////////////////////////////////////////
// Hawk::Value
//////////////////////////////////////////////////////////////////
Hawk::Value::IndexIterator Hawk::Value::IndexIterator::END;
const hawk_ooch_t* Hawk::Value::getEmptyStr()
{
static const hawk_ooch_t* EMPTY_STRING = HAWK_T("");
return EMPTY_STRING;
}
const hawk_bch_t* Hawk::Value::getEmptyMbs()
{
static const hawk_bch_t* EMPTY_STRING = HAWK_BT("");
return EMPTY_STRING;
}
Hawk::Value::IntIndex::IntIndex (hawk_int_t x)
{
ptr = buf;
len = 0;
#define NTOC(n) (HAWK_T("0123456789")[n])
int base = 10;
hawk_int_t last = x % base;
hawk_int_t y = 0;
int dig = 0;
if (x < 0) buf[len++] = HAWK_T('-');
x = x / base;
if (x < 0) x = -x;
while (x > 0)
{
y = y * base + (x % base);
x = x / base;
dig++;
}
while (y > 0)
{
buf[len++] = NTOC (y % base);
y = y / base;
dig--;
}
while (dig > 0)
{
dig--;
buf[len++] = HAWK_T('0');
}
if (last < 0) last = -last;
buf[len++] = NTOC(last);
buf[len] = HAWK_T('\0');
#undef NTOC
}
#if defined(HAWK_VALUE_USE_IN_CLASS_PLACEMENT_NEW)
void* Hawk::Value::operator new (hawk_oow_t n, Run* run) throw ()
{
void* ptr = hawk_rtx_allocmem (run->rtx, HAWK_SIZEOF(run) + n);
if (ptr == HAWK_NULL) return HAWK_NULL;
*(Run**)ptr = run;
return (char*)ptr + HAWK_SIZEOF(run);
}
void* Hawk::Value::operator new[] (hawk_oow_t n, Run* run) throw ()
{
void* ptr = hawk_rtx_allocmem (run->rtx, HAWK_SIZEOF(run) + n);
if (ptr == HAWK_NULL) return HAWK_NULL;
*(Run**)ptr = run;
return (char*)ptr + HAWK_SIZEOF(run);
}
#if !defined(__BORLANDC__) && !defined(__WATCOMC__)
void Hawk::Value::operator delete (void* ptr, Run* run)
{
// this placement delete is to be called when the constructor
// throws an exception and it's caught by the caller.
hawk_rtx_freemem (run->rtx, (char*)ptr - HAWK_SIZEOF(run));
}
void Hawk::Value::operator delete[] (void* ptr, Run* run)
{
// this placement delete is to be called when the constructor
// throws an exception and it's caught by the caller.
hawk_rtx_freemem (run->rtx, (char*)ptr - HAWK_SIZEOF(run));
}
#endif
void Hawk::Value::operator delete (void* ptr)
{
// this delete is to be called for normal destruction.
void* p = (char*)ptr - HAWK_SIZEOF(Run*);
hawk_rtx_freemem ((*(Run**)p)->rtx, p);
}
void Hawk::Value::operator delete[] (void* ptr)
{
// this delete is to be called for normal destruction.
void* p = (char*)ptr - HAWK_SIZEOF(Run*);
hawk_rtx_freemem ((*(Run**)p)->rtx, p);
}
#endif
Hawk::Value::Value (): run(HAWK_NULL), val(hawk_get_nil_val())
{
this->cached.str.ptr = HAWK_NULL;
this->cached.str.len = 0;
this->cached.mbs.ptr = HAWK_NULL;
this->cached.mbs.len = 0;
}
Hawk::Value::Value (Run& run): run(&run), val(hawk_get_nil_val())
{
this->cached.str.ptr = HAWK_NULL;
this->cached.str.len = 0;
this->cached.mbs.ptr = HAWK_NULL;
this->cached.mbs.len = 0;
}
Hawk::Value::Value (Run* run): run(run), val(hawk_get_nil_val())
{
this->cached.str.ptr = HAWK_NULL;
this->cached.str.len = 0;
this->cached.mbs.ptr = HAWK_NULL;
this->cached.mbs.len = 0;
}
Hawk::Value::Value (const Value& v): run(v.run), val(v.val)
{
if (this->run) hawk_rtx_refupval (this->run->rtx, this->val);
this->cached.str.ptr = HAWK_NULL;
this->cached.str.len = 0;
this->cached.mbs.ptr = HAWK_NULL;
this->cached.mbs.len = 0;
}
Hawk::Value::~Value ()
{
if (this->run)
{
hawk_rtx_refdownval (this->run->rtx, val);
if (this->cached.str.ptr) hawk_rtx_freemem (this->run->rtx, cached.str.ptr);
if (this->cached.mbs.ptr) hawk_rtx_freemem (this->run->rtx, cached.mbs.ptr);
}
}
Hawk::Value& Hawk::Value::operator= (const Value& v)
{
if (this == &v) return *this;
if (this->run)
{
hawk_rtx_refdownval (this->run->rtx, this->val);
if (this->cached.str.ptr)
{
hawk_rtx_freemem (this->run->rtx, this->cached.str.ptr);
this->cached.str.ptr = HAWK_NULL;
this->cached.str.len = 0;
}
if (this->cached.mbs.ptr)
{
hawk_rtx_freemem (this->run->rtx, this->cached.mbs.ptr);
this->cached.mbs.ptr = HAWK_NULL;
this->cached.mbs.len = 0;
}
}
this->run = v.run;
this->val = v.val;
if (this->run) hawk_rtx_refupval (this->run->rtx, this->val);
return *this;
}
void Hawk::Value::clear ()
{
if (this->run)
{
hawk_rtx_refdownval (this->run->rtx, this->val);
if (this->cached.str.ptr)
{
hawk_rtx_freemem (this->run->rtx, this->cached.str.ptr);
this->cached.str.ptr = HAWK_NULL;
this->cached.str.len = 0;
}
if (this->cached.mbs.ptr)
{
hawk_rtx_freemem (this->run->rtx, this->cached.mbs.ptr);
this->cached.mbs.ptr = HAWK_NULL;
this->cached.mbs.len = 0;
}
this->run = HAWK_NULL;
this->val = hawk_get_nil_val();
}
}
Hawk::Value::operator hawk_int_t () const
{
hawk_int_t v;
if (this->getInt(&v) <= -1) v = 0;
return v;
}
Hawk::Value::operator hawk_flt_t () const
{
hawk_flt_t v;
if (this->getFlt(&v) <= -1) v = 0.0;
return v;
}
Hawk::Value::operator const hawk_ooch_t* () const
{
const hawk_ooch_t* ptr;
hawk_oow_t len;
if (Hawk::Value::getStr(&ptr, &len) <= -1) ptr = getEmptyStr();
return ptr;
}
#if defined(HAWK_OOCH_IS_UCH)
Hawk::Value::operator const hawk_bch_t* () const
{
const hawk_bch_t* ptr;
hawk_oow_t len;
if (Hawk::Value::getMbs(&ptr, &len) <= -1) ptr = getEmptyMbs();
return ptr;
}
#endif
int Hawk::Value::getInt (hawk_int_t* v) const
{
hawk_int_t lv = 0;
HAWK_ASSERT (this->val != HAWK_NULL);
if (this->run)
{
int n = hawk_rtx_valtoint(this->run->rtx, this->val, &lv);
if (n <= -1)
{
run->hawk->retrieveError (this->run);
return -1;
}
}
*v = lv;
return 0;
}
int Hawk::Value::getFlt (hawk_flt_t* v) const
{
hawk_flt_t rv = 0;
HAWK_ASSERT (this->val != HAWK_NULL);
if (this->run)
{
int n = hawk_rtx_valtoflt(this->run->rtx, this->val, &rv);
if (n <= -1)
{
run->hawk->retrieveError (this->run);
return -1;
}
}
*v = rv;
return 0;
}
int Hawk::Value::getNum (hawk_int_t* lv, hawk_flt_t* fv) const
{
HAWK_ASSERT (this->val != HAWK_NULL);
if (this->run)
{
int n = hawk_rtx_valtonum(this->run->rtx, this->val, lv, fv);
if (n <= -1)
{
run->hawk->retrieveError (this->run);
return -1;
}
return n;
}
*lv = 0;
return 0;
}
int Hawk::Value::getStr (const hawk_ooch_t** str, hawk_oow_t* len) const
{
const hawk_ooch_t* p = getEmptyStr();
hawk_oow_t l = 0;
HAWK_ASSERT (this->val != HAWK_NULL);
if (this->run)
{
if (HAWK_RTX_GETVALTYPE(this->run->rtx, this->val) == HAWK_VAL_STR)
{
p = ((hawk_val_str_t*)this->val)->val.ptr;
l = ((hawk_val_str_t*)this->val)->val.len;
}
else
{
if (!cached.str.ptr)
{
hawk_rtx_valtostr_out_t out;
out.type = HAWK_RTX_VALTOSTR_CPLDUP;
if (hawk_rtx_valtostr(this->run->rtx, this->val, &out) <= -1)
{
run->hawk->retrieveError (this->run);
return -1;
}
p = out.u.cpldup.ptr;
l = out.u.cpldup.len;
cached.str.ptr = out.u.cpldup.ptr;
cached.str.len = out.u.cpldup.len;
}
else
{
p = cached.str.ptr;
l = cached.str.len;
}
}
}
*str = p;
*len = l;
return 0;
}
int Hawk::Value::getMbs (const hawk_bch_t** str, hawk_oow_t* len) const
{
const hawk_bch_t* p = getEmptyMbs();
hawk_oow_t l = 0;
HAWK_ASSERT (this->val != HAWK_NULL);
if (this->run)
{
if (HAWK_RTX_GETVALTYPE(this->run->rtx, this->val) == HAWK_VAL_MBS)
{
p = ((hawk_val_mbs_t*)this->val)->val.ptr;
l = ((hawk_val_mbs_t*)this->val)->val.len;
}
else
{
if (!cached.mbs.ptr)
{
p = hawk_rtx_valtobcstrdup(this->run->rtx, this->val, &l);
if (!p)
{
run->hawk->retrieveError (this->run);
return -1;
}
cached.mbs.ptr = (hawk_bch_t*)p;
cached.mbs.len = l;
}
else
{
p = cached.mbs.ptr;
l = cached.mbs.len;
}
}
}
*str = p;
*len = l;
return 0;
}
int Hawk::Value::setVal (hawk_val_t* v)
{
if (this->run == HAWK_NULL)
{
/* no runtime context assoicated. unfortunately, i can't
* set an error number for the same reason */
return -1;
}
return this->setVal(this->run, v);
}
int Hawk::Value::setVal (Run* r, hawk_val_t* v)
{
if (this->run != HAWK_NULL)
{
hawk_rtx_refdownval (this->run->rtx, val);
if (cached.str.ptr)
{
hawk_rtx_freemem (this->run->rtx, cached.str.ptr);
cached.str.ptr = HAWK_NULL;
cached.str.len = 0;
}
if (cached.mbs.ptr)
{
hawk_rtx_freemem (this->run->rtx, cached.mbs.ptr);
cached.mbs.ptr = HAWK_NULL;
cached.mbs.len = 0;
}
}
HAWK_ASSERT (cached.str.ptr == HAWK_NULL);
HAWK_ASSERT (cached.mbs.ptr == HAWK_NULL);
hawk_rtx_refupval (r->rtx, v);
this->run = r;
this->val = v;
return 0;
}
int Hawk::Value::setInt (hawk_int_t v)
{
if (this->run == HAWK_NULL)
{
/* no runtime context assoicated. unfortunately, i can't
* set an error number for the same reason */
return -1;
}
return this->setInt(this->run, v);
}
int Hawk::Value::setInt (Run* r, hawk_int_t v)
{
hawk_val_t* tmp;
tmp = hawk_rtx_makeintval(r->rtx, v);
if (tmp == HAWK_NULL)
{
r->hawk->retrieveError (r);
return -1;
}
int n = this->setVal(r, tmp);
HAWK_ASSERT (n == 0);
return n;
}
int Hawk::Value::setFlt (hawk_flt_t v)
{
if (this->run == HAWK_NULL)
{
/* no runtime context assoicated. unfortunately, i can't
* set an error number for the same reason */
return -1;
}
return this->setFlt(this->run, v);
}
int Hawk::Value::setFlt (Run* r, hawk_flt_t v)
{
hawk_val_t* tmp;
tmp = hawk_rtx_makefltval(r->rtx, v);
if (tmp == HAWK_NULL)
{
r->hawk->retrieveError (r);
return -1;
}
int n = this->setVal(r, tmp);
HAWK_ASSERT (n == 0);
return n;
}
//////////////////////////////////////////////////////////////////
int Hawk::Value::setStr (const hawk_uch_t* str, hawk_oow_t len, bool numeric)
{
if (this->run == HAWK_NULL)
{
/* no runtime context assoicated. unfortunately, i can't
* set an error number for the same reason */
return -1;
}
return this->setStr(this->run, str, len, numeric);
}
int Hawk::Value::setStr (Run* r, const hawk_uch_t* str, hawk_oow_t len, bool numeric)
{
hawk_val_t* tmp;
tmp = numeric? hawk_rtx_makenumorstrvalwithuchars(r->rtx, str, len):
hawk_rtx_makestrvalwithuchars(r->rtx, str, len);
if (tmp == HAWK_NULL)
{
r->hawk->retrieveError (r);
return -1;
}
int n = this->setVal(r, tmp);
HAWK_ASSERT (n == 0);
return n;
}
int Hawk::Value::setStr (const hawk_uch_t* str, bool numeric)
{
if (HAWK_UNLIKELY(!this->run)) return -1;
return this->setStr(this->run, str, numeric);
}
int Hawk::Value::setStr (Run* r, const hawk_uch_t* str, bool numeric)
{
hawk_val_t* tmp;
tmp = numeric? hawk_rtx_makenumorstrvalwithuchars(r->rtx, str, hawk_count_ucstr(str)):
hawk_rtx_makestrvalwithucstr(r->rtx, str);
if (tmp == HAWK_NULL)
{
r->hawk->retrieveError (r);
return -1;
}
int n = this->setVal(r, tmp);
HAWK_ASSERT (n == 0);
return n;
}
//////////////////////////////////////////////////////////////////
int Hawk::Value::setStr (const hawk_bch_t* str, hawk_oow_t len, bool numeric)
{
if (this->run == HAWK_NULL)
{
/* no runtime context assoicated. unfortunately, i can't
* set an error number for the same reason */
return -1;
}
return this->setStr(this->run, str, len, numeric);
}
int Hawk::Value::setStr (Run* r, const hawk_bch_t* str, hawk_oow_t len, bool numeric)
{
hawk_val_t* tmp;
tmp = numeric? hawk_rtx_makenumorstrvalwithbchars(r->rtx, str, len):
hawk_rtx_makestrvalwithbchars(r->rtx, str, len);
if (tmp == HAWK_NULL)
{
r->hawk->retrieveError (r);
return -1;
}
int n = this->setVal(r, tmp);
HAWK_ASSERT (n == 0);
return n;
}
int Hawk::Value::setStr (const hawk_bch_t* str, bool numeric)
{
if (HAWK_UNLIKELY(!this->run)) return -1;
return this->setStr(this->run, str, numeric);
}
int Hawk::Value::setStr (Run* r, const hawk_bch_t* str, bool numeric)
{
hawk_val_t* tmp;
tmp = numeric? hawk_rtx_makenumorstrvalwithbchars(r->rtx, str, hawk_count_bcstr(str)):
hawk_rtx_makestrvalwithbcstr(r->rtx, str);
if (tmp == HAWK_NULL)
{
r->hawk->retrieveError (r);
return -1;
}
int n = this->setVal(r, tmp);
HAWK_ASSERT (n == 0);
return n;
}
//////////////////////////////////////////////////////////////////
int Hawk::Value::setMbs (const hawk_bch_t* str, hawk_oow_t len)
{
if (this->run == HAWK_NULL)
{
/* no runtime context assoicated. unfortunately, i can't
* set an error number for the same reason */
return -1;
}
return this->setMbs(this->run, str, len);
}
int Hawk::Value::setMbs (Run* r, const hawk_bch_t* str, hawk_oow_t len)
{
hawk_val_t* tmp;
hawk_bcs_t oocs;
oocs.ptr = (hawk_bch_t*)str;
oocs.len = len;
tmp = hawk_rtx_makembsvalwithbcs(r->rtx, &oocs);
if (!tmp)
{
r->hawk->retrieveError (r);
return -1;
}
int n = this->setVal(r, tmp);
HAWK_ASSERT (n == 0);
return n;
}
int Hawk::Value::setMbs (const hawk_bch_t* str)
{
if (HAWK_UNLIKELY(!this->run)) return -1;
return this->setMbs(this->run, str);
}
int Hawk::Value::setMbs (Run* r, const hawk_bch_t* str)
{
hawk_val_t* tmp;
tmp = hawk_rtx_makembsvalwithbchars(r->rtx, str, hawk_count_bcstr(str));
if (!tmp)
{
r->hawk->retrieveError (r);
return -1;
}
int n = this->setVal(r, tmp);
HAWK_ASSERT (n == 0);
return n;
}
int Hawk::Value::setIndexedVal (const Index& idx, hawk_val_t* v)
{
if (HAWK_UNLIKELY(!this->run)) return -1;
return this->setIndexedVal(this->run, idx, v);
}
int Hawk::Value::setIndexedVal (Run* r, const Index& idx, hawk_val_t* v)
{
HAWK_ASSERT (r != HAWK_NULL);
if (HAWK_RTX_GETVALTYPE(r->rtx, this->val) != HAWK_VAL_MAP)
{
// the previous value is not a map.
// a new map value needs to be created first.
hawk_val_t* map = hawk_rtx_makemapval(r->rtx);
if (map == HAWK_NULL)
{
r->hawk->retrieveError (r);
return -1;
}
hawk_rtx_refupval (r->rtx, map);
// update the map with a given value
if (hawk_rtx_setmapvalfld(r->rtx, map, idx.ptr, idx.len, v) == HAWK_NULL)
{
hawk_rtx_refdownval (r->rtx, map);
r->hawk->retrieveError (r);
return -1;
}
// free the previous value
if (this->run)
{
// if val is not nil, this->run can't be NULL
hawk_rtx_refdownval (this->run->rtx, this->val);
}
this->run = r;
this->val = map;
}
else
{
HAWK_ASSERT (run != HAWK_NULL);
// if the previous value is a map, things are a bit simpler
// however it needs to check if the runtime context matches
// with the previous one.
if (this->run != r)
{
// it can't span across multiple runtime contexts
this->run->setError (HAWK_EINVAL);
this->run->hawk->retrieveError (run);
return -1;
}
// update the map with a given value
if (hawk_rtx_setmapvalfld(r->rtx, val, idx.ptr, idx.len, v) == HAWK_NULL)
{
r->hawk->retrieveError (r);
return -1;
}
}
return 0;
}
int Hawk::Value::setIndexedInt (const Index& idx, hawk_int_t v)
{
if (run == HAWK_NULL) return -1;
return this->setIndexedInt (run, idx, v);
}
int Hawk::Value::setIndexedInt (Run* r, const Index& idx, hawk_int_t v)
{
hawk_val_t* tmp = hawk_rtx_makeintval (r->rtx, v);
if (tmp == HAWK_NULL)
{
r->hawk->retrieveError (r);
return -1;
}
hawk_rtx_refupval (r->rtx, tmp);
int n = this->setIndexedVal(r, idx, tmp);
hawk_rtx_refdownval (r->rtx, tmp);
return n;
}
int Hawk::Value::setIndexedFlt (const Index& idx, hawk_flt_t v)
{
if (run == HAWK_NULL) return -1;
return this->setIndexedFlt(run, idx, v);
}
int Hawk::Value::setIndexedFlt (Run* r, const Index& idx, hawk_flt_t v)
{
hawk_val_t* tmp = hawk_rtx_makefltval(r->rtx, v);
if (tmp == HAWK_NULL)
{
r->hawk->retrieveError (r);
return -1;
}
hawk_rtx_refupval (r->rtx, tmp);
int n = this->setIndexedVal(r, idx, tmp);
hawk_rtx_refdownval (r->rtx, tmp);
return n;
}
///////////////////////////////////////////////////////////////////
int Hawk::Value::setIndexedStr (const Index& idx, const hawk_uch_t* str, hawk_oow_t len, bool numeric)
{
if (HAWK_UNLIKELY(!this->run)) return -1; // NOTE: this->run isn't available. neither is this->run->hawk. unable to set an error code
return this->setIndexedStr(this->run, idx, str, len, numeric);
}
int Hawk::Value::setIndexedStr (Run* r, const Index& idx, const hawk_uch_t* str, hawk_oow_t len, bool numeric)
{
hawk_val_t* tmp;
tmp = numeric? hawk_rtx_makenumorstrvalwithuchars(r->rtx, str, len):
hawk_rtx_makestrvalwithuchars(r->rtx, str, len);
if (HAWK_UNLIKELY(!tmp))
{
r->hawk->retrieveError (r);
return -1;
}
hawk_rtx_refupval (r->rtx, tmp);
int n = this->setIndexedVal(r, idx, tmp);
hawk_rtx_refdownval (r->rtx, tmp);
return n;
}
int Hawk::Value::setIndexedStr (const Index& idx, const hawk_uch_t* str, bool numeric)
{
if (run == HAWK_NULL) return -1; // NOTE: this->run isn't available. neither is this->run->hawk. unable to set an error code
return this->setIndexedStr(run, idx, str, numeric);
}
int Hawk::Value::setIndexedStr (Run* r, const Index& idx, const hawk_uch_t* str, bool numeric)
{
hawk_val_t* tmp;
tmp = numeric? hawk_rtx_makenumorstrvalwithuchars(r->rtx, str, hawk_count_ucstr(str)):
hawk_rtx_makestrvalwithucstr(r->rtx, str);
if (HAWK_UNLIKELY(!tmp))
{
r->hawk->retrieveError (r);
return -1;
}
hawk_rtx_refupval (r->rtx, tmp);
int n = this->setIndexedVal(r, idx, tmp);
hawk_rtx_refdownval (r->rtx, tmp);
return n;
}
int Hawk::Value::setIndexedStr (const Index& idx, const hawk_bch_t* str, hawk_oow_t len, bool numeric)
{
if (HAWK_UNLIKELY(!this->run)) return -1; // NOTE: this->run isn't available. neither is this->run->hawk. unable to set an error code
return this->setIndexedStr(this->run, idx, str, len, numeric);
}
int Hawk::Value::setIndexedStr (Run* r, const Index& idx, const hawk_bch_t* str, hawk_oow_t len, bool numeric)
{
hawk_val_t* tmp;
tmp = numeric? hawk_rtx_makenumorstrvalwithbchars(r->rtx, str, len):
hawk_rtx_makestrvalwithbchars(r->rtx, str, len);
if (HAWK_UNLIKELY(!tmp))
{
r->hawk->retrieveError (r);
return -1;
}
hawk_rtx_refupval (r->rtx, tmp);
int n = this->setIndexedVal(r, idx, tmp);
hawk_rtx_refdownval (r->rtx, tmp);
return n;
}
int Hawk::Value::setIndexedStr (const Index& idx, const hawk_bch_t* str, bool numeric)
{
if (HAWK_UNLIKELY(!this->run)) return -1; // NOTE: this->run isn't available. neither is this->run->hawk. unable to set an error code
return this->setIndexedStr(run, idx, str, numeric);
}
int Hawk::Value::setIndexedStr (Run* r, const Index& idx, const hawk_bch_t* str, bool numeric)
{
hawk_val_t* tmp;
tmp = numeric? hawk_rtx_makenumorstrvalwithbchars(r->rtx, str, hawk_count_bcstr(str)):
hawk_rtx_makestrvalwithbcstr(r->rtx, str);
if (HAWK_UNLIKELY(!tmp))
{
r->hawk->retrieveError (r);
return -1;
}
hawk_rtx_refupval (r->rtx, tmp);
int n = this->setIndexedVal(r, idx, tmp);
hawk_rtx_refdownval (r->rtx, tmp);
return n;
}
///////////////////////////////////////////////////////////////////
int Hawk::Value::setIndexedMbs (const Index& idx, const hawk_bch_t* str, hawk_oow_t len)
{
if (HAWK_UNLIKELY(!this->run)) return -1; // NOTE: this->run isn't available. neither is this->run->hawk. unable to set an error code
return this->setIndexedMbs(this->run, idx, str, len);
}
int Hawk::Value::setIndexedMbs (Run* r, const Index& idx, const hawk_bch_t* str, hawk_oow_t len)
{
hawk_val_t* tmp;
hawk_bcs_t oocs;
oocs.ptr = (hawk_bch_t*)str;
oocs.len = len;
tmp = hawk_rtx_makembsvalwithbcs(r->rtx, &oocs);
if (HAWK_UNLIKELY(!tmp))
{
r->hawk->retrieveError (r);
return -1;
}
hawk_rtx_refupval (r->rtx, tmp);
int n = this->setIndexedVal(r, idx, tmp);
hawk_rtx_refdownval (r->rtx, tmp);
return n;
}
int Hawk::Value::setIndexedMbs (const Index& idx, const hawk_bch_t* str)
{
if (HAWK_UNLIKELY(!this->run)) return -1; // NOTE: this->run isn't available. neither is this->run->hawk. unable to set an error code
return this->setIndexedMbs(run, idx, str);
}
int Hawk::Value::setIndexedMbs (Run* r, const Index& idx, const hawk_bch_t* str)
{
hawk_val_t* tmp;
tmp = hawk_rtx_makembsvalwithbchars(r->rtx, str, hawk_count_bcstr(str));
if (HAWK_UNLIKELY(!tmp))
{
r->hawk->retrieveError (r);
return -1;
}
hawk_rtx_refupval (r->rtx, tmp);
int n = this->setIndexedVal(r, idx, tmp);
hawk_rtx_refdownval (r->rtx, tmp);
return n;
}
bool Hawk::Value::isIndexed () const
{
HAWK_ASSERT (val != HAWK_NULL);
return HAWK_RTX_GETVALTYPE(this->run->rtx, val) == HAWK_VAL_MAP;
}
int Hawk::Value::getIndexed (const Index& idx, Value* v) const
{
HAWK_ASSERT (val != HAWK_NULL);
// not a map. v is just nil. not an error
if (HAWK_RTX_GETVALTYPE(this->run->rtx, val) != HAWK_VAL_MAP)
{
v->clear ();
return 0;
}
// get the value from the map.
hawk_val_t* fv = hawk_rtx_getmapvalfld(this->run->rtx, val, (hawk_ooch_t*)idx.ptr, idx.len);
// the key is not found. it is not an error. v is just nil
if (fv == HAWK_NULL)
{
v->clear ();
return 0;
}
// if v.set fails, it should return an error
return v->setVal (this->run, fv);
}
Hawk::Value::IndexIterator Hawk::Value::getFirstIndex (Index* idx) const
{
HAWK_ASSERT (this->val != HAWK_NULL);
if (HAWK_RTX_GETVALTYPE(this->run->rtx, this->val) != HAWK_VAL_MAP) return IndexIterator::END;
HAWK_ASSERT (this->run != HAWK_NULL);
Hawk::Value::IndexIterator itr;
hawk_val_map_itr_t* iptr;
iptr = hawk_rtx_getfirstmapvalitr(this->run->rtx, this->val, &itr);
if (iptr == HAWK_NULL) return IndexIterator::END; // no more key
idx->set (HAWK_VAL_MAP_ITR_KEY(iptr));
return itr;
}
Hawk::Value::IndexIterator Hawk::Value::getNextIndex (Index* idx, const IndexIterator& curitr) const
{
HAWK_ASSERT (val != HAWK_NULL);
if (HAWK_RTX_GETVALTYPE(this->run->rtx, val) != HAWK_VAL_MAP) return IndexIterator::END;
HAWK_ASSERT (this->run != HAWK_NULL);
Hawk::Value::IndexIterator itr(curitr);
hawk_val_map_itr_t* iptr;
iptr = hawk_rtx_getnextmapvalitr(this->run->rtx, this->val, &itr);
if (iptr == HAWK_NULL) return IndexIterator::END; // no more key
idx->set (HAWK_VAL_MAP_ITR_KEY(iptr));
return itr;
}
//////////////////////////////////////////////////////////////////
// Hawk::Run
//////////////////////////////////////////////////////////////////
Hawk::Run::Run (Hawk* hawk): hawk(hawk), rtx (HAWK_NULL)
{
}
Hawk::Run::Run (Hawk* hawk, hawk_rtx_t* rtx): hawk(hawk), rtx (rtx)
{
HAWK_ASSERT (this->rtx != HAWK_NULL);
}
Hawk::Run::~Run ()
{
}
void Hawk::Run::halt () const
{
HAWK_ASSERT (this->rtx != HAWK_NULL);
hawk_rtx_halt (this->rtx);
}
bool Hawk::Run::isHalt () const
{
HAWK_ASSERT (this->rtx != HAWK_NULL);
return !!hawk_rtx_ishalt(this->rtx);
}
hawk_errnum_t Hawk::Run::getErrorNumber () const
{
HAWK_ASSERT (this->rtx != HAWK_NULL);
return hawk_rtx_geterrnum(this->rtx);
}
hawk_loc_t Hawk::Run::getErrorLocation () const
{
HAWK_ASSERT (this->rtx != HAWK_NULL);
return *hawk_rtx_geterrloc(this->rtx);
}
const hawk_ooch_t* Hawk::Run::getErrorMessage () const
{
HAWK_ASSERT (this->rtx != HAWK_NULL);
return hawk_rtx_geterrmsg(this->rtx);
}
const hawk_uch_t* Hawk::Run::getErrorMessageU () const
{
HAWK_ASSERT (this->rtx != HAWK_NULL);
return hawk_rtx_geterrumsg(this->rtx);
}
const hawk_bch_t* Hawk::Run::getErrorMessageB () const
{
HAWK_ASSERT (this->rtx != HAWK_NULL);
return hawk_rtx_geterrbmsg(this->rtx);
}
void Hawk::Run::setError (hawk_errnum_t code, const hawk_loc_t* loc)
{
HAWK_ASSERT (this->rtx != HAWK_NULL);
hawk_rtx_seterrnum (this->rtx, loc, code);
}
void Hawk::Run::formatError (hawk_errnum_t code, const hawk_loc_t* loc, const hawk_bch_t* fmt, ...)
{
HAWK_ASSERT (this->rtx != HAWK_NULL);
va_list ap;
va_start (ap, fmt);
hawk_rtx_seterrbvfmt (this->rtx, loc, code, fmt, ap);
va_end (ap);
}
void Hawk::Run::formatError (hawk_errnum_t code, const hawk_loc_t* loc, const hawk_uch_t* fmt, ...)
{
HAWK_ASSERT (this->rtx != HAWK_NULL);
va_list ap;
va_start (ap, fmt);
hawk_rtx_seterruvfmt (this->rtx, loc, code, fmt, ap);
va_end (ap);
}
int Hawk::Run::setGlobal (int id, hawk_int_t v)
{
HAWK_ASSERT (this->rtx != HAWK_NULL);
hawk_val_t* tmp = hawk_rtx_makeintval(this->rtx, v);
if (HAWK_UNLIKELY(!tmp)) return -1;
hawk_rtx_refupval (this->rtx, tmp);
int n = hawk_rtx_setgbl(this->rtx, id, tmp);
hawk_rtx_refdownval (this->rtx, tmp);
return n;
}
int Hawk::Run::setGlobal (int id, hawk_flt_t v)
{
HAWK_ASSERT (this->rtx != HAWK_NULL);
hawk_val_t* tmp = hawk_rtx_makefltval (this->rtx, v);
if (HAWK_UNLIKELY(!tmp)) return -1;
hawk_rtx_refupval (this->rtx, tmp);
int n = hawk_rtx_setgbl(this->rtx, id, tmp);
hawk_rtx_refdownval (this->rtx, tmp);
return n;
}
int Hawk::Run::setGlobal (int id, const hawk_uch_t* ptr, hawk_oow_t len, bool mbs)
{
HAWK_ASSERT (this->rtx != HAWK_NULL);
hawk_val_t* tmp = mbs? hawk_rtx_makembsvalwithuchars(this->rtx, ptr, len):
hawk_rtx_makestrvalwithuchars(this->rtx, ptr, len);
if (HAWK_UNLIKELY(!tmp)) return -1;
hawk_rtx_refupval (this->rtx, tmp);
int n = hawk_rtx_setgbl(this->rtx, id, tmp);
hawk_rtx_refdownval (this->rtx, tmp);
return n;
}
int Hawk::Run::setGlobal (int id, const hawk_bch_t* ptr, hawk_oow_t len, bool mbs)
{
HAWK_ASSERT (this->rtx != HAWK_NULL);
hawk_val_t* tmp = mbs? hawk_rtx_makembsvalwithbchars(this->rtx, ptr, len):
hawk_rtx_makestrvalwithbchars(this->rtx, ptr, len);
if (HAWK_UNLIKELY(!tmp)) return -1;
hawk_rtx_refupval (this->rtx, tmp);
int n = hawk_rtx_setgbl(this->rtx, id, tmp);
hawk_rtx_refdownval (this->rtx, tmp);
return n;
}
int Hawk::Run::setGlobal (int id, const hawk_uch_t* ptr, bool mbs)
{
HAWK_ASSERT (this->rtx != HAWK_NULL);
hawk_val_t* tmp = mbs? hawk_rtx_makembsvalwithucstr(this->rtx, ptr):
hawk_rtx_makestrvalwithucstr(this->rtx, ptr);
if (HAWK_UNLIKELY(!tmp)) return -1;
hawk_rtx_refupval (this->rtx, tmp);
int n = hawk_rtx_setgbl(this->rtx, id, tmp);
hawk_rtx_refdownval (this->rtx, tmp);
return n;
}
int Hawk::Run::setGlobal (int id, const hawk_bch_t* ptr, bool mbs)
{
HAWK_ASSERT (this->rtx != HAWK_NULL);
hawk_val_t* tmp = mbs? hawk_rtx_makembsvalwithbcstr(this->rtx, ptr):
hawk_rtx_makestrvalwithbcstr(this->rtx, ptr);
if (HAWK_UNLIKELY(!tmp)) return -1;
hawk_rtx_refupval (this->rtx, tmp);
int n = hawk_rtx_setgbl(this->rtx, id, tmp);
hawk_rtx_refdownval (this->rtx, tmp);
return n;
}
int Hawk::Run::setGlobal (int id, const Value& gbl)
{
HAWK_ASSERT (this->rtx != HAWK_NULL);
return hawk_rtx_setgbl(this->rtx, id, (hawk_val_t*)gbl);
}
int Hawk::Run::getGlobal (int id, Value& g) const
{
HAWK_ASSERT (this->rtx != HAWK_NULL);
return g.setVal ((Run*)this, hawk_rtx_getgbl (this->rtx, id));
}
//////////////////////////////////////////////////////////////////
// Hawk
//////////////////////////////////////////////////////////////////
Hawk::Hawk (Mmgr* mmgr):
Mmged(mmgr), hawk(HAWK_NULL),
#if defined(HAWK_USE_HTB_FOR_FUNCTION_MAP)
functionMap(HAWK_NULL),
#else
functionMap(this),
#endif
source_reader(HAWK_NULL), source_writer(HAWK_NULL),
pipe_handler(HAWK_NULL), file_handler(HAWK_NULL),
console_handler(HAWK_NULL), runctx(this)
{
HAWK_MEMSET (&errinf, 0, HAWK_SIZEOF(errinf));
errinf.num = HAWK_ENOERR;
this->_cmgr = hawk_get_cmgr_by_id(HAWK_CMGR_UTF8);
}
const hawk_ooch_t* Hawk::getErrorString (hawk_errnum_t num) const
{
HAWK_ASSERT (this->hawk != HAWK_NULL);
HAWK_ASSERT (this->dflerrstr != HAWK_NULL);
return this->dflerrstr(num);
}
const hawk_ooch_t* Hawk::xerrstr (hawk_t* a, hawk_errnum_t num)
{
Hawk* hawk = *(Hawk**)GET_XTN(a);
return hawk->getErrorString(num);
}
hawk_errnum_t Hawk::getErrorNumber () const
{
return this->errinf.num;
}
hawk_loc_t Hawk::getErrorLocation () const
{
return this->errinf.loc;
}
const hawk_ooch_t* Hawk::getErrorLocationFile () const
{
return this->errinf.loc.file;
}
const hawk_uch_t* Hawk::getErrorLocationFileU () const
{
#if defined(HAWK_OOCH_IS_UCH)
return this->errinf.loc.file;
#else
if (!this->errinf.loc.file) return HAWK_NULL;
hawk_oow_t wcslen, mbslen;
wcslen = HAWK_COUNTOF(this->xerrlocfile);
hawk_conv_bcstr_to_ucstr_with_cmgr (this->errinf.loc.file, &mbslen, this->xerrlocfile, &wcslen, this->getCmgr(), 1);
return this->xerrlocfile;
#endif
}
const hawk_bch_t* Hawk::getErrorLocationFileB () const
{
#if defined(HAWK_OOCH_IS_UCH)
if (!this->errinf.loc.file) return HAWK_NULL;
hawk_oow_t wcslen, mbslen;
mbslen = HAWK_COUNTOF(this->xerrlocfile);
hawk_conv_ucstr_to_bcstr_with_cmgr (this->errinf.loc.file, &wcslen, this->xerrlocfile, &mbslen, this->getCmgr());
return this->xerrlocfile;
#else
return this->errinf.loc.file;
#endif
}
const hawk_ooch_t* Hawk::getErrorMessage () const
{
return this->errinf.msg;
}
const hawk_uch_t* Hawk::getErrorMessageU () const
{
#if defined(HAWK_OOCH_IS_UCH)
return this->errinf.msg;
#else
hawk_oow_t wcslen, mbslen;
wcslen = HAWK_COUNTOF(this->xerrmsg);
hawk_conv_bcstr_to_ucstr_with_cmgr (this->errinf.msg, &mbslen, this->xerrmsg, &wcslen, this->getCmgr(), 1);
return this->xerrmsg;
#endif
}
const hawk_bch_t* Hawk::getErrorMessageB () const
{
#if defined(HAWK_OOCH_IS_UCH)
hawk_oow_t wcslen, mbslen;
mbslen = HAWK_COUNTOF(this->xerrmsg);
hawk_conv_ucstr_to_bcstr_with_cmgr (this->errinf.msg, &wcslen, this->xerrmsg, &mbslen, this->getCmgr());
return this->xerrmsg;
#else
return this->errinf.msg;
#endif
}
void Hawk::setError (hawk_errnum_t code, const hawk_loc_t* loc)
{
if (this->hawk)
{
hawk_seterrnum (this->hawk, loc, code);
this->retrieveError ();
}
else
{
HAWK_MEMSET (&this->errinf, 0, HAWK_SIZEOF(this->errinf));
this->errinf.num = code;
if (loc != HAWK_NULL) this->errinf.loc = *loc;
hawk_copy_oocstr (this->errinf.msg, HAWK_COUNTOF(this->errinf.msg), hawk_dfl_errstr(code));
}
}
void Hawk::formatError (hawk_errnum_t code, const hawk_loc_t* loc, const hawk_bch_t* fmt, ...)
{
if (this->hawk)
{
va_list ap;
va_start (ap, fmt);
hawk_seterrbvfmt (this->hawk, loc, code, fmt, ap);
va_end (ap);
this->retrieveError ();
}
else
{
HAWK_MEMSET (&this->errinf, 0, HAWK_SIZEOF(this->errinf));
this->errinf.num = code;
if (loc != HAWK_NULL) this->errinf.loc = *loc;
hawk_copy_oocstr (this->errinf.msg, HAWK_COUNTOF(this->errinf.msg), hawk_dfl_errstr(code));
}
}
void Hawk::formatError (hawk_errnum_t code, const hawk_loc_t* loc, const hawk_uch_t* fmt, ...)
{
if (this->hawk)
{
va_list ap;
va_start (ap, fmt);
hawk_seterruvfmt (this->hawk, loc, code, fmt, ap);
va_end (ap);
this->retrieveError ();
}
else
{
HAWK_MEMSET (&this->errinf, 0, HAWK_SIZEOF(this->errinf));
this->errinf.num = code;
if (loc != HAWK_NULL) this->errinf.loc = *loc;
hawk_copy_oocstr (this->errinf.msg, HAWK_COUNTOF(this->errinf.msg), HAWK_T("not ready to set an error message"));
}
}
void Hawk::clearError ()
{
HAWK_MEMSET (&errinf, 0, HAWK_SIZEOF(errinf));
errinf.num = HAWK_ENOERR;
}
void Hawk::retrieveError ()
{
if (this->hawk == HAWK_NULL)
{
this->clearError ();
}
else
{
hawk_geterrinf (this->hawk, &errinf);
}
}
void Hawk::retrieveError (Run* run)
{
HAWK_ASSERT (run != HAWK_NULL);
if (run->rtx == HAWK_NULL) return;
hawk_rtx_geterrinf (run->rtx, &errinf);
}
static void fini_xtn (hawk_t* hawk, void* ctx)
{
xtn_t* xtn = GET_XTN(hawk);
xtn->hawk->uponClosing ();
}
static void clear_xtn (hawk_t* hawk, void* ctx)
{
xtn_t* xtn = GET_XTN(hawk);
xtn->hawk->uponClearing ();
}
int Hawk::open ()
{
HAWK_ASSERT (this->hawk == HAWK_NULL);
#if defined(HAWK_USE_HTB_FOR_FUNCTION_MAP)
HAWK_ASSERT (this->functionMap == HAWK_NULL);
#endif
hawk_prm_t prm;
HAWK_MEMSET (&prm, 0, HAWK_SIZEOF(prm));
prm.math.pow = &Hawk::pow;
prm.math.mod = &Hawk::mod;
prm.modopen = &Hawk::modopen;
prm.modclose = &Hawk::modclose;
prm.modgetsym = &Hawk::modgetsym;
hawk_errnum_t errnum;
this->hawk = hawk_open(this->getMmgr(), HAWK_SIZEOF(xtn_t), this->getCmgr(), &prm, &errnum);
if (!this->hawk)
{
this->setError (errnum);
return -1;
}
this->hawk->_instsize += HAWK_SIZEOF(xtn_t);
// associate this Hawk object with the underlying hawk object
xtn_t* xtn = (xtn_t*)GET_XTN(this->hawk);
xtn->hawk = this;
xtn->ecb.close = fini_xtn;
xtn->ecb.clear = clear_xtn;
this->dflerrstr = hawk_geterrstr(this->hawk);
// TODO: revive this too when hawk_seterrstr is revived()
// hawk_seterrstr (this->hawk, Hawk::xerrstr);
#if defined(HAWK_USE_HTB_FOR_FUNCTION_MAP)
this->functionMap = hawk_htb_open(
hawk_getgem(this->hawk), HAWK_SIZEOF(this), 512, 70,
HAWK_SIZEOF(hawk_ooch_t), 1
);
if (this->functionMap == HAWK_NULL)
{
hawk_close (this->hawk);
this->hawk = HAWK_NULL;
this->setError (HAWK_ENOMEM);
return -1;
}
*(Hawk**)hawk_htb_getxtn(this->functionMap) = this;
static hawk_htb_style_t style =
{
{
HAWK_HTB_COPIER_DEFAULT, // keep the key pointer only
HAWK_HTB_COPIER_INLINE // copy the value into the pair
},
{
HAWK_HTB_FREEER_DEFAULT, // free nothing
HAWK_HTB_FREEER_DEFAULT // free nothing
},
HAWK_HTB_COMPER_DEFAULT,
HAWK_HTB_KEEPER_DEFAULT,
HAWK_HTB_SIZER_DEFAULT,
HAWK_HTB_HASHER_DEFAULT
};
hawk_htb_setstyle (this->functionMap, &style);
#endif
// push the call back after everything else is ok.
hawk_pushecb (this->hawk, &xtn->ecb);
return 0;
}
void Hawk::close ()
{
this->fini_runctx ();
this->clearArguments ();
#if defined(HAWK_USE_HTB_FOR_FUNCTION_MAP)
if (this->functionMap)
{
hawk_htb_close (this->functionMap);
this->functionMap = HAWK_NULL;
}
#else
this->functionMap.clear ();
#endif
if (this->hawk)
{
hawk_close (this->hawk);
this->hawk = HAWK_NULL;
}
this->clearError ();
}
hawk_cmgr_t* Hawk::getCmgr () const
{
return this->hawk? hawk_getcmgr(this->hawk): this->_cmgr;
}
void Hawk::setCmgr (hawk_cmgr_t* cmgr)
{
if (this->hawk) hawk_setcmgr(this->hawk, cmgr);
this->_cmgr = cmgr;
}
void Hawk::uponClosing ()
{
// nothing to do
}
void Hawk::uponClearing ()
{
// nothing to do
}
Hawk::Run* Hawk::parse (Source& in, Source& out)
{
HAWK_ASSERT (this->hawk != HAWK_NULL);
if (&in == &Source::NONE)
{
this->setError (HAWK_EINVAL);
return HAWK_NULL;
}
this->fini_runctx ();
source_reader = &in;
source_writer = (&out == &Source::NONE)? HAWK_NULL: &out;
hawk_sio_cbs_t sio;
sio.in = Hawk::readSource;
sio.out = (source_writer == HAWK_NULL)? HAWK_NULL: Hawk::writeSource;
int n = hawk_parse(this->hawk, &sio);
if (n <= -1)
{
this->retrieveError ();
return HAWK_NULL;
}
if (this->init_runctx() <= -1) return HAWK_NULL;
return &this->runctx;
}
Hawk::Run* Hawk::resetRunContext ()
{
if (this->runctx.rtx)
{
this->fini_runctx ();
if (this->init_runctx() <= -1) return HAWK_NULL;
return &this->runctx;
}
else return HAWK_NULL;
}
int Hawk::loop (Value* ret)
{
HAWK_ASSERT (this->hawk != HAWK_NULL);
HAWK_ASSERT (this->runctx.rtx != HAWK_NULL);
hawk_val_t* rv = hawk_rtx_loop (this->runctx.rtx);
if (rv == HAWK_NULL)
{
this->retrieveError (&this->runctx);
return -1;
}
ret->setVal (&this->runctx, rv);
hawk_rtx_refdownval (this->runctx.rtx, rv);
return 0;
}
int Hawk::call (const hawk_bch_t* name, Value* ret, const Value* args, hawk_oow_t nargs)
{
HAWK_ASSERT (this->hawk != HAWK_NULL);
HAWK_ASSERT (this->runctx.rtx != HAWK_NULL);
hawk_val_t* buf[16];
hawk_val_t** ptr = HAWK_NULL;
if (args != HAWK_NULL)
{
if (nargs <= HAWK_COUNTOF(buf)) ptr = buf;
else
{
ptr = (hawk_val_t**)hawk_allocmem(this->hawk, HAWK_SIZEOF(hawk_val_t*) * nargs);
if (ptr == HAWK_NULL)
{
this->runctx.setError (HAWK_ENOMEM);
this->retrieveError (&this->runctx);
return -1;
}
}
for (hawk_oow_t i = 0; i < nargs; i++) ptr[i] = (hawk_val_t*)args[i];
}
hawk_val_t* rv = hawk_rtx_callwithbcstr(this->runctx.rtx, name, ptr, nargs);
if (ptr != HAWK_NULL && ptr != buf) hawk_freemem (this->hawk, ptr);
if (rv == HAWK_NULL)
{
this->retrieveError (&this->runctx);
return -1;
}
ret->setVal (&this->runctx, rv);
hawk_rtx_refdownval (this->runctx.rtx, rv);
return 0;
}
int Hawk::call (const hawk_uch_t* name, Value* ret, const Value* args, hawk_oow_t nargs)
{
HAWK_ASSERT (this->hawk != HAWK_NULL);
HAWK_ASSERT (this->runctx.rtx != HAWK_NULL);
hawk_val_t* buf[16];
hawk_val_t** ptr = HAWK_NULL;
if (args != HAWK_NULL)
{
if (nargs <= HAWK_COUNTOF(buf)) ptr = buf;
else
{
ptr = (hawk_val_t**)hawk_allocmem(this->hawk, HAWK_SIZEOF(hawk_val_t*) * nargs);
if (ptr == HAWK_NULL)
{
this->runctx.setError (HAWK_ENOMEM);
this->retrieveError (&this->runctx);
return -1;
}
}
for (hawk_oow_t i = 0; i < nargs; i++) ptr[i] = (hawk_val_t*)args[i];
}
hawk_val_t* rv = hawk_rtx_callwithucstr(this->runctx.rtx, name, ptr, nargs);
if (ptr != HAWK_NULL && ptr != buf) hawk_freemem (this->hawk, ptr);
if (rv == HAWK_NULL)
{
this->retrieveError (&this->runctx);
return -1;
}
ret->setVal (&this->runctx, rv);
hawk_rtx_refdownval (this->runctx.rtx, rv);
return 0;
}
int Hawk::exec (Value* ret, const Value* args, hawk_oow_t nargs)
{
int n = (this->runctx.rtx->hawk->parse.pragma.entry[0] != '\0')?
this->call(this->runctx.rtx->hawk->parse.pragma.entry, ret, args, nargs): this->loop(ret);
#if defined(HAWK_ENABLE_GC)
/* i assume this function is a usual hawk program starter.
* call garbage collection after a whole program finishes */
hawk_rtx_gc (this->runctx.rtx, HAWK_RTX_GC_GEN_FULL);
#endif
return n;
}
void Hawk::halt ()
{
HAWK_ASSERT (this->hawk != HAWK_NULL);
hawk_haltall (this->hawk);
}
int Hawk::init_runctx ()
{
if (this->runctx.rtx) return 0;
hawk_rio_cbs_t rio;
rio.pipe = pipeHandler;
rio.file = fileHandler;
rio.console = consoleHandler;
hawk_rtx_t* rtx = hawk_rtx_open(this->hawk, HAWK_SIZEOF(rxtn_t), &rio);
if (HAWK_UNLIKELY(!rtx))
{
this->retrieveError();
return -1;
}
rtx->_instsize += HAWK_SIZEOF(rxtn_t);
this->runctx.rtx = rtx;
rxtn_t* rxtn = GET_RXTN(rtx);
rxtn->run = &this->runctx;
return 0;
}
void Hawk::fini_runctx ()
{
if (this->runctx.rtx)
{
hawk_rtx_close (this->runctx.rtx);
this->runctx.rtx = HAWK_NULL;
}
}
int Hawk::getTrait () const
{
HAWK_ASSERT (this->hawk != HAWK_NULL);
int val;
hawk_getopt (this->hawk, HAWK_OPT_TRAIT, &val);
return val;
}
void Hawk::setTrait (int trait)
{
HAWK_ASSERT (this->hawk != HAWK_NULL);
hawk_setopt (this->hawk, HAWK_OPT_TRAIT, &trait);
}
hawk_oow_t Hawk::getMaxDepth (depth_t id) const
{
HAWK_ASSERT (this->hawk != HAWK_NULL);
hawk_oow_t depth;
hawk_getopt (this->hawk, (hawk_opt_t)id, &depth);
return depth;
}
void Hawk::setMaxDepth (depth_t id, hawk_oow_t depth)
{
HAWK_ASSERT (this->hawk != HAWK_NULL);
hawk_setopt (this->hawk, (hawk_opt_t)id, &depth);
}
int Hawk::setIncludeDirs (const hawk_uch_t* dirs)
{
#if defined(HAWK_OOCH_IS_UCH)
return hawk_setopt(this->hawk, HAWK_OPT_INCLUDEDIRS, dirs);
#else
hawk_ooch_t* tmp;
tmp = hawk_duputobcstr(hawk, dirs, HAWK_NULL);
if (HAWK_UNLIKELY(!tmp)) return -1;
int n = hawk_setopt(hawk, HAWK_OPT_INCLUDEDIRS, tmp);
hawk_freemem (hawk, tmp);
return n;
#endif
}
int Hawk::setIncludeDirs (const hawk_bch_t* dirs)
{
#if defined(HAWK_OOCH_IS_UCH)
hawk_ooch_t* tmp;
tmp = hawk_dupbtoucstr(hawk, dirs, HAWK_NULL, 1);
if (HAWK_UNLIKELY(!tmp)) return -1;
int n = hawk_setopt(hawk, HAWK_OPT_INCLUDEDIRS, tmp);
hawk_freemem (hawk, tmp);
return n;
#else
return hawk_setopt(this->hawk, HAWK_OPT_INCLUDEDIRS, dirs);
#endif
}
int Hawk::dispatch_function (Run* run, const hawk_fnc_info_t* fi)
{
bool has_ref_arg = false;
#if defined(HAWK_USE_HTB_FOR_FUNCTION_MAP)
hawk_htb_pair_t* pair;
pair = hawk_htb_search(this->functionMap, fi->name.ptr, fi->name.len);
if (pair == HAWK_NULL)
{
run->formatError (HAWK_EFUNNF, HAWK_NULL, HAWK_T("function '%.*js' not defined"), &fi->name.len, &fi->name.ptr);
return -1;
}
FunctionHandler handler;
handler = *(FunctionHandler*)HAWK_HTB_VPTR(pair);
#else
FunctionMap::Pair* pair = this->functionMap.search(Cstr(fi->name.ptr, fi->name.len));
if (pair == HAWK_NULL)
{
run->formatError (HAWK_EFUNNF, HAWK_NULL, HAWK_T("function '%.*js' not defined"), &fi->name.len, &fi->name.ptr);
return -1;
}
FunctionHandler handler;
handler = pair->value;
#endif
hawk_oow_t i, nargs = hawk_rtx_getnargs(run->rtx);
Value buf[16];
Value* args;
if (nargs <= HAWK_COUNTOF(buf)) args = buf;
else
{
#if defined(AWK_VALUE_USE_IN_CLASS_PLACEMENT_NEW)
args = new(run) Value[nargs];
if (args == HAWK_NULL)
{
run->setError (HAWK_ENOMEM);
return -1;
}
#else
try
{
//args = (Value*)::operator new (HAWK_SIZEOF(Value) * nargs, this->getMmgr());
args = (Value*)this->getMmgr()->allocate(HAWK_SIZEOF(Value) * nargs);
}
catch (...) { args = HAWK_NULL; }
if (args == HAWK_NULL)
{
run->setError (HAWK_ENOMEM);
return -1;
}
for (i = 0; i < nargs; i++)
{
// call the default constructor on the space allocated above.
// no exception handling is implemented here as i know
// that Value::Value() doesn't throw an exception
new((HAWK::Mmgr*)HAWK_NULL, (void*)&args[i]) Value ();
}
#endif
}
for (i = 0; i < nargs; i++)
{
int xx;
hawk_val_t* v = hawk_rtx_getarg (run->rtx, i);
if (HAWK_RTX_GETVALTYPE (run->rtx, v) == HAWK_VAL_REF)
{
hawk_val_ref_t* ref = (hawk_val_ref_t*)v;
switch (ref->id)
{
case hawk_val_ref_t::HAWK_VAL_REF_POS:
{
hawk_oow_t idx = (hawk_oow_t)ref->adr;
if (idx == 0)
{
xx = args[i].setStr(run, HAWK_OOECS_PTR(&run->rtx->inrec.line), HAWK_OOECS_LEN(&run->rtx->inrec.line));
}
else if (idx <= run->rtx->inrec.nflds)
{
xx = args[i].setStr (run,
run->rtx->inrec.flds[idx-1].ptr,
run->rtx->inrec.flds[idx-1].len);
}
else
{
xx = args[i].setStr (run, HAWK_T(""), (hawk_oow_t)0);
}
break;
}
case hawk_val_ref_t::HAWK_VAL_REF_GBL:
{
hawk_oow_t idx = (hawk_oow_t)ref->adr;
hawk_val_t* val = (hawk_val_t*)HAWK_RTX_STACK_GBL(run->rtx, idx);
xx = args[i].setVal (run, val);
break;
}
default:
xx = args[i].setVal (run, *(ref->adr));
break;
}
has_ref_arg = true;
}
else
{
xx = args[i].setVal (run, v);
}
if (xx <= -1)
{
run->setError (HAWK_ENOMEM);
if (args != buf) delete[] args;
return -1;
}
}
Value ret (run);
int n;
try { n = (this->*handler) (*run, ret, args, nargs, fi); }
catch (...) { n = -1; }
if (n >= 0 && has_ref_arg)
{
for (i = 0; i < nargs; i++)
{
// Do NOT change the run field from function handler
HAWK_ASSERT (args[i].run == run);
hawk_val_t* v = hawk_rtx_getarg(run->rtx, i);
if (HAWK_RTX_GETVALTYPE(run->rtx, v) == HAWK_VAL_REF)
{
if (hawk_rtx_setrefval(run->rtx, (hawk_val_ref_t*)v, args[i].toVal()) <= -1)
{
n = -1;
break;
}
}
}
}
if (args != buf)
{
#if defined(AWK_VALUE_USE_IN_CLASS_PLACEMENT_NEW)
delete[] args;
#else
for (i = nargs; i > 0; )
{
--i;
args[i].Value::~Value ();
}
//::operator delete (args, this->getMmgr());
this->getMmgr()->dispose (args);
#endif
}
if (n <= -1)
{
/* this is really the handler error. the underlying engine
* will take care of the error code. */
return -1;
}
hawk_rtx_setretval (run->rtx, ret.toVal());
return 0;
}
int Hawk::xstrs_t::add (hawk_t* hawk, const hawk_uch_t* arg, hawk_oow_t len)
{
if (this->len >= this->capa)
{
hawk_oocs_t* ptr;
hawk_oow_t capa = this->capa;
capa += 64;
ptr = (hawk_oocs_t*)hawk_reallocmem(hawk, this->ptr, HAWK_SIZEOF(hawk_oocs_t)*(capa + 1));
if (ptr == HAWK_NULL) return -1;
this->ptr = ptr;
this->capa = capa;
}
#if defined(HAWK_OOCH_IS_UCH)
this->ptr[this->len].len = len;
this->ptr[this->len].ptr = hawk_dupuchars(hawk, arg, len);
#else
this->ptr[this->len].ptr = hawk_duputobchars(hawk, arg, len, &this->ptr[this->len].len);
#endif
if (this->ptr[this->len].ptr == HAWK_NULL) return -1;
this->len++;
this->ptr[this->len].len = 0;
this->ptr[this->len].ptr = HAWK_NULL;
return 0;
}
int Hawk::xstrs_t::add (hawk_t* hawk, const hawk_bch_t* arg, hawk_oow_t len)
{
if (this->len >= this->capa)
{
hawk_oocs_t* ptr;
hawk_oow_t capa = this->capa;
capa += 64;
ptr = (hawk_oocs_t*)hawk_reallocmem(hawk, this->ptr, HAWK_SIZEOF(hawk_oocs_t)*(capa + 1));
if (ptr == HAWK_NULL) return -1;
this->ptr = ptr;
this->capa = capa;
}
#if defined(HAWK_OOCH_IS_UCH)
this->ptr[this->len].ptr = hawk_dupbtouchars(hawk, arg, len, &this->ptr[this->len].len, 0);
#else
this->ptr[this->len].len = len;
this->ptr[this->len].ptr = hawk_dupbchars(hawk, arg, len);
#endif
if (this->ptr[this->len].ptr == HAWK_NULL) return -1;
this->len++;
this->ptr[this->len].len = 0;
this->ptr[this->len].ptr = HAWK_NULL;
return 0;
}
void Hawk::xstrs_t::clear (hawk_t* hawk)
{
if (this->ptr != HAWK_NULL)
{
while (this->len > 0)
hawk_freemem (hawk, this->ptr[--this->len].ptr);
hawk_freemem (hawk, this->ptr);
this->ptr = HAWK_NULL;
this->capa = 0;
}
}
int Hawk::addArgument (const hawk_uch_t* arg, hawk_oow_t len)
{
HAWK_ASSERT (this->hawk != HAWK_NULL);
int n = this->runarg.add(this->hawk, arg, len);
if (n <= -1) this->setError (HAWK_ENOMEM);
return n;
}
int Hawk::addArgument (const hawk_uch_t* arg)
{
return this->addArgument(arg, hawk_count_ucstr(arg));
}
int Hawk::addArgument (const hawk_bch_t* arg, hawk_oow_t len)
{
HAWK_ASSERT (this->hawk != HAWK_NULL);
int n = this->runarg.add(this->hawk, arg, len);
if (n <= -1) this->setError (HAWK_ENOMEM);
return n;
}
int Hawk::addArgument (const hawk_bch_t* arg)
{
return this->addArgument(arg, hawk_count_bcstr(arg));
}
void Hawk::clearArguments ()
{
this->runarg.clear (this->hawk);
}
int Hawk::addGlobal(const hawk_bch_t* name)
{
HAWK_ASSERT (this->hawk != HAWK_NULL);
int n = hawk_addgblwithbcstr(this->hawk, name);
if (n <= -1) this->retrieveError ();
return n;
}
int Hawk::addGlobal(const hawk_uch_t* name)
{
HAWK_ASSERT (this->hawk != HAWK_NULL);
int n = hawk_addgblwithucstr(this->hawk, name);
if (n <= -1) this->retrieveError ();
return n;
}
int Hawk::deleteGlobal (const hawk_bch_t* name)
{
HAWK_ASSERT (this->hawk != HAWK_NULL);
int n = hawk_delgblwithbcstr(this->hawk, name);
if (n <= -1) this->retrieveError ();
return n;
}
int Hawk::deleteGlobal (const hawk_uch_t* name)
{
HAWK_ASSERT (this->hawk != HAWK_NULL);
int n = hawk_delgblwithucstr(this->hawk, name);
if (n <= -1) this->retrieveError ();
return n;
}
int Hawk::findGlobal (const hawk_bch_t* name, bool inc_builtins)
{
HAWK_ASSERT (this->hawk != HAWK_NULL);
int n = hawk_findgblwithbcstr(this->hawk, name, inc_builtins);
if (n <= -1) this->retrieveError ();
return n;
}
int Hawk::findGlobal (const hawk_uch_t* name, bool inc_builtins)
{
HAWK_ASSERT (this->hawk != HAWK_NULL);
int n = hawk_findgblwithucstr(this->hawk, name, inc_builtins);
if (n <= -1) this->retrieveError ();
return n;
}
int Hawk::setGlobal (int id, const Value& v)
{
HAWK_ASSERT (this->hawk != HAWK_NULL);
HAWK_ASSERT (this->runctx.rtx != HAWK_NULL);
if (v.run != &this->runctx)
{
this->setError (HAWK_EINVAL);
return -1;
}
int n = this->runctx.setGlobal(id, v);
if (n <= -1) this->retrieveError ();
return n;
}
int Hawk::getGlobal (int id, Value& v)
{
HAWK_ASSERT (this->hawk != HAWK_NULL);
HAWK_ASSERT (runctx.rtx != HAWK_NULL);
int n = runctx.getGlobal (id, v);
if (n <= -1) this->retrieveError ();
return n;
}
int Hawk::addFunction (
const hawk_bch_t* name, hawk_oow_t minArgs, hawk_oow_t maxArgs,
const hawk_bch_t* argSpec, FunctionHandler handler, int validOpts)
{
HAWK_ASSERT (this->hawk != HAWK_NULL);
hawk_fnc_mspec_t spec;
HAWK_MEMSET (&spec, 0, HAWK_SIZEOF(spec));
spec.arg.min = minArgs;
spec.arg.max = maxArgs;
spec.arg.spec = argSpec;
spec.impl = this->functionHandler;
spec.trait = validOpts;
hawk_fnc_t* fnc = hawk_addfncwithbcstr(this->hawk, name, &spec);
if (fnc == HAWK_NULL)
{
this->retrieveError ();
return -1;
}
#if defined(HAWK_USE_HTB_FOR_FUNCTION_MAP)
// handler is a pointer to a member function.
// sizeof(handler) is likely to be greater than sizeof(void*)
// copy the handler pointer into the table.
//
// the function name exists in the underlying function table.
// use the pointer to the name to maintain the hash table.
hawk_htb_pair_t* pair = hawk_htb_upsert(this->functionMap, (hawk_ooch_t*)fnc->name.ptr, fnc->name.len, &handler, HAWK_SIZEOF(handler));
if (!pair)
{
hawk_delfncwithbcstr (this->hawk, name);
this->retrieveError ();
return -1;
}
#else
FunctionMap::Pair* pair;
try { pair = this->functionMap.upsert(Cstr(fnc->name.ptr, fnc->name.len), handler); }
catch (...) { pair = HAWK_NULL; }
if (!pair)
{
hawk_delfncwithbcstr (this->hawk, name);
this->setError (HAWK_ENOMEM);
return -1;
}
#endif
return 0;
}
int Hawk::addFunction (
const hawk_uch_t* name, hawk_oow_t minArgs, hawk_oow_t maxArgs,
const hawk_uch_t* argSpec, FunctionHandler handler, int validOpts)
{
HAWK_ASSERT (this->hawk != HAWK_NULL);
hawk_fnc_wspec_t spec;
HAWK_MEMSET (&spec, 0, HAWK_SIZEOF(spec));
spec.arg.min = minArgs;
spec.arg.max = maxArgs;
spec.arg.spec = argSpec;
spec.impl = this->functionHandler;
spec.trait = validOpts;
hawk_fnc_t* fnc = hawk_addfncwithucstr(this->hawk, name, &spec);
if (fnc == HAWK_NULL)
{
this->retrieveError ();
return -1;
}
#if defined(HAWK_USE_HTB_FOR_FUNCTION_MAP)
// handler is a pointer to a member function.
// sizeof(handler) is likely to be greater than sizeof(void*)
// copy the handler pointer into the table.
//
// the function name exists in the underlying function table.
// use the pointer to the name to maintain the hash table.
hawk_htb_pair_t* pair = hawk_htb_upsert(this->functionMap, (hawk_ooch_t*)fnc->name.ptr, fnc->name.len, &handler, HAWK_SIZEOF(handler));
if (!pair)
{
hawk_delfncwithucstr (this->hawk, name);
this->retrieveError ();
return -1;
}
#else
FunctionMap::Pair* pair;
try { pair = this->functionMap.upsert(Cstr(fnc->name.ptr, fnc->name.len), handler); }
catch (...) { pair = HAWK_NULL; }
if (!pair)
{
hawk_delfncwithucstr (this->hawk, name);
this->setError (HAWK_ENOMEM);
return -1;
}
#endif
return 0;
}
int Hawk::deleteFunction (const hawk_ooch_t* name)
{
HAWK_ASSERT (this->hawk != HAWK_NULL);
int n = hawk_delfnc(this->hawk, name);
if (n == 0)
{
#if defined(HAWK_USE_HTB_FOR_FUNCTION_MAP)
hawk_htb_delete (this->functionMap, name, hawk_count_oocstr(name));
#else
this->functionMap.remove (Cstr(name));
#endif
}
else this->retrieveError ();
return n;
}
hawk_ooi_t Hawk::readSource (hawk_t* hawk, hawk_sio_cmd_t cmd, hawk_sio_arg_t* arg, hawk_ooch_t* data, hawk_oow_t count)
{
xtn_t* xtn = GET_XTN(hawk);
Source::Data sdat(xtn->hawk, Source::READ, arg);
switch (cmd)
{
case HAWK_SIO_CMD_OPEN:
return xtn->hawk->source_reader->open(sdat);
case HAWK_SIO_CMD_CLOSE:
return xtn->hawk->source_reader->close(sdat);
case HAWK_SIO_CMD_READ:
return xtn->hawk->source_reader->read(sdat, data, count);
default:
hawk_seterrnum (hawk, HAWK_NULL, HAWK_EINTERN);
return -1;
}
}
hawk_ooi_t Hawk::writeSource (hawk_t* hawk, hawk_sio_cmd_t cmd, hawk_sio_arg_t* arg, hawk_ooch_t* data, hawk_oow_t count)
{
xtn_t* xtn = GET_XTN(hawk);
Source::Data sdat (xtn->hawk, Source::WRITE, arg);
switch (cmd)
{
case HAWK_SIO_CMD_OPEN:
return xtn->hawk->source_writer->open (sdat);
case HAWK_SIO_CMD_CLOSE:
return xtn->hawk->source_writer->close (sdat);
case HAWK_SIO_CMD_WRITE:
return xtn->hawk->source_writer->write (sdat, data, count);
default:
hawk_seterrnum (hawk, HAWK_NULL, HAWK_EINTERN);
return -1;
}
}
hawk_ooi_t Hawk::pipeHandler (hawk_rtx_t* rtx, hawk_rio_cmd_t cmd, hawk_rio_arg_t* riod, void* data, hawk_oow_t count)
{
rxtn_t* rxtn = GET_RXTN(rtx);
Hawk* hawk = rxtn->run->hawk;
HAWK_ASSERT ((riod->type & 0xFF) == HAWK_RIO_PIPE);
Pipe pipe (rxtn->run, riod);
try
{
if (hawk->pipe_handler)
{
switch (cmd)
{
case HAWK_RIO_CMD_OPEN:
return hawk->pipe_handler->open(pipe);
case HAWK_RIO_CMD_CLOSE:
return hawk->pipe_handler->close(pipe);
case HAWK_RIO_CMD_READ:
return hawk->pipe_handler->read(pipe, (hawk_ooch_t*)data, count);
case HAWK_RIO_CMD_READ_BYTES:
return hawk->pipe_handler->readBytes(pipe, (hawk_bch_t*)data, count);
case HAWK_RIO_CMD_WRITE:
return hawk->pipe_handler->write(pipe, (const hawk_ooch_t*)data, count);
case HAWK_RIO_CMD_WRITE_BYTES:
return hawk->pipe_handler->writeBytes(pipe, (const hawk_bch_t*)data, count);
case HAWK_RIO_CMD_FLUSH:
return hawk->pipe_handler->flush(pipe);
default:
hawk_rtx_seterrnum (rtx, HAWK_NULL, HAWK_EINTERN);
return -1;
}
}
else
{
switch (cmd)
{
case HAWK_RIO_CMD_OPEN:
return hawk->openPipe(pipe);
case HAWK_RIO_CMD_CLOSE:
return hawk->closePipe(pipe);
case HAWK_RIO_CMD_READ:
return hawk->readPipe(pipe, (hawk_ooch_t*)data, count);
case HAWK_RIO_CMD_READ_BYTES:
return hawk->readPipeBytes(pipe, (hawk_bch_t*)data, count);
case HAWK_RIO_CMD_WRITE:
return hawk->writePipe(pipe, (const hawk_ooch_t*)data, count);
case HAWK_RIO_CMD_WRITE_BYTES:
return hawk->writePipeBytes(pipe, (const hawk_bch_t*)data, count);
case HAWK_RIO_CMD_FLUSH:
return hawk->flushPipe(pipe);
default:
hawk_rtx_seterrnum (rtx, HAWK_NULL, HAWK_EINTERN);
return -1;
}
}
}
catch (...)
{
return -1;
}
}
hawk_ooi_t Hawk::fileHandler (hawk_rtx_t* rtx, hawk_rio_cmd_t cmd, hawk_rio_arg_t* riod, void* data, hawk_oow_t count)
{
rxtn_t* rxtn = GET_RXTN(rtx);
Hawk* hawk = rxtn->run->hawk;
HAWK_ASSERT ((riod->type & 0xFF) == HAWK_RIO_FILE);
File file (rxtn->run, riod);
try
{
if (hawk->file_handler)
{
switch (cmd)
{
case HAWK_RIO_CMD_OPEN:
return hawk->file_handler->open(file);
case HAWK_RIO_CMD_CLOSE:
return hawk->file_handler->close(file);
case HAWK_RIO_CMD_READ:
return hawk->file_handler->read(file, (hawk_ooch_t*)data, count);
case HAWK_RIO_CMD_READ_BYTES:
return hawk->file_handler->readBytes(file, (hawk_bch_t*)data, count);
case HAWK_RIO_CMD_WRITE:
return hawk->file_handler->write(file, (const hawk_ooch_t*)data, count);
case HAWK_RIO_CMD_WRITE_BYTES:
return hawk->file_handler->writeBytes(file, (const hawk_bch_t*)data, count);
case HAWK_RIO_CMD_FLUSH:
return hawk->file_handler->flush(file);
default:
hawk_rtx_seterrnum (rtx, HAWK_NULL, HAWK_EINTERN);
return -1;
}
}
else
{
switch (cmd)
{
case HAWK_RIO_CMD_OPEN:
return hawk->openFile(file);
case HAWK_RIO_CMD_CLOSE:
return hawk->closeFile(file);
case HAWK_RIO_CMD_READ:
return hawk->readFile(file, (hawk_ooch_t*)data, count);
case HAWK_RIO_CMD_READ_BYTES:
return hawk->readFileBytes(file, (hawk_bch_t*)data, count);
case HAWK_RIO_CMD_WRITE:
return hawk->writeFile(file, (const hawk_ooch_t*)data, count);
case HAWK_RIO_CMD_WRITE_BYTES:
return hawk->writeFileBytes(file, (const hawk_bch_t*)data, count);
case HAWK_RIO_CMD_FLUSH:
return hawk->flushFile(file);
default:
hawk_rtx_seterrnum (rtx, HAWK_NULL, HAWK_EINTERN);
return -1;
}
}
}
catch (...)
{
return -1;
}
}
hawk_ooi_t Hawk::consoleHandler (hawk_rtx_t* rtx, hawk_rio_cmd_t cmd, hawk_rio_arg_t* riod, void* data, hawk_oow_t count)
{
rxtn_t* rxtn = GET_RXTN(rtx);
Hawk* hawk = rxtn->run->hawk;
HAWK_ASSERT ((riod->type & 0xFF) == HAWK_RIO_CONSOLE);
Console console (rxtn->run, riod);
try
{
if (hawk->console_handler)
{
switch (cmd)
{
case HAWK_RIO_CMD_OPEN:
return hawk->console_handler->open(console);
case HAWK_RIO_CMD_CLOSE:
return hawk->console_handler->close(console);
case HAWK_RIO_CMD_READ:
return hawk->console_handler->read(console, (hawk_ooch_t*)data, count);
case HAWK_RIO_CMD_READ_BYTES:
return hawk->console_handler->readBytes(console, (hawk_bch_t*)data, count);
case HAWK_RIO_CMD_WRITE:
return hawk->console_handler->write(console, (const hawk_ooch_t*)data, count);
case HAWK_RIO_CMD_WRITE_BYTES:
return hawk->console_handler->writeBytes(console, (const hawk_bch_t*)data, count);
case HAWK_RIO_CMD_FLUSH:
return hawk->console_handler->flush(console);
case HAWK_RIO_CMD_NEXT:
return hawk->console_handler->next(console);
default:
hawk_rtx_seterrnum (rtx, HAWK_NULL, HAWK_EINTERN);
return -1;
}
}
else
{
switch (cmd)
{
case HAWK_RIO_CMD_OPEN:
return hawk->openConsole(console);
case HAWK_RIO_CMD_CLOSE:
return hawk->closeConsole(console);
case HAWK_RIO_CMD_READ:
return hawk->readConsole(console, (hawk_ooch_t*)data, count);
case HAWK_RIO_CMD_READ_BYTES:
return hawk->readConsoleBytes(console, (hawk_bch_t*)data, count);
case HAWK_RIO_CMD_WRITE:
return hawk->writeConsole(console, (const hawk_ooch_t*)data, count);
case HAWK_RIO_CMD_WRITE_BYTES:
return hawk->writeConsoleBytes(console, (const hawk_bch_t*)data, count);
case HAWK_RIO_CMD_FLUSH:
return hawk->flushConsole(console);
case HAWK_RIO_CMD_NEXT:
return hawk->nextConsole(console);
default:
hawk_rtx_seterrnum (rtx, HAWK_NULL, HAWK_EINTERN);
return -1;
}
}
}
catch (...)
{
return -1;
}
}
int Hawk::openPipe (Pipe& io)
{
((Run*)io)->setError (HAWK_ENOIMPL);
return -1;
}
int Hawk::closePipe (Pipe& io)
{
((Run*)io)->setError (HAWK_ENOIMPL);
return -1;
}
hawk_ooi_t Hawk::readPipe (Pipe& io, hawk_ooch_t* buf, hawk_oow_t len)
{
((Run*)io)->setError (HAWK_ENOIMPL);
return -1;
}
hawk_ooi_t Hawk::readPipeBytes (Pipe& io, hawk_bch_t* buf, hawk_oow_t len)
{
((Run*)io)->setError (HAWK_ENOIMPL);
return -1;
}
hawk_ooi_t Hawk::writePipe (Pipe& io, const hawk_ooch_t* buf, hawk_oow_t len)
{
((Run*)io)->setError (HAWK_ENOIMPL);
return -1;
}
hawk_ooi_t Hawk::writePipeBytes (Pipe& io, const hawk_bch_t* buf, hawk_oow_t len)
{
((Run*)io)->setError (HAWK_ENOIMPL);
return -1;
}
int Hawk::flushPipe (Pipe& io)
{
((Run*)io)->setError (HAWK_ENOIMPL);
return -1;
}
int Hawk::openFile (File& io)
{
((Run*)io)->setError (HAWK_ENOIMPL);
return -1;
}
int Hawk::closeFile (File& io)
{
((Run*)io)->setError (HAWK_ENOIMPL);
return -1;
}
hawk_ooi_t Hawk::readFile (File& io, hawk_ooch_t* buf, hawk_oow_t len)
{
((Run*)io)->setError (HAWK_ENOIMPL);
return -1;
}
hawk_ooi_t Hawk::readFileBytes (File& io, hawk_bch_t* buf, hawk_oow_t len)
{
((Run*)io)->setError (HAWK_ENOIMPL);
return -1;
}
hawk_ooi_t Hawk::writeFile (File& io, const hawk_ooch_t* buf, hawk_oow_t len)
{
((Run*)io)->setError (HAWK_ENOIMPL);
return -1;
}
hawk_ooi_t Hawk::writeFileBytes (File& io, const hawk_bch_t* buf, hawk_oow_t len)
{
((Run*)io)->setError (HAWK_ENOIMPL);
return -1;
}
int Hawk::flushFile (File& io)
{
((Run*)io)->setError (HAWK_ENOIMPL);
return -1;
}
int Hawk::openConsole (Console& io)
{
((Run*)io)->setError (HAWK_ENOIMPL);
return -1;
}
int Hawk::closeConsole (Console& io)
{
((Run*)io)->setError (HAWK_ENOIMPL);
return -1;
}
hawk_ooi_t Hawk::readConsole (Console& io, hawk_ooch_t* buf, hawk_oow_t len)
{
((Run*)io)->setError (HAWK_ENOIMPL);
return -1;
}
hawk_ooi_t Hawk::readConsoleBytes (Console& io, hawk_bch_t* buf, hawk_oow_t len)
{
((Run*)io)->setError (HAWK_ENOIMPL);
return -1;
}
hawk_ooi_t Hawk::writeConsole (Console& io, const hawk_ooch_t* buf, hawk_oow_t len)
{
((Run*)io)->setError (HAWK_ENOIMPL);
return -1;
}
hawk_ooi_t Hawk::writeConsoleBytes (Console& io, const hawk_bch_t* buf, hawk_oow_t len)
{
((Run*)io)->setError (HAWK_ENOIMPL);
return -1;
}
int Hawk::flushConsole (Console& io)
{
((Run*)io)->setError (HAWK_ENOIMPL);
return -1;
}
int Hawk::nextConsole (Console& io)
{
((Run*)io)->setError (HAWK_ENOIMPL);
return -1;
}
int Hawk::functionHandler (hawk_rtx_t* rtx, const hawk_fnc_info_t* fi)
{
rxtn_t* rxtn = GET_RXTN(rtx);
return rxtn->run->hawk->dispatch_function(rxtn->run, fi);
}
hawk_flt_t Hawk::pow (hawk_t* hawk, hawk_flt_t x, hawk_flt_t y)
{
xtn_t* xtn = GET_XTN(hawk);
return xtn->hawk->pow(x, y);
}
hawk_flt_t Hawk::mod (hawk_t* hawk, hawk_flt_t x, hawk_flt_t y)
{
xtn_t* xtn = GET_XTN(hawk);
return xtn->hawk->mod(x, y);
}
void* Hawk::modopen (hawk_t* hawk, const hawk_mod_spec_t* spec)
{
xtn_t* xtn = GET_XTN(hawk);
return xtn->hawk->modopen(spec);
}
void Hawk::modclose (hawk_t* hawk, void* handle)
{
xtn_t* xtn = GET_XTN(hawk);
xtn->hawk->modclose (handle);
}
void* Hawk::modgetsym (hawk_t* hawk, void* handle, const hawk_ooch_t* name)
{
xtn_t* xtn = GET_XTN(hawk);
return xtn->hawk->modgetsym(handle, name);
}
/////////////////////////////////
HAWK_END_NAMESPACE(HAWK)
/////////////////////////////////
void* operator new (hawk_oow_t size, HAWK::Mmgr* mmgr) /*HAWK_CXX_THREXCEPT1(HAWK::Mmgr::MemoryError)*/
{
return mmgr->allocate(size);
}
#if defined(HAWK_CXX_NO_OPERATOR_DELETE_OVERLOADING)
void hawk_operator_delete (void* ptr, HAWK::Mmgr* mmgr)
#else
void operator delete (void* ptr, HAWK::Mmgr* mmgr)
#endif
{
mmgr->dispose (ptr);
}
void* operator new (hawk_oow_t size, HAWK::Mmgr* mmgr, void* existing_ptr) /*HAWK_CXX_THREXCEPT1(HAWK::Mmgr::MemoryError)*/
{
// mmgr unused. i put it in the parameter list to make this function
// less conflicting with the stock ::operator new() that doesn't allocate.
return existing_ptr;
}
#if 0
void* operator new[] (hawk_oow_t size, HAWK::Mmgr* mmgr)
{
return mmgr->allocate(size);
}
void operator delete[] (void* ptr, HAWK::Mmgr* mmgr)
{
mmgr->dispose (ptr);
}
#endif