1use crate::ast::*;
60use std::collections::HashMap;
61use std::fmt;
62
63#[derive(Debug, Clone, PartialEq)]
64pub enum Value {
65 Bool(bool),
66 UInt(u64),
67 Int(i64),
68 String(String),
69 Address(String),
70 Bytes(Vec<u8>),
71 Null,
72}
73
74impl Value {
75 pub fn to_bool(&self) -> Result<bool, InterpreterError> {
76 match self {
77 Value::Bool(b) => Ok(*b),
78 Value::UInt(n) => Ok(*n != 0),
79 Value::Int(n) => Ok(*n != 0),
80 Value::String(s) => Ok(!s.is_empty()),
81 Value::Address(addr) => Ok(addr != "0x0000000000000000000000000000000000000000"),
82 Value::Bytes(b) => Ok(!b.is_empty()),
83 Value::Null => Ok(false),
84 }
85 }
86
87 pub fn type_name(&self) -> &'static str {
88 match self {
89 Value::Bool(_) => "bool",
90 Value::UInt(_) => "uint",
91 Value::Int(_) => "int",
92 Value::String(_) => "string",
93 Value::Address(_) => "address",
94 Value::Bytes(_) => "bytes",
95 Value::Null => "null",
96 }
97 }
98}
99
100impl fmt::Display for Value {
101 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
102 match self {
103 Value::Bool(b) => write!(f, "{}", b),
104 Value::UInt(n) => write!(f, "{}", n),
105 Value::Int(n) => write!(f, "{}", n),
106 Value::String(s) => write!(f, "\"{}\"", s),
107 Value::Address(addr) => write!(f, "{}", addr),
108 Value::Bytes(b) => write!(f, "0x{}", hex::encode(b)),
109 Value::Null => write!(f, "null"),
110 }
111 }
112}
113
114#[derive(Debug, Clone, PartialEq)]
115pub enum InterpreterError {
116 UndefinedVariable(String),
117 TypeMismatch { expected: String, found: String },
118 UnsupportedOperation(String),
119 DivisionByZero,
120 InvalidLiteral(String),
121 FunctionNotFound(String),
122 InvalidArguments(String),
123 RuntimeError(String),
124}
125
126impl fmt::Display for InterpreterError {
127 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
128 match self {
129 InterpreterError::UndefinedVariable(name) => write!(f, "Undefined variable: {}", name),
130 InterpreterError::TypeMismatch { expected, found } => {
131 write!(f, "Type mismatch: expected {}, found {}", expected, found)
132 }
133 InterpreterError::UnsupportedOperation(op) => write!(f, "Unsupported operation: {}", op),
134 InterpreterError::DivisionByZero => write!(f, "Division by zero"),
135 InterpreterError::InvalidLiteral(lit) => write!(f, "Invalid literal: {}", lit),
136 InterpreterError::FunctionNotFound(name) => write!(f, "Function not found: {}", name),
137 InterpreterError::InvalidArguments(msg) => write!(f, "Invalid arguments: {}", msg),
138 InterpreterError::RuntimeError(msg) => write!(f, "Runtime error: {}", msg),
139 }
140 }
141}
142
143impl std::error::Error for InterpreterError {}
144
145#[derive(Debug, Clone)]
146pub struct InterpreterContext {
147 variables: HashMap<String, Value>,
148 functions: HashMap<String, BuiltinFunction>,
149}
150
151impl Default for InterpreterContext {
152 fn default() -> Self {
153 let mut context = Self {
154 variables: HashMap::new(),
155 functions: HashMap::new(),
156 };
157 context.register_builtin_functions();
158 context
159 }
160}
161
162impl InterpreterContext {
163 pub fn new() -> Self {
164 Self::default()
165 }
166
167 pub fn set_variable(&mut self, name: String, value: Value) {
168 self.variables.insert(name, value);
169 }
170
171 pub fn get_variable(&self, name: &str) -> Option<&Value> {
172 self.variables.get(name)
173 }
174
175 fn register_builtin_functions(&mut self) {
176 self.functions.insert("keccak256".to_string(), BuiltinFunction::Keccak256);
177 self.functions.insert("sha256".to_string(), BuiltinFunction::Sha256);
178 self.functions.insert("ripemd160".to_string(), BuiltinFunction::Ripemd160);
179 self.functions.insert("ecrecover".to_string(), BuiltinFunction::Ecrecover);
180 }
181
182 pub fn get_function(&self, name: &str) -> Option<&BuiltinFunction> {
183 self.functions.get(name)
184 }
185}
186
187#[derive(Debug, Clone, PartialEq)]
188pub enum BuiltinFunction {
189 Keccak256,
190 Sha256,
191 Ripemd160,
192 Ecrecover,
193}
194
195#[derive(Debug)]
196pub struct SolidityInterpreter {
197 context: InterpreterContext,
198}
199
200impl Default for SolidityInterpreter {
201 fn default() -> Self {
202 Self::new()
203 }
204}
205
206impl SolidityInterpreter {
207 pub fn new() -> Self {
208 Self {
209 context: InterpreterContext::new(),
210 }
211 }
212
213 pub fn with_context(context: InterpreterContext) -> Self {
214 Self { context }
215 }
216
217 pub fn context_mut(&mut self) -> &mut InterpreterContext {
218 &mut self.context
219 }
220
221 pub fn context(&self) -> &InterpreterContext {
222 &self.context
223 }
224
225 pub fn evaluate(&self, expr: &Expression) -> Result<Value, InterpreterError> {
226 match expr {
227 Expression::Literal(lit) => self.evaluate_literal(lit),
228 Expression::Identifier(name) => self.evaluate_identifier(name),
229 Expression::Binary(bin_expr) => self.evaluate_binary_expression(bin_expr),
230 Expression::Unary(unary_expr) => self.evaluate_unary_expression(unary_expr),
231 Expression::FunctionCall(call_expr) => self.evaluate_function_call(call_expr),
232 Expression::MemberAccess(member_expr) => self.evaluate_member_access(member_expr),
233 Expression::IndexAccess(index_expr) => self.evaluate_index_access(index_expr),
234 Expression::Conditional(cond_expr) => self.evaluate_conditional(cond_expr),
235 Expression::Tuple(tuple_expr) => self.evaluate_tuple(tuple_expr),
236 Expression::Array(array_expr) => self.evaluate_array(array_expr),
237 Expression::TypeConversion(conv_expr) => self.evaluate_type_conversion(conv_expr),
238 Expression::Assignment(_) => Err(InterpreterError::UnsupportedOperation(
239 "Assignment expressions are not supported in predicate evaluation".to_string(),
240 )),
241 Expression::New(_) => Err(InterpreterError::UnsupportedOperation(
242 "New expressions are not supported in predicate evaluation".to_string(),
243 )),
244 }
245 }
246
247 pub fn evaluate_predicate(&self, expr: &Expression) -> Result<bool, InterpreterError> {
248 let value = self.evaluate(expr)?;
249 value.to_bool()
250 }
251
252 fn evaluate_literal(&self, literal: &Literal) -> Result<Value, InterpreterError> {
253 match literal {
254 Literal::Boolean(b) => Ok(Value::Bool(*b)),
255 Literal::Number(num_lit) => self.evaluate_number_literal(num_lit),
256 Literal::String(str_lit) => Ok(Value::String(str_lit.value.clone())),
257 Literal::HexString(hex_lit) => self.evaluate_hex_string_literal(hex_lit),
258 Literal::UnicodeString(unicode_lit) => Ok(Value::String(unicode_lit.value.clone())),
259 }
260 }
261
262 fn evaluate_number_literal(&self, num_lit: &NumberLiteral) -> Result<Value, InterpreterError> {
263 let trimmed_value = num_lit.value.trim();
264 if let Ok(uint_val) = trimmed_value.parse::<u64>() {
265 Ok(Value::UInt(uint_val))
266 } else if let Ok(int_val) = trimmed_value.parse::<i64>() {
267 Ok(Value::Int(int_val))
268 } else {
269 Err(InterpreterError::InvalidLiteral(format!(
270 "Cannot parse number: {}",
271 num_lit.value
272 )))
273 }
274 }
275
276 fn evaluate_hex_string_literal(&self, hex_lit: &HexStringLiteral) -> Result<Value, InterpreterError> {
277 let hex_str = hex_lit.value.strip_prefix("0x").unwrap_or(&hex_lit.value);
278
279 match hex::decode(hex_str) {
281 Ok(bytes) => Ok(Value::Bytes(bytes)),
282 Err(_) => Err(InterpreterError::InvalidLiteral(format!(
283 "Invalid hex string: {}",
284 hex_lit.value
285 ))),
286 }
287 }
288
289 fn evaluate_identifier(&self, name: &str) -> Result<Value, InterpreterError> {
290 self.context
291 .get_variable(name)
292 .cloned()
293 .ok_or_else(|| InterpreterError::UndefinedVariable(name.to_string()))
294 }
295
296 fn evaluate_binary_expression(&self, bin_expr: &BinaryExpression) -> Result<Value, InterpreterError> {
297 let left = self.evaluate(&bin_expr.left)?;
298 let right = self.evaluate(&bin_expr.right)?;
299
300 match &bin_expr.operator {
301 BinaryOperator::Add => self.evaluate_add(&left, &right),
302 BinaryOperator::Sub => self.evaluate_sub(&left, &right),
303 BinaryOperator::Mul => self.evaluate_mul(&left, &right),
304 BinaryOperator::Div => self.evaluate_div(&left, &right),
305 BinaryOperator::Mod => self.evaluate_mod(&left, &right),
306 BinaryOperator::Exp => self.evaluate_exp(&left, &right),
307 BinaryOperator::Equal => Ok(Value::Bool(self.values_equal(&left, &right))),
308 BinaryOperator::NotEqual => Ok(Value::Bool(!self.values_equal(&left, &right))),
309 BinaryOperator::LessThan => self.evaluate_less_than(&left, &right),
310 BinaryOperator::LessThanOrEqual => self.evaluate_less_than_or_equal(&left, &right),
311 BinaryOperator::GreaterThan => self.evaluate_greater_than(&left, &right),
312 BinaryOperator::GreaterThanOrEqual => self.evaluate_greater_than_or_equal(&left, &right),
313 BinaryOperator::And => self.evaluate_logical_and(&left, &right),
314 BinaryOperator::Or => self.evaluate_logical_or(&left, &right),
315 BinaryOperator::BitAnd => self.evaluate_bit_and(&left, &right),
316 BinaryOperator::BitOr => self.evaluate_bit_or(&left, &right),
317 BinaryOperator::BitXor => self.evaluate_bit_xor(&left, &right),
318 BinaryOperator::ShiftLeft => self.evaluate_shift_left(&left, &right),
319 BinaryOperator::ShiftRight => self.evaluate_shift_right(&left, &right),
320 BinaryOperator::ShiftRightArithmetic => self.evaluate_shift_right_arithmetic(&left, &right),
321 }
322 }
323
324 fn evaluate_unary_expression(&self, unary_expr: &UnaryExpression) -> Result<Value, InterpreterError> {
325 let operand = self.evaluate(&unary_expr.operand)?;
326
327 match &unary_expr.operator {
328 UnaryOperator::Plus => Ok(operand), UnaryOperator::Minus => self.evaluate_unary_minus(&operand),
330 UnaryOperator::Not => self.evaluate_logical_not(&operand),
331 UnaryOperator::BitNot => self.evaluate_bit_not(&operand),
332 UnaryOperator::Increment | UnaryOperator::Decrement => {
333 Err(InterpreterError::UnsupportedOperation(
334 "Increment/decrement operators are not supported in predicate evaluation".to_string(),
335 ))
336 }
337 UnaryOperator::Delete => Err(InterpreterError::UnsupportedOperation(
338 "Delete operator is not supported in predicate evaluation".to_string(),
339 )),
340 }
341 }
342
343 fn evaluate_function_call(&self, call_expr: &FunctionCallExpression) -> Result<Value, InterpreterError> {
344 if let Expression::Identifier(func_name) = &*call_expr.function {
346 if let Some(builtin_func) = self.context.get_function(func_name) {
347 let args: Result<Vec<Value>, InterpreterError> = call_expr
348 .arguments
349 .iter()
350 .map(|arg| self.evaluate(arg))
351 .collect();
352 let args = args?;
353 return self.evaluate_builtin_function(builtin_func, &args);
354 }
355 }
356
357 Err(InterpreterError::FunctionNotFound(
358 "Complex function calls are not yet supported".to_string(),
359 ))
360 }
361
362 fn evaluate_member_access(&self, member_expr: &MemberAccessExpression) -> Result<Value, InterpreterError> {
363 let _object = self.evaluate(&member_expr.object)?;
364 Err(InterpreterError::UnsupportedOperation(
366 "Member access is not yet supported in predicate evaluation".to_string(),
367 ))
368 }
369
370 fn evaluate_index_access(&self, index_expr: &IndexAccessExpression) -> Result<Value, InterpreterError> {
371 let _object = self.evaluate(&index_expr.object)?;
372 Err(InterpreterError::UnsupportedOperation(
374 "Index access is not yet supported in predicate evaluation".to_string(),
375 ))
376 }
377
378 fn evaluate_conditional(&self, cond_expr: &ConditionalExpression) -> Result<Value, InterpreterError> {
379 let condition = self.evaluate(&cond_expr.condition)?;
380 let condition_bool = condition.to_bool()?;
381
382 if condition_bool {
383 self.evaluate(&cond_expr.true_expr)
384 } else {
385 self.evaluate(&cond_expr.false_expr)
386 }
387 }
388
389 fn evaluate_tuple(&self, tuple_expr: &TupleExpression) -> Result<Value, InterpreterError> {
390 Err(InterpreterError::UnsupportedOperation(
392 format!("Tuple expressions are not supported in predicate evaluation (found {} elements)",
393 tuple_expr.elements.len())
394 ))
395 }
396
397 fn evaluate_array(&self, array_expr: &ArrayExpression) -> Result<Value, InterpreterError> {
398 Err(InterpreterError::UnsupportedOperation(
400 format!("Array expressions are not supported in predicate evaluation (found {} elements)",
401 array_expr.elements.len())
402 ))
403 }
404
405 fn evaluate_type_conversion(&self, conv_expr: &TypeConversionExpression) -> Result<Value, InterpreterError> {
406 let value = self.evaluate(&conv_expr.expression)?;
407 Err(InterpreterError::UnsupportedOperation(
409 format!("Type conversion is not yet supported in predicate evaluation (converting {} to type)",
410 value.type_name())
411 ))
412 }
413
414 fn evaluate_add(&self, left: &Value, right: &Value) -> Result<Value, InterpreterError> {
415 match (left, right) {
416 (Value::UInt(a), Value::UInt(b)) => Ok(Value::UInt(a + b)),
417 (Value::Int(a), Value::Int(b)) => Ok(Value::Int(a + b)),
418 (Value::UInt(a), Value::Int(b)) => Ok(Value::Int(*a as i64 + b)),
419 (Value::Int(a), Value::UInt(b)) => Ok(Value::Int(a + *b as i64)),
420 (Value::String(a), Value::String(b)) => Ok(Value::String(format!("{}{}", a, b))),
421 _ => Err(InterpreterError::TypeMismatch {
422 expected: "numeric or string".to_string(),
423 found: format!("{} and {}", left.type_name(), right.type_name()),
424 }),
425 }
426 }
427
428 fn evaluate_sub(&self, left: &Value, right: &Value) -> Result<Value, InterpreterError> {
429 match (left, right) {
430 (Value::UInt(a), Value::UInt(b)) => {
431 if a >= b {
432 Ok(Value::UInt(a - b))
433 } else {
434 Ok(Value::Int(*a as i64 - *b as i64))
435 }
436 }
437 (Value::Int(a), Value::Int(b)) => Ok(Value::Int(a - b)),
438 (Value::UInt(a), Value::Int(b)) => Ok(Value::Int(*a as i64 - b)),
439 (Value::Int(a), Value::UInt(b)) => Ok(Value::Int(a - *b as i64)),
440 _ => Err(InterpreterError::TypeMismatch {
441 expected: "numeric".to_string(),
442 found: format!("{} and {}", left.type_name(), right.type_name()),
443 }),
444 }
445 }
446
447 fn evaluate_mul(&self, left: &Value, right: &Value) -> Result<Value, InterpreterError> {
448 match (left, right) {
449 (Value::UInt(a), Value::UInt(b)) => Ok(Value::UInt(a * b)),
450 (Value::Int(a), Value::Int(b)) => Ok(Value::Int(a * b)),
451 (Value::UInt(a), Value::Int(b)) => Ok(Value::Int(*a as i64 * b)),
452 (Value::Int(a), Value::UInt(b)) => Ok(Value::Int(a * *b as i64)),
453 _ => Err(InterpreterError::TypeMismatch {
454 expected: "numeric".to_string(),
455 found: format!("{} and {}", left.type_name(), right.type_name()),
456 }),
457 }
458 }
459
460 fn evaluate_div(&self, left: &Value, right: &Value) -> Result<Value, InterpreterError> {
461 match (left, right) {
462 (Value::UInt(a), Value::UInt(b)) => {
463 if *b == 0 {
464 Err(InterpreterError::DivisionByZero)
465 } else {
466 Ok(Value::UInt(a / b))
467 }
468 }
469 (Value::Int(a), Value::Int(b)) => {
470 if *b == 0 {
471 Err(InterpreterError::DivisionByZero)
472 } else {
473 Ok(Value::Int(a / b))
474 }
475 }
476 (Value::UInt(a), Value::Int(b)) => {
477 if *b == 0 {
478 Err(InterpreterError::DivisionByZero)
479 } else {
480 Ok(Value::Int(*a as i64 / b))
481 }
482 }
483 (Value::Int(a), Value::UInt(b)) => {
484 if *b == 0 {
485 Err(InterpreterError::DivisionByZero)
486 } else {
487 Ok(Value::Int(a / *b as i64))
488 }
489 }
490 _ => Err(InterpreterError::TypeMismatch {
491 expected: "numeric".to_string(),
492 found: format!("{} and {}", left.type_name(), right.type_name()),
493 }),
494 }
495 }
496
497 fn evaluate_mod(&self, left: &Value, right: &Value) -> Result<Value, InterpreterError> {
498 match (left, right) {
499 (Value::UInt(a), Value::UInt(b)) => {
500 if *b == 0 {
501 Err(InterpreterError::DivisionByZero)
502 } else {
503 Ok(Value::UInt(a % b))
504 }
505 }
506 (Value::Int(a), Value::Int(b)) => {
507 if *b == 0 {
508 Err(InterpreterError::DivisionByZero)
509 } else {
510 Ok(Value::Int(a % b))
511 }
512 }
513 _ => Err(InterpreterError::TypeMismatch {
514 expected: "numeric".to_string(),
515 found: format!("{} and {}", left.type_name(), right.type_name()),
516 }),
517 }
518 }
519
520 fn evaluate_exp(&self, left: &Value, right: &Value) -> Result<Value, InterpreterError> {
521 match (left, right) {
522 (Value::UInt(base), Value::UInt(exp)) => {
523 if *exp > 32 {
524 Err(InterpreterError::RuntimeError("Exponent too large".to_string()))
525 } else {
526 Ok(Value::UInt(base.pow(*exp as u32)))
527 }
528 }
529 _ => Err(InterpreterError::TypeMismatch {
530 expected: "uint".to_string(),
531 found: format!("{} and {}", left.type_name(), right.type_name()),
532 }),
533 }
534 }
535
536 fn values_equal(&self, left: &Value, right: &Value) -> bool {
537 match (left, right) {
538 (Value::Bool(a), Value::Bool(b)) => a == b,
539 (Value::UInt(a), Value::UInt(b)) => a == b,
540 (Value::Int(a), Value::Int(b)) => a == b,
541 (Value::UInt(a), Value::Int(b)) => *a as i64 == *b,
542 (Value::Int(a), Value::UInt(b)) => *a == *b as i64,
543 (Value::String(a), Value::String(b)) => a == b,
544 (Value::Address(a), Value::Address(b)) => a == b,
545 (Value::Bytes(a), Value::Bytes(b)) => a == b,
546 (Value::Null, Value::Null) => true,
547 _ => false,
548 }
549 }
550
551 fn evaluate_less_than(&self, left: &Value, right: &Value) -> Result<Value, InterpreterError> {
552 match (left, right) {
553 (Value::UInt(a), Value::UInt(b)) => Ok(Value::Bool(a < b)),
554 (Value::Int(a), Value::Int(b)) => Ok(Value::Bool(a < b)),
555 (Value::UInt(a), Value::Int(b)) => Ok(Value::Bool((*a as i64) < *b)),
556 (Value::Int(a), Value::UInt(b)) => Ok(Value::Bool(*a < (*b as i64))),
557 _ => Err(InterpreterError::TypeMismatch {
558 expected: "numeric".to_string(),
559 found: format!("{} and {}", left.type_name(), right.type_name()),
560 }),
561 }
562 }
563
564 fn evaluate_less_than_or_equal(&self, left: &Value, right: &Value) -> Result<Value, InterpreterError> {
565 match (left, right) {
566 (Value::UInt(a), Value::UInt(b)) => Ok(Value::Bool(a <= b)),
567 (Value::Int(a), Value::Int(b)) => Ok(Value::Bool(a <= b)),
568 (Value::UInt(a), Value::Int(b)) => Ok(Value::Bool((*a as i64) <= *b)),
569 (Value::Int(a), Value::UInt(b)) => Ok(Value::Bool(*a <= (*b as i64))),
570 _ => Err(InterpreterError::TypeMismatch {
571 expected: "numeric".to_string(),
572 found: format!("{} and {}", left.type_name(), right.type_name()),
573 }),
574 }
575 }
576
577 fn evaluate_greater_than(&self, left: &Value, right: &Value) -> Result<Value, InterpreterError> {
578 match (left, right) {
579 (Value::UInt(a), Value::UInt(b)) => Ok(Value::Bool(a > b)),
580 (Value::Int(a), Value::Int(b)) => Ok(Value::Bool(a > b)),
581 (Value::UInt(a), Value::Int(b)) => Ok(Value::Bool((*a as i64) > *b)),
582 (Value::Int(a), Value::UInt(b)) => Ok(Value::Bool(*a > (*b as i64))),
583 _ => Err(InterpreterError::TypeMismatch {
584 expected: "numeric".to_string(),
585 found: format!("{} and {}", left.type_name(), right.type_name()),
586 }),
587 }
588 }
589
590 fn evaluate_greater_than_or_equal(&self, left: &Value, right: &Value) -> Result<Value, InterpreterError> {
591 match (left, right) {
592 (Value::UInt(a), Value::UInt(b)) => Ok(Value::Bool(a >= b)),
593 (Value::Int(a), Value::Int(b)) => Ok(Value::Bool(a >= b)),
594 (Value::UInt(a), Value::Int(b)) => Ok(Value::Bool((*a as i64) >= *b)),
595 (Value::Int(a), Value::UInt(b)) => Ok(Value::Bool(*a >= (*b as i64))),
596 _ => Err(InterpreterError::TypeMismatch {
597 expected: "numeric".to_string(),
598 found: format!("{} and {}", left.type_name(), right.type_name()),
599 }),
600 }
601 }
602
603 fn evaluate_logical_and(&self, left: &Value, right: &Value) -> Result<Value, InterpreterError> {
604 let left_bool = left.to_bool()?;
605 let right_bool = right.to_bool()?;
606 Ok(Value::Bool(left_bool && right_bool))
607 }
608
609 fn evaluate_logical_or(&self, left: &Value, right: &Value) -> Result<Value, InterpreterError> {
610 let left_bool = left.to_bool()?;
611 let right_bool = right.to_bool()?;
612 Ok(Value::Bool(left_bool || right_bool))
613 }
614
615 fn evaluate_bit_and(&self, left: &Value, right: &Value) -> Result<Value, InterpreterError> {
616 match (left, right) {
617 (Value::UInt(a), Value::UInt(b)) => Ok(Value::UInt(a & b)),
618 (Value::Int(a), Value::Int(b)) => Ok(Value::Int(a & b)),
619 _ => Err(InterpreterError::TypeMismatch {
620 expected: "integer".to_string(),
621 found: format!("{} and {}", left.type_name(), right.type_name()),
622 }),
623 }
624 }
625
626 fn evaluate_bit_or(&self, left: &Value, right: &Value) -> Result<Value, InterpreterError> {
627 match (left, right) {
628 (Value::UInt(a), Value::UInt(b)) => Ok(Value::UInt(a | b)),
629 (Value::Int(a), Value::Int(b)) => Ok(Value::Int(a | b)),
630 _ => Err(InterpreterError::TypeMismatch {
631 expected: "integer".to_string(),
632 found: format!("{} and {}", left.type_name(), right.type_name()),
633 }),
634 }
635 }
636
637 fn evaluate_bit_xor(&self, left: &Value, right: &Value) -> Result<Value, InterpreterError> {
638 match (left, right) {
639 (Value::UInt(a), Value::UInt(b)) => Ok(Value::UInt(a ^ b)),
640 (Value::Int(a), Value::Int(b)) => Ok(Value::Int(a ^ b)),
641 _ => Err(InterpreterError::TypeMismatch {
642 expected: "integer".to_string(),
643 found: format!("{} and {}", left.type_name(), right.type_name()),
644 }),
645 }
646 }
647
648 fn evaluate_shift_left(&self, left: &Value, right: &Value) -> Result<Value, InterpreterError> {
649 match (left, right) {
650 (Value::UInt(a), Value::UInt(b)) => {
651 if *b > 64 {
652 Err(InterpreterError::RuntimeError("Shift amount too large".to_string()))
653 } else {
654 Ok(Value::UInt(a << b))
655 }
656 }
657 _ => Err(InterpreterError::TypeMismatch {
658 expected: "uint".to_string(),
659 found: format!("{} and {}", left.type_name(), right.type_name()),
660 }),
661 }
662 }
663
664 fn evaluate_shift_right(&self, left: &Value, right: &Value) -> Result<Value, InterpreterError> {
665 match (left, right) {
666 (Value::UInt(a), Value::UInt(b)) => {
667 if *b > 64 {
668 Err(InterpreterError::RuntimeError("Shift amount too large".to_string()))
669 } else {
670 Ok(Value::UInt(a >> b))
671 }
672 }
673 _ => Err(InterpreterError::TypeMismatch {
674 expected: "uint".to_string(),
675 found: format!("{} and {}", left.type_name(), right.type_name()),
676 }),
677 }
678 }
679
680 fn evaluate_shift_right_arithmetic(&self, left: &Value, right: &Value) -> Result<Value, InterpreterError> {
681 match (left, right) {
682 (Value::Int(a), Value::UInt(b)) => {
683 if *b > 64 {
684 Err(InterpreterError::RuntimeError("Shift amount too large".to_string()))
685 } else {
686 Ok(Value::Int(a >> b))
687 }
688 }
689 _ => Err(InterpreterError::TypeMismatch {
690 expected: "int and uint".to_string(),
691 found: format!("{} and {}", left.type_name(), right.type_name()),
692 }),
693 }
694 }
695
696 fn evaluate_unary_minus(&self, operand: &Value) -> Result<Value, InterpreterError> {
697 match operand {
698 Value::UInt(n) => Ok(Value::Int(-(*n as i64))),
699 Value::Int(n) => Ok(Value::Int(-n)),
700 _ => Err(InterpreterError::TypeMismatch {
701 expected: "numeric".to_string(),
702 found: operand.type_name().to_string(),
703 }),
704 }
705 }
706
707 fn evaluate_logical_not(&self, operand: &Value) -> Result<Value, InterpreterError> {
708 let bool_val = operand.to_bool()?;
709 Ok(Value::Bool(!bool_val))
710 }
711
712 fn evaluate_bit_not(&self, operand: &Value) -> Result<Value, InterpreterError> {
713 match operand {
714 Value::UInt(n) => Ok(Value::UInt(!n)),
715 Value::Int(n) => Ok(Value::Int(!n)),
716 _ => Err(InterpreterError::TypeMismatch {
717 expected: "integer".to_string(),
718 found: operand.type_name().to_string(),
719 }),
720 }
721 }
722
723 fn evaluate_builtin_function(
724 &self,
725 func: &BuiltinFunction,
726 args: &[Value],
727 ) -> Result<Value, InterpreterError> {
728 match func {
729 BuiltinFunction::Keccak256 => {
730 if args.len() != 1 {
731 return Err(InterpreterError::InvalidArguments(
732 "keccak256 expects exactly 1 argument".to_string(),
733 ));
734 }
735 Ok(Value::Bytes(vec![0u8; 32])) }
737 BuiltinFunction::Sha256 => {
738 if args.len() != 1 {
739 return Err(InterpreterError::InvalidArguments(
740 "sha256 expects exactly 1 argument".to_string(),
741 ));
742 }
743 Ok(Value::Bytes(vec![1u8; 32])) }
745 BuiltinFunction::Ripemd160 => {
746 if args.len() != 1 {
747 return Err(InterpreterError::InvalidArguments(
748 "ripemd160 expects exactly 1 argument".to_string(),
749 ));
750 }
751 Ok(Value::Bytes(vec![2u8; 20])) }
753 BuiltinFunction::Ecrecover => {
754 if args.len() != 4 {
755 return Err(InterpreterError::InvalidArguments(
756 "ecrecover expects exactly 4 arguments".to_string(),
757 ));
758 }
759 Ok(Value::Address("0x0000000000000000000000000000000000000000".to_string()))
761 }
762 }
763 }
764}
765
766#[cfg(test)]
767mod tests {
768 use super::*;
769 use crate::parser::parse_expression; #[test]
772 fn test_evaluate_boolean_literal() {
773 let interpreter = SolidityInterpreter::new();
774
775 let true_expr = Expression::Literal(Literal::Boolean(true));
776 let false_expr = Expression::Literal(Literal::Boolean(false));
777
778 assert_eq!(interpreter.evaluate(&true_expr).unwrap(), Value::Bool(true));
779 assert_eq!(interpreter.evaluate(&false_expr).unwrap(), Value::Bool(false));
780 }
781
782 #[test]
783 fn test_evaluate_number_literal() {
784 let interpreter = SolidityInterpreter::new();
785
786 let num_expr = Expression::Literal(Literal::Number(NumberLiteral {
787 value: "42".to_string(),
788 sub_denomination: None,
789 }));
790
791 assert_eq!(interpreter.evaluate(&num_expr).unwrap(), Value::UInt(42));
792 }
793
794 #[test]
795 fn test_evaluate_binary_comparison() {
796 let interpreter = SolidityInterpreter::new();
797
798 let left = Box::new(Expression::Literal(Literal::Number(NumberLiteral {
799 value: "10".to_string(),
800 sub_denomination: None,
801 })));
802
803 let right = Box::new(Expression::Literal(Literal::Number(NumberLiteral {
804 value: "5".to_string(),
805 sub_denomination: None,
806 })));
807
808 let gt_expr = Expression::Binary(BinaryExpression {
809 left: left.clone(),
810 operator: BinaryOperator::GreaterThan,
811 right: right.clone(),
812 });
813
814 let lt_expr = Expression::Binary(BinaryExpression {
815 left: left.clone(),
816 operator: BinaryOperator::LessThan,
817 right: right.clone(),
818 });
819
820 assert!(interpreter.evaluate_predicate(>_expr).unwrap());
821 assert!(!interpreter.evaluate_predicate(<_expr).unwrap());
822 }
823
824 #[test]
825 fn test_evaluate_logical_and() {
826 let interpreter = SolidityInterpreter::new();
827
828 let true_expr = Box::new(Expression::Literal(Literal::Boolean(true)));
829 let false_expr = Box::new(Expression::Literal(Literal::Boolean(false)));
830
831 let and_expr = Expression::Binary(BinaryExpression {
832 left: true_expr.clone(),
833 operator: BinaryOperator::And,
834 right: false_expr.clone(),
835 });
836
837 assert!(!interpreter.evaluate_predicate(&and_expr).unwrap());
838 }
839
840 #[test]
841 fn test_evaluate_logical_not() {
842 let interpreter = SolidityInterpreter::new();
843
844 let true_expr = Box::new(Expression::Literal(Literal::Boolean(true)));
845
846 let not_expr = Expression::Unary(UnaryExpression {
847 operator: UnaryOperator::Not,
848 operand: true_expr,
849 is_prefix: true,
850 });
851
852 assert!(!interpreter.evaluate_predicate(¬_expr).unwrap());
853 }
854
855 #[test]
856 fn test_evaluate_conditional() {
857 let interpreter = SolidityInterpreter::new();
858
859 let condition = Box::new(Expression::Literal(Literal::Boolean(true)));
860 let true_branch = Box::new(Expression::Literal(Literal::Number(NumberLiteral {
861 value: "1".to_string(),
862 sub_denomination: None,
863 })));
864 let false_branch = Box::new(Expression::Literal(Literal::Number(NumberLiteral {
865 value: "0".to_string(),
866 sub_denomination: None,
867 })));
868
869 let cond_expr = Expression::Conditional(ConditionalExpression {
870 condition,
871 true_expr: true_branch,
872 false_expr: false_branch,
873 });
874
875 assert_eq!(interpreter.evaluate(&cond_expr).unwrap(), Value::UInt(1));
876 }
877
878 #[test]
879 fn test_variable_lookup() {
880 let mut interpreter = SolidityInterpreter::new();
881 interpreter.context_mut().set_variable("x".to_string(), Value::Bool(true));
882
883 let var_expr = Expression::Identifier("x".to_string());
884
885 assert!(interpreter.evaluate_predicate(&var_expr).unwrap());
886 }
887
888 #[test]
889 fn test_undefined_variable() {
890 let interpreter = SolidityInterpreter::new();
891
892 let var_expr = Expression::Identifier("undefined".to_string());
893
894 match interpreter.evaluate(&var_expr) {
895 Err(InterpreterError::UndefinedVariable(name)) => {
896 assert_eq!(name, "undefined");
897 }
898 _ => panic!("Expected UndefinedVariable error"),
899 }
900 }
901
902 #[test]
903 fn test_value_to_bool_conversion() {
904 assert!(Value::Bool(true).to_bool().unwrap());
905 assert!(!Value::Bool(false).to_bool().unwrap());
906 assert!(Value::UInt(1).to_bool().unwrap());
907 assert!(!Value::UInt(0).to_bool().unwrap());
908 assert!(Value::Int(-1).to_bool().unwrap());
909 assert!(!Value::Int(0).to_bool().unwrap());
910 assert!(Value::String("hello".to_string()).to_bool().unwrap());
911 assert!(!Value::String("".to_string()).to_bool().unwrap());
912 assert!(!Value::Null.to_bool().unwrap());
913 }
914
915 #[test]
916 fn test_evaluate_new_value_gt_zero_predicate() {
917 let mut interpreter = SolidityInterpreter::new();
918
919 let new_value_ident = Expression::Identifier("_newValue".to_string());
921 let zero_literal = Expression::Literal(Literal::Number(NumberLiteral {
922 value: "0".to_string(),
923 sub_denomination: None,
924 }));
925 let expr = Expression::Binary(BinaryExpression {
926 left: Box::new(new_value_ident),
927 operator: BinaryOperator::GreaterThan,
928 right: Box::new(zero_literal),
929 });
930
931 interpreter.context_mut().set_variable("_newValue".to_string(), Value::UInt(42));
934 match interpreter.evaluate_predicate(&expr) {
935 Ok(result) => assert!(result, "Expected '42 > 0' to be true"),
936 Err(e) => panic!("Evaluation failed for _newValue = 42: {}", e),
937 }
938
939 interpreter.context_mut().set_variable("_newValue".to_string(), Value::UInt(0));
942 match interpreter.evaluate_predicate(&expr) {
943 Ok(result) => assert!(!result, "Expected '0 > 0' to be false"),
944 Err(e) => panic!("Evaluation failed for _newValue = 0: {}", e),
945 }
946
947 interpreter.context_mut().set_variable("_newValue".to_string(), Value::UInt(1));
950 match interpreter.evaluate_predicate(&expr) {
951 Ok(result) => assert!(result, "Expected '1 > 0' to be true"),
952 Err(e) => panic!("Evaluation failed for _newValue = 1: {}", e),
953 }
954 }
955
956 #[test]
957 fn test_evaluate_parsed_expression_new_value_gt_zero() {
958 let mut interpreter = SolidityInterpreter::new();
959
960 let expression_str = "_newValue > 0";
962 let parsed_expr = match parse_expression(expression_str) {
963 Ok(expr) => expr,
964 Err(e) => panic!("Failed to parse expression '{}': {}", expression_str, e),
965 };
966
967 interpreter.context_mut().set_variable("_newValue".to_string(), Value::UInt(42));
970 match interpreter.evaluate_predicate(&parsed_expr) {
971 Ok(result) => assert!(result, "Expected '42 > 0' (parsed) to be true"),
972 Err(e) => panic!("Parsed evaluation failed for _newValue = 42: {}", e),
973 }
974
975 interpreter.context_mut().set_variable("_newValue".to_string(), Value::UInt(0));
978 match interpreter.evaluate_predicate(&parsed_expr) {
979 Ok(result) => assert!(!result, "Expected '0 > 0' (parsed) to be false"),
980 Err(e) => panic!("Parsed evaluation failed for _newValue = 0: {}", e),
981 }
982
983 interpreter.context_mut().set_variable("_newValue".to_string(), Value::UInt(1));
986 match interpreter.evaluate_predicate(&parsed_expr) {
987 Ok(result) => assert!(result, "Expected '1 > 0' (parsed) to be true"),
988 Err(e) => panic!("Parsed evaluation failed for _newValue = 1: {}", e),
989 }
990 }
991
992 #[test]
993 fn test_evaluate_parsed_expression_new_value_gt_zero_signed() {
994 let mut interpreter = SolidityInterpreter::new();
995
996 let expression_str = "_newValue > 0";
998 let parsed_expr = match parse_expression(expression_str) {
999 Ok(expr) => expr,
1000 Err(e) => panic!("Failed to parse expression '{}': {}", expression_str, e),
1001 };
1002
1003 interpreter.context_mut().set_variable("_newValue".to_string(), Value::Int(42));
1006 match interpreter.evaluate_predicate(&parsed_expr) {
1007 Ok(result) => assert!(result, "Expected '42 > 0' (parsed) to be true"),
1008 Err(e) => panic!("Parsed evaluation failed for _newValue = 42: {}", e),
1009 }
1010
1011 interpreter.context_mut().set_variable("_newValue".to_string(), Value::Int(0));
1014 match interpreter.evaluate_predicate(&parsed_expr) {
1015 Ok(result) => assert!(!result, "Expected '0 > 0' (parsed) to be false"),
1016 Err(e) => panic!("Parsed evaluation failed for _newValue = 0: {}", e),
1017 }
1018
1019 interpreter.context_mut().set_variable("_newValue".to_string(), Value::Int(1));
1022 match interpreter.evaluate_predicate(&parsed_expr) {
1023 Ok(result) => assert!(result, "Expected '1 > 0' (parsed) to be true"),
1024 Err(e) => panic!("Parsed evaluation failed for _newValue = 1: {}", e),
1025 }
1026 }
1027
1028
1029}