module Take class Unit class Compiler include PredictMatch attr_reader :parent def initialize(file, tokens) @file = file @tokens = tokens @enum = tokens.each @parent = nil end def compile @parent ||= begin @parent = AST::Parent.new(name: File.basename(@file). gsub(/\..*\z/, "")) while peek do part = predict(:group => :group, :prefix => :prefix) @parent.children << part if part end add_parent_prefix @parent.source = sourcify([0, 0]) @parent end end def compile_group group = match(:group) node = AST::Group.new(name: group[1], source: sourcify(group)) until peek == :group_end part = compile_part node.children << part if part end match(:group_end) node end def compile_part predict :group => :group, :test => :test, :before => :before, :after => :after, :macro => :macro end def compile_test test = match(:test) body = match(:block) AST::Test.new(name: test[1], children: [AST::Block.new({ body: body[1], source: sourcify(body) })], source: sourcify(test)) end def compile_before before = match(:before) body = match(:block) AST::Before.new(name: before[1], children: [AST::Block.new({ body: body[1], source: sourcify(body) })], source: sourcify(before)) end def compile_after after = match(:after) body = match(:block) AST::After.new(name: after[1], children: [AST::Block.new({ body: body[1], source: sourcify(body) })], source: sourcify(after)) end def compile_prefix prefix = match(:prefix) body = match(:block) @parent.children << AST::Prefix.new( name: prefix[1], children: [AST::Block.new({ body: body[1], source: sourcify(body) })], source: sourcify(prefix)) nil end def compile_macro end private def input @enum end def sourcify(token) hash = Hash[[:line, :column].zip(token[-2..-1])] hash.merge(file: @file) end def add_parent_prefix prefix = AST::Prefix.new(name: "_generated_prefix") prefix.children << AST::Block.new(body: <<-DOC) #define __FILE \"#{@file}\" #include \"utest.h\" static size_t tests = 0; static size_t failed = 0; DOC @parent.children << prefix end end end end