Skip to content

Commit

Permalink
Added all sorts from Bend repo
Browse files Browse the repository at this point in the history
  • Loading branch information
vkobinski committed Jun 24, 2024
1 parent 500d2cb commit 24cc6f4
Show file tree
Hide file tree
Showing 13 changed files with 428 additions and 205 deletions.
8 changes: 8 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -20,3 +20,11 @@ build:

run_examples:
python -m examples.quicksort
python -m examples.radix_sort
bend run examples/radix_sort.bend
python -m examples.insertion_sort
bend run examples/insertion_sort.bend
python -m examples.bitonic_sort
bend run examples/bitonic_sort.bend
python -m examples.bubble_sort
bend run examples/bubble_sort.bend
258 changes: 138 additions & 120 deletions crates/benda/src/types/book.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ use core::panic;
use std::cell::RefCell;
use std::vec;

use bend::fun::{self, Book as BendBook, Name, Rule};
use bend::fun::{self, Book as BendBook, CtrField, Name, Rule};
use bend::imp::{self, Expr, Stmt};
use indexmap::IndexMap;
use num_traits::ToPrimitive;
Expand Down Expand Up @@ -70,146 +70,111 @@ impl Term {
}
}

#[pyclass(name = "Ctr2")]
#[derive(Clone, Debug)]
pub struct Ctr2 {
entire_name: String,
name: String,
fields: IndexMap<String, Option<Py<PyAny>>>,
}

