superscript 0.4.2 → 0.8.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: e12ad2456097931fa8ae7d7ceb5870ded64f9f13d4602568e3696b9af55b1ae8
4
- data.tar.gz: 920979e9fce25c924a51e83c2b830bafb50532659f2a7fbcb70216dc4e226fa6
3
+ metadata.gz: 0bc0b05122c192f2a84ec91cadc082732fed684193b8188f8199bba45028325a
4
+ data.tar.gz: d984d3bf79427a748d7eff8fe5eb52e9be1b79cf8fa4eb2c296876d1e86619e1
5
5
  SHA512:
6
- metadata.gz: 59c7e83257e769ae2456305fb3c25ae16decc905314a931a1cbf156575775eec38c1ea0c6e30a959868ab58dae48f5e70aa262494e3b75c566bf6b5e3abd9ae6
7
- data.tar.gz: da64fb8f666dd4ff92ddc2d54b7cd4940435f4c8f5bbae5729b23b424feab31d98548fa7cc04ead529963b3a78660c0839b9ee343c880c618a0404ccdd222e59
6
+ metadata.gz: 35ae9ec98919157414db881ab46c8f37038bba5464592539ecb51459d1769d183fa9c734412ca26935444819c0281a8f444d5acbb262bc981511c585a05a439c
7
+ data.tar.gz: 3d17e452859eaea0861b5971dd7f04077689e7920c446a504b6ecacb4034d4092520ba32f99f2b674071376d736cc0f227575f860ca9622eb06b8d27f74e5aee
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- superscript (0.4.2)
4
+ superscript (0.8.0)
5
5
 
6
6
  GEM
7
7
  remote: https://rubygems.org/
@@ -1,6 +1,22 @@
1
1
  class Go < Superscript::Dsl
2
2
  def go(*args)
3
- puts "Go #{args.join(" ")}"
3
+ self.say "Go #{args.join(" ")}!"
4
+ end
5
+
6
+ def hang
7
+ sleep 9999
8
+ end
9
+
10
+ def say(message)
11
+ puts message
12
+ end
13
+
14
+ def struct
15
+ Struct.new(:name).new("joe")
16
+ end
17
+
18
+ def now
19
+ Time.now
4
20
  end
5
21
 
6
22
  def explode!
@@ -1,3 +1,2 @@
1
- go "gators"
2
-
3
- explode!
1
+ a = struct
2
+ go a.name
@@ -4,11 +4,18 @@ $stdout.sync = true
4
4
 
5
5
  require "bundler/setup"
6
6
  require "superscript"
7
+ require "optparse"
7
8
 
8
- if ARGV.length == 0
9
- puts "USAGE: superscript dsl.rb [script.rb]"
10
- exit 1
11
- end
9
+ options = {
10
+ methods: false,
11
+ on_error_exec: nil
12
+ }
13
+ ARGV << "-h" if ARGV.empty?
14
+
15
+ optparse = OptionParser.new do |opt|
16
+ opt.on('--allow-methods') { |o| options[:methods] = true }
17
+ opt.on('--on-error-exec CMD') { |o| options[:on_error_exec] = o }
18
+ end.parse!
12
19
 
13
20
  best_guess_path = if ARGV[0].start_with? "/"
14
21
  ARGV[0]
@@ -22,13 +29,15 @@ ctx_classname = File.basename(ARGV[0]).split(".").first.capitalize
22
29
  ctx = (eval "#{ctx_classname}").new
23
30
 
24
31
  if ARGV[1]
25
- runner = Superscript::Runner.new ARGV[1]
32
+ runner = Superscript::Runner.new ARGV[1], options
26
33
  runner.run! ctx
27
34
  else
28
- runner = Superscript::Runner.new
35
+ require "readline"
36
+
37
+ runner = Superscript::Runner.new nil, options
29
38
  loop do
30
- print "> "
31
- contents = STDIN.gets
39
+ contents = Readline.readline "> ", true
40
+
32
41
  value = runner.run! ctx, contents: contents
33
42
  puts " => #{value.inspect}"
34
43
  end
@@ -1,7 +1,4 @@
1
1
  module Superscript
2
2
  class Ctx
