Skip to content
Browse files

kernel/ reorg! New functionality goes in kernel/core only. kernel.rba…

… have been

replaced with bootstrap.rba and core.rba. Currently both are loaded automatically
from main.
  • Loading branch information...
1 parent bdee387 commit 54689804c80973de40c1f9e75810cb49e60826df @evanphx evanphx committed Jan 21, 2007
Showing with 875 additions and 604 deletions.
  1. +39 −6 Rakefile
  2. 0 kernel/{ → bootstrap}/00auto_fields.rb
  3. +0 −4 kernel/{ → bootstrap}/00io.rb
  4. 0 kernel/{ → bootstrap}/00object.rb
  5. 0 kernel/{ → bootstrap}/01class.rb
  6. 0 kernel/{ → bootstrap}/02module.rb
  7. 0 kernel/{ → bootstrap}/03hash.rb
  8. +35 −0 kernel/bootstrap/04kernel.rb
  9. +0 −68 kernel/{ → bootstrap}/array.rb
  10. 0 kernel/{ → bootstrap}/bignum.rb
  11. 0 kernel/{ → bootstrap}/class.rb
  12. 0 kernel/{ → bootstrap}/compiled_method.rb
  13. +1 −1 kernel/{ → bootstrap}/context.rb
  14. +149 −0 kernel/bootstrap/core.rb
  15. +18 −0 kernel/{ → bootstrap}/exception.rb
  16. 0 kernel/{ → bootstrap}/fixnum.rb
  17. 0 kernel/{ → bootstrap}/float.rb
  18. +14 −0 kernel/bootstrap/gc.rb
  19. 0 kernel/{ → bootstrap}/global.rb
  20. 0 kernel/{ → bootstrap}/method_missing.rb
  21. 0 kernel/{ → bootstrap}/method_table.rb
  22. 0 kernel/{ → bootstrap}/module.rb
  23. 0 kernel/{ → bootstrap}/nil.rb
  24. 0 kernel/{ → bootstrap}/regexp.rb
  25. +4 −0 kernel/bootstrap/ruby.rb
  26. +0 −172 kernel/{ → bootstrap}/string.rb
  27. 0 kernel/{ → bootstrap}/symbol.rb
  28. 0 kernel/{ → bootstrap}/tuple.rb
  29. +0 −285 kernel/core.rb
  30. 0 kernel/{enumerable.rb → core/01enumerable.rb}
  31. +256 −0 kernel/core/02range.rb
  32. 0 kernel/{comparable.rb → core/03comparable.rb}
  33. 0 kernel/{numeric.rb → core/04numeric.rb}
  34. 0 kernel/{ → core}/__loader.rb
  35. +64 −1 kernel/core/array.rb
  36. 0 kernel/{ → core}/compression.rb
  37. 0 kernel/{ → core}/continuation.rb
  38. +65 −0 kernel/core/object.rb
  39. +17 −0 kernel/core/process.rb
  40. 0 kernel/{ → core}/readline.rb
  41. +156 −0 kernel/core/string.rb
  42. 0 kernel/{ → core}/throw_catch.rb
  43. BIN runtime/bootstrap.rba
  44. BIN runtime/core.rba
  45. BIN runtime/kernel.rba
  46. +1 −1 shotgun/lib/cpu_instructions.c
  47. +1 −1 shotgun/lib/cpu_marshal.c
  48. +4 −3 shotgun/lib/grammer_runtime.c
  49. +4 −2 shotgun/lib/machine.c
  50. +1 −1 shotgun/lib/symbol.c
  51. +46 −59 shotgun/main.c
