hivemind 0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: f2764d5a862cc3857083c1477149d9371a287b5e
4
+ data.tar.gz: c77dec53e2a89d414049b1a8ee27012b447f10ca
5
+ SHA512:
6
+ metadata.gz: afaea2fd77b4ed39da1da4e29026fff23731cfe1ff0c57ba04351ae3f62a8b2398210c7eb947c082443c12d4bf7b2128a1f7ef2b7c634c6d5c09480136ad6637
7
+ data.tar.gz: 36c436652012e46864ceb2665d5006113c21c0137c0a4628744a9d84a7070a59c5fceaa31c80037664b72eb16dc82fdc403ab6e1035b88909e16bc5bd2569f1a
data/.gitignore ADDED
@@ -0,0 +1,22 @@
1
+ #Logs
2
+ application/logs/*.php
3
+
4
+ # Content types
5
+ /application/xml/types/*.xml
6
+
7
+ # Custom builds and generated php files
8
+ /core/documentation/build
9
+ /core/views/admin/content/translations.php
10
+
11
+ # Attachs and cache files #
12
+ *.tmp
13
+ /attach/cache/
14
+ /attach/
15
+ /application/cache/_bancha/*.css
16
+ /application/cache/_bancha/*.js
17
+
18
+ Gemfile.lock
19
+ *.pyc
20
+ *.doc
21
+ *.txt
22
+
data/Gemfile ADDED
@@ -0,0 +1,7 @@
1
+ source 'https://rubygems.org'
2
+
3
+ group :development, :test do
4
+ gem 'bundler'
5
+ gem 'rspec'
6
+ gem 'skeptic'
7
+ end
data/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2016 Alexander Ivanov
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy of
6
+ this software and associated documentation files (the "Software"), to deal in
7
+ the Software without restriction, including without limitation the rights to
8
+ use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
9
+ the Software, and to permit persons to whom the Software is furnished to do so,
10
+ 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, FITNESS
17
+ FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
18
+ COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
19
+ IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
20
+ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,42 @@
1
+ [![Build Status](https://travis-ci.org/alehander42/hivemind.svg?branch=master)](https://travis-ci.org/alehander42/hivemind)
2
+ [![MIT License](http://img.shields.io/badge/License-MIT-blue.svg)](LICENSE)
3
+
4
+ # hivemind
5
+
6
+ A programming language for HackFMI 5
7
+
8
+ A compiler for hivemind
9
+
10
+ # Usage
11
+
12
+ Run a file
13
+
14
+ ```bash
15
+ hivemind <filename>
16
+ ```
17
+
18
+ Translate a file into another syntax representation
19
+
20
+ ```bash
21
+ hivemind render a.hm pythonic a2.hm
22
+ ```
23
+
24
+ # Language
25
+
26
+ The language is just a simple python/ruby-like language for now.
27
+
28
+ # Features(language & env)
29
+
30
+
31
+ # Future development
32
+
33
+ * fluid folder/file structure representations
34
+ * editor plugins
35
+ * more syntaxes
36
+
37
+ ## License
38
+
39
+ Copyright 2016 [Alexander Ivanov](https://twitter.com/alehander42)
40
+
41
+ Distributed under the MIT License.
42
+
data/Rakefile ADDED
@@ -0,0 +1,18 @@
1
+ require 'rubygems'
2
+ require 'bundler'
3
+ begin
4
+ Bundler.setup(:default, :development)
5
+ rescue Bundler::BundlerError => e
6
+ $stderr.puts e.message
7
+ $stderr.puts "Run `bundle install` to install missing gems"
8
+ exit e.status_code
9
+ end
10
+ require 'rake'
11
+
12
+ require 'rspec/core'
13
+ require 'rspec/core/rake_task'
14
+ RSpec::Core::RakeTask.new(:spec) do |spec|
15
+ spec.pattern = FileList['spec/**/*_spec.rb']
16
+ end
17
+
18
+ task :default => :spec
data/bin/hivemind ADDED
@@ -0,0 +1,52 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
4
+
5
+ require 'hivemind'
6
+
7
+ SYNTAXES_PATH = File.join(File.expand_path(File.join(File.dirname(__FILE__), '..')), 'syntaxes')
8
+
9
+ def astify(source, syntax)
10
+ parser, refs = Hivemind::Syntax.generate_syntax(syntax)
11
+ success, tree, _ = parser.parse(source, refs)
12
+ tree
13
+ end
14
+
15
+ def syntax_file(f)
16
+ File.read(File.join(SYNTAXES_PATH, "#{f}.syntax"))
17
+ end
18
+
19
+ if ARGV.length == 1
20
+ filename = ARGV[0]
21
+ source = File.read(filename)
22
+ syntax_line, _, source = source.partition("\n")
23
+ if !syntax_line.start_with? 'syntax: '
24
+ puts "file doesn't specify a syntax"
25
+ exit 1
26
+ end
27
+ syntax = syntax_file(syntax_line.partition(': ').last)
28
+ tree = astify(source.lstrip, syntax)
29
+ vm = Hivemind::VM.new(tree)
30
+ result = vm.run Hivemind::Runtime::HivemindEnv
31
+ elsif ARGV.length == 4
32
+ filename, second_syntax_name, save = ARGV[1..-1]
33
+ source = File.read(filename)
34
+ syntax_line, _, source = source.partition("\n")
35
+ if !syntax_line.start_with? 'syntax: '
36
+ puts "first line of file doesn't specify a syntax"
37
+ exit 1
38
+ end
39
+ first = syntax_file(syntax_line.partition(': ').last)
40
+ second = syntax_file(second_syntax_name)
41
+ tree = astify(source.lstrip, first)
42
+ result = Hivemind::Renderer.new(tree, second).render
43
+ File.write(save, "syntax: #{second_syntax_name}\n\n#{result}")
44
+ else
45
+ puts <<-USAGE
46
+ hivemind <filename>
47
+ runs the file
48
+ hivemind render <filename> <syntax> <new_filename>
49
+ renders the source with <syntax>
50
+ USAGE
51
+ end
52
+
data/hivemind.gemspec ADDED
@@ -0,0 +1,57 @@
1
+ # Generated by jeweler
2
+ # DO NOT EDIT THIS FILE DIRECTLY
3
+ # Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
4
+ # -*- encoding: utf-8 -*-
5
+ # stub: skeptic 0.0.16 ruby lib
6
+
7
+ Gem::Specification.new do |s|
8
+ s.name = "hivemind"
9
+ s.version = "0.1"
10
+
11
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
12
+ s.require_paths = ["lib"]
13
+ s.authors = ["Alexander Ivanov"]
14
+ s.date = "2016-03-12"
15
+ s.description = "A multi-syntax programming language"
16
+ s.email = "alehande42@gmail.com"
17
+ s.executables = ["hivemind"]
18
+ s.extra_rdoc_files = [
19
+ "LICENSE",
20
+ "README.md"
21
+ ]
22
+ s.files = [
23
+ "bin/hivemind",
24
+ "lib/hivemind.rb",
25
+ ".gitignore",
26
+ "Gemfile",
27
+ "LICENSE",
28
+ "README.md",
29
+ "Rakefile",
30
+ "hivemind.gemspec",
31
+ "lib/hivemind/code_viewer.rb",
32
+ "lib/hivemind/combinators.rb",
33
+ "lib/hivemind/environment.rb",
34
+ "lib/hivemind/errors.rb",
35
+ "lib/hivemind/renderer.rb",
36
+ "lib/hivemind/runtime.rb",
37
+ "lib/hivemind/syntax.rb",
38
+ "lib/hivemind/universal_ast.rb",
39
+ "lib/hivemind/vm.rb",
40
+ "spec/spec_helper.rb",
41
+ "spec/hivemind/parser_spec.rb",
42
+ "spec/hivemind/vm_spec.rb",
43
+ "spec/hivemind/universal_ast_spec.rb",
44
+ "syntaxes/pythonic.syntax",
45
+ "syntaxes/lolcode.syntax",
46
+ "syntaxes/paren.syntax"
47
+ ]
48
+ s.homepage = "http://github.com/alehander42/hivemind"
49
+ s.licenses = ["MIT"]
50
+ s.rubygems_version = "2.4.8"
51
+ s.summary = "A multi-syntax language"
52
+
53
+ s.add_development_dependency(%q<rspec>, ["= 2.14.1"])
54
+ s.add_development_dependency(%q<bundler>, [">= 0"])
55
+ s.add_development_dependency(%q<skeptic>, [">= 0"])
56
+ end
57
+
data/lib/hivemind.rb ADDED
@@ -0,0 +1,6 @@
1
+ require_relative 'hivemind/universal_ast'
2
+ require_relative 'hivemind/environment'
3
+ require_relative 'hivemind/vm'
4
+ require_relative 'hivemind/runtime'
5
+ require_relative 'hivemind/syntax'
6
+ require_relative 'hivemind/renderer'
@@ -0,0 +1,41 @@
1
+ # 'universal_ast'
2
+
3
+ # module Hivemind
4
+ # class CodeViewer
5
+ # def initialize(tree)
6
+ # @tree = tree
7
+ # end
8
+
9
+ # def view_as(query)
10
+ # hierarchy = QueryAnalyzer.parse(query)
11
+ # rebuild_tree(hierarchy)
12
+ # end
13
+
14
+ # def rebuild_tree(hierarchy)
15
+ # if hierarchy[0].type == @code_view.hierarchy[0].type
16
+ # # only sorting maybe
17
+ # # and sorting still not supported
18
+ # @tree
19
+ # else
20
+ # # method > code
21
+ # new_tree = UniversalAST::Image.new([])
22
+ # top = {}
23
+ # if hierarchy[0].type == :method
24
+ # @tree.statements.each do |statement|
25
+ # statement.methods.each do |method|
26
+ # top[method.method_name.value] ||= {}
27
+ # top[method.method_name.value][statement.class_name.value] = [args, method.body]
28
+ # end
29
+ # end
30
+ # else
31
+ # @tree.statements.each do |statement|
32
+ # statement.body.each do |method|
33
+ # top[method.class_name.value] ||= {}
34
+ # top[method.class_name.value][statement.method_name.value] = [args, method.body]
35
+ # end
36
+ # end
37
+ # end
38
+ # end
39
+ # end
40
+ # end
41
+ # end
@@ -0,0 +1,202 @@
1
+ require_relative 'universal_ast'
2
+
3
+ class Combinator
4
+ def &(other)
5
+ And.new(self, other)
6
+ end
7
+
8
+ def |(other)
9
+ Or.new(self, other)
10
+ end
11
+ end
12
+
13
+ class Lit < Combinator
14
+ attr_reader :value
15
+
16
+ def initialize(value)
17
+ @value = value
18
+ end
19
+
20
+ def parse(input, refs)
21
+ if input.start_with?(@value)
22
+ [true, @value, input[@value.length.. -1]]
23
+ else
24
+ [false, '', input]
25
+ end
26
+ end
27
+ end
28
+
29
+ class Mat < Combinator
30
+ attr_reader :regex
31
+
32
+ def initialize(regex)
33
+ @regex = /\A#{regex}/
34
+ end
35
+
36
+ def parse(input, refs)
37
+ match = @regex.match(input)
38
+ if match
39
+ [true, input[0..match.to_s.size - 1], input[match.to_s.size.. -1]]
40
+ else
41
+ [false, '', input]
42
+ end
43
+ end
44
+ end
45
+
46
+ class Binary < Combinator
47
+ attr_accessor :first, :second
48
+
49
+ def initialize(first, second)
50
+ @first, @second = first, second
51
+ end
52
+ end
53
+
54
+ class And < Binary
55
+ def parse(input, refs)
56
+ first_success, first_result, remaining = @first.parse(input, refs)
57
+ if first_success
58
+ second_success, second_result, remaining = @second.parse(remaining, refs)
59
+ if second_success
60
+ return [true, combine(first_result, second_result), remaining]
61
+ end
62
+ end
63
+ [false, [], input]
64
+ end
65
+
66
+ def combine(first_result, second_result)
67
+ if @first.is_a?(And)
68
+ first_result + [second_result]
69
+ else
70
+ [first_result, second_result]
71
+ end
72
+ end
73
+ end
74
+
75
+ class Or < Binary
76
+ def parse(input, refs)
77
+ [@first, @second].each do |combinator|
78
+ success, result, remaining = combinator.parse(input, refs)
79
+ return [true, result, remaining] if success
80
+ end
81
+ [false, '', input]
82
+ end
83
+ end
84
+
85
+ class Many < Combinator
86
+ attr_accessor :parser
87
+
88
+ def initialize(parser, as: nil)
89
+ @parser = parser
90
+ end
91
+
92
+ def parse(input, refs)
93
+ success = true
94
+ remaining = input
95
+ results = []
96
+ while success
97
+ success, result, remaining = @parser.parse(remaining, refs)
98
+ results.push(result) if success
99
+ end
100
+ [true, results, remaining]
101
+ end
102
+ end
103
+
104
+ class Join < Combinator
105
+ attr_accessor :parser, :as
106
+
107
+ def initialize(parser, separator, as: nil)
108
+ @parser = parser
109
+ @separator = separator
110
+ @as = as.to_sym
111
+ @separator_parser = Lit.new(@separator) & Mat.new(/ */) #workaround hivemind
112
+ @@depth ||= 0
113
+ end
114
+
115
+ def parse(input, refs)
116
+ success = true
117
+ remaining = input
118
+ results = []
119
+ while success
120
+ # puts "#{' ' * @@depth}BEFORE " + @parser.label.to_s
121
+ # p [" " * @@depth, remaining]
122
+
123
+ # @@depth += 1
124
+ success, result, remaining = @parser.parse(remaining, refs)
125
+ # @@depth -= 1
126
+ # puts "#{' ' * @@depth}AFTER " + @parser.label.to_s
127
+ # p [" " * @@depth, success, remaining, results.length]
128
+ # puts
129
+
130
+ results.push(result) if success
131
+ if success
132
+ if remaining.start_with? ' (' # fix later
133
+ remaining = "\n#{remaining}"
134
+ end
135
+ success, result, remaining = @separator_parser.parse(remaining, refs)
136
+ end
137
+ end
138
+ [true, results, remaining]
139
+ end
140
+ end
141
+
142
+ class Ref < Combinator
143
+ attr_accessor :label
144
+
145
+ def initialize(label, as: nil)
146
+ @label = label
147
+ @as = as
148
+ end
149
+
150
+ def parse(input, refs)
151
+ ref_parser = refs[@label.to_sym]
152
+ ref_parser.parse(input, refs)
153
+ end
154
+ end
155
+
156
+ class Maybe < Combinator
157
+ attr_accessor :parser
158
+
159
+ def initialize(parser)
160
+ @parser = parser
161
+ end
162
+
163
+ def parse(input, refs)
164
+ _, result, remaining = @parser.parse(input, refs)
165
+ [true, result, remaining]
166
+ end
167
+ end
168
+
169
+ class Apply < Combinator
170
+ attr_accessor :parser
171
+ attr_reader :transformation
172
+
173
+ def initialize(parser, &transformation)
174
+ @parser, @transformation = parser, transformation
175
+ end
176
+
177
+ def parse(input, refs)
178
+ success, result, remaining = @parser.parse(input, refs)
179
+ result = @transformation.call(result) if success
180
+ [success, result, remaining]
181
+ end
182
+ end
183
+
184
+ def literal(value)
185
+ Literal.new(value)
186
+ end
187
+
188
+ def many(combinator)
189
+ Many.new(combinator)
190
+ end
191
+
192
+ def maybe(combinator)
193
+ Maybe.new(combinator)
194
+ end
195
+
196
+ def apply(combinator, &transformation)
197
+ Apply.new(combinator, &transformation)
198
+ end
199
+
200
+ def match(regex)
201
+ Match.new(regex)
202
+ end