sim_kernel/pratt/
object.rs1use std::sync::Arc;
2
3use crate::{
4 CORE_TABLE_CLASS_ID, ClassRef, Cx, DefaultFactory, Expr, Factory, Fixity, Object, Result,
5 Symbol, Value,
6};
7
8use super::types::PrattTable;
9
10#[derive(Clone)]
14pub struct PrattTableObject {
15 pub symbol: Symbol,
17 pub table: PrattTable,
19}
20
21impl PrattTableObject {
22 pub fn new(symbol: Symbol, table: PrattTable) -> Self {
24 Self { symbol, table }
25 }
26}
27
28impl Object for PrattTableObject {
29 fn display(&self, _cx: &mut Cx) -> Result<String> {
30 Ok(format!("#<pratt-table {}>", self.symbol))
31 }
32
33 fn as_any(&self) -> &dyn std::any::Any {
34 self
35 }
36}
37
38impl crate::ObjectCompat for PrattTableObject {
39 fn class(&self, cx: &mut Cx) -> Result<ClassRef> {
40 if let Some(value) = cx
41 .registry()
42 .class_by_symbol(&Symbol::qualified("core", "Table"))
43 {
44 return Ok(value.clone());
45 }
46 cx.factory()
47 .class_stub(CORE_TABLE_CLASS_ID, Symbol::qualified("core", "Table"))
48 }
49 fn as_expr(&self, _cx: &mut Cx) -> Result<Expr> {
50 Ok(Expr::Symbol(self.symbol.clone()))
51 }
52 fn as_table(&self, cx: &mut Cx) -> Result<Value> {
53 let operators = self
54 .table
55 .operators()
56 .into_iter()
57 .map(|operator| {
58 cx.factory().table(vec![
59 (Symbol::new("symbol"), cx.factory().symbol(operator.symbol)?),
60 (
61 Symbol::new("fixity"),
62 cx.factory().string(
63 match operator.fixity {
64 Fixity::Prefix => "prefix",
65 Fixity::InfixLeft => "infix-left",
66 Fixity::InfixRight => "infix-right",
67 Fixity::Postfix => "postfix",
68 Fixity::Mixfix => "mixfix",
69 }
70 .to_owned(),
71 )?,
72 ),
73 (
74 Symbol::new("left-bp"),
75 cx.factory().number_literal(
76 Symbol::qualified("numbers", "f64"),
77 operator.left_bp.to_string(),
78 )?,
79 ),
80 (
81 Symbol::new("right-bp"),
82 cx.factory().number_literal(
83 Symbol::qualified("numbers", "f64"),
84 operator.right_bp.to_string(),
85 )?,
86 ),
87 ])
88 })
89 .collect::<Result<Vec<_>>>()?;
90
91 cx.factory().table(vec![
92 (
93 Symbol::new("symbol"),
94 cx.factory().symbol(self.symbol.clone())?,
95 ),
96 (Symbol::new("operators"), cx.factory().list(operators)?),
97 ])
98 }
99}
100
101pub fn pratt_table_value(symbol: Symbol, table: PrattTable) -> Value {
103 DefaultFactory
104 .opaque(Arc::new(PrattTableObject::new(symbol, table)))
105 .expect("pratt table object should always be boxable")
106}