2020-06-24 20:02:42 +03:00
|
|
|
---
|
|
|
|
layout: developer-doc
|
|
|
|
title: Builtin Base Methods
|
|
|
|
category: runtime
|
|
|
|
tags: [runtime, base, standard, library]
|
|
|
|
order: 7
|
|
|
|
---
|
|
|
|
|
|
|
|
# Builtin Base Methods
|
2020-07-21 15:59:40 +03:00
|
|
|
|
2020-06-24 20:02:42 +03:00
|
|
|
While we strive to implement most of the Enso standard library in Enso itself,
|
|
|
|
it is necessary for certain methods, particularly ones involving operations out
|
|
|
|
of reach for the standard language semantics, or primitive system calls, to be
|
|
|
|
implemented in Java.
|
|
|
|
|
|
|
|
To facilitate this process, we have created an annotation-based DSL for easier
|
|
|
|
generation of such methods' boilerplate.
|
|
|
|
|
|
|
|
<!-- MarkdownTOC levels="2,3" autolink="true" -->
|
|
|
|
|
|
|
|
- [DSL Overview](#dsl-overview)
|
|
|
|
- [`@BuiltinMethod` Annotation](#builtinmethod-annotation)
|
|
|
|
- [Structural Requirements](#structural-requirements)
|
|
|
|
- [`Execute` Method Semantics](#execute-method-semantics)
|
|
|
|
- [Generated Node](#generated-node)
|
|
|
|
|
|
|
|
<!-- /MarkdownTOC -->
|
|
|
|
|
|
|
|
## DSL Overview
|
2020-07-21 15:59:40 +03:00
|
|
|
|
|
|
|
The Enso Base DSL exposes certain annotations that allow to generate boilerplate
|
|
|
|
transforming standard Truffle nodes into a shape that can easily be exported to
|
|
|
|
the Base library. This DSL facilitates automatic parsing and typechecking of
|
|
|
|
method arguments and wrapping the node in an actual `Function` object.
|
2020-06-24 20:02:42 +03:00
|
|
|
|
|
|
|
## `@BuiltinMethod` Annotation
|
2020-07-21 15:59:40 +03:00
|
|
|
|
2020-06-24 20:02:42 +03:00
|
|
|
The `@BuiltinMethod` annotation is applied to a Truffle `Node` subclass that
|
|
|
|
should be treated as a builtin method. It takes the following arguments:
|
|
|
|
|
|
|
|
1. `type` **String** the name of the type the method will be registered on.
|
|
|
|
2. `name` **String** the method name.
|
|
|
|
3. `description` **String** a summary of the method's behavior, for
|
|
|
|
documentation purposes.
|
|
|
|
4. `alwaysDirect` **Boolean = `true`** describes whether the function can always
|
|
|
|
be safely called directly. It should be set to `false` for methods that
|
|
|
|
evaluate user code in a tail position (e.g. `if_then_else`). If the method
|
|
|
|
does not take functions or thunks as parameters, or it only evaluates these
|
|
|
|
in a non-tail position, this parameter should be left defaulted.
|
|
|
|
|
|
|
|
The annotation will generate a `RootNode` subclass in the same package as the
|
2020-07-21 15:59:40 +03:00
|
|
|
declaring node, with a name basing on the declaring node's name. The name of the
|
|
|
|
generated node is the name of the original node, with the `Node` suffix stripped
|
|
|
|
and the `MethodGen` suffix appended. E.g. `AndOperatorNode` will generate a
|
|
|
|
`AndOperatorMethodGen` root node.
|
2020-06-24 20:02:42 +03:00
|
|
|
|
|
|
|
## Structural Requirements
|
2020-07-21 15:59:40 +03:00
|
|
|
|
2020-06-24 20:02:42 +03:00
|
|
|
The DSL places certain structural requirements on the declaring node.
|
|
|
|
|
2020-07-21 15:59:40 +03:00
|
|
|
1. **Construction:** The node must be constructible using either a
|
|
|
|
paremeterless, static `build` method or a parameterless constructor. If a
|
|
|
|
suitable `build` method is defined, it will be preferred over the
|
2020-06-24 20:02:42 +03:00
|
|
|
constructor.
|
|
|
|
2. **Execution:** The node must declare a single, accessible (i.e. at least
|
|
|
|
package-private), non-void method named `execute`.
|
2020-07-21 15:59:40 +03:00
|
|
|
|
2020-06-24 20:02:42 +03:00
|
|
|
## `Execute` Method Semantics
|
2020-07-21 15:59:40 +03:00
|
|
|
|
2020-06-24 20:02:42 +03:00
|
|
|
The `execute` method defined by the declaring node has the following semantics.
|
|
|
|
|
|
|
|
1. Return type. If the return type is `Stateful`, the method is assumed to
|
2020-07-21 15:59:40 +03:00
|
|
|
modify the monadic state. For any other return type, the method cannot modify
|
|
|
|
the monadic state.
|
|
|
|
2. Arguments. The method may take any number of arguments, though at least an
|
|
|
|
argument named `self` must be present. The arguments have following
|
2020-06-24 20:02:42 +03:00
|
|
|
semantics:
|
2020-07-21 15:59:40 +03:00
|
|
|
1. An `Object` argument may be annotated with `@MonadicState`. This tells the
|
|
|
|
DSL to substitute it for the current value of monadic state. Note that
|
|
|
|
this value is read-only. In order to modify state, the method must return
|
|
|
|
a `Stateful`.
|
2020-06-24 20:02:42 +03:00
|
|
|
2. Any `VirtualFrame` argument will be passed the current execution frame.
|
2020-07-21 15:59:40 +03:00
|
|
|
3. Any `CallerInfo` argument will be passed the current `CallerInfo` and mark
|
|
|
|
the method as requiring the caller info at runtime.
|
2020-06-24 20:02:42 +03:00
|
|
|
4. All other arguments are treated as positional arguments to the method.
|
2020-07-21 15:59:40 +03:00
|
|
|
Note that according to the language specification, any method must take an
|
|
|
|
argument named `this`. Because of a naming conflict with Java, this
|
|
|
|
argument is called `_this` in the DSL. Please note that it is mandatory to
|
|
|
|
take an argument called `_this`, even if it is unused.
|
|
|
|
5. The positional arguments can be of any typed specified by the runtime type
|
|
|
|
system (see `org.enso.interpreter.runtime.Types`) or `Object`. Arguments
|
|
|
|
typed as `Thunk` mark the argument as suspended in the generated function
|
|
|
|
header.
|
|
|
|
|
2020-06-24 20:02:42 +03:00
|
|
|
## Generated Node
|
2020-07-21 15:59:40 +03:00
|
|
|
|
2020-06-24 20:02:42 +03:00
|
|
|
The DSL generates a single root node per annotated class. This node handles
|
|
|
|
reading the arguments from the execution frame and typechecking them, before
|
|
|
|
delegating to the declaring node.
|
|
|
|
|
|
|
|
The generated node also defines a static `makeFunction(Language)` method,
|
2020-07-21 15:59:40 +03:00
|
|
|
wrapping the node in a runtime function object.
|