expressir 0.2.15 → 0.2.21

Sign up to get free protection for your applications and to get access to all the features.
Files changed (62) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/rake.yml +5 -0
  3. data/.github/workflows/release.yml +16 -4
  4. data/README.adoc +3 -3
  5. data/exe/format +66 -12
  6. data/ext/express-parser/extconf.rb +2 -0
  7. data/lib/expressir/express_exp/cache.rb +48 -0
  8. data/lib/expressir/express_exp/formatter.rb +185 -135
  9. data/lib/expressir/express_exp/hyperlink_formatter.rb +1 -3
  10. data/lib/expressir/express_exp/parser.rb +33 -29
  11. data/lib/expressir/express_exp/schema_head_formatter.rb +2 -7
  12. data/lib/expressir/express_exp/visitor.rb +11 -30
  13. data/lib/expressir/model.rb +2 -0
  14. data/lib/expressir/model/cache.rb +13 -0
  15. data/lib/expressir/model/entity.rb +6 -6
  16. data/lib/expressir/model/expressions/query_expression.rb +3 -3
  17. data/lib/expressir/model/function.rb +15 -11
  18. data/lib/expressir/model/informal_proposition.rb +4 -1
  19. data/lib/expressir/model/interfaced_item.rb +4 -1
  20. data/lib/expressir/model/model_element.rb +43 -13
  21. data/lib/expressir/model/procedure.rb +15 -11
  22. data/lib/expressir/model/repository.rb +3 -3
  23. data/lib/expressir/model/rule.rb +16 -12
  24. data/lib/expressir/model/schema.rb +52 -48
  25. data/lib/expressir/model/statements/alias.rb +3 -3
  26. data/lib/expressir/model/statements/repeat.rb +3 -3
  27. data/lib/expressir/model/subtype_constraint.rb +1 -6
  28. data/lib/expressir/model/type.rb +9 -5
  29. data/lib/expressir/version.rb +1 -1
  30. data/original/examples/syntax/{hyperlink.exp → multiple.exp} +8 -8
  31. data/original/examples/syntax/multiple.yaml +184 -0
  32. data/original/examples/syntax/multiple_formatted.exp +71 -0
  33. data/original/examples/syntax/multiple_hyperlink_formatted.exp +71 -0
  34. data/original/examples/syntax/multiple_schema_head_hyperlink_formatted.exp +13 -0
  35. data/original/examples/syntax/remark.exp +41 -41
  36. data/original/examples/syntax/remark.yaml +446 -0
  37. data/original/examples/syntax/remark_formatted.exp +62 -50
  38. data/original/examples/syntax/{simple.exp → single.exp} +1 -1
  39. data/original/examples/syntax/single.yaml +9 -0
  40. data/original/examples/syntax/single_formatted.exp +6 -0
  41. data/original/examples/syntax/single_formatted.yaml +19 -0
  42. data/original/examples/syntax/syntax.exp +29 -19
  43. data/original/examples/syntax/syntax.yaml +3439 -0
  44. data/original/examples/syntax/syntax_formatted.exp +271 -131
  45. data/original/examples/syntax/syntax_schema_head_formatted.exp +18 -0
  46. data/spec/expressir/express_exp/cache_spec.rb +64 -0
  47. data/spec/expressir/express_exp/formatter_spec.rb +111 -0
  48. data/spec/expressir/express_exp/parser_spec.rb +98 -0
  49. data/spec/expressir/model/{model_element/find_spec.rb → model_element_spec.rb} +96 -10
  50. metadata +24 -21
  51. data/original/examples/syntax/hyperlink_formatted.exp +0 -51
  52. data/original/examples/syntax/source.exp +0 -16
  53. data/spec/expressir/express_exp/formatter/remark_spec.rb +0 -28
  54. data/spec/expressir/express_exp/formatter/syntax_spec.rb +0 -28
  55. data/spec/expressir/express_exp/hyperlink_formatter_spec.rb +0 -24
  56. data/spec/expressir/express_exp/parser/head_source_spec.rb +0 -38
  57. data/spec/expressir/express_exp/parser/multiple_spec.rb +0 -37
  58. data/spec/expressir/express_exp/parser/remark_spec.rb +0 -411
  59. data/spec/expressir/express_exp/parser/source_spec.rb +0 -29
  60. data/spec/expressir/express_exp/parser/syntax_spec.rb +0 -3086
  61. data/spec/expressir/express_exp/schema_head_formatter_spec.rb +0 -36
  62. data/spec/expressir/model/model_element/hash_spec.rb +0 -66
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 01b9d48b15ce85744e4c19cbe55752d22744388f738367cd486f2afa2ac10835
4
- data.tar.gz: 44fbef691d15a6c0feee280e86aabda10401f6b5d344fc3596cbc7315e816c76
3
+ metadata.gz: 58e1bbf9a216e77cfda6594ad7040dba57086b8776c05b884bfcb25174967237
4
+ data.tar.gz: cf12bb3deef6b060f0d634e894a6bbcf10734cdcb8b3329d79ccb1d569d95a62
5
5
  SHA512:
