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 std::fmt::Display for ParseError {
18 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
19 match self {
20 Self::UnexpectedToken(tok) =>
21 write!(f, "[PARSE-001] Unexpected token '{tok}' — the lexer hit something it didn't expect. Binary habit? Check 'fn' vs 'func', trit vs bool.\n → details: stdlib/errors/PARSE-001.tern | ternlang errors PARSE-001"),
22 Self::ExpectedToken(expected, found) =>
23 write!(f, "[PARSE-002] Expected {expected} but found '{found}'. Missing type annotation, brace, or semicolon?\n → details: stdlib/errors/PARSE-002.tern | ternlang errors PARSE-002"),
24 Self::InvalidTrit(val) =>
25 write!(f, "[PARSE-003] '{val}' is not a valid trit. Trits are -1, 0, or +1 — the universe has exactly three states.\n → details: stdlib/errors/PARSE-003.tern | ternlang errors PARSE-003"),
26 Self::NonExhaustiveMatch(msg) =>
27 write!(f, "[PARSE-004] Non-exhaustive match: {msg}. Ternary has three states — cover -1, 0, and +1 or the compiler won't let you through.\n → details: stdlib/errors/PARSE-004.tern | ternlang errors PARSE-004"),
28 }
29 }
30}
31
32impl<'a> Parser<'a> {
33 pub fn new(input: &'a str) -> Self {
34 Self { lex: Token::lexer(input) }
35 }
36
37 pub fn parse_program(&mut self) -> Result<Program, ParseError> {
38 let mut imports = Vec::new();
39 let mut import_specs = Vec::new();
40 let mut structs = Vec::new();
41 let mut agents = Vec::new();
42 let mut functions = Vec::new();
43 let mut toplevel_stmts: Vec<Stmt> = Vec::new();
44
45 while self.peek_token().is_ok() {
46 match self.peek_token()? {
47 Token::Use => {
48 if let Stmt::Use { path } = self.parse_stmt()? {
49 imports.push(path);
50 }
51 }
52 Token::From => {
53 if let Stmt::FromImport { spec } = self.parse_stmt()? {
54 import_specs.push(spec);
55 }
56 }
57 Token::Struct => structs.push(self.parse_struct_def()?),
58 Token::Agent => agents.push(self.parse_agent_def()?),
59 Token::Fn | Token::At => functions.push(self.parse_function()?),
60 _ => toplevel_stmts.push(self.parse_stmt()?),
62 }
63 }
64
65 if !toplevel_stmts.is_empty() && !functions.iter().any(|f| f.name == "main") {
68 functions.push(Function {
69 name: "main".to_string(),
70 params: vec![],
71 return_type: Type::Trit,
72 body: toplevel_stmts,
73 directive: None,
74 });
75 }
76
77 Ok(Program { imports, import_specs, structs, agents, functions })
78 }
79
80 fn parse_agent_def(&mut self) -> Result<AgentDef, ParseError> {
81 self.expect(Token::Agent)?;
82 let name = match self.next_token()? {
83 Token::Ident(n) => n,
84 t => return Err(ParseError::ExpectedToken("agent name".into(), format!("{:?}", t))),
85 };
86 self.expect(Token::LBrace)?;
87 let mut methods = Vec::new();
88 while self.peek_token()? != Token::RBrace {
89 methods.push(self.parse_function()?);
90 }
91 self.expect(Token::RBrace)?;
92 Ok(AgentDef { name, methods })
93 }
94
95 fn parse_struct_def(&mut self) -> Result<StructDef, ParseError> {
96 self.expect(Token::Struct)?;
97 let name = match self.next_token()? {
98 Token::Ident(n) => n,
99 t => return Err(ParseError::ExpectedToken("struct name".into(), format!("{:?}", t))),
100 };
101 self.expect(Token::LBrace)?;
102 let mut fields = Vec::new();
103 while self.peek_token()? != Token::RBrace {
104 let field_name = match self.next_token()? {
105 Token::Ident(n) => n,
106 t => return Err(ParseError::ExpectedToken("field name".into(), format!("{:?}", t))),
107 };
108 self.expect(Token::Colon)?;
109 let field_type = self.parse_type()?;
110 fields.push((field_name, field_type));
111 if let Ok(Token::Comma) = self.peek_token() { self.next_token()?; }
112 }
113 self.expect(Token::RBrace)?;
114 Ok(StructDef { name, fields })
115 }
116
117 pub fn parse_function(&mut self) -> Result<Function, ParseError> {
118 let directive = if let Ok(Token::At) = self.peek_token() {
119 self.next_token()?;
120 let dir = match self.next_token()? {
121 Token::SparseSkip => "sparseskip".to_string(),
122 Token::Ident(n) => n,
123 t => return Err(ParseError::ExpectedToken("directive".into(), format!("{:?}", t))),
124 };
125 Some(dir)
126 } else {
127 None
128 };
129
130 self.expect(Token::Fn)?;
131 let name = match self.next_token()? {
132 Token::Ident(n) => n,
133 t => return Err(ParseError::ExpectedToken("function name".into(), format!("{:?}", t))),
134 };
135
136 self.expect(Token::LParen)?;
137 let mut params = Vec::new();
138 if self.peek_token()? != Token::RParen {
139 loop {
140 let p_name = match self.next_token()? {
141 Token::Ident(n) => n,
142 t => return Err(ParseError::ExpectedToken("parameter name".into(), format!("{:?}", t))),
143 };
144 self.expect(Token::Colon)?;
145 let p_type = self.parse_type()?;
146 params.push((p_name, p_type));
147 if self.peek_token()? == Token::Comma { self.next_token()?; } else { break; }
148 }
149 }
150 self.expect(Token::RParen)?;
151 self.expect(Token::Arrow)?;
152 let return_type = self.parse_type()?;
153 let body = match self.parse_block()? {
154 Stmt::Block(stmts) => stmts,
155 _ => unreachable!(),
156 };
157 Ok(Function { name, params, return_type, body, directive })
158 }
159
160 fn next_token(&mut self) -> Result<Token, ParseError> {
161 self.lex.next()
162 .map(|res| res.map_err(|_| ParseError::UnexpectedToken("Invalid token".into())))
163 .transpose()?
164 .ok_or(ParseError::UnexpectedToken("EOF".into()))
165 }
166
167 fn peek_token(&mut self) -> Result<Token, ParseError> {
168 let mut cloned = self.lex.clone();
169 cloned.next()
170 .map(|res| res.map_err(|_| ParseError::UnexpectedToken("Invalid token".into())))
171 .transpose()?
172 .ok_or(ParseError::UnexpectedToken("EOF".into()))
173 }
174
175 pub fn parse_expr(&mut self) -> Result<Expr, ParseError> {
176 self.parse_binary_expr(0)
177 }
178
179 fn parse_binary_expr(&mut self, min_prec: i8) -> Result<Expr, ParseError> {
180 let mut lhs = self.parse_unary_expr()?;
181 loop {
182 let Ok(op_token) = self.peek_token() else { break };
183 if op_token == Token::RBrace || op_token == Token::Comma || op_token == Token::RParen || op_token == Token::Semicolon || op_token == Token::Return { break; }
184 let prec = self.get_precedence(&op_token);
185 if prec < min_prec { break; }
186 self.next_token()?;
187 let rhs = self.parse_binary_expr(prec + 1)?;
188 lhs = Expr::BinaryOp {
189 op: self.token_to_binop(op_token),
190 lhs: Box::new(lhs),
191 rhs: Box::new(rhs),
192 };
193 }
194 Ok(lhs)
195 }
196
197 fn get_precedence(&self, token: &Token) -> i8 {
198 match token {
199 Token::Or => 0,
200 Token::And => 1,
201 Token::Equal | Token::NotEqual => 2,
202 Token::LAngle | Token::RAngle => 2, Token::LessEqual | Token::GreaterEqual => 2,
204 Token::Plus | Token::Minus => 3,
205 Token::Star | Token::Slash | Token::Percent => 4,
206 _ => -1,
207 }
208 }
209
210 fn token_to_binop(&self, token: Token) -> BinOp {
211 match token {
212 Token::Plus => BinOp::Add,
213 Token::Minus => BinOp::Sub,
214 Token::Star => BinOp::Mul,
215 Token::Slash => BinOp::Div,
216 Token::Percent => BinOp::Mod,
217 Token::Equal => BinOp::Equal,
218 Token::NotEqual => BinOp::NotEqual,
219 Token::And => BinOp::And,
220 Token::Or => BinOp::Or,
221 Token::LAngle => BinOp::Less,
222 Token::RAngle => BinOp::Greater,
223 Token::LessEqual => BinOp::LessEqual,
224 Token::GreaterEqual => BinOp::GreaterEqual,
225 _ => unreachable!(),
226 }
227 }
228
229 fn parse_unary_expr(&mut self) -> Result<Expr, ParseError> {
231 let mut expr = self.parse_primary_expr()?;
232 loop {
233 match self.peek_token()? {
234 Token::Dot => {
235 self.next_token()?; let field = match self.next_token()? {
237 Token::Ident(n) => n,
238 t => return Err(ParseError::ExpectedToken("field name".into(), format!("{:?}", t))),
239 };
240 expr = Expr::FieldAccess { object: Box::new(expr), field };
241 }
242 Token::LBracket => {
243 self.next_token()?; let row = self.parse_expr()?;
245 if let Ok(Token::Comma) = self.peek_token() {
246 self.next_token()?; let col = self.parse_expr()?;
248 self.expect(Token::RBracket)?;
249 expr = Expr::Index { object: Box::new(expr), row: Box::new(row), col: Box::new(col) };
250 } else {
251 self.expect(Token::RBracket)?;
252 expr = Expr::Index { object: Box::new(expr), row: Box::new(row), col: Box::new(Expr::IntLiteral(0)) };
254 }
255 }
256 Token::UncertainBranch => {
257 let mut lookahead = self.lex.clone();
261 lookahead.next(); let after_q = lookahead.next();
263 let is_uncertain_branch = matches!(after_q, Some(Ok(Token::LBrace)));
264 if !is_uncertain_branch {
265 self.next_token()?; expr = Expr::Propagate { expr: Box::new(expr) };
267 } else {
268 break;
269 }
270 }
271 _ => break,
272 }
273 }
274 Ok(expr)
275 }
276
277 fn parse_primary_expr(&mut self) -> Result<Expr, ParseError> {
278 let token = self.next_token()?;
279 match token {
280 Token::Spawn => {
283 let node_addr = if let Ok(Token::Remote) = self.peek_token() {
284 self.next_token()?; match self.next_token()? {
286 Token::StringLit(addr) => Some(addr),
287 t => return Err(ParseError::ExpectedToken("node address string".into(), format!("{:?}", t))),
288 }
289 } else {
290 None
291 };
292 let agent_name = match self.next_token()? {
293 Token::Ident(n) => n,
294 t => return Err(ParseError::ExpectedToken("agent name".into(), format!("{:?}", t))),
295 };
296 Ok(Expr::Spawn { agent_name, node_addr })
297 }
298 Token::Await => {
300 let target = self.parse_unary_expr()?;
301 Ok(Expr::Await { target: Box::new(target) })
302 }
303 Token::NodeId => Ok(Expr::NodeId),
304 Token::Minus => {
305 let expr = self.parse_unary_expr()?;
306 Ok(Expr::UnaryOp { op: UnOp::Neg, expr: Box::new(expr) })
307 }
308 Token::LBracket => {
309 let mut vals = Vec::new();
310 loop {
311 match self.next_token()? {
312 Token::TritLiteral => {
313 let s = self.lex.slice();
314 let v = s.parse::<i8>().unwrap_or(0);
315 vals.push(v);
316 }
317 Token::Int(v) => vals.push(v as i8),
318 Token::Minus => {
319 match self.next_token()? {
320 Token::Int(v) => vals.push(-(v as i8)),
321 t => return Err(ParseError::UnexpectedToken(format!("tensor literal element after '-': {:?}", t))),
322 }
323 }
324 Token::Affirm => vals.push(1),
325 Token::Tend => vals.push(0),
326 Token::Reject => vals.push(-1),
327 t => return Err(ParseError::UnexpectedToken(format!("tensor literal element: {:?}", t))),
328 }
329 if self.peek_token()? == Token::Comma {
330 self.next_token()?;
331 } else {
332 break;
333 }
334 }
335 self.expect(Token::RBracket)?;
336 Ok(Expr::TritTensorLiteral(vals))
337 }
338 Token::TritLiteral => {
339 let slice = self.lex.slice();
340 let val = slice.parse::<i8>()
341 .map_err(|_| ParseError::InvalidTrit(slice.to_string()))?;
342 Ok(Expr::TritLiteral(val))
343 }
344 Token::Affirm => Ok(Expr::TritLiteral(1)),
346 Token::Tend => Ok(Expr::TritLiteral(0)),
347 Token::Reject => Ok(Expr::TritLiteral(-1)),
348 Token::Int(val) => Ok(Expr::IntLiteral(val)),
349 Token::Float(val) => Ok(Expr::FloatLiteral(val)),
350 Token::StringLit(s) => Ok(Expr::StringLiteral(s)),
351 Token::Ident(name) => {
352 if name == "cast" {
354 if let Ok(Token::LParen) = self.peek_token() {
355 self.next_token()?;
356 let inner = self.parse_expr()?;
357 self.expect(Token::RParen)?;
358 return Ok(Expr::Cast { expr: Box::new(inner), ty: Type::Trit });
361 }
362 }
363
364 if let Ok(Token::LParen) = self.peek_token() {
365 self.next_token()?;
367 let mut args = Vec::new();
368 if self.peek_token()? != Token::RParen {
369 loop {
370 args.push(self.parse_expr()?);
371 if self.peek_token()? == Token::Comma {
372 self.next_token()?;
373 } else {
374 break;
375 }
376 }
377 }
378 self.expect(Token::RParen)?;
379 Ok(Expr::Call { callee: name, args })
380 } else if let Ok(Token::LBrace) = self.peek_token() {
381 let mut lookahead = self.lex.clone();
385 let _ = lookahead.next(); let maybe_ident = lookahead.next();
387 let maybe_colon = lookahead.next();
388
389 let is_struct_literal = matches!(maybe_ident, Some(Ok(Token::Ident(_)))) &&
390 matches!(maybe_colon, Some(Ok(Token::Colon)));
391
392 if is_struct_literal {
393 self.next_token()?; let mut fields = Vec::new();
395 while self.peek_token()? != Token::RBrace {
396 let f_name = match self.next_token()? {
397 Token::Ident(n) => n,
398 t => return Err(ParseError::ExpectedToken("field name".into(), format!("{:?}", t))),
399 };
400 self.expect(Token::Colon)?;
401 let f_val = self.parse_expr()?;
402 fields.push((f_name, f_val));
403 if let Ok(Token::Comma) = self.peek_token() {
404 self.next_token()?;
405 } else {
406 break;
407 }
408 }
409 self.expect(Token::RBrace)?;
410 Ok(Expr::StructLiteral { name, fields })
411 } else {
412 Ok(Expr::Ident(name))
413 }
414 } else {
415 Ok(Expr::Ident(name))
416 }
417 }
418 Token::LParen => {
419 let expr = self.parse_expr()?;
420 self.expect(Token::RParen)?;
421 Ok(expr)
422 }
423 _ => Err(ParseError::UnexpectedToken(format!("{:?}", token))),
424 }
425 }
426
427 pub fn parse_stmt(&mut self) -> Result<Stmt, ParseError> {
428 let token = self.peek_token()?;
429 match token {
430 Token::At => {
431 self.next_token()?;
432 let dir = match self.next_token()? {
433 Token::SparseSkip => "sparseskip".to_string(),
434 Token::Ident(n) => n,
435 t => return Err(ParseError::ExpectedToken("directive".into(), format!("{:?}", t))),
436 };
437 let stmt = self.parse_stmt()?;
438 Ok(Stmt::Decorated { directive: dir, stmt: Box::new(stmt) })
439 }
440
441 Token::Use => {
442 self.next_token()?;
443 let mut path = Vec::new();
444 loop {
445 let segment = match self.next_token()? {
447 Token::Ident(n) => n,
448 Token::TritType => "trit".to_string(),
449 Token::TritTensor => "trittensor".to_string(),
450 t => return Err(ParseError::ExpectedToken("module path segment".into(), format!("{:?}", t))),
451 };
452 path.push(segment);
453 if let Ok(Token::DoubleColon) = self.peek_token() {
454 self.next_token()?;
455 } else {
456 break;
457 }
458 }
459 self.expect(Token::Semicolon)?;
460 Ok(Stmt::Use { path })
461 }
462
463 Token::From => {
465 self.next_token()?;
466 let source = match self.peek_token()? {
468 Token::StringLit(_) => {
469 if let Token::StringLit(s) = self.next_token()? {
470 ImportSource::File(s)
471 } else { unreachable!() }
472 }
473 _ => {
474 let mut path = Vec::new();
475 loop {
476 let segment = match self.next_token()? {
477 Token::Ident(n) => n,
478 Token::TritType => "trit".to_string(),
479 Token::TritTensor => "trittensor".to_string(),
480 t => return Err(ParseError::ExpectedToken("module path segment".into(), format!("{:?}", t))),
481 };
482 path.push(segment);
483 if let Ok(Token::DoubleColon) = self.peek_token() {
484 self.next_token()?;
485 } else {
486 break;
487 }
488 }
489 ImportSource::Module(path)
490 }
491 };
492 self.expect(Token::Import)?;
493 let names = if let Ok(Token::Star) = self.peek_token() {
495 self.next_token()?;
496 ImportNames::Wildcard
497 } else {
498 let mut named = Vec::new();
499 loop {
500 match self.next_token()? {
501 Token::Ident(n) => named.push(n),
502 t => return Err(ParseError::ExpectedToken("import name".into(), format!("{:?}", t))),
503 }
504 if let Ok(Token::Comma) = self.peek_token() {
505 self.next_token()?;
506 } else {
507 break;
508 }
509 }
510 ImportNames::Named(named)
511 };
512 self.expect(Token::Semicolon)?;
513 Ok(Stmt::FromImport { spec: ImportSpec { source, names } })
514 }
515
516 Token::Let => {
517 self.next_token()?;
518 let _mutable = if let Ok(Token::Mut) = self.peek_token() {
520 self.next_token()?; true
521 } else { false };
522
523 let name = match self.next_token()? {
524 Token::Ident(n) => n,
525 t => return Err(ParseError::ExpectedToken("identifier".into(), format!("{:?}", t))),
526 };
527 self.expect(Token::Colon)?;
528 let ty = self.parse_type()?;
529 let value = if let Ok(Token::Assign) = self.peek_token() {
530 self.next_token()?;
531 self.parse_expr()?
532 } else {
533 Expr::TritLiteral(0)
534 };
535 self.expect(Token::Semicolon)?;
536 Ok(Stmt::Let { name, ty, value })
537 }
538
539 Token::If => {
540 self.next_token()?;
541 let condition = self.parse_expr()?;
542 if let Ok(Token::UncertainBranch) = self.peek_token() {
543 self.next_token()?;
544 let on_pos = Box::new(self.parse_block()?);
545 self.expect(Token::Else)?;
546 let on_zero = Box::new(self.parse_block()?);
547 self.expect(Token::Else)?;
548 let on_neg = Box::new(self.parse_block()?);
549 Ok(Stmt::IfTernary { condition, on_pos, on_zero, on_neg })
550 } else {
551 let then_branch = Box::new(self.parse_block()?);
554 let else_branch = if let Ok(Token::Else) = self.peek_token() {
555 self.next_token()?;
556 Box::new(self.parse_block()?)
557 } else {
558 Box::new(Stmt::Block(vec![]))
559 };
560 Ok(Stmt::IfTernary {
561 condition,
562 on_pos: then_branch,
563 on_zero: else_branch.clone(),
564 on_neg: else_branch,
565 })
566 }
567 }
568
569 Token::Match => {
570 self.next_token()?;
571 let condition = self.parse_expr()?;
572 self.expect(Token::LBrace)?;
573 let mut arms = Vec::new();
574 while self.peek_token()? != Token::RBrace {
575 let val = match self.next_token()? {
576 Token::TritLiteral => {
577 let slice = self.lex.slice();
578 slice.parse::<i64>().map_err(|_| ParseError::InvalidTrit(slice.to_string()))?
579 }
580 Token::Int(v) => v,
581 Token::Minus => {
582 match self.next_token()? {
583 Token::Int(v) => -v,
584 t => return Err(ParseError::ExpectedToken("integer literal after '-'".into(), format!("{:?}", t))),
585 }
586 }
587 Token::Affirm => 1,
588 Token::Tend => 0,
589 Token::Reject => -1,
590 t => return Err(ParseError::ExpectedToken("pattern (int or trit)".into(), format!("{:?}", t))),
591 };
592 self.expect(Token::FatArrow)?;
593 let stmt = self.parse_stmt()?;
594 arms.push((val, stmt));
595 }
596 self.expect(Token::RBrace)?;
597
598 Ok(Stmt::Match { condition, arms })
599 }
600
601 Token::For => {
603 self.next_token()?;
604 let var = match self.next_token()? {
605 Token::Ident(n) => n,
606 t => return Err(ParseError::ExpectedToken("loop variable".into(), format!("{:?}", t))),
607 };
608 self.expect(Token::In)?;
609 let iter = self.parse_expr()?;
610 let body = Box::new(self.parse_block()?);
611 Ok(Stmt::ForIn { var, iter, body })
612 }
613
614 Token::While => {
616 self.next_token()?;
617 let condition = self.parse_expr()?;
618 if let Ok(Token::UncertainBranch) = self.peek_token() {
619 self.next_token()?;
620 let on_pos = Box::new(self.parse_block()?);
621 self.expect(Token::Else)?;
622 let on_zero = Box::new(self.parse_block()?);
623 self.expect(Token::Else)?;
624 let on_neg = Box::new(self.parse_block()?);
625 Ok(Stmt::WhileTernary { condition, on_pos, on_zero, on_neg })
626 } else {
627 let body = Box::new(self.parse_block()?);
630 Ok(Stmt::WhileTernary {
631 condition,
632 on_pos: body,
633 on_zero: Box::new(Stmt::Break),
634 on_neg: Box::new(Stmt::Break),
635 })
636 }
637 }
638
639 Token::Loop => {
641 self.next_token()?;
642 let body = Box::new(self.parse_block()?);
643 Ok(Stmt::Loop { body })
644 }
645
646 Token::Send => {
648 self.next_token()?;
649 let target = self.parse_expr()?;
650 let message = self.parse_expr()?;
651 self.expect(Token::Semicolon)?;
652 Ok(Stmt::Send { target, message })
653 }
654
655 Token::Break => {
656 self.next_token()?;
657 self.expect(Token::Semicolon)?;
658 Ok(Stmt::Break)
659 }
660
661 Token::Continue => {
662 self.next_token()?;
663 self.expect(Token::Semicolon)?;
664 Ok(Stmt::Continue)
665 }
666
667 Token::Return => {
668 self.next_token()?;
669 let expr = self.parse_expr()?;
670 self.expect(Token::Semicolon)?;
671 Ok(Stmt::Return(expr))
672 }
673
674 Token::LBrace => self.parse_block(),
675
676 Token::Fn => Err(ParseError::UnexpectedToken("Fn".into())),
681
682 _ => {
683 let expr = self.parse_expr()?;
685
686 if let Ok(Token::Assign) = self.peek_token() {
688 match expr {
689 Expr::FieldAccess { object, field } => {
690 if let Expr::Ident(obj_name) = *object {
691 self.next_token()?; let value = self.parse_expr()?;
693 self.expect(Token::Semicolon)?;
694 return Ok(Stmt::FieldSet { object: obj_name, field, value });
695 }
696 }
697 Expr::Index { object, row, col } => {
698 if let Expr::Ident(obj_name) = *object {
699 self.next_token()?; let value = self.parse_expr()?;
701 self.expect(Token::Semicolon)?;
702 return Ok(Stmt::IndexSet { object: obj_name, row: *row, col: *col, value });
703 }
704 }
705 Expr::Ident(name) => {
706 self.next_token()?; let value = self.parse_expr()?;
708 self.expect(Token::Semicolon)?;
709 return Ok(Stmt::Set { name, value });
710 }
711 _ => {}
712 }
713 return Err(ParseError::UnexpectedToken("invalid assignment target".into()));
714 }
715
716 self.expect(Token::Semicolon)?;
717 Ok(Stmt::Expr(expr))
718 }
719 }
720 }
721
722 fn parse_block(&mut self) -> Result<Stmt, ParseError> {
723 self.expect(Token::LBrace)?;
724 let mut stmts = Vec::new();
725 while self.peek_token()? != Token::RBrace {
726 stmts.push(self.parse_stmt()?);
727 }
728 self.expect(Token::RBrace)?;
729 Ok(Stmt::Block(stmts))
730 }
731
732 fn parse_type(&mut self) -> Result<Type, ParseError> {
733 let token = self.next_token()?;
734 match token {
735 Token::TritType => {
736 if let Ok(Token::LBracket) = self.peek_token() {
737 self.next_token()?;
738 self.expect(Token::RBracket)?;
739 Ok(Type::TritTensor { dims: vec![0] })
740 } else {
741 Ok(Type::Trit)
742 }
743 }
744 Token::AgentRef => Ok(Type::AgentRef),
745 Token::TritTensor => {
746 self.expect(Token::LAngle)?;
747 let mut dims = Vec::new();
748 loop {
749 let d = match self.next_token()? {
750 Token::Int(v) => v as usize,
751 Token::TritLiteral => {
753 let s = self.lex.slice();
754 s.parse::<i8>().unwrap_or(0).max(0) as usize
755 }
756 t => return Err(ParseError::ExpectedToken("dimension".into(), format!("{:?}", t))),
757 };
758 dims.push(d);
759 if self.peek_token()? == Token::Ident("x".to_string()) {
760 self.next_token()?;
761 } else {
762 break;
763 }
764 }
765 self.expect(Token::RAngle)?;
766 Ok(Type::TritTensor { dims })
767 }
768 Token::Ident(ref name) => match name.as_str() {
769 "int" => Ok(Type::Int),
770 "float" => Ok(Type::Float),
771 "bool" => Ok(Type::Bool),
772 "string" => Ok(Type::String),
773 _ => Ok(Type::Named(name.clone())),
775 },
776 _ => Err(ParseError::UnexpectedToken(format!("{:?}", token))),
777 }
778 }
779
780 fn expect(&mut self, expected: Token) -> Result<(), ParseError> {
781 let token = self.next_token()?;
782 if token == expected {
783 Ok(())
784 } else {
785 Err(ParseError::ExpectedToken(format!("{:?}", expected), format!("{:?}", token)))
786 }
787 }
788}
789
790#[cfg(test)]
791mod tests {
792 use super::*;
793
794 #[test]
795 fn test_parse_function() {
796 let input = "fn invert(signal: trit) -> trit { return -signal; }";
797 let mut parser = Parser::new(input);
798 let func = parser.parse_function().unwrap();
799 assert_eq!(func.name, "invert");
800 assert_eq!(func.params[0].1, Type::Trit);
801 assert_eq!(func.return_type, Type::Trit);
802 }
803
804 #[test]
805 fn test_parse_match() {
806 let input = "match x { 1 => return 1; 0 => return 0; -1 => return -1; }";
807 let mut parser = Parser::new(input);
808 let stmt = parser.parse_stmt().unwrap();
809 if let Stmt::Match { arms, .. } = stmt {
810 assert_eq!(arms.len(), 3);
811 assert_eq!(arms[0].0, 1);
812 assert_eq!(arms[1].0, 0);
813 assert_eq!(arms[2].0, -1);
814 } else {
815 panic!("Expected Match");
816 }
817 }
818
819 #[test]
820 fn test_match_parses_non_exhaustive() {
821 let input = "match x { 1 => return 1; -1 => return -1; }";
823 let mut parser = Parser::new(input);
824 let result = parser.parse_stmt();
825 assert!(result.is_ok(), "should parse successfully even if non-exhaustive");
826 }
827
828 #[test]
829 fn test_parse_for_loop() {
830 let input = "for item in weights { return item; }";
831 let mut parser = Parser::new(input);
832 let stmt = parser.parse_stmt().unwrap();
833 assert!(matches!(stmt, Stmt::ForIn { .. }));
834 }
835
836 #[test]
837 fn test_parse_loop_break() {
838 let input = "loop { break; }";
839 let mut parser = Parser::new(input);
840 let stmt = parser.parse_stmt().unwrap();
841 assert!(matches!(stmt, Stmt::Loop { .. }));
842 }
843
844 #[test]
845 fn test_parse_use() {
846 let input = "use std::trit;";
847 let mut parser = Parser::new(input);
848 let stmt = parser.parse_stmt().unwrap();
849 if let Stmt::Use { path } = stmt {
850 assert_eq!(path, vec!["std", "trit"]);
851 } else {
852 panic!("Expected Use");
853 }
854 }
855
856 #[test]
857 fn test_parse_mut_let() {
858 let input = "let mut signal: trit = 1;";
859 let mut parser = Parser::new(input);
860 let stmt = parser.parse_stmt().unwrap();
861 assert!(matches!(stmt, Stmt::Let { .. }));
862 }
863
864 #[test]
865 fn test_parse_struct_def() {
866 let input = "struct Signal { value: trit, weight: trit }";
867 let mut parser = Parser::new(input);
868 let s = parser.parse_struct_def().unwrap();
869 assert_eq!(s.name, "Signal");
870 assert_eq!(s.fields.len(), 2);
871 assert_eq!(s.fields[0], ("value".to_string(), Type::Trit));
872 assert_eq!(s.fields[1], ("weight".to_string(), Type::Trit));
873 }
874
875 #[test]
876 fn test_parse_field_access() {
877 let input = "let v: trit = sig.value;";
878 let mut parser = Parser::new(input);
879 let stmt = parser.parse_stmt().unwrap();
880 if let Stmt::Let { value: Expr::FieldAccess { field, .. }, .. } = stmt {
881 assert_eq!(field, "value");
882 } else {
883 panic!("Expected FieldAccess in let binding");
884 }
885 }
886
887 #[test]
888 fn test_parse_field_set() {
889 let input = "sig.value = 1;";
890 let mut parser = Parser::new(input);
891 let stmt = parser.parse_stmt().unwrap();
892 assert!(matches!(stmt, Stmt::FieldSet { .. }));
893 }
894
895 #[test]
896 fn test_parse_cast() {
897 let input = "let t: trit = cast(flag);";
898 let mut parser = Parser::new(input);
899 let stmt = parser.parse_stmt().unwrap();
900 if let Stmt::Let { value: Expr::Cast { .. }, .. } = stmt {
901 } else {
903 panic!("Expected Cast in let binding");
904 }
905 }
906
907 #[test]
908 fn test_parse_named_type() {
909 let input = "let s: Signal;";
910 let mut parser = Parser::new(input);
911 let stmt = parser.parse_stmt().unwrap();
912 if let Stmt::Let { ty: Type::Named(name), .. } = stmt {
913 assert_eq!(name, "Signal");
914 } else {
915 panic!("Expected Named type");
916 }
917 }
918
919 #[test]
920 fn test_parse_agent_def() {
921 let input = r#"
922 agent Voter {
923 fn handle(msg: trit) -> trit {
924 match msg {
925 1 => { return 1; }
926 0 => { return 0; }
927 -1 => { return -1; }
928 }
929 }
930 }
931 "#;
932 let mut parser = Parser::new(input);
933 let agent = parser.parse_agent_def().unwrap();
934 assert_eq!(agent.name, "Voter");
935 assert_eq!(agent.methods.len(), 1);
936 assert_eq!(agent.methods[0].name, "handle");
937 }
938
939 #[test]
940 fn test_parse_spawn() {
941 let input = "let v: agentref = spawn Voter;";
942 let mut parser = Parser::new(input);
943 let stmt = parser.parse_stmt().unwrap();
944 if let Stmt::Let { ty: Type::AgentRef, value: Expr::Spawn { agent_name, node_addr }, .. } = stmt {
945 assert_eq!(agent_name, "Voter");
946 assert_eq!(node_addr, None);
947 } else {
948 panic!("Expected spawn in let binding");
949 }
950 }
951
952 #[test]
953 fn test_parse_spawn_remote() {
954 let input = r#"let v: agentref = spawn remote "10.0.0.1:7373" Voter;"#;
955 let mut parser = Parser::new(input);
956 let stmt = parser.parse_stmt().unwrap();
957 if let Stmt::Let { ty: Type::AgentRef, value: Expr::Spawn { agent_name, node_addr }, .. } = stmt {
958 assert_eq!(agent_name, "Voter");
959 assert_eq!(node_addr, Some("10.0.0.1:7373".to_string()));
960 } else {
961 panic!("Expected remote spawn in let binding");
962 }
963 }
964
965 #[test]
966 fn test_parse_send() {
967 let input = "send v 1;";
968 let mut parser = Parser::new(input);
969 let stmt = parser.parse_stmt().unwrap();
970 assert!(matches!(stmt, Stmt::Send { .. }));
971 }
972
973 #[test]
974 fn test_parse_await() {
975 let input = "let reply: trit = await v;";
976 let mut parser = Parser::new(input);
977 let stmt = parser.parse_stmt().unwrap();
978 if let Stmt::Let { value: Expr::Await { .. }, .. } = stmt {
979 } else {
981 panic!("Expected await in let binding");
982 }
983 }
984}