Skip to main content

truthlinked_axiom_compiler/
parser.rs

1//! Recursive-descent parser for .cell source.
2
3use crate::ast::*;
4use crate::lexer::{Tok, Token};
5
6#[derive(Debug, thiserror::Error)]
7#[error("parse error at {line}:{col}: {msg}")]
8pub struct ParseError {
9    pub line: usize,
10    pub col: usize,
11    pub msg: String,
12}
13
14pub struct Parser {
15    tokens: Vec<Tok>,
16    pos: usize,
17}
18
19impl Parser {
20    pub fn new(tokens: Vec<Tok>) -> Self {
21        Self { tokens, pos: 0 }
22    }
23
24    fn peek(&self) -> &Token {
25        &self.tokens[self.pos].token
26    }
27    fn span(&self) -> (usize, usize) {
28        let s = &self.tokens[self.pos].span;
29        (s.line, s.col)
30    }
31
32    fn err(&self, msg: impl Into<String>) -> ParseError {
33        let (line, col) = self.span();
34        ParseError {
35            line,
36            col,
37            msg: msg.into(),
38        }
39    }
40
41    fn advance(&mut self) -> &Token {
42        let t = &self.tokens[self.pos].token;
43        if self.pos + 1 < self.tokens.len() {
44            self.pos += 1;
45        }
46        t
47    }
48
49    fn expect(&mut self, expected: &Token) -> Result<(), ParseError> {
50        if self.peek() == expected {
51            self.advance();
52            Ok(())
53        } else {
54            Err(self.err(format!("expected {:?}, got {:?}", expected, self.peek())))
55        }
56    }
57
58    fn expect_ident(&mut self) -> Result<String, ParseError> {
59        match self.peek().clone() {
60            Token::Ident(s) => {
61                self.advance();
62                Ok(s)
63            }
64            other => Err(self.err(format!("expected identifier, got {:?}", other))),
65        }
66    }
67
68    fn eat(&mut self, t: &Token) -> bool {
69        if self.peek() == t {
70            self.advance();
71            true
72        } else {
73            false
74        }
75    }
76
77    // ── Top level ─────────────────────────────────────────────────────────
78
79    pub fn parse_cell(&mut self) -> Result<CellDef, ParseError> {
80        self.expect(&Token::Cell)?;
81        let name = self.expect_ident()?;
82        self.expect(&Token::LBrace)?;
83
84        let mut errors = vec![];
85        let mut storage = vec![];
86        let mut init = None;
87        let mut fns = vec![];
88
89        loop {
90            match self.peek().clone() {
91                Token::RBrace | Token::Eof => break,
92                Token::Error => {
93                    self.advance();
94                    errors.push(self.parse_error_decl()?);
95                }
96                Token::Storage => {
97                    self.advance();
98                    storage.push(self.parse_storage_decl()?);
99                }
100                Token::Init => {
101                    self.advance();
102                    init = Some(self.parse_init()?);
103                }
104                Token::Pub => {
105                    self.advance();
106                    self.expect(&Token::Fn)?;
107                    fns.push(self.parse_fn(true)?);
108                }
109                Token::Fn => {
110                    self.advance();
111                    fns.push(self.parse_fn(false)?);
112                }
113                other => return Err(self.err(format!("unexpected {:?} in cell body", other))),
114            }
115        }
116        self.expect(&Token::RBrace)?;
117        Ok(CellDef {
118            name,
119            structs: vec![],
120            errors,
121            storage,
122            init,
123            fns,
124        })
125    }
126
127    fn parse_error_decl(&mut self) -> Result<ErrorDecl, ParseError> {
128        let name = self.expect_ident()?;
129        self.expect(&Token::Semicolon)?;
130        Ok(ErrorDecl { name })
131    }
132
133    fn parse_storage_decl(&mut self) -> Result<StorageDecl, ParseError> {
134        let name = self.expect_ident()?;
135        self.expect(&Token::Colon)?;
136        let ty = self.parse_type()?;
137        let commutative = self.eat(&Token::Commutative);
138        self.expect(&Token::Semicolon)?;
139        Ok(StorageDecl {
140            name,
141            ty,
142            commutative,
143        })
144    }
145
146    fn parse_type(&mut self) -> Result<Type, ParseError> {
147        match self.peek().clone() {
148            Token::U64 => {
149                self.advance();
150                Ok(Type::U64)
151            }
152            Token::U128 => {
153                self.advance();
154                Ok(Type::U128)
155            }
156            Token::U256 => {
157                self.advance();
158                Ok(Type::U256)
159            }
160            Token::Address => {
161                self.advance();
162                Ok(Type::Address)
163            }
164            Token::Bool => {
165                self.advance();
166                Ok(Type::Bool)
167            }
168            Token::Mapping => {
169                self.advance();
170                self.expect(&Token::LParen)?;
171                let k = self.parse_type()?;
172                self.expect(&Token::FatArrow)?;
173                let v = self.parse_type()?;
174                self.expect(&Token::RParen)?;
175                Ok(Type::Mapping(Box::new(k), Box::new(v)))
176            }
177            Token::LBracket => {
178                // array<T> written as [T]
179                self.advance();
180                let inner = self.parse_type()?;
181                self.expect(&Token::RBracket)?;
182                Ok(Type::Array(Box::new(inner)))
183            }
184            other => Err(self.err(format!("expected type, got {:?}", other))),
185        }
186    }
187
188    fn parse_params(&mut self) -> Result<Vec<Param>, ParseError> {
189        self.expect(&Token::LParen)?;
190        let mut params = vec![];
191        while self.peek() != &Token::RParen {
192            let owned = self.eat(&Token::Owned);
193            let name = self.expect_ident()?;
194            self.expect(&Token::Colon)?;
195            let ty = self.parse_type()?;
196            params.push(Param { name, ty, owned });
197            if !self.eat(&Token::Comma) {
198                break;
199            }
200        }
201        self.expect(&Token::RParen)?;
202        Ok(params)
203    }
204
205    fn parse_init(&mut self) -> Result<InitDef, ParseError> {
206        let params = self.parse_params()?;
207        let body = self.parse_block()?;
208        Ok(InitDef { params, body })
209    }
210
211    fn parse_fn(&mut self, public: bool) -> Result<FnDef, ParseError> {
212        let name = self.expect_ident()?;
213        let params = self.parse_params()?;
214        let ret = if self.eat(&Token::Arrow) {
215            if self.peek() == &Token::LParen {
216                // tuple return: -> (T1, T2, ...)
217                self.advance();
218                let mut types = vec![];
219                while self.peek() != &Token::RParen && self.peek() != &Token::Eof {
220                    types.push(self.parse_type()?);
221                    if !self.eat(&Token::Comma) {
222                        break;
223                    }
224                }
225                self.expect(&Token::RParen)?;
226                Some(types)
227            } else {
228                Some(vec![self.parse_type()?])
229            }
230        } else {
231            None
232        };
233        let body = self.parse_block()?;
234        Ok(FnDef {
235            name,
236            public,
237            params,
238            ret,
239            body,
240        })
241    }
242
243    // ── Block & statements ────────────────────────────────────────────────
244
245    fn parse_block(&mut self) -> Result<Vec<Stmt>, ParseError> {
246        self.expect(&Token::LBrace)?;
247        let mut stmts = vec![];
248        while self.peek() != &Token::RBrace && self.peek() != &Token::Eof {
249            stmts.push(self.parse_stmt()?);
250        }
251        self.expect(&Token::RBrace)?;
252        Ok(stmts)
253    }
254
255    fn parse_stmt(&mut self) -> Result<Stmt, ParseError> {
256        match self.peek().clone() {
257            Token::Let => {
258                self.advance();
259                let name = self.expect_ident()?;
260                // optional type annotation: let x: u256 = ...
261                let ty = if self.eat(&Token::Colon) {
262                    Some(self.parse_type()?)
263                } else {
264                    None
265                };
266                self.expect(&Token::Assign)?;
267                let expr = self.parse_expr()?;
268                self.expect(&Token::Semicolon)?;
269                Ok(Stmt::Let { name, ty, expr })
270            }
271            Token::Require => {
272                self.advance();
273                let expr = self.parse_expr()?;
274                self.expect(&Token::Semicolon)?;
275                Ok(Stmt::Require { expr })
276            }
277            Token::Revert => {
278                self.advance();
279                let error = self.expect_ident()?;
280                self.expect(&Token::Semicolon)?;
281                Ok(Stmt::Revert { error })
282            }
283            Token::Return => {
284                self.advance();
285                if self.peek() == &Token::Semicolon {
286                    self.advance();
287                    return Ok(Stmt::Return { exprs: vec![] });
288                }
289                // return (a, b, c);  or  return expr;
290                let exprs = if self.peek() == &Token::LParen {
291                    self.advance();
292                    let mut v = vec![];
293                    while self.peek() != &Token::RParen && self.peek() != &Token::Eof {
294                        v.push(self.parse_expr()?);
295                        if !self.eat(&Token::Comma) {
296                            break;
297                        }
298                    }
299                    self.expect(&Token::RParen)?;
300                    v
301                } else {
302                    vec![self.parse_expr()?]
303                };
304                self.expect(&Token::Semicolon)?;
305                Ok(Stmt::Return { exprs })
306            }
307            Token::Emit => {
308                self.advance();
309                let event = self.expect_ident()?;
310                self.expect(&Token::LBrace)?;
311                let mut fields = vec![];
312                while self.peek() != &Token::RBrace {
313                    let fname = self.expect_ident()?;
314                    let fexpr = if self.eat(&Token::Colon) {
315                        self.parse_expr()?
316                    } else {
317                        Expr::Var(fname.clone())
318                    };
319                    fields.push((fname, fexpr));
320                    if !self.eat(&Token::Comma) {
321                        break;
322                    }
323                }
324                self.expect(&Token::RBrace)?;
325                self.expect(&Token::Semicolon)?;
326                Ok(Stmt::Emit { event, fields })
327            }
328            Token::If => {
329                self.advance();
330                let cond = self.parse_expr()?;
331                let then = self.parse_block()?;
332                let else_ = if self.eat(&Token::Else) {
333                    self.parse_block()?
334                } else {
335                    vec![]
336                };
337                Ok(Stmt::If { cond, then, else_ })
338            }
339            Token::While => {
340                self.advance();
341                let cond = self.parse_expr()?;
342                let body = self.parse_block()?;
343                Ok(Stmt::While { cond, body })
344            }
345            Token::For => {
346                self.advance();
347                let var = self.expect_ident()?;
348                self.expect(&Token::In)?;
349                let start = self.parse_expr()?;
350                self.expect(&Token::DotDot)?;
351                let end = self.parse_expr()?;
352                let body = self.parse_block()?;
353                Ok(Stmt::For {
354                    var,
355                    start,
356                    end,
357                    body,
358                })
359            }
360            Token::Loop => {
361                self.advance();
362                let body = self.parse_block()?;
363                Ok(Stmt::Loop { body })
364            }
365            Token::Break => {
366                self.advance();
367                self.expect(&Token::Semicolon)?;
368                Ok(Stmt::Break)
369            }
370            Token::Continue => {
371                self.advance();
372                self.expect(&Token::Semicolon)?;
373                Ok(Stmt::Continue)
374            }
375            Token::Ident(_) => self.parse_assign_or_expr(),
376            _ => {
377                let expr = self.parse_expr()?;
378                self.expect(&Token::Semicolon)?;
379                Ok(Stmt::Expr(expr))
380            }
381        }
382    }
383
384    fn parse_assign_or_expr(&mut self) -> Result<Stmt, ParseError> {
385        let name = self.expect_ident()?;
386
387        // Check for index: name[key] = ...
388        let lvalue = if self.peek() == &Token::LBracket {
389            self.advance();
390            let key = self.parse_expr()?;
391            self.expect(&Token::RBracket)?;
392            LValue::Index {
393                base: name.clone(),
394                key: Box::new(key),
395            }
396        } else if self.peek() == &Token::Dot {
397            self.advance();
398            let field = self.expect_ident()?;
399            LValue::Field {
400                base: name.clone(),
401                field,
402            }
403        } else {
404            LValue::Var(name.clone())
405        };
406
407        match self.peek().clone() {
408            Token::Assign => {
409                self.advance();
410                let expr = self.parse_expr()?;
411                self.expect(&Token::Semicolon)?;
412                Ok(Stmt::Assign {
413                    target: lvalue,
414                    expr,
415                })
416            }
417            Token::PlusEq => {
418                self.advance();
419                let expr = self.parse_expr()?;
420                self.expect(&Token::Semicolon)?;
421                Ok(Stmt::AssignAdd {
422                    target: lvalue,
423                    expr,
424                })
425            }
426            Token::MinusEq => {
427                self.advance();
428                let expr = self.parse_expr()?;
429                self.expect(&Token::Semicolon)?;
430                Ok(Stmt::AssignSub {
431                    target: lvalue,
432                    expr,
433                })
434            }
435            Token::StarEq => {
436                self.advance();
437                let expr = self.parse_expr()?;
438                self.expect(&Token::Semicolon)?;
439                Ok(Stmt::AssignMul {
440                    target: lvalue,
441                    expr,
442                })
443            }
444            Token::SlashEq => {
445                self.advance();
446                let expr = self.parse_expr()?;
447                self.expect(&Token::Semicolon)?;
448                Ok(Stmt::AssignDiv {
449                    target: lvalue,
450                    expr,
451                })
452            }
453            Token::LParen if matches!(lvalue, LValue::Var(_)) => {
454                let args = self.parse_call_args()?;
455                self.expect(&Token::Semicolon)?;
456                Ok(Stmt::Expr(Expr::Call { name, args }))
457            }
458            Token::ColonColon => {
459                // name::method(...) - put name back as ident and re-parse as expr
460                // We already consumed name, so reconstruct the path expression
461                self.advance(); // consume ::
462                let method = self.expect_ident()?;
463                let mut args = self.parse_call_args()?;
464                let expr = match (name.as_str(), method.as_str()) {
465                    (_, "balance") => {
466                        if args.len() != 2 {
467                            return Err(self.err("token::balance(token, account)"));
468                        }
469                        let account = args.remove(1);
470                        let token = args.remove(0);
471                        Expr::TokenBalance {
472                            token: Box::new(token),
473                            account: Box::new(account),
474                        }
475                    }
476                    (_, "transfer") => {
477                        if args.len() != 4 {
478                            return Err(self.err("token::transfer(token, from, to, amount)"));
479                        }
480                        let amount = args.remove(3);
481                        let to = args.remove(2);
482                        let from = args.remove(1);
483                        let token = args.remove(0);
484                        Expr::TokenTransfer {
485                            token: Box::new(token),
486                            from: Box::new(from),
487                            to: Box::new(to),
488                            amount: Box::new(amount),
489                        }
490                    }
491                    (_, "mint") => {
492                        if args.len() != 3 {
493                            return Err(self.err("token::mint(token, to, amount)"));
494                        }
495                        let amount = args.remove(2);
496                        let to = args.remove(1);
497                        let token = args.remove(0);
498                        Expr::TokenMint {
499                            token: Box::new(token),
500                            to: Box::new(to),
501                            amount: Box::new(amount),
502                        }
503                    }
504                    (_, "burn") => {
505                        if args.len() != 3 {
506                            return Err(self.err("token::burn(token, owner, amount)"));
507                        }
508                        let amount = args.remove(2);
509                        let owner = args.remove(1);
510                        let token = args.remove(0);
511                        Expr::TokenBurn {
512                            token: Box::new(token),
513                            owner: Box::new(owner),
514                            amount: Box::new(amount),
515                        }
516                    }
517                    ("accord", "request") => {
518                        if args.len() != 3 {
519                            return Err(self.err("accord::request(url, method, body)"));
520                        }
521                        let body = args.remove(2);
522                        let method = args.remove(1);
523                        let url = args.remove(0);
524                        Expr::AccordRequest {
525                            url: Box::new(url),
526                            method: Box::new(method),
527                            body: Box::new(body),
528                        }
529                    }
530                    ("accord", "read") => {
531                        if args.len() != 1 {
532                            return Err(self.err("accord::read(request_id)"));
533                        }
534                        Expr::AccordRead {
535                            request_id: Box::new(args.remove(0)),
536                        }
537                    }
538                    _ => return Err(self.err(format!("unknown path {}::{}", name, method))),
539                };
540                self.expect(&Token::Semicolon)?;
541                Ok(Stmt::Expr(expr))
542            }
543            _ => {
544                self.expect(&Token::Semicolon)?;
545                Ok(Stmt::Expr(Expr::Var(name)))
546            }
547        }
548    }
549
550    // ── Expressions (Pratt-style precedence) ─────────────────────────────
551
552    fn parse_expr(&mut self) -> Result<Expr, ParseError> {
553        self.parse_logic_or()
554    }
555
556    fn parse_logic_or(&mut self) -> Result<Expr, ParseError> {
557        let mut lhs = self.parse_logic_and()?;
558        while self.peek() == &Token::PipePipe {
559            self.advance();
560            let rhs = self.parse_logic_and()?;
561            lhs = Expr::Bin {
562                op: BinOp::LogicOr,
563                lhs: Box::new(lhs),
564                rhs: Box::new(rhs),
565            };
566        }
567        Ok(lhs)
568    }
569
570    fn parse_logic_and(&mut self) -> Result<Expr, ParseError> {
571        let mut lhs = self.parse_or()?;
572        while self.peek() == &Token::AmpAmp {
573            self.advance();
574            let rhs = self.parse_or()?;
575            lhs = Expr::Bin {
576                op: BinOp::LogicAnd,
577                lhs: Box::new(lhs),
578                rhs: Box::new(rhs),
579            };
580        }
581        Ok(lhs)
582    }
583
584    fn parse_or(&mut self) -> Result<Expr, ParseError> {
585        let mut lhs = self.parse_and()?;
586        while self.peek() == &Token::Pipe {
587            self.advance();
588            let rhs = self.parse_and()?;
589            lhs = Expr::Bin {
590                op: BinOp::Or,
591                lhs: Box::new(lhs),
592                rhs: Box::new(rhs),
593            };
594        }
595        Ok(lhs)
596    }
597
598    fn parse_and(&mut self) -> Result<Expr, ParseError> {
599        let mut lhs = self.parse_cmp()?;
600        while self.peek() == &Token::Amp {
601            self.advance();
602            let rhs = self.parse_cmp()?;
603            lhs = Expr::Bin {
604                op: BinOp::And,
605                lhs: Box::new(lhs),
606                rhs: Box::new(rhs),
607            };
608        }
609        Ok(lhs)
610    }
611
612    fn parse_cmp(&mut self) -> Result<Expr, ParseError> {
613        let lhs = self.parse_add()?;
614        let op = match self.peek() {
615            Token::Eq => BinOp::Eq,
616            Token::Ne => BinOp::Ne,
617            Token::Lt => BinOp::Lt,
618            Token::Le => BinOp::Le,
619            Token::Gt => BinOp::Gt,
620            Token::Ge => BinOp::Ge,
621            _ => return Ok(lhs),
622        };
623        self.advance();
624        let rhs = self.parse_add()?;
625        Ok(Expr::Bin {
626            op,
627            lhs: Box::new(lhs),
628            rhs: Box::new(rhs),
629        })
630    }
631
632    fn parse_add(&mut self) -> Result<Expr, ParseError> {
633        let mut lhs = self.parse_mul()?;
634        loop {
635            let op = match self.peek() {
636                Token::Plus => BinOp::Add,
637                Token::Minus => BinOp::Sub,
638                Token::Caret => BinOp::Xor,
639                Token::Shl => BinOp::Shl,
640                Token::Shr => BinOp::Shr,
641                _ => break,
642            };
643            self.advance();
644            let rhs = self.parse_mul()?;
645            lhs = Expr::Bin {
646                op,
647                lhs: Box::new(lhs),
648                rhs: Box::new(rhs),
649            };
650        }
651        Ok(lhs)
652    }
653
654    fn parse_mul(&mut self) -> Result<Expr, ParseError> {
655        let mut lhs = self.parse_unary()?;
656        loop {
657            let op = match self.peek() {
658                Token::Star => BinOp::Mul,
659                Token::Slash => BinOp::Div,
660                Token::Percent => BinOp::Rem,
661                _ => break,
662            };
663            self.advance();
664            let rhs = self.parse_unary()?;
665            lhs = Expr::Bin {
666                op,
667                lhs: Box::new(lhs),
668                rhs: Box::new(rhs),
669            };
670        }
671        Ok(lhs)
672    }
673
674    fn parse_unary(&mut self) -> Result<Expr, ParseError> {
675        if self.eat(&Token::Bang) {
676            let e = self.parse_primary()?;
677            return Ok(Expr::Not(Box::new(e)));
678        }
679        self.parse_primary()
680    }
681
682    fn parse_primary(&mut self) -> Result<Expr, ParseError> {
683        let mut expr = self.parse_primary_base()?;
684        // Postfix: expr[key] and expr.field
685        loop {
686            if self.peek() == &Token::LBracket {
687                self.advance();
688                let key = self.parse_expr()?;
689                self.expect(&Token::RBracket)?;
690                expr = Expr::Index {
691                    base: Box::new(expr),
692                    key: Box::new(key),
693                };
694            } else if self.peek() == &Token::Dot {
695                self.advance();
696                let field = self.expect_ident()?;
697                expr = Expr::Field {
698                    base: Box::new(expr),
699                    field,
700                };
701            } else {
702                break;
703            }
704        }
705        Ok(expr)
706    }
707
708    fn parse_primary_base(&mut self) -> Result<Expr, ParseError> {
709        match self.peek().clone() {
710            Token::Int(v) => {
711                self.advance();
712                Ok(Expr::Int(v))
713            }
714            Token::Str(b) => {
715                self.advance();
716                Ok(Expr::Bytes(b))
717            }
718            Token::LParen => {
719                self.advance();
720                let e = self.parse_expr()?;
721                self.expect(&Token::RParen)?;
722                Ok(e)
723            }
724
725            // call cell.method(args) [-> type]
726            Token::Call => {
727                self.advance();
728                let cell_name = self.expect_ident()?;
729                self.expect(&Token::Dot)?;
730                let method = self.expect_ident()?;
731                let args = self.parse_call_args()?;
732                let ret = if self.eat(&Token::Arrow) {
733                    Some(self.parse_type()?)
734                } else {
735                    None
736                };
737                Ok(Expr::CallCell {
738                    cell: Box::new(Expr::Var(cell_name)),
739                    method,
740                    args,
741                    ret,
742                })
743            }
744
745            // context builtins & identifiers (includes accord:: and token:: paths)
746            Token::Ident(s) => {
747                self.advance();
748                match s.as_str() {
749                    "caller" => Ok(Expr::Caller),
750                    "owner" => Ok(Expr::Owner),
751                    "height" => Ok(Expr::Height),
752                    "timestamp" => Ok(Expr::Timestamp),
753                    "value" => Ok(Expr::Var(s)),
754                    "self" => Ok(Expr::SelfAddr),
755                    "true" => Ok(Expr::Int(1)),
756                    "false" => Ok(Expr::Int(0)),
757                    "hash" => {
758                        // hash(expr) - sha256 of the 32-byte register value
759                        self.expect(&Token::LParen)?;
760                        let inner = self.parse_expr()?;
761                        self.expect(&Token::RParen)?;
762                        Ok(Expr::Hash(Box::new(inner)))
763                    }
764                    // path expressions: accord:: and token::
765                    "accord" | "token" => {
766                        let ns = s.clone();
767                        self.expect(&Token::ColonColon)?;
768                        let method = self.expect_ident()?;
769                        let mut args = self.parse_call_args()?;
770                        match (ns.as_str(), method.as_str()) {
771                            ("accord", "request") => {
772                                if args.len() != 3 {
773                                    return Err(self.err("accord::request(url, method, body)"));
774                                }
775                                let body = args.remove(2);
776                                let meth = args.remove(1);
777                                let url = args.remove(0);
778                                Ok(Expr::AccordRequest {
779                                    url: Box::new(url),
780                                    method: Box::new(meth),
781                                    body: Box::new(body),
782                                })
783                            }
784                            ("accord", "read") => {
785                                if args.len() != 1 {
786                                    return Err(self.err("accord::read(request_id)"));
787                                }
788                                Ok(Expr::AccordRead {
789                                    request_id: Box::new(args.remove(0)),
790                                })
791                            }
792                            (_, "balance") => {
793                                if args.len() != 2 {
794                                    return Err(self.err("token::balance(token, account)"));
795                                }
796                                let account = args.remove(1);
797                                let token = args.remove(0);
798                                Ok(Expr::TokenBalance {
799                                    token: Box::new(token),
800                                    account: Box::new(account),
801                                })
802                            }
803                            (_, "transfer") => {
804                                if args.len() != 4 {
805                                    return Err(
806                                        self.err("token::transfer(token, from, to, amount)")
807                                    );
808                                }
809                                let amount = args.remove(3);
810                                let to = args.remove(2);
811                                let from = args.remove(1);
812                                let token = args.remove(0);
813                                Ok(Expr::TokenTransfer {
814                                    token: Box::new(token),
815                                    from: Box::new(from),
816                                    to: Box::new(to),
817                                    amount: Box::new(amount),
818                                })
819                            }
820                            (_, "mint") => {
821                                if args.len() != 3 {
822                                    return Err(self.err("token::mint(token, to, amount)"));
823                                }
824                                let amount = args.remove(2);
825                                let to = args.remove(1);
826                                let token = args.remove(0);
827                                Ok(Expr::TokenMint {
828                                    token: Box::new(token),
829                                    to: Box::new(to),
830                                    amount: Box::new(amount),
831                                })
832                            }
833                            (_, "burn") => {
834                                if args.len() != 3 {
835                                    return Err(self.err("token::burn(token, owner, amount)"));
836                                }
837                                let amount = args.remove(2);
838                                let owner = args.remove(1);
839                                let token = args.remove(0);
840                                Ok(Expr::TokenBurn {
841                                    token: Box::new(token),
842                                    owner: Box::new(owner),
843                                    amount: Box::new(amount),
844                                })
845                            }
846                            _ => Err(self.err(format!("unknown path {}::{}", ns, method))),
847                        }
848                    }
849                    name => {
850                        if self.peek() == &Token::LParen {
851                            let args = self.parse_call_args()?;
852                            Ok(Expr::Call {
853                                name: name.to_string(),
854                                args,
855                            })
856                        } else {
857                            Ok(Expr::Var(name.to_string()))
858                        }
859                    }
860                }
861            }
862
863            other => Err(self.err(format!("unexpected {:?} in expression", other))),
864        }
865    }
866
867    fn parse_call_args(&mut self) -> Result<Vec<Expr>, ParseError> {
868        self.expect(&Token::LParen)?;
869        let mut args = vec![];
870        while self.peek() != &Token::RParen && self.peek() != &Token::Eof {
871            args.push(self.parse_expr()?);
872            if !self.eat(&Token::Comma) {
873                break;
874            }
875        }
876        self.expect(&Token::RParen)?;
877        Ok(args)
878    }
879}
880
881pub fn parse(tokens: Vec<Tok>) -> Result<CellDef, ParseError> {
882    Parser::new(tokens).parse_cell()
883}