Module: JSE::Functors::Lisp
- Defined in:
- lib/jse/functors/lisp.rb
Constant Summary collapse
- LISP_FUNCTORS =
{ "$eval" => method(:eval_fn), "$apply" => method(:apply_fn), "$lambda" => method(:lambda_fn), "$def" => method(:def_fn), "$defn" => method(:defn), }.freeze
Class Method Summary collapse
- .apply_fn(env, *args) ⇒ Object
- .def_fn(env, *args) ⇒ Object
- .defn(env, *args) ⇒ Object
- .eval_fn(env, *args) ⇒ Object
- .lambda_fn(env, *args) ⇒ Object
Class Method Details
.apply_fn(env, *args) ⇒ Object
9 10 11 12 13 14 15 |
# File 'lib/jse/functors/lisp.rb', line 9 def self.apply_fn(env, *args) raise "$apply requires (functor, arglist)" if args.length < 2 functor = args[0].respond_to?(:apply) ? env.eval(args[0]) : args[0] arglist = args[1].respond_to?(:apply) ? env.eval(args[1]) : args[1] raise "$apply second argument must be a list" unless arglist.is_a?(Array) functor.call(env, *arglist) end |
.def_fn(env, *args) ⇒ Object
35 36 37 38 39 40 41 42 43 44 45 46 47 48 |
# File 'lib/jse/functors/lisp.rb', line 35 def self.def_fn(env, *args) raise "$def requires (name, value)" if args.length < 2 name_node = args[0] name = if name_node.is_a?(Ast::SymbolNode) name_node.name elsif name_node.is_a?(String) name_node else name_node.to_s end value = args[1].respond_to?(:apply) ? env.eval(args[1]) : args[1] env.register(name, value) value end |
.defn(env, *args) ⇒ Object
50 51 52 53 54 55 56 57 58 59 60 61 |
# File 'lib/jse/functors/lisp.rb', line 50 def self.defn(env, *args) raise "$defn requires (name, params, body)" if args.length < 3 name_node = args[0] name = if name_node.is_a?(Ast::SymbolNode) name_node.name else name_node.to_s end lambda_result = lambda_fn(env, args[1], args[2]) env.register(name, lambda_result) lambda_result end |
.eval_fn(env, *args) ⇒ Object
4 5 6 7 |
# File 'lib/jse/functors/lisp.rb', line 4 def self.eval_fn(env, *args) raise "$eval requires 1 argument" if args.empty? env.eval(args[0]) end |
.lambda_fn(env, *args) ⇒ Object
17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 |
# File 'lib/jse/functors/lisp.rb', line 17 def self.lambda_fn(env, *args) raise "$lambda requires (params, body)" if args.length < 2 params_raw = args[0] body = args[1] params = if params_raw.is_a?(Ast::ArrayNode) params_raw.elements.map { |e| e.is_a?(Ast::SymbolNode) ? e.name : e } elsif params_raw.is_a?(Ast::SymbolNode) [params_raw.name] elsif params_raw.is_a?(Array) params_raw else [params_raw.to_s] end Ast::LambdaNode.new(params, body, env) end |