public override IContext Reduce(IContext ctx) { var newCtx = BuiltIn.First(Cdr).Reduce(ctx); if (newCtx.Value != ClCell.Nil && newCtx.Value != ClBool.False) { return(BuiltIn.Second(Cdr).Reduce(newCtx)); } var elseBranch = BuiltIn.Cddr(Cdr); return(elseBranch == ClCell.Nil ? new Context(newCtx.Env) : BuiltIn.First(elseBranch).Reduce(newCtx)); }
public override IContext Reduce(IContext context) { if (BuiltIn.Cddr(Cdr) != ClCell.Nil) { throw new SyntaxError("Invalid function body format"); } var parameters = BuiltIn.First(Cdr) as ClCell; if (parameters is null) { throw new SyntaxError("Invalid function parameters format"); } var invalidParam = BuiltIn.Seq(parameters).FirstOrDefault(x => x as ClSymbol is null); if (invalidParam is not null) { throw new SyntaxError($"Binding statement should have {nameof(ClSymbol)} on the left-hand-side"); } var body = BuiltIn.Second(Cdr); return(context.FromValue(new ClFn(parameters, body, new Env(context.Env)))); }
private IEnumerable <ClObj> VariableDefinitionExpressions() { var expressions = BuiltIn.Head(Cdr).Cast <ClCell>(); var bindings = BuiltIn.Seq(expressions) .Select(expression => { if (expression is not ClCell variableDefinition) { throw new SyntaxError("Invalid bindings format"); } if (variableDefinition == ClCell.Nil) { throw new SyntaxError($"Variable definition expression cannot be {nameof(ClCell.Nil)}"); } if (BuiltIn.Cddr(variableDefinition) != ClCell.Nil) { throw new SyntaxError("Variable definition expression should have format (var val)"); } return(variableDefinition); }); return(bindings .Select(x => BuiltIn.ListOf(ClSymbol.Define, BuiltIn.First(x), BuiltIn.Second(x)))); }