teacher 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 5f045b662218cb1306c73ab4d6358a440638c9e0
4
+ data.tar.gz: 35ed5ad00b3fb5c687ef173f8367296f9130bd33
5
+ SHA512:
6
+ metadata.gz: 932037dbbe7f05e2418cbb9ddc02501bfe71a938f74640a25f15b849bd22735832d09ec8837383b02c50ef8a3153fd678d4881631d9c0bb84e46e8c58b90c3c4
7
+ data.tar.gz: 8705924a2baec42b99aa039789486360ee7c4415b2a6c8de800d2605ea0589ebe88b07abba5b0f9571778cf25efc976a7ee97ccbd48527cc055c9f894e6efb45
data/.gitignore ADDED
@@ -0,0 +1,34 @@
1
+ *.gem
2
+ *.rbc
3
+ /.config
4
+ /coverage/
5
+ /InstalledFiles
6
+ /pkg/
7
+ /spec/reports/
8
+ /test/tmp/
9
+ /test/version_tmp/
10
+ /tmp/
11
+
12
+ ## Specific to RubyMotion:
13
+ .dat*
14
+ .repl_history
15
+ build/
16
+
17
+ ## Documentation cache and generated files:
18
+ /.yardoc/
19
+ /_yardoc/
20
+ /doc/
21
+ /rdoc/
22
+
23
+ ## Environment normalisation:
24
+ /.bundle/
25
+ /lib/bundler/man/
26
+
27
+ # for a library or gem, you might want to ignore these files since the code is
28
+ # intended to run in multiple environments; otherwise, check them in:
29
+ # Gemfile.lock
30
+ # .ruby-version
31
+ # .ruby-gemset
32
+
33
+ # unless supporting rvm < 1.11.0 or doing something fancy, ignore this:
34
+ .rvmrc
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in teacher.gemspec
4
+ gemspec
data/Gemfile.lock ADDED
@@ -0,0 +1,21 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ teacher (0.0.1)
5
+ treetop (= 1.5.3)
6
+
7
+ GEM
8
+ remote: https://rubygems.org/
9
+ specs:
10
+ polyglot (0.3.4)
11
+ rake (10.3.1)
12
+ treetop (1.5.3)
13
+ polyglot (~> 0.3)
14
+
15
+ PLATFORMS
16
+ ruby
17
+
18
+ DEPENDENCIES
19
+ bundler (~> 1.5)
20
+ rake
21
+ teacher!
data/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2014 Marcos Felipe Pimenta Rodrigues
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2014 mrodrigues
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,62 @@
1
+ # Grade Calculator
2
+ Flexible language for defining grades calculations.
3
+
4
+ ## How to use
5
+ Consider the following input:
6
+ ```
7
+ # Assign values to variables
8
+ e1=8
9
+ e2=6
10
+ e3=4
11
+ t=6
12
+ re=6
13
+
14
+ # Publish these variables
15
+ pub(e1)
16
+ pub(e2)
17
+ pub(e3)
18
+ pub(t)
19
+ pub(re)
20
+
21
+ # Returns the smaller expression *in a symbolic way*
22
+ smaller=min(e1,e2,e3)
23
+
24
+ # Substitute the *variable* on the left by the right one
25
+ # *ONLY* expressions that return identifiers should be
26
+ # used on the left side
27
+ sub(smaller,re)
28
+
29
+ # Calculate the final grade
30
+ fg=(3*(2*e1+2*e2+3*e3)/7+t)/4
31
+ pub(fg)
32
+ ```
33
+
34
+ Interpreting the language:
35
+ ```
36
+ require 'teacher'
37
+
38
+ teacher = Teacher::Base.new
39
+
40
+ teacher.run(File.read("example.teacher"))
41
+ scope = teacher.scope
42
+
43
+ scope.published_variables["e1"] # => 8.0
44
+ scope.symbols["e1"] # => 8.0
45
+
46
+ scope.published_variables["e2"] # => 6.0
47
+ scope.symbols["e2"] # => 6.0
48
+
49
+ scope.published_variables["e3"] # => 4.0
50
+ scope.symbols["e3"] # => 4.0
51
+
52
+ scope.published_variables["t"] # => 6.0
53
+ scope.symbols["t"] # => 6.0
54
+
55
+ scope.published_variables["re"] # => 6.0
56
+ scope.symbols["re"] # => 6.0
57
+
58
+ scope.symbols["smaller"] # => identificador "e3"
59
+
60
+ scope.published_variables["fg"] # => 6.428571428571429
61
+ scope.symbols["fg"] # => 6.428571428571429
62
+ ```
data/Rakefile ADDED
@@ -0,0 +1 @@
1
+ require "bundler/gem_tasks"
data/example.teacher ADDED
@@ -0,0 +1,18 @@
1
+ e1=8
2
+ e2=6
3
+ e3=4
4
+ t=6
5
+ re=6
6
+
7
+ pub(e1)
8
+ pub(e2)
9
+ pub(e3)
10
+ pub(t)
11
+ pub(re)
12
+
13
+ smaller=min(e1,e2,e3)
14
+
15
+ sub(smaller,re)
16
+
17
+ fg=(3*(2*e1+2*e2+3*e3)/7+t)/4
18
+ pub(fg)
@@ -0,0 +1,93 @@
1
+ # Based on http://floris.briolas.nl/floris/2008/07/simple-calculator-with-antlr/comment-page-1/
2
+
3
+ grammar Teacher
4
+ rule program
5
+ statement* <Program>
6
+ end
7
+
8
+ rule statement
9
+ (expression newline / assignment newline) <Statement> / newline
10
+ end
11
+
12
+ rule expression
13
+ function_call / additive
14
+ end
15
+
16
+ rule newline
17
+ "\r"? "\n" { def eval(scope); end }
18
+ end
19
+
20
+ rule assignment
21
+ identifier "=" expression <Assignment>
22
+ end
23
+
24
+ rule additive
25
+ operand_1:multitive operator:additive_operator operand_2:additive <BinaryOperation>
26
+ /
27
+ multitive
28
+ end
29
+
30
+ rule additive_operator
31
+ '+' {
32
+ def apply(a, b)
33
+ a + b
34
+ end
35
+ }
36
+ /
37
+ '-' {
38
+ def apply(a, b)
39
+ a - b
40
+ end
41
+ }
42
+ end
43
+
44
+ rule multitive
45
+ operand_1:atom operator:multitive_operator operand_2:multitive <BinaryOperation>
46
+ /
47
+ atom
48
+ end
49
+
50
+ rule multitive_operator
51
+ '*' {
52
+ def apply(a, b)
53
+ a * b
54
+ end
55
+ }
56
+ /
57
+ '/' {
58
+ def apply(a, b)
59
+ a / b
60
+ end
61
+ }
62
+ end
63
+
64
+ rule function_call
65
+ name:identifier "(" abc:list? ")" <FunctionCall>
66
+ end
67
+
68
+ rule list
69
+ (expression "," list+ <List>)
70
+ /
71
+ expression
72
+ end
73
+
74
+ rule group
75
+ "(" additive ")" <Group>
76
+ end
77
+
78
+ rule number
79
+ [0-9]+ <Number>
80
+ end
81
+
82
+ rule identifier
83
+ [a-zA-Z]+ [a-zA-Z_0-9]* <Identifier>
84
+ end
85
+
86
+ rule space
87
+ [ \t]* <Space>
88
+ end
89
+
90
+ rule atom
91
+ number / identifier / group
92
+ end
93
+ end
data/lib/teacher.rb ADDED
@@ -0,0 +1,31 @@
1
+ require 'teacher/version'
2
+
3
+ require 'treetop'
4
+
5
+ require 'teacher/scope'
6
+ require 'teacher/function'
7
+ require 'teacher/nodes'
8
+
9
+ Treetop.load("grammar/teacher")
10
+
11
+ module Teacher
12
+
13
+ class Base
14
+
15
+ attr_accessor :scope
16
+
17
+ def initialize
18
+ @parser = TeacherParser.new
19
+ end
20
+
21
+ def run(string)
22
+ @scope = TopLevel.new
23
+ @tree = parse(string)
24
+ @tree.eval(scope)
25
+ end
26
+
27
+ def parse(string)
28
+ @parser.parse(string)
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,26 @@
1
+ module Teacher
2
+
3
+ class Function
4
+ def initialize(scope, &block)
5
+ @scope = scope
6
+ @body = block
7
+ end
8
+
9
+ def call(scope, args)
10
+ args.reject! { |a| a.text_value.blank? }
11
+ if args.to_a.any?
12
+ tmp = [args.first]
13
+ if args.length > 1
14
+ last = args.last.elements.first
15
+ if last.is_a?(List)
16
+ tmp += last.eval(self)
17
+ else
18
+ tmp << last
19
+ end
20
+ end
21
+ args = tmp
22
+ end
23
+ @body.call(*args)
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,70 @@
1
+ module Teacher
2
+ class Program < Treetop::Runtime::SyntaxNode
3
+ def eval(scope)
4
+ elements.map { |e, i| e.eval(scope) }.last
5
+ end
6
+ end
7
+
8
+ module Number
9
+ def eval(scope); text_value.to_f; end
10
+ end
11
+
12
+ class Identifier < Treetop::Runtime::SyntaxNode
13
+ def eval(scope); scope[text_value]; end
14
+ end
15
+
16
+ module Statement
17
+ def eval(scope)
18
+ elements.first.eval(scope)
19
+ end
20
+ end
21
+
22
+ class Space < Treetop::Runtime::SyntaxNode
23
+ def eval(scope); end
24
+ end
25
+
26
+ class BinaryOperation < Treetop::Runtime::SyntaxNode
27
+ def eval(scope)
28
+ operand_1 = elements.first
29
+ operand_2 = elements.last
30
+ loop do
31
+ operand_1 = operand_1.eval(scope)
32
+ break unless operand_1.is_a? Identifier
33
+ end
34
+ loop do
35
+ operand_2 = operand_2.eval(scope)
36
+ break unless operand_2.is_a? Identifier
37
+ end
38
+ operator.apply(operand_1, operand_2)
39
+ end
40
+ end
41
+
42
+ class List < Treetop::Runtime::SyntaxNode
43
+ def eval(scope)
44
+ last = elements.last.elements.first
45
+ last = last.eval(scope) if last.is_a?(List)
46
+ [elements.first, *last]
47
+ end
48
+ end
49
+
50
+ class FunctionCall < Treetop::Runtime::SyntaxNode
51
+ def eval(scope)
52
+ func = scope[name.text_value]
53
+ args = elements[2]
54
+ args = args.is_a?(List) ? args.elements : [args]
55
+ func.call(scope, args)
56
+ end
57
+ end
58
+
59
+ class Group < Treetop::Runtime::SyntaxNode
60
+ def eval(scope)
61
+ elements[1].eval(scope)
62
+ end
63
+ end
64
+
65
+ class Assignment < Treetop::Runtime::SyntaxNode
66
+ def eval(scope)
67
+ scope[elements.first.text_value] = elements.last.eval(scope)
68
+ end
69
+ end
70
+ end
@@ -0,0 +1,42 @@
1
+ module Teacher
2
+ class Scope
3
+
4
+ attr_reader :published_variables, :symbols
5
+
6
+ def initialize(parent = nil)
7
+ @parent = parent || {}
8
+ @symbols = {}
9
+ @published_variables = {}
10
+ end
11
+
12
+ def [](name)
13
+ @symbols[name] || @parent[name]
14
+ end
15
+
16
+ def []=(name, value)
17
+ @symbols[name] = value
18
+ end
19
+ end
20
+
21
+ class TopLevel < Scope
22
+ def initialize(*args)
23
+ super
24
+
25
+ self["min"] = Function.new(self) do |*arguments|
26
+ arguments.min_by { |a| a.eval(self) }
27
+ end
28
+
29
+ self["sub"] = self["substitute"] = Function.new(self) do |target, origin|
30
+ loop do
31
+ target = target.eval(self)
32
+ break if target.is_a?(Identifier)
33
+ end
34
+ @symbols[target.text_value] = origin.eval(self)
35
+ end
36
+
37
+ self["pub"] = self["publish"] = Function.new(self) do |identifier|
38
+ @published_variables[identifier.text_value] = identifier.eval(self)
39
+ end
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,3 @@
1
+ module Teacher
2
+ VERSION = "0.0.1"
3
+ end
data/teacher.gemspec ADDED
@@ -0,0 +1,23 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'teacher/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "teacher"
8
+ spec.version = Teacher::VERSION
9
+ spec.authors = ["mrodrigues"]
10
+ spec.email = ["mrodrigues.uff@gmail.com"]
11
+ spec.summary = %q{Flexible language for defining grades calculations.}
12
+ spec.homepage = "https://github.com/mrodrigues/teacher"
13
+ spec.license = "MIT"
14
+
15
+ spec.files = `git ls-files -z`.split("\x0")
16
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
17
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
18
+ spec.require_paths = ["lib"]
19
+
20
+ spec.add_development_dependency "bundler", "~> 1.5"
21
+ spec.add_development_dependency "rake"
22
+ spec.add_runtime_dependency "treetop", "1.5.3"
23
+ end
metadata ADDED
@@ -0,0 +1,101 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: teacher
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - mrodrigues
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2014-05-01 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ~>
18
+ - !ruby/object:Gem::Version
19
+ version: '1.5'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ~>
25
+ - !ruby/object:Gem::Version
26
+ version: '1.5'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - '>='
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - '>='
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: treetop
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - '='
46
+ - !ruby/object:Gem::Version
47
+ version: 1.5.3
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - '='
53
+ - !ruby/object:Gem::Version
54
+ version: 1.5.3
55
+ description:
56
+ email:
57
+ - mrodrigues.uff@gmail.com
58
+ executables: []
59
+ extensions: []
60
+ extra_rdoc_files: []
61
+ files:
62
+ - .gitignore
63
+ - Gemfile
64
+ - Gemfile.lock
65
+ - LICENSE
66
+ - LICENSE.txt
67
+ - README.md
68
+ - Rakefile
69
+ - example.teacher
70
+ - grammar/teacher.treetop
71
+ - lib/teacher.rb
72
+ - lib/teacher/function.rb
73
+ - lib/teacher/nodes.rb
74
+ - lib/teacher/scope.rb
75
+ - lib/teacher/version.rb
76
+ - teacher.gemspec
77
+ homepage: https://github.com/mrodrigues/teacher
78
+ licenses:
79
+ - MIT
80
+ metadata: {}
81
+ post_install_message:
82
+ rdoc_options: []
83
+ require_paths:
84
+ - lib
85
+ required_ruby_version: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - '>='
88
+ - !ruby/object:Gem::Version
89
+ version: '0'
90
+ required_rubygems_version: !ruby/object:Gem::Requirement
91
+ requirements:
92
+ - - '>='
93
+ - !ruby/object:Gem::Version
94
+ version: '0'
95
+ requirements: []
96
+ rubyforge_project:
97
+ rubygems_version: 2.0.3
98
+ signing_key:
99
+ specification_version: 4
100
+ summary: Flexible language for defining grades calculations.
101
+ test_files: []