libfishsoup integration

This commit is contained in:
Masashi 2025-12-17 19:16:17 +05:30
commit a2f2f18910
6 changed files with 262 additions and 6 deletions

View file

@ -78,7 +78,7 @@ RAYLIB_LIBS=$(pkg-config --libs raylib 2>/dev/null || echo "-lraylib -lm")
ODE_CFLAGS=$(pkg-config --cflags ode 2>/dev/null || echo "-I/usr/include") ODE_CFLAGS=$(pkg-config --cflags ode 2>/dev/null || echo "-I/usr/include")
ODE_LIBS=$(pkg-config --libs ode 2>/dev/null || echo "-lode -lm") ODE_LIBS=$(pkg-config --libs ode 2>/dev/null || echo "-lode -lm")
if ! gcc $OPTIMIZE_FLAG -I. "$C_FILE" libsuicmez/libsuicmez.c libsuicmez/suicmez_gc.c $RAYLIB_CFLAGS $RAYLIB_LIBS $ODE_CFLAGS $ODE_LIBS -lm -o "$OUTPUT_BINARY" 2>&1; then if ! gcc $OPTIMIZE_FLAG -I. -Ilibfishsoup/include "$C_FILE" libsuicmez/libsuicmez.c libsuicmez/suicmez_gc.c libfishsoup/src/*.c $RAYLIB_CFLAGS $RAYLIB_LIBS $ODE_CFLAGS $ODE_LIBS -lm -o "$OUTPUT_BINARY" 2>&1; then
echo "" echo ""
echo "✗ C compilation failed" echo "✗ C compilation failed"
exit 1 exit 1

View file

@ -922,3 +922,52 @@ const char* suic_uuid_generate_v4_seeded(uint64_t seed) {
suic_random_seed((uint32_t)seed); suic_random_seed((uint32_t)seed);
return suic_uuid_generate_v4(); return suic_uuid_generate_v4();
} }
/* ===== FISHSOUP NETWORKING IMPLEMENTATION ===== */
/* Client functions */
fishsoup_client_t* suic_fishsoup_client_create(const char* host, int port) {
return fishsoup_client(host, port);
}
void suic_fishsoup_client_on_packet(fishsoup_client_t* client, suic_fishsoup_client_on_packet_fn on_packet) {
fishsoup_client_on_packet(client, on_packet);
}
int suic_fishsoup_client_poll(fishsoup_client_t* client) {
return fishsoup_client_poll(client);
}
void suic_fishsoup_client_destroy(fishsoup_client_t* client) {
fishsoup_client_destroy(client);
}
/* Server functions */
fishsoup_server_t* suic_fishsoup_server_create(int port) {
return fishsoup_server(port);
}
int suic_fishsoup_server_clients(fishsoup_server_t* server) {
return fishsoup_server_clients(server);
}
void suic_fishsoup_server_loop(fishsoup_server_t* server) {
fishsoup_server_loop(server);
}
void suic_fishsoup_server_on_client(fishsoup_server_t* server, suic_fishsoup_server_on_client_fn on_client) {
fishsoup_server_on_client(server, on_client);
}
void suic_fishsoup_server_destroy(fishsoup_server_t* server) {
fishsoup_server_destroy(server);
}
/* Packet functions */
int suic_fishsoup_packet_send(int fd, fishsoup_packet_t* packet) {
return fishsoup_packet_send(fd, packet);
}
int suic_fishsoup_packet_recv(int fd, fishsoup_packet_t* packet) {
return fishsoup_packet_recv(fd, packet);
}

View file

