| ... | ... | @@ -26,6 +26,11 @@ pub enum Type { |
| 26 | 26 | |
| 27 | 27 | #[derive(Debug)] |
| 28 | 28 | pub enum Ast { |
| 29 | ConstantDeclaration { |
| 30 | name: String, |
| 31 | typ: Type, |
| 32 | value: Box<Ast> |
| 33 | }, |
| 29 | 34 | VariableDeclaration { |
| 30 | 35 | name: String, |
| 31 | 36 | typ: Type, |
| ... | ... | @@ -49,6 +54,41 @@ fn parse_expression(tokens: &mut dyn PeekableIterator<Item=&Token>) -> Result<As |
| 49 | 54 | /// Precondition: There is at least one token in the iterator |
| 50 | 55 | fn parse_statement(tokens: &mut dyn PeekableIterator<Item=&Token>) -> Result<Ast> { |
| 51 | 56 | match tokens.next().unwrap() { |
| 57 | Token::Let => { |
| 58 | let name = match tokens.next() { |
| 59 | Some(Token::Identifier(name)) => name, |
| 60 | _ => return Err(AstError::new("Expected identifier after var").into()) |
| 61 | }; |
| 62 | let typ = match tokens.next() { |
| 63 | Some(Token::Colon) => { |
| 64 | match tokens.next() { |
| 65 | Some(Token::Identifier(typ)) => { |
| 66 | match typ.as_str() { |
| 67 | "int" => Type::Int, |
| 68 | "float" => Type::Float, |
| 69 | "bigint" => Type::Bigint, |
| 70 | _ => return Err(AstError::new("Expected type after colon").into()) |
| 71 | } |
| 72 | }, |
| 73 | _ => return Err(AstError::new("Expected type after colon").into()) |
| 74 | } |
| 75 | }, |
| 76 | _ => return Err(AstError::new("Expected colon after identifier").into()) |
| 77 | }; |
| 78 | let value = match tokens.next() { |
| 79 | Some(Token::Equals) => parse_expression(tokens)?, |
| 80 | _ => return Err(AstError::new("Expected equals after identifier").into()) |
| 81 | }; |
| 82 | match tokens.next() { |
| 83 | Some(Token::Semicolon) => (), |
| 84 | _ => return Err(AstError::new("Expected semicolon after variable declaration").into()) |
| 85 | }; |
| 86 | Ok(Ast::ConstantDeclaration { |
| 87 | name: name.clone(), |
| 88 | typ, |
| 89 | value: Box::new(value), |
| 90 | }) |
| 91 | }, |
| 52 | 92 | Token::Var => { |
| 53 | 93 | let name = match tokens.next() { |
| 54 | 94 | Some(Token::Identifier(name)) => name, |