Skip to content

Commit

Permalink
Update README.md
Browse files Browse the repository at this point in the history
Adding CodeClimate badge

Updating Docs

Adding .gitignore

Update README.md

Adding YARD Docs badge

Adding SC::Spec

Adding SC::Spec::Parser

Adding SC::Spec::Parser tests

Adding Rake

Adding Travis Config

Create LICENSE

Updating gemspec

adding minitest as dep

Adding CC coverage report

Adding SC::Database tests

Mocking sample class for SC::Database tests

Improving SC::Databasetest coverage

SC tests
  • Loading branch information
robertodecurnex committed Mar 4, 2015
1 parent 7bc5020 commit fdbae53
Show file tree
Hide file tree
Showing 24 changed files with 451 additions and 85 deletions.
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
Gemfile.lock
coverage/*
sample/Gemfile.lock
.yardoc
7 changes: 7 additions & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
language: ruby
rvm:
- ruby-head
- 2.2.1
addons:
code_climate:
repo_token: 41068f41a81afe631660b946d25f757ac81d7d65b6e9fd5bd196db1aaf7bd619
3 changes: 3 additions & 0 deletions Gemfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
source 'https://rubygems.org'

gemspec
21 changes: 21 additions & 0 deletions LICENSE
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
The MIT License (MIT)

Copyright (c) 2015 Roberto Decurnex

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
6 changes: 6 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,12 @@

Specs driven social meta-programming

[![Build Status](https://api.travis-ci.org/robertodecurnex/sc.png)](https://travis-ci.org/robertodecurnex/sc)
[![Code Climate](https://codeclimate.com/github/robertodecurnex/sc/badges/gpa.svg)](https://codeclimate.com/github/robertodecurnex/sc)
[![Coverage Status](https://coveralls.io/repos/robertodecurnex/sc/badge.svg?branch=master)](https://coveralls.io/r/robertodecurnex/sc?branch=master)
[![Test Coverage](https://codeclimate.com/github/robertodecurnex/sc/badges/coverage.svg)](https://codeclimate.com/github/robertodecurnex/sc)
[![YARD Docs](https://img.shields.io/badge/YARD-Docs-blue.svg)](http://www.rubydoc.info/github/robertodecurnex/sc/master)

## Prototype

```ruby
Expand Down
68 changes: 2 additions & 66 deletions lib/sc.rb
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
require 'yaml'

require_relative 'sc/database.rb'
require_relative 'sc/spec.rb'

# Specs driven social meta-programming
module SC
Expand All @@ -14,8 +15,7 @@ module ClassMethods

# Register the given method name supporting the given parameters.
#
# @param [Symbol|String] name the method name to register
# @param [<Symbol|String>] params that the method supports
# @param [{String, Symbol=><String, Symbol>}] interfaces hash of method names and required param names that the method supports
def implements interfaces
interfaces.each do |method_name, required_params|
λ = SC::Database.fetch(self, method_name, *required_params)
Expand All @@ -27,67 +27,3 @@ def implements interfaces

end

__END__
content, meta = File.read('sample.rb').split("__END__\n")
place_holders = content.scan /#sc \w+(?:\(\w+(?:, \w+)*\))?/
rules = meta.scan /sc \w+(?: \w+(?:, \w+)*)?: \w+\n(?: {2,4}[^\n]+(?:, [^\n]+)* -> [^\n]+\n)+/

protos = {}
facts = {}

rules.each do |rule|
split = rule.split("\n")
definition = split.shift.split(/(?::|,)? /)
protos[definition[1]] = definition[2..-1].map {|e| puts e; eval(e)}
facts[definition[1]] = split.inject([]) do |memo, fact|
memo << fact.strip.split(/(?:, )|(?: -> )/).map {|e| eval(e)}
memo
end
end

kb = {
[String, String] => [
%q{lambda {|string| string + 'lalala' }},
%q{lambda {|string| "Say Hello to #{string}" }}
],
[String, String, String] => [
%q{lambda {|s1, s2| "Nada q ver" }},
%q{lambda {|s1, s2| "#{s1} plus #{s1} == #{s2}" }},
%q{lambda {|s1, s2| "God help us" }}
]
}

resp = {}

protos.each do |name, signature|
throw "No tengo esa signature sorete!" if kb[signature].nil?
resp[name] = kb[signature].detect do |code|
facts[name].all? do |fact|
eval(code).call(*fact[0..-2]) == fact[-1]
end
end
end

puts resp.inspect

sc_class = "\nclass SC\n"

place_holders.each do |ph|
puts ph
a, proto_name, *var_names = ph.split(/[ (),]/)
var_names = var_names.reject {|v| v.empty?}
puts var_names.inspect
content.gsub!(ph, "#{ph}\nSC.#{ph.sub('#sc ','')}")
protos[proto_name]
sc_class << <<TAIL
def SC.#{proto_name}(#{var_names.join(', ')})
#{resp[proto_name]}.call(#{var_names.join(', ')})
end
TAIL
end

sc_class << "end\n"

content = sc_class + content

File.write('sample_out.rb', content)
11 changes: 7 additions & 4 deletions lib/sc/database.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,13 @@ module SC
# to fetch specific elements by different criterias.
class Database

attr_accessor :index
attr_accessor :cache, :index, :sc_path

def initialize
self.index = YAML.load_file('./.sc/index.yml')
def initialize sc_path='./.sc'
@@instance = self
self.cache = {}
self.sc_path = sc_path
self.index = YAML.load_file("#{self.sc_path}/index.yml")
end

# Instance delegator of SC::Database#fetch
Expand Down Expand Up @@ -37,7 +40,7 @@ def self.instance
# @return [Proc] the labda that would be implemented
def fetch klass, method_name, *required_params
λ_id = self.index["#{klass}"]["#{method_name}:#{required_params.count}"]
eval(File.read("./.sc/cache/#{λ_id}.rb"))
return self.cache[λ_id] ||= eval(File.read("#{self.sc_path}/cache/#{λ_id}.rb"))
end

end
Expand Down
20 changes: 20 additions & 0 deletions lib/sc/spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
require_relative 'spec/parser.rb'
require_relative 'spec/rule.rb'
require_relative 'spec/signature.rb'

module SC

class Spec

attr_accessor :rules, :signature

# @param [SC::Spec::Signature] signature spec signature
# @param [<SC::Spec::Rule>] rules collection of spec rules
def initialize signature, rules
self.rules = rules
self.signature = signature
end

end

end
72 changes: 72 additions & 0 deletions lib/sc/spec/parser.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
module SC

class Spec

# Parser to get SC::Spec instances from the metadata on the program's files
class Parser

attr_accessor :file_path

# @param [String] file_path the path of the file to parse
def initialize file_path
self.file_path = file_path
end

# Look for specs on the given file and parse them as SC::Specs
#
# @return [<SC::Spec>] collection of specs found in the given file
def parse
/.*^__END__$(?<raw_specs>.*)\Z/m =~ File.read(self.file_path)
return raw_specs.split('spec_for')[1..-1].map do |raw_spec|
self.parse_spec raw_spec
end
end

# Parses a raw spec and returns an SC::Spec instance
#
# @param [String] raw_spec raw spec
# @return [SC::Spec] the SC::Spec instance
def parse_spec raw_spec
spec_raw_signature, *spec_raw_rules = raw_spec.split("\n")

spec_signature = self.parse_spec_signature(spec_raw_signature)

spec_rules = spec_raw_rules.map do |spec_raw_rule|
self.parse_spec_rule(spec_raw_rule)
end

return SC::Spec.new(spec_signature, spec_rules)
end

# Returns a SC::Spec::Rule instance from the raw spec rule
#
# @param [String] spec_raw_rule raw rule if the spec
# @return [SC::Spec::Rule]
def parse_spec_rule spec_raw_rule
# REGEX HERE PLEASE, F%#&!@* EASY
raw_params, raw_output = spec_raw_rule.split('->').map(&:strip)
output = eval(raw_output)
params = raw_params.split(/,\s+/).map do |raw_param|
eval(raw_param)
end

return SC::Spec::Rule.new(params, output)
end

# Returns a SC::Spec::Signature from the raw spec signature
#
# @param [String] spec_raw_signature raw signature of the spec
# @param [<SC::Spec::Signature]
def parse_spec_signature spec_raw_signature
# REGEX HERE PLEASE, F%#&!@* EASY
raw_name_and_params_types, output_type = spec_raw_signature.split('->').map(&:strip)
name, *params_types = raw_name_and_params_types.split(/,?\s+/).map(&:strip)

return SC::Spec::Signature.new(name, params_types, output_type)
end

end

end

end
22 changes: 22 additions & 0 deletions lib/sc/spec/rule.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
module SC

class Spec

# Assert representation based on input params and an expected output.
# Meant to be used against an algorith to test its behavior.
class Rule

attr_accessor :output, :params

# @param [<Object>] parmas set of input params
# @param [<Object>] output expected result
def initialize params, output
self.output = output
self.params = params
end

end

end

end
23 changes: 23 additions & 0 deletions lib/sc/spec/signature.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
module SC

class Spec

# Representation of the required input/output types
class Signature

attr_accessor :name, :output_type, :params_types

# @param [String] name local name of the algorith (not sure if needed)
# @param [<String>] param_types types of the expected input params
# @param [String] output_type type of the expected output
def initialize name, params_types, output_type
self.name = name
self.output_type = output_type
self.params_types = params_types
end

end

end

end
5 changes: 5 additions & 0 deletions rakefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
task default: %w[test]

task :test do
ruby "test/test.rb"
end
14 changes: 0 additions & 14 deletions sample/Gemfile.lock

This file was deleted.

13 changes: 12 additions & 1 deletion sc.gemspec
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,18 @@ Gem::Specification.new do |s|
s.version = '0.1'

s.files = [
'lib/sc.rb'
'README.md',
'lib/sc.rb',
'lib/sc/database.rb',
'lib/sc/spec.rb',
'lib/sc/spec/parser.rb',
'lib/sc/spec/rule.rb',
'lib/sc/spec/signature.rb'
]

s.add_development_dependency 'codeclimate-test-reporter'
s.add_development_dependency 'minitest'
s.add_development_dependency 'rake'
s.add_development_dependency 'yard'
end

7 changes: 7 additions & 0 deletions test/files/.sc/cache/2e0dcba288b50596b4cdd8680fffbf2e.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# THIS FILE HAS BEEN AUTOGENERATED BY CS
# DO NOT MODIFY ITS CONTENT. IT WILL BE
# OVERWRITTEN.

lambda do |f1, f2, f3|
return f3 * f2 / f1
end
7 changes: 7 additions & 0 deletions test/files/.sc/cache/7e46ad07603d4044a8d70c9004c48adf.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# THIS FILE HAS BEEN AUTOGENERATED BY CS
# DO NOT MODIFY ITS CONTENT. IT WILL BE
# OVERWRITTEN.

lambda do |s1|
return "Say Hello to #{s1}"
end
7 changes: 7 additions & 0 deletions test/files/.sc/cache/aac019283279bcb5f59f9760865f7d77.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# THIS FILE HAS BEEN AUTOGENERATED BY CS
# DO NOT MODIFY ITS CONTENT. IT WILL BE
# OVERWRITTEN.

lambda do |i1, i2|
return i1 + i2
end
9 changes: 9 additions & 0 deletions test/files/.sc/index.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# THIS FILE HAS BEEN AUTOGENERATED BY CS
# DO NOT MODIFY ITS CONTENT. IT WILL BE
# OVERWRITTEN.

Sample:
"hello:1": 7e46ad07603d4044a8d70c9004c48adf
"sum:2": aac019283279bcb5f59f9760865f7d77
"rule_of_three:3": 2e0dcba288b50596b4cdd8680fffbf2e

Loading

0 comments on commit fdbae53

Please sign in to comment.