Skip to content

Commit

Permalink
recursively evaluate sequence nodes
Browse files Browse the repository at this point in the history
this allows #language -injected grammars to return sequences that
further declare macros, etc.

otherwise it ends up being under one big sequence, which is compiled all
at once.
  • Loading branch information
vito committed Jun 13, 2015
1 parent 9c856c5 commit c4bb8ec
Show file tree
Hide file tree
Showing 5 changed files with 51 additions and 5 deletions.
3 changes: 2 additions & 1 deletion grammar.kpeg
Expand Up @@ -61,7 +61,8 @@
end

def set_lang(n)
@_grammar_lang = require("#{n}/language/parser")::Parser.new(nil)
require "atomy/codeloader"
@_grammar_lang = Atomy::CodeLoader.require("#{n}/language/parser")::Parser.new(nil)
end
}

Expand Down
19 changes: 15 additions & 4 deletions lib/atomy/codeloader.rb
Expand Up @@ -145,14 +145,25 @@ def run_script(path)

node = Atomy::Parser.parse_file(file)

res = nil
node.nodes.each do |n|
res = mod.evaluate(n, mod.compile_context)
end
res = evaluate_sequences(node, mod)

[res, mod]
end

def evaluate_sequences(n, mod)
if n.is_a?(Atomy::Grammar::AST::Sequence)
res = nil

n.nodes.each do |sub|
res = evaluate_sequences(sub, mod)
end

res
else
mod.evaluate(n, mod.compile_context)
end
end

def find_source(path, search_in = $LOAD_PATH)
if qualified?(path)
expanded = File.expand_path(path)
Expand Down
13 changes: 13 additions & 0 deletions spec/atomy/codeloader_spec.rb
Expand Up @@ -119,6 +119,19 @@

expect(res).to eq(mod)
end

it "recursively evaluates sequences" do
$LOAD_PATH.unshift File.expand_path(fixture("."))

begin
res, _ = Atomy::CodeLoader.run_script(
fixture("codeloader/run_script/language-using.ay"))

expect(res).to eq("forty-two")
ensure
$LOAD_PATH.shift
end
end
end

describe ".require" do
Expand Down
20 changes: 20 additions & 0 deletions spec/fixtures/codeloader/language/parser.ay
@@ -0,0 +1,20 @@
require("atomy/bootstrap")
require("atomy/grammar")

eval("
class Parser
def initialize(str)
@str = str
end

def external_invoke(other, rule, *args)
other.result = Atomy::Grammar::AST::Sequence.new([
Atomy::Bootstrap.macro_definer(
Atomy::Grammar::AST::Quote.new(Atomy::Grammar::AST::Number.new(42)),
Atomy::Grammar::AST::Quote.new(Atomy::Grammar::AST::StringLiteral.new(\"forty-two\")),
),
Atomy::Grammar::AST::Number.new(42),
])
end
end
")
1 change: 1 addition & 0 deletions spec/fixtures/codeloader/run_script/language-using.ay
@@ -0,0 +1 @@
#language codeloader

0 comments on commit c4bb8ec

Please sign in to comment.