#[pymethods]
impl Ctr2 {
#[classattr]
fn __match_args__() -> PyResult<Py<PyAny>> {
Python::with_gil(|py| {
Ok(PyTuple::new_bound(py, vec!["1", "2", "3", "4", "5"])
.into_py(py))
})
}

fn __str__(&self) -> String {
format!("Bend ADT: {}", self.entire_name)
}

#[pyo3(signature = (*args))]
fn __call__(&mut self, args: Bound<'_, PyTuple>) -> PyResult<PyObject> {
let py = args.py();

for (i, field) in self.fields.iter_mut().enumerate() {
field.1.replace(args.get_item(i).unwrap().to_object(py));
}

Ok(Py::new(py, self.clone()).unwrap().as_any().clone())
}

fn __setattr__(&mut self, field: Bound<PyAny>, value: Bound<PyAny>) {
if let Some(val) = self.fields.get_mut(&field.to_string()) {
val.replace(value.to_object(field.py()));
}
}

fn __getattr__(&self, object: Bound<PyAny>) -> PyResult<PyObject> {
let field = object.to_string();

let py = object.py();

if field == "type" {
return Ok(PyString::new_bound(py, &self.entire_name).into_py(py));
}

if &object.to_string() == "name" {
return Ok(PyString::new_bound(py, &self.name).into());
macro_rules! generate_structs {
($name:literal, $iden: ident) => {
#[pyclass(name = $name)]
#[derive(Clone, Debug)]
pub struct $iden {
entire_name: String,
name: String,
fields: IndexMap<String, Option<Py<PyAny>>>,
}

if let Ok(val) = object.to_string().parse::<usize>() {
let return_val = self.fields.get_index(val - 1);
if let Some(return_val) = return_val {
return Ok(return_val.1.clone().into_py(py));
impl InsertField for $iden {
fn insert_field(&mut self, field: &CtrField) {
self.fields.insert(field.nam.to_string(), None);
}
}

if let Some(val) = self.fields.get(&object.to_string()) {
Ok(val.clone().into_py(object.py()))
} else {
new_err(format!("Could not find attr {}", object))
}
}
}

#[pyclass(name = "Ctr")]
#[derive(Clone, Debug)]
pub struct Ctr {
entire_name: String,
name: String,
fields: IndexMap<String, Option<Py<PyAny>>>,
}
#[pymethods]
impl $iden {
#[classattr]
fn __match_args__() -> PyResult<Py<PyAny>> {
Python::with_gil(|py| {
Ok(PyTuple::new_bound(py, vec!["1", "2", "3", "4", "5"])
.into_py(py))
})
}

#[pymethods]
impl Ctr {
#[classattr]
fn __match_args__() -> PyResult<Py<PyAny>> {
Python::with_gil(|py| {
Ok(PyTuple::new_bound(py, vec!["1", "2", "3", "4", "5"])
.into_py(py))
})
}
fn __str__(&self) -> String {
format!("Bend ADT: {}", self.entire_name)
}

fn __str__(&self) -> String {
format!("Bend ADT: {}", self.entire_name)
}
#[pyo3(signature = (*args))]
fn __call__(
&mut self,
args: Bound<'_, PyTuple>,
) -> PyResult<PyObject> {
let py = args.py();

#[pyo3(signature = (*args))]
fn __call__(&mut self, args: Bound<'_, PyTuple>) -> PyResult<PyObject> {
let py = args.py();
for (i, field) in self.fields.iter_mut().enumerate() {
field.1.replace(args.get_item(i).unwrap().to_object(py));
}

for (i, field) in self.fields.iter_mut().enumerate() {
field.1.replace(args.get_item(i).unwrap().to_object(py));
}
Ok(Py::new(py, self.clone()).unwrap().as_any().clone())
}

Ok(Py::new(py, self.clone()).unwrap().as_any().clone())
}
fn __setattr__(
&mut self,
field: Bound<PyAny>,
value: Bound<PyAny>,
) {
if let Some(val) = self.fields.get_mut(&field.to_string()) {
val.replace(value.to_object(field.py()));
}
}

fn __setattr__(&mut self, field: Bound<PyAny>, value: Bound<PyAny>) {
if let Some(val) = self.fields.get_mut(&field.to_string()) {
val.replace(value.to_object(field.py()));
}
}
fn __getattr__(&self, object: Bound<PyAny>) -> PyResult<PyObject> {
let field = object.to_string();

fn __getattr__(&self, object: Bound<PyAny>) -> PyResult<PyObject> {
let field = object.to_string();
let py = object.py();

let py = object.py();
if field == "type" {
return Ok(
PyString::new_bound(py, &self.entire_name).into_py(py)
);
}

if field == "type" {
return Ok(PyString::new_bound(py, &self.entire_name).into_py(py));
}
if &object.to_string() == "name" {
return Ok(PyString::new_bound(py, &self.name).into());
}

if &object.to_string() == "name" {
return Ok(PyString::new_bound(py, &self.name).into());
}
if let Ok(val) = object.to_string().parse::<usize>() {
let return_val = self.fields.get_index(val - 1);
if let Some(return_val) = return_val {
return Ok(return_val.1.clone().into_py(py));
}
}

if let Ok(val) = object.to_string().parse::<usize>() {
let return_val = self.fields.get_index(val - 1);
if let Some(return_val) = return_val {
return Ok(return_val.1.clone().into_py(py));
if let Some(val) = self.fields.get(&object.to_string()) {
Ok(val.clone().into_py(object.py()))
} else {
new_err(format!("Could not find attr {}", object))
}
}
}

if let Some(val) = self.fields.get(&object.to_string()) {
Ok(val.clone().into_py(object.py()))
} else {
new_err(format!("Could not find attr {}", object))
}
}
};
}

generate_structs!("Ctr1", Ctr1);
generate_structs!("Ctr2", Ctr2);
generate_structs!("Ctr3", Ctr3);
generate_structs!("Ctr4", Ctr4);
generate_structs!("Ctr5", Ctr5);

#[pyclass(name = "Ctrs")]
#[derive(Clone, Debug, Default)]
pub struct Ctrs {
fields: IndexMap<String, Py<PyAny>>,
first: Option<Ctr>,
first: Option<Ctr1>,
second: Option<Ctr2>,
third: Option<Ctr3>,
fourth: Option<Ctr4>,
fifth: Option<Ctr5>,
}

trait InsertField {
fn insert_field(&mut self, field: &CtrField);
}

#[pymethods]
Expand All @@ -224,8 +189,11 @@ impl Ctrs {
let index = self.fields.get_index_of(name).unwrap();

let res = match index {
0 => Ctr::type_object_bound(py),
0 => Ctr1::type_object_bound(py),
1 => Ctr2::type_object_bound(py),
2 => Ctr3::type_object_bound(py),
3 => Ctr4::type_object_bound(py),
4 => Ctr5::type_object_bound(py),
_ => {
return new_err(
"Type can only have up to 2 constructors".to_string(),
Expand Down Expand Up @@ -415,8 +383,11 @@ impl Book {
for (adt_name, bend_adt) in bend_book.adts.iter() {
let mut all_ctrs = Ctrs::default();

let mut first: Option<Ctr> = None;
let mut first: Option<Ctr1> = None;
let mut second: Option<Ctr2> = None;
let mut third: Option<Ctr3> = None;
let mut fourth: Option<Ctr4> = None;
let mut fifth: Option<Ctr5> = None;

for (index, (ctr_name, ctr_fields)) in
bend_adt.ctrs.iter().enumerate()
Expand All @@ -425,7 +396,7 @@ impl Book {

Python::with_gil(|py| match index {
0 => {
let mut ct = Ctr {
let mut ct = Ctr1 {
name: new_name.clone(),
entire_name: ctr_name.to_string(),
fields: IndexMap::new(),
Expand All @@ -452,12 +423,59 @@ impl Book {
.fields
.insert(new_name, ct.into_py(py).as_any().clone());
}
_ => panic!("Type must have only 2 Ctrs"),
2 => {
let mut ct = Ctr3 {
name: new_name.clone(),
entire_name: ctr_name.to_string(),
fields: IndexMap::new(),
};
for c in ctr_fields {
ct.fields.insert(c.nam.to_string(), None);
}
third = Some(ct.clone());
all_ctrs
.fields
.insert(new_name, ct.into_py(py).as_any().clone());
}
3 => {
let mut ct = Ctr4 {
name: new_name.clone(),
entire_name: ctr_name.to_string(),
fields: IndexMap::new(),
};
for c in ctr_fields {
ct.fields.insert(c.nam.to_string(), None);
}
fourth = Some(ct.clone());
all_ctrs
.fields
.insert(new_name, ct.into_py(py).as_any().clone());
}

4 => {
let mut ct = Ctr5 {
name: new_name.clone(),
entire_name: ctr_name.to_string(),
fields: IndexMap::new(),
};
for c in ctr_fields {
ct.fields.insert(c.nam.to_string(), None);
}
fifth = Some(ct.clone());
all_ctrs
.fields
.insert(new_name, ct.into_py(py).as_any().clone());
}

_ => panic!("Type must have up to 5 Ctrs"),
});
}

all_ctrs.first = first;
all_ctrs.second = second;
all_ctrs.third = third;
all_ctrs.fourth = fourth;
all_ctrs.fifth = fifth;

adts.adts.insert(adt_name.to_string(), all_ctrs);
}
Expand Down
34 changes: 17 additions & 17 deletions crates/benda/src/types/user_adt.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,23 +23,23 @@ impl<'py> UserAdt<'py> {
// return None;
//}

let binding = data.getattr("type").unwrap().to_string();

for (nam, _ctr) in &book.ctrs {
let new_nam = nam.to_string();
let two_names = new_nam.split_once('/').unwrap();

if nam.to_string() == binding {
return Some(Self {
book: book.clone(),
data,
entire_nam: Name::new(new_nam.clone()),
adt: book
.adts
.get(&Name::new(two_names.0.to_string()))
.unwrap()
.clone(),
});
if let Ok(binding) = data.getattr("type") {
for (nam, _ctr) in &book.ctrs {
let new_nam = nam.to_string();
let two_names = new_nam.split_once('/').unwrap();

if nam.to_string() == binding.to_string() {
return Some(Self {
book: book.clone(),
data,
entire_nam: Name::new(new_nam.clone()),
adt: book
.adts
.get(&Name::new(two_names.0.to_string()))
.unwrap()
.clone(),
});
}
}
}

Expand Down
Loading

0 comments on commit 24cc6f4

Please sign in to comment.