#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <math.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <unistd.h>
#include <arpa/inet.h>
#include "types.h"
#include "native_functions.h"
#include "interpreter.h"
void register_native_func(char *name, NativeFunc func) {
NativeFuncDef *nf = &native_funcs[native_func_cnt++];
strncpy(nf->name, name, 31);
nf->name[31] = 0;
nf->func = func;
}
long native_socket(long *args, int argc) {
int domain = (int)args[0];
int type = (int)args[1];
int protocol = (int)args[2];
return socket(domain, type, protocol);
}
long native_bind(long *args, int argc) {
int sockfd = (int)args[0];
int port = (int)args[1];
struct sockaddr_in addr;
memset(&addr, 0, sizeof(addr));
addr.sin_family = AF_INET;
addr.sin_addr.s_addr = INADDR_ANY;
addr.sin_port = htons(port);
return bind(sockfd, (struct sockaddr*)&addr, sizeof(addr));
}
long native_listen(long *args, int argc) {
int sockfd = (int)args[0];
int backlog = (int)args[1];
return listen(sockfd, backlog);
}
long native_accept(long *args, int argc) {
int sockfd = (int)args[0];
return accept(sockfd, NULL, NULL);
}
long native_recv(long *args, int argc) {
int sockfd = (int)args[0];
int addr = (int)args[1];
int len = (int)args[2];
int flags = (int)args[3];
char temp_buf[8192];
if (len > 8192) len = 8192;
int result = recv(sockfd, temp_buf, len, flags);
if (result > 0) {
for (int i = 0; i < result; i++) {
memory[addr + i] = temp_buf[i];
}
}
return result;
}
long native_send(long *args, int argc) {
int sockfd = (int)args[0];
long buf_arg = args[1];
int len = (int)args[2];
int flags = (int)args[3];
if (buf_arg > MEM_SIZE * 8 || buf_arg < 0) {
return send(sockfd, (char*)buf_arg, len, flags);
}
char temp_buf[8192];
if (len > 8192) len = 8192;
for (int i = 0; i < len; i++) {
temp_buf[i] = (char)memory[buf_arg + i];
}
return send(sockfd, temp_buf, len, flags);
}
long native_close(long *args, int argc) {
int fd = (int)args[0];
return close(fd);
}
long native_strlen(long *args, int argc) {
char *str = (char*)args[0];
return strlen(str);
}
long native_AF_INET(long *args, int argc) {
return AF_INET;
}
long native_SOCK_STREAM(long *args, int argc) {
return SOCK_STREAM;
}
long native_sqrt(long *args, int argc) {
return (long)sqrt((double)args[0]);
}
long native_pow(long *args, int argc) {
return (long)pow((double)args[0], (double)args[1]);
}
long native_sin(long *args, int argc) {
return (long)(sin((double)args[0]) * 1000000);
}
long native_cos(long *args, int argc) {
return (long)(cos((double)args[0]) * 1000000);
}
long native_tan(long *args, int argc) {
return (long)(tan((double)args[0]) * 1000000);
}
long native_abs(long *args, int argc) {
return (long)abs((int)args[0]);
}
long native_floor(long *args, int argc) {
return (long)floor((double)args[0]);
}
long native_ceil(long *args, int argc) {
return (long)ceil((double)args[0]);
}
long native_strpos(long *args, int argc) {
char *haystack = (char*)args[0];
char *needle = (char*)args[1];
char *pos = strstr(haystack, needle);
if (pos) {
return pos - haystack;
}
return -1;
}
long native_substr(long *args, int argc) {
char *str = (char*)args[0];
int start = (int)args[1];
int length = (int)args[2];
char *result = &str_pool[str_pool_idx];
int str_len = strlen(str);
if (start < 0) start = 0;
if (start >= str_len) return (long)"";
if (start + length > str_len) length = str_len - start;
if (length < 0) return (long)"";
if (str_pool_idx + length + 1 >= STR_POOL_SIZE) {
error("String pool overflow");
}
strncpy(result, str + start, length);
result[length] = 0;
str_pool_idx += length + 1;
return (long)result;
}
long native_upper(long *args, int argc) {
char *str = (char*)args[0];
char *result = &str_pool[str_pool_idx];
int len = strlen(str);
if (str_pool_idx + len + 1 >= STR_POOL_SIZE) {
error("String pool overflow");
}
for (int i = 0; i <= len; i++) {
result[i] = toupper(str[i]);
}
str_pool_idx += len + 1;
return (long)result;
}
long native_lower(long *args, int argc) {
char *str = (char*)args[0];
char *result = &str_pool[str_pool_idx];
int len = strlen(str);
if (str_pool_idx + len + 1 >= STR_POOL_SIZE) {
error("String pool overflow");
}
for (int i = 0; i <= len; i++) {
result[i] = tolower(str[i]);
}
str_pool_idx += len + 1;
return (long)result;
}
long native_strip(long *args, int argc) {
char *str = (char*)args[0];
char *result = &str_pool[str_pool_idx];
while (*str && isspace(*str)) str++;
int len = strlen(str);
while (len > 0 && isspace(str[len - 1])) len--;
if (str_pool_idx + len + 1 >= STR_POOL_SIZE) {
error("String pool overflow");
}
strncpy(result, str, len);
result[len] = 0;
str_pool_idx += len + 1;
return (long)result;
}
long native_replace(long *args, int argc) {
char *str = (char*)args[0];
char *old_str = (char*)args[1];
char *new_str = (char*)args[2];
char *result = &str_pool[str_pool_idx];
char *src = str;
char *dst = result;
int old_len = strlen(old_str);
int new_len = strlen(new_str);
while (*src) {
if (strncmp(src, old_str, old_len) == 0) {
if (str_pool_idx + (dst - result) + new_len + strlen(src + old_len) + 1 >= STR_POOL_SIZE) {
error("String pool overflow");
}
strcpy(dst, new_str);
dst += new_len;
src += old_len;
} else {
*dst++ = *src++;
}
}
*dst = 0;
int total_len = dst - result;
str_pool_idx += total_len + 1;
return (long)result;
}
long native_startswith(long *args, int argc) {
char *str = (char*)args[0];
char *prefix = (char*)args[1];
int prefix_len = strlen(prefix);
return strncmp(str, prefix, prefix_len) == 0;
}
long native_endswith(long *args, int argc) {
char *str = (char*)args[0];
char *suffix = (char*)args[1];
int str_len = strlen(str);
int suffix_len = strlen(suffix);
if (suffix_len > str_len) return 0;
return strcmp(str + str_len - suffix_len, suffix) == 0;
}
void register_native_functions() {
register_native_func("socket", native_socket);
register_native_func("bind", native_bind);
register_native_func("listen", native_listen);
register_native_func("accept", native_accept);
register_native_func("recv", native_recv);
register_native_func("send", native_send);
register_native_func("close", native_close);
register_native_func("strlen", native_strlen);
register_native_func("AF_INET", native_AF_INET);
register_native_func("SOCK_STREAM", native_SOCK_STREAM);
register_native_func("sqrt", native_sqrt);
register_native_func("pow", native_pow);
register_native_func("sin", native_sin);
register_native_func("cos", native_cos);
register_native_func("tan", native_tan);
register_native_func("abs", native_abs);
register_native_func("floor", native_floor);
register_native_func("ceil", native_ceil);
register_native_func("strpos", native_strpos);
register_native_func("substr", native_substr);
register_native_func("upper", native_upper);
register_native_func("lower", native_lower);
register_native_func("strip", native_strip);
register_native_func("replace", native_replace);
register_native_func("startswith", native_startswith);
register_native_func("endswith", native_endswith);
}