[DEV] start a new project from scratch

This commit is contained in:
Edouard DUPIN 2014-07-17 21:42:05 +02:00
parent 209d18ed08
commit 9e770c657b
57 changed files with 245 additions and 10076 deletions

38
eci/Lexer.cpp Normal file
View File

@ -0,0 +1,38 @@
/**
* @author Edouard DUPIN
*
* @copyright 2014, Edouard DUPIN, all right reserved
*
* @license APACHE-2 (see license file)
*/
#include <eci/Lexer.h>
#include <eci/debug.h>
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;
}

33
eci/Lexer.h Normal file
View File

@ -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 <etk/types.h>
#include <etk/stdTools.h>
#include <regex>
#include <map>
#include <vector>
namespace eci {
using LexerResult = std::vector<std::pair<int32_t, std::string>>;
class Lexer {
private:
std::map<int32_t, std::regex> m_searchList;
public:
Lexer();
~Lexer();
void append(int32_t _tokenId, const std::string& _regularExpression);
LexerResult interprete(const std::string& _data);
};
}
#endif

View File

@ -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;
}
}

View File

@ -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

View File

@ -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 <ctype.h>
#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 */

View File

@ -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

View File

@ -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 <errno.h>
#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 */

View File

@ -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 */

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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 <errno.h>
#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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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 */

View File

@ -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

View File

@ -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 <time.h>
#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

View File

@ -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

View File

@ -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 <stdio.h>
#include <unistd.h>
#include <limits.h>
#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 */

View File

@ -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

14
eci/debug.cpp Normal file
View File

@ -0,0 +1,14 @@
/**
* @author Edouard DUPIN
*
* @copyright 2011, Edouard DUPIN, all right reserved
*
* @license APACHE-2 (see license file)
*/
#include <eci/debug.h>
int32_t eci::getLogId() {
static int32_t g_val = etk::log::registerInstance("eci");
return g_val;
}

52
eci/debug.h Normal file
View File

@ -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 <etk/log.h>
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

25
eci/eci.cpp Normal file
View File

@ -0,0 +1,25 @@
/**
* @author Edouard DUPIN
*
* @copyright 2014, Edouard DUPIN, all right reserved
*
* @license APACHE-2 (see license file)
*/
#include <eci/eci.h>
#include <eci/debug.h>
#include <eci/lang/ParserCpp.h>
#include <etk/os/FSNode.h>
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;
}

View File

@ -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

File diff suppressed because it is too large Load Diff

View File

@ -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

View File

@ -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);
}

View File

@ -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

View File

@ -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 */

View File

@ -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

View File

@ -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 <eci/lex.h>
#include <eci/parse.h>
#include <eci/expression.h>
#include <eci/heap.h>
#include <eci/table.h>
#include <eci/type.h>
#include <eci/variable.h>
#include <eci/include.h>
#include <eci/clibrary.h>
#include <eci/platform.h>
#include <eci/cstdlib/ctype.h>
#include <eci/cstdlib/errno.h>
#include <eci/cstdlib/math.h>
#include <eci/cstdlib/stdbool.h>
#include <eci/cstdlib/stdio.h>
#include <eci/cstdlib/stdlib.h>
#include <eci/cstdlib/string.h>
#include <eci/cstdlib/time.h>
#include <eci/cstdlib/unistd.h>
// 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

30
eci/lang/ParserCpp.cpp Normal file
View File

@ -0,0 +1,30 @@
/**
* @author Edouard DUPIN
*
* @copyright 2014, Edouard DUPIN, all right reserved
*
* @license APACHE-2 (see license file)
*/
#include <eci/lang/ParserCpp.h>
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;
}

26
eci/lang/ParserCpp.h Normal file
View File

@ -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 <eci/Lexer.h>
namespace eci {
class ParserCpp {
private:
eci::Lexer m_lexer;
eci::LexerResult m_result;
public:
ParserCpp();
~ParserCpp();
bool parse(const std::string& _data);
};
}
#endif

975
eci/lex.c
View File

@ -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;
}

View File

@ -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

View File

@ -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");
}

