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 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 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 fn peek_token(&mut self) -> Result<Token, ParseError> {
190 let mut cloned = self.lex.clone();
191 cloned.next()
192 .map(|res| res.map_err(|_| ParseError::UnexpectedToken("Invalid token".into())))
193 .transpose()?
194 .ok_or(ParseError::UnexpectedToken("EOF".into()))
195 }
196
197 pub fn parse_expr(&mut self) -> Result<Expr, ParseError> {
198 self.parse_binary_expr(0)
199 }
200
201 fn parse_binary_expr(&mut self, min_prec: i8) -> Result<Expr, ParseError> {
202 let mut lhs = self.parse_unary_expr()?;
203 loop {
204 let Ok(op_token) = self.peek_token() else { break };
205 if op_token == Token::RBrace || op_token == Token::Comma || op_token == Token::RParen || op_token == Token::Semicolon || op_token == Token::Return { break; }
206 let prec = self.get_precedence(&op_token);
207 if prec < min_prec { break; }
208 self.next_token()?;
209 let rhs = self.parse_binary_expr(prec + 1)?;
210 lhs = Expr::BinaryOp {
211 op: self.token_to_binop(op_token),
212 lhs: Box::new(lhs),
213 rhs: Box::new(rhs),
214 };
215 }
216 Ok(lhs)
217 }
218
219 fn get_precedence(&self, token: &Token) -> i8 {
220 match token {
221 Token::Or => 0,
222 Token::And => 1,
223 Token::Equal | Token::NotEqual => 2,
224 Token::LAngle | Token::RAngle => 2, Token::LessEqual | Token::GreaterEqual => 2,
226 Token::Plus | Token::Minus => 3,
227 Token::Star | Token::Slash | Token::Percent => 4,
228 _ => -1,
229 }
230 }
231
232 fn token_to_binop(&self, token: Token) -> BinOp {
233 match token {
234 Token::Plus => BinOp::Add,
235 Token::Minus => BinOp::Sub,
236 Token::Star => BinOp::Mul,
237 Token::Slash => BinOp::Div,
238 Token::Percent => BinOp::Mod,
239 Token::Equal => BinOp::Equal,
240 Token::NotEqual => BinOp::NotEqual,
241 Token::And => BinOp::And,
242 Token::Or => BinOp::Or,
243 Token::LAngle => BinOp::Less,
244 Token::RAngle => BinOp::Greater,
245 Token::LessEqual => BinOp::LessEqual,
246 Token::GreaterEqual => BinOp::GreaterEqual,
247 _ => unreachable!(),
248 }
249 }
250
251 fn parse_unary_expr(&mut self) -> Result<Expr, ParseError> {
253 let mut expr = self.parse_primary_expr()?;
254 loop {
255 match self.peek_token()? {
256 Token::Dot => {
257 self.next_token()?; let field = match self.next_token()? {
259 Token::Ident(n) => n,
260 t => return Err(ParseError::ExpectedToken("field name".into(), format!("{:?}", t))),
261 };
262 expr = Expr::FieldAccess { object: Box::new(expr), field };
263 }
264 Token::LBracket => {
265 self.next_token()?; let row = self.parse_expr()?;
267 if let Ok(Token::Comma) = self.peek_token() {
268 self.next_token()?; let col = self.parse_expr()?;
270 self.expect(Token::RBracket)?;
271 expr = Expr::Index { object: Box::new(expr), row: Box::new(row), col: Box::new(col) };
272 } else {
273 self.expect(Token::RBracket)?;
274 expr = Expr::Index { object: Box::new(expr), row: Box::new(row), col: Box::new(Expr::IntLiteral(0)) };
276 }
277 }
278 Token::UncertainBranch => {
279 let mut lookahead = self.lex.clone();
283 lookahead.next(); let after_q = lookahead.next();
285 let is_uncertain_branch = matches!(after_q, Some(Ok(Token::LBrace)));
286 if !is_uncertain_branch {
287 self.next_token()?; expr = Expr::Propagate { expr: Box::new(expr) };
289 } else {
290 break;
291 }
292 }
293 _ => break,
294 }
295 }
296 Ok(expr)
297 }
298
299 fn parse_primary_expr(&mut self) -> Result<Expr, ParseError> {
300 let token = self.next_token()?;
301 match token {
302 Token::Spawn => {
305 let node_addr = if let Ok(Token::Remote) = self.peek_token() {
306 self.next_token()?; match self.next_token()? {
308 Token::StringLit(addr) => Some(addr),
309 t => return Err(ParseError::ExpectedToken("node address string".into(), format!("{:?}", t))),
310 }
311 } else {
312 None
313 };
314 let agent_name = match self.next_token()? {
315 Token::Ident(n) => n,
316 t => return Err(ParseError::ExpectedToken("agent name".into(), format!("{:?}", t))),
317 };
318 Ok(Expr::Spawn { agent_name, node_addr })
319 }
320 Token::Await => {
322 let target = self.parse_unary_expr()?;
323 Ok(Expr::Await { target: Box::new(target) })
324 }
325 Token::NodeId => Ok(Expr::NodeId),
326 Token::Minus => {
327 let expr = self.parse_unary_expr()?;
328 Ok(Expr::UnaryOp { op: UnOp::Neg, expr: Box::new(expr) })
329 }
330 Token::LBracket => {
331 let mut vals = Vec::new();
332 loop {
333 match self.next_token()? {
334 Token::TritLiteral => {
335 let s = self.lex.slice();
336 let v = s.parse::<i8>().unwrap_or(0);
337 vals.push(v);
338 }
339 Token::Int(v) => vals.push(v as i8),
340 Token::Minus => {
341 match self.next_token()? {
342 Token::Int(v) => vals.push(-(v as i8)),
343 t => return Err(ParseError::UnexpectedToken(format!("tensor literal element after '-': {:?}", t))),
344 }
345 }
346 Token::Affirm => vals.push(1),
347 Token::Tend => vals.push(0),
348 Token::Reject => vals.push(-1),
349 t => return Err(ParseError::UnexpectedToken(format!("tensor literal element: {:?}", t))),
350 }
351 if self.peek_token()? == Token::Comma {
352 self.next_token()?;
353 } else {
354 break;
355 }
356 }
357 self.expect(Token::RBracket)?;
358 Ok(Expr::TritTensorLiteral(vals))
359 }
360 Token::TritLiteral => {
361 let slice = self.lex.slice();
362 let val = slice.parse::<i8>()
363 .map_err(|_| ParseError::InvalidTrit(slice.to_string()))?;
364 Ok(Expr::TritLiteral(val))
365 }
366 Token::Affirm => Ok(Expr::TritLiteral(1)),
368 Token::Tend => Ok(Expr::TritLiteral(0)),
369 Token::Reject => Ok(Expr::TritLiteral(-1)),
370 Token::Int(val) => Ok(Expr::IntLiteral(val)),
371 Token::Float(val) => Ok(Expr::FloatLiteral(val)),
372 Token::StringLit(s) => Ok(Expr::StringLiteral(s)),
373 Token::Ident(name) => {
374 if name == "cast" {
376 if let Ok(Token::LParen) = self.peek_token() {
377 self.next_token()?;
378 let inner = self.parse_expr()?;
379 self.expect(Token::RParen)?;
380 return Ok(Expr::Cast { expr: Box::new(inner), ty: Type::Trit });
383 }
384 }
385
386 if let Ok(Token::LParen) = self.peek_token() {
387 self.next_token()?;
389 let mut args = Vec::new();
390 if self.peek_token()? != Token::RParen {
391 loop {
392 args.push(self.parse_expr()?);
393 if self.peek_token()? == Token::Comma {
394 self.next_token()?;
395 } else {
396 break;
397 }
398 }
399 }
400 self.expect(Token::RParen)?;
401 Ok(Expr::Call { callee: name, args })
402 } else if let Ok(Token::LBrace) = self.peek_token() {
403 let mut lookahead = self.lex.clone();
407 let _ = lookahead.next(); let maybe_ident = lookahead.next();
409 let maybe_colon = lookahead.next();
410
411 let is_struct_literal = matches!(maybe_ident, Some(Ok(Token::Ident(_)))) &&
412 matches!(maybe_colon, Some(Ok(Token::Colon)));
413
414 if is_struct_literal {
415 self.next_token()?; let mut fields = Vec::new();
417 while self.peek_token()? != Token::RBrace {
418 let f_name = match self.next_token()? {
419 Token::Ident(n) => n,
420 t => return Err(ParseError::ExpectedToken("field name".into(), format!("{:?}", t))),
421 };
422 self.expect(Token::Colon)?;
423 let f_val = self.parse_expr()?;
424 fields.push((f_name, f_val));
425 if let Ok(Token::Comma) = self.peek_token() {
426 self.next_token()?;
427 } else {
428 break;
429 }
430 }
431 self.expect(Token::RBrace)?;
432 Ok(Expr::StructLiteral { name, fields })
433 } else {
434 Ok(Expr::Ident(name))
435 }
436 } else {
437 Ok(Expr::Ident(name))
438 }
439 }
440 Token::LParen => {
441 let expr = self.parse_expr()?;
442 self.expect(Token::RParen)?;
443 Ok(expr)
444 }
445 _ => Err(ParseError::UnexpectedToken(format!("{:?}", token))),
446 }
447 }
448
449 pub fn parse_stmt(&mut self) -> Result<Stmt, ParseError> {
450 let token = self.peek_token()?;
451 match token {
452 Token::At => {
453 self.next_token()?;
454 let dir = match self.next_token()? {
455 Token::SparseSkip => "sparseskip".to_string(),
456 Token::Ident(n) => n,
457 t => return Err(ParseError::ExpectedToken("directive".into(), format!("{:?}", t))),
458 };
459 let stmt = self.parse_stmt()?;
460 Ok(Stmt::Decorated { directive: dir, stmt: Box::new(stmt) })
461 }
462
463 Token::Use => {
464 self.next_token()?;
465 let mut path = Vec::new();
466 loop {
467 let segment = match self.next_token()? {
469 Token::Ident(n) => n,
470 Token::TritType => "trit".to_string(),
471 Token::TritTensor => "trittensor".to_string(),
472 t => return Err(ParseError::ExpectedToken("module path segment".into(), format!("{:?}", t))),
473 };
474 path.push(segment);
475 if let Ok(Token::DoubleColon) = self.peek_token() {
476 self.next_token()?;
477 } else {
478 break;
479 }
480 }
481 self.expect(Token::Semicolon)?;
482 Ok(Stmt::Use { path })
483 }
484
485 Token::From => {
487 self.next_token()?;
488 let source = match self.peek_token()? {
490 Token::StringLit(_) => {
491 if let Token::StringLit(s) = self.next_token()? {
492 ImportSource::File(s)
493 } else { unreachable!() }
494 }
495 _ => {
496 let mut path = Vec::new();
497 loop {
498 let segment = match self.next_token()? {
499 Token::Ident(n) => n,
500 Token::TritType => "trit".to_string(),
501 Token::TritTensor => "trittensor".to_string(),
502 t => return Err(ParseError::ExpectedToken("module path segment".into(), format!("{:?}", t))),
503 };
504 path.push(segment);
505 if let Ok(Token::DoubleColon) = self.peek_token() {
506 self.next_token()?;
507 } else {
508 break;
509 }
510 }
511 ImportSource::Module(path)
512 }
513 };
514 self.expect(Token::Import)?;
515 let names = if let Ok(Token::Star) = self.peek_token() {
517 self.next_token()?;
518 ImportNames::Wildcard
519 } else {
520 let mut named = Vec::new();
521 loop {
522 match self.next_token()? {
523 Token::Ident(n) => named.push(n),
524 t => return Err(ParseError::ExpectedToken("import name".into(), format!("{:?}", t))),
525 }
526 if let Ok(Token::Comma) = self.peek_token() {
527 self.next_token()?;
528 } else {
529 break;
530 }
531 }
532 ImportNames::Named(named)
533 };
534 self.expect(Token::Semicolon)?;
535 Ok(Stmt::FromImport { spec: ImportSpec { source, names } })
536 }
537
538 Token::Let => {
539 self.next_token()?;
540 let _mutable = if let Ok(Token::Mut) = self.peek_token() {
542 self.next_token()?; true
543 } else { false };
544
545 let name = match self.next_token()? {
546 Token::Ident(n) => n,
547 t => return Err(ParseError::ExpectedToken("identifier".into(), format!("{:?}", t))),
548 };
549 self.expect(Token::Colon)?;
550 let ty = self.parse_type()?;
551 let value = if let Ok(Token::Assign) = self.peek_token() {
552 self.next_token()?;
553 self.parse_expr()?
554 } else {
555 Expr::TritLiteral(0)
556 };
557 self.expect(Token::Semicolon)?;
558 Ok(Stmt::Let { name, ty, value })
559 }
560
561 Token::If => {
562 self.next_token()?;
563 let condition = self.parse_expr()?;
564 if let Ok(Token::UncertainBranch) = self.peek_token() {
565 self.next_token()?;
566 let on_pos = Box::new(self.parse_block()?);
567 self.expect(Token::Else)?;
568 let on_zero = Box::new(self.parse_block()?);
569 self.expect(Token::Else)?;
570 let on_neg = Box::new(self.parse_block()?);
571 Ok(Stmt::IfTernary { condition, on_pos, on_zero, on_neg })
572 } else {
573 let then_branch = Box::new(self.parse_block()?);
576 let else_branch = if let Ok(Token::Else) = self.peek_token() {
577 self.next_token()?;
578 Box::new(self.parse_block()?)
579 } else {
580 Box::new(Stmt::Block(vec![]))
581 };
582 Ok(Stmt::IfTernary {
583 condition,
584 on_pos: then_branch,
585 on_zero: else_branch.clone(),
586 on_neg: else_branch,
587 })
588 }
589 }
590
591 Token::Match => {
592 self.next_token()?;
593 let condition = self.parse_expr()?;
594 self.expect(Token::LBrace)?;
595 let mut arms = Vec::new();
596 while self.peek_token()? != Token::RBrace {
597 let pattern = match self.next_token()? {
598 Token::TritLiteral => {
599 let slice = self.lex.slice();
600 Pattern::Trit(slice.parse::<i8>().map_err(|_| ParseError::InvalidTrit(slice.to_string()))?)
601 }
602 Token::Int(v) => Pattern::Int(v),
603 Token::Float(v) => Pattern::Float(v),
604 Token::Minus => {
605 match self.next_token()? {
606 Token::Int(v) => Pattern::Int(-v),
607 Token::Float(v) => Pattern::Float(-v),
608 t => return Err(ParseError::ExpectedToken("number literal after '-'".into(), format!("{:?}", t))),
609 }
610 }
611 Token::Affirm => Pattern::Trit(1),
612 Token::Tend => Pattern::Trit(0),
613 Token::Reject => Pattern::Trit(-1),
614 t => return Err(ParseError::ExpectedToken("pattern (int, float or trit)".into(), format!("{:?}", t))),
615 };
616 self.expect(Token::FatArrow)?;
617 let stmt = self.parse_stmt()?;
618 arms.push((pattern, stmt));
619 }
620 self.expect(Token::RBrace)?;
621
622 Ok(Stmt::Match { condition, arms })
623 }
624
625 Token::For => {
627 self.next_token()?;
628 let var = match self.next_token()? {
629 Token::Ident(n) => n,
630 t => return Err(ParseError::ExpectedToken("loop variable".into(), format!("{:?}", t))),
631 };
632 self.expect(Token::In)?;
633 let iter = self.parse_expr()?;
634 let body = Box::new(self.parse_block()?);
635 Ok(Stmt::ForIn { var, iter, body })
636 }
637
638 Token::While => {
640 self.next_token()?;
641 let condition = self.parse_expr()?;
642 if let Ok(Token::UncertainBranch) = self.peek_token() {
643 self.next_token()?;
644 let on_pos = Box::new(self.parse_block()?);
645 self.expect(Token::Else)?;
646 let on_zero = Box::new(self.parse_block()?);
647 self.expect(Token::Else)?;
648 let on_neg = Box::new(self.parse_block()?);
649 Ok(Stmt::WhileTernary { condition, on_pos, on_zero, on_neg })
650 } else {
651 let body = Box::new(self.parse_block()?);
654 Ok(Stmt::WhileTernary {
655 condition,
656 on_pos: body,
657 on_zero: Box::new(Stmt::Break),
658 on_neg: Box::new(Stmt::Break),
659 })
660 }
661 }
662
663 Token::Loop => {
665 self.next_token()?;
666 let body = Box::new(self.parse_block()?);
667 Ok(Stmt::Loop { body })
668 }
669
670 Token::Send => {
672 self.next_token()?;
673 let target = self.parse_expr()?;
674 let message = self.parse_expr()?;
675 self.expect(Token::Semicolon)?;
676 Ok(Stmt::Send { target, message })
677 }
678
679 Token::Break => {
680 self.next_token()?;
681 self.expect(Token::Semicolon)?;
682 Ok(Stmt::Break)
683 }
684
685 Token::Continue => {
686 self.next_token()?;
687 self.expect(Token::Semicolon)?;
688 Ok(Stmt::Continue)
689 }
690
691 Token::Return => {
692 self.next_token()?;
693 let expr = self.parse_expr()?;
694 self.expect(Token::Semicolon)?;
695 Ok(Stmt::Return(expr))
696 }
697
698 Token::LBrace => self.parse_block(),
699
700 Token::Fn => Err(ParseError::UnexpectedToken("Fn".into())),
705
706 _ => {
707 let expr = self.parse_expr()?;
709
710 if let Ok(Token::Assign) = self.peek_token() {
712 match expr {
713 Expr::FieldAccess { object, field } => {
714 if let Expr::Ident(obj_name) = *object {
715 self.next_token()?; let value = self.parse_expr()?;
717 self.expect(Token::Semicolon)?;
718 return Ok(Stmt::FieldSet { object: obj_name, field, value });
719 }
720 }
721 Expr::Index { object, row, col } => {
722 if let Expr::Ident(obj_name) = *object {
723 self.next_token()?; let value = self.parse_expr()?;
725 self.expect(Token::Semicolon)?;
726 return Ok(Stmt::IndexSet { object: obj_name, row: *row, col: *col, value });
727 }
728 }
729 Expr::Ident(name) => {
730 self.next_token()?; let value = self.parse_expr()?;
732 self.expect(Token::Semicolon)?;
733 return Ok(Stmt::Set { name, value });
734 }
735 _ => {}
736 }
737 return Err(ParseError::UnexpectedToken("invalid assignment target".into()));
738 }
739
740 self.expect(Token::Semicolon)?;
741 Ok(Stmt::Expr(expr))
742 }
743 }
744 }
745
746 fn parse_block(&mut self) -> Result<Stmt, ParseError> {
747 self.expect(Token::LBrace)?;
748 let mut stmts = Vec::new();
749 while self.peek_token()? != Token::RBrace {
750 stmts.push(self.parse_stmt()?);
751 }
752 self.expect(Token::RBrace)?;
753 Ok(Stmt::Block(stmts))
754 }
755
756 fn parse_type(&mut self) -> Result<Type, ParseError> {
757 let token = self.next_token()?;
758 match token {
759 Token::TritType => {
760 if let Ok(Token::LBracket) = self.peek_token() {
761 self.next_token()?;
762 self.expect(Token::RBracket)?;
763 Ok(Type::TritTensor { dims: vec![0] })
764 } else {
765 Ok(Type::Trit)
766 }
767 }
768 Token::AgentRef => Ok(Type::AgentRef),
769 Token::TritTensor => {
770 self.expect(Token::LAngle)?;
771 let mut dims = Vec::new();
772 loop {
773 let d = match self.next_token()? {
774 Token::Int(v) => v as usize,
775 Token::TritLiteral => {
777 let s = self.lex.slice();
778 s.parse::<i8>().unwrap_or(0).max(0) as usize
779 }
780 t => return Err(ParseError::ExpectedToken("dimension".into(), format!("{:?}", t))),
781 };
782 dims.push(d);
783 if self.peek_token()? == Token::Ident("x".to_string()) {
784 self.next_token()?;
785 } else {
786 break;
787 }
788 }
789 self.expect(Token::RAngle)?;
790 Ok(Type::TritTensor { dims })
791 }
792 Token::Ident(ref name) => match name.as_str() {
793 "int" => {
794 if let Ok(Token::LBracket) = self.peek_token() {
795 self.next_token()?;
796 self.expect(Token::RBracket)?;
797 Ok(Type::IntTensor { dims: vec![0] })
798 } else {
799 Ok(Type::Int)
800 }
801 }
802 "float" => {
803 if let Ok(Token::LBracket) = self.peek_token() {
804 self.next_token()?;
805 self.expect(Token::RBracket)?;
806 Ok(Type::FloatTensor { dims: vec![0] })
807 } else {
808 Ok(Type::Float)
809 }
810 }
811 "bool" => Ok(Type::Bool),
812 "string" => Ok(Type::String),
813 _ => Ok(Type::Named(name.clone())),
815 },
816 _ => Err(ParseError::UnexpectedToken(format!("{:?}", token))),
817 }
818 }
819
820 fn expect(&mut self, expected: Token) -> Result<(), ParseError> {
821 let token = self.next_token()?;
822 if token == expected {
823 Ok(())
824 } else {
825 Err(ParseError::ExpectedToken(format!("{:?}", expected), format!("{:?}", token)))
826 }
827 }
828}
829
830#[cfg(test)]
831mod tests {
832 use super::*;
833
834 #[test]
835 fn test_parse_function() {
836 let input = "fn invert(signal: trit) -> trit { return -signal; }";
837 let mut parser = Parser::new(input);
838 let func = parser.parse_function().unwrap();
839 assert_eq!(func.name, "invert");
840 assert_eq!(func.params[0].1, Type::Trit);
841 assert_eq!(func.return_type, Type::Trit);
842 }
843
844 #[test]
845 fn test_parse_match() {
846 let input = "match x { 1 => return 1; 0 => return 0; -1 => return -1; }";
847 let mut parser = Parser::new(input);
848 let stmt = parser.parse_stmt().unwrap();
849 if let Stmt::Match { arms, .. } = stmt {
850 assert_eq!(arms.len(), 3);
851 assert_eq!(arms[0].0, 1);
852 assert_eq!(arms[1].0, 0);
853 assert_eq!(arms[2].0, -1);
854 } else {
855 panic!("Expected Match");
856 }
857 }
858
859 #[test]
860 fn test_match_parses_non_exhaustive() {
861 let input = "match x { 1 => return 1; -1 => return -1; }";
863 let mut parser = Parser::new(input);
864 let result = parser.parse_stmt();
865 assert!(result.is_ok(), "should parse successfully even if non-exhaustive");
866 }
867
868 #[test]
869 fn test_parse_for_loop() {
870 let input = "for item in weights { return item; }";
871 let mut parser = Parser::new(input);
872 let stmt = parser.parse_stmt().unwrap();
873 assert!(matches!(stmt, Stmt::ForIn { .. }));
874 }
875
876 #[test]
877 fn test_parse_loop_break() {
878 let input = "loop { break; }";
879 let mut parser = Parser::new(input);
880 let stmt = parser.parse_stmt().unwrap();
881 assert!(matches!(stmt, Stmt::Loop { .. }));
882 }
883
884 #[test]
885 fn test_parse_use() {
886 let input = "use std::trit;";
887 let mut parser = Parser::new(input);
888 let stmt = parser.parse_stmt().unwrap();
889 if let Stmt::Use { path } = stmt {
890 assert_eq!(path, vec!["std", "trit"]);
891 } else {
892 panic!("Expected Use");
893 }
894 }
895
896 #[test]
897 fn test_parse_mut_let() {
898 let input = "let mut signal: trit = 1;";
899 let mut parser = Parser::new(input);
900 let stmt = parser.parse_stmt().unwrap();
901 assert!(matches!(stmt, Stmt::Let { .. }));
902 }
903
904 #[test]
905 fn test_parse_struct_def() {
906 let input = "struct Signal { value: trit, weight: trit }";
907 let mut parser = Parser::new(input);
908 let s = parser.parse_struct_def().unwrap();
909 assert_eq!(s.name, "Signal");
910 assert_eq!(s.fields.len(), 2);
911 assert_eq!(s.fields[0], ("value".to_string(), Type::Trit));
912 assert_eq!(s.fields[1], ("weight".to_string(), Type::Trit));
913 }
914
915 #[test]
916 fn test_parse_field_access() {
917 let input = "let v: trit = sig.value;";
918 let mut parser = Parser::new(input);
919 let stmt = parser.parse_stmt().unwrap();
920 if let Stmt::Let { value: Expr::FieldAccess { field, .. }, .. } = stmt {
921 assert_eq!(field, "value");
922 } else {
923 panic!("Expected FieldAccess in let binding");
924 }
925 }
926
927 #[test]
928 fn test_parse_field_set() {
929 let input = "sig.value = 1;";
930 let mut parser = Parser::new(input);
931 let stmt = parser.parse_stmt().unwrap();
932 assert!(matches!(stmt, Stmt::FieldSet { .. }));
933 }
934
935 #[test]
936 fn test_parse_cast() {
937 let input = "let t: trit = cast(flag);";
938 let mut parser = Parser::new(input);
939 let stmt = parser.parse_stmt().unwrap();
940 if let Stmt::Let { value: Expr::Cast { .. }, .. } = stmt {
941 } else {
943 panic!("Expected Cast in let binding");
944 }
945 }
946
947 #[test]
948 fn test_parse_named_type() {
949 let input = "let s: Signal;";
950 let mut parser = Parser::new(input);
951 let stmt = parser.parse_stmt().unwrap();
952 if let Stmt::Let { ty: Type::Named(name), .. } = stmt {
953 assert_eq!(name, "Signal");
954 } else {
955 panic!("Expected Named type");
956 }
957 }
958
959 #[test]
960 fn test_parse_agent_def() {
961 let input = r#"
962 agent Voter {
963 fn handle(msg: trit) -> trit {
964 match msg {
965 1 => { return 1; }
966 0 => { return 0; }
967 -1 => { return -1; }
968 }
969 }
970 }
971 "#;
972 let mut parser = Parser::new(input);
973 let agent = parser.parse_agent_def().unwrap();
974 assert_eq!(agent.name, "Voter");
975 assert_eq!(agent.methods.len(), 1);
976 assert_eq!(agent.methods[0].name, "handle");
977 }
978
979 #[test]
980 fn test_parse_spawn() {
981 let input = "let v: agentref = spawn Voter;";
982 let mut parser = Parser::new(input);
983 let stmt = parser.parse_stmt().unwrap();
984 if let Stmt::Let { ty: Type::AgentRef, value: Expr::Spawn { agent_name, node_addr }, .. } = stmt {
985 assert_eq!(agent_name, "Voter");
986 assert_eq!(node_addr, None);
987 } else {
988 panic!("Expected spawn in let binding");
989 }
990 }
991
992 #[test]
993 fn test_parse_spawn_remote() {
994 let input = r#"let v: agentref = spawn remote "10.0.0.1:7373" Voter;"#;
995 let mut parser = Parser::new(input);
996 let stmt = parser.parse_stmt().unwrap();
997 if let Stmt::Let { ty: Type::AgentRef, value: Expr::Spawn { agent_name, node_addr }, .. } = stmt {
998 assert_eq!(agent_name, "Voter");
999 assert_eq!(node_addr, Some("10.0.0.1:7373".to_string()));
1000 } else {
1001 panic!("Expected remote spawn in let binding");
1002 }
1003 }
1004
1005 #[test]
1006 fn test_parse_send() {
1007 let input = "send v 1;";
1008 let mut parser = Parser::new(input);
1009 let stmt = parser.parse_stmt().unwrap();
1010 assert!(matches!(stmt, Stmt::Send { .. }));
1011 }
1012
1013 #[test]
1014 fn test_parse_await() {
1015 let input = "let reply: trit = await v;";
1016 let mut parser = Parser::new(input);
1017 let stmt = parser.parse_stmt().unwrap();
1018 if let Stmt::Let { value: Expr::Await { .. }, .. } = stmt {
1019 } else {
1021 panic!("Expected await in let binding");
1022 }
1023 }
1024}