extern crate alloc;
use crate::bytecode::{
data::ByteData,
ops::ArgType::*,
ops::Operations::*,
types::Types::{self, *},
};
use crate::reader::Reader;
use alloc::vec::Vec;
#[derive(Debug, Clone)]
pub struct ByteStream {
pos: usize,
pub bytes: Vec<Byte>,
}
impl From<Vec<ByteStream>> for ByteStream {
fn from(streams: Vec<ByteStream>) -> Self {
let mut stream = ByteStream::new();
for s in streams {
stream.emitstream(s);
}
stream
}
}
impl From<ByteStream> for Vec<Byte> {
fn from(stream: ByteStream) -> Self {
stream.bytes
}
}
impl From<Vec<u8>> for ByteStream {
fn from(bytes: Vec<u8>) -> Self {
let mut reader = Reader::new_read(&bytes);
reader.group()
}
}
impl From<ByteStream> for Vec<u8> {
fn from(stream: ByteStream) -> Self {
let mut bytes = Vec::new();
for byte in stream.bytes {
bytes.push(*byte.data as u8);
}
bytes
}
}
impl From<Vec<Byte>> for ByteStream {
fn from(bytes: Vec<Byte>) -> Self {
ByteStream { pos: 0, bytes }
}
}
impl From<&[Byte]> for ByteStream {
fn from(bytes: &[Byte]) -> Self {
ByteStream {
pos: 0,
bytes: bytes.to_vec(),
}
}
}
impl From<&[ByteStream]> for ByteStream {
fn from(streams: &[ByteStream]) -> Self {
let mut stream = ByteStream::new();
for s in streams {
stream.emitstream(s.clone());
}
stream
}
}
impl Default for ByteStream {
fn default() -> ByteStream {
ByteStream {
pos: usize::default(),
bytes: Vec::default(),
}
}
}
impl ByteStream {
#[allow(dead_code)]
pub fn new() -> ByteStream {
ByteStream {
pos: 0,
bytes: Vec::new(),
}
}
pub fn emit(&mut self, byte: Byte) -> Self {
self.bytes.push(byte);
self.clone()
}
pub fn emitstream(&mut self, stream: ByteStream) -> Self {
for byte in stream.bytes {
self.bytes.push(byte);
}
self.clone()
}
pub fn stringify(&self) -> String {
let mut string = String::new();
for byte in &self.bytes {
string.push(byte.tp as u8 as char);
string.push(char::from_u32(*byte.data as u32).unwrap_or('\0'));
}
string
}
}
#[derive(Debug, Clone)]
pub struct Byte {
pub data: Box<u64>,
pub pos: usize,
pub tp: Types,
}
impl Byte {
pub fn unwrap(&self) -> u64 {
*self.data.clone()
}
}
#[macro_export]
macro_rules! typed {
($tp:ident, $val:expr) => {
Byte {
data: Box::new($val),
pos: 0,
tp: Types::$tp,
}
};
}
#[macro_export]
macro_rules! op {
($op:ident) => {{
use $crate::bytecode::ops::Operations::*;
Byte {
data: Box::new($op as u64),
pos: 0,
tp: Types::TypeOp,
}
}};
}
#[macro_export]
macro_rules! constant {
($val:expr) => {
Byte {
data: Box::new($val),
pos: 0,
tp: Types::TypeU64,
}
};
}
#[macro_export]
macro_rules! string {
($val:expr) => {
{
let mut stream = ByteStream::new();
for c in $val.chars() {
stream.emitstream(stream!((TypeU8, c as u64)));
}
stream
}
};
}
#[macro_export]
macro_rules! emits {
($($val:expr),*) => {
{
let mut stream = ByteStream::new();
$(stream.bytes.push($val);)*
stream
}
};
}
#[macro_export]
macro_rules! byte {
(($tp:ident, $val:expr)) => {
typed!($tp, $val)
};
($val:expr) => {
constant!($val)
};
}
#[macro_export]
macro_rules! stream {
($(($tp:ident, $val:expr)),*) => {
{
let mut stream = ByteStream::new();
$(
stream.bytes.push(byte!(($tp, $val)));
)*
stream
}
};
}
#[macro_export]
macro_rules! func {
($name:expr) => {
Byte {
data: Box::new(stringtohex($name.to_string())),
pos: 0,
tp: Types::TypeFunc,
}
};
}
pub fn stringtohex(string: String) -> u64 {
let mut hex = String::new();
for c in string.chars() {
hex.push_str((format!("{:02x}", c as u8)).trim());
}
u64::from_str_radix(&hex, 16).unwrap()
}
impl Byte {
fn stringify(&self) -> String {
format!("{:02x}", *(self.data))
}
fn assembly(&self) -> String {
let mut string = String::new();
string.push_str(&format!("{:?}", self.tp));
string.push_str(&format!("{:02x} ", *(self.data)));
string
}
}
impl std::fmt::Display for Byte {
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
write!(f, "{:02x}", *(self.data))
}
}
impl std::fmt::Display for ByteStream {
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
let mut string = String::new();
for byte in &self.bytes {
string.push_str(&format!("{:x}{:02x} ", byte.tp as u8, *(byte.data)));
}
write!(f, "{}", string)
}
}