Added support for conditionals to parser
Not to eval yet
This commit is contained in:
parent
9cc9c5977d
commit
2d21de7cc3
2
conditional.schala
Normal file
2
conditional.schala
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
|
||||||
|
if true then 20 else 40 end
|
@ -119,6 +119,7 @@ impl CodeGen for Function {
|
|||||||
|
|
||||||
impl CodeGen for Expression {
|
impl CodeGen for Expression {
|
||||||
fn codegen(&self, data: &mut CompilationData) -> LLVMValueRef {
|
fn codegen(&self, data: &mut CompilationData) -> LLVMValueRef {
|
||||||
|
println!("Running codegen on: {:?}", self);
|
||||||
use self::Expression::*;
|
use self::Expression::*;
|
||||||
|
|
||||||
let int_type = LLVMWrap::Int64TypeInContext(data.context);
|
let int_type = LLVMWrap::Int64TypeInContext(data.context);
|
||||||
|
@ -45,7 +45,7 @@ pub enum Expression {
|
|||||||
Variable(String),
|
Variable(String),
|
||||||
BinExp(String, Box<Expression>, Box<Expression>),
|
BinExp(String, Box<Expression>, Box<Expression>),
|
||||||
Call(String, Vec<Expression>),
|
Call(String, Vec<Expression>),
|
||||||
Conditional(Box<Expression>, Box<Expression>, Option<Box<Expression>>),
|
Conditional(Box<Expression>, Box<Vec<Expression>>, Option<Box<Vec<Expression>>>),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl fmt::Display for ASTNode {
|
impl fmt::Display for ASTNode {
|
||||||
@ -311,13 +311,53 @@ impl Parser {
|
|||||||
self.next();
|
self.next();
|
||||||
Expression::StringLiteral(s)
|
Expression::StringLiteral(s)
|
||||||
}
|
}
|
||||||
|
Some(Keyword(Kw::If)) => try!(self.conditional_expr()),
|
||||||
Some(Identifier(_)) => try!(self.identifier_expr()),
|
Some(Identifier(_)) => try!(self.identifier_expr()),
|
||||||
Some(Token::LParen) => try!(self.paren_expr()),
|
Some(Token::LParen) => try!(self.paren_expr()),
|
||||||
Some(_) => return ParseError::result_from_str("Expected primary expression"),
|
Some(e) => {
|
||||||
|
panic!();
|
||||||
|
return ParseError::result_from_str("Expected primary expression");
|
||||||
|
}
|
||||||
None => return ParseError::result_from_str("Expected primary expression received EoI"),
|
None => return ParseError::result_from_str("Expected primary expression received EoI"),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn conditional_expr(&mut self) -> ParseResult<Expression> {
|
||||||
|
use tokenizer::Token::*;
|
||||||
|
expect!(self, Keyword(Kw::If));
|
||||||
|
let test = try!(self.expression());
|
||||||
|
expect!(self, Keyword(Kw::Then));
|
||||||
|
let mut then_block = Vec::new();
|
||||||
|
loop {
|
||||||
|
match self.peek() {
|
||||||
|
None | Some(Keyword(Kw::Else)) | Some(Keyword(Kw::End)) => break,
|
||||||
|
_ => {
|
||||||
|
let exp = try!(self.expression());
|
||||||
|
then_block.push(exp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
let else_block = if let Some(Keyword(Kw::Else)) = self.peek() {
|
||||||
|
self.next();
|
||||||
|
let mut else_exprs = Vec::new();
|
||||||
|
loop {
|
||||||
|
match self.peek() {
|
||||||
|
None | Some(Keyword(Kw::End)) => break,
|
||||||
|
_ => {
|
||||||
|
let exp = try!(self.expression());
|
||||||
|
else_exprs.push(exp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Some(Box::new(else_exprs))
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
};
|
||||||
|
|
||||||
|
expect!(self, Keyword(Kw::End));
|
||||||
|
Ok(Expression::Conditional(Box::new(test), Box::new(then_block), else_block))
|
||||||
|
}
|
||||||
|
|
||||||
fn identifier_expr(&mut self) -> ParseResult<Expression> {
|
fn identifier_expr(&mut self) -> ParseResult<Expression> {
|
||||||
use tokenizer::Token::*;
|
use tokenizer::Token::*;
|
||||||
let name = expect_identifier!(self);
|
let name = expect_identifier!(self);
|
||||||
|
Loading…
Reference in New Issue
Block a user