private static Expression ParseTerm(TokenStream tokenStream, SymbolTable symbols) { if (tokenStream.Peek() == '(') { tokenStream.Consume('('); var inner = ParseExp(tokenStream, symbols); tokenStream.Consume(')'); return inner; } if (tokenStream.Peek() == 'λ') { tokenStream.Consume('λ'); char id = tokenStream.Peek(); if (!Char.IsLetter(id)) throw new ParserException(String.Format("Expected identifier at position {0}", tokenStream.Position)); tokenStream.Consume(id); tokenStream.Consume('.'); var variable = new Symbol(id); var body = ParseExp(tokenStream, symbols.Plus(id, variable)); return new Lambda(variable, body); } if (Char.IsLetter(tokenStream.Peek())) { char id = tokenStream.Peek(); tokenStream.Consume(id); var variable = symbols.Lookup(id); if (variable != null) return new BoundVariable(variable); else return new FreeVariable(id); } throw new ParserException(String.Format("Unexpected character \"{0}\" at position {1}", tokenStream.Peek(), tokenStream.Position)); }
public SymbolTable Plus(char id, Symbol variable) { var symbols = _symbols.ContainsKey(id) ? _symbols.Remove(id) : _symbols; symbols = symbols.Add(id, variable); return new SymbolTable(symbols); }
public override Expression Replace(Symbol variable, Expression argument) { var newHead = _head.Replace(variable, argument); var newTail = _tail.Replace(variable, argument); if (newHead == _head && newTail == _tail) return this; return new Apply(newHead, newTail); }
public override Expression Replace(Symbol variable, Expression argument) { var newBody = _body.Replace(variable, argument); if (newBody == _body) return this; ImmutableList<char> taken = newBody.FreeVariableNames(new Symbol[] { _variable }.ToImmutableList()); if (taken.Contains(_variable.Default)) { int ordinal = (int)(char.ToLower(_variable.Default) - 'a') + 1 % 26; while (taken.Contains((char)('a' + ordinal))) ordinal++; var newVariable = new Symbol((char)('a' + ordinal)); newBody = newBody.Replace(_variable, new BoundVariable(newVariable)); return new Lambda(newVariable, newBody); } return new Lambda(_variable, newBody); }
public override bool DependsUpon(Symbol variable) { return _head.DependsUpon(variable) || _tail.DependsUpon(variable); }
public override Expression Replace(Symbol variable, Expression argument) { return this; }
public override bool DependsUpon(Symbol variable) { return false; }
public override Expression Replace(Symbol variable, Expression argument) { if (_variable == variable) return argument; return this; }
public override bool DependsUpon(Symbol variable) { return _variable == variable; }
public BoundVariable(Symbol variable) { _variable = variable; }
public override bool DependsUpon(Symbol variable) { return _body.DependsUpon(variable); }
public Lambda(Symbol variable, Expression body) { _variable = variable; _body = body; }
public abstract bool DependsUpon(Symbol variable);
public abstract Expression Replace(Symbol variable, Expression argument);