refactor: separate Type to its own file

replace/7746dba3cc6b3860afe1faf69e86ed84ee46988d
Natapat Samutpong 2022-02-06 13:18:39 +07:00
parent 3297545d4d
commit f939903df2
6 changed files with 154 additions and 148 deletions

View File

@ -1,4 +1,5 @@
use crate::{vm::instr::*, compiler::parser::Sexpr::{self, *}};
use crate::{vm::{instr::*, types::Type}, compiler::parser::Sexpr::{self, *}};
pub struct Compiler {
// Compiled instructions
pub instructions: Vec<Instr>,

View File

@ -1,149 +1,6 @@
use std::{fmt::Display, str::FromStr, ops::{Add, Sub, Mul, Div, Not}};
use std::{fmt::Display, str::FromStr};
use crate::vm::vm::Error::{self, InvalidAriphmeticOperation};
/// Literal types for the assembler.
#[derive(Clone, Debug, PartialEq)]
pub enum Type {
Null,
Int(i64),
Float(f64),
Boolean(bool),
String(String),
}
impl Type {
pub fn is_null(&self) -> bool {
match self {
Type::Null => true,
_ => false,
}
}
pub fn trim(&self) -> Type {
match self {
Type::String(s) => Type::String(s[1..s.len() - 1].to_string()),
_ => self.clone(),
}
}
pub fn fmt(&self) -> String {
match self {
Type::Null => "null".to_string(),
Type::Int(i) => i.to_string(),
Type::Float(f) => f.to_string(),
Type::Boolean(b) => match b {
true => "true".to_string(),
false => "false".to_string(),
},
Type::String(s) => s.clone(),
}
}
}
impl Add for Type {
type Output = Result<Type, Error>;
fn add(self, other: Type) -> Result<Type, Error> {
match (self, other) {
(Type::Int(lhs), Type::Int(rhs)) => Ok(Type::Int(lhs + rhs)),
(Type::Int(lhs), Type::Float(rhs)) => Ok(Type::Float(lhs as f64 + rhs)),
(Type::Float(lhs), Type::Int(rhs)) => Ok(Type::Float(lhs + rhs as f64)),
(Type::Float(lhs), Type::Float(rhs)) => Ok(Type::Float(lhs + rhs)),
(Type::String(lhs), Type::String(rhs)) => Ok(Type::String(format!("{}{}", lhs, rhs))),
_ => Err(InvalidAriphmeticOperation),
}
}
}
impl Sub for Type {
type Output = Result<Type, Error>;
fn sub(self, other: Type) -> Result<Type, Error> {
match (self, other) {
(Type::Int(lhs), Type::Int(rhs)) => Ok(Type::Int(lhs - rhs)),
(Type::Int(lhs), Type::Float(rhs)) => Ok(Type::Float(lhs as f64 - rhs)),
(Type::Float(lhs), Type::Int(rhs)) => Ok(Type::Float(lhs - rhs as f64)),
(Type::Float(lhs), Type::Float(rhs)) => Ok(Type::Float(lhs - rhs)),
_ => Err(InvalidAriphmeticOperation),
}
}
}
impl Mul for Type {
type Output = Result<Type, Error>;
fn mul(self, other: Type) -> Result<Type, Error> {
match (self, other) {
(Type::Int(lhs), Type::Int(rhs)) => Ok(Type::Int(lhs * rhs)),
(Type::Int(lhs), Type::Float(rhs)) => Ok(Type::Float(lhs as f64 * rhs)),
(Type::Float(lhs), Type::Int(rhs)) => Ok(Type::Float(lhs * rhs as f64)),
(Type::Float(lhs), Type::Float(rhs)) => Ok(Type::Float(lhs * rhs)),
_ => Err(InvalidAriphmeticOperation),
}
}
}
impl Div for Type {
type Output = Result<Type, Error>;
fn div(self, other: Type) -> Result<Type, Error> {
match (self, other) {
(Type::Int(lhs), Type::Int(rhs)) => Ok(Type::Int(lhs / rhs)),
(Type::Int(lhs), Type::Float(rhs)) => Ok(Type::Float(lhs as f64 / rhs)),
(Type::Float(lhs), Type::Int(rhs)) => Ok(Type::Float(lhs / rhs as f64)),
(Type::Float(lhs), Type::Float(rhs)) => Ok(Type::Float(lhs / rhs)),
_ => Err(InvalidAriphmeticOperation),
}
}
}
impl Not for Type {
type Output = Result<Type, Error>;
fn not(self) -> Result<Type, Error> {
match self {
Type::Boolean(b) => Ok(Type::Boolean(!b)),
_ => Err(InvalidAriphmeticOperation),
}
}
}
impl Display for Type {
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
match self {
Type::Int(i) => write!(f, "{}", i),
Type::Float(fl) => write!(f, "{}", fl),
Type::Boolean(b) => write!(f, "{}", b),
Type::String(s) => write!(f, "\"{}\"", s),
_ => unreachable!(),
}
}
}
impl FromStr for Type {
type Err = String;
fn from_str(s: &str) -> Result<Self, Self::Err> {
match s {
"true" => Ok(Type::Boolean(true)),
"false" => Ok(Type::Boolean(false)),
_ => {
let i = s.parse::<i64>();
if i.is_ok() {
Ok(Type::Int(i.unwrap()))
} else {
let fl = s.parse::<f64>();
if fl.is_ok() {
Ok(Type::Float(fl.unwrap()))
} else {
Ok(Type::String(s.to_string()))
}
}
}
}
}
}
use crate::vm::types::Type;
#[derive(Clone, Copy, Debug)]
pub struct Register { pub value: usize }

View File

