#![allow(dead_code)]
#![allow(unused_variables)]
#![allow(unused_parens)]
#![allow(unused_imports)]
#![allow(unused_mut)]
#![allow(unused_macros)]
#![allow(non_snake_case)]
#![allow(non_camel_case_types)]
#![allow(non_upper_case_globals)]
use std::rc::Rc;
use std::ops::{Deref,DerefMut};
use std::collections::{HashMap,HashSet};
use std::any::Any;
use crate::zc_parser;
use crate::zc_parser::ZCParser;
use crate::{lbup,lbdown,lbget};
use bumpalo::Bump;
pub struct LBox<T:?Sized>
{
pub exp:Box<T>,
pub line:u32,
pub column:u32,
pub uid:u32, }
impl<T> LBox<T>
{
pub fn new(e:T,ln:usize,col:usize ) -> LBox<T>
{ LBox { exp:Box::new(e), line:ln as u32, column:col as u32,uid:0, } }
pub fn make(e:T,ln:usize,col:usize, u:u32) -> LBox<T>
{ LBox { exp:Box::new(e), line:ln as u32, column:col as u32,uid:u, } }
pub fn transfer<U>(&self,e:U) -> LBox<U>
{
LBox::make(e,self.line(),self.column(),self.uid)
}
pub fn line(&self)-> usize {self.line as usize}
pub fn column(&self)->usize {self.column as usize}
pub fn uid(&self) -> u32 {self.uid}
}impl<T> Deref for LBox<T>
{
type Target = T;
fn deref(&self) -> &Self::Target {
&self.exp
}
}
impl<T> DerefMut for LBox<T>
{
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.exp
}
}
impl<T:Default> Default for LBox<T>
{
fn default() -> Self {LBox::new(T::default(),0,0)}
}
impl<T:Clone> Clone for LBox<T>
{
fn clone(&self) -> Self
{
LBox {
exp : self.exp.clone(),
line: self.line,
column: self.column,
uid:self.uid,
}
}}
impl<T:?Sized> AsRef<T> for LBox<T>
{
fn as_ref(&self) -> &T { &*self.exp }
}
impl<T:?Sized> AsMut<T> for LBox<T>
{
fn as_mut(&mut self) -> &mut T { &mut *self.exp }
}
impl<T:Default+?Sized> LBox<T>
{
pub fn take(&mut self) -> T
{ let mut res = T::default();
std::mem::swap(&mut res, self.as_mut());
res
}
pub fn from_lc(c:LC<T>) -> Self
{
LBox{exp:Box::new(c.0), line:c.1.0, column:c.1.1, uid:c.1.2}
}
}
impl<'t> LBox<dyn Any+'t>
{
pub fn downcast<U:'t>(self) -> Option<LBox<U>>
{
let boxdown = self.exp.downcast::<U>();
if let Err(_) = boxdown {return None;}
Some(LBox {
exp : boxdown.unwrap(),
line: self.line,
column: self.column,
uid:self.uid,
})
}
pub fn upcast<T:'t>(lb:LBox<T>) -> Self
{
let bx:Box<dyn Any+'t> = lb.exp; LBox { exp:bx, line:lb.line, column:lb.column, uid:lb.uid, }
}
}
impl Default for LBox<dyn Any>
{
fn default() -> Self {LBox::upcast(LBox::new("LBox<dyn Any> defaults to this string",0,0))}
}
impl<T:std::fmt::Debug> std::fmt::Debug for LBox<T> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
std::fmt::Debug::fmt(&**self, f)
}
}
pub struct LRc<T:?Sized>
{
pub exp:Rc<T>,
pub line:u32,
pub column:u32,
}
impl<T> LRc<T>
{
pub fn new(e:T,ln:usize,col:usize ) -> LRc<T>
{ LRc { exp:Rc::new(e), line:ln as u32, column:col as u32, } }
pub fn transfer<U>(&self,e:U) -> LRc<U>
{
LRc::new(e,self.line(),self.column() )
}
pub fn clone(lrc:&LRc<T>) -> LRc<T>
{
LRc {
exp: Rc::clone(&lrc.exp),
line: lrc.line,
column: lrc.column,
}
} pub fn line(&self) -> usize {self.line as usize}
pub fn column(&self) -> usize {self.column as usize}
}
impl<T:Clone> Clone for LRc<T>
{
fn clone(&self) -> Self
{
LRc::clone(self)
}}
impl<T> Deref for LRc<T>
{
type Target = T;
fn deref(&self) -> &Self::Target {
&self.exp
}
}
impl<T:Default> Default for LRc<T>
{
fn default() -> Self {LRc::new(T::default(),0,0)}
}
impl LRc<dyn Any+'static>
{
pub fn downcast<U:'static>(self) -> Option<LRc<U>>
{
let rcdown = self.exp.downcast::<U>();
if let Err(_) = rcdown {return None;}
Some(LRc {
exp : rcdown.unwrap(),
line: self.line,
column: self.column,
})
}
pub fn upcast<T:'static>(lb:LRc<T>) -> Self
{
let bx:Rc<dyn Any> = lb.exp;
LRc { exp:bx, line:lb.line, column:lb.column, }
}
}
impl Default for LRc<dyn Any+'static>
{
fn default() -> Self {LRc::upcast(LRc::new("LRc<dyn Any> defaults to this string",0,0 ))}
}
impl<T:std::fmt::Debug> std::fmt::Debug for LRc<T> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
std::fmt::Debug::fmt(&**self, f)
}
}
pub struct LC<T>(pub T,pub (u32,u32,u32));
impl<T:Default> Default for LC<T> {
fn default() -> Self {LC(T::default(),(0,0,0))}
}
impl<T> Deref for LC<T>
{
type Target = T;
fn deref(&self) -> &Self::Target {
&self.0
}
}
impl<T> DerefMut for LC<T>
{
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.0
}
}
impl<T> AsRef<T> for LC<T>
{
fn as_ref(&self) -> &T { &self.0 }
}
impl<T> AsMut<T> for LC<T>
{
fn as_mut(&mut self) -> &mut T { &mut self.0 }
}
impl<T:std::fmt::Debug> std::fmt::Debug for LC<T> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
std::fmt::Debug::fmt(&self.0, f)
}
}
impl<T> LC<T>
{
pub fn make(x:T,ln:usize,cl:usize,uid:u32) -> Self {
LC(x,(ln as u32,cl as u32,uid))
}
pub fn new(x:T,ln:usize,cl:usize) -> Self {
LC(x,(ln as u32,cl as u32,0))
}
pub fn line(&self) -> usize { (self.1.0) as usize }
pub fn column(&self) -> usize { (self.1.1) as usize }
pub fn lncl(&self) -> (u32,u32) { (self.1.0,self.1.1) }
pub fn uid(&self) -> u32 { self.1.2 }
pub fn value(&self) -> &T { &self.0 }
pub fn transfer<U>(&self,x:U) -> LC<U> {
LC::make(x,self.line(),self.column(),self.1.2)
}
pub fn consume(self) -> T { self.0 }
}
impl<T:Default+?Sized> LC<T>
{
pub fn from_lbox(mut lb:LBox<T>) -> Self {
LC::make(lb.take(),lb.line(),lb.column(),lb.uid())
}
}
impl<T:Default+?Sized> LC<T>
{
pub fn take(&mut self) -> T
{ let mut res = T::default();
std::mem::swap(&mut res, self.as_mut());
res
}
}
pub struct Bumper<'t,ET:Default>
{
bump:Option<&'t Bump>,
exstate: ET,
}impl<T:Default> Default for Bumper<'_,T> {
fn default() -> Self { Bumper{exstate:T::default(), bump:None} }
}
impl<'t,T:Default> Bumper<'t,T>
{
pub fn set(&mut self, b:&'t Bump) { self.bump = Some(b); }
pub fn is_set(&self) -> bool { self.bump.is_some() }
pub fn get(&self)->&'t Bump { self.bump.expect("bump arena not set") }
pub fn make<S>(&self,x:S) -> &'t S {
self.get().alloc(x)
}
pub fn make_safe<S>(&self,x:S) -> Option<&'t S> {
if self.bump.is_some() {Some(self.get().alloc(x))}
else {None}
}
pub fn alloc<S>(&self,x:S) -> Option<&'t mut S> {
self.bump.map(|b|b.alloc(x))
}
pub fn state(&mut self) -> &mut T { &mut self.exstate }
}
type ABox = LBox<GenAbsyn>;
#[derive(Clone,Debug)]
enum GenAbsyn
{
Integer(i64),
BigInteger(String),
Float(f64),
Symbol(&'static str),
Keyword(&'static str),
Alphanum(String),
Stringlit(String),
Verbatim(String),
Uniop(usize,ABox),
Binop(usize,ABox,ABox),
Ternop(usize,ABox,ABox,ABox),
Sequence(usize,Vec<ABox>),
Partial(ABox,String), NewLine,
Whitespaces(usize),
Nothing,
}
impl GenAbsyn
{
fn is_complete(&self) -> bool
{
match self
{
GenAbsyn::Partial(_,_) => false,
GenAbsyn::Uniop(_,s) => {
println!("s.line {}{}",s.line,s.column);
s.is_complete()
},
GenAbsyn::Binop(_,a,b) => a.is_complete() && b.is_complete(),
GenAbsyn::Ternop(_,a,b,c) => a.is_complete() && b.is_complete() && c.is_complete(),
GenAbsyn::Sequence(_,v) => {
for x in v { if !x.is_complete() {return false; } }
true
}
_ => true,
}
}}
impl Default for GenAbsyn
{
fn default() -> Self { GenAbsyn::Nothing }
}
struct Absyn_Statics<const N:usize,const M:usize,const P:usize>
{
pub KEYWORDS: [&'static str; N],
pub SYMBOLS: [&'static str; M],
pub OPERATORS: [&'static str; P],
pub Keyhash:HashMap<&'static str,usize>,
pub Symhash:HashMap<&'static str,usize>,
pub Ophash: HashMap<&'static str,usize>,
}
impl<const N:usize,const M:usize,const P:usize> Absyn_Statics<N,M,P>
{
fn new(k:[&'static str; N],s:[&'static str;M],p:[&'static str;P])
-> Absyn_Statics<N,M,P>
{
let mut newas = Absyn_Statics {
KEYWORDS: k,
SYMBOLS: s,
OPERATORS:p,
Keyhash: HashMap::with_capacity(N),
Symhash: HashMap::with_capacity(M),
Ophash: HashMap::with_capacity(P),
};
for i in 0..N { newas.Keyhash.insert(k[i],i); }
for i in 0..M { newas.Symhash.insert(s[i],i); }
for i in 0..P { newas.Ophash.insert(p[i],i); }
return newas;
}
pub fn is_keyword(&self,k:&str) -> bool
{ self.Keyhash.contains_key(k) }
pub fn is_symbol(&self,k:&str) -> bool
{ self.Symhash.contains_key(k) }
pub fn is_operator(&self,k:&str) -> bool
{ self.Ophash.contains_key(k) }
}
#[macro_export]
macro_rules! lbup {
( $x:expr ) => {
LBox::upcast($x)
};
}
#[macro_export]
macro_rules! lbdown {
( $x:expr,$t:ty ) => {
$x.downcast::<$t>().unwrap()
};
}
#[macro_export]
macro_rules! lbget {
( $x:expr,$t:ty ) => {
*$x.downcast::<$t>().unwrap().exp
};
}
#[macro_export]
macro_rules! unbox {
( $x:expr ) => {
*$x.exp
};
}
#[macro_export]
macro_rules! makelbox {
($si:expr, $e:expr) => {
LBox::new($e,$si.line,$si.column)
};
}
#[macro_export]
macro_rules! makelrc {
($si:expr, $e:expr) => {
LRc::new($e,$si.line,$si.column)
};
}