Skip to content

Commit

Permalink
Implement alias definitions
Browse files Browse the repository at this point in the history
Closes #42
  • Loading branch information
brendanzab committed Jul 18, 2019
1 parent b0eec37 commit a7ffb19
Show file tree
Hide file tree
Showing 30 changed files with 474 additions and 106 deletions.
5 changes: 5 additions & 0 deletions crates/ddl-test/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,11 @@ test!(fail_duplicate_definitions, "fail_duplicate_definitions.ddl");
test!(fail_unexpected_token, "fail_unexpected_token.ddl");
test!(fail_unexpected_character, "fail_unexpected_character.ddl");

mod alias {
test!(pass_simple, "alias/pass_simple.ddl");
test!(pass_simple_doc, "alias/pass_simple_doc.ddl");
}

#[rustfmt::skip]
mod r#struct {
test!(pass_empty, "struct/pass_empty.ddl");
Expand Down
5 changes: 4 additions & 1 deletion crates/ddl/src/binary/read.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,13 @@ pub fn read_module_item(
) -> Result<Term, ddl_rt::ReadError> {
for item in &module.items {
match item {
core::Item::Alias(alias) if alias.name.0 == name => {
return read_ty(&alias.term, ctxt);
}
core::Item::Struct(struct_ty) if struct_ty.name.0 == name => {
return read_struct_ty(struct_ty, ctxt);
}
core::Item::Struct(_) => {}
core::Item::Alias(_) | core::Item::Struct(_) => {}
}
}

Expand Down
80 changes: 54 additions & 26 deletions crates/ddl/src/compile/doc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,21 +17,49 @@ pub fn compile_module(writer: &mut impl Write, module: &core::Module) -> io::Res
writeln!(writer, "-->")?;

for item in &module.items {
writeln!(writer)?;
match item {
core::Item::Struct(struct_ty) => {
writeln!(writer)?;
compile_struct_item(writer, struct_ty)?;
}
core::Item::Alias(alias) => compile_alias(writer, alias)?,
core::Item::Struct(struct_ty) => compile_struct_ty(writer, struct_ty)?,
}
}

Ok(())
}

