surfer_translation_types/
translator.rs1#[cfg(feature = "wasm_plugins")]
4use extism_convert::{FromBytes, Json, ToBytes};
5use eyre::Result;
6use num::BigUint;
7use serde::{Deserialize, Serialize};
8use std::sync::mpsc::Sender;
9
10use crate::result::TranslationResult;
11use crate::{
12 TranslationPreference, ValueKind, VariableEncoding, VariableInfo, VariableMeta, VariableValue,
13};
14
15#[cfg_attr(feature = "wasm_plugins", derive(FromBytes, ToBytes))]
16#[cfg_attr(feature = "wasm_plugins", encoding(Json))]
17#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
18pub enum TrueName {
19 SourceCode {
25 line_number: usize,
26 before: String,
27 this: String,
28 after: String,
29 },
30}
31
32#[cfg_attr(feature = "wasm_plugins", derive(FromBytes, ToBytes))]
41#[cfg_attr(feature = "wasm_plugins", encoding(Json))]
42#[derive(Clone, Debug, Serialize, Deserialize)]
43pub struct VariableNameInfo {
44 pub true_name: Option<TrueName>,
47 pub priority: Option<i32>,
56}
57
58#[cfg_attr(feature = "wasm_plugins", derive(FromBytes, ToBytes))]
59#[cfg_attr(feature = "wasm_plugins", encoding(Json))]
60#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
61pub enum WaveSource {
62 File(String),
63 Data,
64 DragAndDrop(Option<String>),
65 Url(String),
66 Cxxrtl,
67}
68
69pub trait Translator<VarId, ScopeId, Message>: Send + Sync {
71 fn name(&self) -> String;
72
73 fn set_wave_source(&self, _wave_source: Option<WaveSource>) {}
75
76 fn translate(
77 &self,
78 variable: &VariableMeta<VarId, ScopeId>,
79 value: &VariableValue,
80 ) -> Result<TranslationResult>;
81
82 fn variable_info(&self, variable: &VariableMeta<VarId, ScopeId>) -> Result<VariableInfo>;
83
84 fn translates(&self, variable: &VariableMeta<VarId, ScopeId>) -> Result<TranslationPreference>;
86
87 fn reload(&self, _sender: Sender<Message>) {}
91
92 fn variable_name_info(
96 &self,
97 variable: &VariableMeta<VarId, ScopeId>,
98 ) -> Option<VariableNameInfo> {
99 let _ = variable;
103 None
104 }
105}
106
107pub trait BasicTranslator<VarId, ScopeId>: Send + Sync {
109 fn name(&self) -> String;
110
111 fn basic_translate(&self, num_bits: u64, value: &VariableValue) -> (String, ValueKind);
112
113 fn translates(&self, variable: &VariableMeta<VarId, ScopeId>) -> Result<TranslationPreference> {
114 translates_all_bit_types(variable)
115 }
116
117 fn variable_info(&self, _variable: &VariableMeta<VarId, ScopeId>) -> Result<VariableInfo> {
118 Ok(VariableInfo::Bits)
119 }
120}
121
122enum NumberParseResult {
123 Numerical(BigUint),
124 Unparsable(String, ValueKind),
125}
126
127fn map_vector_variable(s: &str) -> NumberParseResult {
130 if let Some(val) = BigUint::parse_bytes(s.as_bytes(), 2) {
131 NumberParseResult::Numerical(val)
132 } else if s.contains('x') {
133 NumberParseResult::Unparsable("UNDEF".to_string(), ValueKind::Undef)
134 } else if s.contains('z') {
135 NumberParseResult::Unparsable("HIGHIMP".to_string(), ValueKind::HighImp)
136 } else if s.contains('-') {
137 NumberParseResult::Unparsable("DON'T CARE".to_string(), ValueKind::DontCare)
138 } else if s.contains('u') {
139 NumberParseResult::Unparsable("UNDEF".to_string(), ValueKind::Undef)
140 } else if s.contains('w') {
141 NumberParseResult::Unparsable("UNDEF WEAK".to_string(), ValueKind::Undef)
142 } else if s.contains('h') || s.contains('l') {
143 NumberParseResult::Unparsable("WEAK".to_string(), ValueKind::Weak)
144 } else {
145 NumberParseResult::Unparsable("UNKNOWN VALUES".to_string(), ValueKind::Undef)
146 }
147}
148
149impl VariableValue {
150 pub fn parse_biguint(self) -> Result<BigUint, (String, ValueKind)> {
151 match self {
152 VariableValue::BigUint(v) => Ok(v),
153 VariableValue::String(s) => match map_vector_variable(&s) {
154 NumberParseResult::Unparsable(v, k) => Err((v, k)),
155 NumberParseResult::Numerical(v) => Ok(v),
156 },
157 }
158 }
159}
160
161pub fn translates_all_bit_types<VarId, ScopeId>(
162 variable: &VariableMeta<VarId, ScopeId>,
163) -> Result<TranslationPreference> {
164 if variable.encoding == VariableEncoding::BitVector {
165 Ok(TranslationPreference::Yes)
166 } else {
167 Ok(TranslationPreference::No)
168 }
169}