~mrms/regum

91bd0d836501550e603b8a18644acbdc08bd8c6d — Marek Maskarinec 1 year, 7 months ago
init commit
8 files changed, 216 insertions(+), 0 deletions(-)

A .gitignore
A Makefile
A README.md
A reg.c
A reg.um
A reg.umi
A test.um
A umka_api.h
A  => .gitignore +1 -0
@@ 1,1 @@
libumka.a

A  => Makefile +3 -0
@@ 1,3 @@

reg.umi: reg.c
	$(CC) -fPIC -shared -o reg.umi reg.c libumka.a

A  => README.md +11 -0
@@ 1,11 @@
# regum

An umka regex library.

## build

Place a built version of `libumka.a` into the repo root. Then run `make`.

## examples

See `test.um`.

A  => reg.c +38 -0
@@ 1,38 @@
#include <regex.h>


#include "umka_api.h"

static int err = 0;

static
void regumFree(UmkaStackSlot *p, UmkaStackSlot *r) {
	regex_t *prog = p[0].ptrVal;

	regfree(prog);
}

void reg__compile(UmkaStackSlot *p, UmkaStackSlot *r) {
	void *umka = r->ptrVal;

	regex_t *prog = umkaAllocData(umka, sizeof(regex_t), regumFree);
	r->ptrVal = prog;

	err = regcomp(prog, p[0].ptrVal, REG_EXTENDED);
}

void reg__error(UmkaStackSlot *p, UmkaStackSlot *r) {
	if (!err) return;
	regex_t *prog = p[1].ptrVal;
	UmkaDynArray(char) *buf = p[0].ptrVal;

	regerror(err, prog, buf->data, buf->len);	
}

void reg__exec(UmkaStackSlot *p, UmkaStackSlot *r) {
	regex_t *prog = (regex_t *)p[2].ptrVal;
	char *buf = (char *)p[1].ptrVal;
	regmatch_t *ret = p[0].ptrVal;

	err = regexec(prog, buf, 1, ret, 0);
}

A  => reg.um +27 -0
@@ 1,27 @@

type Reg* = ^struct{}

type Match* = struct {
	start, end: int32
}

fn reg__compile(ex: str): Reg
fn compile*(ex: str): Reg {
	return reg__compile(ex)
}

fn reg__error(r: Reg, buf: ^[]char)
fn getError*(r: Reg): str {
	buf := make([]char, 4096)	
	reg__error(r, &buf)

	return str(buf)	
}

fn reg__exec(r: Reg, buf: str, ret: ^Match)
fn exec*(r: Reg, buf: str): Match {
	m := Match{}
	reg__exec(r, buf, &m)

	return m
}

A  => reg.umi +0 -0
A  => test.um +21 -0
@@ 1,21 @@

import (
	"reg.um"								
)

fn main() {
	r := reg.compile("a.")

	err := reg.getError(r)
	if len(err) > 0 {
		printf("err: %s\n", err)
		return
	}

	s := "abcda\nefgahn"
	m := reg.exec(r, s)
	if m.start >= 0 {
		printf("%s\n", repr(m))
		printf("%s\n", slice(s, m.start, m.end))
	}
}

A  => umka_api.h +115 -0
@@ 1,115 @@
#ifndef UMKA_API_H_INCLUDED
#define UMKA_API_H_INCLUDED


#ifdef _WIN32
    #if defined(UMKA_STATIC)
        #define UMKA_EXPORT
        #define UMKA_IMPORT
    #else
        #define UMKA_EXPORT __declspec(dllexport)
        #define UMKA_IMPORT __declspec(dllimport)
    #endif
#else
    #define UMKA_EXPORT __attribute__((visibility("default")))
    #define UMKA_IMPORT __attribute__((visibility("default")))
#endif

#ifdef UMKA_BUILD
    #define UMKA_API UMKA_EXPORT
#else
    #define UMKA_API UMKA_IMPORT
#endif


#include <stdint.h>
#include <stdbool.h>


#if defined(__cplusplus)
extern "C" {
#endif


typedef union
{
    int64_t intVal;
    uint64_t uintVal;
    void *ptrVal;
    double realVal;
    float real32Val;
} UmkaStackSlot;


typedef void (*UmkaExternFunc)(UmkaStackSlot *params, UmkaStackSlot *result);


typedef enum
{
    UMKA_HOOK_CALL,
    UMKA_HOOK_RETURN,
} UmkaHookEvent;


typedef void (*UmkaHookFunc)(const char *fileName, const char *funcName, int line);


#define UmkaDynArray(T) struct \
{ \
    void *internal; \
    int64_t len; \
    int64_t itemSize; \
    T *data; \
}


typedef struct
{
    void *internal1;
    void *internal2;
} UmkaMap;


enum
{
    UMKA_MSG_LEN = 255
};


typedef struct
{
    char fileName[UMKA_MSG_LEN + 1];
    char fnName[UMKA_MSG_LEN + 1];
    int line, pos;
    char msg[UMKA_MSG_LEN + 1];
} UmkaError;


typedef void (*UmkaWarningCallback)(UmkaError *warning);


UMKA_API void *umkaAlloc            (void);
UMKA_API bool umkaInit              (void *umka, const char *fileName, const char *sourceString, int stackSize, const char *locale, int argc, char **argv, bool fileSystemEnabled, bool implLibsEnabled, UmkaWarningCallback warningCallback);
UMKA_API bool umkaCompile           (void *umka);
UMKA_API bool umkaRun               (void *umka);
UMKA_API bool umkaCall              (void *umka, int entryOffset, int numParamSlots, UmkaStackSlot *params, UmkaStackSlot *result);
UMKA_API void umkaFree              (void *umka);
UMKA_API void umkaGetError          (void *umka, UmkaError *err);
UMKA_API void umkaAsm               (void *umka, char *buf, int size);
UMKA_API bool umkaAddModule         (void *umka, const char *fileName, const char *sourceString);
UMKA_API bool umkaAddFunc           (void *umka, const char *name, UmkaExternFunc func);
UMKA_API int  umkaGetFunc           (void *umka, const char *moduleName, const char *funcName);
UMKA_API bool umkaGetCallStack      (void *umka, int depth, int *offset, char *name, int size);
UMKA_API void umkaSetHook           (void *umka, UmkaHookEvent event, UmkaHookFunc hook);
UMKA_API void *umkaAllocData        (void *umka, int size, UmkaExternFunc onFree);
UMKA_API void umkaIncRef            (void *umka, void *ptr);
UMKA_API void umkaDecRef            (void *umka, void *ptr);
UMKA_API void *umkaGetMapItem       (void *umka, UmkaMap *map, UmkaStackSlot key);
UMKA_API const char *umkaGetVersion (void);


#if defined(__cplusplus)
}
#endif

#endif // UMKA_API_H_INCLUDED