nydp 0.2.2 → 0.2.3

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,20 @@
1
+ (examples-for or=
2
+ ("assign a simple nil variable"
3
+ (let x nil (or= x 42) x)
4
+ 42)
5
+
6
+ ("assign a simple non-nil variable"
7
+ (let x 99 (or= x 42) x)
8
+ 99)
9
+
10
+ ("assign a nil hash value"
11
+ (let h (hash)
12
+ (or= h.x 43)
13
+ h.x)
14
+ 43)
15
+
16
+ ("assign a non-nil hash value"
17
+ (let h { x 999 }
18
+ (or= h.x 43)
19
+ h.x)
20
+ 999))
@@ -1,35 +1,9 @@
1
- module Nydp
2
- PLUGINS = []
3
-
4
- def self.plug_in plugin ; PLUGINS << plugin ; end
5
- def self.load_rake_tasks; PLUGINS.each &:load_rake_tasks ; end
6
- def self.setup ns; PLUGINS.each { |plg| plg.setup ns } ; end
7
- def self.loadfiles; PLUGINS.map(&:loadfiles).flatten ; end
8
- def self.testfiles; PLUGINS.map(&:testfiles).flatten ; end
9
- def self.plugin_names ; PLUGINS.map(&:name) ; end
10
- def self.loadall ns, plugin, files
11
- vm = VM.new(ns)
12
- apply_function ns, :"script-run", :"plugin-start", plugin.name if plugin
13
- files.each { |f|
14
- script_name = f.gsub plugin.base_path, ""
15
- reader = Nydp::StreamReader.new(File.new(f))
16
- Nydp::Runner.new(vm, ns, reader, nil, (script_name || f)).run
17
- }
18
- ensure
19
- apply_function ns, :"script-run", :"plugin-end", plugin.name if plugin
20
- end
1
+ require 'date'
2
+ require 'set'
21
3
 
22
- def self.build_nydp extra_files=nil
23
- ns = { }
24
- setup(ns)
25
- PLUGINS.each { |plg|
26
- loadall ns, plg, plg.loadfiles
27
- loadall ns, plg, plg.testfiles
28
- }
29
- loadall ns, nil, extra_files if extra_files
30
- ns
4
+ module Nydp
5
+ class Namespace < Hash
31
6
  end
32
-
33
7
  def self.apply_function ns, function_name, *args
34
8
  function = r2n(function_name.to_sym, ns).value
35
9
  args = r2n args, ns
@@ -43,12 +17,21 @@ module Nydp
43
17
  def self.eval_src ns, src_txt, name=nil ; eval_with Nydp::Runner, ns, src_txt, name ; end
44
18
  def self.eval_src! ns, src_txt, name=nil ; eval_with Nydp::ExplodeRunner, ns, src_txt, name ; end
45
19
  def self.eval_with runner, ns, src_txt, name ; runner.new(VM.new(ns), ns, reader(src_txt), nil, name).run ; end
20
+ def self.ms t1, t0 ; ((t1 - t0) * 1000).to_i ; end
46
21
 
47
- def self.repl
22
+ def self.repl options={ }
23
+ launch_time = Time.now
24
+ last_script_time = Time.now
48
25
  puts "welcome to nydp"
49
- puts "^D to exit"
50
26
  reader = Nydp::ReadlineReader.new $stdin, "nydp > "
51
- ns = build_nydp
27
+ ns = build_nydp do |script|
28
+ this_script_time = Time.now
29
+ puts "script #{script} time #{ms this_script_time, last_script_time}ms" if options[:verbose]
30
+ last_script_time = this_script_time
31
+ end
32
+ load_time = Time.now
33
+ puts "repl ready in #{ms(load_time, launch_time)}ms"
34
+ puts "^D to exit"
52
35
  Nydp::Runner.new(VM.new(ns), ns, reader, $stdout, "<stdin>").run
53
36
  end
54
37
 
@@ -59,9 +42,9 @@ module Nydp
59
42
  ns = build_nydp
60
43
  Nydp::Runner.new(VM.new(ns), ns, reader, nil, "<test-runner>").run
61
44
  end
