/
vit1251
/
cmm
Обзор
Документация
Войти
/
vit1251
/
cmm
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
CI/CD
Аналитика
Безопасность
master
src/types_ser.cpp
227 строк
7 KB
Vitold S
Commits added a large set of example and demo programs,
26 июл 2026, 14:31
26 июл 2026, 14:31
8e0776e
Код
Авторство
О чём код?
#include "types_ser.h" #include <cstring> #include <string> #include <vector> #include <sstream> // Binary format (v1): // magic "CMMT" (4B) // version u32 (1) // module_name: string // // structs_count: u32 // struct_entries... // // pub_fns_count: u32 // fn_sig entries... // // pub_consts_count: u32 // const_name strings... // // string: u32 length + bytes (no null term) // // struct_entry: // name_flags: string (last byte = flags: bit0=pub) // fields_count: u32 // fields[]: name_string + type_desc // // fn_sig: // name: string (mangled) // ret_type: type_desc // param_count: u32 // param_types: type_desc[] // // type_desc: // u8 kind // kind=0 PRIM: u8 prim (0=i32,1=u32,2=i64,3=u64,4=i8,5=u8,6=f32,7=f64,8=bool,9=void) // kind=1 PTR: type_desc pointee // kind=2 STRUCT: module_string + name_string // kind=3 ARRAY: u32 count + type_desc elem // kind=4 NAMED: name_string enum TypeKind : uint8_t { TK_PRIM = 0, TK_PTR = 1, TK_STRUCT = 2, TK_ARRAY = 3, TK_NAMED = 4 }; enum PrimType : uint8_t { PRIM_I32 = 0, PRIM_U32 = 1, PRIM_I64 = 2, PRIM_U64 = 3, PRIM_I8 = 4, PRIM_U8 = 5, PRIM_F32 = 6, PRIM_F64 = 7, PRIM_BOOL = 8, PRIM_VOID = 9 }; static PrimType prim_from_name(const std::string& name) { if (name == "i32") return PRIM_I32; if (name == "u32") return PRIM_U32; if (name == "i64") return PRIM_I64; if (name == "u64") return PRIM_U64; if (name == "i8") return PRIM_I8; if (name == "u8") return PRIM_U8; if (name == "f32") return PRIM_F32; if (name == "f64") return PRIM_F64; if (name == "bool") return PRIM_BOOL; if (name == "void") return PRIM_VOID; return PRIM_I32; } static const char* prim_name(PrimType p) { switch (p) { case PRIM_I32: return "i32"; case PRIM_U32: return "u32"; case PRIM_I64: return "i64"; case PRIM_U64: return "u64"; case PRIM_I8: return "i8"; case PRIM_U8: return "u8"; case PRIM_F32: return "f32"; case PRIM_F64: return "f64"; case PRIM_BOOL: return "bool"; case PRIM_VOID: return "void"; } return "i32"; } struct SerStream { std::string data; void wr_u8(uint8_t v) { data.push_back((char)v); } void wr_u32(uint32_t v) { data.push_back((char)(v & 0xFF)); data.push_back((char)((v >> 8) & 0xFF)); data.push_back((char)((v >> 16) & 0xFF)); data.push_back((char)((v >> 24) & 0xFF)); } void wr_str(const std::string& s) { wr_u32(s.size()); data.append(s); } void wr_type(const std::string& tn); }; struct DeserStream { const uint8_t* ptr; size_t size; size_t pos = 0; DeserStream(const std::string& d) : ptr((const uint8_t*)d.data()), size(d.size()) {} uint8_t rd_u8() { return pos < size ? ptr[pos++] : 0; } uint32_t rd_u32() { if (pos + 4 > size) return 0; uint32_t v = (uint32_t)ptr[pos] | ((uint32_t)ptr[pos+1] << 8) | ((uint32_t)ptr[pos+2] << 16) | ((uint32_t)ptr[pos+3] << 24); pos += 4; return v; } std::string rd_str() { uint32_t len = rd_u32(); if (pos + len > size) return ""; std::string s((const char*)ptr + pos, len); pos += len; return s; } std::string rd_type(); }; void SerStream::wr_type(const std::string& tn) { if (tn == "i32" || tn == "u32" || tn == "i64" || tn == "u64" || tn == "i8" || tn == "u8" || tn == "f32" || tn == "f64" || tn == "bool" || tn == "void") { wr_u8(TK_PRIM); wr_u8(prim_from_name(tn)); return; } if (!tn.empty() && tn[0] == '*') { wr_u8(TK_PTR); wr_type(tn.substr(1)); return; } if (!tn.empty() && tn[0] == '[') { size_t end = tn.find(']'); if (end != std::string::npos) { wr_u8(TK_ARRAY); wr_u32((uint32_t)std::stoull(tn.substr(1, end - 1))); wr_type(tn.substr(end + 1)); return; } } wr_u8(TK_NAMED); wr_str(tn); } std::string DeserStream::rd_type() { uint8_t k = rd_u8(); if (k == TK_PRIM) return prim_name((PrimType)rd_u8()); if (k == TK_PTR) return "*" + rd_type(); if (k == TK_ARRAY) { uint32_t cnt = rd_u32(); return "[" + std::to_string(cnt) + "]" + rd_type(); } if (k == TK_NAMED) return rd_str(); return "void"; } static void serialize_struct(SerStream& s, const StructDecl& sd) { std::string nf = sd.name; nf.push_back((char)(sd.is_pub ? 1 : 0)); s.wr_str(nf); s.wr_u32(sd.fields.size()); for (auto& f : sd.fields) { s.wr_str(f.name); s.wr_type(f.type_name); } } static void serialize_fn(SerStream& s, const FnDecl& fn) { s.wr_str(fn.name); s.wr_type(fn.ret_type_name); s.wr_u32(fn.params.size()); for (auto& p : fn.params) s.wr_type(p.type_name); } std::string serialize_cmm_types(const Program& prog, const std::string& module_name) { SerStream s; s.data.append("CMMT"); s.wr_u32(1); s.wr_str(module_name); // Pub structs std::vector<const StructDecl*> pub_structs; for (auto& sd : prog.structs) if (sd.is_pub) pub_structs.push_back(&sd); s.wr_u32(pub_structs.size()); for (auto* sd : pub_structs) serialize_struct(s, *sd); // Pub functions (non-extern) std::vector<const FnDecl*> pub_fns; for (auto& fn : prog.functions) if (fn->is_pub && !fn->is_extern) pub_fns.push_back(fn.get()); s.wr_u32(pub_fns.size()); for (auto* fn : pub_fns) serialize_fn(s, *fn); // Pub constants std::vector<const ConstantDecl*> pub_consts; for (auto& cd : prog.constants) if (cd.is_pub) pub_consts.push_back(&cd); s.wr_u32(pub_consts.size()); for (auto* cd : pub_consts) s.wr_str(cd->name); return s.data; } bool deserialize_cmm_types(const std::string& data, CmmModuleInfo& info) { DeserStream s(data); char magic[5] = {}; for (int i = 0; i < 4; i++) magic[i] = s.rd_u8(); if (strcmp(magic, "CMMT") != 0) return false; s.rd_u32(); // version info.module_name = s.rd_str(); if (info.module_name.empty()) return false; // Structs uint32_t sc = s.rd_u32(); for (uint32_t i = 0; i < sc; i++) { std::string nf = s.rd_str(); uint8_t flags = (uint8_t)nf.back(); StructDecl sd; sd.name = nf.substr(0, nf.size() - 1); sd.is_pub = (flags & 1) != 0; uint32_t fc = s.rd_u32(); for (uint32_t j = 0; j < fc; j++) { StructField f; f.name = s.rd_str(); f.type_name = s.rd_type(); sd.fields.push_back(f); } info.structs.push_back(std::move(sd)); } // Functions uint32_t fnc = s.rd_u32(); for (uint32_t i = 0; i < fnc; i++) { FnSig sig; sig.name = s.rd_str(); sig.ret_type = s.rd_type(); uint32_t pc = s.rd_u32(); for (uint32_t j = 0; j < pc; j++) sig.param_types.push_back(s.rd_type()); info.pub_fns.push_back(std::move(sig)); } // Constants uint32_t cc = s.rd_u32(); for (uint32_t i = 0; i < cc; i++) info.pub_const_names.push_back(s.rd_str()); return true; }