ceml 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
data/.document ADDED
@@ -0,0 +1,5 @@
1
+ README.rdoc
2
+ lib/**/*.rb
3
+ bin/*
4
+ features/**/*.feature
5
+ LICENSE
data/.gitignore ADDED
@@ -0,0 +1,21 @@
1
+ ## MAC OS
2
+ .DS_Store
3
+
4
+ ## TEXTMATE
5
+ *.tmproj
6
+ tmtags
7
+
8
+ ## EMACS
9
+ *~
10
+ \#*
11
+ .\#*
12
+
13
+ ## VIM
14
+ *.swp
15
+
16
+ ## PROJECT::GENERAL
17
+ coverage
18
+ rdoc
19
+ pkg
20
+
21
+ ## PROJECT::SPECIFIC
data/LICENSE ADDED
@@ -0,0 +1,4 @@
1
+ Copyright (c) 2009 Citizen Logistics, Inc.
2
+
3
+ This software is licensed under the AGPL, the Affero General Public License 3.0.
4
+
data/Makefile ADDED
@@ -0,0 +1,5 @@
1
+ ceml:
2
+ tt lib/ceml/tt/*.treetop
3
+
4
+ test:
5
+ testrb test
data/README.markdown ADDED
@@ -0,0 +1,86 @@
1
+ Introducing CEML
2
+ ================
3
+
4
+ CEML is the world's first programming language custom-built for bringing people together.
5
+
6
+ It's for describing live coordinated events among people with different roles and across places.
7
+
8
+ All assignments and reassignments given through Groundcrew are actually CEML programs which are then executed on the server, resulting in a test message-, IM-, or mobile application-based coordination.
9
+
10
+ A sample program
11
+ ----------------
12
+
13
+ "some quiet time"
14
+ takes 10m
15
+ offers quiet observation connection peace
16
+ gather many agents, 1 landmark
17
+
18
+ tell agents:
19
+ at |landmark|, find a place to sit w hands on left leg
20
+ in silence, listen to noises in the park
21
+ after |duration|, cough gently and leave one at a time
22
+
23
+ or the slightly more complex rendezvous:
24
+
25
+ "a high five"
26
+ takes 2m
27
+ offers connection inclusion
28
+ gather 1 mobile_agent, 1 stationary_agent, 1 streetcorner
29
+
30
+ ask stationary_agent re clothing: What are you wearing (so the other person can recognize you)?
31
+
32
+ tell stationary_agent:
33
+ mill around at |streetcorner|
34
+ a stranger will approach you and give you a high five
35
+ when that happens nod and run in the direction they came from
36
+ find some trash and clean it up
37
+
38
+ tell mobile_agent:
39
+ go to |streetcorner| and
40
+ find someone wearing |stationary_agent.clothing|
41
+ give them a high five
42
+ nod, and keep walking around the corner
43
+
44
+ There are more examples in this repo.
45
+
46
+ Other resources
47
+ ---------------
48
+
49
+ There is a TextMate bundle which does syntax highlighting for CEML. Someone will make a vim mode soon. I am sure of it.
50
+
51
+ Reference - Commands
52
+ --------------------
53
+
54
+ CEML has a small number of keywords at this point: `gather`, `tell`, `ask`, and `assign` are the main four. `nab` is a variant of `gather`. `takes` and `offers` have a supporting role to provide metadata.
55
+
56
+ ### ask [role] re [varname]: [question]
57
+
58
+ Used to indicate that the information for the varname can be obtained by asking someone in the role/group the question provided.
59
+
60
+ ### tell [role]: [assignment]
61
+
62
+ Says to give the assignment to the people who match the role. Note that the assignment may have variables embedded within it, in which case the server will attempt to get values by asking questions, etc, before sending these assignments.
63
+
64
+ ### gather rolespec1, rolespec2, ... [block]
65
+
66
+ Declares a set of roles which need to be filled to run this script.
67
+
68
+ ### offers [tags]
69
+
70
+ Helps the user or the system pick which agents to involve, based on what they're up for.
71
+
72
+ ### takes [duration] [optional skill tags]
73
+
74
+ Also helps the user or the system pick which agents to involve, based on their skills and/or available time.
75
+
76
+ Reference - Syntax
77
+ ------------------
78
+
79
+ The syntax is simple and a bit like a cross between tcl and ruby. Every line starts with a command keyword, some arguments, and possibly a string after a colon. The terminal string parameter can be indented on the following line.
80
+
81
+ Copyright
82
+ ------------------
83
+
84
+ Copyright (c) 2010 Citizen Logistics, Inc. See LICENSE for details.
85
+
86
+ This software is licensed under the AGPL, the Affero General Public License 3.0.
data/Rakefile ADDED
@@ -0,0 +1,53 @@
1
+ require 'rubygems'
2
+ require 'rake'
3
+
4
+ begin
5
+ require 'jeweler'
6
+ Jeweler::Tasks.new do |gem|
7
+ gem.name = "ceml"
8
+ gem.summary = %Q{a language for coordinating real world events}
9
+ gem.description = %Q{a language for coordinating real world events}
10
+ gem.email = "joe@citizenlogistics.com"
11
+ gem.homepage = "http://github.com/citizenlogistics/ceml"
12
+ gem.authors = ["Joe Edelman"]
13
+ gem.add_dependency "treetop"
14
+ # gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
15
+ end
16
+ Jeweler::GemcutterTasks.new
17
+ rescue LoadError
18
+ puts "Jeweler (or a dependency) not available. Install it with: gem install jeweler"
19
+ end
20
+
21
+ require 'rake/testtask'
22
+ Rake::TestTask.new(:test) do |test|
23
+ test.libs << 'lib' << 'test'
24
+ test.pattern = 'test/**/test_*.rb'
25
+ test.verbose = true
26
+ end
27
+
28
+ begin
29
+ require 'rcov/rcovtask'
30
+ Rcov::RcovTask.new do |test|
31
+ test.libs << 'test'
32
+ test.pattern = 'test/**/test_*.rb'
33
+ test.verbose = true
34
+ end
35
+ rescue LoadError
36
+ task :rcov do
37
+ abort "RCov is not available. In order to run rcov, you must: sudo gem install spicycode-rcov"
38
+ end
39
+ end
40
+
41
+ task :test => :check_dependencies
42
+
43
+ task :default => :test
44
+
45
+ require 'rake/rdoctask'
46
+ Rake::RDocTask.new do |rdoc|
47
+ version = File.exist?('VERSION') ? File.read('VERSION') : ""
48
+
49
+ rdoc.rdoc_dir = 'rdoc'
50
+ rdoc.title = "ceml #{version}"
51
+ rdoc.rdoc_files.include('README*')
52
+ rdoc.rdoc_files.include('lib/**/*.rb')
53
+ end
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.2.0
@@ -0,0 +1,322 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
3
+ <plist version="1.0">
4
+ <dict>
5
+ <key>fileTypes</key>
6
+ <array>
7
+ <string>ceml</string>
8
+ </array>
9
+ <key>foldingStartMarker</key>
10
+ <string>\{\s*$</string>
11
+ <key>foldingStopMarker</key>
12
+ <string>^\s*\}</string>
13
+ <key>name</key>
14
+ <string>ceml</string>
15
+ <key>patterns</key>
16
+ <array>
17
+ <dict>
18
+ <key>begin</key>
19
+ <string>^\s*(involves|gather|nab|teams of)\s+</string>
20
+ <key>beginCaptures</key>
21
+ <dict>
22
+ <key>1</key>
23
+ <dict>
24
+ <key>name</key>
25
+ <string>keyword.control.assignment.ceml</string>
26
+ </dict>
27
+ </dict>
28
+ <key>end</key>
29
+ <string>$</string>
30
+ <key>name</key>
31
+ <string>meta.assume.ceml</string>
32
+ <key>patterns</key>
33
+ <array>
34
+ <dict>
35
+ <key>captures</key>
36
+ <dict>
37
+ <key>1</key>
38
+ <dict>
39
+ <key>name</key>
40
+ <string>constant.numeric.ceml</string>
41
+ </dict>
42
+ <key>2</key>
43
+ <dict>
44
+ <key>name</key>
45
+ <string>entity.name.roles.ceml</string>
46
+ </dict>
47
+ </dict>
48
+ <key>match</key>
49
+ <string>([\d-]+|many)\s+([\w-]+)</string>
50
+ <key>name</key>
51
+ <string>meta.rolecount.ceml</string>
52
+ </dict>
53
+ <dict>
54
+ <key>captures</key>
55
+ <dict>
56
+ <key>1</key>
57
+ <dict>
58
+ <key>name</key>
59
+ <string>keyword.control.assignment.ceml</string>
60
+ </dict>
61
+ </dict>
62
+ <key>match</key>
63
+ <string>(within)</string>
64
+ <key>name</key>
65
+ <string>radius</string>
66
+ </dict>
67
+ <dict>
68
+ <key>captures</key>
69
+ <dict>
70
+ <key>1</key>
71
+ <dict>
72
+ <key>name</key>
73
+ <string>keyword.control.assignment.ceml</string>
74
+ </dict>
75
+ </dict>
76
+ <key>match</key>
77
+ <string>(and)</string>
78
+ <key>name</key>
79
+ <string>radius</string>
80
+ </dict>
81
+ </array>
82
+ </dict>
83
+ <dict>
84
+ <key>begin</key>
85
+ <string>^\s*(tell)\s+([\w-]+)\s*:</string>
86
+ <key>beginCaptures</key>
87
+ <dict>
88
+ <key>1</key>
89
+ <dict>
90
+ <key>name</key>
91
+ <string>keyword.control.assignment.ceml</string>
92
+ </dict>
93
+ <key>2</key>
94
+ <dict>
95
+ <key>name</key>
96
+ <string>entity.name.roles.ceml</string>
97
+ </dict>
98
+ </dict>
99
+ <key>contentName</key>
100
+ <string>string.unquoted.ceml</string>
101
+ <key>end</key>
102
+ <string>^\b</string>
103
+ <key>name</key>
104
+ <string>meta.tell.ceml</string>
105
+ <key>patterns</key>
106
+ <array>
107
+ <dict>
108
+ <key>include</key>
109
+ <string>#linkvars</string>
110
+ </dict>
111
+ <dict>
112
+ <key>include</key>
113
+ <string>#popups</string>
114
+ </dict>
115
+ </array>
116
+ </dict>
117
+ <dict>
118
+ <key>begin</key>
119
+ <string>^\s*(ask)\s+([\w-]+)\s*(re)\s*([\w-]+):</string>
120
+ <key>beginCaptures</key>
121
+ <dict>
122
+ <key>1</key>
123
+ <dict>
124
+ <key>name</key>
125
+ <string>keyword.control.assignment.ceml</string>
126
+ </dict>
127
+ <key>2</key>
128
+ <dict>
129
+ <key>name</key>
130
+ <string>entity.name.roles.ceml</string>
131
+ </dict>
132
+ <key>3</key>
133
+ <dict>
134
+ <key>name</key>
135
+ <string>keyword.control.assignment.ceml</string>
136
+ </dict>
137
+ <key>4</key>
138
+ <dict>
139
+ <key>name</key>
140
+ <string>entity.name.roles.ceml</string>
141
+ </dict>
142
+ </dict>
143
+ <key>contentName</key>
144
+ <string>string.unquoted.ceml</string>
145
+ <key>end</key>
146
+ <string>^\b</string>
147
+ <key>name</key>
148
+ <string>meta.ask.ceml</string>
149
+ <key>patterns</key>
150
+ <array>
151
+ <dict>
152
+ <key>include</key>
153
+ <string>#linkvars</string>
154
+ </dict>
155
+ <dict>
156
+ <key>include</key>
157
+ <string>#popups</string>
158
+ </dict>
159
+ </array>
160
+ </dict>
161
+ <dict>
162
+ <key>captures</key>
163
+ <dict>
164
+ <key>1</key>
165
+ <dict>
166
+ <key>name</key>
167
+ <string>keyword.control.offering.ceml</string>
168
+ </dict>
169
+ <key>2</key>
170
+ <dict>
171
+ <key>name</key>
172
+ <string>string.quoted.double.ceml</string>
173
+ </dict>
174
+ </dict>
175
+ <key>match</key>
176
+ <string>^\s*(offers)\s+(.*)$</string>
177
+ <key>name</key>
178
+ <string>meta.offering.ceml</string>
179
+ </dict>
180
+ <dict>
181
+ <key>match</key>
182
+ <string>\b(type|for|rank|within|lasting|takes|req|popularity|players|from|provides|in|join|cue|end|exit|after|join_cue|cue_act)\b</string>
183
+ <key>name</key>
184
+ <string>support.variable.ceml</string>
185
+ </dict>
186
+ <dict>
187
+ <key>match</key>
188
+ <string>\b(many|within|re)\b</string>
189
+ <key>name</key>
190
+ <string>support.constant.ceml</string>
191
+ </dict>
192
+ <dict>
193
+ <key>match</key>
194
+ <string>\b(context|askfor)\b</string>
195
+ <key>name</key>
196
+ <string>keyword.control.ceml</string>
197
+ </dict>
198
+ <dict>
199
+ <key>captures</key>
200
+ <dict>
201
+ <key>1</key>
202
+ <dict>
203
+ <key>name</key>
204
+ <string>keyword.control.idea.ceml</string>
205
+ </dict>
206
+ <key>2</key>
207
+ <dict>
208
+ <key>name</key>
209
+ <string>entity.name.type.idea.ceml</string>
210
+ </dict>
211
+ </dict>
212
+ <key>match</key>
213
+ <string>^\s*(snippet|to|ask|within)\s+([.a-zA-Z0-9_/-]+)</string>
214
+ <key>name</key>
215
+ <string>meta.moo.ceml</string>
216
+ </dict>
217
+ <dict>
218
+ <key>captures</key>
219
+ <dict>
220
+ <key>1</key>
221
+ <dict>
222
+ <key>name</key>
223
+ <string>punctuation.definition.comment.js</string>
224
+ </dict>
225
+ </dict>
226
+ <key>match</key>
227
+ <string>(//).*$\n?</string>
228
+ <key>name</key>
229
+ <string>comment.line.double-slash.js</string>
230
+ </dict>
231
+ <dict>
232
+ <key>match</key>
233
+ <string>\b\d+m?\b</string>
234
+ <key>name</key>
235
+ <string>constant.numeric.ceml</string>
236
+ </dict>
237
+ <dict>
238
+ <key>begin</key>
239
+ <string>(?&lt;=\w):\s+</string>
240
+ <key>contentName</key>
241
+ <string>string.unquoted.ceml</string>
242
+ <key>end</key>
243
+ <string>$</string>
244
+ <key>name</key>
245
+ <string>meta.assign-stanza.ceml</string>
246
+ <key>patterns</key>
247
+ <array>
248
+ <dict>
249
+ <key>include</key>
250
+ <string>#linkvars</string>
251
+ </dict>
252
+ <dict>
253
+ <key>include</key>
254
+ <string>#popups</string>
255
+ </dict>
256
+ </array>
257
+ </dict>
258
+ <dict>
259
+ <key>begin</key>
260
+ <string>"</string>
261
+ <key>end</key>
262
+ <string>"</string>
263
+ <key>name</key>
264
+ <string>string.quoted.double.ceml</string>
265
+ <key>patterns</key>
266
+ <array>
267
+ <dict>
268
+ <key>include</key>
269
+ <string>#linkvars</string>
270
+ </dict>
271
+ <dict>
272
+ <key>include</key>
273
+ <string>#popups</string>
274
+ </dict>
275
+ <dict>
276
+ <key>match</key>
277
+ <string>\\.</string>
278
+ <key>name</key>
279
+ <string>constant.character.escape.ceml</string>
280
+ </dict>
281
+ </array>
282
+ </dict>
283
+ </array>
284
+ <key>repository</key>
285
+ <dict>
286
+ <key>linkvars</key>
287
+ <dict>
288
+ <key>captures</key>
289
+ <dict>
290
+ <key>1</key>
291
+ <dict>
292
+ <key>name</key>
293
+ <string>source.ceml.embedded.ceml</string>
294
+ </dict>
295
+ </dict>
296
+ <key>match</key>
297
+ <string>\|([\w\.-]+)\|</string>
298
+ <key>name</key>
299
+ <string>meta.variable.parameter.ceml</string>
300
+ </dict>
301
+ <key>popups</key>
302
+ <dict>
303
+ <key>captures</key>
304
+ <dict>
305
+ <key>2</key>
306
+ <dict>
307
+ <key>name</key>
308
+ <string>markup.quote.popup.ceml</string>
309
+ </dict>
310
+ </dict>
311
+ <key>match</key>
312
+ <string>(\[)(.*?)(\])</string>
313
+ <key>name</key>
314
+ <string>meta.popup.ceml</string>
315
+ </dict>
316
+ </dict>
317
+ <key>scopeName</key>
318
+ <string>source.ceml</string>
319
+ <key>uuid</key>
320
+ <string>BE4CE07F-C4D9-40FE-82BB-2BB28B2DE828</string>
321
+ </dict>
322
+ </plist>
@@ -0,0 +1,17 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
3
+ <plist version="1.0">
4
+ <dict>
5
+ <key>name</key>
6
+ <string>CEML</string>
7
+ <key>ordering</key>
8
+ <array>
9
+ <string>BE4CE07F-C4D9-40FE-82BB-2BB28B2DE828</string>
10
+ <string>81308D28-59AA-49FB-AB70-28BBC14E830A</string>
11
+ <string>8B695B35-5292-4ABB-981D-9D4DF4B5760E</string>
12
+ <string>043B37C6-EA61-4099-B158-26FCCF9A6332</string>
13
+ </array>
14
+ <key>uuid</key>
15
+ <string>4F110E92-4A52-4762-B378-B89ECBBAF031</string>
16
+ </dict>
17
+ </plist>
@@ -0,0 +1,15 @@
1
+ "a breakfast exchange"
2
+ gather 2 agents within 1 block
3
+ takes 45m
4
+
5
+ tell agents:
6
+ Okay, you need to make breakfast for a stranger and hide it
7
+ somewhere public in town. Do it fast, cause in 30m I will ask
8
+ you where you hid it and tell you where to find yours.
9
+
10
+ after 30m
11
+ ask agents re where:
12
+ Where did you hide your breakfast?
13
+ tell agents:
14
+ Go find your breakfast at |otherguy.where|. Send back any reports.
15
+ Thanks for playing!
@@ -0,0 +1,24 @@
1
+ "a citizen investigation"
2
+ takes 20m
3
+ involves 1 photographer, 1-2 interviewers, 1-3 reporters, 1 topic, 1 location
4
+
5
+ offers connection inclusion democracy adventure
6
+
7
+ ask photographer re clothing: What are you wearing? (so the others can recognize you?)
8
+
9
+ tell photographer:
10
+ go to |location|. the other members of your team will find you.
11
+ research |topic| by taking photos and sending them back to this number.
12
+ do this for |duration|
13
+
14
+
15
+ tell interviewers:
16
+ go to |location| and find someone wearing |clothing|. that's your photographer.
17
+ your assignment is to interview people to research |topic|
18
+ do this for |duration|
19
+
20
+
21
+ tell reporters:
22
+ go to |location| and find someone wearing |clothing|. that's your photographer.
23
+ your assignment is to to research |topic| and send back textual reports
24
+ do this for |duration|. good luck!
@@ -0,0 +1,19 @@
1
+ "a high five"
2
+ takes 2m
3
+ offers connection inclusion
4
+ involves 1 mobile_agent, 1 stationary_agent, 1 streetcorner
5
+
6
+ ask stationary_agent re clothing:
7
+ What are you wearing (so the other person can recognize you)?
8
+
9
+ tell stationary_agent:
10
+ mill around at |streetcorner|
11
+ a stranger will approach you and give you a high five
12
+ when that happens nod and run in the direction they came from
13
+ find some trash and clean it up
14
+
15
+ tell mobile_agent:
16
+ go to |streetcorner| and
17
+ find someone wearing |mobile_agent.clothing|
18
+ give them a high five
19
+ nod, and keep walking around the corner
@@ -0,0 +1,52 @@
1
+ module CEML
2
+ module CastingStatement
3
+ extend Forwardable
4
+ def_delegators :roles_phrase, :roles, :[], :min
5
+
6
+ def type
7
+ elements.first.text_value.split.first.to_sym
8
+ end
9
+
10
+ def max
11
+ in_teams? ? 10000 : roles_phrase.max
12
+ end
13
+
14
+ def radius
15
+ within.empty? ? 1600 * 50 : within.distance.meters
16
+ end
17
+
18
+ def in_teams?
19
+ type == :teams
20
+ end
21
+
22
+ def nab?
23
+ type == :nab
24
+ end
25
+ end
26
+
27
+
28
+ module CastingRoles
29
+ def role_nodes
30
+ return [role] if more_roles.empty?
31
+ return [role] + more_roles.roles_phrase.role_nodes
32
+ end
33
+
34
+ def roles
35
+ role_nodes.map{ |r| r.name.to_sym }
36
+ end
37
+
38
+ def [](x)
39
+ role_nodes.detect{ |r| r.name.to_sym == x }
40
+ end
41
+
42
+ def min
43
+ role_nodes.map(&:min).inject(0, &:+)
44
+ end
45
+
46
+ def max
47
+ role_nodes.map(&:max).inject(0, &:+)
48
+ end
49
+ end
50
+
51
+
52
+ end