Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Compile numbers and empty lists

  • Loading branch information...
commit 64bceb1e7299ba4afa6051691d85fcc0bd85a6a5 1 parent 7aff167
@txus authored
View
1  lib/lambra.rb
@@ -1,4 +1,5 @@
require 'lambra/version'
require 'lambra/syntax'
require 'lambra/parser'
+require 'lambra/bytecode_compiler'
require 'lambra/library'
View
68 lib/lambra/bytecode_compiler.rb
@@ -0,0 +1,68 @@
+module Lambra
+ class BytecodeCompiler
+ attr_reader :generator
+ alias g generator
+
+ def initialize
+ @generator = Rubinius::Generator.new
+ end
+
+ def compile(ast, debugging=false)
+ if debugging
+ require 'pp'
+ pp ast.to_sexp
+ end
+
+ # if ast.respond_to?(:filename) && ast.filename
+ # g.file = ast.filename
+ # else
+ # g.file = :"(lambra)"
+ # end
+
+ g.set_line ast.line || 1
+
+ ast.accept(self)
+
+ debug if debugging
+ g.ret
+
+ finalize
+ end
+
+ def visit_List(o)
+ return g.push_nil if o.elements.count.zero?
+ end
+
+ def visit_Number(o)
+ g.push_literal o.value
+ end
+
+ def visit_Sequence(o)
+ o.elements.compact.each do |element|
+ element.accept(self)
+ end
+ end
+
+ def finalize
+ # g.local_names = s.variables
+ # g.local_count = s.variables.size
+ g.close
+ g
+ end
+
+ def set_line(o)
+ g.set_line o.line if o.line
+ end
+
+ def debug(gen = self.g)
+ p '*****'
+ ip = 0
+ while instruction = gen.stream[ip]
+ instruct = Rubinius::InstructionSet[instruction]
+ ip += instruct.size
+ puts instruct.name
+ end
+ p '**end**'
+ end
+ end
+end
View
7 lib/lambra/library/code_loader.rb
@@ -1,12 +1,13 @@
module Lambra
class CodeLoader
def self.evaluate(string)
- # We're just parsing for now
- Lambra::Parser.parse_to_sexp string
+ ast = Lambra::Parser.parse string
+ visitor = BytecodeCompiler.new
+ cm = visitor.compile(ast)
end
def self.execute_file(name)
- value = Lambra::Parser.parse_to_sexp IO.read(name)
+ value = Lambra::Parser.parse IO.read(name)
p value
end
end
View
9 lib/lambra/parser.rb
@@ -9,4 +9,13 @@ def self.parse_to_sexp(string)
parser.result.to_sexp
end
+
+ def self.parse(string)
+ parser = new string
+ unless parser.parse
+ parser.raise_error
+ end
+
+ parser.result
+ end
end
View
10 lib/lambra/syntax/ast.rb
@@ -1,6 +1,16 @@
module Lambra
module AST
+
+ module Visitable
+ def accept(visitor)
+ name = self.class.name.split("::").last
+ visitor.send "visit_#{name}", self
+ end
+ end
+
class Node
+ include Visitable
+
attr_reader :line, :column
def sexp_name
View
1  spec/custom.rb
@@ -1,4 +1,5 @@
require 'custom/runner/relates'
require 'custom/matchers/parse_as'
+require 'custom/matchers/compile_as'
require 'custom/utils/options'
require 'custom/utils/script'
View
26 spec/custom/matchers/compile_as.rb
@@ -0,0 +1,26 @@
+class CompileAsMatcher
+ def initialize(expected)
+ @expected = expected
+ end
+
+ def matches?(actual)
+ ast = Lambra::Parser.parse actual
+ visitor = Lambra::BytecodeCompiler.new
+ visitor.compile(ast)
+
+
+ @actual = visitor.generator
+ @expected.stream == @actual.stream
+ end
+
+ def failure_message
+ ["Expected:\n#{@actual.stream.inspect}\n",
+ "to equal:\n#{@expected.stream.inspect}"]
+ end
+end
+
+class Object
+ def compile_as(generator, *plugins)
+ CompileAsMatcher.new generator
+ end
+end
View
2  spec/custom/runner/relates.rb
@@ -73,7 +73,7 @@ def compile(*plugins, &block)
ruby = @ruby
it "is compiled from #{format ruby}" do
- generator = Rubinius::TestGenerator.new
+ generator = Rubinius::Generator.new
generator.instance_eval(&block)
ruby.should compile_as(generator, *plugins)
View
20 spec/syntax/ast_spec.rb
@@ -3,6 +3,11 @@
describe "The Comment node" do
relates ";hello\n()" do
parse { [:sequence] }
+
+ compile do |g|
+ g.push_nil
+ g.ret
+ end
end
end
@@ -21,14 +26,29 @@
describe "The Number node" do
relates "42" do
parse { [:number, 42] }
+
+ compile do |g|
+ g.push_literal 42
+ g.ret
+ end
end
relates "1.23" do
parse { [:number, 1.23] }
+
+ compile do |g|
+ g.push_literal 1.23
+ g.ret
+ end
end
relates "0x2a" do
parse { [:number, 42] }
+
+ compile do |g|
+ g.push_literal 42
+ g.ret
+ end
end
end
Please sign in to comment.
Something went wrong with that request. Please try again.