fn compile_struct_item(writer: &mut impl Write, struct_ty: &core::StructType) -> io::Result<()> {
fn compile_alias(writer: &mut impl Write, alias: &core::Alias) -> io::Result<()> {
writeln!(writer, "## {}", alias.name)?;

if !alias.doc.is_empty() {
writeln!(writer)?;
writeln!(writer, "### Description")?;
writeln!(writer)?;
for doc_line in alias.doc.iter() {
// TODO: Bump inner heading levels
let doc_line = match doc_line {
line if line.starts_with(" ") => &line[" ".len()..],
line => &line[..],
};
writeln!(writer, "{}", doc_line)?;
}
}

writeln!(writer)?;
writeln!(writer, "### Definition")?;
writeln!(writer)?;
writeln!(writer, "```")?;
writeln!(writer, "{}", compile_ty(&alias.term))?;
writeln!(writer, "```")?;

Ok(())
}

fn compile_struct_ty(writer: &mut impl Write, struct_ty: &core::StructType) -> io::Result<()> {
writeln!(writer, "## {}", struct_ty.name)?;

if !struct_ty.doc.is_empty() {
writeln!(writer)?;
writeln!(writer, "### Description")?;
writeln!(writer)?;
for doc_line in struct_ty.doc.iter() {
// TODO: Bump inner heading levels
Expand All @@ -45,7 +73,7 @@ fn compile_struct_item(writer: &mut impl Write, struct_ty: &core::StructType) ->

if !struct_ty.fields.is_empty() {
writeln!(writer)?;
writeln!(writer, "### Fields")?;
writeln!(writer, "### Definition")?;
writeln!(writer)?;

if struct_ty.fields.iter().all(|field| field.doc.is_empty()) {
Expand Down Expand Up @@ -85,26 +113,26 @@ fn compile_field_description(doc_lines: &[String]) -> String {
}
}

fn compile_ty(term: &core::Term) -> String {
fn compile_ty(term: &core::Term) -> &str {
match term {
core::Term::U8(_) => "U8".to_owned(),
core::Term::U16Le(_) => "U16Le".to_owned(),
core::Term::U16Be(_) => "U16Be".to_owned(),
core::Term::U32Le(_) => "U32Le".to_owned(),
core::Term::U32Be(_) => "U32Be".to_owned(),
core::Term::U64Le(_) => "U64Le".to_owned(),
core::Term::U64Be(_) => "U64Be".to_owned(),
core::Term::S8(_) => "S8".to_owned(),
core::Term::S16Le(_) => "S16Le".to_owned(),
core::Term::S16Be(_) => "S16Be".to_owned(),
core::Term::S32Le(_) => "S32Le".to_owned(),
core::Term::S32Be(_) => "S32Be".to_owned(),
core::Term::S64Le(_) => "S64Le".to_owned(),
core::Term::S64Be(_) => "S64Be".to_owned(),
core::Term::F32Le(_) => "F32Le".to_owned(),
core::Term::F32Be(_) => "F32Be".to_owned(),
core::Term::F64Le(_) => "F64Le".to_owned(),
core::Term::F64Be(_) => "F64Be".to_owned(),
core::Term::Error(_) => "**invalid data description**".to_owned(),
core::Term::U8(_) => "U8",
core::Term::U16Le(_) => "U16Le",
core::Term::U16Be(_) => "U16Be",
core::Term::U32Le(_) => "U32Le",
core::Term::U32Be(_) => "U32Be",
core::Term::U64Le(_) => "U64Le",
core::Term::U64Be(_) => "U64Be",
core::Term::S8(_) => "S8",
core::Term::S16Le(_) => "S16Le",
core::Term::S16Be(_) => "S16Be",
core::Term::S32Le(_) => "S32Le",
core::Term::S32Be(_) => "S32Be",
core::Term::S64Le(_) => "S64Le",
core::Term::S64Be(_) => "S64Be",
core::Term::F32Le(_) => "F32Le",
core::Term::F32Be(_) => "F32Be",
core::Term::F64Le(_) => "F64Le",
core::Term::F64Be(_) => "F64Be",
core::Term::Error(_) => "**invalid data description**",
}
}
108 changes: 57 additions & 51 deletions crates/ddl/src/compile/rust.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,18 +15,28 @@ pub fn compile_module(writer: &mut impl Write, module: &core::Module) -> io::Res
writeln!(writer, "// It is not intended for manual editing.")?;

for item in &module.items {
writeln!(writer)?;
match item {
core::Item::Struct(struct_ty) => {
writeln!(writer)?;
compile_struct_item(writer, struct_ty)?;
}
core::Item::Alias(alias) => compile_alias(writer, alias)?,
core::Item::Struct(struct_ty) => compile_struct_ty(writer, struct_ty)?,
}
}

Ok(())
}

fn compile_struct_item(writer: &mut impl Write, struct_ty: &core::StructType) -> io::Result<()> {
fn compile_alias(writer: &mut impl Write, alias: &core::Alias) -> io::Result<()> {
for doc_line in alias.doc.iter() {
writeln!(writer, "///{}", doc_line)?;
}

let ty = compile_ty(&alias.term);
writeln!(writer, "pub type {} = {};", alias.name, ty)?;

Ok(())
}

fn compile_struct_ty(writer: &mut impl Write, struct_ty: &core::StructType) -> io::Result<()> {
// Struct definition

for doc_line in struct_ty.doc.iter() {
Expand All @@ -42,12 +52,8 @@ fn compile_struct_item(writer: &mut impl Write, struct_ty: &core::StructType) ->
writeln!(writer, " ///{}", doc_line)?;
}

write!(
writer,
" pub {}: {},",
field.name,
compile_host_ty(&field.term),
)?;
let ty = compile_host_ty(&field.term);
write!(writer, " pub {}: {},", field.name, ty,)?;
writeln!(writer)?;
}
writeln!(writer, "}}")?;
Expand Down Expand Up @@ -104,50 +110,50 @@ fn compile_struct_item(writer: &mut impl Write, struct_ty: &core::StructType) ->
Ok(())
}

fn compile_ty(term: &core::Term) -> String {
fn compile_ty(term: &core::Term) -> &str {
match term {
core::Term::U8(_) => "ddl_rt::U8".to_owned(),
core::Term::U16Le(_) => "ddl_rt::U16Le".to_owned(),
core::Term::U16Be(_) => "ddl_rt::U16Be".to_owned(),
core::Term::U32Le(_) => "ddl_rt::U32Le".to_owned(),
core::Term::U32Be(_) => "ddl_rt::U32Be".to_owned(),
core::Term::U64Le(_) => "ddl_rt::U64Le".to_owned(),
core::Term::U64Be(_) => "ddl_rt::U64Be".to_owned(),
core::Term::S8(_) => "ddl_rt::I8".to_owned(),
core::Term::S16Le(_) => "ddl_rt::I16Le".to_owned(),
core::Term::S16Be(_) => "ddl_rt::I16Be".to_owned(),
core::Term::S32Le(_) => "ddl_rt::I32Le".to_owned(),
core::Term::S32Be(_) => "ddl_rt::I32Be".to_owned(),
core::Term::S64Le(_) => "ddl_rt::I64Le".to_owned(),
core::Term::S64Be(_) => "ddl_rt::I64Be".to_owned(),
core::Term::F32Le(_) => "ddl_rt::F32Le".to_owned(),
core::Term::F32Be(_) => "ddl_rt::F32Be".to_owned(),
core::Term::F64Le(_) => "ddl_rt::F64Le".to_owned(),
core::Term::F64Be(_) => "ddl_rt::F64Be".to_owned(),
core::Term::Error(_) => "ddl_rt::InvalidDataDescription".to_owned(),
core::Term::U8(_) => "ddl_rt::U8",
core::Term::U16Le(_) => "ddl_rt::U16Le",
core::Term::U16Be(_) => "ddl_rt::U16Be",
core::Term::U32Le(_) => "ddl_rt::U32Le",
core::Term::U32Be(_) => "ddl_rt::U32Be",
core::Term::U64Le(_) => "ddl_rt::U64Le",
core::Term::U64Be(_) => "ddl_rt::U64Be",
core::Term::S8(_) => "ddl_rt::I8",
core::Term::S16Le(_) => "ddl_rt::I16Le",
core::Term::S16Be(_) => "ddl_rt::I16Be",
core::Term::S32Le(_) => "ddl_rt::I32Le",
core::Term::S32Be(_) => "ddl_rt::I32Be",
core::Term::S64Le(_) => "ddl_rt::I64Le",
core::Term::S64Be(_) => "ddl_rt::I64Be",
core::Term::F32Le(_) => "ddl_rt::F32Le",
core::Term::F32Be(_) => "ddl_rt::F32Be",
core::Term::F64Le(_) => "ddl_rt::F64Le",
core::Term::F64Be(_) => "ddl_rt::F64Be",
core::Term::Error(_) => "ddl_rt::InvalidDataDescription",
}
}

fn compile_host_ty(term: &core::Term) -> String {
fn compile_host_ty(term: &core::Term) -> &str {
match term {
core::Term::U8(_) => "u8".to_owned(),
core::Term::U16Le(_) => "u16".to_owned(),
core::Term::U16Be(_) => "u16".to_owned(),
core::Term::U32Le(_) => "u32".to_owned(),
core::Term::U32Be(_) => "u32".to_owned(),
core::Term::U64Le(_) => "u64".to_owned(),
core::Term::U64Be(_) => "u64".to_owned(),
core::Term::S8(_) => "i8".to_owned(),
core::Term::S16Le(_) => "i16".to_owned(),
core::Term::S16Be(_) => "i16".to_owned(),
core::Term::S32Le(_) => "i32".to_owned(),
core::Term::S32Be(_) => "i32".to_owned(),
core::Term::S64Le(_) => "i64".to_owned(),
core::Term::S64Be(_) => "i64".to_owned(),
core::Term::F32Le(_) => "f32".to_owned(),
core::Term::F32Be(_) => "f32".to_owned(),
core::Term::F64Le(_) => "f64".to_owned(),
core::Term::F64Be(_) => "f64".to_owned(),
core::Term::Error(_) => "ddl_rt::InvalidDataDescription".to_owned(),
core::Term::U8(_) => "u8",
core::Term::U16Le(_) => "u16",
core::Term::U16Be(_) => "u16",
core::Term::U32Le(_) => "u32",
core::Term::U32Be(_) => "u32",
core::Term::U64Le(_) => "u64",
core::Term::U64Be(_) => "u64",
core::Term::S8(_) => "i8",
core::Term::S16Le(_) => "i16",
core::Term::S16Be(_) => "i16",
core::Term::S32Le(_) => "i32",
core::Term::S32Be(_) => "i32",
core::Term::S64Le(_) => "i64",
core::Term::S64Be(_) => "i64",
core::Term::F32Le(_) => "f32",
core::Term::F32Be(_) => "f32",
core::Term::F64Le(_) => "f64",
core::Term::F64Be(_) => "f64",
core::Term::Error(_) => "ddl_rt::InvalidDataDescription",
}
}
15 changes: 12 additions & 3 deletions crates/ddl/src/concrete/grammar.lalrpop
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ use codespan::{ByteIndex, FileId, Span};
use codespan_reporting::diagnostic::Diagnostic;
use std::sync::Arc;

use crate::concrete::{Item, Module, SpannedString, StructType, Term, TypeField};
use crate::concrete::{Alias, Item, Module, SpannedString, StructType, Term, TypeField};
use crate::lexer::Token;

grammar(file_id: FileId, report: &mut dyn FnMut(Diagnostic));
Expand All @@ -23,6 +23,8 @@ extern {
"!" => Token::Bang,
":" => Token::Colon,
"," => Token::Comma,
"=" => Token::Equals,
";" => Token::Semi,
}
}

Expand All @@ -31,13 +33,20 @@ pub Module: Module = {
};

Item: Item = {
<docs: "doc comment"*>
<doc: "doc comment"*>
<start: @L> <name: Identifier> "=" <term: Term> ";" <end: @R> => {
let span = Span::from(start..end);
let doc = Arc::from(doc);

Item::Alias(Alias { span, doc, name, term })
},
<doc: "doc comment"*>
<start: @L> "struct" <name: Identifier> "{"
<fields: (<Field> ",")*>
<last: Field?>
"}" <end: @R> => {
let span = Span::from(start..end);
let doc = Arc::from(docs);
let doc = Arc::from(doc);
let mut fields = fields;
fields.extend(last);

Expand Down
19 changes: 19 additions & 0 deletions crates/ddl/src/concrete/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,12 @@ pub enum Item {
/// struct <name> {}
/// ```
Struct(StructType),
/// Alias definitions.
///
/// ```text
/// alias <name> = <term>;
/// ```
Alias(Alias),
}

/// A struct type definition.
Expand All @@ -63,6 +69,19 @@ pub struct StructType {
pub fields: Vec<TypeField>,
}

/// Alias definition.
#[derive(Debug, Clone)]
pub struct Alias {
/// The full span of this definition.
pub span: Span,
/// Doc comment.
pub doc: Arc<[String]>,
/// Name of this definition.
pub name: SpannedString,
/// Fields in the struct.
pub term: Term,
}

/// A field in a struct type definition.
#[derive(Debug, Clone)]
pub struct TypeField {
Expand Down
12 changes: 11 additions & 1 deletion crates/ddl/src/core/grammar.lalrpop
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ use codespan::{ByteIndex, FileId, Span};
use codespan_reporting::diagnostic::{Diagnostic, Severity};
use std::sync::Arc;

use crate::core::{Item, Label, Module, StructType, Term, TypeField};
use crate::core::{Alias, Item, Label, Module, StructType, Term, TypeField};
use crate::diagnostics;
use crate::lexer::Token;

Expand All @@ -24,6 +24,8 @@ extern {
"!" => Token::Bang,
":" => Token::Colon,
"," => Token::Comma,
"=" => Token::Equals,
";" => Token::Semi,
}
}

Expand All @@ -32,6 +34,14 @@ pub Module: Module = {
};

Item: Item = {
<doc: "doc comment"*>
<start: @L> <name: "identifier"> "=" <term: Term> ";" <end: @R> => {
let span = Span::from(start..end);
let doc = Arc::from(doc);
let name = Label(name);

Item::Alias(Alias { span, doc, name, term })
},
<docs: "doc comment"*>
<start: @L> "struct" <name: "identifier"> "{"
<fields: (<Field> ",")*>
Expand Down

0 comments on commit a7ffb19

Please sign in to comment.