diff --git a/eci/Lexer.cpp b/eci/Lexer.cpp new file mode 100644 index 0000000..c770134 --- /dev/null +++ b/eci/Lexer.cpp @@ -0,0 +1,38 @@ +/** + * @author Edouard DUPIN + * + * @copyright 2014, Edouard DUPIN, all right reserved + * + * @license APACHE-2 (see license file) + */ + +#include +#include + +eci::Lexer::Lexer() { + +} + +eci::Lexer::~Lexer() { + +} + +void eci::Lexer::append(int32_t _tokenId, const std::string& _regularExpression) { + m_searchList.insert(std::make_pair(_tokenId, std::regex(_regularExpression))); +} + +eci::LexerResult eci::Lexer::interprete(const std::string& _data) { + eci::LexerResult result; + for (auto &it : m_searchList) { + ECI_INFO("Parse RegEx : " << it.first);// << " : '" << it.second.str() << "'"); + std::sregex_iterator it_search(_data.begin(), _data.end(), it.second); + std::sregex_iterator it_end; + for (std::sregex_iterator i = it_search; i != it_end; ++i) { + std::smatch match = *i; + std::string match_str = match.str(); + ECI_INFO(" " << match_str); + } + } + return result; +} + diff --git a/eci/Lexer.h b/eci/Lexer.h new file mode 100644 index 0000000..54c0009 --- /dev/null +++ b/eci/Lexer.h @@ -0,0 +1,33 @@ +/** + * @author Edouard DUPIN + * + * @copyright 2014, Edouard DUPIN, all right reserved + * + * @license APACHE-2 (see license file) + */ + +#ifndef __ECI_LEXER_H__ +#define __ECI_LEXER_H__ + +#include +#include +#include +#include +#include + + +namespace eci { + using LexerResult = std::vector>; + + class Lexer { + private: + std::map m_searchList; + public: + Lexer(); + ~Lexer(); + void append(int32_t _tokenId, const std::string& _regularExpression); + LexerResult interprete(const std::string& _data); + }; +} + +#endif diff --git a/eci/clibrary.c b/eci/clibrary.c deleted file mode 100644 index 4a6aa61..0000000 --- a/eci/clibrary.c +++ /dev/null @@ -1,124 +0,0 @@ -/** - * @author Edouard DUPIN - * - * @copyright 2014, Edouard DUPIN, all right reserved - * - * @license APACHE-2 (see license file) - */ - -#include "picoc.h" -#include "interpreter.h" - -/* the picoc version string */ -static const char *VersionString = NULL; - -/* endian-ness checking */ -static const int __ENDIAN_CHECK__ = 1; - -static int BigEndian = 0; -static int LittleEndian = 0; - - -/* global initialisation for libraries */ -void LibraryInit() { - /* define the version number macro */ - VersionString = TableStrRegister(ECI_VERSION); - VariableDefinePlatformVar(NULL, "ECI_VERSION", CharPtrType, (union AnyValue *)&VersionString, FALSE); - /* define endian-ness macros */ - BigEndian = ((*(char*)&__ENDIAN_CHECK__) == 0); - LittleEndian = ((*(char*)&__ENDIAN_CHECK__) == 1); - VariableDefinePlatformVar(NULL, "BIG_ENDIAN", &IntType, (union AnyValue *)&BigEndian, FALSE); - VariableDefinePlatformVar(NULL, "LITTLE_ENDIAN", &IntType, (union AnyValue *)&LittleEndian, FALSE); -} - -/* add a library */ -void LibraryAdd(struct Table *_globalTable, const char *_libraryName, struct LibraryFunction *_funcList) { - struct ParseState Parser; - int Count; - char *Identifier; - struct ValueType *ReturnType; - struct Value *NewValue; - void *Tokens; - const char *IntrinsicName = TableStrRegister("c library"); - /* read all the library definitions */ - for (Count = 0; _funcList[Count].Prototype != NULL; Count++) { - Tokens = LexAnalyse(IntrinsicName, _funcList[Count].Prototype, strlen((char *)_funcList[Count].Prototype), NULL); - LexInitParser(&Parser, _funcList[Count].Prototype, Tokens, IntrinsicName, TRUE); - TypeParse(&Parser, &ReturnType, &Identifier, NULL); - NewValue = ParseFunctionDefinition(&Parser, ReturnType, Identifier); - NewValue->Val->FuncDef.Intrinsic = _funcList[Count].Func; - HeapFreeMem(Tokens); - } -} - -/* print a type to a stream without using printf/sprintf */ -void PrintType(struct ValueType* _type, IOFILE *_stream) { - switch (_type->Base) { - case TypeVoid: - PrintStr("void", _stream); - break; - case TypeInt: - PrintStr("int", _stream); - break; - case TypeShort: - PrintStr("short", _stream); - break; - case TypeChar: - PrintStr("char", _stream); - break; - case TypeLong: - PrintStr("long", _stream); - break; - case TypeUnsignedInt: - PrintStr("unsigned int", _stream); - break; - case TypeUnsignedShort: - PrintStr("unsigned short", _stream); - break; - case TypeUnsignedLong: - PrintStr("unsigned long", _stream); - break; - case TypeFP: - PrintStr("double", _stream); - break; - case TypeFunction: - PrintStr("function", _stream); - break; - case TypeMacro: - PrintStr("macro", _stream); - break; - case TypePointer: - if (_type->FromType) { - PrintType(_type->FromType, _stream); - } - PrintCh('*', _stream); - break; - case TypeArray: - PrintType(_type->FromType, _stream); - PrintCh('[', _stream); - if (_type->ArraySize != 0) { - PrintSimpleInt(_type->ArraySize, _stream); - } - PrintCh(']', _stream); - break; - case TypeStruct: - PrintStr("struct ", _stream); - PrintStr(_type->Identifier, _stream); - break; - case TypeUnion: - PrintStr("union ", _stream); - PrintStr(_type->Identifier, _stream); - break; - case TypeEnum: - PrintStr("enum ", _stream); - PrintStr(_type->Identifier, _stream); - break; - case TypeGotoLabel: - PrintStr("goto label ", _stream); - break; - case Type_Type: - PrintStr("type ", _stream); - break; - } -} - diff --git a/eci/clibrary.h b/eci/clibrary.h deleted file mode 100644 index c0c5fcc..0000000 --- a/eci/clibrary.h +++ /dev/null @@ -1,20 +0,0 @@ -/** - * @author Edouard DUPIN - * - * @copyright 2014, Edouard DUPIN, all right reserved - * - * @license APACHE-2 (see license file) - */ - -#ifndef __ECI_C_LIBRARY_H__ -#define __ECI_C_LIBRARY_H__ - - - -void LibraryInit(); -void LibraryAdd(struct Table* _globalTable, const char* _libraryName, struct LibraryFunction* _funcList); -void CLibraryInit(); -void PrintType(struct ValueType* _type, IOFILE* _stream); - - -#endif diff --git a/eci/cstdlib/ctype.c b/eci/cstdlib/ctype.c deleted file mode 100644 index 8a1f526..0000000 --- a/eci/cstdlib/ctype.c +++ /dev/null @@ -1,101 +0,0 @@ -/** - * @author Edouard DUPIN - * - * @copyright 2014, Edouard DUPIN, all right reserved - * - * @license APACHE-2 (see license file) - */ - -/* string.h library for large systems - small embedded systems use clibrary.c instead */ -#include -#include "../interpreter.h" - -#ifndef BUILTIN_MINI_STDLIB - -void StdIsalnum(struct ParseState *_parser, struct Value *_returnValue, struct Value **_param, int _numArgs) { - _returnValue->Val->Integer = isalnum(_param[0]->Val->Integer); -} - -void StdIsalpha(struct ParseState *_parser, struct Value *_returnValue, struct Value **_param, int _numArgs) { - _returnValue->Val->Integer = isalpha(_param[0]->Val->Integer); -} - -void StdIsblank(struct ParseState *_parser, struct Value *_returnValue, struct Value **_param, int _numArgs) { - int ch = _param[0]->Val->Integer; - _returnValue->Val->Integer = (ch == ' ') | (ch == '\t'); -} - -void StdIscntrl(struct ParseState *_parser, struct Value *_returnValue, struct Value **_param, int _numArgs) { - _returnValue->Val->Integer = iscntrl(_param[0]->Val->Integer); -} - -void StdIsdigit(struct ParseState *_parser, struct Value *_returnValue, struct Value **_param, int _numArgs) { - _returnValue->Val->Integer = isdigit(_param[0]->Val->Integer); -} - -void StdIsgraph(struct ParseState *_parser, struct Value *_returnValue, struct Value **_param, int _numArgs) { - _returnValue->Val->Integer = isgraph(_param[0]->Val->Integer); -} - -void StdIslower(struct ParseState *_parser, struct Value *_returnValue, struct Value **_param, int _numArgs) { - _returnValue->Val->Integer = islower(_param[0]->Val->Integer); -} - -void StdIsprint(struct ParseState *_parser, struct Value *_returnValue, struct Value **_param, int _numArgs) { - _returnValue->Val->Integer = isprint(_param[0]->Val->Integer); -} - -void StdIspunct(struct ParseState *_parser, struct Value *_returnValue, struct Value **_param, int _numArgs) { - _returnValue->Val->Integer = ispunct(_param[0]->Val->Integer); -} - -void StdIsspace(struct ParseState *_parser, struct Value *_returnValue, struct Value **_param, int _numArgs) { - _returnValue->Val->Integer = isspace(_param[0]->Val->Integer); -} - -void StdIsupper(struct ParseState *_parser, struct Value *_returnValue, struct Value **_param, int _numArgs) { - _returnValue->Val->Integer = isupper(_param[0]->Val->Integer); -} - -void StdIsxdigit(struct ParseState *_parser, struct Value *_returnValue, struct Value **_param, int _numArgs) { - _returnValue->Val->Integer = isxdigit(_param[0]->Val->Integer); -} - -void StdTolower(struct ParseState *_parser, struct Value *_returnValue, struct Value **_param, int _numArgs) { - _returnValue->Val->Integer = tolower(_param[0]->Val->Integer); -} - -void StdToupper(struct ParseState *_parser, struct Value *_returnValue, struct Value **_param, int _numArgs) { - _returnValue->Val->Integer = toupper(_param[0]->Val->Integer); -} - -void StdIsascii(struct ParseState *_parser, struct Value *_returnValue, struct Value **_param, int _numArgs) { - _returnValue->Val->Integer = isascii(_param[0]->Val->Integer); -} - -void StdToascii(struct ParseState *_parser, struct Value *_returnValue, struct Value **_param, int _numArgs) { - _returnValue->Val->Integer = toascii(_param[0]->Val->Integer); -} - -/* all string.h functions */ -struct LibraryFunction StdCtypeFunctions[] = { - { StdIsalnum, "int isalnum(int);" }, - { StdIsalpha, "int isalpha(int);" }, - { StdIsblank, "int isblank(int);" }, - { StdIscntrl, "int iscntrl(int);" }, - { StdIsdigit, "int isdigit(int);" }, - { StdIsgraph, "int isgraph(int);" }, - { StdIslower, "int islower(int);" }, - { StdIsprint, "int isprint(int);" }, - { StdIspunct, "int ispunct(int);" }, - { StdIsspace, "int isspace(int);" }, - { StdIsupper, "int isupper(int);" }, - { StdIsxdigit, "int isxdigit(int);" }, - { StdTolower, "int tolower(int);" }, - { StdToupper, "int toupper(int);" }, - { StdIsascii, "int isascii(int);" }, - { StdToascii, "int toascii(int);" }, - { NULL, NULL } -}; - -#endif /* !BUILTIN_MINI_STDLIB */ diff --git a/eci/cstdlib/ctype.h b/eci/cstdlib/ctype.h deleted file mode 100644 index 6ee406b..0000000 --- a/eci/cstdlib/ctype.h +++ /dev/null @@ -1,15 +0,0 @@ -/** - * @author Edouard DUPIN - * - * @copyright 2014, Edouard DUPIN, all right reserved - * - * @license APACHE-2 (see license file) - */ - -#ifndef __ECI_C_TYPE_H__ -#define __ECI_C_TYPE_H__ - - -extern struct LibraryFunction StdCtypeFunctions[]; - -#endif diff --git a/eci/cstdlib/errno.c b/eci/cstdlib/errno.c deleted file mode 100644 index 3e94b74..0000000 --- a/eci/cstdlib/errno.c +++ /dev/null @@ -1,582 +0,0 @@ -/** - * @author Edouard DUPIN - * - * @copyright 2014, Edouard DUPIN, all right reserved - * - * @license APACHE-2 (see license file) - */ - -/* string.h library for large systems - small embedded systems use clibrary.c instead */ -#include -#include "../interpreter.h" - -#ifndef BUILTIN_MINI_STDLIB - -#ifdef EACCES -static int EACCESValue = EACCES; -#endif - -#ifdef EADDRINUSE -static int EADDRINUSEValue = EADDRINUSE; -#endif - -#ifdef EADDRNOTAVAIL -static int EADDRNOTAVAILValue = EADDRNOTAVAIL; -#endif - -#ifdef EAFNOSUPPORT -static int EAFNOSUPPORTValue = EAFNOSUPPORT; -#endif - -#ifdef EAGAIN -static int EAGAINValue = EAGAIN; -#endif - -#ifdef EALREADY -static int EALREADYValue = EALREADY; -#endif - -#ifdef EBADF -static int EBADFValue = EBADF; -#endif - -#ifdef EBADMSG -static int EBADMSGValue = EBADMSG; -#endif - -#ifdef EBUSY -static int EBUSYValue = EBUSY; -#endif - -#ifdef ECANCELED -static int ECANCELEDValue = ECANCELED; -#endif - -#ifdef ECHILD -static int ECHILDValue = ECHILD; -#endif - -#ifdef ECONNABORTED -static int ECONNABORTEDValue = ECONNABORTED; -#endif - -#ifdef ECONNREFUSED -static int ECONNREFUSEDValue = ECONNREFUSED; -#endif - -#ifdef ECONNRESET -static int ECONNRESETValue = ECONNRESET; -#endif - -#ifdef EDEADLK -static int EDEADLKValue = EDEADLK; -#endif - -#ifdef EDESTADDRREQ -static int EDESTADDRREQValue = EDESTADDRREQ; -#endif - -#ifdef EDOM -static int EDOMValue = EDOM; -#endif - -#ifdef EDQUOT -static int EDQUOTValue = EDQUOT; -#endif - -#ifdef EEXIST -static int EEXISTValue = EEXIST; -#endif - -#ifdef EFAULT -static int EFAULTValue = EFAULT; -#endif - -#ifdef EFBIG -static int EFBIGValue = EFBIG; -#endif - -#ifdef EHOSTUNREACH -static int EHOSTUNREACHValue = EHOSTUNREACH; -#endif - -#ifdef EIDRM -static int EIDRMValue = EIDRM; -#endif - -#ifdef EILSEQ -static int EILSEQValue = EILSEQ; -#endif - -#ifdef EINPROGRESS -static int EINPROGRESSValue = EINPROGRESS; -#endif - -#ifdef EINTR -static int EINTRValue = EINTR; -#endif - -#ifdef EINVAL -static int EINVALValue = EINVAL; -#endif - -#ifdef EIO -static int EIOValue = EIO; -#endif - -#ifdef EISCONN -static int EISCONNValue = EISCONN; -#endif - -#ifdef EISDIR -static int EISDIRValue = EISDIR; -#endif - -#ifdef ELOOP -static int ELOOPValue = ELOOP; -#endif - -#ifdef EMFILE -static int EMFILEValue = EMFILE; -#endif - -#ifdef EMLINK -static int EMLINKValue = EMLINK; -#endif - -#ifdef EMSGSIZE -static int EMSGSIZEValue = EMSGSIZE; -#endif - -#ifdef EMULTIHOP -static int EMULTIHOPValue = EMULTIHOP; -#endif - -#ifdef ENAMETOOLONG -static int ENAMETOOLONGValue = ENAMETOOLONG; -#endif - -#ifdef ENETDOWN -static int ENETDOWNValue = ENETDOWN; -#endif - -#ifdef ENETRESET -static int ENETRESETValue = ENETRESET; -#endif - -#ifdef ENETUNREACH -static int ENETUNREACHValue = ENETUNREACH; -#endif - -#ifdef ENFILE -static int ENFILEValue = ENFILE; -#endif - -#ifdef ENOBUFS -static int ENOBUFSValue = ENOBUFS; -#endif - -#ifdef ENODATA -static int ENODATAValue = ENODATA; -#endif - -#ifdef ENODEV -static int ENODEVValue = ENODEV; -#endif - -#ifdef ENOENT -static int ENOENTValue = ENOENT; -#endif - -#ifdef ENOEXEC -static int ENOEXECValue = ENOEXEC; -#endif - -#ifdef ENOLCK -static int ENOLCKValue = ENOLCK; -#endif - -#ifdef ENOLINK -static int ENOLINKValue = ENOLINK; -#endif - -#ifdef ENOMEM -static int ENOMEMValue = ENOMEM; -#endif - -#ifdef ENOMSG -static int ENOMSGValue = ENOMSG; -#endif - -#ifdef ENOPROTOOPT -static int ENOPROTOOPTValue = ENOPROTOOPT; -#endif - -#ifdef ENOSPC -static int ENOSPCValue = ENOSPC; -#endif - -#ifdef ENOSR -static int ENOSRValue = ENOSR; -#endif - -#ifdef ENOSTR -static int ENOSTRValue = ENOSTR; -#endif - -#ifdef ENOSYS -static int ENOSYSValue = ENOSYS; -#endif - -#ifdef ENOTCONN -static int ENOTCONNValue = ENOTCONN; -#endif - -#ifdef ENOTDIR -static int ENOTDIRValue = ENOTDIR; -#endif - -#ifdef ENOTEMPTY -static int ENOTEMPTYValue = ENOTEMPTY; -#endif - -#ifdef ENOTRECOVERABLE -static int ENOTRECOVERABLEValue = ENOTRECOVERABLE; -#endif - -#ifdef ENOTSOCK -static int ENOTSOCKValue = ENOTSOCK; -#endif - -#ifdef ENOTSUP -static int ENOTSUPValue = ENOTSUP; -#endif - -#ifdef ENOTTY -static int ENOTTYValue = ENOTTY; -#endif - -#ifdef ENXIO -static int ENXIOValue = ENXIO; -#endif - -#ifdef EOPNOTSUPP -static int EOPNOTSUPPValue = EOPNOTSUPP; -#endif - -#ifdef EOVERFLOW -static int EOVERFLOWValue = EOVERFLOW; -#endif - -#ifdef EOWNERDEAD -static int EOWNERDEADValue = EOWNERDEAD; -#endif - -#ifdef EPERM -static int EPERMValue = EPERM; -#endif - -#ifdef EPIPE -static int EPIPEValue = EPIPE; -#endif - -#ifdef EPROTO -static int EPROTOValue = EPROTO; -#endif - -#ifdef EPROTONOSUPPORT -static int EPROTONOSUPPORTValue = EPROTONOSUPPORT; -#endif - -#ifdef EPROTOTYPE -static int EPROTOTYPEValue = EPROTOTYPE; -#endif - -#ifdef ERANGE -static int ERANGEValue = ERANGE; -#endif - -#ifdef EROFS -static int EROFSValue = EROFS; -#endif - -#ifdef ESPIPE -static int ESPIPEValue = ESPIPE; -#endif - -#ifdef ESRCH -static int ESRCHValue = ESRCH; -#endif - -#ifdef ESTALE -static int ESTALEValue = ESTALE; -#endif - -#ifdef ETIME -static int ETIMEValue = ETIME; -#endif - -#ifdef ETIMEDOUT -static int ETIMEDOUTValue = ETIMEDOUT; -#endif - -#ifdef ETXTBSY -static int ETXTBSYValue = ETXTBSY; -#endif - -#ifdef EWOULDBLOCK -static int EWOULDBLOCKValue = EWOULDBLOCK; -#endif - -#ifdef EXDEV -static int EXDEVValue = EXDEV; -#endif - - -/* creates various system-dependent definitions */ -void StdErrnoSetupFunc(void) { - /* defines */ - #ifdef EACCES - VariableDefinePlatformVar(NULL, "EACCES", &IntType, (union AnyValue *)&EACCESValue, FALSE); - #endif - #ifdef EADDRINUSE - VariableDefinePlatformVar(NULL, "EADDRINUSE", &IntType, (union AnyValue *)&EADDRINUSEValue, FALSE); - #endif - #ifdef EADDRNOTAVAIL - VariableDefinePlatformVar(NULL, "EADDRNOTAVAIL", &IntType, (union AnyValue *)&EADDRNOTAVAILValue, FALSE); - #endif - #ifdef EAFNOSUPPORT - VariableDefinePlatformVar(NULL, "EAFNOSUPPORT", &IntType, (union AnyValue *)&EAFNOSUPPORTValue, FALSE); - #endif - #ifdef EAGAIN - VariableDefinePlatformVar(NULL, "EAGAIN", &IntType, (union AnyValue *)&EAGAINValue, FALSE); - #endif - #ifdef EALREADY - VariableDefinePlatformVar(NULL, "EALREADY", &IntType, (union AnyValue *)&EALREADYValue, FALSE); - #endif - #ifdef EBADF - VariableDefinePlatformVar(NULL, "EBADF", &IntType, (union AnyValue *)&EBADFValue, FALSE); - #endif - #ifdef EBADMSG - VariableDefinePlatformVar(NULL, "EBADMSG", &IntType, (union AnyValue *)&EBADMSGValue, FALSE); - #endif - #ifdef EBUSY - VariableDefinePlatformVar(NULL, "EBUSY", &IntType, (union AnyValue *)&EBUSYValue, FALSE); - #endif - #ifdef ECANCELED - VariableDefinePlatformVar(NULL, "ECANCELED", &IntType, (union AnyValue *)&ECANCELEDValue, FALSE); - #endif - #ifdef ECHILD - VariableDefinePlatformVar(NULL, "ECHILD", &IntType, (union AnyValue *)&ECHILDValue, FALSE); - #endif - #ifdef ECONNABORTED - VariableDefinePlatformVar(NULL, "ECONNABORTED", &IntType, (union AnyValue *)&ECONNABORTEDValue, FALSE); - #endif - #ifdef ECONNREFUSED - VariableDefinePlatformVar(NULL, "ECONNREFUSED", &IntType, (union AnyValue *)&ECONNREFUSEDValue, FALSE); - #endif - #ifdef ECONNRESET - VariableDefinePlatformVar(NULL, "ECONNRESET", &IntType, (union AnyValue *)&ECONNRESETValue, FALSE); - #endif - #ifdef EDEADLK - VariableDefinePlatformVar(NULL, "EDEADLK", &IntType, (union AnyValue *)&EDEADLKValue, FALSE); - #endif - #ifdef EDESTADDRREQ - VariableDefinePlatformVar(NULL, "EDESTADDRREQ", &IntType, (union AnyValue *)&EDESTADDRREQValue, FALSE); - #endif - #ifdef EDOM - VariableDefinePlatformVar(NULL, "EDOM", &IntType, (union AnyValue *)&EDOMValue, FALSE); - #endif - #ifdef EDQUOT - VariableDefinePlatformVar(NULL, "EDQUOT", &IntType, (union AnyValue *)&EDQUOTValue, FALSE); - #endif - #ifdef EEXIST - VariableDefinePlatformVar(NULL, "EEXIST", &IntType, (union AnyValue *)&EEXISTValue, FALSE); - #endif - #ifdef EFAULT - VariableDefinePlatformVar(NULL, "EFAULT", &IntType, (union AnyValue *)&EFAULTValue, FALSE); - #endif - #ifdef EFBIG - VariableDefinePlatformVar(NULL, "EFBIG", &IntType, (union AnyValue *)&EFBIGValue, FALSE); - #endif - #ifdef EHOSTUNREACH - VariableDefinePlatformVar(NULL, "EHOSTUNREACH", &IntType, (union AnyValue *)&EHOSTUNREACHValue, FALSE); - #endif - #ifdef EIDRM - VariableDefinePlatformVar(NULL, "EIDRM", &IntType, (union AnyValue *)&EIDRMValue, FALSE); - #endif - #ifdef EILSEQ - VariableDefinePlatformVar(NULL, "EILSEQ", &IntType, (union AnyValue *)&EILSEQValue, FALSE); - #endif - #ifdef EINPROGRESS - VariableDefinePlatformVar(NULL, "EINPROGRESS", &IntType, (union AnyValue *)&EINPROGRESSValue, FALSE); - #endif - #ifdef EINTR - VariableDefinePlatformVar(NULL, "EINTR", &IntType, (union AnyValue *)&EINTRValue, FALSE); - #endif - #ifdef EINVAL - VariableDefinePlatformVar(NULL, "EINVAL", &IntType, (union AnyValue *)&EINVALValue, FALSE); - #endif - #ifdef EIO - VariableDefinePlatformVar(NULL, "EIO", &IntType, (union AnyValue *)&EIOValue, FALSE); - #endif - #ifdef EISCONN - VariableDefinePlatformVar(NULL, "EISCONN", &IntType, (union AnyValue *)&EISCONNValue, FALSE); - #endif - #ifdef EISDIR - VariableDefinePlatformVar(NULL, "EISDIR", &IntType, (union AnyValue *)&EISDIRValue, FALSE); - #endif - #ifdef ELOOP - VariableDefinePlatformVar(NULL, "ELOOP", &IntType, (union AnyValue *)&ELOOPValue, FALSE); - #endif - #ifdef EMFILE - VariableDefinePlatformVar(NULL, "EMFILE", &IntType, (union AnyValue *)&EMFILEValue, FALSE); - #endif - #ifdef EMLINK - VariableDefinePlatformVar(NULL, "EMLINK", &IntType, (union AnyValue *)&EMLINKValue, FALSE); - #endif - #ifdef EMSGSIZE - VariableDefinePlatformVar(NULL, "EMSGSIZE", &IntType, (union AnyValue *)&EMSGSIZEValue, FALSE); - #endif - #ifdef EMULTIHOP - VariableDefinePlatformVar(NULL, "EMULTIHOP", &IntType, (union AnyValue *)&EMULTIHOPValue, FALSE); - #endif - #ifdef ENAMETOOLONG - VariableDefinePlatformVar(NULL, "ENAMETOOLONG", &IntType, (union AnyValue *)&ENAMETOOLONGValue, FALSE); - #endif - #ifdef ENETDOWN - VariableDefinePlatformVar(NULL, "ENETDOWN", &IntType, (union AnyValue *)&ENETDOWNValue, FALSE); - #endif - #ifdef ENETRESET - VariableDefinePlatformVar(NULL, "ENETRESET", &IntType, (union AnyValue *)&ENETRESETValue, FALSE); - #endif - #ifdef ENETUNREACH - VariableDefinePlatformVar(NULL, "ENETUNREACH", &IntType, (union AnyValue *)&ENETUNREACHValue, FALSE); - #endif - #ifdef ENFILE - VariableDefinePlatformVar(NULL, "ENFILE", &IntType, (union AnyValue *)&ENFILEValue, FALSE); - #endif - #ifdef ENOBUFS - VariableDefinePlatformVar(NULL, "ENOBUFS", &IntType, (union AnyValue *)&ENOBUFSValue, FALSE); - #endif - #ifdef ENODATA - VariableDefinePlatformVar(NULL, "ENODATA", &IntType, (union AnyValue *)&ENODATAValue, FALSE); - #endif - #ifdef ENODEV - VariableDefinePlatformVar(NULL, "ENODEV", &IntType, (union AnyValue *)&ENODEVValue, FALSE); - #endif - #ifdef ENOENT - VariableDefinePlatformVar(NULL, "ENOENT", &IntType, (union AnyValue *)&ENOENTValue, FALSE); - #endif - #ifdef ENOEXEC - VariableDefinePlatformVar(NULL, "ENOEXEC", &IntType, (union AnyValue *)&ENOEXECValue, FALSE); - #endif - #ifdef ENOLCK - VariableDefinePlatformVar(NULL, "ENOLCK", &IntType, (union AnyValue *)&ENOLCKValue, FALSE); - #endif - #ifdef ENOLINK - VariableDefinePlatformVar(NULL, "ENOLINK", &IntType, (union AnyValue *)&ENOLINKValue, FALSE); - #endif - #ifdef ENOMEM - VariableDefinePlatformVar(NULL, "ENOMEM", &IntType, (union AnyValue *)&ENOMEMValue, FALSE); - #endif - #ifdef ENOMSG - VariableDefinePlatformVar(NULL, "ENOMSG", &IntType, (union AnyValue *)&ENOMSGValue, FALSE); - #endif - #ifdef ENOPROTOOPT - VariableDefinePlatformVar(NULL, "ENOPROTOOPT", &IntType, (union AnyValue *)&ENOPROTOOPTValue, FALSE); - #endif - #ifdef ENOSPC - VariableDefinePlatformVar(NULL, "ENOSPC", &IntType, (union AnyValue *)&ENOSPCValue, FALSE); - #endif - #ifdef ENOSR - VariableDefinePlatformVar(NULL, "ENOSR", &IntType, (union AnyValue *)&ENOSRValue, FALSE); - #endif - #ifdef ENOSTR - VariableDefinePlatformVar(NULL, "ENOSTR", &IntType, (union AnyValue *)&ENOSTRValue, FALSE); - #endif - #ifdef ENOSYS - VariableDefinePlatformVar(NULL, "ENOSYS", &IntType, (union AnyValue *)&ENOSYSValue, FALSE); - #endif - #ifdef ENOTCONN - VariableDefinePlatformVar(NULL, "ENOTCONN", &IntType, (union AnyValue *)&ENOTCONNValue, FALSE); - #endif - #ifdef ENOTDIR - VariableDefinePlatformVar(NULL, "ENOTDIR", &IntType, (union AnyValue *)&ENOTDIRValue, FALSE); - #endif - #ifdef ENOTEMPTY - VariableDefinePlatformVar(NULL, "ENOTEMPTY", &IntType, (union AnyValue *)&ENOTEMPTYValue, FALSE); - #endif - #ifdef ENOTRECOVERABLE - VariableDefinePlatformVar(NULL, "ENOTRECOVERABLE", &IntType, (union AnyValue *)&ENOTRECOVERABLEValue, FALSE); - #endif - #ifdef ENOTSOCK - VariableDefinePlatformVar(NULL, "ENOTSOCK", &IntType, (union AnyValue *)&ENOTSOCKValue, FALSE); - #endif - #ifdef ENOTSUP - VariableDefinePlatformVar(NULL, "ENOTSUP", &IntType, (union AnyValue *)&ENOTSUPValue, FALSE); - #endif - #ifdef ENOTTY - VariableDefinePlatformVar(NULL, "ENOTTY", &IntType, (union AnyValue *)&ENOTTYValue, FALSE); - #endif - #ifdef ENXIO - VariableDefinePlatformVar(NULL, "ENXIO", &IntType, (union AnyValue *)&ENXIOValue, FALSE); - #endif - #ifdef EOPNOTSUPP - VariableDefinePlatformVar(NULL, "EOPNOTSUPP", &IntType, (union AnyValue *)&EOPNOTSUPPValue, FALSE); - #endif - #ifdef EOVERFLOW - VariableDefinePlatformVar(NULL, "EOVERFLOW", &IntType, (union AnyValue *)&EOVERFLOWValue, FALSE); - #endif - #ifdef EOWNERDEAD - VariableDefinePlatformVar(NULL, "EOWNERDEAD", &IntType, (union AnyValue *)&EOWNERDEADValue, FALSE); - #endif - #ifdef EPERM - VariableDefinePlatformVar(NULL, "EPERM", &IntType, (union AnyValue *)&EPERMValue, FALSE); - #endif - #ifdef EPIPE - VariableDefinePlatformVar(NULL, "EPIPE", &IntType, (union AnyValue *)&EPIPEValue, FALSE); - #endif - #ifdef EPROTO - VariableDefinePlatformVar(NULL, "EPROTO", &IntType, (union AnyValue *)&EPROTOValue, FALSE); - #endif - #ifdef EPROTONOSUPPORT - VariableDefinePlatformVar(NULL, "EPROTONOSUPPORT", &IntType, (union AnyValue *)&EPROTONOSUPPORTValue, FALSE); - #endif - #ifdef EPROTOTYPE - VariableDefinePlatformVar(NULL, "EPROTOTYPE", &IntType, (union AnyValue *)&EPROTOTYPEValue, FALSE); - #endif - #ifdef ERANGE - VariableDefinePlatformVar(NULL, "ERANGE", &IntType, (union AnyValue *)&ERANGEValue, FALSE); - #endif - #ifdef EROFS - VariableDefinePlatformVar(NULL, "EROFS", &IntType, (union AnyValue *)&EROFSValue, FALSE); - #endif - #ifdef ESPIPE - VariableDefinePlatformVar(NULL, "ESPIPE", &IntType, (union AnyValue *)&ESPIPEValue, FALSE); - #endif - #ifdef ESRCH - VariableDefinePlatformVar(NULL, "ESRCH", &IntType, (union AnyValue *)&ESRCHValue, FALSE); - #endif - #ifdef ESTALE - VariableDefinePlatformVar(NULL, "ESTALE", &IntType, (union AnyValue *)&ESTALEValue, FALSE); - #endif - #ifdef ETIME - VariableDefinePlatformVar(NULL, "ETIME", &IntType, (union AnyValue *)&ETIMEValue, FALSE); - #endif - #ifdef ETIMEDOUT - VariableDefinePlatformVar(NULL, "ETIMEDOUT", &IntType, (union AnyValue *)&ETIMEDOUTValue, FALSE); - #endif - #ifdef ETXTBSY - VariableDefinePlatformVar(NULL, "ETXTBSY", &IntType, (union AnyValue *)&ETXTBSYValue, FALSE); - #endif - #ifdef EWOULDBLOCK - VariableDefinePlatformVar(NULL, "EWOULDBLOCK", &IntType, (union AnyValue *)&EWOULDBLOCKValue, FALSE); - #endif - #ifdef EXDEV - VariableDefinePlatformVar(NULL, "EXDEV", &IntType, (union AnyValue *)&EXDEVValue, FALSE); - #endif - VariableDefinePlatformVar(NULL, "errno", &IntType, (union AnyValue *)&errno, TRUE); -} - -#endif /* !BUILTIN_MINI_STDLIB */ diff --git a/eci/cstdlib/math.c b/eci/cstdlib/math.c deleted file mode 100644 index ed1d330..0000000 --- a/eci/cstdlib/math.c +++ /dev/null @@ -1,168 +0,0 @@ -/** - * @author Edouard DUPIN - * - * @copyright 2014, Edouard DUPIN, all right reserved - * - * @license APACHE-2 (see license file) - */ - -/* stdio.h library for large systems - small embedded systems use clibrary.c instead */ -#include "../interpreter.h" - -#ifndef BUILTIN_MINI_STDLIB - -static double M_EValue = 2.7182818284590452354; /* e */ -static double M_LOG2EValue = 1.4426950408889634074; /* log_2 e */ -static double M_LOG10EValue = 0.43429448190325182765; /* log_10 e */ -static double M_LN2Value = 0.69314718055994530942; /* log_e 2 */ -static double M_LN10Value = 2.30258509299404568402; /* log_e 10 */ -static double M_PIValue = 3.14159265358979323846; /* pi */ -static double M_PI_2Value = 1.57079632679489661923; /* pi/2 */ -static double M_PI_4Value = 0.78539816339744830962; /* pi/4 */ -static double M_1_PIValue = 0.31830988618379067154; /* 1/pi */ -static double M_2_PIValue = 0.63661977236758134308; /* 2/pi */ -static double M_2_SQRTPIValue = 1.12837916709551257390; /* 2/sqrt(pi) */ -static double M_SQRT2Value = 1.41421356237309504880; /* sqrt(2) */ -static double M_SQRT1_2Value = 0.70710678118654752440; /* 1/sqrt(2) */ - - -void MathSin(struct ParseState *_parser, struct Value *_returnValue, struct Value **_param, int _numArgs) { - _returnValue->Val->FP = sin(_param[0]->Val->FP); -} - -void MathCos(struct ParseState *_parser, struct Value *_returnValue, struct Value **_param, int _numArgs){ - _returnValue->Val->FP = cos(_param[0]->Val->FP); -} - -void MathTan(struct ParseState *_parser, struct Value *_returnValue, struct Value **_param, int _numArgs) { - _returnValue->Val->FP = tan(_param[0]->Val->FP); -} - -void MathAsin(struct ParseState *_parser, struct Value *_returnValue, struct Value **_param, int _numArgs) { - _returnValue->Val->FP = asin(_param[0]->Val->FP); -} - -void MathAcos(struct ParseState *_parser, struct Value *_returnValue, struct Value **_param, int _numArgs) { - _returnValue->Val->FP = acos(_param[0]->Val->FP); -} - -void MathAtan(struct ParseState *_parser, struct Value *_returnValue, struct Value **_param, int _numArgs) { - _returnValue->Val->FP = atan(_param[0]->Val->FP); -} - -void MathAtan2(struct ParseState *_parser, struct Value *_returnValue, struct Value **_param, int _numArgs) { - _returnValue->Val->FP = atan2(_param[0]->Val->FP, _param[1]->Val->FP); -} - -void MathSinh(struct ParseState *_parser, struct Value *_returnValue, struct Value **_param, int _numArgs) { - _returnValue->Val->FP = sinh(_param[0]->Val->FP); -} - -void MathCosh(struct ParseState *_parser, struct Value *_returnValue, struct Value **_param, int _numArgs) { - _returnValue->Val->FP = cosh(_param[0]->Val->FP); -} - -void MathTanh(struct ParseState *_parser, struct Value *_returnValue, struct Value **_param, int _numArgs) { - _returnValue->Val->FP = tanh(_param[0]->Val->FP); -} - -void MathExp(struct ParseState *_parser, struct Value *_returnValue, struct Value **_param, int _numArgs) { - _returnValue->Val->FP = exp(_param[0]->Val->FP); -} - -void MathFabs(struct ParseState *_parser, struct Value *_returnValue, struct Value **_param, int _numArgs) { - _returnValue->Val->FP = fabs(_param[0]->Val->FP); -} - -void MathFmod(struct ParseState *_parser, struct Value *_returnValue, struct Value **_param, int _numArgs) { - _returnValue->Val->FP = fmod(_param[0]->Val->FP, _param[1]->Val->FP); -} - -void MathFrexp(struct ParseState *_parser, struct Value *_returnValue, struct Value **_param, int _numArgs) { - _returnValue->Val->FP = frexp(_param[0]->Val->FP, _param[1]->Val->Pointer); -} - -void MathLdexp(struct ParseState *_parser, struct Value *_returnValue, struct Value **_param, int _numArgs) { - _returnValue->Val->FP = ldexp(_param[0]->Val->FP, _param[1]->Val->Integer); -} - -void MathLog(struct ParseState *_parser, struct Value *_returnValue, struct Value **_param, int _numArgs) { - _returnValue->Val->FP = log(_param[0]->Val->FP); -} - -void MathLog10(struct ParseState *_parser, struct Value *_returnValue, struct Value **_param, int _numArgs) { - _returnValue->Val->FP = log10(_param[0]->Val->FP); -} - -void MathModf(struct ParseState *_parser, struct Value *_returnValue, struct Value **_param, int _numArgs) { - _returnValue->Val->FP = modf(_param[0]->Val->FP, _param[0]->Val->Pointer); -} - -void MathPow(struct ParseState *_parser, struct Value *_returnValue, struct Value **_param, int _numArgs) { - _returnValue->Val->FP = pow(_param[0]->Val->FP, _param[1]->Val->FP); -} - -void MathSqrt(struct ParseState *_parser, struct Value *_returnValue, struct Value **_param, int _numArgs) { - _returnValue->Val->FP = sqrt(_param[0]->Val->FP); -} - -void MathRound(struct ParseState *_parser, struct Value *_returnValue, struct Value **_param, int _numArgs) { - /* this awkward definition of "round()" due to it being inconsistently - * declared in math.h */ - _returnValue->Val->FP = ceil(_param[0]->Val->FP - 0.5); -} - -void MathCeil(struct ParseState *_parser, struct Value *_returnValue, struct Value **_param, int _numArgs) { - _returnValue->Val->FP = ceil(_param[0]->Val->FP); -} - -void MathFloor(struct ParseState *_parser, struct Value *_returnValue, struct Value **_param, int _numArgs) { - _returnValue->Val->FP = floor(_param[0]->Val->FP); -} - -/* all math.h functions */ -struct LibraryFunction MathFunctions[] = { - { MathAcos, "float acos(float);" }, - { MathAsin, "float asin(float);" }, - { MathAtan, "float atan(float);" }, - { MathAtan2, "float atan2(float, float);" }, - { MathCeil, "float ceil(float);" }, - { MathCos, "float cos(float);" }, - { MathCosh, "float cosh(float);" }, - { MathExp, "float exp(float);" }, - { MathFabs, "float fabs(float);" }, - { MathFloor, "float floor(float);" }, - { MathFmod, "float fmod(float, float);" }, - { MathFrexp, "float frexp(float, int *);" }, - { MathLdexp, "float ldexp(float, int);" }, - { MathLog, "float log(float);" }, - { MathLog10, "float log10(float);" }, - { MathModf, "float modf(float, float *);" }, - { MathPow, "float pow(float,float);" }, - { MathRound, "float round(float);" }, - { MathSin, "float sin(float);" }, - { MathSinh, "float sinh(float);" }, - { MathSqrt, "float sqrt(float);" }, - { MathTan, "float tan(float);" }, - { MathTanh, "float tanh(float);" }, - { NULL, NULL } -}; - -/* creates various system-dependent definitions */ -void MathSetupFunc() { - VariableDefinePlatformVar(NULL, "M_E", &FPType, (union AnyValue *)&M_EValue, FALSE); - VariableDefinePlatformVar(NULL, "M_LOG2E", &FPType, (union AnyValue *)&M_LOG2EValue, FALSE); - VariableDefinePlatformVar(NULL, "M_LOG10E", &FPType, (union AnyValue *)&M_LOG10EValue, FALSE); - VariableDefinePlatformVar(NULL, "M_LN2", &FPType, (union AnyValue *)&M_LN2Value, FALSE); - VariableDefinePlatformVar(NULL, "M_LN10", &FPType, (union AnyValue *)&M_LN10Value, FALSE); - VariableDefinePlatformVar(NULL, "M_PI", &FPType, (union AnyValue *)&M_PIValue, FALSE); - VariableDefinePlatformVar(NULL, "M_PI_2", &FPType, (union AnyValue *)&M_PI_2Value, FALSE); - VariableDefinePlatformVar(NULL, "M_PI_4", &FPType, (union AnyValue *)&M_PI_4Value, FALSE); - VariableDefinePlatformVar(NULL, "M_1_PI", &FPType, (union AnyValue *)&M_1_PIValue, FALSE); - VariableDefinePlatformVar(NULL, "M_2_PI", &FPType, (union AnyValue *)&M_2_PIValue, FALSE); - VariableDefinePlatformVar(NULL, "M_2_SQRTPI", &FPType, (union AnyValue *)&M_2_SQRTPIValue, FALSE); - VariableDefinePlatformVar(NULL, "M_SQRT2", &FPType, (union AnyValue *)&M_SQRT2Value, FALSE); - VariableDefinePlatformVar(NULL, "M_SQRT1_2", &FPType, (union AnyValue *)&M_SQRT1_2Value, FALSE); -} - -#endif /* !BUILTIN_MINI_STDLIB */ diff --git a/eci/cstdlib/math.h b/eci/cstdlib/math.h deleted file mode 100644 index 1bef9a1..0000000 --- a/eci/cstdlib/math.h +++ /dev/null @@ -1,16 +0,0 @@ -/** - * @author Edouard DUPIN - * - * @copyright 2014, Edouard DUPIN, all right reserved - * - * @license APACHE-2 (see license file) - */ - -#ifndef __ECI_MATH_H__ -#define __ECI_MATH_H__ - - -extern struct LibraryFunction MathFunctions[]; -void MathSetupFunc(); - -#endif diff --git a/eci/cstdlib/stdbool.c b/eci/cstdlib/stdbool.c deleted file mode 100644 index a2f3190..0000000 --- a/eci/cstdlib/stdbool.c +++ /dev/null @@ -1,29 +0,0 @@ -/** - * @author Edouard DUPIN - * - * @copyright 2014, Edouard DUPIN, all right reserved - * - * @license APACHE-2 (see license file) - */ - -/* string.h library for large systems - small embedded systems use clibrary.c instead */ -#include "../interpreter.h" - -#ifndef BUILTIN_MINI_STDLIB - -static int trueValue = 1; -static int falseValue = 0; - - -/* structure definitions */ -const char StdboolDefs[] = "typedef int bool;"; - -/* creates various system-dependent definitions */ -void StdboolSetupFunc() { - /* defines */ - VariableDefinePlatformVar(NULL, "true", &IntType, (union AnyValue *)&trueValue, FALSE); - VariableDefinePlatformVar(NULL, "false", &IntType, (union AnyValue *)&falseValue, FALSE); - VariableDefinePlatformVar(NULL, "__bool_true_false_are_defined", &IntType, (union AnyValue *)&trueValue, FALSE); -} - -#endif diff --git a/eci/cstdlib/stdbool.h b/eci/cstdlib/stdbool.h deleted file mode 100644 index 1a50f2a..0000000 --- a/eci/cstdlib/stdbool.h +++ /dev/null @@ -1,16 +0,0 @@ -/** - * @author Edouard DUPIN - * - * @copyright 2014, Edouard DUPIN, all right reserved - * - * @license APACHE-2 (see license file) - */ - -#ifndef __ECI_STD_BOOL_H__ -#define __ECI_STD_BOOL_H__ - - -extern const char StdboolDefs[]; -void StdboolSetupFunc(); - -#endif diff --git a/eci/cstdlib/stdio.c b/eci/cstdlib/stdio.c deleted file mode 100644 index ffc7597..0000000 --- a/eci/cstdlib/stdio.c +++ /dev/null @@ -1,659 +0,0 @@ -/** - * @author Edouard DUPIN - * - * @copyright 2014, Edouard DUPIN, all right reserved - * - * @license APACHE-2 (see license file) - */ - -/* stdio.h library for large systems - small embedded systems use clibrary.c instead */ -#include -#include "../interpreter.h" - -#ifndef BUILTIN_MINI_STDLIB - -#define MAX_FORMAT 80 -#define MAX_SCANF_ARGS 10 - -FILE *CStdOut; - -static int ZeroValue = 0; -static int EOFValue = EOF; -static int SEEK_SETValue = SEEK_SET; -static int SEEK_CURValue = SEEK_CUR; -static int SEEK_ENDValue = SEEK_END; -static int BUFSIZValue = BUFSIZ; -static int FILENAME_MAXValue = FILENAME_MAX; -static int _IOFBFValue = _IOFBF; -static int _IOLBFValue = _IOLBF; -static int _IONBFValue = _IONBF; -static int L_tmpnamValue = L_tmpnam; -static int GETS_MAXValue = 255; /* arbitrary maximum size of a gets() file */ - -static FILE *stdinValue; -static FILE *stdoutValue; -static FILE *stderrValue; - -struct ValueType *FilePtrType = NULL; - - -/* our own internal output stream which can output to FILE * or strings */ -typedef struct StdOutStreamStruct { - FILE *FilePtr; - char *StrOutPtr; - int StrOutLen; - int CharCount; -} StdOutStream; - -/* our representation of varargs within picoc */ -struct StdVararg { - struct Value **_param; - int _numArgs; -}; - -/* initialises the I/O system so error reporting works */ -void BasicIOInit() { - CStdOut = stdout; - stdinValue = stdin; - stdoutValue = stdout; - stderrValue = stderr; -} - -/* output a single character to either a FILE * or a string */ -void StdioOutPutc(int OutCh, StdOutStream *Stream) { - if (Stream->FilePtr != NULL) { - /* output to stdio stream */ - putc(OutCh, Stream->FilePtr); - Stream->CharCount++; - } else if ( Stream->StrOutLen < 0 - || Stream->StrOutLen > 1) { - /* output to a string */ - *Stream->StrOutPtr = OutCh; - Stream->StrOutPtr++; - if (Stream->StrOutLen > 1) { - Stream->StrOutLen--; - } - Stream->CharCount++; - } -} - -/* output a string to either a FILE * or a string */ -void StdioOutPuts(const char *Str, StdOutStream *Stream) { - if (Stream->FilePtr != NULL) { - /* output to stdio stream */ - fputs(Str, Stream->FilePtr); - } else { - /* output to a string */ - while (*Str != '\0') { - if ( Stream->StrOutLen < 0 - || Stream->StrOutLen > 1) { - /* output to a string */ - *Stream->StrOutPtr = *Str; - Str++; - Stream->StrOutPtr++; - if (Stream->StrOutLen > 1) { - Stream->StrOutLen--; - } - Stream->CharCount++; - } - } - } -} - -/* printf-style format of an int or other word-sized object */ -void StdioFprintfWord(StdOutStream *Stream, const char *Format, unsigned int Value) { - if (Stream->FilePtr != NULL) { - Stream->CharCount += fprintf(Stream->FilePtr, Format, Value); - } else if (Stream->StrOutLen >= 0) { - int CCount = snprintf(Stream->StrOutPtr, Stream->StrOutLen, Format, Value); - Stream->StrOutPtr += CCount; - Stream->StrOutLen -= CCount; - Stream->CharCount += CCount; - } else { - int CCount = sprintf(Stream->StrOutPtr, Format, Value); - Stream->CharCount += CCount; - Stream->StrOutPtr += CCount; - } -} - -/* printf-style format of a floating point number */ -void StdioFprintfFP(StdOutStream *Stream, const char *Format, double Value) { - if (Stream->FilePtr != NULL) { - Stream->CharCount += fprintf(Stream->FilePtr, Format, Value); - } else if (Stream->StrOutLen >= 0) { - int CCount = snprintf(Stream->StrOutPtr, Stream->StrOutLen, Format, Value); - Stream->StrOutPtr += CCount; - Stream->StrOutLen -= CCount; - Stream->CharCount += CCount; - } else { - int CCount = sprintf(Stream->StrOutPtr, Format, Value); - Stream->CharCount += CCount; - Stream->StrOutPtr += CCount; - } -} - -/* printf-style format of a pointer */ -void StdioFprintfPointer(StdOutStream *Stream, const char *Format, void *Value) { - if (Stream->FilePtr != NULL) { - Stream->CharCount += fprintf(Stream->FilePtr, Format, Value); - } else if (Stream->StrOutLen >= 0) { - int CCount = snprintf(Stream->StrOutPtr, Stream->StrOutLen, Format, Value); - Stream->StrOutPtr += CCount; - Stream->StrOutLen -= CCount; - Stream->CharCount += CCount; - } else { - int CCount = sprintf(Stream->StrOutPtr, Format, Value); - Stream->CharCount += CCount; - Stream->StrOutPtr += CCount; - } -} - -/* internal do-anything v[s][n]printf() formatting system with output to strings or FILE * */ -int StdioBasePrintf(struct ParseState *_parser, FILE *Stream, char *StrOut, int StrOutLen, char *Format, struct StdVararg *Args) { - struct Value *ThisArg = Args->_param[0]; - int ArgCount = 0; - char *FPos = Format; - char OneFormatBuf[MAX_FORMAT+1]; - int OneFormatCount; - struct ValueType *ShowType; - StdOutStream SOStream; - SOStream.FilePtr = Stream; - SOStream.StrOutPtr = StrOut; - SOStream.StrOutLen = StrOutLen; - SOStream.CharCount = 0; - while (*FPos != '\0') { - if (*FPos == '%') { - /* work out what type we're printing */ - FPos++; - ShowType = NULL; - OneFormatBuf[0] = '%'; - OneFormatCount = 1; - do { - switch (*FPos) { - case 'd': - case 'i': - ShowType = &IntType; - break; - /* integer decimal */ - case 'o': - case 'u': - case 'x': - case 'X': - ShowType = &IntType; - break; - /* integer base conversions */ - case 'e': - case 'E': - ShowType = &FPType; - break; - /* double, exponent form */ - case 'f': - case 'F': - ShowType = &FPType; - break; - /* double, fixed-point */ - case 'g': - case 'G': - ShowType = &FPType; - break; - /* double, flexible format */ - case 'a': - case 'A': - ShowType = &IntType; - break; - /* hexadecimal, 0x- format */ - case 'c': - ShowType = &IntType; - break; - /* character */ - case 's': - ShowType = CharPtrType; - break; - /* string */ - case 'p': - ShowType = VoidPtrType; - break; - /* pointer */ - case 'n': - ShowType = &VoidType; - break; - /* number of characters written */ - case 'm': - ShowType = &VoidType; - break; - /* strerror(errno) */ - case '%': - ShowType = &VoidType; - break; - /* just a '%' character */ - case '\0': - ShowType = &VoidType; - break; - /* end of format string */ - } - /* copy one character of format across to the OneFormatBuf */ - OneFormatBuf[OneFormatCount] = *FPos; - OneFormatCount++; - /* do special actions depending on the conversion type */ - if (ShowType == &VoidType) { - switch (*FPos) { - case 'm': - StdioOutPuts(strerror(errno), &SOStream); - break; - case '%': - StdioOutPutc(*FPos, &SOStream); - break; - case '\0': - OneFormatBuf[OneFormatCount] = '\0'; - StdioOutPutc(*FPos, &SOStream); - break; - case 'n': - ThisArg = (struct Value *)((char *)ThisArg + MEM_ALIGN(sizeof(struct Value) + TypeStackSizeValue(ThisArg))); - if ( ThisArg->Typ->Base == TypeArray - && ThisArg->Typ->FromType->Base == TypeInt) { - *(int *)ThisArg->Val->Pointer = SOStream.CharCount; - } - break; - } - } - FPos++; - } while ( ShowType == NULL - && OneFormatCount < MAX_FORMAT); - if (ShowType != &VoidType) { - if (ArgCount >= Args->_numArgs) { - StdioOutPuts("XXX", &SOStream); - } else { - /* null-terminate the buffer */ - OneFormatBuf[OneFormatCount] = '\0'; - /* print this argument */ - ThisArg = (struct Value *)((char *)ThisArg + MEM_ALIGN(sizeof(struct Value) + TypeStackSizeValue(ThisArg))); - if (ShowType == &IntType) { - /* show a signed integer */ - if (IS_NUMERIC_COERCIBLE(ThisArg)) { - StdioFprintfWord(&SOStream, OneFormatBuf, ExpressionCoerceUnsignedInteger(ThisArg)); - } else { - StdioOutPuts("XXX", &SOStream); - } - } else if (ShowType == &FPType) { - /* show a floating point number */ - if (IS_NUMERIC_COERCIBLE(ThisArg)) { - StdioFprintfFP(&SOStream, OneFormatBuf, ExpressionCoerceFP(ThisArg)); - } else { - StdioOutPuts("XXX", &SOStream); - } - } else if (ShowType == CharPtrType) { - if (ThisArg->Typ->Base == TypePointer) { - StdioFprintfPointer(&SOStream, OneFormatBuf, ThisArg->Val->Pointer); - } else if ( ThisArg->Typ->Base == TypeArray - && ThisArg->Typ->FromType->Base == TypeChar) { - StdioFprintfPointer(&SOStream, OneFormatBuf, &ThisArg->Val->ArrayMem[0]); - } else { - StdioOutPuts("XXX", &SOStream); - } - } else if (ShowType == VoidPtrType) { - if (ThisArg->Typ->Base == TypePointer) { - StdioFprintfPointer(&SOStream, OneFormatBuf, ThisArg->Val->Pointer); - } else if (ThisArg->Typ->Base == TypeArray) { - StdioFprintfPointer(&SOStream, OneFormatBuf, &ThisArg->Val->ArrayMem[0]); - } else { - StdioOutPuts("XXX", &SOStream); - } - } - ArgCount++; - } - } - } else { - /* just output a normal character */ - StdioOutPutc(*FPos, &SOStream); - FPos++; - } - } - /* null-terminate */ - if ( SOStream.StrOutPtr != NULL - && SOStream.StrOutLen > 0) { - *SOStream.StrOutPtr = '\0'; - } - return SOStream.CharCount; -} - -/* internal do-anything v[s][n]scanf() formatting system with input from strings or FILE * */ -int StdioBaseScanf(struct ParseState *_parser, FILE *Stream, char *StrIn, char *Format, struct StdVararg *Args) { - struct Value *ThisArg = Args->_param[0]; - int ArgCount = 0; - void *ScanfArg[MAX_SCANF_ARGS]; - if (Args->_numArgs > MAX_SCANF_ARGS) { - ProgramFail(_parser, "too many arguments to scanf() - %d max", MAX_SCANF_ARGS); - } - for (ArgCount = 0; ArgCount < Args->_numArgs; ++ArgCount) { - ThisArg = (struct Value *)((char *)ThisArg + MEM_ALIGN(sizeof(struct Value) + TypeStackSizeValue(ThisArg))); - if (ThisArg->Typ->Base == TypePointer) { - ScanfArg[ArgCount] = ThisArg->Val->Pointer; - } else if (ThisArg->Typ->Base == TypeArray) { - ScanfArg[ArgCount] = &ThisArg->Val->ArrayMem[0]; - } else { - ProgramFail(_parser, "non-pointer argument to scanf() - argument %d after format", ArgCount+1); - } - } - if (Stream != NULL) { - return fscanf(Stream, Format, ScanfArg[0], ScanfArg[1], ScanfArg[2], ScanfArg[3], ScanfArg[4], ScanfArg[5], ScanfArg[6], ScanfArg[7], ScanfArg[8], ScanfArg[9]); - } else { - return sscanf(StrIn, Format, ScanfArg[0], ScanfArg[1], ScanfArg[2], ScanfArg[3], ScanfArg[4], ScanfArg[5], ScanfArg[6], ScanfArg[7], ScanfArg[8], ScanfArg[9]); - } -} - -/* stdio calls */ -void StdioFopen(struct ParseState *_parser, struct Value *_returnValue, struct Value **_param, int _numArgs) { - _returnValue->Val->Pointer = fopen(_param[0]->Val->Pointer, _param[1]->Val->Pointer); -} - -void StdioFreopen(struct ParseState *_parser, struct Value *_returnValue, struct Value **_param, int _numArgs) { - _returnValue->Val->Pointer = freopen(_param[0]->Val->Pointer, _param[1]->Val->Pointer, _param[2]->Val->Pointer); -} - -void StdioFclose(struct ParseState *_parser, struct Value *_returnValue, struct Value **_param, int _numArgs) { - _returnValue->Val->Integer = fclose(_param[0]->Val->Pointer); -} - -void StdioFread(struct ParseState *_parser, struct Value *_returnValue, struct Value **_param, int _numArgs) { - _returnValue->Val->Integer = fread(_param[0]->Val->Pointer, _param[1]->Val->Integer, _param[2]->Val->Integer, _param[3]->Val->Pointer); -} - -void StdioFwrite(struct ParseState *_parser, struct Value *_returnValue, struct Value **_param, int _numArgs) { - _returnValue->Val->Integer = fwrite(_param[0]->Val->Pointer, _param[1]->Val->Integer, _param[2]->Val->Integer, _param[3]->Val->Pointer); -} - -void StdioFgetc(struct ParseState *_parser, struct Value *_returnValue, struct Value **_param, int _numArgs) { - _returnValue->Val->Integer = fgetc(_param[0]->Val->Pointer); -} - -void StdioFgets(struct ParseState *_parser, struct Value *_returnValue, struct Value **_param, int _numArgs) { - _returnValue->Val->Pointer = fgets(_param[0]->Val->Pointer, _param[1]->Val->Integer, _param[2]->Val->Pointer); -} - -void StdioRemove(struct ParseState *_parser, struct Value *_returnValue, struct Value **_param, int _numArgs) { - _returnValue->Val->Integer = remove(_param[0]->Val->Pointer); -} - -void StdioRename(struct ParseState *_parser, struct Value *_returnValue, struct Value **_param, int _numArgs) { - _returnValue->Val->Integer = rename(_param[0]->Val->Pointer, _param[1]->Val->Pointer); -} - -void StdioRewind(struct ParseState *_parser, struct Value *_returnValue, struct Value **_param, int _numArgs) { - rewind(_param[0]->Val->Pointer); -} - -void StdioTmpfile(struct ParseState *_parser, struct Value *_returnValue, struct Value **_param, int _numArgs) { - _returnValue->Val->Pointer = tmpfile(); -} - -void StdioClearerr(struct ParseState *_parser, struct Value *_returnValue, struct Value **_param, int _numArgs) { - clearerr((FILE *)_param[0]->Val->Pointer); -} - -void StdioFeof(struct ParseState *_parser, struct Value *_returnValue, struct Value **_param, int _numArgs) { - _returnValue->Val->Integer = feof((FILE *)_param[0]->Val->Pointer); -} - -void StdioFerror(struct ParseState *_parser, struct Value *_returnValue, struct Value **_param, int _numArgs) { - _returnValue->Val->Integer = ferror((FILE *)_param[0]->Val->Pointer); -} - -void StdioFileno(struct ParseState *_parser, struct Value *_returnValue, struct Value **_param, int _numArgs) { - _returnValue->Val->Integer = fileno(_param[0]->Val->Pointer); -} - -void StdioFflush(struct ParseState *_parser, struct Value *_returnValue, struct Value **_param, int _numArgs) { - _returnValue->Val->Integer = fflush(_param[0]->Val->Pointer); -} - -void StdioFgetpos(struct ParseState *_parser, struct Value *_returnValue, struct Value **_param, int _numArgs) { - _returnValue->Val->Integer = fgetpos(_param[0]->Val->Pointer, _param[1]->Val->Pointer); -} - -void StdioFsetpos(struct ParseState *_parser, struct Value *_returnValue, struct Value **_param, int _numArgs) { - _returnValue->Val->Integer = fsetpos(_param[0]->Val->Pointer, _param[1]->Val->Pointer); -} - -void StdioFputc(struct ParseState *_parser, struct Value *_returnValue, struct Value **_param, int _numArgs) { - _returnValue->Val->Integer = fputc(_param[0]->Val->Integer, _param[1]->Val->Pointer); -} - -void StdioFputs(struct ParseState *_parser, struct Value *_returnValue, struct Value **_param, int _numArgs) { - _returnValue->Val->Integer = fputs(_param[0]->Val->Pointer, _param[1]->Val->Pointer); -} - -void StdioFtell(struct ParseState *_parser, struct Value *_returnValue, struct Value **_param, int _numArgs) { - _returnValue->Val->Integer = ftell(_param[0]->Val->Pointer); -} - -void StdioFseek(struct ParseState *_parser, struct Value *_returnValue, struct Value **_param, int _numArgs) { - _returnValue->Val->Integer = fseek(_param[0]->Val->Pointer, _param[1]->Val->Integer, _param[2]->Val->Integer); -} - -void StdioPerror(struct ParseState *_parser, struct Value *_returnValue, struct Value **_param, int _numArgs) { - perror(_param[0]->Val->Pointer); -} - -void StdioPutc(struct ParseState *_parser, struct Value *_returnValue, struct Value **_param, int _numArgs) { - _returnValue->Val->Integer = putc(_param[0]->Val->Integer, _param[1]->Val->Pointer); -} - -void StdioPutchar(struct ParseState *_parser, struct Value *_returnValue, struct Value **_param, int _numArgs) { - _returnValue->Val->Integer = putchar(_param[0]->Val->Integer); -} - -void StdioSetbuf(struct ParseState *_parser, struct Value *_returnValue, struct Value **_param, int _numArgs) { - setbuf(_param[0]->Val->Pointer, _param[1]->Val->Pointer); -} - -void StdioSetvbuf(struct ParseState *_parser, struct Value *_returnValue, struct Value **_param, int _numArgs) { - setvbuf(_param[0]->Val->Pointer, _param[1]->Val->Pointer, _param[2]->Val->Integer, _param[3]->Val->Integer); -} - -void StdioUngetc(struct ParseState *_parser, struct Value *_returnValue, struct Value **_param, int _numArgs) { - _returnValue->Val->Integer = ungetc(_param[0]->Val->Integer, _param[1]->Val->Pointer); -} - -void StdioPuts(struct ParseState *_parser, struct Value *_returnValue, struct Value **_param, int _numArgs) { - _returnValue->Val->Integer = puts(_param[0]->Val->Pointer); -} - -void StdioGets(struct ParseState *_parser, struct Value *_returnValue, struct Value **_param, int _numArgs) { - _returnValue->Val->Pointer = fgets(_param[0]->Val->Pointer, GETS_MAXValue, stdin); - if (_returnValue->Val->Pointer != NULL) { - char *EOLPos = strchr(_param[0]->Val->Pointer, '\n'); - if (EOLPos != NULL) { - *EOLPos = '\0'; - } - } -} - -void StdioGetchar(struct ParseState *_parser, struct Value *_returnValue, struct Value **_param, int _numArgs) { - _returnValue->Val->Integer = getchar(); -} - -void StdioPrintf(struct ParseState *_parser, struct Value *_returnValue, struct Value **_param, int _numArgs) { - struct StdVararg PrintfArgs; - PrintfArgs._param = _param; - PrintfArgs._numArgs = _numArgs-1; - _returnValue->Val->Integer = StdioBasePrintf(_parser, stdout, NULL, 0, _param[0]->Val->Pointer, &PrintfArgs); -} - -void StdioVprintf(struct ParseState *_parser, struct Value *_returnValue, struct Value **_param, int _numArgs) { - _returnValue->Val->Integer = StdioBasePrintf(_parser, stdout, NULL, 0, _param[0]->Val->Pointer, _param[1]->Val->Pointer); -} - -void StdioFprintf(struct ParseState *_parser, struct Value *_returnValue, struct Value **_param, int _numArgs) { - struct StdVararg PrintfArgs; - PrintfArgs._param = _param + 1; - PrintfArgs._numArgs = _numArgs-2; - _returnValue->Val->Integer = StdioBasePrintf(_parser, _param[0]->Val->Pointer, NULL, 0, _param[1]->Val->Pointer, &PrintfArgs); -} - -void StdioVfprintf(struct ParseState *_parser, struct Value *_returnValue, struct Value **_param, int _numArgs) { - _returnValue->Val->Integer = StdioBasePrintf(_parser, _param[0]->Val->Pointer, NULL, 0, _param[1]->Val->Pointer, _param[2]->Val->Pointer); -} - -void StdioSprintf(struct ParseState *_parser, struct Value *_returnValue, struct Value **_param, int _numArgs) { - struct StdVararg PrintfArgs; - PrintfArgs._param = _param + 1; - PrintfArgs._numArgs = _numArgs-2; - _returnValue->Val->Integer = StdioBasePrintf(_parser, NULL, _param[0]->Val->Pointer, -1, _param[1]->Val->Pointer, &PrintfArgs); -} - -void StdioSnprintf(struct ParseState *_parser, struct Value *_returnValue, struct Value **_param, int _numArgs) { - struct StdVararg PrintfArgs; - PrintfArgs._param = _param+2; - PrintfArgs._numArgs = _numArgs-3; - _returnValue->Val->Integer = StdioBasePrintf(_parser, NULL, _param[0]->Val->Pointer, _param[1]->Val->Integer, _param[2]->Val->Pointer, &PrintfArgs); -} - -void StdioScanf(struct ParseState *_parser, struct Value *_returnValue, struct Value **_param, int _numArgs) { - struct StdVararg ScanfArgs; - ScanfArgs._param = _param; - ScanfArgs._numArgs = _numArgs-1; - _returnValue->Val->Integer = StdioBaseScanf(_parser, stdin, NULL, _param[0]->Val->Pointer, &ScanfArgs); -} - -void StdioFscanf(struct ParseState *_parser, struct Value *_returnValue, struct Value **_param, int _numArgs) { - struct StdVararg ScanfArgs; - ScanfArgs._param = _param+1; - ScanfArgs._numArgs = _numArgs-2; - _returnValue->Val->Integer = StdioBaseScanf(_parser, _param[0]->Val->Pointer, NULL, _param[1]->Val->Pointer, &ScanfArgs); -} - -void StdioSscanf(struct ParseState *_parser, struct Value *_returnValue, struct Value **_param, int _numArgs) { - struct StdVararg ScanfArgs; - ScanfArgs._param = _param+1; - ScanfArgs._numArgs = _numArgs-2; - _returnValue->Val->Integer = StdioBaseScanf(_parser, NULL, _param[0]->Val->Pointer, _param[1]->Val->Pointer, &ScanfArgs); -} - -void StdioVsprintf(struct ParseState *_parser, struct Value *_returnValue, struct Value **_param, int _numArgs) { - _returnValue->Val->Integer = StdioBasePrintf(_parser, NULL, _param[0]->Val->Pointer, -1, _param[1]->Val->Pointer, _param[2]->Val->Pointer); -} - -void StdioVsnprintf(struct ParseState *_parser, struct Value *_returnValue, struct Value **_param, int _numArgs) { - _returnValue->Val->Integer = StdioBasePrintf(_parser, NULL, _param[0]->Val->Pointer, _param[1]->Val->Integer, _param[2]->Val->Pointer, _param[3]->Val->Pointer); -} - -void StdioVscanf(struct ParseState *_parser, struct Value *_returnValue, struct Value **_param, int _numArgs) { - _returnValue->Val->Integer = StdioBaseScanf(_parser, stdin, NULL, _param[0]->Val->Pointer, _param[1]->Val->Pointer); -} - -void StdioVfscanf(struct ParseState *_parser, struct Value *_returnValue, struct Value **_param, int _numArgs) { - _returnValue->Val->Integer = StdioBaseScanf(_parser, _param[0]->Val->Pointer, NULL, _param[1]->Val->Pointer, _param[2]->Val->Pointer); -} - -void StdioVsscanf(struct ParseState *_parser, struct Value *_returnValue, struct Value **_param, int _numArgs) { - _returnValue->Val->Integer = StdioBaseScanf(_parser, NULL, _param[0]->Val->Pointer, _param[1]->Val->Pointer, _param[2]->Val->Pointer); -} - -/* handy structure definitions */ -const char StdioDefs[] = "\ -typedef struct __va_listStruct va_list; \ -typedef struct __FILEStruct FILE;\ -"; - -/* all stdio functions */ -struct LibraryFunction StdioFunctions[] = { - { StdioFopen, "FILE *fopen(char *, char *);" }, - { StdioFreopen, "FILE *freopen(char *, char *, FILE *);" }, - { StdioFclose, "int fclose(FILE *);" }, - { StdioFread, "int fread(void *, int, int, FILE *);" }, - { StdioFwrite, "int fwrite(void *, int, int, FILE *);" }, - { StdioFgetc, "int fgetc(FILE *);" }, - { StdioFgetc, "int getc(FILE *);" }, - { StdioFgets, "char *fgets(char *, int, FILE *);" }, - { StdioFputc, "int fputc(int, FILE *);" }, - { StdioFputs, "int fputs(char *, FILE *);" }, - { StdioRemove, "int remove(char *);" }, - { StdioRename, "int rename(char *, char *);" }, - { StdioRewind, "void rewind(FILE *);" }, - { StdioTmpfile, "FILE *tmpfile();" }, - { StdioClearerr,"void clearerr(FILE *);" }, - { StdioFeof, "int feof(FILE *);" }, - { StdioFerror, "int ferror(FILE *);" }, - { StdioFileno, "int fileno(FILE *);" }, - { StdioFflush, "int fflush(FILE *);" }, - { StdioFgetpos, "int fgetpos(FILE *, int *);" }, - { StdioFsetpos, "int fsetpos(FILE *, int *);" }, - { StdioFtell, "int ftell(FILE *);" }, - { StdioFseek, "int fseek(FILE *, int, int);" }, - { StdioPerror, "void perror(char *);" }, - { StdioPutc, "int putc(char *, FILE *);" }, - { StdioPutchar, "int putchar(int);" }, - { StdioPutchar, "int fputchar(int);" }, - { StdioSetbuf, "void setbuf(FILE *, char *);" }, - { StdioSetvbuf, "void setvbuf(FILE *, char *, int, int);" }, - { StdioUngetc, "int ungetc(int, FILE *);" }, - { StdioPuts, "int puts(char *);" }, - { StdioGets, "char *gets(char *);" }, - { StdioGetchar, "int getchar();" }, - { StdioPrintf, "int printf(char *, ...);" }, - { StdioFprintf, "int fprintf(FILE *, char *, ...);" }, - { StdioSprintf, "int sprintf(char *, char *, ...);" }, - { StdioSnprintf,"int snprintf(char *, int, char *, ...);" }, - { StdioScanf, "int scanf(char *, ...);" }, - { StdioFscanf, "int fscanf(FILE *, char *, ...);" }, - { StdioSscanf, "int sscanf(char *, char *, ...);" }, - { StdioVprintf, "int vprintf(char *, va_list);" }, - { StdioVfprintf,"int vfprintf(FILE *, char *, va_list);" }, - { StdioVsprintf,"int vsprintf(char *, char *, va_list);" }, - { StdioVsnprintf,"int vsnprintf(char *, int, char *, va_list);" }, - { StdioVscanf, "int vscanf(char *, va_list);" }, - { StdioVfscanf, "int vfscanf(FILE *, char *, va_list);" }, - { StdioVsscanf, "int vsscanf(char *, char *, va_list);" }, - { NULL, NULL } -}; - -/* creates various system-dependent definitions */ -void StdioSetupFunc(void) { - struct ValueType *StructFileType; - struct ValueType *FilePtrType; - /* make a "struct __FILEStruct" which is the same size as a native FILE structure */ - StructFileType = TypeCreateOpaqueStruct(NULL, TableStrRegister("__FILEStruct"), sizeof(FILE)); - /* get a FILE * type */ - FilePtrType = TypeGetMatching(NULL, StructFileType, TypePointer, 0, StrEmpty, TRUE); - /* make a "struct __va_listStruct" which is the same size as our struct StdVararg */ - TypeCreateOpaqueStruct(NULL, TableStrRegister("__va_listStruct"), sizeof(FILE)); - /* define EOF equal to the system EOF */ - VariableDefinePlatformVar(NULL, "EOF", &IntType, (union AnyValue *)&EOFValue, FALSE); - VariableDefinePlatformVar(NULL, "SEEK_SET", &IntType, (union AnyValue *)&SEEK_SETValue, FALSE); - VariableDefinePlatformVar(NULL, "SEEK_CUR", &IntType, (union AnyValue *)&SEEK_CURValue, FALSE); - VariableDefinePlatformVar(NULL, "SEEK_END", &IntType, (union AnyValue *)&SEEK_ENDValue, FALSE); - VariableDefinePlatformVar(NULL, "BUFSIZ", &IntType, (union AnyValue *)&BUFSIZValue, FALSE); - VariableDefinePlatformVar(NULL, "FILENAME_MAX", &IntType, (union AnyValue *)&FILENAME_MAXValue, FALSE); - VariableDefinePlatformVar(NULL, "_IOFBF", &IntType, (union AnyValue *)&_IOFBFValue, FALSE); - VariableDefinePlatformVar(NULL, "_IOLBF", &IntType, (union AnyValue *)&_IOLBFValue, FALSE); - VariableDefinePlatformVar(NULL, "_IONBF", &IntType, (union AnyValue *)&_IONBFValue, FALSE); - VariableDefinePlatformVar(NULL, "L_tmpnam", &IntType, (union AnyValue *)&L_tmpnamValue, FALSE); - VariableDefinePlatformVar(NULL, "GETS_MAX", &IntType, (union AnyValue *)&GETS_MAXValue, FALSE); - /* define stdin, stdout and stderr */ - VariableDefinePlatformVar(NULL, "stdin", FilePtrType, (union AnyValue *)&stdinValue, FALSE); - VariableDefinePlatformVar(NULL, "stdout", FilePtrType, (union AnyValue *)&stdoutValue, FALSE); - VariableDefinePlatformVar(NULL, "stderr", FilePtrType, (union AnyValue *)&stderrValue, FALSE); - /* define NULL, TRUE and FALSE */ - if (!VariableDefined(TableStrRegister("NULL"))) { - VariableDefinePlatformVar(NULL, "NULL", &IntType, (union AnyValue *)&ZeroValue, FALSE); - } -} - -/* portability-related I/O calls */ -void PrintCh(char OutCh, FILE *Stream) { - putc(OutCh, Stream); -} - -void PrintSimpleInt(long Num, FILE *Stream) { - fprintf(Stream, "%ld", Num); -} - -void PrintStr(const char *Str, FILE *Stream) { - fputs(Str, Stream); -} - -void PrintFP(double Num, FILE *Stream) { - fprintf(Stream, "%f", Num); -} - -#endif diff --git a/eci/cstdlib/stdio.h b/eci/cstdlib/stdio.h deleted file mode 100644 index d50ac77..0000000 --- a/eci/cstdlib/stdio.h +++ /dev/null @@ -1,17 +0,0 @@ -/** - * @author Edouard DUPIN - * - * @copyright 2014, Edouard DUPIN, all right reserved - * - * @license APACHE-2 (see license file) - */ - -#ifndef __ECI_STDIO_H__ -#define __ECI_STDIO_H__ - - -extern const char StdioDefs[]; -extern struct LibraryFunction StdioFunctions[]; -void StdioSetupFunc(); - -#endif diff --git a/eci/cstdlib/stdlib.c b/eci/cstdlib/stdlib.c deleted file mode 100644 index 5f59ed4..0000000 --- a/eci/cstdlib/stdlib.c +++ /dev/null @@ -1,120 +0,0 @@ -/** - * @author Edouard DUPIN - * - * @copyright 2014, Edouard DUPIN, all right reserved - * - * @license APACHE-2 (see license file) - */ - -/* stdlib.h library for large systems - small embedded systems use clibrary.c instead */ -#include "../interpreter.h" - -#ifndef BUILTIN_MINI_STDLIB - -static int ZeroValue = 0; - -void StdlibAtof(struct ParseState *_parser, struct Value *_returnValue, struct Value **_param, int _numArgs) { - _returnValue->Val->FP = atof(_param[0]->Val->Pointer); -} - -void StdlibAtoi(struct ParseState *_parser, struct Value *_returnValue, struct Value **_param, int _numArgs) { - _returnValue->Val->Integer = atoi(_param[0]->Val->Pointer); -} - -void StdlibAtol(struct ParseState *_parser, struct Value *_returnValue, struct Value **_param, int _numArgs) { - _returnValue->Val->Integer = atol(_param[0]->Val->Pointer); -} - -void StdlibStrtod(struct ParseState *_parser, struct Value *_returnValue, struct Value **_param, int _numArgs) { - _returnValue->Val->FP = strtod(_param[0]->Val->Pointer, _param[1]->Val->Pointer); -} - -void StdlibStrtol(struct ParseState *_parser, struct Value *_returnValue, struct Value **_param, int _numArgs) { - _returnValue->Val->Integer = strtol(_param[0]->Val->Pointer, _param[1]->Val->Pointer, _param[2]->Val->Integer); -} - -void StdlibStrtoul(struct ParseState *_parser, struct Value *_returnValue, struct Value **_param, int _numArgs) { - _returnValue->Val->Integer = strtoul(_param[0]->Val->Pointer, _param[1]->Val->Pointer, _param[2]->Val->Integer); -} - -void StdlibMalloc(struct ParseState *_parser, struct Value *_returnValue, struct Value **_param, int _numArgs) { - _returnValue->Val->Pointer = malloc(_param[0]->Val->Integer); -} - -void StdlibCalloc(struct ParseState *_parser, struct Value *_returnValue, struct Value **_param, int _numArgs) { - _returnValue->Val->Pointer = calloc(_param[0]->Val->Integer, _param[1]->Val->Integer); -} - -void StdlibRealloc(struct ParseState *_parser, struct Value *_returnValue, struct Value **_param, int _numArgs) { - _returnValue->Val->Pointer = realloc(_param[0]->Val->Pointer, _param[1]->Val->Integer); -} - -void StdlibFree(struct ParseState *_parser, struct Value *_returnValue, struct Value **_param, int _numArgs) { - free(_param[0]->Val->Pointer); -} - -void StdlibRand(struct ParseState *_parser, struct Value *_returnValue, struct Value **_param, int _numArgs) { - _returnValue->Val->Integer = rand(); -} - -void StdlibSrand(struct ParseState *_parser, struct Value *_returnValue, struct Value **_param, int _numArgs) { - srand(_param[0]->Val->Integer); -} - -void StdlibAbort(struct ParseState *_parser, struct Value *_returnValue, struct Value **_param, int _numArgs) { - ProgramFail(_parser, "abort"); -} - -void StdlibExit(struct ParseState *_parser, struct Value *_returnValue, struct Value **_param, int _numArgs) { - PlatformExit(_param[0]->Val->Integer); -} - -void StdlibGetenv(struct ParseState *_parser, struct Value *_returnValue, struct Value **_param, int _numArgs) { - _returnValue->Val->Pointer = getenv(_param[0]->Val->Pointer); -} - -void StdlibSystem(struct ParseState *_parser, struct Value *_returnValue, struct Value **_param, int _numArgs) { - _returnValue->Val->Integer = system(_param[0]->Val->Pointer); -} - -void StdlibAbs(struct ParseState *_parser, struct Value *_returnValue, struct Value **_param, int _numArgs) { - _returnValue->Val->Integer = abs(_param[0]->Val->Integer); -} - -void StdlibLabs(struct ParseState *_parser, struct Value *_returnValue, struct Value **_param, int _numArgs) { - _returnValue->Val->Integer = labs(_param[0]->Val->Integer); -} - -/* all stdlib.h functions */ -struct LibraryFunction StdlibFunctions[] = -{ - { StdlibAtof, "float atof(char *);" }, - { StdlibStrtod, "float strtod(char *,char **);" }, - { StdlibAtoi, "int atoi(char *);" }, - { StdlibAtol, "int atol(char *);" }, - { StdlibStrtol, "int strtol(char *,char **,int);" }, - { StdlibStrtoul, "int strtoul(char *,char **,int);" }, - { StdlibMalloc, "void *malloc(int);" }, - { StdlibCalloc, "void *calloc(int,int);" }, - { StdlibRealloc, "void *realloc(void *,int);" }, - { StdlibFree, "void free(void *);" }, - { StdlibRand, "int rand();" }, - { StdlibSrand, "void srand(int);" }, - { StdlibAbort, "void abort();" }, - { StdlibExit, "void exit(int);" }, - { StdlibGetenv, "char *getenv(char *);" }, - { StdlibSystem, "int system(char *);" }, - { StdlibAbs, "int abs(int);" }, - { StdlibLabs, "int labs(int);" }, - { NULL, NULL } -}; - -/* creates various system-dependent definitions */ -void StdlibSetupFunc() { - /* define NULL, TRUE and FALSE */ - if (!VariableDefined(TableStrRegister("NULL"))) { - VariableDefinePlatformVar(NULL, "NULL", &IntType, (union AnyValue *)&ZeroValue, FALSE); - } -} - -#endif diff --git a/eci/cstdlib/stdlib.h b/eci/cstdlib/stdlib.h deleted file mode 100644 index 213235f..0000000 --- a/eci/cstdlib/stdlib.h +++ /dev/null @@ -1,16 +0,0 @@ -/** - * @author Edouard DUPIN - * - * @copyright 2014, Edouard DUPIN, all right reserved - * - * @license APACHE-2 (see license file) - */ - -#ifndef __ECI_STD_LIB_H__ -#define __ECI_STD_LIB_H__ - - -extern struct LibraryFunction StdlibFunctions[]; -void StdlibSetupFunc(); - -#endif diff --git a/eci/cstdlib/string.c b/eci/cstdlib/string.c deleted file mode 100644 index 83f0287..0000000 --- a/eci/cstdlib/string.c +++ /dev/null @@ -1,159 +0,0 @@ -/** - * @author Edouard DUPIN - * - * @copyright 2014, Edouard DUPIN, all right reserved - * - * @license APACHE-2 (see license file) - */ - -/* string.h library for large systems - small embedded systems use clibrary.c instead */ -#include "../interpreter.h" - -#ifndef BUILTIN_MINI_STDLIB - -static int ZeroValue = 0; - -void StringStrcpy(struct ParseState *_parser, struct Value *_returnValue, struct Value **_param, int _numArgs) { - _returnValue->Val->Pointer = strcpy(_param[0]->Val->Pointer, _param[1]->Val->Pointer); -} - -void StringStrncpy(struct ParseState *_parser, struct Value *_returnValue, struct Value **_param, int _numArgs) { - _returnValue->Val->Pointer = strncpy(_param[0]->Val->Pointer, _param[1]->Val->Pointer, _param[2]->Val->Integer); -} - -void StringStrcmp(struct ParseState *_parser, struct Value *_returnValue, struct Value **_param, int _numArgs) { - _returnValue->Val->Integer = strcmp(_param[0]->Val->Pointer, _param[1]->Val->Pointer); -} - -void StringStrncmp(struct ParseState *_parser, struct Value *_returnValue, struct Value **_param, int _numArgs) { - _returnValue->Val->Integer = strncmp(_param[0]->Val->Pointer, _param[1]->Val->Pointer, _param[2]->Val->Integer); -} - -void StringStrcat(struct ParseState *_parser, struct Value *_returnValue, struct Value **_param, int _numArgs) { - _returnValue->Val->Pointer = strcat(_param[0]->Val->Pointer, _param[1]->Val->Pointer); -} - -void StringStrncat(struct ParseState *_parser, struct Value *_returnValue, struct Value **_param, int _numArgs) { - _returnValue->Val->Pointer = strncat(_param[0]->Val->Pointer, _param[1]->Val->Pointer, _param[2]->Val->Integer); -} - -void StringIndex(struct ParseState *_parser, struct Value *_returnValue, struct Value **_param, int _numArgs) { - _returnValue->Val->Pointer = index(_param[0]->Val->Pointer, _param[1]->Val->Integer); -} - -void StringRindex(struct ParseState *_parser, struct Value *_returnValue, struct Value **_param, int _numArgs) { - _returnValue->Val->Pointer = rindex(_param[0]->Val->Pointer, _param[1]->Val->Integer); -} - -void StringStrlen(struct ParseState *_parser, struct Value *_returnValue, struct Value **_param, int _numArgs) { - _returnValue->Val->Integer = strlen(_param[0]->Val->Pointer); -} - -void StringMemset(struct ParseState *_parser, struct Value *_returnValue, struct Value **_param, int _numArgs) { - _returnValue->Val->Pointer = memset(_param[0]->Val->Pointer, _param[1]->Val->Integer, _param[2]->Val->Integer); -} - -void StringMemcpy(struct ParseState *_parser, struct Value *_returnValue, struct Value **_param, int _numArgs) { - _returnValue->Val->Pointer = memcpy(_param[0]->Val->Pointer, _param[1]->Val->Pointer, _param[2]->Val->Integer); -} - -void StringMemcmp(struct ParseState *_parser, struct Value *_returnValue, struct Value **_param, int _numArgs) { - _returnValue->Val->Integer = memcmp(_param[0]->Val->Pointer, _param[1]->Val->Pointer, _param[2]->Val->Integer); -} - -void StringMemmove(struct ParseState *_parser, struct Value *_returnValue, struct Value **_param, int _numArgs) { - _returnValue->Val->Pointer = memmove(_param[0]->Val->Pointer, _param[1]->Val->Pointer, _param[2]->Val->Integer); -} - -void StringMemchr(struct ParseState *_parser, struct Value *_returnValue, struct Value **_param, int _numArgs) { - _returnValue->Val->Pointer = memchr(_param[0]->Val->Pointer, _param[1]->Val->Integer, _param[2]->Val->Integer); -} - -void StringStrchr(struct ParseState *_parser, struct Value *_returnValue, struct Value **_param, int _numArgs) { - _returnValue->Val->Pointer = strchr(_param[0]->Val->Pointer, _param[1]->Val->Integer); -} - -void StringStrrchr(struct ParseState *_parser, struct Value *_returnValue, struct Value **_param, int _numArgs) { - _returnValue->Val->Pointer = strrchr(_param[0]->Val->Pointer, _param[1]->Val->Integer); -} - -void StringStrcoll(struct ParseState *_parser, struct Value *_returnValue, struct Value **_param, int _numArgs) { - _returnValue->Val->Integer = strcoll(_param[0]->Val->Pointer, _param[1]->Val->Pointer); -} - -void StringStrerror(struct ParseState *_parser, struct Value *_returnValue, struct Value **_param, int _numArgs) { - _returnValue->Val->Pointer = strerror(_param[0]->Val->Integer); -} - -void StringStrspn(struct ParseState *_parser, struct Value *_returnValue, struct Value **_param, int _numArgs) { - _returnValue->Val->Integer = strspn(_param[0]->Val->Pointer, _param[1]->Val->Pointer); -} - -void StringStrcspn(struct ParseState *_parser, struct Value *_returnValue, struct Value **_param, int _numArgs) { - _returnValue->Val->Integer = strcspn(_param[0]->Val->Pointer, _param[1]->Val->Pointer); -} - -void StringStrpbrk(struct ParseState *_parser, struct Value *_returnValue, struct Value **_param, int _numArgs) { - _returnValue->Val->Pointer = strpbrk(_param[0]->Val->Pointer, _param[1]->Val->Pointer); -} - -void StringStrstr(struct ParseState *_parser, struct Value *_returnValue, struct Value **_param, int _numArgs) { - _returnValue->Val->Pointer = strstr(_param[0]->Val->Pointer, _param[1]->Val->Pointer); -} - -void StringStrtok(struct ParseState *_parser, struct Value *_returnValue, struct Value **_param, int _numArgs) { - _returnValue->Val->Pointer = strtok(_param[0]->Val->Pointer, _param[1]->Val->Pointer); -} - -void StringStrxfrm(struct ParseState *_parser, struct Value *_returnValue, struct Value **_param, int _numArgs) { - _returnValue->Val->Integer = strxfrm(_param[0]->Val->Pointer, _param[1]->Val->Pointer, _param[2]->Val->Integer); -} - -void StringStrdup(struct ParseState *_parser, struct Value *_returnValue, struct Value **_param, int _numArgs) { - _returnValue->Val->Pointer = strdup(_param[0]->Val->Pointer); -} - -void StringStrtok_r(struct ParseState *_parser, struct Value *_returnValue, struct Value **_param, int _numArgs) { - _returnValue->Val->Pointer = strtok_r(_param[0]->Val->Pointer, _param[1]->Val->Pointer, _param[2]->Val->Pointer); -} - -/* all string.h functions */ -struct LibraryFunction StringFunctions[] = { - { StringIndex, "char *index(char *,int);" }, - { StringRindex, "char *rindex(char *,int);" }, - { StringMemcpy, "void *memcpy(void *,void *,int);" }, - { StringMemmove, "void *memmove(void *,void *,int);" }, - { StringMemchr, "void *memchr(char *,int,int);" }, - { StringMemcmp, "int memcmp(void *,void *,int);" }, - { StringMemset, "void *memset(void *,int,int);" }, - { StringStrcat, "char *strcat(char *,char *);" }, - { StringStrncat, "char *strncat(char *,char *,int);" }, - { StringStrchr, "char *strchr(char *,int);" }, - { StringStrrchr, "char *strrchr(char *,int);" }, - { StringStrcmp, "int strcmp(char *,char *);" }, - { StringStrncmp, "int strncmp(char *,char *,int);" }, - { StringStrcoll, "int strcoll(char *,char *);" }, - { StringStrcpy, "char *strcpy(char *,char *);" }, - { StringStrncpy, "char *strncpy(char *,char *,int);" }, - { StringStrerror, "char *strerror(int);" }, - { StringStrlen, "int strlen(char *);" }, - { StringStrspn, "int strspn(char *,char *);" }, - { StringStrcspn, "int strcspn(char *,char *);" }, - { StringStrpbrk, "char *strpbrk(char *,char *);" }, - { StringStrstr, "char *strstr(char *,char *);" }, - { StringStrtok, "char *strtok(char *,char *);" }, - { StringStrxfrm, "int strxfrm(char *,char *,int);" }, - { StringStrdup, "char *strdup(char *);" }, - { StringStrtok_r, "char *strtok_r(char *,char *,char **);" }, - { NULL, NULL } -}; - -/* creates various system-dependent definitions */ -void StringSetupFunc() { - /* define NULL */ - if (!VariableDefined(TableStrRegister("NULL"))) { - VariableDefinePlatformVar(NULL, "NULL", &IntType, (union AnyValue *)&ZeroValue, FALSE); - } -} - -#endif /* !BUILTIN_MINI_STDLIB */ diff --git a/eci/cstdlib/string.h b/eci/cstdlib/string.h deleted file mode 100644 index d498bb3..0000000 --- a/eci/cstdlib/string.h +++ /dev/null @@ -1,16 +0,0 @@ -/** - * @author Edouard DUPIN - * - * @copyright 2014, Edouard DUPIN, all right reserved - * - * @license APACHE-2 (see license file) - */ - -#ifndef __ECI_STRING_H__ -#define __ECI_STRING_H__ - - -extern struct LibraryFunction StringFunctions[]; -void StringSetupFunc(); - -#endif diff --git a/eci/cstdlib/time.c b/eci/cstdlib/time.c deleted file mode 100644 index b1f5f2f..0000000 --- a/eci/cstdlib/time.c +++ /dev/null @@ -1,112 +0,0 @@ -/** - * @author Edouard DUPIN - * - * @copyright 2014, Edouard DUPIN, all right reserved - * - * @license APACHE-2 (see license file) - */ - -/* string.h library for large systems - small embedded systems use clibrary.c instead */ -#include -#include "../interpreter.h" - -#ifndef BUILTIN_MINI_STDLIB - -static int CLOCKS_PER_SECValue = CLOCKS_PER_SEC; - -#ifdef CLK_PER_SEC -static int CLK_PER_SECValue = CLK_PER_SEC; -#endif - -#ifdef CLK_TCK -static int CLK_TCKValue = CLK_TCK; -#endif - -void StdAsctime(struct ParseState *_parser, struct Value *_returnValue, struct Value **_param, int _numArgs) { - _returnValue->Val->Pointer = asctime(_param[0]->Val->Pointer); -} - -void StdClock(struct ParseState *_parser, struct Value *_returnValue, struct Value **_param, int _numArgs) { - _returnValue->Val->Integer = clock(); -} - -void StdCtime(struct ParseState *_parser, struct Value *_returnValue, struct Value **_param, int _numArgs) { - _returnValue->Val->Pointer = ctime(_param[0]->Val->Pointer); -} - -void StdDifftime(struct ParseState *_parser, struct Value *_returnValue, struct Value **_param, int _numArgs) { - _returnValue->Val->FP = difftime((time_t)_param[0]->Val->Integer, _param[1]->Val->Integer); -} - -void StdGmtime(struct ParseState *_parser, struct Value *_returnValue, struct Value **_param, int _numArgs) { - _returnValue->Val->Pointer = gmtime(_param[0]->Val->Pointer); -} - -void StdGmtime_r(struct ParseState *_parser, struct Value *_returnValue, struct Value **_param, int _numArgs) { - _returnValue->Val->Pointer = gmtime_r(_param[0]->Val->Pointer, _param[1]->Val->Pointer); -} - -void StdLocaltime(struct ParseState *_parser, struct Value *_returnValue, struct Value **_param, int _numArgs) { - _returnValue->Val->Pointer = localtime(_param[0]->Val->Pointer); -} - -void StdMktime(struct ParseState *_parser, struct Value *_returnValue, struct Value **_param, int _numArgs) { - _returnValue->Val->Integer = mktime(_param[0]->Val->Pointer); -} - -void StdTime(struct ParseState *_parser, struct Value *_returnValue, struct Value **_param, int _numArgs) { - _returnValue->Val->Integer = time(_param[0]->Val->Pointer); -} - -void StdStrftime(struct ParseState *_parser, struct Value *_returnValue, struct Value **_param, int _numArgs) { - _returnValue->Val->Integer = strftime(_param[0]->Val->Pointer, _param[1]->Val->Integer, _param[2]->Val->Pointer, _param[3]->Val->Pointer); -} - -void StdStrptime(struct ParseState *_parser, struct Value *_returnValue, struct Value **_param, int _numArgs) { - extern char *strptime(const char *s, const char *format, struct tm *tm); - _returnValue->Val->Pointer = strptime(_param[0]->Val->Pointer, _param[1]->Val->Pointer, _param[2]->Val->Pointer); -} - -void StdTimegm(struct ParseState *_parser, struct Value *_returnValue, struct Value **_param, int _numArgs) { - _returnValue->Val->Integer = timegm(_param[0]->Val->Pointer); -} - -/* handy structure definitions */ -const char StdTimeDefs[] = "\ -typedef int time_t; \ -typedef int clock_t;\ -"; - -/* all string.h functions */ -struct LibraryFunction StdTimeFunctions[] = { - { StdAsctime, "char *asctime(struct tm *);" }, - { StdClock, "time_t clock();" }, - { StdCtime, "char *ctime(int *);" }, - { StdDifftime, "double difftime(int, int);" }, - { StdGmtime, "struct tm *gmtime(int *);" }, - { StdGmtime_r, "struct tm *gmtime_r(int *, struct tm *);" }, - { StdLocaltime, "struct tm *localtime(int *);" }, - { StdMktime, "int mktime(struct tm *ptm);" }, - { StdTime, "int time(int *);" }, - { StdStrftime, "int strftime(char *, int, char *, struct tm *);" }, - { StdStrptime, "char *strptime(char *, char *, struct tm *);" }, - { StdTimegm, "int timegm(struct tm *);" }, - { NULL, NULL } -}; - - -/* creates various system-dependent definitions */ -void StdTimeSetupFunc() { - /* make a "struct tm" which is the same size as a native tm structure */ - TypeCreateOpaqueStruct(NULL, TableStrRegister("tm"), sizeof(struct tm)); - /* define CLK_PER_SEC etc. */ - VariableDefinePlatformVar(NULL, "CLOCKS_PER_SEC", &IntType, (union AnyValue *)&CLOCKS_PER_SECValue, FALSE); -#ifdef CLK_PER_SEC - VariableDefinePlatformVar(NULL, "CLK_PER_SEC", &IntType, (union AnyValue *)&CLK_PER_SECValue, FALSE); -#endif -#ifdef CLK_TCK - VariableDefinePlatformVar(NULL, "CLK_TCK", &IntType, (union AnyValue *)&CLK_TCKValue, FALSE); -#endif -} - -#endif diff --git a/eci/cstdlib/time.h b/eci/cstdlib/time.h deleted file mode 100644 index 7f01a57..0000000 --- a/eci/cstdlib/time.h +++ /dev/null @@ -1,16 +0,0 @@ -/** - * @author Edouard DUPIN - * - * @copyright 2014, Edouard DUPIN, all right reserved - * - * @license APACHE-2 (see license file) - */ - -#ifndef __ECI_TIME_H__ -#define __ECI_TIME_H__ - -extern const char StdTimeDefs[]; -extern struct LibraryFunction StdTimeFunctions[]; -void StdTimeSetupFunc(); - -#endif diff --git a/eci/cstdlib/unistd.c b/eci/cstdlib/unistd.c deleted file mode 100644 index 3f014dd..0000000 --- a/eci/cstdlib/unistd.c +++ /dev/null @@ -1,381 +0,0 @@ -/** - * @author Edouard DUPIN - * - * @copyright 2014, Edouard DUPIN, all right reserved - * - * @license APACHE-2 (see license file) - */ - -/* stdlib.h library for large systems - small embedded systems use clibrary.c instead */ -#include -#include -#include -#include "../interpreter.h" - -#ifndef BUILTIN_MINI_STDLIB - -static int ZeroValue = 0; - -void UnistdAccess(struct ParseState *_parser, struct Value *_returnValue, struct Value **_param, int _numArgs) { - _returnValue->Val->Integer = access(_param[0]->Val->Pointer, _param[1]->Val->Integer); -} - -void UnistdAlarm(struct ParseState *_parser, struct Value *_returnValue, struct Value **_param, int _numArgs) { - _returnValue->Val->Integer = alarm(_param[0]->Val->Integer); -} - -void UnistdChdir(struct ParseState *_parser, struct Value *_returnValue, struct Value **_param, int _numArgs) { - _returnValue->Val->Integer = chdir(_param[0]->Val->Pointer); -} - -void UnistdChroot(struct ParseState *_parser, struct Value *_returnValue, struct Value **_param, int _numArgs) { - _returnValue->Val->Integer = chroot(_param[0]->Val->Pointer); -} - -void UnistdChown(struct ParseState *_parser, struct Value *_returnValue, struct Value **_param, int _numArgs) { - _returnValue->Val->Integer = chown(_param[0]->Val->Pointer, _param[1]->Val->Integer, _param[2]->Val->Integer); -} - -void UnistdClose(struct ParseState *_parser, struct Value *_returnValue, struct Value **_param, int _numArgs) { - _returnValue->Val->Integer = close(_param[0]->Val->Integer); -} - -void UnistdConfstr(struct ParseState *_parser, struct Value *_returnValue, struct Value **_param, int _numArgs) { - _returnValue->Val->Integer = confstr(_param[0]->Val->Integer, _param[1]->Val->Pointer, _param[2]->Val->Integer); -} - -void UnistdCtermid(struct ParseState *_parser, struct Value *_returnValue, struct Value **_param, int _numArgs) { - _returnValue->Val->Pointer = ctermid(_param[0]->Val->Pointer); -} - -void UnistdDup(struct ParseState *_parser, struct Value *_returnValue, struct Value **_param, int _numArgs) { - _returnValue->Val->Integer = dup(_param[0]->Val->Integer); -} - -void UnistdDup2(struct ParseState *_parser, struct Value *_returnValue, struct Value **_param, int _numArgs) { - _returnValue->Val->Integer = dup2(_param[0]->Val->Integer, _param[1]->Val->Integer); -} - -void Unistd_Exit(struct ParseState *_parser, struct Value *_returnValue, struct Value **_param, int _numArgs) { - _exit(_param[0]->Val->Integer); -} - -void UnistdFchown(struct ParseState *_parser, struct Value *_returnValue, struct Value **_param, int _numArgs) { - _returnValue->Val->Integer = fchown(_param[0]->Val->Integer, _param[1]->Val->Integer, _param[2]->Val->Integer); -} - -void UnistdFchdir(struct ParseState *_parser, struct Value *_returnValue, struct Value **_param, int _numArgs) { - _returnValue->Val->Integer = fchdir(_param[0]->Val->Integer); -} - -void UnistdFdatasync(struct ParseState *_parser, struct Value *_returnValue, struct Value **_param, int _numArgs) { - _returnValue->Val->Integer = fdatasync(_param[0]->Val->Integer); -} - -void UnistdFork(struct ParseState *_parser, struct Value *_returnValue, struct Value **_param, int _numArgs) { - _returnValue->Val->Integer = fork(); -} - -void UnistdFpathconf(struct ParseState *_parser, struct Value *_returnValue, struct Value **_param, int _numArgs) { - _returnValue->Val->Integer = fpathconf(_param[0]->Val->Integer, _param[1]->Val->Integer); -} - -void UnistdFsync(struct ParseState *_parser, struct Value *_returnValue, struct Value **_param, int _numArgs) { - _returnValue->Val->Integer = fsync(_param[0]->Val->Integer); -} - -void UnistdFtruncate(struct ParseState *_parser, struct Value *_returnValue, struct Value **_param, int _numArgs) { - _returnValue->Val->Integer = ftruncate(_param[0]->Val->Integer, _param[1]->Val->Integer); -} - -void UnistdGetcwd(struct ParseState *_parser, struct Value *_returnValue, struct Value **_param, int _numArgs) { - _returnValue->Val->Pointer = getcwd(_param[0]->Val->Pointer, _param[1]->Val->Integer); -} - -void UnistdGetdtablesize(struct ParseState *_parser, struct Value *_returnValue, struct Value **_param, int _numArgs) { - _returnValue->Val->Integer = getdtablesize(); -} - -void UnistdGetegid(struct ParseState *_parser, struct Value *_returnValue, struct Value **_param, int _numArgs) { - _returnValue->Val->Integer = getegid(); -} - -void UnistdGeteuid(struct ParseState *_parser, struct Value *_returnValue, struct Value **_param, int _numArgs) { - _returnValue->Val->Integer = geteuid(); -} - -void UnistdGetgid(struct ParseState *_parser, struct Value *_returnValue, struct Value **_param, int _numArgs) { - _returnValue->Val->Integer = getgid(); -} - -void UnistdGethostid(struct ParseState *_parser, struct Value *_returnValue, struct Value **_param, int _numArgs) { - _returnValue->Val->Integer = gethostid(); -} - -void UnistdGetlogin(struct ParseState *_parser, struct Value *_returnValue, struct Value **_param, int _numArgs) { - _returnValue->Val->Pointer = getlogin(); -} - -void UnistdGetlogin_r(struct ParseState *_parser, struct Value *_returnValue, struct Value **_param, int _numArgs) { - _returnValue->Val->Integer = getlogin_r(_param[0]->Val->Pointer, _param[1]->Val->Integer); -} - -void UnistdGetpagesize(struct ParseState *_parser, struct Value *_returnValue, struct Value **_param, int _numArgs) { - _returnValue->Val->Integer = getpagesize(); -} - -void UnistdGetpass(struct ParseState *_parser, struct Value *_returnValue, struct Value **_param, int _numArgs) { - _returnValue->Val->Pointer = getpass(_param[0]->Val->Pointer); -} - -void UnistdGetpgrp(struct ParseState *_parser, struct Value *_returnValue, struct Value **_param, int _numArgs) { - _returnValue->Val->Integer = getpgrp(); -} - -void UnistdGetpid(struct ParseState *_parser, struct Value *_returnValue, struct Value **_param, int _numArgs) { - _returnValue->Val->Integer = getpid(); -} - -void UnistdGetppid(struct ParseState *_parser, struct Value *_returnValue, struct Value **_param, int _numArgs) { - _returnValue->Val->Integer = getppid(); -} - -void UnistdGetuid(struct ParseState *_parser, struct Value *_returnValue, struct Value **_param, int _numArgs) { - _returnValue->Val->Integer = getuid(); -} - -void UnistdGetwd(struct ParseState *_parser, struct Value *_returnValue, struct Value **_param, int _numArgs) { - _returnValue->Val->Pointer = getcwd(_param[0]->Val->Pointer, PATH_MAX); -} - -void UnistdIsatty(struct ParseState *_parser, struct Value *_returnValue, struct Value **_param, int _numArgs) { - _returnValue->Val->Integer = isatty(_param[0]->Val->Integer); -} - -void UnistdLchown(struct ParseState *_parser, struct Value *_returnValue, struct Value **_param, int _numArgs) { - _returnValue->Val->Integer = lchown(_param[0]->Val->Pointer, _param[1]->Val->Integer, _param[2]->Val->Integer); -} - -void UnistdLink(struct ParseState *_parser, struct Value *_returnValue, struct Value **_param, int _numArgs) { - _returnValue->Val->Integer = link(_param[0]->Val->Pointer, _param[1]->Val->Pointer); -} - -void UnistdLockf(struct ParseState *_parser, struct Value *_returnValue, struct Value **_param, int _numArgs) { - _returnValue->Val->Integer = lockf(_param[0]->Val->Integer, _param[1]->Val->Integer, _param[2]->Val->Integer); -} - -void UnistdLseek(struct ParseState *_parser, struct Value *_returnValue, struct Value **_param, int _numArgs) { - _returnValue->Val->Integer = lseek(_param[0]->Val->Integer, _param[1]->Val->Integer, _param[2]->Val->Integer); -} - -void UnistdNice(struct ParseState *_parser, struct Value *_returnValue, struct Value **_param, int _numArgs) { - _returnValue->Val->Integer = nice(_param[0]->Val->Integer); -} - -void UnistdPathconf(struct ParseState *_parser, struct Value *_returnValue, struct Value **_param, int _numArgs) { - _returnValue->Val->Integer = pathconf(_param[0]->Val->Pointer, _param[1]->Val->Integer); -} - -void UnistdPause(struct ParseState *_parser, struct Value *_returnValue, struct Value **_param, int _numArgs) { - _returnValue->Val->Integer = pause(); -} - -void UnistdRead(struct ParseState *_parser, struct Value *_returnValue, struct Value **_param, int _numArgs) { - _returnValue->Val->Integer = read(_param[0]->Val->Integer, _param[1]->Val->Pointer, _param[2]->Val->Integer); -} - -void UnistdReadlink(struct ParseState *_parser, struct Value *_returnValue, struct Value **_param, int _numArgs) { - _returnValue->Val->Integer = readlink(_param[0]->Val->Pointer, _param[1]->Val->Pointer, _param[2]->Val->Integer); -} - -void UnistdRmdir(struct ParseState *_parser, struct Value *_returnValue, struct Value **_param, int _numArgs) { - _returnValue->Val->Integer = rmdir(_param[0]->Val->Pointer); -} - -void UnistdSbrk(struct ParseState *_parser, struct Value *_returnValue, struct Value **_param, int _numArgs) { - _returnValue->Val->Pointer = sbrk(_param[0]->Val->Integer); -} - -void UnistdSetgid(struct ParseState *_parser, struct Value *_returnValue, struct Value **_param, int _numArgs) { - _returnValue->Val->Integer = setgid(_param[0]->Val->Integer); -} - -void UnistdSetpgid(struct ParseState *_parser, struct Value *_returnValue, struct Value **_param, int _numArgs) { - _returnValue->Val->Integer = setpgid(_param[0]->Val->Integer, _param[1]->Val->Integer); -} - -void UnistdSetpgrp(struct ParseState *_parser, struct Value *_returnValue, struct Value **_param, int _numArgs) { - _returnValue->Val->Integer = setpgrp(); -} - -void UnistdSetregid(struct ParseState *_parser, struct Value *_returnValue, struct Value **_param, int _numArgs) { - _returnValue->Val->Integer = setregid(_param[0]->Val->Integer, _param[1]->Val->Integer); -} - -void UnistdSetreuid(struct ParseState *_parser, struct Value *_returnValue, struct Value **_param, int _numArgs) { - _returnValue->Val->Integer = setreuid(_param[0]->Val->Integer, _param[1]->Val->Integer); -} - -void UnistdSetsid(struct ParseState *_parser, struct Value *_returnValue, struct Value **_param, int _numArgs) { - _returnValue->Val->Integer = setsid(); -} - -void UnistdSetuid(struct ParseState *_parser, struct Value *_returnValue, struct Value **_param, int _numArgs) { - _returnValue->Val->Integer = setuid(_param[0]->Val->Integer); -} - -void UnistdSleep(struct ParseState *_parser, struct Value *_returnValue, struct Value **_param, int _numArgs) { - _returnValue->Val->Integer = sleep(_param[0]->Val->Integer); -} - -void UnistdSymlink(struct ParseState *_parser, struct Value *_returnValue, struct Value **_param, int _numArgs) { - _returnValue->Val->Integer = symlink(_param[0]->Val->Pointer, _param[1]->Val->Pointer); -} - -void UnistdSync(struct ParseState *_parser, struct Value *_returnValue, struct Value **_param, int _numArgs) { - sync(); -} - -void UnistdSysconf(struct ParseState *_parser, struct Value *_returnValue, struct Value **_param, int _numArgs) { - _returnValue->Val->Integer = sysconf(_param[0]->Val->Integer); -} - -void UnistdTcgetpgrp(struct ParseState *_parser, struct Value *_returnValue, struct Value **_param, int _numArgs) { - _returnValue->Val->Integer = tcgetpgrp(_param[0]->Val->Integer); -} - -void UnistdTcsetpgrp(struct ParseState *_parser, struct Value *_returnValue, struct Value **_param, int _numArgs) { - _returnValue->Val->Integer = tcsetpgrp(_param[0]->Val->Integer, _param[1]->Val->Integer); -} - -void UnistdTruncate(struct ParseState *_parser, struct Value *_returnValue, struct Value **_param, int _numArgs) { - _returnValue->Val->Integer = truncate(_param[0]->Val->Pointer, _param[1]->Val->Integer); -} - -void UnistdTtyname(struct ParseState *_parser, struct Value *_returnValue, struct Value **_param, int _numArgs) { - _returnValue->Val->Pointer = ttyname(_param[0]->Val->Integer); -} - -void UnistdTtyname_r(struct ParseState *_parser, struct Value *_returnValue, struct Value **_param, int _numArgs) { - _returnValue->Val->Integer = ttyname_r(_param[0]->Val->Integer, _param[1]->Val->Pointer, _param[2]->Val->Integer); -} - -void UnistdUalarm(struct ParseState *_parser, struct Value *_returnValue, struct Value **_param, int _numArgs) { - _returnValue->Val->Integer = ualarm(_param[0]->Val->Integer, _param[1]->Val->Integer); -} - -void UnistdUnlink(struct ParseState *_parser, struct Value *_returnValue, struct Value **_param, int _numArgs) { - _returnValue->Val->Integer = unlink(_param[0]->Val->Pointer); -} - -void UnistdUsleep(struct ParseState *_parser, struct Value *_returnValue, struct Value **_param, int _numArgs) { - _returnValue->Val->Integer = usleep(_param[0]->Val->Integer); -} - -void UnistdVfork(struct ParseState *_parser, struct Value *_returnValue, struct Value **_param, int _numArgs) { - _returnValue->Val->Integer = vfork(); -} - -void UnistdWrite(struct ParseState *_parser, struct Value *_returnValue, struct Value **_param, int _numArgs) { - _returnValue->Val->Integer = write(_param[0]->Val->Integer, _param[1]->Val->Pointer, _param[2]->Val->Integer); -} - - -/* handy structure definitions */ -const char UnistdDefs[] = "\ -typedef int uid_t; \ -typedef int gid_t; \ -typedef int pid_t; \ -typedef int off_t; \ -typedef int size_t; \ -typedef int ssize_t; \ -typedef int useconds_t;\ -typedef int intptr_t;\ -"; - -/* all unistd.h functions */ -struct LibraryFunction UnistdFunctions[] = { - { UnistdAccess, "int access(char *, int);" }, - { UnistdAlarm, "unsigned int alarm(unsigned int);" }, - { UnistdChdir, "int chdir(char *);" }, - { UnistdChroot, "int chroot(char *);" }, - { UnistdChown, "int chown(char *, uid_t, gid_t);" }, - { UnistdClose, "int close(int);" }, - { UnistdConfstr, "size_t confstr(int, char *, size_t);" }, - { UnistdCtermid, "char *ctermid(char *);" }, - { UnistdDup, "int dup(int);" }, - { UnistdDup2, "int dup2(int, int);" }, - { Unistd_Exit, "void _exit(int);" }, - { UnistdFchown, "int fchown(int, uid_t, gid_t);" }, - { UnistdFchdir, "int fchdir(int);" }, - { UnistdFdatasync, "int fdatasync(int);" }, - { UnistdFork, "pid_t fork(void);" }, - { UnistdFpathconf, "long fpathconf(int, int);" }, - { UnistdFsync, "int fsync(int);" }, - { UnistdFtruncate, "int ftruncate(int, off_t);" }, - { UnistdGetcwd, "char *getcwd(char *, size_t);" }, - { UnistdGetdtablesize, "int getdtablesize(void);" }, - { UnistdGetegid, "gid_t getegid(void);" }, - { UnistdGeteuid, "uid_t geteuid(void);" }, - { UnistdGetgid, "gid_t getgid(void);" }, - { UnistdGethostid, "long gethostid(void);" }, - { UnistdGetlogin, "char *getlogin(void);" }, - { UnistdGetlogin_r, "int getlogin_r(char *, size_t);" }, - { UnistdGetpagesize, "int getpagesize(void);" }, - { UnistdGetpass, "char *getpass(char *);" }, - { UnistdGetpgrp, "pid_t getpgrp(void);" }, - { UnistdGetpid, "pid_t getpid(void);" }, - { UnistdGetppid, "pid_t getppid(void);" }, - { UnistdGetuid, "uid_t getuid(void);" }, - { UnistdGetwd, "char *getwd(char *);" }, - { UnistdIsatty, "int isatty(int);" }, - { UnistdLchown, "int lchown(char *, uid_t, gid_t);" }, - { UnistdLink, "int link(char *, char *);" }, - { UnistdLockf, "int lockf(int, int, off_t);" }, - { UnistdLseek, "off_t lseek(int, off_t, int);" }, - { UnistdNice, "int nice(int);" }, - { UnistdPathconf, "long pathconf(char *, int);" }, - { UnistdPause, "int pause(void);" }, - { UnistdRead, "ssize_t read(int, void *, size_t);" }, - { UnistdReadlink, "int readlink(char *, char *, size_t);" }, - { UnistdRmdir, "int rmdir(char *);" }, - { UnistdSbrk, "void *sbrk(intptr_t);" }, - { UnistdSetgid, "int setgid(gid_t);" }, - { UnistdSetpgid, "int setpgid(pid_t, pid_t);" }, - { UnistdSetpgrp, "pid_t setpgrp(void);" }, - { UnistdSetregid, "int setregid(gid_t, gid_t);" }, - { UnistdSetreuid, "int setreuid(uid_t, uid_t);" }, - { UnistdSetsid, "pid_t setsid(void);" }, - { UnistdSetuid, "int setuid(uid_t);" }, - { UnistdSleep, "unsigned int sleep(unsigned int);" }, - { UnistdSymlink, "int symlink(char *, char *);" }, - { UnistdSync, "void sync(void);" }, - { UnistdSysconf, "long sysconf(int);" }, - { UnistdTcgetpgrp, "pid_t tcgetpgrp(int);" }, - { UnistdTcsetpgrp, "int tcsetpgrp(int, pid_t);" }, - { UnistdTruncate, "int truncate(char *, off_t);" }, - { UnistdTtyname, "char *ttyname(int);" }, - { UnistdTtyname_r, "int ttyname_r(int, char *, size_t);" }, - { UnistdUalarm, "useconds_t ualarm(useconds_t, useconds_t);" }, - { UnistdUnlink, "int unlink(char *);" }, - { UnistdUsleep, "int usleep(useconds_t);" }, - { UnistdVfork, "pid_t vfork(void);" }, - { UnistdWrite, "ssize_t write(int, void *, size_t);" }, - { NULL, NULL } -}; - -/* creates various system-dependent definitions */ -void UnistdSetupFunc() { - /* define NULL */ - if (!VariableDefined(TableStrRegister("NULL"))) { - VariableDefinePlatformVar(NULL, "NULL", &IntType, (union AnyValue *)&ZeroValue, FALSE); - } - /* define optarg and friends */ - VariableDefinePlatformVar(NULL, "optarg", CharPtrType, (union AnyValue *)&optarg, TRUE); - VariableDefinePlatformVar(NULL, "optind", &IntType, (union AnyValue *)&optind, TRUE); - VariableDefinePlatformVar(NULL, "opterr", &IntType, (union AnyValue *)&opterr, TRUE); - VariableDefinePlatformVar(NULL, "optopt", &IntType, (union AnyValue *)&optopt, TRUE); -} - -#endif /* !BUILTIN_MINI_STDLIB */ - diff --git a/eci/cstdlib/unistd.h b/eci/cstdlib/unistd.h deleted file mode 100644 index 6cd20dd..0000000 --- a/eci/cstdlib/unistd.h +++ /dev/null @@ -1,17 +0,0 @@ -/** - * @author Edouard DUPIN - * - * @copyright 2014, Edouard DUPIN, all right reserved - * - * @license APACHE-2 (see license file) - */ - -#ifndef __ECI_UNI_STD_H__ -#define __ECI_UNI_STD_H__ - - -extern const char UnistdDefs[]; -extern struct LibraryFunction UnistdFunctions[]; -void UnistdSetupFunc(); - -#endif diff --git a/eci/debug.cpp b/eci/debug.cpp new file mode 100644 index 0000000..fe3d930 --- /dev/null +++ b/eci/debug.cpp @@ -0,0 +1,14 @@ +/** + * @author Edouard DUPIN + * + * @copyright 2011, Edouard DUPIN, all right reserved + * + * @license APACHE-2 (see license file) + */ + +#include + +int32_t eci::getLogId() { + static int32_t g_val = etk::log::registerInstance("eci"); + return g_val; +} diff --git a/eci/debug.h b/eci/debug.h new file mode 100644 index 0000000..1407f57 --- /dev/null +++ b/eci/debug.h @@ -0,0 +1,52 @@ +/** + * @author Edouard DUPIN + * + * @copyright 2011, Edouard DUPIN, all right reserved + * + * @license APACHE-2 (see license file) + */ + +#ifndef __ECI_DEBUG_H__ +#define __ECI_DEBUG_H__ + +#include + +namespace eci { + int32_t getLogId(); +}; +// TODO : Review this problem of multiple intanciation of "std::stringbuf sb" +#define ECI_BASE(info,data) \ + do { \ + if (info <= etk::log::getLevel(eci::getLogId())) { \ + std::stringbuf sb; \ + std::ostream tmpStream(&sb); \ + tmpStream << data; \ + etk::log::logStream(eci::getLogId(), info, __LINE__, __class__, __func__, tmpStream); \ + } \ + } while(0) + +#define ECI_CRITICAL(data) ECI_BASE(1, data) +#define ECI_ERROR(data) ECI_BASE(2, data) +#define ECI_WARNING(data) ECI_BASE(3, data) +#ifdef DEBUG + #define ECI_INFO(data) ECI_BASE(4, data) + #define ECI_DEBUG(data) ECI_BASE(5, data) + #define ECI_VERBOSE(data) ECI_BASE(6, data) + #define ECI_TODO(data) ECI_BASE(4, "TODO : " << data) +#else + #define ECI_INFO(data) do { } while(false) + #define ECI_DEBUG(data) do { } while(false) + #define ECI_VERBOSE(data) do { } while(false) + #define ECI_TODO(data) do { } while(false) +#endif + +#define ECI_ASSERT(cond,data) \ + do { \ + if (!(cond)) { \ + ECI_CRITICAL(data); \ + assert(!#cond); \ + } \ + } while (0) + +#endif + diff --git a/eci/eci.cpp b/eci/eci.cpp new file mode 100644 index 0000000..e6dd70d --- /dev/null +++ b/eci/eci.cpp @@ -0,0 +1,25 @@ +/** + * @author Edouard DUPIN + * + * @copyright 2014, Edouard DUPIN, all right reserved + * + * @license APACHE-2 (see license file) + */ + +#include +#include +#include +#include + +int main(int argc, char** argv) { + ECI_INFO("Start Application interpeter languages"); + if (argc<=1) { + ECI_CRITICAL("need the file to parse"); + return -1; + } + eci::ParserCpp tmpParser; + std::string data = etk::FSNodeReadAllData(argv[1]); + tmpParser.parse(data); + + return 0; +} \ No newline at end of file diff --git a/eci/cstdlib/errno.h b/eci/eci.h similarity index 65% rename from eci/cstdlib/errno.h rename to eci/eci.h index 71bcaf6..f194249 100644 --- a/eci/cstdlib/errno.h +++ b/eci/eci.h @@ -6,9 +6,7 @@ * @license APACHE-2 (see license file) */ -#ifndef __ECI_ERRNO_H__ -#define __ECI_ERRNO_H__ - -void StdErrnoSetupFunc(); +#ifndef __ECI_H__ +#define __ECI_H__ #endif diff --git a/eci/expression.c b/eci/expression.c deleted file mode 100644 index f60a68a..0000000 --- a/eci/expression.c +++ /dev/null @@ -1,1529 +0,0 @@ -/** - * @author Edouard DUPIN - * - * @copyright 2014, Edouard DUPIN, all right reserved - * - * @license APACHE-2 (see license file) - */ - -#include "interpreter.h" - - -/* whether evaluation is left to right for a given precedence level */ -#define IS_LEFT_TO_RIGHT(p) ((p) != 2 && (p) != 14) -#define BRACKET_PRECEDENCE 20 -#define IS_TYPE_TOKEN(t) ((t) >= TokenIntType && (t) <= TokenUnsignedType) - -#define DEEP_PRECEDENCE (BRACKET_PRECEDENCE*1000) - -#ifdef DEBUG_EXPRESSIONS -#define debugf printf -#else -void debugf(char *Format, ...) { -} -#endif - -/* local prototypes */ -enum OperatorOrder { - OrderNone, - OrderPrefix, - OrderInfix, - OrderPostfix -}; - -/* a stack of expressions we use in evaluation */ -struct ExpressionStack -{ - struct ExpressionStack *Next; /* the next lower item on the stack */ - struct Value *Val; /* the value for this stack node */ - enum LexToken Op; /* the operator */ - short unsigned int Precedence; /* the operator precedence of this node */ - unsigned char Order; /* the evaluation order of this operator */ -}; - -/* operator precedence definitions */ -struct OpPrecedence { - unsigned int PrefixPrecedence:4; - unsigned int PostfixPrecedence:4; - unsigned int InfixPrecedence:4; - char *Name; -}; - -/* NOTE: the order of this array must correspond exactly to the order of these tokens in enum LexToken */ -static struct OpPrecedence OperatorPrecedence[] = -{ - /* TokenNone, */ { 0, 0, 0, "none" }, - /* TokenComma, */ { 0, 0, 0, "," }, - /* TokenAssign, */ { 0, 0, 2, "=" }, - /* TokenAddAssign, */ { 0, 0, 2, "+=" }, - /* TokenSubtractAssign, */ { 0, 0, 2, "-=" }, - /* TokenMultiplyAssign, */ { 0, 0, 2, "*=" }, - /* TokenDivideAssign, */ { 0, 0, 2, "/=" }, - /* TokenModulusAssign, */ { 0, 0, 2, "%=" }, - /* TokenShiftLeftAssign, */ { 0, 0, 2, "<<=" }, - /* TokenShiftRightAssign, */ { 0, 0, 2, ">>=" }, - /* TokenArithmeticAndAssign, */ { 0, 0, 2, "&=" }, - /* TokenArithmeticOrAssign, */ { 0, 0, 2, "|=" }, - /* TokenArithmeticExorAssign, */ { 0, 0, 2, "^=" }, - /* TokenQuestionMark, */ { 0, 0, 3, "?" }, - /* TokenColon, */ { 0, 0, 3, ":" }, - /* TokenLogicalOr, */ { 0, 0, 4, "||" }, - /* TokenLogicalAnd, */ { 0, 0, 5, "&&" }, - /* TokenArithmeticOr, */ { 0, 0, 6, "|" }, - /* TokenArithmeticExor, */ { 0, 0, 7, "^" }, - /* TokenAmpersand, */ { 14, 0, 8, "&" }, - /* TokenEqual, */ { 0, 0, 9, "==" }, - /* TokenNotEqual, */ { 0, 0, 9, "!=" }, - /* TokenLessThan, */ { 0, 0, 10, "<" }, - /* TokenGreaterThan, */ { 0, 0, 10, ">" }, - /* TokenLessEqual, */ { 0, 0, 10, "<=" }, - /* TokenGreaterEqual, */ { 0, 0, 10, ">=" }, - /* TokenShiftLeft, */ { 0, 0, 11, "<<" }, - /* TokenShiftRight, */ { 0, 0, 11, ">>" }, - /* TokenPlus, */ { 14, 0, 12, "+" }, - /* TokenMinus, */ { 14, 0, 12, "-" }, - /* TokenAsterisk, */ { 14, 0, 13, "*" }, - /* TokenSlash, */ { 0, 0, 13, "/" }, - /* TokenModulus, */ { 0, 0, 13, "%" }, - /* TokenIncrement, */ { 14, 15, 0, "++" }, - /* TokenDecrement, */ { 14, 15, 0, "--" }, - /* TokenUnaryNot, */ { 14, 0, 0, "!" }, - /* TokenUnaryExor, */ { 14, 0, 0, "~" }, - /* TokenSizeof, */ { 14, 0, 0, "sizeof" }, - /* TokenCast, */ { 14, 0, 0, "cast" }, - /* TokenLeftSquareBracket, */ { 0, 0, 15, "[" }, - /* TokenRightSquareBracket, */ { 0, 15, 0, "]" }, - /* TokenDot, */ { 0, 0, 15, "." }, - /* TokenArrow, */ { 0, 0, 15, "->" }, - /* TokenOpenBracket, */ { 15, 0, 0, "(" }, - /* TokenCloseBracket, */ { 0, 15, 0, ")" } -}; - -void ExpressionParseFunctionCall(struct ParseState *_parser, struct ExpressionStack **_stackTop, const char *_funcName, int _runIt); - -#ifdef DEBUG_EXPRESSIONS -/* show the contents of the expression stack */ -void ExpressionStackShow(struct ExpressionStack *_stackTop) { - printf("Expression stack [0x%lx,0x%lx]: ", (long)HeapStackTop, (long)_stackTop); - - while (_stackTop != NULL) { - if (_stackTop->Order == OrderNone) { - /* it's a value */ - if (_stackTop->Val->IsLValue) { - printf("lvalue="); - }else { - printf("value="); - } - switch (_stackTop->Val->Typ->Base) { - case TypeVoid: printf("void"); break; - case TypeInt: printf("%d:int", _stackTop->Val->Val->Integer); break; - case TypeShort: printf("%d:short", _stackTop->Val->Val->ShortInteger); break; - case TypeChar: printf("%d:char", _stackTop->Val->Val->Character); break; - case TypeLong: printf("%d:long", _stackTop->Val->Val->LongInteger); break; - case TypeUnsignedShort: printf("%d:unsigned short", _stackTop->Val->Val->UnsignedShortInteger); break; - case TypeUnsignedInt: printf("%d:unsigned int", _stackTop->Val->Val->UnsignedInteger); break; - case TypeUnsignedLong: printf("%d:unsigned long", _stackTop->Val->Val->UnsignedLongInteger); break; - case TypeFP: printf("%f:fp", _stackTop->Val->Val->FP); break; - case TypeFunction: printf("%s:function", _stackTop->Val->Val->Identifier); break; - case TypeMacro: printf("%s:macro", _stackTop->Val->Val->Identifier); break; - case TypePointer: - if (_stackTop->Val->Val->Pointer == NULL) - printf("ptr(NULL)"); - else if (_stackTop->Val->Typ->FromType->Base == TypeChar) - printf("\"%s\":string", (char *)_stackTop->Val->Val->Pointer); - else - printf("ptr(0x%lx)", (long)_stackTop->Val->Val->Pointer); - break; - case TypeArray: printf("array"); break; - case TypeStruct: printf("%s:struct", _stackTop->Val->Val->Identifier); break; - case TypeUnion: printf("%s:union", _stackTop->Val->Val->Identifier); break; - case TypeEnum: printf("%s:enum", _stackTop->Val->Val->Identifier); break; - case Type_Type: PrintType(_stackTop->Val->Val->Typ, CStdOut); printf(":type"); break; - default: printf("unknown"); break; - } - printf("[0x%lx,0x%lx]", (long)_stackTop, (long)_stackTop->Val); - } else { - /* it's an operator */ - printf("op='%s' %s %d", OperatorPrecedence[(int)_stackTop->Op].Name, - (_stackTop->Order == OrderPrefix) ? "prefix" : ((_stackTop->Order == OrderPostfix) ? "postfix" : "infix"), - _stackTop->Precedence); - printf("[0x%lx]", (long)_stackTop); - } - _stackTop = _stackTop->Next; - if (_stackTop != NULL) { - printf(", "); - } - } - printf("\n"); -} -#endif - -long ExpressionCoerceInteger(struct Value *_value) { - switch (_value->Typ->Base) { - case TypeInt: - return (long)_value->Val->Integer; - case TypeChar: - return (long)_value->Val->Character; - case TypeShort: - return (long)_value->Val->ShortInteger; - case TypeLong: - return (long)_value->Val->LongInteger; - case TypeUnsignedInt: - return (long)_value->Val->UnsignedInteger; - case TypeUnsignedShort: - return (long)_value->Val->UnsignedShortInteger; - case TypeUnsignedLong: - return (long)_value->Val->UnsignedLongInteger; - case TypePointer: - return (long)_value->Val->Pointer; - case TypeFP: - return (long)_value->Val->FP; - default: - return 0; - } -} - -unsigned long ExpressionCoerceUnsignedInteger(struct Value *_value) { - switch (_value->Typ->Base) { - case TypeInt: - return (unsigned long)_value->Val->Integer; - case TypeChar: - return (unsigned long)_value->Val->Character; - case TypeShort: - return (unsigned long)_value->Val->ShortInteger; - case TypeLong: - return (unsigned long)_value->Val->LongInteger; - case TypeUnsignedInt: - return (unsigned long)_value->Val->UnsignedInteger; - case TypeUnsignedShort: - return (unsigned long)_value->Val->UnsignedShortInteger; - case TypeUnsignedLong: - return (unsigned long)_value->Val->UnsignedLongInteger; - case TypePointer: - return (unsigned long)_value->Val->Pointer; - case TypeFP: - return (unsigned long)_value->Val->FP; - default: - return 0; - } -} - -double ExpressionCoerceFP(struct Value *_value) { - switch (_value->Typ->Base) { - case TypeInt: - return (double)_value->Val->Integer; - case TypeChar: - return (double)_value->Val->Character; - case TypeShort: - return (double)_value->Val->ShortInteger; - case TypeLong: - return (double)_value->Val->LongInteger; - case TypeUnsignedInt: - return (double)_value->Val->UnsignedInteger; - case TypeUnsignedShort: - return (double)_value->Val->UnsignedShortInteger; - case TypeUnsignedLong: - return (double)_value->Val->UnsignedLongInteger; - case TypeFP: - return (double)_value->Val->FP; - default: - return 0.0; - } -} - -/* assign an integer value */ -long ExpressionAssignInt(struct ParseState *_parser, struct Value *_destValue, long _fromInt, int _after) { - long Result; - if (!_destValue->IsLValue) { - ProgramFail(_parser, "can't assign to this"); - } - if (_after) { - Result = ExpressionCoerceInteger(_destValue); - } else { - Result = _fromInt; - } - switch (_destValue->Typ->Base) { - case TypeInt: - _destValue->Val->Integer = _fromInt; - break; - case TypeShort: - _destValue->Val->ShortInteger = (short)_fromInt; - break; - case TypeChar: - _destValue->Val->Character = (unsigned char)_fromInt; - break; - case TypeLong: - _destValue->Val->LongInteger = (long)_fromInt; - break; - case TypeUnsignedInt: - _destValue->Val->UnsignedInteger = (unsigned int)_fromInt; - break; - case TypeUnsignedShort: - _destValue->Val->UnsignedShortInteger = (unsigned short)_fromInt; - break; - case TypeUnsignedLong: - _destValue->Val->UnsignedLongInteger = (unsigned long)_fromInt; - break; - default: - break; - } - return Result; -} - -/* assign a floating point value */ -double ExpressionAssignFP(struct ParseState *_parser, struct Value *_destValue, double _fromFP) { - if (!_destValue->IsLValue) { - ProgramFail(_parser, "can't assign to this"); - } - _destValue->Val->FP = _fromFP; - return _fromFP; -} - -/* push a node on to the expression stack */ -void ExpressionStackPushValueNode(struct ParseState *_parser, struct ExpressionStack **_stackTop, struct Value *_valueLoc) { - struct ExpressionStack *StackNode = VariableAlloc(_parser, sizeof(struct ExpressionStack), FALSE); - StackNode->Next = *_stackTop; - StackNode->Val = _valueLoc; - *_stackTop = StackNode; -#ifdef FANCY_ERROR_MESSAGES - StackNode->Line = _parser->Line; - StackNode->CharacterPos = _parser->CharacterPos; -#endif -#ifdef DEBUG_EXPRESSIONS - ExpressionStackShow(*_stackTop); -#endif -} - -/* push a blank value on to the expression stack by type */ -struct Value *ExpressionStackPushValueByType(struct ParseState *_parser, - struct ExpressionStack **_stackTop, - struct ValueType *_pushType) { - struct Value *valueLoc = VariableAllocValueFromType(_parser, _pushType, FALSE, NULL, FALSE); - ExpressionStackPushValueNode(_parser, _stackTop, valueLoc); - return valueLoc; -} - -/* push a value on to the expression stack */ -void ExpressionStackPushValue(struct ParseState *_parser, - struct ExpressionStack **_stackTop, - struct Value *_pushValue) { - struct Value *valueLoc = VariableAllocValueAndCopy(_parser, _pushValue, FALSE); - ExpressionStackPushValueNode(_parser, _stackTop, valueLoc); -} - -void ExpressionStackPushLValue(struct ParseState *_parser, - struct ExpressionStack **_stackTop, - struct Value *_pushValue, - int Offset) { - struct Value *valueLoc = VariableAllocValueShared(_parser, _pushValue); - valueLoc->Val = (void *)((char *)valueLoc->Val + Offset); - ExpressionStackPushValueNode(_parser, _stackTop, valueLoc); -} - -void ExpressionStackPushDereference(struct ParseState *_parser, - struct ExpressionStack **_stackTop, - struct Value *_dereferenceValue) { - struct Value *DerefVal; - struct Value *valueLoc; - int Offset; - struct ValueType *DerefType; - int DerefIsLValue; - void *DerefDataLoc = VariableDereferencePointer(_parser, _dereferenceValue, &DerefVal, &Offset, &DerefType, &DerefIsLValue); - if (DerefDataLoc == NULL) { - ProgramFail(_parser, "NULL pointer dereference"); - } - valueLoc = VariableAllocValueFromExistingData(_parser, DerefType, (union AnyValue *)DerefDataLoc, DerefIsLValue, DerefVal); - ExpressionStackPushValueNode(_parser, _stackTop, valueLoc); -} - -void ExpressionPushInt(struct ParseState *_parser, - struct ExpressionStack **_stackTop, - long _intValue) { - struct Value *valueLoc = VariableAllocValueFromType(_parser, &IntType, FALSE, NULL, FALSE); - valueLoc->Val->Integer = _intValue; - ExpressionStackPushValueNode(_parser, _stackTop, valueLoc); -} - -void ExpressionPushFP(struct ParseState *_parser, - struct ExpressionStack **_stackTop, - double _fPValue) { - struct Value *valueLoc = VariableAllocValueFromType(_parser, &FPType, FALSE, NULL, FALSE); - valueLoc->Val->FP = _fPValue; - ExpressionStackPushValueNode(_parser, _stackTop, valueLoc); -} - -/* assign to a pointer */ -void ExpressionAssignToPointer(struct ParseState *_parser, - struct Value *_toValue, - struct Value *_fromValue, - const char *_funcName, - int _paramNo, - int _allowPointerCoercion) { - struct ValueType *PointedToType = _toValue->Typ->FromType; - if ( _fromValue->Typ == _toValue->Typ - || _fromValue->Typ == VoidPtrType - || ( _toValue->Typ == VoidPtrType - && _fromValue->Typ->Base == TypePointer) ) { - // plain old pointer assignment - _toValue->Val->Pointer = _fromValue->Val->Pointer; - } else if ( _fromValue->Typ->Base == TypeArray - && ( PointedToType == _fromValue->Typ->FromType - || _toValue->Typ == VoidPtrType) ) { - // the form is: blah *x = array of blah - _toValue->Val->Pointer = (void *)&_fromValue->Val->ArrayMem[0]; - } else if ( _fromValue->Typ->Base == TypePointer - && _fromValue->Typ->FromType->Base == TypeArray - && ( PointedToType == _fromValue->Typ->FromType->FromType - || _toValue->Typ == VoidPtrType) ) { - // the form is: blah *x = pointer to array of blah - _toValue->Val->Pointer = VariableDereferencePointer(_parser, _fromValue, NULL, NULL, NULL, NULL); - } else if ( IS_NUMERIC_COERCIBLE(_fromValue) - && ExpressionCoerceInteger(_fromValue) == 0){ - // null pointer assignment - _toValue->Val->Pointer = NULL; - } else if (_allowPointerCoercion && IS_NUMERIC_COERCIBLE(_fromValue)) { - // assign integer to native pointer - _toValue->Val->Pointer = (void *)(unsigned long)ExpressionCoerceUnsignedInteger(_fromValue); - } else if ( _allowPointerCoercion - && _fromValue->Typ->Base == TypePointer) { - /* assign a pointer to a pointer to a different type */ - _toValue->Val->Pointer = _fromValue->Val->Pointer; - } else { - AssignFail(_parser, "%t from %t", _toValue->Typ, _fromValue->Typ, 0, 0, _funcName, _paramNo); - } -} - -/* assign any kind of value */ -void ExpressionAssign(struct ParseState *_parser, - struct Value *_destValue, - struct Value *_sourceValue, - int _force, - const char *_funcName, - int _paramNo, - int _allowPointerCoercion) { - if ( !_destValue->IsLValue - && !_force) { - AssignFail(_parser, "not an lvalue", NULL, NULL, 0, 0, _funcName, _paramNo); - } - if ( IS_NUMERIC_COERCIBLE(_destValue) - && !IS_NUMERIC_COERCIBLE_PLUS_POINTERS(_sourceValue, _allowPointerCoercion)) { - AssignFail(_parser, "%t from %t", _destValue->Typ, _sourceValue->Typ, 0, 0, _funcName, _paramNo); - } - switch (_destValue->Typ->Base) { - case TypeInt: - _destValue->Val->Integer = ExpressionCoerceInteger(_sourceValue); - break; - case TypeShort: - _destValue->Val->ShortInteger = ExpressionCoerceInteger(_sourceValue); - break; - case TypeChar: - _destValue->Val->Character = ExpressionCoerceUnsignedInteger(_sourceValue); - break; - case TypeLong: - _destValue->Val->LongInteger = ExpressionCoerceInteger(_sourceValue); - break; - case TypeUnsignedInt: - _destValue->Val->UnsignedInteger = ExpressionCoerceUnsignedInteger(_sourceValue); - break; - case TypeUnsignedShort: - _destValue->Val->UnsignedShortInteger = ExpressionCoerceUnsignedInteger(_sourceValue); - break; - case TypeUnsignedLong: - _destValue->Val->UnsignedLongInteger = ExpressionCoerceUnsignedInteger(_sourceValue); - break; - case TypeFP: - if (!IS_NUMERIC_COERCIBLE_PLUS_POINTERS(_sourceValue, _allowPointerCoercion)) { - AssignFail(_parser, "%t from %t", _destValue->Typ, _sourceValue->Typ, 0, 0, _funcName, _paramNo); - } - _destValue->Val->FP = ExpressionCoerceFP(_sourceValue); - break; - case TypePointer: - ExpressionAssignToPointer(_parser, _destValue, _sourceValue, _funcName, _paramNo, _allowPointerCoercion); - break; - case TypeArray: - if (_destValue->Typ != _sourceValue->Typ) { - AssignFail(_parser, "%t from %t", _destValue->Typ, _sourceValue->Typ, 0, 0, _funcName, _paramNo); - } - if (_destValue->Typ->ArraySize != _sourceValue->Typ->ArraySize) { - AssignFail(_parser, "from an array of size %d to one of size %d", NULL, NULL, _destValue->Typ->ArraySize, _sourceValue->Typ->ArraySize, _funcName, _paramNo); - } - memcpy((void *)_destValue->Val, (void *)_sourceValue->Val, TypeSizeValue(_destValue, FALSE)); - break; - case TypeStruct: - case TypeUnion: - if (_destValue->Typ != _sourceValue->Typ) { - AssignFail(_parser, "%t from %t", _destValue->Typ, _sourceValue->Typ, 0, 0, _funcName, _paramNo); - } - memcpy((void *)_destValue->Val, (void *)_sourceValue->Val, TypeSizeValue(_sourceValue, FALSE)); - break; - default: - AssignFail(_parser, "%t", _destValue->Typ, NULL, 0, 0, _funcName, _paramNo); - break; - } -} - -/* evaluate the first half of a ternary operator x ? y : z */ -void ExpressionQuestionMarkOperator(struct ParseState *_parser, - struct ExpressionStack **_stackTop, - struct Value *_bottomValue, - struct Value *_topValue) { - if (!IS_NUMERIC_COERCIBLE(_topValue)) { - ProgramFail(_parser, "first argument to '?' should be a number"); - } - if (ExpressionCoerceInteger(_topValue)) { - /* the condition's true, return the _bottomValue */ - ExpressionStackPushValue(_parser, _stackTop, _bottomValue); - } else { - /* the condition's false, return void */ - ExpressionStackPushValueByType(_parser, _stackTop, &VoidType); - } -} - -/* evaluate the second half of a ternary operator x ? y : z */ -void ExpressionColonOperator(struct ParseState *_parser, - struct ExpressionStack **_stackTop, - struct Value *_bottomValue, - struct Value *_topValue) { - if (_topValue->Typ->Base == TypeVoid) { - /* invoke the "else" part - return the _bottomValue */ - ExpressionStackPushValue(_parser, _stackTop, _bottomValue); - } else { - /* it was a "then" - return the _topValue */ - ExpressionStackPushValue(_parser, _stackTop, _topValue); - } -} - -/* evaluate a prefix operator */ -void ExpressionPrefixOperator(struct ParseState *_parser, - struct ExpressionStack **_stackTop, - enum LexToken _op, - struct Value *_topValue) { - struct Value *Result; - union AnyValue *ValPtr; - debugf("ExpressionPrefixOperator()\n"); - switch (_op) { - case TokenAmpersand: - if (!_topValue->IsLValue) { - ProgramFail(_parser, "can't get the address of this"); - } - ValPtr = _topValue->Val; - Result = VariableAllocValueFromType(_parser, TypeGetMatching(_parser, _topValue->Typ, TypePointer, 0, StrEmpty, TRUE), FALSE, NULL, FALSE); - Result->Val->Pointer = (void *)ValPtr; - ExpressionStackPushValueNode(_parser, _stackTop, Result); - break; - case TokenAsterisk: - ExpressionStackPushDereference(_parser, _stackTop, _topValue); - break; - case TokenSizeof: - /* return the size of the argument */ - if (_topValue->Typ == &TypeType) { - ExpressionPushInt(_parser, _stackTop, TypeSize(_topValue->Val->Typ, _topValue->Val->Typ->ArraySize, TRUE)); - } else { - ExpressionPushInt(_parser, _stackTop, TypeSize(_topValue->Typ, _topValue->Typ->ArraySize, TRUE)); - } - break; - default: - /* an arithmetic operator */ - if (_topValue->Typ == &FPType) { - /* floating point prefix arithmetic */ - double ResultFP = 0.0; - switch (_op) { - case TokenPlus: - ResultFP = _topValue->Val->FP; - break; - case TokenMinus: - ResultFP = -_topValue->Val->FP; - break; - default: - ProgramFail(_parser, "invalid operation"); - break; - } - ExpressionPushFP(_parser, _stackTop, ResultFP); - } else if (IS_NUMERIC_COERCIBLE(_topValue)) { - /* integer prefix arithmetic */ - long ResultInt = 0; - long TopInt = ExpressionCoerceInteger(_topValue); - switch (_op) { - case TokenPlus: - ResultInt = TopInt; - break; - case TokenMinus: - ResultInt = -TopInt; - break; - case TokenIncrement: - ResultInt = ExpressionAssignInt(_parser, _topValue, TopInt+1, FALSE); - break; - case TokenDecrement: - ResultInt = ExpressionAssignInt(_parser, _topValue, TopInt-1, FALSE); - break; - case TokenUnaryNot: - ResultInt = !TopInt; - break; - case TokenUnaryExor: - ResultInt = ~TopInt; - break; - default: - ProgramFail(_parser, "invalid operation"); - break; - } - ExpressionPushInt(_parser, _stackTop, ResultInt); - } else if (_topValue->Typ->Base == TypePointer) { - /* pointer prefix arithmetic */ - int Size = TypeSize(_topValue->Typ->FromType, 0, TRUE); - struct Value *StackValue; - void *ResultPtr; - if (_topValue->Val->Pointer == NULL) { - ProgramFail(_parser, "invalid use of a NULL pointer"); - } - if (!_topValue->IsLValue) { - ProgramFail(_parser, "can't assign to this"); - } - switch (_op) { - case TokenIncrement: - _topValue->Val->Pointer = (void *)((char *)_topValue->Val->Pointer + Size); - break; - case TokenDecrement: - _topValue->Val->Pointer = (void *)((char *)_topValue->Val->Pointer - Size); - break; - default: - ProgramFail(_parser, "invalid operation"); - break; - } - ResultPtr = _topValue->Val->Pointer; - StackValue = ExpressionStackPushValueByType(_parser, _stackTop, _topValue->Typ); - StackValue->Val->Pointer = ResultPtr; - } else { - ProgramFail(_parser, "invalid operation"); - } - break; - } -} - -/* evaluate a postfix operator */ -void ExpressionPostfixOperator(struct ParseState *_parser, - struct ExpressionStack **_stackTop, - enum LexToken _op, - struct Value *_topValue) { - debugf("ExpressionPostfixOperator()\n"); - if (IS_NUMERIC_COERCIBLE(_topValue)) { - long ResultInt = 0; - long TopInt = ExpressionCoerceInteger(_topValue); - switch (_op) { - case TokenIncrement: - ResultInt = ExpressionAssignInt(_parser, _topValue, TopInt+1, TRUE); - break; - case TokenDecrement: - ResultInt = ExpressionAssignInt(_parser, _topValue, TopInt-1, TRUE); - break; - case TokenRightSquareBracket: - ProgramFail(_parser, "not supported"); - // TODO : ... - break; - case TokenCloseBracket: - ProgramFail(_parser, "not supported"); - // TODO : ... - break; - default: - ProgramFail(_parser, "invalid operation"); - break; - } - ExpressionPushInt(_parser, _stackTop, ResultInt); - } else if (_topValue->Typ->Base == TypePointer) { - /* pointer postfix arithmetic */ - int Size = TypeSize(_topValue->Typ->FromType, 0, TRUE); - struct Value *StackValue; - void *OrigPointer = _topValue->Val->Pointer; - if (_topValue->Val->Pointer == NULL) { - ProgramFail(_parser, "invalid use of a NULL pointer"); - } - if (!_topValue->IsLValue) { - ProgramFail(_parser, "can't assign to this"); - } - switch (_op) { - case TokenIncrement: - _topValue->Val->Pointer = (void *)((char *)_topValue->Val->Pointer + Size); - break; - case TokenDecrement: - _topValue->Val->Pointer = (void *)((char *)_topValue->Val->Pointer - Size); - break; - default: - ProgramFail(_parser, "invalid operation"); - break; - } - StackValue = ExpressionStackPushValueByType(_parser, _stackTop, _topValue->Typ); - StackValue->Val->Pointer = OrigPointer; - } else { - ProgramFail(_parser, "invalid operation"); - } -} - -/* evaluate an infix operator */ -void ExpressionInfixOperator(struct ParseState *_parser, - struct ExpressionStack **_stackTop, - enum LexToken _op, - struct Value *_bottomValue, - struct Value *_topValue) { - long ResultInt = 0; - struct Value *StackValue; - void *Pointer; - debugf("ExpressionInfixOperator()\n"); - if ( _bottomValue == NULL - || _topValue == NULL) { - ProgramFail(_parser, "invalid expression"); - } - if (_op == TokenLeftSquareBracket) { - /* array index */ - int ArrayIndex; - struct Value *Result = NULL; - if (!IS_NUMERIC_COERCIBLE(_topValue)) { - ProgramFail(_parser, "array index must be an integer"); - } - ArrayIndex = ExpressionCoerceInteger(_topValue); - /* make the array element result */ - switch (_bottomValue->Typ->Base) { - case TypeArray: - Result = VariableAllocValueFromExistingData(_parser, _bottomValue->Typ->FromType, (union AnyValue *)(&_bottomValue->Val->ArrayMem[0] + TypeSize(_bottomValue->Typ, ArrayIndex, TRUE)), _bottomValue->IsLValue, _bottomValue->LValueFrom); - break; - case TypePointer: - Result = VariableAllocValueFromExistingData(_parser, _bottomValue->Typ->FromType, (union AnyValue *)((char *)_bottomValue->Val->Pointer + TypeSize(_bottomValue->Typ->FromType, 0, TRUE) * ArrayIndex), _bottomValue->IsLValue, _bottomValue->LValueFrom); - break; - default: - ProgramFail(_parser, "this %t is not an array", _bottomValue->Typ); - } - ExpressionStackPushValueNode(_parser, _stackTop, Result); - } else if (_op == TokenQuestionMark) { - ExpressionQuestionMarkOperator(_parser, _stackTop, _topValue, _bottomValue); - } else if (_op == TokenColon) { - ExpressionColonOperator(_parser, _stackTop, _topValue, _bottomValue); - } else if ( (_topValue->Typ == &FPType && _bottomValue->Typ == &FPType) - || (_topValue->Typ == &FPType && IS_NUMERIC_COERCIBLE(_bottomValue)) - || (IS_NUMERIC_COERCIBLE(_topValue) && _bottomValue->Typ == &FPType) ) { - /* floating point infix arithmetic */ - int ResultIsInt = FALSE; - double ResultFP = 0.0; - double TopFP = (_topValue->Typ == &FPType) ? _topValue->Val->FP : (double)ExpressionCoerceInteger(_topValue); - double BottomFP = (_bottomValue->Typ == &FPType) ? _bottomValue->Val->FP : (double)ExpressionCoerceInteger(_bottomValue); - switch (_op) { - case TokenAssign: - ResultFP = ExpressionAssignFP(_parser, _bottomValue, TopFP); - break; - case TokenAddAssign: - ResultFP = ExpressionAssignFP(_parser, _bottomValue, BottomFP + TopFP); - break; - case TokenSubtractAssign: - ResultFP = ExpressionAssignFP(_parser, _bottomValue, BottomFP - TopFP); - break; - case TokenMultiplyAssign: - ResultFP = ExpressionAssignFP(_parser, _bottomValue, BottomFP * TopFP); - break; - case TokenDivideAssign: - ResultFP = ExpressionAssignFP(_parser, _bottomValue, BottomFP / TopFP); - break; - case TokenEqual: - ResultInt = BottomFP == TopFP; - ResultIsInt = TRUE; - break; - case TokenNotEqual: - ResultInt = BottomFP != TopFP; - ResultIsInt = TRUE; - break; - case TokenLessThan: - ResultInt = BottomFP < TopFP; - ResultIsInt = TRUE; - break; - case TokenGreaterThan: - ResultInt = BottomFP > TopFP; - ResultIsInt = TRUE; - break; - case TokenLessEqual: - ResultInt = BottomFP <= TopFP; - ResultIsInt = TRUE; - break; - case TokenGreaterEqual: - ResultInt = BottomFP >= TopFP; - ResultIsInt = TRUE; - break; - case TokenPlus: - ResultFP = BottomFP + TopFP; - break; - case TokenMinus: - ResultFP = BottomFP - TopFP; - break; - case TokenAsterisk: - ResultFP = BottomFP * TopFP; - break; - case TokenSlash: - ResultFP = BottomFP / TopFP; - break; - default: - ProgramFail(_parser, "invalid operation"); - break; - } - if (ResultIsInt) { - ExpressionPushInt(_parser, _stackTop, ResultInt); - } else { - ExpressionPushFP(_parser, _stackTop, ResultFP); - } - } else if (IS_NUMERIC_COERCIBLE(_topValue) && IS_NUMERIC_COERCIBLE(_bottomValue)) { - /* integer operation */ - long TopInt = ExpressionCoerceInteger(_topValue); - long BottomInt = ExpressionCoerceInteger(_bottomValue); - switch (_op) { - case TokenAssign: - ResultInt = ExpressionAssignInt(_parser, _bottomValue, TopInt, FALSE); - break; - case TokenAddAssign: - ResultInt = ExpressionAssignInt(_parser, _bottomValue, BottomInt + TopInt, FALSE); - break; - case TokenSubtractAssign: - ResultInt = ExpressionAssignInt(_parser, _bottomValue, BottomInt - TopInt, FALSE); - break; - case TokenMultiplyAssign: - ResultInt = ExpressionAssignInt(_parser, _bottomValue, BottomInt * TopInt, FALSE); - break; - case TokenDivideAssign: - ResultInt = ExpressionAssignInt(_parser, _bottomValue, BottomInt / TopInt, FALSE); - break; -#ifndef NO_MODULUS - case TokenModulusAssign: - ResultInt = ExpressionAssignInt(_parser, _bottomValue, BottomInt % TopInt, FALSE); - break; -#endif - case TokenShiftLeftAssign: - ResultInt = ExpressionAssignInt(_parser, _bottomValue, BottomInt << TopInt, FALSE); - break; - case TokenShiftRightAssign: - ResultInt = ExpressionAssignInt(_parser, _bottomValue, BottomInt >> TopInt, FALSE); - break; - case TokenArithmeticAndAssign: - ResultInt = ExpressionAssignInt(_parser, _bottomValue, BottomInt & TopInt, FALSE); - break; - case TokenArithmeticOrAssign: - ResultInt = ExpressionAssignInt(_parser, _bottomValue, BottomInt | TopInt, FALSE); - break; - case TokenArithmeticExorAssign: - ResultInt = ExpressionAssignInt(_parser, _bottomValue, BottomInt ^ TopInt, FALSE); - break; - case TokenLogicalOr: - ResultInt = BottomInt || TopInt; - break; - case TokenLogicalAnd: - ResultInt = BottomInt && TopInt; - break; - case TokenArithmeticOr: - ResultInt = BottomInt | TopInt; - break; - case TokenArithmeticExor: - ResultInt = BottomInt ^ TopInt; - break; - case TokenAmpersand: - ResultInt = BottomInt & TopInt; - break; - case TokenEqual: - ResultInt = BottomInt == TopInt; - break; - case TokenNotEqual: - ResultInt = BottomInt != TopInt; - break; - case TokenLessThan: - ResultInt = BottomInt < TopInt; - break; - case TokenGreaterThan: - ResultInt = BottomInt > TopInt; - break; - case TokenLessEqual: - ResultInt = BottomInt <= TopInt; - break; - case TokenGreaterEqual: - ResultInt = BottomInt >= TopInt; - break; - case TokenShiftLeft: - ResultInt = BottomInt << TopInt; - break; - case TokenShiftRight: - ResultInt = BottomInt >> TopInt; - break; - case TokenPlus: - ResultInt = BottomInt + TopInt; - break; - case TokenMinus: - ResultInt = BottomInt - TopInt; - break; - case TokenAsterisk: - ResultInt = BottomInt * TopInt; - break; - case TokenSlash: - ResultInt = BottomInt / TopInt; - break; -#ifndef NO_MODULUS - case TokenModulus: - ResultInt = BottomInt % TopInt; - break; -#endif - default: - ProgramFail(_parser, "invalid operation"); - break; - } - ExpressionPushInt(_parser, _stackTop, ResultInt); - } else if (_bottomValue->Typ->Base == TypePointer && IS_NUMERIC_COERCIBLE(_topValue)) { - /* pointer/integer infix arithmetic */ - long TopInt = ExpressionCoerceInteger(_topValue); - if ( _op == TokenEqual - || _op == TokenNotEqual) { - /* comparison to a NULL pointer */ - if (TopInt != 0) { - ProgramFail(_parser, "invalid operation"); - } - if (_op == TokenEqual) { - ExpressionPushInt(_parser, _stackTop, _bottomValue->Val->Pointer == NULL); - } else { - ExpressionPushInt(_parser, _stackTop, _bottomValue->Val->Pointer != NULL); - } - } else if ( _op == TokenPlus - || _op == TokenMinus) { - /* pointer arithmetic */ - int Size = TypeSize(_bottomValue->Typ->FromType, 0, TRUE); - Pointer = _bottomValue->Val->Pointer; - if (Pointer == NULL) { - ProgramFail(_parser, "invalid use of a NULL pointer"); - } - if (_op == TokenPlus) { - Pointer = (void *)((char *)Pointer + TopInt * Size); - } else { - Pointer = (void *)((char *)Pointer - TopInt * Size); - } - StackValue = ExpressionStackPushValueByType(_parser, _stackTop, _bottomValue->Typ); - StackValue->Val->Pointer = Pointer; - } else if ( _op == TokenAssign - && TopInt == 0) { - /* assign a NULL pointer */ - HeapUnpopStack(sizeof(struct Value)); - ExpressionAssign(_parser, _bottomValue, _topValue, FALSE, NULL, 0, FALSE); - ExpressionStackPushValueNode(_parser, _stackTop, _bottomValue); - } else if ( _op == TokenAddAssign - || _op == TokenSubtractAssign) { - /* pointer arithmetic */ - int Size = TypeSize(_bottomValue->Typ->FromType, 0, TRUE); - Pointer = _bottomValue->Val->Pointer; - if (Pointer == NULL) { - ProgramFail(_parser, "invalid use of a NULL pointer"); - } - if (_op == TokenAddAssign) { - Pointer = (void *)((char *)Pointer + TopInt * Size); - } else { - Pointer = (void *)((char *)Pointer - TopInt * Size); - } - HeapUnpopStack(sizeof(struct Value)); - _bottomValue->Val->Pointer = Pointer; - ExpressionStackPushValueNode(_parser, _stackTop, _bottomValue); - } else { - ProgramFail(_parser, "invalid operation"); - } - } else if ( _bottomValue->Typ->Base == TypePointer - && _topValue->Typ->Base == TypePointer - && _op != TokenAssign) { - /* pointer/pointer operations */ - char *TopLoc = (char *)_topValue->Val->Pointer; - char *BottomLoc = (char *)_bottomValue->Val->Pointer; - switch (_op) { - case TokenEqual: - ExpressionPushInt(_parser, _stackTop, BottomLoc == TopLoc); - break; - case TokenNotEqual: - ExpressionPushInt(_parser, _stackTop, BottomLoc != TopLoc); - break; - case TokenMinus: - ExpressionPushInt(_parser, _stackTop, BottomLoc - TopLoc); - break; - default: - ProgramFail(_parser, "invalid operation"); - break; - } - } else if (_op == TokenAssign) { - /* assign a non-numeric type */ - HeapUnpopStack(sizeof(struct Value)); /* XXX - possible bug if lvalue is a temp value and takes more than sizeof(struct Value) */ - ExpressionAssign(_parser, _bottomValue, _topValue, FALSE, NULL, 0, FALSE); - ExpressionStackPushValueNode(_parser, _stackTop, _bottomValue); - } else if (_op == TokenCast) { - /* cast a value to a different type */ /* XXX - possible bug if the destination type takes more than sizeof(struct Value) + sizeof(struct ValueType *) */ - struct Value *valueLoc = ExpressionStackPushValueByType(_parser, _stackTop, _bottomValue->Val->Typ); - ExpressionAssign(_parser, valueLoc, _topValue, TRUE, NULL, 0, TRUE); - } else { - ProgramFail(_parser, "invalid operation"); - } -} - -/* take the contents of the expression stack and compute the top until there's nothing greater than the given precedence */ -void ExpressionStackCollapse(struct ParseState *_parser, - struct ExpressionStack **_stackTop, - int Precedence, - int *IgnorePrecedence) { - int FoundPrecedence = Precedence; - struct Value *topValue; - struct Value *BottomValue; - struct ExpressionStack *TopStackNode = *_stackTop; - struct ExpressionStack *TopOperatorNode; - debugf("ExpressionStackCollapse(%d):\n", Precedence); -#ifdef DEBUG_EXPRESSIONS - ExpressionStackShow(*_stackTop); -#endif - while (TopStackNode != NULL && TopStackNode->Next != NULL && FoundPrecedence >= Precedence) { - /* find the top operator on the stack */ - if (TopStackNode->Order == OrderNone) { - TopOperatorNode = TopStackNode->Next; - } else { - TopOperatorNode = TopStackNode; - } - FoundPrecedence = TopOperatorNode->Precedence; - /* does it have a high enough precedence? */ - if (FoundPrecedence >= Precedence && TopOperatorNode != NULL) { - /* execute this operator */ - switch (TopOperatorNode->Order) { - case OrderPrefix: - /* prefix evaluation */ - debugf("prefix evaluation\n"); - topValue = TopStackNode->Val; - /* pop the value and then the prefix operator - assume they'll still be there until we're done */ - HeapPopStack(NULL, sizeof(struct ExpressionStack) + sizeof(struct Value) + TypeStackSizeValue(topValue)); - HeapPopStack(TopOperatorNode, sizeof(struct ExpressionStack)); - *_stackTop = TopOperatorNode->Next; - /* do the prefix operation */ - if ( _parser->Mode == RunModeRun - && FoundPrecedence < *IgnorePrecedence) { - /* run the operator */ - ExpressionPrefixOperator(_parser, _stackTop, TopOperatorNode->Op, topValue); - } else { - /* we're not running it so just return 0 */ - ExpressionPushInt(_parser, _stackTop, 0); - } - break; - case OrderPostfix: - /* postfix evaluation */ - debugf("postfix evaluation\n"); - topValue = TopStackNode->Next->Val; - /* pop the postfix operator and then the value - assume they'll still be there until we're done */ - HeapPopStack(NULL, sizeof(struct ExpressionStack)); - HeapPopStack(topValue, sizeof(struct ExpressionStack) + sizeof(struct Value) + TypeStackSizeValue(topValue)); - *_stackTop = TopStackNode->Next->Next; - /* do the postfix operation */ - if ( _parser->Mode == RunModeRun - && FoundPrecedence < *IgnorePrecedence) { - /* run the operator */ - ExpressionPostfixOperator(_parser, _stackTop, TopOperatorNode->Op, topValue); - } else { - /* we're not running it so just return 0 */ - ExpressionPushInt(_parser, _stackTop, 0); - } - break; - case OrderInfix: - /* infix evaluation */ - debugf("infix evaluation\n"); - topValue = TopStackNode->Val; - if (topValue != NULL) { - BottomValue = TopOperatorNode->Next->Val; - /* pop a value, the operator and another value - assume they'll still be there until we're done */ - HeapPopStack(NULL, sizeof(struct ExpressionStack) + sizeof(struct Value) + TypeStackSizeValue(topValue)); - HeapPopStack(NULL, sizeof(struct ExpressionStack)); - HeapPopStack(BottomValue, sizeof(struct ExpressionStack) + sizeof(struct Value) + TypeStackSizeValue(BottomValue)); - *_stackTop = TopOperatorNode->Next->Next; - /* do the infix operation */ - if (_parser->Mode == RunModeRun && FoundPrecedence <= *IgnorePrecedence) { - /* run the operator */ - ExpressionInfixOperator(_parser, _stackTop, TopOperatorNode->Op, BottomValue, topValue); - } else { - /* we're not running it so just return 0 */ - ExpressionPushInt(_parser, _stackTop, 0); - } - } else { - FoundPrecedence = -1; - } - break; - case OrderNone: - /* this should never happen */ - assert(TopOperatorNode->Order != OrderNone); - break; - } - /* if we've returned above the ignored precedence level turn ignoring off */ - if (FoundPrecedence <= *IgnorePrecedence) { - *IgnorePrecedence = DEEP_PRECEDENCE; - } - } -#ifdef DEBUG_EXPRESSIONS - ExpressionStackShow(*_stackTop); -#endif - TopStackNode = *_stackTop; - } - debugf("ExpressionStackCollapse() finished\n"); -#ifdef DEBUG_EXPRESSIONS - ExpressionStackShow(*_stackTop); -#endif -} - -/* push an operator on to the expression stack */ -void ExpressionStackPushOperator(struct ParseState *_parser, struct ExpressionStack **_stackTop, enum OperatorOrder Order, enum LexToken Token, int Precedence) { - struct ExpressionStack *StackNode = VariableAlloc(_parser, sizeof(struct ExpressionStack), FALSE); - StackNode->Next = *_stackTop; - StackNode->Order = Order; - StackNode->Op = Token; - StackNode->Precedence = Precedence; - *_stackTop = StackNode; - debugf("ExpressionStackPushOperator()\n"); -#ifdef FANCY_ERROR_MESSAGES - StackNode->Line = _parser->Line; - StackNode->CharacterPos = _parser->CharacterPos; -#endif -#ifdef DEBUG_EXPRESSIONS - ExpressionStackShow(*_stackTop); -#endif -} - -/* do the '.' and '->' operators */ -void ExpressionGetStructElement(struct ParseState *_parser, struct ExpressionStack **_stackTop, enum LexToken Token) { - struct Value *Ident; - /* get the identifier following the '.' or '->' */ - if (LexGetToken(_parser, &Ident, TRUE) != TokenIdentifier) { - ProgramFail(_parser, "need an structure or union member after '%s'", (Token == TokenDot) ? "." : "->"); - } - if (_parser->Mode == RunModeRun) { - /* look up the struct element */ - struct Value *ParamVal = (*_stackTop)->Val; - struct Value *StructVal = ParamVal; - struct ValueType *StructType = ParamVal->Typ; - char *DerefDataLoc = (char *)ParamVal->Val; - struct Value *MemberValue; - struct Value *Result; - /* if we're doing '->' dereference the struct pointer first */ - if (Token == TokenArrow) { - DerefDataLoc = VariableDereferencePointer(_parser, ParamVal, &StructVal, NULL, &StructType, NULL); - } - if (StructType->Base != TypeStruct && StructType->Base != TypeUnion) { - ProgramFail(_parser, "can't use '%s' on something that's not a struct or union %s : it's a %t", (Token == TokenDot) ? "." : "->", (Token == TokenArrow) ? "pointer" : "", ParamVal->Typ); - } - if (!TableGet(StructType->Members, Ident->Val->Identifier, &MemberValue, NULL, NULL, NULL)) { - ProgramFail(_parser, "doesn't have a member called '%s'", Ident->Val->Identifier); - } - /* pop the value - assume it'll still be there until we're done */ - HeapPopStack(ParamVal, sizeof(struct ExpressionStack) + sizeof(struct Value) + TypeStackSizeValue(StructVal)); - *_stackTop = (*_stackTop)->Next; - /* make the result value for this member only */ - Result = VariableAllocValueFromExistingData(_parser, MemberValue->Typ, (void *)(DerefDataLoc + MemberValue->Val->Integer), TRUE, (StructVal != NULL) ? StructVal->LValueFrom : NULL); - ExpressionStackPushValueNode(_parser, _stackTop, Result); - } -} - -/* parse an expression with operator precedence */ -int ExpressionParse(struct ParseState *_parser, struct Value **Result) { - struct Value *LexValue; - int PrefixState = TRUE; - int Done = FALSE; - int BracketPrecedence = 0; - int LocalPrecedence; - int Precedence = 0; - int IgnorePrecedence = DEEP_PRECEDENCE; - struct ExpressionStack *_stackTop = NULL; - int TernaryDepth = 0; - debugf("ExpressionParse():\n"); - do { - struct ParseState PreState; - enum LexToken Token; - ParserCopy(&PreState, _parser); - Token = LexGetToken(_parser, &LexValue, TRUE); - if ( ( ( (int)Token > TokenComma - && (int)Token <= (int)TokenOpenBracket) - || ( Token == TokenCloseBracket - && BracketPrecedence != 0) ) - && ( Token != TokenColon - || TernaryDepth > 0) ) { - /* it's an operator with precedence */ - if (PrefixState) { - /* expect a prefix operator */ - if (OperatorPrecedence[(int)Token].PrefixPrecedence == 0) { - ProgramFail(_parser, "operator not expected here"); - } - LocalPrecedence = OperatorPrecedence[(int)Token].PrefixPrecedence; - Precedence = BracketPrecedence + LocalPrecedence; - if (Token == TokenOpenBracket) { - /* it's either a new bracket level or a cast */ - enum LexToken BracketToken = LexGetToken(_parser, &LexValue, FALSE); - if ( IS_TYPE_TOKEN(BracketToken) - && ( _stackTop == NULL - || _stackTop->Op != TokenSizeof) ) { - /* it's a cast - get the new type */ - struct ValueType *CastType; - char *CastIdentifier; - struct Value *CastTypeValue; - TypeParse(_parser, &CastType, &CastIdentifier, NULL); - if (LexGetToken(_parser, &LexValue, TRUE) != TokenCloseBracket) { - ProgramFail(_parser, "brackets not closed"); - } - // scan and collapse the stack to the precedence of this infix cast operator, then push - Precedence = BracketPrecedence + OperatorPrecedence[(int)TokenCast].PrefixPrecedence; - ExpressionStackCollapse(_parser, &_stackTop, Precedence+1, &IgnorePrecedence); - CastTypeValue = VariableAllocValueFromType(_parser, &TypeType, FALSE, NULL, FALSE); - CastTypeValue->Val->Typ = CastType; - ExpressionStackPushValueNode(_parser, &_stackTop, CastTypeValue); - ExpressionStackPushOperator(_parser, &_stackTop, OrderInfix, TokenCast, Precedence); - } else { - /* boost the bracket operator precedence */ - BracketPrecedence += BRACKET_PRECEDENCE; - } - } else { - //scan and collapse the stack to the precedence of this operator, then push - ExpressionStackCollapse(_parser, &_stackTop, Precedence, &IgnorePrecedence); - ExpressionStackPushOperator(_parser, &_stackTop, OrderPrefix, Token, Precedence); - } - } else { - // expect an infix or postfix operator - if (OperatorPrecedence[(int)Token].PostfixPrecedence != 0) { - switch (Token) { - case TokenCloseBracket: - case TokenRightSquareBracket: - if (BracketPrecedence == 0) { - // assume this bracket is after the end of the expression - ParserCopy(_parser, &PreState); - Done = TRUE; - } else { - // collapse to the bracket precedence - ExpressionStackCollapse(_parser, &_stackTop, BracketPrecedence, &IgnorePrecedence); - BracketPrecedence -= BRACKET_PRECEDENCE; - } - break; - default: - // scan and collapse the stack to the precedence of this operator, then push - Precedence = BracketPrecedence + OperatorPrecedence[(int)Token].PostfixPrecedence; - ExpressionStackCollapse(_parser, &_stackTop, Precedence, &IgnorePrecedence); - ExpressionStackPushOperator(_parser, &_stackTop, OrderPostfix, Token, Precedence); - break; - } - } else if (OperatorPrecedence[(int)Token].InfixPrecedence != 0) { - // scan and collapse the stack, then push - Precedence = BracketPrecedence + OperatorPrecedence[(int)Token].InfixPrecedence; - // for right to left order, only go down to the next higher precedence so we evaluate it in reverse order - // for left to right order, collapse down to this precedence so we evaluate it in forward order - if (IS_LEFT_TO_RIGHT(OperatorPrecedence[(int)Token].InfixPrecedence)) { - ExpressionStackCollapse(_parser, &_stackTop, Precedence, &IgnorePrecedence); - } else { - ExpressionStackCollapse(_parser, &_stackTop, Precedence+1, &IgnorePrecedence); - } - if ( Token == TokenDot - || Token == TokenArrow) { - ExpressionGetStructElement(_parser, &_stackTop, Token); /* this operator is followed by a struct element so handle it as a special case */ - } else { - /* if it's a && or || operator we may not need to evaluate the right hand side of the expression */ - if ( ( Token == TokenLogicalOr - || Token == TokenLogicalAnd) - && IS_NUMERIC_COERCIBLE(_stackTop->Val)) { - long LHSInt = ExpressionCoerceInteger(_stackTop->Val); - if ( ( ( Token == TokenLogicalOr - && LHSInt) - || ( Token == TokenLogicalAnd - && !LHSInt) ) - && (IgnorePrecedence > Precedence) ) - IgnorePrecedence = Precedence; - } - // push the operator on the stack - ExpressionStackPushOperator(_parser, &_stackTop, OrderInfix, Token, Precedence); - PrefixState = TRUE; - switch (Token) { - case TokenQuestionMark: - TernaryDepth++; - break; - case TokenColon: - TernaryDepth--; - break; - default: - break; - } - } - /* treat an open square bracket as an infix array index operator followed by an open bracket */ - if (Token == TokenLeftSquareBracket) { - /* boost the bracket operator precedence, then push */ - BracketPrecedence += BRACKET_PRECEDENCE; - } - } else { - ProgramFail(_parser, "operator not expected here"); - } - } - } else if (Token == TokenIdentifier) { - /* it's a variable, function or a macro */ - if (!PrefixState) { - ProgramFail(_parser, "identifier not expected here"); - } - if (LexGetToken(_parser, NULL, FALSE) == TokenOpenBracket) { - ExpressionParseFunctionCall(_parser, &_stackTop, LexValue->Val->Identifier, _parser->Mode == RunModeRun && Precedence < IgnorePrecedence); - } else { - if (_parser->Mode == RunModeRun && Precedence < IgnorePrecedence) { - struct Value *VariableValue = NULL; - VariableGet(_parser, LexValue->Val->Identifier, &VariableValue); - if (VariableValue->Typ->Base == TypeMacro) { - /* evaluate a macro as a kind of simple subroutine */ - struct ParseState Macro_parser; - struct Value *MacroResult; - ParserCopy(&Macro_parser, &VariableValue->Val->MacroDef.Body); - if (VariableValue->Val->MacroDef.NumParams != 0) { - ProgramFail(&Macro_parser, "macro arguments missing"); - } - if ( !ExpressionParse(&Macro_parser, &MacroResult) - || LexGetToken(&Macro_parser, NULL, FALSE) != TokenEndOfFunction) { - ProgramFail(&Macro_parser, "expression expected"); - } - ExpressionStackPushValueNode(_parser, &_stackTop, MacroResult); - } else if (VariableValue->Typ == TypeVoid) { - ProgramFail(_parser, "a void value isn't much use here"); - } else { - ExpressionStackPushLValue(_parser, &_stackTop, VariableValue, 0); /* it's a value variable */ - } - } else { - // push a dummy value - ExpressionPushInt(_parser, &_stackTop, 0); - } - } - // if we've successfully ignored the RHS turn ignoring off - if (Precedence <= IgnorePrecedence) { - IgnorePrecedence = DEEP_PRECEDENCE; - } - PrefixState = FALSE; - } else if ( (int)Token > TokenCloseBracket - && (int)Token <= TokenCharacterConstant) { - /* it's a value of some sort, push it */ - if (!PrefixState) { - ProgramFail(_parser, "value not expected here"); - } - PrefixState = FALSE; - ExpressionStackPushValue(_parser, &_stackTop, LexValue); - } else if (IS_TYPE_TOKEN(Token)) { - /* it's a type. push it on the stack like a value. this is used in sizeof() */ - struct ValueType *Typ; - char *Identifier; - struct Value *TypeValue; - if (!PrefixState) { - ProgramFail(_parser, "type not expected here"); - } - PrefixState = FALSE; - ParserCopy(_parser, &PreState); - TypeParse(_parser, &Typ, &Identifier, NULL); - TypeValue = VariableAllocValueFromType(_parser, &TypeType, FALSE, NULL, FALSE); - TypeValue->Val->Typ = Typ; - ExpressionStackPushValueNode(_parser, &_stackTop, TypeValue); - } else { - // it isn't a token from an expression - ParserCopy(_parser, &PreState); - Done = TRUE; - } - } while (!Done); - // check that brackets have been closed - if (BracketPrecedence > 0) { - ProgramFail(_parser, "brackets not closed"); - } - // scan and collapse the stack to precedence 0 - ExpressionStackCollapse(_parser, &_stackTop, 0, &IgnorePrecedence); - // fix up the stack and return the result if we're in run mode - if (_stackTop != NULL) { - // all that should be left is a single value on the stack - if (_parser->Mode == RunModeRun) { - if ( _stackTop->Order != OrderNone - || _stackTop->Next != NULL) { - ProgramFail(_parser, "invalid expression"); - } - *Result = _stackTop->Val; - HeapPopStack(_stackTop, sizeof(struct ExpressionStack)); - } else { - HeapPopStack(_stackTop->Val, sizeof(struct ExpressionStack) + sizeof(struct Value) + TypeStackSizeValue(_stackTop->Val)); - } - } - debugf("ExpressionParse() done\n\n"); -#ifdef DEBUG_EXPRESSIONS - ExpressionStackShow(_stackTop); -#endif - return _stackTop != NULL; -} - - -/* do a parameterised macro call */ -void ExpressionParseMacroCall(struct ParseState *_parser, struct ExpressionStack **_stackTop, const char *MacroName, struct MacroDef *MDef) { - struct Value *ReturnValue = NULL; - struct Value *Param; - struct Value **ParamArray = NULL; - int ArgCount; - enum LexToken Token; - if (_parser->Mode == RunModeRun) { - /* create a stack frame for this macro */ - ExpressionStackPushValueByType(_parser, _stackTop, &FPType); /* largest return type there is */ - ReturnValue = (*_stackTop)->Val; - HeapPushStackFrame(); - ParamArray = HeapAllocStack(sizeof(struct Value *) * MDef->NumParams); - if (ParamArray == NULL) { - ProgramFail(_parser, "out of memory"); - } - } else { - ExpressionPushInt(_parser, _stackTop, 0); - } - // parse arguments - ArgCount = 0; - do { - if (ExpressionParse(_parser, &Param)) { - if (_parser->Mode == RunModeRun) { - if (ArgCount < MDef->NumParams) { - ParamArray[ArgCount] = Param; - } else { - ProgramFail(_parser, "too many arguments to %s()", MacroName); - } - } - ArgCount++; - Token = LexGetToken(_parser, NULL, TRUE); - if ( Token != TokenComma - && Token != TokenCloseBracket) { - ProgramFail(_parser, "comma expected"); - } - } else { - /* end of argument list? */ - Token = LexGetToken(_parser, NULL, TRUE); - if (!TokenCloseBracket) { - ProgramFail(_parser, "bad argument"); - } - } - } while (Token != TokenCloseBracket); - - if (_parser->Mode == RunModeRun) { - /* evaluate the macro */ - struct ParseState Macro_parser; - int Count; - struct Value *EvalValue; - if (ArgCount < MDef->NumParams) { - ProgramFail(_parser, "not enough arguments to '%s'", MacroName); - } - if (MDef->Body.Pos == NULL) { - ProgramFail(_parser, "'%s' is undefined", MacroName); - } - ParserCopy(&Macro_parser, &MDef->Body); - VariableStackFrameAdd(_parser, MacroName, 0); - TopStackFrame->NumParams = ArgCount; - TopStackFrame->ReturnValue = ReturnValue; - for (Count = 0; Count < MDef->NumParams; Count++) { - VariableDefine(_parser, MDef->ParamName[Count], ParamArray[Count], NULL, TRUE); - } - ExpressionParse(&Macro_parser, &EvalValue); - ExpressionAssign(_parser, ReturnValue, EvalValue, TRUE, MacroName, 0, FALSE); - VariableStackFramePop(_parser); - HeapPopStackFrame(); - } -} - -/* do a function call */ -void ExpressionParseFunctionCall(struct ParseState *_parser, struct ExpressionStack **_stackTop, const char *_funcName, int _runIt) { - struct Value *ReturnValue = NULL; - struct Value *FuncValue; - struct Value *Param; - struct Value **ParamArray = NULL; - int ArgCount; - enum LexToken Token = LexGetToken(_parser, NULL, TRUE); /* open bracket */ - enum RunMode OldMode = _parser->Mode; - if (_runIt) { - /* get the function definition */ - VariableGet(_parser, _funcName, &FuncValue); - if (FuncValue->Typ->Base == TypeMacro) { - /* this is actually a macro, not a function */ - ExpressionParseMacroCall(_parser, _stackTop, _funcName, &FuncValue->Val->MacroDef); - return; - } - if (FuncValue->Typ->Base != TypeFunction) { - ProgramFail(_parser, "%t is not a function - can't call", FuncValue->Typ); - } - ExpressionStackPushValueByType(_parser, _stackTop, FuncValue->Val->FuncDef.ReturnType); - ReturnValue = (*_stackTop)->Val; - HeapPushStackFrame(); - ParamArray = HeapAllocStack(sizeof(struct Value *) * FuncValue->Val->FuncDef.NumParams); - if (ParamArray == NULL) { - ProgramFail(_parser, "out of memory"); - } - } else { - ExpressionPushInt(_parser, _stackTop, 0); - _parser->Mode = RunModeSkip; - } - // parse arguments - ArgCount = 0; - do { - if ( _runIt - && ArgCount < FuncValue->Val->FuncDef.NumParams) { - ParamArray[ArgCount] = VariableAllocValueFromType(_parser, FuncValue->Val->FuncDef.ParamType[ArgCount], FALSE, NULL, FALSE); - } - if (ExpressionParse(_parser, &Param)) { - if (_runIt) { - if (ArgCount < FuncValue->Val->FuncDef.NumParams) { - ExpressionAssign(_parser, ParamArray[ArgCount], Param, TRUE, _funcName, ArgCount+1, FALSE); - VariableStackPop(_parser, Param); - } else { - if (!FuncValue->Val->FuncDef.VarArgs) { - ProgramFail(_parser, "too many arguments to %s()", _funcName); - } - } - } - ArgCount++; - Token = LexGetToken(_parser, NULL, TRUE); - if (Token != TokenComma && Token != TokenCloseBracket) { - ProgramFail(_parser, "comma expected"); - } - } else { - /* end of argument list? */ - Token = LexGetToken(_parser, NULL, TRUE); - if (!TokenCloseBracket) { - ProgramFail(_parser, "bad argument"); - } - } - } while (Token != TokenCloseBracket); - if (_runIt) { - /* run the function */ - if (ArgCount < FuncValue->Val->FuncDef.NumParams) { - ProgramFail(_parser, "not enough arguments to '%s'", _funcName); - } - if (FuncValue->Val->FuncDef.Intrinsic == NULL) { - /* run a user-defined function */ - struct ParseState FuncParser; - int Count; - if (FuncValue->Val->FuncDef.Body.Pos == NULL) { - ProgramFail(_parser, "'%s' is undefined", _funcName); - } - ParserCopy(&FuncParser, &FuncValue->Val->FuncDef.Body); - VariableStackFrameAdd(_parser, _funcName, FuncValue->Val->FuncDef.Intrinsic ? FuncValue->Val->FuncDef.NumParams : 0); - TopStackFrame->NumParams = ArgCount; - TopStackFrame->ReturnValue = ReturnValue; - for (Count = 0; Count < FuncValue->Val->FuncDef.NumParams; ++Count) { - VariableDefine(_parser, FuncValue->Val->FuncDef.ParamName[Count], ParamArray[Count], NULL, TRUE); - } - if (ParseStatement(&FuncParser, TRUE) != ParseResultOk) { - ProgramFail(&FuncParser, "function body expected"); - } - if (_runIt) { - if ( FuncParser.Mode == RunModeRun - && FuncValue->Val->FuncDef.ReturnType != &VoidType) { - ProgramFail(&FuncParser, "no value returned from a function returning %t", FuncValue->Val->FuncDef.ReturnType); - } else if (FuncParser.Mode == RunModeGoto) { - ProgramFail(&FuncParser, "couldn't find goto label '%s'", FuncParser.SearchGotoLabel); - } - } - VariableStackFramePop(_parser); - } else { - FuncValue->Val->FuncDef.Intrinsic(_parser, ReturnValue, ParamArray, ArgCount); - } - HeapPopStackFrame(); - } - _parser->Mode = OldMode; -} - -/* parse an expression */ -long ExpressionParseInt(struct ParseState *_parser) { - struct Value *Val; - long Result = 0; - if (!ExpressionParse(_parser, &Val)) { - ProgramFail(_parser, "expression expected"); - } - if (_parser->Mode == RunModeRun) { - if (!IS_NUMERIC_COERCIBLE(Val)) { - ProgramFail(_parser, "integer value expected instead of %t", Val->Typ); - } - Result = ExpressionCoerceInteger(Val); - VariableStackPop(_parser, Val); - } - return Result; -} - diff --git a/eci/expression.h b/eci/expression.h deleted file mode 100644 index 7a0cd88..0000000 --- a/eci/expression.h +++ /dev/null @@ -1,19 +0,0 @@ -/** - * @author Edouard DUPIN - * - * @copyright 2014, Edouard DUPIN, all right reserved - * - * @license APACHE-2 (see license file) - */ - -#ifndef __ECI_EXPRESSION_H__ -#define __ECI_EXPRESSION_H__ - -int ExpressionParse(struct ParseState *_parser, struct Value **_result); -long ExpressionParseInt(struct ParseState *_parser); -void ExpressionAssign(struct ParseState *_parser, struct Value *_destValue, struct Value *_sourceValue, int _force, const char *_funcName, int _paramNo, int _allowPointerCoercion); -long ExpressionCoerceInteger(struct Value *_value); -unsigned long ExpressionCoerceUnsignedInteger(struct Value *_value); -double ExpressionCoerceFP(struct Value *_value); - -#endif diff --git a/eci/heap.c b/eci/heap.c deleted file mode 100644 index e6095da..0000000 --- a/eci/heap.c +++ /dev/null @@ -1,127 +0,0 @@ -/** - * @author Edouard DUPIN - * - * @copyright 2014, Edouard DUPIN, all right reserved - * - * @license APACHE-2 (see license file) - */ - -/* stack grows up from the bottom and heap grows down from the top of heap space */ -#include "interpreter.h" - -#define FREELIST_BUCKETS 8 /* freelists for 4, 8, 12 ... 32 byte allocs */ -#define SPLIT_MEM_THRESHOLD 16 /* don't split memory which is close in size */ - -static unsigned char *HeapMemory = NULL; /* stack memory since our heap is malloc()ed */ -static void *HeapBottom = NULL; /* the bottom of the (downward-growing) heap */ -static void *StackFrame = NULL; /* the current stack frame */ -void *HeapStackTop = NULL; /* the top of the stack */ - -static struct AllocNode *FreeListBucket[FREELIST_BUCKETS]; /* we keep a pool of freelist buckets to reduce fragmentation */ -static struct AllocNode *FreeListBig; /* free memory which doesn't fit in a bucket */ - -#ifdef DEBUG_HEAP -void ShowBigList() { - struct AllocNode *LPos; - printf("Heap: bottom=0x%lx 0x%lx-0x%lx, big freelist=", (long)HeapBottom, (long)&HeapMemory[0], (long)&HeapMemory[HEAP_SIZE]); - for (LPos = FreeListBig; LPos != NULL; LPos = LPos->NextFree) { - printf("0x%lx:%d ", (long)LPos, LPos->Size); - } - printf("\n"); -} -#endif - -/* initialise the stack and heap storage */ -void HeapInit(int StackOrHeapSize) { - int Count; - int AlignOffset = 0; - HeapMemory = malloc(StackOrHeapSize); - while (((unsigned long)&HeapMemory[AlignOffset] & (sizeof(ALIGN_TYPE)-1)) != 0) { - AlignOffset++; - } - StackFrame = &HeapMemory[AlignOffset]; - HeapStackTop = &HeapMemory[AlignOffset]; - *(void **)StackFrame = NULL; - HeapBottom = &HeapMemory[StackOrHeapSize-sizeof(ALIGN_TYPE)+AlignOffset]; - FreeListBig = NULL; - for (Count = 0; Count < FREELIST_BUCKETS; Count++) { - FreeListBucket[Count] = NULL; - } -} - -void HeapCleanup() { - free(HeapMemory); -} - -/* allocate some space on the stack, in the current stack frame - * clears memory. can return NULL if out of stack space */ -void *HeapAllocStack(int Size) { - char *NewMem = HeapStackTop; - char *NewTop = (char *)HeapStackTop + MEM_ALIGN(Size); -#ifdef DEBUG_HEAP - printf("HeapAllocStack(%ld) at 0x%lx\n", (unsigned long)MEM_ALIGN(Size), (unsigned long)HeapStackTop); -#endif - if (NewTop > (char *)HeapBottom) { - return NULL; - } - HeapStackTop = (void *)NewTop; - memset((void *)NewMem, '\0', Size); - return NewMem; -} - -/* allocate some space on the stack, in the current stack frame */ -void HeapUnpopStack(int Size) { -#ifdef DEBUG_HEAP - printf("HeapUnpopStack(%ld) at 0x%lx\n", (unsigned long)MEM_ALIGN(Size), (unsigned long)HeapStackTop); -#endif - HeapStackTop = (void *)((char *)HeapStackTop + MEM_ALIGN(Size)); -} - -/* free some space at the top of the stack */ -int HeapPopStack(void *Addr, int Size) { - int ToLose = MEM_ALIGN(Size); - if (ToLose > ((char *)HeapStackTop - (char *)&HeapMemory[0])) { - return FALSE; - } -#ifdef DEBUG_HEAP - printf("HeapPopStack(0x%lx, %ld) back to 0x%lx\n", (unsigned long)Addr, (unsigned long)MEM_ALIGN(Size), (unsigned long)HeapStackTop - ToLose); -#endif - HeapStackTop = (void *)((char *)HeapStackTop - ToLose); - assert(Addr == NULL || HeapStackTop == Addr); - return TRUE; -} - -/* push a new stack frame on to the stack */ -void HeapPushStackFrame() { -#ifdef DEBUG_HEAP - printf("Adding stack frame at 0x%lx\n", (unsigned long)HeapStackTop); -#endif - *(void **)HeapStackTop = StackFrame; - StackFrame = HeapStackTop; - HeapStackTop = (void *)((char *)HeapStackTop + MEM_ALIGN(sizeof(ALIGN_TYPE))); -} - -/* pop the current stack frame, freeing all memory in the frame. can return NULL */ -int HeapPopStackFrame() { - if (*(void **)StackFrame != NULL) { - HeapStackTop = StackFrame; - StackFrame = *(void **)StackFrame; -#ifdef DEBUG_HEAP - printf("Popping stack frame back to 0x%lx\n", (unsigned long)HeapStackTop); -#endif - return TRUE; - } else { - return FALSE; - } -} - -/* allocate some dynamically allocated memory. memory is cleared. can return NULL if out of memory */ -void *HeapAllocMem(int Size) { - return calloc(Size, 1); -} - -/* free some dynamically allocated memory */ -void HeapFreeMem(void *Mem) { - free(Mem); -} - diff --git a/eci/heap.h b/eci/heap.h deleted file mode 100644 index 93a8189..0000000 --- a/eci/heap.h +++ /dev/null @@ -1,23 +0,0 @@ -/** - * @author Edouard DUPIN - * - * @copyright 2014, Edouard DUPIN, all right reserved - * - * @license APACHE-2 (see license file) - */ - -#ifndef __ECI_HEAP_H__ -#define __ECI_HEAP_H__ - - -void HeapInit(int _stackSize); -void HeapCleanup(); -void *HeapAllocStack(int _size); -int HeapPopStack(void *_addr, int _size); -void HeapUnpopStack(int _size); -void HeapPushStackFrame(); -int HeapPopStackFrame(); -void *HeapAllocMem(int _size); -void HeapFreeMem(void *_mem); - -#endif diff --git a/eci/include.c b/eci/include.c deleted file mode 100644 index ae6d2c1..0000000 --- a/eci/include.c +++ /dev/null @@ -1,100 +0,0 @@ -/** - * @author Edouard DUPIN - * - * @copyright 2014, Edouard DUPIN, all right reserved - * - * @license APACHE-2 (see license file) - */ - -#include "picoc.h" -#include "interpreter.h" - -#ifndef NO_HASH_INCLUDE - -/* a list of libraries we can include */ -struct IncludeLibrary { - char *IncludeName; - void (*SetupFunction)(void); - struct LibraryFunction *FuncList; - const char *SetupCSource; - struct IncludeLibrary *NextLib; -}; - -struct IncludeLibrary *IncludeLibList = NULL; - -/* initialise the built-in include libraries */ -void IncludeInit() { -#ifndef BUILTIN_MINI_STDLIB - IncludeRegister("ctype.h", NULL, &StdCtypeFunctions[0], NULL); - IncludeRegister("errno.h", &StdErrnoSetupFunc, NULL, NULL); - IncludeRegister("math.h", &MathSetupFunc, &MathFunctions[0], NULL); - IncludeRegister("stdbool.h", &StdboolSetupFunc, NULL, StdboolDefs); - IncludeRegister("stdio.h", &StdioSetupFunc, &StdioFunctions[0], StdioDefs); - IncludeRegister("stdlib.h", &StdlibSetupFunc, &StdlibFunctions[0], NULL); - IncludeRegister("string.h", &StringSetupFunc, &StringFunctions[0], NULL); - IncludeRegister("time.h", &StdTimeSetupFunc, &StdTimeFunctions[0], StdTimeDefs); - IncludeRegister("unistd.h", &UnistdSetupFunc, &UnistdFunctions[0], UnistdDefs); -#endif -} - -/* clean up space used by the include system */ -void IncludeCleanup() { - struct IncludeLibrary *ThisInclude = IncludeLibList; - struct IncludeLibrary *NextInclude; - while (ThisInclude != NULL) { - NextInclude = ThisInclude->NextLib; - HeapFreeMem(ThisInclude); - ThisInclude = NextInclude; - } - IncludeLibList = NULL; -} - -/* register a new build-in include file */ -void IncludeRegister(const char *IncludeName, void (*SetupFunction)(void), struct LibraryFunction *FuncList, const char *SetupCSource) { - struct IncludeLibrary *NewLib = HeapAllocMem(sizeof(struct IncludeLibrary)); - NewLib->IncludeName = TableStrRegister(IncludeName); - NewLib->SetupFunction = SetupFunction; - NewLib->FuncList = FuncList; - NewLib->SetupCSource = SetupCSource; - NewLib->NextLib = IncludeLibList; - IncludeLibList = NewLib; -} - -/* include all of the system headers */ -void PicocIncludeAllSystemHeaders() { - struct IncludeLibrary *ThisInclude = IncludeLibList; - for (; ThisInclude != NULL; ThisInclude = ThisInclude->NextLib) { - IncludeFile(ThisInclude->IncludeName); - } -} - -/* include one of a number of predefined libraries, or perhaps an actual file */ -void IncludeFile(char *FileName) { - struct IncludeLibrary *LInclude; - // scan for the include file name to see if it's in our list of predefined includes - for (LInclude = IncludeLibList; LInclude != NULL; LInclude = LInclude->NextLib) { - if (strcmp(LInclude->IncludeName, FileName) == 0) { - // found it - protect against multiple inclusion - if (!VariableDefined(FileName)) { - VariableDefine(NULL, FileName, NULL, &VoidType, FALSE); - // run an extra startup function if there is one - if (LInclude->SetupFunction != NULL) { - (*LInclude->SetupFunction)(); - } - // parse the setup C source code - may define types etc. - if (LInclude->SetupCSource != NULL) { - PicocParse(FileName, LInclude->SetupCSource, strlen(LInclude->SetupCSource), TRUE, TRUE, FALSE); - } - // set up the library functions - if (LInclude->FuncList != NULL) { - LibraryAdd(&GlobalTable, FileName, LInclude->FuncList); - } - } - return; - } - } - // not a predefined file, read a real file - PicocPlatformScanFile(FileName); -} - -#endif /* NO_HASH_INCLUDE */ diff --git a/eci/include.h b/eci/include.h deleted file mode 100644 index 874e6ca..0000000 --- a/eci/include.h +++ /dev/null @@ -1,21 +0,0 @@ -/** - * @author Edouard DUPIN - * - * @copyright 2014, Edouard DUPIN, all right reserved - * - * @license APACHE-2 (see license file) - */ - -#ifndef __ECI_INCLUDE_H__ -#define __ECI_INCLUDE_H__ - - -void IncludeInit(); -void IncludeCleanup(); -void IncludeRegister(const char *_includeName, void (*_setupFunction)(void), struct LibraryFunction *_funcList, const char *_setupCSource); -void IncludeFile(char *_filename); -/* the following is defined in picoc.h: - * void PicocIncludeAllSystemHeaders(); */ - - -#endif diff --git a/eci/interpreter.h b/eci/interpreter.h deleted file mode 100644 index 3ae552a..0000000 --- a/eci/interpreter.h +++ /dev/null @@ -1,354 +0,0 @@ -/** - * @author Edouard DUPIN - * - * @copyright 2014, Edouard DUPIN, all right reserved - * - * @license APACHE-2 (see license file) - */ - -#ifndef __ECI_INTERPRETER_H__ -#define __ECI_INTERPRETER_H__ - -#include "platform.h" - - -/* handy definitions */ -#ifndef TRUE -#define TRUE 1 -#define FALSE 0 -#endif - -#ifndef NULL -#define NULL 0 -#endif - -#ifndef min -#define min(x,y) (((x)<(y))?(x):(y)) -#endif - -#define MEM_ALIGN(x) (((x) + sizeof(ALIGN_TYPE) - 1) & ~(sizeof(ALIGN_TYPE)-1)) - -#define GETS_BUF_MAX 256 - -/* small processors use a simplified FILE * for stdio, otherwise use the system FILE * */ -#ifdef BUILTIN_MINI_STDLIB -typedef struct OutputStream IOFILE; -#else -typedef FILE IOFILE; -#endif - -/* coercion of numeric types to other numeric types */ -#define IS_FP(v) ((v)->Typ->Base == TypeFP) -#define FP_VAL(v) ((v)->Val->FP) - -#define IS_POINTER_COERCIBLE(v, ap) ((ap) ? ((v)->Typ->Base == TypePointer) : 0) -#define POINTER_COERCE(v) ((int)(v)->Val->Pointer) - -#define IS_INTEGER_NUMERIC_TYPE(t) ((t)->Base >= TypeInt && (t)->Base <= TypeUnsignedLong) -#define IS_INTEGER_NUMERIC(v) IS_INTEGER_NUMERIC_TYPE((v)->Typ) -#define IS_NUMERIC_COERCIBLE(v) (IS_INTEGER_NUMERIC(v) || IS_FP(v)) -#define IS_NUMERIC_COERCIBLE_PLUS_POINTERS(v,ap) (IS_NUMERIC_COERCIBLE(v) || IS_POINTER_COERCIBLE(v,ap)) - - -struct Table; - -/* lexical tokens */ -enum LexToken { - /* 0x00 */ TokenNone, - /* 0x01 */ TokenComma, - /* 0x02 */ TokenAssign, TokenAddAssign, TokenSubtractAssign, TokenMultiplyAssign, TokenDivideAssign, TokenModulusAssign, - /* 0x08 */ TokenShiftLeftAssign, TokenShiftRightAssign, TokenArithmeticAndAssign, TokenArithmeticOrAssign, TokenArithmeticExorAssign, - /* 0x0d */ TokenQuestionMark, TokenColon, - /* 0x0f */ TokenLogicalOr, - /* 0x10 */ TokenLogicalAnd, - /* 0x11 */ TokenArithmeticOr, - /* 0x12 */ TokenArithmeticExor, - /* 0x13 */ TokenAmpersand, - /* 0x14 */ TokenEqual, TokenNotEqual, - /* 0x16 */ TokenLessThan, TokenGreaterThan, TokenLessEqual, TokenGreaterEqual, - /* 0x1a */ TokenShiftLeft, TokenShiftRight, - /* 0x1c */ TokenPlus, TokenMinus, - /* 0x1e */ TokenAsterisk, TokenSlash, TokenModulus, - /* 0x21 */ TokenIncrement, TokenDecrement, TokenUnaryNot, TokenUnaryExor, TokenSizeof, TokenCast, - /* 0x27 */ TokenLeftSquareBracket, TokenRightSquareBracket, TokenDot, TokenArrow, - /* 0x2b */ TokenOpenBracket, TokenCloseBracket, - /* 0x2d */ TokenIdentifier, TokenIntegerConstant, TokenFPConstant, TokenStringConstant, TokenCharacterConstant, - /* 0x32 */ TokenSemicolon, TokenEllipsis, - /* 0x34 */ TokenLeftBrace, TokenRightBrace, - /* 0x36 */ TokenIntType, TokenCharType, TokenFloatType, TokenDoubleType, TokenVoidType, TokenEnumType, - /* 0x3c */ TokenLongType, TokenSignedType, TokenShortType, TokenStaticType, TokenAutoType, TokenRegisterType, TokenExternType, TokenStructType, TokenUnionType, TokenUnsignedType, TokenTypedef, - /* 0x46 */ TokenContinue, TokenDo, TokenElse, TokenFor, TokenGoto, TokenIf, TokenWhile, TokenBreak, TokenSwitch, TokenCase, TokenDefault, TokenReturn, - /* 0x52 */ TokenHashDefine, TokenHashInclude, TokenHashIf, TokenHashIfdef, TokenHashIfndef, TokenHashElse, TokenHashEndif, - /* 0x59 */ TokenNew, TokenDelete, - /* 0x5b */ TokenOpenMacroBracket, - /* 0x5c */ TokenEOF, TokenEndOfLine, TokenEndOfFunction -}; - -/* used in dynamic memory allocation */ -struct AllocNode { - unsigned int Size; - struct AllocNode *NextFree; -}; - -/* whether we're running or skipping code */ -enum RunMode { - RunModeRun, //!< we're running code as we parse it - RunModeSkip, //!< skipping code, not running - RunModeReturn, //!< returning from a function - RunModeCaseSearch, //!< searching for a case label - RunModeBreak, //!< breaking out of a switch/while/do - RunModeContinue, //!< as above but repeat the loop - RunModeGoto //!< searching for a goto label -}; - -/* parser state - has all this detail so we can parse nested files */ -struct ParseState { - const unsigned char *Pos; - const char *FileName; - short int Line; - short int CharacterPos; - enum RunMode Mode; //!< whether to skip or run code - int SearchLabel; //!< what case label we're searching for - const char *SearchGotoLabel; //!< what goto label we're searching for - short int HashIfLevel; - short int HashIfEvaluateToLevel; - const char *SourceText; -}; - -/* values */ -enum BaseType { - TypeVoid, //!< no type - TypeInt, //!< integer - TypeShort, //!< short integer - TypeChar, //!< a single character (unsigned) - TypeLong, //!< long integer - TypeUnsignedInt, //!< unsigned integer - TypeUnsignedShort, //!< unsigned short integer - TypeUnsignedLong, //!< unsigned long integer - TypeFP, //!< floating point - TypeFunction, //!< a function - TypeMacro, //!< a macro - TypePointer, //!< a pointer - TypeArray, //!< an array of a sub-type - TypeStruct, //!< aggregate type - TypeUnion, //!< merged type - TypeEnum, //!< enumerated integer type - TypeGotoLabel, //!< a label we can "goto" - Type_Type //!< a type for storing types -}; - -/* data type */ -struct ValueType { - enum BaseType Base; //!< what kind of type this is - int ArraySize; //!< the size of an array type - int Sizeof; //!< the storage required - int AlignBytes; //!< the alignment boundary of this type - const char *Identifier; //!< the name of a struct or union - struct ValueType *FromType; //!< the type we're derived from (or NULL) - struct ValueType *DerivedTypeList; //!< first in a list of types derived from this one - struct ValueType *Next; //!< next item in the derived type list - struct Table *Members; //!< members of a struct or union - int OnHeap; //!< true if allocated on the heap - int StaticQualifier; //!< true if it's a static -}; - -/* function definition */ -struct FuncDef { - struct ValueType *ReturnType; //!< the return value type - int NumParams; //!< the number of parameters - int VarArgs; //!< has a variable number of arguments after the explicitly specified ones - struct ValueType **ParamType; //!< array of parameter types - char **ParamName; //!< array of parameter names - void (*Intrinsic)(); //!< intrinsic call address or NULL - struct ParseState Body; //!< lexical tokens of the function body if not intrinsic -}; - -/* macro definition */ -struct MacroDef { - int NumParams; //!< the number of parameters - char **ParamName; //!< array of parameter names - struct ParseState Body; //!< lexical tokens of the function body if not intrinsic -}; - -/* values */ -union AnyValue { - unsigned char Character; - short ShortInteger; - int Integer; - long LongInteger; - unsigned short UnsignedShortInteger; - unsigned int UnsignedInteger; - unsigned long UnsignedLongInteger; - char *Identifier; - char ArrayMem[2]; //!< placeholder for where the data starts, doesn't point to it - struct ValueType *Typ; - struct FuncDef FuncDef; - struct MacroDef MacroDef; - double FP; - void *Pointer; //!< unsafe native pointers -}; - -struct Value -{ - struct ValueType *Typ; //!< the type of this value - union AnyValue *Val; //!< pointer to the AnyValue which holds the actual content - struct Value *LValueFrom; //!< if an LValue, this is a Value our LValue is contained within (or NULL) - char ValOnHeap; //!< the AnyValue is on the heap (but this Value is on the stack) - char ValOnStack; //!< the AnyValue is on the stack along with this Value - char IsLValue; //!< is modifiable and is allocated somewhere we can usefully modify it -}; - -/* hash table data structure */ -struct TableEntry { - struct TableEntry *Next; //!< next item in this hash chain - const char *DeclFileName; //!< where the variable was declared - unsigned short DeclLine; - unsigned short DeclColumn; - union TableEntryPayload { - struct ValueEntry { - char *Key; //!< points to the shared string table - struct Value *Val; //!< the value we're storing - } v; //!< used for tables of values - char Key[1]; //!< dummy size - used for the shared string table - } p; -}; - -struct Table { - short Size; - short OnHeap; - struct TableEntry **HashTable; -}; - -/* stack frame for function calls */ -struct StackFrame { - struct ParseState ReturnParser; //!< how we got here - const char *FuncName; //!< the name of the function we're in - struct Value *ReturnValue; //!< copy the return value here - struct Value **Parameter; //!< array of parameter values - int NumParams; //!< the number of parameters - struct Table LocalTable; //!< the local variables and parameters - struct TableEntry *LocalHashTable[LOCAL_TABLE_SIZE]; - struct StackFrame *PreviousStackFrame; //!< the next lower stack frame -}; - -/* lexer state */ -enum LexMode { - LexModeNormal, - LexModeHashInclude, - LexModeHashDefine, - LexModeHashDefineSpace, - LexModeHashDefineSpaceIdent -}; - -struct LexState { - const char *Pos; - const char *End; - const char *FileName; - int Line; - int CharacterPos; - const char *SourceText; - enum LexMode Mode; - int EmitExtraNewlines; -}; - -/* library function definition */ -struct LibraryFunction { - void (*Func)(struct ParseState *Parser, struct Value *, struct Value **, int); - const char *Prototype; -}; - -/* output stream-type specific state information */ -union OutputStreamInfo { - struct StringOutputStream { - struct ParseState *Parser; - char *WritePos; - } Str; -}; - -/* stream-specific method for writing characters to the console */ -typedef void CharWriter(unsigned char, union OutputStreamInfo *); - -/* used when writing output to a string - eg. sprintf() */ -struct OutputStream { - CharWriter *Putch; - union OutputStreamInfo i; -}; - -/* possible results of parsing a statement */ -enum ParseResult { - ParseResultEOF, - ParseResultError, - ParseResultOk -}; - -/* globals */ -extern void *HeapStackTop; -extern struct Table GlobalTable; -extern struct StackFrame *TopStackFrame; -extern struct ValueType UberType; -extern struct ValueType IntType; -extern struct ValueType CharType; -extern struct ValueType FPType; -extern struct ValueType VoidType; -extern struct ValueType TypeType; -extern struct ValueType FunctionType; -extern struct ValueType MacroType; -extern struct ValueType GotoLabelType; -extern struct ValueType *CharPtrType; -extern struct ValueType *CharPtrPtrType; -extern struct ValueType *CharArrayType; -extern struct ValueType *VoidPtrType; -extern char *StrEmpty; -extern struct PointerValue NULLPointer; -extern struct LibraryFunction CLibrary[]; -extern struct LibraryFunction PlatformLibrary[]; -extern IOFILE *CStdOut; - -#include -#include -#include - -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - - -// TODO : Move this ... platform.h: - -/* the following are defined in picoc.h: - * void PicocCallMain(int argc, char **argv); - * int PicocPlatformSetExitPoint(); - * void PicocInitialise(int StackSize); - * void PicocCleanup(); - * void PicocPlatformScanFile(const char *FileName); - * extern int PicocExitValue; */ -void ProgramFail(struct ParseState *_parser, const char *_message, ...); -void AssignFail(struct ParseState *_parser, const char *_mormat, struct ValueType *_type1, struct ValueType *_type2, int _num1, int _num2, const char *_funcName, int _paramNo); -void LexFail(struct LexState *_lexer, const char *_message, ...); -void PlatformCleanup(); -char *PlatformGetLine(char *_buf, int _maxLen, const char *_prompt); -int PlatformGetCharacter(); -void PlatformPutc(unsigned char _outCh, union OutputStreamInfo *); -void PlatformErrorPrefix(struct ParseState *_parser); -void PlatformPrintf(const char *_format, ...); -void PlatformVPrintf(const char *_format, va_list _args); -void PlatformExit(int _exitVal); -char *PlatformMakeTempName(char *_tempNameBuffer); -void PlatformLibraryInit(); - - -#endif diff --git a/eci/lang/ParserCpp.cpp b/eci/lang/ParserCpp.cpp new file mode 100644 index 0000000..2472e88 --- /dev/null +++ b/eci/lang/ParserCpp.cpp @@ -0,0 +1,30 @@ +/** + * @author Edouard DUPIN + * + * @copyright 2014, Edouard DUPIN, all right reserved + * + * @license APACHE-2 (see license file) + */ + +#include + +enum cppTokenList { + tokenCppMultilineComment, + tokenCppSingleLineComment, + +}; + +eci::ParserCpp::ParserCpp() { + m_lexer.append(tokenCppMultilineComment, "/\\*.*\\*/"); + m_lexer.append(tokenCppSingleLineComment, "//$"); +} + +eci::ParserCpp::~ParserCpp() { + +} + +bool eci::ParserCpp::parse(const std::string& _data) { + m_result = m_lexer.interprete(_data); + return false; +} + diff --git a/eci/lang/ParserCpp.h b/eci/lang/ParserCpp.h new file mode 100644 index 0000000..ed41098 --- /dev/null +++ b/eci/lang/ParserCpp.h @@ -0,0 +1,26 @@ +/** + * @author Edouard DUPIN + * + * @copyright 2014, Edouard DUPIN, all right reserved + * + * @license APACHE-2 (see license file) + */ + +#ifndef __ECI_PARSER_CPP_H__ +#define __ECI_PARSER_CPP_H__ + +#include + +namespace eci { + class ParserCpp { + private: + eci::Lexer m_lexer; + eci::LexerResult m_result; + public: + ParserCpp(); + ~ParserCpp(); + bool parse(const std::string& _data); + }; +} + +#endif diff --git a/eci/lex.c b/eci/lex.c deleted file mode 100644 index 5ca605e..0000000 --- a/eci/lex.c +++ /dev/null @@ -1,975 +0,0 @@ -/** - * @author Edouard DUPIN - * - * @copyright 2014, Edouard DUPIN, all right reserved - * - * @license APACHE-2 (see license file) - */ - -#include "interpreter.h" - -#define isCidstart(c) (isalpha(c) || (c)=='_' || (c)=='#') -#define isCident(c) (isalnum(c) || (c)=='_') - -#define IS_HEX_ALPHA_DIGIT(c) (((c) >= 'a' && (c) <= 'f') || ((c) >= 'A' && (c) <= 'F')) -#define IS_BASE_DIGIT(c,b) (((c) >= '0' && (c) < '0' + (((b)<10)?(b):10)) || (((b) > 10) ? IS_HEX_ALPHA_DIGIT(c) : FALSE)) -#define GET_BASE_DIGIT(c) (((c) <= '9') ? ((c) - '0') : (((c) <= 'F') ? ((c) - 'A' + 10) : ((c) - 'a' + 10))) - -#define NEXTIS(c,x,y) { if (NextChar == (c)) { LEXER_INC(_lexer); GotToken = (x); } else GotToken = (y); } -#define NEXTIS3(c,x,d,y,z) { if (NextChar == (c)) { LEXER_INC(_lexer); GotToken = (x); } else NEXTIS(d,y,z) } -#define NEXTIS4(c,x,d,y,e,z,a) { if (NextChar == (c)) { LEXER_INC(_lexer); GotToken = (x); } else NEXTIS3(d,y,e,z,a) } -#define NEXTIS3PLUS(c,x,d,y,e,z,a) { if (NextChar == (c)) { LEXER_INC(_lexer); GotToken = (x); } else if (NextChar == (d)) { if (_lexer->Pos[1] == (e)) { LEXER_INCN(_lexer, 2); GotToken = (z); } else { LEXER_INC(_lexer); GotToken = (y); } } else GotToken = (a); } -#define NEXTISEXACTLY3(c,d,y,z) { if (NextChar == (c) && _lexer->Pos[1] == (d)) { LEXER_INCN(_lexer, 2); GotToken = (y); } else GotToken = (z); } - -#define LEXER_INC(l) ( (l)->Pos++, (l)->CharacterPos++ ) -#define LEXER_INCN(l, n) ( (l)->Pos+=(n), (l)->CharacterPos+=(n) ) -#define TOKEN_DATA_OFFSET 2 - -#define MAX_CHAR_VALUE 255 /* maximum value which can be represented by a "char" data type */ - -static union AnyValue LexAnyValue; -static struct Value LexValue = { - TypeVoid, - &LexAnyValue, - FALSE, - FALSE -}; - -struct ReservedWord { - const char *Word; - enum LexToken Token; - const char *SharedWord; /* word stored in shared string space */ -}; - -static struct ReservedWord ReservedWords[] = { - { "#define", TokenHashDefine, NULL }, - { "#else", TokenHashElse, NULL }, - { "#endif", TokenHashEndif, NULL }, - { "#if", TokenHashIf, NULL }, - { "#ifdef", TokenHashIfdef, NULL }, - { "#ifndef", TokenHashIfndef, NULL }, - { "#include", TokenHashInclude, NULL }, - { "auto", TokenAutoType, NULL }, - { "break", TokenBreak, NULL }, - { "case", TokenCase, NULL }, - { "char", TokenCharType, NULL }, - { "continue", TokenContinue, NULL }, - { "default", TokenDefault, NULL }, - { "delete", TokenDelete, NULL }, - { "do", TokenDo, NULL }, - { "double", TokenDoubleType, NULL }, - { "else", TokenElse, NULL }, - { "enum", TokenEnumType, NULL }, - { "extern", TokenExternType, NULL }, - { "float", TokenFloatType, NULL }, - { "for", TokenFor, NULL }, - { "goto", TokenGoto, NULL }, - { "if", TokenIf, NULL }, - { "int", TokenIntType, NULL }, - { "long", TokenLongType, NULL }, - { "new", TokenNew, NULL }, - { "register", TokenRegisterType, NULL }, - { "return", TokenReturn, NULL }, - { "short", TokenShortType, NULL }, - { "signed", TokenSignedType, NULL }, - { "sizeof", TokenSizeof, NULL }, - { "static", TokenStaticType, NULL }, - { "struct", TokenStructType, NULL }, - { "switch", TokenSwitch, NULL }, - { "typedef", TokenTypedef, NULL }, - { "union", TokenUnionType, NULL }, - { "unsigned", TokenUnsignedType, NULL }, - { "void", TokenVoidType, NULL }, - { "while", TokenWhile, NULL } -}; - -/* linked list of tokens used in interactive mode */ -struct TokenLine { - struct TokenLine *Next; - unsigned char *Tokens; - int NumBytes; -}; - -static struct TokenLine *InteractiveHead = NULL; -static struct TokenLine *InteractiveTail = NULL; -static struct TokenLine *InteractiveCurrentLine = NULL; -static int LexUseStatementPrompt = FALSE; - - -/* initialise the lexer */ -void LexInit() { - int Count; - for (Count = 0; Count < sizeof(ReservedWords) / sizeof(struct ReservedWord); Count++) { - ReservedWords[Count].SharedWord = TableStrRegister(ReservedWords[Count].Word); - } -} - -/* deallocate */ -void LexCleanup() { - LexInteractiveClear(NULL); -} - -/* check if a word is a reserved word - used while scanning */ -enum LexToken LexCheckReservedWord(const char *_word) { - int Count; - for (Count = 0; Count < sizeof(ReservedWords) / sizeof(struct ReservedWord); Count++) { - if (_word == ReservedWords[Count].SharedWord) { - return ReservedWords[Count].Token; - } - } - return TokenNone; -} - -/* get a numeric literal - used while scanning */ -enum LexToken LexGetNumber(struct LexState *_lexer, struct Value *_value) { - int Result = 0; - int Base = 10; - enum LexToken ResultToken; - double FPResult; - double FPDiv; - if (*_lexer->Pos == '0') { - /* a binary, octal or hex literal */ - LEXER_INC(_lexer); - if (_lexer->Pos != _lexer->End) { - if ( *_lexer->Pos == 'x' - || *_lexer->Pos == 'X') { - Base = 16; - LEXER_INC(_lexer); - } else if (*_lexer->Pos == 'b' || *_lexer->Pos == 'B') { - Base = 2; - LEXER_INC(_lexer); - } else if (*_lexer->Pos != '.') { - Base = 8; - } - } - } - /* get the value */ - for (; _lexer->Pos != _lexer->End && IS_BASE_DIGIT(*_lexer->Pos, Base); LEXER_INC(_lexer)) { - Result = Result * Base + GET_BASE_DIGIT(*_lexer->Pos); - } - if (Result >= 0 && Result <= MAX_CHAR_VALUE) { - _value->Typ = &CharType; - _value->Val->Character = Result; - ResultToken = TokenCharacterConstant; - } else { - _value->Typ = &IntType; - _value->Val->Integer = Result; - ResultToken = TokenIntegerConstant; - } - if (_lexer->Pos == _lexer->End) { - return ResultToken; - } - if ( *_lexer->Pos == 'l' - || *_lexer->Pos == 'L') { - LEXER_INC(_lexer); - return ResultToken; - } - if ( _lexer->Pos == _lexer->End - || *_lexer->Pos != '.') { - return ResultToken; - } - _value->Typ = &FPType; - LEXER_INC(_lexer); - for (FPDiv = 1.0/Base, FPResult = (double)Result; _lexer->Pos != _lexer->End && IS_BASE_DIGIT(*_lexer->Pos, Base); LEXER_INC(_lexer), FPDiv /= (double)Base) { - FPResult += GET_BASE_DIGIT(*_lexer->Pos) * FPDiv; - } - - if ( _lexer->Pos != _lexer->End - && ( *_lexer->Pos == 'e' - || *_lexer->Pos == 'E') ) { - double ExponentMultiplier = 1.0; - LEXER_INC(_lexer); - if (_lexer->Pos != _lexer->End && *_lexer->Pos == '-') { - ExponentMultiplier = -1.0; - LEXER_INC(_lexer); - } - for (Result = 0; _lexer->Pos != _lexer->End && IS_BASE_DIGIT(*_lexer->Pos, Base); LEXER_INC(_lexer)) { - Result = Result * (double)Base + GET_BASE_DIGIT(*_lexer->Pos); - } - FPResult *= pow((double)Base, (double)Result * ExponentMultiplier); - } - _value->Val->FP = FPResult; - return TokenFPConstant; -} - -/* get a reserved word or identifier - used while scanning */ -enum LexToken LexGetWord(struct LexState *_lexer, struct Value *_value) { - const char *StartPos = _lexer->Pos; - enum LexToken Token; - do { - LEXER_INC(_lexer); - } while ( _lexer->Pos != _lexer->End - && isCident((int)*_lexer->Pos)); - _value->Typ = NULL; - _value->Val->Identifier = TableStrRegister2(StartPos, _lexer->Pos - StartPos); - Token = LexCheckReservedWord(_value->Val->Identifier); - switch (Token) { - case TokenHashInclude: _lexer->Mode = LexModeHashInclude; break; - case TokenHashDefine: _lexer->Mode = LexModeHashDefine; break; - default: break; - } - if (Token != TokenNone) { - return Token; - } - if (_lexer->Mode == LexModeHashDefineSpace) { - _lexer->Mode = LexModeHashDefineSpaceIdent; - } - return TokenIdentifier; -} - -/* unescape a character from an octal character constant */ -unsigned char LexUnEscapeCharacterConstant(const char** _from, const char* _end, unsigned char _firstChar, int _base) { - unsigned char total = GET_BASE_DIGIT(_firstChar); - int CCount; - for (CCount = 0; IS_BASE_DIGIT(**_from, _base) && CCount < 2; CCount++, (*_from)++) { - total = total * _base + GET_BASE_DIGIT(**_from); - } - return total; -} - -/* unescape a character from a string or character constant */ -unsigned char LexUnEscapeCharacter(const char **_from, const char *_end) { - unsigned char ThisChar; - while ( *_from != _end - && **_from == '\\' - && &(*_from)[1] != _end - && (*_from)[1] == '\n' ) { - (*_from) += 2; /* skip escaped end of lines with LF line termination */ - } - while ( *_from != _end - && **_from == '\\' - && &(*_from)[1] != _end - && &(*_from)[2] != _end - && (*_from)[1] == '\r' - && (*_from)[2] == '\n') { - (*_from) += 3; /* skip escaped end of lines with CR/LF line termination */ - } - if (*_from == _end) { - return '\\'; - } - if (**_from == '\\') { - /* it's escaped */ - (*_from)++; - if (*_from == _end) { - return '\\'; - } - ThisChar = *(*_from)++; - switch (ThisChar) { - case '\\': - return '\\'; - case '\'': - return '\''; - case '"': - return '"'; - case 'a': - return '\a'; - case 'b': - return '\b'; - case 'f': - return '\f'; - case 'n': - return '\n'; - case 'r': - return '\r'; - case 't': - return '\t'; - case 'v': - return '\v'; - case '0': - case '1': - case '2': - case '3': - return LexUnEscapeCharacterConstant(_from, _end, ThisChar, 8); - case 'x': - return LexUnEscapeCharacterConstant(_from, _end, '0', 16); - default: - return ThisChar; - } - } else { - return *(*_from)++; - } -} - -/* get a string constant - used while scanning */ -enum LexToken LexGetStringConstant(struct LexState *_lexer, struct Value *_value, char _endChar) { - int Escape = FALSE; - const char *StartPos = _lexer->Pos; - const char *EndPos; - char *EscBuf; - char *EscBufPos; - char *RegString; - struct Value *ArrayValue; - - while ( _lexer->Pos != _lexer->End - && ( *_lexer->Pos != _endChar - || Escape)) { - /* find the end */ - if (Escape) { - if ( *_lexer->Pos == '\r' - && _lexer->Pos+1 != _lexer->End) { - _lexer->Pos++; - } - if ( *_lexer->Pos == '\n' - && _lexer->Pos+1 != _lexer->End) { - _lexer->Line++; - _lexer->Pos++; - _lexer->CharacterPos = 0; - _lexer->EmitExtraNewlines++; - } - Escape = FALSE; - } else if (*_lexer->Pos == '\\') { - Escape = TRUE; - } - LEXER_INC(_lexer); - } - EndPos = _lexer->Pos; - EscBuf = HeapAllocStack(EndPos - StartPos); - if (EscBuf == NULL) { - LexFail(_lexer, "out of memory"); - } - for (EscBufPos = EscBuf, _lexer->Pos = StartPos; _lexer->Pos != EndPos;) { - *EscBufPos++ = LexUnEscapeCharacter(&_lexer->Pos, EndPos); - } - /* try to find an existing copy of this string literal */ - RegString = TableStrRegister2(EscBuf, EscBufPos - EscBuf); - HeapPopStack(EscBuf, EndPos - StartPos); - ArrayValue = VariableStringLiteralGet(RegString); - if (ArrayValue == NULL) { - /* create and store this string literal */ - ArrayValue = VariableAllocValueAndData(NULL, 0, FALSE, NULL, TRUE); - ArrayValue->Typ = CharArrayType; - ArrayValue->Val = (union AnyValue *)RegString; - VariableStringLiteralDefine(RegString, ArrayValue); - } - /* create the the pointer for this char* */ - _value->Typ = CharPtrType; - _value->Val->Pointer = RegString; - if (*_lexer->Pos == _endChar) { - LEXER_INC(_lexer); - } - return TokenStringConstant; -} - -/* get a character constant - used while scanning */ -enum LexToken LexGetCharacterConstant(struct LexState *_lexer, struct Value *_value) { - _value->Typ = &CharType; - _value->Val->Character = LexUnEscapeCharacter(&_lexer->Pos, _lexer->End); - if (_lexer->Pos != _lexer->End && *_lexer->Pos != '\'') { - LexFail(_lexer, "expected \"'\""); // " - } - LEXER_INC(_lexer); - return TokenCharacterConstant; -} - -/* skip a comment - used while scanning */ -void LexSkipComment(struct LexState *_lexer, char _nextChar, enum LexToken *_returnToken) { - if (_nextChar == '*') { - /* conventional C comment */ - while (_lexer->Pos != _lexer->End && (*(_lexer->Pos-1) != '*' || *_lexer->Pos != '/')) { - if (*_lexer->Pos == '\n') { - _lexer->EmitExtraNewlines++; - } - LEXER_INC(_lexer); - } - if (_lexer->Pos != _lexer->End) { - LEXER_INC(_lexer); - } - _lexer->Mode = LexModeNormal; - } else { - /* C++ style comment */ - while ( _lexer->Pos != _lexer->End - && *_lexer->Pos != '\n') { - LEXER_INC(_lexer); - } - } -} - -/* get a single token from the source - used while scanning */ -enum LexToken LexScanGetToken(struct LexState *_lexer, struct Value **_value) { - char ThisChar; - char NextChar; - enum LexToken GotToken = TokenNone; - /* handle cases line multi-line comments or string constants which mess up the line count */ - if (_lexer->EmitExtraNewlines > 0) { - _lexer->EmitExtraNewlines--; - return TokenEndOfLine; - } - /* scan for a token */ - do { - *_value = &LexValue; - while ( _lexer->Pos != _lexer->End - && isspace((int)*_lexer->Pos)) { - if (*_lexer->Pos == '\n') { - _lexer->Line++; - _lexer->Pos++; - _lexer->Mode = LexModeNormal; - _lexer->CharacterPos = 0; - return TokenEndOfLine; - } else if ( _lexer->Mode == LexModeHashDefine - || _lexer->Mode == LexModeHashDefineSpace) { - _lexer->Mode = LexModeHashDefineSpace; - } else if (_lexer->Mode == LexModeHashDefineSpaceIdent) { - _lexer->Mode = LexModeNormal; - } - LEXER_INC(_lexer); - } - if ( _lexer->Pos == _lexer->End - || *_lexer->Pos == '\0') { - return TokenEOF; - } - ThisChar = *_lexer->Pos; - if (isCidstart((int)ThisChar)) { - return LexGetWord(_lexer, *_value); - } - if (isdigit((int)ThisChar)) { - return LexGetNumber(_lexer, *_value); - } - NextChar = (_lexer->Pos+1 != _lexer->End) ? *(_lexer->Pos+1) : 0; - LEXER_INC(_lexer); - switch (ThisChar) { - case '"': - GotToken = LexGetStringConstant(_lexer, *_value, '"'); - break; - case '\'': //' - GotToken = LexGetCharacterConstant(_lexer, *_value); - break; - case '(': - if (_lexer->Mode == LexModeHashDefineSpaceIdent) { - GotToken = TokenOpenMacroBracket; - } else { - GotToken = TokenOpenBracket; - } - _lexer->Mode = LexModeNormal; - break; - case ')': - GotToken = TokenCloseBracket; - break; - case '=': - NEXTIS('=', TokenEqual, TokenAssign); - break; - case '+': - NEXTIS3('=', TokenAddAssign, '+', TokenIncrement, TokenPlus); - break; - case '-': - NEXTIS4('=', TokenSubtractAssign, '>', TokenArrow, '-', TokenDecrement, TokenMinus); - break; - case '*': - NEXTIS('=', TokenMultiplyAssign, TokenAsterisk); - break; - case '/': - if ( NextChar == '/' - || NextChar == '*') { - LEXER_INC(_lexer); - LexSkipComment(_lexer, NextChar, &GotToken); - } else { - NEXTIS('=', TokenDivideAssign, TokenSlash); - } - break; - case '%': - NEXTIS('=', TokenModulusAssign, TokenModulus); - break; - case '<': - if (_lexer->Mode == LexModeHashInclude) { - GotToken = LexGetStringConstant(_lexer, *_value, '>'); - } else { - NEXTIS3PLUS('=', TokenLessEqual, '<', TokenShiftLeft, '=', TokenShiftLeftAssign, TokenLessThan); - } - break; - case '>': - NEXTIS3PLUS('=', TokenGreaterEqual, '>', TokenShiftRight, '=', TokenShiftRightAssign, TokenGreaterThan); - break; - case ';': - GotToken = TokenSemicolon; - break; - case '&': - NEXTIS3('=', TokenArithmeticAndAssign, '&', TokenLogicalAnd, TokenAmpersand); - break; - case '|': - NEXTIS3('=', TokenArithmeticOrAssign, '|', TokenLogicalOr, TokenArithmeticOr); - break; - case '{': - GotToken = TokenLeftBrace; - break; - case '}': - GotToken = TokenRightBrace; - break; - case '[': - GotToken = TokenLeftSquareBracket; - break; - case ']': - GotToken = TokenRightSquareBracket; - break; - case '!': - NEXTIS('=', TokenNotEqual, TokenUnaryNot); - break; - case '^': - NEXTIS('=', TokenArithmeticExorAssign, TokenArithmeticExor); - break; - case '~': - GotToken = TokenUnaryExor; - break; - case ',': - GotToken = TokenComma; - break; - case '.': - NEXTISEXACTLY3('.', '.', TokenEllipsis, TokenDot); - break; - case '?': - GotToken = TokenQuestionMark; - break; - case ':': - GotToken = TokenColon; - break; - default: - LexFail(_lexer, "illegal character '%c'", ThisChar); - break; - } - } while (GotToken == TokenNone); - return GotToken; -} - -/* what size value goes with each token */ -int LexTokenSize(enum LexToken _token) { - switch (_token) { - case TokenIdentifier: - case TokenStringConstant: - return sizeof(char *); - case TokenIntegerConstant: - return sizeof(int); - case TokenCharacterConstant: - return sizeof(unsigned char); - case TokenFPConstant: - return sizeof(double); - default: - return 0; - } -} - -/* produce tokens from the lexer and return a heap buffer with the result - used for scanning */ -void *LexTokenise(struct LexState *_lexer, int *_tokenLen) { - enum LexToken Token; - void *HeapMem; - struct Value *GotValue; - int MemUsed = 0; - int ValueSize; - int ReserveSpace = (_lexer->End - _lexer->Pos) * 4 + 16; - void *TokenSpace = HeapAllocStack(ReserveSpace); - char *TokenPos = (char *)TokenSpace; - int LastCharacterPos = 0; - if (TokenSpace == NULL) { - LexFail(_lexer, "out of memory"); - } - do { - /* store the token at the end of the stack area */ - Token = LexScanGetToken(_lexer, &GotValue); -#ifdef DEBUG_LEXER - printf("Token: %02x\n", Token); -#endif - *(unsigned char *)TokenPos = Token; - TokenPos++; - MemUsed++; - *(unsigned char *)TokenPos = (unsigned char)LastCharacterPos; - TokenPos++; - MemUsed++; - ValueSize = LexTokenSize(Token); - if (ValueSize > 0) { - /* store a value as well */ - memcpy((void *)TokenPos, (void *)GotValue->Val, ValueSize); - TokenPos += ValueSize; - MemUsed += ValueSize; - } - LastCharacterPos = _lexer->CharacterPos; - } while (Token != TokenEOF); - HeapMem = HeapAllocMem(MemUsed); - if (HeapMem == NULL) { - LexFail(_lexer, "out of memory"); - } - assert(ReserveSpace >= MemUsed); - memcpy(HeapMem, TokenSpace, MemUsed); - HeapPopStack(TokenSpace, ReserveSpace); -#ifdef DEBUG_LEXER - { - int Count; - printf("Tokens: "); - for (Count = 0; Count < MemUsed; Count++) { - printf("%02x ", *((unsigned char *)HeapMem+Count)); - } - printf("\n"); - } -#endif - if (_tokenLen) { - *_tokenLen = MemUsed; - } - return HeapMem; -} - -/* lexically analyse some source text */ -void *LexAnalyse(const char* _fileName, const char* _source, int _sourceLen, int *_tokenLen) { - struct LexState Lexer; - Lexer.Pos = _source; - Lexer.End = _source + _sourceLen; - Lexer.Line = 1; - Lexer.FileName = _fileName; - Lexer.Mode = LexModeNormal; - Lexer.EmitExtraNewlines = 0; - Lexer.CharacterPos = 1; - Lexer.SourceText = _source; - return LexTokenise(&Lexer, _tokenLen); -} - -/* prepare to parse a pre-tokenised buffer */ -void LexInitParser(struct ParseState* _parser, const char* _sourceText, void* _tokenSource, const char* _fileName, int _runIt){ - _parser->Pos = _tokenSource; - _parser->Line = 1; - _parser->FileName = _fileName; - _parser->Mode = _runIt ? RunModeRun : RunModeSkip; - _parser->SearchLabel = 0; - _parser->HashIfLevel = 0; - _parser->HashIfEvaluateToLevel = 0; - _parser->CharacterPos = 0; - _parser->SourceText = _sourceText; -} - -/* get the next token, without pre-processing */ -enum LexToken LexGetRawToken(struct ParseState *_parser, struct Value **_value, int _incPos) { - enum LexToken Token = TokenNone; - int ValueSize; - char *Prompt = NULL; - do { - /* get the next token */ - if ( _parser->Pos == NULL - && InteractiveHead != NULL) { - _parser->Pos = InteractiveHead->Tokens; - } - if ( _parser->FileName != StrEmpty - || InteractiveHead != NULL) { - /* skip leading newlines */ - while ((Token = (enum LexToken)*(unsigned char *)_parser->Pos) == TokenEndOfLine) { - _parser->Line++; - _parser->Pos += TOKEN_DATA_OFFSET; - } - } - if ( _parser->FileName == StrEmpty - && ( InteractiveHead == NULL - || Token == TokenEOF) ) { - /* we're at the end of an interactive input token list */ - char LineBuffer[LINEBUFFER_MAX]; - void *LineTokens; - int LineBytes; - struct TokenLine *LineNode; - if ( InteractiveHead == NULL - || (unsigned char *)_parser->Pos == &InteractiveTail->Tokens[InteractiveTail->NumBytes-TOKEN_DATA_OFFSET]) { - /* get interactive input */ - if (LexUseStatementPrompt) { - Prompt = INTERACTIVE_PROMPT_STATEMENT; - LexUseStatementPrompt = FALSE; - } else { - Prompt = INTERACTIVE_PROMPT_LINE; - } - if (PlatformGetLine(&LineBuffer[0], LINEBUFFER_MAX, Prompt) == NULL) { - return TokenEOF; - } - /* put the new line at the end of the linked list of interactive lines */ - LineTokens = LexAnalyse(StrEmpty, &LineBuffer[0], strlen(LineBuffer), &LineBytes); - LineNode = VariableAlloc(_parser, sizeof(struct TokenLine), TRUE); - LineNode->Tokens = LineTokens; - LineNode->NumBytes = LineBytes; - if (InteractiveHead == NULL) { - /* start a new list */ - InteractiveHead = LineNode; - _parser->Line = 1; - _parser->CharacterPos = 0; - } else { - InteractiveTail->Next = LineNode; - } - InteractiveTail = LineNode; - InteractiveCurrentLine = LineNode; - _parser->Pos = LineTokens; - } else { - /* go to the next token line */ - if (_parser->Pos != &InteractiveCurrentLine->Tokens[InteractiveCurrentLine->NumBytes-TOKEN_DATA_OFFSET]) { - /* scan for the line */ - for (InteractiveCurrentLine = InteractiveHead; _parser->Pos != &InteractiveCurrentLine->Tokens[InteractiveCurrentLine->NumBytes-TOKEN_DATA_OFFSET]; InteractiveCurrentLine = InteractiveCurrentLine->Next) { - assert(InteractiveCurrentLine->Next != NULL); - } - } - assert(InteractiveCurrentLine != NULL); - InteractiveCurrentLine = InteractiveCurrentLine->Next; - assert(InteractiveCurrentLine != NULL); - _parser->Pos = InteractiveCurrentLine->Tokens; - } - Token = (enum LexToken)*(unsigned char *)_parser->Pos; - } - } while ( ( _parser->FileName == StrEmpty - && Token == TokenEOF) - || Token == TokenEndOfLine); - _parser->CharacterPos = *((unsigned char *)_parser->Pos + 1); - ValueSize = LexTokenSize(Token); - if (ValueSize > 0) { - /* this token requires a value - unpack it */ - if (_value != NULL) { - switch (Token) { - case TokenStringConstant: - LexValue.Typ = CharPtrType; - break; - case TokenIdentifier: - LexValue.Typ = NULL; - break; - case TokenIntegerConstant: - LexValue.Typ = &IntType; - break; - case TokenCharacterConstant: - LexValue.Typ = &CharType; - break; - case TokenFPConstant: - LexValue.Typ = &FPType; - break; - default: - break; - } - memcpy((void *)LexValue.Val, (void *)((char *)_parser->Pos + TOKEN_DATA_OFFSET), ValueSize); - LexValue.ValOnHeap = FALSE; - LexValue.ValOnStack = FALSE; - LexValue.IsLValue = FALSE; - LexValue.LValueFrom = NULL; - *_value = &LexValue; - } - if (_incPos) { - _parser->Pos += ValueSize + TOKEN_DATA_OFFSET; - } - } else { - if (_incPos && Token != TokenEOF) { - _parser->Pos += TOKEN_DATA_OFFSET; - } - } -#ifdef DEBUG_LEXER - printf("Got token=%02x inc=%d pos=%d\n", Token, _incPos, _parser->CharacterPos); -#endif - assert(Token >= TokenNone && Token <= TokenEndOfFunction); - return Token; -} - -/* correct the token position depending if we already incremented the position */ -void LexHashIncPos(struct ParseState *_parser, int _incPos) { - if (!_incPos) { - LexGetRawToken(_parser, NULL, TRUE); - } -} - -/* handle a #ifdef directive */ -void LexHashIfdef(struct ParseState *_parser, int _ifNot) { - /* get symbol to check */ - struct Value *IdentValue; - struct Value *SavedValue; - int IsDefined; - enum LexToken Token = LexGetRawToken(_parser, &IdentValue, TRUE); - if (Token != TokenIdentifier) { - ProgramFail(_parser, "identifier expected"); - } - /* is the identifier defined? */ - IsDefined = TableGet(&GlobalTable, IdentValue->Val->Identifier, &SavedValue, NULL, NULL, NULL); - if ( _parser->HashIfEvaluateToLevel == _parser->HashIfLevel - && ( ( IsDefined - && !_ifNot) - || ( !IsDefined - && _ifNot) ) ) { - /* #if is active, evaluate to this new level */ - _parser->HashIfEvaluateToLevel++; - } - _parser->HashIfLevel++; -} - -/* handle a #if directive */ -void LexHashIf(struct ParseState *_parser) { - /* get symbol to check */ - struct Value *IdentValue; - struct Value *SavedValue; - struct ParseState MacroParser; - enum LexToken Token = LexGetRawToken(_parser, &IdentValue, TRUE); - if (Token == TokenIdentifier) { - /* look up a value from a macro definition */ - if (!TableGet(&GlobalTable, IdentValue->Val->Identifier, &SavedValue, NULL, NULL, NULL)) { - ProgramFail(_parser, "'%s' is undefined", IdentValue->Val->Identifier); - } - if (SavedValue->Typ->Base != TypeMacro) { - ProgramFail(_parser, "value expected"); - } - ParserCopy(&MacroParser, &SavedValue->Val->MacroDef.Body); - Token = LexGetRawToken(&MacroParser, &IdentValue, TRUE); - } - if (Token != TokenCharacterConstant) { - ProgramFail(_parser, "value expected"); - } - /* is the identifier defined? */ - if (_parser->HashIfEvaluateToLevel == _parser->HashIfLevel && IdentValue->Val->Character) { - /* #if is active, evaluate to this new level */ - _parser->HashIfEvaluateToLevel++; - } - _parser->HashIfLevel++; -} - -/* handle a #else directive */ -void LexHashElse(struct ParseState *_parser) { - if (_parser->HashIfEvaluateToLevel == _parser->HashIfLevel - 1) { - _parser->HashIfEvaluateToLevel++; /* #if was not active, make this next section active */ - } else if (_parser->HashIfEvaluateToLevel == _parser->HashIfLevel) { - /* #if was active, now go inactive */ - if (_parser->HashIfLevel == 0) { - ProgramFail(_parser, "#else without #if"); - } - _parser->HashIfEvaluateToLevel--; - } -} - -/* handle a #endif directive */ -void LexHashEndif(struct ParseState *_parser) { - if (_parser->HashIfLevel == 0) { - ProgramFail(_parser, "#endif without #if"); - } - _parser->HashIfLevel--; - if (_parser->HashIfEvaluateToLevel > _parser->HashIfLevel) { - _parser->HashIfEvaluateToLevel = _parser->HashIfLevel; - } -} - -/* get the next token given a parser state, pre-processing as we go */ -enum LexToken LexGetToken(struct ParseState *_parser, struct Value **_value, int _incPos) { - enum LexToken Token; - int TryNextToken; - /* implements the pre-processor #if commands */ - do { - int WasPreProcToken = TRUE; - Token = LexGetRawToken(_parser, _value, _incPos); - switch (Token) { - case TokenHashIfdef: - LexHashIncPos(_parser, _incPos); - LexHashIfdef(_parser, FALSE); - break; - case TokenHashIfndef: - LexHashIncPos(_parser, _incPos); - LexHashIfdef(_parser, TRUE); - break; - case TokenHashIf: - LexHashIncPos(_parser, _incPos); - LexHashIf(_parser); - break; - case TokenHashElse: - LexHashIncPos(_parser, _incPos); - LexHashElse(_parser); - break; - case TokenHashEndif: - LexHashIncPos(_parser, _incPos); - LexHashEndif(_parser); - break; - default: - WasPreProcToken = FALSE; - break; - } - /* if we're going to reject this token, increment the token pointer to the next one */ - TryNextToken = (_parser->HashIfEvaluateToLevel < _parser->HashIfLevel && Token != TokenEOF) || WasPreProcToken; - if (!_incPos && TryNextToken) { - LexGetRawToken(_parser, NULL, TRUE); - } - } while (TryNextToken); - return Token; -} - -/* take a quick peek at the next token, skipping any pre-processing */ -enum LexToken LexRawPeekToken(struct ParseState *_parser) { - return (enum LexToken)*(unsigned char *)_parser->Pos; -} - -/* find the end of the line */ -void LexToEndOfLine(struct ParseState *_parser) { - while (TRUE) { - enum LexToken Token = (enum LexToken)*(unsigned char *)_parser->Pos; - if ( Token == TokenEndOfLine - || Token == TokenEOF) { - return; - } else { - LexGetRawToken(_parser, NULL, TRUE); - } - } -} - -/* copy the tokens from StartParser to EndParser into new memory, removing TokenEOFs and terminate with a TokenEndOfFunction */ -void *LexCopyTokens(struct ParseState* _startParser, struct ParseState* _endParser) { - int MemSize = 0; - int CopySize; - unsigned char *Pos = (unsigned char *)_startParser->Pos; - unsigned char *NewTokens; - unsigned char *NewTokenPos; - struct TokenLine *ILine; - if (InteractiveHead == NULL) { - /* non-interactive mode - copy the tokens */ - MemSize = _endParser->Pos - _startParser->Pos; - NewTokens = VariableAlloc(_startParser, MemSize + TOKEN_DATA_OFFSET, TRUE); - memcpy(NewTokens, (void *)_startParser->Pos, MemSize); - } else { - /* we're in interactive mode - add up line by line */ - for (InteractiveCurrentLine = InteractiveHead; InteractiveCurrentLine != NULL && (Pos < &InteractiveCurrentLine->Tokens[0] || Pos >= &InteractiveCurrentLine->Tokens[InteractiveCurrentLine->NumBytes]); InteractiveCurrentLine = InteractiveCurrentLine->Next) - {} /* find the line we just counted */ - - if (_endParser->Pos >= _startParser->Pos && _endParser->Pos < &InteractiveCurrentLine->Tokens[InteractiveCurrentLine->NumBytes]) { - /* all on a single line */ - MemSize = _endParser->Pos - _startParser->Pos; - NewTokens = VariableAlloc(_startParser, MemSize + TOKEN_DATA_OFFSET, TRUE); - memcpy(NewTokens, (void *)_startParser->Pos, MemSize); - } else { - /* it's spread across multiple lines */ - MemSize = &InteractiveCurrentLine->Tokens[InteractiveCurrentLine->NumBytes-TOKEN_DATA_OFFSET] - Pos; - for (ILine = InteractiveCurrentLine->Next; ILine != NULL && (_endParser->Pos < &ILine->Tokens[0] || _endParser->Pos >= &ILine->Tokens[ILine->NumBytes]); ILine = ILine->Next) { - MemSize += ILine->NumBytes - TOKEN_DATA_OFFSET; - } - assert(ILine != NULL); - MemSize += _endParser->Pos - &ILine->Tokens[0]; - NewTokens = VariableAlloc(_startParser, MemSize + TOKEN_DATA_OFFSET, TRUE); - CopySize = &InteractiveCurrentLine->Tokens[InteractiveCurrentLine->NumBytes-TOKEN_DATA_OFFSET] - Pos; - memcpy(NewTokens, Pos, CopySize); - NewTokenPos = NewTokens + CopySize; - for (ILine = InteractiveCurrentLine->Next; ILine != NULL && (_endParser->Pos < &ILine->Tokens[0] || _endParser->Pos >= &ILine->Tokens[ILine->NumBytes]); ILine = ILine->Next) { - memcpy(NewTokenPos, &ILine->Tokens[0], ILine->NumBytes - TOKEN_DATA_OFFSET); - NewTokenPos += ILine->NumBytes-TOKEN_DATA_OFFSET; - } - assert(ILine != NULL); - memcpy(NewTokenPos, &ILine->Tokens[0], _endParser->Pos - &ILine->Tokens[0]); - } - } - NewTokens[MemSize] = (unsigned char)TokenEndOfFunction; - return NewTokens; -} - -/* indicate that we've completed up to this point in the interactive input and free expired tokens */ -void LexInteractiveClear(struct ParseState *_parser) { - while (InteractiveHead != NULL) { - struct TokenLine *NextLine = InteractiveHead->Next; - HeapFreeMem(InteractiveHead->Tokens); - HeapFreeMem(InteractiveHead); - InteractiveHead = NextLine; - } - if (_parser != NULL) { - _parser->Pos = NULL; - } - InteractiveTail = NULL; -} - -/* indicate that we've completed up to this point in the interactive input and free expired tokens */ -void LexInteractiveCompleted(struct ParseState *_parser) { - while (InteractiveHead != NULL && !(_parser->Pos >= &InteractiveHead->Tokens[0] && _parser->Pos < &InteractiveHead->Tokens[InteractiveHead->NumBytes])) { - /* this token line is no longer needed - free it */ - struct TokenLine *NextLine = InteractiveHead->Next; - HeapFreeMem(InteractiveHead->Tokens); - HeapFreeMem(InteractiveHead); - InteractiveHead = NextLine; - if (InteractiveHead == NULL) { - // we've emptied the list - _parser->Pos = NULL; - InteractiveTail = NULL; - } - } -} - -/* the next time we prompt, make it the full statement prompt */ -void LexInteractiveStatementPrompt() { - LexUseStatementPrompt = TRUE; -} diff --git a/eci/lex.h b/eci/lex.h deleted file mode 100644 index f6d2caa..0000000 --- a/eci/lex.h +++ /dev/null @@ -1,25 +0,0 @@ -/** - * @author Edouard DUPIN - * - * @copyright 2014, Edouard DUPIN, all right reserved - * - * @license APACHE-2 (see license file) - */ - -#ifndef __ECI_LEX_H__ -#define __ECI_LEX_H__ - - -void LexInit(); -void LexCleanup(); -void* LexAnalyse(const char* _fileName, const char *_source, int _sourceLen, int *_tokenLen); -void LexInitParser(struct ParseState* _parser, const char *_sourceText, void* _tokenSource, const char* _fileName, int _runIt); -enum LexToken LexGetToken(struct ParseState* _parser, struct Value **_value, int _incPos); -enum LexToken LexRawPeekToken(struct ParseState* _parser); -void LexToEndOfLine(struct ParseState* _parser); -void* LexCopyTokens(struct ParseState* _startParser, struct ParseState* _endParser); -void LexInteractiveClear(struct ParseState* _parser); -void LexInteractiveCompleted(struct ParseState* _parser); -void LexInteractiveStatementPrompt(); - -#endif diff --git a/eci/parse.c b/eci/parse.c deleted file mode 100644 index 70bd3f9..0000000 --- a/eci/parse.c +++ /dev/null @@ -1,766 +0,0 @@ -/** - * @author Edouard DUPIN - * - * @copyright 2014, Edouard DUPIN, all right reserved - * - * @license APACHE-2 (see license file) - */ - -#include "picoc.h" -#include "interpreter.h" - -/* a chunk of heap-allocated tokens we'll cleanup when we're done */ -struct CleanupTokenNode { - void *Tokens; - const char *SourceText; - struct CleanupTokenNode *Next; -}; - -static struct CleanupTokenNode *CleanupTokenList = NULL; - -/* deallocate any memory */ -void ParseCleanup() { - while (CleanupTokenList != NULL) { - struct CleanupTokenNode *Next = CleanupTokenList->Next; - HeapFreeMem(CleanupTokenList->Tokens); - if (CleanupTokenList->SourceText != NULL) { - HeapFreeMem((void *)CleanupTokenList->SourceText); - } - HeapFreeMem(CleanupTokenList); - CleanupTokenList = Next; - } -} - -/* parse a statement, but only run it if Condition is TRUE */ -enum ParseResult ParseStatementMaybeRun(struct ParseState *Parser, int Condition, int CheckTrailingSemicolon) { - if (Parser->Mode != RunModeSkip && !Condition) { - enum RunMode OldMode = Parser->Mode; - int Result; - Parser->Mode = RunModeSkip; - Result = ParseStatement(Parser, CheckTrailingSemicolon); - Parser->Mode = OldMode; - return Result; - } else { - return ParseStatement(Parser, CheckTrailingSemicolon); - } -} - -/* count the number of parameters to a function or macro */ -int ParseCountParams(struct ParseState *Parser) { - int ParamCount = 0; - enum LexToken Token = LexGetToken(Parser, NULL, TRUE); - if ( Token != TokenCloseBracket - && Token != TokenEOF) { - /* count the number of parameters */ - ParamCount++; - while ((Token = LexGetToken(Parser, NULL, TRUE)) != TokenCloseBracket && Token != TokenEOF) { - if (Token == TokenComma) { - ParamCount++; - } - } - } - return ParamCount; -} - -/* parse a function definition and store it for later */ -struct Value *ParseFunctionDefinition(struct ParseState *Parser, struct ValueType *ReturnType, char *Identifier) { - struct ValueType *ParamType; - char *ParamIdentifier; - enum LexToken Token = TokenNone; - struct ParseState ParamParser; - struct Value *FuncValue; - struct Value *OldFuncValue; - struct ParseState FuncBody; - int ParamCount = 0; - - if (TopStackFrame != NULL) { - ProgramFail(Parser, "nested function definitions are not allowed"); - } - LexGetToken(Parser, NULL, TRUE); /* open bracket */ - ParserCopy(&ParamParser, Parser); - ParamCount = ParseCountParams(Parser); - if (ParamCount > PARAMETER_MAX) { - ProgramFail(Parser, "too many parameters"); - } - FuncValue = VariableAllocValueAndData(Parser, sizeof(struct FuncDef) + sizeof(struct ValueType *) * ParamCount + sizeof(const char *) * ParamCount, FALSE, NULL, TRUE); - FuncValue->Typ = &FunctionType; - FuncValue->Val->FuncDef.ReturnType = ReturnType; - FuncValue->Val->FuncDef.NumParams = ParamCount; - FuncValue->Val->FuncDef.VarArgs = FALSE; - FuncValue->Val->FuncDef.ParamType = (struct ValueType **)((char *)FuncValue->Val + sizeof(struct FuncDef)); - FuncValue->Val->FuncDef.ParamName = (char **)((char *)FuncValue->Val->FuncDef.ParamType + sizeof(struct ValueType *) * ParamCount); - for (ParamCount = 0; ParamCount < FuncValue->Val->FuncDef.NumParams; ++ParamCount) { - /* harvest the parameters into the function definition */ - if (ParamCount == FuncValue->Val->FuncDef.NumParams-1 && LexGetToken(&ParamParser, NULL, FALSE) == TokenEllipsis) { - /* ellipsis at end */ - FuncValue->Val->FuncDef.NumParams--; - FuncValue->Val->FuncDef.VarArgs = TRUE; - break; - } else { - /* add a parameter */ - TypeParse(&ParamParser, &ParamType, &ParamIdentifier, NULL); - if (ParamType->Base == TypeVoid) { - /* this isn't a real parameter at all - delete it */ - ParamCount--; - FuncValue->Val->FuncDef.NumParams--; - } else { - FuncValue->Val->FuncDef.ParamType[ParamCount] = ParamType; - FuncValue->Val->FuncDef.ParamName[ParamCount] = ParamIdentifier; - } - } - Token = LexGetToken(&ParamParser, NULL, TRUE); - if ( Token != TokenComma - && ParamCount < FuncValue->Val->FuncDef.NumParams-1) { - ProgramFail(&ParamParser, "comma expected"); - } - } - if ( FuncValue->Val->FuncDef.NumParams != 0 - && Token != TokenCloseBracket - && Token != TokenComma - && Token != TokenEllipsis) { - ProgramFail(&ParamParser, "bad parameter"); - } - - if (strcmp(Identifier, "main") == 0) { - /* make sure it's int main() */ - if ( FuncValue->Val->FuncDef.ReturnType != &IntType - && FuncValue->Val->FuncDef.ReturnType != &VoidType ) { - ProgramFail(Parser, "main() should return an int or void"); - } - if ( FuncValue->Val->FuncDef.NumParams != 0 - && ( FuncValue->Val->FuncDef.NumParams != 2 - || FuncValue->Val->FuncDef.ParamType[0] != &IntType) ) { - ProgramFail(Parser, "bad parameters to main()"); - } - } - /* look for a function body */ - Token = LexGetToken(Parser, NULL, FALSE); - if (Token == TokenSemicolon) { - LexGetToken(Parser, NULL, TRUE); /* it's a prototype, absorb the trailing semicolon */ - } else { - /* it's a full function definition with a body */ - if (Token != TokenLeftBrace) { - ProgramFail(Parser, "bad function definition"); - } - ParserCopy(&FuncBody, Parser); - if (ParseStatementMaybeRun(Parser, FALSE, TRUE) != ParseResultOk) { - ProgramFail(Parser, "function definition expected"); - } - FuncValue->Val->FuncDef.Body = FuncBody; - FuncValue->Val->FuncDef.Body.Pos = LexCopyTokens(&FuncBody, Parser); - /* is this function already in the global table? */ - if (TableGet(&GlobalTable, Identifier, &OldFuncValue, NULL, NULL, NULL)) { - if (OldFuncValue->Val->FuncDef.Body.Pos == NULL) { - /* override an old function prototype */ - VariableFree(TableDelete(&GlobalTable, Identifier)); - } else { - ProgramFail(Parser, "'%s' is already defined", Identifier); - } - } - } - if (!TableSet(&GlobalTable, Identifier, FuncValue, (char *)Parser->FileName, Parser->Line, Parser->CharacterPos)) { - ProgramFail(Parser, "'%s' is already defined", Identifier); - } - return FuncValue; -} - -/* assign an initial value to a variable */ -void ParseDeclarationAssignment(struct ParseState *Parser, struct Value *NewVariable, int DoAssignment) { - struct Value *CValue; - int ArrayIndex; - enum LexToken Token = TokenComma; - if (LexGetToken(Parser, NULL, FALSE) == TokenLeftBrace) { - /* this is an array initialiser */ - LexGetToken(Parser, NULL, TRUE); - for (ArrayIndex = 0; (Parser->Mode != RunModeRun && Token == TokenComma) || (Parser->Mode == RunModeRun && ArrayIndex < NewVariable->Typ->ArraySize); ArrayIndex++) { - struct Value *ArrayElement = NULL; - if (Token != TokenComma) { - ProgramFail(Parser, "comma expected"); - } - if (Parser->Mode == RunModeRun) { - ArrayElement = VariableAllocValueFromExistingData(Parser, NewVariable->Typ->FromType, (union AnyValue *)(&NewVariable->Val->ArrayMem[0] + TypeSize(NewVariable->Typ->FromType, 0, TRUE) * ArrayIndex), TRUE, NewVariable); - } - if (!ExpressionParse(Parser, &CValue)) { - ProgramFail(Parser, "expression expected"); - } - if (Parser->Mode == RunModeRun && DoAssignment) { - ExpressionAssign(Parser, ArrayElement, CValue, FALSE, NULL, 0, FALSE); - VariableStackPop(Parser, CValue); - VariableStackPop(Parser, ArrayElement); - } - Token = LexGetToken(Parser, NULL, TRUE); - } - if (Token == TokenComma) { - Token = LexGetToken(Parser, NULL, TRUE); - } - if (Token != TokenRightBrace) { - ProgramFail(Parser, "'}' expected"); - } - } else { - /* this is a normal expression initialiser */ - if (!ExpressionParse(Parser, &CValue)) { - ProgramFail(Parser, "expression expected"); - } - if ( Parser->Mode == RunModeRun - && DoAssignment) { - ExpressionAssign(Parser, NewVariable, CValue, FALSE, NULL, 0, FALSE); - VariableStackPop(Parser, CValue); - } - } -} - -/* declare a variable or function */ -int ParseDeclaration(struct ParseState *Parser, enum LexToken Token) { - char *Identifier; - struct ValueType *BasicType; - struct ValueType *Typ; - struct Value *NewVariable = NULL; - int IsStatic = FALSE; - int FirstVisit = FALSE; - TypeParseFront(Parser, &BasicType, &IsStatic); - do { - TypeParseIdentPart(Parser, BasicType, &Typ, &Identifier); - if ( ( Token != TokenVoidType - && Token != TokenStructType - && Token != TokenUnionType - && Token != TokenEnumType) - && Identifier == StrEmpty) { - ProgramFail(Parser, "identifier expected"); - } - if (Identifier != StrEmpty) { - /* handle function definitions */ - if (LexGetToken(Parser, NULL, FALSE) == TokenOpenBracket) { - ParseFunctionDefinition(Parser, Typ, Identifier); - return FALSE; - } else { - if ( Typ == &VoidType - && Identifier != StrEmpty) { - ProgramFail(Parser, "can't define a void variable"); - } - if ( Parser->Mode == RunModeRun - || Parser->Mode == RunModeGoto) { - NewVariable = VariableDefineButIgnoreIdentical(Parser, Identifier, Typ, IsStatic, &FirstVisit); - } - if (LexGetToken(Parser, NULL, FALSE) == TokenAssign) { - /* we're assigning an initial value */ - LexGetToken(Parser, NULL, TRUE); - ParseDeclarationAssignment(Parser, NewVariable, !IsStatic || FirstVisit); - } - } - } - Token = LexGetToken(Parser, NULL, FALSE); - if (Token == TokenComma) { - LexGetToken(Parser, NULL, TRUE); - } - } while (Token == TokenComma); - return TRUE; -} - -/* parse a #define macro definition and store it for later */ -void ParseMacroDefinition(struct ParseState *Parser) { - struct Value *MacroName; - char *MacroNameStr; - struct Value *ParamName; - struct Value *MacroValue; - if (LexGetToken(Parser, &MacroName, TRUE) != TokenIdentifier) { - ProgramFail(Parser, "identifier expected"); - } - MacroNameStr = MacroName->Val->Identifier; - if (LexRawPeekToken(Parser) == TokenOpenMacroBracket) { - /* it's a parameterised macro, read the parameters */ - enum LexToken Token = LexGetToken(Parser, NULL, TRUE); - struct ParseState ParamParser; - int NumParams; - int ParamCount = 0; - ParserCopy(&ParamParser, Parser); - NumParams = ParseCountParams(&ParamParser); - MacroValue = VariableAllocValueAndData(Parser, sizeof(struct MacroDef) + sizeof(const char *) * NumParams, FALSE, NULL, TRUE); - MacroValue->Val->MacroDef.NumParams = NumParams; - MacroValue->Val->MacroDef.ParamName = (char **)((char *)MacroValue->Val + sizeof(struct MacroDef)); - Token = LexGetToken(Parser, &ParamName, TRUE); - while (Token == TokenIdentifier) { - /* store a parameter name */ - MacroValue->Val->MacroDef.ParamName[ParamCount++] = ParamName->Val->Identifier; - /* get the trailing comma */ - Token = LexGetToken(Parser, NULL, TRUE); - if (Token == TokenComma) { - Token = LexGetToken(Parser, &ParamName, TRUE); - } else if (Token != TokenCloseBracket) { - ProgramFail(Parser, "comma expected"); - } - } - if (Token != TokenCloseBracket) { - ProgramFail(Parser, "close bracket expected"); - } - } else { - /* allocate a simple unparameterised macro */ - MacroValue = VariableAllocValueAndData(Parser, sizeof(struct MacroDef), FALSE, NULL, TRUE); - MacroValue->Val->MacroDef.NumParams = 0; - } - - /* copy the body of the macro to execute later */ - ParserCopy(&MacroValue->Val->MacroDef.Body, Parser); - MacroValue->Typ = &MacroType; - LexToEndOfLine(Parser); - MacroValue->Val->MacroDef.Body.Pos = LexCopyTokens(&MacroValue->Val->MacroDef.Body, Parser); - if (!TableSet(&GlobalTable, MacroNameStr, MacroValue, (char *)Parser->FileName, Parser->Line, Parser->CharacterPos)) { - ProgramFail(Parser, "'%s' is already defined", MacroNameStr); - } -} - -/* copy the entire parser state */ -void ParserCopy(struct ParseState *To, struct ParseState *From) { - memcpy((void *)To, (void *)From, sizeof(*To)); -} - -/* copy where we're at in the parsing */ -void ParserCopyPos(struct ParseState *To, struct ParseState *From) { - To->Pos = From->Pos; - To->Line = From->Line; - To->HashIfLevel = From->HashIfLevel; - To->HashIfEvaluateToLevel = From->HashIfEvaluateToLevel; - To->CharacterPos = From->CharacterPos; -} - -/* parse a "for" statement */ -void ParseFor(struct ParseState *Parser) { - int Condition; - struct ParseState PreConditional; - struct ParseState PreIncrement; - struct ParseState PreStatement; - struct ParseState After; - if (LexGetToken(Parser, NULL, TRUE) != TokenOpenBracket) { - ProgramFail(Parser, "'(' expected"); - } - if (ParseStatement(Parser, TRUE) != ParseResultOk) { - ProgramFail(Parser, "statement expected"); - } - ParserCopyPos(&PreConditional, Parser); - if (LexGetToken(Parser, NULL, FALSE) == TokenSemicolon) { - Condition = TRUE; - } else { - Condition = ExpressionParseInt(Parser); - } - if (LexGetToken(Parser, NULL, TRUE) != TokenSemicolon) { - ProgramFail(Parser, "';' expected"); - } - ParserCopyPos(&PreIncrement, Parser); - ParseStatementMaybeRun(Parser, FALSE, FALSE); - if (LexGetToken(Parser, NULL, TRUE) != TokenCloseBracket) { - ProgramFail(Parser, "')' expected"); - } - ParserCopyPos(&PreStatement, Parser); - if (ParseStatementMaybeRun(Parser, Condition, TRUE) != ParseResultOk) { - ProgramFail(Parser, "statement expected"); - } - if (Parser->Mode == RunModeContinue) { - Parser->Mode = RunModeRun; - } - ParserCopyPos(&After, Parser); - while (Condition && Parser->Mode == RunModeRun) { - ParserCopyPos(Parser, &PreIncrement); - ParseStatement(Parser, FALSE); - - ParserCopyPos(Parser, &PreConditional); - if (LexGetToken(Parser, NULL, FALSE) == TokenSemicolon) { - Condition = TRUE; - } else { - Condition = ExpressionParseInt(Parser); - } - if (Condition) { - ParserCopyPos(Parser, &PreStatement); - ParseStatement(Parser, TRUE); - if (Parser->Mode == RunModeContinue) { - Parser->Mode = RunModeRun; - } - } - } - if (Parser->Mode == RunModeBreak) { - Parser->Mode = RunModeRun; - } - ParserCopyPos(Parser, &After); -} - -/* parse a block of code and return what mode it returned in */ -enum RunMode ParseBlock(struct ParseState *Parser, int AbsorbOpenBrace, int Condition) { - if (AbsorbOpenBrace && LexGetToken(Parser, NULL, TRUE) != TokenLeftBrace) { - ProgramFail(Parser, "'{' expected"); - } - if (Parser->Mode == RunModeSkip || !Condition) { - /* condition failed - skip this block instead */ - enum RunMode OldMode = Parser->Mode; - Parser->Mode = RunModeSkip; - while (ParseStatement(Parser, TRUE) == ParseResultOk) { - - } - Parser->Mode = OldMode; - } else { - /* just run it in its current mode */ - while (ParseStatement(Parser, TRUE) == ParseResultOk) { - - } - } - if (LexGetToken(Parser, NULL, TRUE) != TokenRightBrace) { - ProgramFail(Parser, "'}' expected"); - } - return Parser->Mode; -} - -/* parse a typedef declaration */ -void ParseTypedef(struct ParseState *Parser) { - struct ValueType *Typ; - struct ValueType **TypPtr; - char *TypeName; - struct Value InitValue; - TypeParse(Parser, &Typ, &TypeName, NULL); - if (Parser->Mode == RunModeRun) { - TypPtr = &Typ; - InitValue.Typ = &TypeType; - InitValue.Val = (union AnyValue *)TypPtr; - VariableDefine(Parser, TypeName, &InitValue, NULL, FALSE); - } -} - -/* parse a statement */ -enum ParseResult ParseStatement(struct ParseState *Parser, int CheckTrailingSemicolon) { - struct Value *CValue; - struct Value *LexerValue; - struct Value *VarValue; - int Condition; - struct ParseState PreState; - enum LexToken Token; - ParserCopy(&PreState, Parser); - Token = LexGetToken(Parser, &LexerValue, TRUE); - switch (Token) { - case TokenEOF: - return ParseResultEOF; - case TokenIdentifier: - /* might be a typedef-typed variable declaration or it might be an expression */ - if (VariableDefined(LexerValue->Val->Identifier)) { - VariableGet(Parser, LexerValue->Val->Identifier, &VarValue); - if (VarValue->Typ->Base == Type_Type) { - *Parser = PreState; - ParseDeclaration(Parser, Token); - break; - } - } else { - /* it might be a goto label */ - enum LexToken NextToken = LexGetToken(Parser, NULL, FALSE); - if (NextToken == TokenColon) { - /* declare the identifier as a goto label */ - LexGetToken(Parser, NULL, TRUE); - if ( Parser->Mode == RunModeGoto - && LexerValue->Val->Identifier == Parser->SearchGotoLabel) { - Parser->Mode = RunModeRun; - } - CheckTrailingSemicolon = FALSE; - break; - } - } - /* else fallthrough to expression */ - - case TokenAsterisk: - case TokenAmpersand: - case TokenIncrement: - case TokenDecrement: - case TokenOpenBracket: - *Parser = PreState; - ExpressionParse(Parser, &CValue); - if (Parser->Mode == RunModeRun) { - VariableStackPop(Parser, CValue); - } - break; - - case TokenLeftBrace: - ParseBlock(Parser, FALSE, TRUE); - CheckTrailingSemicolon = FALSE; - break; - - case TokenIf: - if (LexGetToken(Parser, NULL, TRUE) != TokenOpenBracket) { - ProgramFail(Parser, "'(' expected"); - } - Condition = ExpressionParseInt(Parser); - if (LexGetToken(Parser, NULL, TRUE) != TokenCloseBracket) { - ProgramFail(Parser, "')' expected"); - } - if (ParseStatementMaybeRun(Parser, Condition, TRUE) != ParseResultOk) { - ProgramFail(Parser, "statement expected"); - } - if (LexGetToken(Parser, NULL, FALSE) == TokenElse) { - LexGetToken(Parser, NULL, TRUE); - if (ParseStatementMaybeRun(Parser, !Condition, TRUE) != ParseResultOk) { - ProgramFail(Parser, "statement expected"); - } - } - CheckTrailingSemicolon = FALSE; - break; - case TokenWhile: - { - struct ParseState PreConditional; - enum RunMode PreMode = Parser->Mode; - if (LexGetToken(Parser, NULL, TRUE) != TokenOpenBracket) { - ProgramFail(Parser, "'(' expected"); - } - ParserCopyPos(&PreConditional, Parser); - do { - ParserCopyPos(Parser, &PreConditional); - Condition = ExpressionParseInt(Parser); - if (LexGetToken(Parser, NULL, TRUE) != TokenCloseBracket) { - ProgramFail(Parser, "')' expected"); - } - if (ParseStatementMaybeRun(Parser, Condition, TRUE) != ParseResultOk) { - ProgramFail(Parser, "statement expected"); - } - if (Parser->Mode == RunModeContinue) { - Parser->Mode = PreMode; - } - } while (Parser->Mode == RunModeRun && Condition); - - if (Parser->Mode == RunModeBreak) { - Parser->Mode = PreMode; - } - CheckTrailingSemicolon = FALSE; - } - break; - case TokenDo: - { - struct ParseState PreStatement; - enum RunMode PreMode = Parser->Mode; - ParserCopyPos(&PreStatement, Parser); - do { - ParserCopyPos(Parser, &PreStatement); - if (ParseStatement(Parser, TRUE) != ParseResultOk) { - ProgramFail(Parser, "statement expected"); - } - if (Parser->Mode == RunModeContinue) { - Parser->Mode = PreMode; - } - if (LexGetToken(Parser, NULL, TRUE) != TokenWhile) { - ProgramFail(Parser, "'while' expected"); - } - if (LexGetToken(Parser, NULL, TRUE) != TokenOpenBracket) { - ProgramFail(Parser, "'(' expected"); - } - Condition = ExpressionParseInt(Parser); - if (LexGetToken(Parser, NULL, TRUE) != TokenCloseBracket) { - ProgramFail(Parser, "')' expected"); - } - } while ( Condition - && Parser->Mode == RunModeRun); - if (Parser->Mode == RunModeBreak) { - Parser->Mode = PreMode; - } - } - break; - case TokenFor: - ParseFor(Parser); - CheckTrailingSemicolon = FALSE; - break; - case TokenSemicolon: - CheckTrailingSemicolon = FALSE; - break; - case TokenIntType: - case TokenShortType: - case TokenCharType: - case TokenLongType: - case TokenFloatType: - case TokenDoubleType: - case TokenVoidType: - case TokenStructType: - case TokenUnionType: - case TokenEnumType: - case TokenSignedType: - case TokenUnsignedType: - case TokenStaticType: - case TokenAutoType: - case TokenRegisterType: - case TokenExternType: - *Parser = PreState; - CheckTrailingSemicolon = ParseDeclaration(Parser, Token); - break; - case TokenHashDefine: - ParseMacroDefinition(Parser); - CheckTrailingSemicolon = FALSE; - break; -#ifndef NO_HASH_INCLUDE - case TokenHashInclude: - if (LexGetToken(Parser, &LexerValue, TRUE) != TokenStringConstant) { - ProgramFail(Parser, "\"filename.h\" expected"); - } - IncludeFile((char *)LexerValue->Val->Pointer); - CheckTrailingSemicolon = FALSE; - break; -#endif - case TokenSwitch: - if (LexGetToken(Parser, NULL, TRUE) != TokenOpenBracket) { - ProgramFail(Parser, "'(' expected"); - } - Condition = ExpressionParseInt(Parser); - if (LexGetToken(Parser, NULL, TRUE) != TokenCloseBracket) { - ProgramFail(Parser, "')' expected"); - } - if (LexGetToken(Parser, NULL, FALSE) != TokenLeftBrace) { - ProgramFail(Parser, "'{' expected"); - } - { - /* new block so we can store parser state */ - enum RunMode OldMode = Parser->Mode; - int OldSearchLabel = Parser->SearchLabel; - Parser->Mode = RunModeCaseSearch; - Parser->SearchLabel = Condition; - ParseBlock(Parser, TRUE, OldMode != RunModeSkip); - if (Parser->Mode != RunModeReturn) { - Parser->Mode = OldMode; - } - Parser->SearchLabel = OldSearchLabel; - } - CheckTrailingSemicolon = FALSE; - break; - case TokenCase: - if (Parser->Mode == RunModeCaseSearch) { - Parser->Mode = RunModeRun; - Condition = ExpressionParseInt(Parser); - Parser->Mode = RunModeCaseSearch; - } else { - Condition = ExpressionParseInt(Parser); - } - if (LexGetToken(Parser, NULL, TRUE) != TokenColon) { - ProgramFail(Parser, "':' expected"); - } - if (Parser->Mode == RunModeCaseSearch && Condition == Parser->SearchLabel) { - Parser->Mode = RunModeRun; - } - CheckTrailingSemicolon = FALSE; - break; - case TokenDefault: - if (LexGetToken(Parser, NULL, TRUE) != TokenColon) { - ProgramFail(Parser, "':' expected"); - } - if (Parser->Mode == RunModeCaseSearch) { - Parser->Mode = RunModeRun; - } - CheckTrailingSemicolon = FALSE; - break; - case TokenBreak: - if (Parser->Mode == RunModeRun) { - Parser->Mode = RunModeBreak; - } - break; - case TokenContinue: - if (Parser->Mode == RunModeRun) { - Parser->Mode = RunModeContinue; - } - break; - case TokenReturn: - if (Parser->Mode == RunModeRun) { - if (TopStackFrame->ReturnValue->Typ->Base != TypeVoid) { - if (!ExpressionParse(Parser, &CValue)) { - ProgramFail(Parser, "value required in return"); - } - ExpressionAssign(Parser, TopStackFrame->ReturnValue, CValue, TRUE, NULL, 0, FALSE); - VariableStackPop(Parser, CValue); - } else { - if (ExpressionParse(Parser, &CValue)) { - ProgramFail(Parser, "value in return from a void function"); - } - } - Parser->Mode = RunModeReturn; - } else { - ExpressionParse(Parser, &CValue); - } - break; - case TokenTypedef: - ParseTypedef(Parser); - break; - case TokenGoto: - if (LexGetToken(Parser, &LexerValue, TRUE) != TokenIdentifier) { - ProgramFail(Parser, "identifier expected"); - } - if (Parser->Mode == RunModeRun) { - /* start scanning for the goto label */ - Parser->SearchGotoLabel = LexerValue->Val->Identifier; - Parser->Mode = RunModeGoto; - } - break; - case TokenDelete: - { - /* try it as a function or variable name to delete */ - if (LexGetToken(Parser, &LexerValue, TRUE) != TokenIdentifier) { - ProgramFail(Parser, "identifier expected"); - } - if (Parser->Mode == RunModeRun) { - /* delete this variable or function */ - CValue = TableDelete(&GlobalTable, LexerValue->Val->Identifier); - if (CValue == NULL) { - ProgramFail(Parser, "'%s' is not defined", LexerValue->Val->Identifier); - } - VariableFree(CValue); - } - break; - } - default: - *Parser = PreState; - return ParseResultError; - } - if (CheckTrailingSemicolon) { - if (LexGetToken(Parser, NULL, TRUE) != TokenSemicolon) { - ProgramFail(Parser, "';' expected"); - } - } - return ParseResultOk; -} - -/* quick scan a source file for definitions */ -void PicocParse(const char *FileName, const char *Source, int SourceLen, int RunIt, int CleanupNow, int CleanupSource) { - struct ParseState Parser; - enum ParseResult Ok; - struct CleanupTokenNode *NewCleanupNode; - void *Tokens = LexAnalyse(FileName, Source, SourceLen, NULL); - /* allocate a cleanup node so we can clean up the tokens later */ - if (!CleanupNow) { - NewCleanupNode = HeapAllocMem(sizeof(struct CleanupTokenNode)); - if (NewCleanupNode == NULL) { - ProgramFail(NULL, "out of memory"); - } - NewCleanupNode->Tokens = Tokens; - if (CleanupSource) { - NewCleanupNode->SourceText = Source; - } else { - NewCleanupNode->SourceText = NULL; - } - NewCleanupNode->Next = CleanupTokenList; - CleanupTokenList = NewCleanupNode; - } - /* do the parsing */ - LexInitParser(&Parser, Source, Tokens, FileName, RunIt); - do { - Ok = ParseStatement(&Parser, TRUE); - } while (Ok == ParseResultOk); - if (Ok == ParseResultError) { - ProgramFail(&Parser, "parse error"); - } - /* clean up */ - if (CleanupNow) { - HeapFreeMem(Tokens); - } -} - -/* parse interactively */ -void PicocParseInteractive() { - struct ParseState Parser; - enum ParseResult Ok; - PlatformPrintf("Starting eci " ECI_VERSION "\n"); - LexInitParser(&Parser, NULL, NULL, StrEmpty, TRUE); - PicocPlatformSetExitPoint(); - LexInteractiveClear(&Parser); - do { - LexInteractiveStatementPrompt(); - Ok = ParseStatement(&Parser, TRUE); - LexInteractiveCompleted(&Parser); - } while (Ok == ParseResultOk); - if (Ok == ParseResultError) { - ProgramFail(&Parser, "parse error"); - } - PlatformPrintf("\n"); -} diff --git a/eci/parse.h b/eci/parse.h deleted file mode 100644 index 21a7bed..0000000 --- a/eci/parse.h +++ /dev/null @@ -1,22 +0,0 @@ -/** - * @author Edouard DUPIN - * - * @copyright 2014, Edouard DUPIN, all right reserved - * - * @license APACHE-2 (see license file) - */ - -#ifndef __ECI_PARSE_H__ -#define __ECI_PARSE_H__ - - -/* the following are defined in picoc.h: - * void PicocParse(const char *FileName, const char *Source, int SourceLen, int RunIt, int CleanupNow, int CleanupSource); - * void PicocParseInteractive(); */ -enum ParseResult ParseStatement(struct ParseState *_parser, int _checkTrailingSemicolon); -struct Value *ParseFunctionDefinition(struct ParseState *_parser, struct ValueType *_returnType, char *_identifier); -void ParseCleanup(); -void ParserCopyPos(struct ParseState *_to, struct ParseState *_from); -void ParserCopy(struct ParseState *_to, struct ParseState *_from); - -#endif diff --git a/eci/picoc.c b/eci/picoc.c deleted file mode 100644 index ceeb546..0000000 --- a/eci/picoc.c +++ /dev/null @@ -1,53 +0,0 @@ -/** - * @author Edouard DUPIN - * - * @copyright 2014, Edouard DUPIN, all right reserved - * - * @license APACHE-2 (see license file) - */ - -/* include only picoc.h here - should be able to use it with only the external interfaces, no internals from interpreter.h */ -#include "picoc.h" - -/* platform-dependent code for running programs is in this file */ - -#include -#include -#include - -#define PICOC_STACK_SIZE (128*1024) /* space for the the stack */ - -int main(int argc, char **argv) { - int ParamCount = 1; - int DontRunMain = FALSE; - int StackSize = getenv("STACKSIZE") ? atoi(getenv("STACKSIZE")) : PICOC_STACK_SIZE; - if (argc < 2) { - printf("Format: picoc ... [- ...] : run a program (calls main() to start it)\n" - " picoc -s ... [- ...] : script mode - runs the program without calling main()\n" - " picoc -i : interactive mode\n"); - exit(1); - } - PicocInitialise(StackSize); - if (strcmp(argv[ParamCount], "-s") == 0 || strcmp(argv[ParamCount], "-m") == 0) { - DontRunMain = TRUE; - PicocIncludeAllSystemHeaders(); - ParamCount++; - } - if (argc > ParamCount && strcmp(argv[ParamCount], "-i") == 0) { - PicocIncludeAllSystemHeaders(); - PicocParseInteractive(); - } else { - if (PicocPlatformSetExitPoint()) { - PicocCleanup(); - return PicocExitValue; - } - for (; ParamCount < argc && strcmp(argv[ParamCount], "-") != 0; ParamCount++) { - PicocPlatformScanFile(argv[ParamCount]); - } - if (!DontRunMain) { - PicocCallMain(argc - ParamCount, &argv[ParamCount]); - } - } - PicocCleanup(); - return PicocExitValue; -} diff --git a/eci/picoc.h b/eci/picoc.h deleted file mode 100644 index 795ac74..0000000 --- a/eci/picoc.h +++ /dev/null @@ -1,45 +0,0 @@ -/** - * @author Edouard DUPIN - * - * @copyright 2014, Edouard DUPIN, all right reserved - * - * @license APACHE-2 (see license file) - */ - -#ifndef __ECI_H__ -#define __ECI_H__ - -/* eci version number */ -#define ECI_VERSION "v0.1" - -/* handy definitions */ -#ifndef TRUE -#define TRUE 1 -#define FALSE 0 -#endif - - -#include - -/* mark where to end the program for platforms which require this */ -extern jmp_buf PicocExitBuf; - -/* this has to be a macro, otherwise errors will occur due to the stack being corrupt */ -#define PicocPlatformSetExitPoint() setjmp(PicocExitBuf) - -/* parse.c */ -void PicocParse(const char *_fileName, const char *_source, int _sourceLen, int _runIt, int _cleanupNow, int _cleanupSource); -void PicocParseInteractive(); - -/* platform.c */ -void PicocCallMain(int _argc, char **_argv); -void PicocInitialise(int _stackSize); -void PicocCleanup(); -void PicocPlatformScanFile(const char *_fileName); - -extern int PicocExitValue; - -/* include.c */ -void PicocIncludeAllSystemHeaders(); - -#endif diff --git a/eci/platform.c b/eci/platform.c deleted file mode 100644 index 403a1f9..0000000 --- a/eci/platform.c +++ /dev/null @@ -1,221 +0,0 @@ -/** - * @author Edouard DUPIN - * - * @copyright 2014, Edouard DUPIN, all right reserved - * - * @license APACHE-2 (see license file) - */ - -#include "picoc.h" -#include "interpreter.h" - -/* the value passed to exit() */ -int PicocExitValue = 0; - -/* initialise everything */ -void PicocInitialise(int StackSize) { - BasicIOInit(); - HeapInit(StackSize); - TableInit(); - VariableInit(); - LexInit(); - TypeInit(); -#ifndef NO_HASH_INCLUDE - IncludeInit(); -#endif - LibraryInit(); -#ifdef BUILTIN_MINI_STDLIB - LibraryAdd(&GlobalTable, "c library", &CLibrary[0]); - CLibraryInit(); -#endif - PlatformLibraryInit(); -} - -/* free memory */ -void PicocCleanup() -{ - PlatformCleanup(); -#ifndef NO_HASH_INCLUDE - IncludeCleanup(); -#endif - ParseCleanup(); - LexCleanup(); - VariableCleanup(); - TypeCleanup(); - TableStrFree(); - HeapCleanup(); -} - -/* platform-dependent code for running programs */ - -#define CALL_MAIN_NO_ARGS_RETURN_VOID "main();" -#define CALL_MAIN_WITH_ARGS_RETURN_VOID "main(__argc,__argv);" -#define CALL_MAIN_NO_ARGS_RETURN_INT "__exit_value = main();" -#define CALL_MAIN_WITH_ARGS_RETURN_INT "__exit_value = main(__argc,__argv);" - -void PicocCallMain(int argc, char **argv) { - /* check if the program wants arguments */ - struct Value *FuncValue = NULL; - if (!VariableDefined(TableStrRegister("main"))) { - ProgramFail(NULL, "main() is not defined"); - } - VariableGet(NULL, TableStrRegister("main"), &FuncValue); - if (FuncValue->Typ->Base != TypeFunction) { - ProgramFail(NULL, "main is not a function - can't call it"); - } - if (FuncValue->Val->FuncDef.NumParams != 0) { - /* define the arguments */ - VariableDefinePlatformVar(NULL, "__argc", &IntType, (union AnyValue *)&argc, FALSE); - VariableDefinePlatformVar(NULL, "__argv", CharPtrPtrType, (union AnyValue *)&argv, FALSE); - } - if (FuncValue->Val->FuncDef.ReturnType == &VoidType) { - if (FuncValue->Val->FuncDef.NumParams == 0) { - PicocParse("startup", CALL_MAIN_NO_ARGS_RETURN_VOID, strlen(CALL_MAIN_NO_ARGS_RETURN_VOID), TRUE, TRUE, FALSE); - } else { - PicocParse("startup", CALL_MAIN_WITH_ARGS_RETURN_VOID, strlen(CALL_MAIN_WITH_ARGS_RETURN_VOID), TRUE, TRUE, FALSE); - } - } else { - VariableDefinePlatformVar(NULL, "__exit_value", &IntType, (union AnyValue *)&PicocExitValue, TRUE); - if (FuncValue->Val->FuncDef.NumParams == 0) { - PicocParse("startup", CALL_MAIN_NO_ARGS_RETURN_INT, strlen(CALL_MAIN_NO_ARGS_RETURN_INT), TRUE, TRUE, FALSE); - } else { - PicocParse("startup", CALL_MAIN_WITH_ARGS_RETURN_INT, strlen(CALL_MAIN_WITH_ARGS_RETURN_INT), TRUE, TRUE, FALSE); - } - } -} - -void PrintSourceTextErrorLine(const char *FileName, const char *SourceText, int Line, int CharacterPos) { - int LineCount; - const char *LinePos; - const char *CPos; - int CCount; - if (SourceText != NULL) { - /* find the source line */ - for (LinePos = SourceText, LineCount = 1; *LinePos != '\0' && LineCount < Line; LinePos++) { - if (*LinePos == '\n') { - LineCount++; - } - } - /* display the line */ - for (CPos = LinePos; *CPos != '\n' && *CPos != '\0'; CPos++) { - PrintCh(*CPos, CStdOut); - } - PrintCh('\n', CStdOut); - /* display the error position */ - for (CPos = LinePos, CCount = 0; *CPos != '\n' && *CPos != '\0' && (CCount < CharacterPos || *CPos == ' '); CPos++, CCount++) { - if (*CPos == '\t') { - PrintCh('\t', CStdOut); - } else { - PrintCh(' ', CStdOut); - } - } - } else { - /* assume we're in interactive mode - try to make the arrow match up with the input text */ - for (CCount = 0; CCount < CharacterPos + strlen(INTERACTIVE_PROMPT_STATEMENT); CCount++) { - PrintCh(' ', CStdOut); - } - } - PlatformPrintf("^\n%s:%d: ", FileName, Line, CharacterPos); -} - -/* display the source line and line number to identify an error */ -void PlatformErrorPrefix(struct ParseState *_parser) { - if (_parser != NULL) { - PrintSourceTextErrorLine(_parser->FileName, _parser->SourceText, _parser->Line, _parser->CharacterPos); - } -} - -/* exit with a message */ -void ProgramFail(struct ParseState *_parser, const char *Message, ...) { - va_list Args; - PlatformErrorPrefix(_parser); - va_start(Args, Message); - PlatformVPrintf(Message, Args); - va_end(Args); - PlatformPrintf("\n"); - PlatformExit(1); -} - -/* like ProgramFail() but gives descriptive error messages for assignment */ -void AssignFail(struct ParseState *_parser, const char *Format, struct ValueType *Type1, struct ValueType *Type2, int Num1, int Num2, const char *FuncName, int ParamNo) { - PlatformErrorPrefix(_parser); - PlatformPrintf("can't %s ", (FuncName == NULL) ? "assign" : "set"); - if (Type1 != NULL) { - PlatformPrintf(Format, Type1, Type2); - } else { - PlatformPrintf(Format, Num1, Num2); - } - if (FuncName != NULL) { - PlatformPrintf(" in argument %d of call to %s()", ParamNo, FuncName); - } - ProgramFail(NULL, ""); -} - -/* exit lexing with a message */ -void LexFail(struct LexState *Lexer, const char *Message, ...) { - va_list Args; - PrintSourceTextErrorLine(Lexer->FileName, Lexer->SourceText, Lexer->Line, Lexer->CharacterPos); - va_start(Args, Message); - PlatformVPrintf(Message, Args); - va_end(Args); - PlatformPrintf("\n"); - PlatformExit(1); -} - -/* printf for compiler error reporting */ -void PlatformPrintf(const char *Format, ...) { - va_list Args; - va_start(Args, Format); - PlatformVPrintf(Format, Args); - va_end(Args); -} - -void PlatformVPrintf(const char *Format, va_list Args) { - const char *FPos; - for (FPos = Format; *FPos != '\0'; FPos++) { - if (*FPos == '%') { - FPos++; - switch (*FPos) { - case 's': - PrintStr(va_arg(Args, char *), CStdOut); - break; - case 'd': - PrintSimpleInt(va_arg(Args, int), CStdOut); - break; - case 'c': - PrintCh(va_arg(Args, int), CStdOut); - break; - case 't': - PrintType(va_arg(Args, struct ValueType *), CStdOut); - break; - case 'f': - PrintFP(va_arg(Args, double), CStdOut); - break; - case '%': - PrintCh('%', CStdOut); - break; - case '\0': - FPos--; - break; - } - } else { - PrintCh(*FPos, CStdOut); - } - } -} - -/* make a new temporary name. takes a static buffer of char [7] as a parameter. should be initialised to "XX0000" - * where XX can be any characters */ -char *PlatformMakeTempName(char *TempNameBuffer) { - int CPos = 5; - while (CPos > 1) { - if (TempNameBuffer[CPos] < '9') { - TempNameBuffer[CPos]++; - return TableStrRegister(TempNameBuffer); - } else { - TempNameBuffer[CPos] = '0'; - CPos--; - } - } - return TableStrRegister(TempNameBuffer); -} diff --git a/eci/platform.h b/eci/platform.h deleted file mode 100644 index 1956d4e..0000000 --- a/eci/platform.h +++ /dev/null @@ -1,42 +0,0 @@ -/** - * @author Edouard DUPIN - * - * @copyright 2014, Edouard DUPIN, all right reserved - * - * @license APACHE-2 (see license file) - */ - -#ifndef __ECI_PLATFORM_H__ -#define __ECI_PLATFORM_H__ - -#define LARGE_INT_POWER_OF_TEN 1000000000 /* the largest power of ten which fits in an int on this architecture */ -#define ALIGN_TYPE void * /* the default data type to use for alignment */ - -#define GLOBAL_TABLE_SIZE 97 /* global variable table */ -#define STRING_TABLE_SIZE 97 /* shared string table size */ -#define STRING_LITERAL_TABLE_SIZE 97 /* string literal table size */ -#define PARAMETER_MAX 16 /* maximum number of parameters to a function */ -#define LINEBUFFER_MAX 256 /* maximum number of characters on a line */ -#define LOCAL_TABLE_SIZE 11 /* size of local variable table (can expand) */ -#define STRUCT_TABLE_SIZE 11 /* size of struct/union member table (can expand) */ - -#define INTERACTIVE_PROMPT_STATEMENT "eci> " -#define INTERACTIVE_PROMPT_LINE " > " - -/* host platform includes */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -extern jmp_buf ExitBuf; - - -#endif diff --git a/eci/platform/library_ffox.c b/eci/platform/library_ffox.c deleted file mode 100644 index 9e68e62..0000000 --- a/eci/platform/library_ffox.c +++ /dev/null @@ -1,13 +0,0 @@ -#include "../interpreter.h" - -/* list of all library functions and their prototypes */ -struct LibraryFunction PlatformLibrary[] = -{ - { NULL, NULL } -}; - -void PlatformLibraryInit() -{ - LibraryAdd(&GlobalTable, "platform library", &PlatformLibrary); -} - diff --git a/eci/platform/library_srv1.c b/eci/platform/library_srv1.c deleted file mode 100644 index a8cd443..0000000 --- a/eci/platform/library_srv1.c +++ /dev/null @@ -1,809 +0,0 @@ -#include "../interpreter.h" - -static int Blobcnt, Blobx1, Blobx2, Bloby1, Bloby2, Iy1, Iy2, Iu1, Iu2, Iv1, Iv2; -static int GPSlat, GPSlon, GPSalt, GPSfix, GPSsat, GPSutc, Elcount, Ercount; -static int ScanVect[16], NNVect[NUM_OUTPUT]; - -struct ValueType *IntArrayType; - - -void SRV1SetupFunc() -{ - IntArrayType = TypeGetMatching(NULL, &IntType, TypeArray, 16, StrEmpty, TRUE); - VariableDefinePlatformVar(NULL, "scanvect", IntArrayType, (union AnyValue *)&ScanVect, FALSE); - VariableDefinePlatformVar(NULL, "neuron", IntArrayType, (union AnyValue *)&NNVect, FALSE); - VariableDefinePlatformVar(NULL, "blobcnt", &IntType, (union AnyValue *)&Blobcnt, FALSE); - VariableDefinePlatformVar(NULL, "blobx1", &IntType, (union AnyValue *)&Blobx1, FALSE); - VariableDefinePlatformVar(NULL, "blobx2", &IntType, (union AnyValue *)&Blobx2, FALSE); - VariableDefinePlatformVar(NULL, "bloby1", &IntType, (union AnyValue *)&Bloby1, FALSE); - VariableDefinePlatformVar(NULL, "bloby2", &IntType, (union AnyValue *)&Bloby2, FALSE); - VariableDefinePlatformVar(NULL, "lcount", &IntType, (union AnyValue *)&Elcount, FALSE); - VariableDefinePlatformVar(NULL, "rcount", &IntType, (union AnyValue *)&Ercount, FALSE); - VariableDefinePlatformVar(NULL, "y1", &IntType, (union AnyValue *)&Iy1, FALSE); - VariableDefinePlatformVar(NULL, "y2", &IntType, (union AnyValue *)&Iy2, FALSE); - VariableDefinePlatformVar(NULL, "u1", &IntType, (union AnyValue *)&Iu1, FALSE); - VariableDefinePlatformVar(NULL, "u2", &IntType, (union AnyValue *)&Iu2, FALSE); - VariableDefinePlatformVar(NULL, "v1", &IntType, (union AnyValue *)&Iv1, FALSE); - VariableDefinePlatformVar(NULL, "v2", &IntType, (union AnyValue *)&Iv2, FALSE); - VariableDefinePlatformVar(NULL, "gpslat", &IntType, (union AnyValue *)&GPSlat, FALSE); - VariableDefinePlatformVar(NULL, "gpslon", &IntType, (union AnyValue *)&GPSlon, FALSE); - VariableDefinePlatformVar(NULL, "gpsalt", &IntType, (union AnyValue *)&GPSalt, FALSE); - VariableDefinePlatformVar(NULL, "gpsfix", &IntType, (union AnyValue *)&GPSfix, FALSE); - VariableDefinePlatformVar(NULL, "gpssat", &IntType, (union AnyValue *)&GPSsat, FALSE); - VariableDefinePlatformVar(NULL, "gpsutc", &IntType, (union AnyValue *)&GPSutc, FALSE); -} - -void Csignal(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) // check for kbhit, return t or nil -{ - if (getsignal()) - ReturnValue->Val->Integer = 1; - else - ReturnValue->Val->Integer = 0; -} - -void Cinput(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) // return 0-9 from console input -{ - ReturnValue->Val->Integer = getch(); -} - -void Cdelay(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) -{ - int del; - - del = Param[0]->Val->Integer; - if ((del < 0) || (del > 1000000)) - return; - delayMS(del); -} - -void Crand(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) -{ - ReturnValue->Val->Integer = (int)rand() % (unsigned int)(Param[0]->Val->Integer + 1); -} - -void Ctime(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) -{ - ReturnValue->Val->Integer = (int)readRTC(); -} - -void Ciodir(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) -{ - int dir; - - dir = Param[0]->Val->Integer; - *pPORTHIO_DIR = ((dir << 10) & 0xFC00) + (*pPORTHIO_DIR & 0x03FF); // H15/14/13/12/11/10 - 1=output, 0=input - *pPORTHIO_INEN = (((~dir) << 10) & 0xFC00) + (*pPORTHIO_INEN & 0x03FF); // invert dir bits to enable inputs -} - -void Cioread(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) -{ - ReturnValue->Val->Integer = (*pPORTHIO >> 10) & 0x003F; -} - -void Ciowrite(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) -{ - *pPORTHIO = ((Param[0]->Val->Integer << 10) & 0xFC00) + (*pPORTHIO & 0x03FF); -} - -void Cpeek(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) -{ - int size, ptr; - unsigned char *cp; - unsigned short *sp; - unsigned int *ip; - - /* x = peek(addr, size); - mask ptr to align with word size */ - ptr = Param[0]->Val->Integer; - size = Param[1]->Val->Integer; - switch (size) { - case 1: // char * - cp = (unsigned char *)ptr; - ReturnValue->Val->Integer = (int)((unsigned int)*cp); - break; - case 2: // short * - sp = (unsigned short *)(ptr & 0xFFFFFFFE); // align with even boundary - ReturnValue->Val->Integer = (int)((unsigned short)*sp); - break; - case 4: // int * - ip = (unsigned int *)(ptr & 0xFFFFFFFC); // aling with quad boundary - ReturnValue->Val->Integer = (int)*ip; - break; - default: - ReturnValue->Val->Integer = 0; - break; - } -} - -void Cpoke(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) -{ - int size, ptr, val; - unsigned char *cp; - unsigned short *sp; - unsigned int *ip; - - /* x = poke(addr, size, val); - mask ptr to align with word size */ - ptr = Param[0]->Val->Integer; - size = Param[1]->Val->Integer; - val = Param[2]->Val->Integer; - switch (size) { - case 1: // char * - cp = (unsigned char *)ptr; - *cp = (unsigned char)(val & 0x000000FF); - break; - case 2: // short * - sp = (unsigned short *)(ptr & 0xFFFFFFFE); - *sp = (unsigned short)(val & 0x0000FFFF); - break; - case 4: // int * - ip = (unsigned int *)(ptr & 0xFFFFFFFC); - *ip = val; - break; - default: // don't bother with bad value - break; - } -} - -void Cencoders(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) -{ - unsigned int ix; - - ix = encoders(); // read left and right encoders; save data to C globals lcount, rcount - Elcount = (ix >> 16) & 0x0000FFFF; - Ercount = ix & 0x0000FFFF; -} - -void Cmotors(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) -{ - lspeed = Param[0]->Val->Integer; - if ((lspeed < -100) || (lspeed > 100)) - ProgramFail(NULL, "motors(): left motor value out of range"); - rspeed = Param[1]->Val->Integer; - if ((rspeed < -100) || (rspeed > 100)) - ProgramFail(NULL, "motors(): right motor value out of range"); - if (!pwm1_init) { - initPWM(); - pwm1_init = 1; - pwm1_mode = PWM_PWM; - base_speed = 50; - } - setPWM(lspeed, rspeed); -} - -void Cmotors2(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) -{ - lspeed2 = Param[0]->Val->Integer; - if ((lspeed2 < -100) || (lspeed2 > 100)) - ProgramFail(NULL, "motors2(): left motor value out of range"); - rspeed2 = Param[1]->Val->Integer; - if ((rspeed2 < -100) || (rspeed2 > 100)) - ProgramFail(NULL, "motors2(): right motor value out of range"); - if (!pwm2_init) { - initPWM2(); - pwm2_init = 1; - pwm2_mode = PWM_PWM; - base_speed2 = 50; - } - setPWM2(lspeed2, rspeed2); -} - -void Cservos(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) -{ - int lspeed, rspeed; - - lspeed = Param[0]->Val->Integer; - if ((lspeed < 0) || (lspeed > 100)) - ProgramFail(NULL, "servos(): TMR2 value out of range"); - rspeed = Param[1]->Val->Integer; - if ((rspeed < 0) || (rspeed > 100)) - ProgramFail(NULL, "servos()(): TMR3 value out of range"); - if (!pwm1_init) { - initPPM1(); - pwm1_init = 1; - pwm1_mode = PWM_PPM; - } - setPPM1(lspeed, rspeed); -} - -void Cservos2(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) -{ - int lspeed, rspeed; - - lspeed = Param[0]->Val->Integer; - if ((lspeed < 0) || (lspeed > 100)) - ProgramFail(NULL, "servos2(): TMR6 value out of range"); - rspeed = Param[1]->Val->Integer; - if ((rspeed < 0) || (rspeed > 100)) - ProgramFail(NULL, "servos2(): TMR7 value out of range"); - if (!pwm2_init) { - initPPM2(); - pwm2_init = 1; - pwm2_mode = PWM_PPM; - } - setPPM2(lspeed, rspeed); -} - -void Claser(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) // laser(1) turns them on, laser(0) turns them off -{ - *pPORTHIO &= 0xFD7F; // turn off both lasers - switch (Param[0]->Val->Integer) { - case 1: - *pPORTHIO |= 0x0080; // turn on left laser - break; - case 2: - *pPORTHIO |= 0x0200; // turn on right laser - break; - case 3: - *pPORTHIO |= 0x0280; // turn on both lasers - break; - } -} - -void Csonar(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) // read sonar module -{ - unsigned int i; - i = Param[0]->Val->Integer; - if ((i<1) || (i>4)) { - ProgramFail(NULL, "sonar(): 1, 2, 3, 4 are only valid selections"); - } - sonar(); - ReturnValue->Val->Integer = sonar_data[i] / 100; -} - -void Crange(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) -{ - ReturnValue->Val->Integer = laser_range(0); -} - -void Cbattery(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) -{ - if (*pPORTHIO & 0x0004) - ReturnValue->Val->Integer = 0; // low battery voltage detected - else - ReturnValue->Val->Integer = 1; // battery voltage okay -} - -void Cvcolor(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) // set color bin - - // vcolor (color, ymin, ymax, umin, umax, vmin, vmax); -{ - int ix; - - ix = Param[0]->Val->Integer; - ymin[ix] = Param[1]->Val->Integer; - ymax[ix] = Param[2]->Val->Integer; - umin[ix] = Param[3]->Val->Integer; - umax[ix] = Param[4]->Val->Integer; - vmin[ix] = Param[5]->Val->Integer; - vmax[ix] = Param[6]->Val->Integer; -} - -void Cvcam(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) // set camera functions - - // enable/disable AGC(4) / AWB(2) / AEC(1) camera controls - // vcam(7) = AGC+AWB+AEC on vcam(0) = AGC+AWB+AEC off -{ - unsigned char cx, i2c_data[2]; - - cx = (unsigned char)Param[0]->Val->Integer & 0x07; - i2c_data[0] = 0x13; - i2c_data[1] = 0xC0 + cx; - i2cwrite(0x30, (unsigned char *)i2c_data, 1, SCCB_ON); // OV9655 - i2cwrite(0x21, (unsigned char *)i2c_data, 1, SCCB_ON); // OV7725 -} - -void Cvfind(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) // set color bin - - // vfind (color, x1, x2, y1, y2); -{ - int ix, x1, x2, y1, y2; - - ix = Param[0]->Val->Integer; - x1 = Param[1]->Val->Integer; - x2 = Param[2]->Val->Integer; - y1 = Param[3]->Val->Integer; - y2 = Param[4]->Val->Integer; - ReturnValue->Val->Integer = vfind((unsigned char *)FRAME_BUF, ix, x1, x2, y1, y2); -} - -void Cvcap(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) -{ - grab_frame(); // capture frame for processing -} - -void Cvrcap(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) -{ - grab_reference_frame(); // capture reference frame for differencing -} - -void Cvdiff(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) -{ - frame_diff_flag = Param[0]->Val->Integer; // set/clear frame_diff_flag -} - -void Cvpix(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) -{ - int x, y, ix; - x = Param[0]->Val->Integer; - y = Param[1]->Val->Integer; - ix = vpix((unsigned char *)FRAME_BUF, x, y); - Iy1 = ((ix>>16) & 0x000000FF); // Y1 - Iu1 = ((ix>>24) & 0x000000FF); // U - Iv1 = ((ix>>8) & 0x000000FF); // V -} - -void Cvscan(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) -{ - int col, thresh, ix; - col = Param[0]->Val->Integer; - if ((col < 1) || (col > 9)) - ProgramFail(NULL, "vscan(): number of columns must be between 1 and 9"); - thresh = Param[1]->Val->Integer; - if ((thresh < 0) || (thresh > 9999)) - ProgramFail(NULL, "vscan(): threshold must be between 0 and 9999"); - ix = vscan((unsigned char *)SPI_BUFFER1, (unsigned char *)FRAME_BUF, thresh, (unsigned int)col, (unsigned int *)&ScanVect[0]); - ReturnValue->Val->Integer = ix; -} - -void Cvmean(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) -{ - vmean((unsigned char *)FRAME_BUF); - Iy1 = mean[0]; - Iu1 = mean[1]; - Iv1 = mean[2]; -} - -// search for blob by color, index; return center point X,Y and width Z -void Cvblob(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) { - int ix, iblob, numblob; - - ix = Param[0]->Val->Integer; - if (ix > MAX_COLORS) - ProgramFail(NULL, "blob(): invalid color index"); - iblob = Param[1]->Val->Integer; - if (iblob > MAX_BLOBS) - ProgramFail(NULL, "blob(): invalid blob index"); - - numblob = vblob((unsigned char *)FRAME_BUF, (unsigned char *)FRAME_BUF3, ix); - - if ((blobcnt[iblob] == 0) || (numblob == -1)) { - Blobcnt = 0; - } else { - Blobcnt = blobcnt[iblob]; - Blobx1 = blobx1[iblob]; - Blobx2 = blobx2[iblob]; - Bloby1 = bloby1[iblob]; - Bloby2 = bloby2[iblob]; - } - ReturnValue->Val->Integer = numblob; -} - -void Cvjpeg (struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) { - unsigned int image_size, qual; - unsigned char *output_start, *output_end; - - qual = Param[0]->Val->Integer; - if ((qual < 1) || (qual > 8)) - ProgramFail(NULL, "vjpeg(): quality parameter out of range"); - - output_start = (unsigned char *)JPEG_BUF; - output_end = encode_image((unsigned char *)FRAME_BUF, output_start, qual, - FOUR_TWO_TWO, imgWidth, imgHeight); - image_size = (unsigned int)(output_end - output_start); - - ReturnValue->Val->Integer = image_size; -} - -void Cvsend (struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) { - unsigned int ix, image_size; - unsigned char *cp; - - image_size = Param[0]->Val->Integer; - if ((image_size < 0) || (image_size > 200000)) - ProgramFail(NULL, "vsend(): image size out of range"); - - led1_on(); - - cp = (unsigned char *)JPEG_BUF; - for (ix=0; ixVal->Integer = ix; -} - -void Ctilt(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) // return reading from HMC6352 I2C compass -{ - unsigned int ix; - - ix = (unsigned int)Param[0]->Val->Integer; - if ((ix<1) || (ix>3)) - ProgramFail(NULL, "tilt(): invalid channel"); - ReturnValue->Val->Integer = tilt(ix); -} - -void Canalog(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) // return reading from HMC6352 I2C compass -{ - unsigned char i2c_data[3], device_id; - unsigned int ix, channel; - unsigned char mask1[] = { 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x04, 0x08 }; - unsigned char mask2[] = { 0x10, 0x20, 0x40, 0x80, 0x00, 0x00, 0x00, 0x00 }; - - // decide which i2c device based on channel range - ix = (unsigned char)Param[0]->Val->Integer; - if ((ix<1) || (ix>28)) - ProgramFail(NULL, "analog(): invalid channel"); - device_id = 0; - switch (ix / 10) { - case 0: - device_id = 0x20; // channels 1-8 - break; - case 1: - device_id = 0x23; // channels 11-18 - break; - case 2: - device_id = 0x24; // channels 21-28 - break; - } - channel = ix % 10; - if ((channel<1) || (channel>8)) - ProgramFail(NULL, "analog(): invalid channel"); - - // set timer register 3 - i2c_data[0] = 0x03; - i2c_data[1] = 0x01; - i2cwrite(device_id, (unsigned char *)i2c_data, 1, SCCB_ON); - - // set analog channel - i2c_data[0] = 0x02; - i2c_data[1] = mask1[channel-1]; - i2c_data[2] = mask2[channel-1]; - i2cwritex(device_id, (unsigned char *)i2c_data, 3, SCCB_ON); - - // small delay - delayUS(1000); - - // read data - i2c_data[0] = 0x00; - i2cread(device_id, (unsigned char *)i2c_data, 2, SCCB_ON); - ix = (((i2c_data[0] & 0x0F) << 8) + i2c_data[1]); - ReturnValue->Val->Integer = ix; -} - -void Cgps(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) -{ - gps_parse(); - GPSlat = gps_gga.lat; - GPSlon = gps_gga.lon; - GPSalt = gps_gga.alt; - GPSfix = gps_gga.fix; - GPSsat = gps_gga.sat; - GPSutc = gps_gga.utc; -} - -void Creadi2c(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) // syntax val = readi2c(device, register); -{ - unsigned char i2c_device, i2c_data[2]; - - i2c_device = (unsigned char)Param[0]->Val->Integer; - i2c_data[0] = (unsigned char)Param[1]->Val->Integer; - - i2cread(i2c_device, (unsigned char *)i2c_data, 1, SCCB_OFF); - ReturnValue->Val->Integer = ((int)i2c_data[0] & 0x000000FF); -} - -void Creadi2c2(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) // syntax two_byte_val = readi2c(device, register); -{ - unsigned char i2c_device, i2c_data[2]; - - i2c_device = (unsigned char)Param[0]->Val->Integer; - i2c_data[0] = (unsigned char)Param[1]->Val->Integer; - - i2cread(i2c_device, (unsigned char *)i2c_data, 2, SCCB_OFF); - ReturnValue->Val->Integer = (((unsigned int)i2c_data[0] << 8) + i2c_data[1]); -} - -void Cwritei2c(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) // syntax writei2c(device, register, value); -{ - unsigned char i2c_device, i2c_data[2]; - - i2c_device = (unsigned char)Param[0]->Val->Integer; - i2c_data[0] = (unsigned char)Param[1]->Val->Integer; - i2c_data[1] = (unsigned char)Param[2]->Val->Integer; - - i2cwrite(i2c_device, (unsigned char *)i2c_data, 1, SCCB_OFF); -} - -void Csin(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) // sin(angle) -{ - int ix; - - ix = Param[0]->Val->Integer; // input to function is angle in degrees - ReturnValue->Val->Integer = sin(ix); -} - -void Ccos(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) // cos(angle) -{ - int ix; - - ix = Param[0]->Val->Integer; // input to function is angle in degrees - ReturnValue->Val->Integer = cos(ix); -} - -void Ctan(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) // tan(angle) -{ - int ix; - - ix = Param[0]->Val->Integer; // input to function is angle in degrees - ReturnValue->Val->Integer = tan(ix); -} - -void Casin(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) // asin(y,hyp) -{ - int y, hyp; - y = Param[0]->Val->Integer; - hyp = Param[1]->Val->Integer; - if (y > hyp) - ProgramFail(NULL, "asin(): opposite greater than hypotenuse"); - ReturnValue->Val->Integer = asin(y, hyp); -} - -void Cacos(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) // acos(x,hyp) -{ - int x, hyp; - x = Param[0]->Val->Integer; - hyp = Param[1]->Val->Integer; - if (x > hyp) - ProgramFail(NULL, "acos(): adjacent greater than hypotenuse"); - ReturnValue->Val->Integer = acos(x, hyp); -} - -void Catan(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) // atan(y,x) -{ - int x ,y; - y = Param[0]->Val->Integer; - x = Param[1]->Val->Integer; - ReturnValue->Val->Integer = atan(y, x); -} - -void Cgps_head(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) // gps_head(lat1, lon1, lat2, lon2) -{ - int lat1, lon1, lat2, lon2; - lat1 = Param[0]->Val->Integer; - lon1 = Param[1]->Val->Integer; - lat2 = Param[2]->Val->Integer; - lon2 = Param[3]->Val->Integer; - ReturnValue->Val->Integer = gps_head(lat1, lon1, lat2, lon2); -} - -void Cgps_dist(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) // gps_dist(lat1, lon1, lat2, lon2) -{ - int lat1, lon1, lat2, lon2; - lat1 = Param[0]->Val->Integer; - lon1 = Param[1]->Val->Integer; - lat2 = Param[2]->Val->Integer; - lon2 = Param[3]->Val->Integer; - ReturnValue->Val->Integer = gps_dist(lat1, lon1, lat2, lon2); -} - -void Csqrt(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) // sqrt(x) -{ - int x; - x = Param[0]->Val->Integer; - ReturnValue->Val->Integer = isqrt(x); -} - -void Cnnset(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) { - int ix, i1; - - ix = Param[0]->Val->Integer; - if (ix > NUM_NPATTERNS) - ProgramFail(NULL, "nnset(): invalid index"); - for (i1=0; i1<8; i1++) - npattern[ix*8 + i1] = (unsigned char)Param[i1+1]->Val->Integer; -} - -void Cnnshow(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) { - int ix; - - ix = Param[0]->Val->Integer; - if (ix > NUM_NPATTERNS) - ProgramFail(NULL, "nnshow(): invalid index"); - nndisplay(ix); -} - -void Cnninit(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) { - nninit_network(); -} - -void Cnntrain(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) { - int ix, i1; - - nntrain_network(10000); - for (ix=0; ixVal->Integer; - for (i2=0; i2<8; i2++) { - if (ch & nmask[i2]) - N_IN(ix++) = 1024; - else - N_IN(ix++) = 0; - } - } - nncalculate_network(); - ix = 0; - max = 0; - for (i1=0; i1Val->Integer = ix; -} - -void Cnnmatchblob(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) { - int ix, i1, max; - - ix = Param[0]->Val->Integer; - if (ix > MAX_BLOBS) - ProgramFail(NULL, "nnmatchblob(): invalid blob index"); - if (!blobcnt[ix]) - ProgramFail(NULL, "nnmatchblob(): not a valid blob"); - /* use data still in blob_buf[] (FRAME_BUF3) - square the aspect ratio of x1, x2, y1, y2 - then subsample blob pixels to populate N_IN(0:63) with 0:1024 values - then nncalculate_network() and display the N_OUT() results */ - nnscale8x8((unsigned char *)FRAME_BUF3, blobix[ix], blobx1[ix], blobx2[ix], - bloby1[ix], bloby2[ix], imgWidth, imgHeight); - nncalculate_network(); - ix = 0; - max = 0; - for (i1=0; i1Val->Integer = ix; -} - -void Cnnlearnblob (struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) { - int ix; - - ix = Param[0]->Val->Integer; - if (ix > NUM_NPATTERNS) - ProgramFail(NULL, "nnlearnblob(): invalid index"); - if (!blobcnt[0]) - ProgramFail(NULL, "nnlearnblob(): no blob to grab"); - nnscale8x8((unsigned char *)FRAME_BUF3, blobix[0], blobx1[0], blobx2[0], - bloby1[0], bloby2[0], imgWidth, imgHeight); - nnpack8x8(ix); - nndisplay(ix); -} - -void Cautorun (struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) { - int ix, t0; - unsigned char ch; - - ix = Param[0]->Val->Integer; - t0 = readRTC(); - while (readRTC() < (t0 + ix*1000)) { // watch for ESC in 'ix' seconds - if (getchar(&ch)) { - if (ch == 0x1B) { // if ESC found, exit picoC - printf("found ESC\r\n"); - ExitBuf[40] = 1; - longjmp(ExitBuf, 1); - } - } - } -} - -void Clineno (struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) { - ReturnValue->Val->Integer = Parser->Line; -} - -void Cerrormsg (struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) { - PlatformErrorPrefix(Parser); - LibPrintf(Parser, ReturnValue, Param, NumArgs); -} - -/* nothing here because we don't add any functions until srv1.h is #included */ -struct LibraryFunction PlatformLibrary[] = -{ - { NULL, NULL } -}; - -/* list of all library functions included with srv1.h */ -struct LibraryFunction SRV1Functions[] = -{ - { Csignal, "int signal();" }, - { Cinput, "int input();" }, - { Cdelay, "void delay(int);" }, - { Crand, "int rand(int);" }, - { Ctime, "int time();" }, - { Ciodir, "void iodir(int);" }, - { Cioread, "int ioread();" }, - { Ciowrite, "void iowrite(int);" }, - { Cpeek, "int peek(int, int);" }, - { Cpoke, "void poke(int, int, int);" }, - { Cmotors, "void motors(int, int);" }, - { Cmotors2, "void motors2(int, int);" }, - { Cservos, "void servos(int, int);" }, - { Cservos2, "void servos2(int, int);" }, - { Cencoders, "void encoders();" }, - { Claser, "void laser(int);" }, - { Csonar, "int sonar(int);" }, - { Crange, "int range();" }, - { Cbattery, "int battery();" }, - { Cvcolor, "void vcolor(int, int, int, int, int, int, int);" }, - { Cvfind, "int vfind(int, int, int, int, int);" }, - { Cvcam, "void vcam(int);" }, - { Cvcap, "void vcap();" }, - { Cvrcap, "void vrcap();" }, - { Cvdiff, "void vdiff(int);" }, - { Cvpix, "void vpix(int, int);" }, - { Cvscan, "int vscan(int, int);" }, - { Cvmean, "void vmean();" }, - { Cvblob, "int vblob(int, int);" }, - { Cvjpeg, "int vjpeg(int);" }, - { Cvsend, "void vsend(int);" }, - { Ccompass, "int compass();" }, - { Canalog, "int analog(int);" }, - { Ctilt, "int tilt(int);" }, - { Cgps, "void gps();" }, - { Creadi2c, "int readi2c(int, int);" }, - { Creadi2c2, "int readi2c2(int, int);" }, - { Cwritei2c, "void writei2c(int, int, int);" }, - { Csin, "int sin(int);" }, - { Ccos, "int cos(int);" }, - { Ctan, "int tan(int);" }, - { Casin, "int asin(int, int);" }, - { Cacos, "int acos(int, int);" }, - { Catan, "int atan(int, int);" }, - { Cgps_head, "int gps_head(int, int, int, int);" }, - { Cgps_dist, "int gps_dist(int, int, int, int);" }, - { Csqrt, "int sqrt(int);" }, - { Cnnshow, "void nnshow(int);" }, - { Cnnset, "void nnset(int, int, int, int, int, int, int, int, int);" }, - { Cnninit, "void nninit();" }, - { Cnntrain, "void nntrain();" }, - { Cnntest, "int nntest(int, int, int, int, int, int, int, int);" }, - { Cnnmatchblob, "int nnmatchblob(int);" }, - { Cnnlearnblob, "void nnlearnblob(int);" }, - { Cautorun, "void autorun(int);" }, - { Clineno, "int lineno();" }, - { Cerrormsg, "void errormsg(char *);" }, - { NULL, NULL } -}; - -void PlatformLibraryInit() -{ - IncludeRegister("srv1.h", &SRV1SetupFunc, &SRV1Functions[0], NULL); -} diff --git a/eci/platform/library_surveyor.c b/eci/platform/library_surveyor.c deleted file mode 100644 index c620406..0000000 --- a/eci/platform/library_surveyor.c +++ /dev/null @@ -1,945 +0,0 @@ -#include "../interpreter.h" -#include "../picoc.h" - -static int Blobcnt, Blobx1, Blobx2, Bloby1, Bloby2, Iy1, Iy2, Iu1, Iu2, Iv1, Iv2; -static int Cxmin, Cxmax, Cymin, Cymax; -static int GPSlat, GPSlon, GPSalt, GPSfix, GPSsat, GPSutc, Elcount, Ercount; -static int ScanVect[16], NNVect[NUM_OUTPUT]; - -void PlatformLibraryInit() -{ - struct ValueType *IntArrayType; - - IntArrayType = TypeGetMatching(NULL, &IntType, TypeArray, 16, StrEmpty, TRUE); - VariableDefinePlatformVar(NULL, "scanvect", IntArrayType, (union AnyValue *)&ScanVect, FALSE); - VariableDefinePlatformVar(NULL, "neuron", IntArrayType, (union AnyValue *)&NNVect, FALSE); - VariableDefinePlatformVar(NULL, "xbuf", CharArrayType, (union AnyValue *)&xbuff, FALSE); - VariableDefinePlatformVar(NULL, "blobcnt", &IntType, (union AnyValue *)&Blobcnt, FALSE); - VariableDefinePlatformVar(NULL, "blobx1", &IntType, (union AnyValue *)&Blobx1, FALSE); - VariableDefinePlatformVar(NULL, "blobx2", &IntType, (union AnyValue *)&Blobx2, FALSE); - VariableDefinePlatformVar(NULL, "bloby1", &IntType, (union AnyValue *)&Bloby1, FALSE); - VariableDefinePlatformVar(NULL, "bloby2", &IntType, (union AnyValue *)&Bloby2, FALSE); - VariableDefinePlatformVar(NULL, "lcount", &IntType, (union AnyValue *)&Elcount, FALSE); - VariableDefinePlatformVar(NULL, "rcount", &IntType, (union AnyValue *)&Ercount, FALSE); - VariableDefinePlatformVar(NULL, "y1", &IntType, (union AnyValue *)&Iy1, FALSE); - VariableDefinePlatformVar(NULL, "y2", &IntType, (union AnyValue *)&Iy2, FALSE); - VariableDefinePlatformVar(NULL, "u1", &IntType, (union AnyValue *)&Iu1, FALSE); - VariableDefinePlatformVar(NULL, "u2", &IntType, (union AnyValue *)&Iu2, FALSE); - VariableDefinePlatformVar(NULL, "v1", &IntType, (union AnyValue *)&Iv1, FALSE); - VariableDefinePlatformVar(NULL, "v2", &IntType, (union AnyValue *)&Iv2, FALSE); - VariableDefinePlatformVar(NULL, "gpslat", &IntType, (union AnyValue *)&GPSlat, FALSE); - VariableDefinePlatformVar(NULL, "gpslon", &IntType, (union AnyValue *)&GPSlon, FALSE); - VariableDefinePlatformVar(NULL, "gpsalt", &IntType, (union AnyValue *)&GPSalt, FALSE); - VariableDefinePlatformVar(NULL, "gpsfix", &IntType, (union AnyValue *)&GPSfix, FALSE); - VariableDefinePlatformVar(NULL, "gpssat", &IntType, (union AnyValue *)&GPSsat, FALSE); - VariableDefinePlatformVar(NULL, "gpsutc", &IntType, (union AnyValue *)&GPSutc, FALSE); - VariableDefinePlatformVar(NULL, "cxmin", &IntType, (union AnyValue *)&Cxmin, FALSE); - VariableDefinePlatformVar(NULL, "cxmax", &IntType, (union AnyValue *)&Cxmax, FALSE); - VariableDefinePlatformVar(NULL, "cymin", &IntType, (union AnyValue *)&Cymin, FALSE); - VariableDefinePlatformVar(NULL, "cymax", &IntType, (union AnyValue *)&Cymax, FALSE); - LibraryAdd(&GlobalTable, "platform library", &PlatformLibrary[0]); -} - -void Csignal(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) // check for kbhit, return t or nil -{ - ReturnValue->Val->Integer = getsignal(); -} - -void Csignal1(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) // check for kbhit, return t or nil -{ - ReturnValue->Val->Integer = uart1Signal(); -} - -void Cinput(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) // return 0-9 from console input -{ - ReturnValue->Val->Integer = getch(); -} - -void Cinput1(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) // return 0-9 from console input -{ - ReturnValue->Val->Integer = uart1GetCh(); -} - -void Cread_int(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) // return 0-9 from console input -{ - int ix, sign; - unsigned char ch; - - ix = 0; - sign = 1; - while (1) { - ch = getch(); - if (ch == '-') { - sign = -1; - continue; - } - if ((ch < '0') || (ch > '9')) { // if not '-' or 0-9, we're done - ReturnValue->Val->Integer = ix * sign; - return; - } - ix = (ix * 10) + (ch & 0x0F); - } -} - -void Cread_str(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) // read string from console -{ - int ix; - unsigned char ch; - - ix = 0; - char *cp = (char *)Param[0]->Val->Pointer; - while (1) { - ch = getch(); - cp[ix++] = ch; - if ((ch == 0) || (ch == 0x01)) { // null or ctrl-A - ix--; - cp[ix] = 0; - break; - } - if (ix > 1023) { - cp[ix] = 0; - ix--; - break; - } - } - ReturnValue->Val->Integer = ix; -} - -void Cinit_uart1(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) // return 0-9 from console input -{ - int ii; - ii = Param[0]->Val->Integer; // ii = baudrate for uart1 - init_uart1(ii); -} - -void Coutput(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) // return 0-9 from console input -{ - int ch; - ch = Param[0]->Val->Integer; - putchar((unsigned char)ch); -} - -void Coutput1(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) // return 0-9 from console input -{ - int ch; - ch = Param[0]->Val->Integer; - uart1SendChar((unsigned char)ch); -} - -void Cdelay(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) -{ - int del; - - del = Param[0]->Val->Integer; - if ((del < 0) || (del > 1000000)) - return; - delayMS(del); -} - -void Crand(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) -{ - ReturnValue->Val->Integer = (int)rand() % (unsigned int)(Param[0]->Val->Integer + 1); -} - -void Ctime(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) -{ - ReturnValue->Val->Integer = (int)readRTC(); -} - -void Ciodir(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) -{ - int dir; - - dir = Param[0]->Val->Integer; - *pPORTHIO_DIR = ((dir << 10) & 0xFC00) + (*pPORTHIO_DIR & 0x03FF); // H15/14/13/12/11/10 - 1=output, 0=input - *pPORTHIO_INEN = (((~dir) << 10) & 0xFC00) + (*pPORTHIO_INEN & 0x03FF); // invert dir bits to enable inputs -} - -void Cioread(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) -{ - ReturnValue->Val->Integer = (*pPORTHIO >> 10) & 0x003F; -} - -void Ciowrite(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) -{ - *pPORTHIO = ((Param[0]->Val->Integer << 10) & 0xFC00) + (*pPORTHIO & 0x03FF); -} - -void Cpeek(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) -{ - int size, ptr; - unsigned char *cp; - unsigned short *sp; - unsigned int *ip; - - /* x = peek(addr, size); - mask ptr to align with word size */ - ptr = Param[0]->Val->Integer; - size = Param[1]->Val->Integer; - switch (size) { - case 1: // char * - cp = (unsigned char *)ptr; - ReturnValue->Val->Integer = (int)((unsigned int)*cp); - break; - case 2: // short * - sp = (unsigned short *)(ptr & 0xFFFFFFFE); // align with even boundary - ReturnValue->Val->Integer = (int)((unsigned short)*sp); - break; - case 4: // int * - ip = (unsigned int *)(ptr & 0xFFFFFFFC); // aling with quad boundary - ReturnValue->Val->Integer = (int)*ip; - break; - default: - ReturnValue->Val->Integer = 0; - break; - } -} - -void Cpoke(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) -{ - int size, ptr, val; - unsigned char *cp; - unsigned short *sp; - unsigned int *ip; - - /* x = poke(addr, size, val); - mask ptr to align with word size */ - ptr = Param[0]->Val->Integer; - size = Param[1]->Val->Integer; - val = Param[2]->Val->Integer; - switch (size) { - case 1: // char * - cp = (unsigned char *)ptr; - *cp = (unsigned char)(val & 0x000000FF); - break; - case 2: // short * - sp = (unsigned short *)(ptr & 0xFFFFFFFE); - *sp = (unsigned short)(val & 0x0000FFFF); - break; - case 4: // int * - ip = (unsigned int *)(ptr & 0xFFFFFFFC); - *ip = val; - break; - default: // don't bother with bad value - break; - } -} - -void Cencoders(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) -{ - unsigned int ix; - - ix = encoders(); // read left and right encoders; save data to C globals lcount, rcount - Elcount = (ix >> 16) & 0x0000FFFF; - Ercount = ix & 0x0000FFFF; -} - -void Cencoderx(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) // return reading from HMC6352 I2C compass -{ - int ix; - - ix = (unsigned char)Param[0]->Val->Integer; - if ((ix<0) || (ix>7)) - ProgramFail(NULL, "encoderx(): invalid channel"); - ReturnValue->Val->Integer = encoder_4wd(ix); -} - -void Cmotors(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) -{ - lspeed = Param[0]->Val->Integer; - if ((lspeed < -100) || (lspeed > 100)) - ProgramFail(NULL, "motors(): left motor value out of range"); - rspeed = Param[1]->Val->Integer; - if ((rspeed < -100) || (rspeed > 100)) - ProgramFail(NULL, "motors(): right motor value out of range"); - if (!pwm1_init) { - initPWM(); - pwm1_init = 1; - pwm1_mode = PWM_PWM; - base_speed = 50; - } - setPWM(lspeed, rspeed); -} - -void Cmotors2(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) -{ - lspeed2 = Param[0]->Val->Integer; - if ((lspeed2 < -100) || (lspeed2 > 100)) - ProgramFail(NULL, "motors2(): left motor value out of range"); - rspeed2 = Param[1]->Val->Integer; - if ((rspeed2 < -100) || (rspeed2 > 100)) - ProgramFail(NULL, "motors2(): right motor value out of range"); - if (!pwm2_init) { - initPWM2(); - pwm2_init = 1; - pwm2_mode = PWM_PWM; - base_speed2 = 50; - } - setPWM2(lspeed2, rspeed2); -} - -/* motor control for SRV-4WD controller */ -void Cmotorx(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) -{ - unsigned char ch; - int ls, rs; - - ls = Param[0]->Val->Integer; - if ((ls < -100) || (ls > 100)) - ProgramFail(NULL, "motors(): left motor value out of range"); - ls = (ls * 127) / 100; // scale to full +/-127 range - rs = Param[1]->Val->Integer; - if ((rs < -100) || (rs > 100)) - ProgramFail(NULL, "motors(): right motor value out of range"); - rs = (rs * 127) / 100; // scale to full +/-127 range - if (xwd_init == 0) { - xwd_init = 1; - init_uart1(115200); - delayMS(10); - } - uart1SendChar('x'); - uart1SendChar((char)ls); - uart1SendChar((char)rs); - while (uart1GetChar(&ch)) // flush the receive buffer - continue; -} - -void Cservos(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) -{ - int lspeed, rspeed; - - lspeed = Param[0]->Val->Integer; - if ((lspeed < 0) || (lspeed > 100)) - ProgramFail(NULL, "servos(): TMR2 value out of range"); - rspeed = Param[1]->Val->Integer; - if ((rspeed < 0) || (rspeed > 100)) - ProgramFail(NULL, "servos()(): TMR3 value out of range"); - if (!pwm1_init) { - initPPM1(); - pwm1_init = 1; - pwm1_mode = PWM_PPM; - } - setPPM1(lspeed, rspeed); -} - -void Cservos2(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) -{ - int lspeed, rspeed; - - lspeed = Param[0]->Val->Integer; - if ((lspeed < 0) || (lspeed > 100)) - ProgramFail(NULL, "servos2(): TMR6 value out of range"); - rspeed = Param[1]->Val->Integer; - if ((rspeed < 0) || (rspeed > 100)) - ProgramFail(NULL, "servos2(): TMR7 value out of range"); - if (!pwm2_init) { - initPPM2(); - pwm2_init = 1; - pwm2_mode = PWM_PPM; - } - setPPM2(lspeed, rspeed); -} - -void Claser(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) // laser(1) turns them on, laser(0) turns them off -{ - *pPORTHIO &= 0xFD7F; // turn off both lasers - switch (Param[0]->Val->Integer) { - case 1: - *pPORTHIO |= 0x0080; // turn on left laser - break; - case 2: - *pPORTHIO |= 0x0200; // turn on right laser - break; - case 3: - *pPORTHIO |= 0x0280; // turn on both lasers - break; - } -} - -void Csonar(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) // read sonar module -{ - unsigned int i; - i = Param[0]->Val->Integer; - if ((i<1) || (i>4)) { - ProgramFail(NULL, "sonar(): 1, 2, 3, 4 are only valid selections"); - } - sonar(); - ReturnValue->Val->Integer = sonar_data[i] / 100; -} - -void Crange(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) -{ - ReturnValue->Val->Integer = laser_range(0); -} - -void Cbattery(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) -{ - if (*pPORTHIO & 0x0004) - ReturnValue->Val->Integer = 0; // low battery voltage detected - else - ReturnValue->Val->Integer = 1; // battery voltage okay -} - -void Cvcolor(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) // set color bin - - // vcolor (color, ymin, ymax, umin, umax, vmin, vmax); -{ - int ix; - - ix = Param[0]->Val->Integer; - ymin[ix] = Param[1]->Val->Integer; - ymax[ix] = Param[2]->Val->Integer; - umin[ix] = Param[3]->Val->Integer; - umax[ix] = Param[4]->Val->Integer; - vmin[ix] = Param[5]->Val->Integer; - vmax[ix] = Param[6]->Val->Integer; -} - -void Cvcam(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) // set camera functions - - // enable/disable AGC(4) / AWB(2) / AEC(1) camera controls - // vcam(7) = AGC+AWB+AEC on vcam(0) = AGC+AWB+AEC off -{ - unsigned char cx, i2c_data[2]; - - cx = (unsigned char)Param[0]->Val->Integer & 0x07; - i2c_data[0] = 0x13; - i2c_data[1] = 0xC0 + cx; - i2cwrite(0x30, (unsigned char *)i2c_data, 1, SCCB_ON); // OV9655 - i2cwrite(0x21, (unsigned char *)i2c_data, 1, SCCB_ON); // OV7725 -} - -void Cvfind(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) // set color bin - - // vfind (color, x1, x2, y1, y2); -{ - int ix, x1, x2, y1, y2; - - ix = Param[0]->Val->Integer; - x1 = Param[1]->Val->Integer; - x2 = Param[2]->Val->Integer; - y1 = Param[3]->Val->Integer; - y2 = Param[4]->Val->Integer; - ReturnValue->Val->Integer = vfind((unsigned char *)FRAME_BUF, ix, x1, x2, y1, y2); -} - -void Cvcap(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) -{ - grab_frame(); // capture frame for processing -} - -void Cvrcap(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) -{ - grab_reference_frame(); // capture reference frame for differencing -} - -void Cvdiff(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) -{ - frame_diff_flag = Param[0]->Val->Integer; // set/clear frame_diff_flag -} - -void Cvpix(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) -{ - int x, y, ix; - x = Param[0]->Val->Integer; - y = Param[1]->Val->Integer; - ix = vpix((unsigned char *)FRAME_BUF, x, y); - Iy1 = ((ix>>16) & 0x000000FF); // Y1 - Iu1 = ((ix>>24) & 0x000000FF); // U - Iv1 = ((ix>>8) & 0x000000FF); // V -} - -void Cvscan(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) -{ - int col, thresh, ix; - col = Param[0]->Val->Integer; - if ((col < 1) || (col > 9)) - ProgramFail(NULL, "vscan(): number of columns must be between 1 and 9"); - thresh = Param[1]->Val->Integer; - if ((thresh < 0) || (thresh > 9999)) - ProgramFail(NULL, "vscan(): threshold must be between 0 and 9999"); - ix = vscan((unsigned char *)SPI_BUFFER1, (unsigned char *)FRAME_BUF, thresh, (unsigned int)col, (unsigned int *)&ScanVect[0]); - ReturnValue->Val->Integer = ix; -} - -void Cvmean(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) -{ - vmean((unsigned char *)FRAME_BUF); - Iy1 = mean[0]; - Iu1 = mean[1]; - Iv1 = mean[2]; -} - -// search for blob by color, index; return center point X,Y and width Z -void Cvblob(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) { - int ix, iblob, numblob; - - ix = Param[0]->Val->Integer; - if (ix > MAX_COLORS) - ProgramFail(NULL, "blob(): invalid color index"); - iblob = Param[1]->Val->Integer; - if (iblob > MAX_BLOBS) - ProgramFail(NULL, "blob(): invalid blob index"); - - numblob = vblob((unsigned char *)FRAME_BUF, (unsigned char *)FRAME_BUF3, ix); - - if ((blobcnt[iblob] == 0) || (numblob == -1)) { - Blobcnt = 0; - } else { - Blobcnt = blobcnt[iblob]; - Blobx1 = blobx1[iblob]; - Blobx2 = blobx2[iblob]; - Bloby1 = bloby1[iblob]; - Bloby2 = bloby2[iblob]; - } - ReturnValue->Val->Integer = numblob; -} - -void Cvjpeg (struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) { - unsigned int image_size, qual; - unsigned char *output_start, *output_end; - - qual = Param[0]->Val->Integer; - if ((qual < 1) || (qual > 8)) - ProgramFail(NULL, "vjpeg(): quality parameter out of range"); - - output_start = (unsigned char *)JPEG_BUF; - output_end = encode_image((unsigned char *)FRAME_BUF, output_start, qual, - FOUR_TWO_TWO, imgWidth, imgHeight); - image_size = (unsigned int)(output_end - output_start); - - ReturnValue->Val->Integer = image_size; -} - -void Cvsend (struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) { - unsigned int ix, image_size; - unsigned char *cp; - - image_size = Param[0]->Val->Integer; - if ((image_size < 0) || (image_size > 200000)) - ProgramFail(NULL, "vsend(): image size out of range"); - - led1_on(); - - cp = (unsigned char *)JPEG_BUF; - for (ix=0; ixVal->Integer = ix; -} - -void Ccompassx(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) // return reading from HMC5843 I2C compass -{ - short x, y, z; - int ix; - - ix = (int)read_compass3x(&x, &y, &z); - Cxmin = cxmin; - Cxmax = cxmax; - Cymin = cymin; - Cymax = cymax; - ReturnValue->Val->Integer = ix; -} - -void Ccompassxcal(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) // return reading from HMC5843 I2C compass -{ - /* cxmin, cxmax, cymin, cymax */ - cxmin = Param[0]->Val->Integer; - cxmax = Param[1]->Val->Integer; - cymin = Param[2]->Val->Integer; - cymax = Param[3]->Val->Integer; - compass_continuous_calibration = Param[4]->Val->Integer; // continuous calibration: off = 0, on = 1 -} - -void Ctilt(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) // return reading from HMC6352 I2C compass -{ - unsigned int ix; - - ix = (unsigned int)Param[0]->Val->Integer; - if ((ix<1) || (ix>3)) - ProgramFail(NULL, "tilt(): invalid channel"); - ReturnValue->Val->Integer = tilt(ix); -} - -void Canalog(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) // return reading from HMC6352 I2C compass -{ - unsigned int ix, channel; - - ix = (unsigned char)Param[0]->Val->Integer; - if ((ix<1) || (ix>28)) - ProgramFail(NULL, "analog(): invalid channel"); - channel = ix % 10; - if ((channel<1) || (channel>8)) - ProgramFail(NULL, "analog(): invalid channel"); - ReturnValue->Val->Integer = analog(ix); -} - - -/* read analog channel 0-7 from SRV-4WD ( - channel 0 = battery level - channel 1 = 5V gyro - channel 2 = 3.3V gyro - channel 3 = IR1 - channel 4 = IR2 - channel 6 = IR3 - channel 7 = IR4 - */ -void Canalogx(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) // return reading from HMC6352 I2C compass -{ - int ix; - - ix = (unsigned char)Param[0]->Val->Integer; - if ((ix<0) || (ix>7)) - ProgramFail(NULL, "analogx(): invalid channel"); - ReturnValue->Val->Integer = analog_4wd(ix); -} - -void Cgps(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) -{ - gps_parse(); - GPSlat = gps_gga.lat; - GPSlon = gps_gga.lon; - GPSalt = gps_gga.alt; - GPSfix = gps_gga.fix; - GPSsat = gps_gga.sat; - GPSutc = gps_gga.utc; -} - -void Creadi2c(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) // syntax val = readi2c(device, register); -{ - unsigned char i2c_device, i2c_data[2]; - - i2c_device = (unsigned char)Param[0]->Val->Integer; - i2c_data[0] = (unsigned char)Param[1]->Val->Integer; - - i2cread(i2c_device, (unsigned char *)i2c_data, 1, SCCB_OFF); - ReturnValue->Val->Integer = ((int)i2c_data[0] & 0x000000FF); -} - -void Creadi2c2(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) // syntax two_byte_val = readi2c(device, register); -{ - unsigned char i2c_device, i2c_data[2]; - - i2c_device = (unsigned char)Param[0]->Val->Integer; - i2c_data[0] = (unsigned char)Param[1]->Val->Integer; - - i2cread(i2c_device, (unsigned char *)i2c_data, 2, SCCB_OFF); - ReturnValue->Val->Integer = (((unsigned int)i2c_data[0] << 8) + i2c_data[1]); -} - -void Cwritei2c(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) // syntax writei2c(device, register, value); -{ - unsigned char i2c_device, i2c_data[2]; - - i2c_device = (unsigned char)Param[0]->Val->Integer; - i2c_data[0] = (unsigned char)Param[1]->Val->Integer; - i2c_data[1] = (unsigned char)Param[2]->Val->Integer; - - i2cwrite(i2c_device, (unsigned char *)i2c_data, 1, SCCB_OFF); -} - -void Cabs(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) // abs(int) -{ - int ix; - - ix = Param[0]->Val->Integer; // return absolute value of int - if (ix < 0) - ix = -ix; - ReturnValue->Val->Integer = ix; -} -void Csin(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) // sin(angle) -{ - int ix; - - ix = Param[0]->Val->Integer; // input to function is angle in degrees - ReturnValue->Val->Integer = sin(ix); -} - -void Ccos(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) // cos(angle) -{ - int ix; - - ix = Param[0]->Val->Integer; // input to function is angle in degrees - ReturnValue->Val->Integer = cos(ix); -} - -void Ctan(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) // tan(angle) -{ - int ix; - - ix = Param[0]->Val->Integer; // input to function is angle in degrees - ReturnValue->Val->Integer = tan(ix); -} - -void Casin(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) // asin(y,hyp) -{ - int y, hyp; - y = Param[0]->Val->Integer; - hyp = Param[1]->Val->Integer; - if (y > hyp) - ProgramFail(NULL, "asin(): opposite greater than hypotenuse"); - ReturnValue->Val->Integer = asin(y, hyp); -} - -void Cacos(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) // acos(x,hyp) -{ - int x, hyp; - x = Param[0]->Val->Integer; - hyp = Param[1]->Val->Integer; - if (x > hyp) - ProgramFail(NULL, "acos(): adjacent greater than hypotenuse"); - ReturnValue->Val->Integer = acos(x, hyp); -} - -void Catan(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) // atan(y,x) -{ - int x ,y; - y = Param[0]->Val->Integer; - x = Param[1]->Val->Integer; - ReturnValue->Val->Integer = atan(y, x); -} - -void Cgps_head(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) // gps_head(lat1, lon1, lat2, lon2) -{ - int lat1, lon1, lat2, lon2; - lat1 = Param[0]->Val->Integer; - lon1 = Param[1]->Val->Integer; - lat2 = Param[2]->Val->Integer; - lon2 = Param[3]->Val->Integer; - ReturnValue->Val->Integer = gps_head(lat1, lon1, lat2, lon2); -} - -void Cgps_dist(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) // gps_dist(lat1, lon1, lat2, lon2) -{ - int lat1, lon1, lat2, lon2; - lat1 = Param[0]->Val->Integer; - lon1 = Param[1]->Val->Integer; - lat2 = Param[2]->Val->Integer; - lon2 = Param[3]->Val->Integer; - ReturnValue->Val->Integer = gps_dist(lat1, lon1, lat2, lon2); -} - -void Csqrt(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) // sqrt(x) -{ - int x; - x = Param[0]->Val->Integer; - ReturnValue->Val->Integer = isqrt(x); -} - -void Cnnset(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) { - int ix, i1; - - ix = Param[0]->Val->Integer; - if (ix > NUM_NPATTERNS) - ProgramFail(NULL, "nnset(): invalid index"); - for (i1=0; i1<8; i1++) - npattern[ix*8 + i1] = (unsigned char)Param[i1+1]->Val->Integer; -} - -void Cnnshow(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) { - int ix; - - ix = Param[0]->Val->Integer; - if (ix > NUM_NPATTERNS) - ProgramFail(NULL, "nnshow(): invalid index"); - nndisplay(ix); -} - -void Cnninit(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) { - nninit_network(); -} - -void Cnntrain(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) { - int ix, i1; - - nntrain_network(10000); - for (ix=0; ixVal->Integer; - for (i2=0; i2<8; i2++) { - if (ch & nmask[i2]) - N_IN(ix++) = 1024; - else - N_IN(ix++) = 0; - } - } - nncalculate_network(); - ix = 0; - max = 0; - for (i1=0; i1Val->Integer = ix; -} - -void Cnnmatchblob(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) { - int ix, i1, max; - - ix = Param[0]->Val->Integer; - if (ix > MAX_BLOBS) - ProgramFail(NULL, "nnmatchblob(): invalid blob index"); - if (!blobcnt[ix]) - ProgramFail(NULL, "nnmatchblob(): not a valid blob"); - /* use data still in blob_buf[] (FRAME_BUF3) - square the aspect ratio of x1, x2, y1, y2 - then subsample blob pixels to populate N_IN(0:63) with 0:1024 values - then nncalculate_network() and display the N_OUT() results */ - nnscale8x8((unsigned char *)FRAME_BUF3, blobix[ix], blobx1[ix], blobx2[ix], - bloby1[ix], bloby2[ix], imgWidth, imgHeight); - nncalculate_network(); - ix = 0; - max = 0; - for (i1=0; i1Val->Integer = ix; -} - -void Cnnlearnblob (struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) { - int ix; - - ix = Param[0]->Val->Integer; - if (ix > NUM_NPATTERNS) - ProgramFail(NULL, "nnlearnblob(): invalid index"); - if (!blobcnt[0]) - ProgramFail(NULL, "nnlearnblob(): no blob to grab"); - nnscale8x8((unsigned char *)FRAME_BUF3, blobix[0], blobx1[0], blobx2[0], - bloby1[0], bloby2[0], imgWidth, imgHeight); - nnpack8x8(ix); - nndisplay(ix); -} - -void Cautorun (struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) { - int ix, t0; - unsigned char ch; - - ix = Param[0]->Val->Integer; - t0 = readRTC(); - while (readRTC() < (t0 + ix*1000)) { // watch for ESC in 'ix' seconds - if (getchar(&ch)) { - if (ch == 0x1B) { // if ESC found, exit picoC - printf("found ESC\r\n"); - PicocExitBuf[40] = 1; - longjmp(PicocExitBuf, 1); - } - } - } -} - -void Clineno (struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) { - ReturnValue->Val->Integer = Parser->Line; -} - -void Cerrormsg (struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) { - PlatformErrorPrefix(Parser); - LibPrintf(Parser, ReturnValue, Param, NumArgs); -} - -/* list of all library functions and their prototypes */ -struct LibraryFunction PlatformLibrary[] = -{ - { Csignal, "int signal();" }, - { Csignal1, "int signal1();" }, - { Cinput, "int input();" }, - { Cinput1, "int input1();" }, - { Cinit_uart1, "void init_uart1(int);" }, - { Cread_int, "int read_int();" }, - { Cread_str, "int read_str(char *);" }, - { Coutput, "void output(int);" }, - { Coutput1, "void output1(int);" }, - { Cdelay, "void delay(int);" }, - { Crand, "int rand(int);" }, - { Ctime, "int time();" }, - { Ciodir, "void iodir(int);" }, - { Cioread, "int ioread();" }, - { Ciowrite, "void iowrite(int);" }, - { Cpeek, "int peek(int, int);" }, - { Cpoke, "void poke(int, int, int);" }, - { Cmotors, "void motors(int, int);" }, - { Cmotors2, "void motors2(int, int);" }, - { Cmotorx, "void motorx(int, int);" }, - { Cservos, "void servos(int, int);" }, - { Cservos2, "void servos2(int, int);" }, - { Cencoders, "void encoders();" }, - { Cencoderx, "int encoderx(int);" }, - { Claser, "void laser(int);" }, - { Csonar, "int sonar(int);" }, - { Crange, "int range();" }, - { Cbattery, "int battery();" }, - { Cvcolor, "void vcolor(int, int, int, int, int, int, int);" }, - { Cvfind, "int vfind(int, int, int, int, int);" }, - { Cvcam, "void vcam(int);" }, - { Cvcap, "void vcap();" }, - { Cvrcap, "void vrcap();" }, - { Cvdiff, "void vdiff(int);" }, - { Cvpix, "void vpix(int, int);" }, - { Cvscan, "int vscan(int, int);" }, - { Cvmean, "void vmean();" }, - { Cvblob, "int vblob(int, int);" }, - { Cvjpeg, "int vjpeg(int);" }, - { Cvsend, "void vsend(int);" }, - { Ccompass, "int compass();" }, - { Ccompassx, "int compassx();" }, - { Ccompassxcal, "void compassxcal(int, int, int, int, int);" }, - { Canalog, "int analog(int);" }, - { Canalogx, "int analogx(int);" }, - { Ctilt, "int tilt(int);" }, - { Cgps, "void gps();" }, - { Creadi2c, "int readi2c(int, int);" }, - { Creadi2c2, "int readi2c2(int, int);" }, - { Cwritei2c, "void writei2c(int, int, int);" }, - { Cabs, "int abs(int);" }, - { Csin, "int sin(int);" }, - { Ccos, "int cos(int);" }, - { Ctan, "int tan(int);" }, - { Casin, "int asin(int, int);" }, - { Cacos, "int acos(int, int);" }, - { Catan, "int atan(int, int);" }, - { Cgps_head, "int gps_head(int, int, int, int);" }, - { Cgps_dist, "int gps_dist(int, int, int, int);" }, - { Csqrt, "int sqrt(int);" }, - { Cnnshow, "void nnshow(int);" }, - { Cnnset, "void nnset(int, int, int, int, int, int, int, int, int);" }, - { Cnninit, "void nninit();" }, - { Cnntrain, "void nntrain();" }, - { Cnntest, "int nntest(int, int, int, int, int, int, int, int);" }, - { Cnnmatchblob, "int nnmatchblob(int);" }, - { Cnnlearnblob, "void nnlearnblob(int);" }, - { Cautorun, "void autorun(int);" }, - { Clineno, "int lineno();" }, - { Cerrormsg, "void errormsg(char *);" }, - { NULL, NULL } -}; - diff --git a/eci/platform/library_unix.c b/eci/platform/library_unix.c deleted file mode 100644 index 56a3aa7..0000000 --- a/eci/platform/library_unix.c +++ /dev/null @@ -1,33 +0,0 @@ -/** - * @author Edouard DUPIN - * - * @copyright 2014, Edouard DUPIN, all right reserved - * - * @license APACHE-2 (see license file) - */ - -#include "../interpreter.h" - -void UnixSetupFunc() { - -} - -void Ctest (struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) { - printf("test(%d)\n", Param[0]->Val->Integer); - Param[0]->Val->Integer = 1234; -} - -void Clineno (struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) { - ReturnValue->Val->Integer = Parser->Line; -} - -/* list of all library functions and their prototypes */ -struct LibraryFunction UnixFunctions[] = { - { Ctest, "void test(int);" }, - { Clineno, "int lineno();" }, - { NULL, NULL } -}; - -void PlatformLibraryInit() { - IncludeRegister("picoc_unix.h", &UnixSetupFunc, &UnixFunctions[0], NULL); -} diff --git a/eci/platform/platform_ffox.c b/eci/platform/platform_ffox.c deleted file mode 100644 index ea7bd7e..0000000 --- a/eci/platform/platform_ffox.c +++ /dev/null @@ -1,51 +0,0 @@ -#include "../interpreter.h" - -/* deallocate any storage */ -void PlatformCleanup() -{ -} - -/* get a line of interactive input */ -char *PlatformGetLine(char *Buf, int MaxLen) -{ - // XXX - unimplemented so far - return NULL; -} - -/* get a character of interactive input */ -int PlatformGetCharacter() -{ - // XXX - unimplemented so far - return 0; -} - -/* write a character to the console */ -void PlatformPutc(unsigned char OutCh, union OutputStreamInfo *Stream) -{ - // XXX - unimplemented so far -} - -/* read a file into memory */ -char *PlatformReadFile(const char *FileName) -{ - // XXX - unimplemented so far - return NULL; -} - -/* read and scan a file for definitions */ -void PlatformScanFile(const char *FileName) -{ - char *SourceStr = PlatformReadFile(FileName); - Parse(FileName, SourceStr, strlen(SourceStr), TRUE); - //free(SourceStr); -} - -/* mark where to end the program for platforms which require this */ -jmp_buf ExitBuf; - -/* exit the program */ -void PlatformExit() -{ - longjmp(ExitBuf, 1); -} - diff --git a/eci/platform/platform_surveyor.c b/eci/platform/platform_surveyor.c deleted file mode 100644 index 1557747..0000000 --- a/eci/platform/platform_surveyor.c +++ /dev/null @@ -1,71 +0,0 @@ -#include "../interpreter.h" -#include "../picoc.h" - -/* mark where to end the program for platforms which require this */ -int PicocExitBuf[41]; - -/* deallocate any storage */ -void PlatformCleanup() -{ -} - -/* get a line of interactive input */ -char *PlatformGetLine(char *Buf, int MaxLen, const char *Prompt) -{ - int ix; - char ch, *cp; - - printf(Prompt); - - ix = 0; - cp = 0; - - // If the first character is \n or \r, eat it - ch = getch(); - if (ch == '\n' || ch == '\r') - { - // And get the next character - ch = getch(); - } - - while (ix++ < MaxLen) { - - if (ch == 0x1B || ch == 0x03) { // ESC character or ctrl-c (to avoid problem with TeraTerm) - exit - printf("Leaving PicoC\n"); - return NULL; - } - if (ch == '\n') { - *cp++ = '\n'; // if newline, send newline character followed by null - *cp = 0; - return Buf; - } - *cp++ = ch; - ix++; - ch = getch(); - } - return NULL; -} - -/* write a character to the console */ -void PlatformPutc(unsigned char OutCh, union OutputStreamInfo *Stream) -{ - if (OutCh == '\n') - putchar('\r'); - - putchar(OutCh); -} - -/* read a character */ -int PlatformGetCharacter() -{ - return getch(); -} - -/* exit the program */ -void PlatformExit(int RetVal) -{ - PicocExitValue = RetVal; - PicocExitBuf[40] = 1; - longjmp(PicocExitBuf, 1); -} - diff --git a/eci/platform/platform_unix.c b/eci/platform/platform_unix.c deleted file mode 100644 index 932d2b4..0000000 --- a/eci/platform/platform_unix.c +++ /dev/null @@ -1,75 +0,0 @@ -/** - * @author Edouard DUPIN - * - * @copyright 2014, Edouard DUPIN, all right reserved - * - * @license APACHE-2 (see license file) - */ - -#include "../picoc.h" -#include "../interpreter.h" - -/* mark where to end the program for platforms which require this */ -jmp_buf PicocExitBuf; - -void PlatformCleanup() { - -} - -/* get a line of interactive input */ -char *PlatformGetLine(char *Buf, int MaxLen, const char *Prompt) { - if (Prompt != NULL) { - printf("%s", Prompt); - } - fflush(stdout); - return fgets(Buf, MaxLen, stdin); -} - -/* get a character of interactive input */ -int PlatformGetCharacter() { - fflush(stdout); - return getchar(); -} - -/* write a character to the console */ -void PlatformPutc(unsigned char OutCh, union OutputStreamInfo *Stream) { - putchar(OutCh); -} - -/* read a file into memory */ -char *PlatformReadFile(const char *FileName) { - struct stat FileInfo; - char *ReadText; - FILE *InFile; - int BytesRead; - if (stat(FileName, &FileInfo)) { - ProgramFail(NULL, "can't read file %s\n", FileName); - } - ReadText = malloc(FileInfo.st_size + 1); - if (ReadText == NULL) { - ProgramFail(NULL, "out of memory\n"); - } - InFile = fopen(FileName, "r"); - if (InFile == NULL) { - ProgramFail(NULL, "can't read file %s\n", FileName); - } - BytesRead = fread(ReadText, 1, FileInfo.st_size, InFile); - if (BytesRead == 0) { - ProgramFail(NULL, "can't read file %s\n", FileName); - } - ReadText[BytesRead] = '\0'; - fclose(InFile); - return ReadText; -} - -/* read and scan a file for definitions */ -void PicocPlatformScanFile(const char *FileName) { - char *SourceStr = PlatformReadFile(FileName); - PicocParse(FileName, SourceStr, strlen(SourceStr), TRUE, FALSE, TRUE); -} - -/* exit the program */ -void PlatformExit(int RetVal) { - PicocExitValue = RetVal; - longjmp(PicocExitBuf, 1); -} diff --git a/eci/table.c b/eci/table.c deleted file mode 100644 index f8559a1..0000000 --- a/eci/table.c +++ /dev/null @@ -1,164 +0,0 @@ -/** - * @author Edouard DUPIN - * - * @copyright 2014, Edouard DUPIN, all right reserved - * - * @license APACHE-2 (see license file) - */ - -#include "interpreter.h" - -struct Table StringTable; -struct TableEntry *StringHashTable[STRING_TABLE_SIZE]; -char *StrEmpty = NULL; - -/* initialise the shared string system */ -void TableInit() { - TableInitTable(&StringTable, &StringHashTable[0], STRING_TABLE_SIZE, TRUE); - StrEmpty = TableStrRegister(""); -} - -/* hash function for strings */ -static unsigned int TableHash(const char *Key, int Len) { - unsigned int Hash = Len; - int Offset; - int Count; - for (Count = 0, Offset = 8; Count < Len; Count++, Offset+=7) { - if (Offset > sizeof(unsigned int) * 8 - 7) { - Offset -= sizeof(unsigned int) * 8 - 6; - } - Hash ^= *Key++ << Offset; - } - return Hash; -} - -/* initialise a table */ -void TableInitTable(struct Table *Tbl, struct TableEntry **HashTable, int Size, int OnHeap) { - Tbl->Size = Size; - Tbl->OnHeap = OnHeap; - Tbl->HashTable = HashTable; - memset((void *)HashTable, '\0', sizeof(struct TableEntry *) * Size); -} - -/* check a hash table entry for a key */ -static struct TableEntry *TableSearch(struct Table *Tbl, const char *Key, int *AddAt) { - struct TableEntry *Entry; - int HashValue = ((unsigned long)Key) % Tbl->Size; /* shared strings have unique addresses so we don't need to hash them */ - for (Entry = Tbl->HashTable[HashValue]; Entry != NULL; Entry = Entry->Next) { - if (Entry->p.v.Key == Key) { - return Entry; /* found */ - } - } - *AddAt = HashValue; /* didn't find it in the chain */ - return NULL; -} - -/* set an identifier to a value. returns FALSE if it already exists. - * Key must be a shared string from TableStrRegister() */ -int TableSet(struct Table *Tbl, char *Key, struct Value *Val, const char *DeclFileName, int DeclLine, int DeclColumn) { - int AddAt; - struct TableEntry *FoundEntry = TableSearch(Tbl, Key, &AddAt); - if (FoundEntry == NULL) { - /* add it to the table */ - struct TableEntry *NewEntry = VariableAlloc(NULL, sizeof(struct TableEntry), Tbl->OnHeap); - NewEntry->DeclFileName = DeclFileName; - NewEntry->DeclLine = DeclLine; - NewEntry->DeclColumn = DeclColumn; - NewEntry->p.v.Key = Key; - NewEntry->p.v.Val = Val; - NewEntry->Next = Tbl->HashTable[AddAt]; - Tbl->HashTable[AddAt] = NewEntry; - return TRUE; - } - return FALSE; -} - -/* find a value in a table. returns FALSE if not found. - * Key must be a shared string from TableStrRegister() */ -int TableGet(struct Table *Tbl, const char *Key, struct Value **Val, const char **DeclFileName, int *DeclLine, int *DeclColumn) { - int AddAt; - struct TableEntry *FoundEntry = TableSearch(Tbl, Key, &AddAt); - if (FoundEntry == NULL) { - return FALSE; - } - *Val = FoundEntry->p.v.Val; - if (DeclFileName != NULL) { - *DeclFileName = FoundEntry->DeclFileName; - *DeclLine = FoundEntry->DeclLine; - *DeclColumn = FoundEntry->DeclColumn; - } - return TRUE; -} - -/* remove an entry from the table */ -struct Value *TableDelete(struct Table *Tbl, const char *Key) { - struct TableEntry **EntryPtr; - int HashValue = ((unsigned long)Key) % Tbl->Size; /* shared strings have unique addresses so we don't need to hash them */ - for (EntryPtr = &Tbl->HashTable[HashValue]; *EntryPtr != NULL; EntryPtr = &(*EntryPtr)->Next) { - if ((*EntryPtr)->p.v.Key == Key) { - struct TableEntry *DeleteEntry = *EntryPtr; - struct Value *Val = DeleteEntry->p.v.Val; - *EntryPtr = DeleteEntry->Next; - HeapFreeMem(DeleteEntry); - return Val; - } - } - return NULL; -} - -/* check a hash table entry for an identifier */ -static struct TableEntry *TableSearchIdentifier(struct Table *Tbl, const char *Key, int Len, int *AddAt) { - struct TableEntry *Entry; - int HashValue = TableHash(Key, Len) % Tbl->Size; - for (Entry = Tbl->HashTable[HashValue]; Entry != NULL; Entry = Entry->Next) { - if (strncmp(&Entry->p.Key[0], (char *)Key, Len) == 0 && Entry->p.Key[Len] == '\0') { - // found - return Entry; - } - } - *AddAt = HashValue; /* didn't find it in the chain */ - return NULL; -} - -/* set an identifier and return the identifier. share if possible */ -char *TableSetIdentifier(struct Table *Tbl, const char *Ident, int IdentLen) { - int AddAt; - struct TableEntry *FoundEntry = TableSearchIdentifier(Tbl, Ident, IdentLen, &AddAt); - if (FoundEntry != NULL) { - return &FoundEntry->p.Key[0]; - } else { - //add it to the table - we economise by not allocating the whole structure here - struct TableEntry *NewEntry = HeapAllocMem(sizeof(struct TableEntry) - sizeof(union TableEntryPayload) + IdentLen + 1); - if (NewEntry == NULL) { - ProgramFail(NULL, "out of memory"); - } - strncpy((char *)&NewEntry->p.Key[0], (char *)Ident, IdentLen); - NewEntry->p.Key[IdentLen] = '\0'; - NewEntry->Next = Tbl->HashTable[AddAt]; - Tbl->HashTable[AddAt] = NewEntry; - return &NewEntry->p.Key[0]; - } - return NULL; -} - -/* register a string in the shared string store */ -char *TableStrRegister2(const char *Str, int Len) { - return TableSetIdentifier(&StringTable, Str, Len); -} - -char *TableStrRegister(const char *Str) { - return TableStrRegister2(Str, strlen((char *)Str)); -} - -/* free all the strings */ -void TableStrFree() { - struct TableEntry *Entry; - struct TableEntry *NextEntry; - int Count; - for (Count = 0; Count < StringTable.Size; Count++) { - for (Entry = StringTable.HashTable[Count]; Entry != NULL; Entry = NextEntry) { - NextEntry = Entry->Next; - HeapFreeMem(Entry); - } - } -} diff --git a/eci/table.h b/eci/table.h deleted file mode 100644 index a00e11d..0000000 --- a/eci/table.h +++ /dev/null @@ -1,23 +0,0 @@ -/** - * @author Edouard DUPIN - * - * @copyright 2014, Edouard DUPIN, all right reserved - * - * @license APACHE-2 (see license file) - */ - -#ifndef __ECI_TABLE_H__ -#define __ECI_TABLE_H__ - - -void TableInit(); -char *TableStrRegister(const char *_str); -char *TableStrRegister2(const char *_str, int Len); -void TableInitTable(struct Table *_table, struct TableEntry **_hashTable, int _size, int _onHeap); -int TableSet(struct Table *_tbl, char *_key, struct Value *_val, const char *_declFileName, int _declLine, int _declColumn); -int TableGet(struct Table *_tbl, const char *_key, struct Value **_val, const char **_declFileName, int *_declLine, int *_declColumn); -struct Value *TableDelete(struct Table *_tbl, const char *_key); -char *TableSetIdentifier(struct Table *_tbl, const char *_ident, int _identLen); -void TableStrFree(); - -#endif diff --git a/eci/type.c b/eci/type.c deleted file mode 100644 index 5144343..0000000 --- a/eci/type.c +++ /dev/null @@ -1,519 +0,0 @@ -/** - * @author Edouard DUPIN - * - * @copyright 2014, Edouard DUPIN, all right reserved - * - * @license APACHE-2 (see license file) - */ - -#include "interpreter.h" - -/* some basic types */ -struct ValueType UberType; -struct ValueType IntType; -struct ValueType ShortType; -struct ValueType CharType; -struct ValueType LongType; -struct ValueType UnsignedIntType; -struct ValueType UnsignedShortType; -struct ValueType UnsignedLongType; -struct ValueType FPType; -struct ValueType VoidType; -struct ValueType TypeType; -struct ValueType FunctionType; -struct ValueType MacroType; -struct ValueType EnumType; -struct ValueType GotoLabelType; -struct ValueType *CharPtrType; -struct ValueType *CharPtrPtrType; -struct ValueType *CharArrayType; -struct ValueType *VoidPtrType; - -static int PointerAlignBytes; -static int IntAlignBytes; - -/* add a new type to the set of types we know about */ -struct ValueType *TypeAdd(struct ParseState *_parser, struct ValueType *ParentType, enum BaseType Base, int ArraySize, const char *Identifier, int Sizeof, int AlignBytes) { - struct ValueType *NewType = VariableAlloc(_parser, sizeof(struct ValueType), TRUE); - NewType->Base = Base; - NewType->ArraySize = ArraySize; - NewType->Sizeof = Sizeof; - NewType->AlignBytes = AlignBytes; - NewType->Identifier = Identifier; - NewType->Members = NULL; - NewType->FromType = ParentType; - NewType->DerivedTypeList = NULL; - NewType->OnHeap = TRUE; - NewType->Next = ParentType->DerivedTypeList; - ParentType->DerivedTypeList = NewType; - return NewType; -} - -/* given a parent type, get a matching derived type and make one if necessary. - * Identifier should be registered with the shared string table. */ -struct ValueType *TypeGetMatching(struct ParseState *_parser, struct ValueType *ParentType, enum BaseType Base, int ArraySize, const char *Identifier, int AllowDuplicates) { - int Sizeof; - int AlignBytes; - struct ValueType *ThisType = ParentType->DerivedTypeList; - while ( ThisType != NULL - && ( ThisType->Base != Base - || ThisType->ArraySize != ArraySize - || ThisType->Identifier != Identifier) ) { - ThisType = ThisType->Next; - } - if (ThisType != NULL) { - if (AllowDuplicates) { - return ThisType; - } else { - ProgramFail(_parser, "data type '%s' is already defined", Identifier); - } - } - switch (Base) { - case TypePointer: - Sizeof = sizeof(void *); - AlignBytes = PointerAlignBytes; - break; - case TypeArray: - Sizeof = ArraySize * ParentType->Sizeof; - AlignBytes = ParentType->AlignBytes; - break; - case TypeEnum: - Sizeof = sizeof(int); - AlignBytes = IntAlignBytes; - break; - default: - Sizeof = 0; - AlignBytes = 0; - break; - /* structs and unions will get bigger when we add members to them */ - } - return TypeAdd(_parser, ParentType, Base, ArraySize, Identifier, Sizeof, AlignBytes); -} - -/* stack space used by a value */ -int TypeStackSizeValue(struct Value *Val) { - if (Val != NULL && Val->ValOnStack) { - return TypeSizeValue(Val, FALSE); - } else { - return 0; - } -} - -/* memory used by a value */ -int TypeSizeValue(struct Value *Val, int Compact) { - if (IS_INTEGER_NUMERIC(Val) && !Compact) { - return sizeof(ALIGN_TYPE); /* allow some extra room for type extension */ - } else if (Val->Typ->Base != TypeArray) { - return Val->Typ->Sizeof; - } else { - return Val->Typ->FromType->Sizeof * Val->Typ->ArraySize; - } -} - -/* memory used by a variable given its type and array size */ -int TypeSize(struct ValueType *Typ, int ArraySize, int Compact) { - if (IS_INTEGER_NUMERIC_TYPE(Typ) && !Compact) { - return sizeof(ALIGN_TYPE); /* allow some extra room for type extension */ - } else if (Typ->Base != TypeArray) { - return Typ->Sizeof; - } else { - return Typ->FromType->Sizeof * ArraySize; - } -} - -/* add a base type */ -void TypeAddBaseType(struct ValueType *TypeNode, enum BaseType Base, int Sizeof, int AlignBytes) { - TypeNode->Base = Base; - TypeNode->ArraySize = 0; - TypeNode->Sizeof = Sizeof; - TypeNode->AlignBytes = AlignBytes; - TypeNode->Identifier = StrEmpty; - TypeNode->Members = NULL; - TypeNode->FromType = NULL; - TypeNode->DerivedTypeList = NULL; - TypeNode->OnHeap = FALSE; - TypeNode->Next = UberType.DerivedTypeList; - UberType.DerivedTypeList = TypeNode; -} - -/* initialise the type system */ -void TypeInit() { - struct IntAlign { - char x; - int y; - } ia; - struct ShortAlign { - char x; - short y; - } sa; - struct CharAlign { - char x; - char y; - } ca; - struct LongAlign { - char x; - long y; - } la; - struct DoubleAlign { - char x; - double y; - } da; - struct PointerAlign { - char x; - void *y; - } pa; - - IntAlignBytes = (char *)&ia.y - &ia.x; - PointerAlignBytes = (char *)&pa.y - &pa.x; - - UberType.DerivedTypeList = NULL; - TypeAddBaseType(&IntType, TypeInt, sizeof(int), IntAlignBytes); - TypeAddBaseType(&ShortType, TypeShort, sizeof(short), (char *)&sa.y - &sa.x); - TypeAddBaseType(&CharType, TypeChar, sizeof(unsigned char), (char *)&ca.y - &ca.x); - TypeAddBaseType(&LongType, TypeLong, sizeof(long), (char *)&la.y - &la.x); - TypeAddBaseType(&UnsignedIntType, TypeUnsignedInt, sizeof(unsigned int), IntAlignBytes); - TypeAddBaseType(&UnsignedShortType, TypeUnsignedShort, sizeof(unsigned short), (char *)&sa.y - &sa.x); - TypeAddBaseType(&UnsignedLongType, TypeUnsignedLong, sizeof(unsigned long), (char *)&la.y - &la.x); - TypeAddBaseType(&VoidType, TypeVoid, 0, 1); - TypeAddBaseType(&FunctionType, TypeFunction, sizeof(int), IntAlignBytes); - TypeAddBaseType(&MacroType, TypeMacro, sizeof(int), IntAlignBytes); - TypeAddBaseType(&GotoLabelType, TypeGotoLabel, 0, 1); - TypeAddBaseType(&FPType, TypeFP, sizeof(double), (char *)&da.y - &da.x); - TypeAddBaseType(&TypeType, Type_Type, sizeof(double), (char *)&da.y - &da.x); /* must be large enough to cast to a double */ - CharArrayType = TypeAdd(NULL, &CharType, TypeArray, 0, StrEmpty, sizeof(char), (char *)&ca.y - &ca.x); - CharPtrType = TypeAdd(NULL, &CharType, TypePointer, 0, StrEmpty, sizeof(void *), PointerAlignBytes); - CharPtrPtrType = TypeAdd(NULL, CharPtrType, TypePointer, 0, StrEmpty, sizeof(void *), PointerAlignBytes); - VoidPtrType = TypeAdd(NULL, &VoidType, TypePointer, 0, StrEmpty, sizeof(void *), PointerAlignBytes); -} - -/* deallocate heap-allocated types */ -void TypeCleanupNode(struct ValueType *Typ) { - struct ValueType *SubType; - struct ValueType *NextSubType; - /* clean up and free all the sub-nodes */ - for (SubType = Typ->DerivedTypeList; SubType != NULL; SubType = NextSubType) { - NextSubType = SubType->Next; - TypeCleanupNode(SubType); - if (SubType->OnHeap) { - /* if it's a struct or union deallocate all the member values */ - if (SubType->Members != NULL) { - VariableTableCleanup(SubType->Members); - HeapFreeMem(SubType->Members); - } - /* free this node */ - HeapFreeMem(SubType); - } - } -} - -void TypeCleanup() { - TypeCleanupNode(&UberType); -} - -/* parse a struct or union declaration */ -void TypeParseStruct(struct ParseState *_parser, struct ValueType **Typ, int IsStruct) { - struct Value *LexValue; - struct ValueType *MemberType; - char *MemberIdentifier; - char *StructIdentifier; - struct Value *MemberValue; - enum LexToken Token; - int AlignBoundary; - Token = LexGetToken(_parser, &LexValue, FALSE); - if (Token == TokenIdentifier) { - LexGetToken(_parser, &LexValue, TRUE); - StructIdentifier = LexValue->Val->Identifier; - Token = LexGetToken(_parser, NULL, FALSE); - } else { - static char TempNameBuf[7] = "^s0000"; - StructIdentifier = PlatformMakeTempName(TempNameBuf); - } - *Typ = TypeGetMatching(_parser, &UberType, IsStruct ? TypeStruct : TypeUnion, 0, StructIdentifier, Token != TokenLeftBrace); - Token = LexGetToken(_parser, NULL, FALSE); - if (Token != TokenLeftBrace) { - /* use the already defined structure */ - if ((*Typ)->Members == NULL) { - ProgramFail(_parser, "structure '%s' isn't defined", LexValue->Val->Identifier); - } - return; - } - if (TopStackFrame != NULL) { - ProgramFail(_parser, "struct/union definitions can only be globals"); - } - LexGetToken(_parser, NULL, TRUE); - (*Typ)->Members = VariableAlloc(_parser, sizeof(struct Table) + STRUCT_TABLE_SIZE * sizeof(struct TableEntry), TRUE); - (*Typ)->Members->HashTable = (struct TableEntry **)((char *)(*Typ)->Members + sizeof(struct Table)); - TableInitTable((*Typ)->Members, (struct TableEntry **)((char *)(*Typ)->Members + sizeof(struct Table)), STRUCT_TABLE_SIZE, TRUE); - do { - TypeParse(_parser, &MemberType, &MemberIdentifier, NULL); - if (MemberType == NULL || MemberIdentifier == NULL) { - ProgramFail(_parser, "invalid type in struct"); - } - MemberValue = VariableAllocValueAndData(_parser, sizeof(int), FALSE, NULL, TRUE); - MemberValue->Typ = MemberType; - if (IsStruct) { - /* allocate this member's location in the struct */ - AlignBoundary = MemberValue->Typ->AlignBytes; - if (((*Typ)->Sizeof & (AlignBoundary-1)) != 0) { - (*Typ)->Sizeof += AlignBoundary - ((*Typ)->Sizeof & (AlignBoundary-1)); - } - MemberValue->Val->Integer = (*Typ)->Sizeof; - (*Typ)->Sizeof += TypeSizeValue(MemberValue, TRUE); - } else { - /* union members always start at 0, make sure it's big enough to hold the largest member */ - MemberValue->Val->Integer = 0; - if (MemberValue->Typ->Sizeof > (*Typ)->Sizeof) { - (*Typ)->Sizeof = TypeSizeValue(MemberValue, TRUE); - } - } - /* make sure to align to the size of the largest member's alignment */ - if ((*Typ)->AlignBytes < MemberValue->Typ->AlignBytes) { - (*Typ)->AlignBytes = MemberValue->Typ->AlignBytes; - } - /* define it */ - if (!TableSet((*Typ)->Members, MemberIdentifier, MemberValue, _parser->FileName, _parser->Line, _parser->CharacterPos)) { - ProgramFail(_parser, "member '%s' already defined", &MemberIdentifier); - } - if (LexGetToken(_parser, NULL, TRUE) != TokenSemicolon) { - ProgramFail(_parser, "semicolon expected"); - } - } while (LexGetToken(_parser, NULL, FALSE) != TokenRightBrace); - /* now align the structure to the size of its largest member's alignment */ - AlignBoundary = (*Typ)->AlignBytes; - if (((*Typ)->Sizeof & (AlignBoundary-1)) != 0) { - (*Typ)->Sizeof += AlignBoundary - ((*Typ)->Sizeof & (AlignBoundary-1)); - } - LexGetToken(_parser, NULL, TRUE); -} - -/* create a system struct which has no user-visible members */ -struct ValueType *TypeCreateOpaqueStruct(struct ParseState *_parser, const char *StructName, int Size) { - struct ValueType *Typ = TypeGetMatching(_parser, &UberType, TypeStruct, 0, StructName, FALSE); - /* create the (empty) table */ - Typ->Members = VariableAlloc(_parser, sizeof(struct Table) + STRUCT_TABLE_SIZE * sizeof(struct TableEntry), TRUE); - Typ->Members->HashTable = (struct TableEntry **)((char *)Typ->Members + sizeof(struct Table)); - TableInitTable(Typ->Members, (struct TableEntry **)((char *)Typ->Members + sizeof(struct Table)), STRUCT_TABLE_SIZE, TRUE); - Typ->Sizeof = Size; - return Typ; -} - -/* parse an enum declaration */ -void TypeParseEnum(struct ParseState *_parser, struct ValueType **Typ) { - struct Value *LexValue; - struct Value InitValue; - enum LexToken Token; - struct ValueType *EnumType; - int EnumValue = 0; - char *EnumIdentifier; - Token = LexGetToken(_parser, &LexValue, FALSE); - if (Token == TokenIdentifier) { - LexGetToken(_parser, &LexValue, TRUE); - EnumIdentifier = LexValue->Val->Identifier; - Token = LexGetToken(_parser, NULL, FALSE); - } else { - static char TempNameBuf[7] = "^e0000"; - EnumIdentifier = PlatformMakeTempName(TempNameBuf); - } - EnumType = TypeGetMatching(_parser, &UberType, TypeEnum, 0, EnumIdentifier, Token != TokenLeftBrace); - *Typ = &IntType; - if (Token != TokenLeftBrace) { - /* use the already defined enum */ - if ((*Typ)->Members == NULL) { - ProgramFail(_parser, "enum '%s' isn't defined", EnumIdentifier); - } - return; - } - if (TopStackFrame != NULL) { - ProgramFail(_parser, "enum definitions can only be globals"); - } - LexGetToken(_parser, NULL, TRUE); - (*Typ)->Members = &GlobalTable; - memset((void *)&InitValue, '\0', sizeof(struct Value)); - InitValue.Typ = &IntType; - InitValue.Val = (union AnyValue *)&EnumValue; - do { - if (LexGetToken(_parser, &LexValue, TRUE) != TokenIdentifier) { - ProgramFail(_parser, "identifier expected"); - } - EnumIdentifier = LexValue->Val->Identifier; - if (LexGetToken(_parser, NULL, FALSE) == TokenAssign) { - LexGetToken(_parser, NULL, TRUE); - EnumValue = ExpressionParseInt(_parser); - } - VariableDefine(_parser, EnumIdentifier, &InitValue, NULL, FALSE); - - Token = LexGetToken(_parser, NULL, TRUE); - if (Token != TokenComma && Token != TokenRightBrace) { - ProgramFail(_parser, "comma expected"); - } - EnumValue++; - } while (Token == TokenComma); -} - -/* parse a type - just the basic type */ -int TypeParseFront(struct ParseState *_parser, struct ValueType **Typ, int *IsStatic) { - struct ParseState Before; - struct Value *LexerValue; - enum LexToken Token; - int Unsigned = FALSE; - struct Value *VarValue; - int StaticQualifier = FALSE; - *Typ = NULL; - /* ignore leading type qualifiers */ - ParserCopy(&Before, _parser); - Token = LexGetToken(_parser, &LexerValue, TRUE); - while ( Token == TokenStaticType - || Token == TokenAutoType - || Token == TokenRegisterType - || Token == TokenExternType) { - if (Token == TokenStaticType) { - StaticQualifier = TRUE; - } - Token = LexGetToken(_parser, &LexerValue, TRUE); - } - if (IsStatic != NULL) { - *IsStatic = StaticQualifier; - } - /* handle signed/unsigned with no trailing type */ - if (Token == TokenSignedType || Token == TokenUnsignedType) { - enum LexToken FollowToken = LexGetToken(_parser, &LexerValue, FALSE); - Unsigned = (Token == TokenUnsignedType); - if ( FollowToken != TokenIntType - && FollowToken != TokenLongType - && FollowToken != TokenShortType - && FollowToken != TokenCharType) { - if (Token == TokenUnsignedType) { - *Typ = &UnsignedIntType; - } else { - *Typ = &IntType; - } - return TRUE; - } - Token = LexGetToken(_parser, &LexerValue, TRUE); - } - switch (Token) { - case TokenIntType: - *Typ = Unsigned ? &UnsignedIntType : &IntType; - break; - case TokenShortType: - *Typ = Unsigned ? &UnsignedShortType : &ShortType; - break; - case TokenCharType: - *Typ = &CharType; - break; - case TokenLongType: - *Typ = Unsigned ? &UnsignedLongType : &LongType; - break; - case TokenFloatType: - case TokenDoubleType: - *Typ = &FPType; - break; - case TokenVoidType: - *Typ = &VoidType; - break; - case TokenStructType: - case TokenUnionType: - if (*Typ != NULL) { - ProgramFail(_parser, "bad type declaration"); - } - TypeParseStruct(_parser, Typ, Token == TokenStructType); - break; - case TokenEnumType: - if (*Typ != NULL) { - ProgramFail(_parser, "bad type declaration"); - } - TypeParseEnum(_parser, Typ); - break; - case TokenIdentifier: - /* we already know it's a typedef-defined type because we got here */ - VariableGet(_parser, LexerValue->Val->Identifier, &VarValue); - *Typ = VarValue->Val->Typ; - break; - default: - ParserCopy(_parser, &Before); - return FALSE; - } - return TRUE; -} - -/* parse a type - the part at the end after the identifier. eg. array specifications etc. */ -struct ValueType *TypeParseBack(struct ParseState *_parser, struct ValueType *FromType) { - enum LexToken Token; - struct ParseState Before; - ParserCopy(&Before, _parser); - Token = LexGetToken(_parser, NULL, TRUE); - if (Token == TokenLeftSquareBracket) { - /* add another array bound */ - enum RunMode OldMode = _parser->Mode; - int ArraySize; - _parser->Mode = RunModeRun; - ArraySize = ExpressionParseInt(_parser); - _parser->Mode = OldMode; - if (LexGetToken(_parser, NULL, TRUE) != TokenRightSquareBracket) { - ProgramFail(_parser, "']' expected"); - } - return TypeGetMatching(_parser, TypeParseBack(_parser, FromType), TypeArray, ArraySize, StrEmpty, TRUE); - } else { - /* the type specification has finished */ - ParserCopy(_parser, &Before); - return FromType; - } -} - -/* parse a type - the part which is repeated with each identifier in a declaration list */ -void TypeParseIdentPart(struct ParseState *_parser, struct ValueType *BasicTyp, struct ValueType **Typ, char **Identifier) { - struct ParseState Before; - enum LexToken Token; - struct Value *LexValue; - int Done = FALSE; - *Typ = BasicTyp; - *Identifier = StrEmpty; - while (!Done) { - ParserCopy(&Before, _parser); - Token = LexGetToken(_parser, &LexValue, TRUE); - switch (Token) { - case TokenOpenBracket: - if (*Typ != NULL) { - ProgramFail(_parser, "bad type declaration"); - } - TypeParse(_parser, Typ, Identifier, NULL); - if (LexGetToken(_parser, NULL, TRUE) != TokenCloseBracket) { - ProgramFail(_parser, "')' expected"); - } - break; - case TokenAsterisk: - if (*Typ == NULL) { - ProgramFail(_parser, "bad type declaration"); - } - *Typ = TypeGetMatching(_parser, *Typ, TypePointer, 0, StrEmpty, TRUE); - break; - case TokenIdentifier: - if ( *Typ == NULL - || *Identifier != StrEmpty) { - ProgramFail(_parser, "bad type declaration"); - } - *Identifier = LexValue->Val->Identifier; - Done = TRUE; - break; - default: - ParserCopy(_parser, &Before); - Done = TRUE; - break; - } - } - if (*Typ == NULL) { - ProgramFail(_parser, "bad type declaration"); - } - if (*Identifier != StrEmpty) { - /* parse stuff after the identifier */ - *Typ = TypeParseBack(_parser, *Typ); - } -} - -/* parse a type - a complete declaration including identifier */ -void TypeParse(struct ParseState *_parser, struct ValueType **Typ, char **Identifier, int *IsStatic) { - struct ValueType *BasicType; - TypeParseFront(_parser, &BasicType, IsStatic); - TypeParseIdentPart(_parser, BasicType, Typ, Identifier); -} - diff --git a/eci/type.h b/eci/type.h deleted file mode 100644 index 3591bbc..0000000 --- a/eci/type.h +++ /dev/null @@ -1,24 +0,0 @@ -/** - * @author Edouard DUPIN - * - * @copyright 2014, Edouard DUPIN, all right reserved - * - * @license APACHE-2 (see license file) - */ - -#ifndef __ECI_TYPE_H__ -#define __ECI_TYPE_H__ - -void TypeInit(); -void TypeCleanup(); -int TypeSize(struct ValueType *_type, int _arraySize, int _compact); -int TypeSizeValue(struct Value *_value, int _compact); -int TypeStackSizeValue(struct Value *_value); -int TypeLastAccessibleOffset(struct Value *_value); -int TypeParseFront(struct ParseState *_parser, struct ValueType **_type, int *_isStatic); -void TypeParseIdentPart(struct ParseState *_parser, struct ValueType *_basicTyp, struct ValueType **_type, char **_identifier); -void TypeParse(struct ParseState *_parser, struct ValueType **_type, char **_identifier, int *_isStatic); -struct ValueType *TypeGetMatching(struct ParseState *_parser, struct ValueType *_parentType, enum BaseType _base, int _arraySize, const char *_identifier, int _allowDuplicates); -struct ValueType *TypeCreateOpaqueStruct(struct ParseState *_parser, const char *_structName, int _size); - -#endif diff --git a/eci/variable.c b/eci/variable.c deleted file mode 100644 index 2696ed1..0000000 --- a/eci/variable.c +++ /dev/null @@ -1,361 +0,0 @@ -/** - * @author Edouard DUPIN - * - * @copyright 2014, Edouard DUPIN, all right reserved - * - * @license APACHE-2 (see license file) - */ - -#include "interpreter.h" - -/* maximum size of a value to temporarily copy while we create a variable */ -#define MAX_TMP_COPY_BUF 256 - -/* the table of global definitions */ -struct Table GlobalTable; -struct TableEntry *GlobalHashTable[GLOBAL_TABLE_SIZE]; - -/* the table of string literal values */ -struct Table StringLiteralTable; -struct TableEntry *StringLiteralHashTable[STRING_LITERAL_TABLE_SIZE]; - -/* the stack */ -struct StackFrame *TopStackFrame = NULL; - - -/* initialise the variable system */ -void VariableInit() { - TableInitTable(&GlobalTable, &GlobalHashTable[0], GLOBAL_TABLE_SIZE, TRUE); - TableInitTable(&StringLiteralTable, &StringLiteralHashTable[0], STRING_LITERAL_TABLE_SIZE, TRUE); - TopStackFrame = NULL; -} - -/* deallocate the contents of a variable */ -void VariableFree(struct Value *_value) { - if (_value->ValOnHeap) { - /* free function bodies */ - if ( _value->Typ == &FunctionType - && _value->Val->FuncDef.Intrinsic == NULL - && _value->Val->FuncDef.Body.Pos != NULL) { - HeapFreeMem((void *)_value->Val->FuncDef.Body.Pos); - } - /* free macro bodies */ - if (_value->Typ == &MacroType) { - HeapFreeMem((void *)_value->Val->MacroDef.Body.Pos); - } - /* free the value */ - HeapFreeMem(_value); - } -} - -/* deallocate the global table and the string literal table */ -void VariableTableCleanup(struct Table *_hashTable) { - struct TableEntry *Entry; - struct TableEntry *NextEntry; - int Count; - for (Count = 0; Count < _hashTable->Size; ++Count) { - for (Entry = _hashTable->HashTable[Count]; Entry != NULL; Entry = NextEntry) { - NextEntry = Entry->Next; - VariableFree(Entry->p.v.Val); - /* free the hash table entry */ - HeapFreeMem(Entry); - } - } -} - -void VariableCleanup() { - VariableTableCleanup(&GlobalTable); - VariableTableCleanup(&StringLiteralTable); -} - -/* allocate some memory, either on the heap or the stack and check if we've run out */ -void *VariableAlloc(struct ParseState *_parser, - int _size, - int _onHeap) { - void *NewValue; - if (_onHeap) { - NewValue = HeapAllocMem(_size); - } else { - NewValue = HeapAllocStack(_size); - } - if (NewValue == NULL) { - ProgramFail(_parser, "out of memory"); - } -#ifdef DEBUG_HEAP - if (!_onHeap) { - printf("pushing %d at 0x%lx\n", _size, (unsigned long)NewValue); - } -#endif - return NewValue; -} - -/* allocate a value either on the heap or the stack using space dependent on what type we want */ -struct Value *VariableAllocValueAndData(struct ParseState *_parser, - int _dataSize, - int _isLValue, - struct Value *_lValueFrom, - int _onHeap) { - struct Value *NewValue = VariableAlloc(_parser, MEM_ALIGN(sizeof(struct Value)) + _dataSize, _onHeap); - NewValue->Val = (union AnyValue *)((char *)NewValue + MEM_ALIGN(sizeof(struct Value))); - NewValue->ValOnHeap = _onHeap; - NewValue->ValOnStack = !_onHeap; - NewValue->IsLValue = _isLValue; - NewValue->LValueFrom = _lValueFrom; - return NewValue; -} - -/* allocate a value given its type */ -struct Value *VariableAllocValueFromType(struct ParseState *_parser, - struct ValueType *_type, - int _isLValue, - struct Value *_lValueFrom, - int _onHeap) { - int Size = TypeSize(_type, _type->ArraySize, FALSE); - struct Value *NewValue = VariableAllocValueAndData(_parser, Size, _isLValue, _lValueFrom, _onHeap); - assert(Size > 0 || _type == &VoidType); - NewValue->Typ = _type; - return NewValue; -} - -/* allocate a value either on the heap or the stack and copy its value. handles overlapping data */ -struct Value *VariableAllocValueAndCopy(struct ParseState *_parser, - struct Value *_fromValue, - int _onHeap) { - struct ValueType *DType = _fromValue->Typ; - struct Value *NewValue; - char TmpBuf[MAX_TMP_COPY_BUF]; - int CopySize = TypeSizeValue(_fromValue, TRUE); - assert(CopySize <= MAX_TMP_COPY_BUF); - memcpy((void *)&TmpBuf[0], (void *)_fromValue->Val, CopySize); - NewValue = VariableAllocValueAndData(_parser, CopySize, _fromValue->IsLValue, _fromValue->LValueFrom, _onHeap); - NewValue->Typ = DType; - memcpy((void *)NewValue->Val, (void *)&TmpBuf[0], CopySize); - return NewValue; -} - -/* allocate a value either on the heap or the stack from an existing AnyValue and type */ -struct Value *VariableAllocValueFromExistingData(struct ParseState *_parser, - struct ValueType *_type, - union AnyValue *_fromValue, - int _isLValue, - struct Value *_lValueFrom) { - struct Value *NewValue = VariableAlloc(_parser, sizeof(struct Value), FALSE); - NewValue->Typ = _type; - NewValue->Val = _fromValue; - NewValue->ValOnHeap = FALSE; - NewValue->ValOnStack = FALSE; - NewValue->IsLValue = _isLValue; - NewValue->LValueFrom = _lValueFrom; - return NewValue; -} - -/* allocate a value either on the heap or the stack from an existing Value, sharing the value */ -struct Value *VariableAllocValueShared(struct ParseState *_parser, - struct Value *_fromValue) { - return VariableAllocValueFromExistingData(_parser, _fromValue->Typ, _fromValue->Val, _fromValue->IsLValue, _fromValue->IsLValue ? _fromValue : NULL); -} - -/* define a variable. Ident must be registered */ -struct Value *VariableDefine(struct ParseState *_parser, - char *_ident, - struct Value *_initValue, - struct ValueType *_type, - int _makeWritable) { - struct Value *AssignValue; - if (_initValue != NULL) { - AssignValue = VariableAllocValueAndCopy(_parser, _initValue, TopStackFrame == NULL); - } else { - AssignValue = VariableAllocValueFromType(_parser, _type, _makeWritable, NULL, TopStackFrame == NULL); - } - AssignValue->IsLValue = _makeWritable; - if (!TableSet((TopStackFrame == NULL) ? &GlobalTable : &TopStackFrame->LocalTable, _ident, AssignValue, _parser ? ((char *)_parser->FileName) : NULL, _parser ? _parser->Line : 0, _parser ? _parser->CharacterPos : 0)) { - ProgramFail(_parser, "'%s' is already defined", _ident); - } - return AssignValue; -} - -/* define a variable. Ident must be registered. If it's a redefinition from the same declaration don't throw an error */ -struct Value *VariableDefineButIgnoreIdentical(struct ParseState *_parser, - char *_ident, - struct ValueType *_type, - int _isStatic, - int *_firstVisit) { - struct Value *ExistingValue; - const char *DeclFileName; - int DeclLine; - int DeclColumn; - if (_isStatic) { - char MangledName[LINEBUFFER_MAX]; - char *MNPos = &MangledName[0]; - char *MNEnd = &MangledName[LINEBUFFER_MAX-1]; - const char *RegisteredMangledName; - /* make the mangled static name (avoiding using sprintf() to minimise library impact) */ - memset((void *)&MangledName, '\0', sizeof(MangledName)); - *MNPos++ = '/'; - strncpy(MNPos, (char *)_parser->FileName, MNEnd - MNPos); - MNPos += strlen(MNPos); - if (TopStackFrame != NULL) { - /* we're inside a function */ - if (MNEnd - MNPos > 0) { - *MNPos++ = '/'; - } - strncpy(MNPos, (char *)TopStackFrame->FuncName, MNEnd - MNPos); - MNPos += strlen(MNPos); - } - if (MNEnd - MNPos > 0) { - *MNPos++ = '/'; - } - strncpy(MNPos, _ident, MNEnd - MNPos); - RegisteredMangledName = TableStrRegister(MangledName); - /* is this static already defined? */ - if (!TableGet(&GlobalTable, RegisteredMangledName, &ExistingValue, &DeclFileName, &DeclLine, &DeclColumn)) { - /* define the mangled-named static variable store in the global scope */ - ExistingValue = VariableAllocValueFromType(_parser, _type, TRUE, NULL, TRUE); - TableSet(&GlobalTable, (char *)RegisteredMangledName, ExistingValue, (char *)_parser->FileName, _parser->Line, _parser->CharacterPos); - *_firstVisit = TRUE; - } - /* static variable exists in the global scope - now make a mirroring variable in our own scope with the short name */ - VariableDefinePlatformVar(_parser, _ident, ExistingValue->Typ, ExistingValue->Val, TRUE); - return ExistingValue; - } else { - if ( _parser->Line != 0 - && TableGet((TopStackFrame == NULL) ? &GlobalTable : &TopStackFrame->LocalTable, _ident, &ExistingValue, &DeclFileName, &DeclLine, &DeclColumn) - && DeclFileName == _parser->FileName - && DeclLine == _parser->Line - && DeclColumn == _parser->CharacterPos) { - return ExistingValue; - } else { - return VariableDefine(_parser, _ident, NULL, _type, TRUE); - } - } -} - -/* check if a variable with a given name is defined. Ident must be registered */ -int VariableDefined(const char *_ident) { - struct Value *FoundValue; - if ( TopStackFrame == NULL - || !TableGet(&TopStackFrame->LocalTable, _ident, &FoundValue, NULL, NULL, NULL)) { - if (!TableGet(&GlobalTable, _ident, &FoundValue, NULL, NULL, NULL)) { - return FALSE; - } - } - return TRUE; -} - -/* get the value of a variable. must be defined. Ident must be registered */ -void VariableGet(struct ParseState *_parser, - const char *_ident, - struct Value **_lValue) { - if ( TopStackFrame == NULL - || !TableGet(&TopStackFrame->LocalTable, _ident, _lValue, NULL, NULL, NULL)) { - if (!TableGet(&GlobalTable, _ident, _lValue, NULL, NULL, NULL)) { - ProgramFail(_parser, "'%s' is undefined", _ident); - } - } -} - -/* define a global variable shared with a platform global. Ident will be registered */ -void VariableDefinePlatformVar(struct ParseState *_parser, - char *_ident, - struct ValueType *_type, - union AnyValue *_fromValue, - int _isWritable) { - struct Value *SomeValue = VariableAllocValueAndData(NULL, 0, _isWritable, NULL, TRUE); - SomeValue->Typ = _type; - SomeValue->Val = _fromValue; - if (!TableSet((TopStackFrame == NULL) ? &GlobalTable : &TopStackFrame->LocalTable, TableStrRegister(_ident), SomeValue, _parser ? _parser->FileName : NULL, _parser ? _parser->Line : 0, _parser ? _parser->CharacterPos : 0)) { - ProgramFail(_parser, "'%s' is already defined", _ident); - } -} - -/* free and/or pop the top value off the stack. Var must be the top value on the stack! */ -void VariableStackPop(struct ParseState *_parser, - struct Value *_variable) { - int Success; -#ifdef DEBUG_HEAP - if (_variable->ValOnStack) { - printf("popping %ld at 0x%lx\n", (unsigned long)(sizeof(struct Value) + TypeSizeValue(_variable, FALSE)), (unsigned long)_variable); - } -#endif - if (_variable->ValOnHeap) { - if (_variable->Val != NULL) { - HeapFreeMem(_variable->Val); - } - Success = HeapPopStack(_variable, sizeof(struct Value)); - /* free from heap */ - } else if (_variable->ValOnStack) { - Success = HeapPopStack(_variable, sizeof(struct Value) + TypeSizeValue(_variable, FALSE)); /* free from stack */ - } else { - Success = HeapPopStack(_variable, sizeof(struct Value)); /* value isn't our problem */ - } - if (!Success) { - ProgramFail(_parser, "stack underrun"); - } -} - -/* add a stack frame when doing a function call */ -void VariableStackFrameAdd(struct ParseState *_parser, - const char *_functionName, - int _numberParameters) { - struct StackFrame *NewFrame; - HeapPushStackFrame(); - NewFrame = HeapAllocStack(sizeof(struct StackFrame) + sizeof(struct Value *) * _numberParameters); - if (NewFrame == NULL) { - ProgramFail(_parser, "out of memory"); - } - ParserCopy(&NewFrame->ReturnParser, _parser); - NewFrame->FuncName = _functionName; - NewFrame->Parameter = (_numberParameters > 0) ? ((void *)((char *)NewFrame + sizeof(struct StackFrame))) : NULL; - TableInitTable(&NewFrame->LocalTable, &NewFrame->LocalHashTable[0], LOCAL_TABLE_SIZE, FALSE); - NewFrame->PreviousStackFrame = TopStackFrame; - TopStackFrame = NewFrame; -} - -/* remove a stack frame */ -void VariableStackFramePop(struct ParseState *_parser) { - if (TopStackFrame == NULL) { - ProgramFail(_parser, "stack is empty - can't go back"); - } - ParserCopy(_parser, &TopStackFrame->ReturnParser); - TopStackFrame = TopStackFrame->PreviousStackFrame; - HeapPopStackFrame(); -} - -/* get a string literal. assumes that Ident is already registered. NULL if not found */ -struct Value *VariableStringLiteralGet(char *_ident) { - struct Value *LVal = NULL; - if (TableGet(&StringLiteralTable, _ident, &LVal, NULL, NULL, NULL)) { - return LVal; - } else { - return NULL; - } -} - -/* define a string literal. assumes that Ident is already registered */ -void VariableStringLiteralDefine(char *_ident, - struct Value *_value) { - TableSet(&StringLiteralTable, _ident, _value, NULL, 0, 0); -} - -/* check a pointer for validity and dereference it for use */ -void *VariableDereferencePointer(struct ParseState *_parser, - struct Value *_pointerValue, - struct Value **_dereferenceValue, - int *_dereferenceOffset, - struct ValueType **_dereferenceType, - int *_dereferenceIsLValue) { - if (_dereferenceValue != NULL) { - *_dereferenceValue = NULL; - } - if (_dereferenceType != NULL) { - *_dereferenceType = _pointerValue->Typ->FromType; - } - if (_dereferenceOffset != NULL) { - *_dereferenceOffset = 0; - } - if (_dereferenceIsLValue != NULL) { - *_dereferenceIsLValue = TRUE; - } - return _pointerValue->Val->Pointer; -} - diff --git a/eci/variable.h b/eci/variable.h deleted file mode 100644 index 497d12b..0000000 --- a/eci/variable.h +++ /dev/null @@ -1,35 +0,0 @@ -/** - * @author Edouard DUPIN - * - * @copyright 2014, Edouard DUPIN, all right reserved - * - * @license APACHE-2 (see license file) - */ - -#ifndef __ECI_VARIABLE_H__ -#define __ECI_VARIABLE_H__ - - -void VariableInit(); -void VariableCleanup(); -void VariableFree(struct Value* _value); -void VariableTableCleanup(struct Table* _hashTable); -void *VariableAlloc(struct ParseState* _parser, int _size, int _onHeap); -void VariableStackPop(struct ParseState *_parser, struct Value *_value); -struct Value *VariableAllocValueAndData(struct ParseState* _parser, int _dataSize, int _isLValue, struct Value *_lValueFrom, int _onHeap); -struct Value *VariableAllocValueAndCopy(struct ParseState* _parser, struct Value *_fromValue, int _onHeap); -struct Value *VariableAllocValueFromType(struct ParseState *_parser, struct ValueType *_type, int _isLValue, struct Value *_lValueFrom, int _onHeap); -struct Value *VariableAllocValueFromExistingData(struct ParseState *_parser, struct ValueType *_type, union AnyValue *_fromValue, int _isLValue, struct Value *_lValueFrom); -struct Value *VariableAllocValueShared(struct ParseState *_parser, struct Value *_fromValue); -struct Value *VariableDefine(struct ParseState *_parser, char *_ident, struct Value *_initValue, struct ValueType *_type, int _makeWritable); -struct Value *VariableDefineButIgnoreIdentical(struct ParseState *_parser, char *_ident, struct ValueType *_type, int _isStatic, int *_firstVisit); -int VariableDefined(const char *Ident); -void VariableGet(struct ParseState *_parser, const char *_ident, struct Value **_lVal); -void VariableDefinePlatformVar(struct ParseState *_parser, char *_ident, struct ValueType *_type, union AnyValue *_fromValue, int _isWritable); -void VariableStackFrameAdd(struct ParseState *_parser, const char *_funcName, int _numParams); -void VariableStackFramePop(struct ParseState *_parser); -struct Value *VariableStringLiteralGet(char *_ident); -void VariableStringLiteralDefine(char *_ident, struct Value *_value); -void *VariableDereferencePointer(struct ParseState *_parser, struct Value *_pointerValue, struct Value **_dereferenceVal, int *_dereferenceOffset, struct ValueType **_dereferenceType, int *_derefIsLValue); - -#endif diff --git a/lutin_eci.py b/lutin_eci.py deleted file mode 100644 index 0a78e84..0000000 --- a/lutin_eci.py +++ /dev/null @@ -1,43 +0,0 @@ -#!/usr/bin/python -import lutinModule as module -import lutinTools as tools -import os -import lutinMultiprocess - -def get_desc(): - return "Ewol C Interpreter" - -def create(target): - # module name is 'edn' and type binary. - myModule = module.Module(__file__, 'eci', 'BINARY') - # add extra compilation flags : - myModule.add_extra_compile_flags() - # add the file to compile: - myModule.add_src_file([ - 'eci/clibrary.c', - 'eci/expression.c', - 'eci/heap.c', - 'eci/include.c', - 'eci/lex.c', - 'eci/parse.c', - 'eci/picoc.c', - 'eci/platform.c', - 'eci/table.c', - 'eci/type.c', - 'eci/variable.c', - 'eci/platform/platform_unix.c', - 'eci/platform/library_unix.c', - 'eci/cstdlib/ctype.c', - 'eci/cstdlib/errno.c', - 'eci/cstdlib/math.c', - 'eci/cstdlib/stdbool.c', - 'eci/cstdlib/stdio.c', - 'eci/cstdlib/stdlib.c', - 'eci/cstdlib/string.c', - 'eci/cstdlib/time.c', - 'eci/cstdlib/unistd.c' - ]) - myModule.add_export_path(tools.get_current_path(__file__)) - # add the currrent module at the - return myModule - diff --git a/lutin_eci2.py b/lutin_eci2.py new file mode 100644 index 0000000..70831ff --- /dev/null +++ b/lutin_eci2.py @@ -0,0 +1,25 @@ +#!/usr/bin/python +import lutinModule as module +import lutinTools as tools +import os +import lutinMultiprocess + +def get_desc(): + return "Ewol C Interpreter" + +def create(target): + # module name is 'edn' and type binary. + myModule = module.Module(__file__, 'eci2', 'BINARY') + # add extra compilation flags : + myModule.add_extra_compile_flags() + # add the file to compile: + myModule.add_src_file([ + 'eci/eci.cpp', + 'eci/Lexer.cpp', + 'eci/debug.cpp', + 'eci/lang/ParserCpp.cpp' + ]) + myModule.add_export_path(tools.get_current_path(__file__)) + myModule.add_module_depend('etk') + return myModule +