semantifold 0.3.0 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +58 -15
- package/build/index.d.ts +48 -2
- package/build/index.d.ts.map +1 -1
- package/build/index.js +57 -8
- package/build/src/artifact-path.d.ts +23 -1
- package/build/src/artifact-path.d.ts.map +1 -1
- package/build/src/artifact-path.js +45 -3
- package/build/src/artifacts.d.ts.map +1 -1
- package/build/src/artifacts.js +66 -1
- package/build/src/backends/c-validation.d.ts.map +1 -1
- package/build/src/backends/c-validation.js +7 -3
- package/build/src/backends/cpp-validation.d.ts.map +1 -1
- package/build/src/backends/cpp-validation.js +7 -3
- package/build/src/backends/csharp.js +7 -1
- package/build/src/backends/dart-runtime.d.ts +2 -0
- package/build/src/backends/dart-runtime.d.ts.map +1 -0
- package/build/src/backends/dart-runtime.js +41 -0
- package/build/src/backends/dart.d.ts +20 -0
- package/build/src/backends/dart.d.ts.map +1 -0
- package/build/src/backends/dart.js +321 -0
- package/build/src/backends/effects.d.ts +60 -0
- package/build/src/backends/effects.d.ts.map +1 -0
- package/build/src/backends/effects.js +746 -0
- package/build/src/backends/go.js +18 -4
- package/build/src/backends/identifiers.d.ts +36 -4
- package/build/src/backends/identifiers.d.ts.map +1 -1
- package/build/src/backends/identifiers.js +154 -10
- package/build/src/backends/index.d.ts.map +1 -1
- package/build/src/backends/index.js +27 -4
- package/build/src/backends/ios.d.ts +68 -0
- package/build/src/backends/ios.d.ts.map +1 -0
- package/build/src/backends/ios.js +1503 -0
- package/build/src/backends/java.d.ts.map +1 -1
- package/build/src/backends/java.js +429 -36
- package/build/src/backends/javascript.d.ts +6 -0
- package/build/src/backends/javascript.d.ts.map +1 -1
- package/build/src/backends/javascript.js +380 -24
- package/build/src/backends/kotlin-runtime.d.ts +3 -0
- package/build/src/backends/kotlin-runtime.d.ts.map +1 -0
- package/build/src/backends/kotlin-runtime.js +29 -0
- package/build/src/backends/kotlin.d.ts +23 -0
- package/build/src/backends/kotlin.d.ts.map +1 -0
- package/build/src/backends/kotlin.js +136 -0
- package/build/src/backends/native-validation.d.ts +2 -2
- package/build/src/backends/native-validation.d.ts.map +1 -1
- package/build/src/backends/native-validation.js +2 -2
- package/build/src/backends/ordered-expressions.d.ts.map +1 -1
- package/build/src/backends/ordered-expressions.js +39 -7
- package/build/src/backends/php-stdlib-support.d.ts +19 -0
- package/build/src/backends/php-stdlib-support.d.ts.map +1 -0
- package/build/src/backends/php-stdlib-support.js +227 -0
- package/build/src/backends/php.d.ts.map +1 -1
- package/build/src/backends/php.js +448 -33
- package/build/src/backends/program.d.ts +81 -0
- package/build/src/backends/program.d.ts.map +1 -0
- package/build/src/backends/program.js +1308 -0
- package/build/src/backends/python.js +7 -1
- package/build/src/backends/ruby.d.ts.map +1 -1
- package/build/src/backends/ruby.js +310 -24
- package/build/src/backends/rust-runtime.d.ts +7 -0
- package/build/src/backends/rust-runtime.d.ts.map +1 -0
- package/build/src/backends/rust-runtime.js +32 -0
- package/build/src/backends/rust-validation.d.ts +9 -0
- package/build/src/backends/rust-validation.d.ts.map +1 -0
- package/build/src/backends/rust-validation.js +78 -0
- package/build/src/backends/rust.d.ts +24 -0
- package/build/src/backends/rust.d.ts.map +1 -0
- package/build/src/backends/rust.js +344 -0
- package/build/src/backends/scalars.d.ts +14 -6
- package/build/src/backends/scalars.d.ts.map +1 -1
- package/build/src/backends/scalars.js +167 -17
- package/build/src/backends/shared.d.ts +23 -4
- package/build/src/backends/shared.d.ts.map +1 -1
- package/build/src/backends/shared.js +2158 -62
- package/build/src/backends/stdlib-support.d.ts +14 -0
- package/build/src/backends/stdlib-support.d.ts.map +1 -0
- package/build/src/backends/stdlib-support.js +237 -0
- package/build/src/backends/swift-runtime.d.ts +3 -0
- package/build/src/backends/swift-runtime.d.ts.map +1 -0
- package/build/src/backends/swift-runtime.js +14 -0
- package/build/src/backends/swift.d.ts +8 -0
- package/build/src/backends/swift.d.ts.map +1 -0
- package/build/src/backends/swift.js +127 -0
- package/build/src/backends/typescript.d.ts.map +1 -1
- package/build/src/backends/typescript.js +344 -24
- package/build/src/backends/wasm.d.ts +43 -0
- package/build/src/backends/wasm.d.ts.map +1 -0
- package/build/src/backends/wasm.js +2164 -0
- package/build/src/backends/writer.d.ts +235 -4
- package/build/src/backends/writer.d.ts.map +1 -1
- package/build/src/backends/writer.js +468 -3
- package/build/src/diagnostic.d.ts +4 -3
- package/build/src/diagnostic.d.ts.map +1 -1
- package/build/src/diagnostic.js +5 -3
- package/build/src/frontends/c.d.ts.map +1 -1
- package/build/src/frontends/c.js +5 -3
- package/build/src/frontends/cpp.d.ts.map +1 -1
- package/build/src/frontends/cpp.js +5 -3
- package/build/src/frontends/csharp.d.ts.map +1 -1
- package/build/src/frontends/csharp.js +7 -3
- package/build/src/frontends/dart.d.ts +10 -0
- package/build/src/frontends/dart.d.ts.map +1 -0
- package/build/src/frontends/dart.js +913 -0
- package/build/src/frontends/index.d.ts +3 -1
- package/build/src/frontends/index.d.ts.map +1 -1
- package/build/src/frontends/index.js +15 -5
- package/build/src/frontends/java.d.ts +110 -1
- package/build/src/frontends/java.d.ts.map +1 -1
- package/build/src/frontends/java.js +1725 -70
- package/build/src/frontends/javascript-typescript.d.ts +69 -1
- package/build/src/frontends/javascript-typescript.d.ts.map +1 -1
- package/build/src/frontends/javascript-typescript.js +1825 -93
- package/build/src/frontends/kotlin.d.ts +10 -0
- package/build/src/frontends/kotlin.d.ts.map +1 -0
- package/build/src/frontends/kotlin.js +685 -0
- package/build/src/frontends/php.d.ts +118 -1
- package/build/src/frontends/php.d.ts.map +1 -1
- package/build/src/frontends/php.js +1583 -76
- package/build/src/frontends/program.d.ts +74 -0
- package/build/src/frontends/program.d.ts.map +1 -0
- package/build/src/frontends/program.js +989 -0
- package/build/src/frontends/ruby.d.ts +68 -1
- package/build/src/frontends/ruby.d.ts.map +1 -1
- package/build/src/frontends/ruby.js +1446 -101
- package/build/src/frontends/rust-parser.d.ts +11 -0
- package/build/src/frontends/rust-parser.d.ts.map +1 -0
- package/build/src/frontends/rust-parser.js +15 -0
- package/build/src/frontends/rust.d.ts +14 -0
- package/build/src/frontends/rust.d.ts.map +1 -0
- package/build/src/frontends/rust.js +715 -0
- package/build/src/frontends/scalars.d.ts +10 -0
- package/build/src/frontends/scalars.d.ts.map +1 -1
- package/build/src/frontends/scalars.js +28 -2
- package/build/src/frontends/swift.d.ts +10 -0
- package/build/src/frontends/swift.d.ts.map +1 -0
- package/build/src/frontends/swift.js +860 -0
- package/build/src/frontends/types.d.ts +186 -0
- package/build/src/frontends/types.d.ts.map +1 -0
- package/build/src/frontends/types.js +634 -0
- package/build/src/language-registry.d.ts +46 -4
- package/build/src/language-registry.d.ts.map +1 -1
- package/build/src/language-registry.js +167 -13
- package/build/src/mapping.d.ts +2 -2
- package/build/src/mapping.d.ts.map +1 -1
- package/build/src/mapping.js +31 -10
- package/build/src/semantic/capabilities.d.ts +66 -0
- package/build/src/semantic/capabilities.d.ts.map +1 -0
- package/build/src/semantic/capabilities.js +649 -0
- package/build/src/semantic/effects.d.ts +26 -0
- package/build/src/semantic/effects.d.ts.map +1 -0
- package/build/src/semantic/effects.js +764 -0
- package/build/src/semantic/generics.d.ts +23 -0
- package/build/src/semantic/generics.d.ts.map +1 -0
- package/build/src/semantic/generics.js +61 -0
- package/build/src/semantic/lifetime.d.ts +37 -0
- package/build/src/semantic/lifetime.d.ts.map +1 -0
- package/build/src/semantic/lifetime.js +527 -0
- package/build/src/semantic/provenance.d.ts +9 -2
- package/build/src/semantic/provenance.d.ts.map +1 -1
- package/build/src/semantic/provenance.js +462 -20
- package/build/src/semantic/scalars.d.ts +11 -0
- package/build/src/semantic/scalars.d.ts.map +1 -1
- package/build/src/semantic/scalars.js +16 -1
- package/build/src/semantic/stdlib.d.ts +254 -0
- package/build/src/semantic/stdlib.d.ts.map +1 -0
- package/build/src/semantic/stdlib.js +880 -0
- package/build/src/semantic/types.d.ts +2952 -202
- package/build/src/semantic/types.d.ts.map +1 -1
- package/build/src/semantic/types.js +688 -15
- package/build/src/semantic/validate.d.ts +85 -5
- package/build/src/semantic/validate.d.ts.map +1 -1
- package/build/src/semantic/validate.js +2576 -98
- package/build/src/stdlib-facades.d.ts +304 -0
- package/build/src/stdlib-facades.d.ts.map +1 -0
- package/build/src/stdlib-facades.js +1167 -0
- package/build/src/stdlib-negotiation.d.ts +69 -0
- package/build/src/stdlib-negotiation.d.ts.map +1 -0
- package/build/src/stdlib-negotiation.js +403 -0
- package/build/src/stdlib-providers.d.ts +72 -0
- package/build/src/stdlib-providers.d.ts.map +1 -0
- package/build/src/stdlib-providers.js +339 -0
- package/build/src/toolchains.d.ts +55 -1
- package/build/src/toolchains.d.ts.map +1 -1
- package/build/src/toolchains.js +15 -4
- package/docs/architecture.md +45 -13
- package/docs/dart.md +60 -0
- package/docs/goals.md +3 -3
- package/docs/ios.md +121 -0
- package/docs/kotlin.md +42 -0
- package/docs/language-support.md +231 -26
- package/docs/multi-file-modules.md +52 -0
- package/docs/parser-qualification.md +121 -8
- package/docs/plans/2026-09-05-standard-library-portability.md +10 -10
- package/docs/rust.md +88 -0
- package/docs/source-maps.md +15 -7
- package/docs/standard-library-portability.md +39 -8
- package/docs/swift.md +44 -0
- package/docs/testing.md +366 -4
- package/docs/webassembly.md +52 -0
- package/index.js +63 -8
- package/node_modules/semantifold-tree-sitter-legacy-internal/README.md +2 -2
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/LICENSE +21 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/README.md +45 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/binding.gyp +30 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/bindings/node/binding.cc +20 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/bindings/node/binding_test.js +9 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/bindings/node/index.d.ts +28 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/bindings/node/index.js +11 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/grammar.js +1630 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/package.json +64 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/prebuilds/darwin-arm64/tree-sitter-rust.node +0 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/prebuilds/darwin-x64/tree-sitter-rust.node +0 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/prebuilds/linux-arm64/tree-sitter-rust.node +0 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/prebuilds/linux-x64/tree-sitter-rust.node +0 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/prebuilds/win32-arm64/tree-sitter-rust.node +0 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/prebuilds/win32-x64/tree-sitter-rust.node +0 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/queries/highlights.scm +159 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/queries/injections.scm +9 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/queries/tags.scm +60 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/src/grammar.json +9405 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/src/node-types.json +5399 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/src/parser.c +192569 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/src/scanner.c +393 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/src/tree_sitter/alloc.h +54 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/src/tree_sitter/array.h +290 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/src/tree_sitter/parser.h +266 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/tree-sitter-rust.wasm +0 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/tree-sitter.json +53 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/package.json +3 -2
- package/node_modules/semantifold-tree-sitter-legacy-internal/src/c.js +5 -4
- package/package.json +5 -2
- package/src/artifact-path.js +47 -2
- package/src/artifacts.js +67 -0
- package/src/backends/c-validation.js +6 -1
- package/src/backends/cpp-validation.js +6 -1
- package/src/backends/csharp.js +3 -0
- package/src/backends/dart-runtime.js +41 -0
- package/src/backends/dart.js +326 -0
- package/src/backends/effects.js +705 -0
- package/src/backends/go.js +14 -2
- package/src/backends/identifiers.js +160 -9
- package/src/backends/index.js +27 -2
- package/src/backends/ios.js +1612 -0
- package/src/backends/java.js +454 -36
- package/src/backends/javascript.js +389 -23
- package/src/backends/kotlin-runtime.js +29 -0
- package/src/backends/kotlin.js +141 -0
- package/src/backends/native-validation.js +1 -1
- package/src/backends/ordered-expressions.js +40 -6
- package/src/backends/php-stdlib-support.js +239 -0
- package/src/backends/php.js +469 -32
- package/src/backends/program.js +1407 -0
- package/src/backends/python.js +3 -0
- package/src/backends/ruby.js +326 -23
- package/src/backends/rust-runtime.js +34 -0
- package/src/backends/rust-validation.js +75 -0
- package/src/backends/rust.js +335 -0
- package/src/backends/scalars.js +141 -16
- package/src/backends/shared.js +2304 -124
- package/src/backends/stdlib-support.js +234 -0
- package/src/backends/swift-runtime.js +14 -0
- package/src/backends/swift.js +132 -0
- package/src/backends/typescript.js +349 -23
- package/src/backends/wasm.js +2208 -0
- package/src/backends/writer.js +520 -2
- package/src/diagnostic.js +4 -2
- package/src/frontends/c.js +4 -2
- package/src/frontends/cpp.js +4 -2
- package/src/frontends/csharp.js +4 -2
- package/src/frontends/dart.js +963 -0
- package/src/frontends/index.js +14 -4
- package/src/frontends/java.js +1977 -69
- package/src/frontends/javascript-typescript.js +2046 -102
- package/src/frontends/kotlin.js +713 -0
- package/src/frontends/php.js +1725 -79
- package/src/frontends/program.js +1062 -0
- package/src/frontends/ruby.js +1624 -98
- package/src/frontends/rust-parser.js +18 -0
- package/src/frontends/rust.js +714 -0
- package/src/frontends/scalars.js +31 -1
- package/src/frontends/swift.js +893 -0
- package/src/frontends/types.js +750 -0
- package/src/language-registry.js +172 -12
- package/src/mapping.js +33 -9
- package/src/semantic/capabilities.js +671 -0
- package/src/semantic/effects.js +737 -0
- package/src/semantic/generics.js +58 -0
- package/src/semantic/lifetime.js +517 -0
- package/src/semantic/provenance.js +412 -19
- package/src/semantic/scalars.js +17 -0
- package/src/semantic/stdlib.js +921 -0
- package/src/semantic/types.js +765 -14
- package/src/semantic/validate.js +2934 -209
- package/src/stdlib-facades.js +1211 -0
- package/src/stdlib-negotiation.js +446 -0
- package/src/stdlib-providers.js +377 -0
- package/src/toolchains.js +16 -3
|
@@ -18,7 +18,10 @@ export class OrderedExpressionPlanner {
|
|
|
18
18
|
*/
|
|
19
19
|
constructor(module, language = "c") {
|
|
20
20
|
this.language = language
|
|
21
|
-
this.functions = new Map(module.functions.map((declaration) => [
|
|
21
|
+
this.functions = new Map(module.functions.map((declaration) => [
|
|
22
|
+
declaration.name,
|
|
23
|
+
scalarName(declaration.returnType, language, declaration.location)
|
|
24
|
+
]))
|
|
22
25
|
this.nextTemporary = 1
|
|
23
26
|
}
|
|
24
27
|
|
|
@@ -33,6 +36,9 @@ export class OrderedExpressionPlanner {
|
|
|
33
36
|
if (expression.kind == "BooleanLiteral") return "boolean"
|
|
34
37
|
if (expression.kind == "StringLiteral") return "string"
|
|
35
38
|
if (expression.kind == "UnaryExpression" || expression.kind == "BinaryExpression") return expression.type
|
|
39
|
+
if (expression.kind != "CallExpression" && expression.kind != "IdentifierExpression") {
|
|
40
|
+
return unsupportedCapability(this.language, "collection expression reached native scalar planning", expression.location)
|
|
41
|
+
}
|
|
36
42
|
const type = expression.kind == "CallExpression" ? this.functions.get(expression.callee) : bindings.get(expression.name)
|
|
37
43
|
|
|
38
44
|
if (!type) return unsupportedCapability(this.language, "unresolved expression type", expression.location)
|
|
@@ -94,9 +100,15 @@ export class OrderedExpressionPlanner {
|
|
|
94
100
|
* @returns {string} Stable SHA-256 profile signature.
|
|
95
101
|
*/
|
|
96
102
|
export function statementSignature(statement) {
|
|
97
|
-
const consumer = statement.kind == "LocalDeclaration" ? [statement.kind, statement.name,
|
|
103
|
+
const consumer = statement.kind == "LocalDeclaration" ? [statement.kind, statement.name,
|
|
104
|
+
scalarName(statement.type, "c", statement.location), statement.mutable] :
|
|
98
105
|
statement.kind == "AssignmentStatement" ? [statement.kind, statement.target.name] : [statement.kind]
|
|
99
|
-
const expression = statement.kind == "IfStatement" ? statement.condition :
|
|
106
|
+
const expression = statement.kind == "IfStatement" ? statement.condition :
|
|
107
|
+
statement.kind == "LocalDeclaration" ? statement.initializer :
|
|
108
|
+
statement.kind == "AssignmentStatement" || statement.kind == "ExpressionStatement" || statement.kind == "PrintStatement" ? statement.expression :
|
|
109
|
+
statement.kind == "ReturnStatement" ? statement.expression : undefined
|
|
110
|
+
|
|
111
|
+
if (!expression) throw new TypeError("Bare return reached native statement signature planning.")
|
|
100
112
|
|
|
101
113
|
return createHash("sha256").update(JSON.stringify([consumer, expressionSignature(expression)])).digest("hex")
|
|
102
114
|
}
|
|
@@ -111,6 +123,8 @@ function expressionSignature(expression) {
|
|
|
111
123
|
if (expression.kind == "IntegerLiteral" || expression.kind == "BooleanLiteral" || expression.kind == "StringLiteral") return [expression.kind, expression.value]
|
|
112
124
|
if (expression.kind == "CallExpression") return [expression.kind, expression.callee, ...expression.arguments.map(expressionSignature)]
|
|
113
125
|
if (expression.kind == "UnaryExpression") return [expression.kind, expression.operation, expression.type, expressionSignature(expression.operand)]
|
|
126
|
+
if (expression.kind != "BinaryExpression") return [expression.kind]
|
|
127
|
+
|
|
114
128
|
return [expression.kind, expression.operation, expression.type, expressionSignature(expression.left), expressionSignature(expression.right)]
|
|
115
129
|
}
|
|
116
130
|
|
|
@@ -139,14 +153,19 @@ export function planNativeModule(module, language = "c") {
|
|
|
139
153
|
block.statements.forEach((statement, index) => {
|
|
140
154
|
const statementPath = `${path}/statements/${index}`
|
|
141
155
|
const field = statement.kind == "IfStatement" ? "condition" : statement.kind == "LocalDeclaration" ? "initializer" : "expression"
|
|
142
|
-
const expression = statement.kind == "IfStatement" ? statement.condition :
|
|
156
|
+
const expression = statement.kind == "IfStatement" ? statement.condition :
|
|
157
|
+
statement.kind == "LocalDeclaration" ? statement.initializer :
|
|
158
|
+
statement.kind == "AssignmentStatement" || statement.kind == "ExpressionStatement" || statement.kind == "PrintStatement" ? statement.expression :
|
|
159
|
+
statement.kind == "ReturnStatement" ? statement.expression : undefined
|
|
143
160
|
/** @type {PlannedStep[]} */
|
|
144
161
|
const steps = []
|
|
162
|
+
|
|
163
|
+
if (!expression) throw new TypeError("Bare return reached native expression planning.")
|
|
145
164
|
const value = planner.plan(expression, `${statementPath}/${field}`, bindings, steps)
|
|
146
165
|
|
|
147
166
|
if (plans.size >= 999999) unsupportedCapability(language, "ordered statement limit", statement.location)
|
|
148
167
|
plans.set(statementPath, {id: String(plans.size + 1).padStart(6, "0"), steps, value})
|
|
149
|
-
if (statement.kind == "LocalDeclaration") bindings.set(statement.name, statement.type.
|
|
168
|
+
if (statement.kind == "LocalDeclaration") bindings.set(statement.name, scalarName(statement.type, language, statement.location))
|
|
150
169
|
if (statement.kind == "IfStatement") {
|
|
151
170
|
visit(statement.consequent, `${statementPath}/consequent`, bindings)
|
|
152
171
|
if (statement.alternate) visit(statement.alternate, `${statementPath}/alternate`, bindings)
|
|
@@ -155,7 +174,22 @@ export function planNativeModule(module, language = "c") {
|
|
|
155
174
|
}
|
|
156
175
|
|
|
157
176
|
module.functions.forEach((declaration, index) => visit(declaration.body, `/functions/${index}/body`,
|
|
158
|
-
new Map(declaration.parameters.map((parameter) => [parameter.name, parameter.type.
|
|
177
|
+
new Map(declaration.parameters.map((parameter) => [parameter.name, scalarName(parameter.type, language, parameter.location)]))))
|
|
159
178
|
visit(module.entryPoint.body, "/entryPoint/body", new Map())
|
|
160
179
|
return plans
|
|
161
180
|
}
|
|
181
|
+
|
|
182
|
+
/**
|
|
183
|
+
* Narrows a type after non-cohort collection rejection.
|
|
184
|
+
* @param {import("../semantic/types.js").SemanticFunctionReturnType} type - Semantic type.
|
|
185
|
+
* @param {"c" | "cpp"} language - Diagnostic language.
|
|
186
|
+
* @param {import("../semantic/types.js").SourceLocation} location - Owning location.
|
|
187
|
+
* @returns {Scalar} Scalar name.
|
|
188
|
+
*/
|
|
189
|
+
function scalarName(type, language, location) {
|
|
190
|
+
if (type.kind != "TypeReference" || type.name == "void") {
|
|
191
|
+
return unsupportedCapability(language, "collection or void type reached native scalar planning", location)
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
return type.name
|
|
195
|
+
}
|
|
@@ -0,0 +1,239 @@
|
|
|
1
|
+
// @ts-check
|
|
2
|
+
|
|
3
|
+
import {protectedEntryName} from "../semantic/stdlib.js"
|
|
4
|
+
|
|
5
|
+
const task037Modules = new Set([
|
|
6
|
+
"semantifold.output", "semantifold.resource", "semantifold.socket-client", "semantifold.text-stream"
|
|
7
|
+
])
|
|
8
|
+
|
|
9
|
+
/** @typedef {{close?: string, connect?: string, eof?: string, read?: string, setup?: string, write?: string}} PhpNativeSeam */
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Generates one isolated PHP provider artifact for the Task 037 canonical module.
|
|
13
|
+
* The optional native seam is generator-internal and exists only for real-runtime provider tests.
|
|
14
|
+
* @param {string} module - Exact canonical module identity.
|
|
15
|
+
* @param {readonly string[]} operations - Reachable operations for this provider.
|
|
16
|
+
* @param {PhpNativeSeam} [seam] - Protected test-owned native call names.
|
|
17
|
+
* @returns {string} Complete PHP provider source.
|
|
18
|
+
*/
|
|
19
|
+
export function generateTask037PhpProviderContent(module, operations, seam = {}) {
|
|
20
|
+
if (!task037Modules.has(module)) throw new RangeError(`Unknown Task 037 PHP provider module '${module}'.`)
|
|
21
|
+
const used = new Set(operations)
|
|
22
|
+
const supported = module == "semantifold.resource" ? "v1_close" : module == "semantifold.socket-client" ? "v1_connect" :
|
|
23
|
+
module == "semantifold.text-stream" ? "v1_read_line" : "v1_write_line"
|
|
24
|
+
|
|
25
|
+
if ([...used].some((operation) => operation != supported)) {
|
|
26
|
+
throw new RangeError(`Unknown operation selected for Task 037 PHP provider module '${module}'.`)
|
|
27
|
+
}
|
|
28
|
+
const body = module == "semantifold.resource" ? resourceProvider(used, seam) :
|
|
29
|
+
module == "semantifold.socket-client" ? socketClientProvider(used, seam) :
|
|
30
|
+
module == "semantifold.text-stream" ? textStreamProvider(used, seam) : outputProvider(used, seam)
|
|
31
|
+
|
|
32
|
+
return `<?php\ndeclare(strict_types=1);\n/* semantifold-task037-protected-provider */\n${body}` +
|
|
33
|
+
"/* semantifold-task037-protected-provider-end */\n"
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* Generates the canonical resource carrier and optional close operation.
|
|
38
|
+
* @param {Set<string>} used - Reachable operations.
|
|
39
|
+
* @param {PhpNativeSeam} seam - Native seam.
|
|
40
|
+
* @returns {string} Provider body.
|
|
41
|
+
*/
|
|
42
|
+
function resourceProvider(used, seam) {
|
|
43
|
+
const entry = protectedEntryName("php", "semantifold.resource", "v1_close")
|
|
44
|
+
const nativeClose = seam.close ? `${seam.close}($handle)` : "fclose($handle)"
|
|
45
|
+
const closeFunction = used.has("v1_close") ? `
|
|
46
|
+
function ${entry}(ByteStream $resource): void {
|
|
47
|
+
$handle = $resource->__semantifoldClaimForClose();
|
|
48
|
+
$warning = null;
|
|
49
|
+
set_error_handler(static function(int $severity, string $message) use (&$warning): bool {
|
|
50
|
+
$warning = substr($message, 0, 256); return true;
|
|
51
|
+
});
|
|
52
|
+
try {
|
|
53
|
+
try { $closed = ${nativeClose}; } catch (Throwable $error) {
|
|
54
|
+
throw new CloseFailure("CloseFailure", 0, $error);
|
|
55
|
+
}
|
|
56
|
+
} finally { restore_error_handler(); }
|
|
57
|
+
if ($warning !== null || $closed !== true) throw new CloseFailure("CloseFailure");
|
|
58
|
+
}
|
|
59
|
+
` : ""
|
|
60
|
+
|
|
61
|
+
return `final class CloseFailure extends RuntimeException {}
|
|
62
|
+
final class ResourceClosed extends RuntimeException {}
|
|
63
|
+
final class ByteStream {
|
|
64
|
+
private mixed $handle;
|
|
65
|
+
private bool $closed = false;
|
|
66
|
+
private function __construct(mixed $handle) { $this->handle = $handle; }
|
|
67
|
+
public static function __semantifoldFromNative(mixed $handle): self {
|
|
68
|
+
if (!is_resource($handle)) throw new RuntimeException("invalid private stream");
|
|
69
|
+
return new self($handle);
|
|
70
|
+
}
|
|
71
|
+
public function __semantifoldClaimForRead(): mixed {
|
|
72
|
+
if ($this->closed) throw new ResourceClosed("ResourceClosed");
|
|
73
|
+
return $this->handle;
|
|
74
|
+
}
|
|
75
|
+
public function __semantifoldClaimForClose(): mixed {
|
|
76
|
+
if ($this->closed) throw new ResourceClosed("ResourceClosed");
|
|
77
|
+
$this->closed = true;
|
|
78
|
+
return $this->handle;
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
${closeFunction}`
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
/**
|
|
85
|
+
* Generates exact validation and transactional blocking stream acquisition.
|
|
86
|
+
* @param {Set<string>} used - Reachable operations.
|
|
87
|
+
* @param {PhpNativeSeam} seam - Native seam.
|
|
88
|
+
* @returns {string} Provider body.
|
|
89
|
+
*/
|
|
90
|
+
function socketClientProvider(used, seam) {
|
|
91
|
+
const entry = protectedEntryName("php", "semantifold.socket-client", "v1_connect")
|
|
92
|
+
|
|
93
|
+
if (!used.has("v1_connect")) return "final class InvalidHost extends RuntimeException {}\n" +
|
|
94
|
+
"final class InvalidPort extends RuntimeException {}\nfinal class ConnectionFailure extends RuntimeException {}\n"
|
|
95
|
+
const nativeConnect = seam.connect
|
|
96
|
+
? `${seam.connect}($host, $port, $errno, $errorMessage)`
|
|
97
|
+
: "fsockopen($host, $port, $errno, $errorMessage)"
|
|
98
|
+
const nativeClose = seam.close ? `${seam.close}($handle)` : "fclose($handle)"
|
|
99
|
+
const setup = seam.setup ? `${seam.setup}($handle);` : ""
|
|
100
|
+
|
|
101
|
+
return `final class InvalidHost extends RuntimeException {}
|
|
102
|
+
final class InvalidPort extends RuntimeException {}
|
|
103
|
+
final class ConnectionFailure extends RuntimeException {}
|
|
104
|
+
function ${entry}(string $host, int $port): ByteStream {
|
|
105
|
+
if ($host === "" || preg_match("//u", $host) !== 1 || str_contains($host, "://")) {
|
|
106
|
+
throw new InvalidHost("InvalidHost");
|
|
107
|
+
}
|
|
108
|
+
if ($port < 1 || $port > 65535) throw new InvalidPort("InvalidPort");
|
|
109
|
+
$errno = 0; $errorMessage = ""; $warning = null;
|
|
110
|
+
set_error_handler(static function(int $severity, string $message) use (&$warning): bool {
|
|
111
|
+
$warning = substr($message, 0, 256); return true;
|
|
112
|
+
});
|
|
113
|
+
try {
|
|
114
|
+
try { $handle = ${nativeConnect}; } catch (Throwable $error) {
|
|
115
|
+
throw new ConnectionFailure("ConnectionFailure", 0, $error);
|
|
116
|
+
}
|
|
117
|
+
} finally { restore_error_handler(); }
|
|
118
|
+
if ($warning !== null || !is_resource($handle)) throw new ConnectionFailure("ConnectionFailure");
|
|
119
|
+
try {
|
|
120
|
+
${setup}
|
|
121
|
+
return ByteStream::__semantifoldFromNative($handle);
|
|
122
|
+
} catch (Throwable $error) {
|
|
123
|
+
$cleanupWarning = null;
|
|
124
|
+
set_error_handler(static function(int $severity, string $message) use (&$cleanupWarning): bool {
|
|
125
|
+
$cleanupWarning = substr($message, 0, 256); return true;
|
|
126
|
+
});
|
|
127
|
+
try { try { ${nativeClose}; } catch (Throwable) {} } finally { restore_error_handler(); }
|
|
128
|
+
throw new ConnectionFailure("ConnectionFailure", 0, $error);
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
`
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
/**
|
|
135
|
+
* Generates blocking line reads with explicit EOF and incremental UTF-8 validation.
|
|
136
|
+
* @param {Set<string>} used - Reachable operations.
|
|
137
|
+
* @param {PhpNativeSeam} seam - Native seam.
|
|
138
|
+
* @returns {string} Provider body.
|
|
139
|
+
*/
|
|
140
|
+
function textStreamProvider(used, seam) {
|
|
141
|
+
const entry = protectedEntryName("php", "semantifold.text-stream", "v1_read_line")
|
|
142
|
+
|
|
143
|
+
if (!used.has("v1_read_line")) return "final class ReadFailure extends RuntimeException {}\n" +
|
|
144
|
+
"final class DecodeFailure extends RuntimeException {}\n"
|
|
145
|
+
const nativeRead = seam.read ? `${seam.read}($handle, 8192)` : "fgets($handle, 8192)"
|
|
146
|
+
const nativeEof = seam.eof ? `${seam.eof}($handle)` : "feof($handle)"
|
|
147
|
+
const validator = `${entry}__validate_utf8`
|
|
148
|
+
|
|
149
|
+
return `final class ReadFailure extends RuntimeException {}
|
|
150
|
+
final class DecodeFailure extends RuntimeException {}
|
|
151
|
+
function ${validator}(string $chunk, int &$remaining, int &$codepoint, int &$minimum): void {
|
|
152
|
+
$length = strlen($chunk);
|
|
153
|
+
for ($index = 0; $index < $length; $index++) {
|
|
154
|
+
$byte = ord($chunk[$index]);
|
|
155
|
+
if ($remaining === 0) {
|
|
156
|
+
if ($byte <= 0x7f) continue;
|
|
157
|
+
if ($byte >= 0xc2 && $byte <= 0xdf) { $remaining = 1; $codepoint = $byte & 0x1f; $minimum = 0x80; continue; }
|
|
158
|
+
if ($byte >= 0xe0 && $byte <= 0xef) { $remaining = 2; $codepoint = $byte & 0x0f; $minimum = 0x800; continue; }
|
|
159
|
+
if ($byte >= 0xf0 && $byte <= 0xf4) { $remaining = 3; $codepoint = $byte & 0x07; $minimum = 0x10000; continue; }
|
|
160
|
+
throw new DecodeFailure("DecodeFailure");
|
|
161
|
+
}
|
|
162
|
+
if ($byte < 0x80 || $byte > 0xbf) throw new DecodeFailure("DecodeFailure");
|
|
163
|
+
$codepoint = ($codepoint << 6) | ($byte & 0x3f); $remaining--;
|
|
164
|
+
if ($remaining === 0 && ($codepoint < $minimum || $codepoint > 0x10ffff ||
|
|
165
|
+
($codepoint >= 0xd800 && $codepoint <= 0xdfff))) throw new DecodeFailure("DecodeFailure");
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
function ${entry}(ByteStream $resource): ?string {
|
|
169
|
+
$handle = $resource->__semantifoldClaimForRead();
|
|
170
|
+
$buffer = ""; $remaining = 0; $codepoint = 0; $minimum = 0;
|
|
171
|
+
while (true) {
|
|
172
|
+
$warning = null;
|
|
173
|
+
set_error_handler(static function(int $severity, string $message) use (&$warning): bool {
|
|
174
|
+
$warning = substr($message, 0, 256); return true;
|
|
175
|
+
});
|
|
176
|
+
try {
|
|
177
|
+
try { $chunk = ${nativeRead}; } catch (Throwable $error) {
|
|
178
|
+
throw new ReadFailure("ReadFailure", 0, $error);
|
|
179
|
+
}
|
|
180
|
+
} finally { restore_error_handler(); }
|
|
181
|
+
if ($warning !== null) throw new ReadFailure("ReadFailure");
|
|
182
|
+
if ($chunk !== false) {
|
|
183
|
+
if (!is_string($chunk) || $chunk === "") throw new ReadFailure("ReadFailure");
|
|
184
|
+
${validator}($chunk, $remaining, $codepoint, $minimum);
|
|
185
|
+
$buffer .= $chunk;
|
|
186
|
+
if (str_ends_with($buffer, "\\n")) return $buffer;
|
|
187
|
+
continue;
|
|
188
|
+
}
|
|
189
|
+
$eofWarning = null;
|
|
190
|
+
set_error_handler(static function(int $severity, string $message) use (&$eofWarning): bool {
|
|
191
|
+
$eofWarning = substr($message, 0, 256); return true;
|
|
192
|
+
});
|
|
193
|
+
try {
|
|
194
|
+
try { $eof = ${nativeEof}; } catch (Throwable $error) {
|
|
195
|
+
throw new ReadFailure("ReadFailure", 0, $error);
|
|
196
|
+
}
|
|
197
|
+
} finally { restore_error_handler(); }
|
|
198
|
+
if ($eofWarning !== null || $eof !== true) throw new ReadFailure("ReadFailure");
|
|
199
|
+
if ($remaining !== 0) throw new DecodeFailure("DecodeFailure");
|
|
200
|
+
return $buffer === "" ? null : $buffer;
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
`
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
/**
|
|
207
|
+
* Generates complete UTF-8 stdout writes through positive-progress native calls.
|
|
208
|
+
* @param {Set<string>} used - Reachable operations.
|
|
209
|
+
* @param {PhpNativeSeam} seam - Native seam.
|
|
210
|
+
* @returns {string} Provider body.
|
|
211
|
+
*/
|
|
212
|
+
function outputProvider(used, seam) {
|
|
213
|
+
const entry = protectedEntryName("php", "semantifold.output", "v1_write_line")
|
|
214
|
+
|
|
215
|
+
if (!used.has("v1_write_line")) return "final class WriteFailure extends RuntimeException {}\n"
|
|
216
|
+
const nativeWrite = seam.write ? `${seam.write}($remainingBytes)` : "fwrite(STDOUT, $remainingBytes)"
|
|
217
|
+
|
|
218
|
+
return `final class WriteFailure extends RuntimeException {}
|
|
219
|
+
function ${entry}(string $text): void {
|
|
220
|
+
$bytes = str_ends_with($text, "\\n") ? $text : $text . "\\n";
|
|
221
|
+
$length = strlen($bytes); $offset = 0;
|
|
222
|
+
while ($offset < $length) {
|
|
223
|
+
$remainingBytes = substr($bytes, $offset); $warning = null;
|
|
224
|
+
set_error_handler(static function(int $severity, string $message) use (&$warning): bool {
|
|
225
|
+
$warning = substr($message, 0, 256); return true;
|
|
226
|
+
});
|
|
227
|
+
try {
|
|
228
|
+
try { $written = ${nativeWrite}; } catch (Throwable $error) {
|
|
229
|
+
throw new WriteFailure("WriteFailure", 0, $error);
|
|
230
|
+
}
|
|
231
|
+
} finally { restore_error_handler(); }
|
|
232
|
+
if ($warning !== null || !is_int($written) || $written <= 0 || $written > strlen($remainingBytes)) {
|
|
233
|
+
throw new WriteFailure("WriteFailure");
|
|
234
|
+
}
|
|
235
|
+
$offset += $written;
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
`
|
|
239
|
+
}
|