cl-ast: Cleanup
- Function bind is now one Pattern - TyRef now allows &Ty (i.e. &[i32], &(char, bool) - Range patterns (they cannot bind, only check whether a value is in range - ArrayRep repeat has been reverted to usize, for now, until early consteval is implemented.
This commit is contained in:
parent
ef92d8b798
commit
7ba808594c
@ -129,7 +129,7 @@ pub struct Static {
|
|||||||
pub struct Function {
|
pub struct Function {
|
||||||
pub name: Sym,
|
pub name: Sym,
|
||||||
pub sign: TyFn,
|
pub sign: TyFn,
|
||||||
pub bind: Vec<Pattern>,
|
pub bind: Pattern,
|
||||||
pub body: Option<Expr>,
|
pub body: Option<Expr>,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -255,7 +255,7 @@ pub struct TyTuple {
|
|||||||
pub struct TyRef {
|
pub struct TyRef {
|
||||||
pub mutable: Mutability,
|
pub mutable: Mutability,
|
||||||
pub count: u16,
|
pub count: u16,
|
||||||
pub to: Path,
|
pub to: Box<Ty>,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The args and return value for a function pointer [Ty]pe
|
/// The args and return value for a function pointer [Ty]pe
|
||||||
@ -360,7 +360,7 @@ pub enum ExprKind {
|
|||||||
While(While),
|
While(While),
|
||||||
/// An [If] expression: `if` [`Expr`] [`Block`] [`Else`]?
|
/// An [If] expression: `if` [`Expr`] [`Block`] [`Else`]?
|
||||||
If(If),
|
If(If),
|
||||||
/// A [For] expression: `for` Pattern `in` [`Expr`] [`Block`] [`Else`]?
|
/// A [For] expression: `for` [`Pattern`] `in` [`Expr`] [`Block`] [`Else`]?
|
||||||
For(For),
|
For(For),
|
||||||
/// A [Break] expression: `break` [`Expr`]?
|
/// A [Break] expression: `break` [`Expr`]?
|
||||||
Break(Break),
|
Break(Break),
|
||||||
@ -392,6 +392,8 @@ pub enum Pattern {
|
|||||||
Literal(Literal),
|
Literal(Literal),
|
||||||
Rest(Option<Box<Pattern>>),
|
Rest(Option<Box<Pattern>>),
|
||||||
Ref(Mutability, Box<Pattern>),
|
Ref(Mutability, Box<Pattern>),
|
||||||
|
RangeExc(Box<Pattern>, Box<Pattern>),
|
||||||
|
RangeInc(Box<Pattern>, Box<Pattern>),
|
||||||
Tuple(Vec<Pattern>),
|
Tuple(Vec<Pattern>),
|
||||||
Array(Vec<Pattern>),
|
Array(Vec<Pattern>),
|
||||||
Struct(Path, Vec<(Sym, Option<Pattern>)>),
|
Struct(Path, Vec<(Sym, Option<Pattern>)>),
|
||||||
@ -557,7 +559,7 @@ pub struct Array {
|
|||||||
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
|
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
|
||||||
pub struct ArrayRep {
|
pub struct ArrayRep {
|
||||||
pub value: Box<Expr>,
|
pub value: Box<Expr>,
|
||||||
pub repeat: Box<Expr>,
|
pub repeat: usize,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// An address-of expression: `&` `mut`? [`Expr`]
|
/// An address-of expression: `&` `mut`? [`Expr`]
|
||||||
|
@ -140,6 +140,14 @@ impl TryFrom<Expr> for Pattern {
|
|||||||
};
|
};
|
||||||
Pattern::TupleStruct(path, args)
|
Pattern::TupleStruct(path, args)
|
||||||
}
|
}
|
||||||
|
ExprKind::Binary(Binary { kind: BinaryKind::RangeExc, parts }) => {
|
||||||
|
let (head, tail) = (Pattern::try_from(parts.0)?, Pattern::try_from(parts.1)?);
|
||||||
|
Pattern::RangeExc(head.into(), tail.into())
|
||||||
|
}
|
||||||
|
ExprKind::Binary(Binary { kind: BinaryKind::RangeInc, parts }) => {
|
||||||
|
let (head, tail) = (Pattern::try_from(parts.0)?, Pattern::try_from(parts.1)?);
|
||||||
|
Pattern::RangeInc(head.into(), tail.into())
|
||||||
|
}
|
||||||
ExprKind::Unary(Unary { kind: UnaryKind::RangeExc, tail }) => {
|
ExprKind::Unary(Unary { kind: UnaryKind::RangeExc, tail }) => {
|
||||||
Pattern::Rest(Some(Pattern::try_from(*tail)?.into()))
|
Pattern::Rest(Some(Pattern::try_from(*tail)?.into()))
|
||||||
}
|
}
|
||||||
|
@ -161,11 +161,19 @@ impl Display for Function {
|
|||||||
Default::default()
|
Default::default()
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
let bind = match bind {
|
||||||
|
Pattern::Tuple(patterns) => patterns.as_slice(),
|
||||||
|
_ => {
|
||||||
|
write!(f, "Invalid argument binder: {bind}")?;
|
||||||
|
Default::default()
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
debug_assert_eq!(bind.len(), types.len());
|
debug_assert_eq!(bind.len(), types.len());
|
||||||
write!(f, "fn {name} ")?;
|
write!(f, "fn {name} ")?;
|
||||||
{
|
{
|
||||||
let mut f = f.delimit(INLINE_PARENS);
|
let mut f = f.delimit(INLINE_PARENS);
|
||||||
|
|
||||||
for (idx, (arg, ty)) in bind.iter().zip(types.iter()).enumerate() {
|
for (idx, (arg, ty)) in bind.iter().zip(types.iter()).enumerate() {
|
||||||
if idx != 0 {
|
if idx != 0 {
|
||||||
f.write_str(", ")?;
|
f.write_str(", ")?;
|
||||||
@ -453,6 +461,8 @@ impl Display for Pattern {
|
|||||||
Pattern::Rest(Some(name)) => write!(f, "..{name}"),
|
Pattern::Rest(Some(name)) => write!(f, "..{name}"),
|
||||||
Pattern::Rest(None) => "..".fmt(f),
|
Pattern::Rest(None) => "..".fmt(f),
|
||||||
Pattern::Ref(mutability, pattern) => write!(f, "&{mutability}{pattern}"),
|
Pattern::Ref(mutability, pattern) => write!(f, "&{mutability}{pattern}"),
|
||||||
|
Pattern::RangeExc(head, tail) => write!(f, "{head}..{tail}"),
|
||||||
|
Pattern::RangeInc(head, tail) => write!(f, "{head}..={tail}"),
|
||||||
Pattern::Tuple(patterns) => separate(patterns, ", ")(f.delimit(INLINE_PARENS)),
|
Pattern::Tuple(patterns) => separate(patterns, ", ")(f.delimit(INLINE_PARENS)),
|
||||||
Pattern::Array(patterns) => separate(patterns, ", ")(f.delimit(INLINE_SQUARE)),
|
Pattern::Array(patterns) => separate(patterns, ", ")(f.delimit(INLINE_SQUARE)),
|
||||||
Pattern::Struct(path, items) => {
|
Pattern::Struct(path, items) => {
|
||||||
|
@ -342,6 +342,8 @@ impl WeightOf for Pattern {
|
|||||||
Pattern::Rest(Some(pattern)) => pattern.weight_of(),
|
Pattern::Rest(Some(pattern)) => pattern.weight_of(),
|
||||||
Pattern::Rest(None) => 0,
|
Pattern::Rest(None) => 0,
|
||||||
Pattern::Ref(mutability, pattern) => mutability.weight_of() + pattern.weight_of(),
|
Pattern::Ref(mutability, pattern) => mutability.weight_of() + pattern.weight_of(),
|
||||||
|
Pattern::RangeExc(head, tail) => head.weight_of() + tail.weight_of(),
|
||||||
|
Pattern::RangeInc(head, tail) => head.weight_of() + tail.weight_of(),
|
||||||
Pattern::Tuple(patterns) | Pattern::Array(patterns) => patterns.weight_of(),
|
Pattern::Tuple(patterns) | Pattern::Array(patterns) => patterns.weight_of(),
|
||||||
Pattern::Struct(path, items) => {
|
Pattern::Struct(path, items) => {
|
||||||
let sitems: usize = items
|
let sitems: usize = items
|
||||||
|
@ -100,7 +100,7 @@ pub trait Fold {
|
|||||||
Function {
|
Function {
|
||||||
name: self.fold_sym(name),
|
name: self.fold_sym(name),
|
||||||
sign: self.fold_ty_fn(sign),
|
sign: self.fold_ty_fn(sign),
|
||||||
bind: bind.into_iter().map(|p| self.fold_pattern(p)).collect(),
|
bind: self.fold_pattern(bind),
|
||||||
body: body.map(|b| self.fold_expr(b)),
|
body: body.map(|b| self.fold_expr(b)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -184,7 +184,7 @@ pub trait Fold {
|
|||||||
}
|
}
|
||||||
fn fold_ty_ref(&mut self, t: TyRef) -> TyRef {
|
fn fold_ty_ref(&mut self, t: TyRef) -> TyRef {
|
||||||
let TyRef { mutable, count, to } = t;
|
let TyRef { mutable, count, to } = t;
|
||||||
TyRef { mutable: self.fold_mutability(mutable), count, to: self.fold_path(to) }
|
TyRef { mutable: self.fold_mutability(mutable), count, to: Box::new(self.fold_ty(*to)) }
|
||||||
}
|
}
|
||||||
fn fold_ty_fn(&mut self, t: TyFn) -> TyFn {
|
fn fold_ty_fn(&mut self, t: TyFn) -> TyFn {
|
||||||
let TyFn { args, rety } = t;
|
let TyFn { args, rety } = t;
|
||||||
@ -246,6 +246,14 @@ pub trait Fold {
|
|||||||
self.fold_mutability(mutability),
|
self.fold_mutability(mutability),
|
||||||
Box::new(self.fold_pattern(*pattern)),
|
Box::new(self.fold_pattern(*pattern)),
|
||||||
),
|
),
|
||||||
|
Pattern::RangeExc(head, tail) => Pattern::RangeInc(
|
||||||
|
Box::new(self.fold_pattern(*head)),
|
||||||
|
Box::new(self.fold_pattern(*tail)),
|
||||||
|
),
|
||||||
|
Pattern::RangeInc(head, tail) => Pattern::RangeInc(
|
||||||
|
Box::new(self.fold_pattern(*head)),
|
||||||
|
Box::new(self.fold_pattern(*tail)),
|
||||||
|
),
|
||||||
Pattern::Tuple(patterns) => {
|
Pattern::Tuple(patterns) => {
|
||||||
Pattern::Tuple(patterns.into_iter().map(|p| self.fold_pattern(p)).collect())
|
Pattern::Tuple(patterns.into_iter().map(|p| self.fold_pattern(p)).collect())
|
||||||
}
|
}
|
||||||
@ -356,10 +364,7 @@ pub trait Fold {
|
|||||||
}
|
}
|
||||||
fn fold_array_rep(&mut self, a: ArrayRep) -> ArrayRep {
|
fn fold_array_rep(&mut self, a: ArrayRep) -> ArrayRep {
|
||||||
let ArrayRep { value, repeat } = a;
|
let ArrayRep { value, repeat } = a;
|
||||||
ArrayRep {
|
ArrayRep { value: Box::new(self.fold_expr(*value)), repeat }
|
||||||
value: Box::new(self.fold_expr(*value)),
|
|
||||||
repeat: Box::new(self.fold_expr(*repeat)),
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
fn fold_addrof(&mut self, a: AddrOf) -> AddrOf {
|
fn fold_addrof(&mut self, a: AddrOf) -> AddrOf {
|
||||||
let AddrOf { mutable, expr } = a;
|
let AddrOf { mutable, expr } = a;
|
||||||
|
@ -82,7 +82,7 @@ pub trait Visit<'a>: Sized {
|
|||||||
let Function { name, sign, bind, body } = f;
|
let Function { name, sign, bind, body } = f;
|
||||||
self.visit_sym(name);
|
self.visit_sym(name);
|
||||||
self.visit_ty_fn(sign);
|
self.visit_ty_fn(sign);
|
||||||
bind.iter().for_each(|p| self.visit_pattern(p));
|
self.visit_pattern(bind);
|
||||||
if let Some(b) = body {
|
if let Some(b) = body {
|
||||||
self.visit_expr(b)
|
self.visit_expr(b)
|
||||||
}
|
}
|
||||||
@ -154,7 +154,7 @@ pub trait Visit<'a>: Sized {
|
|||||||
fn visit_ty_ref(&mut self, t: &'a TyRef) {
|
fn visit_ty_ref(&mut self, t: &'a TyRef) {
|
||||||
let TyRef { mutable, count: _, to } = t;
|
let TyRef { mutable, count: _, to } = t;
|
||||||
self.visit_mutability(mutable);
|
self.visit_mutability(mutable);
|
||||||
self.visit_path(to);
|
self.visit_ty(to);
|
||||||
}
|
}
|
||||||
fn visit_ty_fn(&mut self, t: &'a TyFn) {
|
fn visit_ty_fn(&mut self, t: &'a TyFn) {
|
||||||
let TyFn { args, rety } = t;
|
let TyFn { args, rety } = t;
|
||||||
@ -215,6 +215,14 @@ pub trait Visit<'a>: Sized {
|
|||||||
self.visit_mutability(mutability);
|
self.visit_mutability(mutability);
|
||||||
self.visit_pattern(pattern);
|
self.visit_pattern(pattern);
|
||||||
}
|
}
|
||||||
|
Pattern::RangeExc(head, tail) => {
|
||||||
|
self.visit_pattern(head);
|
||||||
|
self.visit_pattern(tail);
|
||||||
|
}
|
||||||
|
Pattern::RangeInc(head, tail) => {
|
||||||
|
self.visit_pattern(head);
|
||||||
|
self.visit_pattern(tail);
|
||||||
|
}
|
||||||
Pattern::Tuple(patterns) => {
|
Pattern::Tuple(patterns) => {
|
||||||
patterns.iter().for_each(|p| self.visit_pattern(p));
|
patterns.iter().for_each(|p| self.visit_pattern(p));
|
||||||
}
|
}
|
||||||
@ -311,9 +319,8 @@ pub trait Visit<'a>: Sized {
|
|||||||
values.iter().for_each(|e| self.visit_expr(e))
|
values.iter().for_each(|e| self.visit_expr(e))
|
||||||
}
|
}
|
||||||
fn visit_array_rep(&mut self, a: &'a ArrayRep) {
|
fn visit_array_rep(&mut self, a: &'a ArrayRep) {
|
||||||
let ArrayRep { value, repeat } = a;
|
let ArrayRep { value, repeat: _ } = a;
|
||||||
self.visit_expr(value);
|
self.visit_expr(value);
|
||||||
self.visit_expr(repeat);
|
|
||||||
}
|
}
|
||||||
fn visit_addrof(&mut self, a: &'a AddrOf) {
|
fn visit_addrof(&mut self, a: &'a AddrOf) {
|
||||||
let AddrOf { mutable, expr } = a;
|
let AddrOf { mutable, expr } = a;
|
||||||
|
@ -57,9 +57,6 @@ impl Callable for Function {
|
|||||||
let FnDecl { name, bind, body, sign: _ } = &*self.decl;
|
let FnDecl { name, bind, body, sign: _ } = &*self.decl;
|
||||||
|
|
||||||
// Check arg mapping
|
// Check arg mapping
|
||||||
if args.len() != bind.len() {
|
|
||||||
return Err(Error::ArgNumber(bind.len(), args.len()));
|
|
||||||
}
|
|
||||||
if self.is_constructor {
|
if self.is_constructor {
|
||||||
return Ok(ConValue::TupleStruct(Box::new((
|
return Ok(ConValue::TupleStruct(Box::new((
|
||||||
name.to_ref(),
|
name.to_ref(),
|
||||||
@ -73,14 +70,10 @@ impl Callable for Function {
|
|||||||
let upvars = self.upvars.take();
|
let upvars = self.upvars.take();
|
||||||
env.push_frame("upvars", upvars);
|
env.push_frame("upvars", upvars);
|
||||||
|
|
||||||
eprintln!("{name}{args:?}");
|
|
||||||
|
|
||||||
// TODO: completely refactor data storage
|
// TODO: completely refactor data storage
|
||||||
let mut frame = env.frame("fn args");
|
let mut frame = env.frame("fn args");
|
||||||
for (bind, value) in bind.iter().zip(args) {
|
for (name, value) in pattern::substitution(bind, ConValue::Tuple(args.into()))? {
|
||||||
for (name, value) in pattern::substitution(bind, value.clone())? {
|
frame.insert(*name, Some(value));
|
||||||
frame.insert(*name, Some(value));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
let res = body.interpret(&mut frame);
|
let res = body.interpret(&mut frame);
|
||||||
drop(frame);
|
drop(frame);
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
//! Collects the "Upvars" of a function at the point of its creation, allowing variable capture
|
//! Collects the "Upvars" of a function at the point of its creation, allowing variable capture
|
||||||
use crate::{convalue::ConValue, env::Environment};
|
use crate::{convalue::ConValue, env::Environment};
|
||||||
use cl_ast::{ast_visitor::visit::*, Function, Let, Path, PathPart, Pattern, Sym};
|
use cl_ast::{Function, Let, Path, PathPart, Pattern, Sym, ast_visitor::visit::*};
|
||||||
use std::collections::{HashMap, HashSet};
|
use std::collections::{HashMap, HashSet};
|
||||||
|
|
||||||
pub fn collect_upvars(f: &Function, env: &Environment) -> super::Upvars {
|
pub fn collect_upvars(f: &Function, env: &Environment) -> super::Upvars {
|
||||||
@ -67,7 +67,7 @@ impl<'a> Visit<'a> for CollectUpvars<'_> {
|
|||||||
fn visit_function(&mut self, f: &'a cl_ast::Function) {
|
fn visit_function(&mut self, f: &'a cl_ast::Function) {
|
||||||
let Function { name: _, sign: _, bind, body } = f;
|
let Function { name: _, sign: _, bind, body } = f;
|
||||||
// parameters can never be upvars
|
// parameters can never be upvars
|
||||||
bind.iter().for_each(|pat| self.visit_pattern(pat));
|
self.visit_pattern(bind);
|
||||||
if let Some(body) = body {
|
if let Some(body) = body {
|
||||||
self.visit_expr(body);
|
self.visit_expr(body);
|
||||||
}
|
}
|
||||||
@ -115,6 +115,8 @@ impl<'a> Visit<'a> for CollectUpvars<'_> {
|
|||||||
self.visit_mutability(mutability);
|
self.visit_mutability(mutability);
|
||||||
self.visit_pattern(pattern);
|
self.visit_pattern(pattern);
|
||||||
}
|
}
|
||||||
|
Pattern::RangeExc(_, _) => {}
|
||||||
|
Pattern::RangeInc(_, _) => {}
|
||||||
Pattern::Tuple(patterns) => {
|
Pattern::Tuple(patterns) => {
|
||||||
patterns.iter().for_each(|p| self.visit_pattern(p));
|
patterns.iter().for_each(|p| self.visit_pattern(p));
|
||||||
}
|
}
|
||||||
|
@ -134,11 +134,12 @@ impl Interpret for Struct {
|
|||||||
.into(),
|
.into(),
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
bind: args
|
bind: Pattern::Tuple(
|
||||||
.iter()
|
args.iter()
|
||||||
.enumerate()
|
.enumerate()
|
||||||
.map(|(idx, _)| Pattern::Name(idx.to_string().into()))
|
.map(|(idx, _)| Pattern::Name(idx.to_string().into()))
|
||||||
.collect(),
|
.collect(),
|
||||||
|
),
|
||||||
body: None,
|
body: None,
|
||||||
};
|
};
|
||||||
let constructor = crate::function::Function::new_constructor(constructor);
|
let constructor = crate::function::Function::new_constructor(constructor);
|
||||||
@ -814,12 +815,8 @@ impl Interpret for Array {
|
|||||||
impl Interpret for ArrayRep {
|
impl Interpret for ArrayRep {
|
||||||
fn interpret(&self, env: &mut Environment) -> IResult<ConValue> {
|
fn interpret(&self, env: &mut Environment) -> IResult<ConValue> {
|
||||||
let Self { value, repeat } = self;
|
let Self { value, repeat } = self;
|
||||||
let repeat = match repeat.interpret(env)? {
|
|
||||||
ConValue::Int(v) => v,
|
|
||||||
_ => Err(Error::TypeError())?,
|
|
||||||
};
|
|
||||||
let value = value.interpret(env)?;
|
let value = value.interpret(env)?;
|
||||||
Ok(ConValue::Array(vec![value; repeat as usize].into()))
|
Ok(ConValue::Array(vec![value; *repeat].into()))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
impl Interpret for AddrOf {
|
impl Interpret for AddrOf {
|
||||||
|
@ -20,6 +20,8 @@ pub fn variables(pat: &Pattern) -> Vec<&Sym> {
|
|||||||
Pattern::Rest(Some(pattern)) => patvars(set, pattern),
|
Pattern::Rest(Some(pattern)) => patvars(set, pattern),
|
||||||
Pattern::Rest(None) => {}
|
Pattern::Rest(None) => {}
|
||||||
Pattern::Ref(_, pattern) => patvars(set, pattern),
|
Pattern::Ref(_, pattern) => patvars(set, pattern),
|
||||||
|
Pattern::RangeExc(_, _) => {}
|
||||||
|
Pattern::RangeInc(_, _) => {}
|
||||||
Pattern::Tuple(patterns) | Pattern::Array(patterns) => {
|
Pattern::Tuple(patterns) | Pattern::Array(patterns) => {
|
||||||
patterns.iter().for_each(|pat| patvars(set, pat))
|
patterns.iter().for_each(|pat| patvars(set, pat))
|
||||||
}
|
}
|
||||||
@ -127,6 +129,70 @@ pub fn append_sub<'pat>(
|
|||||||
todo!("Dereference <{r}> in pattern matching {pat}")
|
todo!("Dereference <{r}> in pattern matching {pat}")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
(Pattern::RangeExc(head, tail), value) => match (head.as_ref(), tail.as_ref(), value) {
|
||||||
|
(
|
||||||
|
Pattern::Literal(Literal::Int(a)),
|
||||||
|
Pattern::Literal(Literal::Int(c)),
|
||||||
|
ConValue::Int(b),
|
||||||
|
) => (*a as isize <= b as _ && b < *c as isize)
|
||||||
|
.then_some(())
|
||||||
|
.ok_or(Error::NotAssignable()),
|
||||||
|
(
|
||||||
|
Pattern::Literal(Literal::Char(a)),
|
||||||
|
Pattern::Literal(Literal::Char(c)),
|
||||||
|
ConValue::Char(b),
|
||||||
|
) => (*a <= b && b < *c)
|
||||||
|
.then_some(())
|
||||||
|
.ok_or(Error::NotAssignable()),
|
||||||
|
(
|
||||||
|
Pattern::Literal(Literal::Float(a)),
|
||||||
|
Pattern::Literal(Literal::Float(c)),
|
||||||
|
ConValue::Float(b),
|
||||||
|
) => (f64::from_bits(*a) <= b && b < f64::from_bits(*c))
|
||||||
|
.then_some(())
|
||||||
|
.ok_or(Error::NotAssignable()),
|
||||||
|
(
|
||||||
|
Pattern::Literal(Literal::String(a)),
|
||||||
|
Pattern::Literal(Literal::String(c)),
|
||||||
|
ConValue::String(b),
|
||||||
|
) => (a.as_str() <= b.to_ref() && b.to_ref() < c.as_str())
|
||||||
|
.then_some(())
|
||||||
|
.ok_or(Error::NotAssignable()),
|
||||||
|
_ => Err(Error::NotAssignable()),
|
||||||
|
},
|
||||||
|
|
||||||
|
(Pattern::RangeInc(head, tail), value) => match (head.as_ref(), tail.as_ref(), value) {
|
||||||
|
(
|
||||||
|
Pattern::Literal(Literal::Int(a)),
|
||||||
|
Pattern::Literal(Literal::Int(c)),
|
||||||
|
ConValue::Int(b),
|
||||||
|
) => (*a as isize <= b && b <= *c as isize)
|
||||||
|
.then_some(())
|
||||||
|
.ok_or(Error::NotAssignable()),
|
||||||
|
(
|
||||||
|
Pattern::Literal(Literal::Char(a)),
|
||||||
|
Pattern::Literal(Literal::Char(c)),
|
||||||
|
ConValue::Char(b),
|
||||||
|
) => (*a <= b && b <= *c)
|
||||||
|
.then_some(())
|
||||||
|
.ok_or(Error::NotAssignable()),
|
||||||
|
(
|
||||||
|
Pattern::Literal(Literal::Float(a)),
|
||||||
|
Pattern::Literal(Literal::Float(c)),
|
||||||
|
ConValue::Float(b),
|
||||||
|
) => (f64::from_bits(*a) <= b && b <= f64::from_bits(*c))
|
||||||
|
.then_some(())
|
||||||
|
.ok_or(Error::NotAssignable()),
|
||||||
|
(
|
||||||
|
Pattern::Literal(Literal::String(a)),
|
||||||
|
Pattern::Literal(Literal::String(c)),
|
||||||
|
ConValue::String(b),
|
||||||
|
) => (a.as_str() <= b.to_ref() && b.to_ref() <= c.as_str())
|
||||||
|
.then_some(())
|
||||||
|
.ok_or(Error::NotAssignable()),
|
||||||
|
_ => Err(Error::NotAssignable()),
|
||||||
|
},
|
||||||
|
|
||||||
(Pattern::Array(patterns), ConValue::Array(values)) => {
|
(Pattern::Array(patterns), ConValue::Array(values)) => {
|
||||||
match rest_binding(sub, patterns, values.into_vec().into())? {
|
match rest_binding(sub, patterns, values.into_vec().into())? {
|
||||||
Some((pattern, values)) => {
|
Some((pattern, values)) => {
|
||||||
|
@ -469,7 +469,7 @@ impl Parse<'_> for Function {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
type FnSig = (Vec<Pattern>, Vec<TyKind>);
|
type FnSig = (Pattern, Vec<TyKind>);
|
||||||
|
|
||||||
impl Parse<'_> for FnSig {
|
impl Parse<'_> for FnSig {
|
||||||
/// Parses the [parameters](Param) associated with a Function
|
/// Parses the [parameters](Param) associated with a Function
|
||||||
@ -484,7 +484,7 @@ impl Parse<'_> for FnSig {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Ok((params, types))
|
Ok((Pattern::Tuple(params), types))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -783,7 +783,7 @@ impl Parse<'_> for TyRef {
|
|||||||
}
|
}
|
||||||
p.consume_peeked();
|
p.consume_peeked();
|
||||||
}
|
}
|
||||||
Ok(TyRef { count, mutable: Mutability::parse(p)?, to: Path::parse(p)? })
|
Ok(TyRef { count, mutable: Mutability::parse(p)?, to: Box::new(Ty::parse(p)?) })
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -203,7 +203,13 @@ fn exprkind_array_rep(p: &mut Parser) -> PResult<ExprKind> {
|
|||||||
value: first.into(),
|
value: first.into(),
|
||||||
repeat: {
|
repeat: {
|
||||||
p.consume_peeked();
|
p.consume_peeked();
|
||||||
Box::new(expr(p, 0)?)
|
let value = p.match_type(TokenKind::Literal, Parsing::ArrayRep)?;
|
||||||
|
match value.data() {
|
||||||
|
TokenData::Integer(size) => *size as usize,
|
||||||
|
_ => {
|
||||||
|
Err(p.error(ErrorKind::Unexpected(TokenKind::Literal), Parsing::ArrayRep))?
|
||||||
|
}
|
||||||
|
}
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
.into(),
|
.into(),
|
||||||
|
@ -54,13 +54,13 @@ fn main() -> Result<(), Box<dyn Error>> {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub use yamler::CLangifier;
|
pub use clangifier::CLangifier;
|
||||||
pub mod yamler {
|
pub mod clangifier {
|
||||||
use crate::yamlify::CLangify;
|
use crate::clangify::CLangify;
|
||||||
use std::{
|
use std::{
|
||||||
fmt::Display,
|
fmt::Display,
|
||||||
io::Write,
|
io::Write,
|
||||||
ops::{Deref, DerefMut},
|
ops::{Add, Deref, DerefMut},
|
||||||
};
|
};
|
||||||
#[derive(Debug, Default)]
|
#[derive(Debug, Default)]
|
||||||
pub struct CLangifier {
|
pub struct CLangifier {
|
||||||
@ -104,12 +104,20 @@ pub mod yamler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Prints a section header and increases indentation
|
/// Prints a section header and increases indentation
|
||||||
pub fn key(&mut self, name: impl Display) -> Section {
|
pub fn nest(&mut self, name: impl Display) -> Section {
|
||||||
print!("{name}");
|
print!("{name}");
|
||||||
self.indent()
|
self.indent()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<C: CLangify + ?Sized> Add<&C> for &mut CLangifier {
|
||||||
|
type Output = Self;
|
||||||
|
|
||||||
|
fn add(self, rhs: &C) -> Self::Output {
|
||||||
|
self.p(rhs)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Tracks the start and end of an indented block (a "section")
|
/// Tracks the start and end of an indented block (a "section")
|
||||||
pub struct Section<'y> {
|
pub struct Section<'y> {
|
||||||
yamler: &'y mut CLangifier,
|
yamler: &'y mut CLangifier,
|
||||||
@ -142,10 +150,11 @@ pub mod yamler {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub mod yamlify {
|
pub mod clangify {
|
||||||
|
use core::panic;
|
||||||
use std::iter;
|
use std::iter;
|
||||||
|
|
||||||
use super::yamler::CLangifier;
|
use super::clangifier::CLangifier;
|
||||||
use cl_ast::*;
|
use cl_ast::*;
|
||||||
|
|
||||||
pub trait CLangify {
|
pub trait CLangify {
|
||||||
@ -153,11 +162,17 @@ pub mod yamlify {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl CLangify for File {
|
impl CLangify for File {
|
||||||
fn print(&self, y: &mut CLangifier) {
|
fn print(&self, mut y: &mut CLangifier) {
|
||||||
let File { name, items } = self;
|
let File { name, items } = self;
|
||||||
// TODO: turn name into include guard
|
// TODO: turn name into include guard
|
||||||
y.p("// Generated from ").p(name).endl();
|
y = (y + "// Generated from " + name).endl();
|
||||||
y.p(items);
|
for (idx, item) in items.iter().enumerate() {
|
||||||
|
if idx > 0 {
|
||||||
|
y.endl().endl();
|
||||||
|
}
|
||||||
|
y.p(item);
|
||||||
|
}
|
||||||
|
y.endl();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
impl CLangify for Visibility {
|
impl CLangify for Visibility {
|
||||||
@ -174,14 +189,14 @@ pub mod yamlify {
|
|||||||
impl CLangify for Attrs {
|
impl CLangify for Attrs {
|
||||||
fn print(&self, y: &mut CLangifier) {
|
fn print(&self, y: &mut CLangifier) {
|
||||||
let Self { meta } = self;
|
let Self { meta } = self;
|
||||||
y.key("Attrs").p(meta);
|
y.nest("Attrs").p(meta);
|
||||||
todo!("Attributes");
|
todo!("Attributes");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
impl CLangify for Meta {
|
impl CLangify for Meta {
|
||||||
fn print(&self, y: &mut CLangifier) {
|
fn print(&self, y: &mut CLangifier) {
|
||||||
let Self { name, kind } = self;
|
let Self { name, kind } = self;
|
||||||
y.key("Meta").p(name).p(kind);
|
y.nest("Meta").p(name).p(kind);
|
||||||
todo!("Attributes");
|
todo!("Attributes");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -199,7 +214,7 @@ pub mod yamlify {
|
|||||||
impl CLangify for Item {
|
impl CLangify for Item {
|
||||||
fn print(&self, y: &mut CLangifier) {
|
fn print(&self, y: &mut CLangifier) {
|
||||||
let Self { span: _, attrs: _, vis, kind } = self;
|
let Self { span: _, attrs: _, vis, kind } = self;
|
||||||
y.p(vis).p(kind).endl().endl();
|
y.p(vis).p(kind);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
impl CLangify for ItemKind {
|
impl CLangify for ItemKind {
|
||||||
@ -241,7 +256,7 @@ pub mod yamlify {
|
|||||||
impl CLangify for Module {
|
impl CLangify for Module {
|
||||||
fn print(&self, y: &mut CLangifier) {
|
fn print(&self, y: &mut CLangifier) {
|
||||||
let Self { name, file } = self;
|
let Self { name, file } = self;
|
||||||
y.key("// mod ").p(name).p(" {").endl();
|
y.nest("// mod ").p(name).p(" {").endl();
|
||||||
y.p(file);
|
y.p(file);
|
||||||
y.endl().p("// } mod ").p(name);
|
y.endl().p("// } mod ").p(name);
|
||||||
}
|
}
|
||||||
@ -255,13 +270,17 @@ pub mod yamlify {
|
|||||||
TyKind::Empty => &[],
|
TyKind::Empty => &[],
|
||||||
_ => panic!("Unsupported function args: {args}"),
|
_ => panic!("Unsupported function args: {args}"),
|
||||||
};
|
};
|
||||||
|
let bind = match bind {
|
||||||
|
Pattern::Tuple(tup) => tup.as_slice(),
|
||||||
|
_ => panic!("Unsupported function binders: {args}"),
|
||||||
|
};
|
||||||
match rety {
|
match rety {
|
||||||
Some(ty) => y.p(ty),
|
Some(ty) => y.p(ty),
|
||||||
None => y.p("void"),
|
None => y.p("void"),
|
||||||
}
|
}
|
||||||
.p(" ")
|
.p(" ")
|
||||||
.p(name)
|
.p(name)
|
||||||
.p("(");
|
.p(" (");
|
||||||
for (idx, (bind, ty)) in bind.iter().zip(types).enumerate() {
|
for (idx, (bind, ty)) in bind.iter().zip(types).enumerate() {
|
||||||
if idx > 0 {
|
if idx > 0 {
|
||||||
y.p(", ");
|
y.p(", ");
|
||||||
@ -269,13 +288,13 @@ pub mod yamlify {
|
|||||||
// y.print("/* TODO: desugar pat match args */");
|
// y.print("/* TODO: desugar pat match args */");
|
||||||
y.p(ty).p(" ").p(bind);
|
y.p(ty).p(" ").p(bind);
|
||||||
}
|
}
|
||||||
y.p(")").p(body);
|
y.p(") ").p(body);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
impl CLangify for Struct {
|
impl CLangify for Struct {
|
||||||
fn print(&self, y: &mut CLangifier) {
|
fn print(&self, y: &mut CLangifier) {
|
||||||
let Self { name, kind } = self;
|
let Self { name, kind } = self;
|
||||||
y.p("struct ").p(name).key(" {").p(kind);
|
y.p("struct ").p(name).nest(" {").p(kind);
|
||||||
y.endl().p("}");
|
y.endl().p("}");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -302,7 +321,7 @@ pub mod yamlify {
|
|||||||
impl CLangify for Enum {
|
impl CLangify for Enum {
|
||||||
fn print(&self, y: &mut CLangifier) {
|
fn print(&self, y: &mut CLangifier) {
|
||||||
let Self { name, variants } = self;
|
let Self { name, variants } = self;
|
||||||
y.key("enum ").p(name).p(" {").endl();
|
y.nest("enum ").p(name).p(" {").endl();
|
||||||
match variants {
|
match variants {
|
||||||
Some(v) => {
|
Some(v) => {
|
||||||
for (idx, variant) in v.iter().enumerate() {
|
for (idx, variant) in v.iter().enumerate() {
|
||||||
@ -336,7 +355,7 @@ pub mod yamlify {
|
|||||||
impl CLangify for Impl {
|
impl CLangify for Impl {
|
||||||
fn print(&self, y: &mut CLangifier) {
|
fn print(&self, y: &mut CLangifier) {
|
||||||
let Self { target, body } = self;
|
let Self { target, body } = self;
|
||||||
y.key("/* TODO: impl ").p(target).p(" { */ ");
|
y.nest("/* TODO: impl ").p(target).p(" { */ ");
|
||||||
y.p(body);
|
y.p(body);
|
||||||
y.p("/* } // impl ").p(target).p(" */ ");
|
y.p("/* } // impl ").p(target).p(" */ ");
|
||||||
}
|
}
|
||||||
@ -372,7 +391,7 @@ pub mod yamlify {
|
|||||||
fn print(&self, y: &mut CLangifier) {
|
fn print(&self, y: &mut CLangifier) {
|
||||||
let Self { stmts } = self;
|
let Self { stmts } = self;
|
||||||
{
|
{
|
||||||
let mut y = y.key("{");
|
let mut y = y.nest("{");
|
||||||
y.endl();
|
y.endl();
|
||||||
if let [
|
if let [
|
||||||
stmts @ ..,
|
stmts @ ..,
|
||||||
@ -442,14 +461,14 @@ pub mod yamlify {
|
|||||||
ExprKind::Break(k) => k.print(y),
|
ExprKind::Break(k) => k.print(y),
|
||||||
ExprKind::Return(k) => k.print(y),
|
ExprKind::Return(k) => k.print(y),
|
||||||
ExprKind::Continue => {
|
ExprKind::Continue => {
|
||||||
y.key("continue");
|
y.nest("continue");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
impl CLangify for Quote {
|
impl CLangify for Quote {
|
||||||
fn print(&self, y: &mut CLangifier) {
|
fn print(&self, y: &mut CLangifier) {
|
||||||
y.key("\"");
|
y.nest("\"");
|
||||||
print!("{self}");
|
print!("{self}");
|
||||||
y.p("\"");
|
y.p("\"");
|
||||||
}
|
}
|
||||||
@ -463,7 +482,7 @@ pub mod yamlify {
|
|||||||
y.p(ty).p(" ").p(mutable).p(name).p("[").p(count).p("]");
|
y.p(ty).p(" ").p(mutable).p(name).p("[").p(count).p("]");
|
||||||
}
|
}
|
||||||
TyKind::Fn(TyFn { args, rety }) => {
|
TyKind::Fn(TyFn { args, rety }) => {
|
||||||
y.key("(").p(rety).p(" *").p(mutable).p(name).p(")(");
|
y.nest("(").p(rety).p(" *").p(mutable).p(name).p(")(");
|
||||||
match args.as_ref() {
|
match args.as_ref() {
|
||||||
TyKind::Empty => {}
|
TyKind::Empty => {}
|
||||||
TyKind::Tuple(TyTuple { types }) => {
|
TyKind::Tuple(TyTuple { types }) => {
|
||||||
@ -498,11 +517,13 @@ pub mod yamlify {
|
|||||||
Pattern::Literal(literal) => y.p(literal),
|
Pattern::Literal(literal) => y.p(literal),
|
||||||
Pattern::Rest(name) => y.p("..").p(name),
|
Pattern::Rest(name) => y.p("..").p(name),
|
||||||
Pattern::Ref(mutability, pattern) => y.p("&").p(mutability).p(pattern),
|
Pattern::Ref(mutability, pattern) => y.p("&").p(mutability).p(pattern),
|
||||||
Pattern::Tuple(patterns) => y.key("Tuple").p(patterns),
|
Pattern::RangeExc(head, tail) => y.p("RangeExc").p(head).p(tail),
|
||||||
Pattern::Array(patterns) => y.key("Array").p(patterns),
|
Pattern::RangeInc(head, tail) => y.p("RangeExc").p(head).p(tail),
|
||||||
|
Pattern::Tuple(patterns) => y.nest("Tuple").p(patterns),
|
||||||
|
Pattern::Array(patterns) => y.nest("Array").p(patterns),
|
||||||
Pattern::Struct(path, items) => {
|
Pattern::Struct(path, items) => {
|
||||||
{
|
{
|
||||||
let mut y = y.key("Struct");
|
let mut y = y.nest("Struct");
|
||||||
y.p(path);
|
y.p(path);
|
||||||
for (name, item) in items {
|
for (name, item) in items {
|
||||||
y.p(name).p(item);
|
y.p(name).p(item);
|
||||||
@ -512,7 +533,7 @@ pub mod yamlify {
|
|||||||
}
|
}
|
||||||
Pattern::TupleStruct(path, items) => {
|
Pattern::TupleStruct(path, items) => {
|
||||||
{
|
{
|
||||||
let mut y = y.key("TupleStruct");
|
let mut y = y.nest("TupleStruct");
|
||||||
y.p(path).p(items);
|
y.p(path).p(items);
|
||||||
}
|
}
|
||||||
y
|
y
|
||||||
@ -524,7 +545,7 @@ pub mod yamlify {
|
|||||||
fn print(&self, y: &mut CLangifier) {
|
fn print(&self, y: &mut CLangifier) {
|
||||||
let Self { scrutinee, arms } = self;
|
let Self { scrutinee, arms } = self;
|
||||||
y.p("/* match ").p(scrutinee);
|
y.p("/* match ").p(scrutinee);
|
||||||
y.key(" { ").p(arms);
|
y.nest(" { ").p(arms);
|
||||||
y.p(" } */");
|
y.p(" } */");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -575,7 +596,7 @@ pub mod yamlify {
|
|||||||
UnaryKind::Not => y.p("!").p(tail),
|
UnaryKind::Not => y.p("!").p(tail),
|
||||||
UnaryKind::RangeInc => todo!("Unary RangeInc in C"),
|
UnaryKind::RangeInc => todo!("Unary RangeInc in C"),
|
||||||
UnaryKind::RangeExc => todo!("Unary RangeExc in C"),
|
UnaryKind::RangeExc => todo!("Unary RangeExc in C"),
|
||||||
UnaryKind::Loop => y.key("while (1) { ").p(tail).p(" }"),
|
UnaryKind::Loop => y.nest("while (1) { ").p(tail).p(" }"),
|
||||||
UnaryKind::At => todo!(),
|
UnaryKind::At => todo!(),
|
||||||
UnaryKind::Tilde => todo!(),
|
UnaryKind::Tilde => todo!(),
|
||||||
};
|
};
|
||||||
@ -584,7 +605,7 @@ pub mod yamlify {
|
|||||||
impl CLangify for Cast {
|
impl CLangify for Cast {
|
||||||
fn print(&self, y: &mut CLangifier) {
|
fn print(&self, y: &mut CLangifier) {
|
||||||
let Self { head, ty } = self;
|
let Self { head, ty } = self;
|
||||||
y.key("(").p(ty).p(")");
|
y.nest("(").p(ty).p(")");
|
||||||
y.p(head);
|
y.p(head);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -611,7 +632,7 @@ pub mod yamlify {
|
|||||||
impl CLangify for Tuple {
|
impl CLangify for Tuple {
|
||||||
fn print(&self, y: &mut CLangifier) {
|
fn print(&self, y: &mut CLangifier) {
|
||||||
let Self { exprs } = self;
|
let Self { exprs } = self;
|
||||||
let mut y = y.key("( ");
|
let mut y = y.nest("( ");
|
||||||
for (idx, expr) in exprs.iter().enumerate() {
|
for (idx, expr) in exprs.iter().enumerate() {
|
||||||
if idx > 0 {
|
if idx > 0 {
|
||||||
y.p(", ");
|
y.p(", ");
|
||||||
@ -633,9 +654,9 @@ pub mod yamlify {
|
|||||||
impl CLangify for Structor {
|
impl CLangify for Structor {
|
||||||
fn print(&self, y: &mut CLangifier) {
|
fn print(&self, y: &mut CLangifier) {
|
||||||
let Self { to, init } = self;
|
let Self { to, init } = self;
|
||||||
y.key("(").p(to).p(")");
|
y.nest("(").p(to).p(")");
|
||||||
{
|
{
|
||||||
let mut y = y.key("{ ");
|
let mut y = y.nest("{ ");
|
||||||
for (idx, field) in init.iter().enumerate() {
|
for (idx, field) in init.iter().enumerate() {
|
||||||
if idx > 0 {
|
if idx > 0 {
|
||||||
y.p(", ");
|
y.p(", ");
|
||||||
@ -657,7 +678,7 @@ pub mod yamlify {
|
|||||||
fn print(&self, y: &mut CLangifier) {
|
fn print(&self, y: &mut CLangifier) {
|
||||||
let Self { values } = self;
|
let Self { values } = self;
|
||||||
{
|
{
|
||||||
let mut y = y.key("{");
|
let mut y = y.nest("{");
|
||||||
y.endl();
|
y.endl();
|
||||||
for (idx, value) in values.iter().enumerate() {
|
for (idx, value) in values.iter().enumerate() {
|
||||||
if idx > 0 {
|
if idx > 0 {
|
||||||
@ -672,14 +693,10 @@ pub mod yamlify {
|
|||||||
impl CLangify for ArrayRep {
|
impl CLangify for ArrayRep {
|
||||||
fn print(&self, y: &mut CLangifier) {
|
fn print(&self, y: &mut CLangifier) {
|
||||||
let Self { value, repeat } = self;
|
let Self { value, repeat } = self;
|
||||||
// TODO: compile time evaluation
|
|
||||||
let ExprKind::Literal(Literal::Int(count)) = &repeat.kind else {
|
|
||||||
panic!("Unsupported repeat count: {repeat}");
|
|
||||||
};
|
|
||||||
{
|
{
|
||||||
let mut y = y.key("{");
|
let mut y = y.nest("{");
|
||||||
y.endl();
|
y.endl();
|
||||||
for idx in 0..*count {
|
for idx in 0..*repeat {
|
||||||
if idx > 0 {
|
if idx > 0 {
|
||||||
y.p(", ");
|
y.p(", ");
|
||||||
}
|
}
|
||||||
@ -707,24 +724,35 @@ pub mod yamlify {
|
|||||||
// declared on every line lmao. This will require type info.
|
// declared on every line lmao. This will require type info.
|
||||||
let Self { cond, pass, fail } = self;
|
let Self { cond, pass, fail } = self;
|
||||||
let Else { body: fail } = fail;
|
let Else { body: fail } = fail;
|
||||||
y.key("while(1) { if (").p(cond).p(")").p(pass);
|
y.nest("while(1) {")
|
||||||
if let Some(fail) = fail {
|
.endl()
|
||||||
y.p("else { ").p(fail).p("; break; }");
|
.p("if (")
|
||||||
|
.p(cond)
|
||||||
|
.p(") ")
|
||||||
|
.p(pass);
|
||||||
|
{
|
||||||
|
let mut y = y.nest(" else {");
|
||||||
|
y.endl();
|
||||||
|
if let Some(fail) = fail {
|
||||||
|
y.p(fail).p(";").endl();
|
||||||
|
}
|
||||||
|
y.p("break;");
|
||||||
}
|
}
|
||||||
|
y.endl().p("}");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
impl CLangify for Else {
|
impl CLangify for Else {
|
||||||
fn print(&self, y: &mut CLangifier) {
|
fn print(&self, y: &mut CLangifier) {
|
||||||
let Self { body } = self;
|
let Self { body } = self;
|
||||||
if let Some(body) = body {
|
if let Some(body) = body {
|
||||||
y.key("else ").p(body);
|
y.p(" else ").p(body);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
impl CLangify for If {
|
impl CLangify for If {
|
||||||
fn print(&self, y: &mut CLangifier) {
|
fn print(&self, y: &mut CLangifier) {
|
||||||
let Self { cond, pass, fail } = self;
|
let Self { cond, pass, fail } = self;
|
||||||
y.p("(").p(cond).p(")");
|
y.p("if (").p(cond).p(")");
|
||||||
y.p(pass).p(fail);
|
y.p(pass).p(fail);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -747,13 +775,13 @@ pub mod yamlify {
|
|||||||
impl CLangify for Break {
|
impl CLangify for Break {
|
||||||
fn print(&self, y: &mut CLangifier) {
|
fn print(&self, y: &mut CLangifier) {
|
||||||
let Self { body } = self;
|
let Self { body } = self;
|
||||||
y.key("break ").p(body);
|
y.nest("break ").p(body);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
impl CLangify for Return {
|
impl CLangify for Return {
|
||||||
fn print(&self, y: &mut CLangifier) {
|
fn print(&self, y: &mut CLangifier) {
|
||||||
let Self { body } = self;
|
let Self { body } = self;
|
||||||
y.key("return ").p(body);
|
y.nest("return ").p(body);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
impl CLangify for Literal {
|
impl CLangify for Literal {
|
||||||
@ -830,7 +858,7 @@ pub mod yamlify {
|
|||||||
fn print(&self, y: &mut CLangifier) {
|
fn print(&self, y: &mut CLangifier) {
|
||||||
let Self { types } = self;
|
let Self { types } = self;
|
||||||
{
|
{
|
||||||
let mut y = y.key("struct {");
|
let mut y = y.nest("struct {");
|
||||||
y.endl();
|
y.endl();
|
||||||
for (idx, ty) in types.iter().enumerate() {
|
for (idx, ty) in types.iter().enumerate() {
|
||||||
if idx > 0 {
|
if idx > 0 {
|
||||||
@ -855,7 +883,7 @@ pub mod yamlify {
|
|||||||
fn print(&self, y: &mut CLangifier) {
|
fn print(&self, y: &mut CLangifier) {
|
||||||
let Self { args, rety } = self;
|
let Self { args, rety } = self;
|
||||||
// TODO: function pointer syntax
|
// TODO: function pointer syntax
|
||||||
y.key("*(").p(rety).p(")(");
|
y.nest("(").p(rety).p(" *)(");
|
||||||
match args.as_ref() {
|
match args.as_ref() {
|
||||||
TyKind::Empty => y,
|
TyKind::Empty => y,
|
||||||
TyKind::Tuple(TyTuple { types }) => {
|
TyKind::Tuple(TyTuple { types }) => {
|
||||||
|
@ -41,7 +41,6 @@ pub use yamler::Yamler;
|
|||||||
pub mod yamler {
|
pub mod yamler {
|
||||||
use crate::yamlify::Yamlify;
|
use crate::yamlify::Yamlify;
|
||||||
use std::{
|
use std::{
|
||||||
fmt::Display,
|
|
||||||
io::Write,
|
io::Write,
|
||||||
ops::{Deref, DerefMut},
|
ops::{Deref, DerefMut},
|
||||||
};
|
};
|
||||||
@ -81,22 +80,25 @@ pub mod yamler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Prints a section header and increases indentation
|
/// Prints a section header and increases indentation
|
||||||
pub fn key(&mut self, name: impl Display) -> Section {
|
pub fn key(&mut self, name: impl Yamlify) -> Section {
|
||||||
println!();
|
println!();
|
||||||
self.print_indentation(&mut std::io::stdout().lock());
|
self.print_indentation(&mut std::io::stdout().lock());
|
||||||
print!("- {name}:");
|
print!("- ");
|
||||||
|
name.yaml(self);
|
||||||
|
print!(":");
|
||||||
self.indent()
|
self.indent()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Prints a yaml key value pair: `- name: "value"`
|
/// Prints a yaml key value pair: `- name: "value"`
|
||||||
pub fn pair<D: Display, T: Yamlify>(&mut self, name: D, value: T) -> &mut Self {
|
pub fn pair<D: Yamlify, T: Yamlify>(&mut self, name: D, value: T) -> &mut Self {
|
||||||
self.key(name).yaml(&value);
|
self.key(name).value(value);
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Prints a yaml scalar value: `"name"``
|
/// Prints a yaml scalar value: `"name"``
|
||||||
pub fn value<D: Display>(&mut self, value: D) -> &mut Self {
|
pub fn value<D: Yamlify>(&mut self, value: D) -> &mut Self {
|
||||||
print!(" {value}");
|
print!(" ");
|
||||||
|
value.yaml(self);
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -334,7 +336,7 @@ pub mod yamlify {
|
|||||||
impl Yamlify for Stmt {
|
impl Yamlify for Stmt {
|
||||||
fn yaml(&self, y: &mut Yamler) {
|
fn yaml(&self, y: &mut Yamler) {
|
||||||
let Self { span: _, kind, semi } = self;
|
let Self { span: _, kind, semi } = self;
|
||||||
y.key("Stmt").yaml(kind).yaml(semi);
|
y.key("Stmt").value(kind).yaml(semi);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
impl Yamlify for Semi {
|
impl Yamlify for Semi {
|
||||||
@ -415,11 +417,17 @@ pub mod yamlify {
|
|||||||
Pattern::Name(name) => y.value(name),
|
Pattern::Name(name) => y.value(name),
|
||||||
Pattern::Literal(literal) => y.value(literal),
|
Pattern::Literal(literal) => y.value(literal),
|
||||||
Pattern::Rest(name) => y.pair("Rest", name),
|
Pattern::Rest(name) => y.pair("Rest", name),
|
||||||
Pattern::Ref(mutability, pattern) => {
|
Pattern::Ref(mutability, pattern) => y.yaml(mutability).pair("Pat", pattern),
|
||||||
y.pair("mutability", mutability).pair("subpattern", pattern)
|
Pattern::RangeInc(head, tail) => {
|
||||||
|
y.key("RangeInc").pair("head", head).pair("tail", tail);
|
||||||
|
y
|
||||||
}
|
}
|
||||||
Pattern::Tuple(patterns) => y.key("Tuple").yaml(patterns),
|
Pattern::RangeExc(head, tail) => {
|
||||||
Pattern::Array(patterns) => y.key("Array").yaml(patterns),
|
y.key("RangeExc").pair("head", head).pair("tail", tail);
|
||||||
|
y
|
||||||
|
}
|
||||||
|
Pattern::Tuple(patterns) => y.key("Tuple").list(patterns),
|
||||||
|
Pattern::Array(patterns) => y.key("Array").list(patterns),
|
||||||
Pattern::Struct(path, items) => {
|
Pattern::Struct(path, items) => {
|
||||||
{
|
{
|
||||||
let mut y = y.key("Struct");
|
let mut y = y.key("Struct");
|
||||||
@ -431,10 +439,7 @@ pub mod yamlify {
|
|||||||
y
|
y
|
||||||
}
|
}
|
||||||
Pattern::TupleStruct(path, items) => {
|
Pattern::TupleStruct(path, items) => {
|
||||||
{
|
y.key("TupleStruct").yaml(path).list(items);
|
||||||
let mut y = y.key("TupleStruct");
|
|
||||||
y.yaml(path).list(items);
|
|
||||||
}
|
|
||||||
y
|
y
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -472,11 +477,6 @@ pub mod yamlify {
|
|||||||
.pair("tail", &parts.1);
|
.pair("tail", &parts.1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
impl Yamlify for ModifyKind {
|
|
||||||
fn yaml(&self, y: &mut Yamler) {
|
|
||||||
y.value(self);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
impl Yamlify for Binary {
|
impl Yamlify for Binary {
|
||||||
fn yaml(&self, y: &mut Yamler) {
|
fn yaml(&self, y: &mut Yamler) {
|
||||||
let Self { kind, parts } = self;
|
let Self { kind, parts } = self;
|
||||||
@ -486,22 +486,12 @@ pub mod yamlify {
|
|||||||
.pair("tail", &parts.1);
|
.pair("tail", &parts.1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
impl Yamlify for BinaryKind {
|
|
||||||
fn yaml(&self, y: &mut Yamler) {
|
|
||||||
y.value(self);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
impl Yamlify for Unary {
|
impl Yamlify for Unary {
|
||||||
fn yaml(&self, y: &mut Yamler) {
|
fn yaml(&self, y: &mut Yamler) {
|
||||||
let Self { kind, tail } = self;
|
let Self { kind, tail } = self;
|
||||||
y.key("Unary").pair("kind", kind).pair("tail", tail);
|
y.key("Unary").pair("kind", kind).pair("tail", tail);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
impl Yamlify for UnaryKind {
|
|
||||||
fn yaml(&self, y: &mut Yamler) {
|
|
||||||
y.value(self);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
impl Yamlify for Cast {
|
impl Yamlify for Cast {
|
||||||
fn yaml(&self, y: &mut Yamler) {
|
fn yaml(&self, y: &mut Yamler) {
|
||||||
let Self { head, ty } = self;
|
let Self { head, ty } = self;
|
||||||
@ -617,13 +607,14 @@ pub mod yamlify {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
impl Yamlify for Literal {
|
impl Yamlify for Literal {
|
||||||
fn yaml(&self, y: &mut Yamler) {
|
fn yaml(&self, _y: &mut Yamler) {
|
||||||
y.value(format_args!("\"{self}\""));
|
match self {
|
||||||
}
|
Literal::Bool(v) => print!("{v}"),
|
||||||
}
|
Literal::Char(v) => print!("'{}'", v.escape_debug()),
|
||||||
impl Yamlify for Sym {
|
Literal::Int(v) => print!("{v}"),
|
||||||
fn yaml(&self, y: &mut Yamler) {
|
Literal::Float(v) => print!("{v}"),
|
||||||
y.value(self);
|
Literal::String(v) => print!("{}", v.escape_debug()),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
impl Yamlify for Ty {
|
impl Yamlify for Ty {
|
||||||
@ -740,14 +731,15 @@ pub mod yamlify {
|
|||||||
macro_rules! scalar {
|
macro_rules! scalar {
|
||||||
($($t:ty),*$(,)?) => {
|
($($t:ty),*$(,)?) => {
|
||||||
$(impl Yamlify for $t {
|
$(impl Yamlify for $t {
|
||||||
fn yaml(&self, y: &mut Yamler) {
|
fn yaml(&self, _y: &mut Yamler) {
|
||||||
y.value(self);
|
print!("{self}");
|
||||||
}
|
}
|
||||||
})*
|
})*
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
scalar! {
|
scalar! {
|
||||||
bool, char, u8, u16, u32, u64, u128, usize, i8, i16, i32, i64, i128, isize, &str, String
|
bool, char, u8, u16, u32, u64, u128, usize, i8, i16, i32, i64, i128, isize, &str, String,
|
||||||
|
BinaryKind, UnaryKind, ModifyKind, Sym,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -5,14 +5,14 @@ struct Student {
|
|||||||
age: i32,
|
age: i32,
|
||||||
}
|
}
|
||||||
|
|
||||||
fn Student (name: str, age: i32) -> Student {
|
fn Student(name: str, age: i32) -> Student {
|
||||||
Student: { name, age }
|
Student { name, age }
|
||||||
}
|
}
|
||||||
|
|
||||||
fn match_test(student: Student) {
|
fn match_test(student: Student) {
|
||||||
match student {
|
match student {
|
||||||
Student: { name: "shark", age } => println("Found a shark of ", age, " year(s)"),
|
Student { name: "shark", age } => println("Found a shark of ", age, " year(s)"),
|
||||||
Student: { name, age: 22 } => println("Found a 22-year-old named ", name),
|
Student { name, age: 22 } => println("Found a 22-year-old named ", name),
|
||||||
Student: { name, age } => println("Found someone named ", name, " of ", age, " year(s)"),
|
Student { name, age } => println("Found someone named ", name, " of ", age, " year(s)"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user