1use slang_error::{LineInfo, CompileResult, CompilerError, ErrorCode};
2use crate::token::{Token, Tokentype};
3use crate::parse_error::ParseError;
4use slang_ir::Location;
5use slang_ir::ast::{
6 BinaryExpr, BinaryOperator, BlockExpr, ConditionalExpr, Expression, FunctionCallExpr,
7 FunctionDeclarationStmt, FunctionTypeExpr, IfStatement, LetStatement, LiteralExpr, LiteralValue, Parameter,
8 Statement, TypeDefinitionStmt, UnaryExpr, UnaryOperator,
9};
10use slang_shared::{CompilationContext, SymbolKind};
11use slang_types::{
12 PrimitiveType, TYPE_NAME_F32, TYPE_NAME_F64, TYPE_NAME_FLOAT, TYPE_NAME_I32, TYPE_NAME_I64,
13 TYPE_NAME_INT, TYPE_NAME_U32, TYPE_NAME_U64, TYPE_NAME_UNKNOWN, TypeId,
14};
15
16pub struct Parser<'a> {
18 tokens: &'a [Token],
20 current: usize,
22 line_info: &'a LineInfo<'a>,
24 errors: Vec<CompilerError>,
26 context: &'a mut CompilationContext,
28}
29
30pub fn parse<'a>(
31 tokens: &'a [Token],
32 line_info: &'a LineInfo,
33 context: &'a mut CompilationContext,
34) -> CompileResult<Vec<Statement>> {
35 let mut parser = Parser::new(tokens, line_info, context);
36 parser.parse()
37}
38
39impl<'a> Parser<'a> {
40 fn new(
48 tokens: &'a [Token],
49 line_info: &'a LineInfo,
50 context: &'a mut CompilationContext,
51 ) -> Self {
52 Parser {
53 tokens,
54 current: 0,
55 line_info,
56 errors: Vec::new(),
57 context,
58 }
59 }
60
61 fn parse(&mut self) -> CompileResult<Vec<Statement>> {
67 let mut statements = Vec::new();
68
69 while !self.is_at_end() {
70 match self.statement() {
71 Ok(stmt) => statements.push(stmt),
72 Err(e) => {
73 self.errors.push(e.to_compiler_error(self.line_info));
74 self.synchronize();
75 }
76 }
77 }
78
79 if !self.errors.is_empty() {
80 Err(std::mem::take(&mut self.errors))
81 } else {
82 Ok(statements)
83 }
84 }
85
86 fn error(&self, error_code: ErrorCode, message: &str) -> ParseError {
96 ParseError::new(
97 error_code,
98 message,
99 self.peek().pos,
100 self.peek().lexeme.len(),
101 )
102 }
103
104 fn error_previous(&self, error_code: ErrorCode, message: &str) -> ParseError {
114 ParseError::new(
115 error_code,
116 message,
117 self.previous().pos,
118 self.previous().lexeme.len(),
119 )
120 }
121
122 fn synchronize(&mut self) {
124 self.advance();
125
126 while !self.is_at_end() {
127 if self.previous().token_type == Tokentype::Semicolon {
128 return;
129 }
130
131 match self.peek().token_type {
132 Tokentype::Let | Tokentype::Fn | Tokentype::Struct | Tokentype::Return => {
133 return;
134 }
135 _ => {}
136 }
137
138 self.advance();
139 }
140 }
141 fn statement(&mut self) -> Result<Statement, ParseError> {
147 if self.match_token(&Tokentype::Let) {
148 self.let_statement()
149 } else if self.match_token(&Tokentype::Struct) {
150 self.type_definition_statement()
151 } else if self.match_token(&Tokentype::Fn) {
152 self.function_declaration_statement()
153 } else if self.match_token(&Tokentype::Return) {
154 self.return_statement()
155 } else if self.match_token(&Tokentype::If) {
156 self.if_statement()
157 } else if self.check(&Tokentype::Identifier) && self.check_next(&Tokentype::Equal) {
158 self.assignment_statement()
159 } else {
160 self.expression_statement()
161 }
162 }
163
164 fn return_statement(&mut self) -> Result<Statement, ParseError> {
170 let return_token = self.previous();
172 let token_pos = return_token.pos;
173 let (line, column) = self.line_info.get_line_col(token_pos);
174 let location = slang_ir::location::Location::new(
175 token_pos,
176 line,
177 column,
178 return_token.lexeme.len(),
179 );
180
181 let value = if !self.check(&Tokentype::Semicolon) {
182 Some(self.expression()?)
183 } else {
184 None
185 };
186
187 if !self.match_token(&Tokentype::Semicolon) {
188 return Err(self.error(
189 ErrorCode::ExpectedSemicolon,
190 "Expected ';' after return value",
191 ));
192 }
193
194 Ok(Statement::Return(slang_ir::ast::ReturnStatement {
195 value,
196 location,
197 }))
198 }
199
200 fn function_declaration_statement(&mut self) -> Result<Statement, ParseError> {
206 if !self.check(&Tokentype::Identifier) {
207 return Err(self.error(
208 ErrorCode::ExpectedIdentifier,
209 &format!("Expected function name found {}", self.peek().token_type),
210 ));
211 }
212 let token = self.advance();
213 let token_pos = token.pos;
214 let name = token.lexeme.clone();
215
216 let (line, column) = self.line_info.get_line_col(token_pos);
217 let location =
218 slang_ir::location::Location::new(token_pos, line, column, name.len());
219
220 if !self.match_token(&Tokentype::LeftParen) {
221 return Err(self.error(
222 ErrorCode::ExpectedOpeningParen,
223 &format!(
224 "Expected '(' after function name, found {}",
225 self.peek().token_type
226 ),
227 ));
228 }
229
230 let mut parameters = Vec::new();
231 if !self.check(&Tokentype::RightParen) {
232 parameters.push(self.parameter()?);
233 while self.match_token(&Tokentype::Comma) {
234 if parameters.len() >= 255 {
235 return Err(self.error(
236 ErrorCode::InvalidSyntax,
237 "Cannot have more than 255 parameters",
238 ));
239 }
240 parameters.push(self.parameter()?);
241 }
242 }
243
244 if !self.match_token(&Tokentype::RightParen) {
245 return Err(self.error(
246 ErrorCode::ExpectedClosingParen,
247 &format!(
248 "Expected ')' after parameters found {}",
249 self.peek().token_type
250 ),
251 ));
252 }
253
254 let return_type = if self.match_token(&Tokentype::Arrow) {
255 self.parse_type()?
256 } else {
257 PrimitiveType::Unit.into()
258 };
259
260 if !self.match_token(&Tokentype::LeftBrace) {
261 return Err(self.error(
262 ErrorCode::ExpectedOpeningBrace,
263 "Expected '{' before function body",
264 ));
265 }
266
267 let body = self.parse_block_expression()?;
268
269 Ok(Statement::FunctionDeclaration(FunctionDeclarationStmt {
270 name,
271 parameters,
272 return_type,
273 body,
274 location,
275 }))
276 }
277
278 fn parameter(&mut self) -> Result<Parameter, ParseError> {
284 if !self.check(&Tokentype::Identifier) {
285 return Err(self.error(ErrorCode::ExpectedIdentifier, "Expected parameter name"));
286 }
287
288 let token_pos = self.peek().pos;
289 let token = self.advance();
290 let name = token.lexeme.clone();
291
292 let (line, column) = self.line_info.get_line_col(token_pos);
293 let location = Location::new(token_pos, line, column, name.len());
294
295 if !self.match_token(&Tokentype::Colon) {
296 return Err(self.error(
297 ErrorCode::ExpectedColon,
298 "Expected ':' after parameter name",
299 ));
300 }
301
302 let param_type = self.parse_type()?;
303
304 Ok(Parameter {
305 name,
306 param_type,
307 location,
308 })
309 }
310
311 fn type_definition_statement(&mut self) -> Result<Statement, ParseError> {
317 if !self.check(&Tokentype::Identifier) {
318 return Err(self.error(
319 ErrorCode::ExpectedIdentifier,
320 "Expected struct name after 'struct' keyword",
321 ));
322 }
323
324 let token = self.peek();
325 let location = self.source_location_from_token(token);
326 let name = self.advance().lexeme.clone();
327
328 if !self.match_token(&Tokentype::LeftBrace) {
329 return Err(self.error(
330 ErrorCode::ExpectedOpeningBrace,
331 "Expected '{' after struct name",
332 ));
333 }
334
335 let mut fields = Vec::new();
336
337 while !self.check(&Tokentype::RightBrace) && !self.is_at_end() {
338 if !self.check(&Tokentype::Identifier) {
339 return Err(self.error(ErrorCode::ExpectedIdentifier, "Expected field name"));
340 }
341 let field_name = self.advance().lexeme.clone();
342
343 if !self.match_token(&Tokentype::Colon) {
344 return Err(self.error(ErrorCode::ExpectedColon, "Expected ':' after field name"));
345 }
346
347 let field_type = self.parse_type()?;
348
349 fields.push((field_name, field_type));
350
351 if !self.match_token(&Tokentype::Comma) && !self.check(&Tokentype::RightBrace) {
352 return Err(self.error(ErrorCode::ExpectedComma, "Expected ',' after field or '}'"));
353 }
354 }
355
356 if !self.match_token(&Tokentype::RightBrace) {
357 return Err(self.error(
358 ErrorCode::ExpectedClosingBrace,
359 "Expected '}' after struct fields",
360 ));
361 }
362
363 if !self.match_token(&Tokentype::Semicolon) {
364 return Err(self.error(
365 ErrorCode::ExpectedSemicolon,
366 "Expected ';' after struct definition",
367 ));
368 }
369
370 Ok(Statement::TypeDefinition(TypeDefinitionStmt {
371 name,
372 fields,
373 location,
374 }))
375 }
376
377 fn let_statement(&mut self) -> Result<Statement, ParseError> {
383 let is_mutable = self.match_token(&Tokentype::Mut);
384
385 if !self.check(&Tokentype::Identifier) {
386 return Err(self.error(
387 ErrorCode::ExpectedIdentifier,
388 "Expected identifier after 'let'",
389 ));
390 }
391
392 let token_pos = self.peek().pos;
393 let (line, column) = self.line_info.get_line_col(token_pos);
394
395 let token = self.advance();
396 let name = token.lexeme.clone();
397 let location =
398 slang_ir::location::Location::new(token_pos, line, column, name.len());
399 let mut var_type = PrimitiveType::Unknown .into();
400
401 if self.match_token(&Tokentype::Colon) {
402 var_type = self.parse_type()?;
403 }
404
405 if !self.match_token(&Tokentype::Equal) {
406 return Err(self.error(
407 ErrorCode::ExpectedEquals,
408 "Expected '=' after variable name",
409 ));
410 }
411
412 let expr = self.expression()?;
413
414 if !self.match_token(&Tokentype::Semicolon) {
415 return Err(self.error(
416 ErrorCode::ExpectedSemicolon,
417 "Expected ';' after let statement",
418 ));
419 }
420
421 Ok(Statement::Let(LetStatement {
422 name,
423 is_mutable,
424 value: expr,
425 expr_type: var_type,
426 location,
427 }))
428 }
429
430 fn expression_statement(&mut self) -> Result<Statement, ParseError> {
436 let expr = self.expression()?;
437
438 match &expr {
440 Expression::Block(_) => {
441 }
443 _ => {
444 if !self.match_token(&Tokentype::Semicolon) {
445 return Err(self.error(
446 ErrorCode::ExpectedSemicolon,
447 "Expected ';' after expression",
448 ));
449 }
450 }
451 }
452
453 Ok(Statement::Expression(expr))
454 }
455
456 fn expression(&mut self) -> Result<Expression, ParseError> {
462 self.logical_or()
463 }
464
465 fn logical_or(&mut self) -> Result<Expression, ParseError> {
471 let mut expr = self.logical_and()?;
472
473 while self.match_token(&Tokentype::Or) {
474 let left_location = expr.location();
475 let right = self.logical_and()?;
476 let right_location = right.location();
477 let span_location = left_location.span_to(&right_location);
478
479 expr = Expression::Binary(BinaryExpr {
480 left: Box::new(expr),
481 operator: BinaryOperator::Or,
482 right: Box::new(right),
483 expr_type: PrimitiveType::Bool.into(),
484 location: span_location,
485 });
486 }
487
488 Ok(expr)
489 }
490
491 fn logical_and(&mut self) -> Result<Expression, ParseError> {
497 let mut expr = self.equality()?;
498
499 while self.match_token(&Tokentype::And) {
500 let left_location = expr.location();
501 let right = self.equality()?;
502 let right_location = right.location();
503 let span_location = left_location.span_to(&right_location);
504
505 expr = Expression::Binary(BinaryExpr {
506 left: Box::new(expr),
507 operator: BinaryOperator::And,
508 right: Box::new(right),
509 expr_type: PrimitiveType::Bool.into(),
510 location: span_location,
511 });
512 }
513
514 Ok(expr)
515 }
516
517 fn equality(&mut self) -> Result<Expression, ParseError> {
523 let mut expr = self.comparison()?;
524
525 while self.match_any(&[Tokentype::EqualEqual, Tokentype::NotEqual]) {
526 let left_location = expr.location();
527 let token = self.previous();
528 let operator = match token.token_type {
529 Tokentype::EqualEqual => BinaryOperator::Equal,
530 Tokentype::NotEqual => BinaryOperator::NotEqual,
531 _ => unreachable!(),
532 };
533 let right = self.comparison()?;
534 let right_location = right.location();
535 let span_location = left_location.span_to(&right_location);
536
537 expr = Expression::Binary(BinaryExpr {
538 left: Box::new(expr),
539 operator,
540 right: Box::new(right),
541 expr_type: PrimitiveType::Bool.into(),
542 location: span_location,
543 });
544 }
545
546 Ok(expr)
547 }
548
549 fn comparison(&mut self) -> Result<Expression, ParseError> {
555 let mut expr = self.term()?;
556
557 while self.match_any(&[
558 Tokentype::Greater,
559 Tokentype::GreaterEqual,
560 Tokentype::Less,
561 Tokentype::LessEqual,
562 ]) {
563 let left_location = expr.location();
564 let token = self.previous();
565 let operator = match token.token_type {
566 Tokentype::Greater => BinaryOperator::GreaterThan,
567 Tokentype::GreaterEqual => BinaryOperator::GreaterThanOrEqual,
568 Tokentype::Less => BinaryOperator::LessThan,
569 Tokentype::LessEqual => BinaryOperator::LessThanOrEqual,
570 _ => unreachable!(),
571 };
572 let right = self.term()?;
573 let right_location = right.location();
574 let span_location = left_location.span_to(&right_location);
575
576 expr = Expression::Binary(BinaryExpr {
577 left: Box::new(expr),
578 operator,
579 right: Box::new(right),
580 expr_type: PrimitiveType::Bool.into(),
581 location: span_location,
582 });
583 }
584
585 Ok(expr)
586 }
587
588 fn term(&mut self) -> Result<Expression, ParseError> {
594 let mut expr = self.factor()?;
595
596 while self.match_any(&[Tokentype::Plus, Tokentype::Minus]) {
597 let left_location = expr.location();
598 let token = self.previous();
599 let operator = match token.token_type {
600 Tokentype::Plus => BinaryOperator::Add,
601 Tokentype::Minus => BinaryOperator::Subtract,
602 _ => unreachable!(),
603 };
604 let right = self.factor()?;
605 let right_location = right.location();
606 let span_location = left_location.span_to(&right_location);
607
608 expr = Expression::Binary(BinaryExpr {
609 left: Box::new(expr),
610 operator,
611 right: Box::new(right),
612 expr_type: PrimitiveType::Unknown.into(),
613 location: span_location,
614 });
615 }
616
617 Ok(expr)
618 }
619
620 fn factor(&mut self) -> Result<Expression, ParseError> {
626 let mut expr = self.unary()?;
627
628 while self.match_any(&[Tokentype::Multiply, Tokentype::Divide]) {
629 let left_location = expr.location();
630 let token = self.previous();
631 let operator = match token.token_type {
632 Tokentype::Multiply => BinaryOperator::Multiply,
633 Tokentype::Divide => BinaryOperator::Divide,
634 _ => unreachable!(),
635 };
636 let right = self.unary()?;
637 let right_location = right.location();
638 let span_location = left_location.span_to(&right_location);
639
640 expr = Expression::Binary(BinaryExpr {
641 left: Box::new(expr),
642 operator,
643 right: Box::new(right),
644 expr_type: PrimitiveType::Unknown.into(),
645 location: span_location,
646 });
647 }
648
649 Ok(expr)
650 }
651
652 fn unary(&mut self) -> Result<Expression, ParseError> {
658 if self.match_token(&Tokentype::Minus) {
659 let token = self.previous();
660 let operator_location = self.source_location_from_token(token);
661 let right = self.primary()?;
662 let right_location = right.location();
663 let span_location = operator_location.span_to(&right_location);
664
665 return Ok(Expression::Unary(UnaryExpr {
666 operator: UnaryOperator::Negate,
667 right: Box::new(right),
668 expr_type: PrimitiveType::Unknown.into(),
669 location: span_location,
670 }));
671 }
672
673 if self.match_token(&Tokentype::Not) {
674 let token = self.previous();
675 let operator_location = self.source_location_from_token(token);
676 let right = self.primary()?;
677 let right_location = right.location();
678 let span_location = operator_location.span_to(&right_location);
679
680 return Ok(Expression::Unary(UnaryExpr {
681 operator: UnaryOperator::Not,
682 right: Box::new(right),
683 expr_type: PrimitiveType::Bool.into(),
684 location: span_location,
685 }));
686 }
687
688 self.primary()
689 }
690
691 fn primary(&mut self) -> Result<Expression, ParseError> {
697 if self.match_token(&Tokentype::IntegerLiteral) {
698 return self.parse_integer();
699 }
700
701 if self.match_token(&Tokentype::FloatLiteral) {
702 return self.parse_float();
703 }
704
705 if self.match_token(&Tokentype::StringLiteral) {
706 let token = self.previous();
707 let value = token.lexeme.clone();
708 return Ok(Expression::Literal(LiteralExpr {
709 value: LiteralValue::String(value),
710 expr_type: PrimitiveType::String.into(),
711 location: self.source_location_from_token(token),
712 }));
713 }
714
715 if self.match_token(&Tokentype::BooleanLiteral) {
716 let token = self.previous();
717 let lexeme = token.lexeme.clone();
718 let bool_value = lexeme == "true";
719 return Ok(Expression::Literal(LiteralExpr {
720 value: LiteralValue::Boolean(bool_value),
721 expr_type: PrimitiveType::Bool.into(),
722 location: self.source_location_from_token(token),
723 }));
724 }
725
726 if self.match_token(&Tokentype::If) {
727 return self.conditional_expression();
728 }
729
730 if self.match_token(&Tokentype::Fn) {
731 return self.parse_function_type_expression();
732 }
733
734 if self.match_token(&Tokentype::LeftParen) {
735 if self.check(&Tokentype::RightParen) {
737 let start_pos = self.previous().pos;
738 self.advance(); let end_pos = self.previous().pos + self.previous().lexeme.len();
740 let (line, column) = self.line_info.get_line_col(start_pos);
741 let location = slang_ir::location::Location::new(
742 start_pos,
743 line,
744 column,
745 end_pos - start_pos,
746 );
747 return Ok(Expression::Literal(LiteralExpr {
748 value: LiteralValue::Unit,
749 expr_type: PrimitiveType::Unit.into(),
750 location,
751 }));
752 }
753
754 let expr = self.expression()?;
755 if !self.match_token(&Tokentype::RightParen) {
756 return Err(self.error(
757 ErrorCode::ExpectedClosingParen,
758 "Expected ')' after expression",
759 ));
760 }
761 return Ok(expr);
762 }
763
764 if self.match_token(&Tokentype::LeftBrace) {
765 let blockexpr = self.parse_block_expression()?;
766 return Ok(Expression::Block(blockexpr));
767 }
768
769 if self.match_token(&Tokentype::Identifier) {
770 let name = self.previous().lexeme.clone();
771
772 if self.match_token(&Tokentype::LeftParen) {
773 return self.finish_call(name);
774 }
775
776 let token = self.previous();
777 let location = self.source_location_from_token(token);
778 return Ok(Expression::Variable(slang_ir::ast::VariableExpr {
779 name,
780 location,
781 }));
782 }
783
784 Err(self.error(
785 ErrorCode::ExpectedExpression,
786 &format!("Expected expression, found {}", self.peek()),
787 ))
788 }
789
790 fn parse_float(&mut self) -> Result<Expression, ParseError> {
796 let token = self.previous();
797 let value_str = token.lexeme.clone();
798 let location = self.source_location_from_token(token);
799 let value = value_str.parse::<f64>().map_err(|_| {
800 self.error_previous(
801 ErrorCode::InvalidNumberLiteral,
802 &format!("Invalid float: {}", value_str),
803 )
804 })?;
805
806 if self.check(&Tokentype::Identifier) {
807 let type_name = self.peek().lexeme.clone();
808
809 match type_name.as_str() {
810 TYPE_NAME_F32 => {
811 self.advance();
812 return Ok(Expression::Literal(LiteralExpr {
813 value: LiteralValue::F32(value as f32),
814 expr_type: PrimitiveType::F32.into(),
815 location,
816 }));
817 }
818 TYPE_NAME_F64 => {
819 self.advance();
820 return Ok(Expression::Literal(LiteralExpr {
821 value: LiteralValue::F64(value),
822 expr_type: PrimitiveType::F64.into(),
823 location,
824 }));
825 }
826 _ => {}
827 }
828 }
829
830 Ok(Expression::Literal(LiteralExpr {
831 value: LiteralValue::UnspecifiedFloat(value),
832 expr_type: PrimitiveType::UnspecifiedFloat.into(),
833 location,
834 }))
835 }
836
837 fn finish_call(&mut self, name: String) -> Result<Expression, ParseError> {
847 let name_token = self.previous();
848 let start_location = self.source_location_from_token(name_token);
849
850 let mut arguments = Vec::new();
851
852 if !self.check(&Tokentype::RightParen) {
853 arguments.push(self.expression()?);
854
855 while self.match_token(&Tokentype::Comma) {
856 if arguments.len() >= 255 {
857 return Err(self.error(
858 ErrorCode::InvalidSyntax,
859 "Cannot have more than 255 arguments",
860 ));
861 }
862 arguments.push(self.expression()?);
863 }
864 }
865
866 if !self.match_token(&Tokentype::RightParen) {
867 return Err(self.error(
868 ErrorCode::ExpectedClosingParen,
869 "Expected ')' after function arguments",
870 ));
871 }
872
873 let closing_paren_token = self.previous();
874 let end_location = self.source_location_from_token(closing_paren_token);
875 let span_location = start_location.span_to(&end_location);
876
877 Ok(Expression::Call(FunctionCallExpr {
878 name,
879 arguments,
880 expr_type: PrimitiveType::Unknown.into(),
881 location: span_location,
882 }))
883 }
884
885 fn parse_integer(&mut self) -> Result<Expression, ParseError> {
891 let token = self.previous();
892 let value_str = token.lexeme.clone();
893 let base_value = value_str.parse::<i64>().map_err(|_| {
894 self.error_previous(
895 ErrorCode::InvalidNumberLiteral,
896 &format!("Invalid integer: {}", value_str),
897 )
898 })?;
899 let location = self.source_location_from_token(token);
900
901 if self.check(&Tokentype::Identifier) {
902 let type_name = self.peek().lexeme.clone();
903
904 match type_name.as_str() {
905 TYPE_NAME_I32 => {
906 self.advance();
907 if base_value > i32::MAX as i64 || base_value < i32::MIN as i64 {
908 return Err(self.error_previous(
909 ErrorCode::ValueOutOfRange,
910 &format!("Value {} is out of range for {}", base_value, TYPE_NAME_I32),
911 ));
912 }
913 return Ok(Expression::Literal(LiteralExpr {
914 value: LiteralValue::I32(base_value as i32),
915 expr_type: PrimitiveType::I32.into(),
916 location,
917 }));
918 }
919 TYPE_NAME_I64 => {
920 self.advance();
921 return Ok(Expression::Literal(LiteralExpr {
922 value: LiteralValue::I64(base_value),
923 expr_type: PrimitiveType::I64.into(),
924 location,
925 }));
926 }
927 TYPE_NAME_U32 => {
928 self.advance();
929 if base_value < 0 || base_value > u32::MAX as i64 {
930 return Err(self.error_previous(
931 ErrorCode::ValueOutOfRange,
932 &format!("Value {} is out of range for {}", base_value, TYPE_NAME_U32),
933 ));
934 }
935 return Ok(Expression::Literal(LiteralExpr {
936 value: LiteralValue::U32(base_value as u32),
937 expr_type: PrimitiveType::U32.into(),
938 location,
939 }));
940 }
941 TYPE_NAME_U64 => {
942 self.advance();
943 if base_value < 0 {
944 return Err(self.error_previous(
945 ErrorCode::ValueOutOfRange,
946 &format!("Value {} is out of range for {}", base_value, TYPE_NAME_U64),
947 ));
948 }
949 return Ok(Expression::Literal(LiteralExpr {
950 value: LiteralValue::U64(base_value as u64),
951 expr_type: PrimitiveType::U64.into(),
952 location,
953 }));
954 }
955 TYPE_NAME_F32 => {
956 self.advance();
957 return Ok(Expression::Literal(LiteralExpr {
958 value: LiteralValue::F32(base_value as f32),
959 expr_type: PrimitiveType::F32.into(),
960 location,
961 }));
962 }
963 TYPE_NAME_F64 => {
964 self.advance();
965 return Ok(Expression::Literal(LiteralExpr {
966 value: LiteralValue::F64(base_value as f64),
967 expr_type: PrimitiveType::F64.into(),
968 location,
969 }));
970 }
971 _ => {}
972 }
973 }
974
975 Ok(Expression::Literal(LiteralExpr {
976 value: LiteralValue::UnspecifiedInteger(base_value),
977 expr_type: PrimitiveType::UnspecifiedInt.into(),
978 location,
979 }))
980 }
981
982 fn parse_type(&mut self) -> Result<TypeId, ParseError> {
988 if self.check(&Tokentype::Fn) {
990 self.advance(); if !self.match_token(&Tokentype::LeftParen) {
994 return Err(self.error(
995 ErrorCode::ExpectedOpeningParen,
996 "Expected '(' after 'fn'",
997 ));
998 }
999
1000 let mut param_types = Vec::new();
1002 if !self.check(&Tokentype::RightParen) {
1003 loop {
1004 param_types.push(self.parse_type()?);
1005 if !self.match_token(&Tokentype::Comma) {
1006 break;
1007 }
1008 }
1009 }
1010
1011 if !self.match_token(&Tokentype::RightParen) {
1013 return Err(self.error(
1014 ErrorCode::ExpectedClosingParen,
1015 "Expected ')' after function parameters",
1016 ));
1017 }
1018
1019 if !self.match_token(&Tokentype::Arrow) {
1021 return Err(self.error(
1022 ErrorCode::InvalidSyntax,
1023 "Expected '->' after function parameters",
1024 ));
1025 }
1026
1027 let return_type = self.parse_type()?;
1029
1030 let function_type_id = self.context.register_function_type(param_types, return_type);
1032 return Ok(function_type_id);
1033 }
1034
1035 if self.check(&Tokentype::LeftParen) {
1036 self.advance();
1037 if !self.match_token(&Tokentype::RightParen) {
1038 return Err(self.error(
1039 ErrorCode::ExpectedClosingParen,
1040 "Expected ')' for unit type",
1041 ));
1042 }
1043 return Ok(PrimitiveType::Unit.into());
1044 }
1045
1046 if !self.check(&Tokentype::Identifier) {
1047 return Err(self.error(ErrorCode::ExpectedIdentifier, "Expected type identifier"));
1048 }
1049
1050 let type_name_token = self.advance();
1051 let type_name = type_name_token.lexeme.clone();
1052
1053 if type_name == TYPE_NAME_INT {
1054 return Err(self.error(
1055 ErrorCode::UnknownType,
1056 &format!(
1057 "'{}' is not a valid type specifier. Use '{}', '{}', '{}', or '{}' instead",
1058 TYPE_NAME_INT, TYPE_NAME_I32, TYPE_NAME_I64, TYPE_NAME_U32, TYPE_NAME_U64
1059 ),
1060 ));
1061 } else if type_name == TYPE_NAME_FLOAT {
1062 return Err(self.error(
1063 ErrorCode::UnknownType,
1064 &format!(
1065 "'{}' is not a valid type specifier. Use '{}' or '{}' instead",
1066 TYPE_NAME_FLOAT, TYPE_NAME_F32, TYPE_NAME_F64
1067 ),
1068 ));
1069 } else if type_name == TYPE_NAME_UNKNOWN {
1070 return Err(self.error_previous(
1071 ErrorCode::UnknownType,
1072 &format!("'{}' is not a valid type specifier", TYPE_NAME_UNKNOWN),
1073 ));
1074 }
1075 if let Some(symbol) = self.context.lookup_symbol(&type_name) {
1076 if symbol.kind() == SymbolKind::Type {
1077 Ok(symbol.type_id.clone())
1078 } else {
1079 Err(self.error_previous(
1080 ErrorCode::UnknownType,
1081 &format!("'{}' is not a type name", type_name),
1082 ))
1083 }
1084 } else {
1085 Err(self.error_previous(
1086 ErrorCode::UnknownType,
1087 &format!("Unknown type: {}", type_name),
1088 ))
1089 }
1090 }
1091
1092 fn source_location_from_token(
1094 &self,
1095 token: &Token,
1096 ) -> slang_ir::location::Location {
1097 let (line, column) = self.line_info.get_line_col(token.pos);
1098 slang_ir::location::Location::new(token.pos, line, column, token.lexeme.len())
1099 }
1100
1101 fn match_token(&mut self, token_type: &Tokentype) -> bool {
1111 if self.check(token_type) {
1112 self.advance();
1113 true
1114 } else {
1115 false
1116 }
1117 }
1118
1119 fn match_any(&mut self, types: &[Tokentype]) -> bool {
1129 for token_type in types.iter() {
1130 if self.check(token_type) {
1131 self.advance();
1132 return true;
1133 }
1134 }
1135 false
1136 }
1137
1138 fn check(&self, token_type: &Tokentype) -> bool {
1148 if self.is_at_end() {
1149 return false;
1150 }
1151 self.peek().token_type == *token_type
1152 }
1153
1154 fn check_next(&self, token_type: &Tokentype) -> bool {
1164 if self.current + 1 >= self.tokens.len() {
1165 return false;
1166 }
1167 self.tokens[self.current + 1].token_type == *token_type
1168 }
1169
1170 fn advance(&mut self) -> &Token {
1177 if !self.is_at_end() {
1178 self.current += 1;
1179 }
1180 self.previous()
1181 }
1182
1183 #[inline]
1189 fn is_at_end(&self) -> bool {
1190 self.peek().token_type == Tokentype::Eof
1191 }
1192
1193 #[inline]
1199 fn peek(&self) -> &Token {
1200 &self.tokens[self.current]
1201 }
1202
1203 #[inline]
1209 fn previous(&self) -> &Token {
1210 &self.tokens[self.current - 1]
1211 }
1212
1213 fn assignment_statement(&mut self) -> Result<Statement, ParseError> {
1219 if !self.check(&Tokentype::Identifier) {
1220 return Err(self.error(
1221 ErrorCode::ExpectedIdentifier,
1222 "Expected identifier for assignment",
1223 ));
1224 }
1225
1226 let token_pos = self.peek().pos;
1227 let (line, column) = self.line_info.get_line_col(token_pos);
1228
1229 let token = self.advance();
1230 let name = token.lexeme.clone();
1231 let location =
1232 slang_ir::location::Location::new(token_pos, line, column, name.len());
1233
1234 if !self.match_token(&Tokentype::Equal) {
1235 return Err(self.error(ErrorCode::ExpectedEquals, "Expected '=' for assignment"));
1236 }
1237
1238 let value = self.expression()?;
1239
1240 if !self.match_token(&Tokentype::Semicolon) {
1241 return Err(self.error(
1242 ErrorCode::ExpectedSemicolon,
1243 "Expected ';' after assignment",
1244 ));
1245 }
1246
1247 Ok(Statement::Assignment(slang_ir::ast::AssignmentStatement {
1248 name,
1249 value,
1250 location,
1251 }))
1252 }
1253
1254 fn conditional_expression(&mut self) -> Result<Expression, ParseError> {
1260 let if_token_pos = self.previous().pos;
1261 let (line, column) = self.line_info.get_line_col(if_token_pos);
1262
1263 let condition = self.expression()?;
1264
1265 if !self.match_token(&Tokentype::LeftBrace) {
1266 return Err(self.error(
1267 ErrorCode::ExpectedOpeningBrace,
1268 "Expected '{' after if condition",
1269 ));
1270 }
1271
1272 let then_branch = self.parse_block_expression()?;
1273
1274 if !self.match_token(&Tokentype::Else) {
1275 return Err(self.error(
1276 ErrorCode::ExpectedElse,
1277 "Expected 'else' after if expression",
1278 ));
1279 }
1280
1281 if !self.match_token(&Tokentype::LeftBrace) {
1282 return Err(self.error(ErrorCode::ExpectedOpeningBrace, "Expected '{' after else"));
1283 }
1284
1285 let else_branch = self.parse_block_expression()?;
1286
1287 let end_pos = self.previous().pos + self.previous().lexeme.len();
1288 let location = slang_ir::location::Location::new(
1289 if_token_pos,
1290 line,
1291 column,
1292 end_pos - if_token_pos,
1293 );
1294
1295 Ok(Expression::Conditional(ConditionalExpr {
1296 condition: Box::new(condition),
1297 then_branch: Box::new(Expression::Block(then_branch)),
1298 else_branch: Box::new(Expression::Block(else_branch)),
1299 expr_type: PrimitiveType::Unknown.into(),
1300 location,
1301 }))
1302 }
1303
1304 fn parse_block_expression(&mut self) -> Result<BlockExpr, ParseError> {
1310 let start_pos = self.current;
1311 let (line, column) = self.line_info.get_line_col(self.tokens[start_pos].pos);
1312
1313 let mut statements = Vec::new();
1314 let mut return_expr: Option<Box<Expression>> = None;
1315
1316 while !self.check(&Tokentype::RightBrace) && !self.is_at_end() {
1317 let checkpoint = self.current;
1318
1319 if let Ok(expr) = self.expression() {
1320 if self.check(&Tokentype::RightBrace) {
1321 return_expr = Some(Box::new(expr));
1322 break;
1323 } else if self.match_token(&Tokentype::Semicolon) {
1324 statements.push(Statement::Expression(expr));
1325 } else {
1326 self.current = checkpoint;
1327 statements.push(self.statement()?);
1328 }
1329 } else {
1330 self.current = checkpoint;
1331 statements.push(self.statement()?);
1332 }
1333 }
1334
1335 if !self.match_token(&Tokentype::RightBrace) {
1336 return Err(self.error(ErrorCode::ExpectedClosingBrace, "Expected '}' after block"));
1337 }
1338
1339 let end_pos = self.previous().pos + self.previous().lexeme.len();
1340 let location = slang_ir::location::Location::new(
1341 self.tokens[start_pos].pos,
1342 line,
1343 column,
1344 end_pos - self.tokens[start_pos].pos,
1345 );
1346
1347 Ok(BlockExpr {
1348 statements,
1349 return_expr,
1350 expr_type: PrimitiveType::Unknown.into(),
1351 location,
1352 })
1353 }
1354
1355 fn if_statement(&mut self) -> Result<Statement, ParseError> {
1361 let if_token_pos = self.previous().pos;
1362 let (line, column) = self.line_info.get_line_col(if_token_pos);
1363
1364 let condition = self.expression()?;
1365
1366 if !self.match_token(&Tokentype::LeftBrace) {
1367 return Err(self.error(
1368 ErrorCode::ExpectedOpeningBrace,
1369 "Expected '{' after if condition",
1370 ));
1371 }
1372
1373 let then_branch = self.parse_block_expression()?;
1374
1375 let else_branch = if self.match_token(&Tokentype::Else) {
1376 if !self.match_token(&Tokentype::LeftBrace) {
1377 return Err(self.error(ErrorCode::ExpectedOpeningBrace, "Expected '{' after else"));
1378 }
1379 Some(self.parse_block_expression()?)
1380 } else {
1381 None
1382 };
1383
1384 let end_pos = self.previous().pos + self.previous().lexeme.len();
1385 let location = slang_ir::location::Location::new(
1386 if_token_pos,
1387 line,
1388 column,
1389 end_pos - if_token_pos,
1390 );
1391
1392 Ok(Statement::If(IfStatement {
1393 condition,
1394 then_branch,
1395 else_branch,
1396 location,
1397 }))
1398 }
1399
1400 fn parse_function_type_expression(&mut self) -> Result<Expression, ParseError> {
1406 let fn_token_pos = self.previous().pos;
1408 let (start_line, start_column) = self.line_info.get_line_col(fn_token_pos);
1409
1410 if !self.match_token(&Tokentype::LeftParen) {
1412 return Err(self.error(
1413 ErrorCode::ExpectedOpeningParen,
1414 "Expected '(' after 'fn'",
1415 ));
1416 }
1417
1418 let mut param_types = Vec::new();
1420 if !self.check(&Tokentype::RightParen) {
1421 loop {
1422 param_types.push(self.parse_type()?);
1423 if !self.match_token(&Tokentype::Comma) {
1424 break;
1425 }
1426 }
1427 }
1428
1429 if !self.match_token(&Tokentype::RightParen) {
1430 return Err(self.error(
1431 ErrorCode::ExpectedClosingParen,
1432 "Expected ')' after function parameters",
1433 ));
1434 }
1435
1436 if !self.match_token(&Tokentype::Arrow) {
1437 return Err(self.error(
1438 ErrorCode::InvalidSyntax,
1439 "Expected '->' after function parameters",
1440 ));
1441 }
1442
1443 let return_type = self.parse_type()?;
1444
1445 let end_token_pos = self.previous().pos;
1446 let end_token_lexeme_len = self.previous().lexeme.len();
1447 let end_pos = end_token_pos + end_token_lexeme_len;
1448 let location = slang_ir::location::Location::new(
1449 fn_token_pos,
1450 start_line,
1451 start_column,
1452 end_pos - fn_token_pos,
1453 );
1454
1455 let expr_type = PrimitiveType::Unknown.into();
1457
1458 Ok(Expression::FunctionType(FunctionTypeExpr {
1459 param_types,
1460 return_type,
1461 expr_type,
1462 location,
1463 }))
1464 }
1465}