Use star for compile-time generic parameters

This commit is contained in:
root committed 2026-10-15 01:41:05 +00:00
1 parent 0d43f46803
commit fe463c05cc
27 files changed
+125 -77

No files matched your search

+3 -3
View File
@@ -90,7 +90,7 @@ type Count = s64
var count := Count(4)
```
An alias to an array, function type, `module`, or `void` has no constructor call. `any` and dependent `value::type` expressions require a generic function context and cannot be closed top-level aliases.
An alias to an array, function type, `module`, or `void` has no constructor call. `*` and dependent `value::type` expressions require a generic function context and cannot be closed top-level aliases.
An alias cannot conflict with a built-in type, struct, function, handler, public standard-library name, or another alias.
@@ -200,7 +200,7 @@ Overload identity is the function name plus canonical parameter types and the va
The compiler ranks matching calls in this order:
1. exact concrete parameters;
2. an `any` specialization without construction;
2. a `*` specialization without construction;
3. fixed parameters with declared construction;
4. variadic parameters.
@@ -250,7 +250,7 @@ A struct receives a generated constructor in field order. User functions can add
Constructor defaults and omitted call arguments do not change the Wasm call ABI. Copied DValue `none` uses Wasm core ABI 26. Future ABI changes must use a new ABI version.
`any` is compile-time polymorphism. It has no runtime representation. In a generic function, `parameter::type` names the concrete static type bound to an earlier `any` parameter. Use it for a later parameter or the function result. The compiler rejects the removed `type(parameter)` spelling.
`*` is the compile-time generic marker. It has no runtime representation. In a generic function, `parameter::type` names the concrete static type bound to an earlier `*` parameter. Use it for a later parameter or the function result. The compiler rejects the removed `type(parameter)` spelling.
## 9. Collections and aggregates
+7 -3
View File
@@ -22,7 +22,7 @@
"as"
],
"genericTypes": [
"any"
"*"
],
"literals": [
"false",
@@ -395,8 +395,12 @@
"match": "(?<![A-Za-z0-9_])(?:module|string|bool|dval|void|f32|f64|s16|s32|s64|u16|u32|u64|s8|u8)(?![A-Za-z0-9_])"
},
{
"name": "storage.type.generic.capy",
"match": "(?<![A-Za-z0-9_])(?:any)(?![A-Za-z0-9_])"
"match": "(?<=:)\\s*(\\*)(?=\\s*[,)=])",
"captures": {
"1": {
"name": "storage.type.generic.capy"
}
}
},
{
"name": "entity.name.type.capy",
+10
View File
@@ -63,6 +63,16 @@ assertScope('print("capy") // note', "capy", "string.quoted.double.capy");
assertScope('print("capy") // note', "note", "comment.line.double-slash.capy");
assertScope("var value : u32 = 42", "42", "constant.numeric.integer.capy");
assertScope("print(value)", "print", "entity.name.function.call.capy");
for (const line of ["function same(first : *, second : first::type) first::type", "function same(first:*) first::type"]) {
assertScope(line, "*", "storage.type.generic.capy");
assertScope(line, "::", "keyword.operator.scope.capy");
}
for (const line of ["var product := left * right", "var product := left*right", "print({product: left * right})"]) {
const result = assertScope(line, "*", "keyword.operator.arithmetic.capy");
assert.ok(!scopesFor(result, line, "*").includes("storage.type.generic.capy"));
}
const ordinaryName = "var any := 1";
assert.ok(!scopesFor(tokenize(ordinaryName), ordinaryName, "any").includes("storage.type.generic.capy"));
for (const line of [
'<><p title="<?= caption ?>">Hello <?= value ?></p></>',
+2 -2
View File
@@ -14,7 +14,7 @@ function test(x : s32, y : s32) s32 { // overload identity: test+s32,s32
}
// polymorphic, instantiated at compile time if not already in namespace
function test(x : any) x::type { // compile-time any is specialized and cached by its concrete parameter type
function test(x : *) x::type { // The compiler specializes and caches this function by its concrete parameter type.
return x*x // specialization fails at the callsite if * is not defined for x::type
}
@@ -70,7 +70,7 @@ function print(xa : s32) {
print("Hello World ", a) // pattern matching tries to find an exact match, if not found, it will try to find the best match that has implicit "as" conversions
// Deferred until after compiler phase 3: this requires partial compilation into a bounded compile-time workspace.
function meta_programming_example(myvar : any) {
function meta_programming_example(myvar : *) {
#compile { // this will be executed at compile time, and can be used to generate code, or perform compile time calculations
print("Polymorphic: ", myvar::type::type_name) // :: denotes type introspection and meta information about a variable
// there can be arbitrary number of #compile and #callsite blocks in a function, and they will be executed in order of appearance
+1 -1
View File
@@ -53,7 +53,7 @@ f84060af8de69766ce434a78ada90d732fe2e182b55f34f933ca4e276b5f3208 site_tests_cap
05a9edb689e63226ad056c845375563642f61fe404c3ee772c02cee3646083d0 site_tests_capy-cross-target.capy.wasm
dc5ba29db10e29ca2dd43ceb855b4593ec4d7682b7e3d0649bdeb0eb820f1cec site_tests_capy-cross-target.capy.wasm.source-map
25d16c1b0eb1741ccfe495acd60529a121db3d4fbc0f194e0d1a44d40deb4bdc site_tests_capy-crypto-random.capy.wasm
5fa47388e74ae09b67f448403e0c6d78f57f5ea5736e974f4bc733f1d488f4d0 site_tests_capy-crypto-random.capy.wasm.source-map
768495624e4146c446ddffbb71f2b285df46372bb3818400ee3eb479a0ddea31 site_tests_capy-crypto-random.capy.wasm.source-map
556fc959eeec32274324c31f82cd1b8fff9e4dca75ed1e2a378f0e77513dbb19 site_tests_capy-csrf.capy.wasm
2b2c833274803ca7eafeb0a01d4f907eebcc80a49324282ffc0427c20fde1f53 site_tests_capy-csrf.capy.wasm.source-map
52a39c6bccfcec345790452a4e1f71f34787a1f5082db84a841a231cd9f6c181 site_tests_capy-current-request.capy.wasm
+4 -2
View File
@@ -56,7 +56,9 @@ def authoritative_words() -> dict[str, list[str]]:
operator_words = {"as"}
keywords -= operator_words
generic_types = set(re.findall(r"`(any)`", section(spec, "8. Functions, overloads, and constructors")))
generic_types = set(re.findall(r"`(\*)`", section(spec, "8. Functions, overloads, and constructors")))
if generic_types != {"*"}:
raise RuntimeError("missing generic marker in the specification")
literals = set(re.findall(r"`(none)`", section(spec, "1. Source files and tokens"))) | {"true", "false"}
reserved = set(re.findall(r"`(emit)`", section(spec, "1. Source files and tokens")))
@@ -223,7 +225,7 @@ def grammar(words: dict[str, list[str]]) -> dict:
]},
"types": {"patterns": [
{"name": "support.type.builtin.capy", "match": word_pattern(words["types"])},
{"name": "storage.type.generic.capy", "match": word_pattern(words["genericTypes"])},
{"match": r"(?<=:)\s*(\*)(?=\s*[,)=])", "captures": {"1": {"name": "storage.type.generic.capy"}}},
{"name": "entity.name.type.capy", "match": r"(?<![A-Za-z0-9_])[A-Z][A-Za-z0-9_]*"},
]},
"constants": {"patterns": [{"name": "constant.language.capy", "match": word_pattern(words["literals"])}]},
+2 -1
View File
@@ -12,7 +12,8 @@
directive: { pattern: /#(?:callsite|compile|exports|import)\b/, alias: 'keyword' },
'handler-name': { pattern: /(\bfunction\s+)[A-Za-z_]\w*(?:\s*:\s*[A-Za-z_]\w*)?(?=\s*\()/, lookbehind: true, alias: 'function' },
keyword: /\b(?:break|continue|else|for|function|host|if|return|struct|trace|type|var|while|as|capture|export)\b/,
'class-name': /\b(?:any|bool|dval|f32|f64|module|s8|s16|s32|s64|u8|u16|u32|u64|string|void)\b/,
'generic-type': { pattern: /(:\s*)\*(?=\s*[,)=])/, lookbehind: true, alias: 'class-name' },
'class-name': /\b(?:bool|dval|f32|f64|module|s8|s16|s32|s64|u8|u16|u32|u64|string|void)\b/,
boolean: /\b(?:true|false)\b/,
constant: /\bnone\b/,
function: /\b[A-Za-z_]\w*(?=\s*\()/,
+24 -19
View File
@@ -164,9 +164,9 @@ int main()
assert(capy::wasm::validate_bearer_unit(defaults.wasm, {.bearer_abi_version = "11"}).valid);
assert(defaults.source_map.find("\t5\t") != std::string::npos);
const auto dependent_type = capy::compile_bearer_unit(
"function f(min : any, max : min::type) min::type { -> min }\n"
"function legacy(value : any) value::type { -> value }\n"
"function CLI(request : dval) { var value := f(1, 2); print(value, legacy(4)) }\n", options);
"function f(min : *, max : min::type) min::type { -> min }\n"
"function identity(value : *) value::type { -> value }\n"
"function CLI(request : dval) { var value := f(1, 2); var dynamic : dval = {value: 4}; print(value, identity(dynamic), identity(-4 * 2), !false) }\n", options);
assert(capy::wasm::validate_bearer_unit(dependent_type.wasm, {.bearer_abi_version = "11"}).valid);
const auto reflection = capy::compile_bearer_unit(
"struct Reflected { count : s32 }\n"
@@ -180,10 +180,15 @@ int main()
assert(metadata_only_bytes.find("MetadataOnly") != std::string::npos && metadata_only_bytes.find("count") != std::string::npos);
assert(metadata_only_bytes.find("bearer_capy_reflect_struct") == std::string::npos);
for (const auto& [source, expected] : {
std::pair{"function f(min : any, max : min::type) min::type { -> min }\nfunction CLI(request : dval) { f(1, \"x\") }\n", "no overload f"},
std::pair{"function f(min : *, max : min::type) min::type { -> min }\nfunction CLI(request : dval) { f(1, \"x\") }\n", "no overload f"},
std::pair{"function CLI(request : dval) { gen_noise(s32(0), s32(1), u64(1), u64(2)) }\n", "no overload __gen_noise"},
std::pair{"function f(min : s32, max : min::type) s32 { -> min }\n", "earlier any parameter"},
std::pair{"function f(min : any, max : later::type) min::type { -> min }\n", "unknown or forward parameter"},
std::pair{"function removed(value : any) value::type { -> value }\n", "unknown type 'any'"},
std::pair{"function removed(value : any) {}\n", "unknown type 'any'"},
std::pair{"function invalid() * { -> 1 }\n", "unknown type '*'"},
std::pair{"function CLI(request : dval) { var invalid : * = 1 }\n", "unknown type '*'"},
std::pair{"function invalid(value : as *) {}\n", "requires a concrete named type constructor"},
std::pair{"function f(min : s32, max : min::type) s32 { -> min }\n", "earlier * parameter"},
std::pair{"function f(min : *, max : later::type) min::type { -> min }\n", "unknown or forward parameter"},
std::pair{"function f(value : s32) type(value) { -> value }\n", "type(value) was removed"},
std::pair{"function CLI(request : dval) { print(s32(1)::size) }\n", "value::size requires a struct"},
std::pair{"function CLI(request : dval) { print(s32(1)::items) }\n", "value::items requires a struct"},
@@ -287,7 +292,7 @@ int main()
std::pair{"function RENDER(value : s32 = 1) {}\n", "Bearer handlers cannot use default parameters"},
std::pair{"function wrong(value : s32 = 1.5) {}\nfunction CLI(request : dval) {}\n", "default parameter literal must have type s32"},
std::pair{"function wrong(value : s32 = {}) {}\nfunction CLI(request : dval) {}\n", "default parameter literal must have type s32"},
std::pair{"function generic(value : any = 1) value::type { -> value }\nfunction CLI(request : dval) {}\n", "generic functions cannot use default parameters"},
std::pair{"function generic(value : * = 1) value::type { -> value }\nfunction CLI(request : dval) {}\n", "generic functions cannot use default parameters"},
std::pair{"function values(...value : s32 = 1) {}\nfunction CLI(request : dval) {}\n", "variadic parameter cannot have a default value"},
std::pair{"function CLI(request : dval) { var value := function(input : s32 = 1) s32 { -> input } }\n", "anonymous functions cannot use default parameters"},
std::pair{"function CLI(request : dval) { var value : function(input : s32 = 1) s32 = function(input : s32) s32 { -> input } }\n", "function types cannot use default parameters"},
@@ -537,7 +542,7 @@ int main()
const std::string component_render_result_bytes(component_render_result.wasm.begin(), component_render_result.wasm.end());
assert(component_render_result_bytes.find("bearer_dv_component_render") != std::string::npos);
const auto generic_before_dval = capy::compile_bearer_unit(
"function choose(value : any) string { -> \"generic\" }\nfunction choose(value : as dval) string { -> \"dval\" }\nfunction CLI(request : dval) { print(choose(1)) }\n", options);
"function choose(value : *) string { -> \"generic\" }\nfunction choose(value : as dval) string { -> \"dval\" }\nfunction CLI(request : dval) { print(choose(1)) }\n", options);
const std::string generic_before_dval_bytes(generic_before_dval.wasm.begin(), generic_before_dval.wasm.end());
assert(generic_before_dval_bytes.find("bearer_dv_s32") == std::string::npos);
for (const char* source : {
@@ -550,15 +555,15 @@ int main()
try { capy::compile_bearer_unit("function CLI(request : dval) { if var wrong : bool = 1 {} }\n", options); assert(false); }
catch (const capy::Error& error) { assert(error.message.find("expected bool, found s64") != std::string::npos); }
constexpr std::string_view generic_source = "function identity(value : any) value::type { -> value }\n"
"function choose(value : any) value::type { -> value }\n"
constexpr std::string_view generic_source = "function identity(value : *) value::type { -> value }\n"
"function choose(value : *) value::type { -> value }\n"
"function choose(value : s32) value::type { -> value + 1 }\n"
"function countdown(value : any) value::type { if value == 0 { return value }; return countdown(value - 1) }\n"
"function countdown(value : *) value::type { if value == 0 { return value }; return countdown(value - 1) }\n"
"function CLI(request : dval) { print(identity(7), choose(4), countdown(3), identity([clone(\"first\"), clone(\"x\")])[1], bool(2)) }\n";
const auto generic = capy::compile_bearer_unit(generic_source, options);
assert(capy::wasm::validate_bearer_unit(generic.wasm, {.bearer_abi_version = "11"}).valid);
const auto generic_method = capy::compile_bearer_unit(
"function same(value : any) value::type { -> value }\nfunction CLI(request : dval) { print((7).same()) }\n", options);
"function same(value : *) value::type { -> value }\nfunction CLI(request : dval) { print((7).same()) }\n", options);
assert(capy::wasm::validate_bearer_unit(generic_method.wasm, {.bearer_abi_version = "11"}).valid);
assert(generic_method.source_map.find("F\t1\tnative-test.capy\n") != std::string::npos);
const auto converted_parameters = capy::compile_bearer_unit(
@@ -633,8 +638,8 @@ int main()
assert(module_exports.source_map.find("F\t1\tnative-test.capy\n") != std::string::npos);
assert(capy::wasm::validate_bearer_unit(module_exports.wasm, {.bearer_abi_version = "11"}).valid);
const auto generic_exports = capy::compile_bearer_unit(
"#exports same\nfunction same(first : any, second : first::type) first::type { -> second }\n", options);
assert(generic_exports.function_exports == std::vector<std::string>({"capy function same(any,$0::type):$0::type"}));
"#exports same\nfunction same(first : *, second : first::type) first::type { -> second }\n", options);
assert(generic_exports.function_exports == std::vector<std::string>({"capy function same(*,$0::type):$0::type"}));
const auto type_exports = capy::compile_bearer_unit(
"#exports echo, MyType, Alias\nstruct MyType { value : s32 }\ntype Alias = MyType\nfunction echo(value : dval) dval { -> value }\nfunction MyType(value : dval) MyType { -> MyType(1) }\n", options);
assert(type_exports.custom_exports == std::vector<std::string>({"echo"}));
@@ -664,7 +669,7 @@ int main()
assert(module_call.source_map.find("F\t2\tcapy://stdlib.capy\n") != std::string::npos);
const auto module_passthrough = capy::compile_bearer_unit(
"function pass(value : module) module { -> value }\n"
"function identity(value : any) value::type { -> value }\n"
"function identity(value : *) value::type { -> value }\n"
"function CLI(request : dval) { var loaded : module = unit_load(\"child.capy\"); var returned : module = pass(loaded); identity(returned).call(\"invoke\") }\n", options);
assert(capy::wasm::validate_bearer_unit(module_passthrough.wasm, {.bearer_abi_version = "11"}).valid);
capy::CompileOptions import_options = options;
@@ -689,7 +694,7 @@ int main()
std::pair{"function bad(value : as [s32]) {}\n", "requires a concrete named type constructor"},
std::pair{"function CLI(request : dval) { var callback : function(value : as s64) s64 = function(value : s64) s64 { -> value } }\n", "only variadic function-type parameters may request conversion"},
std::pair{"function CLI(request : dval) { var value := 1 as s64 }\n", "call the target type constructor instead"},
std::pair{"struct Point { x : s32 }\nfunction string(value : any) string { -> value + \"!\" }\nfunction show(value : as string) {}\nfunction CLI(request : dval) { show(Point(1)) }\n", "string operators require string operands"},
std::pair{"struct Point { x : s32 }\nfunction string(value : *) string { -> value + \"!\" }\nfunction show(value : as string) {}\nfunction CLI(request : dval) { show(Point(1)) }\n", "string operators require string operands"},
std::pair{"function s32(value : string) string { -> value }\nfunction CLI(request : dval) {}\n", "constructor 's32' must return s32"},
std::pair{"struct Point { x : s32 }\nfunction Point(x : s32) Point { -> Point(x) }\nfunction CLI(request : dval) {}\n", "duplicates the generated Point field constructor"},
std::pair{"function CLI(request : dval) { var loaded : module = unit_load(\"x\"); var values := [loaded] }\n", "module is opaque and cannot be stored in array layouts"},
@@ -924,7 +929,7 @@ int main()
std::pair{"function sqlite_connect(path : string) u64 { -> u64(0) }\nfunction CLI(request : dval) {}\n", "reserved by the Capy standard library"},
std::pair{"function CLI(request : dval) { var callback : function(__bearer_value : s32) s32 = function(__bearer_value : s32) s32 { -> __bearer_value } }\n", "__bearer_* names are reserved for the Capy standard library"},
std::pair{"function CLI(request : dval) { for value, __bearer_key := dval({}) { value } }\n", "__bearer_* names are reserved for the Capy standard library"},
std::pair{"function duplicate(value : any) value::type { -> value }\nfunction duplicate(value : any) value::type { -> value }\nfunction CLI(request : dval) {}\n", "duplicate overload duplicate(any)"},
std::pair{"function duplicate(value : *) value::type { -> value }\nfunction duplicate(value : *) value::type { -> value }\nfunction CLI(request : dval) {}\n", "duplicate overload duplicate(*)"},
})
{
try
@@ -961,8 +966,8 @@ int main()
catch (const capy::Error& error) { assert(error.message.find(expected) != std::string::npos); }
}
for (const auto source : {
"function square(value : any) value::type { -> value * value }\nfunction CLI(request : dval) { square(clone(\"x\")) }\n",
"function choose(a : any, b : s32) a::type { -> a }\nfunction choose(a : s32, b : any) b::type { -> b }\nfunction CLI(request : dval) { choose(1, 1) }\n",
"function square(value : *) value::type { -> value * value }\nfunction CLI(request : dval) { square(clone(\"x\")) }\n",
"function choose(a : *, b : s32) a::type { -> a }\nfunction choose(a : s32, b : *) b::type { -> b }\nfunction CLI(request : dval) { choose(1, 1) }\n",
"function incomplete(value : bool) s32 { if value { return 1 } }\nfunction CLI(request : dval) { print(incomplete(false)) }\n",
"function CLI(request : dval) { print(9223372036854775808) }\n",
"function CLI(request : dval) { print(-9223372036854775809) }\n",
+12 -4
View File
@@ -210,14 +210,16 @@ int main(int argc, char** argv)
assert(import->path == "child.capy" && import->alias == "child");
}
{
Program p = parse("function value(min : any, max : min::type) min::type { -> min }\n", "dependent.capy");
Program p = parse("function value(min : *, max : min::type) min::type { -> min }\n", "dependent.capy");
auto* function = static_cast<Function*>(p.items[0]);
assert(function->parameters[0].type_expr->kind == ExprKind::Name);
assert(static_cast<Name*>(function->parameters[0].type_expr)->value == "*");
assert(type_name(*function->parameters[1].type_expr) == "min::type" && type_name(*function->return_type) == "min::type");
auto* parameter_type = static_cast<ScopeLookup*>(function->parameters[1].type_expr);
assert(static_cast<Name*>(parameter_type->value)->value == "min" && parameter_type->member == "type");
bool rejected = false;
try {
Program removed = parse("function value(min : any, max : type(min)) type(min) { -> min }\n", "removed.capy");
Program removed = parse("function value(min : *, max : type(min)) type(min) { -> min }\n", "removed.capy");
type_name(*static_cast<Function*>(removed.items[0])->parameters[1].type_expr);
}
catch (const Error&) { rejected = true; }
@@ -269,7 +271,7 @@ int main(int argc, char** argv)
expect_error("function CLI(request : dval) { for value in [1] {} }\n", "old loop syntax is not supported. Use ':=' after the loop bindings");
expect_error("function CLI(request : dval) { for value, value := [1] {} }\n", "loop bindings must have different names");
expect_error("trace function bad() string {}\n", "trace modifier applies only to host function declarations");
expect_error("function bad(value : any, value : any) value::type { value }\n", "function parameter 'value' is already declared");
expect_error("function bad(value : *, value : *) value::type { value }\n", "function parameter 'value' is already declared");
try
{
parse("\"broken", "bad.capy");
@@ -313,7 +315,7 @@ int main(int argc, char** argv)
expect_error("function CLI(request : dval) { #exports first }\n", "#exports is a top-level directive");
expect_error("#import child.capy as child\n", "#import requires a string path");
expect_error("function CLI(request : dval) { #import \"child.capy\" as child }\n", "#import is a top-level directive");
expect_error("function meta(x : any) { #compile { emit(x) } }\n", "#compile compile-time metaprogramming is deferred beyond Capy phase 3");
expect_error("function meta(x : *) { #compile { emit(x) } }\n", "#compile compile-time metaprogramming is deferred beyond Capy phase 3");
expect_error("#wat", "unknown compiler directive #wat");
expect_error("@", "unexpected character '@'");
expect_error("1s32", "numeric suffixes were removed");
@@ -367,6 +369,12 @@ int main(int argc, char** argv)
const std::string expected = "function f(n : s32) s32\n{\n\tvar a := -1;\n\tvar b := n * -2;\n\tif !(a < b)\n\t{\n\t\treturn -a\n\t}\n\t;\n\tfor i := 0..n\n\t{\n\t\ta = a + i\n\t}\n\t;\n\t-> a - b\n}\n";
assert(format_source(source) == expected);
assert(format_source(expected) == expected);
const std::string generic = "function same(first:*,second:first::type) first::type { -> first }\nfunction identity(value:*) value::type { -> value }\n";
const std::string generic_formatted = format_source(generic);
assert(generic_formatted.find("first : *, second : first::type") != std::string::npos);
assert(generic_formatted.find("value : *) value::type") != std::string::npos);
assert(format_source(generic_formatted) == generic_formatted);
assert(parse(generic_formatted).items.size() == 2);
const std::string annotations = "struct Pair { x : s32\ny : s32 }\nfunction f(n : as s32) { var x : dval = {key: -1}\nprint(key: x) }\n";
const std::string formatted = format_source(annotations);
assert(formatted.find("x : s32") != std::string::npos);
+14
View File
@@ -3,6 +3,10 @@ const assert = require('node:assert/strict');
const fs = require('node:fs');
const path = require('node:path');
const Prism = require('../site/assets/highlight.js');
const vm = require('node:vm');
if (process.argv.includes('--source')) {
vm.runInNewContext(fs.readFileSync(path.join(__dirname, 'site-highlighter/capy.js'), 'utf8'), { Prism });
}
function text(html) {
return html.replace(/<[^>]*>/g, '').replace(/&lt;/g, '<').replace(/&gt;/g, '>').replace(/&quot;/g, '"').replace(/&amp;/g, '&');
@@ -18,6 +22,16 @@ function check(source, language, tokens = []) {
check('#import "/lib/auth.capy" as auth\n#exports current_user\nfunction current_user(input : dval) dval { -> {id: 7, name: "Ada"} }', 'capy', ['directive', 'keyword', 'class-name', 'property', 'function']);
check('function COMPONENT: CARD(props : dval) { var title := props.title?; print(title) }', 'capy', ['handler-name', 'operator']);
check('function label(name : as string, request : capture dval) string { -> name }', 'capy', ['keyword', 'class-name']);
for (const source of ['function same(first : *, second : first::type) first::type', 'function same(first:*) first::type']) {
check(source, 'capy', ['generic-type', 'class-name']);
assert.match(Prism.highlight(source, Prism.languages.capy, 'capy'), /class="token generic-type class-name">\*<\/span>/);
}
for (const source of ['var product := left * right', 'var product := left*right', 'print({product: left * right})']) {
const html = Prism.highlight(source, Prism.languages.capy, 'capy');
assert.match(html, /class="token operator">\*<\/span>/);
assert.doesNotMatch(html, /generic-type/);
}
assert.doesNotMatch(Prism.highlight('var any := 1', Prism.languages.capy, 'capy'), /class-name|generic-type/);
check('// "quoted comment"\nprint("escaped \\"quote\\"", 1.5, true, none)', 'capy', ['comment', 'string', 'number', 'boolean']);
check('print(<><article class="card"><h1><?= props.title ?></h1><?: props.body ?></article></>)', 'capy', ['html-literal', 'tag', 'capy-field']);
check('print(<><section><?= if ready { -> <><b>yes</b></> } else { -> "no" } ?></section></>)', 'capy', ['html-literal', 'keyword']);
+2 -1
View File
@@ -26,7 +26,8 @@ Prism.languages.ini={comment:{pattern:/(^[ \f\t\v]*)[#;][^\n\r]*/m,lookbehind:!0
directive: { pattern: /#(?:callsite|compile|exports|import)\b/, alias: 'keyword' },
'handler-name': { pattern: /(\bfunction\s+)[A-Za-z_]\w*(?:\s*:\s*[A-Za-z_]\w*)?(?=\s*\()/, lookbehind: true, alias: 'function' },
keyword: /\b(?:break|continue|else|for|function|host|if|return|struct|trace|type|var|while|as|capture|export)\b/,
'class-name': /\b(?:any|bool|dval|f32|f64|module|s8|s16|s32|s64|u8|u16|u32|u64|string|void)\b/,
'generic-type': { pattern: /(:\s*)\*(?=\s*[,)=])/, lookbehind: true, alias: 'class-name' },
'class-name': /\b(?:bool|dval|f32|f64|module|s8|s16|s32|s64|u8|u16|u32|u64|string|void)\b/,
boolean: /\b(?:true|false)\b/,
constant: /\bnone\b/,
function: /\b[A-Za-z_]\w*(?=\s*\()/,
+2 -2
View File
@@ -1170,7 +1170,7 @@ function COMPONENT(props : dval)
{
found = true
}
if consider(tokens, "/doc/guide/values-and-types/", "3. Types", "Learn Capy", "3. Types\nEvery Capy value has a type. The compiler checks types before the program runs. It usually infers the type of a local value.\n\n## Integers\n\nAn integer literal has type `s64` when no other type is stated:\n\n```capy\nfunction RENDER()\n{\n var answer := 42\n print(answer, \"\\n\")\n}\n\n```\n\n**Output**\n\n```text\n42\n\n```\n\nState the type on the local, or construct the value explicitly:\n\n```capy\nfunction RENDER()\n{\n var signed : s64 = 8\n var inferred_signed := s64(9)\n var unsigned : u64 = 10\n var inferred_unsigned := u64(11)\n print(signed, \" \", inferred_signed, \" \", unsigned, \" \", inferred_unsigned, \"\\n\")\n}\n\n```\n\n\nBoth forms produce the stated integer type. `var signed : s64 = s64(8)` also compiles, but the constructor repeats the annotation.\n\nParameters, function results, assignments, typed arrays, struct fields, and the other operand in an expression can also state the integer type. Thus, a function that accepts `u64` can receive the plain literal `8`. An unconstrained literal remains `s64`.\n\nArithmetic requires operands of the same type. Use a constructor when the surrounding code does not state the required type.\n\n## Booleans and floating-point numbers\n\nA `bool` is either `true` or `false`. Conditions require a boolean value.\n\n```capy\nfunction RENDER()\n{\n var enabled := true\n var ratio := 2.5\n print(enabled, \" \", ratio, \"\\n\")\n}\n\n```\n\n\nA decimal point or exponent makes an `f64` literal.\n\n## Strings\n\nA `string` stores bytes:\n\n```capy\nfunction RENDER()\n{\n var name := \"Ada\"\n var empty := \"\"\n print(name, empty, \"\\n\")\n}\n\n```\n\n\nAn empty string is still a string value. It is not missing data.\n\n## Arrays and structs\n\nAn array contains values of one type:\n\n```capy\nfunction RENDER()\n{\n var names := [\"Ada\", \"Grace\"]\n print(names[0], \"\\n\")\n}\n\n```\n\n\nA struct gives names to fixed fields:\n\n```capy\nstruct Point\n{\n x : s32\n y : s32\n}\n\nfunction RENDER()\n{\n var point := Point(3, 4)\n print(point.x, \" \", point.y, \"\\n\")\n}\n\n```\n\n\n## Copy or share\n\nNumbers and booleans are copied: after `var b := a`, changing `b` leaves `a` alone. Strings are values too. A string never changes in place, so it makes no difference whether two names share one.\n\nArrays, structs, and dvals are objects. `var b := a` makes `b` a second name for the same object, and so do parameters, return values, closure captures, and member reads. A change made through one name shows through all of them. When you need a separate copy, `clone(value)` makes one.\n\nA variable can be pointed at another object with `=`. A parameter cannot.\n\nThe collections chapter covers arrays and structs in detail, the dynamic values chapter covers `dval`.\n\n## Numeric functions\n\nUse the `math` functions for floating-point calculations and numeric bounds. Use the `bits` functions for integer masks, shifts, rotations, counts, and bit reinterpretation.\n\nSee the `math` function reference for floating-point operations and predicates. See the `bits` function reference for integer bit operations and floating-point bit reinterpretation.\n\n## Dynamic values and none\n\nA `dval` holds data whose shape is known only at run time. The `none` value represents missing dynamic data:\n\n```capy\nfunction RENDER()\n{\n var profile := { name: \"Ada\" }\n var missing := none\n print(profile.name, \" \", missing?, \"\\n\")\n}\n\n```\n\n\n`none` is different from `\"\"`, `false`, an empty map, and an empty list. A `dval` is also an object that variables refer to, never a copy. The dynamic-values chapter explains mutation, safe reads, and conversions.\n\n## Type aliases and static type names\n\nA type alias gives another name to a type. It does not create a distinct type at runtime.\n\nUse `expression::type_name` to get the resolved static type of an expression. Capy evaluates the expression once.\n\n```capy\ntype Count = s64\n\nfunction RENDER()\n{\n var total : Count = 12\n var labels := [\"new\", \"done\"]\n print(total::type_name, \" \", labels::type_name, \"\\n\")\n}\n\n```\n\n**Output**\n\n```text\ns64 [string]\n\n```\n\n\nAn alias reports its target type. Arrays use `[item_type]`. Structs use their declared name. Function values use their complete function type.\n\nA `dval` expression reports `dval`, regardless of its current contents. Use `get_type_name(value)` to inspect the value stored inside a `dval`.\n\n## Struct field inspection\n\nStruct values have two additional reflection expressions:\n\n| Expression | Result | Meaning |\n| --- | --- | --- |\n| `value::size` | `s64` | The number of declared fields. This is not a byte size. |\n| `value::items` | `dval` | A new map of the current field values, keyed by field name. |\n\nEach `items` entry contains `value` and `type_name`. Use `fields.name.value` for a fixed field. Use `fields[key][\"value\"]` for a dynamic field namLine truncated
if consider(tokens, "/doc/guide/values-and-types/", "3. Types", "Learn Capy", "3. Types\nEvery Capy value has a type. The compiler checks types before the program runs. It usually infers the type of a local value.\n\n## Integers\n\nAn integer literal has type `s64` when no other type is stated:\n\n```capy\nfunction RENDER()\n{\n var answer := 42\n print(answer, \"\\n\")\n}\n\n```\n\n**Output**\n\n```text\n42\n\n```\n\nState the type on the local, or construct the value explicitly:\n\n```capy\nfunction RENDER()\n{\n var signed : s64 = 8\n var inferred_signed := s64(9)\n var unsigned : u64 = 10\n var inferred_unsigned := u64(11)\n print(signed, \" \", inferred_signed, \" \", unsigned, \" \", inferred_unsigned, \"\\n\")\n}\n\n```\n\n\nBoth forms produce the stated integer type. `var signed : s64 = s64(8)` also compiles, but the constructor repeats the annotation.\n\nParameters, function results, assignments, typed arrays, struct fields, and the other operand in an expression can also state the integer type. Thus, a function that accepts `u64` can receive the plain literal `8`. An unconstrained literal remains `s64`.\n\nArithmetic requires operands of the same type. Use a constructor when the surrounding code does not state the required type.\n\n## Booleans and floating-point numbers\n\nA `bool` is either `true` or `false`. Conditions require a boolean value.\n\n```capy\nfunction RENDER()\n{\n var enabled := true\n var ratio := 2.5\n print(enabled, \" \", ratio, \"\\n\")\n}\n\n```\n\n\nA decimal point or exponent makes an `f64` literal.\n\n## Strings\n\nA `string` stores bytes:\n\n```capy\nfunction RENDER()\n{\n var name := \"Ada\"\n var empty := \"\"\n print(name, empty, \"\\n\")\n}\n\n```\n\n\nAn empty string is still a string value. It is not missing data.\n\n## Arrays and structs\n\nAn array contains values of one type:\n\n```capy\nfunction RENDER()\n{\n var names := [\"Ada\", \"Grace\"]\n print(names[0], \"\\n\")\n}\n\n```\n\n\nA struct gives names to fixed fields:\n\n```capy\nstruct Point\n{\n x : s32\n y : s32\n}\n\nfunction RENDER()\n{\n var point := Point(3, 4)\n print(point.x, \" \", point.y, \"\\n\")\n}\n\n```\n\n\n## Copy or share\n\nNumbers and booleans are copied: after `var b := a`, changing `b` leaves `a` alone. Strings are values too. A string never changes in place, so it makes no difference whether two names share one.\n\nArrays, structs, and dvals are objects. `var b := a` makes `b` a second name for the same object, and so do parameters, return values, closure captures, and member reads. A change made through one name shows through all of them. When you need a separate copy, `clone(value)` makes one.\n\nA variable can be pointed at another object with `=`. A parameter cannot.\n\nThe collections chapter covers arrays and structs in detail, the dynamic values chapter covers `dval`.\n\n## Numeric functions\n\nUse the `math` functions for floating-point calculations and numeric bounds. Use the `bits` functions for integer masks, shifts, rotations, counts, and bit reinterpretation.\n\nSee the `math` function reference for floating-point operations and predicates. See the `bits` function reference for integer bit operations and floating-point bit reinterpretation.\n\n## Dynamic values and none\n\nA `dval` holds data whose shape is known only at run time. The `none` value represents missing dynamic data:\n\n```capy\nfunction RENDER()\n{\n var profile := { name: \"Ada\" }\n var missing := none\n print(profile.name, \" \", missing?, \"\\n\")\n}\n\n```\n\n\n`none` is different from `\"\"`, `false`, an empty map, and an empty list. A `dval` is also an object that variables refer to, never a copy. The dynamic-values chapter explains mutation, safe reads, and conversions.\n\n## Type aliases and static type names\n\nA type alias gives another name to a type. It does not create a distinct type at runtime.\n\nUse `expression::type_name` to get the resolved static type of an expression. Capy evaluates the expression once.\n\n```capy\ntype Count = s64\n\nfunction RENDER()\n{\n var total : Count = 12\n var labels := [\"new\", \"done\"]\n print(total::type_name, \" \", labels::type_name, \"\\n\")\n}\n\n```\n\n**Output**\n\n```text\ns64 [string]\n\n```\n\n\nAn alias reports its target type. Arrays use `[item_type]`. Structs use their declared name. Function values use their complete function type.\n\nA `dval` expression reports `dval`, regardless of its current contents. Use `get_type_name(value)` to inspect the value stored inside a `dval`.\n\n## Struct field inspection\n\nStruct values have two additional reflection expressions:\n\n| Expression | Result | Meaning |\n| --- | --- | --- |\n| `value::size` | `s64` | The number of declared fields. This is not a byte size. |\n| `value::items` | `dval` | A new map of the current field values, keyed by field name. |\n\nEach `items` entry contains `value` and `type_name`. Use `fields.name.value` for a fixed field. Use `fields[key][\"value\"]` for a dynamic field namLine truncated
{
found = true
}
@@ -1178,7 +1178,7 @@ function COMPONENT(props : dval)
{
found = true
}
if consider(tokens, "/doc/guide/functions-and-closures/", "5. Functions", "Learn Capy", "5. Functions\nA function gives a name to a calculation. Parameters describe its input. The declared result type describes its output.\n\n## Define and call a function\n\n```capy\nfunction greet(name : capture string) string\n{\n -> \"Hello, \" + name\n}\n\nfunction RENDER()\n{\n var name := \"Ada\"\n print(greet(), \"\\n\")\n}\n\n```\n\n**Output**\n\n```text\nHello, Ada\n\n```\n\nThe `->` expression supplies the function result. Use `return` when a function must finish early.\n\n## Parameters and defaults\n\nParameters have names and types:\n\n```capy\nfunction label(name : string, suffix : string = \"!\") string\n{\n -> name + suffix\n}\n\nfunction RENDER()\n{\n print(label(\"Capy\"), \"\\n\")\n}\n\n```\n\n\n`label(\"Capy\")` uses the default suffix. Defaults are trailing literals. A direct call can omit them, but a function value keeps the full parameter list.\n\nCapy evaluates arguments once from left to right.\n\n## Capture parameters\n\nA capture parameter uses the caller's variable with the same name when the caller omits its argument. The first example captures `name`.\n\nWrite `name : capture Type` for an exact type match. Write `name : capture as Type` to permit one constructor conversion.\n\nCapture parameters follow all ordinary parameters, including parameters with defaults. The caller can also pass an explicit argument.\n\nA missing caller variable is a compile error. The diagnostic names the function and the capture parameter.\n\nA helper that uses request-dependent functions must declare `request : capture dval`. Each helper in a call chain needs that capture.\n\n```capy\nfunction set_title(title : string, request : capture dval)\n{\n request.page_title = title\n}\n```\n\nHandlers bind `request` implicitly. Exported `(dval) dval` functions also capture `request` implicitly. They need no explicit capture declaration.\n\n## Map entry arguments\n\nAn argument of the form `key: value` is a map entry. Adjacent map entries form one map argument:\n\n```capy\nfunction describe(name : string, options : dval = {}) string\n{\n -> name + \" \" + json_encode(options)\n}\n\nfunction RENDER()\n{\n print(describe(\"list\", page: 2, per_page: 20), \"\\n\")\n print(describe(\"list\",\n {\n page: 2,\n per_page: 20\n }\n ),\n \"\\n\"\n )\n}\n\n```\n\n**Output**\n\n```text\nlist {\"page\": 2.000000, \"per_page\": 20.000000}\nlist {\"page\": 2.000000, \"per_page\": 20.000000}\n\n```\n\n\nBoth calls pass the same map and compile to the same code. Use map entries for options and for the input of a unit call.\n\nA map entry does not name a parameter. `describe(name: \"list\")` passes one map, and the compiler reports that no overload accepts it. A key is an identifier or a string.\n\nAn ordinary argument ends the map. In `find(1, page: 2, true)` the call receives `1`, the map `{page: 2}`, and `true`. Two map parameters in sequence need braces for the second map. Struct constructors take ordinary arguments.\n\n## Overloads\n\nSeveral functions can have the same name when their parameter types differ:\n\n```capy\nfunction describe(value : s32) string\n{\n -> \"integer\"\n}\nfunction describe(value : string) string\n{\n -> \"string\"\n}\n\nfunction RENDER()\n{\n print(describe(42), \" \", describe(\"Ada\"), \"\\n\")\n}\n\n```\n\n\nThe argument types select the overload. A result type never selects one.\n\n## Conversion parameters\n\nA parameter declared with `as` permits one constructor conversion:\n\n```capy\nfunction show(value : as string)\n{\n print(value, \"\\n\")\n}\n\nfunction RENDER()\n{\n show(42)\n}\n\n```\n\n\nThe call behaves as if it passed `string(42)`. Capy does not chain several conversions.\n\n## Function values\n\nA function can be stored and called through a typed value:\n\n```capy\nfunction double(value : s32) s32\n{\n -> value * 2\n}\n\nfunction RENDER()\n{\n var operation : function(value : s32) s32 = double\n var answer := operation(21)\n print(answer, \"\\n\")\n}\n\n```\n\n\nA lambda defines a small function at its point of use:\n\n```capy\nfunction RENDER()\n{\n var add_one := function(value : s32) s32\n {\n -> value + 1\n }\n print(add_one(41), \"\\n\")\n}\n\n```\n\n\nA lambda can read outer variables. A captured number, boolean, or string is copied. A captured array, `dval`, or struct is the same object the outer code holds, so the closure can change its contents and the outer code sees the change. A capture cannot be reassigned.\n\n```capy\nfunction RENDER()\n{\n var offset := 2\n var values := [10]\n var update := function() s64\n {\n values.push(20)\n -> offset + length(values)\n }\n print(update(), \" \", values[1], \"\\n\")\n}\n\n```\n\n\n## Store a callback in a dynamic value\n\nA `dval` can store a named function or a closure for the rest of the request. Read it with its complete function type:\n\n```capy\nfunction add_one(value : s32) s32\n{\n -> value + 1\n}\n\nfunction RENDER()\n{\n vLine truncated
if consider(tokens, "/doc/guide/functions-and-closures/", "5. Functions", "Learn Capy", "5. Functions\nA function gives a name to a calculation. Parameters describe its input. The declared result type describes its output.\n\n## Define and call a function\n\n```capy\nfunction greet(name : capture string) string\n{\n -> \"Hello, \" + name\n}\n\nfunction RENDER()\n{\n var name := \"Ada\"\n print(greet(), \"\\n\")\n}\n\n```\n\n**Output**\n\n```text\nHello, Ada\n\n```\n\nThe `->` expression supplies the function result. Use `return` when a function must finish early.\n\n## Parameters and defaults\n\nParameters have names and types:\n\n```capy\nfunction label(name : string, suffix : string = \"!\") string\n{\n -> name + suffix\n}\n\nfunction RENDER()\n{\n print(label(\"Capy\"), \"\\n\")\n}\n\n```\n\n\n`label(\"Capy\")` uses the default suffix. Defaults are trailing literals. A direct call can omit them, but a function value keeps the full parameter list.\n\nCapy evaluates arguments once from left to right.\n\n## Capture parameters\n\nA capture parameter uses the caller's variable with the same name when the caller omits its argument. The first example captures `name`.\n\nWrite `name : capture Type` for an exact type match. Write `name : capture as Type` to permit one constructor conversion.\n\nCapture parameters follow all ordinary parameters, including parameters with defaults. The caller can also pass an explicit argument.\n\nA missing caller variable is a compile error. The diagnostic names the function and the capture parameter.\n\nA helper that uses request-dependent functions must declare `request : capture dval`. Each helper in a call chain needs that capture.\n\n```capy\nfunction set_title(title : string, request : capture dval)\n{\n request.page_title = title\n}\n```\n\nHandlers bind `request` implicitly. Exported `(dval) dval` functions also capture `request` implicitly. They need no explicit capture declaration.\n\n## Map entry arguments\n\nAn argument of the form `key: value` is a map entry. Adjacent map entries form one map argument:\n\n```capy\nfunction describe(name : string, options : dval = {}) string\n{\n -> name + \" \" + json_encode(options)\n}\n\nfunction RENDER()\n{\n print(describe(\"list\", page: 2, per_page: 20), \"\\n\")\n print(describe(\"list\",\n {\n page: 2,\n per_page: 20\n }\n ),\n \"\\n\"\n )\n}\n\n```\n\n**Output**\n\n```text\nlist {\"page\": 2.000000, \"per_page\": 20.000000}\nlist {\"page\": 2.000000, \"per_page\": 20.000000}\n\n```\n\n\nBoth calls pass the same map and compile to the same code. Use map entries for options and for the input of a unit call.\n\nA map entry does not name a parameter. `describe(name: \"list\")` passes one map, and the compiler reports that no overload accepts it. A key is an identifier or a string.\n\nAn ordinary argument ends the map. In `find(1, page: 2, true)` the call receives `1`, the map `{page: 2}`, and `true`. Two map parameters in sequence need braces for the second map. Struct constructors take ordinary arguments.\n\n## Overloads\n\nSeveral functions can have the same name when their parameter types differ:\n\n```capy\nfunction describe(value : s32) string\n{\n -> \"integer\"\n}\nfunction describe(value : string) string\n{\n -> \"string\"\n}\n\nfunction RENDER()\n{\n print(describe(42), \" \", describe(\"Ada\"), \"\\n\")\n}\n\n```\n\n\nThe argument types select the overload. A result type never selects one.\n\n## Conversion parameters\n\nA parameter declared with `as` permits one constructor conversion:\n\n```capy\nfunction show(value : as string)\n{\n print(value, \"\\n\")\n}\n\nfunction RENDER()\n{\n show(42)\n}\n\n```\n\n\nThe call behaves as if it passed `string(42)`. Capy does not chain several conversions.\n\n## Function values\n\nA function can be stored and called through a typed value:\n\n```capy\nfunction double(value : s32) s32\n{\n -> value * 2\n}\n\nfunction RENDER()\n{\n var operation : function(value : s32) s32 = double\n var answer := operation(21)\n print(answer, \"\\n\")\n}\n\n```\n\n\nA lambda defines a small function at its point of use:\n\n```capy\nfunction RENDER()\n{\n var add_one := function(value : s32) s32\n {\n -> value + 1\n }\n print(add_one(41), \"\\n\")\n}\n\n```\n\n\nA lambda can read outer variables. A captured number, boolean, or string is copied. A captured array, `dval`, or struct is the same object the outer code holds, so the closure can change its contents and the outer code sees the change. A capture cannot be reassigned.\n\n```capy\nfunction RENDER()\n{\n var offset := 2\n var values := [10]\n var update := function() s64\n {\n values.push(20)\n -> offset + length(values)\n }\n print(update(), \" \", values[1], \"\\n\")\n}\n\n```\n\n\n## Store a callback in a dynamic value\n\nA `dval` can store a named function or a closure for the rest of the request. Read it with its complete function type:\n\n```capy\nfunction add_one(value : s32) s32\n{\n -> value + 1\n}\n\nfunction RENDER()\n{\n vLine truncated
{
found = true
}
+1 -1
View File
@@ -1,4 +1,4 @@
function COMPONENT(props : dval)
{
print("<div class=\"doc-detail-layout\"><main class=\"content doc-page doc-detail\"><div class=\"doc-title\"><h2>gen_noise</h2><span class=\"call-boundary host-call\">host call</span></div><div class=\"doc-section signatures\"><h3>Capy</h3><pre>function gen_noise(min : any, max : min::type, index : u64, seed : u64) min::type</pre></div><div class=\"doc-section content\"><h3>Description</h3><p><code>gen_noise()</code> returns deterministic noise for the range values, index, and seed.</p><p>Only <code>u64</code> and <code>f64</code> bounds are supported. Integer bounds are inclusive.</p><p>Float generation uses the existing fixed precision. The function does not accept a precision parameter.</p><p>Use the same inputs to reproduce a value.</p></div><div class=\"doc-section params\"><h3>Parameters</h3><div><p>min : first range value</p></div><div><p>max : second range value</p></div><div><p>index : deterministic input position</p></div><div><p>seed : deterministic input seed</p></div><div></div></div><div class=\"doc-section\"><h3>Return Values</h3><p>A deterministic value with the same type as <code>min</code>.</p></div><div class=\"doc-section example\"><h3>Example</h3><div class=\"example-language capy\"><h4>Capy</h4><pre class=\"example-source\">var integer := gen_noise(u64(1), u64(10), u64(1), u64(2))\nvar floating := gen_noise(0.0, 1.0, u64(1), u64(2))\nprint(integer, &quot; &quot;, floating, &quot;\\n&quot;)\n</pre></div></div></main><aside class=\"doc-section see-also\"><h3>See also</h3><a class=\"related-link\" href=\"/doc/api/gen-noise64/\">gen_noise64</a><a class=\"related-link\" href=\"/doc/api/draw-int/\">draw_int</a><a class=\"related-link\" href=\"/doc/api/draw-float/\">draw_float</a><a class=\"related-link\" href=\"/doc/api/random-bytes/\">random_bytes</a></aside></div>")
print("<div class=\"doc-detail-layout\"><main class=\"content doc-page doc-detail\"><div class=\"doc-title\"><h2>gen_noise</h2><span class=\"call-boundary host-call\">host call</span></div><div class=\"doc-section signatures\"><h3>Capy</h3><pre>function gen_noise(min : *, max : min::type, index : u64, seed : u64) min::type</pre></div><div class=\"doc-section content\"><h3>Description</h3><p><code>gen_noise()</code> returns deterministic noise for the range values, index, and seed.</p><p>Only <code>u64</code> and <code>f64</code> bounds are supported. Integer bounds are inclusive.</p><p>Float generation uses the existing fixed precision. The function does not accept a precision parameter.</p><p>Use the same inputs to reproduce a value.</p></div><div class=\"doc-section params\"><h3>Parameters</h3><div><p>min : first range value</p></div><div><p>max : second range value</p></div><div><p>index : deterministic input position</p></div><div><p>seed : deterministic input seed</p></div><div></div></div><div class=\"doc-section\"><h3>Return Values</h3><p>A deterministic value with the same type as <code>min</code>.</p></div><div class=\"doc-section example\"><h3>Example</h3><div class=\"example-language capy\"><h4>Capy</h4><pre class=\"example-source\">var integer := gen_noise(u64(1), u64(10), u64(1), u64(2))\nvar floating := gen_noise(0.0, 1.0, u64(1), u64(2))\nprint(integer, &quot; &quot;, floating, &quot;\\n&quot;)\n</pre></div></div></main><aside class=\"doc-section see-also\"><h3>See also</h3><a class=\"related-link\" href=\"/doc/api/gen-noise64/\">gen_noise64</a><a class=\"related-link\" href=\"/doc/api/draw-int/\">draw_int</a><a class=\"related-link\" href=\"/doc/api/draw-float/\">draw_float</a><a class=\"related-link\" href=\"/doc/api/random-bytes/\">random_bytes</a></aside></div>")
}
@@ -3,6 +3,6 @@ function COMPONENT(props : dval)
print("<div class=\"doc-detail-layout\"><main class=\"content doc-page doc-detail\"><div class=\"doc-title\"><h2>5. Functions</h2></div><div class=\"doc-section content\"><p>A function gives a name to a calculation. Parameters describe its input. The declared result type describes its output.</p><h2>Define and call a function</h2><pre><code class=\"language-capy\">function greet(name : capture string) string\n{\n -&gt; &quot;Hello, &quot; + name\n}\n\nfunction RENDER()\n{\n var name := &quot;Ada&quot;\n print(greet(), &quot;\\n&quot;)\n}\n</code></pre><p><strong>Output</strong></p><pre><code class=\"language-text\">Hello, Ada\n</code></pre><p>The <code>-&gt;</code> expression supplies the function result. Use <code>return</code> when a function must finish early.</p><h2>Parameters and defaults</h2><p>Parameters have names and types:</p><pre><code class=\"language-capy\">function label(name : string, suffix : string = &quot;!&quot;) string\n{\n -&gt; name + suffix\n}\n\nfunction RENDER()\n{\n print(label(&quot;Capy&quot;), &quot;\\n&quot;)\n}\n</code></pre><p><code>label(&quot;Capy&quot;)</code> uses the default suffix. Defaults are trailing literals. A direct call can omit them, but a function value keeps the full parameter list.</p><p>Capy evaluates arguments once from left to right.</p><h2>Capture parameters</h2><p>A capture parameter uses the caller&#39;s variable with the same name when the caller omits its argument. The first example captures <code>name</code>.</p><p>Write <code>name : capture Type</code> for an exact type match. Write <code>name : capture as Type</code> to permit one constructor conversion.</p><p>Capture parameters follow all ordinary parameters, including parameters with defaults. The caller can also pass an explicit argument.</p><p>A missing caller variable is a compile error. The diagno")
print("stic names the function and the capture parameter.</p><p>A helper that uses request-dependent functions must declare <code>request : capture dval</code>. Each helper in a call chain needs that capture.</p><pre><code class=\"language-capy\">function set_title(title : string, request : capture dval)\n{\n request.page_title = title\n}</code></pre><p>Handlers bind <code>request</code> implicitly. Exported <code>(dval) dval</code> functions also capture <code>request</code> implicitly. They need no explicit capture declaration.</p><h2>Map entry arguments</h2><p>An argument of the form <code>key: value</code> is a map entry. Adjacent map entries form one map argument:</p><pre><code class=\"language-capy\">function describe(name : string, options : dval = {}) string\n{\n -&gt; name + &quot; &quot; + json_encode(options)\n}\n\nfunction RENDER()\n{\n print(describe(&quot;list&quot;, page: 2, per_page: 20), &quot;\\n&quot;)\n print(describe(&quot;list&quot;,\n {\n page: 2,\n per_page: 20\n }\n ),\n &quot;\\n&quot;\n )\n}\n</code></pre><p><strong>Output</strong></p><pre><code class=\"language-text\">list {&quot;page&quot;: 2.000000, &quot;per_page&quot;: 20.000000}\nlist {&quot;page&quot;: 2.000000, &quot;per_page&quot;: 20.000000}\n</code></pre><p>Both calls pass the same map and compile to the same code. Use map entries for options and for the input of a unit call.</p><p>A map entry does not name a parameter. <code>describe(name: &quot;list&quot;)</code> passes one map, and the compiler reports that no overload accepts it. A key is an identifier or a string.</p><p>An ordinary argument ends the map. In <code>find(1, page: 2, true)</code> the call receives <code>1</code>, the map <code>{page: 2}</code>, and <code>true</code>. Two map parameters in sequence need braces for the second map. Struct construc")
print("tors take ordinary arguments.</p><h2>Overloads</h2><p>Several functions can have the same name when their parameter types differ:</p><pre><code class=\"language-capy\">function describe(value : s32) string\n{\n -&gt; &quot;integer&quot;\n}\nfunction describe(value : string) string\n{\n -&gt; &quot;string&quot;\n}\n\nfunction RENDER()\n{\n print(describe(42), &quot; &quot;, describe(&quot;Ada&quot;), &quot;\\n&quot;)\n}\n</code></pre><p>The argument types select the overload. A result type never selects one.</p><h2>Conversion parameters</h2><p>A parameter declared with <code>as</code> permits one constructor conversion:</p><pre><code class=\"language-capy\">function show(value : as string)\n{\n print(value, &quot;\\n&quot;)\n}\n\nfunction RENDER()\n{\n show(42)\n}\n</code></pre><p>The call behaves as if it passed <code>string(42)</code>. Capy does not chain several conversions.</p><h2>Function values</h2><p>A function can be stored and called through a typed value:</p><pre><code class=\"language-capy\">function double(value : s32) s32\n{\n -&gt; value * 2\n}\n\nfunction RENDER()\n{\n var operation : function(value : s32) s32 = double\n var answer := operation(21)\n print(answer, &quot;\\n&quot;)\n}\n</code></pre><p>A lambda defines a small function at its point of use:</p><pre><code class=\"language-capy\">function RENDER()\n{\n var add_one := function(value : s32) s32\n {\n -&gt; value + 1\n }\n print(add_one(41), &quot;\\n&quot;)\n}\n</code></pre><p>A lambda can read outer variables. A captured number, boolean, or string is copied. A captured array, <code>dval</code>, or struct is the same object the outer code holds, so the closure can change its contents and the outer code sees the change. A capture cannot be reassigned.</p><pre><code class=\"language-capy\">function RENDER()\n{\n var offset := 2\n var values := [10]\n var ")
print("update := function() s64\n {\n values.push(20)\n -&gt; offset + length(values)\n }\n print(update(), &quot; &quot;, values[1], &quot;\\n&quot;)\n}\n</code></pre><h2>Store a callback in a dynamic value</h2><p>A <code>dval</code> can store a named function or a closure for the rest of the request. Read it with its complete function type:</p><pre><code class=\"language-capy\">function add_one(value : s32) s32\n{\n -&gt; value + 1\n}\n\nfunction RENDER()\n{\n var step := s32(2)\n var callbacks := {\n named: add_one,\n captured: function(value : s32) s32\n {\n -&gt; value + step\n }\n }\n var named : function(value : s32) s32 = callbacks.named\n var captured : function(value : s32) s32 = callbacks.captured\n print(named(1), &quot; &quot;, captured(1), &quot;\\n&quot;)\n}\n</code></pre><p><strong>Output</strong></p><pre><code class=\"language-text\">2 3\n</code></pre><p>The function type must match exactly. A mismatch traps. A callable does not cross a public boundary. BRRB, JSON, YAML, and XML replace it with <code>none</code>. Maps keep keys. Lists keep indexes.</p><h2>Generic and variadic functions</h2><p>An <code>any</code> parameter creates a compile-time generic function. Use it when the same operation is valid for several concrete types.</p><p>A variadic parameter collects values into a typed array:</p><pre><code class=\"language-capy\">function print_all(...values : as string)\n{\n for value := values\n {\n print(value)\n }\n}\n\nfunction RENDER()\n{\n print_all(&quot;one&quot;, &quot; &quot;, &quot;two&quot;, &quot;\\n&quot;)\n}\n</code></pre><p>Use <code>...items</code> to spread an array into a variadic call.</p></div><nav class=\"guide-navigation\" aria-label=\"Capy guide navigation\"><div class=\"guide-previous\">Previous: <a href=\"/doc/guide/expressions-and-control-flow/\">4. Expressions and control flow</a")
print("></div><div class=\"guide-index\"><a href=\"/doc/\">Guide index</a></div><div class=\"guide-next\">Next: <a href=\"/doc/guide/strings-and-markup/\">6. Strings and HTML</a></div></nav></main><aside class=\"doc-section see-also\"><h3>See also</h3><a class=\"related-link\" href=\"/doc/guide/install-and-first-program/\">1. Getting started</a><a class=\"related-link\" href=\"/doc/guide/source-structure-and-syntax/\">2. Basic syntax</a><a class=\"related-link\" href=\"/doc/guide/values-and-types/\">3. Types</a><a class=\"related-link\" href=\"/doc/guide/expressions-and-control-flow/\">4. Expressions and control flow</a><a class=\"related-link\" href=\"/doc/guide/strings-and-markup/\">6. Strings and HTML</a><a class=\"related-link\" href=\"/doc/guide/collections-and-records/\">7. Arrays and structs</a><a class=\"related-link\" href=\"/doc/guide/dynamic-values/\">8. Dynamic values</a><a class=\"related-link\" href=\"/doc/guide/web-handlers-and-requests/\">9. Handling a web request</a><a class=\"related-link\" href=\"/doc/guide/units-components-and-exports/\">10. Units and components</a><a class=\"related-link\" href=\"/doc/guide/tasks-and-commands/\">11. Tasks and commands</a><a class=\"related-link\" href=\"/doc/guide/services/\">12. Services</a><a class=\"related-link\" href=\"/doc/guide/errors-testing-and-style/\">13. Errors and testing</a><a class=\"related-link\" href=\"/doc/guide/coming-from-react/\">14. Coming from React</a><a class=\"related-link\" href=\"/doc/api/print/\">print</a></aside></div>")
print("update := function() s64\n {\n values.push(20)\n -&gt; offset + length(values)\n }\n print(update(), &quot; &quot;, values[1], &quot;\\n&quot;)\n}\n</code></pre><h2>Store a callback in a dynamic value</h2><p>A <code>dval</code> can store a named function or a closure for the rest of the request. Read it with its complete function type:</p><pre><code class=\"language-capy\">function add_one(value : s32) s32\n{\n -&gt; value + 1\n}\n\nfunction RENDER()\n{\n var step := s32(2)\n var callbacks := {\n named: add_one,\n captured: function(value : s32) s32\n {\n -&gt; value + step\n }\n }\n var named : function(value : s32) s32 = callbacks.named\n var captured : function(value : s32) s32 = callbacks.captured\n print(named(1), &quot; &quot;, captured(1), &quot;\\n&quot;)\n}\n</code></pre><p><strong>Output</strong></p><pre><code class=\"language-text\">2 3\n</code></pre><p>The function type must match exactly. A mismatch traps. A callable does not cross a public boundary. BRRB, JSON, YAML, and XML replace it with <code>none</code>. Maps keep keys. Lists keep indexes.</p><h2>Generic and variadic functions</h2><p>A <code>*</code> parameter creates a compile-time generic function. Use it when the same operation is valid for several concrete types.</p><p>A variadic parameter collects values into a typed array:</p><pre><code class=\"language-capy\">function print_all(...values : as string)\n{\n for value := values\n {\n print(value)\n }\n}\n\nfunction RENDER()\n{\n print_all(&quot;one&quot;, &quot; &quot;, &quot;two&quot;, &quot;\\n&quot;)\n}\n</code></pre><p>Use <code>...items</code> to spread an array into a variadic call.</p></div><nav class=\"guide-navigation\" aria-label=\"Capy guide navigation\"><div class=\"guide-previous\">Previous: <a href=\"/doc/guide/expressions-and-control-flow/\">4. Expressions and control flow</a></")
print("div><div class=\"guide-index\"><a href=\"/doc/\">Guide index</a></div><div class=\"guide-next\">Next: <a href=\"/doc/guide/strings-and-markup/\">6. Strings and HTML</a></div></nav></main><aside class=\"doc-section see-also\"><h3>See also</h3><a class=\"related-link\" href=\"/doc/guide/install-and-first-program/\">1. Getting started</a><a class=\"related-link\" href=\"/doc/guide/source-structure-and-syntax/\">2. Basic syntax</a><a class=\"related-link\" href=\"/doc/guide/values-and-types/\">3. Types</a><a class=\"related-link\" href=\"/doc/guide/expressions-and-control-flow/\">4. Expressions and control flow</a><a class=\"related-link\" href=\"/doc/guide/strings-and-markup/\">6. Strings and HTML</a><a class=\"related-link\" href=\"/doc/guide/collections-and-records/\">7. Arrays and structs</a><a class=\"related-link\" href=\"/doc/guide/dynamic-values/\">8. Dynamic values</a><a class=\"related-link\" href=\"/doc/guide/web-handlers-and-requests/\">9. Handling a web request</a><a class=\"related-link\" href=\"/doc/guide/units-components-and-exports/\">10. Units and components</a><a class=\"related-link\" href=\"/doc/guide/tasks-and-commands/\">11. Tasks and commands</a><a class=\"related-link\" href=\"/doc/guide/services/\">12. Services</a><a class=\"related-link\" href=\"/doc/guide/errors-testing-and-style/\">13. Errors and testing</a><a class=\"related-link\" href=\"/doc/guide/coming-from-react/\">14. Coming from React</a><a class=\"related-link\" href=\"/doc/api/print/\">print</a></aside></div>")
}
+3 -3
View File
@@ -3,7 +3,7 @@ function COMPONENT(props : dval)
print("<div class=\"doc-detail-layout\"><main class=\"content doc-page doc-detail\"><div class=\"doc-title\"><h2>3. Types</h2></div><div class=\"doc-section content\"><p>Every Capy value has a type. The compiler checks types before the program runs. It usually infers the type of a local value.</p><h2>Integers</h2><p>An integer literal has type <code>s64</code> when no other type is stated:</p><pre><code class=\"language-capy\">function RENDER()\n{\n var answer := 42\n print(answer, &quot;\\n&quot;)\n}\n</code></pre><p><strong>Output</strong></p><pre><code class=\"language-text\">42\n</code></pre><p>State the type on the local, or construct the value explicitly:</p><pre><code class=\"language-capy\">function RENDER()\n{\n var signed : s64 = 8\n var inferred_signed := s64(9)\n var unsigned : u64 = 10\n var inferred_unsigned := u64(11)\n print(signed, &quot; &quot;, inferred_signed, &quot; &quot;, unsigned, &quot; &quot;, inferred_unsigned, &quot;\\n&quot;)\n}\n</code></pre><p>Both forms produce the stated integer type. <code>var signed : s64 = s64(8)</code> also compiles, but the constructor repeats the annotation.</p><p>Parameters, function results, assignments, typed arrays, struct fields, and the other operand in an expression can also state the integer type. Thus, a function that accepts <code>u64</code> can receive the plain literal <code>8</code>. An unconstrained literal remains <code>s64</code>.</p><p>Arithmetic requires operands of the same type. Use a constructor when the surrounding code does not state the required type.</p><h2>Booleans and floating-point numbers</h2><p>A <code>bool</code> is either <code>true</code> or <code>false</code>. Conditions require a boolean value.</p><pre><code class=\"language-capy\">function RENDER()\n{\n var enabled := true\n var ratio := 2.5\n print(enabled, &quot; &quot;")
print(", ratio, &quot;\\n&quot;)\n}\n</code></pre><p>A decimal point or exponent makes an <code>f64</code> literal.</p><h2>Strings</h2><p>A <code>string</code> stores bytes:</p><pre><code class=\"language-capy\">function RENDER()\n{\n var name := &quot;Ada&quot;\n var empty := &quot;&quot;\n print(name, empty, &quot;\\n&quot;)\n}\n</code></pre><p>An empty string is still a string value. It is not missing data.</p><h2>Arrays and structs</h2><p>An array contains values of one type:</p><pre><code class=\"language-capy\">function RENDER()\n{\n var names := [&quot;Ada&quot;, &quot;Grace&quot;]\n print(names[0], &quot;\\n&quot;)\n}\n</code></pre><p>A struct gives names to fixed fields:</p><pre><code class=\"language-capy\">struct Point\n{\n x : s32\n y : s32\n}\n\nfunction RENDER()\n{\n var point := Point(3, 4)\n print(point.x, &quot; &quot;, point.y, &quot;\\n&quot;)\n}\n</code></pre><h2>Copy or share</h2><p>Numbers and booleans are copied: after <code>var b := a</code>, changing <code>b</code> leaves <code>a</code> alone. Strings are values too. A string never changes in place, so it makes no difference whether two names share one.</p><p>Arrays, structs, and dvals are objects. <code>var b := a</code> makes <code>b</code> a second name for the same object, and so do parameters, return values, closure captures, and member reads. A change made through one name shows through all of them. When you need a separate copy, <code>clone(value)</code> makes one.</p><p>A variable can be pointed at another object with <code>=</code>. A parameter cannot.</p><p>The collections chapter covers arrays and structs in detail, the dynamic values chapter covers <code>dval</code>.</p><h2>Numeric functions</h2><p>Use the <code>math</code> functions for floating-point calculations and numeric bounds. Use the <code>bits</code> functions for")
print(" integer masks, shifts, rotations, counts, and bit reinterpretation.</p><p>See the <code>math</code> function reference for floating-point operations and predicates. See the <code>bits</code> function reference for integer bit operations and floating-point bit reinterpretation.</p><h2>Dynamic values and none</h2><p>A <code>dval</code> holds data whose shape is known only at run time. The <code>none</code> value represents missing dynamic data:</p><pre><code class=\"language-capy\">function RENDER()\n{\n var profile := { name: &quot;Ada&quot; }\n var missing := none\n print(profile.name, &quot; &quot;, missing?, &quot;\\n&quot;)\n}\n</code></pre><p><code>none</code> is different from <code>&quot;&quot;</code>, <code>false</code>, an empty map, and an empty list. A <code>dval</code> is also an object that variables refer to, never a copy. The dynamic-values chapter explains mutation, safe reads, and conversions.</p><h2>Type aliases and static type names</h2><p>A type alias gives another name to a type. It does not create a distinct type at runtime.</p><p>Use <code>expression::type_name</code> to get the resolved static type of an expression. Capy evaluates the expression once.</p><pre><code class=\"language-capy\">type Count = s64\n\nfunction RENDER()\n{\n var total : Count = 12\n var labels := [&quot;new&quot;, &quot;done&quot;]\n print(total::type_name, &quot; &quot;, labels::type_name, &quot;\\n&quot;)\n}\n</code></pre><p><strong>Output</strong></p><pre><code class=\"language-text\">s64 [string]\n</code></pre><p>An alias reports its target type. Arrays use <code>[item_type]</code>. Structs use their declared name. Function values use their complete function type.</p><p>A <code>dval</code> expression reports <code>dval</code>, regardless of its current contents. Use <code>get_type_name(value)")
print("</code> to inspect the value stored inside a <code>dval</code>.</p><h2>Struct field inspection</h2><p>Struct values have two additional reflection expressions:</p><table><thead><tr><th>Expression</th><th>Result</th><th>Meaning</th></tr></thead><tbody><tr><td><code>value::size</code></td><td><code>s64</code></td><td>The number of declared fields. This is not a byte size.</td></tr><tr><td><code>value::items</code></td><td><code>dval</code></td><td>A new map of the current field values, keyed by field name.</td></tr></tbody></table><p>Each <code>items</code> entry contains <code>value</code> and <code>type_name</code>. Use <code>fields.name.value</code> for a fixed field. Use <code>fields[key][&quot;value&quot;]</code> for a dynamic field name.</p><p><code>value::items</code> evaluates its receiver once. Changing the returned map does not change the struct. The compiler rejects <code>size</code> and <code>items</code> on non-struct values.</p><p>The struct reference defines field conversions for scalars, strings, DValues, nested structs, arrays, and function values.</p><h2>Dependent generic types</h2><p>A generic function can use the concrete type of an earlier <code>any</code> parameter. Write <code>parameter::type</code> in a later parameter or the function result:</p><pre><code class=\"language-capy\">function same(first : any, second : first::type) first::type\n{\n -&gt; second\n}</code></pre><p><code>parameter::type</code> is a compile-time type expression. It does not inspect a runtime value. The compiler rejects the removed <code>type(parameter)</code> spelling.</p></div><nav class=\"guide-navigation\" aria-label=\"Capy guide navigation\"><div class=\"guide-previous\">Previous: <a href=\"/doc/guide/source-structure-and-syntax/\">2. Basic syntax</a></div><div class=\"guide-index\">")
print("<a href=\"/doc/\">Guide index</a></div><div class=\"guide-next\">Next: <a href=\"/doc/guide/expressions-and-control-flow/\">4. Expressions and control flow</a></div></nav></main><aside class=\"doc-section see-also\"><h3>See also</h3><a class=\"related-link\" href=\"/doc/guide/install-and-first-program/\">1. Getting started</a><a class=\"related-link\" href=\"/doc/guide/source-structure-and-syntax/\">2. Basic syntax</a><a class=\"related-link\" href=\"/doc/guide/expressions-and-control-flow/\">4. Expressions and control flow</a><a class=\"related-link\" href=\"/doc/guide/functions-and-closures/\">5. Functions</a><a class=\"related-link\" href=\"/doc/guide/strings-and-markup/\">6. Strings and HTML</a><a class=\"related-link\" href=\"/doc/guide/collections-and-records/\">7. Arrays and structs</a><a class=\"related-link\" href=\"/doc/guide/dynamic-values/\">8. Dynamic values</a><a class=\"related-link\" href=\"/doc/guide/web-handlers-and-requests/\">9. Handling a web request</a><a class=\"related-link\" href=\"/doc/guide/units-components-and-exports/\">10. Units and components</a><a class=\"related-link\" href=\"/doc/guide/tasks-and-commands/\">11. Tasks and commands</a><a class=\"related-link\" href=\"/doc/guide/services/\">12. Services</a><a class=\"related-link\" href=\"/doc/guide/errors-testing-and-style/\">13. Errors and testing</a><a class=\"related-link\" href=\"/doc/guide/coming-from-react/\">14. Coming from React</a><a class=\"related-link\" href=\"/doc/type/dvalue/\">Dynamic values</a><a class=\"related-link\" href=\"/doc/type/struct/\">struct</a><a class=\"related-link\" href=\"/doc/api/get-type-name/\">get_type_name</a><a class=\"related-link\" href=\"/doc/type/bool/\">bool</a><a class=\"related-link\" href=\"/doc/type/s8/\">s8</a><a class=\"related-link\" href=\"/doc/type/s16/\">s16</a><a class=\"related-link\" href=\"/doc/type/s32/\">s32</a><a cl")
print("ass=\"related-link\" href=\"/doc/type/s64/\">s64</a><a class=\"related-link\" href=\"/doc/type/u8/\">u8</a><a class=\"related-link\" href=\"/doc/type/u16/\">u16</a><a class=\"related-link\" href=\"/doc/type/u32/\">u32</a><a class=\"related-link\" href=\"/doc/type/u64/\">u64</a><a class=\"related-link\" href=\"/doc/type/f32/\">f32</a><a class=\"related-link\" href=\"/doc/type/f64/\">f64</a><a class=\"related-link\" href=\"/doc/api/string/\">string</a><a class=\"related-link\" href=\"/doc/api/dval/\">dval</a><a class=\"related-link\" href=\"/doc/api/length/\">length</a><a class=\"related-link\" href=\"/doc/api/sqrt/\">sqrt</a><a class=\"related-link\" href=\"/doc/api/bit-and/\">bit_and</a></aside></div>")
print("</code> to inspect the value stored inside a <code>dval</code>.</p><h2>Struct field inspection</h2><p>Struct values have two additional reflection expressions:</p><table><thead><tr><th>Expression</th><th>Result</th><th>Meaning</th></tr></thead><tbody><tr><td><code>value::size</code></td><td><code>s64</code></td><td>The number of declared fields. This is not a byte size.</td></tr><tr><td><code>value::items</code></td><td><code>dval</code></td><td>A new map of the current field values, keyed by field name.</td></tr></tbody></table><p>Each <code>items</code> entry contains <code>value</code> and <code>type_name</code>. Use <code>fields.name.value</code> for a fixed field. Use <code>fields[key][&quot;value&quot;]</code> for a dynamic field name.</p><p><code>value::items</code> evaluates its receiver once. Changing the returned map does not change the struct. The compiler rejects <code>size</code> and <code>items</code> on non-struct values.</p><p>The struct reference defines field conversions for scalars, strings, DValues, nested structs, arrays, and function values.</p><h2>Dependent generic types</h2><p>A generic function can use the concrete type of an earlier <code>*</code> parameter. Write <code>parameter::type</code> in a later parameter or the function result:</p><pre><code class=\"language-capy\">function same(first : *, second : first::type) first::type\n{\n -&gt; second\n}</code></pre><p><code>parameter::type</code> is a compile-time type expression. It does not inspect a runtime value. The compiler rejects the removed <code>type(parameter)</code> spelling.</p></div><nav class=\"guide-navigation\" aria-label=\"Capy guide navigation\"><div class=\"guide-previous\">Previous: <a href=\"/doc/guide/source-structure-and-syntax/\">2. Basic syntax</a></div><div class=\"guide-index\"><a h")
print("ref=\"/doc/\">Guide index</a></div><div class=\"guide-next\">Next: <a href=\"/doc/guide/expressions-and-control-flow/\">4. Expressions and control flow</a></div></nav></main><aside class=\"doc-section see-also\"><h3>See also</h3><a class=\"related-link\" href=\"/doc/guide/install-and-first-program/\">1. Getting started</a><a class=\"related-link\" href=\"/doc/guide/source-structure-and-syntax/\">2. Basic syntax</a><a class=\"related-link\" href=\"/doc/guide/expressions-and-control-flow/\">4. Expressions and control flow</a><a class=\"related-link\" href=\"/doc/guide/functions-and-closures/\">5. Functions</a><a class=\"related-link\" href=\"/doc/guide/strings-and-markup/\">6. Strings and HTML</a><a class=\"related-link\" href=\"/doc/guide/collections-and-records/\">7. Arrays and structs</a><a class=\"related-link\" href=\"/doc/guide/dynamic-values/\">8. Dynamic values</a><a class=\"related-link\" href=\"/doc/guide/web-handlers-and-requests/\">9. Handling a web request</a><a class=\"related-link\" href=\"/doc/guide/units-components-and-exports/\">10. Units and components</a><a class=\"related-link\" href=\"/doc/guide/tasks-and-commands/\">11. Tasks and commands</a><a class=\"related-link\" href=\"/doc/guide/services/\">12. Services</a><a class=\"related-link\" href=\"/doc/guide/errors-testing-and-style/\">13. Errors and testing</a><a class=\"related-link\" href=\"/doc/guide/coming-from-react/\">14. Coming from React</a><a class=\"related-link\" href=\"/doc/type/dvalue/\">Dynamic values</a><a class=\"related-link\" href=\"/doc/type/struct/\">struct</a><a class=\"related-link\" href=\"/doc/api/get-type-name/\">get_type_name</a><a class=\"related-link\" href=\"/doc/type/bool/\">bool</a><a class=\"related-link\" href=\"/doc/type/s8/\">s8</a><a class=\"related-link\" href=\"/doc/type/s16/\">s16</a><a class=\"related-link\" href=\"/doc/type/s32/\">s32</a><a class=")
print("\"related-link\" href=\"/doc/type/s64/\">s64</a><a class=\"related-link\" href=\"/doc/type/u8/\">u8</a><a class=\"related-link\" href=\"/doc/type/u16/\">u16</a><a class=\"related-link\" href=\"/doc/type/u32/\">u32</a><a class=\"related-link\" href=\"/doc/type/u64/\">u64</a><a class=\"related-link\" href=\"/doc/type/f32/\">f32</a><a class=\"related-link\" href=\"/doc/type/f64/\">f64</a><a class=\"related-link\" href=\"/doc/api/string/\">string</a><a class=\"related-link\" href=\"/doc/api/dval/\">dval</a><a class=\"related-link\" href=\"/doc/api/length/\">length</a><a class=\"related-link\" href=\"/doc/api/sqrt/\">sqrt</a><a class=\"related-link\" href=\"/doc/api/bit-and/\">bit_and</a></aside></div>")
}
+1 -1
View File
@@ -204,7 +204,7 @@ inline constexpr DocCapySignature doc_capy_signatures[] = {
{"floor", "function floor(value : f32) f32", "lib"},
{"floor", "function floor(value : f64) f64", "lib"},
{"flush_output", "function flush_output() bool", "host"},
{"gen_noise", "function gen_noise(min : any, max : min::type, index : u64, seed : u64) min::type", "host"},
{"gen_noise", "function gen_noise(min : *, max : min::type, index : u64, seed : u64) min::type", "host"},
{"gen_noise64", "function gen_noise64(index : u64, seed : u64 = 0) u64", "host"},
{"gen_sha1", "function gen_sha1(value : string) string", "lib"},
{"get", "function get(value : dval, key : string) dval", "lib"},
+1 -1
View File
@@ -1,5 +1,5 @@
:sig
function gen_noise(min : any, max : min::type, index : u64, seed : u64) min::type
function gen_noise(min : *, max : min::type, index : u64, seed : u64) min::type
:params
min : first range value
@@ -175,10 +175,10 @@ The struct reference defines field conversions for scalars, strings, DValues, ne
## Dependent generic types
A generic function can use the concrete type of an earlier `any` parameter. Write `parameter::type` in a later parameter or the function result:
A generic function can use the concrete type of an earlier `*` parameter. Write `parameter::type` in a later parameter or the function result:
```capy
function same(first : any, second : first::type) first::type
function same(first : *, second : first::type) first::type
{
-> second
}
@@ -227,7 +227,7 @@ The function type must match exactly. A mismatch traps. A callable does not cros
## Generic and variadic functions
An `any` parameter creates a compile-time generic function. Use it when the same operation is valid for several concrete types.
A `*` parameter creates a compile-time generic function. Use it when the same operation is valid for several concrete types.
A variadic parameter collects values into a typed array:
+1 -1
View File
@@ -14,7 +14,7 @@ function select(value : as s64) s32
{
-> 2
}
function choose(value : any) value::type
function choose(value : *) value::type
{
-> value
}
+1 -1
View File
@@ -21,7 +21,7 @@ function describe(value : string) string
{
-> "string"
}
function identity(value : any) value::type
function identity(value : *) value::type
{
-> value
}
+4 -4
View File
@@ -30,12 +30,12 @@ function subtract(left : s32, right : s32) s32
-> left - right
}
function identity(value : any) value::type
function identity(value : *) value::type
{
-> value
}
function choose(value : any) value::type
function choose(value : *) value::type
{
-> value
}
@@ -45,7 +45,7 @@ function choose(value : s32) value::type
-> value + 1
}
function same(first : any, second : first::type) first::type
function same(first : *, second : first::type) first::type
{
-> second
}
@@ -65,7 +65,7 @@ function pair_label(value : TextPair) string
-> value.text
}
function countdown(value : any) value::type
function countdown(value : *) value::type
{
if value == 0
{
+18 -18
View File
@@ -458,8 +458,8 @@ std::string type_of_expression(const Expr* expression, bool allow_void = false)
return type + ") " + type_of_expression(function->return_type, true);
}
std::string name = type_name(*expression);
if (name == "any" || name.find("::type") != std::string::npos)
throw Error(expression->location, "compile-time any and dependent types are only valid in a generic function declaration");
if (name == "*" || name.find("::type") != std::string::npos)
throw Error(expression->location, "compile-time * and dependent types are only valid in a generic function declaration");
if (name == "s8" || name == "s16" || name == "s32" || name == "s64" || name == "u8" || name == "u16" || name == "u32" || name == "u64" || name == "f32" || name == "f64" || name == "bool" || name == "string" || name == "dval" ||
name == "module" || name == "void")
return name;
@@ -615,7 +615,7 @@ bool generic_matches(const GenericDefinition& generic, const std::vector<std::st
for (std::size_t i = 0; i < types.size(); ++i)
{
const int dependency = generic.dependent_parameters[i];
if (dependency < 0 && generic.patterns[i] == "any")
if (dependency < 0 && generic.patterns[i] == "*")
continue;
if ((dependency >= 0 && types[i] != types[static_cast<std::size_t>(dependency)]) ||
(dependency < 0 && generic.patterns[i] != types[i]))
@@ -1153,7 +1153,7 @@ struct Module
resolving_defaults.erase(request);
if (auto found = generics_.find(name); found != generics_.end())
for (const GenericDefinition& generic : found->second)
if (generic.patterns.size() == 1 && (generic.patterns[0] == "any" || generic.patterns[0] == source))
if (generic.patterns.size() == 1 && (generic.patterns[0] == "*" || generic.patterns[0] == source))
{
const std::string result = generic.dependent_result == 0 ? source : generic.fixed_result;
if (result == target)
@@ -7115,7 +7115,7 @@ void Module::collect()
for (Expr* item : items_)
if (auto alias = dynamic_cast<TypeAlias*>(item))
{
if (alias->name == "true" || alias->name == "false" || alias->name == "any" ||
if (alias->name == "true" || alias->name == "false" || alias->name == "*" ||
alias->name == "s8" || alias->name == "s16" || alias->name == "s32" || alias->name == "s64" || alias->name == "u8" || alias->name == "u16" || alias->name == "u32" || alias->name == "u64" || alias->name == "f32" || alias->name == "f64" || alias->name == "bool" ||
alias->name == "string" || alias->name == "dval" || alias->name == "module" || alias->name == "void")
throw Error(alias->location, "type alias name '" + alias->name + "' is reserved");
@@ -7242,7 +7242,7 @@ void Module::collect()
for (std::size_t parameter_index = 0; parameter_index < function->parameters.size(); ++parameter_index)
{
const auto& parameter = function->parameters[parameter_index];
const bool any = dynamic_cast<Name*>(parameter.type_expr) && static_cast<Name*>(parameter.type_expr)->value == "any";
const bool wildcard = dynamic_cast<Name*>(parameter.type_expr) && static_cast<Name*>(parameter.type_expr)->value == "*";
const auto dependency_name = dependent_type_parameter(parameter.type_expr);
int dependency = -1;
if (dependency_name)
@@ -7252,14 +7252,14 @@ void Module::collect()
if (dependency < 0)
throw Error(parameter.type_expr->location, "dependent type names an unknown or forward parameter");
const Expr* source_type = function->parameters[static_cast<std::size_t>(dependency)].type_expr;
if (!(dynamic_cast<const Name*>(source_type) && type_name(*source_type) == "any"))
throw Error(parameter.type_expr->location, "dependent type requires an earlier any parameter");
if (!(dynamic_cast<const Name*>(source_type) && type_name(*source_type) == "*"))
throw Error(parameter.type_expr->location, "dependent type requires an earlier * parameter");
}
generic = generic || any || dependency >= 0;
generic = generic || wildcard || dependency >= 0;
dependent_parameters.push_back(dependency);
std::string type;
if (any || dependency >= 0)
type = "any";
if (wildcard || dependency >= 0)
type = "*";
else
type = value_type(parameter.type_expr);
if (parameter.variadic)
@@ -7274,9 +7274,9 @@ void Module::collect()
conversions.push_back(parameter.variadic ? false : parameter.convert);
captures.push_back(parameter.capture);
parameter_names.push_back(parameter.name);
if (parameter.capture && (any || dependency >= 0))
if (parameter.capture && (wildcard || dependency >= 0))
throw Error(parameter.type_expr->location, "a capture parameter needs a concrete type");
if (parameter.convert && (any || !dynamic_cast<Name*>(parameter.type_expr)))
if (parameter.convert && (wildcard || !dynamic_cast<Name*>(parameter.type_expr)))
throw Error(parameter.type_expr->location, "'as' parameter conversion requires a concrete named type constructor");
if (parameters.back() == "void")
throw Error(parameter.type_expr->location, "function parameters cannot have type void");
@@ -7294,13 +7294,13 @@ void Module::collect()
if (variadic && function->host)
throw Error(function->location, "host declarations cannot use variadic parameters");
if (variadic && generic)
throw Error(function->location, "variadic parameters cannot use any yet");
throw Error(function->location, "variadic parameters cannot use * yet");
if (handler && variadic)
throw Error(function->location, "Bearer handlers cannot use variadic parameters");
if (handler && std::any_of(default_values.begin(), default_values.end(), [](Expr* value) { return value; }))
throw Error(function->location, "Bearer handlers cannot use default parameters");
if (handler && generic)
throw Error(function->location, "Bearer handlers cannot use any parameters");
throw Error(function->location, "Bearer handlers cannot use * parameters");
if (handler && std::any_of(conversions.begin(), conversions.end(), [](bool value) { return value; }))
throw Error(function->location, "Bearer handlers cannot request parameter conversion");
if (handler && std::any_of(captures.begin(), captures.end(), [](bool value) { return value; }))
@@ -7368,8 +7368,8 @@ void Module::collect()
throw Error(function->return_type->location, "dependent result names an unknown parameter");
if (dependent_parameters[static_cast<std::size_t>(dependent)] < 0 &&
!(dynamic_cast<Name*>(function->parameters[static_cast<std::size_t>(dependent)].type_expr) &&
type_name(*function->parameters[static_cast<std::size_t>(dependent)].type_expr) == "any"))
throw Error(function->return_type->location, "dependent result requires an any parameter");
type_name(*function->parameters[static_cast<std::size_t>(dependent)].type_expr) == "*"))
throw Error(function->return_type->location, "dependent result requires a * parameter");
}
else
fixed_result = value_type(function->return_type, true);
@@ -8389,7 +8389,7 @@ Module::Capabilities Module::discover_capabilities()
scan_string_names.clear();
scan_value_names.clear();
for (std::size_t i = 0; i < generic.function->parameters.size(); ++i)
if (generic.patterns[i] != "any")
if (generic.patterns[i] != "*")
{
const std::string& type = generic.patterns[i];
if (type == "string")
+3
View File
@@ -741,6 +741,8 @@ Expr* Parser::prefix()
return while_expr(current.location);
return program_.make<Name>(current.location, current.text);
}
if (current.text == "*")
return program_.make<Name>(current.location, current.text);
if (current.text == "->")
return result_expr(current.location, true);
if (current.text == "...")
@@ -1359,6 +1361,7 @@ std::string format_source(std::string_view source)
const bool unary_minus = is_symbol(token, "-") && !value_end;
if (is_symbol(token, "..") || is_symbol(token, "...")) { write(text); continue; }
if (is_symbol(token, "!") || unary_minus) { if (before && before->kind == TokenKind::identifier) space(); write(text); continue; }
if (is_symbol(token, "*") && before && is_symbol(*before, ":")) { write(text); continue; }
if (token.kind == TokenKind::symbol) { space(); write(text); space(); continue; }
if (before && (before->kind == TokenKind::identifier || before->kind == TokenKind::integer || before->kind == TokenKind::floating || before->kind == TokenKind::string || before->kind == TokenKind::markup || is_symbol(*before, ")") || is_symbol(*before, "]") || is_symbol(*before, "}"))) space();
write(raw(token));
+1 -1
View File
@@ -889,7 +889,7 @@ function mysql_info(handle : u64, key : string) dval {
function random_bytes(count : u64) string { -> __bearer_random_bytes(count) }
function __gen_noise(min : u64, max : u64, index : u64, seed : u64) u64 { -> __bearer_noise_u64(__bearer_noise_gen_int(), min, max, index, seed) }
function __gen_noise(min : f64, max : f64, index : u64, seed : u64) f64 { -> __bearer_noise_f64(__bearer_noise_gen_float(), min, max, index, seed, 0.000000000001) }
function gen_noise(min : any, max : min::type, index : u64, seed : u64) min::type { -> __gen_noise(min, max, index, seed) }
function gen_noise(min : *, max : min::type, index : u64, seed : u64) min::type { -> __gen_noise(min, max, index, seed) }
function gen_noise64(index : u64, seed : u64 = 0) u64 { -> __bearer_noise_u64(__bearer_noise_gen_noise64(), index, seed, 0, 0) }
function draw_int(from : u64, to : u64) u64 { -> __bearer_noise_u64(__bearer_noise_draw_int(), from, to, 0, 0) }
function draw_float(from : f64, to : f64, precision : f64 = 0.000000000001) f64 { -> __bearer_noise_f64(__bearer_noise_draw_float(), from, to, 0, 0, precision) }
+2 -2
View File
@@ -2,7 +2,7 @@
#pragma once
#include <string_view>
namespace capy::stdlib {
inline constexpr char digest[] __attribute__((used)) = "003ab3997ed254da057b2bd074a8d5898b3d5517006bcb1f90a30bcc7d52436a";
inline constexpr unsigned char source[] = {47,47,32,80,114,105,118,97,116,101,32,116,121,112,101,100,32,104,111,115,116,32,65,66,73,32,100,101,99,108,97,114,97,116,105,111,110,115,46,32,32,78,97,109,101,115,32,109,97,112,32,100,105,114,101,99,116,108,121,32,116,111,32,101,110,118,32,115,121,109,98,111,108,115,46,10,104,111,115,116,32,102,117,110,99,116,105,111,110,32,95,95,98,101,97,114,101,114,95,112,114,105,110,116,95,98,121,116,101,115,40,118,97,108,117,101,32,58,32,115,116,114,105,110,103,41,10,104,111,115,116,32,102,117,110,99,116,105,111,110,32,95,95,98,101,97,114,101,114,95,102,108,117,115,104,95,111,117,116,112,117,116,40,41,32,98,111,111,108,10,104,111,115,116,32,102,117,110,99,116,105,111,110,32,95,95,98,101,97,114,101,114,95,112,111,119,95,102,51,50,40,98,97,115,101,32,58,32,102,51,50,44,32,101,120,112,111,110,101,110,116,32,58,32,102,51,50,41,32,102,51,50,10,104,111,115,116,32,102,117,110,99,116,105,111,110,32,95,95,98,101,97,114,101,114,95,112,111,119,95,102,54,52,40,98,97,115,101,32,58,32,102,54,52,44,32,101,120,112,111,110,101,110,116,32,58,32,102,54,52,41,32,102,54,52,10,104,111,115,116,32,102,117,110,99,116,105,111,110,32,95,95,98,101,97,114,101,114,95,108,111,103,95,102,51,50,40,118,97,108,117,101,32,58,32,102,51,50,41,32,102,51,50,10,104,111,115,116,32,102,117,110,99,116,105,111,110,32,95,95,98,101,97,114,101,114,95,108,111,103,95,102,54,52,40,118,97,108,117,101,32,58,32,102,54,52,41,32,102,54,52,10,104,111,115,116,32,102,117,110,99,116,105,111,110,32,95,95,98,101,97,114,101,114,95,101,120,112,95,102,51,50,40,118,97,108,117,101,32,58,32,102,51,50,41,32,102,51,50,10,104,111,115,116,32,102,117,110,99,116,105,111,110,32,95,95,98,101,97,114,101,114,95,101,120,112,95,102,54,52,40,118,97,108,117,101,32,58,32,102,54,52,41,32,102,54,52,10,104,111,115,116,32,102,117,110,99,116,105,111,110,32,95,95,98,101,97,114,101,114,95,115,105,110,95,102,51,50,40,118,97,108,117,101,32,58,32,102,51,50,41,32,102,51,50,10,104,111,115,116,32,102,117,110,99,116,105,111,110,32,95,95,98,101,97,114,101,114,95,115,105,110,95,102,54,52,40,118,97,108,117,101,32,58,32,102,54,52,41,32,102,54,52,10,104,111,115,116,32,102,117,110,99,116,105,111,110,32,95,95,98,101,97,114,101,114,95,99,111,115,95,102,51,50,40,118,97,108,117,101,32,58,32,102,51,50,41,32,102,51,50,10,104,111,115,116,32,102,117,110,99,116,105,111,110,32,95,95,98,101,97,114,101,114,95,99,111,115,95,102,54,52,40,118,97,108,117,101,32,58,32,102,54,52,41,32,102,54,52,10,104,111,115,116,32,102,117,110,99,116,105,111,110,32,95,95,98,101,97,114,101,114,95,97,116,97,110,50,95,102,51,50,40,121,32,58,32,102,51,50,44,32,120,32,58,32,102,51,50,41,32,102,51,50,10,104,111,115,116,32,102,117,110,99,116,105,111,110,32,95,95,98,101,97,114,101,114,95,97,116,97,110,50,95,102,54,52,40,121,32,58,32,102,54,52,44,32,120,32,58,32,102,54,52,41,32,102,54,52,10,104,111,115,116,32,102,117,110,99,116,105,111,110,32,95,95,98,101,97,114,101,114,95,100,118,95,110,111,110,101,40,41,32,100,118,97,108,10,104,111,115,116,32,102,117,110,99,116,105,111,110,32,95,95,98,101,97,114,101,114,95,99,97,112,121,95,114,101,102,108,101,99,116,95,115,116,114,117,99,116,40,111,98,106,101,99,116,32,58,32,115,51,50,44,32,109,101,109,111,114,121,95,98,97,115,101,32,58,32,115,51,50,44,32,115,116,114,117,99,116,95,100,101,115,99,114,105,112,116,111,114,95,111,102,102,115,101,116,32,58,32,115,51,50,41,32,100,118,97,108,10,104,111,115,116,32,102,117,110,99,116,105,111,110,32,95,95,98,101,97,114,101,114,95,100,118,95,105,115,95,110,111,110,101,40,118,97,108,117,101,32,58,32,100,118,97,108,41,32,98,111,111,108,10,104,111,115,116,32,102,117,110,99,116,105,111,110,32,95,95,98,101,97,114,101,114,95,100,118,95,114,101,113,117,105,114,101,40,118,97,108,117,101,32,58,32,100,118,97,108,44,32,112,97,116,104,32,58,32,115,116,114,105,110,103,41,32,100,118,97,108,10,104,111,115,116,32,102,117,110,99,116,105,111,110,32,95,95,98,101,97,114,101,114,95,100,118,95,115,101,116,95,112,97,116,104,40,118,97,108,117,101,32,58,32,100,118,97,108,44,32,112,97,116,104,32,58,32,100,118,97,108,44,32,114,101,112,108,97,99,101,109,101,110,116,32,58,32,100,118,97,108,41,32,100,118,97,108,10,104,111,115,116,32,102,117,110,99,116,105,111,110,32,95,95,98,101,97,114,101,114,95,100,118,95,97,112,112,108,121,40,111,112,101,114,97,116,105,111,110,32,58,32,115,51,50,44,32,118,97,108,117,101,32,58,32,100,118,97,108,44,32,107,101,121,32,58,32,115,116,114,105,110,103,44,32,97,114,103,117,109,101,110,116,32,58,32,100,118,97,108,41,32,100,118,97,108,10,104,111,115,116,32,102,117,110,99,116,105,111,110,32,95,95,98,101,97,114,101,114,95,100,118,97,108,95,114,101,112,108,97,99,101,40,116,97,114,103,101,116,32,58,32,100,118,97,108,44,32,114,101,112,108,97,99,101,109,101,110,116,32,58,32,100,118,97,108,41,32,100,118,97,108,10,104,111,115,116,32,102,117,110,99,116,105,111,110,32,95,95,98,101,97,114,101,114,95,100,118,95,101,120,116,114,97,99,116,95,115,116,114,105,110,103,40,118,97,108,117,101,32,58,32,100,118,97,108,44,32,102,97,108,108,98,97,99,107,32,58,32,115,116,Line truncated
inline constexpr char digest[] __attribute__((used)) = "7626bbf3b48afc319f5e25d991f31c55e9e1b65c72fbba80d5b1eab66692823b";
inline constexpr unsigned char source[] = {47,47,32,80,114,105,118,97,116,101,32,116,121,112,101,100,32,104,111,115,116,32,65,66,73,32,100,101,99,108,97,114,97,116,105,111,110,115,46,32,32,78,97,109,101,115,32,109,97,112,32,100,105,114,101,99,116,108,121,32,116,111,32,101,110,118,32,115,121,109,98,111,108,115,46,10,104,111,115,116,32,102,117,110,99,116,105,111,110,32,95,95,98,101,97,114,101,114,95,112,114,105,110,116,95,98,121,116,101,115,40,118,97,108,117,101,32,58,32,115,116,114,105,110,103,41,10,104,111,115,116,32,102,117,110,99,116,105,111,110,32,95,95,98,101,97,114,101,114,95,102,108,117,115,104,95,111,117,116,112,117,116,40,41,32,98,111,111,108,10,104,111,115,116,32,102,117,110,99,116,105,111,110,32,95,95,98,101,97,114,101,114,95,112,111,119,95,102,51,50,40,98,97,115,101,32,58,32,102,51,50,44,32,101,120,112,111,110,101,110,116,32,58,32,102,51,50,41,32,102,51,50,10,104,111,115,116,32,102,117,110,99,116,105,111,110,32,95,95,98,101,97,114,101,114,95,112,111,119,95,102,54,52,40,98,97,115,101,32,58,32,102,54,52,44,32,101,120,112,111,110,101,110,116,32,58,32,102,54,52,41,32,102,54,52,10,104,111,115,116,32,102,117,110,99,116,105,111,110,32,95,95,98,101,97,114,101,114,95,108,111,103,95,102,51,50,40,118,97,108,117,101,32,58,32,102,51,50,41,32,102,51,50,10,104,111,115,116,32,102,117,110,99,116,105,111,110,32,95,95,98,101,97,114,101,114,95,108,111,103,95,102,54,52,40,118,97,108,117,101,32,58,32,102,54,52,41,32,102,54,52,10,104,111,115,116,32,102,117,110,99,116,105,111,110,32,95,95,98,101,97,114,101,114,95,101,120,112,95,102,51,50,40,118,97,108,117,101,32,58,32,102,51,50,41,32,102,51,50,10,104,111,115,116,32,102,117,110,99,116,105,111,110,32,95,95,98,101,97,114,101,114,95,101,120,112,95,102,54,52,40,118,97,108,117,101,32,58,32,102,54,52,41,32,102,54,52,10,104,111,115,116,32,102,117,110,99,116,105,111,110,32,95,95,98,101,97,114,101,114,95,115,105,110,95,102,51,50,40,118,97,108,117,101,32,58,32,102,51,50,41,32,102,51,50,10,104,111,115,116,32,102,117,110,99,116,105,111,110,32,95,95,98,101,97,114,101,114,95,115,105,110,95,102,54,52,40,118,97,108,117,101,32,58,32,102,54,52,41,32,102,54,52,10,104,111,115,116,32,102,117,110,99,116,105,111,110,32,95,95,98,101,97,114,101,114,95,99,111,115,95,102,51,50,40,118,97,108,117,101,32,58,32,102,51,50,41,32,102,51,50,10,104,111,115,116,32,102,117,110,99,116,105,111,110,32,95,95,98,101,97,114,101,114,95,99,111,115,95,102,54,52,40,118,97,108,117,101,32,58,32,102,54,52,41,32,102,54,52,10,104,111,115,116,32,102,117,110,99,116,105,111,110,32,95,95,98,101,97,114,101,114,95,97,116,97,110,50,95,102,51,50,40,121,32,58,32,102,51,50,44,32,120,32,58,32,102,51,50,41,32,102,51,50,10,104,111,115,116,32,102,117,110,99,116,105,111,110,32,95,95,98,101,97,114,101,114,95,97,116,97,110,50,95,102,54,52,40,121,32,58,32,102,54,52,44,32,120,32,58,32,102,54,52,41,32,102,54,52,10,104,111,115,116,32,102,117,110,99,116,105,111,110,32,95,95,98,101,97,114,101,114,95,100,118,95,110,111,110,101,40,41,32,100,118,97,108,10,104,111,115,116,32,102,117,110,99,116,105,111,110,32,95,95,98,101,97,114,101,114,95,99,97,112,121,95,114,101,102,108,101,99,116,95,115,116,114,117,99,116,40,111,98,106,101,99,116,32,58,32,115,51,50,44,32,109,101,109,111,114,121,95,98,97,115,101,32,58,32,115,51,50,44,32,115,116,114,117,99,116,95,100,101,115,99,114,105,112,116,111,114,95,111,102,102,115,101,116,32,58,32,115,51,50,41,32,100,118,97,108,10,104,111,115,116,32,102,117,110,99,116,105,111,110,32,95,95,98,101,97,114,101,114,95,100,118,95,105,115,95,110,111,110,101,40,118,97,108,117,101,32,58,32,100,118,97,108,41,32,98,111,111,108,10,104,111,115,116,32,102,117,110,99,116,105,111,110,32,95,95,98,101,97,114,101,114,95,100,118,95,114,101,113,117,105,114,101,40,118,97,108,117,101,32,58,32,100,118,97,108,44,32,112,97,116,104,32,58,32,115,116,114,105,110,103,41,32,100,118,97,108,10,104,111,115,116,32,102,117,110,99,116,105,111,110,32,95,95,98,101,97,114,101,114,95,100,118,95,115,101,116,95,112,97,116,104,40,118,97,108,117,101,32,58,32,100,118,97,108,44,32,112,97,116,104,32,58,32,100,118,97,108,44,32,114,101,112,108,97,99,101,109,101,110,116,32,58,32,100,118,97,108,41,32,100,118,97,108,10,104,111,115,116,32,102,117,110,99,116,105,111,110,32,95,95,98,101,97,114,101,114,95,100,118,95,97,112,112,108,121,40,111,112,101,114,97,116,105,111,110,32,58,32,115,51,50,44,32,118,97,108,117,101,32,58,32,100,118,97,108,44,32,107,101,121,32,58,32,115,116,114,105,110,103,44,32,97,114,103,117,109,101,110,116,32,58,32,100,118,97,108,41,32,100,118,97,108,10,104,111,115,116,32,102,117,110,99,116,105,111,110,32,95,95,98,101,97,114,101,114,95,100,118,97,108,95,114,101,112,108,97,99,101,40,116,97,114,103,101,116,32,58,32,100,118,97,108,44,32,114,101,112,108,97,99,101,109,101,110,116,32,58,32,100,118,97,108,41,32,100,118,97,108,10,104,111,115,116,32,102,117,110,99,116,105,111,110,32,95,95,98,101,97,114,101,114,95,100,118,95,101,120,116,114,97,99,116,95,115,116,114,105,110,103,40,118,97,108,117,101,32,58,32,100,118,97,108,44,32,102,97,108,108,98,97,99,107,32,58,32,115,116,Line truncated
inline const std::string_view text(reinterpret_cast<const char*>(source), sizeof(source));
}
+1 -1
View File
@@ -1,7 +1,7 @@
#pragma once
#define BEARER_WASM_CORE_ABI_VERSION 40
#define BEARER_COMPILER_UNIT_ABI_VERSION 39
#define BEARER_COMPILER_UNIT_ABI_VERSION 40
#define BEARER_WASM_OBJECT_WORD_SIZE 4
#define BEARER_WASM_OBJECT_REFS_OFFSET 0