6
- metadata.gz: 8049d49a9c11790c0fb45a3d37e5d8574b18aaf7d3de92b9dd870668bf6131005ff2ce1630d391962dbd6c936ea80d9d6cf95cdca0f6926358640b1ca46e9312
7
- data.tar.gz: d90065bbfda420df3dce91ad2b016e14a145d751f70914823f0d5db8b86ff212c0c4ebce20f77d2a6fa85a343d91e172c3094a66a851db6af64d95af9495aa84
6
+ metadata.gz: eb15652a0cca4901425feea15981e60ce302b55471fcd8b95b2f98df1174f87e9a2eba7c233f97d3678349b5187f2785a7f23cf3bc0845a373bda668c66791c8
7
+ data.tar.gz: 1a9b788abfc17361421943a7b10c83fa47b0d6653e57b6ffa645175d33354b387de2506b70f271a781d97000c037b122ecab4b383d310293643335e64868bafc
@@ -43,3 +43,8 @@ jobs:
43
43
  - run: bundle exec rake compile
44
44
 
45
45
  - run: bundle exec rake
46
+
47
+ - uses: actions/upload-artifact@v2
48
+ with:
49
+ name: express_parser-${{ matrix.os }}-${{ matrix.ruby }}
50
+ path: lib/expressir/express_exp/express_parser.so
@@ -1,9 +1,15 @@
1
1
  name: release
2
2
 
3
3
  on:
4
+ workflow_dispatch:
5
+ inputs:
6
+ next_version:
7
+ description: |
8
+ Next release version. Possible values: x.y.z, major, minor, patch or pre|rc|etc
9
+ required: true
10
+ default: 'patch'
4
11
  push:
5
12
  tags: [ v* ]
6
- workflow_dispatch:
7
13
 
8
14
  jobs:
9
15
  pack:
@@ -20,9 +26,15 @@ jobs:
20
26
  - uses: ruby/setup-ruby@v1
21
27
  with:
22
28
  ruby-version: '2.6'
29
+ bundler-cache: true
23
30
 
24
- - run: bundle install --jobs 4 --retry 3
31
+ - if: ${{ github.event_name == 'workflow_dispatch' }}
32
+ run: |
33
+ git config user.name github-actions
34
+ git config user.email github-actions@github.com
35
+ gem bump --version ${{ github.event.inputs.next_version }} --tag --push
25
36
 
37
+ # build gem WITHOUT pre-built native extension
26
38
  - run: gem build expressir.gemspec
27
39
 
28
40
  - if: matrix.host == 'linux'
@@ -31,6 +43,7 @@ jobs:
31
43
  name: pkg-ruby
32
44
  path: expressir-*.gem
33
45
 
46
+ # build gem WITH pre-built native extension
34
47
  - run: bundle exec rake gem:${{ matrix.host }}
35
48
 
36
49
  - uses: actions/upload-artifact@v2
@@ -38,8 +51,7 @@ jobs:
38
51
  name: pkg-${{ matrix.host }}
