Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
43 changes: 37 additions & 6 deletions ast/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,32 @@ impl For {
}
}

#[derive(Debug, Clone, PartialEq)]
pub struct If {
pub expr: Box<Expr>,
pub body: Box<Expr>,
}

impl If {
pub fn new(if_expr: Box<Expr>, if_body: Box<Expr>) -> Self {
If {
expr: if_expr,
body: if_body,
}
}
}

#[derive(Debug, Clone, PartialEq)]
pub struct Destructure {
pub elements: Vec<Box<Expr>>,
}

impl Destructure {
pub fn new(elements: Vec<Box<Expr>>) -> Self {
Destructure { elements }
}
}

#[derive(Debug, Clone, PartialEq)]
pub struct Match {
pub expr: Box<Expr>,
Expand Down Expand Up @@ -300,27 +326,27 @@ pub struct EnumDecl {
pub visibility: Option<Lexeme>,
pub mutability: Lexeme,
pub identifier: Box<Expr>,
pub declarators: Vec<Box<Expr>>,
pub variants: Vec<Box<Expr>>,
pub sig: Option<Box<Expr>>,
pub variant: Option<Box<Expr>>,
pub enum_type: Option<Box<Expr>>,
}

impl EnumDecl {
pub fn new(
visibility: Option<Lexeme>,
mutability: Lexeme,
identifier: Box<Expr>,
declarators: Vec<Box<Expr>>,
variants: Vec<Box<Expr>>,
sig: Option<Box<Expr>>,
variant: Option<Box<Expr>>,
enum_type: Option<Box<Expr>>,
) -> Self {
EnumDecl {
visibility,
mutability,
identifier,
declarators,
variants,
sig,
variant,
enum_type,
}
}
}
Expand All @@ -330,6 +356,7 @@ pub struct ErrorDecl {
pub visibility: Option<Lexeme>,
pub mutability: Lexeme,
pub identifier: Box<Expr>,
pub variants: Vec<Box<Expr>>,
pub sig: Option<Box<Expr>>,
}

Expand All @@ -338,12 +365,14 @@ impl ErrorDecl {
visibility: Option<Lexeme>,
mutability: Lexeme,
identifier: Box<Expr>,
variants: Vec<Box<Expr>>,
sig: Option<Box<Expr>>,
) -> Self {
ErrorDecl {
visibility,
mutability,
identifier,
variants,
sig,
}
}
Expand Down Expand Up @@ -676,6 +705,8 @@ pub enum Expr {
ArrayDecl(ArrayDecl),
Rest(Rest),
For(For),
Destructure(Destructure),
If(If),
While(While),
Match(Match),
Arm(Arm),
Expand Down
4 changes: 2 additions & 2 deletions ebnf.txt
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
<fn> ::= "fn " "(" <args>? ") " <block>
<struct> ::= "struct " "{ " <declarators>? "}"
<error> ::= "error " ("| " <ident>)+
<if> ::= "if " "(" <expr> ")" (<fn> | <block>) ("else if "(" <expr> ")" (<fn> | <block>))* ("else " ( <fn> | <block>))?
<if> ::= "if " "(" <expr> ")" (<fn> | <block>)
<for> ::= "for " "(" <expr> ")" (<fn> | <block>)
<while> ::= "while " "(" <expr> ")" (<fn> | <block>)
<match> ::= "match " "(" <expr> ")" "{ " <arm>+ "}"
Expand Down Expand Up @@ -41,7 +41,7 @@
<array_access> ::= "[" <expr> "]"
<invoke> ::= "." <ident>
<call> ::= "(" (<or> ("," <or>)*)? ")"
<struct_body> ::= "{" (<ident> ":" <ident>)* "}"
<struct_body> ::= "{" (<ident> ":" <or> ("," <ident> ":" <or>))? "}"
<terminal> ::= "_" | "true " | "false " | "undefined " | "self " | "never " | <num> | <ident> | <chars> | <array_decl> | <anon_fn> | "(" <expr> ")"
<anon_fn> ::= "fn " "(" <args>? ") " <block>
<ident> ::= ([a-z] | [A-Z]) ([A-Z] | [a-z] | [0-9] | "_")*
Expand Down
14 changes: 14 additions & 0 deletions linter/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ impl<'buf, 'ttb, 'sco> LintSource<'buf, 'ttb, 'sco> {
Expr::Declarator(declarator) => self.check_declarator(&declarator),
Expr::Match(_match) => self.check_match(&_match),
Expr::For(_for) => self.check_for(&_for),
Expr::If(_if) => self.check_if(&_if),
Expr::Invoke(invoke) => self.check_invoke(&invoke),
Expr::PropAccess(prop) => self.check_prop_access(&prop),
Expr::Arm(arm) => self.check_arm(&arm),
Expand Down Expand Up @@ -152,6 +153,19 @@ impl<'buf, 'ttb, 'sco> LintSource<'buf, 'ttb, 'sco> {
ok_simple_tree!(UndefinedValue, typ)
}

pub fn check_if(&mut self, _if: &If) -> ResultTreeType {
let res = self.lint_recurse(&_if.expr)?;
let body = self.lint_recurse(&_if.body)?;
let if_op = IfOp {
in_expr: res.0,
in_curried: res.1,
body: body.0,
body_curried: body.1,
};
let cur = if_op.body_curried.clone();
ok_tree!(If, if_op, cur)
}

pub fn check_for(&mut self, _for: &For) -> ResultTreeType {
let res = self.lint_recurse(&_for.expr)?;
let body = self.lint_recurse(&_for.var_loop)?;
Expand Down
90 changes: 56 additions & 34 deletions parser/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ impl<'s> Parser<'s> {
) -> ResultExpr {
let mut variants: Vec<Box<Expr>> = vec![];
while let Some(_) = self.lexer.collect_if(Token::Bar) {
let x = self.ident().xconvert_to_sym_decl()?;
let x = self.ident().xconvert_to_decl()?;
variants.push(x);
}
result_expr!(TagDecl, visibility, mutability, identifier, variants, sig)
Expand All @@ -71,15 +71,12 @@ impl<'s> Parser<'s> {
identifier: Box<Expr>,
sig: Option<Box<Expr>>,
) -> ResultExpr {
let _ = self
.lexer
.collect_if(Token::OBrace)
.xexpect_token(&self, "expected '{'".to_string())?;
let _ = self
.lexer
.collect_if(Token::CBrace)
.xexpect_token(&self, "expected '}'".to_string())?;
result_expr!(ErrorDecl, visibility, mutability, identifier, sig)
let mut variants: Vec<Box<Expr>> = vec![];
while let Some(_) = self.lexer.collect_if(Token::Bar) {
let x = self.ident().xconvert_to_decl()?;
variants.push(x);
}
result_expr!(ErrorDecl, visibility, mutability, identifier, variants, sig)
}

pub fn _enum(
Expand All @@ -99,7 +96,7 @@ impl<'s> Parser<'s> {
.xexpect_token(&self, "expected ')'".to_string())?;
}
while let Some(_) = self.lexer.collect_if(Token::Bar) {
let x = self.ident().xconvert_to_sym_decl()?;
let x = self.ident().xconvert_to_decl()?;
variants.push(x);
}
result_expr!(EnumDecl, visibility, mutability, identifier, variants, sig, enum_type)
Expand Down Expand Up @@ -131,9 +128,9 @@ impl<'s> Parser<'s> {
.collect_of_if(&[Token::Let, Token::Const, Token::Type, Token::Impl])
.xexpect_token(&self, "expected mutability".to_string())?;
let identifier = self
.ident()
.xexpect_expr(&self, "expected identifier".to_string())
.xconvert_to_sym_decl()?;
.destructure()
.xexpect_expr(&self, "expected identifier, or destructure".to_string())
.xconvert_to_decl()?;
let sig = self.opt_signature()?;
let _ = self
.lexer
Expand Down Expand Up @@ -266,7 +263,7 @@ impl<'s> Parser<'s> {
let sig = self
.opt_signature()
.xexpect_expr(&self, "expected signature".to_string())?;
return result_expr!(Declarator, id.xconvert_to_sym_decl().unwrap(), sig)
return result_expr!(Declarator, id.xconvert_to_decl().unwrap(), sig)
.xconvert_to_result_opt();
}
pub fn args(&mut self) -> Result<Option<Vec<Box<Expr>>>> {
Expand Down Expand Up @@ -421,8 +418,9 @@ impl<'s> Parser<'s> {
let mutability = self.lexer.collect_of_if(&[Token::Let, Token::Const]);
if let Some(muta) = mutability {
let identifier = self
.ident()
.xexpect_expr(&self, "expected an identifier".to_string())?;
.destructure()
.xexpect_expr(&self, "expected identifier, or destructure".to_string())
.xconvert_to_decl()?;
let sig = self.opt_signature()?;
let _ = self
.lexer
Expand All @@ -449,8 +447,11 @@ impl<'s> Parser<'s> {
.lexer
.collect_if(Token::CParen)
.xexpect_token(&self, "expected ')'".to_string())?;
if let Some(_fn) = self.anon_fn()? {
return bubble_expr!(If, x, _fn);
}
let blk = self.block()?;
return bubble_expr!(For, x, blk);
return bubble_expr!(If, x, blk);
}
pub fn _while(&mut self) -> ResultOptExpr {
let f = self.lexer.collect_if(Token::While);
Expand Down Expand Up @@ -492,6 +493,27 @@ impl<'s> Parser<'s> {
let blk = self.block()?;
return bubble_expr!(For, x, blk);
}
pub fn destructure(&mut self) -> ResultOptExpr {
let brace = self.lexer.collect_if(Token::OBrace);
if brace.is_some() {
let mut idents: Vec<Box<Expr>> = vec![];
loop {
match self.ident() {
Some(x) => {
idents.push(Box::new(Expr::SymbolDecl(x.into_symbol())));
let _ = self.lexer.collect_if(Token::Comma);
}
None => break,
}
}
let _ = self
.lexer
.collect_if(Token::CBrace)
.xexpect_token(&self, "expected '}' or more identifiers".to_string())?;
return bubble_expr!(Destructure, idents);
}
return Ok(self.ident());
}
pub fn block(&mut self) -> ResultExpr {
self.lexer
.collect_if(Token::OBrace)
Expand Down Expand Up @@ -996,12 +1018,12 @@ trait ConvertToResult {
fn xconvert_to_result(self, parser: &Parser, title: String) -> ResultExpr;
}

trait ConvertToSymbolDecl {
fn xconvert_to_sym_decl(self) -> ResultExpr;
trait ConvertToDecl {
fn xconvert_to_decl(self) -> ResultExpr;
}

trait ConvertToSymbolDeclResult {
fn xconvert_to_sym_decl(self) -> ResultExpr;
trait ConvertToDeclResult {
fn xconvert_to_decl(self) -> ResultExpr;
}

trait ConvertToResultOpt {
Expand Down Expand Up @@ -1077,22 +1099,25 @@ impl ExpectExpr for OptExpr {
}
}

impl ConvertToSymbolDeclResult for ResultExpr {
fn xconvert_to_sym_decl(self) -> ResultExpr {
impl ConvertToDeclResult for ResultExpr {
fn xconvert_to_decl(self) -> ResultExpr {
match self {
Err(x) => Err(x),
Ok(val) => match *val {
Expr::Symbol(x) => {
return Ok(Box::new(Expr::SymbolDecl(x)));
}
Expr::Destructure(_) => {
return Ok(val);
}
_ => panic!("type lang issue, expected into symbol"),
},
}
}
}

impl ConvertToSymbolDecl for OptExpr {
fn xconvert_to_sym_decl(self) -> ResultExpr {
impl ConvertToDecl for OptExpr {
fn xconvert_to_decl(self) -> ResultExpr {
match self {
None => panic!("type lang issue, expected a symbol"),
Some(val) => match *val {
Expand Down Expand Up @@ -1310,14 +1335,11 @@ mod tests {
token: Token::Let,
span: 2..5,
},
expr!(
Symbol,
Lexeme {
slice: String::from("x"),
token: Token::Symbol,
span: 6..7
}
),
Box::new(Expr::SymbolDecl(Symbol::new(Lexeme {
slice: String::from("x"),
token: Token::Symbol,
span: 6..7
}))),
None,
expr!(
Number,
Expand Down
Loading
Loading