// Parses list of member names to import from the object represented in the // result of _parseImportNameOrModule, which will be a file module or object // from Sympl.Globals. This is also used to parse the list of renames for // these same members. // private IdOrKeywordToken[] ParseImportNames(Lexer lexer, string nameKinds, bool allowKeywords) { Token token = lexer.GetToken(); List <IdOrKeywordToken> names = new List <IdOrKeywordToken>(); if (token is IdOrKeywordToken) { IdOrKeywordToken idToken = (IdOrKeywordToken)token; if (!idToken.IsKeywordToken) { names.Add(idToken); } } else if (token == SyntaxToken.Paren) { lexer.PutToken(token); object[] memberTokens = ParseList(lexer, "Import " + nameKinds + ".") .Elements; IdOrKeywordToken[] memberIdTokens = EnsureListOfIds(memberTokens, allowKeywords, "Import " + nameKinds + " must be valid IDs."); } else if (token == SyntaxToken.CloseParen) { lexer.PutToken(token); } else { throw new SymplParseException( "Import takes dotted names, then member vars."); } return(names.ToArray()); }
public static Expression AnalyzeBinaryExpr(SymplBinaryExpr expr, AnalysisScope scope) { // The language has the following special logic to handle And and Or // x And y == if x then y // x Or y == if x then x else (if y then y) if (expr.Operation == ExpressionType.And) { return(AnalyzeIfExpr( new SymplIfExpr( expr.Left, expr.Right, null), scope)); } else if (expr.Operation == ExpressionType.Or) { // Use (LetStar (tmp expr) (if tmp tmp)) to represent (if expr expr) // to remore duplicate evaluation. // So x Or y is translated into // (Let* (tmp1 x) // (If tmp1 tmp1 // (Let* (tmp2 y) (If tmp2 tmp2)))) // IdOrKeywordToken tmp2 = new IdOrKeywordToken( // Real implementation needs to ensure unique ID in scope chain. "__tmpLetVariable2"); var tmpExpr2 = new SymplIdExpr(tmp2); var binding2 = new LetBinding(tmp2, expr.Right);; var ifExpr2 = new SymplIfExpr( tmpExpr2, tmpExpr2, null); var letExpr2 = new SymplLetStarExpr( new[] { binding2 }, new[] { ifExpr2 }); IdOrKeywordToken tmp1 = new IdOrKeywordToken( // Real implementation needs to ensure unique ID in scope chain. "__tmpLetVariable1"); var tmpExpr1 = new SymplIdExpr(tmp1); LetBinding binding1 = new LetBinding(tmp1, expr.Left);; SymplExpr ifExpr1 = new SymplIfExpr( tmpExpr1, tmpExpr1, letExpr2); return(AnalyzeLetStarExpr( new SymplLetStarExpr( new[] { binding1 }, new[] { ifExpr1 } ), scope )); } return(Expression.Dynamic( scope.GetRuntime().GetBinaryOperationBinder(expr.Operation), typeof(object), AnalyzeExpr(expr.Left, scope), AnalyzeExpr(expr.Right, scope) )); }
private IdOrKeywordToken[] EnsureListOfIds(object[] list, bool allowKeywords, string error) { foreach (var t in list) { IdOrKeywordToken id = t as IdOrKeywordToken; if (id == null || (!allowKeywords && id.IsKeywordToken)) { throw new SymplParseException(error); } } return(list.Select(t => (IdOrKeywordToken)t).ToArray()); }
private SymplExpr ParseDefun(Lexer lexer) { Token token = lexer.GetToken(); if (token != KeywordToken.Defun) { throw new SymplParseException("Internal: parsing Defun?"); } IdOrKeywordToken name = lexer.GetToken() as IdOrKeywordToken; if (name == null || name.IsKeywordToken) { throw new SymplParseException( "Defun must have an ID for name -- " + name.ToString()); } var parms = ParseParams(lexer, "Defun"); var body = ParseBody(lexer, "Hit EOF in function body" + name.Name); return(new SymplDefunExpr(name.Name, parms, body)); }
public SymplIdExpr(IdOrKeywordToken id) { _idToken = id; }
public LetBinding(IdOrKeywordToken variable, SymplExpr value) { _variable = variable; _value = value; }