@ -1,3 +1,5 @@
/// Type for instrs.
pub mod types;
/// Definition of the VM instructions.
pub mod instr;
/// Definition of the instruction parser.

View File

@ -1,6 +1,6 @@
use regex::Regex;
use crate::vm::instr::*;
use crate::vm::{instr::*, types::Type};
const REGEX: &str = r###"[^\s\$";]+|"[^"]*"|;.*"###;

146
blspc/src/vm/types.rs Normal file
View File

@ -0,0 +1,146 @@
use std::{fmt::Display, str::FromStr, ops::{Add, Sub, Mul, Div, Not}};
use crate::vm::vm::Error::{self, InvalidAriphmeticOperation};
/// Literal types for the assembler.
#[derive(Clone, Debug, PartialEq)]
pub enum Type {
Null,
Int(i64),
Float(f64),
Boolean(bool),
String(String),
}
impl Type {
pub fn is_null(&self) -> bool {
match self {
Type::Null => true,
_ => false,
}
}
pub fn trim(&self) -> Type {
match self {
Type::String(s) => Type::String(s[1..s.len() - 1].to_string()),
_ => self.clone(),
}
}
pub fn fmt(&self) -> String {
match self {
Type::Null => "null".to_string(),
Type::Int(i) => i.to_string(),
Type::Float(f) => f.to_string(),
Type::Boolean(b) => match b {
true => "true".to_string(),
false => "false".to_string(),
},
Type::String(s) => s.clone(),
}
}
}
impl Add for Type {
type Output = Result<Type, Error>;
fn add(self, other: Type) -> Result<Type, Error> {
match (self, other) {
(Type::Int(lhs), Type::Int(rhs)) => Ok(Type::Int(lhs + rhs)),
(Type::Int(lhs), Type::Float(rhs)) => Ok(Type::Float(lhs as f64 + rhs)),
(Type::Float(lhs), Type::Int(rhs)) => Ok(Type::Float(lhs + rhs as f64)),
(Type::Float(lhs), Type::Float(rhs)) => Ok(Type::Float(lhs + rhs)),
(Type::String(lhs), Type::String(rhs)) => Ok(Type::String(format!("{}{}", lhs, rhs))),
_ => Err(InvalidAriphmeticOperation),
}
}
}
impl Sub for Type {
type Output = Result<Type, Error>;
fn sub(self, other: Type) -> Result<Type, Error> {
match (self, other) {
(Type::Int(lhs), Type::Int(rhs)) => Ok(Type::Int(lhs - rhs)),
(Type::Int(lhs), Type::Float(rhs)) => Ok(Type::Float(lhs as f64 - rhs)),
(Type::Float(lhs), Type::Int(rhs)) => Ok(Type::Float(lhs - rhs as f64)),
(Type::Float(lhs), Type::Float(rhs)) => Ok(Type::Float(lhs - rhs)),
_ => Err(InvalidAriphmeticOperation),
}
}
}
impl Mul for Type {
type Output = Result<Type, Error>;
fn mul(self, other: Type) -> Result<Type, Error> {
match (self, other) {
(Type::Int(lhs), Type::Int(rhs)) => Ok(Type::Int(lhs * rhs)),
(Type::Int(lhs), Type::Float(rhs)) => Ok(Type::Float(lhs as f64 * rhs)),
(Type::Float(lhs), Type::Int(rhs)) => Ok(Type::Float(lhs * rhs as f64)),
(Type::Float(lhs), Type::Float(rhs)) => Ok(Type::Float(lhs * rhs)),
_ => Err(InvalidAriphmeticOperation),
}
}
}
impl Div for Type {
type Output = Result<Type, Error>;
fn div(self, other: Type) -> Result<Type, Error> {
match (self, other) {
(Type::Int(lhs), Type::Int(rhs)) => Ok(Type::Int(lhs / rhs)),
(Type::Int(lhs), Type::Float(rhs)) => Ok(Type::Float(lhs as f64 / rhs)),
(Type::Float(lhs), Type::Int(rhs)) => Ok(Type::Float(lhs / rhs as f64)),
(Type::Float(lhs), Type::Float(rhs)) => Ok(Type::Float(lhs / rhs)),
_ => Err(InvalidAriphmeticOperation),
}
}
}
impl Not for Type {
type Output = Result<Type, Error>;
fn not(self) -> Result<Type, Error> {
match self {
Type::Boolean(b) => Ok(Type::Boolean(!b)),
_ => Err(InvalidAriphmeticOperation),
}
}
}
impl Display for Type {
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
match self {
Type::Int(i) => write!(f, "{}", i),
Type::Float(fl) => write!(f, "{}", fl),
Type::Boolean(b) => write!(f, "{}", b),
Type::String(s) => write!(f, "\"{}\"", s),
_ => unreachable!(),
}
}
}
impl FromStr for Type {
type Err = String;
fn from_str(s: &str) -> Result<Self, Self::Err> {
match s {
"true" => Ok(Type::Boolean(true)),
"false" => Ok(Type::Boolean(false)),
_ => {
let i = s.parse::<i64>();
if i.is_ok() {
Ok(Type::Int(i.unwrap()))
} else {
let fl = s.parse::<f64>();
if fl.is_ok() {
Ok(Type::Float(fl.unwrap()))
} else {
Ok(Type::String(s.to_string()))
}
}
}
}
}
}

View File

@ -1,6 +1,6 @@
use std::{io::{self, Read}, fmt::Display, fs::File};
use crate::vm::instr::{Instr::{self, *}, Type, Register};
use crate::vm::{instr::{Instr::{self, *}, Register}, types::Type};
pub enum Error {
NoMainFunction,