$ rake
$ ruby -I. test.rb
- 
Need to add support for regexps. 
- 
The current implementation translates the AST directly to ragel, should we generate a GTG first so the table is more compact? 
| *.c | |
| *.rl | 
$ rake
$ ruby -I. test.rb
Need to add support for regexps.
The current implementation translates the AST directly to ragel, should we generate a GTG first so the table is more compact?
| require 'mkmf' | |
| # :stopdoc: | |
| create_makefile 'router' | |
| # :startdoc: | |
| task :clean do | |
| rm_f 'router.c' | |
| rm_f 'router.rl' | |
| rm_f 'router.o' | |
| rm_f 'Makefile' | |
| rm_f 'router.bundle' | |
| rm_f 'router.so' | |
| end | |
| task :default do | |
| ruby 'route_compiler.rb > router.rl' | |
| sh 'ragel router.rl' | |
| ruby 'extconf.rb' | |
| sh 'make' | |
| end | 
| require 'journey' | |
| def asts paths | |
| parser = Journey::Parser.new | |
| Journey::Nodes::Or.new paths.map { |x| parser.parse x } | |
| end | |
| class Ragel < Journey::Visitors::Visitor | |
| def terminal(n) | |
| n.left.inspect | |
| end | |
| def visit_OR(n) | |
| "(#{n.children.map { |x| visit x }.join ' | '})" | |
| end | |
| def visit_GROUP(n) | |
| "(#{visit n})" | |
| end | |
| def visit_CAT(n) | |
| "#{visit n.left} . #{visit n.right}" | |
| end | |
| end | |
| ## These come from your routes.rb | |
| ast = asts %w{ | |
| /articles | |
| /articles/new | |
| } | |
| ragel = Ragel.new.accept ast | |
| data = <<-eoc | |
| #include <ruby.h> | |
| %%{ | |
| machine router; | |
| action match { ret = Qtrue; } | |
| main := #{ragel} %match; | |
| }%% | |
| %% write data; | |
| static VALUE match(VALUE self, VALUE string) | |
| { | |
| int cs = 0; | |
| char *p = RSTRING_PTR(string); | |
| char *pe = p + RSTRING_LEN(string); | |
| char *eof = pe; | |
| VALUE ret = Qfalse; | |
| %% write init; | |
| %% write exec; | |
| return ret; | |
| } | |
| void Init_router() | |
| { | |
| VALUE mRouter = rb_define_class("Router", rb_cObject); | |
| rb_define_method(mRouter, "match", match, 1); | |
| } | |
| eoc | |
| puts data | 
| # ruby -I. test.rb | |
| require 'router' | |
| require 'minitest/autorun' | |
| class RouterTest < MiniTest::Unit::TestCase | |
| def setup | |
| @router = Router.new | |
| end | |
| def test_omg | |
| assert @router.match '/articles/new' | |
| refute @router.match '/articles/nw' | |
| assert @router.match '/articles' | |
| end | |
| end |