462 lines
14 KiB
Plaintext
462 lines
14 KiB
Plaintext
// Hover provider for the ƿit LSP.
|
|
// Shows documentation for intrinsic functions and variable info.
|
|
|
|
// Intrinsic function documentation database.
|
|
// Each entry: {signature, description}
|
|
def intrinsic_docs = {
|
|
abs: {
|
|
signature: "abs(number)",
|
|
description: "Absolute value. Returns null for non-numbers."
|
|
},
|
|
apply: {
|
|
signature: "apply(function, array)",
|
|
description: "Execute the function, passing array elements as input values."
|
|
},
|
|
array: {
|
|
signature: "array(value, ...)",
|
|
description: "Create arrays. Polymorphic: array(number) creates sized array, array(array) copies, array(array, fn) maps, array(text) splits into characters, array(text, sep) splits by separator."
|
|
},
|
|
ceiling: {
|
|
signature: "ceiling(number, place)",
|
|
description: "Round up. If place is 0 or null, round to smallest integer >= number."
|
|
},
|
|
character: {
|
|
signature: "character(value)",
|
|
description: "If text, returns the first character. If a non-negative integer, returns the character from that codepoint."
|
|
},
|
|
codepoint: {
|
|
signature: "codepoint(text)",
|
|
description: "Returns the codepoint number of the first character."
|
|
},
|
|
ends_with: {
|
|
signature: "ends_with(text, suffix)",
|
|
description: "Returns true if the text ends with the given suffix."
|
|
},
|
|
every: {
|
|
signature: "every(array, function)",
|
|
description: "Returns true if every element satisfies the predicate."
|
|
},
|
|
extract: {
|
|
signature: "extract(text, pattern, from, to)",
|
|
description: "Match text to pattern. Returns a record of saved fields, or null if no match."
|
|
},
|
|
fallback: {
|
|
signature: "fallback(requestor_array)",
|
|
description: "Returns a requestor that tries each requestor in order until one succeeds."
|
|
},
|
|
filter: {
|
|
signature: "filter(array, function)",
|
|
description: "Returns a new array containing elements for which function returns true."
|
|
},
|
|
find: {
|
|
signature: "find(array, function, reverse, from)",
|
|
description: "Returns the element number where function returns true, or null if not found. If second arg is not a function, compares directly."
|
|
},
|
|
floor: {
|
|
signature: "floor(number, place)",
|
|
description: "Round down. If place is 0 or null, round to greatest integer <= number."
|
|
},
|
|
format: {
|
|
signature: "format(text, collection, transformer)",
|
|
description: "Substitute {key} placeholders in text with values from a collection (array or record)."
|
|
},
|
|
fraction: {
|
|
signature: "fraction(number)",
|
|
description: "Returns the fractional part of a number."
|
|
},
|
|
is_array: {
|
|
signature: "is_array(value)",
|
|
description: "Returns true if the value is an array."
|
|
},
|
|
is_blob: {
|
|
signature: "is_blob(value)",
|
|
description: "Returns true if the value is a blob."
|
|
},
|
|
is_character: {
|
|
signature: "is_character(value)",
|
|
description: "Returns true if the value is a single character."
|
|
},
|
|
is_data: {
|
|
signature: "is_data(value)",
|
|
description: "Returns true if the value is data (not a function)."
|
|
},
|
|
is_digit: {
|
|
signature: "is_digit(value)",
|
|
description: "Returns true if the value is a digit character."
|
|
},
|
|
is_false: {
|
|
signature: "is_false(value)",
|
|
description: "Returns true if the value is false."
|
|
},
|
|
is_fit: {
|
|
signature: "is_fit(value)",
|
|
description: "Returns true if the value is a fit integer."
|
|
},
|
|
is_function: {
|
|
signature: "is_function(value)",
|
|
description: "Returns true if the value is a function."
|
|
},
|
|
is_integer: {
|
|
signature: "is_integer(value)",
|
|
description: "Returns true if the value is an integer."
|
|
},
|
|
is_letter: {
|
|
signature: "is_letter(value)",
|
|
description: "Returns true if the value is a letter character."
|
|
},
|
|
is_logical: {
|
|
signature: "is_logical(value)",
|
|
description: "Returns true if the value is a logical (boolean)."
|
|
},
|
|
is_lower: {
|
|
signature: "is_lower(value)",
|
|
description: "Returns true if the value is a lowercase character."
|
|
},
|
|
is_null: {
|
|
signature: "is_null(value)",
|
|
description: "Returns true if the value is null."
|
|
},
|
|
is_number: {
|
|
signature: "is_number(value)",
|
|
description: "Returns true if the value is a number."
|
|
},
|
|
is_object: {
|
|
signature: "is_object(value)",
|
|
description: "Returns true if the value is an object (record)."
|
|
},
|
|
is_pattern: {
|
|
signature: "is_pattern(value)",
|
|
description: "Returns true if the value is a pattern (regex)."
|
|
},
|
|
is_stone: {
|
|
signature: "is_stone(value)",
|
|
description: "Returns true if the value is frozen (stoned)."
|
|
},
|
|
is_text: {
|
|
signature: "is_text(value)",
|
|
description: "Returns true if the value is text."
|
|
},
|
|
is_true: {
|
|
signature: "is_true(value)",
|
|
description: "Returns true if the value is true."
|
|
},
|
|
is_upper: {
|
|
signature: "is_upper(value)",
|
|
description: "Returns true if the value is an uppercase character."
|
|
},
|
|
is_whitespace: {
|
|
signature: "is_whitespace(value)",
|
|
description: "Returns true if the value is a whitespace character."
|
|
},
|
|
length: {
|
|
signature: "length(value)",
|
|
description: "Array: number of elements. Text: number of codepoints. Function: arity. Blob: number of bits. Record: record.length()."
|
|
},
|
|
logical: {
|
|
signature: "logical(value)",
|
|
description: "Convert to logical. 0/false/null/\"false\" produce false; 1/true/\"true\" produce true."
|
|
},
|
|
lower: {
|
|
signature: "lower(text)",
|
|
description: "Returns text with all uppercase characters converted to lowercase."
|
|
},
|
|
max: {
|
|
signature: "max(number, number)",
|
|
description: "Returns the larger of two numbers."
|
|
},
|
|
min: {
|
|
signature: "min(number, number)",
|
|
description: "Returns the smaller of two numbers."
|
|
},
|
|
modulo: {
|
|
signature: "modulo(dividend, divisor)",
|
|
description: "Result has the sign of the divisor."
|
|
},
|
|
neg: {
|
|
signature: "neg(number)",
|
|
description: "Negate. Reverse the sign of a number."
|
|
},
|
|
normalize: {
|
|
signature: "normalize(text)",
|
|
description: "Unicode normalize."
|
|
},
|
|
not: {
|
|
signature: "not(logical)",
|
|
description: "Returns the opposite logical. Returns null for non-logicals."
|
|
},
|
|
number: {
|
|
signature: "number(value, radix_or_format)",
|
|
description: "Convert to number. Polymorphic: number(logical), number(text), number(text, radix), number(text, format)."
|
|
},
|
|
parallel: {
|
|
signature: "parallel(requestor_array, throttle, need)",
|
|
description: "Start all requestors concurrently. Optional throttle limits concurrency; optional need specifies minimum successes."
|
|
},
|
|
print: {
|
|
signature: "print(value)",
|
|
description: "Print a value to standard output."
|
|
},
|
|
race: {
|
|
signature: "race(requestor_array, throttle, need)",
|
|
description: "Like parallel but returns as soon as needed results are obtained. Default need is 1."
|
|
},
|
|
record: {
|
|
signature: "record(value, ...)",
|
|
description: "Create records. Polymorphic: record(record) copies, record(record, record) merges, record(array) creates from keys."
|
|
},
|
|
reduce: {
|
|
signature: "reduce(array, function, initial, reverse)",
|
|
description: "Reduce an array to a single value by applying a function to pairs of elements."
|
|
},
|
|
remainder: {
|
|
signature: "remainder(dividend, divisor)",
|
|
description: "For fit integers: dividend - ((dividend // divisor) * divisor)."
|
|
},
|
|
replace: {
|
|
signature: "replace(text, target, replacement, limit)",
|
|
description: "Return text with target replaced. Target can be text or pattern. Replacement can be text or function."
|
|
},
|
|
reverse: {
|
|
signature: "reverse(array)",
|
|
description: "Returns a new array with elements in the opposite order."
|
|
},
|
|
round: {
|
|
signature: "round(number, place)",
|
|
description: "Round to nearest."
|
|
},
|
|
search: {
|
|
signature: "search(text, target, from)",
|
|
description: "Search text for target. Returns character position or null."
|
|
},
|
|
sequence: {
|
|
signature: "sequence(requestor_array)",
|
|
description: "Process requestors in order. Each result becomes input to the next."
|
|
},
|
|
sign: {
|
|
signature: "sign(number)",
|
|
description: "Returns -1, 0, or 1."
|
|
},
|
|
some: {
|
|
signature: "some(array, function)",
|
|
description: "Returns true if any element satisfies the predicate."
|
|
},
|
|
sort: {
|
|
signature: "sort(array, select)",
|
|
description: "Returns a new sorted array. Sort keys must be all numbers or all texts. Ascending and stable."
|
|
},
|
|
starts_with: {
|
|
signature: "starts_with(text, prefix)",
|
|
description: "Returns true if the text starts with the given prefix."
|
|
},
|
|
stone: {
|
|
signature: "stone(value)",
|
|
description: "Petrify the value, making it permanently immutable. Deep freeze."
|
|
},
|
|
text: {
|
|
signature: "text(value, ...)",
|
|
description: "Convert to text. Polymorphic: text(array, sep) joins, text(number, radix/format) formats, text(text, from, to) substrings."
|
|
},
|
|
trim: {
|
|
signature: "trim(text, reject)",
|
|
description: "Remove characters from both ends. Default removes whitespace."
|
|
},
|
|
trunc: {
|
|
signature: "trunc(number, place)",
|
|
description: "Truncate toward zero."
|
|
},
|
|
upper: {
|
|
signature: "upper(text)",
|
|
description: "Returns text with all lowercase characters converted to uppercase."
|
|
},
|
|
whole: {
|
|
signature: "whole(number)",
|
|
description: "Returns the whole part of a number."
|
|
},
|
|
meme: {
|
|
signature: "meme()",
|
|
description: "Create a new meme (prototype chain marker)."
|
|
},
|
|
proto: {
|
|
signature: "proto(object, meme)",
|
|
description: "Set the prototype meme of an object."
|
|
},
|
|
isa: {
|
|
signature: "isa(object, meme)",
|
|
description: "Returns true if the object has the given meme in its prototype chain."
|
|
},
|
|
splat: {
|
|
signature: "splat(function, array)",
|
|
description: "Call function with array elements as separate arguments."
|
|
},
|
|
use: {
|
|
signature: "use(path)",
|
|
description: "Load a module. Returns the module's exported value. Modules are cached and frozen."
|
|
},
|
|
pi: {
|
|
signature: "pi",
|
|
description: "An approximation of circumference / diameter: 3.1415926535897932."
|
|
}
|
|
}
|
|
|
|
// Actor intrinsic documentation
|
|
def actor_docs = {
|
|
"$me": {
|
|
signature: "$me",
|
|
description: "The address of this actor."
|
|
},
|
|
"$send": {
|
|
signature: "$send(address, message)",
|
|
description: "Send a message to another actor."
|
|
},
|
|
"$start": {
|
|
signature: "$start(script, env)",
|
|
description: "Start a new actor from a script path."
|
|
},
|
|
"$stop": {
|
|
signature: "$stop()",
|
|
description: "Stop this actor."
|
|
},
|
|
"$delay": {
|
|
signature: "$delay(milliseconds)",
|
|
description: "Delay processing for a number of milliseconds."
|
|
},
|
|
"$receiver": {
|
|
signature: "$receiver(function)",
|
|
description: "Set the message receiver function for this actor."
|
|
},
|
|
"$clock": {
|
|
signature: "$clock(interval, message)",
|
|
description: "Send a message to self at regular intervals."
|
|
},
|
|
"$portal": {
|
|
signature: "$portal(name)",
|
|
description: "Create a named portal for inter-actor communication."
|
|
},
|
|
"$contact": {
|
|
signature: "$contact(portal_name)",
|
|
description: "Connect to a named portal."
|
|
},
|
|
"$couple": {
|
|
signature: "$couple(address)",
|
|
description: "Couple with another actor for lifecycle management."
|
|
},
|
|
"$unneeded": {
|
|
signature: "$unneeded(function)",
|
|
description: "Set a function to be called when this actor is no longer needed."
|
|
},
|
|
"$connection": {
|
|
signature: "$connection(address)",
|
|
description: "Establish a connection with another actor."
|
|
},
|
|
"$time_limit": {
|
|
signature: "$time_limit(milliseconds)",
|
|
description: "Set a time limit for this actor's execution."
|
|
}
|
|
}
|
|
|
|
// Provide hover info for a token.
|
|
var hover = function(doc, line, col, token_at) {
|
|
var tok = token_at(doc, line, col)
|
|
var info = null
|
|
var name = null
|
|
var _i = 0
|
|
var _j = 0
|
|
var scope = null
|
|
var v = null
|
|
|
|
if (tok == null) {
|
|
return null
|
|
}
|
|
|
|
// Check intrinsic functions
|
|
if (tok.kind == "name" && tok.value != null) {
|
|
name = tok.value
|
|
info = intrinsic_docs[name]
|
|
if (info != null) {
|
|
return {
|
|
contents: {
|
|
kind: "markdown",
|
|
value: `**${info.signature}**\n\n${info.description}`
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// Check actor intrinsics ($name)
|
|
if (tok.value != null && starts_with(tok.value, "$")) {
|
|
info = actor_docs[tok.value]
|
|
if (info != null) {
|
|
return {
|
|
contents: {
|
|
kind: "markdown",
|
|
value: `**${info.signature}**\n\n${info.description}`
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// Check keywords
|
|
if (tok.kind == "var" || tok.kind == "def") {
|
|
return {
|
|
contents: {
|
|
kind: "markdown",
|
|
value: (tok.kind == "var")
|
|
? "**var** — Declare a mutable variable."
|
|
: "**def** — Declare a constant."
|
|
}
|
|
}
|
|
}
|
|
|
|
if (tok.kind == "disrupt") {
|
|
return {
|
|
contents: {
|
|
kind: "markdown",
|
|
value: "**disrupt** — Raise an error. Use with **disruption** block to handle errors."
|
|
}
|
|
}
|
|
}
|
|
|
|
if (tok.kind == "disruption") {
|
|
return {
|
|
contents: {
|
|
kind: "markdown",
|
|
value: "**disruption** — Error handling block. Catches errors raised by **disrupt**."
|
|
}
|
|
}
|
|
}
|
|
|
|
// User variable: show declaration info from scope
|
|
if (tok.kind == "name" && tok.value != null && doc.ast != null && doc.ast.scopes != null) {
|
|
_i = 0
|
|
while (_i < length(doc.ast.scopes)) {
|
|
scope = doc.ast.scopes[_i]
|
|
if (scope.vars != null) {
|
|
_j = 0
|
|
while (_j < length(scope.vars)) {
|
|
v = scope.vars[_j]
|
|
if (v.name == tok.value) {
|
|
return {
|
|
contents: {
|
|
kind: "markdown",
|
|
value: (v.is_const == true)
|
|
? `**def** ${v.name}`
|
|
: `**var** ${v.name}`
|
|
}
|
|
}
|
|
}
|
|
_j = _j + 1
|
|
}
|
|
}
|
|
_i = _i + 1
|
|
}
|
|
}
|
|
|
|
return null
|
|
}
|
|
|
|
return {
|
|
hover: hover,
|
|
intrinsic_docs: intrinsic_docs,
|
|
actor_docs: actor_docs
|
|
}
|