Skip to content

Commit

Permalink
Syntax 2 (#31)
Browse files Browse the repository at this point in the history
* a little more playing, and syntax feeling better
  • Loading branch information
coffeebe4code authored Dec 10, 2024
1 parent 2c71ff9 commit a40bec7
Show file tree
Hide file tree
Showing 8 changed files with 264 additions and 68 deletions.
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

0 comments on commit a40bec7

Please sign in to comment.