RC Standard Library
The RC language standard library is organized into modular categories for easy maintenance and extensibility.
Structure
src/stdlib/
├── stdlib.h # Main registration header
├── stdlib.c # Registers all stdlib modules
├── string/ # String manipulation functions
│ ├── string_stdlib.h
│ └── string_stdlib.c
├── math/ # Mathematical functions
│ ├── math_stdlib.h
│ └── math_stdlib.c
├── io/ # Input/Output operations
│ ├── file_stdlib.h
│ ├── file_stdlib.c # File I/O functions
│ ├── socket_stdlib.h
│ └── socket_stdlib.c # Network socket functions
├── async/ # Asynchronous operations
│ ├── async_stdlib.h
│ └── async_stdlib.c # Async I/O and coroutines
└── constants/ # System constants
├── constants_stdlib.h
└── constants_stdlib.c
Available Functions
String Functions (string/)
strlen(str)- Get string lengthstrpos(haystack, needle)- Find substring positionsubstr(str, start, length)- Extract substringupper(str)- Convert to uppercaselower(str)- Convert to lowercasestrip(str)- Trim whitespacereplace(str, old, new)- Replace substringstartswith(str, prefix)- Check if starts with prefixendswith(str, suffix)- Check if ends with suffix
Math Functions (math/)
sqrt(x)- Square rootpow(base, exp)- Power functionsin(x),cos(x),tan(x)- Trigonometric functionsabs(x)- Absolute valuefloor(x),ceil(x)- Rounding functionsint_to_double(x)- Convert int to doubledouble_to_int(x)- Convert double to intdouble_add(a, b),double_sub(a, b),double_mul(a, b),double_div(a, b)- Double arithmetic
File I/O Functions (io/file_stdlib.c)
fopen(filename, mode)- Open filefclose(file)- Close filefread(file, addr, size)- Read from filefwrite(file, buf, size)- Write to filefgets(file, max_size)- Read line from filefputs(file, str)- Write string to filefeof(file)- Check end of fileftell(file)- Get file positionfseek(file, offset, whence)- Seek in filefremove(filename)- Delete filefrename(oldname, newname)- Rename file
Socket Functions (io/socket_stdlib.c)
socket(domain, type, protocol)- Create socketbind(sockfd, port)- Bind socket to portlisten(sockfd, backlog)- Listen for connectionsaccept(sockfd)- Accept connectionrecv(sockfd, addr, len, flags)- Receive datasend(sockfd, buf, len, flags)- Send dataclose(fd)- Close file descriptor
Async Functions (async/)
async_fread(file, addr, size)- Async file readasync_fwrite(file, buf, size)- Async file writeasync_recv(sockfd, addr, len, flags)- Async socket receiveasync_send(sockfd, buf, len, flags)- Async socket sendasync_wait(id)- Wait for async operationasync_poll(id)- Poll async operation statusasync_result(id)- Get async operation resultawait(coroutine_id)- Await coroutine completiongather(coro1, coro2, ...)- Wait for multiple coroutines
Constants (constants/)
AF_INET()- IPv4 address familySOCK_STREAM()- TCP socket typeSEEK_SET()- Seek from beginningSEEK_CUR()- Seek from current positionSEEK_END()- Seek from end
Adding New Functions
1. Add to Existing Category
To add a new function to an existing category (e.g., a new math function):
- Open the appropriate category file:
src/stdlib/math/math_stdlib.c - Add your function implementation:
long native_my_function(long *args, int argc) {
if (!args || argc < 1) {
return 0;
}
// Your implementation here
return result;
}
- Register it in the category's registration function:
void register_math_stdlib() {
// ... existing registrations ...
register_native_func("my_function", native_my_function);
}
- Rebuild:
make clean && make
2. Add New Category
To add a new category (e.g., datetime):
- Create directory:
mkdir -p src/stdlib/datetime - Create header file:
src/stdlib/datetime/datetime_stdlib.h
#ifndef DATETIME_STDLIB_H
#define DATETIME_STDLIB_H
void register_datetime_stdlib();
#endif
- Create implementation:
src/stdlib/datetime/datetime_stdlib.c
#include <time.h>
#include "../../types.h"
#include "datetime_stdlib.h"
extern void register_native_func(char *name, NativeFunc func);
long native_time(long *args, int argc) {
return (long)time(NULL);
}
void register_datetime_stdlib() {
register_native_func("time", native_time);
}
- Add to
src/stdlib/stdlib.c:
#include "datetime/datetime_stdlib.h"
void register_stdlib() {
// ... existing registrations ...
register_datetime_stdlib();
}
- Add to Makefile SOURCES:
SOURCES = ... \
$(SRC_DIR)/stdlib/datetime/datetime_stdlib.c
- Create build directory in Makefile dirs target:
dirs:
# ... existing directories ...
@mkdir -p $(BUILD_DIR)/stdlib/datetime
- Rebuild:
make clean && make
Function Signature
All native functions must follow this signature:
long native_function_name(long *args, int argc)
Where:
args- Array of long arguments passed from RC codeargc- Number of arguments- Returns a
longvalue
Best Practices
- Always validate arguments (check argc and args pointer)
- Use appropriate error handling
- Document your functions with comments
- Test your functions thoroughly
- Keep functions focused and single-purpose
- Use the string pool for string allocations (str_pool)
- Check bounds when accessing memory array
- Follow the existing code style
Testing
After making changes:
- Build:
make clean && make - Run all tests:
make test - Run specific category tests (e.g.,
make run-math-test)
Architecture Notes
- All stdlib modules are automatically registered when
register_stdlib()is called fromsrc/native_functions.c - The registration happens during interpreter initialization in
src/main.c - Native functions are stored in the global
native_funcsarray - Function lookup is performed by name during parsing
| .. | ||
| async | ||
| constants | ||
| eval | ||
| io | ||
| math | ||
| string | ||
| README.md | ||
| stdlib.c | ||
| stdlib.h | ||