Implements debug, index and assign traits in Rust target.
This commit is contained in:
parent
916e65674f
commit
b275827704
3 changed files with 107 additions and 46 deletions
|
|
@ -1,5 +1,5 @@
|
||||||
use crate::{
|
use crate::{
|
||||||
ast::{AstNode, DataType, Expression, ExpressionContent},
|
ast::{AstNode, DataType, Expression, ExpressionContent, Parameter},
|
||||||
emit::{camel_to_snake_case, emit_indentation},
|
emit::{camel_to_snake_case, emit_indentation},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -72,7 +72,7 @@ fn emit_expression<W: std::io::Write>(collector: &mut W, expression: &Expression
|
||||||
if expression.size == 1 {
|
if expression.size == 1 {
|
||||||
emit_expression(collector, &inner_expression)?;
|
emit_expression(collector, &inner_expression)?;
|
||||||
if inner_expression.size > 1 {
|
if inner_expression.size > 1 {
|
||||||
collector.write_fmt(format_args!(".get_f({})", indices[0]))?;
|
collector.write_fmt(format_args!("[{}]", indices[0]))?;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
collector.write_all(b"swizzle!(")?;
|
collector.write_all(b"swizzle!(")?;
|
||||||
|
|
@ -101,7 +101,7 @@ fn emit_expression<W: std::io::Write>(collector: &mut W, expression: &Expression
|
||||||
emit_expression(collector, &inner_expression)?;
|
emit_expression(collector, &inner_expression)?;
|
||||||
collector.write_fmt(format_args!(".g{}", array_index))?;
|
collector.write_fmt(format_args!(".g{}", array_index))?;
|
||||||
if inner_expression.size > 1 {
|
if inner_expression.size > 1 {
|
||||||
collector.write_fmt(format_args!(".get_f({})", *component_index))?;
|
collector.write_fmt(format_args!("[{}]", *component_index))?;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if indices.len() > 1 {
|
if indices.len() > 1 {
|
||||||
|
|
@ -165,15 +165,35 @@ fn emit_expression<W: std::io::Write>(collector: &mut W, expression: &Expression
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn emit_assign_trait<W: std::io::Write>(collector: &mut W, result: &Parameter, parameters: &[Parameter]) -> std::io::Result<()> {
|
||||||
|
if result.multi_vector_class() != parameters[0].multi_vector_class() {
|
||||||
|
return Ok(());
|
||||||
|
}
|
||||||
|
collector.write_fmt(format_args!(
|
||||||
|
"impl {}Assign<{}> for {} {{\n fn ",
|
||||||
|
result.name,
|
||||||
|
parameters[1].multi_vector_class().class_name,
|
||||||
|
parameters[0].multi_vector_class().class_name
|
||||||
|
))?;
|
||||||
|
camel_to_snake_case(collector, result.name)?;
|
||||||
|
collector.write_fmt(format_args!(
|
||||||
|
"_assign(&mut self, other: {}) {{\n *self = (*self).",
|
||||||
|
parameters[1].multi_vector_class().class_name
|
||||||
|
))?;
|
||||||
|
camel_to_snake_case(collector, result.name)?;
|
||||||
|
collector.write_all(b"(other);\n }\n}\n\n")
|
||||||
|
}
|
||||||
|
|
||||||
pub fn emit_code<W: std::io::Write>(collector: &mut W, ast_node: &AstNode, indentation: usize) -> std::io::Result<()> {
|
pub fn emit_code<W: std::io::Write>(collector: &mut W, ast_node: &AstNode, indentation: usize) -> std::io::Result<()> {
|
||||||
match &ast_node {
|
match &ast_node {
|
||||||
AstNode::None => {}
|
AstNode::None => {}
|
||||||
AstNode::Preamble => {
|
AstNode::Preamble => {
|
||||||
collector.write_all(b"#![allow(clippy::assign_op_pattern)]\n")?;
|
collector.write_all(b"#![allow(clippy::assign_op_pattern)]\n")?;
|
||||||
collector.write_all(b"use crate::{*, simd::*};\nuse std::ops::{Add, Neg, Sub, Mul, Div};\n\n")?;
|
collector
|
||||||
|
.write_all(b"use crate::{simd::*, *};\nuse std::ops::{Add, AddAssign, Div, DivAssign, Mul, MulAssign, Neg, Sub, SubAssign};\n\n")?;
|
||||||
}
|
}
|
||||||
AstNode::ClassDefinition { class } => {
|
AstNode::ClassDefinition { class } => {
|
||||||
collector.write_fmt(format_args!("#[derive(Clone, Copy)]\npub struct {} {{\n", class.class_name))?;
|
collector.write_fmt(format_args!("#[derive(Clone, Copy, Debug)]\npub struct {} {{\n", class.class_name))?;
|
||||||
for (i, group) in class.grouped_basis.iter().enumerate() {
|
for (i, group) in class.grouped_basis.iter().enumerate() {
|
||||||
emit_indentation(collector, indentation + 1)?;
|
emit_indentation(collector, indentation + 1)?;
|
||||||
collector.write_all(b"/// ")?;
|
collector.write_all(b"/// ")?;
|
||||||
|
|
@ -283,6 +303,12 @@ pub fn emit_code<W: std::io::Write>(collector: &mut W, ast_node: &AstNode, inden
|
||||||
}
|
}
|
||||||
emit_indentation(collector, indentation + 1)?;
|
emit_indentation(collector, indentation + 1)?;
|
||||||
collector.write_all(b"}\n}\n\n")?;
|
collector.write_all(b"}\n}\n\n")?;
|
||||||
|
match result.name {
|
||||||
|
"Add" | "Sub" | "Mul" | "Div" => {
|
||||||
|
emit_assign_trait(collector, result, ¶meters)?;
|
||||||
|
}
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
|
|
|
||||||
22
src/lib.rs
22
src/lib.rs
|
|
@ -1,10 +1,10 @@
|
||||||
#![cfg_attr(all(target_arch = "wasm32", target_feature = "simd128"), feature(wasm_simd))]
|
#![cfg_attr(all(target_arch = "wasm32", target_feature = "simd128"), feature(wasm_simd))]
|
||||||
#![cfg_attr(all(any(target_arch = "arm", target_arch = "aarch64"), target_feature = "neon"), feature(stdsimd))]
|
#![cfg_attr(all(any(target_arch = "arm", target_arch = "aarch64"), target_feature = "neon"), feature(stdsimd))]
|
||||||
|
|
||||||
pub mod simd;
|
|
||||||
pub mod complex;
|
pub mod complex;
|
||||||
pub mod ppga2d;
|
pub mod ppga2d;
|
||||||
pub mod ppga3d;
|
pub mod ppga3d;
|
||||||
|
pub mod simd;
|
||||||
|
|
||||||
impl complex::Scalar {
|
impl complex::Scalar {
|
||||||
pub const fn new(real: f32) -> Self {
|
pub const fn new(real: f32) -> Self {
|
||||||
|
|
@ -34,11 +34,11 @@ impl complex::MultiVector {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn real(self) -> f32 {
|
pub fn real(self) -> f32 {
|
||||||
self.g0.get_f(0)
|
self.g0[0]
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn imaginary(self) -> f32 {
|
pub fn imaginary(self) -> f32 {
|
||||||
self.g0.get_f(1)
|
self.g0[1]
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn from_polar(magnitude: f32, angle: f32) -> Self {
|
pub fn from_polar(magnitude: f32, angle: f32) -> Self {
|
||||||
|
|
@ -71,7 +71,7 @@ pub trait Dual {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Negates elements with `grade % 2 == 1`
|
/// Negates elements with `grade % 2 == 1`
|
||||||
///
|
///
|
||||||
/// Also called main involution
|
/// Also called main involution
|
||||||
pub trait Automorph {
|
pub trait Automorph {
|
||||||
type Output;
|
type Output;
|
||||||
|
|
@ -99,7 +99,7 @@ pub trait GeometricProduct<T> {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Dual of the geometric product grade filtered by `t == r + s`
|
/// Dual of the geometric product grade filtered by `t == r + s`
|
||||||
///
|
///
|
||||||
/// Also called join
|
/// Also called join
|
||||||
pub trait RegressiveProduct<T> {
|
pub trait RegressiveProduct<T> {
|
||||||
type Output;
|
type Output;
|
||||||
|
|
@ -107,7 +107,7 @@ pub trait RegressiveProduct<T> {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Geometric product grade filtered by `t == r + s`
|
/// Geometric product grade filtered by `t == r + s`
|
||||||
///
|
///
|
||||||
/// Also called meet or exterior product
|
/// Also called meet or exterior product
|
||||||
pub trait OuterProduct<T> {
|
pub trait OuterProduct<T> {
|
||||||
type Output;
|
type Output;
|
||||||
|
|
@ -115,7 +115,7 @@ pub trait OuterProduct<T> {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Geometric product grade filtered by `t == (r - s).abs()`
|
/// Geometric product grade filtered by `t == (r - s).abs()`
|
||||||
///
|
///
|
||||||
/// Also called fat dot product
|
/// Also called fat dot product
|
||||||
pub trait InnerProduct<T> {
|
pub trait InnerProduct<T> {
|
||||||
type Output;
|
type Output;
|
||||||
|
|
@ -141,7 +141,7 @@ pub trait ScalarProduct<T> {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// `self * other * self`
|
/// `self * other * self`
|
||||||
///
|
///
|
||||||
/// Basically a sandwich product without an involution
|
/// Basically a sandwich product without an involution
|
||||||
pub trait Reflection<T> {
|
pub trait Reflection<T> {
|
||||||
type Output;
|
type Output;
|
||||||
|
|
@ -149,7 +149,7 @@ pub trait Reflection<T> {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// `self * other * self.transpose()`
|
/// `self * other * self.transpose()`
|
||||||
///
|
///
|
||||||
/// Also called sandwich product
|
/// Also called sandwich product
|
||||||
pub trait Transformation<T> {
|
pub trait Transformation<T> {
|
||||||
type Output;
|
type Output;
|
||||||
|
|
@ -163,7 +163,7 @@ pub trait SquaredMagnitude {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Length as scalar
|
/// Length as scalar
|
||||||
///
|
///
|
||||||
/// Also called amplitude, absolute value or norm
|
/// Also called amplitude, absolute value or norm
|
||||||
pub trait Magnitude {
|
pub trait Magnitude {
|
||||||
type Output;
|
type Output;
|
||||||
|
|
@ -171,7 +171,7 @@ pub trait Magnitude {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Direction without magnitude (set to scalar `1.0`)
|
/// Direction without magnitude (set to scalar `1.0`)
|
||||||
///
|
///
|
||||||
/// Also called sign or normalize
|
/// Also called sign or normalize
|
||||||
pub trait Signum {
|
pub trait Signum {
|
||||||
type Output;
|
type Output;
|
||||||
|
|
|
||||||
95
src/simd.rs
95
src/simd.rs
|
|
@ -1,3 +1,5 @@
|
||||||
|
use std::ops::{Index, IndexMut};
|
||||||
|
|
||||||
#[cfg(target_arch = "aarch64")]
|
#[cfg(target_arch = "aarch64")]
|
||||||
pub use std::arch::aarch64::*;
|
pub use std::arch::aarch64::*;
|
||||||
#[cfg(target_arch = "arm")]
|
#[cfg(target_arch = "arm")]
|
||||||
|
|
@ -122,33 +124,63 @@ macro_rules! swizzle {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Simd32x4 {
|
impl Index<usize> for Simd32x4 {
|
||||||
pub fn get_f(&self, index: usize) -> f32 {
|
type Output = f32;
|
||||||
unsafe { self.f32x4[index] }
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn set_f(&mut self, index: usize, value: f32) {
|
fn index(&self, index: usize) -> &Self::Output {
|
||||||
unsafe { self.f32x4[index] = value; }
|
unsafe { &self.f32x4[index] }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Simd32x3 {
|
impl Index<usize> for Simd32x3 {
|
||||||
pub fn get_f(&self, index: usize) -> f32 {
|
type Output = f32;
|
||||||
unsafe { self.f32x3[index] }
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn set_f(&mut self, index: usize, value: f32) {
|
fn index(&self, index: usize) -> &Self::Output {
|
||||||
unsafe { self.f32x3[index] = value; }
|
unsafe { &self.f32x3[index] }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Simd32x2 {
|
impl Index<usize> for Simd32x2 {
|
||||||
pub fn get_f(&self, index: usize) -> f32 {
|
type Output = f32;
|
||||||
unsafe { self.f32x2[index] }
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn set_f(&mut self, index: usize, value: f32) {
|
fn index(&self, index: usize) -> &Self::Output {
|
||||||
unsafe { self.f32x2[index] = value; }
|
unsafe { &self.f32x2[index] }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl IndexMut<usize> for Simd32x4 {
|
||||||
|
fn index_mut(&mut self, index: usize) -> &mut Self::Output {
|
||||||
|
unsafe { &mut self.f32x4[index] }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl IndexMut<usize> for Simd32x3 {
|
||||||
|
fn index_mut(&mut self, index: usize) -> &mut Self::Output {
|
||||||
|
unsafe { &mut self.f32x3[index] }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl IndexMut<usize> for Simd32x2 {
|
||||||
|
fn index_mut(&mut self, index: usize) -> &mut Self::Output {
|
||||||
|
unsafe { &mut self.f32x2[index] }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl std::convert::From<Simd32x4> for [f32; 4] {
|
||||||
|
fn from(simd: Simd32x4) -> Self {
|
||||||
|
unsafe { simd.f32x4 }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl std::convert::From<Simd32x3> for [f32; 3] {
|
||||||
|
fn from(simd: Simd32x3) -> Self {
|
||||||
|
unsafe { simd.f32x3 }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl std::convert::From<Simd32x2> for [f32; 2] {
|
||||||
|
fn from(simd: Simd32x2) -> Self {
|
||||||
|
unsafe { simd.f32x2 }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -196,30 +228,33 @@ impl std::convert::From<f32> for Simd32x2 {
|
||||||
|
|
||||||
impl std::fmt::Debug for Simd32x4 {
|
impl std::fmt::Debug for Simd32x4 {
|
||||||
fn fmt(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
|
fn fmt(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
|
||||||
formatter.debug_tuple("Vec4")
|
formatter
|
||||||
.field(&self.get_f(0))
|
.debug_tuple("Vec4")
|
||||||
.field(&self.get_f(1))
|
.field(&self[0])
|
||||||
.field(&self.get_f(2))
|
.field(&self[1])
|
||||||
.field(&self.get_f(3))
|
.field(&self[2])
|
||||||
|
.field(&self[3])
|
||||||
.finish()
|
.finish()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl std::fmt::Debug for Simd32x3 {
|
impl std::fmt::Debug for Simd32x3 {
|
||||||
fn fmt(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
|
fn fmt(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
|
||||||
formatter.debug_tuple("Vec3")
|
formatter
|
||||||
.field(&self.get_f(0))
|
.debug_tuple("Vec3")
|
||||||
.field(&self.get_f(1))
|
.field(&self[0])
|
||||||
.field(&self.get_f(2))
|
.field(&self[1])
|
||||||
|
.field(&self[2])
|
||||||
.finish()
|
.finish()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl std::fmt::Debug for Simd32x2 {
|
impl std::fmt::Debug for Simd32x2 {
|
||||||
fn fmt(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
|
fn fmt(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
|
||||||
formatter.debug_tuple("Vec2")
|
formatter
|
||||||
.field(&self.get_f(0))
|
.debug_tuple("Vec2")
|
||||||
.field(&self.get_f(1))
|
.field(&self[0])
|
||||||
|
.field(&self[1])
|
||||||
.finish()
|
.finish()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue