Add variable declaration parsing
This commit is contained in:
parent
97ae0e5ce6
commit
5d69d05c7b
1 changed files with 28 additions and 2 deletions
|
@ -10,7 +10,7 @@ use crate::compiler::{
|
||||||
|
|
||||||
pub fn parse<'source>(tokens: &[Token<'source>]) -> Expression<'source> {
|
pub fn parse<'source>(tokens: &[Token<'source>]) -> Expression<'source> {
|
||||||
let mut pos = 0;
|
let mut pos = 0;
|
||||||
let result = parse_expression(0, &mut pos, tokens);
|
let result = parse_block_level_expressions(&mut pos, tokens);
|
||||||
|
|
||||||
if pos != tokens.len() {
|
if pos != tokens.len() {
|
||||||
panic!(
|
panic!(
|
||||||
|
@ -22,6 +22,20 @@ pub fn parse<'source>(tokens: &[Token<'source>]) -> Expression<'source> {
|
||||||
result
|
result
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Horrible name, basically used to get the full expressions contained
|
||||||
|
// in blocks or at the top level of the program
|
||||||
|
fn parse_block_level_expressions<'source>(
|
||||||
|
pos: &mut usize,
|
||||||
|
tokens: &[Token<'source>],
|
||||||
|
) -> Expression<'source> {
|
||||||
|
// Special handling for variable declaration, since it is only allowed in very specifc places
|
||||||
|
if peek(pos, tokens).text == "var" {
|
||||||
|
parse_var_declaration(pos, tokens)
|
||||||
|
} else {
|
||||||
|
parse_expression(0, pos, tokens)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn parse_expression<'source>(
|
fn parse_expression<'source>(
|
||||||
level: usize,
|
level: usize,
|
||||||
pos: &mut usize,
|
pos: &mut usize,
|
||||||
|
@ -82,6 +96,7 @@ fn parse_term<'source>(pos: &mut usize, tokens: &[Token<'source>]) -> Expression
|
||||||
TokenType::Identifier => match token.text {
|
TokenType::Identifier => match token.text {
|
||||||
"if" => parse_conditional(pos, tokens),
|
"if" => parse_conditional(pos, tokens),
|
||||||
"true" | "false" => parse_bool_literal(pos, tokens),
|
"true" | "false" => parse_bool_literal(pos, tokens),
|
||||||
|
"var" => panic!("Invalid variable declaration {}", token),
|
||||||
_ => {
|
_ => {
|
||||||
if peek(&mut (*pos + 1), tokens).text == "(" {
|
if peek(&mut (*pos + 1), tokens).text == "(" {
|
||||||
parse_function(pos, tokens)
|
parse_function(pos, tokens)
|
||||||
|
@ -99,6 +114,17 @@ fn parse_term<'source>(pos: &mut usize, tokens: &[Token<'source>]) -> Expression
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn parse_var_declaration<'source>(
|
||||||
|
pos: &mut usize,
|
||||||
|
tokens: &[Token<'source>],
|
||||||
|
) -> Expression<'source> {
|
||||||
|
consume_string(pos, tokens, "var");
|
||||||
|
let name = consume_type(pos, tokens, TokenType::Identifier).text;
|
||||||
|
consume_string(pos, tokens, "=");
|
||||||
|
let value = parse_expression(0, pos, tokens);
|
||||||
|
VarDeclaration(name, Box::new(value))
|
||||||
|
}
|
||||||
|
|
||||||
fn parse_conditional<'source>(pos: &mut usize, tokens: &[Token<'source>]) -> Expression<'source> {
|
fn parse_conditional<'source>(pos: &mut usize, tokens: &[Token<'source>]) -> Expression<'source> {
|
||||||
consume_string(pos, tokens, "if");
|
consume_string(pos, tokens, "if");
|
||||||
let condition = Box::new(parse_expression(0, pos, tokens));
|
let condition = Box::new(parse_expression(0, pos, tokens));
|
||||||
|
@ -128,7 +154,7 @@ fn parse_block<'source>(pos: &mut usize, tokens: &[Token<'source>]) -> Expressio
|
||||||
|
|
||||||
let mut expressions = Vec::new();
|
let mut expressions = Vec::new();
|
||||||
loop {
|
loop {
|
||||||
expressions.push(parse_expression(0, pos, tokens));
|
expressions.push(parse_block_level_expressions(pos, tokens));
|
||||||
|
|
||||||
if peek(pos, tokens).text == "}" {
|
if peek(pos, tokens).text == "}" {
|
||||||
break;
|
break;
|
||||||
|
|
Reference in a new issue