pr 05.c
This commit is contained in:
parent
00ad4730c8
commit
4cee158206
@ -1,6 +1,6 @@
|
||||
use crate::analysis::symbols::SymbolId;
|
||||
use crate::analysis::symbols::{SymbolArena, SymbolId};
|
||||
use crate::frontends::pbs::ast::NodeId;
|
||||
use prometeu_analysis::interner::NameId;
|
||||
use prometeu_analysis::interner::{NameId, NameInterner};
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
#[derive(Copy, Clone, Debug, Eq, PartialEq, Hash, Serialize, Deserialize)]
|
||||
@ -38,6 +38,43 @@ impl TypeArena {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn format_type(
|
||||
type_id: TypeId,
|
||||
arena: &TypeArena,
|
||||
interner: &NameInterner,
|
||||
symbols: Option<&SymbolArena>,
|
||||
) -> String {
|
||||
let kind = arena.kind(type_id);
|
||||
match kind {
|
||||
TypeKind::Primitive { name } => interner.resolve(*name).to_string(),
|
||||
TypeKind::Optional { inner } => {
|
||||
let inner_str = format_type(*inner, arena, interner, symbols);
|
||||
format!("optional<{}>", inner_str)
|
||||
}
|
||||
TypeKind::Result { ok, err } => {
|
||||
let ok_str = format_type(*ok, arena, interner, symbols);
|
||||
let err_str = format_type(*err, arena, interner, symbols);
|
||||
format!("result<{}, {}>", ok_str, err_str)
|
||||
}
|
||||
TypeKind::Array { inner, len } => {
|
||||
let inner_str = format_type(*inner, arena, interner, symbols);
|
||||
if let Some(n) = len {
|
||||
format!("array<{}>[{}]", inner_str, n)
|
||||
} else {
|
||||
format!("array<{}>", inner_str)
|
||||
}
|
||||
}
|
||||
TypeKind::Struct { sym } => {
|
||||
if let Some(symbol_arena) = symbols {
|
||||
let symbol = symbol_arena.get(*sym);
|
||||
interner.resolve(symbol.name).to_string()
|
||||
} else {
|
||||
format!("struct#{}", sym.0)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Default, Serialize, Deserialize)]
|
||||
pub struct TypeFacts {
|
||||
pub node_type: Vec<Option<TypeId>>,
|
||||
@ -122,14 +159,78 @@ mod tests {
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn type_facts_auto_grows_for_symbol_ids() {
|
||||
let mut facts = TypeFacts::new();
|
||||
let sid = SymbolId(20);
|
||||
let tid = TypeId(2);
|
||||
fn format_type_optional() {
|
||||
let mut arena = TypeArena::new();
|
||||
let mut interner = NameInterner::new();
|
||||
let int_name = interner.intern("int");
|
||||
let int_t = arena.intern_type(TypeKind::Primitive { name: int_name });
|
||||
let opt_t = arena.intern_type(TypeKind::Optional { inner: int_t });
|
||||
|
||||
assert_eq!(facts.get_symbol_type(sid), None);
|
||||
facts.set_symbol_type(sid, tid);
|
||||
assert_eq!(facts.get_symbol_type(sid), Some(tid));
|
||||
assert!(facts.symbol_type.len() > 20);
|
||||
let formatted = format_type(opt_t, &arena, &interner, None);
|
||||
assert_eq!(formatted, "optional<int>");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn format_type_result() {
|
||||
let mut arena = TypeArena::new();
|
||||
let mut interner = NameInterner::new();
|
||||
let int_name = interner.intern("int");
|
||||
let string_name = interner.intern("string");
|
||||
let int_t = arena.intern_type(TypeKind::Primitive { name: int_name });
|
||||
let string_t = arena.intern_type(TypeKind::Primitive { name: string_name });
|
||||
let res_t = arena.intern_type(TypeKind::Result { ok: int_t, err: string_t });
|
||||
|
||||
let formatted = format_type(res_t, &arena, &interner, None);
|
||||
assert_eq!(formatted, "result<int, string>");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn format_type_array_len() {
|
||||
let mut arena = TypeArena::new();
|
||||
let mut interner = NameInterner::new();
|
||||
let bool_name = interner.intern("bool");
|
||||
let bool_t = arena.intern_type(TypeKind::Primitive { name: bool_name });
|
||||
|
||||
let arr_dynamic = arena.intern_type(TypeKind::Array { inner: bool_t, len: None });
|
||||
let arr_fixed = arena.intern_type(TypeKind::Array { inner: bool_t, len: Some(10) });
|
||||
|
||||
assert_eq!(format_type(arr_dynamic, &arena, &interner, None), "array<bool>");
|
||||
assert_eq!(format_type(arr_fixed, &arena, &interner, None), "array<bool>[10]");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn format_type_struct_with_arena() {
|
||||
use crate::analysis::symbols::{Symbol, SymbolKind};
|
||||
use crate::common::spans::Span;
|
||||
|
||||
let mut arena = TypeArena::new();
|
||||
let mut interner = NameInterner::new();
|
||||
let mut symbols = SymbolArena::new();
|
||||
|
||||
let my_struct_name = interner.intern("MyStruct");
|
||||
let sym_id = symbols.insert(Symbol {
|
||||
name: my_struct_name,
|
||||
kind: SymbolKind::Struct,
|
||||
exported: false,
|
||||
module: 0,
|
||||
decl_span: Span::new(0, 0, 0),
|
||||
});
|
||||
|
||||
let struct_t = arena.intern_type(TypeKind::Struct { sym: sym_id });
|
||||
|
||||
let formatted = format_type(struct_t, &arena, &interner, Some(&symbols));
|
||||
assert_eq!(formatted, "MyStruct");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn format_type_struct_fallback() {
|
||||
let mut arena = TypeArena::new();
|
||||
let interner = NameInterner::new();
|
||||
let sym_id = SymbolId(42);
|
||||
|
||||
let struct_t = arena.intern_type(TypeKind::Struct { sym: sym_id });
|
||||
|
||||
let formatted = format_type(struct_t, &arena, &interner, None);
|
||||
assert_eq!(formatted, "struct#42");
|
||||
}
|
||||
}
|
||||
|
||||
Binary file not shown.
Loading…
x
Reference in New Issue
Block a user