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_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
|
||||||
|
|
|
||||||
|
|
@ -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);
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -651,10 +651,22 @@ impl Transpiler {
|
||||||
"get_time_us" => "suic_get_time_us",
|
"get_time_us" => "suic_get_time_us",
|
||||||
"get_unix_time" => "suic_get_unix_time",
|
"get_unix_time" => "suic_get_unix_time",
|
||||||
"sleep_ms" => "suic_sleep_ms",
|
"sleep_ms" => "suic_sleep_ms",
|
||||||
// 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",
|
||||||
_ => func,
|
// 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)
|
format!("{}({})", c_func_name, args_str)
|
||||||
|
|
|
||||||
|
|
@ -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(),
|
||||||
|
|
|
||||||
|
|
@ -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 {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue