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