View File

@ -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

View File

@ -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 <stdlib.h>
#include <stdio.h>
#include <string.h>
#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 <csource1.c>... [- <arg1>...] : run a program (calls main() to start it)\n"
" picoc -s <csource1.c>... [- <arg1>...] : 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;
}

View File

@ -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 <setjmp.h>
/* 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

View File

@ -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);
}

View File

@ -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 <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <string.h>
#include <assert.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <stdarg.h>
#include <setjmp.h>
#include <math.h>
extern jmp_buf ExitBuf;
#endif

View File

@ -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);
}

View File

@ -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; ix<image_size; ix++)
putchar(*cp++);
led0_on();
}
void Ccompass(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) // return reading from HMC6352 I2C compass
{
unsigned char i2c_data[2];
unsigned int ix;
i2c_data[0] = 0x41; // read compass twice to clear last reading
i2cread(0x22, (unsigned char *)i2c_data, 2, SCCB_ON);
delayMS(20);
i2c_data[0] = 0x41;
i2cread(0x22, (unsigned char *)i2c_data, 2, SCCB_ON);
ix = ((unsigned int)(i2c_data[0] << 8) + i2c_data[1]) / 10;
ReturnValue->Val->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; ix<NUM_NPATTERNS; ix++) {
nnset_pattern(ix);
nncalculate_network();
for (i1=0; i1<NUM_OUTPUT; i1++)
printf(" %3d", N_OUT(i1)/10);
printf("\r\n");
}
}
void Cnntest(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) {
int ix, i1, i2, max;
unsigned char ch;
ix = 0;
for (i1=0; i1<8; i1++) {
ch = (unsigned char)Param[i1]->Val->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; i1<NUM_OUTPUT; i1++) {
NNVect[i1] = N_OUT(i1)/10;
if (max < NNVect[i1]) {
ix = i1;
max = NNVect[i1];
}
}
ReturnValue->Val->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; i1<NUM_OUTPUT; i1++) {
NNVect[i1] = N_OUT(i1)/10;
if (max < NNVect[i1]) {
ix = i1;
max = NNVect[i1];
}
}
ReturnValue->Val->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);
}

View File

@ -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; ix<image_size; ix++)
putchar(*cp++);
led0_on();
}
void Ccompass(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) // return reading from HMC6352 I2C compass
{
unsigned char i2c_data[2];
unsigned int ix;
i2c_data[0] = 0x41; // read compass twice to clear last reading
i2cread(0x22, (unsigned char *)i2c_data, 2, SCCB_ON);
delayMS(20);
i2c_data[0] = 0x41;
i2cread(0x22, (unsigned char *)i2c_data, 2, SCCB_ON);
ix = ((unsigned int)(i2c_data[0] << 8) + i2c_data[1]) / 10;
ReturnValue->Val->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; ix<NUM_NPATTERNS; ix++) {
nnset_pattern(ix);
nncalculate_network();
for (i1=0; i1<NUM_OUTPUT; i1++)
printf(" %3d", N_OUT(i1)/10);
printf("\r\n");
}
}
void Cnntest(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) {
int ix, i1, i2, max;
unsigned char ch;
ix = 0;
for (i1=0; i1<8; i1++) {
ch = (unsigned char)Param[i1]->Val->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; i1<NUM_OUTPUT; i1++) {
NNVect[i1] = N_OUT(i1)/10;
if (max < NNVect[i1]) {
ix = i1;
max = NNVect[i1];
}
}
ReturnValue->Val->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; i1<NUM_OUTPUT; i1++) {
NNVect[i1] = N_OUT(i1)/10;
if (max < NNVect[i1]) {
ix = i1;
max = NNVect[i1];
}
}
ReturnValue->Val->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 }
};

View File

@ -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);
}

View File

@ -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);
}

View File

@ -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);
}

View File

@ -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);
}

View File

@ -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);
}
}
}

View File

@ -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

View File

@ -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);
}

View File

@ -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

View File

@ -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;
}

View File

@ -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

View File

@ -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

25
lutin_eci2.py Normal file
View File

@ -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