mulang 5.3.0 → 6.0.4

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.
@@ -1,43 +1,115 @@
1
1
  module Mulang::Language
2
- class Native
3
- def initialize(language)
4
- @language = language
2
+ CORE_LANGUAGES = %w(
3
+ Java
4
+ JavaScript
5
+ Prolog
6
+ Haskell
7
+ Python
8
+ Python2
9
+ Python3
10
+ Ruby
11
+ Php
12
+ C
13
+ Mulang
14
+ )
15
+
16
+ class Base
17
+ def identifiers(content, **options)
18
+ Mulang.analyse(identifiers_analysis(content, **options), **options)['outputIdentifiers'] rescue nil
19
+ end
20
+
21
+ def identifiers_analysis(content, **options)
22
+ build_analysis content, {includeOutputIdentifiers: true}, **options
23
+ end
24
+
25
+ def transformed_asts(content, operations, **options)
26
+ Mulang.analyse(transformed_asts_analysis(content, operations, **options), **options)['transformedAsts'] rescue nil
27
+ end
28
+
29
+ def transformed_asts_analysis(content, operations, **options)
30
+ build_analysis content, {transformationSpecs: operations}, **options
5
31
  end
6
32
 
7
- def ast(content)
8
- Mulang.analyse(ast_analysis(content))['intermediateLanguage'] rescue nil
33
+ def normalization_options(**options)
34
+ options.except(:serialization).presence
9
35
  end
10
36
 
11
- def ast_analysis(content)
37
+ def ast(content, **options)
38
+ Mulang.analyse(ast_analysis(content, **options), **options)['outputAst'] rescue nil
39
+ end
40
+
41
+ def ast_analysis(content, **options)
42
+ build_analysis content, {includeOutputAst: true}, **options
43
+ end
44
+
45
+ def build_analysis(content, spec, **options)
12
46
  {
13
- sample: { tag: 'CodeSample', language: @language, content: content },
14
- spec: { expectations: [], smellsSet: { tag: 'NoSmells' }, includeIntermediateLanguage: true }
47
+ sample: sample(content),
48
+ spec: {
49
+ expectations: [],
50
+ smellsSet: { tag: 'NoSmells' },
51
+ includeOutputAst: false,
52
+ normalizationOptions: normalization_options(options)
53
+ }.merge(spec).compact
15
54
  }
16
55
  end
56
+ end
57
+
58
+ class Native < Base
59
+ attr_accessor :name
60
+
61
+ def initialize(language_name)
62
+ @name = language_name
63
+ end
17
64
 
18
65
  def sample(content)
19
66
  {
20
67
  tag: 'CodeSample',
21
- language: @language,
68
+ language: @name,
22
69
  content: content
23
70
  }
24
71
  end
72
+
73
+ def core_name
74
+ @name
75
+ end
25
76
  end
26
77
 
27
- class External
28
- def initialize(&tool)
78
+ class External < Base
79
+ attr_accessor :name
80
+
81
+ def initialize(language_name = nil, &tool)
82
+ @name = language_name
29
83
  @tool = block_given? ? tool : proc { |it| it }
30
84
  end
31
85
 
32
- def ast(content)
33
- @tool.call(content) rescue nil
86
+ def ast(content, **args)
87
+ if args[:serialization]
88
+ super
89
+ else
90
+ call_tool content
91
+ end
34
92
  end
35
93
 
36
94
  def sample(content)
37
95
  {
38
96
  tag: 'MulangSample',
39
- ast: ast(content)
97
+ ast: call_tool(content)
40
98
  }
41
99
  end
100
+
101
+ def build_analysis(*)
102
+ super.deep_merge(spec: {originalLanguage: core_name}.compact)
103
+ end
104
+
105
+ def core_name
106
+ @name.in?(CORE_LANGUAGES) ? name : nil
107
+ end
108
+
109
+ private
110
+
111
+ def call_tool(content)
112
+ @tool.call(content) rescue nil
113
+ end
42
114
  end
43
115
  end
