Add parser support for direct field mutation via `obj.field = expr` syntax, enabling mutable object state after creation. Extend the OOP test suite with dedicated mutation tests (`oop_mutation_test.rc`) and advanced examples (`oop_advanced.rc`) covering BankAccount, Player, and Rectangle classes. Update `oop_working.rc` with mutation test cases and revise TUTORIAL.md documentation to describe field mutation, setter methods, and complete OOP examples with mutation. Add Makefile targets for running the new mutation and advanced tests.
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 executablebuild/- 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.