nydp 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (69) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +18 -0
  3. data/.rspec +2 -0
  4. data/Gemfile +4 -0
  5. data/LICENSE.txt +22 -0
  6. data/README.md +58 -0
  7. data/Rakefile +1 -0
  8. data/bin/nydp +5 -0
  9. data/bin/nydp-tests +5 -0
  10. data/lib/lisp/boot.nydp +219 -0
  11. data/lib/lisp/test-runner.nydp +39 -0
  12. data/lib/lisp/tests/foundation-test.nydp +28 -0
  13. data/lib/nydp.rb +143 -0
  14. data/lib/nydp/assignment.rb +40 -0
  15. data/lib/nydp/builtin.rb +8 -0
  16. data/lib/nydp/builtin/apply.rb +16 -0
  17. data/lib/nydp/builtin/car.rb +5 -0
  18. data/lib/nydp/builtin/cdr.rb +5 -0
  19. data/lib/nydp/builtin/cdr_set.rb +8 -0
  20. data/lib/nydp/builtin/comment.rb +5 -0
  21. data/lib/nydp/builtin/cons.rb +16 -0
  22. data/lib/nydp/builtin/divide.rb +13 -0
  23. data/lib/nydp/builtin/error.rb +6 -0
  24. data/lib/nydp/builtin/eval.rb +14 -0
  25. data/lib/nydp/builtin/greater_than.rb +10 -0
  26. data/lib/nydp/builtin/hash.rb +30 -0
  27. data/lib/nydp/builtin/inspect.rb +5 -0
  28. data/lib/nydp/builtin/is_equal.rb +5 -0
  29. data/lib/nydp/builtin/less_than.rb +10 -0
  30. data/lib/nydp/builtin/millisecs.rb +7 -0
  31. data/lib/nydp/builtin/minus.rb +13 -0
  32. data/lib/nydp/builtin/plus.rb +28 -0
  33. data/lib/nydp/builtin/pre_compile.rb +5 -0
  34. data/lib/nydp/builtin/puts.rb +7 -0
  35. data/lib/nydp/builtin/quit.rb +5 -0
  36. data/lib/nydp/builtin/random_string.rb +11 -0
  37. data/lib/nydp/builtin/times.rb +13 -0
  38. data/lib/nydp/builtin/to_string.rb +12 -0
  39. data/lib/nydp/builtin/to_sym.rb +21 -0
  40. data/lib/nydp/builtin/vm_info.rb +13 -0
  41. data/lib/nydp/closure.rb +17 -0
  42. data/lib/nydp/compiler.rb +49 -0
  43. data/lib/nydp/cond.rb +56 -0
  44. data/lib/nydp/context_symbol.rb +22 -0
  45. data/lib/nydp/error.rb +4 -0
  46. data/lib/nydp/function_invocation.rb +52 -0
  47. data/lib/nydp/helper.rb +32 -0
  48. data/lib/nydp/interpreted_function.rb +79 -0
  49. data/lib/nydp/lexical_context.rb +38 -0
  50. data/lib/nydp/literal.rb +40 -0
  51. data/lib/nydp/pair.rb +112 -0
  52. data/lib/nydp/parser.rb +123 -0
  53. data/lib/nydp/string_atom.rb +24 -0
  54. data/lib/nydp/string_token.rb +21 -0
  55. data/lib/nydp/symbol.rb +47 -0
  56. data/lib/nydp/symbol_lookup.rb +43 -0
  57. data/lib/nydp/tokeniser.rb +80 -0
  58. data/lib/nydp/truth.rb +37 -0
  59. data/lib/nydp/version.rb +3 -0
  60. data/lib/nydp/vm.rb +76 -0
  61. data/nydp.gemspec +27 -0
  62. data/spec/boot_spec.rb +119 -0
  63. data/spec/embedded_spec.rb +106 -0
  64. data/spec/nypd_spec.rb +127 -0
  65. data/spec/pair_spec.rb +102 -0
  66. data/spec/parser_spec.rb +191 -0
  67. data/spec/spec_helper.rb +10 -0
  68. data/spec/symbol_spec.rb +32 -0
  69. metadata +176 -0
