Handling type annotations in the AST

This commit is contained in:
greg 2017-09-27 22:27:50 -07:00
parent 4c81c36d67
commit 9ad506fc78
1 changed files with 43 additions and 25 deletions

View File

@ -420,7 +420,13 @@ pub enum Variant {
} }
#[derive(Debug, PartialEq)] #[derive(Debug, PartialEq)]
pub enum Expression { pub struct Expression(ExpressionType, Option<TypeAnno>);
#[derive(Debug, PartialEq)]
pub struct TypeAnno(Rc<String>);
#[derive(Debug, PartialEq)]
pub enum ExpressionType {
IntLiteral(u64), IntLiteral(u64),
FloatLiteral(f64), FloatLiteral(f64),
StringLiteral(Rc<String>), StringLiteral(Rc<String>),
@ -566,7 +572,7 @@ impl Parser {
}); });
parse_method!(expression(&mut self) -> ParseResult<Expression> { parse_method!(expression(&mut self) -> ParseResult<Expression> {
let expr_body = self.precedence_expr(Operation::min_precedence()); let mut expr_body = self.precedence_expr(Operation::min_precedence())?;
let type_anno = match self.peek() { let type_anno = match self.peek() {
Colon => { Colon => {
self.next(); self.next();
@ -574,10 +580,14 @@ impl Parser {
}, },
_ => None _ => None
}; };
expr_body if let Some(a) = expr_body.1 {
panic!("UNexpected thing {:?}", a);
}
expr_body.1 = type_anno;
Ok(expr_body)
}); });
parse_method!(type_anno(&mut self) -> ParseResult<()> { parse_method!(type_anno(&mut self) -> ParseResult<TypeAnno> {
let type_name = self.identifier()?; let type_name = self.identifier()?;
let param = match self.peek() { let param = match self.peek() {
LAngleBracket => { LAngleBracket => {
@ -588,13 +598,11 @@ impl Parser {
}, },
_ => None _ => None
}; };
Ok(()) Ok(TypeAnno(type_name))
}); });
// this implements Pratt parsing, see http://journal.stuffwithstuff.com/2011/03/19/pratt-parsers-expression-parsing-made-easy/ // this implements Pratt parsing, see http://journal.stuffwithstuff.com/2011/03/19/pratt-parsers-expression-parsing-made-easy/
fn precedence_expr(&mut self, precedence: i32) -> ParseResult<Expression> { fn precedence_expr(&mut self, precedence: i32) -> ParseResult<Expression> {
use self::Expression::*;
let next_token = self.peek(); let next_token = self.peek();
let record = ParseRecord { let record = ParseRecord {
production_name: "precedence_expr".to_string(), production_name: "precedence_expr".to_string(),
@ -620,7 +628,7 @@ impl Parser {
}; };
let rhs = self.precedence_expr(new_precedence)?; let rhs = self.precedence_expr(new_precedence)?;
let operation = Operation(op_str); let operation = Operation(op_str);
lhs = BinExp(operation, Box::new(lhs), Box::new(rhs)); lhs = Expression(ExpressionType::BinExp(operation, Box::new(lhs), Box::new(rhs)), None);
} }
Ok(lhs) Ok(lhs)
} }
@ -633,7 +641,9 @@ impl Parser {
_ => unreachable!(), _ => unreachable!(),
}; };
let expr = self.primary()?; let expr = self.primary()?;
Ok(Expression::PrefixExp(Operation(op_str), Box::new(expr))) Ok(Expression(
ExpressionType::PrefixExp(Operation(op_str), Box::new(expr)),
None))
}, },
_ => self.primary() _ => self.primary()
} }
@ -657,23 +667,24 @@ impl Parser {
}); });
parse_method!(identifier_expr(&mut self) -> ParseResult<Expression> { parse_method!(identifier_expr(&mut self) -> ParseResult<Expression> {
use self::ExpressionType::*;
let identifier = self.identifier()?; let identifier = self.identifier()?;
match self.peek() { match self.peek() {
LParen => { LParen => {
let call_params = self.call_expr()?; let call_params = self.call_expr()?;
Ok(Expression::Call { Ok(Expression(Call {
name: identifier, name: identifier,
params: call_params, params: call_params,
}) }, None))
}, },
LSquareBracket => { LSquareBracket => {
let indexers = self.index_expr()?; let indexers = self.index_expr()?;
Ok(Expression::Index { Ok(Expression(Index {
indexee: Box::new(Expression::Variable(identifier)), indexee: Box::new(Expression(Variable(identifier), None)),
indexers: indexers, indexers: indexers,
}) }, None))
} }
_ => Ok(Expression::Variable(identifier)) _ => Ok(Expression(Variable(identifier), None))
} }
}); });
@ -716,7 +727,7 @@ impl Parser {
let condition = self.expression()?; let condition = self.expression()?;
let then_clause = self.block()?; let then_clause = self.block()?;
let else_clause = self.else_clause()?; let else_clause = self.else_clause()?;
Ok(Expression::IfExpression(Box::new(condition), then_clause, else_clause)) Ok(Expression(ExpressionType::IfExpression(Box::new(condition), then_clause, else_clause), None))
}); });
parse_method!(else_clause(&mut self) -> ParseResult<Option<Vec<Statement>>> { parse_method!(else_clause(&mut self) -> ParseResult<Option<Vec<Statement>>> {
@ -751,7 +762,7 @@ impl Parser {
expect!(self, LCurlyBrace, "Expected '{'"); expect!(self, LCurlyBrace, "Expected '{'");
let body = self.match_body()?; let body = self.match_body()?;
expect!(self, RCurlyBrace, "Expected '}'"); expect!(self, RCurlyBrace, "Expected '}'");
Ok(Expression::MatchExpression(Box::new(expr), body)) Ok(Expression(ExpressionType::MatchExpression(Box::new(expr), body), None))
}); });
parse_method!(match_body(&mut self) -> ParseResult<Vec<MatchArm>> { parse_method!(match_body(&mut self) -> ParseResult<Vec<MatchArm>> {
@ -785,13 +796,20 @@ impl Parser {
}); });
parse_method!(literal(&mut self) -> ParseResult<Expression> { parse_method!(literal(&mut self) -> ParseResult<Expression> {
use self::ExpressionType::*;
match self.peek() { match self.peek() {
DigitGroup(_) | HexNumberSigil | BinNumberSigil | Period => self.number_literal(), DigitGroup(_) | HexNumberSigil | BinNumberSigil | Period => self.number_literal(),
Keyword(Kw::True) => { self.next(); Ok(Expression::BoolLiteral(true)) }, Keyword(Kw::True) => {
Keyword(Kw::False) => { self.next(); Ok(Expression::BoolLiteral(false)) }, self.next();
Ok(Expression(BoolLiteral(true), None))
},
Keyword(Kw::False) => {
self.next();
Ok(Expression(BoolLiteral(false), None))
},
StrLiteral(s) => { StrLiteral(s) => {
self.next(); self.next();
Ok(Expression::StringLiteral(s)) Ok(Expression(StringLiteral(s), None))
} }
e => ParseError::new(&format!("Expected a literal expression, got {:?}", e)), e => ParseError::new(&format!("Expected a literal expression, got {:?}", e)),
} }
@ -805,12 +823,12 @@ impl Parser {
}); });
parse_method!(int_literal(&mut self) -> ParseResult<Expression> { parse_method!(int_literal(&mut self) -> ParseResult<Expression> {
use self::Expression::*; use self::ExpressionType::*;
match self.next() { match self.next() {
BinNumberSigil => { BinNumberSigil => {
let digits = self.digits()?; let digits = self.digits()?;
let n = parse_binary(digits)?; let n = parse_binary(digits)?;
Ok(IntLiteral(n)) Ok(Expression(IntLiteral(n), None))
}, },
HexNumberSigil => { HexNumberSigil => {
ParseError::new("Not implemented") ParseError::new("Not implemented")
@ -820,20 +838,20 @@ impl Parser {
}); });
parse_method!(float_literal(&mut self) -> ParseResult<Expression> { parse_method!(float_literal(&mut self) -> ParseResult<Expression> {
use self::Expression::*; use self::ExpressionType::*;
let mut digits = self.digits()?; let mut digits = self.digits()?;
if let TokenType::Period = self.peek() { if let TokenType::Period = self.peek() {
self.next(); self.next();
digits.push_str("."); digits.push_str(".");
digits.push_str(&self.digits()?); digits.push_str(&self.digits()?);
match digits.parse::<f64>() { match digits.parse::<f64>() {
Ok(f) => Ok(FloatLiteral(f)), Ok(f) => Ok(Expression(FloatLiteral(f), None)),
Err(e) => ParseError::new(&format!("Float failed to parse with error: {}", e)), Err(e) => ParseError::new(&format!("Float failed to parse with error: {}", e)),
} }
} else { } else {
match digits.parse::<u64>() { match digits.parse::<u64>() {
Ok(d) => Ok(IntLiteral(d)), Ok(d) => Ok(Expression(IntLiteral(d), None)),
Err(e) => ParseError::new(&format!("Integer failed to parse with error: {}", e)), Err(e) => ParseError::new(&format!("Integer failed to parse with error: {}", e)),
} }
} }