Skip to content

Commit

Permalink
Merge pull request #21 from ricglz/sixth-delivery
Browse files Browse the repository at this point in the history
sixth delivery
  • Loading branch information
ricglz authored May 24, 2022
2 parents 8166c98 + c77695f commit f96e205
Show file tree
Hide file tree
Showing 8 changed files with 492 additions and 33 deletions.
2 changes: 1 addition & 1 deletion examples/valid/aritmetic.ra
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ func main(): void {
f = 2 > 1;
e = 3 == 3;
f = 3 != 2;
g = "2" + 2.0;
g = "2.1" + 2.0;
h = 2 - 2.0;
i = 4 * 4;
j = 4 / 4;
Expand Down
3 changes: 3 additions & 0 deletions examples/valid/hello_world.ra
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
func main(): void {
print("Hello world!");
}
119 changes: 99 additions & 20 deletions src/address/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,10 @@ fn get_type_base(data_type: &Types) -> usize {
}

pub trait GenericAddressManager {
fn get_address_counter(&self) -> AddressCounter;
fn get_address(&mut self, data_type: &Types) -> Option<usize>;
fn size(&self) -> usize;
fn get_base(&self) -> usize;
}

#[derive(PartialEq, Clone)]
Expand All @@ -62,6 +64,10 @@ impl AddressManager {
}

impl GenericAddressManager for AddressManager {
#[inline]
fn get_address_counter(&self) -> AddressCounter {
self.counter.clone()
}
fn get_address(&mut self, data_type: &Types) -> Option<usize> {
let type_counter = self
.counter
Expand All @@ -75,6 +81,7 @@ impl GenericAddressManager for AddressManager {
let type_base = get_type_base(&data_type);
Some(self.base + type_counter_clone + type_base)
}
#[inline]
fn size(&self) -> usize {
self.counter
.to_owned()
Expand All @@ -83,6 +90,10 @@ impl GenericAddressManager for AddressManager {
.reduce(|a, v| a + v)
.unwrap_or(0)
}
#[inline]
fn get_base(&self) -> usize {
self.base
}
}

impl fmt::Debug for AddressManager {
Expand Down Expand Up @@ -146,14 +157,24 @@ impl TempAddressManager {
}

impl GenericAddressManager for TempAddressManager {
#[inline]
fn get_address_counter(&self) -> AddressCounter {
self.address_manager.get_address_counter()
}
#[inline]
fn get_address(&mut self, data_type: &Types) -> Option<usize> {
self.type_released_addresses(data_type)
.pop()
.or(self.address_manager.get_address(data_type))
}
#[inline]
fn size(&self) -> usize {
self.address_manager.size()
}
#[inline]
fn get_base(&self) -> usize {
self.address_manager.base
}
}

impl fmt::Debug for TempAddressManager {
Expand All @@ -162,12 +183,23 @@ impl fmt::Debug for TempAddressManager {
}
}

type Memory = HashMap<Types, Vec<VariableValue>>;

#[derive(PartialEq, Clone)]
pub struct ConstantMemory {
base: usize,
memory: Memory,
memory: HashMap<Types, Vec<VariableValue>>,
}

fn get_address_info(address: usize, base: usize) -> (usize, usize, Types) {
let contextless_address = address - base;
let type_determinant = contextless_address / THRESHOLD;
let address_type = match type_determinant {
0 => Types::INT,
1 => Types::FLOAT,
2 => Types::STRING,
3 => Types::BOOL,
_ => unreachable!(),
};
(contextless_address, type_determinant, address_type)
}

impl ConstantMemory {
Expand Down Expand Up @@ -209,23 +241,15 @@ impl ConstantMemory {
Some((address, data_type))
}

fn get(&self, address: usize) -> Option<VariableValue> {
let contextless_address = address - self.base;
let type_determinant = contextless_address / THRESHOLD;
let address_type = match type_determinant {
0 => Types::INT,
1 => Types::FLOAT,
2 => Types::STRING,
3 => Types::BOOL,
_ => unreachable!(),
};
let type_memory = self.memory.get(&address_type).unwrap();
Some(
type_memory
.get(contextless_address - type_determinant * THRESHOLD)
.unwrap()
.to_owned(),
)
pub fn get(&self, address: usize) -> VariableValue {
let (contextless_address, type_determinant, address_type) =
get_address_info(address, self.base);
self.memory
.get(&address_type)
.unwrap()
.get(contextless_address - type_determinant * THRESHOLD)
.unwrap()
.to_owned()
}
}

Expand All @@ -235,5 +259,60 @@ impl fmt::Debug for ConstantMemory {
}
}

#[derive(Clone, Debug)]
pub struct Memory {
base: usize,
int_pointer: usize,
float_pointer: usize,
string_pointer: usize,
bool_pointer: usize,
space: Vec<Option<VariableValue>>,
}

impl Memory {
pub fn new(manager: Box<dyn GenericAddressManager>) -> Self {
let counter = manager.get_address_counter();
let base = manager.get_base();
let int_pointer: usize = 0;
let float_pointer = int_pointer + counter.get(&Types::INT).unwrap();
let string_pointer = float_pointer + counter.get(&Types::FLOAT).unwrap();
let bool_pointer = string_pointer + counter.get(&Types::STRING).unwrap();
let total_size = bool_pointer + counter.get(&Types::BOOL).unwrap();
let space = vec![None; total_size];
Memory {
base,
int_pointer,
float_pointer,
string_pointer,
bool_pointer,
space,
}
}

fn get_index(&self, address: usize) -> (usize, Types) {
let (contextless_address, _, address_type) = get_address_info(address, self.base);
let type_index = contextless_address % THRESHOLD;
let pointer = match address_type {
Types::INT => self.int_pointer,
Types::FLOAT => self.float_pointer,
Types::STRING => self.string_pointer,
Types::BOOL => self.bool_pointer,
data_type => unreachable!("{:?}", data_type),
};
(type_index + pointer, address_type)
}

pub fn get(&self, address: usize) -> Option<VariableValue> {
let index = self.get_index(address).0;
self.space.get(index).unwrap().to_owned()
}

pub fn write(&mut self, address: usize, uncast: VariableValue) {
let (index, address_type) = self.get_index(address);
let value = uncast.cast_to(address_type);
*self.space.get_mut(index).unwrap() = Some(value);
}
}

#[cfg(test)]
mod tests;
6 changes: 4 additions & 2 deletions src/dir_func/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,11 @@ pub mod function;
pub mod variable;
pub mod variable_value;

#[derive(PartialEq, Debug)]
pub type FunctionTable = HashMap<String, Function>;

#[derive(PartialEq, Debug, Clone)]
pub struct DirFunc {
pub functions: HashMap<String, Function>,
pub functions: FunctionTable,
pub global_fn: GlobalScope,
}

Expand Down
155 changes: 155 additions & 0 deletions src/dir_func/variable_value.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
use std::fmt;
use std::ops::{Add, BitAnd, BitOr, Div, Mul, Not, Sub};

use crate::{ast::ast_kind::AstNodeKind, enums::Types};

Expand All @@ -10,6 +11,33 @@ pub enum VariableValue {
Bool(bool),
}

impl VariableValue {
pub fn is_number(&self) -> bool {
match self {
Self::Integer(_) | Self::Float(_) | Self::String(_) => true,
_ => false,
}
}

#[inline]
fn cast_to_bool(&self) -> VariableValue {
Self::Bool(bool::from(self))
}

#[inline]
fn cast_to_float(&self) -> VariableValue {
Self::Float(f64::from(self))
}

pub fn cast_to(&self, to: Types) -> VariableValue {
match to {
Types::BOOL => self.cast_to_bool(),
Types::FLOAT => self.cast_to_float(),
_ => self.clone(),
}
}
}

impl From<&VariableValue> for Types {
fn from(v: &VariableValue) -> Self {
match v {
Expand All @@ -33,6 +61,39 @@ impl From<AstNodeKind<'_>> for VariableValue {
}
}

impl From<VariableValue> for f64 {
fn from(v: VariableValue) -> Self {
match v {
VariableValue::Integer(a) => a.to_string().parse().unwrap(),
VariableValue::Float(a) => a,
VariableValue::String(a) => a.parse().unwrap(),
_ => unreachable!(),
}
}
}

impl From<&VariableValue> for f64 {
fn from(v: &VariableValue) -> Self {
Self::from(v.to_owned())
}
}

impl From<VariableValue> for bool {
fn from(v: VariableValue) -> Self {
match v {
VariableValue::Integer(a) => a != 0,
VariableValue::Bool(a) => a,
_ => unreachable!(),
}
}
}

impl From<&VariableValue> for bool {
fn from(v: &VariableValue) -> Self {
Self::from(v.to_owned())
}
}

impl fmt::Debug for VariableValue {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let value = match self {
Expand All @@ -44,3 +105,97 @@ impl fmt::Debug for VariableValue {
write!(f, "{}", value)
}
}

impl Add for VariableValue {
type Output = Self;

fn add(self, other: Self) -> Self::Output {
if let (Self::Integer(a), Self::Integer(b)) = (self.clone(), other.clone()) {
Self::Integer(a + b)
} else {
Self::Float(f64::from(self) + f64::from(other))
}
}
}

impl Sub for VariableValue {
type Output = Self;

fn sub(self, other: Self) -> Self::Output {
if let (Self::Integer(a), Self::Integer(b)) = (self.clone(), other.clone()) {
Self::Integer(a - b)
} else {
Self::Float(f64::from(self) - f64::from(other))
}
}
}

impl Mul for VariableValue {
type Output = Self;

fn mul(self, other: Self) -> Self::Output {
if let (Self::Integer(a), Self::Integer(b)) = (self.clone(), other.clone()) {
Self::Integer(a * b)
} else {
Self::Float(f64::from(self) * f64::from(other))
}
}
}

impl Div for VariableValue {
type Output = Self;

fn div(self, other: Self) -> Self::Output {
if let (Self::Integer(a), Self::Integer(b)) = (self.clone(), other.clone()) {
Self::Integer(a / b)
} else {
Self::Float(f64::from(self) / f64::from(other))
}
}
}

impl PartialOrd for VariableValue {
fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
match (self.is_number(), other.is_number()) {
(true, true) => {
let a = f64::from(self);
let b = f64::from(other);
a.partial_cmp(&b)
}
_ => match (self, other) {
(Self::Bool(a), Self::Bool(b)) => {
if a == b {
Some(std::cmp::Ordering::Equal)
} else {
Some(std::cmp::Ordering::Less)
}
}
_ => None,
},
}
}
}

impl BitOr for VariableValue {
type Output = Self;

fn bitor(self, other: Self) -> Self::Output {
Self::Bool(bool::from(self) | bool::from(other))
}
}

impl BitAnd for VariableValue {
type Output = Self;

fn bitand(self, other: Self) -> Self::Output {
Self::Bool(bool::from(self) & bool::from(other))
}
}

impl Not for VariableValue {
type Output = Self;

fn not(self) -> Self::Output {
Self::Bool(!bool::from(self))
}
}
Loading

0 comments on commit f96e205

Please sign in to comment.