private static Expression ParseApplicationExpression(IEnumerator<Token> tokens, SymbolTable table) { ApplicationExpression result = null; while (true) { var expression = ParsePrimaryExpression(tokens, table); if (expression == null) break; if (result == null) result = new ApplicationExpression { Left = expression, Right = null }; else if (result.Right == null) result.Right = expression; else result = new ApplicationExpression { Left = result, Right = expression }; } if (result == null) throw new Exception("expression expected"); if (result.Right == null) return result.Left; // PrimaryExpression else return result; }
public SymbolTable(SymbolTable parent) { _parent = parent; if (parent != null) { _bottom = parent._bottom; } else { _bottom = this; _boundSymbols = new Dictionary<int, string>(); _builtinNames = new BuiltinNames(this); } }
public static Expression Parse(string text, SymbolTable table) { var tokens = Tokenize(text); var enumerator = tokens.GetEnumerator(); if (!enumerator.MoveNext()) throw new Exception("token list must not be empty"); var expression = ParseExpression(enumerator, table); if (enumerator.Current.Type != TokenType.Eof) throw new Exception("unexpected token '" + enumerator.Current.Text + "'"); return expression; }
public static Expression ConvertToBuiltin(Expression expression, SymbolTable table) { // _Bool bool boolValue; if (RecognizeBool(expression, out boolValue)) return table.BuiltinNames.CreateBool(boolValue); // _Integer int integerValue; if (RecognizeInteger(expression, out integerValue)) return table.BuiltinNames.CreateInteger(integerValue); // _List BuiltinList listValue; if (RecognizeList(expression, out listValue)) return table.BuiltinNames.CreateList(listValue); // _Pair BuiltinPair pairValue; if (RecognizePair(expression, out pairValue)) return table.BuiltinNames.CreatePair(pairValue); // _Maybe Expression maybeValue; if (RecognizeMaybe(expression, out maybeValue)) return table.BuiltinNames.CreateMaybe(maybeValue); return null; }
public BuiltinNames(SymbolTable table) { int x = table.Register("x"); int y = table.Register("y"); _names = new Dictionary<string, Expression>(); _names.Add("_True", CreateBool(true)); _names.Add("_False", CreateBool(false)); _names.Add("_Zero", CreateInteger(0)); _names.Add("_Successor", new AbstractionExpression { Left = new SymbolRef(x), Right = new BuiltinExpression { Left = new BoundSymbolExpression { Symbol = new SymbolRef(x) }, Right = null, Evaluate = _SuccessorEvaluate } }); _names.Add("_Null", new FreeSymbolExpression { Name = "_List", Tag = null, Display = _ListDisplay }); _names.Add("_Nothing", new FreeSymbolExpression { Name = "_Maybe", Tag = null, Display = _MaybeDisplay }); }
private static Expression ParseAbstractionExpression(IEnumerator<Token> tokens, SymbolTable table) { if (tokens.Current.Type == TokenType.Symbol && tokens.Current.Text == "\\") { tokens.MoveNext(); var bindList = ParseBindList(tokens); if (tokens.Current.Type == TokenType.Symbol && tokens.Current.Text == ".") { SymbolTable childTable = new SymbolTable(table); var bindIdList = new List<int>(bindList.Count); for (int i = 0; i < bindList.Count; i++) bindIdList.Add(childTable.Register(bindList[i])); tokens.MoveNext(); var rest = ParseAbstractionExpression(tokens, childTable); Expression rhs = rest; for (int i = 0; i < bindIdList.Count; i++) { rhs = new AbstractionExpression { Left = new SymbolRef(bindIdList[bindIdList.Count - i - 1]), Right = rhs }; } return rhs; } else { throw new Exception("'.' expected"); } } else { return ParseApplicationExpression(tokens, table); } }
private static Expression ParsePrimaryExpression(IEnumerator<Token> tokens, SymbolTable table) { if (tokens.Current.Type == TokenType.Symbol && tokens.Current.Text == "(") { tokens.MoveNext(); var expression = ParseExpression(tokens, table); if (tokens.Current.Type == TokenType.Symbol && tokens.Current.Text == ")") { tokens.MoveNext(); return expression; } else { throw new Exception("')' expected"); } } else if (tokens.Current.Type == TokenType.Id) { string name = tokens.Current.Text; int id = table.Lookup(name); tokens.MoveNext(); if (id != 0) return new BoundSymbolExpression { Symbol = new SymbolRef(id) }; else return new FreeSymbolExpression { Name = name }; } else { return null; } }
private static Expression ParseExpression(IEnumerator<Token> tokens, SymbolTable table) { return ParseAbstractionExpression(tokens, table); }
private string _PairDisplay(Expression expression, SymbolTable table) { var freeSymbol = (FreeSymbolExpression)expression; BuiltinPair pair = (BuiltinPair)freeSymbol.Tag; StringBuilder sb = new StringBuilder(); sb.Append("<" + freeSymbol.Name + ">"); Expression displayExpression; // First displayExpression = Evaluator.ConvertToBuiltin(pair.First, table); if (displayExpression == null) displayExpression = pair.First; sb.Append("(" + Evaluator.ConvertToString(displayExpression, table) + ")"); // Second displayExpression = Evaluator.ConvertToBuiltin(pair.Second, table); if (displayExpression == null) displayExpression = pair.Second; sb.Append("(" + Evaluator.ConvertToString(displayExpression, table) + ")"); return sb.ToString(); }
private string _MaybeDisplay(Expression expression, SymbolTable table) { var freeSymbol = (FreeSymbolExpression)expression; Expression value = (Expression)freeSymbol.Tag; StringBuilder sb = new StringBuilder(); sb.Append("<" + freeSymbol.Name + ">"); Expression displayExpression; if (value != null) { displayExpression = Evaluator.ConvertToBuiltin(value, table); if (displayExpression == null) displayExpression = value; sb.Append("(" + Evaluator.ConvertToString(displayExpression, table) + ")"); } else { sb.Append("Nothing"); } return sb.ToString(); }
private string _ListDisplay(Expression expression, SymbolTable table) { var freeSymbol = (FreeSymbolExpression)expression; BuiltinList list = (BuiltinList)freeSymbol.Tag; StringBuilder sb = new StringBuilder(); sb.Append("<" + freeSymbol.Name + ">"); if (list == null) { sb.Append("Null"); } else { do { var displayExpression = Evaluator.ConvertToBuiltin(list.First, table); if (displayExpression == null) displayExpression = list.First; sb.Append("(" + Evaluator.ConvertToString(displayExpression, table) + ")"); list = list.Second; } while (list != null); } return sb.ToString(); }
private string _IntegerDisplay(Expression expression, SymbolTable table) { var freeSymbol = (FreeSymbolExpression)expression; return "<" + freeSymbol.Name + ">" + ((int)freeSymbol.Tag).ToString(); }
public static string ConvertToString(Expression expression, SymbolTable table) { if (expression is BoundSymbolExpression) { var boundSymbol = (BoundSymbolExpression)expression; return table.Lookup(boundSymbol.Symbol.Symbol); } else if (expression is FreeSymbolExpression) { var freeSymbol = (FreeSymbolExpression)expression; if (freeSymbol.Display != null) return freeSymbol.Display(freeSymbol, table); return freeSymbol.Name; } else if (expression is AbstractionExpression) { var abstraction = (AbstractionExpression)expression; return "\\" + table.Lookup(abstraction.Left.Symbol) + "." + ConvertToString(abstraction.Right, table); } else if (expression is ApplicationExpression) { var application = (ApplicationExpression)expression; string left; string right; if (application.Left is AbstractionExpression) left = "(" + ConvertToString(application.Left, table) + ")"; else left = ConvertToString(application.Left, table); if ((application.Right is AbstractionExpression) || (application.Right is ApplicationExpression)) right = "(" + ConvertToString(application.Right, table) + ")"; else right = ConvertToString(application.Right, table); return left + " " + right; } else if (expression is LazyExpression) { var lazy = (LazyExpression)expression; return "<#" + lazy.Id.ToString() + ">"; } else if (expression is BuiltinExpression) { var builtin = (BuiltinExpression)expression; if (builtin.Display != null) return builtin.Display(expression, table); string left = builtin.Left != null ? ConvertToString(builtin.Left, table) : ""; string right = builtin.Right != null ? ConvertToString(builtin.Right, table) : ""; if (right == "") return "<BUILTIN>(" + left + ")"; else return "<BUILTIN>(" + left + ")(" + right + ")"; } else { return "???"; } }