public override Expression Generate(object args, CodeBlock c) { var refs = ClrGenerator.SaveReferences(); object arg = Builtins.First(args); object typespec = (Builtins.Second(args)); Cons body = Builtins.Cdr(Builtins.Cdr(args)) as Cons; var returntype = ClrGenerator.ExtractTypeInfo(Builtins.List(quote, Builtins.Second(typespec))); CodeBlock cb = Ast.CodeBlock(SpanHint, GetLambdaName(c), returntype); NameHint = SymbolId.Empty; cb.Filename = LocationHint; cb.Parent = c; bool isrest = AssignParameters(cb, arg, Builtins.Car(typespec)); List <Statement> stmts = new List <Statement>(); FillBody(cb, stmts, body, true); Type dt = GetDelegateType(cb); Type ct = GetClosureType(cb); Expression ex = Ast.New(ct.GetConstructor(new Type[] { dt }), Ast.CodeBlockExpression(cb, true, dt)); ClrGenerator.ResetReferences(refs); return(ex); }
protected static bool AssignParameters(CodeBlock cb, object arg, object types) { bool isrest = false; Cons cargs = arg as Cons; Cons ctypes = types as Cons; if (cargs != null) { while (cargs != null) { SymbolId an = (SymbolId)Builtins.First(cargs); if (ctypes == null) { Builtins.SyntaxError("AssignParameters", "missing parameter type", Builtins.UnGenSymInternal(an), Builtins.FALSE); } object type = Builtins.First(ctypes); Type clrtype = ClrGenerator.ExtractTypeInfo(Builtins.List(quote, type)); CreateParameter(an, cb, clrtype); Cons r = cargs.cdr as Cons; Cons rt = ctypes.cdr as Cons; // not sure I can even handle this... if (r == null && cargs.cdr != null) { SymbolId ta = (SymbolId)cargs.cdr; CreateParameter(ta, cb, typeof(object)); isrest = true; break; } else { cargs = r; ctypes = rt; } } if (ctypes != null) { Builtins.SyntaxError("AssignParameters", "extra parameter type(s)", ctypes, Builtins.FALSE); } } else if (arg != null) // empty { SymbolId an = (SymbolId)arg; isrest = true; CreateParameter(an, cb, typeof(object)); } // else both null, which is OK, no? return(isrest); }
protected static bool AssignParameters(CodeBlock cb, object arg, object types) { bool isrest = false; Cons cargs = arg as Cons; Cons ctypes = types as Cons; if (cargs != null) { while (cargs != null) { SymbolId an = (SymbolId)Builtins.First(cargs); object type = Builtins.First(ctypes); Type clrtype = ClrGenerator.ExtractTypeInfo(Builtins.List(quote, type)); CreateParameter(an, cb, clrtype); Cons r = cargs.cdr as Cons; Cons rt = ctypes.cdr as Cons; if (r == null && cargs.cdr != null) { SymbolId ta = (SymbolId)cargs.cdr; CreateParameter(ta, cb, typeof(object)); isrest = true; break; } else { cargs = r; ctypes = rt; } } } else if (arg != null) // empty { SymbolId an = (SymbolId)arg; isrest = true; CreateParameter(an, cb, typeof(object)); } return(isrest); }
public override Expression Generate(object args, CodeBlock c) { Cons lambdas = args as Cons; int arlen = lambdas == null ? 0 : lambdas.Length; if (arlen == 1) { if (lambdagen == null) { lambdagen = Context.Scope.LookupName(SymbolTable.StringToId("typed-lambda")) as TypedLambdaGenerator; } return(lambdagen.Generate(lambdas.car, c)); } else { List <CodeBlockDescriptor> cbs = new List <CodeBlockDescriptor>(); string lambdaname = GetLambdaName(c); NameHint = SymbolId.Empty; var sh = SpanHint; var lh = LocationHint; while (lambdas != null) { var refs = ClrGenerator.SaveReferences(); object actual = lambdas.car; object arg = Builtins.First(actual); object typespec = (Builtins.Second(actual)); Cons body = Builtins.Cdr(Builtins.Cdr(actual)) as Cons; var returntype = ClrGenerator.ExtractTypeInfo(Builtins.List(quote, Builtins.Second(typespec))); CodeBlock cb = Ast.CodeBlock(SpanHint, lambdaname, returntype); NameHint = SymbolId.Empty; cb.Filename = lh; cb.Parent = c; bool isrest = AssignParameters(cb, arg, Builtins.Car(typespec)); List <Statement> stmts = new List <Statement>(); FillBody(cb, stmts, body, true); Type dt = GetDelegateType(cb); Type ct = GetClosureType(cb); var cbe = Ast.CodeBlockExpression(cb, true, dt); Expression ex = Ast.New(ct.GetConstructor(new Type[] { dt }), cbe); CodeBlockDescriptor cbd = new CodeBlockDescriptor(); cbd.arity = isrest ? -cb.ParameterCount : cb.ParameterCount; cbd.callable = ex; cbd.codeblock = cbe; cbd.varargs = isrest; descriptorshack2.Add(cbd.callable, cbd); cbs.Add(cbd); lambdas = lambdas.cdr as Cons; ClrGenerator.ResetReferences(refs); } return(MakeTypedCaseClosure(lambdaname, cbs)); } }