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() {
71 if let Some(main_fn) = functions.iter_mut().find(|f| f.name == "main") {
72 let mut decls: Vec<Stmt> = Vec::new();
75 for s in toplevel_stmts {
76 match &s {
77 Stmt::Expr(Expr::Call { callee, .. }) if callee == "main" => {
78 }
80 _ => decls.push(s),
81 }
82 }
83 let mut new_body = decls;
85 new_body.append(&mut main_fn.body);
86 main_fn.body = new_body;
87 } else {
88 functions.push(Function {
90 name: "main".to_string(),
91 params: vec![],
92 return_type: Type::Trit,
93 body: toplevel_stmts,
94 directive: None,
95 });
96 }
97 }
98
99 Ok(Program { imports, import_specs, structs, agents, functions })
100 }
101
102 pub fn parse_agent_def(&mut self) -> Result<AgentDef, ParseError> {
103 self.expect(Token::Agent)?;
104 let name = match self.next_token()? {
105 Token::Ident(n) => n,
106 t => return Err(ParseError::ExpectedToken("agent name".into(), format!("{:?}", t))),
107 };
108 self.expect(Token::LBrace)?;
109 let mut methods = Vec::new();
110 while self.peek_token()? != Token::RBrace {
111 methods.push(self.parse_function()?);
112 }
113 self.expect(Token::RBrace)?;
114 Ok(AgentDef { name, methods })
115 }
116
117 pub fn parse_struct_def(&mut self) -> Result<StructDef, ParseError> {
118 self.expect(Token::Struct)?;
119 let name = match self.next_token()? {
120 Token::Ident(n) => n,
121 t => return Err(ParseError::ExpectedToken("struct name".into(), format!("{:?}", t))),
122 };
123 self.expect(Token::LBrace)?;
124 let mut fields = Vec::new();
125 while self.peek_token()? != Token::RBrace {
126 let field_name = match self.next_token()? {
127 Token::Ident(n) => n,
128 t => return Err(ParseError::ExpectedToken("field name".into(), format!("{:?}", t))),
129 };
130 self.expect(Token::Colon)?;
131 let field_type = self.parse_type()?;
132 fields.push((field_name, field_type));
133 if let Ok(Token::Comma) = self.peek_token() { self.next_token()?; }
134 }
135 self.expect(Token::RBrace)?;
136 Ok(StructDef { name, fields })
137 }
138
139 pub fn parse_function(&mut self) -> Result<Function, ParseError> {
140 let directive = if let Ok(Token::At) = self.peek_token() {
141 self.next_token()?;
142 let dir = match self.next_token()? {
143 Token::SparseSkip => "sparseskip".to_string(),
144 Token::Ident(n) => n,
145 t => return Err(ParseError::ExpectedToken("directive".into(), format!("{:?}", t))),
146 };
147 Some(dir)
148 } else {
149 None
150 };
151
152 self.expect(Token::Fn)?;
153 let name = match self.next_token()? {
154 Token::Ident(n) => n,
155 t => return Err(ParseError::ExpectedToken("function name".into(), format!("{:?}", t))),
156 };
157
158 self.expect(Token::LParen)?;
159 let mut params = Vec::new();
160 if self.peek_token()? != Token::RParen {
161 loop {
162 let p_name = match self.next_token()? {
163 Token::Ident(n) => n,
164 t => return Err(ParseError::ExpectedToken("parameter name".into(), format!("{:?}", t))),
165 };
166 self.expect(Token::Colon)?;
167 let p_type = self.parse_type()?;
168 params.push((p_name, p_type));
169 if self.peek_token()? == Token::Comma { self.next_token()?; } else { break; }
170 }
171 }
172 self.expect(Token::RParen)?;
173 self.expect(Token::Arrow)?;
174 let return_type = self.parse_type()?;
175 let body = match self.parse_block()? {
176 Stmt::Block(stmts) => stmts,
177 _ => unreachable!(),
178 };
179 Ok(Function { name, params, return_type, body, directive })
180 }
181
182 fn next_token(&mut self) -> Result<Token, ParseError> {
183 self.lex.next()
184 .map(|res| res.map_err(|_| ParseError::UnexpectedToken("Invalid token".into())))
185 .transpose()?
186 .ok_or(ParseError::UnexpectedToken("EOF".into()))
187 }
188
189 pub fn peek_token(&mut self) -> Result<Token, ParseError> {
190 let mut cloned = self.lex.clone();
191 match cloned.next() {
192 Some(Ok(t)) => Ok(t),
193 Some(Err(_)) => Err(ParseError::UnexpectedToken("Invalid token during peek".into())),
194 None => Err(ParseError::UnexpectedToken("EOF".into())),
195 }
196 }
197
198 pub fn parse_expr(&mut self) -> Result<Expr, ParseError> {
199 self.parse_binary_expr(0)
200 }
201
202 fn parse_binary_expr(&mut self, min_prec: i8) -> Result<Expr, ParseError> {
203 let mut lhs = self.parse_unary_expr()?;
204 loop {
205 let Ok(op_token) = self.peek_token() else { break };
206 if op_token == Token::RBrace || op_token == Token::Comma || op_token == Token::RParen || op_token == Token::Semicolon || op_token == Token::Return { break; }
207 let prec = self.get_precedence(&op_token);
208 if prec < min_prec { break; }
209 self.next_token()?;
210 let rhs = self.parse_binary_expr(prec + 1)?;
211 lhs = Expr::BinaryOp {
212 op: self.token_to_binop(op_token),
213 lhs: Box::new(lhs),
214 rhs: Box::new(rhs),
215 };
216 }
217 Ok(lhs)
218 }
219
220 fn get_precedence(&self, token: &Token) -> i8 {
221 match token {
222 Token::Or => 0,
223 Token::And => 1,
224 Token::Equal | Token::NotEqual => 2,
225 Token::LAngle | Token::RAngle => 2, Token::LessEqual | Token::GreaterEqual => 2,
227 Token::Plus | Token::Minus => 3,
228 Token::Star | Token::Slash | Token::Percent => 4,
229 _ => -1,
230 }
231 }
232
233 fn token_to_binop(&self, token: Token) -> BinOp {
234 match token {
235 Token::Plus => BinOp::Add,
236 Token::Minus => BinOp::Sub,
237 Token::Star => BinOp::Mul,
238 Token::Slash => BinOp::Div,
239 Token::Percent => BinOp::Mod,
240 Token::Equal => BinOp::Equal,
241 Token::NotEqual => BinOp::NotEqual,
242 Token::And => BinOp::And,
243 Token::Or => BinOp::Or,
244 Token::LAngle => BinOp::Less,
245 Token::RAngle => BinOp::Greater,
246 Token::LessEqual => BinOp::LessEqual,
247 Token::GreaterEqual => BinOp::GreaterEqual,
248 _ => unreachable!(),
249 }
250 }
251
252 fn parse_unary_expr(&mut self) -> Result<Expr, ParseError> {
254 let mut expr = self.parse_primary_expr()?;
255 loop {
256 match self.peek_token()? {
257 Token::Dot => {
258 self.next_token()?; let field = match self.next_token()? {
260 Token::Ident(n) => n,
261 t => return Err(ParseError::ExpectedToken("field name".into(), format!("{:?}", t))),
262 };
263 expr = Expr::FieldAccess { object: Box::new(expr), field };
264 }
265 Token::LBracket => {
266 self.next_token()?; let row_or_start = self.parse_expr()?;
268 if let Ok(Token::Range) = self.peek_token() {
269 self.next_token()?; let end = self.parse_expr()?;
271 let stride = if let Ok(Token::Semicolon) = self.peek_token() {
272 self.next_token()?;
273 self.parse_expr()?
274 } else {
275 Expr::IntLiteral(1)
276 };
277 self.expect(Token::RBracket)?;
278 expr = Expr::Slice {
279 object: Box::new(expr),
280 start: Box::new(row_or_start),
281 end: Box::new(end),
282 stride: Box::new(stride),
283 };
284 } else if let Ok(Token::Comma) = self.peek_token() {
285 self.next_token()?; let col = self.parse_expr()?;
287 self.expect(Token::RBracket)?;
288 expr = Expr::Index { object: Box::new(expr), row: Box::new(row_or_start), col: Box::new(col) };
289 } else {
290 self.expect(Token::RBracket)?;
291 expr = Expr::Index { object: Box::new(expr), row: Box::new(row_or_start), col: Box::new(Expr::IntLiteral(-1)) };
293 }
294 }
295 Token::UncertainBranch => {
296 let mut lookahead = self.lex.clone();
300 lookahead.next(); let after_q = lookahead.next();
302 let is_uncertain_branch = matches!(after_q, Some(Ok(Token::LBrace)));
303 if !is_uncertain_branch {
304 self.next_token()?; expr = Expr::Propagate { expr: Box::new(expr) };
306 } else {
307 break;
308 }
309 }
310 _ => break,
311 }
312 }
313 Ok(expr)
314 }
315
316 fn parse_primary_expr(&mut self) -> Result<Expr, ParseError> {
317 let token = self.next_token()?;
318 match token {
319 Token::Spawn => {
322 let node_addr = if let Ok(Token::Remote) = self.peek_token() {
323 self.next_token()?; match self.next_token()? {
325 Token::StringLit(addr) => Some(addr),
326 t => return Err(ParseError::ExpectedToken("node address string".into(), format!("{:?}", t))),
327 }
328 } else {
329 None
330 };
331 let agent_name = match self.next_token()? {
332 Token::Ident(n) => n,
333 t => return Err(ParseError::ExpectedToken("agent name".into(), format!("{:?}", t))),
334 };
335 Ok(Expr::Spawn { agent_name, node_addr })
336 }
337 Token::Await => {
339 let target = self.parse_unary_expr()?;
340 Ok(Expr::Await { target: Box::new(target) })
341 }
342 Token::NodeId => Ok(Expr::NodeId),
343 Token::Minus => {
344 let expr = self.parse_unary_expr()?;
345 Ok(Expr::UnaryOp { op: UnOp::Neg, expr: Box::new(expr) })
346 }
347 Token::LBracket => {
348 let mut vals = Vec::new();
349 loop {
350 match self.next_token()? {
351 Token::TritLiteral => {
352 let s = self.lex.slice();
353 let v = s.parse::<i8>().unwrap_or(0);
354 vals.push(v);
355 }
356 Token::Int(v) => vals.push(v as i8),
357 Token::Minus => {
358 match self.next_token()? {
359 Token::Int(v) => vals.push(-(v as i8)),
360 t => return Err(ParseError::UnexpectedToken(format!("tensor literal element after '-': {:?}", t))),
361 }
362 }
363 Token::Affirm => vals.push(1),
364 Token::Tend => vals.push(0),
365 Token::Reject => vals.push(-1),
366 t => return Err(ParseError::UnexpectedToken(format!("tensor literal element: {:?}", t))),
367 }
368 if self.peek_token()? == Token::Comma {
369 self.next_token()?;
370 } else {
371 break;
372 }
373 }
374 self.expect(Token::RBracket)?;
375 Ok(Expr::TritTensorLiteral(vals))
376 }
377 Token::TritLiteral => {
378 let slice = self.lex.slice();
379 let val = slice.parse::<i8>()
380 .map_err(|_| ParseError::InvalidTrit(slice.to_string()))?;
381 Ok(Expr::TritLiteral(val))
382 }
383 Token::Affirm => Ok(Expr::TritLiteral(1)),
385 Token::Tend => Ok(Expr::TritLiteral(0)),
386 Token::Reject => Ok(Expr::TritLiteral(-1)),
387 Token::Int(val) => Ok(Expr::IntLiteral(val)),
388 Token::Float(val) => Ok(Expr::FloatLiteral(val)),
389 Token::StringLit(s) => Ok(Expr::StringLiteral(s)),
390 Token::Ident(name) => {
391 if name == "cast" {
393 if let Ok(Token::LParen) = self.peek_token() {
394 self.next_token()?;
395 let inner = self.parse_expr()?;
396 self.expect(Token::RParen)?;
397 return Ok(Expr::Cast { expr: Box::new(inner), ty: Type::Trit });
400 }
401 }
402
403 if let Ok(Token::LParen) = self.peek_token() {
404 self.next_token()?;
406 let mut args = Vec::new();
407 if self.peek_token()? != Token::RParen {
408 loop {
409 args.push(self.parse_expr()?);
410 if self.peek_token()? == Token::Comma {
411 self.next_token()?;
412 } else {
413 break;
414 }
415 }
416 }
417 self.expect(Token::RParen)?;
418 Ok(Expr::Call { callee: name, args })
419 } else if let Ok(Token::LBrace) = self.peek_token() {
420 let mut lookahead = self.lex.clone();
424 let _ = lookahead.next(); let maybe_ident = lookahead.next();
426 let maybe_colon = lookahead.next();
427
428 let is_struct_literal = matches!(maybe_ident, Some(Ok(Token::Ident(_)))) &&
429 matches!(maybe_colon, Some(Ok(Token::Colon)));
430
431 if is_struct_literal {
432 self.next_token()?; let mut fields = Vec::new();
434 while self.peek_token()? != Token::RBrace {
435 let f_name = match self.next_token()? {
436 Token::Ident(n) => n,
437 t => return Err(ParseError::ExpectedToken("field name".into(), format!("{:?}", t))),
438 };
439 self.expect(Token::Colon)?;
440 let f_val = self.parse_expr()?;
441 fields.push((f_name, f_val));
442 if let Ok(Token::Comma) = self.peek_token() {
443 self.next_token()?;
444 } else {
445 break;
446 }
447 }
448 self.expect(Token::RBrace)?;
449 Ok(Expr::StructLiteral { name, fields })
450 } else {
451 Ok(Expr::Ident(name))
452 }
453 } else {
454 Ok(Expr::Ident(name))
455 }
456 }
457 Token::LParen => {
458 let expr = self.parse_expr()?;
459 self.expect(Token::RParen)?;
460 Ok(expr)
461 }
462 _ => Err(ParseError::UnexpectedToken(format!("{:?}", token))),
463 }
464 }
465
466 pub fn parse_stmt(&mut self) -> Result<Stmt, ParseError> {
467 let token = self.peek_token()?;
468 match token {
469 Token::At => {
470 self.next_token()?;
471 let dir = match self.next_token()? {
472 Token::SparseSkip => "sparseskip".to_string(),
473 Token::Ident(n) => n,
474 t => return Err(ParseError::ExpectedToken("directive".into(), format!("{:?}", t))),
475 };
476 let stmt = self.parse_stmt()?;
477 Ok(Stmt::Decorated { directive: dir, stmt: Box::new(stmt) })
478 }
479
480 Token::Use => {
481 self.next_token()?;
482 let mut path = Vec::new();
483 loop {
484 let segment = match self.next_token()? {
486 Token::Ident(n) => n,
487 Token::TritType => "trit".to_string(),
488 Token::TritTensor => "trittensor".to_string(),
489 t => return Err(ParseError::ExpectedToken("module path segment".into(), format!("{:?}", t))),
490 };
491 path.push(segment);
492 if let Ok(Token::DoubleColon) = self.peek_token() {
493 self.next_token()?;
494 } else {
495 break;
496 }
497 }
498 self.expect(Token::Semicolon)?;
499 Ok(Stmt::Use { path })
500 }
501
502 Token::From => {
504 self.next_token()?;
505 let source = match self.peek_token()? {
507 Token::StringLit(_) => {
508 if let Token::StringLit(s) = self.next_token()? {
509 ImportSource::File(s)
510 } else { unreachable!() }
511 }
512 _ => {
513 let mut path = Vec::new();
514 loop {
515 let segment = match self.next_token()? {
516 Token::Ident(n) => n,
517 Token::TritType => "trit".to_string(),
518 Token::TritTensor => "trittensor".to_string(),
519 t => return Err(ParseError::ExpectedToken("module path segment".into(), format!("{:?}", t))),
520 };
521 path.push(segment);
522 if let Ok(Token::DoubleColon) = self.peek_token() {
523 self.next_token()?;
524 } else {
525 break;
526 }
527 }
528 ImportSource::Module(path)
529 }
530 };
531 self.expect(Token::Import)?;
532 let names = if let Ok(Token::Star) = self.peek_token() {
534 self.next_token()?;
535 ImportNames::Wildcard
536 } else {
537 let mut named = Vec::new();
538 loop {
539 match self.next_token()? {
540 Token::Ident(n) => named.push(n),
541 t => return Err(ParseError::ExpectedToken("import name".into(), format!("{:?}", t))),
542 }
543 if let Ok(Token::Comma) = self.peek_token() {
544 self.next_token()?;
545 } else {
546 break;
547 }
548 }
549 ImportNames::Named(named)
550 };
551 self.expect(Token::Semicolon)?;
552 Ok(Stmt::FromImport { spec: ImportSpec { source, names } })
553 }
554
555 Token::Let => {
556 self.next_token()?;
557 let _mutable = if let Ok(Token::Mut) = self.peek_token() {
559 self.next_token()?; true
560 } else { false };
561
562 let name = match self.next_token()? {
563 Token::Ident(n) => n,
564 t => return Err(ParseError::ExpectedToken("identifier".into(), format!("{:?}", t))),
565 };
566 self.expect(Token::Colon)?;
567 let ty = self.parse_type()?;
568 let value = if let Ok(Token::Assign) = self.peek_token() {
569 self.next_token()?;
570 self.parse_expr()?
571 } else {
572 Expr::TritLiteral(0)
573 };
574 self.expect(Token::Semicolon)?;
575 Ok(Stmt::Let { name, ty, value })
576 }
577
578 Token::If => {
579 self.next_token()?;
580 let condition = self.parse_expr()?;
581 if let Ok(Token::UncertainBranch) = self.peek_token() {
582 self.next_token()?;
583 let on_pos = Box::new(self.parse_block()?);
584 self.expect(Token::Else)?;
585 let on_zero = Box::new(self.parse_block()?);
586 self.expect(Token::Else)?;
587 let on_neg = Box::new(self.parse_block()?);
588 Ok(Stmt::IfTernary { condition, on_pos, on_zero, on_neg })
589 } else {
590 let then_branch = Box::new(self.parse_block()?);
593 let else_branch = if let Ok(Token::Else) = self.peek_token() {
594 self.next_token()?;
595 if let Ok(Token::If) = self.peek_token() {
597 Box::new(self.parse_stmt()?)
598 } else {
599 Box::new(self.parse_block()?)
600 }
601 } else {
602 Box::new(Stmt::Block(vec![]))
603 };
604 Ok(Stmt::IfTernary {
605 condition,
606 on_pos: then_branch,
607 on_zero: else_branch.clone(),
608 on_neg: else_branch,
609 })
610 }
611 }
612
613 Token::Match => {
614 self.next_token()?;
615 let condition = self.parse_expr()?;
616 self.expect(Token::LBrace)?;
617 let mut arms = Vec::new();
618 while self.peek_token()? != Token::RBrace {
619 let pattern = match self.next_token()? {
620 Token::TritLiteral => {
621 let slice = self.lex.slice();
622 Pattern::Trit(slice.parse::<i8>().map_err(|_| ParseError::InvalidTrit(slice.to_string()))?)
623 }
624 Token::Int(v) => Pattern::Int(v),
625 Token::Float(v) => Pattern::Float(v),
626 Token::Minus => {
627 match self.next_token()? {
628 Token::Int(v) => Pattern::Int(-v),
629 Token::Float(v) => Pattern::Float(-v),
630 t => return Err(ParseError::ExpectedToken("number literal after '-'".into(), format!("{:?}", t))),
631 }
632 }
633 Token::Affirm => Pattern::Trit(1),
634 Token::Tend => Pattern::Trit(0),
635 Token::Reject => Pattern::Trit(-1),
636 Token::Ident(ref s) if s == "_" => Pattern::Wildcard,
637 t => return Err(ParseError::ExpectedToken("pattern (int, float, trit, or _)".into(), format!("{:?}", t))),
638 };
639 self.expect(Token::FatArrow)?;
640 let stmt = self.parse_stmt()?;
641 arms.push((pattern, stmt));
642 }
643 self.expect(Token::RBrace)?;
644
645 Ok(Stmt::Match { condition, arms })
646 }
647
648 Token::For => {
650 self.next_token()?;
651 let var = match self.next_token()? {
652 Token::Ident(n) => n,
653 t => return Err(ParseError::ExpectedToken("loop variable".into(), format!("{:?}", t))),
654 };
655 self.expect(Token::In)?;
656 let iter = self.parse_expr()?;
657 let body = Box::new(self.parse_block()?);
658 Ok(Stmt::ForIn { var, iter, body })
659 }
660
661 Token::While => {
663 self.next_token()?;
664 let condition = self.parse_expr()?;
665 if let Ok(Token::UncertainBranch) = self.peek_token() {
666 self.next_token()?;
667 let on_pos = Box::new(self.parse_block()?);
668 self.expect(Token::Else)?;
669 let on_zero = Box::new(self.parse_block()?);
670 self.expect(Token::Else)?;
671 let on_neg = Box::new(self.parse_block()?);
672 Ok(Stmt::WhileTernary { condition, on_pos, on_zero, on_neg })
673 } else {
674 let body = Box::new(self.parse_block()?);
677 let (on_zero, on_neg) = if let Ok(Token::Else) = self.peek_token() {
678 self.next_token()?;
679 let zero = Box::new(self.parse_block()?);
680 self.expect(Token::Else)?;
681 let neg = Box::new(self.parse_block()?);
682 (zero, neg)
683 } else {
684 (Box::new(Stmt::Break), Box::new(Stmt::Break))
685 };
686 Ok(Stmt::WhileTernary {
687 condition,
688 on_pos: body,
689 on_zero,
690 on_neg,
691 })
692 }
693 }
694
695 Token::Loop => {
697 self.next_token()?;
698 let body = Box::new(self.parse_block()?);
699 Ok(Stmt::Loop { body })
700 }
701
702 Token::Send => {
704 self.next_token()?;
705 let target = self.parse_expr()?;
706 let message = self.parse_expr()?;
707 self.expect(Token::Semicolon)?;
708 Ok(Stmt::Send { target, message })
709 }
710
711 Token::Break => {
712 self.next_token()?;
713 self.expect(Token::Semicolon)?;
714 Ok(Stmt::Break)
715 }
716
717 Token::Continue => {
718 self.next_token()?;
719 self.expect(Token::Semicolon)?;
720 Ok(Stmt::Continue)
721 }
722
723 Token::Return => {
724 self.next_token()?;
725 let expr = self.parse_expr()?;
726 self.expect(Token::Semicolon)?;
727 Ok(Stmt::Return(expr))
728 }
729
730 Token::LBrace => self.parse_block(),
731
732 Token::Fn => Err(ParseError::UnexpectedToken("Fn".into())),
737
738 _ => {
739 let expr = self.parse_expr()?;
741
742 if let Ok(Token::Assign) = self.peek_token() {
744 match expr {
745 Expr::FieldAccess { object, field } => {
746 if let Expr::Ident(obj_name) = *object {
747 self.next_token()?; let value = self.parse_expr()?;
749 self.expect(Token::Semicolon)?;
750 return Ok(Stmt::FieldSet { object: obj_name, field, value });
751 }
752 }
753 Expr::Index { object, row, col } => {
754 if let Expr::Ident(obj_name) = *object {
755 self.next_token()?; let value = self.parse_expr()?;
757 self.expect(Token::Semicolon)?;
758 return Ok(Stmt::IndexSet { object: obj_name, row: *row, col: *col, value });
759 }
760 }
761 Expr::Ident(name) => {
762 self.next_token()?; let value = self.parse_expr()?;
764 self.expect(Token::Semicolon)?;
765 return Ok(Stmt::Set { name, value });
766 }
767 _ => {}
768 }
769 return Err(ParseError::UnexpectedToken("invalid assignment target".into()));
770 }
771
772 self.expect(Token::Semicolon)?;
773 Ok(Stmt::Expr(expr))
774 }
775 }
776 }
777
778 fn parse_block(&mut self) -> Result<Stmt, ParseError> {
779 self.expect(Token::LBrace)?;
780 let mut stmts = Vec::new();
781 while self.peek_token()? != Token::RBrace {
782 stmts.push(self.parse_stmt()?);
783 }
784 self.expect(Token::RBrace)?;
785 Ok(Stmt::Block(stmts))
786 }
787
788 fn parse_type(&mut self) -> Result<Type, ParseError> {
789 let token = self.next_token()?;
790 match token {
791 Token::SparseSkip => Ok(Type::Trit), Token::Packed => {
793 self.expect(Token::TritType)?;
794 if let Ok(Token::LBracket) = self.peek_token() {
795 self.next_token()?;
796 let dim = if let Ok(Token::Int(n)) = self.peek_token() {
797 self.next_token()?;
798 n as usize
799 } else { 0 };
800 self.expect(Token::RBracket)?;
801 Ok(Type::PackedTritTensor { dims: vec![dim] })
802 } else {
803 Ok(Type::PackedTritTensor { dims: vec![0] })
804 }
805 }
806 Token::TritType => {
807 if let Ok(Token::LBracket) = self.peek_token() {
808 self.next_token()?;
809 let dim = if let Ok(Token::Int(n)) = self.peek_token() {
810 self.next_token()?;
811 n as usize
812 } else { 0 };
813 self.expect(Token::RBracket)?;
814 Ok(Type::TritTensor { dims: vec![dim] })
815 } else {
816 Ok(Type::Trit)
817 }
818 }
819 Token::AgentRef => Ok(Type::AgentRef),
820 Token::TritTensor => {
821 self.expect(Token::LAngle)?;
822 let mut dims = Vec::new();
823 loop {
824 let d = match self.next_token()? {
825 Token::Int(v) => v as usize,
826 Token::TritLiteral => {
828 let s = self.lex.slice();
829 s.parse::<i8>().unwrap_or(0).max(0) as usize
830 }
831 t => return Err(ParseError::ExpectedToken("dimension".into(), format!("{:?}", t))),
832 };
833 dims.push(d);
834 if self.peek_token()? == Token::Ident("x".to_string()) {
835 self.next_token()?;
836 } else {
837 break;
838 }
839 }
840 self.expect(Token::RAngle)?;
841 Ok(Type::TritTensor { dims })
842 }
843 Token::Ident(ref name) => match name.as_str() {
844 "int" => {
845 match self.peek_token() {
846 Ok(Token::LBracket) => {
847 self.next_token()?; let dim = if let Ok(Token::Int(n)) = self.peek_token() {
849 self.next_token()?;
850 n as usize
851 } else { 0 };
852 self.expect(Token::RBracket)?;
853 Ok(Type::IntTensor { dims: vec![dim] })
854 }
855 _ => Ok(Type::Int)
856 }
857 }
858 "float" => {
859 match self.peek_token() {
860 Ok(Token::LBracket) => {
861 self.next_token()?; let dim = if let Ok(Token::Int(n)) = self.peek_token() {
863 self.next_token()?;
864 n as usize
865 } else { 0 };
866 self.expect(Token::RBracket)?;
867 Ok(Type::FloatTensor { dims: vec![dim] })
868 }
869 _ => Ok(Type::Float)
870 }
871 }
872 "bool" => Ok(Type::Bool),
873 "string" => Ok(Type::String),
874 _ => Ok(Type::Named(name.clone())),
876 },
877 _ => Err(ParseError::UnexpectedToken(format!("{:?}", token))),
878 }
879 }
880
881 fn expect(&mut self, expected: Token) -> Result<(), ParseError> {
882 let token = self.next_token()?;
883 if token == expected {
884 Ok(())
885 } else {
886 Err(ParseError::ExpectedToken(format!("{:?}", expected), format!("{:?}", token)))
887 }
888 }
889}
890
891#[cfg(test)]
892mod tests {
893 use super::*;
894
895 #[test]
896 fn test_parse_function() {
897 let input = "fn invert(signal: trit) -> trit { return -signal; }";
898 let mut parser = Parser::new(input);
899 let func = parser.parse_function().unwrap();
900 assert_eq!(func.name, "invert");
901 assert_eq!(func.params[0].1, Type::Trit);
902 assert_eq!(func.return_type, Type::Trit);
903 }
904
905 #[test]
906 fn test_parse_match() {
907 let input = "match x { 1 => return 1; 0 => return 0; -1 => return -1; }";
908 let mut parser = Parser::new(input);
909 let stmt = parser.parse_stmt().unwrap();
910 if let Stmt::Match { arms, .. } = stmt {
911 use crate::ast::Pattern;
912 assert_eq!(arms.len(), 3);
913 assert_eq!(arms[0].0, Pattern::Int(1));
914 assert_eq!(arms[1].0, Pattern::Int(0));
915 assert_eq!(arms[2].0, Pattern::Int(-1));
916 } else {
917 panic!("Expected Match");
918 }
919 }
920
921 #[test]
922 fn test_match_parses_non_exhaustive() {
923 let input = "match x { 1 => return 1; -1 => return -1; }";
925 let mut parser = Parser::new(input);
926 let result = parser.parse_stmt();
927 assert!(result.is_ok(), "should parse successfully even if non-exhaustive");
928 }
929
930 #[test]
931 fn test_parse_for_loop() {
932 let input = "for item in weights { return item; }";
933 let mut parser = Parser::new(input);
934 let stmt = parser.parse_stmt().unwrap();
935 assert!(matches!(stmt, Stmt::ForIn { .. }));
936 }
937
938 #[test]
939 fn test_parse_loop_break() {
940 let input = "loop { break; }";
941 let mut parser = Parser::new(input);
942 let stmt = parser.parse_stmt().unwrap();
943 assert!(matches!(stmt, Stmt::Loop { .. }));
944 }
945
946 #[test]
947 fn test_parse_use() {
948 let input = "use std::trit;";
949 let mut parser = Parser::new(input);
950 let stmt = parser.parse_stmt().unwrap();
951 if let Stmt::Use { path } = stmt {
952 assert_eq!(path, vec!["std", "trit"]);
953 } else {
954 panic!("Expected Use");
955 }
956 }
957
958 #[test]
959 fn test_parse_mut_let() {
960 let input = "let mut signal: trit = 1;";
961 let mut parser = Parser::new(input);
962 let stmt = parser.parse_stmt().unwrap();
963 assert!(matches!(stmt, Stmt::Let { .. }));
964 }
965
966 #[test]
967 fn test_parse_struct_def() {
968 let input = "struct Signal { value: trit, weight: trit }";
969 let mut parser = Parser::new(input);
970 let s = parser.parse_struct_def().unwrap();
971 assert_eq!(s.name, "Signal");
972 assert_eq!(s.fields.len(), 2);
973 assert_eq!(s.fields[0], ("value".to_string(), Type::Trit));
974 assert_eq!(s.fields[1], ("weight".to_string(), Type::Trit));
975 }
976
977 #[test]
978 fn test_parse_field_access() {
979 let input = "let v: trit = sig.value;";
980 let mut parser = Parser::new(input);
981 let stmt = parser.parse_stmt().unwrap();
982 if let Stmt::Let { value: Expr::FieldAccess { field, .. }, .. } = stmt {
983 assert_eq!(field, "value");
984 } else {
985 panic!("Expected FieldAccess in let binding");
986 }
987 }
988
989 #[test]
990 fn test_parse_field_set() {
991 let input = "sig.value = 1;";
992 let mut parser = Parser::new(input);
993 let stmt = parser.parse_stmt().unwrap();
994 assert!(matches!(stmt, Stmt::FieldSet { .. }));
995 }
996
997 #[test]
998 fn test_parse_cast() {
999 let input = "let t: trit = cast(flag);";
1000 let mut parser = Parser::new(input);
1001 let stmt = parser.parse_stmt().unwrap();
1002 if let Stmt::Let { value: Expr::Cast { .. }, .. } = stmt {
1003 } else {
1005 panic!("Expected Cast in let binding");
1006 }
1007 }
1008
1009 #[test]
1010 fn test_parse_named_type() {
1011 let input = "let s: Signal;";
1012 let mut parser = Parser::new(input);
1013 let stmt = parser.parse_stmt().unwrap();
1014 if let Stmt::Let { ty: Type::Named(name), .. } = stmt {
1015 assert_eq!(name, "Signal");
1016 } else {
1017 panic!("Expected Named type");
1018 }
1019 }
1020
1021 #[test]
1022 fn test_parse_agent_def() {
1023 let input = r#"
1024 agent Voter {
1025 fn handle(msg: trit) -> trit {
1026 match msg {
1027 1 => { return 1; }
1028 0 => { return 0; }
1029 -1 => { return -1; }
1030 }
1031 }
1032 }
1033 "#;
1034 let mut parser = Parser::new(input);
1035 let agent = parser.parse_agent_def().unwrap();
1036 assert_eq!(agent.name, "Voter");
1037 assert_eq!(agent.methods.len(), 1);
1038 assert_eq!(agent.methods[0].name, "handle");
1039 }
1040
1041 #[test]
1042 fn test_parse_spawn() {
1043 let input = "let v: agentref = spawn Voter;";
1044 let mut parser = Parser::new(input);
1045 let stmt = parser.parse_stmt().unwrap();
1046 if let Stmt::Let { ty: Type::AgentRef, value: Expr::Spawn { agent_name, node_addr }, .. } = stmt {
1047 assert_eq!(agent_name, "Voter");
1048 assert_eq!(node_addr, None);
1049 } else {
1050 panic!("Expected spawn in let binding");
1051 }
1052 }
1053
1054 #[test]
1055 fn test_parse_spawn_remote() {
1056 let input = r#"let v: agentref = spawn remote "10.0.0.1:7373" Voter;"#;
1057 let mut parser = Parser::new(input);
1058 let stmt = parser.parse_stmt().unwrap();
1059 if let Stmt::Let { ty: Type::AgentRef, value: Expr::Spawn { agent_name, node_addr }, .. } = stmt {
1060 assert_eq!(agent_name, "Voter");
1061 assert_eq!(node_addr, Some("10.0.0.1:7373".to_string()));
1062 } else {
1063 panic!("Expected remote spawn in let binding");
1064 }
1065 }
1066
1067 #[test]
1068 fn test_parse_send() {
1069 let input = "send v 1;";
1070 let mut parser = Parser::new(input);
1071 let stmt = parser.parse_stmt().unwrap();
1072 assert!(matches!(stmt, Stmt::Send { .. }));
1073 }
1074
1075 #[test]
1076 fn test_parse_await() {
1077 let input = "let reply: trit = await v;";
1078 let mut parser = Parser::new(input);
1079 let stmt = parser.parse_stmt().unwrap();
1080 if let Stmt::Let { value: Expr::Await { .. }, .. } = stmt {
1081 } else {
1083 panic!("Expected await in let binding");
1084 }
1085 }
1086}