@ -392,4 +392,95 @@ const char* suic_uuid_generate_v4(void);
/* Generate a random UUID v4 from seed */ /* Generate a random UUID v4 from seed */
const char* suic_uuid_generate_v4_seeded(uint64_t seed); const char* suic_uuid_generate_v4_seeded(uint64_t seed);
/* ===== FISHSOUP NETWORKING API ===== */
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <unistd.h>
#include <poll.h>
#define FISHSOUP_PORT 3219
#define FISHSOUP_PING 3
enum fishsoup_packet_type {
FISHSOUP_PACKET_PING = 0,
FISHSOUP_PACKET_PONG
};
#define FISHSOUP_PACKET_FLAG_BROADCAST (1 << 0)
typedef struct fishsoup_packet_header fishsoup_packet_header_t;
typedef struct fishsoup_packet fishsoup_packet_t;
typedef struct fishsoup_client fishsoup_client_t;
typedef struct fishsoup_server fishsoup_server_t;
#pragma pack(1)
struct fishsoup_packet_header {
unsigned char type;
unsigned char flag;
unsigned short length;
};
#pragma pack()
struct fishsoup_packet {
fishsoup_packet_header_t header;
void* data;
};
struct fishsoup_client {
int fd;
time_t last_ping;
void (*on_packet)(fishsoup_client_t* client, fishsoup_packet_t* packet);
struct {
int sent_ping;
int cleanup;
} server;
};
struct fishsoup_server {
int fd;
struct sockaddr_in address;
fishsoup_client_t* clients;
void (*on_client)(fishsoup_server_t* server, fishsoup_client_t* client);
};
fishsoup_client_t* fishsoup_client(const char* host, int port);
void fishsoup_client_on_packet(fishsoup_client_t* client, void (*on_packet)(fishsoup_client_t* client, fishsoup_packet_t* packet));
int fishsoup_client_poll(fishsoup_client_t* client);
void fishsoup_client_destroy(fishsoup_client_t* client);
fishsoup_server_t* fishsoup_server(int port);
int fishsoup_server_clients(fishsoup_server_t* server);
void fishsoup_server_loop(fishsoup_server_t* server);
void fishsoup_server_on_client(fishsoup_server_t* server, void (*on_client)(fishsoup_server_t* server, fishsoup_client_t* client));
void fishsoup_server_destroy(fishsoup_server_t* server);
int fishsoup_fd_send(int fd, const void* buf, int length);
int fishsoup_fd_recv(int fd, void* buf, int length);
int fishsoup_packet_send(int fd, fishsoup_packet_t* packet);
int fishsoup_packet_recv(int fd, fishsoup_packet_t* packet);
typedef void (*suic_fishsoup_client_on_packet_fn)(fishsoup_client_t* client, fishsoup_packet_t* packet);
typedef void (*suic_fishsoup_server_on_client_fn)(fishsoup_server_t* server, fishsoup_client_t* client);
/* Client functions */
fishsoup_client_t* suic_fishsoup_client_create(const char* host, int port);
void suic_fishsoup_client_on_packet(fishsoup_client_t* client, suic_fishsoup_client_on_packet_fn on_packet);
int suic_fishsoup_client_poll(fishsoup_client_t* client);
void suic_fishsoup_client_destroy(fishsoup_client_t* client);
/* Server functions */
fishsoup_server_t* suic_fishsoup_server_create(int port);
int suic_fishsoup_server_clients(fishsoup_server_t* server);
void suic_fishsoup_server_loop(fishsoup_server_t* server);
void suic_fishsoup_server_on_client(fishsoup_server_t* server, suic_fishsoup_server_on_client_fn on_client);
void suic_fishsoup_server_destroy(fishsoup_server_t* server);
/* Packet functions */
int suic_fishsoup_packet_send(int fd, fishsoup_packet_t* packet);
int suic_fishsoup_packet_recv(int fd, fishsoup_packet_t* packet);
#endif // LIBSUICMEZ_H #endif // LIBSUICMEZ_H

View file

@ -654,6 +654,18 @@ impl Transpiler {
// UUID generation API // UUID generation API
"uuid_generate_v4" => "suic_uuid_generate_v4", "uuid_generate_v4" => "suic_uuid_generate_v4",
"uuid_generate_v4_seeded" => "suic_uuid_generate_v4_seeded", "uuid_generate_v4_seeded" => "suic_uuid_generate_v4_seeded",
// Fishsoup networking API
"fishsoup_client_create" => "suic_fishsoup_client_create",
"fishsoup_client_on_packet" => "suic_fishsoup_client_on_packet",
"fishsoup_client_poll" => "suic_fishsoup_client_poll",
"fishsoup_client_destroy" => "suic_fishsoup_client_destroy",
"fishsoup_server_create" => "suic_fishsoup_server_create",
"fishsoup_server_clients" => "suic_fishsoup_server_clients",
"fishsoup_server_loop" => "suic_fishsoup_server_loop",
"fishsoup_server_on_client" => "suic_fishsoup_server_on_client",
"fishsoup_server_destroy" => "suic_fishsoup_server_destroy",
"fishsoup_packet_send" => "suic_fishsoup_packet_send",
"fishsoup_packet_recv" => "suic_fishsoup_packet_recv",
_ => func, _ => func,
}; };

View file

@ -679,7 +679,7 @@ impl Parser {
// Parse from clause // Parse from clause
self.expect(Token::KeywordFrom)?; self.expect(Token::KeywordFrom)?;
let from = match self.next() { let from = match self.next() {
Some((Token::Variable(n), _)) => n, Some((Token::String(n), _)) => n,
Some((_, span)) => return self.error( Some((_, span)) => return self.error(
"Expected library name after 'from'. Example: extern add() -> int from \"libc\"" "Expected library name after 'from'. Example: extern add() -> int from \"libc\""
.to_string(), .to_string(),

View file

@ -1200,6 +1200,96 @@ impl TypeChecker {
return_type: Type::String, return_type: Type::String,
}, },
); );
// ===== FISHSOUP NETWORKING API =====
self.env.functions.insert(
"fishsoup_client_create".to_string(),
FunctionType {
type_params: vec![],
params: vec![Type::String, Type::Int],
return_type: Type::Ptr(Box::new(Type::Unit)), // opaque pointer
},
);
self.env.functions.insert(
"fishsoup_client_on_packet".to_string(),
FunctionType {
type_params: vec![],
params: vec![Type::Ptr(Box::new(Type::Unit)), Type::Ptr(Box::new(Type::Unit))], // client, callback
return_type: Type::Unit,
},
);
self.env.functions.insert(
"fishsoup_client_poll".to_string(),
FunctionType {
type_params: vec![],
params: vec![Type::Ptr(Box::new(Type::Unit))],
return_type: Type::Int,
},
);
self.env.functions.insert(
"fishsoup_client_destroy".to_string(),
FunctionType {
type_params: vec![],
params: vec![Type::Ptr(Box::new(Type::Unit))],
return_type: Type::Unit,
},
);
self.env.functions.insert(
"fishsoup_server_create".to_string(),
FunctionType {
type_params: vec![],
params: vec![Type::Int],
return_type: Type::Ptr(Box::new(Type::Unit)), // opaque pointer
},
);
self.env.functions.insert(
"fishsoup_server_clients".to_string(),
FunctionType {
type_params: vec![],
params: vec![Type::Ptr(Box::new(Type::Unit))],
return_type: Type::Int,
},
);
self.env.functions.insert(
"fishsoup_server_loop".to_string(),
FunctionType {
type_params: vec![],
params: vec![Type::Ptr(Box::new(Type::Unit))],
return_type: Type::Unit,
},
);
self.env.functions.insert(
"fishsoup_server_on_client".to_string(),
FunctionType {
type_params: vec![],
params: vec![Type::Ptr(Box::new(Type::Unit)), Type::Ptr(Box::new(Type::Unit))], // server, callback
return_type: Type::Unit,
},
);
self.env.functions.insert(
"fishsoup_server_destroy".to_string(),
FunctionType {
type_params: vec![],
params: vec![Type::Ptr(Box::new(Type::Unit))],
return_type: Type::Unit,
},
);
self.env.functions.insert(
"fishsoup_packet_send".to_string(),
FunctionType {
type_params: vec![],
params: vec![Type::Int, Type::Ptr(Box::new(Type::Unit))], // fd, packet
return_type: Type::Int,
},
);
self.env.functions.insert(
"fishsoup_packet_recv".to_string(),
FunctionType {
type_params: vec![],
params: vec![Type::Int, Type::Ptr(Box::new(Type::Unit))], // fd, packet
return_type: Type::Int,
},
);
} }
fn collect_definitions(&mut self, node: &ASTNode) -> Result<(), TypeError> { fn collect_definitions(&mut self, node: &ASTNode) -> Result<(), TypeError> {
@ -1257,6 +1347,20 @@ impl TypeChecker {
}; };
self.env.add_function(f.name.clone(), func_type); self.env.add_function(f.name.clone(), func_type);
} }
ASTNodeKind::Extern(ext) => {
let param_types: Vec<Type> = ext
.args
.iter()
.map(|ty| self.type_annot_to_type(ty))
.collect();
let return_type = self.type_annot_to_type(&ext.return_type);
let func_type = FunctionType {
type_params: vec![],
params: param_types,
return_type,
};
self.env.add_function(ext.name.clone(), func_type);
}
ASTNodeKind::Trait(t) => { ASTNodeKind::Trait(t) => {
let mut methods = HashMap::new(); let mut methods = HashMap::new();
for sig in &t.methods { for sig in &t.methods {