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