39
52
  path: pkg/*.gem
40
53
 
41
-
42
- release:
54
+ publish:
43
55
  runs-on: ubuntu-18.04
44
56
  needs: pack
45
57
  steps:
data/README.adoc CHANGED
@@ -1,8 +1,8 @@
1
1
  = Expressir: EXPRESS in Ruby
2
2
 
3
- image:https://github.com/lutaml/expressir/workflows/ubuntu/badge.svg[ubuntu]
4
- image:https://github.com/lutaml/expressir/workflows/macos/badge.svg[macos]
5
- image:https://github.com/lutaml/expressir/workflows/windows/badge.svg[windows]
3
+ image:https://img.shields.io/gem/v/expressir.svg["Gem Version", link="https://rubygems.org/gems/expressir"]
4
+ // image:https://codeclimate.com/github/lutaml/expressir/badges/gpa.svg["Code Climate", link="https://codeclimate.com/github/lutaml/expressir"]
5
+ image:https://github.com/lutaml/expressir/workflows/rake/badge.svg["Build Status", link="https://github.com/lutaml/expressir/actions?workflow=rake"]
6
6
 
7
7
  == Purpose
8
8
 
data/exe/format CHANGED
@@ -1,27 +1,81 @@
1
1
  #!/usr/bin/env ruby
2
2
 
3
+ require "yaml"
4
+ require "tempfile"
3
5
  require "expressir/express_exp/parser"
6
+ require "expressir/express_exp/formatter"
7
+ require "expressir/express_exp/schema_head_formatter"
4
8
  require "expressir/express_exp/hyperlink_formatter"
9
+ require "expressir/express_exp/cache"
5
10
 
6
- input_files = [
11
+ exp_files = [
7
12
  # basic test
8
13
  # '../iso-10303-stepmod/data/resources/action_schema/action_schema_annotated.exp',
9
14
  # '../iso-10303-stepmod/data/resources/basic_attribute_schema/basic_attribute_schema_annotated.exp',
10
15
  # '../iso-10303-stepmod/data/resources/support_resource_schema/support_resource_schema_annotated.exp',
11
16
  # cyclic reference test
17
+ # '../iso-10303-stepmod/data/modules/analysis/mim_annotated.exp',
18
+ # '../iso-10303-stepmod/data/modules/analysis_product_relationships/mim_annotated.exp',
19
+ # cyclic reference test 2
12
20
  # '../iso-10303-stepmod/data/resources/product_property_definition_schema/product_property_definition_schema_annotated.exp',
13
- # '../iso-10303-stepmod/data/resources/product_property_representation_schema/product_property_representation_schema_annotated.exp'
14
- # renamed reference test
15
- '../iso-10303-stepmod/ballots/ballots/ap210_wg12/express/resources/mathematical_functions_schema.exp',
16
- '../iso-10303-stepmod/data/resources/iso13584_expressions_schema/iso13584_expressions_schema.exp',
17
- # all valid iso-10303-stepmod files (takes 10 min)
21
+ # '../iso-10303-stepmod/data/resources/product_property_representation_schema/product_property_representation_schema_annotated.exp',
22
+ # renamed reference test (36s)
23
+ # '../iso-10303-stepmod/ballots/ballots/ap210_wg12/express/resources/mathematical_functions_schema.exp',
24
+ # '../iso-10303-stepmod/data/resources/iso13584_expressions_schema/iso13584_expressions_schema.exp',
25
+ # annotated-express test (12s)
26
+ # see https://github.com/metanorma/annotated-express/blob/master/data/documents/resources/fundamentals_of_product_description_and_support/sections/04-schemas.adoc
27
+ '../iso-10303-stepmod/data/resources/action_schema/action_schema_annotated.exp',
28
+ '../iso-10303-stepmod/data/resources/application_context_schema/application_context_schema_annotated.exp',
29
+ '../iso-10303-stepmod/data/resources/approval_schema/approval_schema_annotated.exp',
30
+ '../iso-10303-stepmod/data/resources/basic_attribute_schema/basic_attribute_schema_annotated.exp',
31
+ '../iso-10303-stepmod/data/resources/certification_schema/certification_schema_annotated.exp',
32
+ '../iso-10303-stepmod/data/resources/contract_schema/contract_schema_annotated.exp',
33
+ '../iso-10303-stepmod/data/resources/date_time_schema/date_time_schema_annotated.exp',
34
+ '../iso-10303-stepmod/data/resources/document_schema/document_schema.exp',
35
+ '../iso-10303-stepmod/data/resources/effectivity_schema/effectivity_schema_annotated.exp',
36
+ '../iso-10303-stepmod/data/resources/experience_schema/experience_schema_annotated.exp',
37
+ '../iso-10303-stepmod/data/resources/external_reference_schema/external_reference_schema_annotated.exp',
38
+ '../iso-10303-stepmod/data/resources/group_schema/group_schema_annotated.exp',
39
+ '../iso-10303-stepmod/data/resources/language_schema/language_schema_annotated.exp',
40
+ '../iso-10303-stepmod/data/resources/location_schema/location_schema_annotated.exp',
41
+ '../iso-10303-stepmod/data/resources/management_resources_schema/management_resources_schema_annotated.exp',
42
+ '../iso-10303-stepmod/data/resources/measure_schema/measure_schema_annotated.exp',
43
+ '../iso-10303-stepmod/data/resources/person_organization_schema/person_organization_schema_annotated.exp',
44
+ '../iso-10303-stepmod/data/resources/process_property_schema/process_property_schema_annotated.exp',
45
+ '../iso-10303-stepmod/data/resources/product_definition_schema/product_definition_schema_annotated.exp',
46
+ '../iso-10303-stepmod/data/resources/product_property_definition_schema/product_property_definition_schema_annotated.exp',
47
+ '../iso-10303-stepmod/data/resources/product_property_representation_schema/product_property_representation_schema_annotated.exp',
48
+ '../iso-10303-stepmod/data/resources/qualifications_schema/qualifications_schema_annotated.exp',
49
+ '../iso-10303-stepmod/data/resources/security_classification_schema/security_classification_schema_annotated.exp',
50
+ '../iso-10303-stepmod/data/resources/support_resource_schema/support_resource_schema_annotated.exp',
51
+ # full test (6m18s + 8s = 6m26s)
18
52
  # *`bundle exec ../stepmod-utils/exe/stepmod-find-express-files ../iso-10303-stepmod`.strip.split("\n").map{|file| File.exists?(file.sub(/\.exp$/, '_annotated.exp')) ? file.sub(/\.exp$/, '_annotated.exp') : file}
19
53
  ]
20
54
 
21
- repo = Expressir::ExpressExp::Parser.from_files(input_files)
22
- # schema = repo.schemas.find{|x| x.id == 'action_schema'}
23
- # schema = repo.schemas.find{|x| x.id == 'product_property_definition_schema'}
24
- schema = repo.schemas.find{|x| x.id == 'mathematical_functions_schema'}
25
- result = Expressir::ExpressExp::HyperlinkFormatter.format(schema)
55
+ start = Time.now
56
+ repository = Expressir::ExpressExp::Parser.from_files(exp_files)
57
+ puts "Parser.from_files time: #{(Time.now - start).round(2)}s"
26
58
 
27
- puts result
59
+ temp_file = Tempfile.new
60
+ begin
61
+ start = Time.now
62
+ Expressir::ExpressExp::Cache.to_file(temp_file, repository)
63
+ puts "Cache.to_file time: #{(Time.now - start).round(2)}s"
64
+
65
+ start = Time.now
66
+ repository = Expressir::ExpressExp::Cache.from_file(temp_file)
67
+ puts "Cache.from_file time: #{(Time.now - start).round(2)}s"
68
+ ensure
69
+ temp_file.close
70
+ temp_file.unlink
71
+ end
72
+
73
+ start = Time.now
74
+ formatter = Class.new(Expressir::ExpressExp::Formatter) do
75
+ include Expressir::ExpressExp::SchemaHeadFormatter
76
+ include Expressir::ExpressExp::HyperlinkFormatter
77
+ end
78
+ result = repository.to_hash(formatter: formatter, skip_empty: true)
79
+ puts "Repository.to_hash time: #{(Time.now - start).round(2)}s"
80
+
81
+ # puts YAML.dump(result)
@@ -37,6 +37,8 @@ if cross_build
37
37
  if RbConfig::CONFIG['target_os'] =~ /mingw32|mswin/
38
38
  # workaround for 'w64-mingw32-as: express_parser.o: too many sections'
39
39
  $CXXFLAGS << " -O3 -Wa,-mbig-obj"
40
+ # workaround for LoadError: 127: The specified procedure could not be found.
41
+ $DLDFLAGS << " -static -static-libgcc -static-libstdc++"
40
42
  end
41
43
  else
42
44
  require 'mkmf-rice'
@@ -0,0 +1,48 @@
1
+ require 'yaml'
2
+ require 'zlib'
3
+ require 'expressir/model'
4
+
5
+ module Expressir
6
+ module ExpressExp
7
+ class Cache
8
+ def self.to_file(file, content, options = {})
9
+ root_path = options[:root_path]
10
+ test_overwrite_version = options[:test_overwrite_version] # don't use, only for tests
11
+
12
+ version = test_overwrite_version || VERSION
13
+
14
+ cache = Model::Cache.new({
15
+ version: version,
16
+ content: content
17
+ })
18
+
19
+ hash = cache.to_hash(root_path: root_path, skip_empty: true)
20
+ yaml = YAML.dump(hash)
21
+ yaml_compressed = Zlib::Deflate.deflate(yaml)
22
+
23
+ File.binwrite(file, yaml_compressed)
24
+ end
25
+
26
+ def self.from_file(file, options = {})
27
+ root_path = options[:root_path]
28
+ test_overwrite_version = options[:test_overwrite_version] # don't use, only for tests
29
+
30
+ version = test_overwrite_version || VERSION
31
+
32
+ yaml_compressed = File.binread(file)
33
+ yaml = Zlib::Inflate.inflate(yaml_compressed)
34
+ hash = YAML.load(yaml)
35
+ cache = Model::ModelElement.from_hash(hash, root_path: root_path)
36
+
37
+ if cache.version != version
38
+ raise CacheLoadError.new("Cache version mismatch, cache version is #{cache.version}, Expressir version is #{VERSION}")
39
+ end
40
+
41
+ cache.content
42
+ end
43
+ end
44
+
45
+ class CacheLoadError < StandardError
46
+ end
47
+ end
48
+ end
@@ -163,7 +163,8 @@ module Expressir
163
163
  elsif node.is_a? Model::Types::String
164
164
  format_types_string(node)
165
165
  else
166
- puts node.class
166
+ STDERR.puts "#{node.class.name} format not implemented"
167
+ ''
167
168
  end
168
169
  end
169
170
 
@@ -245,51 +246,55 @@ module Expressir
245
246
  *if node.abstract and !node.supertype_expression
246
247
  [
247
248
  "\n",
248
- INDENT,
249
- 'ABSTRACT',
250
- ' ',
251
- 'SUPERTYPE'
249
+ indent([
250
+ 'ABSTRACT',
251
+ ' ',
252
+ 'SUPERTYPE'
253
+ ].join(''))
252
254
  ].join('')
253
255
  end,
254
256
  *if node.abstract and node.supertype_expression
255
257
  [
256
258
  "\n",
257
- INDENT,
258
- 'ABSTRACT',
259
- ' ',
260
- 'SUPERTYPE',
261
- ' ',
262
- 'OF',
263
- ' ',
264
- '(',
265
- format(node.supertype_expression),
266
- ')'
259
+ indent([
260
+ 'ABSTRACT',
261
+ ' ',
262
+ 'SUPERTYPE',
263
+ ' ',
264
+ 'OF',
265
+ ' ',
266
+ '(',
267
+ format(node.supertype_expression),
268
+ ')'
269
+ ].join(''))
267
270
  ].join('')
268
271
  end,
269
272
  *if !node.abstract and node.supertype_expression
270
273
  [
271
274
  "\n",
272
- INDENT,
273
- 'SUPERTYPE',
274
- ' ',
275
- 'OF',
276
- ' ',
277
- '(',
278
- format(node.supertype_expression),
279
- ')'
275
+ indent([
276
+ 'SUPERTYPE',
277
+ ' ',
278
+ 'OF',
279
+ ' ',
280
+ '(',
281
+ format(node.supertype_expression),
282
+ ')'
283
+ ].join(''))
280
284
  ].join('')
281
285
  end,
282
- *if node.subtype_of and node.subtype_of.length > 0
286
+ *if node.subtype_of.length > 0
283
287
  [
284
288
  "\n",
285
- INDENT,
286
- 'SUBTYPE',
287
- ' ',
288
- 'OF',
289
- ' ',
290
- '(',
291
- node.subtype_of.map{|x| format(x)}.join(', '),
292
- ')'
289
+ indent([
290
+ 'SUBTYPE',
291
+ ' ',
292
+ 'OF',
293
+ ' ',
294
+ '(',
295
+ node.subtype_of.map{|x| format(x)}.join(', '),
296
+ ')'
297
+ ].join(''))
293
298
  ].join('')
294
299
  end,
295
300
  ';'
@@ -298,28 +303,28 @@ module Expressir
298
303
  indent(explicit_attributes.map{|x| format(x)}.join("\n"))
299
304
  end,
300
305
  *if derived_attributes and derived_attributes.length > 0
301
- indent([
306
+ [
302
307
  'DERIVE',
303
308
  indent(derived_attributes.map{|x| format(x)}.join("\n")),
304
- ].join("\n"))
309
+ ]
305
310
  end,
306
311
  *if inverse_attributes and inverse_attributes.length > 0
307
- indent([
312
+ [
308
313
  'INVERSE',
309
314
  indent(inverse_attributes.map{|x| format(x)}.join("\n")),
310
- ].join("\n"))
315
+ ]
311
316
  end,
312
- *if node.unique and node.unique.length > 0
313
- indent([
317
+ *if node.unique.length > 0
318
+ [
314
319
  'UNIQUE',
315
320
  indent(node.unique.map{|x| format(x)}.join("\n"))
316
- ].join("\n"))
321
+ ]
317
322
  end,
318
- *if node.where and node.where.length > 0
319
- indent([
323
+ *if node.where.length > 0
324
+ [
320
325
  'WHERE',
321
326
  indent(node.where.map{|x| format(x)}.join("\n")),
322
- ].join("\n"))
327
+ ]
323
328
  end,
324
329
  [
325
330
  'END_ENTITY',
@@ -338,10 +343,11 @@ module Expressir
338
343
  'FUNCTION',
339
344
  ' ',
340
345
  node.id,
341
- *if node.parameters and node.parameters.length > 0
346
+ *if node.parameters.length > 0
347
+ parameter_indent = INDENT_CHAR * "FUNCTION #{node.id}(".length
342
348
  [
343
349
  '(',
344
- node.parameters.map{|x| format(x)}.join('; '),
350
+ node.parameters.map{|x| format(x)}.join(";\n#{parameter_indent}"),
345
351
  ')'
346
352
  ].join('')
347
353
  end,
@@ -351,22 +357,22 @@ module Expressir
351
357
  format(node.return_type),
352
358
  ';'
353
359
  ].join(''),
354
- *if node.types and node.types.length > 0
360
+ *if node.types.length > 0
355
361
  indent(node.types.map{|x| format(x)}.join("\n"))
356
362
  end,
357
- *if node.entities and node.entities.length > 0
363
+ *if node.entities.length > 0
358
364
  indent(node.entities.map{|x| format(x)}.join("\n"))
359
365
  end,
360
- *if node.subtype_constraints and node.subtype_constraints.length > 0
366
+ *if node.subtype_constraints.length > 0
361
367
  indent(node.subtype_constraints.map{|x| format(x)}.join("\n"))
362
368
  end,
363
- *if node.functions and node.functions.length > 0
369
+ *if node.functions.length > 0
364
370
  indent(node.functions.map{|x| format(x)}.join("\n"))
365
371
  end,
366
- *if node.procedures and node.procedures.length > 0
372
+ *if node.procedures.length > 0
367
373
  indent(node.procedures.map{|x| format(x)}.join("\n"))
368
374
  end,
369
- *if node.constants and node.constants.length > 0
375
+ *if node.constants.length > 0
370
376
  indent([
371
377
  'CONSTANT',
372
378
  indent(node.constants.map{|x| format(x)}.join("\n")),
@@ -376,7 +382,7 @@ module Expressir
376
382
  ].join('')
377
383
  ].join("\n"))
378
384
  end,
379
- *if node.variables and node.variables.length > 0
385
+ *if node.variables.length > 0
380
386
  indent([
381
387
  'LOCAL',
382
388
  indent(node.variables.map{|x| format(x)}.join("\n")),
@@ -386,7 +392,7 @@ module Expressir
386
392
  ].join('')
387
393
  ].join("\n"))
388
394
  end,
389
- *if node.statements and node.statements.length > 0
395
+ *if node.statements.length > 0
390
396
  indent(node.statements.map{|x| format(x)}.join("\n"))
391
397
  end,
392
398
  [
@@ -406,13 +412,15 @@ module Expressir
406
412
  'FROM',
407
413
  ' ',
408
414
  format(node.schema),
409
- *if node.items and node.items.length > 0
415
+ *if node.items.length > 0
416
+ item_indent = INDENT_CHAR * '('.length
410
417
  [
411
418
  "\n",
412
- INDENT,
413
- '(',
414
- node.items.map{|x| format(x)}.join(', '),
415
- ')'
419
+ indent([
420
+ '(',
421
+ node.items.map{|x| format(x)}.join(",\n#{item_indent}"),
422
+ ')'
423
+ ].join(''))
416
424
  ].join('')
417
425
  end,
418
426
  ';',
@@ -455,31 +463,32 @@ module Expressir
455
463
  'PROCEDURE',
456
464
  ' ',
457
465
  node.id,
458
- *if node.parameters and node.parameters.length > 0
466
+ *if node.parameters.length > 0
467
+ parameter_indent = INDENT_CHAR * "PROCEDURE #{node.id}(".length
459
468
  [
460
469
  '(',
461
- node.parameters.map{|x| format(x)}.join('; '),
470
+ node.parameters.map{|x| format(x)}.join(";\n#{parameter_indent}"),
462
471
  ')'
463
472
  ].join('')
464
473
  end,
465
474
  ';'
466
475
  ].join(''),
467
- *if node.types and node.types.length > 0
476
+ *if node.types.length > 0
468
477
  indent(node.types.map{|x| format(x)}.join("\n"))
469
478
  end,
470
- *if node.entities and node.entities.length > 0
479
+ *if node.entities.length > 0
471
480
  indent(node.entities.map{|x| format(x)}.join("\n"))
472
481
  end,
473
- *if node.subtype_constraints and node.subtype_constraints.length > 0
482
+ *if node.subtype_constraints.length > 0
474
483
  indent(node.subtype_constraints.map{|x| format(x)}.join("\n"))
475
484
  end,
476
- *if node.functions and node.functions.length > 0
485
+ *if node.functions.length > 0
477
486
  indent(node.functions.map{|x| format(x)}.join("\n"))
478
487
  end,
479
- *if node.procedures and node.procedures.length > 0
488
+ *if node.procedures.length > 0
480
489
  indent(node.procedures.map{|x| format(x)}.join("\n"))
481
490
  end,
482
- *if node.constants and node.constants.length > 0
491
+ *if node.constants.length > 0
483
492
  indent([
484
493
  'CONSTANT',
485
494
  indent(node.constants.map{|x| format(x)}.join("\n")),
@@ -489,7 +498,7 @@ module Expressir
489
498
  ].join('')
490
499
  ].join("\n"))
491
500
  end,
492
- *if node.variables and node.variables.length > 0
501
+ *if node.variables.length > 0
493
502
  indent([
494
503
  'LOCAL',
495
504
  indent(node.variables.map{|x| format(x)}.join("\n")),
@@ -499,7 +508,7 @@ module Expressir
499
508
  ].join('')
500
509
  ].join("\n"))
501
510
  end,
502
- *if node.statements and node.statements.length > 0
511
+ *if node.statements.length > 0
503
512
  indent(node.statements.map{|x| format(x)}.join("\n"))
504
513
  end,
505
514
  [
@@ -510,11 +519,7 @@ module Expressir
510
519
  end
511
520
 
512
521
  def format_repository(node)
513
- [
514
- *if node.schemas and node.schemas.length > 0
515
- node.schemas.map{|node| format(node)}
516
- end
517
- ].join("\n")
522
+ node.schemas.map{|node| format(node)}.join("\n\n")
518
523
  end
519
524
 
520
525
  def format_rule(node)
@@ -531,22 +536,22 @@ module Expressir
531
536
  ')',
532
537
  ';'
533
538
  ].join(''),
534
- *if node.types and node.types.length > 0
539
+ *if node.types.length > 0
535
540
  indent(node.types.map{|x| format(x)}.join("\n"))
536
541
  end,
537
- *if node.entities and node.entities.length > 0
542
+ *if node.entities.length > 0
538
543
  indent(node.entities.map{|x| format(x)}.join("\n"))
539
544
  end,
540
- *if node.subtype_constraints and node.subtype_constraints.length > 0
545
+ *if node.subtype_constraints.length > 0
541
546
  indent(node.subtype_constraints.map{|x| format(x)}.join("\n"))
542
547
  end,
543
- *if node.functions and node.functions.length > 0
548
+ *if node.functions.length > 0
544
549
  indent(node.functions.map{|x| format(x)}.join("\n"))
545
550
  end,
546
- *if node.procedures and node.procedures.length > 0
551
+ *if node.procedures.length > 0
547
552
  indent(node.procedures.map{|x| format(x)}.join("\n"))
548
553
  end,
549
- *if node.constants and node.constants.length > 0
554
+ *if node.constants.length > 0
550
555
  indent([
551
556
  'CONSTANT',
552
557
  indent(node.constants.map{|x| format(x)}.join("\n")),
@@ -556,7 +561,7 @@ module Expressir
556
561
  ].join('')
557
562
  ].join("\n"))
558
563
  end,
559
- *if node.variables and node.variables.length > 0
564
+ *if node.variables.length > 0
560
565
  indent([
561
566
  'LOCAL',
562
567
  indent(node.variables.map{|x| format(x)}.join("\n")),
@@ -566,14 +571,14 @@ module Expressir
566
571
  ].join('')
567
572
  ].join("\n"))
568
573
  end,
569
- *if node.statements and node.statements.length > 0
574
+ *if node.statements.length > 0
570
575
  indent(node.statements.map{|x| format(x)}.join("\n"))
571
576
  end,
572
- *if node.where and node.where.length > 0
573
- indent([
577
+ *if node.where.length > 0
578
+ [
574
579
  'WHERE',
575
580
  indent(node.where.map{|x| format(x)}.join("\n"))
576
- ].join("\n"))
581
+ ]
577
582
  end,
578
583
  [
579
584
  'END_RULE',
@@ -582,7 +587,7 @@ module Expressir
582
587
  ].join("\n")
583
588
  end
584
589
 
585
- def format_schema(node)
590
+ def format_schema_head(node)
586
591
  [
587
592
  [
588
593
  'SCHEMA',
@@ -596,10 +601,18 @@ module Expressir
596
601
  end,
597
602
  ';'
598
603
  ].join(''),
599
- *if node.interfaces and node.interfaces.length > 0
600
- node.interfaces.map{|x| format(x)}.join("\n")
601
- end,
602
- *if node.constants and node.constants.length > 0
604
+ *if node.interfaces.length > 0
605
+ [
606
+ '',
607
+ node.interfaces.map{|x| format(x)}.join("\n")
608
+ ]
609
+ end
610
+ ].join("\n")
611
+ end
612
+
613
+ def format_schema(node)
614
+ schema_declarations = [
615
+ *if node.constants.length > 0
603
616
  [
604
617
  'CONSTANT',
605
618
  indent(node.constants.map{|x| format(x)}.join("\n")),
@@ -609,23 +622,34 @@ module Expressir
609
622
  ].join('')
610
623
  ].join("\n")
611
624
  end,
612
- *if node.types and node.types.length > 0
613
- node.types.map{|x| format(x)}.join("\n")
625
+ *if node.types.length > 0
626
+ node.types.map{|x| format(x)}
614
627
  end,
615
- *if node.entities and node.entities.length > 0
616
- node.entities.map{|x| format(x)}.join("\n")
628
+ *if node.entities.length > 0
629
+ node.entities.map{|x| format(x)}
617
630
  end,
618
- *if node.subtype_constraints and node.subtype_constraints.length > 0
619
- node.subtype_constraints.map{|x| format(x)}.join("\n")
631
+ *if node.subtype_constraints.length > 0
632
+ node.subtype_constraints.map{|x| format(x)}
620
633
  end,
621
- *if node.functions and node.functions.length > 0
622
- node.functions.map{|x| format(x)}.join("\n")
634
+ *if node.functions.length > 0
635
+ node.functions.map{|x| format(x)}
623
636
  end,
624
- *if node.procedures and node.procedures.length > 0
625
- node.procedures.map{|x| format(x)}.join("\n")
637
+ *if node.rules.length > 0
638
+ node.rules.map{|x| format(x)}
626
639
  end,
627
- *if node.rules and node.rules.length > 0
628
- node.rules.map{|x| format(x)}.join("\n")
640
+ *if node.procedures and node.procedures.length > 0
641
+ node.procedures.map{|x| format(x)}
642
+ end
643
+ ]
644
+
645
+ [
646
+ format_schema_head(node),
647
+ *if schema_declarations.length > 0
648
+ [
649
+ '',
650
+ schema_declarations.join("\n\n"),
651
+ ''
652
+ ]
629
653
  end,
630
654
  [
631
655
  'END_SCHEMA',
@@ -655,7 +679,7 @@ module Expressir
655
679
  ';'
656
680
  ].join(''))
657
681
  end,
658
- *if node.total_over and node.total_over.length > 0
682
+ *if node.total_over.length > 0
659
683
  indent([
660
684
  'TOTAL_OVER',
661
685
  '(',
@@ -689,11 +713,11 @@ module Expressir
689
713
  format(node.type),
690
714
  ';',
691
715
  ].join(''),
692
- *if node.where and node.where.length > 0
693
- indent([
716
+ *if node.where.length > 0
717
+ [
694
718
  'WHERE',
695
719
  indent(node.where.map{|x| format(x)}.join("\n"))
696
- ].join("\n"))
720
+ ]
697
721
  end,
698
722
  [
699
723
  'END_TYPE',
@@ -707,7 +731,6 @@ module Expressir
707
731
  *if node.id
708
732
  [
709
733
  node.id,
710
- ' ',
711
734
  ':',
712
735
  ' '
713
736
  ].join('')
@@ -741,7 +764,6 @@ module Expressir
741
764
  *if node.id
742
765
  [
743
766
  node.id,
744
- ' ',
745
767
  ':',
746
768
  ' '
747
769
  ].join('')
@@ -976,7 +998,7 @@ module Expressir
976
998
  format(node.expression),
977
999
  ';'
978
1000
  ].join(''),
979
- *if node.statements and node.statements.length > 0
1001
+ *if node.statements.length > 0
980
1002
  indent(node.statements.map{|x| format(x)}.join("\n"))
981
1003
  end,
982
1004
  *format_remarks(node),
@@ -1001,7 +1023,7 @@ module Expressir
1001
1023
  def format_statements_call(node)
1002
1024
  [
1003
1025
  format(node.ref),
1004
- *if node.parameters and node.parameters.length > 0
1026
+ *if node.parameters.length > 0
1005
1027
  [
1006
1028
  '(',
1007
1029
  node.parameters.map{|x| format(x)}.join(', '),
@@ -1021,7 +1043,7 @@ module Expressir
1021
1043
  ' ',
1022
1044
  'OF'
1023
1045
  ].join(''),
1024
- *if node.actions and node.actions.length > 0
1046
+ *if node.actions.length > 0
1025
1047
  node.actions.map{|x| format(x)}
1026
1048
  end,
1027
1049
  *if node.otherwise_statement
@@ -1055,7 +1077,7 @@ module Expressir
1055
1077
  def format_statements_compound(node)
1056
1078
  [
1057
1079
  'BEGIN',
1058
- *if node.statements and node.statements.length > 0
1080
+ *if node.statements.length > 0
1059
1081
  indent(node.statements.map{|x| format(x)}.join("\n"))
1060
1082
  end,
1061
1083
  [
@@ -1081,10 +1103,10 @@ module Expressir
1081
1103
  ' ',
1082
1104
  'THEN'
1083
1105
  ].join(''),
1084
- *if node.statements and node.statements.length > 0
1106
+ *if node.statements.length > 0
1085
1107
  indent(node.statements.map{|x| format(x)}.join("\n"))
1086
1108
  end,
1087
- *if node.else_statements and node.else_statements.length > 0
1109
+ *if node.else_statements.length > 0
1088
1110
  [
1089
1111
  'ELSE',
1090
1112
  indent(node.else_statements.map{|x| format(x)}.join("\n")),
@@ -1145,7 +1167,7 @@ module Expressir
1145
1167
  end,
1146
1168
  ';'
1147
1169
  ].join(''),
1148
- *if node.statements and node.statements.length > 0
1170
+ *if node.statements.length > 0
1149
1171
  indent(node.statements.map{|x| format(x)}.join("\n"))
1150
1172
  end,
1151
1173
  *format_remarks(node),
@@ -1267,14 +1289,17 @@ module Expressir
1267
1289
  ].join('')
1268
1290
  end,
1269
1291
  'ENUMERATION',
1270
- *if node.items and node.items.length > 0
1292
+ *if node.items.length > 0
1293
+ item_indent = INDENT_CHAR * '('.length
1271
1294
  [
1272
1295
  ' ',
1273
1296
  'OF',
1274
- ' ',
1275
- '(',
1276
- node.items.map{|x| format(x)}.join(', '),
1277
- ')'
1297
+ "\n",
1298
+ indent([
1299
+ '(',
1300
+ node.items.map{|x| format(x)}.join(",\n#{item_indent}"),
1301
+ ')'
1302
+ ].join(''))
1278
1303
  ].join('')
1279
1304
  end,
1280
1305
  *if node.extension_type
@@ -1285,25 +1310,44 @@ module Expressir
1285
1310
  format(node.extension_type)
1286
1311
  ].join('')
1287
1312
  end,
1288
- *if node.extension_items and node.extension_items.length > 0
1313
+ *if node.extension_items.length > 0
1314
+ item_indent = INDENT_CHAR * '('.length
1289
1315
  [
1290
1316
  ' ',
1291
1317
  'WITH',
1292
- ' ',
1293
- '(',
1294
- node.extension_items.map{|x| format(x)}.join(', '),
1295
- ')'
1318
+ "\n",
1319
+ indent([
1320
+ '(',
1321
+ node.extension_items.map{|x| format(x)}.join(",\n#{item_indent}"),
1322
+ ')'
1323
+ ].join(''))
1296
1324
  ].join('')
1297
1325
  end
1298
1326
  ].join('')
1299
1327
  end
1300
1328
 
1301
1329
  def format_types_generic_entity(node)
1302
- 'GENERIC_ENTITY'
1330
+ [
1331
+ 'GENERIC_ENTITY',
1332
+ *if node.id
1333
+ [
1334
+ ':',
1335
+ node.id
1336
+ ]
1337
+ end
1338
+ ].join('')
1303
1339
  end
1304
1340
 
1305
1341
  def format_types_generic(node)
1306
- 'GENERIC'
1342
+ [
1343
+ 'GENERIC',
1344
+ *if node.id
1345
+ [
1346
+ ':',
1347
+ node.id
1348
+ ]
1349
+ end
1350
+ ].join('')
1307
1351
  end
1308
1352
 
1309
1353
  def format_types_integer(node)
@@ -1373,12 +1417,15 @@ module Expressir
1373
1417
  ].join('')
1374
1418
  end,
1375
1419
  'SELECT',
1376
- *if node.items and node.items.length > 0
1420
+ *if node.items.length > 0
1421
+ item_indent = INDENT_CHAR * '('.length
1377
1422
  [
1378
- ' ',
1379
- '(',
1380
- node.items.map{|x| format(x)}.join(', '),
1381
- ')'
1423
+ "\n",
1424
+ indent([
1425
+ '(',
1426
+ node.items.map{|x| format(x)}.join(",\n#{item_indent}"),
1427
+ ')'
1428
+ ].join(''))
1382
1429
  ].join('')
1383
1430
  end,
1384
1431
  *if node.extension_type
@@ -1389,14 +1436,17 @@ module Expressir
1389
1436
  format(node.extension_type)
1390
1437
  ].join('')
1391
1438
  end,
1392
- *if node.extension_items and node.extension_items.length > 0
1439
+ *if node.extension_items.length > 0
1440
+ item_indent = INDENT_CHAR * '('.length
1393
1441
  [
1394
1442
  ' ',
1395
1443
  'WITH',
1396
- ' ',
1397
- '(',
1398
- node.extension_items.map{|x| format(x)}.join(', '),
1399
- ')'
1444
+ "\n",
1445
+ indent([
1446
+ '(',
1447
+ node.extension_items.map{|x| format(x)}.join(",\n#{item_indent}"),
1448
+ ')'
1449
+ ].join(''))
1400
1450
  ].join('')
1401
1451
  end
1402
1452
  ].join('')