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 name: Sym,
|
||||
pub sign: TyFn,
|
||||
pub bind: Vec<Pattern>,
|
||||
pub bind: Pattern,
|
||||
pub body: Option<Expr>,
|
||||
}
|
||||
|
||||
@ -255,7 +255,7 @@ pub struct TyTuple {
|
||||
pub struct TyRef {
|
||||
pub mutable: Mutability,
|
||||
pub count: u16,
|
||||
pub to: Path,
|
||||
pub to: Box<Ty>,
|
||||
}
|
||||
|
||||
/// The args and return value for a function pointer [Ty]pe
|
||||
@ -360,7 +360,7 @@ pub enum ExprKind {
|
||||
While(While),
|
||||
/// An [If] expression: `if` [`Expr`] [`Block`] [`Else`]?
|
||||
If(If),
|
||||
/// A [For] expression: `for` Pattern `in` [`Expr`] [`Block`] [`Else`]?
|
||||
/// A [For] expression: `for` [`Pattern`] `in` [`Expr`] [`Block`] [`Else`]?
|
||||
For(For),
|
||||
/// A [Break] expression: `break` [`Expr`]?
|
||||
Break(Break),
|
||||
@ -392,6 +392,8 @@ pub enum Pattern {
|
||||
Literal(Literal),
|
||||
Rest(Option<Box<Pattern>>),
|
||||
Ref(Mutability, Box<Pattern>),
|
||||
RangeExc(Box<Pattern>, Box<Pattern>),
|
||||
RangeInc(Box<Pattern>, Box<Pattern>),
|
||||
Tuple(Vec<Pattern>),
|
||||
Array(Vec<Pattern>),
|
||||
Struct(Path, Vec<(Sym, Option<Pattern>)>),
|
||||
@ -557,7 +559,7 @@ pub struct Array {
|
||||
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
|
||||
pub struct ArrayRep {
|
||||
pub value: Box<Expr>,
|
||||
pub repeat: Box<Expr>,
|
||||
pub repeat: usize,
|
||||
}
|
||||
|
||||
/// An address-of expression: `&` `mut`? [`Expr`]
|
||||
|
@ -140,6 +140,14 @@ impl TryFrom<Expr> for Pattern {
|
||||
};
|
||||
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 }) => {
|
||||
Pattern::Rest(Some(Pattern::try_from(*tail)?.into()))
|
||||
}
|
||||
|
@ -161,11 +161,19 @@ impl Display for Function {
|
||||
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());
|
||||
write!(f, "fn {name} ")?;
|
||||
{
|
||||
let mut f = f.delimit(INLINE_PARENS);
|
||||
|
||||
for (idx, (arg, ty)) in bind.iter().zip(types.iter()).enumerate() {
|
||||
if idx != 0 {
|
||||
f.write_str(", ")?;
|
||||
@ -453,6 +461,8 @@ impl Display for Pattern {
|
||||
Pattern::Rest(Some(name)) => write!(f, "..{name}"),
|
||||
Pattern::Rest(None) => "..".fmt(f),
|
||||
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::Array(patterns) => separate(patterns, ", ")(f.delimit(INLINE_SQUARE)),
|
||||
Pattern::Struct(path, items) => {
|
||||
|
@ -342,6 +342,8 @@ impl WeightOf for Pattern {
|
||||
Pattern::Rest(Some(pattern)) => pattern.weight_of(),
|
||||
Pattern::Rest(None) => 0,
|
||||
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::Struct(path, items) => {
|
||||
let sitems: usize = items
|
||||
|
@ -100,7 +100,7 @@ pub trait Fold {
|
||||
Function {
|
||||
name: self.fold_sym(name),
|
||||
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)),
|
||||
}
|
||||
}
|
||||
@ -184,7 +184,7 @@ pub trait Fold {
|
||||
}
|
||||
fn fold_ty_ref(&mut self, t: TyRef) -> TyRef {
|
||||
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 {
|
||||
let TyFn { args, rety } = t;
|
||||
@ -246,6 +246,14 @@ pub trait Fold {
|
||||
self.fold_mutability(mutability),
|
||||
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.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 {
|
||||
let ArrayRep { value, repeat } = a;
|
||||
ArrayRep {
|
||||
value: Box::new(self.fold_expr(*value)),
|
||||
repeat: Box::new(self.fold_expr(*repeat)),
|
||||
}
|
||||
ArrayRep { value: Box::new(self.fold_expr(*value)), repeat }
|
||||
}
|
||||
fn fold_addrof(&mut self, a: AddrOf) -> AddrOf {
|
||||
let AddrOf { mutable, expr } = a;
|
||||
|
@ -82,7 +82,7 @@ pub trait Visit<'a>: Sized {
|
||||
let Function { name, sign, bind, body } = f;
|
||||
self.visit_sym(name);
|
||||
self.visit_ty_fn(sign);
|
||||
bind.iter().for_each(|p| self.visit_pattern(p));
|
||||
self.visit_pattern(bind);
|
||||
if let Some(b) = body {
|
||||
self.visit_expr(b)
|
||||
}
|
||||
@ -154,7 +154,7 @@ pub trait Visit<'a>: Sized {
|
||||
fn visit_ty_ref(&mut self, t: &'a TyRef) {
|
||||
let TyRef { mutable, count: _, to } = t;
|
||||
self.visit_mutability(mutable);
|
||||
self.visit_path(to);
|
||||
self.visit_ty(to);
|
||||
}
|
||||
fn visit_ty_fn(&mut self, t: &'a TyFn) {
|
||||
let TyFn { args, rety } = t;
|
||||
@ -215,6 +215,14 @@ pub trait Visit<'a>: Sized {
|
||||
self.visit_mutability(mutability);
|
||||
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) => {
|
||||
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))
|
||||
}
|
||||
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(repeat);
|
||||
}
|
||||
fn visit_addrof(&mut self, a: &'a AddrOf) {
|
||||
let AddrOf { mutable, expr } = a;
|
||||
|
@ -57,9 +57,6 @@ impl Callable for Function {
|
||||
let FnDecl { name, bind, body, sign: _ } = &*self.decl;
|
||||
|
||||
// Check arg mapping
|
||||
if args.len() != bind.len() {
|
||||
return Err(Error::ArgNumber(bind.len(), args.len()));
|
||||
}
|
||||
if self.is_constructor {
|
||||
return Ok(ConValue::TupleStruct(Box::new((
|
||||
name.to_ref(),
|
||||
@ -73,14 +70,10 @@ impl Callable for Function {
|
||||
let upvars = self.upvars.take();
|
||||
env.push_frame("upvars", upvars);
|
||||
|
||||
eprintln!("{name}{args:?}");
|
||||
|
||||
// TODO: completely refactor data storage
|
||||
let mut frame = env.frame("fn args");
|
||||
for (bind, value) in bind.iter().zip(args) {
|
||||
for (name, value) in pattern::substitution(bind, value.clone())? {
|
||||
frame.insert(*name, Some(value));
|
||||
}
|
||||
for (name, value) in pattern::substitution(bind, ConValue::Tuple(args.into()))? {
|
||||
frame.insert(*name, Some(value));
|
||||
}
|
||||
let res = body.interpret(&mut frame);
|
||||
drop(frame);
|
||||
|
@ -1,6 +1,6 @@
|
||||
//! Collects the "Upvars" of a function at the point of its creation, allowing variable capture
|
||||
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};
|
||||
|
||||
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) {
|
||||
let Function { name: _, sign: _, bind, body } = f;
|
||||
// parameters can never be upvars
|
||||
bind.iter().for_each(|pat| self.visit_pattern(pat));
|
||||
self.visit_pattern(bind);
|
||||
if let Some(body) = body {
|
||||
self.visit_expr(body);
|
||||
}
|
||||
@ -115,6 +115,8 @@ impl<'a> Visit<'a> for CollectUpvars<'_> {
|
||||
self.visit_mutability(mutability);
|
||||
self.visit_pattern(pattern);
|
||||
}
|
||||
Pattern::RangeExc(_, _) => {}
|
||||
Pattern::RangeInc(_, _) => {}
|
||||
Pattern::Tuple(patterns) => {
|
||||
patterns.iter().for_each(|p| self.visit_pattern(p));
|
||||
}
|
||||
|
@ -134,11 +134,12 @@ impl Interpret for Struct {
|
||||
.into(),
|
||||
),
|
||||
},
|
||||
bind: args
|
||||
.iter()
|
||||
.enumerate()
|
||||
.map(|(idx, _)| Pattern::Name(idx.to_string().into()))
|
||||
.collect(),
|
||||
bind: Pattern::Tuple(
|
||||
args.iter()
|
||||
.enumerate()
|
||||
.map(|(idx, _)| Pattern::Name(idx.to_string().into()))
|
||||
.collect(),
|
||||
),
|
||||
body: None,
|
||||
};
|
||||
let constructor = crate::function::Function::new_constructor(constructor);
|
||||
@ -814,12 +815,8 @@ impl Interpret for Array {
|
||||
impl Interpret for ArrayRep {
|
||||
fn interpret(&self, env: &mut Environment) -> IResult<ConValue> {
|
||||
let Self { value, repeat } = self;
|
||||
let repeat = match repeat.interpret(env)? {
|
||||
ConValue::Int(v) => v,
|
||||
_ => Err(Error::TypeError())?,
|
||||
};
|
||||
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 {
|
||||
|
@ -20,6 +20,8 @@ pub fn variables(pat: &Pattern) -> Vec<&Sym> {
|
||||
Pattern::Rest(Some(pattern)) => patvars(set, pattern),
|
||||
Pattern::Rest(None) => {}
|
||||
Pattern::Ref(_, pattern) => patvars(set, pattern),
|
||||
Pattern::RangeExc(_, _) => {}
|
||||
Pattern::RangeInc(_, _) => {}
|
||||
Pattern::Tuple(patterns) | Pattern::Array(patterns) => {
|
||||
patterns.iter().for_each(|pat| patvars(set, pat))
|
||||
}
|
||||
@ -127,6 +129,70 @@ pub fn append_sub<'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)) => {
|
||||
match rest_binding(sub, patterns, values.into_vec().into())? {
|
||||
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 {
|
||||
/// Parses the [parameters](Param) associated with a Function
|
||||
@ -484,7 +484,7 @@ impl Parse<'_> for FnSig {
|
||||
break;
|
||||
}
|
||||
}
|
||||
Ok((params, types))
|
||||
Ok((Pattern::Tuple(params), types))
|
||||
}
|
||||
}
|
||||
|
||||
@ -783,7 +783,7 @@ impl Parse<'_> for TyRef {
|
||||
}
|
||||
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(),
|
||||
repeat: {
|
||||
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(),
|
||||
|
@ -54,13 +54,13 @@ fn main() -> Result<(), Box<dyn Error>> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub use yamler::CLangifier;
|
||||
pub mod yamler {
|
||||
use crate::yamlify::CLangify;
|
||||
pub use clangifier::CLangifier;
|
||||
pub mod clangifier {
|
||||
use crate::clangify::CLangify;
|
||||
use std::{
|
||||
fmt::Display,
|
||||
io::Write,
|
||||
ops::{Deref, DerefMut},
|
||||
ops::{Add, Deref, DerefMut},
|
||||
};
|
||||
#[derive(Debug, Default)]
|
||||
pub struct CLangifier {
|
||||
@ -104,12 +104,20 @@ pub mod yamler {
|
||||
}
|
||||
|
||||
/// 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}");
|
||||
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")
|
||||
pub struct Section<'y> {
|
||||
yamler: &'y mut CLangifier,
|
||||
@ -142,10 +150,11 @@ pub mod yamler {
|
||||
}
|
||||
}
|
||||
|
||||
pub mod yamlify {
|
||||
pub mod clangify {
|
||||
use core::panic;
|
||||
use std::iter;
|
||||
|
||||
use super::yamler::CLangifier;
|
||||
use super::clangifier::CLangifier;
|
||||
use cl_ast::*;
|
||||
|
||||
pub trait CLangify {
|
||||
@ -153,11 +162,17 @@ pub mod yamlify {
|
||||
}
|
||||
|
||||
impl CLangify for File {
|
||||
fn print(&self, y: &mut CLangifier) {
|
||||
fn print(&self, mut y: &mut CLangifier) {
|
||||
let File { name, items } = self;
|
||||
// TODO: turn name into include guard
|
||||
y.p("// Generated from ").p(name).endl();
|
||||
y.p(items);
|
||||
y = (y + "// Generated from " + name).endl();
|
||||
for (idx, item) in items.iter().enumerate() {
|
||||
if idx > 0 {
|
||||
y.endl().endl();
|
||||
}
|
||||
y.p(item);
|
||||
}
|
||||
y.endl();
|
||||
}
|
||||
}
|
||||
impl CLangify for Visibility {
|
||||
@ -174,14 +189,14 @@ pub mod yamlify {
|
||||
impl CLangify for Attrs {
|
||||
fn print(&self, y: &mut CLangifier) {
|
||||
let Self { meta } = self;
|
||||
y.key("Attrs").p(meta);
|
||||
y.nest("Attrs").p(meta);
|
||||
todo!("Attributes");
|
||||
}
|
||||
}
|
||||
impl CLangify for Meta {
|
||||
fn print(&self, y: &mut CLangifier) {
|
||||
let Self { name, kind } = self;
|
||||
y.key("Meta").p(name).p(kind);
|
||||
y.nest("Meta").p(name).p(kind);
|
||||
todo!("Attributes");
|
||||
}
|
||||
}
|
||||
@ -199,7 +214,7 @@ pub mod yamlify {
|
||||
impl CLangify for Item {
|
||||
fn print(&self, y: &mut CLangifier) {
|
||||
let Self { span: _, attrs: _, vis, kind } = self;
|
||||
y.p(vis).p(kind).endl().endl();
|
||||
y.p(vis).p(kind);
|
||||
}
|
||||
}
|
||||
impl CLangify for ItemKind {
|
||||
@ -241,7 +256,7 @@ pub mod yamlify {
|
||||
impl CLangify for Module {
|
||||
fn print(&self, y: &mut CLangifier) {
|
||||
let Self { name, file } = self;
|
||||
y.key("// mod ").p(name).p(" {").endl();
|
||||
y.nest("// mod ").p(name).p(" {").endl();
|
||||
y.p(file);
|
||||
y.endl().p("// } mod ").p(name);
|
||||
}
|
||||
@ -255,13 +270,17 @@ pub mod yamlify {
|
||||
TyKind::Empty => &[],
|
||||
_ => panic!("Unsupported function args: {args}"),
|
||||
};
|
||||
let bind = match bind {
|
||||
Pattern::Tuple(tup) => tup.as_slice(),
|
||||
_ => panic!("Unsupported function binders: {args}"),
|
||||
};
|
||||
match rety {
|
||||
Some(ty) => y.p(ty),
|
||||
None => y.p("void"),
|
||||
}
|
||||
.p(" ")
|
||||
.p(name)
|
||||
.p("(");
|
||||
.p(" (");
|
||||
for (idx, (bind, ty)) in bind.iter().zip(types).enumerate() {
|
||||
if idx > 0 {
|
||||
y.p(", ");
|
||||
@ -269,13 +288,13 @@ pub mod yamlify {
|
||||
// y.print("/* TODO: desugar pat match args */");
|
||||
y.p(ty).p(" ").p(bind);
|
||||
}
|
||||
y.p(")").p(body);
|
||||
y.p(") ").p(body);
|
||||
}
|
||||
}
|
||||
impl CLangify for Struct {
|
||||
fn print(&self, y: &mut CLangifier) {
|
||||
let Self { name, kind } = self;
|
||||
y.p("struct ").p(name).key(" {").p(kind);
|
||||
y.p("struct ").p(name).nest(" {").p(kind);
|
||||
y.endl().p("}");
|
||||
}
|
||||
}
|
||||
@ -302,7 +321,7 @@ pub mod yamlify {
|
||||
impl CLangify for Enum {
|
||||
fn print(&self, y: &mut CLangifier) {
|
||||
let Self { name, variants } = self;
|
||||
y.key("enum ").p(name).p(" {").endl();
|
||||
y.nest("enum ").p(name).p(" {").endl();
|
||||
match variants {
|
||||
Some(v) => {
|
||||
for (idx, variant) in v.iter().enumerate() {
|
||||
@ -336,7 +355,7 @@ pub mod yamlify {
|
||||
impl CLangify for Impl {
|
||||
fn print(&self, y: &mut CLangifier) {
|
||||
let Self { target, body } = self;
|
||||
y.key("/* TODO: impl ").p(target).p(" { */ ");
|
||||
y.nest("/* TODO: impl ").p(target).p(" { */ ");
|
||||
y.p(body);
|
||||
y.p("/* } // impl ").p(target).p(" */ ");
|
||||
}
|
||||
@ -372,7 +391,7 @@ pub mod yamlify {
|
||||
fn print(&self, y: &mut CLangifier) {
|
||||
let Self { stmts } = self;
|
||||
{
|
||||
let mut y = y.key("{");
|
||||
let mut y = y.nest("{");
|
||||
y.endl();
|
||||
if let [
|
||||
stmts @ ..,
|
||||
@ -442,14 +461,14 @@ pub mod yamlify {
|
||||
ExprKind::Break(k) => k.print(y),
|
||||
ExprKind::Return(k) => k.print(y),
|
||||
ExprKind::Continue => {
|
||||
y.key("continue");
|
||||
y.nest("continue");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
impl CLangify for Quote {
|
||||
fn print(&self, y: &mut CLangifier) {
|
||||
y.key("\"");
|
||||
y.nest("\"");
|
||||
print!("{self}");
|
||||
y.p("\"");
|
||||
}
|
||||
@ -463,7 +482,7 @@ pub mod yamlify {
|
||||
y.p(ty).p(" ").p(mutable).p(name).p("[").p(count).p("]");
|
||||
}
|
||||
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() {
|
||||
TyKind::Empty => {}
|
||||
TyKind::Tuple(TyTuple { types }) => {
|
||||
@ -498,11 +517,13 @@ pub mod yamlify {
|
||||
Pattern::Literal(literal) => y.p(literal),
|
||||
Pattern::Rest(name) => y.p("..").p(name),
|
||||
Pattern::Ref(mutability, pattern) => y.p("&").p(mutability).p(pattern),
|
||||
Pattern::Tuple(patterns) => y.key("Tuple").p(patterns),
|
||||
Pattern::Array(patterns) => y.key("Array").p(patterns),
|
||||
Pattern::RangeExc(head, tail) => y.p("RangeExc").p(head).p(tail),
|
||||
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) => {
|
||||
{
|
||||
let mut y = y.key("Struct");
|
||||
let mut y = y.nest("Struct");
|
||||
y.p(path);
|
||||
for (name, item) in items {
|
||||
y.p(name).p(item);
|
||||
@ -512,7 +533,7 @@ pub mod yamlify {
|
||||
}
|
||||
Pattern::TupleStruct(path, items) => {
|
||||
{
|
||||
let mut y = y.key("TupleStruct");
|
||||
let mut y = y.nest("TupleStruct");
|
||||
y.p(path).p(items);
|
||||
}
|
||||
y
|
||||
@ -524,7 +545,7 @@ pub mod yamlify {
|
||||
fn print(&self, y: &mut CLangifier) {
|
||||
let Self { scrutinee, arms } = self;
|
||||
y.p("/* match ").p(scrutinee);
|
||||
y.key(" { ").p(arms);
|
||||
y.nest(" { ").p(arms);
|
||||
y.p(" } */");
|
||||
}
|
||||
}
|
||||
@ -575,7 +596,7 @@ pub mod yamlify {
|
||||
UnaryKind::Not => y.p("!").p(tail),
|
||||
UnaryKind::RangeInc => todo!("Unary RangeInc 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::Tilde => todo!(),
|
||||
};
|
||||
@ -584,7 +605,7 @@ pub mod yamlify {
|
||||
impl CLangify for Cast {
|
||||
fn print(&self, y: &mut CLangifier) {
|
||||
let Self { head, ty } = self;
|
||||
y.key("(").p(ty).p(")");
|
||||
y.nest("(").p(ty).p(")");
|
||||
y.p(head);
|
||||
}
|
||||
}
|
||||
@ -611,7 +632,7 @@ pub mod yamlify {
|
||||
impl CLangify for Tuple {
|
||||
fn print(&self, y: &mut CLangifier) {
|
||||
let Self { exprs } = self;
|
||||
let mut y = y.key("( ");
|
||||
let mut y = y.nest("( ");
|
||||
for (idx, expr) in exprs.iter().enumerate() {
|
||||
if idx > 0 {
|
||||
y.p(", ");
|
||||
@ -633,9 +654,9 @@ pub mod yamlify {
|
||||
impl CLangify for Structor {
|
||||
fn print(&self, y: &mut CLangifier) {
|
||||
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() {
|
||||
if idx > 0 {
|
||||
y.p(", ");
|
||||
@ -657,7 +678,7 @@ pub mod yamlify {
|
||||
fn print(&self, y: &mut CLangifier) {
|
||||
let Self { values } = self;
|
||||
{
|
||||
let mut y = y.key("{");
|
||||
let mut y = y.nest("{");
|
||||
y.endl();
|
||||
for (idx, value) in values.iter().enumerate() {
|
||||
if idx > 0 {
|
||||
@ -672,14 +693,10 @@ pub mod yamlify {
|
||||
impl CLangify for ArrayRep {
|
||||
fn print(&self, y: &mut CLangifier) {
|
||||
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();
|
||||
for idx in 0..*count {
|
||||
for idx in 0..*repeat {
|
||||
if idx > 0 {
|
||||
y.p(", ");
|
||||
}
|
||||
@ -707,24 +724,35 @@ pub mod yamlify {
|
||||
// declared on every line lmao. This will require type info.
|
||||
let Self { cond, pass, fail } = self;
|
||||
let Else { body: fail } = fail;
|
||||
y.key("while(1) { if (").p(cond).p(")").p(pass);
|
||||
if let Some(fail) = fail {
|
||||
y.p("else { ").p(fail).p("; break; }");
|
||||
y.nest("while(1) {")
|
||||
.endl()
|
||||
.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 {
|
||||
fn print(&self, y: &mut CLangifier) {
|
||||
let Self { body } = self;
|
||||
if let Some(body) = body {
|
||||
y.key("else ").p(body);
|
||||
y.p(" else ").p(body);
|
||||
}
|
||||
}
|
||||
}
|
||||
impl CLangify for If {
|
||||
fn print(&self, y: &mut CLangifier) {
|
||||
let Self { cond, pass, fail } = self;
|
||||
y.p("(").p(cond).p(")");
|
||||
y.p("if (").p(cond).p(")");
|
||||
y.p(pass).p(fail);
|
||||
}
|
||||
}
|
||||
@ -747,13 +775,13 @@ pub mod yamlify {
|
||||
impl CLangify for Break {
|
||||
fn print(&self, y: &mut CLangifier) {
|
||||
let Self { body } = self;
|
||||
y.key("break ").p(body);
|
||||
y.nest("break ").p(body);
|
||||
}
|
||||
}
|
||||
impl CLangify for Return {
|
||||
fn print(&self, y: &mut CLangifier) {
|
||||
let Self { body } = self;
|
||||
y.key("return ").p(body);
|
||||
y.nest("return ").p(body);
|
||||
}
|
||||
}
|
||||
impl CLangify for Literal {
|
||||
@ -830,7 +858,7 @@ pub mod yamlify {
|
||||
fn print(&self, y: &mut CLangifier) {
|
||||
let Self { types } = self;
|
||||
{
|
||||
let mut y = y.key("struct {");
|
||||
let mut y = y.nest("struct {");
|
||||
y.endl();
|
||||
for (idx, ty) in types.iter().enumerate() {
|
||||
if idx > 0 {
|
||||
@ -855,7 +883,7 @@ pub mod yamlify {
|
||||
fn print(&self, y: &mut CLangifier) {
|
||||
let Self { args, rety } = self;
|
||||
// TODO: function pointer syntax
|
||||
y.key("*(").p(rety).p(")(");
|
||||
y.nest("(").p(rety).p(" *)(");
|
||||
match args.as_ref() {
|
||||
TyKind::Empty => y,
|
||||
TyKind::Tuple(TyTuple { types }) => {
|
||||
|
@ -41,7 +41,6 @@ pub use yamler::Yamler;
|
||||
pub mod yamler {
|
||||
use crate::yamlify::Yamlify;
|
||||
use std::{
|
||||
fmt::Display,
|
||||
io::Write,
|
||||
ops::{Deref, DerefMut},
|
||||
};
|
||||
@ -81,22 +80,25 @@ pub mod yamler {
|
||||
}
|
||||
|
||||
/// 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!();
|
||||
self.print_indentation(&mut std::io::stdout().lock());
|
||||
print!("- {name}:");
|
||||
print!("- ");
|
||||
name.yaml(self);
|
||||
print!(":");
|
||||
self.indent()
|
||||
}
|
||||
|
||||
/// Prints a yaml key value pair: `- name: "value"`
|
||||
pub fn pair<D: Display, T: Yamlify>(&mut self, name: D, value: T) -> &mut Self {
|
||||
self.key(name).yaml(&value);
|
||||
pub fn pair<D: Yamlify, T: Yamlify>(&mut self, name: D, value: T) -> &mut Self {
|
||||
self.key(name).value(value);
|
||||
self
|
||||
}
|
||||
|
||||
/// Prints a yaml scalar value: `"name"``
|
||||
pub fn value<D: Display>(&mut self, value: D) -> &mut Self {
|
||||
print!(" {value}");
|
||||
pub fn value<D: Yamlify>(&mut self, value: D) -> &mut Self {
|
||||
print!(" ");
|
||||
value.yaml(self);
|
||||
self
|
||||
}
|
||||
|
||||
@ -334,7 +336,7 @@ pub mod yamlify {
|
||||
impl Yamlify for Stmt {
|
||||
fn yaml(&self, y: &mut Yamler) {
|
||||
let Self { span: _, kind, semi } = self;
|
||||
y.key("Stmt").yaml(kind).yaml(semi);
|
||||
y.key("Stmt").value(kind).yaml(semi);
|
||||
}
|
||||
}
|
||||
impl Yamlify for Semi {
|
||||
@ -415,11 +417,17 @@ pub mod yamlify {
|
||||
Pattern::Name(name) => y.value(name),
|
||||
Pattern::Literal(literal) => y.value(literal),
|
||||
Pattern::Rest(name) => y.pair("Rest", name),
|
||||
Pattern::Ref(mutability, pattern) => {
|
||||
y.pair("mutability", mutability).pair("subpattern", pattern)
|
||||
Pattern::Ref(mutability, pattern) => y.yaml(mutability).pair("Pat", pattern),
|
||||
Pattern::RangeInc(head, tail) => {
|
||||
y.key("RangeInc").pair("head", head).pair("tail", tail);
|
||||
y
|
||||
}
|
||||
Pattern::Tuple(patterns) => y.key("Tuple").yaml(patterns),
|
||||
Pattern::Array(patterns) => y.key("Array").yaml(patterns),
|
||||
Pattern::RangeExc(head, tail) => {
|
||||
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) => {
|
||||
{
|
||||
let mut y = y.key("Struct");
|
||||
@ -431,10 +439,7 @@ pub mod yamlify {
|
||||
y
|
||||
}
|
||||
Pattern::TupleStruct(path, items) => {
|
||||
{
|
||||
let mut y = y.key("TupleStruct");
|
||||
y.yaml(path).list(items);
|
||||
}
|
||||
y.key("TupleStruct").yaml(path).list(items);
|
||||
y
|
||||
}
|
||||
};
|
||||
@ -472,11 +477,6 @@ pub mod yamlify {
|
||||
.pair("tail", &parts.1);
|
||||
}
|
||||
}
|
||||
impl Yamlify for ModifyKind {
|
||||
fn yaml(&self, y: &mut Yamler) {
|
||||
y.value(self);
|
||||
}
|
||||
}
|
||||
impl Yamlify for Binary {
|
||||
fn yaml(&self, y: &mut Yamler) {
|
||||
let Self { kind, parts } = self;
|
||||
@ -486,22 +486,12 @@ pub mod yamlify {
|
||||
.pair("tail", &parts.1);
|
||||
}
|
||||
}
|
||||
impl Yamlify for BinaryKind {
|
||||
fn yaml(&self, y: &mut Yamler) {
|
||||
y.value(self);
|
||||
}
|
||||
}
|
||||
impl Yamlify for Unary {
|
||||
fn yaml(&self, y: &mut Yamler) {
|
||||
let Self { kind, tail } = self;
|
||||
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 {
|
||||
fn yaml(&self, y: &mut Yamler) {
|
||||
let Self { head, ty } = self;
|
||||
@ -617,13 +607,14 @@ pub mod yamlify {
|
||||
}
|
||||
}
|
||||
impl Yamlify for Literal {
|
||||
fn yaml(&self, y: &mut Yamler) {
|
||||
y.value(format_args!("\"{self}\""));
|
||||
}
|
||||
}
|
||||
impl Yamlify for Sym {
|
||||
fn yaml(&self, y: &mut Yamler) {
|
||||
y.value(self);
|
||||
fn yaml(&self, _y: &mut Yamler) {
|
||||
match self {
|
||||
Literal::Bool(v) => print!("{v}"),
|
||||
Literal::Char(v) => print!("'{}'", v.escape_debug()),
|
||||
Literal::Int(v) => print!("{v}"),
|
||||
Literal::Float(v) => print!("{v}"),
|
||||
Literal::String(v) => print!("{}", v.escape_debug()),
|
||||
}
|
||||
}
|
||||
}
|
||||
impl Yamlify for Ty {
|
||||
@ -740,14 +731,15 @@ pub mod yamlify {
|
||||
macro_rules! scalar {
|
||||
($($t:ty),*$(,)?) => {
|
||||
$(impl Yamlify for $t {
|
||||
fn yaml(&self, y: &mut Yamler) {
|
||||
y.value(self);
|
||||
fn yaml(&self, _y: &mut Yamler) {
|
||||
print!("{self}");
|
||||
}
|
||||
})*
|
||||
};
|
||||
}
|
||||
|
||||
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,
|
||||
}
|
||||
|
||||
fn Student (name: str, age: i32) -> Student {
|
||||
Student: { name, age }
|
||||
fn Student(name: str, age: i32) -> Student {
|
||||
Student { name, age }
|
||||
}
|
||||
|
||||
fn match_test(student: Student) {
|
||||
match student {
|
||||
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 } => println("Found someone named ", name, " 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 } => println("Found someone named ", name, " of ", age, " year(s)"),
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user