Skip to content
Merged
64 changes: 0 additions & 64 deletions CODE_QUALITY.md

This file was deleted.

16 changes: 15 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ LDFLAGS = -lm
SRCDIR = src
BENCHDIR = bench
TESTDIR = tests
EXAMPLEDIR = examples
BUILDDIR = build

# Source files
Expand All @@ -25,7 +26,11 @@ BENCH_BINS = $(patsubst $(BENCHDIR)/%.c,$(BUILDDIR)/%,$(BENCH_SRCS))
TEST_SRCS = $(wildcard $(TESTDIR)/*.c)
TEST_BINS = $(patsubst $(TESTDIR)/%.c,$(BUILDDIR)/%,$(TEST_SRCS))

.PHONY: all lib bench test clean help debug debug-test
# Example sources
EXAMPLE_SRCS = $(wildcard $(EXAMPLEDIR)/*.c)
EXAMPLE_BINS = $(patsubst $(EXAMPLEDIR)/%.c,$(BUILDDIR)/%,$(EXAMPLE_SRCS))

.PHONY: all lib bench test examples clean help debug debug-test

# Default target
all: lib bench
Expand All @@ -39,6 +44,7 @@ help:
@echo " make lib - Build library object file (release mode)"
@echo " make bench - Build all benchmarks"
@echo " make test - Build and run all tests"
@echo " make examples - Build all examples"
@echo " make debug - Build library in debug mode (-g -O0, asserts enabled)"
@echo " make debug-test - Build and run tests in debug mode"
@echo " make clean - Remove all build artifacts"
Expand Down Expand Up @@ -101,6 +107,14 @@ $(BUILDDIR)/%: $(TESTDIR)/%.c $(LIB_OBJ) | $(BUILDDIR)
$(CC) $(CFLAGS) -I$(SRCDIR) $< $(LIB_OBJ) -o $@ $(LDFLAGS)
@echo "✓ Built: $@"

# Build all examples
examples: $(EXAMPLE_BINS)

$(BUILDDIR)/%: $(EXAMPLEDIR)/%.c $(LIB_OBJ) | $(BUILDDIR)
@echo "Building example: $@"
$(CC) $(CFLAGS) -I$(SRCDIR) $< $(LIB_OBJ) -o $@ $(LDFLAGS) -lpthread
@echo "✓ Built: $@"

# Clean build artifacts
clean:
@echo "Cleaning build artifacts..."
Expand Down
109 changes: 68 additions & 41 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,22 +11,18 @@ miniexpr is designed to be embedded directly into larger projects, not distribut
- Vectorized evaluation for processing arrays efficiently
- Thread-safe operations for parallel processing

## Main Functions
**Note**: This is a pre-alpha project.

### `me_compile()`
```c
me_expr *me_compile(const char *expression, const me_variable *variables,
int var_count, void *output, int nitems,
me_dtype dtype, int *error);
```
Parses an expression string and creates a compiled expression tree. Variables are bound at compile time. Returns `NULL` on error.
## API Functions

miniexpr provides a simple, focused API with just two main functions:

### `me_compile_chunk()`
```c
me_expr *me_compile_chunk(const char *expression, const me_variable *variables,
int var_count, me_dtype dtype, int *error);
```
Compiles an expression for chunked evaluation. This variant is optimized for use with `me_eval_chunk()` and `me_eval_chunk_threadsafe()`, where variable and output pointers are provided during evaluation rather than compilation.
Compiles an expression for evaluation. Variable and output pointers are provided during evaluation rather than compilation.

**Simple Usage**: Just provide variable names - everything else is optional:

Expand All @@ -36,7 +32,7 @@ me_expr *expr = me_compile_chunk("x + y", vars, 2, ME_FLOAT64, &err);

// Later, provide data in the same order as vars array
const void *data[] = {x_array, y_array}; // x first, y second
me_eval_chunk(expr, data, 2, output, nitems);
me_eval_chunk_threadsafe(expr, data, 2, output, nitems);
```

For mixed types (use `ME_AUTO` for output dtype to infer from variables):
Expand All @@ -46,9 +42,9 @@ me_expr *expr = me_compile_chunk("temp * count", vars, 2, ME_AUTO, &err);
// Result type will be inferred (ME_FLOAT64 in this case)
```

Variables are matched by position (order) in the arrays. Unspecified fields (address, type, context) default to NULL/0.
Variables are matched by position (order) in the arrays. Unspecified fields default to NULL/0.

### `dtype` Parameter Rules
#### `dtype` Parameter Rules

The `dtype` parameter has two mutually exclusive modes:

Expand All @@ -63,46 +59,26 @@ The `dtype` parameter has two mutually exclusive modes:

Mixing modes (some vars with types, some `ME_AUTO`) will cause compilation to fail.

Returns `NULL` on error.

### `me_eval()`
```c
void me_eval(const me_expr *n);
```
Evaluates the compiled expression on vectors. Results are written to the output buffer specified during compilation.

### `me_eval_fused()`
```c
void me_eval_fused(const me_expr *n);
```
Evaluates using fused bytecode for faster execution on complex expressions.

### `me_eval_chunk()`
```c
void me_eval_chunk(const me_expr *expr, const void **vars_chunk, int n_vars,
void *output_chunk, int chunk_nitems);
```
Evaluates a compiled expression with new variable and output pointers, allowing processing of large arrays in chunks without recompilation. **Not thread-safe**.

### `me_eval_chunk_threadsafe()`
```c
void me_eval_chunk_threadsafe(const me_expr *expr, const void **vars_chunk,
int n_vars, void *output_chunk, int chunk_nitems);
```
Thread-safe version of `me_eval_chunk()` for parallel evaluation across multiple threads.
Evaluates the compiled expression with new variable and output pointers. This allows processing arrays in chunks without recompilation, and is thread-safe for parallel evaluation across multiple threads.

**Parameters:**
- `expr`: Compiled expression (from `me_compile_chunk`)
- `vars_chunk`: Array of pointers to variable data chunks (same order as in `me_compile_chunk`)
- `n_vars`: Number of variables (must match the number used in `me_compile_chunk`)
- `output_chunk`: Pointer to output buffer for this chunk
- `chunk_nitems`: Number of elements in this chunk

### `me_free()`
```c
void me_free(me_expr *n);
```
Frees the compiled expression. Safe to call on `NULL` pointers.

### `me_print()`
```c
void me_print(const me_expr *n);
```
Prints debugging information about the syntax tree.

## Data Types

miniexpr supports various data types through the `me_dtype` enumeration:
Expand All @@ -116,7 +92,58 @@ miniexpr supports various data types through the `me_dtype` enumeration:

To use miniexpr in your project, simply include the source files (`miniexpr.c` and `miniexpr.h`) directly in your build system.

For examples and detailed usage, see the [Getting Started Guide](doc/get-started.md).
### Quick Example

```c
#include "miniexpr.h"

// Define variables
me_variable vars[] = {{"x"}, {"y"}};
int err;

// Compile expression
me_expr *expr = me_compile_chunk("x + y", vars, 2, ME_FLOAT64, &err);

// Prepare data
double x_data[] = {1.0, 2.0, 3.0};
double y_data[] = {4.0, 5.0, 6.0};
double result[3];

const void *var_ptrs[] = {x_data, y_data};

// Evaluate (thread-safe)
me_eval_chunk_threadsafe(expr, var_ptrs, 2, result, 3);

// Clean up
me_free(expr);
```

## Examples

The `examples/` directory contains complete, runnable examples demonstrating various features:

- **01_simple_expression.c** - Basic arithmetic expressions (beginner)
- **02_complex_expression.c** - Complex formulas with trigonometry
- **03_mixed_types.c** - Type promotion and ME_AUTO inference
- **04_large_dataset.c** - Processing 1M elements in chunks
- **05_parallel_evaluation.c** - Multi-threaded parallel processing
- **06_debug_print.c** - Expression tree visualization with me_print()

Build and run:
```bash
make examples
./build/01_simple_expression
```

See [examples/README.md](examples/README.md) for detailed documentation of each example.

## Documentation

- **[examples/README.md](examples/README.md)** - Complete examples with explanations
- **[QUICK_REFERENCE.md](QUICK_REFERENCE.md)** - Complete API reference
- **[doc/get-started.md](doc/get-started.md)** - Getting started guide
- **[doc/data-types.md](doc/data-types.md)** - Data types guide
- **[doc/parallel-processing.md](doc/parallel-processing.md)** - Parallel processing patterns

## Contributing

Expand Down
Loading