public override IContext Reduce(IContext ctx) { var identifier = BuiltIn.First(Cdr).Cast <ClSymbol>(); var(value, env) = BuiltIn.Second(Cdr).Reduce(ctx); env.Bind(identifier, value); return(new Context(env)); }
public override IContext Reduce(IContext ctx) { var identifier = BuiltIn.First(Cdr).Cast <ClSymbol>(); var newCtx = BuiltIn.Second(Cdr).Reduce(ctx); newCtx.Env.Assign(identifier, newCtx.Value); return(new Context(newCtx.Env)); }
public void Eval_ReturnUnreducedList_WhenItemOfListHasComplicatedForm() { var begin = BuiltIn.ListOf(ClSymbol.Begin, ClBool.True, Value.Foo, Value.Bar); var logicAnd = BuiltIn.ListOf(ClSymbol.And, ClBool.True, Value.One); var expr = BuiltIn.Quote(BuiltIn.ListOf(begin, logicAnd)); var ctx = expr.Reduce(_ctx); Assert.That(BuiltIn.First(ctx.Value), Is.EqualTo(begin)); Assert.That(BuiltIn.Second(ctx.Value), Is.EqualTo(logicAnd)); }
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)))); }
static ClObj Transform(ClObj clauses) { if (clauses == ClCell.Nil) { return(ClBool.False); } var clause = BuiltIn.First(clauses) as ClCell; if (clause is null) { throw new SyntaxError("Clause must be a cell"); } if (clause.Car.Equals(ClSymbol.Else)) { return(BuiltIn.Tail(clauses) == ClCell.Nil ? new ClCell(ClSymbol.Begin, clause.Cdr) : throw new SyntaxError("Else clause must be last condition")); } return(BuiltIn.ListOf(ClSymbol.If, clause.Car, new ClCell(ClSymbol.Begin, clause.Cdr), Transform(BuiltIn.Tail(clauses)))); }
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)))); }