Permalink
Browse files

Spawn primitive kind of works

  • Loading branch information...
1 parent 5ebb171 commit 821983d04cede1dfc135a6ab150eae584a860b56 @txus committed Feb 12, 2014
File renamed without changes.
File renamed without changes.
View
@@ -4,4 +4,5 @@
require 'lambra/syntax'
require 'lambra/parser'
require 'lambra/bytecode_compiler'
+require 'lambra/process'
require 'lambra/library'
View
@@ -1,4 +1,5 @@
require 'set'
+require 'thread'
class PrimitiveFunction
def initialize(&block)
@@ -15,11 +16,11 @@ def call(*args)
# @block_environment = blk_env
# @executable = blk_env.compiled_code
# end
-#
+#
# def call(*args)
# @executable.invoke(:anonymous, @executable.scope.module, Object.new, args, nil)
# end
-#
+#
# def to_proc
# Proc.__from_block__(@block_environment)
# end
@@ -56,6 +57,7 @@ module GlobalScope
:- => PrimitiveFunction.new { |*args| args.inject(:-) },
:/ => PrimitiveFunction.new { |a, b| a / b },
:* => PrimitiveFunction.new { |a, b| a * b },
+ :send => PrimitiveFunction.new { |pid, *args| Process[pid].push(*args) }
})
class Keyword
@@ -3,7 +3,7 @@ class BytecodeCompiler
attr_reader :generator
alias g generator
- SPECIAL_FORMS = %w(def fn let)
+ SPECIAL_FORMS = %w(def fn let spawn)
PRIMITIVE_FORMS = %w(println + - / *)
def initialize(generator=nil)
@@ -82,6 +82,15 @@ def visit_SpecialForm(car, cdr)
end
g.send :call, arguments.count
+ when 'spawn'
+ g.push_cpath_top
+ g.find_const :Lambra
+ g.find_const :Process
+
+ fn = cdr.shift
+ fn.accept(self)
+
+ g.send_with_block :spawn, 0
end
end
@@ -1,3 +1,5 @@
+require_relative '../bootstrap'
+
module Lambra
class CodeLoader
def self.evaluate(string)
@@ -11,8 +13,6 @@ def self.execute(ast)
gen.encode
cm = gen.package Rubinius::CompiledCode
- require_relative '../bootstrap'
-
env = GlobalScope
file = if ast.respond_to?(:filename) && ast.filename
View
@@ -0,0 +1,47 @@
+require 'thread'
+
+module Lambra
+ class Message
+ def initialize(*args)
+ @contents = args
+ end
+ end
+
+ class Process
+ @processes = {}
+
+ def self.[](pid)
+ @processes[pid]
+ end
+
+ def self.[]=(pid, process)
+ @processes[pid] = process
+ end
+
+ def self.spawn(&fn)
+ Thread.new do
+ new(&fn).tap { |process|
+ self[Thread.current.object_id] = process
+ Thread.current[:process] = process
+ }.call
+ end
+ end
+
+ def initialize(&fn)
+ @mailbox = Queue.new
+ @fn = fn
+ end
+
+ def call
+ @fn.call
+ end
+
+ def push(*args)
+ @mailbox.push(Message.new(*args))
+ end
+
+ def pop
+ @mailbox.pop
+ end
+ end
+end

0 comments on commit 821983d

Please sign in to comment.