0
# Language Implementation SPI
1
2
Service Provider Interface (SPI) for implementing programming languages on the Truffle framework, including language registration, context management, and environment setup.
3
4
## Capabilities
5
6
### TruffleLanguage
7
8
Main SPI class that language implementers extend to create new programming languages for GraalVM.
9
10
```java { .api }
11
/**
12
* Base class for implementing programming languages on Truffle
13
* Extend this class and use @Registration to create a new language
14
*/
15
public abstract class TruffleLanguage<C> {
16
17
/**
18
* Creates a new context for language execution
19
* @param env The language environment
20
* @return New language context
21
*/
22
protected abstract C createContext(Env env);
23
24
/**
25
* Parses source code and returns an executable call target
26
* @param request Parse request containing source and parsing options
27
* @return Executable call target
28
* @throws Exception if parsing fails
29
*/
30
protected abstract CallTarget parse(ParsingRequest request) throws Exception;
31
32
/**
33
* Executes inline source code within an existing context
34
* @param request Inline execution request
35
* @return Execution result
36
* @throws Exception if execution fails
37
*/
38
protected Object executeInline(InlineParsingRequest request) throws Exception {
39
throw new UnsupportedOperationException("Inline execution not supported");
40
}
41
42
/**
43
* Finds meta-object for a given value (optional)
44
* @param context Language context
45
* @param value Value to find meta-object for
46
* @return Meta-object or null if not supported
47
*/
48
protected Object findMetaObject(C context, Object value) {
49
return null;
50
}
51
52
/**
53
* Returns display string for a value (optional)
54
* @param context Language context
55
* @param value Value to display
56
* @return Display string
57
*/
58
protected String toString(C context, Object value) {
59
return Objects.toString(value);
60
}
61
62
/**
63
* Finds source location for a value (optional)
64
* @param context Language context
65
* @param value Value to find location for
66
* @return Source section or null if not available
67
*/
68
protected SourceSection findSourceLocation(C context, Object value) {
69
return null;
70
}
71
72
/**
73
* Checks if a value is an object of this language
74
* @param context Language context
75
* @param value Value to check
76
* @return True if value belongs to this language
77
*/
78
protected boolean isObjectOfLanguage(C context, Object value) {
79
return false;
80
}
81
82
/**
83
* Returns the language home directory (optional)
84
* @return Language home path or null
85
*/
86
protected String getLanguageHome() {
87
return null;
88
}
89
90
/**
91
* Initializes the language (called once per language)
92
* @param context Language context
93
*/
94
protected void initializeContext(C context) throws Exception {
95
// Default implementation does nothing
96
}
97
98
/**
99
* Finalizes context before disposal
100
* @param context Language context
101
*/
102
protected void finalizeContext(C context) {
103
// Default implementation does nothing
104
}
105
106
/**
107
* Disposes the language context
108
* @param context Language context to dispose
109
*/
110
protected void disposeContext(C context) {
111
// Default implementation does nothing
112
}
113
}
114
```
115
116
**Usage Examples:**
117
118
```java
119
import com.oracle.truffle.api.TruffleLanguage;
120
import com.oracle.truffle.api.TruffleLanguage.Registration;
121
122
@Registration(
123
id = "mylang",
124
name = "My Language",
125
version = "1.0",
126
defaultMimeType = "application/x-mylang",
127
characterMimeTypes = {"application/x-mylang"},
128
fileTypeDetectors = MyLanguageFileDetector.class
129
)
130
public class MyLanguage extends TruffleLanguage<MyLanguageContext> {
131
132
@Override
133
protected MyLanguageContext createContext(Env env) {
134
return new MyLanguageContext(env);
135
}
136
137
@Override
138
protected CallTarget parse(ParsingRequest request) throws Exception {
139
Source source = request.getSource();
140
MyLanguageParser parser = new MyLanguageParser(source);
141
RootNode rootNode = parser.parse();
142
return rootNode.getCallTarget();
143
}
144
145
@Override
146
protected Object findMetaObject(MyLanguageContext context, Object value) {
147
if (value instanceof MyLanguageNumber) {
148
return context.getNumberMetaObject();
149
} else if (value instanceof MyLanguageString) {
150
return context.getStringMetaObject();
151
}
152
return null;
153
}
154
155
@Override
156
protected String toString(MyLanguageContext context, Object value) {
157
if (value instanceof MyLanguageObject) {
158
return ((MyLanguageObject) value).toDisplayString();
159
}
160
return super.toString(context, value);
161
}
162
}
163
```
164
165
### Language Registration
166
167
Annotation for registering languages with the Truffle language registry.
168
169
```java { .api }
170
/**
171
* Annotation for registering Truffle languages
172
*/
173
@Target(ElementType.TYPE)
174
@Retention(RetentionPolicy.RUNTIME)
175
public @interface Registration {
176
/** Unique language identifier */
177
String id();
178
179
/** Human-readable language name */
180
String name();
181
182
/** Language implementation version */
183
String version() default "";
184
185
/** Default MIME type for the language */
186
String defaultMimeType() default "";
187
188
/** All supported MIME types */
189
String[] mimeType() default {};
190
191
/** Character-based MIME types */
192
String[] characterMimeTypes() default {};
193
194
/** Binary MIME types */
195
String[] byteMimeTypes() default {};
196
197
/** Dependency on other languages */
198
String[] dependentLanguages() default {};
199
200
/** File type detectors */
201
Class<?>[] fileTypeDetectors() default {};
202
203
/** Whether language is interactive (REPL-capable) */
204
boolean interactive() default false;
205
206
/** Whether language is internal (not directly accessible) */
207
boolean internal() default false;
208
209
/** Language website URL */
210
String website() default "";
211
}
212
```
213
214
### Language Environment
215
216
Environment object providing access to language configuration and polyglot services.
217
218
```java { .api }
219
/**
220
* Environment for language execution providing access to configuration and services
221
*/
222
public final class Env {
223
/** Returns the language options */
224
public OptionValues getOptions();
225
226
/** Returns command line arguments */
227
public String[] getApplicationArguments();
228
229
/** Checks if a MIME type is supported */
230
public boolean isMimeTypeSupported(String mimeType);
231
232
/** Parses source in another language */
233
public CallTarget parsePublic(Source source, String... argumentNames);
234
235
/** Parses inline source */
236
public CallTarget parseInline(Source source, Node location, MaterializedFrame frame);
237
238
/** Creates a new TruffleFile for file system access */
239
public TruffleFile getTruffleFile(String path);
240
241
/** Creates a new TruffleFile with URI */
242
public TruffleFile getTruffleFile(URI uri);
243
244
/** Returns the temporary directory */
245
public TruffleFile getTempDirectory();
246
247
/** Returns the current working directory */
248
public TruffleFile getCurrentWorkingDirectory();
249
250
/** Checks if native access is allowed */
251
public boolean isNativeAccessAllowed();
252
253
/** Checks if host access is allowed */
254
public boolean isHostLookupAllowed();
255
256
/** Looks up a host symbol */
257
public Object lookupHostSymbol(String symbolName);
258
259
/** Converts a host value to guest */
260
public Object asGuestValue(Object hostValue);
261
262
/** Converts a guest value to host */
263
public Object asHostValue(Object guestValue);
264
265
/** Checks if a value is host object */
266
public boolean isHostObject(Object guestValue);
267
268
/** Returns polyglot bindings */
269
public Object getPolyglotBindings();
270
271
/** Imports a polyglot symbol */
272
public Object importSymbol(String symbolName);
273
274
/** Exports a polyglot symbol */
275
public void exportSymbol(String symbolName, Object value);
276
277
/** Registers service provider */
278
public <T> T lookup(InstrumentInfo instrumentInfo, Class<T> serviceClass);
279
}
280
```
281
282
### Parsing Requests
283
284
Request objects for parsing source code.
285
286
```java { .api }
287
/**
288
* Request for parsing source code
289
*/
290
public final class ParsingRequest {
291
/** Returns the source to parse */
292
public Source getSource();
293
294
/** Returns argument names for the executable */
295
public List<String> getArgumentNames();
296
297
/** Checks if parsing is for inline execution */
298
public boolean isInline();
299
300
/** Returns the frame for inline parsing */
301
public MaterializedFrame getFrame();
302
303
/** Returns the location node for inline parsing */
304
public Node getLocation();
305
}
306
307
/**
308
* Request for inline parsing and execution
309
*/
310
public final class InlineParsingRequest {
311
/** Returns the source to parse */
312
public Source getSource();
313
314
/** Returns the frame for execution */
315
public MaterializedFrame getFrame();
316
317
/** Returns the location node */
318
public Node getLocation();
319
}
320
```
321
322
### Language Information and Access
323
324
Information about registered languages and access to language instances.
325
326
```java { .api }
327
/**
328
* Information about a registered language
329
*/
330
public final class LanguageInfo {
331
/** Returns the language ID */
332
public String getId();
333
334
/** Returns the language name */
335
public String getName();
336
337
/** Returns the language version */
338
public String getVersion();
339
340
/** Returns the default MIME type */
341
public String getDefaultMimeType();
342
343
/** Returns all MIME types */
344
public Set<String> getMimeTypes();
345
346
/** Checks if language is interactive */
347
public boolean isInteractive();
348
349
/** Checks if language is internal */
350
public boolean isInternal();
351
}
352
353
/**
354
* Utility for accessing language information and instances
355
*/
356
public final class LanguageAccess {
357
/** Gets current language instance */
358
public static <T extends TruffleLanguage<?>> T getCurrentLanguage(Class<T> languageClass);
359
360
/** Gets current language context */
361
public static <C> C getCurrentContext(Class<? extends TruffleLanguage<C>> languageClass);
362
363
/** Gets language info for current language */
364
public static LanguageInfo getCurrentLanguageInfo();
365
}
366
```
367
368
**Usage Examples:**
369
370
```java
371
public class MyLanguageContext {
372
private final Env env;
373
private final TruffleFile homeDirectory;
374
private final Map<String, Object> globals;
375
376
public MyLanguageContext(Env env) {
377
this.env = env;
378
this.homeDirectory = env.getCurrentWorkingDirectory();
379
this.globals = new HashMap<>();
380
381
// Initialize built-in functions
382
globals.put("print", new MyLanguagePrintFunction());
383
globals.put("import", new MyLanguageImportFunction());
384
}
385
386
public Object getGlobal(String name) {
387
// Check local globals first
388
Object value = globals.get(name);
389
if (value != null) {
390
return value;
391
}
392
393
// Try polyglot bindings
394
InteropLibrary interop = InteropLibrary.getUncached();
395
Object bindings = env.getPolyglotBindings();
396
try {
397
if (interop.isMemberReadable(bindings, name)) {
398
return interop.readMember(bindings, name);
399
}
400
} catch (Exception e) {
401
// Ignore and continue
402
}
403
404
// Try host lookup if allowed
405
if (env.isHostLookupAllowed()) {
406
try {
407
return env.lookupHostSymbol(name);
408
} catch (Exception e) {
409
// Symbol not found
410
}
411
}
412
413
return null;
414
}
415
}
416
```
417
418
## Common Types
419
420
```java { .api }
421
public final class OptionValues {
422
/** Gets the value of an option */
423
public <T> T get(OptionKey<T> optionKey);
424
425
/** Checks if an option has been set */
426
public boolean hasBeenSet(OptionKey<?> optionKey);
427
428
/** Returns all set options */
429
public Set<OptionKey<?>> getKeys();
430
}
431
432
public final class OptionKey<T> {
433
/** Creates a new option key with default value */
434
public OptionKey(T defaultValue);
435
436
/** Creates a new option key with default value and validator */
437
public OptionKey(T defaultValue, OptionType<T> type);
438
439
/** Returns the default value */
440
public T getDefaultValue();
441
442
/** Returns the option type */
443
public OptionType<T> getType();
444
}
445
446
public interface InstrumentInfo {
447
/** Returns the instrument ID */
448
String getId();
449
450
/** Returns the instrument name */
451
String getName();
452
453
/** Returns the instrument version */
454
String getVersion();
455
}
456
```