// 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); }
// these functions serve to ensure that symbols in nodes are defined as the right type protected TypedValue DefSymbolValue(IdentNode node, TypedValue value) { if (node.Sym.IsValue && node.Sym.DataType == value.DataType) { return(node.Sym.Value); } Logger.WriteLine(3, "Getsym adding {0} value:{1} type:{2}", node.Sym.Name, value, value.DataType); // will create new symbol and store in symbol table, so other nodes see the same thing if (node.Sym.IsUndef) { Symbols.DefineValue(node.Name, value); } else if (value.GetType() == typeof(IdentValue) && node.Sym.Value is IdentValue) { ; // any subclass will do for flag. TODO: reverse operation if flag defined first } else { _currentparser.Syntax("already defined {0} as type {1}", node.Name, node.Sym.DataType); } return(value); }
protected ZoneValue DefZone(IdentNode node) { return(DefSymbolValue(node, new ZoneValue { Value = node.Name }) as ZoneValue); }
protected IdentValue DefIdent(IdentNode node) { return(DefSymbolValue(node, new IdentValue { Value = node.Name }) as IdentValue); }
protected PositionValue DefPosition(IdentNode node) { return(DefSymbolValue(node, PositionValue.Create(node.Name)) as PositionValue); }
protected PlayerValue DefPlayer(IdentNode node) { return(DefSymbolValue(node, PlayerValue.Create(node.Name)) as PlayerValue); }
protected PieceValue DefPiece(IdentNode node) { return(DefSymbolValue(node, PieceValue.Create(node.Name)) as PieceValue); }
protected MoveTypeValue DefMoveType(IdentNode node) { return(DefSymbolValue(node, new MoveTypeValue { Value = node.Name }) as MoveTypeValue); }
protected DirectionValue DefDirection(IdentNode node) { return(DefSymbolValue(node, new DirectionValue { Value = node.Name }) as DirectionValue); }
protected AttributeValue DefAttribute(IdentNode node) { return(DefSymbolValue(node, AttributeValue.Create(node.Name)) as AttributeValue); }