@@ -0,0 +1,40 @@
1
+ module Nydp
2
+ class AssignmentInstruction
3
+ def initialize name
4
+ @name = name
5
+ end
6
+
7
+ def execute vm
8
+ @name.assign vm.peek_arg, vm.peek_context
9
+ end
10
+
11
+ def to_s
12
+ "#assign #{@name}"
13
+ end
14
+ end
15
+
16
+ class Assignment
17
+ include Helper
18
+
19
+ def self.build args, bindings
20
+ name = Compiler.compile args.car, bindings
21
+ raise "can't assign to #{name.inspect} : expression was #{args}" unless name.respond_to?(:assign)
22
+ value_expr = args.cdr.car
23
+ Assignment.new name, Compiler.compile(value_expr, bindings), value_expr
24
+ end
25
+
26
+ def initialize name, value, value_src
27
+ @value_src = value_src
28
+ n = AssignmentInstruction.new name
29
+ @instructions = cons(value, cons(n))
30
+ end
31
+
32
+ def to_s
33
+ "#assignment #{@instructions.cdr.car} #{@value_src}"
34
+ end
35
+
36
+ def execute vm
37
+ vm.push_instructions @instructions, vm.peek_context
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,8 @@
1
+ require 'nydp'
2
+
3
+ module Nydp::Builtin
4
+ end
5
+
6
+ Dir[File.join(File.dirname(__FILE__), "builtin", "**/*.rb")].each {|f|
7
+ require f
8
+ }
@@ -0,0 +1,16 @@
1
+ class Nydp::Builtin::Apply
2
+ include Nydp::Helper
3
+
4
+ def invoke vm, args
5
+ args.car.invoke vm, apply_args(args.cdr)
6
+ end
7
+
8
+ private
9
+
10
+ def apply_args args
11
+ raise "Apply: expected a list : got #{args.inspect}" unless pair? args
12
+ raise "Apply: improper list : cdr is ruby nil" if args.cdr.nil?
13
+ return args.car if Nydp.NIL.is? args.cdr
14
+ cons args.car, apply_args(args.cdr)
15
+ end
16
+ end
@@ -0,0 +1,5 @@
1
+ class Nydp::Builtin::Car
2
+ def invoke vm, args
3
+ vm.push_arg args.car.car
4
+ end
5
+ end
@@ -0,0 +1,5 @@
1
+ class Nydp::Builtin::Cdr
2
+ def invoke vm, args
3
+ vm.push_arg args.car.cdr
4
+ end
5
+ end
@@ -0,0 +1,8 @@
1
+ class Nydp::Builtin::CdrSet
2
+ def invoke vm, args
3
+ pair = args.car
4
+ arg = args.cdr.car
5
+ pair.cdr = arg
6
+ vm.push_arg pair
7
+ end
8
+ end
@@ -0,0 +1,5 @@
1
+ class Nydp::Builtin::Comment
2
+ def invoke vm, args
3
+ vm.push_arg Nydp.NIL
4
+ end
5
+ end
@@ -0,0 +1,16 @@
1
+ module Nydp::Builtin
2
+ class Cons
3
+ def invoke vm, args
4
+ vm.push_arg Nydp::Pair.new(args.car, args.cdr.car)
5
+ end
6
+ end
7
+
8
+ class IsPair
9
+ include Nydp::Helper
10
+ def invoke vm, args
11
+ arg = args.car
12
+ result = pair?(arg) ? Nydp.T : Nydp.NIL
13
+ vm.push_arg result
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,13 @@
1
+ class Nydp::Builtin::Divide
2
+ def invoke vm, args
3
+ vm.push_arg divide(args.cdr, args.car)
4
+ end
5
+
6
+ def divide args, accum
7
+ if Nydp.NIL.is? args
8
+ accum
9
+ else
10
+ divide(args.cdr, (accum / args.car))
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,6 @@
1
+ class Nydp::Builtin::Error
2
+ def invoke vm, args
3
+ s = args.map { |a| a.to_s }
4
+ raise Nydp::Error.new(args.inspect)
5
+ end
6
+ end
@@ -0,0 +1,14 @@
1
+ class Nydp::Builtin::Eval
2
+ def initialize ns
3
+ @ns = ns
4
+ end
5
+
6
+ def invoke vm, args
7
+ evaluator = Nydp::Runner.new Nydp::VM.new, @ns
8
+ vm.push_arg evaluator.evaluate args.car
9
+ end
10
+
11
+ def to_s
12
+ "Builtin:eval"
13
+ end
14
+ end
@@ -0,0 +1,10 @@
1
+ class Nydp::Builtin::GreaterThan
2
+ def invoke vm, args
3
+ vm.push_arg (greater_than(args.car, args.cdr) ? Nydp.T : Nydp.NIL)
4
+ end
5
+
6
+ def greater_than arg, args
7
+ return true if Nydp.NIL.is? args
8
+ (arg > args.car) && greater_than(args.car, args.cdr)
9
+ end
10
+ end
@@ -0,0 +1,30 @@
1
+ class Nydp::Builtin::Hash
2
+ def invoke vm, args
3
+ vm.push_arg({ })
4
+ end
5
+ end
6
+
7
+ class Nydp::Builtin::HashGet
8
+ def invoke vm, args
9
+ hash = args.car
10
+ key = args.cdr.car
11
+ vm.push_arg(hash[key] || Nydp.NIL)
12
+ end
13
+ end
14
+
15
+ class Nydp::Builtin::HashSet
16
+ def invoke vm, args
17
+ hash = args.car
18
+ key = args.cdr.car
19
+ value = args.cdr.cdr.car
20
+ hash[key] = value
21
+ vm.push_arg value
22
+ end
23
+ end
24
+
25
+ class Nydp::Builtin::HashKeys
26
+ def invoke vm, args
27
+ hash = args.car
28
+ vm.push_arg Nydp::Pair.from_list hash.keys
29
+ end
30
+ end
@@ -0,0 +1,5 @@
1
+ class Nydp::Builtin::Inspect
2
+ def invoke vm, args
3
+ vm.push_arg args.car.inspect
4
+ end
5
+ end
@@ -0,0 +1,5 @@
1
+ class Nydp::Builtin::IsEqual
2
+ def invoke vm, args
3
+ vm.push_arg ((args.car == args.cdr.car) ? Nydp.T : Nydp.NIL)
4
+ end
5
+ end
@@ -0,0 +1,10 @@
1
+ class Nydp::Builtin::LessThan
2
+ def invoke vm, args
3
+ vm.push_arg (less_than(args.car, args.cdr) ? Nydp.T : Nydp.NIL)
4
+ end
5
+
6
+ def less_than arg, args
7
+ return true if Nydp.NIL.is? args
8
+ (arg < args.car) && less_than(args.car, args.cdr)
9
+ end
10
+ end
@@ -0,0 +1,7 @@
1
+ class Nydp::Builtin::Millisecs
2
+ include Nydp::Helper
3
+
4
+ def invoke vm, args
5
+ vm.push_arg (Time.now.to_f * 1000).to_i
6
+ end
7
+ end
@@ -0,0 +1,13 @@
1
+ class Nydp::Builtin::Minus
2
+ def invoke vm, args
3
+ vm.push_arg diff(args.cdr, args.car)
4
+ end
5
+
6
+ def diff args, accum
7
+ if Nydp.NIL.is? args
8
+ accum
9
+ else
10
+ diff(args.cdr, (accum - args.car))
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,28 @@
1
+ class Nydp::Builtin::Plus
2
+ def invoke vm, args
3
+ vm.push_arg sum(args, origin(args.car))
4
+ end
5
+
6
+ def sum args, accum
7
+ if Nydp.NIL.is? args
8
+ accum
9
+ else
10
+ sum(args.cdr, (accum + args.car))
11
+ end
12
+ end
13
+
14
+ def origin obj
15
+ case obj
16
+ when Fixnum
17
+ 0
18
+ when Nydp::Pair
19
+ Nydp.NIL
20
+ when String, Nydp::StringAtom
21
+ Nydp::StringAtom.new ""
22
+ end
23
+ end
24
+
25
+ def to_s
26
+ "Builtin:+"
27
+ end
28
+ end
@@ -0,0 +1,5 @@
1
+ class Nydp::Builtin::PreCompile
2
+ def invoke vm, args
3
+ vm.push_arg args.car
4
+ end
5
+ end
@@ -0,0 +1,7 @@
1
+ class Nydp::Builtin::Puts
2
+ def invoke vm, args
3
+ s = args.map { |a| a.to_s }
4
+ puts s.join ' '
5
+ vm.push_arg args.car
6
+ end
7
+ end
@@ -0,0 +1,5 @@
1
+ class Nydp::Builtin::Quit
2
+ def invoke vm, args
3
+ exit
4
+ end
5
+ end
@@ -0,0 +1,11 @@
1
+ class Nydp::Builtin::RandomString
2
+ @@random_chars = ["A","B","C","D","E","F","G","H","J","K","L","M","N","P","Q","R","S","T","U","V","W","X","Y","Z","2","3","4","5","6","7","8","9"]
3
+
4
+ def invoke vm, args
5
+ s = ""
6
+ 1.upto(10) {
7
+ s << @@random_chars[rand(@@random_chars.size)]
8
+ }
9
+ Nydp::StringAtom.new s
10
+ end
11
+ end
@@ -0,0 +1,13 @@
1
+ class Nydp::Builtin::Times
2
+ def invoke vm, args
3
+ vm.push_arg multiply(args, 1)
4
+ end
5
+
6
+ def multiply args, accum
7
+ if Nydp.NIL.is? args
8
+ accum
9
+ else
10
+ multiply(args.cdr, (accum * args.car))
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,12 @@
1
+ class Nydp::Builtin::ToString
2
+ def invoke vm, args
3
+ arg = args.car
4
+ val = case arg.class
5
+ when Nydp::StringAtom
6
+ arg
7
+ else
8
+ Nydp::StringAtom.new arg.to_s
9
+ end
10
+ vm.push_arg val
11
+ end
12
+ end
@@ -0,0 +1,21 @@
1
+ class Nydp::Builtin::ToSym
2
+ def initialize ns
3
+ @ns = ns
4
+ end
5
+ def invoke vm, args
6
+ arg = args.car
7
+ val = case arg.class
8
+ when Nydp::Symbol
9
+ arg
10
+ else
11
+ Nydp::Symbol.mk arg.to_s.to_sym, @ns
12
+ end
13
+ vm.push_arg val
14
+ end
15
+ end
16
+
17
+
18
+
19
+
20
+
21
+
@@ -0,0 +1,13 @@
1
+ class Nydp::Builtin::VmInfo
2
+ VMINFO_NS = { }
3
+ CONTEXTS = Nydp::Symbol.mk :contexts, VMINFO_NS
4
+ INSTRUCTIONS = Nydp::Symbol.mk :instructions, VMINFO_NS
5
+ ARGS = Nydp::Symbol.mk :args, VMINFO_NS
6
+
7
+ def invoke vm, args
8
+ context_count = Nydp::Pair.new CONTEXTS, vm.contexts.size
9
+ instruction_count = Nydp::Pair.new INSTRUCTIONS, vm.instructions.size
10
+ arg_count = Nydp::Pair.new ARGS, vm.args.size
11
+ vm.push_arg Nydp::Pair.from_list [context_count, instruction_count, arg_count]
12
+ end
13
+ end
@@ -0,0 +1,17 @@
1
+ module Nydp
2
+ class Closure
3
+ attr_accessor :ifn, :context
4
+
5
+ def initialize ifn, context
6
+ @ifn, @context = ifn, context
7
+ end
8
+
9
+ def invoke vm, arg_values
10
+ ifn.invoke vm, context, arg_values
11
+ end
12
+
13
+ def to_s
14
+ "(closure #{context.inspect} : #{ifn.to_s})"
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,49 @@
1
+ require 'nydp/cond'
2
+ require 'nydp/function_invocation'
3
+ require 'nydp/interpreted_function'
4
+ require 'nydp/literal'
5
+
6
+ module Nydp
7
+ class Compiler
8
+ extend Helper
9
+
10
+ def self.compile expression, bindings
11
+ if expression.is_a? Nydp::Symbol
12
+ SymbolLookup.build expression, bindings
13
+ elsif literal? expression
14
+ Literal.build expression, bindings
15
+ elsif expression.is_a? Nydp::Pair
16
+ compile_pair expression, bindings
17
+ end
18
+ end
19
+
20
+ def self.maybe_cons a, b
21
+ Nydp.NIL.is?(a) ? b : cons(a, b)
22
+ end
23
+
24
+ def self.compile_each expr, bindings
25
+ if Nydp.NIL.is?(expr)
26
+ expr
27
+ elsif pair?(expr)
28
+ maybe_cons compile(expr.car, bindings), compile_each(expr.cdr, bindings)
29
+ else
30
+ compile(expr, bindings)
31
+ end
32
+ end
33
+
34
+ def self.compile_pair expression, bindings
35
+ key = expression.car
36
+ if sym?(key, :cond)
37
+ Cond.build expression.cdr, bindings
38
+ elsif sym?(key, :quote)
39
+ Literal.build expression.cadr, bindings
40
+ elsif sym?(key, :assign)
41
+ Assignment.build expression.cdr, bindings
42
+ elsif sym?(key, :fn)
43
+ InterpretedFunction.build expression.cadr, expression.cddr, bindings
44
+ else
45
+ FunctionInvocation.build expression, bindings
46
+ end
47
+ end
48
+ end
49
+ end