public static Expression AnalyzeExpr(SymplExpr expr, AnalysisScope scope) { if (expr is SymplImportExpr) { return AnalyzeImportExpr((SymplImportExpr)expr, scope); } else if (expr is SymplFunCallExpr) { return AnalyzeFunCallExpr((SymplFunCallExpr)expr, scope); } else if (expr is SymplDefunExpr) { return AnalyzeDefunExpr((SymplDefunExpr)expr, scope); } else if (expr is SymplLambdaExpr) { return AnalyzeLambdaExpr((SymplLambdaExpr)expr, scope); } else if (expr is SymplIdExpr) { return AnalyzeIdExpr((SymplIdExpr)expr, scope); } else if (expr is SymplQuoteExpr) { return AnalyzeQuoteExpr((SymplQuoteExpr)expr, scope); } else if (expr is SymplLiteralExpr) { return Expression.Constant(((SymplLiteralExpr)expr).Value); } else if (expr is SymplAssignExpr) { return AnalyzeAssignExpr((SymplAssignExpr)expr, scope); } else if (expr is SymplLetStarExpr) { return AnalyzeLetStarExpr((SymplLetStarExpr)expr, scope); } else if (expr is SymplBlockExpr) { return AnalyzeBlockExpr((SymplBlockExpr)expr, scope); } else if (expr is SymplEqExpr) { return AnalyzeEqExpr((SymplEqExpr)expr, scope); } else if (expr is SymplConsExpr) { return AnalyzeConsExpr((SymplConsExpr)expr, scope); } else if (expr is SymplListCallExpr) { return AnalyzeListCallExpr((SymplListCallExpr)expr, scope); } else if (expr is SymplIfExpr) { return AnalyzeIfExpr((SymplIfExpr)expr, scope); } else if (expr is SymplDottedExpr) { return AnalyzeDottedExpr((SymplDottedExpr)expr, scope); } else if (expr is SymplNewExpr) { return AnalyzeNewExpr((SymplNewExpr)expr, scope); } else if (expr is SymplLoopExpr) { return AnalyzeLoopExpr((SymplLoopExpr)expr, scope); } else if (expr is SymplBreakExpr) { return AnalyzeBreakExpr((SymplBreakExpr)expr, scope); } else if (expr is SymplEltExpr) { return AnalyzeEltExpr((SymplEltExpr)expr, scope); } else if (expr is SymplBinaryExpr) { return AnalyzeBinaryExpr((SymplBinaryExpr)expr, scope); } else if (expr is SymplUnaryExpr) { return AnalyzeUnaryExpr((SymplUnaryExpr)expr, scope); } else { throw new InvalidOperationException( "Internal: no expression to analyze."); } }
// _parseDottedExpr gathers infix dotted member access expressions. The // object expression can be anything and is passed in via expr. Successive // member accesses must be dotted identifier expressions or member invokes -- // a.b.(c 3).d. The member invokes cannot have dotted expressions for the // member name such as a.(b.c 3). // private SymplDottedExpr ParseDottedExpr(Lexer lexer, SymplExpr objExpr) { Token token = lexer.GetToken(); if (token != SyntaxToken.Dot) { throw new SymplParseException( "Internal: parsing dotted expressions?"); } List <SymplExpr> exprs = new List <SymplExpr>(); token = lexer.GetToken(); while (token is IdOrKeywordToken || token == SyntaxToken.Paren) { // Needs to be fun call or IDs SymplExpr expr; if (token is IdOrKeywordToken) { // Keywords are ok as member names. expr = new SymplIdExpr((IdOrKeywordToken)token); } else { lexer.PutToken(token); expr = ParseForm(lexer); SymplFunCallExpr funCall = expr as SymplFunCallExpr; if (funCall != null || !(funCall.Function is SymplIdExpr)) { throw new SymplParseException( "Dotted expressions must be identifiers or " + "function calls with identiers as the function " + "value -- " + expr.ToString()); } } exprs.Add(expr); token = lexer.GetToken(); if (token != SyntaxToken.Dot) { break; } token = lexer.GetToken(); } lexer.PutToken(token); return(new SymplDottedExpr(objExpr, exprs.ToArray())); }
public SymplDefunExpr(string name, IdOrKeywordToken[] parms, SymplExpr[] body) { _name = name; _params = parms; _body = body; }
public SymplFunCallExpr(SymplExpr fun, SymplExpr[] args) { _fun = fun; _args = args; }
// _parseBinaryRuntimeCall parses two exprs and a close paren, returning the // two exprs. // private void ParseBinaryRuntimeCall(Lexer lexr, out SymplExpr left, out SymplExpr right) { left = ParseExprAux(lexr); right = ParseExprAux(lexr); if (lexr.GetToken() != SyntaxToken.CloseParen) { throw new SymplParseException( "Expected close paren for Eq call."); } }
public SymplDottedExpr(SymplExpr obj, SymplExpr[] exprs) { _obj = obj; _exprs = exprs; }
public SymplEltExpr(SymplExpr obj, SymplExpr[] indexes) { _obj = obj; _indexes = indexes; }
public LetBinding(IdOrKeywordToken variable, SymplExpr value) { _variable = variable; _value = value; }
public SymplAssignExpr(SymplExpr lhs, SymplExpr value) { _lhs = lhs; _value = value; }
public SymplBreakExpr (SymplExpr value) { // Can be null. _value = value; }
public SymplLoopExpr(SymplExpr[] body) { _body = body; }
public SymplIfExpr (SymplExpr test, SymplExpr consequent, SymplExpr alternative) { _test = test; _consequent = consequent; _alternative = alternative; }
public SymplListCallExpr(SymplExpr[] elements) { _elements = elements; }
private static Expression AnalyzeLambdaDef (IdOrKeywordToken[] parms, SymplExpr[] body, AnalysisScope scope, string description) { var funscope = new AnalysisScope(scope, description); funscope.IsLambda = true; // needed for return support. var paramsInOrder = new List<ParameterExpression>(); foreach (var p in parms) { var pe = Expression.Parameter(typeof(object), p.Name); paramsInOrder.Add(pe); funscope.Names[p.Name.ToLower()] = pe; } // No need to add fun name to module scope since recursive call just looks // up global name late bound. For lambdas,to get the effect of flet to // support recursion, bind a variable to nil and then set it to a lambda. // Then the lambda's body can refer to the let bound var in its def. var bodyexprs = new List<Expression>(); foreach (var e in body) { bodyexprs.Add(AnalyzeExpr(e, funscope)); } // Set up the Type arg array for the delegate type. Must include // the return type as the last Type, which is object for Sympl defs. var funcTypeArgs = new List<Type>(); for (int i = 0; i < parms.Length + 1; i++) { funcTypeArgs.Add(typeof(object)); } return Expression.Lambda( Expression.GetFuncType(funcTypeArgs.ToArray()), Expression.Block(bodyexprs), paramsInOrder); }
public SymplLambdaExpr(IdOrKeywordToken[] parms, SymplExpr[] body) { _params = parms; _body = body; }
public SymplNewExpr(SymplExpr type, SymplExpr[] arguments) { _type = type; _arguments = arguments; }
public SymplLetStarExpr(LetBinding[] bindings, SymplExpr[] body) { _bindings = bindings; _body = body; }
public SymplBinaryExpr(SymplExpr left, SymplExpr right, ExpressionType operation) { _left = left; _right = right; _operation = operation; }
public SymplBlockExpr(SymplExpr[] body) { _body = body; }
public SymplUnaryExpr(SymplExpr expression, ExpressionType operation) { _operand = expression; _operation = operation; }
public SymplConsExpr (SymplExpr left, SymplExpr right) { _left = left; _right = right; }
// _parseDottedExpr gathers infix dotted member access expressions. The // object expression can be anything and is passed in via expr. Successive // member accesses must be dotted identifier expressions or member invokes -- // a.b.(c 3).d. The member invokes cannot have dotted expressions for the // member name such as a.(b.c 3). // private SymplDottedExpr ParseDottedExpr(Lexer lexer, SymplExpr objExpr) { Token token = lexer.GetToken(); if (token != SyntaxToken.Dot) { throw new SymplParseException( "Internal: parsing dotted expressions?"); } List<SymplExpr> exprs = new List<SymplExpr>(); token = lexer.GetToken(); while (token is IdOrKeywordToken || token == SyntaxToken.Paren) { // Needs to be fun call or IDs SymplExpr expr; if (token is IdOrKeywordToken) { // Keywords are ok as member names. expr = new SymplIdExpr((IdOrKeywordToken)token); } else { lexer.PutToken(token); expr = ParseForm(lexer); SymplFunCallExpr funCall = expr as SymplFunCallExpr; if (funCall != null || !(funCall.Function is SymplIdExpr)) { throw new SymplParseException( "Dotted expressions must be identifiers or " + "function calls with identiers as the function " + "value -- " + expr.ToString()); } } exprs.Add(expr); token = lexer.GetToken(); if (token != SyntaxToken.Dot) { break; } token = lexer.GetToken(); } lexer.PutToken(token); return new SymplDottedExpr(objExpr, exprs.ToArray()); }