62
-
63
45
  end
64
46
 
47
+ require "nydp/plugin"
65
48
  require "nydp/core"
66
49
  require "nydp/date"
67
50
  require "nydp/runner"
@@ -1,6 +1,3 @@
1
- require 'nydp'
2
- require 'nydp/error'
3
-
4
1
  module Nydp::Builtin
5
2
  module Base
6
3
  include Nydp::Helper
@@ -1,4 +1,4 @@
1
- require 'nydp'
1
+ require 'nydp/plugin'
2
2
 
3
3
  module Nydp
4
4
  class Core
@@ -86,6 +86,19 @@ module Nydp
86
86
  end
87
87
 
88
88
  # TODO generate various Invocation_XXX classes on-demand instead of hand_coding them all up front
89
+ class Invocation_LEX < Invocation::Base
90
+ def initialize expr, src
91
+ super src
92
+ @sym = expr.car
93
+ end
94
+
95
+ def execute vm
96
+ @sym.value(vm.current_context).invoke_1 vm
97
+ rescue Exception => e
98
+ handle e, @sym.value(vm.current_context), Nydp::NIL
99
+ end
100
+ end
101
+
89
102
  class Invocation_SYM < Invocation::Base
90
103
  def initialize expr, src
91
104
  super src
@@ -99,6 +112,22 @@ module Nydp
99
112
  end
100
113
  end
101
114
 
115
+ class Invocation_LEX_LEX < Invocation::Base
116
+ def initialize expr, src
117
+ super src
118
+ @lex0 = expr.car
119
+ @lex1 = expr.cdr.car
120
+ end
121
+
122
+ def execute vm
123
+ fn = @lex0.value(vm.current_context)
124
+ a0 = @lex1.value(vm.current_context)
125
+ fn.invoke_2 vm, a0
126
+ rescue Exception => e
127
+ handle e, fn, cons(a0)
128
+ end
129
+ end
130
+
102
131
  class Invocation_SYM_LEX < Invocation::Base
103
132
  def initialize expr, src
104
133
  super src
@@ -115,6 +144,24 @@ module Nydp
115
144
  end
116
145
  end
117
146
 
147
+ class Invocation_LEX_LEX_LEX < Invocation::Base
148
+ def initialize expr, src
149
+ super src
150
+ @lex_0 = expr.car
151
+ @lex_1 = expr.cdr.car
152
+ @lex_2 = expr.cdr.cdr.car
153
+ end
154
+
155
+ def execute vm
156
+ fn = @lex_0.value(vm.current_context)
157
+ a0 = @lex_1.value(vm.current_context)
158
+ a1 = @lex_2.value(vm.current_context)
159
+ fn.invoke_3 vm, a0, a1
160
+ rescue Exception => e
161
+ handle e, fn, cons(a0, cons(a1))
162
+ end
163
+ end
164
+
118
165
  class Invocation_SYM_LEX_LEX < Invocation::Base
119
166
  def initialize expr, src
120
167
  super src
@@ -0,0 +1,33 @@
1
+ module Nydp
2
+ PLUGINS = []
3
+
4
+ def self.plug_in plugin ; PLUGINS << plugin ; end
5
+ def self.load_rake_tasks; PLUGINS.each &:load_rake_tasks ; end
6
+ def self.setup ns; PLUGINS.each { |plg| plg.setup ns } ; end
7
+ def self.loadfiles; PLUGINS.map(&:loadfiles).flatten ; end
8
+ def self.testfiles; PLUGINS.map(&:testfiles).flatten ; end
9
+ def self.plugin_names ; PLUGINS.map(&:name) ; end
10
+ def self.loadall ns, plugin, files
11
+ vm = VM.new(ns)
12
+ apply_function ns, :"script-run", :"plugin-start", plugin.name if plugin
13
+ files.each { |f|
14
+ script_name = f.gsub plugin.base_path, ""
15
+ reader = Nydp::StreamReader.new(File.new(f))
16
+ Nydp::Runner.new(vm, ns, reader, nil, (script_name || f)).run
17
+ yield script_name if block_given?
18
+ }
19
+ ensure
20
+ apply_function ns, :"script-run", :"plugin-end", plugin.name if plugin
21
+ end
22
+
23
+ def self.build_nydp extra_files=nil, &block
24
+ ns = Namespace.new
25
+ setup(ns)
26
+ PLUGINS.each { |plg|
27
+ loadall ns, plg, plg.loadfiles, &block
28
+ loadall ns, plg, plg.testfiles, &block
29
+ }
30
+ loadall ns, nil, extra_files, &block if extra_files
31
+ ns
32
+ end
33
+ end
@@ -4,9 +4,9 @@ class Nydp::Symbol
4
4
  attr_reader :hash
