Skip to content

Commit

Permalink
refs #30. Parse #define statements
Browse files Browse the repository at this point in the history
  • Loading branch information
elimirks committed Jan 16, 2022
1 parent 26f9b37 commit 0627c3c
Show file tree
Hide file tree
Showing 3 changed files with 73 additions and 8 deletions.
9 changes: 9 additions & 0 deletions src/ast.rs
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ pub struct RootStatements {
pub functions: Vec<RSFunction>,
pub variables: Vec<RSVariable>,
pub imports: Vec<RSImport>,
pub defines: Vec<RSDefine>,
}

impl RootStatements {
Expand All @@ -56,6 +57,7 @@ impl RootStatements {
functions: vec!(),
variables: vec!(),
imports: vec!(),
defines: vec!(),
}
}
}
Expand All @@ -77,6 +79,13 @@ pub struct RSImport {
pub path: String,
}

pub struct RSDefine {
pub pos: Pos,
pub name: String,
pub args: Vec<String>,
pub body: Expr,
}

#[derive(Debug)]
pub enum Statement {
// Statement representing executing a single expr
Expand Down
67 changes: 59 additions & 8 deletions src/parser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -203,7 +203,7 @@ fn parse_var_entry(c: &mut ParseContext, name: String) -> Result<Var, CompErr> {
}
}

// Expects the @import token to have been parsed
// Expects the #import token to have been parsed
fn parse_import(
c: &mut ParseContext
) -> Result<RSImport, CompErr> {
Expand All @@ -221,10 +221,51 @@ fn parse_import(
}
}

// Parses everything after the name of a function
fn parse_fun(
c: &mut ParseContext, pos: Pos, name: String
) -> Result<RSFunction, CompErr> {
// Expects the #define token to have been parsed
fn parse_define(
c: &mut ParseContext
) -> Result<RSDefine, CompErr> {
let pos = c.pos();
let name = match pop_tok(c)? {
(_, Token::Id(id)) => id,
(pos, tok) => return CompErr::err(&pos, format!(
"ID expected. {:?} given", tok)),
};

// Handles cases with ambiguous parens
let next1 = pop_tok(c)?;
let next2 = pop_tok(c)?;
let should_parse_args = if next1.1 == Token::LParen {
if let (_, Token::Id(_)) = next2 {
true
} else {
next2.1 == Token::RParen
}
} else {
false
};
push_tok(c, next2);
push_tok(c, next1);

let args = if should_parse_args {
parse_args(c)?
} else {
vec!()
};
let body = parse_expr(c)?;
parse_tok(c, Token::Semicolon)?;

Ok(RSDefine {
pos,
name,
args,
body,
})
}

fn parse_args(
c: &mut ParseContext
) -> Result<Vec<String>, CompErr> {
parse_tok(c, Token::LParen)?;

let mut args = Vec::<String>::new();
Expand Down Expand Up @@ -256,10 +297,18 @@ fn parse_fun(
&pos, format!("Unexpected token: {:?}", other)),
}
}

Ok(args)
}

// Parses everything after the name of a function
fn parse_fun(
c: &mut ParseContext, pos: Pos, name: String
) -> Result<RSFunction, CompErr> {
Ok(RSFunction {
pos: pos,
name: name,
args: args,
pos,
name,
args: parse_args(c)?,
body: parse_statement(c)?,
})
}
Expand Down Expand Up @@ -862,6 +911,8 @@ fn parse_content(
},
(_, Token::Import) =>
root_statements.imports.push(parse_import(&mut c)?),
(_, Token::Define) =>
root_statements.defines.push(parse_define(&mut c)?),
(_, Token::Eof) => break,
(pos, tok) => return CompErr::err(&pos, format!(
"Expected id. {:?} found", tok)),
Expand Down
5 changes: 5 additions & 0 deletions src/tokenizer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ pub enum Token {
Char(Vec<char>),
Int(i64),
Import,
Define,
Return,
Auto,
Case,
Expand Down Expand Up @@ -184,6 +185,10 @@ fn get_tok_meta(c: &mut ParseContext) -> Result<(Pos, Token), CompErr> {
c.offset += 1 + next_word.len();
Ok((c.pos(), Token::Import))
},
"define" => {
c.offset += 1 + next_word.len();
Ok((c.pos(), Token::Define))
},
other => {
CompErr::err(&pos, format!("Invalid token: #{}", other))
},
Expand Down

0 comments on commit 0627c3c

Please sign in to comment.