Skip to content

Commit

Permalink
initial commit
Browse files Browse the repository at this point in the history
  • Loading branch information
Andrew Weiss committed Apr 15, 2019
0 parents commit 2356d6b
Show file tree
Hide file tree
Showing 10 changed files with 1,165 additions and 0 deletions.
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
/target
**/*.rs.bk
Cargo.lock
1 change: 1 addition & 0 deletions .rustfmt.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
tab_spaces = 2
8 changes: 8 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
[package]
name = "cddl"
version = "0.1.0"
authors = ["Andrew Weiss <[email protected]>"]
edition = "2018"

[dependencies]
whoami = "0.4.1"
173 changes: 173 additions & 0 deletions src/ast.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,173 @@
use super::token::Token;
use std::fmt;
use std::string::ToString;

pub trait Node {
fn token_literal(&self) -> Option<String>;
}

#[derive(Default, Debug)]
pub struct CDDL {
pub rules: Vec<Rule>,
}

impl Node for CDDL {
fn token_literal(&self) -> Option<String> {
if self.rules.len() > 0 {
return self.rules[0].token_literal();
}

None
}
}

#[derive(Debug)]
pub struct Identifier(pub Token);

impl Node for Identifier {
fn token_literal(&self) -> Option<String> {
Some(format!("{:?}", self.0))
}
}

impl From<String> for Identifier {
fn from(s: String) -> Self {
Identifier(Token::IDENT(s))
}
}

impl ToString for Identifier {
fn to_string(&self) -> String {
format!("{}", self.0.to_string())
}
}

#[derive(Debug)]
pub enum Rule {
Type(TypeRule),
Group(GroupRule),
}

impl Node for Rule {
fn token_literal(&self) -> Option<String> {
match self {
Rule::Type(tr) => tr.token_literal(),
Rule::Group(gr) => gr.token_literal(),
}
}
}

#[derive(Debug)]
pub struct TypeRule {
pub name: Identifier,
pub generic_param: Option<GenericParm>,
pub is_type_choice_alternate: bool,
pub value: Type,
}

impl TypeRule {
pub fn token_literal(&self) -> Option<String> {
self.name.token_literal()
}
}

#[derive(Debug)]
pub struct GroupRule {
pub name: Identifier,
pub generic_para: Option<GenericParm>,
pub is_group_choice_alternate: bool,
pub entry: GroupEntry,
}

impl Node for GroupRule {
fn token_literal(&self) -> Option<String> {
Some("".into())
}
}

#[derive(Default, Debug)]
pub struct GenericParm(pub Vec<Identifier>);

#[derive(Debug)]
pub struct GenericArg(pub Vec<Type1>);

#[derive(Debug)]
pub struct Type(pub Vec<Type1>);

#[derive(Debug)]
pub struct Type1 {
pub type2: Type2,
pub operator: Option<(RangeCtlOp, Type2)>,
}

#[derive(Debug)]
pub enum RangeCtlOp {
RangeOp(bool),
CtlOp(String),
}

#[derive(Debug)]
pub enum Type2 {
Value(Identifier),
Typename((Identifier, Option<GenericArg>)),
Group(Type),
Map(Group),
Array(Group),
Unwrap((Identifier, Option<GenericArg>)),
ChoiceFromInlineGroup(Group),
ChoiceFromGroup((Identifier, Option<GenericArg>)),
TaggedData(String),
TaggedDataMajorType(String),
Any,
}

impl<'a> fmt::Display for Type2 {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
Type2::Typename((tn, _)) => write!(f, "{}", tn.0),
_ => write!(f, ""),
}
}
}

#[derive(Debug)]
pub struct Group(Vec<GroupChoice>);

#[derive(Debug)]
pub struct GroupChoice(Vec<GroupEntry>);

#[derive(Debug)]
pub enum GroupEntry {
MemberKey(MemberKeyEntry),
Groupname(GroupnameEntry),
InlineGroup((Option<Occur>, Group)),
}

#[derive(Debug)]
pub struct MemberKeyEntry {
pub occur: Option<Occur>,
pub member_key: Option<MemberKey>,
pub entry_type: Type,
}

#[derive(Debug)]
pub struct GroupnameEntry {
pub occur: Option<Occur>,
pub name: Identifier,
pub generic_arg: Option<GenericArg>,
}

#[derive(Debug)]
pub enum MemberKey {
// if true, cut is present
Type1((Type1, bool)),
Bareword(Identifier),
Value(String)
}

#[derive(Debug)]
pub enum Occur {
Exact((usize, usize)),
OneOrMore,
Optional,
}
16 changes: 16 additions & 0 deletions src/bin/repl.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
use cddl::repl;
use std::{error::Error, io};
use whoami;

fn main() -> Result<(), Box<Error>> {
let username = whoami::username();

println!("Hello {}! This is the CDDL language!", username);

println!("Feel free to type in commands");

let input = io::stdin();
let output = io::stdout();
repl::start(input.lock(), output.lock())?;
Ok(())
}
Loading

0 comments on commit 2356d6b

Please sign in to comment.