5
5
 
6
6
  def initialize name
7
+ name = name.to_s
7
8
  @name = name.to_sym
8
- @inspection = name.to_s
9
- @inspection = "|#{name}|" if untidy(@inspection)
9
+ @inspection = "|#{name}|" if untidy(name)
10
10
  @hash = name.hash
11
11
  end
12
12
 
@@ -34,12 +34,12 @@ class Nydp::Symbol
34
34
 
35
35
  def self.find name, ns ; ns[name.to_sym] ; end
36
36
 
37
- def nydp_type ; :symbol ; end
38
- def inspect ; @inspection ; end
39
- def to_s ; name.to_s ; end
40
- def to_sym ; name ; end
41
- def to_ruby ; to_sym ; end
42
- def eql? other ; self == other ; end
37
+ def nydp_type ; :symbol ; end
38
+ def inspect ; @inspection || name.to_s ; end
39
+ def to_s ; name.to_s ; end
40
+ def to_sym ; name ; end
41
+ def to_ruby ; to_sym ; end
42
+ def eql? other ; self == other ; end
43
43
  def is? nm ; self.name == nm.to_sym ; end
44
44
  def > other ; self.name > other.name ; end
45
45
  def < other ; self.name < other.name ; end
@@ -2,12 +2,24 @@ require "strscan"
2
2
 
3
3
  module Nydp
4
4
  class Tokeniser
5
+ BACKSLASH = /\\/.freeze
6
+ COMMENT = /;.*$/.freeze
7
+ QUOTE = /"/.freeze
8
+ PIPE = /\|/.freeze
9
+ LIST_PFX = /[^\s()]*\(/.freeze
10
+ BRACE_PFX = /[^\s()\}\{]*\{/.freeze
11
+ RPAREN = /\)/.freeze
12
+ RBRACE = /\}/.freeze
13
+ FLOAT = /[-+]?[0-9]*\.[0-9]+([eE][-+]?[0-9]+)?/.freeze
14
+ INTEGER = /[-+]?[0-9]+/.freeze
15
+ ATOM_PIPE = /[^\s()"{}\|]+\|/.freeze
16
+ ATOM = /[^\s()"{}\|]+/.freeze
17
+
5
18
  attr_accessor :state, :finished
6
19
 
7
20
  def initialize reader
8
21
  @reader = reader
9
22
  @scanner = StringScanner.new("")
10
- @state = :lisp
11
23
  end
12
24
 
13
25
  def no_more?
@@ -30,7 +42,7 @@ module Nydp
30
42
  rep = open_delimiter.to_s
31
43
  string = ""
32
44
  while (!no_more?)
33
- if esc = s.scan(/\\/)
45
+ if esc = s.scan(BACKSLASH)
34
46
  rep << esc
35
47
  ch = s.getch
36
48
  case ch
@@ -76,29 +88,29 @@ module Nydp
76
88
  if no_more?
77
89
  @finished = true
78
90
  return nil
79
- elsif comment = s.scan(/;.*$/)
91
+ elsif comment = s.scan(COMMENT)
80
92
  tok = [:comment, comment[1..-1].strip]
81
- elsif open_str = s.scan(/"/)
93
+ elsif open_str = s.scan(QUOTE)
82
94
  tok = [:string_open_delim, open_str]
83
- elsif open_sym = s.scan(/\|/)
95
+ elsif open_sym = s.scan(PIPE)
84
96
  tok = [:sym_open_delim, open_sym]
85
- elsif list_prefix = s.scan(/[^\s()]*\(/)
97
+ elsif list_prefix = s.scan(LIST_PFX)
86
98
  tok = [:left_paren, list_prefix[0...-1]]
87
- elsif list_prefix = s.scan(/[^\s()\}\{]*\{/)
99
+ elsif list_prefix = s.scan(BRACE_PFX)
88
100
  tok = [:left_brace, list_prefix[0...-1]]
89
- elsif s.scan(/\)/)
101
+ elsif s.scan(RPAREN)
90
102
  tok = [:right_paren]
91
- elsif s.scan(/\}/)
103
+ elsif s.scan(RBRACE)
92
104
  tok = [:right_brace]
93
- elsif number = s.scan(/[-+]?[0-9]*\.[0-9]+([eE][-+]?[0-9]+)?/)
105
+ elsif number = s.scan(FLOAT)
94
106
  tok = [:number, number.to_f]
95
- elsif integer = s.scan(/[-+]?[0-9]+/)
107
+ elsif integer = s.scan(INTEGER)
96
108
  tok = [:number, integer.to_i]
97
- elsif atom = s.scan(/[^\s()"{}\|]+\|/)
109
+ elsif atom = s.scan(ATOM_PIPE)
98
110
  atom = atom[0...-1]
99
- rest = next_string_fragment("|", /\|/, nil) || Nydp::StringFragmentToken.new("", "")
111
+ rest = next_string_fragment("|", PIPE, nil) || Nydp::StringFragmentToken.new("", "")
100
112
  tok = [:symbol, "#{atom}#{rest.string}"]
101
- elsif atom = s.scan(/[^\s()"{}\|]+/)
113
+ elsif atom = s.scan(ATOM)
102
114
  tok = [:symbol, atom]
103
115
  else
104
116
  s.getch
@@ -1,3 +1,3 @@
1
1
  module Nydp
2
- VERSION = "0.2.2"
2
+ VERSION = "0.2.3"
3
3
  end
@@ -14,6 +14,10 @@ module Nydp
14
14
  @ns = ns
15
15
  end
16
16
 
17
+ def r2n obj
18
+ super obj, self.ns
19
+ end
20
+
17
21
  def thread expr=nil
18
22
  instructions.push expr if expr
19
23
  while instructions.first
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: nydp
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.2
4
+ version: 0.2.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Conan Dalton
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-06-16 00:00:00.000000000 Z
11
+ date: 2016-10-28 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -91,7 +91,12 @@ files:
91
91
  - lib/lisp/core-017-builtin-dox.nydp
92
92
  - lib/lisp/core-020-utils.nydp
93
93
  - lib/lisp/core-030-syntax.nydp
94
+ - lib/lisp/core-035-flow-control.nydp
95
+ - lib/lisp/core-037-list-utils.nydp
94
96
  - lib/lisp/core-040-utils.nydp
97
+ - lib/lisp/core-041-string-utils.nydp
98
+ - lib/lisp/core-042-date-utils.nydp
99
+ - lib/lisp/core-043-list-utils.nydp
95
100
  - lib/lisp/core-045-dox-utils.nydp
96
101
  - lib/lisp/core-050-test-runner.nydp
97
102
  - lib/lisp/core-060-benchmarking.nydp
@@ -130,6 +135,7 @@ files:
130
135
  - lib/lisp/tests/len-examples.nydp
131
136
  - lib/lisp/tests/list-tests.nydp
132
137
  - lib/lisp/tests/mapsum-examples.nydp
138
+ - lib/lisp/tests/orequal-examples.nydp
133
139
  - lib/lisp/tests/parser-tests.nydp
134
140
  - lib/lisp/tests/plus-plus-examples.nydp
135
141
  - lib/lisp/tests/pre-compile-examples.nydp
@@ -206,6 +212,7 @@ files:
206
212
  - lib/nydp/literal.rb
207
213
  - lib/nydp/pair.rb
208
214
  - lib/nydp/parser.rb
215
+ - lib/nydp/plugin.rb
209
216
  - lib/nydp/readline_history.rb
210
217
  - lib/nydp/runner.rb
211
218
  - lib/nydp/string_atom.rb