3
- def method_missing(*args)
4
- ::Superscript.error :ctx_method_missing, "No such command or variable '#{args.first}'"
5
- end
6
3
  end
7
4
  end
@@ -1,31 +1,14 @@
1
- module Superscript
2
- def self.error(where, *args)
3
- puts "-- [ superscript error ] --"
4
- error_message = ""
5
- case where
6
- when :exception
7
- exception = args.first
8
- pp exception
9
- pp exception.backtrace_locations
10
- error_message = exception
11
- when :ctx_method_missing, :tp_singleton_method_added, :tp_command_not_found
12
- error_message = args.first
13
- when :tp_class_define, :tp_module_define
14
- error_message = args.first
15
- else
16
- pp [:unknown_where, where, args]
17
- error_message = args.join(" ")
18
- end
1
+ Signal.trap "TERM" do
2
+ exit 0
3
+ end
19
4
 
20
- puts error_message
21
- if ENV["SUPERSCRIPT_ERROR_EXEC"]
22
- error_exec_pid = spawn ENV["SUPERSCRIPT_ERROR_EXEC"], error_message
23
- Process.wait error_exec_pid
24
- end
25
- exit 1
26
- end
5
+ module Superscript
27
6
  class Runner
28
- def initialize path=nil
7
+ def initialize path=nil, opts={}
8
+ @methods = opts[:methods] || false
9
+ @on_error_exec = opts[:on_error_exec]
10
+
11
+ @armed = false
29
12
  @path = if path
30
13
  path
31
14
  else
@@ -33,32 +16,77 @@ module Superscript
33
16
  end
34
17
  end
35
18
 
19
+ def error!(where, *args)
20
+ puts "-- [ superscript error ] --"
21
+ error_message = ""
22
+ case where
23
+ when :exception
24
+ exception = args.first
25
+ error_message = exception
26
+ when :tp_call_superscript, :tp_call_superscript_global
27
+ error_message = "Can't touch this"
28
+ when :ctx_method_missing, :tp_singleton_method_added, :tp_command_not_found
29
+ error_message = args.first
30
+ when :tp_class_define, :tp_module_define
31
+ error_message = args.first
32
+ else
33
+ pp [:unknown_where, where, args]
34
+ error_message = args.join(" ")
35
+ end
36
+
37
+ puts error_message
38
+ if @on_error_exec
39
+ system("#{@on_error_exec} #{error_message}")
40
+ end
41
+
42
+ unless @path == "<interactive>"
43
+ exit 1
44
+ end
45
+ end
46
+
47
+ def arm!(reason=nil)
48
+ p [:arm!, reason] if ENV["SUPERSCRIPT_DEBUG"]
49
+ @armed = true
50
+ end
51
+ def disarm!(reason=nil)
52
+ p [:disarm!, reason] if ENV["SUPERSCRIPT_DEBUG"]
53
+ @armed = false
54
+ end
55
+
36
56
  def run!(ctx, contents:nil)
37
57
  contents = File.read(@path) unless contents
58
+ $__superscript_none_of_yer_business = self
59
+ ctx.define_singleton_method "method_missing" do |*args|
60
+ $__superscript_none_of_yer_business.error! :ctx_method_missing, "No such command or variable '#{args.first}'"
61
+ end
38
62
 
39
- @armed = false
63
+ disarm! :at_start
40
64
  trace = TracePoint.new do |tp|
41
65
  if ENV["SUPERSCRIPT_DEBUG"]
42
66
  p [@armed, tp.path, tp.lineno, tp.method_id, tp.event, tp.defined_class]
43
67
  end
44
68
 
69
+ if tp.event == :line && tp.path == @path && !@armed
70
+ arm!
71
+ end
72
+
45
73
  if tp.defined_class&.name == "BasicObject" && tp.method_id == :instance_eval
46
74
  if tp.event == :script_compiled
47
- @armed = true
75
+ arm! :script_compiled
48
76
  elsif tp.event == :c_return
49
- @armed = false
77
+ disarm! :script_done
50
78
  end
51
79
  end
52
80
 