View
45 Rakefile
@@ -215,16 +215,49 @@ namespace :build do
puts "Building hints and fields..."
Rake::Task['build:fields'].invoke
end
+
+ task :bootstrap => 'kernel/hints' do
+ Dir.chdir "kernel" do
+ files = Dir["bootstrap/*.rb"].sort
+
+ changed = []
+ files.each do |file|
+ cmp = "#{file}c"
+ unless File.exists?(cmp) and File.mtime(cmp) >= File.mtime(file)
+ changed << cmp
+ system "../bin/obsolete.rcompile #{file}"
+ raise "Failed to compile #{file}" if $?.exitstatus != 0
+ end
+ file << "c"
+ end
+
+ File.open(".load_order.txt","w") do |f|
+ f.puts files.join("\n")
+ end
+
+ kern = "../runtime/bootstrap.rba"
+
+ # File.unlink("../kernel.rba") if File.exists?("../kernel.rba")
+ if File.exists? kern
+ if changed.empty?
+ puts "No files to update."
+ else
+ system "zip -u #{kern} .load_order.txt #{changed.join(' ')}"
+ end
+ else
+ system "zip #{kern} .load_order.txt #{files.join(' ')}"
+ end
+ end
+ end
desc "Build the kernel."
- task :kernel => 'kernel/hints' do
+ task :core => 'kernel/hints' do
files = nil
Dir.chdir("kernel") do
- files = Dir["*.rb"].sort
- files.delete "__loader.rb"
+ files = Dir["core/*.rb"].sort
+ files.delete "core/__loader.rb"
- files += Dir["core/*.rb"]
- files << "__loader.rb"
+ files << "core/__loader.rb"
changed = []
files.each do |file|
@@ -241,7 +274,7 @@ namespace :build do
f.puts files.join("\n")
end
- kern = "../runtime/kernel.rba"
+ kern = "../runtime/core.rba"
# File.unlink("../kernel.rba") if File.exists?("../kernel.rba")
if File.exists? kern
View
0 kernel/00auto_fields.rb → kernel/bootstrap/00auto_fields.rb
File renamed without changes.
View
4 kernel/00io.rb → kernel/bootstrap/00io.rb
@@ -4,8 +4,4 @@ def write(str)
exc = IOError.new("Unable to write '#{str}' via #{self}")
raise exc
end
-
- def <<(obj)
- write(obj.to_s)
- end
end
View
0 kernel/00object.rb → kernel/bootstrap/00object.rb
File renamed without changes.
View
0 kernel/01class.rb → kernel/bootstrap/01class.rb
File renamed without changes.
View
0 kernel/02module.rb → kernel/bootstrap/02module.rb
File renamed without changes.
View
0 kernel/03hash.rb → kernel/bootstrap/03hash.rb
File renamed without changes.
View
35 kernel/bootstrap/04kernel.rb
@@ -0,0 +1,35 @@
+module Kernel
+ def puts(*a)
+ a = [""] if a.empty?
+ a.each { |obj| STDOUT.puts obj.to_s }
+ end
+
+ def p(*a)
+ a = [nil] if a.empty?
+ a.each { |obj| STDOUT.puts obj.inspect }
+ end
+
+ def print(*args)
+ args.each do |obj|
+ STDOUT.write obj.to_s
+ end
+ end
+
+ def raise(exc=$!, msg=nil)
+ if exc.kind_of?(String)
+ exc = RuntimeError.new(exc)
+ elsif msg
+ cls = exc
+ exc = cls.new(msg)
+ end
+ Ruby.asm "push exc\nraise_exc"
+ end
+
+ def exit(code=0)
+ Process.exit(code)
+ end
+
+ def at_exit(&block)
+ Ruby::AtExit << block
+ end
+end
View
68 kernel/array.rb → kernel/bootstrap/array.rb
@@ -27,10 +27,6 @@ def each
self
end
- def index(val)
- find_index { |o| o == val }
- end
-
def ==(other)
return false unless other.kind_of?(Array)
return false if @total != other.size
@@ -89,7 +85,6 @@ def [](idx)
@tuple.at(idx)
end
-
def first
return nil if @total == 0
@tuple.at(0)
@@ -139,40 +134,6 @@ def +(other)
other.each { |e| out << e }
return out
end
-
- def -(other)
- out = []
- each { |e|
- unless other.include?(e)
- out << e
- end
- }
- return out
- end
-
- def &(other)
- out=[]
- self.uniq!
- each { |e|
- if other.include?(e)
- out << e
- end
- }
- return out
- end
-
- # TODO: test val for negative values and floats
- def *(val)
- if val.class == String
- return self.join(val)
- else
- out=[]
- val.times do
- out.push *self
- end
- return out
- end
- end
def <=>(other)
each_with_index do |a, i| #Should use zip, but it wasn't liking it.
@@ -222,33 +183,4 @@ def pop
@total -= 1
return ele
end
-
- def reverse
- ary = []
- i = @total - 1
- while i >= 0
- ary << self[i]
- i -= 1
- end
- return ary
- end
-
- def uniq
- seen = {}
- ary = []
- i = 0
- while i < @total
- e = @tuple.at(i)
- ary << e unless seen[e]
- seen[e] = true
- i += 1
- end
- ary
- end
-
- def uniq!
- ary = self.uniq
- ary.size == self.size ? nil : replace(ary)
- end
-
end
View
0 kernel/bignum.rb → kernel/bootstrap/bignum.rb
File renamed without changes.
View
0 kernel/class.rb → kernel/bootstrap/class.rb
File renamed without changes.
View
0 kernel/compiled_method.rb → kernel/bootstrap/compiled_method.rb
File renamed without changes.
View
2 kernel/context.rb → kernel/bootstrap/context.rb
@@ -177,7 +177,7 @@ def new(&block)
# Obi-Wan: [with a small wave of his hand] You don't need to see his identification.
# Stormtrooper: We don't need to see his identification
#
- # Using a binding to obtain the given proc where the binding was created
+ # Using a binging to obtain the given proc where the binding was created
#
# def stormtrooper
# binding
View
149 kernel/bootstrap/core.rb
@@ -0,0 +1,149 @@
+
+class InvalidIndex < Exception
+end
+
+class Object
+ include Kernel
+
+ def initialize
+ end
+
+ def class
+ Ruby.primitive :logical_class
+ end
+
+ def object_id
+ Ruby.primitive :object_id
+ end
+
+ def hash
+ Ruby.primitive :hash_object
+ end
+
+ def nil?
+ false
+ end
+
+ def undef?
+ false
+ end
+
+ def kind_of?(cls)
+ self.class < cls
+ end
+
+ def instance_of?(cls)
+ self.class == cls
+ end
+
+ alias :is_a? :kind_of?
+
+ def copy_from(other, start)
+ Ruby.primitive :dup_into
+ end
+
+ def dup
+ nw = self.class.allocate
+ nw.copy_from(self, 0)
+ return nw
+ end
+
+ def equal?(other)
+ object_id == other.object_id
+ end
+
+ alias :== :equal?
+ alias :eql? :equal?
+ alias :=== :equal?
+
+ def to_s
+ "#<#{self.class.name}:0x#{self.object_id.to_s(16)}>"
+ end
+
+ def inspect
+ if !@__ivars__ || !@__ivars__.is_a?(Array) || @__ivars__.empty?
+ return self.to_s
+ end
+
+ res = "#<#{self.class.name}:0x#{self.object_id.to_s(16)} "
+ parts = []
+ @__ivars__.each do |k,v|
+ parts << "#{k}=#{v.inspect}"
+ end
+ res << parts.join(" ")
+ res << ">"
+ return res
+ end
+
+ def respond_to?(meth)
+ begin
+ !self.class.instance_method(meth).nil?
+ rescue NameError
+ false
+ end
+ end
+
+ def __send__(name, *args, &prc)
+ meth = self.class.instance_method(name)
+ meth = meth.bind(self)
+ meth.call(*args, &prc)
+ end
+
+ alias :send :__send__
+
+ def method(name)
+ self.class.instance_method(name).bind(self)
+ end
+
+ def lambda
+ env = nil
+ Ruby.asm "push_block\nset env\n"
+ unless env
+ raise ArgumentError, "Unable to create a Proc if a block is not passed in"
+ end
+
+ return Proc.from_environment(env)
+ end
+
+end
+
+TRUE = true
+FALSE = false
+
+class TrueClass
+ def &(other)
+ (other.nil? or other == false) ? false : true
+ end
+
+ def ^(other)
+ (other.nil? or other == false) ? true : false
+ end
+
+ def |(other)
+ true
+ end
+
+ def to_s
+ "true"
+ end
+
+ alias :inspect :to_s
+end
+
+class FalseClass
+ def &(other)
+ false
+ end
+
+ def ^(other)
+ (other == false or other.nil?) ? false : true
+ end
+
+ alias :| :^
+
+ def to_s
+ "false"
+ end
+
+ alias :inspect :to_s
+end
View
18 kernel/exception.rb → kernel/bootstrap/exception.rb
@@ -27,3 +27,21 @@ class ScriptError < Exception
class NotImplementedError < Exception
end
+class SyntaxError
+ self.instance_fields = 4
+
+ ivar_as_index :column => 2, :line => 3
+
+ def column
+ @column
+ end
+
+ def line
+ @line
+ end
+
+ def import_position(c,l)
+ @column = c
+ @line = l
+ end
+end
View
0 kernel/fixnum.rb → kernel/bootstrap/fixnum.rb
File renamed without changes.
View
0 kernel/float.rb → kernel/bootstrap/float.rb
File renamed without changes.
View
14 kernel/bootstrap/gc.rb
@@ -0,0 +1,14 @@
+class GC
+
+ def self.start
+ run(false)
+ end
+
+ def self.promote_all
+ run(true)
+ end
+
+ def self.run(tenure)
+ Ruby.primitive :gc_start
+ end
+end
View
0 kernel/global.rb → kernel/bootstrap/global.rb
File renamed without changes.
View
0 kernel/method_missing.rb → kernel/bootstrap/method_missing.rb
File renamed without changes.
View
0 kernel/method_table.rb → kernel/bootstrap/method_table.rb
File renamed without changes.
View
0 kernel/module.rb → kernel/bootstrap/module.rb
File renamed without changes.
View
0 kernel/nil.rb → kernel/bootstrap/nil.rb
File renamed without changes.
View
0 kernel/regexp.rb → kernel/bootstrap/regexp.rb
File renamed without changes.
View
4 kernel/bootstrap/ruby.rb
@@ -0,0 +1,4 @@
+
+module Ruby
+ AtExit = []
+end
View
172 kernel/string.rb → kernel/bootstrap/string.rb
@@ -108,159 +108,6 @@ def to_sym
end
alias :intern :to_sym
- def to_sexp_full(name, line, newlines)
- Ruby.primitive :string_to_sexp
- end
-
- def to_sexp(name="(eval)",line=1,newlines=true)
- out = to_sexp_full(name, line, newlines)
- if out.kind_of? Tuple
- exc = SyntaxError.new out.at(0)
- exc.import_position out.at(1), out.at(2)
- raise exc
- end
- return out
- end
-
- def *(num)
- str = []
- num.times { str << self }
- return str.join("")
- end
-
- def reverse
- str = ""
- i = @bytes - 1
- while i >= 0
- str << self[i,1]
- i -= 1
- end
- return str
- end
-
- def reverse!
- sd = self.reverse
- @data = sd.data
- @bytes = sd.size
- return self
- end
-
- def strip
- r = /\s*([^\s](.*[^\s])?)\s*/m
- m = r.match(self)
- return '' unless m
- return m.captures[0]
- end
-
- def strip!
- sd = self.strip
- @data = sd.data
- @bytes = sd.size
- return self
- end
-
- def =~(pattern)
- m = pattern.match(self)
- m ? m.full.at(0) : nil
- end
-
- def include?(arg)
- if arg.is_a? Fixnum
- @data.each { |b| return true if b == arg }
- return false
- elsif arg.is_a? String
- return (self.index(arg) != nil)
- else
- raise ArgumentError.new("String#include? cannot accept #{arg.class} objects")
- end
- end
-
- def index(arg, offset = nil )
- if arg.is_a? Fixnum
- i = 0
- @data.each { |b| return i if b == arg; i += 1 }
- elsif arg.is_a? String
- idx = 0
- if offset
- if offset >= 0
- return nil if offset >= self.size
- idx = offset
- else
- return nil if (1-offset) >= self.size
- idx = self.size + offset
- end
- end
- argsize = arg.size
- max = self.size - argsize
- if max >= 0 and argsize > 0
- idx.upto(max) do |i|
- if @data.get_byte(i) == arg.data.get_byte(0)
- return i if substring(i,argsize) == arg
- end
- end
- end
- elsif arg.is_a? Regexp
- idx = offset ? offset : 0
- mstr = self[idx..-1]
- offset = self.size - mstr.size
- m = arg.match(mstr)
- if m
- return offset + m.begin(0)
- end
- return nil
- else
- raise ArgumentError.new("String#index cannot accept #{arg.class} objects")
- end
- return nil
- end
-
- def [](arg, len = nil)
- if len
- len = len.to_i
- return nil if len < 0
- end
-
- if arg.is_a? String
- unless len.nil?
- raise ArgumentError.new("String#[] got incorrect arguments.") # TODO: Make this helpful.
- end
- return (self.include?(arg) ? arg.dup : nil)
- elsif arg.respond_to? :match
- m = arg.match(self)
- return m[len.to_i] if m && len
- return m[0] if m
- return nil
- elsif arg.respond_to?(:first) and arg.respond_to?(:last)
- from = arg.first
- to = arg.last
- to = to - 1 if arg.respond_to?(:exclude_end?) && arg.exclude_end?
- size = self.size
- from = from + size if from < 0
- to = to + size if to < 0
- len = to - from + 1
- self[from, len]
-
- elsif arg and arg.respond_to?(:to_i)
- arg = arg.to_i
- size = self.size
- arg = arg + size if arg < 0
- if 0 <= arg && arg < size
- if len
- len = size - arg if arg + len >= size
- substring(arg, len)
- else
- @data.get_byte(arg)
- end
- else # invalid start index
- len ? "" : nil
- end
- else
- raise ArgumentError.new("String#[] cannot accept #{arg.class} objects")
- end
- end
-
- alias_method :slice, :[]
-
def each_byte(&prc)
@data.each(&prc)
end
@@ -366,25 +213,6 @@ def to_i(radix=10)
end
end
-class SyntaxError
- self.instance_fields = 4
-
- ivar_as_index :column => 2, :line => 3
-
- def column
- @column
- end
-
- def line
- @line
- end
-
- def import_position(c,l)
- @column = c
- @line = l
- end
-end
-
class ByteArray
def self.new(cnt)
Ruby.primitive :allocate_bytes
View
0 kernel/symbol.rb → kernel/bootstrap/symbol.rb
File renamed without changes.
View
0 kernel/tuple.rb → kernel/bootstrap/tuple.rb
File renamed without changes.
View
285 kernel/core.rb
@@ -1,285 +0,0 @@
-
-module Ruby
- AtExit = []
-end
-
-module Kernel
- def puts(*a)
- a = [""] if a.empty?
- a.each { |obj| STDOUT.puts obj.to_s }
- end
-
- def p(*a)
- a = [nil] if a.empty?
- a.each { |obj| STDOUT.puts obj.inspect }
- end
-
- def print(*args)
- args.each do |obj|
- STDOUT.write obj.to_s
- end
- end
-
- def raise(exc=$!, msg=nil)
- if exc.kind_of?(String)
- exc = RuntimeError.new(exc)
- elsif msg
- cls = exc
- exc = cls.new(msg)
- end
- Ruby.asm "push exc\nraise_exc"
- end
-
- def exit(code=0)
- Process.exit(code)
- end
-
- def at_exit(&block)
- Ruby::AtExit << block
- end
-end
-
-class Process
- def self.exit(code)
- Ruby.primitive :process_exit
- end
-
- def self.micro_sleep(ms)
- Ruby.primitive :micro_sleep
- end
-
- def self.sleep(sec)
- micro_sleep(sec * 1_000_000)
- end
-
- def self.usleep(sec)
- micro_sleep(sec * 1_000)
- end
-end
-
-class InvalidIndex < Exception
-end
-
-class Object
- include Kernel
-
- def initialize
- end
-
- def class
- Ruby.primitive :logical_class
- end
-
- def object_id
- Ruby.primitive :object_id
- end
-
- def hash
- Ruby.primitive :hash_object
- end
-
- def nil?
- false
- end
-
- def undef?
- false
- end
-
- def kind_of?(cls)
- self.class < cls
- end
-
- def instance_of?(cls)
- self.class == cls
- end
-
- alias :is_a? :kind_of?
-
- def copy_from(other, start)
- Ruby.primitive :dup_into
- end
-
- def dup
- nw = self.class.allocate
- nw.copy_from(self, 0)
- return nw
- end
-
- def equal?(other)
- object_id == other.object_id
- end
-
- alias :== :equal?
- alias :eql? :equal?
- alias :=== :equal?
-
- def to_s
- "#<#{self.class.name}:0x#{self.object_id.to_s(16)}>"
- end
-
- def inspect
- if !@__ivars__ || !@__ivars__.is_a?(Array) || @__ivars__.empty?
- return self.to_s
- end
-
- res = "#<#{self.class.name}:0x#{self.object_id.to_s(16)} "
- parts = []
- @__ivars__.each do |k,v|
- parts << "#{k}=#{v.inspect}"
- end
- res << parts.join(" ")
- res << ">"
- return res
- end
-
- def respond_to?(meth)
- begin
- !self.class.instance_method(meth).nil?
- rescue NameError
- false
- end
- end
-
- def __send__(name, *args, &prc)
- meth = self.class.instance_method(name)
- meth = meth.bind(self)
- meth.call(*args, &prc)
- end
-
- alias :send :__send__
-
- def method(name)
- self.class.instance_method(name).bind(self)
- end
-
- def lambda
- env = nil
- Ruby.asm "push_block\nset env\n"
- unless env
- raise ArgumentError, "Unable to create a Proc if a block is not passed in"
- end
-
- return Proc.from_environment(env)
- end
-
- # call-seq:
- # obj.instance_exec(arg...) {|var...| block } => obj
- #
- # Executes the given block within the context of the receiver
- # (_obj_). In order to set the context, the variable +self+ is set
- # to _obj_ while the code is executing, giving the code access to
- # _obj_'s instance variables. Arguments are passed as block parameters.
- #
- # class Klass
- # def initialize
- # @secret = 99
- # end
- # end
- # k = Klass.new
- # k.instance_exec(5) {|x| @secret+x } #=> 104
- def instance_exec(*args, &prc)
- raise ArgumentError, "Missing block" unless block_given?
- env = prc.block.dup
- env.put(1, env.home.dup) # home: MethodContext
- env.home.put(9, self) # receiver: Object
- proc = Proc.from_environment(env)
- proc.call(*args)
- end
-
- # call-seq:
- # obj.instance_eval(string [, filename [, lineno]] ) => obj
- # obj.instance_eval {| | block } => obj
- #
- # Evaluates a string containing Ruby source code, or the given block,
- # within the context of the receiver (_obj_). In order to set the
- # context, the variable +self+ is set to _obj_ while
- # the code is executing, giving the code access to _obj_'s
- # instance variables. In the version of <code>instance_eval</code>
- # that takes a +String+, the optional second and third
- # parameters supply a filename and starting line number that are used
- # when reporting compilation errors.
- #
- # class Klass
- # def initialize
- # @secret = 99
- # end
- # end
- # k = Klass.new
- # k.instance_eval { @secret } #=> 99
- def instance_eval(string = nil, filename = "(eval)", line = 1, &prc)
- if block_given?
- instance_exec(&prc)
- else
- cm = string.compile_as_method
- cm.activate(self, [])
- end
- end
-
- def instance_variables
- if !@__ivars__ or @__ivars__.size == 0
- return []
- end
- res = []
- @__ivars__.each do |k,v|
- res << k.to_s
- end
- return res
- end
-end
-
-TRUE = true
-FALSE = false
-
-class TrueClass
- def &(other)
- (other.nil? or other == false) ? false : true
- end
-
- def ^(other)
- (other.nil? or other == false) ? true : false
- end
-
- def |(other)
- true
- end
-
- def to_s
- "true"
- end
-
- alias :inspect :to_s
-end
-
-class FalseClass
- def &(other)
- false
- end
-
- def ^(other)
- (other == false or other.nil?) ? false : true
- end
-
- alias :| :^
-
- def to_s
- "false"
- end
-
- alias :inspect :to_s
-end
-
-class GC
-
- def self.start
- run(false)
- end
-
- def self.promote_all
- run(true)
- end
-
- def self.run(tenure)
- Ruby.primitive :gc_start
- end
-end
View
0 kernel/enumerable.rb → kernel/core/01enumerable.rb
File renamed without changes.
View
256 kernel/core/02range.rb
@@ -0,0 +1,256 @@
+# Ryan Davis and Eric Hodel wrote this. They rock.
+#
+class Range
+
+ include Enumerable
+
+ ##
+ # call-seq:
+ # Range.new(start, end, exclusive=false) => range
+ #
+ # Constructs a range using the given <em>start</em> and <em>end</em>.
+ # If the third parameter is omitted or is <tt>false</tt>, the
+ # <em>range</em> will include the end object; otherwise, it will be
+ # excluded.
+
+ def initialize(first, last, exclude_end=false)
+ @first = first
+ @last = last
+ @exclude_end = exclude_end
+ end
+
+ ##
+ # call-seq:
+ # rng == obj => true or false
+ #
+ # Returns <tt>true</tt> only if <em>obj</em> is a Range, has
+ # equivalent beginning and end items (by comparing them with
+ # <tt>==</tt>), and has the same #exclude_end? setting as <i>rng</t>.
+ #
+ # (0..2) == (0..2) #=> true
+ # (0..2) == Range.new(0,2) #=> true
+ # (0..2) == (0...2) #=> false
+
+ def ==(other)
+ return false unless Range === other
+ return self.first == other.first && self.last == other.last && self.exclude_end? == other.exclude_end?
+ end
+
+ ##
+ # call-seq:
+ # rng === obj => true or false
+ # rng.member?(val) => true or false
+ # rng.include?(val) => true or false
+ #
+ # Returns <tt>true</tt> if <em>obj</em> is an element of <em>rng</em>,
+ # <tt>false</tt> otherwise. Conveniently, <tt>===</tt> is the
+ # comparison operator used by <tt>case</tt> statements.
+ #
+ # case 79
+ # when 1..50 then print "low\n"
+ # when 51..75 then print "medium\n"
+ # when 76..100 then print "high\n"
+ # end
+ #
+ # <em>produces:</em>
+ #
+ # high
+
+ def ===(value)
+ if @first <= value then
+ if self.exclude_end? then
+ return true if value < @last
+ else
+ return true if value <= @last
+ end
+ end
+ return false
+ rescue
+ return false
+ end
+ alias_method :member?, :===
+ alias_method :include?, :===
+
+ ##
+ # call-seq:
+ # rng.each {| i | block } => rng
+ #
+ # Iterates over the elements <em>rng</em>, passing each in turn to the
+ # block. You can only iterate if the start object of the range
+ # supports the <tt>succ</tt> method (which means that you can't
+ # iterate over ranges of <tt>Float</tt> objects).
+ #
+ # (10..15).each do |n|
+ # print n, ' '
+ # end
+ #
+ # <em>produces:</em>
+ #
+ # 10 11 12 13 14 15
+
+ def each
+ first = self.first # dup?
+ last = self.last
+
+ if Fixnum === first && Fixnum === last then
+ last -= 1 if self.exclude_end?
+ first.upto(last) { |i| yield(i) }
+ elsif String === first then
+ first.upto(last) do |s|
+ next if @exclude_end && s == last
+ yield(s)
+ end
+ else
+ current = first
+ if @exclude_end then
+ loop do
+ break if current == last
+ yield(current)
+ current = current.succ
+ end
+ else
+ loop do
+ yield(current)
+ break if current == last
+ current = current.succ
+ end
+ end
+ end
+ return self
+ end
+
+ ##
+ # call-seq:
+ # rng.eql?(obj) => true or false
+ #
+ # Returns <tt>true</tt> only if <em>obj</em> is a Range, has
+ # equivalent beginning and end items (by comparing them with #eql?),
+ # and has the same #exclude_end? setting as <em>rng</em>.
+ #
+ # (0..2) == (0..2) #=> true
+ # (0..2) == Range.new(0,2) #=> true
+ # (0..2) == (0...2) #=> false
+
+ def eql?(other)
+ return false unless Range === other
+ return self.first.eql?(other.first) &&
+ self.last.eql?(other.last) &&
+ self.exclude_end? == other.exclude_end?
+ end
+
+ ##
+ # call-seq:
+ # rng.exclude_end? => true or false
+ #
+ # Returns <tt>true</tt> if <em>rng</em> excludes its end value.
+
+ def exclude_end?
+ @exclude_end
+ end
+
+ ##
+ # call-seq:
+ # rng.first => obj
+ # rng.begin => obj
+ #
+ # Returns the first object in <em>rng</em>.
+
+ def first
+ @first
+ end
+ alias_method :begin, :first
+
+ ##
+ # call-seq:
+ # rng.hash => fixnum
+ #
+ # Generate a hash value such that two ranges with the same start and
+ # end points, and the same value for the "exclude end" flag, generate
+ # the same hash value.
+
+ def hash
+ excl = @exclude_end ? 1 : 0
+ hash = excl
+ hash ^= @first.hash << 1
+ hash ^= @last.hash << 9
+ hash ^= excl << 24;
+ return hash
+ end
+
+ ##
+ # call-seq:
+ # rng.inspect => string
+ #
+ # Convert this range object to a printable form (using
+ # <tt>inspect</tt> to convert the start and end objects).
+
+ def inspect
+ joiner = @exclude_end ? "..." : ".."
+ return "#{@first.inspect}#{joiner}#{@last.inspect}"
+ end
+
+ ##
+ # call-seq:
+ # rng.end => obj
+ # rng.last => obj
+ #
+ # Returns the object that defines the end of <em>rng</em>.
+ #
+ # (1..10).end #=> 10
+ # (1...10).end #=> 10
+
+ def last
+ return @last
+ end
+ alias_method :end, :last
+
+ ##
+ # call-seq:
+ # rng.step(n=1) {| obj | block } => rng
+ #
+ # Iterates over <em>rng</em>, passing each <em>n</em>th element to the
+ # block. If the range contains numbers or strings, natural ordering is
+ # used. Otherwise <tt>step</tt> invokes <tt>succ</tt> to iterate
+ # through range elements. The following code uses class <tt>Xs</tt>,
+ # which is defined in the class-level documentation.
+ #
+ # range = Xs.new(1)..Xs.new(10)
+ # range.step(2) {|x| puts x}
+ # range.step(3) {|x| puts x}
+ #
+ # <em>produces:</em>
+ #
+ # 1 x
+ # 3 xxx
+ # 5 xxxxx
+ # 7 xxxxxxx
+ # 9 xxxxxxxxx
+ # 1 x
+ # 4 xxxx
+ # 7 xxxxxxx
+ # 10 xxxxxxxxxx
+
+ def step(n=1)
+ if n == 1 then
+ each { |o| yield(o) }
+ else
+ counter = 0
+ each do |o|
+ yield(o) if counter % n == 0
+ counter += 1
+ end
+ end
+ end
+
+ ##
+ # call-seq:
+ # rng.to_s => string
+ #
+ # Convert this range object to a printable form.
+
+ def to_s
+ joiner = @exclude_end ? "..." : ".."
+ return "#{@first}#{joiner}#{@last}"
+ end
+end
+
View
0 kernel/comparable.rb → kernel/core/03comparable.rb
File renamed without changes.
View
0 kernel/numeric.rb → kernel/core/04numeric.rb
File renamed without changes.
View
0 kernel/__loader.rb → kernel/core/__loader.rb
File renamed without changes.
View
65 kernel/core/array.rb
@@ -499,7 +499,7 @@ def index(obj)
i += 1
end
nil
- end
+ end
# TODO fill out pack.
def pack(schema)
@@ -527,4 +527,67 @@ def pack(schema)
return ret
end
+
+ def reverse
+ ary = []
+ i = @total - 1
+ while i >= 0
+ ary << self[i]
+ i -= 1
+ end
+ return ary
+ end
+
+ def uniq
+ seen = {}
+ ary = []
+ i = 0
+ while i < @total
+ e = @tuple.at(i)
+ ary << e unless seen[e]
+ seen[e] = true
+ i += 1
+ end
+ ary
+ end
+
+ def uniq!
+ ary = self.uniq
+ ary.size == self.size ? nil : replace(ary)
+ end
+
+ def -(other)
+ out = []
+ each { |e|
+ unless other.include?(e)
+ out << e
+ end
+ }
+ return out
+ end
+
+ def &(other)
+ out=[]
+ self.uniq!
+ each { |e|
+ if other.include?(e)
+ out << e
+ end
+ }
+ return out
+ end
+
+ # TODO: test val for negative values and floats
+ def *(val)
+ if val.class == String
+ return self.join(val)
+ else
+ out=[]
+ val.times do
+ out.push *self
+ end
+ return out
+ end
+ end
+
end
View
0 kernel/compression.rb → kernel/core/compression.rb
File renamed without changes.
View
0 kernel/continuation.rb → kernel/core/continuation.rb
File renamed without changes.
View
65 kernel/core/object.rb
@@ -0,0 +1,65 @@
+class Object
+ # call-seq:
+ # obj.instance_exec(arg...) {|var...| block } => obj
+ #
+ # Executes the given block within the context of the receiver
+ # (_obj_). In order to set the context, the variable +self+ is set
+ # to _obj_ while the code is executing, giving the code access to
+ # _obj_'s instance variables. Arguments are passed as block parameters.
+ #
+ # class Klass
+ # def initialize
+ # @secret = 99
+ # end
+ # end
+ # k = Klass.new
+ # k.instance_exec(5) {|x| @secret+x } #=> 104
+ def instance_exec(*args, &prc)
+ raise ArgumentError, "Missing block" unless block_given?
+ env = prc.block.dup
+ env.put(1, env.home.dup) # home: MethodContext
+ env.home.put(9, self) # receiver: Object
+ proc = Proc.from_environment(env)
+ proc.call(*args)
+ end
+
+ # call-seq:
+ # obj.instance_eval(string [, filename [, lineno]] ) => obj
+ # obj.instance_eval {| | block } => obj
+ #
+ # Evaluates a string containing Ruby source code, or the given block,
+ # within the context of the receiver (_obj_). In order to set the
+ # context, the variable +self+ is set to _obj_ while
+ # the code is executing, giving the code access to _obj_'s
+ # instance variables. In the version of <code>instance_eval</code>
+ # that takes a +String+, the optional second and third
+ # parameters supply a filename and starting line number that are used
+ # when reporting compilation errors.
+ #
+ # class Klass
+ # def initialize
+ # @secret = 99
+ # end
+ # end
+ # k = Klass.new
+ # k.instance_eval { @secret } #=> 99
+ def instance_eval(string = nil, filename = "(eval)", line = 1, &prc)
+ if block_given?
+ instance_exec(&prc)
+ else
+ cm = string.compile_as_method
+ cm.activate(self, [])
+ end
+ end
+
+ def instance_variables
+ if !@__ivars__ or @__ivars__.size == 0
+ return []
+ end
+ res = []
+ @__ivars__.each do |k,v|
+ res << k.to_s
+ end
+ return res
+ end
+end
View
17 kernel/core/process.rb
@@ -0,0 +1,17 @@
+class Process
+ def self.exit(code)
+ Ruby.primitive :process_exit
+ end
+
+ def self.micro_sleep(ms)
+ Ruby.primitive :micro_sleep
+ end
+
+ def self.sleep(sec)
+ micro_sleep(sec * 1_000_000)
+ end
+
+ def self.usleep(sec)
+ micro_sleep(sec * 1_000)
+ end
+end
View
0 kernel/readline.rb → kernel/core/readline.rb
File renamed without changes.
View
156 kernel/core/string.rb
@@ -0,0 +1,156 @@
+class String
+ def to_sexp_full(name, line, newlines)
+ Ruby.primitive :string_to_sexp
+ end
+
+ def to_sexp(name="(eval)",line=1,newlines=true)
+ out = to_sexp_full(name, line, newlines)
+ if out.kind_of? Tuple
+ exc = SyntaxError.new out.at(0)
+ exc.import_position out.at(1), out.at(2)
+ raise exc
+ end
+ return out
+ end
+
+ def *(num)
+ str = []
+ num.times { str << self }
+ return str.join("")
+ end
+
+ def reverse
+ str = ""
+ i = @bytes - 1
+ while i >= 0
+ str << self[i,1]
+ i -= 1
+ end
+ return str
+ end
+
+ def reverse!
+ sd = self.reverse
+ @data = sd.data
+ @bytes = sd.size
+ return self
+ end
+
+ def strip
+ r = /\s*([^\s](.*[^\s])?)\s*/m
+ m = r.match(self)
+ return '' unless m
+ return m.captures[0]
+ end
+
+ def strip!
+ sd = self.strip
+ @data = sd.data
+ @bytes = sd.size
+ return self
+ end
+
+ def =~(pattern)
+ m = pattern.match(self)
+ m ? m.full.at(0) : nil
+ end
+
+ def include?(arg)
+ if arg.is_a? Fixnum
+ @data.each { |b| return true if b == arg }
+ return false
+ elsif arg.is_a? String
+ return (self.index(arg) != nil)
+ else
+ raise ArgumentError.new("String#include? cannot accept #{arg.class} objects")
+ end
+ end
+
+ def index(arg, offset = nil )
+ if arg.is_a? Fixnum
+ i = 0
+ @data.each { |b| return i if b == arg; i += 1 }
+ elsif arg.is_a? String
+ idx = 0
+ if offset
+ if offset >= 0
+ return nil if offset >= self.size
+ idx = offset
+ else
+ return nil if (1-offset) >= self.size
+ idx = self.size + offset
+ end
+ end
+ argsize = arg.size
+ max = self.size - argsize
+ if max >= 0 and argsize > 0
+ idx.upto(max) do |i|
+ if @data.get_byte(i) == arg.data.get_byte(0)
+ return i if substring(i,argsize) == arg
+ end
+ end
+ end
+ elsif arg.is_a? Regexp
+ idx = offset ? offset : 0
+ mstr = self[idx..-1]
+ offset = self.size - mstr.size
+ m = arg.match(mstr)
+ if m
+ return offset + m.begin(0)
+ end
+ return nil
+ else
+ raise ArgumentError.new("String#index cannot accept #{arg.class} objects")
+ end
+ return nil
+ end
+
+ def [](arg, len = nil)
+ if len
+ len = len.to_i
+ return nil if len < 0
+ end
+
+ if arg.is_a? String
+ unless len.nil?
+ raise ArgumentError.new("String#[] got incorrect arguments.") # TODO: Make this helpful.
+ end
+ return (self.include?(arg) ? arg.dup : nil)
+ elsif arg.respond_to? :match
+ m = arg.match(self)
+ return m[len.to_i] if m && len
+ return m[0] if m
+ return nil
+ elsif arg.respond_to?(:first) and arg.respond_to?(:last)
+ from = arg.first
+ to = arg.last
+ to = to - 1 if arg.respond_to?(:exclude_end?) && arg.exclude_end?
+ size = self.size
+ from = from + size if from < 0
+ to = to + size if to < 0
+ len = to - from + 1
+ self[from, len]
+
+ elsif arg and arg.respond_to?(:to_i)
+ arg = arg.to_i
+ size = self.size
+ arg = arg + size if arg < 0
+ if 0 <= arg && arg < size
+ if len
+ len = size - arg if arg + len >= size
+ substring(arg, len)
+ else
+ @data.get_byte(arg)
+ end
+ else # invalid start index
+ len ? "" : nil
+ end
+ else
+ raise ArgumentError.new("String#[] cannot accept #{arg.class} objects")
+ end
+ end
+
+ alias_method :slice, :[]
+
+
+end
View
0 kernel/throw_catch.rb → kernel/core/throw_catch.rb
File renamed without changes.
View
BIN runtime/bootstrap.rba
Binary file not shown.
View
BIN runtime/core.rba
Binary file not shown.
View
BIN runtime/kernel.rba
Binary file not shown.
View
2 shotgun/lib/cpu_instructions.c
@@ -388,7 +388,7 @@ void cpu_run(STATE, cpu c) {
// #define stack_push(obj) SET_FIELD(c->stack, ++(c->sp), obj)
#define stack_push(obj) if(!cpu_stack_push(state, c, obj, TRUE)) { goto stack_error; }
- #if EXCESSIVE_TRACING
+ #if 0
printf("%-15s: OP: %s (%d/%d)\n",
rbs_symbol_to_cstring(state, cmethod_get_name(c->method)),
cpu_op_to_name(state, op), op, c->ip);
View
2 shotgun/lib/cpu_marshal.c
@@ -371,7 +371,7 @@ static void marshal(STATE, OBJECT obj, GString *buf, struct marshal_state *ms) {
} else if(kls == BASIC_CLASS(floatpoint)) {
marshal_floatpoint(state, obj, buf);
} else {
- printf("Unable to marshal class %p = %s!\n", (void *)kls, rbs_inspect(state, kls));
+ printf("Unable to marshal class %p = %s!\n", (void *)kls, rbs_inspect(state, kls));
}
}
}
View
7 shotgun/lib/grammer_runtime.c
@@ -164,6 +164,10 @@ static OBJECT cstring_to_symbol(STATE, char *str) {
char *op_to_name(ID id);
+static char* print_quark(GQuark quark) {
+ return (char*)g_quark_to_string(id_to_quark(quark));
+}
+
static OBJECT quark_to_symbol(STATE, GQuark quark) {
char *op;
op = op_to_name(quark);
@@ -173,9 +177,6 @@ static OBJECT quark_to_symbol(STATE, GQuark quark) {
return cstring_to_symbol(state, (char*)g_quark_to_string(id_to_quark(quark)));
}
-static char* print_quark(GQuark quark) {
- return (char*)g_quark_to_string(id_to_quark(quark));
-}
static OBJECT gstring2rubinius(STATE, GString *str) {
return string_new2(state, str->str, str->len);
View
6 shotgun/lib/machine.c
@@ -390,7 +390,7 @@ int machine_run(machine m) {
cpu_run(m->s, m->c);
if(RTEST(m->c->exception)) {
machine_show_exception(m, m->c->exception);
- return TRUE;
+ return FALSE;
}
return TRUE;
}
@@ -516,7 +516,9 @@ OBJECT machine_load_archive(machine m, char *path) {
cm = archive_get_object(m->s, path, files);
if(!RTEST(cm)) return Qfalse;
cpu_run_script(m->s, m->c, cm);
- machine_run(m);
+ if(!machine_run(m)) {
+ return Qfalse;
+ }
files = nxt;
nxt = strchr(nxt, '\n');
}
View
2 shotgun/lib/symbol.c
@@ -33,7 +33,7 @@ OBJECT symtbl_new(STATE) {
OBJECT symtbl_lookup_cstr(STATE, OBJECT self, char *str) {
unsigned int hash;
OBJECT strs, idx, syms;
-
+
hash = string_hash_cstr(state, str);
strs = symtbl_get_strings(self);
syms = symtbl_get_symbols(self);
View
105 shotgun/main.c
@@ -3,79 +3,49 @@
#include "shotgun.h"
#include "machine.h"
#include <sys/stat.h>
-#include <libgen.h>
#include <string.h>
+#include <setjmp.h>
void *__main_address;
-/* WATCH OUT: pointer returned by find_kernel should be free'd by called */
+/* TODO incorporate system paths calculated at compile time. */
+char *search_path[] = {"runtime", NULL};
-static char *find_kernel(char *rubinius_path) {
+static char *search_for(char *evs, char *file) {
char *env;
- char *dir;
- char *rb_path = NULL;
- char kernel_path[PATH_MAX+1];
- struct stat st = {0,};
-
- env = getenv("KERNEL");
-
- if(env) {
- strncpy (&kernel_path[0], env, PATH_MAX );
- }
- else
- {
- /* We need to get the dir part of the rubinius path */
- /* as dirname can modify its parameter (at least if we keep POSIX */
- /* compliance), we need to dup it first (at think about releasing */
- rb_path = strdup ( rubinius_path );
- dir = dirname ( rb_path );
+ char path[PATH_MAX];
+ struct stat _st;
+ int i;
- snprintf (&kernel_path[0], PATH_MAX, "%s/../runtime/kernel.rba", dir);
-
- /* Is kernel.rba available ? */
- if (stat( kernel_path, &st) != 0)
- {
- /* No ? so let's build a potential path to kernel.rbc */
- snprintf (&kernel_path[0], PATH_MAX, "%s/../runtime/kernel.rbc", dir);
- }
- }
-
- if ( rb_path != NULL )
- {
- free (rb_path);
- rb_path = NULL;
+ #define file_exists_p(file) stat(file, &_st) == 0
+
+ env = getenv(evs);
+ if(env) {
+ if(file_exists_p(env)) return strdup(env);
+ return NULL;
}
- /* Let's dup kernel_path (called needs to think about freeing it) */
- rb_path = strdup ( &kernel_path[0]);
+ for(i = 0; search_path[i]; i++) {
+ snprintf(path, PATH_MAX, "%s/%s", search_path[i], file);
+ if(file_exists_p(path)) {
+ return strdup(path);
+ }
+ }
- return rb_path;
+ return NULL;
}
int main(int argc, char **argv) {
- char *kernel;
+ char *archive;
machine m;
- struct stat st;
int offset = 0;
int flag;
-
+
/* Setup the global that contains the address of the
frame pointer for main. This is so the missing
backtrace knows where to stop looking for return address. */
__main_address = __builtin_frame_address(0);
- kernel = find_kernel( argv[0] );
- if(!kernel) {
- printf("Unable to find a kernel to load!\n");
- return 1;
- }
-
- if(stat(kernel, &st) < 0) {
- printf("Kernel '%s' not found.\n", kernel);
- free (kernel);
- return 1;
- }
-
m = machine_new();
machine_save_args(m, argc, argv);
machine_setup_standard_io(m);
@@ -86,22 +56,39 @@ int main(int argc, char **argv) {
machine_setup_argv(m, argc-offset, argv+offset);
machine_setup_env(m);
- if(strstr(kernel, ".rba")) {
- flag = machine_load_archive(m, kernel);
- } else {
- flag = machine_run_file(m, kernel);
+ /* Load the bootstrap. */
+
+ archive = search_for("BOOTSTRAP", "bootstrap.rba");
+ if(!archive) {
+ printf("Unable to find a bootstrap (bootstrap.rba) to load!\n");
+ return 1;
}
+
+ flag = machine_load_archive(m, archive);
+
+ if(!flag) {
+ printf("Unable to run %s\n", archive);
+ return 1;
+ }
+
+ /* Load the core. */
+
+ archive = search_for("CORE", "core.rba");
+ if(!archive) {
+ printf("Unable to find a core (core.rba) to load!\n");
+ return 1;
+ }
+
+ flag = machine_load_archive(m, archive);
if(!flag) {
- printf("Unable to run %s\n", kernel);
- free (kernel);
+ printf("Unable to run %s\n", archive);
return 1;
}
// machine_emit_memory(m);
// object_memory_print_stats(m->s->om);
- free (kernel);
return 0;
}

0 comments on commit 5468980

Please sign in to comment.
Something went wrong with that request. Please try again.