libfishsoup integration
This commit is contained in:
parent
3257bb449e
commit
a2f2f18910
6 changed files with 262 additions and 6 deletions
|
|
@ -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_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 "✗ C compilation failed"
|
||||
exit 1
|
||||
|
|
|
|||
|
|
@ -922,3 +922,52 @@ const char* suic_uuid_generate_v4_seeded(uint64_t seed) {
|
|||
suic_random_seed((uint32_t)seed);
|
||||
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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -392,4 +392,95 @@ const char* suic_uuid_generate_v4(void);
|
|||
/* Generate a random UUID v4 from 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
|
||||
|
|
|
|||
|
|
@ -651,10 +651,22 @@ impl Transpiler {
|
|||
"get_time_us" => "suic_get_time_us",
|
||||
"get_unix_time" => "suic_get_unix_time",
|
||||
"sleep_ms" => "suic_sleep_ms",
|
||||
// UUID generation API
|
||||
"uuid_generate_v4" => "suic_uuid_generate_v4",
|
||||
"uuid_generate_v4_seeded" => "suic_uuid_generate_v4_seeded",
|
||||
_ => func,
|
||||
// UUID generation API
|
||||
"uuid_generate_v4" => "suic_uuid_generate_v4",
|
||||
"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,
|
||||
};
|
||||
|
||||
format!("{}({})", c_func_name, args_str)
|
||||
|
|
|
|||
|
|
@ -679,7 +679,7 @@ impl Parser {
|
|||
// Parse from clause
|
||||
self.expect(Token::KeywordFrom)?;
|
||||
let from = match self.next() {
|
||||
Some((Token::Variable(n), _)) => n,
|
||||
Some((Token::String(n), _)) => n,
|
||||
Some((_, span)) => return self.error(
|
||||
"Expected library name after 'from'. Example: extern add() -> int from \"libc\""
|
||||
.to_string(),
|
||||
|
|
|
|||
|
|
@ -1200,6 +1200,96 @@ impl TypeChecker {
|
|||
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> {
|
||||
|
|
@ -1257,6 +1347,20 @@ impl TypeChecker {
|
|||
};
|
||||
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) => {
|
||||
let mut methods = HashMap::new();
|
||||
for sig in &t.methods {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue