1
0
Fork 0
forked from AbleOS/ableos

Compare commits

..

No commits in common. "f9451e3d7ddd8e1d814acdb5814ad3698b67215b" and "b5cdc9c4fd397958dd70ce943628f4e6c27f6f4a" have entirely different histories.

4 changed files with 121 additions and 230 deletions

View file

@ -1,31 +0,0 @@
declarations ::= <declaration> <declarations>
declaration ::= <enum_decl> | <struct_decl> | <type_decl> | <protocol_decl>
type_decl ::= "type" <ident> <ident> ";"
enum_decl ::= "enum" <ident> "{" "}"
| "enum" <ident> "{" <enum_members> "}"
enum_members ::= <enum_member> ["," <enum_member>]+ [","]
enum_member ::= <ident> "=" <number>
struct_decl ::= "struct" <ident> "{" "}"
| "struct" <ident> "{" <struct_members> "}"
struct_members ::= <struct_member>
| <struct_member> ","
| <struct_member> "," <struct_members>
| <struct_member> "," <struct_members>
protocol_decl ::= "protocol" <ident> "{" "}"
| "protocol" <ident> "{" <protocol_member>+ "}"
protocol_member ::= "fn" <ident>"("[<arg_list>]")" "->" <ident> ";"
arg_list ::= <ident> ["," <ident>]+

View file

@ -19,10 +19,6 @@ enum Token {
#[token("protocol")] #[token("protocol")]
Protocol, Protocol,
// Tokens can be literal strings, of any length.
#[token("type")]
Type,
#[token("enum")] #[token("enum")]
Enum, Enum,
@ -43,7 +39,6 @@ enum Token {
#[token(":")] #[token(":")]
Colon, Colon,
#[token(";")] #[token(";")]
SemiColon, SemiColon,
@ -62,11 +57,11 @@ enum Token {
#[regex("[1234567890]+", |lex|{lex.slice().parse::<u64>().unwrap()})] #[regex("[1234567890]+", |lex|{lex.slice().parse::<u64>().unwrap()})]
Number(u64), Number(u64),
#[regex(r"@[a-zA-Z_]+", /*|lex|{lex.slice().to_string()}*/ logos::skip)] #[regex(r"@[a-zA-Z_]+", |lex|{lex.slice().to_string()})]
Decorator, Decorator(String),
#[regex(r#"@[a-zA-Z_]+\([a-zA-Z,0-9=]+\)"#, /*|lex|{lex.slice().to_string()}*/ logos::skip)] #[regex(r#"@[a-zA-Z_]+\([a-zA-Z,0-9=]+\)"#, |lex|{lex.slice().to_string()})]
DecoratorOption, DecoratorOption(String),
} }
pub fn build_idl(name: String) { pub fn build_idl(name: String) {
@ -83,7 +78,7 @@ pub fn build_idl(name: String) {
} }
} }
println!("{:#?}", parse(tokens)); println!("{:?}", parse(tokens));
} }
fn build(a: Vec<Token>) { fn build(a: Vec<Token>) {

View file

@ -1,14 +1,17 @@
use std::{iter::Peekable, slice::Iter}; use std::{iter::Peekable, slice::Iter};
use super::Token; use super::Token;
#[derive(Debug, Clone, PartialEq)] #[derive(Debug, Clone, PartialEq)]
pub struct AST(Vec<Declaration>); pub struct AST(Vec<DecoratedDeclaration>);
#[derive(Debug, Clone, PartialEq)]
struct DecoratedDeclaration(Option<Decorator>, Declaration);
#[derive(Debug, Clone, PartialEq)]
struct Decorator(String);
#[derive(Debug, Clone, PartialEq)] #[derive(Debug, Clone, PartialEq)]
enum Declaration{ enum Declaration{
EnumDeclaration(EnumDeclaration), EnumDeclaration,
StructDeclaration(StructDeclaration), StructDeclaration(StructDeclaration),
TypeDeclaration(TypeDeclaration),
ProtocolDeclaration, ProtocolDeclaration,
} }
#[derive(Debug, Clone, PartialEq)] #[derive(Debug, Clone, PartialEq)]
@ -17,186 +20,110 @@ struct StructDeclaration {
members : Vec<StructMember>, members : Vec<StructMember>,
} }
#[derive(Debug, Clone, PartialEq)] #[derive(Debug, Clone, PartialEq)]
struct TypeDeclaration {
name : String,
type_name : String,
}
#[derive(Debug, Clone, PartialEq)]
struct StructMember { struct StructMember {
name : String, name : String,
type_name : String, type_name : String,
} }
#[derive(Debug, Clone, PartialEq)]
struct EnumDeclaration {
name : String,
members : Vec<EnumMember>,
}
#[derive(Debug, Clone, PartialEq)]
struct EnumMember {
name : String,
number: u64,
}
fn parse_decorated_declarations(tokens : &mut Peekable<Iter<'_, Token>>) -> Vec<DecoratedDeclaration>{
let mut declarations : Vec<DecoratedDeclaration> = Vec::new();
loop {
match tokens.peek() {
Some(_) => {
let decoration = parse_decoration(tokens);
assert!(decoration == None, "NO DECORATIONS!!!");
let declaration = parse_declaration(tokens);
/// Consume's a token that's expected. If the token that's consumed is not declarations.push(DecoratedDeclaration(decoration, declaration));
/// the given expected token then panic },
fn consume(tokens : &mut Peekable<Iter<'_, Token>>, token : Token) { None => break,
let a = tokens.next();
match a {
None => panic!("Expected {:?}, Got End Of File", token),
Some(a) => if *a != token {
panic!("Expected {:?}, Got {:?}", token, *a);
} }
} }
return declarations
}
fn parse_decoration(tokens : &mut Peekable<Iter<'_, Token>>) -> Option<Decorator> {
match tokens.peek().unwrap() {
Token::Decorator(s) => {
tokens.next();
Some(Decorator(s.to_string()))
},
Token::DecoratorOption(s) => {
tokens.next();
Some(Decorator(s.to_string()))
},
_ => None,
}
}
fn parse_declaration(tokens : &mut Peekable<Iter<'_, Token>>) -> Declaration {
match tokens.next().expect("Expected a statement, got end of tokens") {
Token::Enum => {
Declaration::EnumDeclaration
},
Token::Struct => {
Declaration::StructDeclaration(parse_struct_declaration(tokens))
},
Token::Protocol => {
Declaration::ProtocolDeclaration
},
_ => panic!("Expected a enumeration, struct or protocol")
}
}
fn parse_struct_declaration(tokens : &mut Peekable<Iter<'_, Token>>) -> StructDeclaration{
if let Token::Identifier(identifier) = tokens.next().unwrap() {
let mut members : Vec<StructMember> = Vec::new();
assert!(tokens.next().expect("expected a {{, got end of token list") == &Token::LBrace, "expected a {{ after identifier in struct declaration");
loop {
match tokens.peek().expect("expected }} or struct members") {
&Token::RBrace => break,
_ => {
// if we're in this branch then there MUST a struct member here
members.push(parse_struct_member(tokens));
// is there a comma here?
// nightmare
if **(tokens.peek().unwrap()) == Token::Comma {
// consume comma
tokens.next();
}
// if there isn't a comma nor a right brace after the struct member
else if **(tokens.peek().unwrap()) != Token::RBrace {
panic!("expected a comma to separate struct members");
}
}
}
}
tokens.next(); // consume closing bracket
return StructDeclaration{
name : identifier.to_string(),
members,
}
}
else {
panic!("Expected an identifier after 'struct'")
}
}
fn parse_struct_member(tokens : &mut Peekable<Iter<'_, Token>>) -> StructMember {
if let Token::Identifier(name) = tokens.next().unwrap(){
assert!(tokens.next().unwrap() == &Token::Colon, "expected colon after struct member name");
if let Token::Identifier(type_name) = tokens.next().unwrap(){
StructMember{name: name.to_string(), type_name: type_name.to_string()}
}
else{
panic!("Expected type name in Struct Member");
}
}
else {
panic!("Expected identifier in Struct Member");
}
} }
pub fn parse(tokens : Vec<Token>) -> AST{ pub fn parse(tokens : Vec<Token>) -> AST{
let mut tokens_iter = tokens.iter().peekable(); let mut tokens_iter = tokens.iter().peekable();
AST(declarations(&mut tokens_iter)) AST(parse_decorated_declarations(&mut tokens_iter))
} }
fn declarations(tokens : &mut Peekable<Iter<'_, Token>>) -> Vec<Declaration> {
let mut decls : Vec<Declaration> = Vec::new();
loop {
match declaration(tokens) {
Some(x) => decls.push(x),
None => break,
}
}
decls
}
fn declaration(tokens : &mut Peekable<Iter<'_, Token>>) -> Option<Declaration> {
match tokens.peek(){
None => None,
Some(tok) => match tok {
Token::Enum => Some(enum_decl(tokens)),
Token::Struct => Some(struct_decl(tokens)),
Token::Type => Some(type_declaration(tokens)),
_ => None,
}
}
}
fn enum_decl(tokens : &mut Peekable<Iter<'_, Token>>) -> Declaration {
consume(tokens, Token::Enum);
let name = identifier(tokens).expect("Expected Identifier after `enum`");
consume(tokens, Token::LBrace);
let mut members = Vec::new();
match tokens.peek().expect("Unexpected EOF after LBrace") {
Token::RBrace => {}, // skip checking for enum_members if empty
_ => {
enum_members(tokens, &mut members);
},
}
consume(tokens, Token::RBrace);
Declaration::EnumDeclaration(EnumDeclaration{name, members})
}
fn enum_members(tokens : &mut Peekable<Iter<'_, Token>>, members: &mut Vec<EnumMember>) {
members.push(enum_member(tokens).unwrap());
loop {
match tokens.peek().expect("Unexpected EOF inside enum declaration") {
Token::Comma => {
consume(tokens, Token::Comma);
if let Some(member) = enum_member(tokens) {
members.push(member);
} else {
break;
}
},
_ => {},
}
}
}
fn enum_member(tokens : &mut Peekable<Iter<'_, Token>>) -> Option<EnumMember> {
let name = identifier(tokens);
if let Some(name) = name {
consume(tokens, Token::Equal);
let number = parse_number(tokens).expect("Expected Number after `=`");
Some(EnumMember{name, number})
} else {
None
}
}
fn struct_decl(tokens : &mut Peekable<Iter<'_, Token>>) -> Declaration {
consume(tokens, Token::Struct);
let name = identifier(tokens).expect("Expected Identifier after `struct`");
consume(tokens, Token::LBrace);
let mut members = Vec::new();
match tokens.peek().expect("Unexpected EOF after LBrace") {
Token::RBrace => {}, // skip checking for struct_members if empty
_ => {
struct_members(tokens, &mut members);
},
}
consume(tokens, Token::RBrace);
Declaration::StructDeclaration(StructDeclaration{name, members})
}
fn struct_members(tokens : &mut Peekable<Iter<'_, Token>>, members: &mut Vec<StructMember>) {
members.push(struct_member(tokens).unwrap());
loop {
match tokens.peek().expect("Unexpected EOF inside struct declaration") {
Token::Comma => {
consume(tokens, Token::Comma);
if let Some(member) = struct_member(tokens) {
members.push(member);
} else {
break;
}
},
_ => {},
}
}
}
fn struct_member(tokens : &mut Peekable<Iter<'_, Token>>) -> Option<StructMember> {
let name = identifier(tokens);
if let Some(name) = name {
consume(tokens, Token::Colon);
let type_name = identifier(tokens).expect("Expected Type after Colon");
Some(StructMember{name, type_name})
} else {
None
}
}
fn type_declaration(tokens : &mut Peekable<Iter<'_, Token>>) -> Declaration {
consume(tokens, Token::Type);
let name = identifier(tokens).expect("Expected Identifier after `type`");
let type_name = identifier(tokens).expect("Expected type after Identifier");
Declaration::TypeDeclaration(TypeDeclaration{name, type_name})
}
fn identifier(tokens : &mut Peekable<Iter<'_, Token>>) -> Option<String> {
let result = tokens.peek().map_or(None, |x| match x {
Token::Identifier(s) => {
Some(s.to_string())
},
_ => None
});
if let Some(_) = result {
tokens.next();
}
result
}
fn parse_number(tokens : &mut Peekable<Iter<'_, Token>>) -> Option<u64> {
let result = tokens.peek().map_or(None, |x| match x {
Token::Number(s) => Some(*s),
_ => None
});
if let Some(_) = result {
tokens.next();
}
result
}

View file

@ -1,25 +1,25 @@
// A comment // A comment
//@auto_increment //@auto_increment
enum LogLevel { //enum LogLevel {
Error = 0, // Error = 0,
Warn = 1, // Warn,
Info = 2, // Info,
Debug = 3, // Debug,
Trace = 4, // Trace,
} //}
//
//@auto_increment //@auto_increment
enum LogResult { //enum LogResult {
Err = 0, // Err = 0,
Ok = 1, // Ok,
} //}
struct Log { struct Log {
log_level: LogLevel, log_level: LogLevel,
} }
//@visibility(public) //@visibility(public)
protocol Log { //protocol Log {
fn log(Log) -> LogResult; // fn log(Log) -> LogResult;
fn flush() -> LogResult; // fn flush() -> LogResult;
} //}