1use crate::lexer::Token;
2use crate::ast::*;
3use logos::{Logos, Lexer};
4
5pub struct Parser<'a> {
6 lex: Lexer<'a, Token>,
7}
8
9#[derive(Debug)]
10pub enum ParseError {
11 UnexpectedToken(String),
12 ExpectedToken(String, String),
13 InvalidTrit(String),
14 NonExhaustiveMatch(String),
15}
16
17impl<'a> Parser<'a> {
18 pub fn new(input: &'a str) -> Self {
19 Self { lex: Token::lexer(input) }
20 }
21
22 pub fn parse_program(&mut self) -> Result<Program, ParseError> {
23 let mut structs = Vec::new();
24 let mut agents = Vec::new();
25 let mut functions = Vec::new();
26 while self.peek_token().is_ok() {
27 match self.peek_token()? {
28 Token::Struct => structs.push(self.parse_struct_def()?),
29 Token::Agent => agents.push(self.parse_agent_def()?),
30 _ => functions.push(self.parse_function()?),
31 }
32 }
33 Ok(Program { structs, agents, functions })
34 }
35
36 fn parse_agent_def(&mut self) -> Result<AgentDef, ParseError> {
37 self.expect(Token::Agent)?;
38 let name = match self.next_token()? {
39 Token::Ident(n) => n,
40 t => return Err(ParseError::ExpectedToken("agent name".into(), format!("{:?}", t))),
41 };
42 self.expect(Token::LBrace)?;
43 let mut methods = Vec::new();
44 while self.peek_token()? != Token::RBrace {
45 methods.push(self.parse_function()?);
46 }
47 self.expect(Token::RBrace)?;
48 Ok(AgentDef { name, methods })
49 }
50
51 fn parse_struct_def(&mut self) -> Result<StructDef, ParseError> {
52 self.expect(Token::Struct)?;
53 let name = match self.next_token()? {
54 Token::Ident(n) => n,
55 t => return Err(ParseError::ExpectedToken("struct name".into(), format!("{:?}", t))),
56 };
57 self.expect(Token::LBrace)?;
58 let mut fields = Vec::new();
59 while self.peek_token()? != Token::RBrace {
60 let field_name = match self.next_token()? {
61 Token::Ident(n) => n,
62 t => return Err(ParseError::ExpectedToken("field name".into(), format!("{:?}", t))),
63 };
64 self.expect(Token::Colon)?;
65 let field_type = self.parse_type()?;
66 fields.push((field_name, field_type));
67 if let Ok(Token::Comma) = self.peek_token() { self.next_token()?; }
68 }
69 self.expect(Token::RBrace)?;
70 Ok(StructDef { name, fields })
71 }
72
73 pub fn parse_function(&mut self) -> Result<Function, ParseError> {
74 self.expect(Token::Fn)?;
75 let name = match self.next_token()? {
76 Token::Ident(n) => n,
77 t => return Err(ParseError::ExpectedToken("function name".into(), format!("{:?}", t))),
78 };
79
80 self.expect(Token::LParen)?;
81 let mut params = Vec::new();
82 if self.peek_token()? != Token::RParen {
83 loop {
84 let p_name = match self.next_token()? {
85 Token::Ident(n) => n,
86 t => return Err(ParseError::ExpectedToken("parameter name".into(), format!("{:?}", t))),
87 };
88 self.expect(Token::Colon)?;
89 let p_type = self.parse_type()?;
90 params.push((p_name, p_type));
91 if self.peek_token()? == Token::Comma { self.next_token()?; } else { break; }
92 }
93 }
94 self.expect(Token::RParen)?;
95 self.expect(Token::Arrow)?;
96 let return_type = self.parse_type()?;
97 let body = match self.parse_block()? {
98 Stmt::Block(stmts) => stmts,
99 _ => unreachable!(),
100 };
101 Ok(Function { name, params, return_type, body })
102 }
103
104 fn next_token(&mut self) -> Result<Token, ParseError> {
105 self.lex.next()
106 .map(|res| res.map_err(|_| ParseError::UnexpectedToken("Invalid token".into())))
107 .transpose()?
108 .ok_or(ParseError::UnexpectedToken("EOF".into()))
109 }
110
111 fn peek_token(&mut self) -> Result<Token, ParseError> {
112 let mut cloned = self.lex.clone();
113 cloned.next()
114 .map(|res| res.map_err(|_| ParseError::UnexpectedToken("Invalid token".into())))
115 .transpose()?
116 .ok_or(ParseError::UnexpectedToken("EOF".into()))
117 }
118
119 pub fn parse_expr(&mut self) -> Result<Expr, ParseError> {
120 self.parse_binary_expr(0)
121 }
122
123 fn parse_binary_expr(&mut self, min_prec: i8) -> Result<Expr, ParseError> {
124 let mut lhs = self.parse_unary_expr()?;
125 loop {
126 let Ok(op_token) = self.peek_token() else { break };
127 let prec = self.get_precedence(&op_token);
128 if prec < min_prec { break; }
129 self.next_token()?;
130 let rhs = self.parse_binary_expr(prec + 1)?;
131 lhs = Expr::BinaryOp {
132 op: self.token_to_binop(op_token),
133 lhs: Box::new(lhs),
134 rhs: Box::new(rhs),
135 };
136 }
137 Ok(lhs)
138 }
139
140 fn get_precedence(&self, token: &Token) -> i8 {
141 match token {
142 Token::Or => 0,
143 Token::And => 1,
144 Token::Equal | Token::NotEqual => 2,
145 Token::Plus | Token::Minus => 3,
146 Token::Star => 4,
147 _ => -1,
148 }
149 }
150
151 fn token_to_binop(&self, token: Token) -> BinOp {
152 match token {
153 Token::Plus => BinOp::Add,
154 Token::Minus => BinOp::Sub,
155 Token::Star => BinOp::Mul,
156 Token::Equal => BinOp::Equal,
157 Token::NotEqual => BinOp::NotEqual,
158 Token::And => BinOp::And,
159 Token::Or => BinOp::Or,
160 _ => unreachable!(),
161 }
162 }
163
164 fn parse_unary_expr(&mut self) -> Result<Expr, ParseError> {
166 let mut expr = self.parse_primary_expr()?;
167 loop {
169 if let Ok(Token::Dot) = self.peek_token() {
170 self.next_token()?; let field = match self.next_token()? {
172 Token::Ident(n) => n,
173 t => return Err(ParseError::ExpectedToken("field name".into(), format!("{:?}", t))),
174 };
175 expr = Expr::FieldAccess { object: Box::new(expr), field };
176 } else {
177 break;
178 }
179 }
180 Ok(expr)
181 }
182
183 fn parse_primary_expr(&mut self) -> Result<Expr, ParseError> {
184 let token = self.next_token()?;
185 match token {
186 Token::Spawn => {
189 let node_addr = if let Ok(Token::Remote) = self.peek_token() {
190 self.next_token()?; match self.next_token()? {
192 Token::StringLit(addr) => Some(addr),
193 t => return Err(ParseError::ExpectedToken("node address string".into(), format!("{:?}", t))),
194 }
195 } else {
196 None
197 };
198 let agent_name = match self.next_token()? {
199 Token::Ident(n) => n,
200 t => return Err(ParseError::ExpectedToken("agent name".into(), format!("{:?}", t))),
201 };
202 Ok(Expr::Spawn { agent_name, node_addr })
203 }
204 Token::Await => {
206 let target = self.parse_unary_expr()?;
207 Ok(Expr::Await { target: Box::new(target) })
208 }
209 Token::NodeId => Ok(Expr::NodeId),
210 Token::Minus => {
211 let expr = self.parse_unary_expr()?;
212 Ok(Expr::UnaryOp { op: UnOp::Neg, expr: Box::new(expr) })
213 }
214 Token::TritLiteral => {
215 let slice = self.lex.slice();
216 let val = slice.parse::<i8>()
217 .map_err(|_| ParseError::InvalidTrit(slice.to_string()))?;
218 Ok(Expr::TritLiteral(val))
219 }
220 Token::Int(val) => Ok(Expr::IntLiteral(val)),
221 Token::StringLit(s) => Ok(Expr::StringLiteral(s)),
222 Token::Ident(name) => {
223 if name == "cast" {
225 if let Ok(Token::LParen) = self.peek_token() {
226 self.next_token()?;
227 let inner = self.parse_expr()?;
228 self.expect(Token::RParen)?;
229 return Ok(Expr::Cast { expr: Box::new(inner), ty: Type::Trit });
232 }
233 }
234
235 if let Ok(Token::LParen) = self.peek_token() {
236 self.next_token()?;
238 let mut args = Vec::new();
239 if self.peek_token()? != Token::RParen {
240 loop {
241 args.push(self.parse_expr()?);
242 if self.peek_token()? == Token::Comma {
243 self.next_token()?;
244 } else {
245 break;
246 }
247 }
248 }
249 self.expect(Token::RParen)?;
250 Ok(Expr::Call { callee: name, args })
251 } else {
252 Ok(Expr::Ident(name))
253 }
254 }
255 Token::LParen => {
256 let expr = self.parse_expr()?;
257 self.expect(Token::RParen)?;
258 Ok(expr)
259 }
260 _ => Err(ParseError::UnexpectedToken(format!("{:?}", token))),
261 }
262 }
263
264 pub fn parse_stmt(&mut self) -> Result<Stmt, ParseError> {
265 let token = self.peek_token()?;
266 match token {
267 Token::At => {
268 self.next_token()?;
269 let dir = match self.next_token()? {
270 Token::SparseSkip => "sparseskip".to_string(),
271 Token::Ident(n) => n,
272 t => return Err(ParseError::ExpectedToken("directive".into(), format!("{:?}", t))),
273 };
274 let stmt = self.parse_stmt()?;
275 Ok(Stmt::Decorated { directive: dir, stmt: Box::new(stmt) })
276 }
277
278 Token::Use => {
279 self.next_token()?;
280 let mut path = Vec::new();
281 loop {
282 let segment = match self.next_token()? {
284 Token::Ident(n) => n,
285 Token::TritType => "trit".to_string(),
286 Token::TritTensor => "trittensor".to_string(),
287 t => return Err(ParseError::ExpectedToken("module path segment".into(), format!("{:?}", t))),
288 };
289 path.push(segment);
290 if let Ok(Token::DoubleColon) = self.peek_token() {
291 self.next_token()?;
292 } else {
293 break;
294 }
295 }
296 self.expect(Token::Semicolon)?;
297 Ok(Stmt::Use { path })
298 }
299
300 Token::Let => {
301 self.next_token()?;
302 let _mutable = if let Ok(Token::Mut) = self.peek_token() {
304 self.next_token()?; true
305 } else { false };
306
307 let name = match self.next_token()? {
308 Token::Ident(n) => n,
309 t => return Err(ParseError::ExpectedToken("identifier".into(), format!("{:?}", t))),
310 };
311 self.expect(Token::Colon)?;
312 let ty = self.parse_type()?;
313 let value = if let Ok(Token::Assign) = self.peek_token() {
314 self.next_token()?;
315 self.parse_expr()?
316 } else {
317 Expr::TritLiteral(0)
318 };
319 self.expect(Token::Semicolon)?;
320 Ok(Stmt::Let { name, ty, value })
321 }
322
323 Token::If => {
324 self.next_token()?;
325 let condition = self.parse_expr()?;
326 self.expect(Token::UncertainBranch)?;
327 let on_pos = Box::new(self.parse_block()?);
328 self.expect(Token::Else)?;
329 let on_zero = Box::new(self.parse_block()?);
330 self.expect(Token::Else)?;
331 let on_neg = Box::new(self.parse_block()?);
332 Ok(Stmt::IfTernary { condition, on_pos, on_zero, on_neg })
333 }
334
335 Token::Match => {
336 self.next_token()?;
337 let condition = self.parse_expr()?;
338 self.expect(Token::LBrace)?;
339 let mut arms = Vec::new();
340 while self.peek_token()? != Token::RBrace {
341 let val = match self.next_token()? {
342 Token::TritLiteral => {
343 let slice = self.lex.slice();
344 slice.parse::<i8>().map_err(|_| ParseError::InvalidTrit(slice.to_string()))?
345 }
346 t => return Err(ParseError::ExpectedToken("trit literal".into(), format!("{:?}", t))),
347 };
348 self.expect(Token::FatArrow)?;
349 let stmt = self.parse_stmt()?;
350 arms.push((val, stmt));
351 }
352 self.expect(Token::RBrace)?;
353
354 let has_pos = arms.iter().any(|(v, _)| *v == 1);
356 let has_zero = arms.iter().any(|(v, _)| *v == 0);
357 let has_neg = arms.iter().any(|(v, _)| *v == -1);
358 if !has_pos || !has_zero || !has_neg {
359 let missing: Vec<&str> = [
360 if !has_pos { Some("1 (truth)") } else { None },
361 if !has_zero { Some("0 (hold)") } else { None },
362 if !has_neg { Some("-1 (conflict)") } else { None },
363 ].iter().filter_map(|x| *x).collect();
364 return Err(ParseError::NonExhaustiveMatch(
365 format!("match missing arms: {}", missing.join(", "))
366 ));
367 }
368
369 Ok(Stmt::Match { condition, arms })
370 }
371
372 Token::For => {
374 self.next_token()?;
375 let var = match self.next_token()? {
376 Token::Ident(n) => n,
377 t => return Err(ParseError::ExpectedToken("loop variable".into(), format!("{:?}", t))),
378 };
379 self.expect(Token::In)?;
380 let iter = self.parse_expr()?;
381 let body = Box::new(self.parse_block()?);
382 Ok(Stmt::ForIn { var, iter, body })
383 }
384
385 Token::While => {
387 self.next_token()?;
388 let condition = self.parse_expr()?;
389 self.expect(Token::UncertainBranch)?;
390 let on_pos = Box::new(self.parse_block()?);
391 self.expect(Token::Else)?;
392 let on_zero = Box::new(self.parse_block()?);
393 self.expect(Token::Else)?;
394 let on_neg = Box::new(self.parse_block()?);
395 Ok(Stmt::WhileTernary { condition, on_pos, on_zero, on_neg })
396 }
397
398 Token::Loop => {
400 self.next_token()?;
401 let body = Box::new(self.parse_block()?);
402 Ok(Stmt::Loop { body })
403 }
404
405 Token::Send => {
407 self.next_token()?;
408 let target = self.parse_expr()?;
409 let message = self.parse_expr()?;
410 self.expect(Token::Semicolon)?;
411 Ok(Stmt::Send { target, message })
412 }
413
414 Token::Break => {
415 self.next_token()?;
416 self.expect(Token::Semicolon)?;
417 Ok(Stmt::Break)
418 }
419
420 Token::Continue => {
421 self.next_token()?;
422 self.expect(Token::Semicolon)?;
423 Ok(Stmt::Continue)
424 }
425
426 Token::Return => {
427 self.next_token()?;
428 let expr = self.parse_expr()?;
429 self.expect(Token::Semicolon)?;
430 Ok(Stmt::Return(expr))
431 }
432
433 Token::LBrace => self.parse_block(),
434
435 _ => {
436 let expr = self.parse_expr()?;
438
439 if let Ok(Token::Assign) = self.peek_token() {
441 if let Expr::FieldAccess { object, field } = expr {
442 if let Expr::Ident(obj_name) = *object {
443 self.next_token()?; let value = self.parse_expr()?;
445 self.expect(Token::Semicolon)?;
446 return Ok(Stmt::FieldSet { object: obj_name, field, value });
447 }
448 }
449 return Err(ParseError::UnexpectedToken("invalid assignment target".into()));
450 }
451
452 self.expect(Token::Semicolon)?;
453 Ok(Stmt::Expr(expr))
454 }
455 }
456 }
457
458 fn parse_block(&mut self) -> Result<Stmt, ParseError> {
459 self.expect(Token::LBrace)?;
460 let mut stmts = Vec::new();
461 while self.peek_token()? != Token::RBrace {
462 stmts.push(self.parse_stmt()?);
463 }
464 self.expect(Token::RBrace)?;
465 Ok(Stmt::Block(stmts))
466 }
467
468 fn parse_type(&mut self) -> Result<Type, ParseError> {
469 let token = self.next_token()?;
470 match token {
471 Token::TritType => Ok(Type::Trit),
472 Token::AgentRef => Ok(Type::AgentRef),
473 Token::TritTensor => {
474 self.expect(Token::LAngle)?;
475 let mut dims = Vec::new();
476 loop {
477 let d = match self.next_token()? {
478 Token::Int(v) => v as usize,
479 Token::TritLiteral => {
481 let s = self.lex.slice();
482 s.parse::<i8>().unwrap_or(0).max(0) as usize
483 }
484 t => return Err(ParseError::ExpectedToken("dimension".into(), format!("{:?}", t))),
485 };
486 dims.push(d);
487 if self.peek_token()? == Token::Ident("x".to_string()) {
488 self.next_token()?;
489 } else {
490 break;
491 }
492 }
493 self.expect(Token::RAngle)?;
494 Ok(Type::TritTensor { dims })
495 }
496 Token::Ident(ref name) => match name.as_str() {
497 "int" => Ok(Type::Int),
498 "float" => Ok(Type::Float),
499 "bool" => Ok(Type::Bool),
500 "string" => Ok(Type::String),
501 _ => Ok(Type::Named(name.clone())),
503 },
504 _ => Err(ParseError::UnexpectedToken(format!("{:?}", token))),
505 }
506 }
507
508 fn expect(&mut self, expected: Token) -> Result<(), ParseError> {
509 let token = self.next_token()?;
510 if token == expected {
511 Ok(())
512 } else {
513 Err(ParseError::ExpectedToken(format!("{:?}", expected), format!("{:?}", token)))
514 }
515 }
516}
517
518#[cfg(test)]
519mod tests {
520 use super::*;
521
522 #[test]
523 fn test_parse_function() {
524 let input = "fn invert(signal: trit) -> trit { return -signal; }";
525 let mut parser = Parser::new(input);
526 let func = parser.parse_function().unwrap();
527 assert_eq!(func.name, "invert");
528 assert_eq!(func.params[0].1, Type::Trit);
529 assert_eq!(func.return_type, Type::Trit);
530 }
531
532 #[test]
533 fn test_parse_match() {
534 let input = "match x { 1 => return 1; 0 => return 0; -1 => return -1; }";
535 let mut parser = Parser::new(input);
536 let stmt = parser.parse_stmt().unwrap();
537 if let Stmt::Match { arms, .. } = stmt {
538 assert_eq!(arms.len(), 3);
539 assert_eq!(arms[0].0, 1);
540 assert_eq!(arms[1].0, 0);
541 assert_eq!(arms[2].0, -1);
542 } else {
543 panic!("Expected Match");
544 }
545 }
546
547 #[test]
548 fn test_match_exhaustiveness_enforced() {
549 let input = "match x { 1 => return 1; -1 => return -1; }";
551 let mut parser = Parser::new(input);
552 let result = parser.parse_stmt();
553 assert!(matches!(result, Err(ParseError::NonExhaustiveMatch(_))),
554 "expected NonExhaustiveMatch error");
555 }
556
557 #[test]
558 fn test_parse_for_loop() {
559 let input = "for item in weights { return item; }";
560 let mut parser = Parser::new(input);
561 let stmt = parser.parse_stmt().unwrap();
562 assert!(matches!(stmt, Stmt::ForIn { .. }));
563 }
564
565 #[test]
566 fn test_parse_loop_break() {
567 let input = "loop { break; }";
568 let mut parser = Parser::new(input);
569 let stmt = parser.parse_stmt().unwrap();
570 assert!(matches!(stmt, Stmt::Loop { .. }));
571 }
572
573 #[test]
574 fn test_parse_use() {
575 let input = "use std::trit;";
576 let mut parser = Parser::new(input);
577 let stmt = parser.parse_stmt().unwrap();
578 if let Stmt::Use { path } = stmt {
579 assert_eq!(path, vec!["std", "trit"]);
580 } else {
581 panic!("Expected Use");
582 }
583 }
584
585 #[test]
586 fn test_parse_mut_let() {
587 let input = "let mut signal: trit = 1;";
588 let mut parser = Parser::new(input);
589 let stmt = parser.parse_stmt().unwrap();
590 assert!(matches!(stmt, Stmt::Let { .. }));
591 }
592
593 #[test]
594 fn test_parse_struct_def() {
595 let input = "struct Signal { value: trit, weight: trit }";
596 let mut parser = Parser::new(input);
597 let s = parser.parse_struct_def().unwrap();
598 assert_eq!(s.name, "Signal");
599 assert_eq!(s.fields.len(), 2);
600 assert_eq!(s.fields[0], ("value".to_string(), Type::Trit));
601 assert_eq!(s.fields[1], ("weight".to_string(), Type::Trit));
602 }
603
604 #[test]
605 fn test_parse_field_access() {
606 let input = "let v: trit = sig.value;";
607 let mut parser = Parser::new(input);
608 let stmt = parser.parse_stmt().unwrap();
609 if let Stmt::Let { value: Expr::FieldAccess { field, .. }, .. } = stmt {
610 assert_eq!(field, "value");
611 } else {
612 panic!("Expected FieldAccess in let binding");
613 }
614 }
615
616 #[test]
617 fn test_parse_field_set() {
618 let input = "sig.value = 1;";
619 let mut parser = Parser::new(input);
620 let stmt = parser.parse_stmt().unwrap();
621 assert!(matches!(stmt, Stmt::FieldSet { .. }));
622 }
623
624 #[test]
625 fn test_parse_cast() {
626 let input = "let t: trit = cast(flag);";
627 let mut parser = Parser::new(input);
628 let stmt = parser.parse_stmt().unwrap();
629 if let Stmt::Let { value: Expr::Cast { .. }, .. } = stmt {
630 } else {
632 panic!("Expected Cast in let binding");
633 }
634 }
635
636 #[test]
637 fn test_parse_named_type() {
638 let input = "let s: Signal;";
639 let mut parser = Parser::new(input);
640 let stmt = parser.parse_stmt().unwrap();
641 if let Stmt::Let { ty: Type::Named(name), .. } = stmt {
642 assert_eq!(name, "Signal");
643 } else {
644 panic!("Expected Named type");
645 }
646 }
647
648 #[test]
649 fn test_parse_agent_def() {
650 let input = r#"
651 agent Voter {
652 fn handle(msg: trit) -> trit {
653 match msg {
654 1 => { return 1; }
655 0 => { return 0; }
656 -1 => { return -1; }
657 }
658 }
659 }
660 "#;
661 let mut parser = Parser::new(input);
662 let agent = parser.parse_agent_def().unwrap();
663 assert_eq!(agent.name, "Voter");
664 assert_eq!(agent.methods.len(), 1);
665 assert_eq!(agent.methods[0].name, "handle");
666 }
667
668 #[test]
669 fn test_parse_spawn() {
670 let input = "let v: agentref = spawn Voter;";
671 let mut parser = Parser::new(input);
672 let stmt = parser.parse_stmt().unwrap();
673 if let Stmt::Let { ty: Type::AgentRef, value: Expr::Spawn { agent_name, node_addr }, .. } = stmt {
674 assert_eq!(agent_name, "Voter");
675 assert_eq!(node_addr, None);
676 } else {
677 panic!("Expected spawn in let binding");
678 }
679 }
680
681 #[test]
682 fn test_parse_spawn_remote() {
683 let input = r#"let v: agentref = spawn remote "10.0.0.1:7373" Voter;"#;
684 let mut parser = Parser::new(input);
685 let stmt = parser.parse_stmt().unwrap();
686 if let Stmt::Let { ty: Type::AgentRef, value: Expr::Spawn { agent_name, node_addr }, .. } = stmt {
687 assert_eq!(agent_name, "Voter");
688 assert_eq!(node_addr, Some("10.0.0.1:7373".to_string()));
689 } else {
690 panic!("Expected remote spawn in let binding");
691 }
692 }
693
694 #[test]
695 fn test_parse_send() {
696 let input = "send v 1;";
697 let mut parser = Parser::new(input);
698 let stmt = parser.parse_stmt().unwrap();
699 assert!(matches!(stmt, Stmt::Send { .. }));
700 }
701
702 #[test]
703 fn test_parse_await() {
704 let input = "let reply: trit = await v;";
705 let mut parser = Parser::new(input);
706 let stmt = parser.parse_stmt().unwrap();
707 if let Stmt::Let { value: Expr::Await { .. }, .. } = stmt {
708 } else {
710 panic!("Expected await in let binding");
711 }
712 }
713}