cl-ast: Add syntax support for generics
This commit is contained in:
parent
681fbc88d3
commit
8ff17fd475
@ -93,6 +93,12 @@ pub enum ItemKind {
|
|||||||
Use(Use),
|
Use(Use),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// A list of type variables to introduce
|
||||||
|
#[derive(Clone, Debug, Default, PartialEq, Eq, Hash)]
|
||||||
|
pub struct Generics {
|
||||||
|
pub vars: Vec<Sym>,
|
||||||
|
}
|
||||||
|
|
||||||
/// An ordered collection of [Items](Item)
|
/// An ordered collection of [Items](Item)
|
||||||
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
|
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
|
||||||
pub struct Module {
|
pub struct Module {
|
||||||
@ -128,6 +134,7 @@ pub struct Static {
|
|||||||
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
|
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
|
||||||
pub struct Function {
|
pub struct Function {
|
||||||
pub name: Sym,
|
pub name: Sym,
|
||||||
|
pub gens: Generics,
|
||||||
pub sign: TyFn,
|
pub sign: TyFn,
|
||||||
pub bind: Pattern,
|
pub bind: Pattern,
|
||||||
pub body: Option<Expr>,
|
pub body: Option<Expr>,
|
||||||
@ -137,6 +144,7 @@ pub struct Function {
|
|||||||
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
|
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
|
||||||
pub struct Struct {
|
pub struct Struct {
|
||||||
pub name: Sym,
|
pub name: Sym,
|
||||||
|
pub gens: Generics,
|
||||||
pub kind: StructKind,
|
pub kind: StructKind,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -160,6 +168,7 @@ pub struct StructMember {
|
|||||||
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
|
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
|
||||||
pub struct Enum {
|
pub struct Enum {
|
||||||
pub name: Sym,
|
pub name: Sym,
|
||||||
|
pub gens: Generics,
|
||||||
pub variants: Option<Vec<Variant>>,
|
pub variants: Option<Vec<Variant>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -112,6 +112,16 @@ impl Display for ItemKind {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Display for Generics {
|
||||||
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||||
|
let Generics { vars } = self;
|
||||||
|
if !vars.is_empty() {
|
||||||
|
separate(vars, ", ")(f.delimit_with("<", ">"))?
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl Display for Alias {
|
impl Display for Alias {
|
||||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||||
let Self { name, from } = self;
|
let Self { name, from } = self;
|
||||||
@ -152,7 +162,7 @@ impl Display for Module {
|
|||||||
|
|
||||||
impl Display for Function {
|
impl Display for Function {
|
||||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||||
let Self { name, sign: sign @ TyFn { args, rety }, bind, body } = self;
|
let Self { name, gens, sign: sign @ TyFn { args, rety }, bind, body } = self;
|
||||||
let types = match **args {
|
let types = match **args {
|
||||||
TyKind::Tuple(TyTuple { ref types }) => types.as_slice(),
|
TyKind::Tuple(TyTuple { ref types }) => types.as_slice(),
|
||||||
TyKind::Empty => Default::default(),
|
TyKind::Empty => Default::default(),
|
||||||
@ -170,7 +180,7 @@ impl Display for Function {
|
|||||||
};
|
};
|
||||||
|
|
||||||
debug_assert_eq!(bind.len(), types.len());
|
debug_assert_eq!(bind.len(), types.len());
|
||||||
write!(f, "fn {name} ")?;
|
write!(f, "fn {name}{gens} ")?;
|
||||||
{
|
{
|
||||||
let mut f = f.delimit(INLINE_PARENS);
|
let mut f = f.delimit(INLINE_PARENS);
|
||||||
|
|
||||||
@ -193,8 +203,8 @@ impl Display for Function {
|
|||||||
|
|
||||||
impl Display for Struct {
|
impl Display for Struct {
|
||||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||||
let Self { name, kind } = self;
|
let Self { name, gens, kind } = self;
|
||||||
write!(f, "struct {name}{kind}")
|
write!(f, "struct {name}{gens}{kind}")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -217,8 +227,8 @@ impl Display for StructMember {
|
|||||||
|
|
||||||
impl Display for Enum {
|
impl Display for Enum {
|
||||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||||
let Self { name, variants: kind } = self;
|
let Self { name, gens, variants: kind } = self;
|
||||||
write!(f, "enum {name}")?;
|
write!(f, "enum {name}{gens}")?;
|
||||||
match kind {
|
match kind {
|
||||||
Some(v) => separate(v, ",\n")(f.delimit(SPACED_BRACES)),
|
Some(v) => separate(v, ",\n")(f.delimit(SPACED_BRACES)),
|
||||||
None => ";".fmt(f),
|
None => ";".fmt(f),
|
||||||
|
@ -65,6 +65,13 @@ impl WeightOf for ItemKind {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl WeightOf for Generics {
|
||||||
|
fn weight_of(&self) -> usize {
|
||||||
|
let Self { vars } = self;
|
||||||
|
vars.iter().map(|v| v.weight_of()).sum()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl WeightOf for Module {
|
impl WeightOf for Module {
|
||||||
fn weight_of(&self) -> usize {
|
fn weight_of(&self) -> usize {
|
||||||
let Self { name, file } = self;
|
let Self { name, file } = self;
|
||||||
@ -95,15 +102,15 @@ impl WeightOf for Static {
|
|||||||
|
|
||||||
impl WeightOf for Function {
|
impl WeightOf for Function {
|
||||||
fn weight_of(&self) -> usize {
|
fn weight_of(&self) -> usize {
|
||||||
let Self { name, sign, bind, body } = self;
|
let Self { name, gens, sign, bind, body } = self;
|
||||||
name.weight_of() + sign.weight_of() + bind.weight_of() + body.weight_of()
|
name.weight_of() + gens.weight_of() + sign.weight_of() + bind.weight_of() + body.weight_of()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl WeightOf for Struct {
|
impl WeightOf for Struct {
|
||||||
fn weight_of(&self) -> usize {
|
fn weight_of(&self) -> usize {
|
||||||
let Self { name, kind } = self;
|
let Self { name, gens, kind } = self;
|
||||||
name.weight_of() + kind.weight_of()
|
name.weight_of() + gens.weight_of() + kind.weight_of()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -126,8 +133,9 @@ impl WeightOf for StructMember {
|
|||||||
|
|
||||||
impl WeightOf for Enum {
|
impl WeightOf for Enum {
|
||||||
fn weight_of(&self) -> usize {
|
fn weight_of(&self) -> usize {
|
||||||
let Self { name, variants } = self;
|
let Self { name, gens, variants } = self;
|
||||||
name.weight_of()
|
name.weight_of()
|
||||||
|
+ gens.weight_of()
|
||||||
+ variants
|
+ variants
|
||||||
.as_ref()
|
.as_ref()
|
||||||
.map_or(size_of_val(variants), |v| v.weight_of())
|
.map_or(size_of_val(variants), |v| v.weight_of())
|
||||||
|
@ -70,6 +70,10 @@ pub trait Fold {
|
|||||||
fn fold_item_kind(&mut self, kind: ItemKind) -> ItemKind {
|
fn fold_item_kind(&mut self, kind: ItemKind) -> ItemKind {
|
||||||
or_fold_item_kind(self, kind)
|
or_fold_item_kind(self, kind)
|
||||||
}
|
}
|
||||||
|
fn fold_generics(&mut self, gens: Generics) -> Generics {
|
||||||
|
let Generics { vars } = gens;
|
||||||
|
Generics { vars: vars.into_iter().map(|sym| self.fold_sym(sym)).collect() }
|
||||||
|
}
|
||||||
fn fold_alias(&mut self, a: Alias) -> Alias {
|
fn fold_alias(&mut self, a: Alias) -> Alias {
|
||||||
let Alias { name, from } = a;
|
let Alias { name, from } = a;
|
||||||
Alias { name: self.fold_sym(name), from: from.map(|from| Box::new(self.fold_ty(*from))) }
|
Alias { name: self.fold_sym(name), from: from.map(|from| Box::new(self.fold_ty(*from))) }
|
||||||
@ -96,17 +100,22 @@ pub trait Fold {
|
|||||||
Module { name: self.fold_sym(name), file: file.map(|v| self.fold_file(v)) }
|
Module { name: self.fold_sym(name), file: file.map(|v| self.fold_file(v)) }
|
||||||
}
|
}
|
||||||
fn fold_function(&mut self, f: Function) -> Function {
|
fn fold_function(&mut self, f: Function) -> Function {
|
||||||
let Function { name, sign, bind, body } = f;
|
let Function { name, gens, sign, bind, body } = f;
|
||||||
Function {
|
Function {
|
||||||
name: self.fold_sym(name),
|
name: self.fold_sym(name),
|
||||||
|
gens: self.fold_generics(gens),
|
||||||
sign: self.fold_ty_fn(sign),
|
sign: self.fold_ty_fn(sign),
|
||||||
bind: self.fold_pattern(bind),
|
bind: self.fold_pattern(bind),
|
||||||
body: body.map(|b| self.fold_expr(b)),
|
body: body.map(|b| self.fold_expr(b)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fn fold_struct(&mut self, s: Struct) -> Struct {
|
fn fold_struct(&mut self, s: Struct) -> Struct {
|
||||||
let Struct { name, kind } = s;
|
let Struct { name, gens, kind } = s;
|
||||||
Struct { name: self.fold_sym(name), kind: self.fold_struct_kind(kind) }
|
Struct {
|
||||||
|
name: self.fold_sym(name),
|
||||||
|
gens: self.fold_generics(gens),
|
||||||
|
kind: self.fold_struct_kind(kind),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
fn fold_struct_kind(&mut self, kind: StructKind) -> StructKind {
|
fn fold_struct_kind(&mut self, kind: StructKind) -> StructKind {
|
||||||
match kind {
|
match kind {
|
||||||
@ -130,9 +139,10 @@ pub trait Fold {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
fn fold_enum(&mut self, e: Enum) -> Enum {
|
fn fold_enum(&mut self, e: Enum) -> Enum {
|
||||||
let Enum { name, variants: kind } = e;
|
let Enum { name, gens, variants: kind } = e;
|
||||||
Enum {
|
Enum {
|
||||||
name: self.fold_sym(name),
|
name: self.fold_sym(name),
|
||||||
|
gens: self.fold_generics(gens),
|
||||||
variants: kind.map(|v| v.into_iter().map(|v| self.fold_variant(v)).collect()),
|
variants: kind.map(|v| v.into_iter().map(|v| self.fold_variant(v)).collect()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -51,6 +51,10 @@ pub trait Visit<'a>: Sized {
|
|||||||
fn visit_item_kind(&mut self, kind: &'a ItemKind) {
|
fn visit_item_kind(&mut self, kind: &'a ItemKind) {
|
||||||
or_visit_item_kind(self, kind)
|
or_visit_item_kind(self, kind)
|
||||||
}
|
}
|
||||||
|
fn visit_generics(&mut self, gens: &'a Generics) {
|
||||||
|
let Generics { vars } = gens;
|
||||||
|
vars.iter().for_each(|name| self.visit_sym(name));
|
||||||
|
}
|
||||||
fn visit_alias(&mut self, a: &'a Alias) {
|
fn visit_alias(&mut self, a: &'a Alias) {
|
||||||
let Alias { name, from } = a;
|
let Alias { name, from } = a;
|
||||||
self.visit_sym(name);
|
self.visit_sym(name);
|
||||||
@ -79,8 +83,9 @@ pub trait Visit<'a>: Sized {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
fn visit_function(&mut self, f: &'a Function) {
|
fn visit_function(&mut self, f: &'a Function) {
|
||||||
let Function { name, sign, bind, body } = f;
|
let Function { name, gens, sign, bind, body } = f;
|
||||||
self.visit_sym(name);
|
self.visit_sym(name);
|
||||||
|
self.visit_generics(gens);
|
||||||
self.visit_ty_fn(sign);
|
self.visit_ty_fn(sign);
|
||||||
self.visit_pattern(bind);
|
self.visit_pattern(bind);
|
||||||
if let Some(b) = body {
|
if let Some(b) = body {
|
||||||
@ -88,8 +93,9 @@ pub trait Visit<'a>: Sized {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
fn visit_struct(&mut self, s: &'a Struct) {
|
fn visit_struct(&mut self, s: &'a Struct) {
|
||||||
let Struct { name, kind } = s;
|
let Struct { name, gens, kind } = s;
|
||||||
self.visit_sym(name);
|
self.visit_sym(name);
|
||||||
|
self.visit_generics(gens);
|
||||||
self.visit_struct_kind(kind);
|
self.visit_struct_kind(kind);
|
||||||
}
|
}
|
||||||
fn visit_struct_kind(&mut self, kind: &'a StructKind) {
|
fn visit_struct_kind(&mut self, kind: &'a StructKind) {
|
||||||
@ -102,8 +108,9 @@ pub trait Visit<'a>: Sized {
|
|||||||
self.visit_ty(ty);
|
self.visit_ty(ty);
|
||||||
}
|
}
|
||||||
fn visit_enum(&mut self, e: &'a Enum) {
|
fn visit_enum(&mut self, e: &'a Enum) {
|
||||||
let Enum { name, variants: kind } = e;
|
let Enum { name, gens, variants: kind } = e;
|
||||||
self.visit_sym(name);
|
self.visit_sym(name);
|
||||||
|
self.visit_generics(gens);
|
||||||
if let Some(variants) = kind {
|
if let Some(variants) = kind {
|
||||||
variants.iter().for_each(|v| self.visit_variant(v))
|
variants.iter().for_each(|v| self.visit_variant(v))
|
||||||
}
|
}
|
||||||
|
@ -54,7 +54,7 @@ impl Callable for Function {
|
|||||||
name
|
name
|
||||||
}
|
}
|
||||||
fn call(&self, env: &mut Environment, args: &[ConValue]) -> IResult<ConValue> {
|
fn call(&self, env: &mut Environment, args: &[ConValue]) -> IResult<ConValue> {
|
||||||
let FnDecl { name, bind, body, sign: _ } = &*self.decl;
|
let FnDecl { name, gens: _, bind, body, sign: _ } = &*self.decl;
|
||||||
|
|
||||||
// Check arg mapping
|
// Check arg mapping
|
||||||
if self.is_constructor {
|
if self.is_constructor {
|
||||||
|
@ -65,7 +65,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: _, gens: _, sign: _, bind, body } = f;
|
||||||
// parameters can never be upvars
|
// parameters can never be upvars
|
||||||
self.visit_pattern(bind);
|
self.visit_pattern(bind);
|
||||||
if let Some(body) = body {
|
if let Some(body) = body {
|
||||||
|
@ -114,13 +114,14 @@ impl Interpret for Function {
|
|||||||
}
|
}
|
||||||
impl Interpret for Struct {
|
impl Interpret for Struct {
|
||||||
fn interpret(&self, env: &mut Environment) -> IResult<ConValue> {
|
fn interpret(&self, env: &mut Environment) -> IResult<ConValue> {
|
||||||
let Self { name, kind } = self;
|
let Self { name, gens: _, kind } = self;
|
||||||
match kind {
|
match kind {
|
||||||
StructKind::Empty => {}
|
StructKind::Empty => {}
|
||||||
StructKind::Tuple(args) => {
|
StructKind::Tuple(args) => {
|
||||||
// Constructs the AST from scratch. TODO: This, better.
|
// Constructs the AST from scratch. TODO: This, better.
|
||||||
let constructor = Function {
|
let constructor = Function {
|
||||||
name: *name,
|
name: *name,
|
||||||
|
gens: Default::default(),
|
||||||
sign: TyFn {
|
sign: TyFn {
|
||||||
args: TyKind::Tuple(TyTuple {
|
args: TyKind::Tuple(TyTuple {
|
||||||
types: args.iter().map(|ty| ty.kind.clone()).collect(),
|
types: args.iter().map(|ty| ty.kind.clone()).collect(),
|
||||||
@ -152,7 +153,7 @@ impl Interpret for Struct {
|
|||||||
}
|
}
|
||||||
impl Interpret for Enum {
|
impl Interpret for Enum {
|
||||||
fn interpret(&self, env: &mut Environment) -> IResult<ConValue> {
|
fn interpret(&self, env: &mut Environment) -> IResult<ConValue> {
|
||||||
let Self { name, variants: kind } = self;
|
let Self { name, gens: _, variants: kind } = self;
|
||||||
if let Some(variants) = kind {
|
if let Some(variants) = kind {
|
||||||
env.push_frame(name.to_ref(), Default::default());
|
env.push_frame(name.to_ref(), Default::default());
|
||||||
for (idx, Variant { name, kind }) in variants.iter().enumerate() {
|
for (idx, Variant { name, kind }) in variants.iter().enumerate() {
|
||||||
|
@ -60,6 +60,7 @@ pub enum Parsing {
|
|||||||
|
|
||||||
Item,
|
Item,
|
||||||
ItemKind,
|
ItemKind,
|
||||||
|
Generics,
|
||||||
Alias,
|
Alias,
|
||||||
Const,
|
Const,
|
||||||
Static,
|
Static,
|
||||||
@ -176,6 +177,7 @@ impl Display for Parsing {
|
|||||||
Parsing::MetaKind => "an attribute's arguments",
|
Parsing::MetaKind => "an attribute's arguments",
|
||||||
Parsing::Item => "an item",
|
Parsing::Item => "an item",
|
||||||
Parsing::ItemKind => "an item",
|
Parsing::ItemKind => "an item",
|
||||||
|
Parsing::Generics => "a list of type arguments",
|
||||||
Parsing::Alias => "a type alias",
|
Parsing::Alias => "a type alias",
|
||||||
Parsing::Const => "a const item",
|
Parsing::Const => "a const item",
|
||||||
Parsing::Static => "a static variable",
|
Parsing::Static => "a static variable",
|
||||||
|
@ -347,6 +347,21 @@ impl Parse<'_> for ItemKind {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Parse<'_> for Generics {
|
||||||
|
fn parse(p: &mut Parser<'_>) -> PResult<Self> {
|
||||||
|
const P: Parsing = Parsing::Generics;
|
||||||
|
let vars = match p.peek_kind(P)? {
|
||||||
|
TokenKind::Lt => delim(
|
||||||
|
sep(Sym::parse, TokenKind::Comma, TokenKind::Gt, P),
|
||||||
|
(TokenKind::Lt, TokenKind::Gt),
|
||||||
|
P,
|
||||||
|
)(p)?,
|
||||||
|
_ => Vec::new(),
|
||||||
|
};
|
||||||
|
Ok(Generics { vars })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl Parse<'_> for Alias {
|
impl Parse<'_> for Alias {
|
||||||
/// Parses a [`type` alias](Alias)
|
/// Parses a [`type` alias](Alias)
|
||||||
fn parse(p: &mut Parser<'_>) -> PResult<Self> {
|
fn parse(p: &mut Parser<'_>) -> PResult<Self> {
|
||||||
@ -442,6 +457,7 @@ impl Parse<'_> for Function {
|
|||||||
p.consume_peeked();
|
p.consume_peeked();
|
||||||
|
|
||||||
let name = Sym::parse(p)?;
|
let name = Sym::parse(p)?;
|
||||||
|
let gens = Generics::parse(p)?;
|
||||||
let (bind, types) = delim(FnSig::parse, PARENS, P)(p)?;
|
let (bind, types) = delim(FnSig::parse, PARENS, P)(p)?;
|
||||||
let sign = TyFn {
|
let sign = TyFn {
|
||||||
args: Box::new(match types.len() {
|
args: Box::new(match types.len() {
|
||||||
@ -456,6 +472,7 @@ impl Parse<'_> for Function {
|
|||||||
};
|
};
|
||||||
Ok(Function {
|
Ok(Function {
|
||||||
name,
|
name,
|
||||||
|
gens,
|
||||||
sign,
|
sign,
|
||||||
bind,
|
bind,
|
||||||
body: match p.peek_kind(P)? {
|
body: match p.peek_kind(P)? {
|
||||||
@ -508,7 +525,7 @@ impl Parse<'_> for Struct {
|
|||||||
/// Parses a [`struct` definition](Struct)
|
/// Parses a [`struct` definition](Struct)
|
||||||
fn parse(p: &mut Parser) -> PResult<Struct> {
|
fn parse(p: &mut Parser) -> PResult<Struct> {
|
||||||
p.match_type(TokenKind::Struct, Parsing::Struct)?;
|
p.match_type(TokenKind::Struct, Parsing::Struct)?;
|
||||||
Ok(Struct { name: Sym::parse(p)?, kind: StructKind::parse(p)? })
|
Ok(Struct { name: Sym::parse(p)?, gens: Generics::parse(p)?, kind: StructKind::parse(p)? })
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -557,6 +574,7 @@ impl Parse<'_> for Enum {
|
|||||||
p.match_type(TokenKind::Enum, Parsing::Enum)?;
|
p.match_type(TokenKind::Enum, Parsing::Enum)?;
|
||||||
Ok(Enum {
|
Ok(Enum {
|
||||||
name: Sym::parse(p)?,
|
name: Sym::parse(p)?,
|
||||||
|
gens: Generics::parse(p)?,
|
||||||
variants: {
|
variants: {
|
||||||
const P: Parsing = Parsing::EnumKind;
|
const P: Parsing = Parsing::EnumKind;
|
||||||
match p.peek_kind(P)? {
|
match p.peek_kind(P)? {
|
||||||
|
@ -232,6 +232,14 @@ pub mod clangify {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
impl CLangify for Generics {
|
||||||
|
fn print(&self, _y: &mut CLangifier) {
|
||||||
|
let Self { vars } = self;
|
||||||
|
if !vars.is_empty() {
|
||||||
|
panic!("C doesn't have generics, dumbass.")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
impl CLangify for Alias {
|
impl CLangify for Alias {
|
||||||
fn print(&self, y: &mut CLangifier) {
|
fn print(&self, y: &mut CLangifier) {
|
||||||
let Self { name, from } = self;
|
let Self { name, from } = self;
|
||||||
@ -263,7 +271,7 @@ pub mod clangify {
|
|||||||
}
|
}
|
||||||
impl CLangify for Function {
|
impl CLangify for Function {
|
||||||
fn print(&self, y: &mut CLangifier) {
|
fn print(&self, y: &mut CLangifier) {
|
||||||
let Self { name, sign, bind, body } = self;
|
let Self { name, gens: _, sign, bind, body } = self;
|
||||||
let TyFn { args, rety } = sign;
|
let TyFn { args, rety } = sign;
|
||||||
let types = match args.as_ref() {
|
let types = match args.as_ref() {
|
||||||
TyKind::Tuple(TyTuple { types }) => types.as_slice(),
|
TyKind::Tuple(TyTuple { types }) => types.as_slice(),
|
||||||
@ -293,7 +301,7 @@ pub mod clangify {
|
|||||||
}
|
}
|
||||||
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, gens: _, kind } = self;
|
||||||
y.p("struct ").p(name).nest(" {").p(kind);
|
y.p("struct ").p(name).nest(" {").p(kind);
|
||||||
y.endl().p("}");
|
y.endl().p("}");
|
||||||
}
|
}
|
||||||
@ -320,7 +328,7 @@ pub mod clangify {
|
|||||||
}
|
}
|
||||||
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, gens: _, variants } = self;
|
||||||
y.nest("enum ").p(name).p(" {").endl();
|
y.nest("enum ").p(name).p(" {").endl();
|
||||||
match variants {
|
match variants {
|
||||||
Some(v) => {
|
Some(v) => {
|
||||||
|
@ -214,6 +214,12 @@ pub mod yamlify {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
impl Yamlify for Generics {
|
||||||
|
fn yaml(&self, y: &mut Yamler) {
|
||||||
|
let Self { vars } = self;
|
||||||
|
y.key("Generics").value(vars);
|
||||||
|
}
|
||||||
|
}
|
||||||
impl Yamlify for Alias {
|
impl Yamlify for Alias {
|
||||||
fn yaml(&self, y: &mut Yamler) {
|
fn yaml(&self, y: &mut Yamler) {
|
||||||
let Self { name, from } = self;
|
let Self { name, from } = self;
|
||||||
@ -243,9 +249,10 @@ pub mod yamlify {
|
|||||||
}
|
}
|
||||||
impl Yamlify for Function {
|
impl Yamlify for Function {
|
||||||
fn yaml(&self, y: &mut Yamler) {
|
fn yaml(&self, y: &mut Yamler) {
|
||||||
let Self { name, sign, bind, body } = self;
|
let Self { name, gens, sign, bind, body } = self;
|
||||||
y.key("Function")
|
y.key("Function")
|
||||||
.pair("name", name)
|
.pair("name", name)
|
||||||
|
.pair("gens", gens)
|
||||||
.pair("sign", sign)
|
.pair("sign", sign)
|
||||||
.pair("bind", bind)
|
.pair("bind", bind)
|
||||||
.pair("body", body);
|
.pair("body", body);
|
||||||
@ -253,8 +260,11 @@ pub mod yamlify {
|
|||||||
}
|
}
|
||||||
impl Yamlify for Struct {
|
impl Yamlify for Struct {
|
||||||
fn yaml(&self, y: &mut Yamler) {
|
fn yaml(&self, y: &mut Yamler) {
|
||||||
let Self { name, kind } = self;
|
let Self { name, gens, kind } = self;
|
||||||
y.key("Struct").pair("name", name).yaml(kind);
|
y.key("Struct")
|
||||||
|
.pair("gens", gens)
|
||||||
|
.pair("name", name)
|
||||||
|
.yaml(kind);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
impl Yamlify for StructKind {
|
impl Yamlify for StructKind {
|
||||||
@ -274,8 +284,8 @@ pub mod yamlify {
|
|||||||
}
|
}
|
||||||
impl Yamlify for Enum {
|
impl Yamlify for Enum {
|
||||||
fn yaml(&self, y: &mut Yamler) {
|
fn yaml(&self, y: &mut Yamler) {
|
||||||
let Self { name, variants: kind } = self;
|
let Self { name,gens, variants: kind } = self;
|
||||||
y.key("Enum").pair("name", name).yaml(kind);
|
y.key("Enum").pair("gens", gens).pair("name", name).yaml(kind);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
impl Yamlify for Variant {
|
impl Yamlify for Variant {
|
||||||
|
@ -66,7 +66,8 @@ fn cat_alias(table: &mut Table, node: Handle, a: &Alias) -> CatResult<()> {
|
|||||||
|
|
||||||
fn cat_struct(table: &mut Table, node: Handle, s: &Struct) -> CatResult<()> {
|
fn cat_struct(table: &mut Table, node: Handle, s: &Struct) -> CatResult<()> {
|
||||||
let parent = parent(table, node);
|
let parent = parent(table, node);
|
||||||
let Struct { name: _, kind } = s;
|
let Struct { name: _, gens: _, kind } = s;
|
||||||
|
// TODO: Generics
|
||||||
let kind = match kind {
|
let kind = match kind {
|
||||||
StructKind::Empty => TypeKind::Adt(Adt::UnitStruct),
|
StructKind::Empty => TypeKind::Adt(Adt::UnitStruct),
|
||||||
StructKind::Tuple(types) => {
|
StructKind::Tuple(types) => {
|
||||||
@ -99,7 +100,8 @@ fn cat_member(
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn cat_enum<'a>(table: &mut Table<'a>, node: Handle, e: &'a Enum) -> CatResult<()> {
|
fn cat_enum<'a>(table: &mut Table<'a>, node: Handle, e: &'a Enum) -> CatResult<()> {
|
||||||
let Enum { name: _, variants: kind } = e;
|
let Enum { name: _, gens: _, variants: kind } = e;
|
||||||
|
// TODO: Genereics
|
||||||
let kind = match kind {
|
let kind = match kind {
|
||||||
None => TypeKind::Adt(Adt::Enum(vec![])),
|
None => TypeKind::Adt(Adt::Enum(vec![])),
|
||||||
Some(variants) => {
|
Some(variants) => {
|
||||||
|
@ -105,7 +105,8 @@ impl<'a> Visit<'a> for Populator<'_, 'a> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn visit_function(&mut self, f: &'a cl_ast::Function) {
|
fn visit_function(&mut self, f: &'a cl_ast::Function) {
|
||||||
let cl_ast::Function { name, sign, bind, body } = f;
|
let cl_ast::Function { name, gens: _, sign, bind, body } = f;
|
||||||
|
// TODO: populate generics?
|
||||||
self.inner.set_source(Source::Function(f));
|
self.inner.set_source(Source::Function(f));
|
||||||
self.set_name(*name);
|
self.set_name(*name);
|
||||||
|
|
||||||
@ -118,7 +119,8 @@ impl<'a> Visit<'a> for Populator<'_, 'a> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn visit_struct(&mut self, s: &'a cl_ast::Struct) {
|
fn visit_struct(&mut self, s: &'a cl_ast::Struct) {
|
||||||
let cl_ast::Struct { name, kind } = s;
|
let cl_ast::Struct { name, gens: _, kind } = s;
|
||||||
|
// TODO: populate generics?
|
||||||
self.inner.set_source(Source::Struct(s));
|
self.inner.set_source(Source::Struct(s));
|
||||||
self.set_name(*name);
|
self.set_name(*name);
|
||||||
|
|
||||||
@ -126,7 +128,8 @@ impl<'a> Visit<'a> for Populator<'_, 'a> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn visit_enum(&mut self, e: &'a cl_ast::Enum) {
|
fn visit_enum(&mut self, e: &'a cl_ast::Enum) {
|
||||||
let cl_ast::Enum { name, variants } = e;
|
let cl_ast::Enum { name, gens: _, variants } = e;
|
||||||
|
// TODO: populate generics?
|
||||||
self.inner.set_source(Source::Enum(e));
|
self.inner.set_source(Source::Enum(e));
|
||||||
self.set_name(*name);
|
self.set_name(*name);
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user