All source listed below is under MIT license if no LICENSE file stating different is available.

RC - Retoor's C Interpreter

RC is a lightweight, recursive-descent C interpreter written in C. It executes a subset of C code directly without compilation, supporting essential language features including control flow, functions, pointers, and an extensive standard library.

Features

Language Support

Data Types

  • Integers (long)
  • Doubles (floating-point numbers)
  • Character pointers (char*)
  • Pointer operations (address-of &, dereference *)
  • Array declarations and indexing

Control Flow

  • if/else statements
  • while loops (including infinite loops)
  • break and continue statements
  • Comparison operators: ==, !=, <, >, <=, >=
  • Logical operators: &&, ||

Functions

  • User-defined functions with parameters
  • Return values
  • Recursive function calls
  • Native C function bindings

Operators

  • Arithmetic: +, -, *, /
  • Unary: -, &, *
  • String concatenation with +
  • Python-style slicing: str[start:end]

Standard Library

Math Functions

  • sqrt(x) - Square root
  • pow(base, exp) - Exponentiation
  • abs(x) - Absolute value
  • sin(x), cos(x), tan(x) - Trigonometric functions
  • floor(x), ceil(x) - Rounding functions

Double Type Functions

  • int_to_double(i) - Convert int to double
  • double_to_int(d) - Convert double to int
  • double_add(a, b), double_sub(a, b) - Double arithmetic
  • double_mul(a, b), double_div(a, b) - Double arithmetic
  • printf with %f format for doubles

String Functions

  • strpos(haystack, needle) - Find substring position
  • substr(str, start, length) - Extract substring
  • upper(str), lower(str) - Case conversion
  • strip(str) - Remove whitespace
  • replace(str, old, new) - Replace substring
  • startswith(str, prefix) - Prefix check
  • endswith(str, suffix) - Suffix check
  • strlen(str) - String length

File I/O

  • fopen(filename, mode) - Open a file
  • fclose(file) - Close a file
  • fread(file, buffer, size) - Read from file
  • fwrite(file, buffer, size) - Write to file
  • fgets(file, max_size) - Read a line
  • fputs(file, string) - Write a string
  • feof(file) - Check end of file
  • ftell(file), fseek(file, offset, whence) - File positioning
  • fremove(filename), frename(old, new) - File operations
  • SEEK_SET, SEEK_CUR, SEEK_END constants

Async I/O (Multi-threaded)

  • async_fread(file, buffer, size) - Async file read
  • async_fwrite(file, buffer, size) - Async file write
  • async_recv(socket, buffer, len, flags) - Async socket receive
  • async_send(socket, buffer, len, flags) - Async socket send
  • async_wait(handle) - Wait for async operation to complete
  • async_poll(handle) - Check if async operation is complete
  • async_result(handle) - Get result of completed async operation

Socket Programming

  • socket(), bind(), listen(), accept()
  • send(), recv(), close()
  • AF_INET, SOCK_STREAM constants

String Slicing

char *str = "Hello World";
char *slice = str[0:5];  // "Hello"

Building

make            # Build the interpreter
make clean      # Remove build artifacts
make help       # Show all available commands

The build process creates:

  • bin/rc - The interpreter executable
  • build/ - Object files (incremental compilation)

Usage

Execute RC programs with the .rc extension:

./bin/rc program.rc

Or use make targets:

make test                  # Run all tests
make run-feature-test      # Run specific test
make run-http-simple       # Run simple HTTP server example

Example Programs

Simple Program

int main() {
    int x = 10;
    int y = 20;
    printf("Sum: %d\n", x + y);
    return 0;
}

String Manipulation

int main() {
    char *text = "Hello World";
    char *upper_text = upper(text);
    char *slice = text[0:5];

    printf("Original: %s\n", text);
    printf("Uppercase: %s\n", upper_text);
    printf("Sliced: %s\n", slice);

    return 0;
}

HTTP Server Examples

Simple HTTP Server (examples/http_simple.rc) Single-connection HTTP server that accepts one request and exits.

Persistent HTTP Server (examples/http_persistent.rc) HTTP server with request counter that continuously accepts connections.

Multi-Connection HTTP Server (examples/http_multi.rc) HTTP server that handles up to 100 consecutive connections.

Project Structure

rc/
├── src/                    # Source code
│   ├── main.c             # Entry point
│   ├── tokenizer.c/h      # Lexical analysis
│   ├── parser.c/h         # Expression parsing
│   ├── interpreter.c/h    # Statement execution
│   ├── native_functions.c/h  # Native bindings
│   ├── string_utils.c/h   # String utilities
│   ├── globals.c          # Global variables
│   └── types.h            # Type definitions
├── tests/                 # Test programs (.rc)
├── examples/              # Example programs (.rc)
├── build/                 # Compiled objects
└── bin/                   # Executable (rc)

Architecture

Tokenizer

Converts source code into tokens, handling keywords, identifiers, literals, and operators. Supports line comments (//) and escape sequences in strings.

Parser

Recursive-descent parser with operator precedence:

  • factor() - Literals, variables, function calls
  • unary() - Unary operators (-, &, *)
  • term() - Multiplication, division
  • add() - Addition, subtraction, string concatenation
  • relational() - Comparison operators
  • expression() - Assignments and top-level expressions

Interpreter

Direct execution model without intermediate bytecode. Uses a virtual memory array for stack and variables, with separate string pool for dynamic strings.

Native Functions

Extensible system for binding C functions. Current bindings include math operations, string manipulation, and socket programming.

Limitations

  • Memory model uses long cells (not byte-accurate)
  • No support for structs, unions, or enums as user types
  • Limited type system (int, double, and char*)
  • Double arithmetic requires explicit helper functions
  • No preprocessor directives
  • Error messages show token index rather than line/column
  • Pointer arithmetic works on virtual memory addresses
  • Maximum 100 concurrent async operations

Testing

The project includes comprehensive test suites:

  • feature_test.rc - Core language features
  • endless_loop_test.rc - Loop constructs
  • math_test.rc - Mathematical operations
  • string_test.rc - String concatenation
  • string_manip_test.rc - Advanced string manipulation

Run all tests:

make test

Run individual tests:

make run-feature-test
make run-math-test
make run-string-manip

Implementation Details

Virtual Machine Model

  • Single memory array (10,000 long cells) for stack and variables
  • Stack pointer (sp) and base pointer (bp) manage activation records
  • Global register (ax) for return values and control flow
  • Separate string pool (100KB) for concatenated strings

Memory Management

  • Stack-based allocation for local variables
  • String pool for dynamic string operations
  • Automatic overflow detection

Function Calls

  • Stack-based activation records
  • Parameter passing via memory array
  • Return address tracking
  • Support for recursion

License

This project is provided as-is for educational and research purposes.

examples
src
tests
Makefile
README.md
TODO2.md
TUTORIAL.md