53
- if tp.event == :return && tp.defined_class.ancestors.include?(Superscript::Ctx)
54
- @armed = true
81
+ if tp.path == @path && tp.event == :return && tp.defined_class.ancestors.include?(Superscript::Ctx)
82
+ arm! :return_to_script_from_dsl_calling_another_dsl_method
55
83
  end
56
84
 
57
85
  next unless @armed
58
86
 
59
87
  case tp.event
60
88
  when :class
61
- ::Superscript.error :tp_module_define, "Defining modules is not allowed"
89
+ error! :tp_module_define, "Defining modules is not allowed"
62
90
  when :line
63
91
  lines = if tp.path == "<interactive>"
64
92
  contents.split("\n")
@@ -69,19 +97,36 @@ module Superscript
69
97
  line = lines[tp.lineno-1].lstrip
70
98
  puts "< #{tp.path}:#{tp.lineno-1}"
71
99
  puts line
100
+
101
+ if line.match(/\$__superscript_none_of_yer_business/)
102
+ tp.disable
103
+ error! :tp_call_superscript_global
104
+ end
72
105
  when :c_call
73
- # allow calls to these classes
74
- next if ["Array", "String","Float", "Integer"].include? tp.defined_class.name
106
+ # allow calls to these instances
107
+ if tp.defined_class.ancestors.at(1) == Struct
108
+ disarm! :safe_instance
109
+ next
110
+ end
111
+ if ["Array", "String","Float", "Integer"].include? tp.defined_class.name
112
+ disarm! :safe_instance
113
+ next
114
+ end
75
115
 
76
116
  case tp.method_id
77
117
  when :singleton_method_added
118
+ if @methods
119
+ next
120
+ end
121
+ trace.disable
122
+ error! :tp_singleton_method_added, "Deffining methods is not allowed"
123
+ when :method_missing
78
124
  trace.disable
79
- ::Superscript.error :tp_singleton_method_added, "Deffining methods is not allowed"
80
125
  else
81
126
  trace.disable
82
127
  case tp.defined_class.name
83
128
  when "Class"
84
- ::Superscript.error :tp_class_define, "Defining classes is not allowed"
129
+ error! :tp_class_define, "Defining classes is not allowed"
85
130
  else
86
131
  class_name = case tp.defined_class.inspect
87
132
  when "Kernel"
@@ -102,17 +147,31 @@ module Superscript
102
147
  "#{class_name}.#{tp.method_id}"
103
148
  end
104
149
 
105
- ::Superscript.error :tp_command_not_found, "Command not found '#{command_name}'"
150
+ error! :tp_command_not_found, "Command not found '#{command_name}'"
106
151
  end
107
152
  end
108
153
  when :call
154
+ if tp.method_id == :method_missing
155
+ tp.disable
156
+ next
157
+ end
158
+
159
+ if tp.defined_class.ancestors.first.to_s == "#<Class:Superscript>"
160
+ tp.disable
161
+ error! :tp_call_superscript
162
+ end
109
163
  # disable if calling some other file
110
- unless tp.path == @path
111
- @armed = false
164
+ # but do not allow call to Superscript.error etc
165
+ if tp.path != @path
166
+ disarm! :calling_other_file
112
167
  end
113
- if tp.defined_class.ancestors.include? Superscript::Ctx
114
- @armed = false
168
+ tp.defined_class.ancestors.each do |ancestor|
169
+ if ancestor.to_s == "Superscript::Dsl"
170
+ disarm! :dsl_method
171
+ break
172
+ end
115
173
  end
174
+
116
175
  end
117
176
  end
118
177
 
@@ -129,7 +188,7 @@ module Superscript
129
188
  print "#{@path}:#{ex.backtrace_locations.first.lineno} "
130
189
  puts ex.message.split(" for ").first
131
190
  else
132
- ::Superscript.error :exception, ex
191
+ error! :exception, ex
133
192
  end
134
193
  ensure
135
194
  trace.disable
@@ -1,3 +1,3 @@
1
1
  module Superscript
2
- VERSION = "0.4.2"
2
+ VERSION = "0.8.0"
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: superscript
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.2
4
+ version: 0.8.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Matti Paksula
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2020-05-20 00:00:00.000000000 Z
11
+ date: 2020-05-25 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler