shift-lang 0.1.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.
Files changed (42) hide show
  1. data/.gitignore +17 -0
  2. data/Gemfile +4 -0
  3. data/LICENSE +22 -0
  4. data/README.md +29 -0
  5. data/Rakefile +2 -0
  6. data/bin/sft +5 -0
  7. data/bin/shift +5 -0
  8. data/lib/app_engine_templates/app.yaml +13 -0
  9. data/lib/app_engine_templates/pystache/__init__.py +8 -0
  10. data/lib/app_engine_templates/pystache/__init__.pyc +0 -0
  11. data/lib/app_engine_templates/pystache/loader.py +47 -0
  12. data/lib/app_engine_templates/pystache/loader.pyc +0 -0
  13. data/lib/app_engine_templates/pystache/template.py +177 -0
  14. data/lib/app_engine_templates/pystache/template.pyc +0 -0
  15. data/lib/app_engine_templates/pystache/view.py +94 -0
  16. data/lib/app_engine_templates/pystache/view.pyc +0 -0
  17. data/lib/heroku_templates/Gemfile +6 -0
  18. data/lib/heroku_templates/Procfile +1 -0
  19. data/lib/shift-lang/builder/db_model.rb +20 -0
  20. data/lib/shift-lang/builder/url_handler.rb +17 -0
  21. data/lib/shift-lang/builder.rb +103 -0
  22. data/lib/shift-lang/generator/javascript_generator.rb +410 -0
  23. data/lib/shift-lang/generator/javascript_templates.rb +37 -0
  24. data/lib/shift-lang/generator/python_generator.rb +330 -0
  25. data/lib/shift-lang/generator/python_templates.rb +44 -0
  26. data/lib/shift-lang/generator/ruby_generator.rb +334 -0
  27. data/lib/shift-lang/generator/ruby_templates.rb +50 -0
  28. data/lib/shift-lang/generator.rb +41 -0
  29. data/lib/shift-lang/parser/control_statement_parser.rb +17 -0
  30. data/lib/shift-lang/parser/db_query_parser.rb +20 -0
  31. data/lib/shift-lang/parser/keyword_parser.rb +52 -0
  32. data/lib/shift-lang/parser/operator_parser.rb +35 -0
  33. data/lib/shift-lang/parser/routing_expression_parser.rb +33 -0
  34. data/lib/shift-lang/parser/simple_expression_parser.rb +87 -0
  35. data/lib/shift-lang/parser/token_parser.rb +69 -0
  36. data/lib/shift-lang/parser/value_returning_expression_parser.rb +18 -0
  37. data/lib/shift-lang/parser/void_statement_parser.rb +12 -0
  38. data/lib/shift-lang/parser.rb +120 -0
  39. data/lib/shift-lang/version.rb +3 -0
  40. data/lib/shift-lang.rb +224 -0
  41. data/shift-lang.gemspec +19 -0
  42. metadata +106 -0
@@ -0,0 +1,330 @@
1
+ require 'erb'
2
+
3
+ require_relative '../builder'
4
+ require_relative './python_templates'
5
+
6
+ module Shift
7
+ module Generator
8
+ class PythonGenerator
9
+ attr_accessor :integer_attributes, :builder, :has_models, :defined_hashes
10
+
11
+ def initialize()
12
+ @integer_attributes = []
13
+ @defined_hashes = []
14
+ @has_models = false
15
+ @builder = Shift::ShiftBuilder.new
16
+ end
17
+
18
+ def get_data_from_file(file_name)
19
+ @builder.get_data_from_file file_name
20
+ end
21
+
22
+ def get_import_statements()
23
+ Shift::Generator::PythonTemplates::IMPORT_WEBAPP_STATEMENT + "\n\n" +
24
+ Shift::Generator::PythonTemplates::IMPORT_PYSTACHE_STATEMENT + "\n\n" +
25
+ (@has_models ? Shift::Generator::PythonTemplates::IMPORT_DATABASE_STATEMENT + "\n\n" : "") +
26
+ Shift::Generator::PythonTemplates::UTILITY_FUNCTIONS + "\n\n"
27
+ end
28
+
29
+ def get_model_data()
30
+ result = ""
31
+
32
+ model_name_template = ERB.new(Shift::Generator::PythonTemplates::MODEL_NAME_TEMPLATE)
33
+
34
+ @builder.models.each do | model |
35
+ model_name = model.name
36
+ result += model_name_template.result(binding) + "\n"
37
+
38
+ model.attributes.each do | attribute |
39
+ if (attribute[:type] == "string")
40
+ result += ("\t" + attribute[:name] + " = " + Shift::Generator::PythonTemplates::DB_STRING_PROPERTY + "\n")
41
+ else
42
+ if (attribute[:type] == "integer")
43
+ @integer_attributes.push attribute[:name]
44
+ result += ("\t" + attribute[:name] + " = " + Shift::Generator::PythonTemplates::DB_INTEGER_PROPERTY + "\n")
45
+ end
46
+ end
47
+ end
48
+ end
49
+
50
+ result
51
+ end
52
+
53
+ def expression_transform(statement, num_tabs)
54
+ tabs = ""
55
+ num_tabs.times { tabs += "\t" }
56
+ key = statement.keys[0]
57
+ case key
58
+ when :assignment_statement
59
+ extra = ""
60
+ if(statement[:assignment_statement][:left].keys[0] == :hash_value)
61
+ val = statement[:assignment_statement][:left][:hash_value].to_s
62
+ hash_var = val[0..(val.index('[') - 1)]
63
+ if !@defined_hashes.include?(hash_var)
64
+ @defined_hashes.push hash_var
65
+ extra += (tabs + "if (('" + hash_var + "' in locals()) == False):\n")
66
+ extra += (tabs + "\t" + hash_var + " = {}\n")
67
+ end
68
+ end
69
+
70
+ left = apply_transforms(statement[:assignment_statement][:left], 0)
71
+ right = apply_transforms(statement[:assignment_statement][:right], 0)
72
+
73
+ if(statement[:assignment_statement][:left].keys[0] == :object_value)
74
+ value_name = statement[:assignment_statement][:left][:object_value].to_s
75
+ value_name = value_name[(value_name.index('.') + 1)..(value_name.length - 1)]
76
+ if(@integer_attributes.include?(value_name))
77
+ right = "int(" + right.to_s + ")"
78
+ end
79
+ end
80
+ extra + tabs + left.to_s + " = " + right.to_s
81
+ end
82
+ end
83
+
84
+ def token_transform(statement, num_tabs)
85
+ tabs = ""
86
+ num_tabs.times { tabs += "\t" }
87
+
88
+ key = statement.keys[0]
89
+
90
+ case key
91
+ when :identifier
92
+ statement[:identifier].to_s
93
+ when :object_value
94
+ if (statement[:object_value].to_s.split(".")[1] == "save")
95
+ tabs + statement[:object_value].to_s.split(".")[0] + ".put()"
96
+ else
97
+ tabs + statement[:object_value].to_s
98
+ end
99
+ when :hash_value
100
+ statement[:hash_value].to_s
101
+ when :string
102
+ statement[:string].to_s
103
+ else
104
+ nil
105
+ end
106
+
107
+ end
108
+
109
+ def query_transform(statement, num_tabs)
110
+ tabs = ""
111
+ num_tabs.times { tabs += "\t" }
112
+ statement = statement[:query]
113
+ case statement[:operation].to_s
114
+ when "all"
115
+ (statement[:model_name].to_s + ".all().fetch(20)")
116
+ when "new"
117
+ (statement[:model_name].to_s + "()")
118
+ when "find"
119
+ # Todo.gql("WHERE priority=" + self.request.get('priority')).fetch(20)
120
+ statement[:model_name].to_s + '.gql("WHERE ' + statement[:condition][:attribute].to_s + " " + statement[:condition][:operator].to_s + '"' + ' + ' +
121
+ apply_transforms(statement[:condition][:value], 0) + ").fetch(20)"
122
+ when "find_by_id"
123
+ item_id = apply_transforms(statement[:item_id], 0)
124
+ (statement[:model_name].to_s + ".get_by_id(int(" + item_id + "))")
125
+ when "update"
126
+ tabs + (statement[:model_name].to_s + ".put()")
127
+ when "delete"
128
+ tabs + (statement[:model_name].to_s + ".delete()")
129
+ end
130
+ end
131
+
132
+ def write_function_transform(statement, num_tabs)
133
+ tabs = ""
134
+ num_tabs.times { tabs += "\t" }
135
+
136
+ write_data_template = ERB.new(Shift::Generator::PythonTemplates::WRITE_DATA_TEMPLATE)
137
+
138
+ write_data = apply_transforms(statement[:write_statement][:write_statement_param], 0)
139
+
140
+ tabs + write_data_template.result(binding) + "\n" +
141
+ tabs + Shift::Generator::PythonTemplates::WRITE_RESPONSE_STATEMENT
142
+ end
143
+
144
+ def write_file_function_transform(statement, num_tabs)
145
+ tabs = ""
146
+ num_tabs.times { tabs += "\t" }
147
+
148
+ write_file_template = ERB.new(PythonTemplates::WRITE_FILE_TEMPLATE)
149
+
150
+ if(statement[:write_file_statement].is_a?(Array))
151
+ file_name = apply_transforms(statement[:write_file_statement][0][:file_name], 0)
152
+ template_values = apply_transforms(statement[:write_file_statement][1][:template_values], 0)
153
+ else
154
+ file_name = apply_transforms(statement[:write_file_statement][:file_name], 0)
155
+ end
156
+
157
+ tabs + write_file_template.result(binding) + "\n" +
158
+ tabs + Shift::Generator::PythonTemplates::WRITE_RESPONSE_STATEMENT
159
+ end
160
+
161
+ def read_statement_transform(statement, num_tabs)
162
+ read_statement_template = ERB.new(Shift::Generator::PythonTemplates::REQUEST_GET_VAR_TEMPLATE)
163
+ var_name = apply_transforms(statement[:read_statement][:read_statement_param], 0)
164
+ read_statement_template.result(binding)
165
+ end
166
+
167
+ def redirect_statement_transform(statement, num_tabs)
168
+ tabs = ""
169
+ num_tabs.times { tabs += "\t" }
170
+
171
+ redirect_statement_template = ERB.new(Shift::Generator::PythonTemplates::REDIRECT_STATEMENT_TEMPLATE)
172
+ url = apply_transforms(statement[:redirect_statement][:redirect_statement_param], 0)
173
+ "\n" + tabs + redirect_statement_template.result(binding)
174
+ end
175
+
176
+ def value_transform(statement, num_tabs)
177
+ tabs = ""
178
+ num_tabs.times { tabs += "\t" }
179
+
180
+ key = statement.keys[0]
181
+
182
+ statement[key].to_s
183
+ end
184
+
185
+ def control_statement_transform(statement, num_tabs)
186
+ tabs = ""
187
+ num_tabs.times { tabs += "\t" }
188
+
189
+ key = statement.keys[0]
190
+
191
+ result = ""
192
+
193
+ case key
194
+ when :if_statement
195
+ result = tabs + "if " + apply_transforms(statement[:if_statement][:condition], 0) + ":"
196
+ when :while_statement
197
+ result = tabs + "while " + apply_transforms(statement[:while_statement][:condition], 0) + ":"
198
+ end
199
+
200
+ result
201
+ end
202
+
203
+ def concatenated_string_expression_transform(statement, num_tabs)
204
+ statement = statement.map do | token |
205
+ apply_transforms(token, 0)
206
+ end
207
+
208
+ statement.join(" + ")
209
+ end
210
+
211
+ def integer_casted_expression_transform(statement, num_tabs)
212
+ statement.delete(:int)
213
+ "int(" + apply_transforms(statement, 0) + ")"
214
+ end
215
+
216
+ def apply_transforms(statement, num_tabs)
217
+ tabs = ""
218
+ num_tabs.times { tabs += "\t" }
219
+
220
+ if(statement.is_a?(Hash))
221
+ key = statement.keys[0]
222
+ case key
223
+ when :assignment_statement
224
+ expression_transform(statement, num_tabs) + "\n"
225
+ when :write_statement
226
+ write_function_transform(statement, num_tabs) + "\n"
227
+ when :write_file_statement
228
+ write_file_function_transform(statement, num_tabs) + "\n"
229
+ when :read_statement
230
+ read_statement_transform(statement, num_tabs)
231
+ when :redirect_statement
232
+ redirect_statement_transform(statement, num_tabs)
233
+ when :arithmetic_expression
234
+ value_transform(statement, num_tabs)
235
+ when :boolean_expression
236
+ value_transform(statement, num_tabs)
237
+ when :if_statement
238
+ control_statement_transform(statement, num_tabs) + "\n"
239
+ when :else_statement
240
+ tabs + value_transform(statement, num_tabs) + ":\n"
241
+ when :for_statement
242
+ tabs + value_transform(statement, num_tabs) + ":\n"
243
+ when :while_statement
244
+ control_statement_transform(statement, num_tabs) + "\n"
245
+ when :query
246
+ query_transform(statement, num_tabs)
247
+ when :int
248
+ integer_casted_expression_transform(statement, num_tabs)
249
+ else
250
+ token_transform(statement, num_tabs)
251
+ end
252
+ else
253
+ if statement.is_a?(Array)
254
+ concatenated_string_expression_transform(statement, num_tabs)
255
+ else
256
+ statement.to_s
257
+ end
258
+ end
259
+ end
260
+
261
+ def url_transform(url)
262
+ if(url.is_a?(Array))
263
+ result_url = ""
264
+ result_vars = ""
265
+ url.each do | token |
266
+ case token.keys[0]
267
+ when :url_token
268
+ result_url += "/" + token[:url_token].to_s
269
+ when :url_variable
270
+ result_url += "/(\\w+)"
271
+ result_vars += ", " + token[:url_variable].to_s
272
+ end
273
+ end
274
+ result = {
275
+ :url => result_url,
276
+ :vars => result_vars
277
+ }
278
+ else
279
+ result = {
280
+ :url => url.to_s,
281
+ :vars => ""
282
+ }
283
+ end
284
+ end
285
+
286
+ def write_data()
287
+ if (@builder.models.length != 0)
288
+ @has_models = true
289
+ end
290
+
291
+ result = get_import_statements + get_model_data
292
+
293
+ last_url = ""
294
+
295
+ base_handler_name = "Handler"
296
+
297
+ i = 0
298
+
299
+ routes = ""
300
+
301
+ @builder.handlers.each do | handlers |
302
+ url_info = url_transform(handlers.url)
303
+ url = url_info[:url]
304
+
305
+ @defined_hashes = []
306
+
307
+ if(url != last_url)
308
+ handler_name = base_handler_name + i.to_s
309
+ result += "\n\nclass " + handler_name + "(webapp2.RequestHandler):\n"
310
+ i += 1
311
+
312
+ routes += "('" + url + "'," + handler_name + "),"
313
+ end
314
+
315
+ result += "\tdef " + handlers.method + "(self" + url_info[:vars] + "):\n"
316
+
317
+ handlers.handler.each do | statement |
318
+ result += apply_transforms(statement[:statement], statement[:num_tabs])
319
+ end
320
+ last_url = url
321
+ end
322
+
323
+ app_template = ERB.new(Shift::Generator::PythonTemplates::WEBAPP2_APPLICATION_TEMPLATE)
324
+ result += "\n\n\n" + app_template.result(binding)
325
+
326
+ result
327
+ end
328
+ end
329
+ end
330
+ end
@@ -0,0 +1,44 @@
1
+ module Shift
2
+ module Generator
3
+ module PythonTemplates
4
+
5
+ IMPORT_WEBAPP_STATEMENT = "import webapp2"
6
+
7
+ IMPORT_PYSTACHE_STATEMENT = "import os\nimport pystache\nmu_root = 'views/'"
8
+
9
+ IMPORT_DATABASE_STATEMENT = "from google.appengine.ext import db"
10
+
11
+ UTILITY_FUNCTIONS = "
12
+ def read_file(file_name):
13
+ f = open(mu_root + file_name)
14
+ template = f.read()
15
+ f.close()
16
+ return template
17
+
18
+ def read_template(file_name, template_values = None):
19
+ template = read_file(file_name)
20
+ if (template_values == None):
21
+ return template
22
+ else:
23
+ return pystache.render(template, template_values)"
24
+
25
+ MODEL_NAME_TEMPLATE = "class <%= model_name %>(db.Model):"
26
+
27
+ DB_STRING_PROPERTY = "db.StringProperty()"
28
+
29
+ DB_INTEGER_PROPERTY = "db.IntegerProperty()"
30
+
31
+ REQUEST_GET_VAR_TEMPLATE = "self.request.get(<%= var_name %>)"
32
+
33
+ WRITE_FILE_TEMPLATE = "response_result = read_template(<%= file_name %><% if template_values %>, <%= template_values %><% end %>)"
34
+
35
+ WRITE_DATA_TEMPLATE = "response_result = <%= write_data %>"
36
+
37
+ WRITE_RESPONSE_STATEMENT = "self.response.out.write(response_result)"
38
+
39
+ REDIRECT_STATEMENT_TEMPLATE = "self.redirect(<%= url %>)"
40
+
41
+ WEBAPP2_APPLICATION_TEMPLATE = "app = webapp2.WSGIApplication([<%= routes %>], debug=True)"
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,334 @@
1
+ require 'erb'
2
+
3
+ require_relative '../builder'
4
+ require_relative './ruby_templates'
5
+
6
+ module Shift
7
+ module Generator
8
+ class RubyGenerator
9
+ attr_accessor :builder, :has_models, :defined_hashes
10
+
11
+ def initialize()
12
+ @blocks = []
13
+ @defined_hashes = []
14
+ @has_models = false
15
+ @builder = Shift::ShiftBuilder.new
16
+ end
17
+
18
+ def get_data(builder)
19
+ @builder = builder
20
+ end
21
+
22
+ def get_data_from_file(file_name)
23
+ @builder.get_data_from_file file_name
24
+ end
25
+
26
+ def get_import_statements()
27
+ Shift::Generator::RubyTemplates::IMPORT_SINATRA_STATEMENT + "\n" +
28
+ Shift::Generator::RubyTemplates::IMPORT_MUSTACHE_STATEMENT + "\n" +
29
+ (@has_models ? (Shift::Generator::RubyTemplates::IMPORT_DATAMAPPER_STATEMENT + "\n\n") : "")
30
+ end
31
+
32
+ def get_model_data()
33
+ result = ""
34
+
35
+ model_name_template = ERB.new(Shift::Generator::RubyTemplates::MODEL_NAME_TEMPLATE)
36
+
37
+
38
+ @builder.models.each do | model |
39
+ model_name = model.name
40
+ result += model_name_template.result(binding) + "\n"
41
+ result += ("\t" + Shift::Generator::RubyTemplates::DATAMAPPER_INCLUDE_STATEMENT + "\n\n" )
42
+ result += ("\t" + "property :id, Serial\n")
43
+
44
+ model.attributes.each do | attribute |
45
+ if (attribute[:type] == "string")
46
+ result += ("\t" + "property :" + attribute[:name] + ", " + RubyTemplates::DB_STRING_PROPERTY + "\n")
47
+ elsif (attribute[:type] == "integer")
48
+ result += ("\t" + "property :" + attribute[:name] + ", " + RubyTemplates::DB_INTEGER_PROPERTY + "\n")
49
+ end
50
+ end
51
+ result += "end\n"
52
+ end
53
+
54
+ result
55
+ end
56
+
57
+ def get_utility_functions()
58
+ Shift::Generator::RubyTemplates::UTILITY_FUNCTIONS + "\n\n" + (@has_models ? (Shift::Generator::RubyTemplates::CONFIGURE_BLOCK + "\n\n") : "")
59
+ end
60
+
61
+ def token_transform(statement, num_tabs)
62
+ tabs = ""
63
+ num_tabs.times { tabs += "\t" }
64
+ key = statement.keys[0]
65
+ case key
66
+ when :identifier
67
+ statement[:identifier].to_s
68
+ when :object_value
69
+ if (statement[:object_value].to_s.split(".")[1] == "save")
70
+ tabs + statement[:object_value].to_s + "\n"
71
+ else
72
+ tabs + statement[:object_value].to_s
73
+ end
74
+ when :hash_value
75
+ statement[:hash_value].to_s
76
+ when :string
77
+ statement[:string].to_s
78
+ else
79
+ statement.to_s
80
+ end
81
+ end
82
+
83
+ def expression_transform(statement, num_tabs)
84
+ tabs = ""
85
+ num_tabs.times { tabs += "\t" }
86
+ key = statement.keys[0]
87
+ case key
88
+ when :assignment_statement
89
+ extra = ""
90
+ if(statement[:assignment_statement][:left].keys[0] == :hash_value)
91
+ val = statement[:assignment_statement][:left][:hash_value].to_s
92
+ hash_var = val[0..(val.index('[') - 1)]
93
+
94
+ if !@defined_hashes.include?(hash_var)
95
+ @defined_hashes.push hash_var
96
+ extra += tabs + "(" + hash_var + " ||= {})\n"
97
+ end
98
+ end
99
+
100
+ left = apply_transforms(statement[:assignment_statement][:left], 0)
101
+ right = apply_transforms(statement[:assignment_statement][:right], 0)
102
+
103
+ extra + tabs + left.to_s + " = " + right.to_s
104
+ end
105
+ end
106
+
107
+ def query_transform(statement, num_tabs)
108
+ tabs = ""
109
+ num_tabs.times { tabs += "\t" }
110
+ statement = statement[:query]
111
+ case statement[:operation].to_s
112
+ when "all"
113
+ (statement[:model_name].to_s + ".all")
114
+ when "new"
115
+ (statement[:model_name].to_s + ".new")
116
+ when "find"
117
+ attribute = statement[:condition][:attribute].to_s
118
+ value = apply_transforms(statement[:condition][:value], 0)
119
+ operator = ""
120
+ case statement[:condition][:operator].to_s.gsub!(" ", "")
121
+ when "<="
122
+ operator = ".lte"
123
+ when ">="
124
+ operator = ".gte"
125
+ when "<"
126
+ operator = ".lt"
127
+ when ">"
128
+ operator = ".gt"
129
+ when "!="
130
+ operator = ".not"
131
+ end
132
+ (statement[:model_name].to_s + ".all(:" + attribute + operator + " => " + value + ")")
133
+ when "find_by_id"
134
+ id = apply_transforms(statement[:item_id], 0)
135
+ (statement[:model_name].to_s + ".get(params[:" + id + "])" )
136
+ when "update"
137
+ tabs + (statement[:model_name].to_s + ".save\n")
138
+ when "delete"
139
+ tabs + (statement[:model_name].to_s + ".destroy\n")
140
+ end
141
+ end
142
+
143
+ def write_function_transform(statement, num_tabs)
144
+ tabs = ""
145
+ num_tabs.times { tabs += "\t" }
146
+
147
+ write_data_template = ERB.new(Shift::Generator::RubyTemplates::WRITE_DATA_TEMPLATE)
148
+
149
+ write_data = apply_transforms(statement[:write_statement][:write_statement_param], 0)
150
+ tabs + write_data_template.result(binding) + "\n" +
151
+ tabs + Shift::Generator::RubyTemplates::WRITE_RESPONSE_TEMPLATE
152
+ end
153
+
154
+ def write_file_function_transform(statement, num_tabs)
155
+ tabs = ""
156
+ num_tabs.times { tabs += "\t" }
157
+
158
+ write_file_template = ERB.new(Shift::Generator::RubyTemplates::WRITE_FILE_TEMPLATE)
159
+
160
+ if(statement[:write_file_statement].is_a?(Array))
161
+ file_name = apply_transforms(statement[:write_file_statement][0][:file_name], 0)
162
+ template_values = apply_transforms(statement[:write_file_statement][1][:template_values], 0)
163
+ else
164
+ file_name = apply_transforms(statement[:write_file_statement][:file_name], 0)
165
+ end
166
+
167
+ tabs + write_file_template.result(binding)
168
+ end
169
+
170
+ def read_statement_transform(statement, num_tabs)
171
+ read_param = apply_transforms(statement[:read_statement][:read_statement_param], 0)
172
+ if ((read_param[0] == "'") || (read_param[0] == '"'))
173
+ read_param = read_param[1..(read_param.length - 2)]
174
+ end
175
+ read_statement = "params[:" + read_param + "]"
176
+ end
177
+
178
+ def redirect_statement_transform(statement, num_tabs)
179
+ tabs = ""
180
+ num_tabs.times { tabs += "\t" }
181
+ redirect_param = apply_transforms(statement[:redirect_statement][:redirect_statement_param], 0)
182
+ redirect_statement = tabs + "redirect(" + redirect_param + ")\n"
183
+ end
184
+
185
+ def value_transform(statement, num_tabs)
186
+ tabs = ""
187
+ num_tabs.times { tabs += "\t" }
188
+ key = statement.keys[0]
189
+ statement[key].to_s
190
+ end
191
+
192
+ def control_statement_transform(statement, num_tabs)
193
+ tabs = ""
194
+ num_tabs.times { tabs += "\t" }
195
+
196
+ key = statement.keys[0]
197
+
198
+ result = ""
199
+
200
+ @blocks.push (num_tabs)
201
+
202
+ case key
203
+ when :if_statement
204
+ result = tabs + "if " + apply_transforms(statement[:if_statement][:condition], 0)
205
+ when :while_statement
206
+ result = tabs + "while " + apply_transforms(statement[:while_statement][:condition], 0)
207
+ end
208
+
209
+ result
210
+ end
211
+
212
+ def url_transform(url)
213
+ if(url.is_a?(Array))
214
+ result_url = ""
215
+
216
+ url.each do | token |
217
+ case token.keys[0]
218
+ when :url_token
219
+ result_url += "/" + token[:url_token].to_s
220
+ when :url_variable
221
+ result_url += "/:" + token[:url_variable].to_s
222
+ end
223
+ end
224
+ result_url
225
+ else
226
+ url.to_s
227
+ end
228
+ end
229
+
230
+ def concatenated_string_expression_transform(statement, num_tabs)
231
+ statement = statement.map do | token |
232
+ apply_transforms(token, 0)
233
+ end
234
+
235
+ statement.join(" + ")
236
+ end
237
+
238
+ def integer_casted_expression_transform(statement, num_tabs)
239
+ statement.delete(:int)
240
+ "(" + apply_transforms(statement, 0) + ").to_i"
241
+ end
242
+
243
+ def apply_transforms(statement, num_tabs)
244
+ tabs = ""
245
+ if num_tabs > 0
246
+ num_tabs = num_tabs - 1
247
+ end
248
+ num_tabs.times { tabs += "\t" }
249
+ result = ""
250
+
251
+ if(@blocks.length > 0)
252
+ if(@blocks[@blocks.length - 1] == num_tabs)
253
+ if (statement.keys[0] != :else_statement)
254
+ t = ""
255
+ @blocks.pop.times { t += "\t" }
256
+ result += t + "end\n"
257
+ end
258
+ end
259
+ end
260
+
261
+ if(statement.is_a?(Hash))
262
+ key = statement.keys[0]
263
+ case key
264
+ when :assignment_statement
265
+ result += expression_transform(statement, num_tabs) + "\n"
266
+ when :query
267
+ result += query_transform(statement, num_tabs)
268
+ when :write_statement
269
+ result += write_function_transform(statement, num_tabs) + "\n"
270
+ when :write_file_statement
271
+ result += write_file_function_transform(statement, num_tabs) + "\n"
272
+ when :read_statement
273
+ result += read_statement_transform(statement, num_tabs)
274
+ when :redirect_statement
275
+ result += redirect_statement_transform(statement, num_tabs)
276
+ when :arithmetic_expression
277
+ result += value_transform(statement, num_tabs)
278
+ when :boolean_expression
279
+ result += value_transform(statement, num_tabs)
280
+ when :if_statement
281
+ result += control_statement_transform(statement, num_tabs) + "\n"
282
+ when :else_statement
283
+ result += tabs + value_transform(statement, num_tabs) + "\n"
284
+ when :for_statement
285
+ @blocks.push(num_tabs)
286
+ result += tabs + value_transform(statement, num_tabs) + "\n"
287
+ when :while_statement
288
+ result += control_statement_transform(statement, num_tabs) + "\n"
289
+ when :int
290
+ integer_casted_expression_transform(statement, num_tabs)
291
+ else
292
+ result += token_transform(statement, num_tabs)
293
+ end
294
+ else
295
+ if statement.is_a?(Array)
296
+ result += concatenated_string_expression_transform(statement, num_tabs)
297
+ else
298
+ result += statement.to_s
299
+ end
300
+ end
301
+ end
302
+
303
+
304
+
305
+ def write_data()
306
+ if (@builder.models.length != 0)
307
+ @has_models = true
308
+ end
309
+
310
+ result = get_import_statements + get_model_data + get_utility_functions
311
+
312
+ @builder.handlers.each do | handlers |
313
+ defined_hashes = []
314
+
315
+ result += handlers.method + " '" + url_transform(handlers.url) + "' do\n"
316
+
317
+ handlers.handler.each do | statement |
318
+ result += apply_transforms(statement[:statement], statement[:num_tabs])
319
+ end
320
+
321
+ @blocks.each do | t |
322
+ tabs = ""
323
+ t.times { tabs += "\t" }
324
+ result += tabs + "end" + "\n"
325
+ end
326
+ @blocks = []
327
+ result += "end\n\n"
328
+
329
+ end
330
+ result
331
+ end
332
+ end
333
+ end
334
+ end