mulang 5.3.0 → 6.0.4

Sign up to get free protection for your applications and to get access to all the features.
@@ -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