@@ -0,0 +1,80 @@
1
+ module Mulang
2
+ module Sexp
3
+
4
+ # Basic S-expression
5
+
6
+ def ms(tag, *contents)
7
+ if contents.empty?
8
+ {tag: tag}
9
+ elsif contents.size == 1
10
+ {tag: tag, contents: contents.first}
11
+ else
12
+ {tag: tag, contents: contents}
13
+ end
14
+ end
15
+
16
+ # Basic elements
17
+
18
+ def primitive(operator)
19
+ ms(:Primitive, operator)
20
+ end
21
+
22
+ def sequence(*contents)
23
+ if contents.empty?
24
+ none
25
+ elsif contents.size == 1
26
+ contents[0]
27
+ else
28
+ ms(:Sequence, *contents)
29
+ end
30
+ end
31
+
32
+ def none
33
+ ms(:None)
34
+ end
35
+
36
+ # Callables
37
+
38
+ def simple_function(name, args, body)
39
+ callable :Function, name, args, body
40
+ end
41
+
42
+ def simple_method(name, args, body)
43
+ callable :Method, name, args, body
44
+ end
45
+
46
+ def primitive_method(name, args, body)
47
+ callable :PrimitiveMethod, name, args, body
48
+ end
49
+
50
+ def callable(type, name, args, body)
51
+ {
52
+ tag: type,
53
+ contents: [
54
+ name,
55
+ [
56
+ [ args, {tag: :UnguardedBody, contents: body }]
57
+ ]
58
+ ]
59
+ }
60
+ end
61
+
62
+ # Applications
63
+
64
+ def primitive_send(sender, op, args)
65
+ ms(:Send, sender, primitive(op), args)
66
+ end
67
+
68
+ def simple_send(sender, message, args)
69
+ ms(:Send, sender, ms(:Reference, message), args)
70
+ end
71
+
72
+ def application(name, args)
73
+ ms :Application, [ms(:Reference, name), args]
74
+ end
75
+
76
+ def binary_application(operator, left, right)
77
+ application operator, [left, right]
78
+ end
79
+ end
80
+ end
@@ -0,0 +1,276 @@
1
+ module Mulang
2
+ module Tokens
3
+ TOKENS = {
4
+ Common: {
5
+ keyword_False: 'false',
6
+ keyword_Null: 'null',
7
+ keyword_True: 'true',
8
+ keyword_For: 'for',
9
+ keyword_If: 'if',
10
+ keyword_Return: 'return',
11
+ keyword_While: 'while',
12
+ operator_And: '&amp;&amp;',
13
+ operator_Divide: '/',
14
+ operator_Equal: '==',
15
+ operator_GreatherOrEqualThan: '&gt;=',
16
+ operator_GreatherThan: '&gt;',
17
+ operator_LessOrEqualThan: '&lt;=',
18
+ operator_LessThan: '&lt;',
19
+ operator_Minus: '-',
20
+ operator_Multiply: '*',
21
+ operator_Negation: '!',
22
+ operator_NotEqual: '!=',
23
+ operator_Or: '||',
24
+ operator_Plus: '+',
25
+ operator_Modulo: '%',
26
+ operator_BitwiseOr: '|',
27
+ operator_BitwiseAnd: '&amp;',
28
+ operator_BitwiseXor: '^',
29
+ operator_BitwiseLeftShift: '&lt;&lt;',
30
+ operator_BitwiseRightShift: '&gt;&gt;'
31
+ },
32
+ C: {
33
+ keyword_False: 'FALSE',
34
+ keyword_Null: 'NULL',
35
+ keyword_True: 'TRUE',
36
+ keyword_For: 'for',
37
+ keyword_If: 'if',
38
+ keyword_Return: 'return',
39
+ keyword_While: 'while',
40
+ keyword_Switch: 'switch',
41
+ operator_And: '&amp;&amp;',
42
+ operator_Divide: '/',
43
+ operator_Equal: '==',
44
+ operator_GreatherOrEqualThan: '&gt;=',
45
+ operator_GreatherThan: '&gt;',
46
+ operator_LessOrEqualThan: '&lt;=',
47
+ operator_LessThan: '&lt;',
48
+ operator_Minus: '-',
49
+ operator_Multiply: '*',
50
+ operator_Negation: '!',
51
+ operator_NotEqual: '!=',
52
+ operator_Or: '||',
53
+ operator_Plus: '+',
54
+ operator_Modulo: '%',
55
+ operator_BitwiseOr: '|',
56
+ operator_BitwiseAnd: '&amp;',
57
+ operator_BitwiseXor: '^',
58
+ operator_BitwiseLeftShift: '&lt;&lt;',
59
+ operator_BitwiseRightShift: '&gt;&gt;'
60
+ },
61
+ Haskell: {
62
+ keyword_False: 'False',
63
+ keyword_True: 'True',
64
+ keyword_If: 'if',
65
+ keyword_TypeAlias: 'type',
66
+ operator_And: '&amp;&amp;',
67
+ operator_Divide: '/',
68
+ operator_Equal: '==',
69
+ operator_GreatherOrEqualThan: '&gt;=',
70
+ operator_GreatherThan: '&gt;',
71
+ operator_LessOrEqualThan: '&lt;=',
72
+ operator_LessThan: '&lt;',
73
+ operator_Minus: '-',
74
+ operator_Multiply: '*',
75
+ operator_Negation: 'not',
76
+ operator_NotEqual: '/=',
77
+ operator_Or: '||',
78
+ operator_Plus: '+',
79
+ operator_Modulo: 'mod',
80
+ operator_Otherwise: 'otherwise',
81
+ operator_BackwardComposition: '.'
82
+ },
83
+ Java: {
84
+ keyword_False: 'false',
85
+ keyword_Null: 'null',
86
+ keyword_True: 'true',
87
+ keyword_For: 'for',
88
+ keyword_If: 'if',
89
+ keyword_Return: 'return',
90
+ keyword_While: 'while',
91
+ keyword_Class: 'class',
92
+ keyword_ForEach: 'for',
93
+ keyword_Interface: 'interface',
94
+ keyword_Switch: 'switch',
95
+ operator_And: '&amp;&amp;',
96
+ operator_Divide: '/',
97
+ operator_Equal: 'equal',
98
+ operator_GreatherOrEqualThan: '&gt;=',
99
+ operator_GreatherThan: '&gt;',
100
+ operator_LessOrEqualThan: '&lt;=',
101
+ operator_LessThan: '&lt;',
102
+ operator_Minus: '-',
103
+ operator_Multiply: '*',
104
+ operator_Negation: '!',
105
+ operator_NotEqual: '!=',
106
+ operator_Or: '||',
107
+ operator_Plus: '+',
108
+ operator_Modulo: '%',
109
+ operator_BitwiseOr: '|',
110
+ operator_BitwiseAnd: '&amp;',
111
+ operator_BitwiseXor: '^',
112
+ operator_BitwiseLeftShift: '&lt;&lt;',
113
+ operator_BitwiseRightShift: '&gt;&gt;',
114
+ operator_Hash: 'hashCode',
115
+ operator_Same: '==',
116
+ operator_NotSame: '!='
117
+ },
118
+ JavaScript: {
119
+ keyword_False: 'false',
120
+ keyword_Null: 'null',
121
+ keyword_True: 'true',
122
+ keyword_For: 'for',
123
+ keyword_If: 'if',
124
+ keyword_Return: 'return',
125
+ keyword_While: 'while',
126
+ operator_And: '&amp;&amp;',
127
+ operator_Divide: '/',
128
+ operator_Equal: '===',
129
+ operator_GreatherOrEqualThan: '&gt;=',
130
+ operator_GreatherThan: '&gt;',
131
+ operator_LessOrEqualThan: '&lt;=',
132
+ operator_LessThan: '&lt;',
133
+ operator_Minus: '-',
134
+ operator_Multiply: '*',
135
+ operator_Negation: '!',
136
+ operator_NotEqual: '!==',
137
+ operator_Or: '||',
138
+ operator_Plus: '+',
139
+ operator_Modulo: '%',
140
+ operator_BitwiseOr: '|',
141
+ operator_BitwiseAnd: '&amp;',
142
+ operator_BitwiseXor: '^',
143
+ operator_BitwiseLeftShift: '&lt;&lt;',
144
+ operator_BitwiseRightShift: '&gt;&gt;',
145
+ operator_Size: 'length',
146
+ operator_Similar: '==',
147
+ operator_NotSimilar: '!=',
148
+ operator_Push: 'push'
149
+ },
150
+ Python: {
151
+ keyword_False: 'False',
152
+ keyword_Null: 'None',
153
+ keyword_True: 'True',
154
+ keyword_For: 'for',
155
+ keyword_If: 'if',
156
+ keyword_Return: 'return',
157
+ keyword_While: 'while',
158
+ operator_And: 'and',
159
+ operator_Divide: '/',
160
+ operator_Equal: '==',
161
+ operator_GreatherOrEqualThan: '&gt;=',
162
+ operator_GreatherThan: '&gt;',
163
+ operator_LessOrEqualThan: '&lt;=',
164
+ operator_LessThan: '&lt;',
165
+ operator_Minus: '-',
166
+ operator_Multiply: '*',
167
+ operator_Negation: 'not',
168
+ operator_NotEqual: '!=',
169
+ operator_Or: 'or',
170
+ operator_Plus: '+',
171
+ operator_Modulo: '%',
172
+ operator_BitwiseOr: '|',
173
+ operator_BitwiseAnd: '&amp;',
174
+ operator_BitwiseXor: '^',
175
+ operator_BitwiseLeftShift: '&lt;&lt;',
176
+ operator_BitwiseRightShift: '&gt;&gt;',
177
+ operator_Hash: 'hash'
178
+ },
179
+ Ruby: {
180
+ keyword_False: 'false',
181
+ keyword_Null: 'null',
182
+ keyword_True: 'true',
183
+ keyword_For: 'for',
184
+ keyword_If: 'if',
185
+ keyword_Return: 'return',
186
+ keyword_While: 'while',
187
+ keyword_Class: 'class',
188
+ keyword_ForEach: 'for',
189
+ keyword_Include: 'include',
190
+ keyword_Switch: 'case',
191
+ operator_And: '&amp;&amp;',
192
+ operator_Divide: '/',
193
+ operator_Equal: '==',
194
+ operator_GreatherOrEqualThan: '&gt;=',
195
+ operator_GreatherThan: '&gt;',
196
+ operator_LessOrEqualThan: '&lt;=',
197
+ operator_LessThan: '&lt;',
198
+ operator_Minus: '-',
199
+ operator_Multiply: '*',
200
+ operator_Negation: '!',
201
+ operator_NotEqual: '!=',
202
+ operator_Or: '||',
203
+ operator_Plus: '+',
204
+ operator_Modulo: '%',
205
+ operator_BitwiseOr: '|',
206
+ operator_BitwiseAnd: '&amp;',
207
+ operator_BitwiseXor: '^',
208
+ operator_BitwiseLeftShift: '&lt;&lt;',
209
+ operator_BitwiseRightShift: '&gt;&gt;',
210
+ operator_Size: 'length',
211
+ operator_Hash: 'hash',
212
+ operator_ForwardComposition: '&gt;&gt;',
213
+ operator_BackwardComposition: '&lt;&lt;'
214
+ },
215
+ Php: {
216
+ keyword_False: 'false',
217
+ keyword_Null: 'null',
218
+ keyword_True: 'true',
219
+ keyword_For: 'for',
220
+ keyword_If: 'if',
221
+ keyword_Return: 'return',
222
+ keyword_While: 'while',
223
+ operator_And: '&amp;&amp;',
224
+ operator_Divide: '/',
225
+ operator_Equal: '==',
226
+ operator_GreatherOrEqualThan: '&gt;=',
227
+ operator_GreatherThan: '&gt;',
228
+ operator_LessOrEqualThan: '&lt;=',
229
+ operator_LessThan: '&lt;',
230
+ operator_Minus: '-',
231
+ operator_Multiply: '*',
232
+ operator_Negation: '!',
233
+ operator_NotEqual: '!=',
234
+ operator_Or: '||',
235
+ operator_Plus: '+',
236
+ operator_Modulo: '%',
237
+ operator_BitwiseOr: '|',
238
+ operator_BitwiseAnd: '&amp;',
239
+ operator_BitwiseXor: '^',
240
+ operator_BitwiseLeftShift: '&lt;&lt;',
241
+ operator_BitwiseRightShift: '&gt;&gt;'
242
+ },
243
+ Prolog: {
244
+ keyword_Fail: 'fail',
245
+ keyword_Findall: 'findall',
246
+ keyword_Forall: 'forall',
247
+ keyword_Not: 'not',
248
+ keyword_Is: 'is',
249
+ operator_Divide: '/',
250
+ operator_GreatherOrEqualThan: '&gt;=',
251
+ operator_GreatherThan: '&gt;',
252
+ operator_LessOrEqualThan: '=&lt;',
253
+ operator_LessThan: '&lt;',
254
+ operator_Minus: '-',
255
+ operator_Multiply: '*',
256
+ operator_NotEqual: '/=',
257
+ operator_Plus: '+'
258
+ }
259
+ }.freeze
260
+
261
+ POLYFILLS = {
262
+ Common: {
263
+ keyword_EntryPoint: 'program',
264
+ keyword_ForEach: 'foreach',
265
+ keyword_Repeat: 'repeat',
266
+ keyword_Switch: 'switch',
267
+ keyword_Yield: 'yield',
268
+ operator_Hash: 'hash',
269
+ operator_BackwardComposition: '.',
270
+ operator_ForwardComposition: '&gt;&gt;'
271
+ }
272
+ }.freeze
273
+
274
+ DEFAULT_TOKENS = TOKENS[:Common].merge(POLYFILLS[:Common]).freeze
275
+ end
276
+ end