// Parse a single node, either an atom or a list in parens // Handle macro expansion too Node ParseNode() { // atom node var sym = Take(); switch (sym.Atom) { case Atoms.IDENT: return(IdentNode.Create(sym.Name, sym)); case Atoms.LITERAL: return(LiteralNode.Create(sym.Value)); case Atoms.LP: if (Check(Atoms.MACRO)) { ExpandMacro(Take()); return(ParseNode()); } else { var nodes = new List <Node>(); while (!Match(Atoms.RP)) { nodes.Add(ParseNode()); } return(ListNode.Create(nodes)); } default: throw ErrNotExpect(sym.Atom); } }
// check ident, return new node if undef or base scope internal Node CheckedIdent(Node node) { if (node.IsIdent) { var ident = node as IdentNode; if (!(ident.Sym.IsUndef || ident.Sym.IsBase)) { throw Error.Assert("checked ident {0}", ident); } var newsym = _symbols.Find(ident.Sym.Name); if (newsym != null && !newsym.IsUndef) { return(IdentNode.Create(ident.Name, newsym)); } } return(node); }