<commit_before>use utils::u256::U256;
use std::cmp::{min};
use super::opcode::Opcode;

pub struct PC<'a> {
    pub position: usize,
    code: &'a [u8],
    stopped: bool
}

impl<'a> PC<'a> {
    pub fn new(code: &'a [u8]) -> Self {
        PC {
            position: 0,
            code: code,
            stopped: false,
        }
    }

    pub fn peek_opcode(&self) -> Opcode {
        let position = self.position;
        let opcode: Opcode = self.code[position].into();
        opcode
    }

    pub fn read_opcode(&mut self) -> Opcode {
        let position = self.position;
        let opcode: Opcode = self.code[position].into();
        self.position += 1;
        opcode
    }

    pub fn stop(&mut self) {
        self.stopped = true;
    }

    pub fn is_stopped(&self) -> bool {
        self.stopped || self.position >= self.code.len()
    }

    pub fn read(&mut self, byte_count: usize) -> U256 {
        let position = self.position;
        self.position += byte_count;
        let max = min(position + byte_count, self.code.len());
        U256::from(&self.code[position..max])
    }

    fn len(&self) -> usize {
        self.code.len()
    }
}<commit_msg>Problem: PC does not support other implementations other than slice Solution: Make it a trait<commit_after>use utils::u256::U256;
use std::cmp::{min};
use super::opcode::Opcode;

pub trait PC {
    fn peek_opcode(&self) -> Opcode;
    fn read_opcode(&mut self) -> Opcode;
    fn stop(&mut self);
    fn stopped(&self) -> bool;
    fn read(&mut self, byte_count: usize) -> U256;
    fn position(&self) -> usize;
}

pub struct VectorPC {
    position: usize,
    code: Vec<u8>,
    stopped: bool
}

impl VectorPC {
    pub fn new(code: &[u8]) -> Self {
        PC {
            position: 0,
            code: code.into(),
            stopped: false,
        }
    }
}

impl<A: Account> From<&A> for VectorPC {
    fn from(account: &A) -> VectorPC {
        let empty: [u8; 0] = [];
        let code = account.code;
        if code.is_some() {
            VectorPC::new(code.unwrap())
        } else {
            VectorPC::new(empty)
        }
    }
}

impl PC for VectorPC {
    fn position(&self) -> usize {
        self.position
    }

    fn peek_opcode(&self) -> Opcode {
        let position = self.position;
        let opcode: Opcode = self.code[position].into();
        opcode
    }

    fn read_opcode(&mut self) -> Opcode {
        let position = self.position;
        let opcode: Opcode = self.code[position].into();
        self.position += 1;
        opcode
    }

    fn stop(&mut self) {
        self.stopped = true;
    }

    fn stopped(&self) -> bool {
        self.stopped || self.position >= self.code.len()
    }

    fn read(&mut self, byte_count: usize) -> U256 {
        let position = self.position;
        self.position += byte_count;
        let max = min(position + byte_count, self.code.len());
        U256::from(&self.code[position..max])
    }
}
{'fraction_non_alphanumeric': 0.14382402707275804, 'fraction_numerical': 0.012521150592216581, 'mean_word_length': 2.0132517838939856, 'pattern_counts': {'":': 0, '<': 9, '<?xml version=': 0, '>': 29, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3982535', 'n_tokens_mistral': 984, 'n_tokens_neox': 973, 'n_words': 244}