⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ctalk.h

📁 C-Talk is interpreted scripting language with C-like syntax and dynamic type checking. Variables in
💻 H
字号:
#ifndef __CTALK_H__
#define __CTALK_H__

#include "stdtp.h"
#include <setjmp.h>

#ifdef __cplusplus
extern "C" { 
#endif

#ifdef _WIN32
#ifdef INSIDE_CTALK
#define DLL_ENTRY __declspec(dllexport)
#else 
#define DLL_ENTRY __declspec(dllimport) 
#endif
#else
#define DLL_ENTRY
#endif

enum CtkTypes {
    CTK_NULL, 
    CTK_INTEGER, 
    CTK_REAL, 
    CTK_PRIMITIVE, 
    CTK_RAW_POINTER,
    // object types
    CTK_STRING, 
    CTK_ARRAY, 
    CTK_FILE, 
    CTK_MUTEX, 
    CTK_THREAD, 
    CTK_FUNCTION, 
    CTK_FRAME,
    CTK_USER_TYPE
}; 
    
typedef long          ctk_integer;
typedef unsigned long ctk_unsigned_integer;
typedef double        ctk_real;

typedef struct CtkObject { 
    int type; 
    union { 
	ctk_integer ivalue;
	ctk_real    rvalue;
	char*       svalue;
	void*       ptr;
    } u;
} CtkObject;

#define TO_INTEGER(o) (((o).type == CTK_INTEGER) ? (o).u.ivalue : (ctk_integer)ctkThrowException("Integer value expected"))

#define TO_REAL(o) (((o).type == CTK_REAL) ? (o).u.rvalue : (ctk_real)ctkThrowException("Real value expected"))

#define TO_STRING(o) (((o).type == CTK_STRING) ? (o).u.svalue : (char*)ctkThrowException("String value expected"))

#define CONVERT(o, type) (((o).type == (type)) ? (o).u.ptr : (void*)ctkThrowException("Conversion failed"))

#define IS_NULL(o) ((o).type == CTK_NULL)

#define IS_INTEGER(o) ((o).type == CTK_INTEGER)

#define IS_REAL(o) ((o).type == CTK_REAL)

#define IS_STRING(o) ((o).type == CTK_STRING)

#define IS_TRUE(o) ((o).u.ivalue != 0)

#define IF_STRING(o) (((o).type == CTK_STRING) ? (o).u.svalue : "")

#define IS_EQUAL(o1, o2) ctkEqual(o1, o2)

#define MAKE_INTEGER(o, i) ((o).type = CTK_INTEGER, (o).u.ivalue = (i))
#define MAKE_REAL(o, r)    ((o).type = CTK_REAL, (o).u.rvalue = (r))
#define MAKE_STRING(o, s)  ((o).type = CTK_STRING, (o).u.svalue = (s))
#define MAKE_RAW_POINTER(o, p) ((o).type = CTK_RAW_POINTER, (o).u.ptr = (p))
#define MAKE_MUTEX(o, m) ((o).type = CTK_MUTEX, (o).u.ptr = (m))
#define MAKE_FRAME(o, p) ((o).type = CTK_FRAME, (o).u.ptr = (p))
#define MAKE_ARRAY(o, a) ((o).type = CTK_ARRAY, (o).u.ptr = (a))
#define MAKE_FUNCTION(o, p) ((o).type = CTK_FUNCTION, (o).u.ptr = (p))
#define MAKE_NULL(o) ((o).type = CTK_NULL, (o).u.ptr = NULL)
#define MAKE_THREAD(o, t) ((o).type = CTK_THREAD, (o).u.ptr = (t))
#define MAKE_FILE(o, f) ((o).type = CTK_FILE, (o).u.ptr = (f))
#define MAKE_PRIMITIVE(o, p) ((o).type = CTK_PRIMITIVE, (o).u.ptr = (void*)(p))

#define CHECK_ALLOC(p) if (p == NULL) ctkNotEnoughMemory()

#define ALLOCATE_STRING(o, s) ((o).type = CTK_STRING, strcpy(((o).u.svalue = (char*)ctkAllocateObject(strlen(s)+1, NULL)), (s)))
    
DLL_ENTRY extern CtkObject ctkNull;
DLL_ENTRY extern CtkObject ctkTrue;
DLL_ENTRY extern CtkObject ctkFalse;

typedef struct CtkNode { 
    int line;
} CtkNode;

struct CtkStmt;
struct CtkFrame;
struct CtkModule;
struct CtkPrimitive;

typedef CtkObject (*CtkPrimitiveFunc)(int nArgs, CtkObject* args);
typedef CtkObject (*CtkPrimitiveTrampoline)(struct CtkPrimitive* prim, int nArgs, CtkObject* args);
    
struct CtkPrimitive;
DLL_ENTRY void ctkAddPrimitive(struct CtkPrimitive* prim);
DLL_ENTRY CtkPrimitive* ctkGetPrimitive(char const* name);


#define CHECK_PRIMITIVE_N_ARGS(nPassed, nExpected) \
    if ((nPassed) != (nExpected)) ctkThrowException("Wrong number of primitive arguments")

#define CHECK_PRIMITIVE_ARGUMENT(arg, exp_type) \
    if ((arg).type != (exp_type)) ctkThrowException("Incompatible type of primitive parameter")

DLL_ENTRY CtkObject ctkDefaultPrimitiveTrampolile(CtkPrimitive* prim, int nArgs, CtkObject* args);
    

typedef struct CtkPrimitive { 
    char const*             name;
    CtkPrimitiveFunc        func;
    CtkPrimitiveTrampoline  trampoline;
    CtkPrimitive*           next;
    int                     overload;
#ifdef __cplusplus
    CtkPrimitive(char const* name, CtkPrimitiveFunc func, int overload=false, 
                 CtkPrimitiveTrampoline trampoline=&ctkDefaultPrimitiveTrampolile) { 
	this->name = name;
	this->func = func;
	this->overload = overload;
        this->trampoline = trampoline;
	ctkAddPrimitive(this);
    }
#endif
} CtkPrimitive;

typedef struct CtkFunction { 
    struct CtkStmt*     stmts;     
    struct CtkFrame*    exterior; 
    struct CtkFunction* next;
    int                 nestedLevel;
    int                 nParams;
    int                 nLocalVars; // including parameters
    char*               name;
    struct CtkModule*   module;
} CtkFunction;
    
typedef struct CtkMutex { 
#ifdef _WIN32
    CRITICAL_SECTION cs;
#else
    pthread_mutex_t mutex;
    pthread_t       owner;
    int             count;
#endif
    int             initialized;
} CtkMutex;

struct CtkThread;

DLL_ENTRY void ctkLockMutex(CtkMutex* mutex);
DLL_ENTRY void ctkUnlockMutex(CtkMutex* mutex);
DLL_ENTRY CtkMutex* ctkCreateMutex();
DLL_ENTRY void ctkInitializeThread(CtkThread* thread);
DLL_ENTRY void ctkDeleteMutex(CtkMutex* mutex);

#ifdef __cplusplus
class CtkCriticalSection { 
  public:
    CtkCriticalSection(CtkMutex* mutex) {
        this->mutex = mutex;
        ctkLockMutex(mutex);
    }
    ~CtkCriticalSection() { 
        ctkUnlockMutex(mutex);
    }
  private:
    CtkMutex* mutex;
};
#endif

typedef struct CtkHashEntry { 
    struct CtkHashEntry* next;
    unsigned             hashCode;
    CtkObject            key;
    CtkObject            value;
} CtkHashEntry;

typedef struct CtkArray { 
    int            nAllocated;
    int            nUsed;
    CtkHashEntry** entries;
} CtkArray;

DLL_ENTRY CtkArray* ctkCreateArray();
DLL_ENTRY CtkArray* ctkCloneArray(CtkArray* arr);
DLL_ENTRY void ctkPutArray(CtkArray* arr, CtkObject key, CtkObject value);
DLL_ENTRY int  ctkDelArray(CtkArray* arr, CtkObject key);
DLL_ENTRY void ctkAddArray(CtkArray* aDst, CtkArray* aSrc);
DLL_ENTRY void ctkSubArray(CtkArray* aDst, CtkArray* aSrc);
DLL_ENTRY CtkObject ctkGetArray(CtkArray* arr, CtkObject key);
DLL_ENTRY void ctkClearArray(CtkArray* arr);
DLL_ENTRY void ctkDeleteArray(CtkArray* arr);
DLL_ENTRY CtkArray* ctkGetCommandLineOptions();
DLL_ENTRY int  ctkEqual(CtkObject o1, CtkObject o2);
DLL_ENTRY char* ctkAllocateStringLiteral(char* str);
DLL_ENTRY void  ctkDeallocateStringLiteral(char* str);

typedef struct CtkQueueItem { 
    struct CtkQueueItem* next;
    CtkObject            value;
} CtkQueueItem;

typedef struct CtkQueue { 
    int           nItems;
    int           nBlocked;
#ifdef _WIN32
    CRITICAL_SECTION cs;
    HANDLE           event;
#else
    pthread_mutex_t  mutex;
    pthread_cond_t   cond;
#endif
    CtkQueueItem* firstItem;
    CtkQueueItem* lastItem;
} CtkQueue;

typedef void (*CtkThreadFunc)(CtkFrame* arg);
typedef void (*CtkFinalizer)(void*); 

typedef struct CtkAllocHeader {     
    struct CtkAllocHeader* next;
    CtkFinalizer           finalizer;
} CtkAllocHeader;

DLL_ENTRY void* ctkAllocateObject(size_t size, CtkFinalizer finalizer);

extern int ctkMaxStackSize;

typedef struct CtkThread { 
#ifdef _WIN32
    DWORD threadId;
#else
    pthread_t thread;
#endif
    CtkThread*       next;
    CtkQueue         queue;
    CtkThreadFunc    func;
    CtkAllocHeader*  mallocList;
    CtkAllocHeader** lastHeader;
    volatile int     memoryAccess;
    int              initialized;
    CtkObject*       stack;
    int              stackSize;
    volatile int     sp;
    void*            arg;
    CtkObject        exceptionObject;
    CtkObject        usedObject; // use it to protect object from GC
    void             (*markFunc)(CtkThread* thread);
    CtkFrame*        callStack;
    CtkFrame*        currFrame;
    CtkFrame*        exceptionTrace;
    jmp_buf*         catchCtx;
    int              ctkThreadId; 
} CtkThread;

#define CTK_MIN_STACK_SIZE 16*1024

DLL_ENTRY CtkThread* ctkCreateThread(CtkThreadFunc f, CtkFrame* arg, size_t stackSize);
DLL_ENTRY void       ctkRunThread(CtkFrame* arg);
DLL_ENTRY void       ctkDeleteThread(CtkThread* thr);
DLL_ENTRY CtkObject  ctkGetMessage(CtkThread* thr);
DLL_ENTRY void       ctkPutMessage(CtkThread* thr, CtkObject msg);
DLL_ENTRY int        ctkGetThreadQueueLength(CtkThread* thr);
DLL_ENTRY CtkThread* ctkGetCurrentThread();
DLL_ENTRY void       ctkSleep(unsigned seconds);
DLL_ENTRY long       ctkGetTimeMillis();

typedef struct CtkFrame { 
    struct CtkFrame* up;
    CtkNode*         call;
    CtkFunction*     func;
    CtkThread*       thread;
    int              nVars;
    CtkObject        vars[1];
} CtkFrame;

DLL_ENTRY void  ctkPrintStackTrace(CtkFrame* frame);
DLL_ENTRY char* ctkGetModuleName(CtkFrame* frame);
DLL_ENTRY char* ctkGetModuleFilePath(CtkFrame* frame);

DLL_ENTRY void  ctkTrace(char const* format, ...);
typedef void (*ctkTraceFunction)(char const* format, va_list args);
DLL_ENTRY ctkTraceFunction  ctkSetTraceFunction(ctkTraceFunction func);
DLL_ENTRY void* ctkThrowException(char const* msg);
DLL_ENTRY void  ctkPropagateException();


typedef struct CtkFile { 
    char* name;
    FILE* f;
} CtkFile;

DLL_ENTRY CtkFile* ctkCreateFile(char const* name, char const* fmt);
DLL_ENTRY void ctkPrint(CtkObject obj);
DLL_ENTRY void ctkPrintFile(CtkFile* file, CtkObject obj);
DLL_ENTRY void ctkFlushFile(CtkFile* file);
DLL_ENTRY void ctkDeleteFile(CtkFile* file);

DLL_ENTRY char* ctkToString(CtkObject obj, char* buf);


DLL_ENTRY void ctkAddFunction(CtkFunction* f);
DLL_ENTRY CtkFunction* ctkGetFunction(char const* name);
DLL_ENTRY CtkFrame* ctkCreateFrame(CtkFunction* func);
DLL_ENTRY CtkObject ctkCallFunction(CtkFunction* func, CtkObject* args);

DLL_ENTRY void  ctkNotEnoughMemory();
DLL_ENTRY int   ctkLoadLibrary(char const* name);
DLL_ENTRY void* ctkFindFunction(char const* name);

/**
 * Check number and types of passed arguments
 * @param nArgs  number of arguments passed to the function (first parameter of any primitive)
 * @param args   array of arguments passed to the function (second parameter of any primitive)
 * @param format format string specifying number and types of expected arguments
 * In format string each character describes one correpondent parameter.
 * Upercase character in format string cause checking of the argument type and copying CtkObject to the placeholder.
 * Lowercase character in format string cause checking and storing arguments in native C format.
 * ',' character in format string split mandatory and optional parameters. 
 * If type or number of parameters doesn't match, exception is thrown.
 * <TABLE BORDER>
 * <TR><TH>Format symbol</TH><TH>Expected C-Talk type of argument</TH><TH>Type of placeholder for parameter value</TH></TR>
 * <TR><TD>o</TD><TD>any</TD><TD>CtkObject</TD></TR>
 * <TR><TD>i</TD><TD>CTK_INTEGER</TD><TD>ctk_integer</TD></TR>
 * <TR><TD>r</TD><TD>CTK_REAL</TD><TD>ctk_real</TD></TR>
 * <TR><TD>p</TD><TD>CTK_RAW_POINTER or CTK_NULL</TD><TD>void*</TD></TR>
 * <TR><TD>P</TD><TD>CTK_RAW_POINTER</TD><TD>CtkObject</TD></TR>
 * <TR><TD>s</TD><TD>CTK_STRING or CTK_NULL</TD><TD>char*</TD></TR>
 * <TR><TD>S</TD><TD>CTK_STRING</TD><TD>CtkObject</TD></TR>
 * <TR><TD>a</TD><TD>CTK_ARRAY or CTK_NULL</TD><TD>CtkArray*</TD></TR>
 * <TR><TD>A</TD><TD>CTK_ARRAY</TD><TD>CtkObject</TD></TR>
 * <TR><TD>f</TD><TD>CTK_FILE or CTK_NULL</TD><TD>CtkFile*</TD></TR>
 * <TR><TD>F</TD><TD>CTK_FILE</TD><TD>CtkObject</TD></TR>
 * <TR><TD>m</TD><TD>CTK_MUTEX or CTK_NULL</TD><TD>CtkMutex*</TD></TR>
 * <TR><TD>M</TD><TD>CTK_MUTEX</TD><TD>CtkObject</TD></TR>
 * <TR><TD>t</TD><TD>CTK_THREAD or CTK_NULL</TD><TD>CtkThread*</TD></TR>
 * <TR><TD>T</TD><TD>CTK_THREAD</TD><TD>CtkObject</TD></TR>
 * <TR><TD>l</TD><TD>CTK_FUNCTION or CTK_NULL</TD><TD>CtkFunction*</TD></TR>
 * <TR><TD>L</TD><TD>CTK_FUNCTION</TD><TD>CtkObject</TD></TR>
 * <TR><TD>u</TD><TD>CTK_USER_TYPE or CTK_NULL</TD><TD>void*</TD></TR>
 * <TR><TD>U</TD><TD>CTK_USER_TYPE</TD><TD>CtkObject</TD></TR>
 * </TABLE>
 */
DLL_ENTRY void ctkParseArguments(int nArgs, CtkObject* args, char const* format, ...);

#ifdef USE_CTALK_EXCEPTION
class CtkException {
  public:
    CtkException(char const* msg) {
        this->msg = msg;
    }
    char const* msg;
};
#endif

#ifdef __cplusplus
}
#endif

#endif

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -