1use crate::ast::*;
2use crate::error::{CompileError, CompileResult, Span};
3use crate::lexer::{SpannedToken, Token};
4
5pub struct Parser {
6 tokens: Vec<SpannedToken>,
7 pos: usize,
8}
9
10impl Parser {
11 pub fn new(tokens: Vec<SpannedToken>) -> Self {
12 Self { tokens, pos: 0 }
13 }
14
15 fn span(&self) -> Span {
16 self.tokens
17 .get(self.pos)
18 .map(|t| t.span.clone())
19 .unwrap_or(Span {
20 offset: 0,
21 line: 0,
22 column: 0,
23 })
24 }
25
26 fn peek(&self) -> &Token {
27 self.tokens
28 .get(self.pos)
29 .map(|t| &t.token)
30 .unwrap_or(&Token::Eof)
31 }
32
33 fn advance(&mut self) -> &Token {
34 let t = &self.tokens[self.pos].token;
35 if self.pos < self.tokens.len() - 1 {
36 self.pos += 1;
37 }
38 t
39 }
40
41 fn expect(&mut self, expected: &Token) -> CompileResult<()> {
42 if self.peek() == expected {
43 self.advance();
44 Ok(())
45 } else {
46 Err(CompileError::syntax(
47 self.span(),
48 format!("expected {:?}, got {:?}", expected, self.peek()),
49 ))
50 }
51 }
52
53 fn expect_ident(&mut self) -> CompileResult<String> {
54 match self.peek().clone() {
55 Token::Ident(name) => {
56 let name = name.clone();
57 self.advance();
58 Ok(name)
59 }
60 _ => Err(CompileError::syntax(
61 self.span(),
62 format!("expected identifier, got {:?}", self.peek()),
63 )),
64 }
65 }
66
67 fn expect_string(&mut self) -> CompileResult<String> {
68 match self.peek().clone() {
69 Token::StringLit(s) => {
70 let s = s.clone();
71 self.advance();
72 Ok(s)
73 }
74 _ => Err(CompileError::syntax(
75 self.span(),
76 format!("expected string literal, got {:?}", self.peek()),
77 )),
78 }
79 }
80
81 pub fn parse_program(&mut self) -> CompileResult<Program> {
84 let span = self.span();
85 self.expect(&Token::Program)?;
86 let name = self.expect_ident()?;
87
88 if self.peek() == &Token::Semi {
90 self.advance();
91 }
92
93 let mut options = Vec::new();
94 let mut definitions = Vec::new();
95 let mut entry = None;
96 let mut state_sets = Vec::new();
97 let mut exit = None;
98
99 loop {
100 match self.peek() {
101 Token::Eof => break,
102 Token::Option_ => {
103 let opt = self.parse_option()?;
104 options.push(opt.clone());
105 definitions.push(Definition::Option(opt));
106 }
107 Token::Int | Token::Short | Token::Long | Token::Float | Token::Double
108 | Token::String_ | Token::Char | Token::Unsigned => {
109 definitions.push(Definition::VarDecl(self.parse_var_decl()?));
110 }
111 Token::Assign => {
112 definitions.push(Definition::Assign(self.parse_assign()?));
113 }
114 Token::Monitor => {
115 definitions.push(Definition::Monitor(self.parse_monitor()?));
116 }
117 Token::Sync => {
118 definitions.push(Definition::Sync(self.parse_sync()?));
119 }
120 Token::EvFlag => {
121 definitions.push(Definition::EvFlag(self.parse_evflag()?));
122 }
123 Token::Entry => {
124 self.advance();
125 entry = Some(self.parse_block()?);
126 }
127 Token::Exit => {
128 self.advance();
129 exit = Some(self.parse_block()?);
130 }
131 Token::Ss => {
132 state_sets.push(self.parse_state_set()?);
133 }
134 Token::EmbeddedLine(_) => {
135 if let Token::EmbeddedLine(code) = self.peek().clone() {
136 let code = code.clone();
137 self.advance();
138 definitions.push(Definition::EmbeddedCode(code));
139 }
140 }
141 _ => {
142 return Err(CompileError::syntax(
143 self.span(),
144 format!("unexpected token at top level: {:?}", self.peek()),
145 ));
146 }
147 }
148 }
149
150 Ok(Program {
151 name,
152 options,
153 definitions,
154 entry,
155 state_sets,
156 exit,
157 span,
158 })
159 }
160
161 fn parse_option(&mut self) -> CompileResult<ProgramOption> {
162 self.expect(&Token::Option_)?;
163 self.expect(&Token::Plus)?;
164
165 let ident = self.expect_ident()?;
166 self.expect(&Token::Semi)?;
167
168 match ident.as_str() {
169 "s" => Ok(ProgramOption::Safe),
170 "r" => Ok(ProgramOption::Reentrant),
171 "m" => Ok(ProgramOption::Main),
172 _ => Err(CompileError::syntax(
173 self.span(),
174 format!("unknown option: +{ident}"),
175 )),
176 }
177 }
178
179 fn parse_type_spec(&mut self) -> CompileResult<TypeSpec> {
180 let ts = match self.peek() {
181 Token::Int => { self.advance(); TypeSpec::Int }
182 Token::Short => { self.advance(); TypeSpec::Short }
183 Token::Long => { self.advance(); TypeSpec::Long }
184 Token::Float => { self.advance(); TypeSpec::Float }
185 Token::Double => { self.advance(); TypeSpec::Double }
186 Token::String_ => { self.advance(); TypeSpec::String }
187 Token::Char => { self.advance(); TypeSpec::Char }
188 Token::Unsigned => {
189 self.advance();
190 let inner = if matches!(
191 self.peek(),
192 Token::Int | Token::Short | Token::Long | Token::Char
193 ) {
194 self.parse_type_spec()?
195 } else {
196 TypeSpec::Int
197 };
198 TypeSpec::Unsigned(Box::new(inner))
199 }
200 _ => {
201 return Err(CompileError::syntax(
202 self.span(),
203 format!("expected type, got {:?}", self.peek()),
204 ));
205 }
206 };
207 Ok(ts)
208 }
209
210 fn parse_var_decl(&mut self) -> CompileResult<VarDecl> {
211 let span = self.span();
212 let type_spec = self.parse_type_spec()?;
213 let name = self.expect_ident()?;
214
215 let mut dimensions = Vec::new();
217 while self.peek() == &Token::LBracket {
218 self.advance();
219 let dim = self.parse_expr()?;
220 self.expect(&Token::RBracket)?;
221 dimensions.push(dim);
222 }
223
224 let init = if self.peek() == &Token::Assign_ {
225 self.advance();
226 if self.peek() == &Token::LBrace {
227 Some(self.parse_brace_init()?)
229 } else {
230 Some(self.parse_expr()?)
231 }
232 } else {
233 None
234 };
235
236 self.expect(&Token::Semi)?;
237
238 Ok(VarDecl {
239 type_spec,
240 name,
241 dimensions,
242 init,
243 span,
244 })
245 }
246
247 fn parse_brace_init(&mut self) -> CompileResult<Expr> {
248 let span = self.span();
249 self.expect(&Token::LBrace)?;
250 let mut elements = Vec::new();
251 if self.peek() != &Token::RBrace {
252 elements.push(self.parse_expr()?);
253 while self.peek() == &Token::Comma {
254 self.advance();
255 if self.peek() == &Token::RBrace {
256 break; }
258 elements.push(self.parse_expr()?);
259 }
260 }
261 self.expect(&Token::RBrace)?;
262 Ok(Expr::ArrayInit(elements, span))
263 }
264
265 fn parse_assign(&mut self) -> CompileResult<Assign> {
266 let span = self.span();
267 self.expect(&Token::Assign)?;
268 let var_name = self.expect_ident()?;
269
270 let pv_name = if self.peek() == &Token::To {
271 self.advance();
272 Some(self.expect_string()?)
273 } else {
274 None
276 };
277
278 self.expect(&Token::Semi)?;
279 Ok(Assign {
280 var_name,
281 pv_name,
282 span,
283 })
284 }
285
286 fn parse_monitor(&mut self) -> CompileResult<Monitor> {
287 let span = self.span();
288 self.expect(&Token::Monitor)?;
289 let var_name = self.expect_ident()?;
290 self.expect(&Token::Semi)?;
291 Ok(Monitor { var_name, span })
292 }
293
294 fn parse_sync(&mut self) -> CompileResult<Sync> {
295 let span = self.span();
296 self.expect(&Token::Sync)?;
297 let var_name = self.expect_ident()?;
298
299 if self.peek() == &Token::To {
301 self.advance();
302 }
303
304 let ef_name = self.expect_ident()?;
305 self.expect(&Token::Semi)?;
306 Ok(Sync {
307 var_name,
308 ef_name,
309 span,
310 })
311 }
312
313 fn parse_evflag(&mut self) -> CompileResult<EvFlagDecl> {
314 let span = self.span();
315 self.expect(&Token::EvFlag)?;
316 let name = self.expect_ident()?;
317 self.expect(&Token::Semi)?;
318 Ok(EvFlagDecl { name, span })
319 }
320
321 fn parse_state_set(&mut self) -> CompileResult<StateSet> {
324 let span = self.span();
325 self.expect(&Token::Ss)?;
326 let name = self.expect_ident()?;
327 self.expect(&Token::LBrace)?;
328
329 let mut local_vars = Vec::new();
330 let mut states = Vec::new();
331
332 loop {
333 match self.peek() {
334 Token::RBrace => {
335 self.advance();
336 break;
337 }
338 Token::State => {
339 states.push(self.parse_state()?);
340 }
341 Token::Int | Token::Short | Token::Long | Token::Float | Token::Double
342 | Token::String_ | Token::Char | Token::Unsigned => {
343 local_vars.push(self.parse_var_decl()?);
344 }
345 _ => {
346 return Err(CompileError::syntax(
347 self.span(),
348 format!("expected state or variable in ss, got {:?}", self.peek()),
349 ));
350 }
351 }
352 }
353
354 Ok(StateSet {
355 name,
356 local_vars,
357 states,
358 span,
359 })
360 }
361
362 fn parse_state(&mut self) -> CompileResult<State> {
363 let span = self.span();
364 self.expect(&Token::State)?;
365 let name = self.expect_ident()?;
366 self.expect(&Token::LBrace)?;
367
368 let mut entry_block = None;
369 let mut transitions = Vec::new();
370 let mut exit_block = None;
371
372 loop {
373 match self.peek() {
374 Token::RBrace => {
375 self.advance();
376 break;
377 }
378 Token::Entry => {
379 self.advance();
380 entry_block = Some(self.parse_block()?);
381 }
382 Token::Exit => {
383 self.advance();
384 exit_block = Some(self.parse_block()?);
385 }
386 Token::When => {
387 transitions.push(self.parse_transition()?);
388 }
389 _ => {
390 return Err(CompileError::syntax(
391 self.span(),
392 format!("expected when/entry/exit in state, got {:?}", self.peek()),
393 ));
394 }
395 }
396 }
397
398 Ok(State {
399 name,
400 entry: entry_block,
401 transitions,
402 exit: exit_block,
403 span,
404 })
405 }
406
407 fn parse_transition(&mut self) -> CompileResult<Transition> {
408 let span = self.span();
409 self.expect(&Token::When)?;
410 self.expect(&Token::LParen)?;
411
412 let condition = if self.peek() == &Token::RParen {
413 None } else {
415 Some(self.parse_expr()?)
416 };
417
418 self.expect(&Token::RParen)?;
419
420 let body = self.parse_block()?;
421
422 let target = match self.peek() {
424 Token::State => {
425 self.advance();
426 let target_name = self.expect_ident()?;
427 TransitionTarget::State(target_name)
428 }
429 Token::Exit => {
430 self.advance();
431 TransitionTarget::Exit
432 }
433 _ => {
434 return Err(CompileError::syntax(
435 self.span(),
436 format!("expected 'state' or 'exit' after when block, got {:?}", self.peek()),
437 ));
438 }
439 };
440
441 Ok(Transition {
442 condition,
443 body,
444 target,
445 span,
446 })
447 }
448
449 fn parse_block(&mut self) -> CompileResult<Block> {
452 let span = self.span();
453 self.expect(&Token::LBrace)?;
454 let mut stmts = Vec::new();
455
456 loop {
457 if self.peek() == &Token::RBrace {
458 self.advance();
459 break;
460 }
461 stmts.push(self.parse_stmt()?);
462 }
463
464 Ok(Block { stmts, span })
465 }
466
467 fn parse_stmt(&mut self) -> CompileResult<Stmt> {
468 match self.peek() {
469 Token::If => self.parse_if(),
470 Token::While => self.parse_while(),
471 Token::For => self.parse_for(),
472 Token::Break => {
473 self.advance();
474 self.expect(&Token::Semi)?;
475 Ok(Stmt::Break)
476 }
477 Token::Return => {
478 self.advance();
479 let val = if self.peek() != &Token::Semi {
480 Some(self.parse_expr()?)
481 } else {
482 None
483 };
484 self.expect(&Token::Semi)?;
485 Ok(Stmt::Return(val))
486 }
487 Token::LBrace => Ok(Stmt::Block(self.parse_block()?)),
488 Token::Int | Token::Short | Token::Long | Token::Float | Token::Double
489 | Token::String_ | Token::Char | Token::Unsigned => {
490 Ok(Stmt::VarDecl(self.parse_var_decl()?))
491 }
492 Token::EmbeddedLine(_) => {
493 if let Token::EmbeddedLine(code) = self.peek().clone() {
494 let code = code.clone();
495 self.advance();
496 Ok(Stmt::EmbeddedCode(code))
497 } else {
498 unreachable!()
499 }
500 }
501 _ => {
502 let expr = self.parse_expr()?;
503 self.expect(&Token::Semi)?;
504 Ok(Stmt::Expr(expr))
505 }
506 }
507 }
508
509 fn parse_if(&mut self) -> CompileResult<Stmt> {
510 self.expect(&Token::If)?;
511 self.expect(&Token::LParen)?;
512 let cond = self.parse_expr()?;
513 self.expect(&Token::RParen)?;
514
515 let then_block = if self.peek() == &Token::LBrace {
516 self.parse_block()?
517 } else {
518 let span = self.span();
519 let stmt = self.parse_stmt()?;
520 Block {
521 stmts: vec![stmt],
522 span,
523 }
524 };
525
526 let else_block = if self.peek() == &Token::Else {
527 self.advance();
528 if self.peek() == &Token::LBrace {
529 Some(self.parse_block()?)
530 } else {
531 let span = self.span();
532 let stmt = self.parse_stmt()?;
533 Some(Block {
534 stmts: vec![stmt],
535 span,
536 })
537 }
538 } else {
539 None
540 };
541
542 Ok(Stmt::If(cond, then_block, else_block))
543 }
544
545 fn parse_while(&mut self) -> CompileResult<Stmt> {
546 self.expect(&Token::While)?;
547 self.expect(&Token::LParen)?;
548 let cond = self.parse_expr()?;
549 self.expect(&Token::RParen)?;
550 let body = if self.peek() == &Token::LBrace {
551 self.parse_block()?
552 } else {
553 let span = self.span();
554 let stmt = self.parse_stmt()?;
555 Block {
556 stmts: vec![stmt],
557 span,
558 }
559 };
560 Ok(Stmt::While(cond, body))
561 }
562
563 fn parse_for(&mut self) -> CompileResult<Stmt> {
564 self.expect(&Token::For)?;
565 self.expect(&Token::LParen)?;
566 let init = if self.peek() == &Token::Semi {
567 None
568 } else {
569 Some(Box::new(self.parse_expr()?))
570 };
571 self.expect(&Token::Semi)?;
572 let cond = if self.peek() == &Token::Semi {
573 None
574 } else {
575 Some(self.parse_expr()?)
576 };
577 self.expect(&Token::Semi)?;
578 let step = if self.peek() == &Token::RParen {
579 None
580 } else {
581 Some(Box::new(self.parse_expr()?))
582 };
583 self.expect(&Token::RParen)?;
584 let body = if self.peek() == &Token::LBrace {
585 self.parse_block()?
586 } else {
587 let span = self.span();
588 let stmt = self.parse_stmt()?;
589 Block {
590 stmts: vec![stmt],
591 span,
592 }
593 };
594 Ok(Stmt::For(init, cond, step, body))
595 }
596
597 fn parse_expr(&mut self) -> CompileResult<Expr> {
600 self.parse_assignment()
601 }
602
603 fn parse_assignment(&mut self) -> CompileResult<Expr> {
604 let lhs = self.parse_ternary()?;
605
606 match self.peek() {
607 Token::Assign_ => {
608 let span = self.span();
609 self.advance();
610 let rhs = self.parse_assignment()?;
611 Ok(Expr::Assign(Box::new(lhs), Box::new(rhs), span))
612 }
613 Token::PlusEq => {
614 let span = self.span();
615 self.advance();
616 let rhs = self.parse_assignment()?;
617 Ok(Expr::CompoundAssign(
618 Box::new(lhs),
619 BinOp::Add,
620 Box::new(rhs),
621 span,
622 ))
623 }
624 Token::MinusEq => {
625 let span = self.span();
626 self.advance();
627 let rhs = self.parse_assignment()?;
628 Ok(Expr::CompoundAssign(
629 Box::new(lhs),
630 BinOp::Sub,
631 Box::new(rhs),
632 span,
633 ))
634 }
635 Token::StarEq => {
636 let span = self.span();
637 self.advance();
638 let rhs = self.parse_assignment()?;
639 Ok(Expr::CompoundAssign(
640 Box::new(lhs),
641 BinOp::Mul,
642 Box::new(rhs),
643 span,
644 ))
645 }
646 Token::SlashEq => {
647 let span = self.span();
648 self.advance();
649 let rhs = self.parse_assignment()?;
650 Ok(Expr::CompoundAssign(
651 Box::new(lhs),
652 BinOp::Div,
653 Box::new(rhs),
654 span,
655 ))
656 }
657 _ => Ok(lhs),
658 }
659 }
660
661 fn parse_ternary(&mut self) -> CompileResult<Expr> {
662 let cond = self.parse_or()?;
663 if self.peek() == &Token::Question {
664 let span = self.span();
665 self.advance();
666 let then_expr = self.parse_expr()?;
667 self.expect(&Token::Colon)?;
668 let else_expr = self.parse_ternary()?;
669 Ok(Expr::Ternary(
670 Box::new(cond),
671 Box::new(then_expr),
672 Box::new(else_expr),
673 span,
674 ))
675 } else {
676 Ok(cond)
677 }
678 }
679
680 fn parse_or(&mut self) -> CompileResult<Expr> {
681 let mut lhs = self.parse_and()?;
682 while self.peek() == &Token::Or {
683 let span = self.span();
684 self.advance();
685 let rhs = self.parse_and()?;
686 lhs = Expr::BinaryOp(Box::new(lhs), BinOp::Or, Box::new(rhs), span);
687 }
688 Ok(lhs)
689 }
690
691 fn parse_and(&mut self) -> CompileResult<Expr> {
692 let mut lhs = self.parse_bitor()?;
693 while self.peek() == &Token::And {
694 let span = self.span();
695 self.advance();
696 let rhs = self.parse_bitor()?;
697 lhs = Expr::BinaryOp(Box::new(lhs), BinOp::And, Box::new(rhs), span);
698 }
699 Ok(lhs)
700 }
701
702 fn parse_bitor(&mut self) -> CompileResult<Expr> {
703 let mut lhs = self.parse_bitxor()?;
704 while self.peek() == &Token::BitOr {
705 let span = self.span();
706 self.advance();
707 let rhs = self.parse_bitxor()?;
708 lhs = Expr::BinaryOp(Box::new(lhs), BinOp::BitOr, Box::new(rhs), span);
709 }
710 Ok(lhs)
711 }
712
713 fn parse_bitxor(&mut self) -> CompileResult<Expr> {
714 let mut lhs = self.parse_bitand()?;
715 while self.peek() == &Token::BitXor {
716 let span = self.span();
717 self.advance();
718 let rhs = self.parse_bitand()?;
719 lhs = Expr::BinaryOp(Box::new(lhs), BinOp::BitXor, Box::new(rhs), span);
720 }
721 Ok(lhs)
722 }
723
724 fn parse_bitand(&mut self) -> CompileResult<Expr> {
725 let mut lhs = self.parse_equality()?;
726 while self.peek() == &Token::BitAnd {
727 let span = self.span();
728 self.advance();
729 let rhs = self.parse_equality()?;
730 lhs = Expr::BinaryOp(Box::new(lhs), BinOp::BitAnd, Box::new(rhs), span);
731 }
732 Ok(lhs)
733 }
734
735 fn parse_equality(&mut self) -> CompileResult<Expr> {
736 let mut lhs = self.parse_comparison()?;
737 loop {
738 let op = match self.peek() {
739 Token::Eq => BinOp::Eq,
740 Token::Ne => BinOp::Ne,
741 _ => break,
742 };
743 let span = self.span();
744 self.advance();
745 let rhs = self.parse_comparison()?;
746 lhs = Expr::BinaryOp(Box::new(lhs), op, Box::new(rhs), span);
747 }
748 Ok(lhs)
749 }
750
751 fn parse_comparison(&mut self) -> CompileResult<Expr> {
752 let mut lhs = self.parse_shift()?;
753 loop {
754 let op = match self.peek() {
755 Token::Lt => BinOp::Lt,
756 Token::Le => BinOp::Le,
757 Token::Gt => BinOp::Gt,
758 Token::Ge => BinOp::Ge,
759 _ => break,
760 };
761 let span = self.span();
762 self.advance();
763 let rhs = self.parse_shift()?;
764 lhs = Expr::BinaryOp(Box::new(lhs), op, Box::new(rhs), span);
765 }
766 Ok(lhs)
767 }
768
769 fn parse_shift(&mut self) -> CompileResult<Expr> {
770 let mut lhs = self.parse_additive()?;
771 loop {
772 let op = match self.peek() {
773 Token::Shl => BinOp::Shl,
774 Token::Shr => BinOp::Shr,
775 _ => break,
776 };
777 let span = self.span();
778 self.advance();
779 let rhs = self.parse_additive()?;
780 lhs = Expr::BinaryOp(Box::new(lhs), op, Box::new(rhs), span);
781 }
782 Ok(lhs)
783 }
784
785 fn parse_additive(&mut self) -> CompileResult<Expr> {
786 let mut lhs = self.parse_multiplicative()?;
787 loop {
788 let op = match self.peek() {
789 Token::Plus => BinOp::Add,
790 Token::Minus => BinOp::Sub,
791 _ => break,
792 };
793 let span = self.span();
794 self.advance();
795 let rhs = self.parse_multiplicative()?;
796 lhs = Expr::BinaryOp(Box::new(lhs), op, Box::new(rhs), span);
797 }
798 Ok(lhs)
799 }
800
801 fn parse_multiplicative(&mut self) -> CompileResult<Expr> {
802 let mut lhs = self.parse_unary()?;
803 loop {
804 let op = match self.peek() {
805 Token::Star => BinOp::Mul,
806 Token::Slash => BinOp::Div,
807 Token::Percent => BinOp::Mod,
808 _ => break,
809 };
810 let span = self.span();
811 self.advance();
812 let rhs = self.parse_unary()?;
813 lhs = Expr::BinaryOp(Box::new(lhs), op, Box::new(rhs), span);
814 }
815 Ok(lhs)
816 }
817
818 fn parse_unary(&mut self) -> CompileResult<Expr> {
819 match self.peek() {
820 Token::Minus => {
821 let span = self.span();
822 self.advance();
823 let expr = self.parse_unary()?;
824 Ok(Expr::UnaryOp(UnaryOp::Neg, Box::new(expr), span))
825 }
826 Token::Not => {
827 let span = self.span();
828 self.advance();
829 let expr = self.parse_unary()?;
830 Ok(Expr::UnaryOp(UnaryOp::Not, Box::new(expr), span))
831 }
832 Token::BitNot => {
833 let span = self.span();
834 self.advance();
835 let expr = self.parse_unary()?;
836 Ok(Expr::UnaryOp(UnaryOp::BitNot, Box::new(expr), span))
837 }
838 Token::PlusPlus => {
839 let span = self.span();
840 self.advance();
841 let expr = self.parse_unary()?;
842 Ok(Expr::PreIncr(Box::new(expr), span))
843 }
844 Token::MinusMinus => {
845 let span = self.span();
846 self.advance();
847 let expr = self.parse_unary()?;
848 Ok(Expr::PreDecr(Box::new(expr), span))
849 }
850 _ => self.parse_postfix(),
851 }
852 }
853
854 fn parse_postfix(&mut self) -> CompileResult<Expr> {
855 let mut expr = self.parse_primary()?;
856
857 loop {
858 match self.peek() {
859 Token::PlusPlus => {
860 let span = self.span();
861 self.advance();
862 expr = Expr::PostIncr(Box::new(expr), span);
863 }
864 Token::MinusMinus => {
865 let span = self.span();
866 self.advance();
867 expr = Expr::PostDecr(Box::new(expr), span);
868 }
869 Token::LBracket => {
870 let span = self.span();
871 self.advance();
872 let index = self.parse_expr()?;
873 self.expect(&Token::RBracket)?;
874 expr = Expr::Index(Box::new(expr), Box::new(index), span);
875 }
876 Token::Dot => {
877 let span = self.span();
878 self.advance();
879 let field = self.expect_ident()?;
880 expr = Expr::Field(Box::new(expr), field, span);
881 }
882 Token::Arrow => {
883 let span = self.span();
884 self.advance();
885 let field = self.expect_ident()?;
886 expr = Expr::Field(Box::new(expr), field, span);
887 }
888 _ => break,
889 }
890 }
891
892 Ok(expr)
893 }
894
895 fn parse_primary(&mut self) -> CompileResult<Expr> {
896 match self.peek().clone() {
897 Token::IntLit(v) => {
898 let span = self.span();
899 let v = v;
900 self.advance();
901 Ok(Expr::IntLit(v, span))
902 }
903 Token::FloatLit(v) => {
904 let span = self.span();
905 let v = v;
906 self.advance();
907 Ok(Expr::FloatLit(v, span))
908 }
909 Token::StringLit(s) => {
910 let span = self.span();
911 let s = s.clone();
912 self.advance();
913 Ok(Expr::StringLit(s, span))
914 }
915 Token::Ident(name) => {
916 let span = self.span();
917 let name = name.clone();
918 self.advance();
919
920 if self.peek() == &Token::LParen {
922 self.advance();
923 let mut args = Vec::new();
924 if self.peek() != &Token::RParen {
925 args.push(self.parse_expr()?);
926 while self.peek() == &Token::Comma {
927 self.advance();
928 args.push(self.parse_expr()?);
929 }
930 }
931 self.expect(&Token::RParen)?;
932 Ok(Expr::Call(name, args, span))
933 } else {
934 Ok(Expr::Ident(name, span))
935 }
936 }
937 Token::LParen => {
938 let span = self.span();
939 self.advance();
940 let expr = self.parse_expr()?;
941 self.expect(&Token::RParen)?;
942 Ok(Expr::Paren(Box::new(expr), span))
943 }
944 _ => Err(CompileError::syntax(
945 self.span(),
946 format!("expected expression, got {:?}", self.peek()),
947 )),
948 }
949 }
950}
951
952#[cfg(test)]
953mod tests {
954 use super::*;
955 use crate::lexer::Lexer;
956
957 fn parse(input: &str) -> Program {
958 let tokens = Lexer::new(input).tokenize().unwrap();
959 Parser::new(tokens).parse_program().unwrap()
960 }
961
962 #[test]
963 fn test_minimal_program() {
964 let p = parse("program test ss s1 { state init { when () { } exit } }");
965 assert_eq!(p.name, "test");
966 assert_eq!(p.state_sets.len(), 1);
967 assert_eq!(p.state_sets[0].name, "s1");
968 assert_eq!(p.state_sets[0].states.len(), 1);
969 assert_eq!(p.state_sets[0].states[0].transitions.len(), 1);
970 }
971
972 #[test]
973 fn test_var_assign_monitor() {
974 let p = parse(r#"
975 program test
976 double x;
977 assign x to "PV:x";
978 monitor x;
979 ss s1 { state init { when () { } exit } }
980 "#);
981 let defs = &p.definitions;
982 assert!(matches!(defs[0], Definition::VarDecl(_)));
983 assert!(matches!(defs[1], Definition::Assign(_)));
984 assert!(matches!(defs[2], Definition::Monitor(_)));
985 }
986
987 #[test]
988 fn test_evflag_sync() {
989 let p = parse(r#"
990 program test
991 double x;
992 assign x to "PV:x";
993 monitor x;
994 evflag ef_x;
995 sync x to ef_x;
996 ss s1 { state init { when () { } exit } }
997 "#);
998 let has_evflag = p
999 .definitions
1000 .iter()
1001 .any(|d| matches!(d, Definition::EvFlag(_)));
1002 let has_sync = p
1003 .definitions
1004 .iter()
1005 .any(|d| matches!(d, Definition::Sync(_)));
1006 assert!(has_evflag);
1007 assert!(has_sync);
1008 }
1009
1010 #[test]
1011 fn test_option_safe() {
1012 let p = parse(r#"
1013 program test
1014 option +s;
1015 ss s1 { state init { when () { } exit } }
1016 "#);
1017 assert_eq!(p.options.len(), 1);
1018 assert!(matches!(p.options[0], ProgramOption::Safe));
1019 }
1020
1021 #[test]
1022 fn test_state_transition() {
1023 let p = parse(r#"
1024 program test
1025 ss s1 {
1026 state a {
1027 when (x > 0) {
1028 y = 1;
1029 } state b
1030 }
1031 state b {
1032 when () { } exit
1033 }
1034 }
1035 "#);
1036 let ss = &p.state_sets[0];
1037 assert_eq!(ss.states.len(), 2);
1038 let t = &ss.states[0].transitions[0];
1039 assert!(matches!(t.target, TransitionTarget::State(ref n) if n == "b"));
1040 }
1041
1042 #[test]
1043 fn test_delay_and_pvput() {
1044 let p = parse(r#"
1045 program test
1046 double counter;
1047 assign counter to "PV:counter";
1048 ss s1 {
1049 state counting {
1050 when (delay(1.0)) {
1051 counter += 1.0;
1052 pvPut(counter);
1053 } state counting
1054 }
1055 }
1056 "#);
1057 let state = &p.state_sets[0].states[0];
1058 assert_eq!(state.transitions.len(), 1);
1059 let cond = state.transitions[0].condition.as_ref().unwrap();
1060 assert!(matches!(cond, Expr::Call(name, _, _) if name == "delay"));
1061 }
1062
1063 #[test]
1064 fn test_entry_exit_blocks() {
1065 let p = parse(r#"
1066 program test
1067 entry { x = 1; }
1068 ss s1 { state init { when () { } exit } }
1069 exit { x = 0; }
1070 "#);
1071 assert!(p.entry.is_some());
1072 assert!(p.exit.is_some());
1073 }
1074
1075 #[test]
1076 fn test_if_else_in_action() {
1077 let p = parse(r#"
1078 program test
1079 int x;
1080 ss s1 {
1081 state init {
1082 when (x > 0) {
1083 if (x > 5) {
1084 y = 1;
1085 } else {
1086 y = 0;
1087 }
1088 } state init
1089 }
1090 }
1091 "#);
1092 let body = &p.state_sets[0].states[0].transitions[0].body;
1093 assert!(matches!(body.stmts[0], Stmt::If(_, _, Some(_))));
1094 }
1095
1096 #[test]
1097 fn test_array_declaration() {
1098 let p = parse(r#"
1099 program test
1100 double arr[10];
1101 ss s1 { state init { when () { } exit } }
1102 "#);
1103 let vd = match &p.definitions[0] {
1104 Definition::VarDecl(vd) => vd,
1105 _ => panic!("expected VarDecl"),
1106 };
1107 assert_eq!(vd.name, "arr");
1108 assert_eq!(vd.dimensions.len(), 1);
1109 assert!(matches!(&vd.dimensions[0], Expr::IntLit(10, _)));
1110 }
1111
1112 #[test]
1113 fn test_array_with_init() {
1114 let p = parse(r#"
1115 program test
1116 int arr[3] = {1, 2, 3};
1117 ss s1 { state init { when () { } exit } }
1118 "#);
1119 let vd = match &p.definitions[0] {
1120 Definition::VarDecl(vd) => vd,
1121 _ => panic!("expected VarDecl"),
1122 };
1123 assert_eq!(vd.name, "arr");
1124 assert!(matches!(&vd.init, Some(Expr::ArrayInit(elems, _)) if elems.len() == 3));
1125 }
1126
1127 #[test]
1128 fn test_embedded_code_top_level() {
1129 let p = parse(r#"
1130 program test
1131 %% use std::io;
1132 ss s1 { state init { when () { } exit } }
1133 "#);
1134 let has_embedded = p.definitions.iter().any(|d| matches!(d, Definition::EmbeddedCode(_)));
1135 assert!(has_embedded);
1136 }
1137
1138 #[test]
1139 fn test_safe_monitor_program() {
1140 let p = parse(r#"
1142 program safeMonitorTest
1143 option +s;
1144 double cnt = 1.0;
1145 assign cnt to "cnt";
1146 monitor cnt;
1147 evflag ef_cnt;
1148 sync cnt to ef_cnt;
1149 ss read {
1150 int n = 1;
1151 state react {
1152 when (n > 10) {
1153 } exit
1154 when (efTestAndClear(ef_cnt)) {
1155 n++;
1156 } state react
1157 }
1158 }
1159 ss write {
1160 state send {
1161 when (delay(0.04)) {
1162 cnt += 1.0;
1163 pvPut(cnt);
1164 } state send
1165 }
1166 }
1167 "#);
1168 assert_eq!(p.name, "safeMonitorTest");
1169 assert_eq!(p.state_sets.len(), 2);
1170 assert_eq!(p.state_sets[0].name, "read");
1171 assert_eq!(p.state_sets[0].local_vars.len(), 1);
1172 assert_eq!(p.state_sets[1].name, "write");
1173 }
1174}