semantifold 0.1.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.
Files changed (111) hide show
  1. package/LICENSE +15 -0
  2. package/README.md +71 -0
  3. package/build/index.d.ts +54 -0
  4. package/build/index.d.ts.map +1 -0
  5. package/build/index.js +45 -0
  6. package/build/src/backends/identifiers.d.ts +19 -0
  7. package/build/src/backends/identifiers.d.ts.map +1 -0
  8. package/build/src/backends/identifiers.js +93 -0
  9. package/build/src/backends/index.d.ts +35 -0
  10. package/build/src/backends/index.d.ts.map +1 -0
  11. package/build/src/backends/index.js +149 -0
  12. package/build/src/backends/java.d.ts +8 -0
  13. package/build/src/backends/java.d.ts.map +1 -0
  14. package/build/src/backends/java.js +172 -0
  15. package/build/src/backends/javascript.d.ts +8 -0
  16. package/build/src/backends/javascript.d.ts.map +1 -0
  17. package/build/src/backends/javascript.js +173 -0
  18. package/build/src/backends/php.d.ts +8 -0
  19. package/build/src/backends/php.d.ts.map +1 -0
  20. package/build/src/backends/php.js +175 -0
  21. package/build/src/backends/ruby.d.ts +8 -0
  22. package/build/src/backends/ruby.d.ts.map +1 -0
  23. package/build/src/backends/ruby.js +155 -0
  24. package/build/src/backends/scalars.d.ts +15 -0
  25. package/build/src/backends/scalars.d.ts.map +1 -0
  26. package/build/src/backends/scalars.js +138 -0
  27. package/build/src/backends/shared.d.ts +26 -0
  28. package/build/src/backends/shared.d.ts.map +1 -0
  29. package/build/src/backends/shared.js +424 -0
  30. package/build/src/backends/typescript.d.ts +8 -0
  31. package/build/src/backends/typescript.d.ts.map +1 -0
  32. package/build/src/backends/typescript.js +160 -0
  33. package/build/src/backends/writer.d.ts +87 -0
  34. package/build/src/backends/writer.d.ts.map +1 -0
  35. package/build/src/backends/writer.js +207 -0
  36. package/build/src/diagnostic.d.ts +67 -0
  37. package/build/src/diagnostic.d.ts.map +1 -0
  38. package/build/src/diagnostic.js +96 -0
  39. package/build/src/frontends/index.d.ts +14 -0
  40. package/build/src/frontends/index.d.ts.map +1 -0
  41. package/build/src/frontends/index.js +36 -0
  42. package/build/src/frontends/java.d.ts +12 -0
  43. package/build/src/frontends/java.d.ts.map +1 -0
  44. package/build/src/frontends/java.js +630 -0
  45. package/build/src/frontends/javascript-typescript.d.ts +19 -0
  46. package/build/src/frontends/javascript-typescript.d.ts.map +1 -0
  47. package/build/src/frontends/javascript-typescript.js +633 -0
  48. package/build/src/frontends/php.d.ts +12 -0
  49. package/build/src/frontends/php.d.ts.map +1 -0
  50. package/build/src/frontends/php.js +523 -0
  51. package/build/src/frontends/ruby.d.ts +12 -0
  52. package/build/src/frontends/ruby.d.ts.map +1 -0
  53. package/build/src/frontends/ruby.js +515 -0
  54. package/build/src/frontends/scalars.d.ts +19 -0
  55. package/build/src/frontends/scalars.d.ts.map +1 -0
  56. package/build/src/frontends/scalars.js +71 -0
  57. package/build/src/mapping.d.ts +160 -0
  58. package/build/src/mapping.d.ts.map +1 -0
  59. package/build/src/mapping.js +1120 -0
  60. package/build/src/semantic/location.d.ts +61 -0
  61. package/build/src/semantic/location.d.ts.map +1 -0
  62. package/build/src/semantic/location.js +142 -0
  63. package/build/src/semantic/operators.d.ts +16 -0
  64. package/build/src/semantic/operators.d.ts.map +1 -0
  65. package/build/src/semantic/operators.js +24 -0
  66. package/build/src/semantic/provenance.d.ts +74 -0
  67. package/build/src/semantic/provenance.d.ts.map +1 -0
  68. package/build/src/semantic/provenance.js +577 -0
  69. package/build/src/semantic/scalars.d.ts +19 -0
  70. package/build/src/semantic/scalars.d.ts.map +1 -0
  71. package/build/src/semantic/scalars.js +40 -0
  72. package/build/src/semantic/types.d.ts +1003 -0
  73. package/build/src/semantic/types.d.ts.map +1 -0
  74. package/build/src/semantic/types.js +279 -0
  75. package/build/src/semantic/validate.d.ts +60 -0
  76. package/build/src/semantic/validate.d.ts.map +1 -0
  77. package/build/src/semantic/validate.js +472 -0
  78. package/docs/architecture.md +39 -0
  79. package/docs/coding-standards.md +7 -0
  80. package/docs/goals.md +7 -0
  81. package/docs/language-support.md +69 -0
  82. package/docs/plans/2026-09-02-initial-toolchain.md +54 -0
  83. package/docs/source-maps.md +134 -0
  84. package/docs/testing.md +25 -0
  85. package/index.js +63 -0
  86. package/package.json +69 -0
  87. package/src/backends/identifiers.js +101 -0
  88. package/src/backends/index.js +159 -0
  89. package/src/backends/java.js +182 -0
  90. package/src/backends/javascript.js +184 -0
  91. package/src/backends/php.js +184 -0
  92. package/src/backends/ruby.js +163 -0
  93. package/src/backends/scalars.js +120 -0
  94. package/src/backends/shared.js +456 -0
  95. package/src/backends/typescript.js +168 -0
  96. package/src/backends/writer.js +224 -0
  97. package/src/diagnostic.js +103 -0
  98. package/src/frontends/index.js +36 -0
  99. package/src/frontends/java.js +735 -0
  100. package/src/frontends/javascript-typescript.js +718 -0
  101. package/src/frontends/php.js +593 -0
  102. package/src/frontends/ruby.js +622 -0
  103. package/src/frontends/scalars.js +77 -0
  104. package/src/mapping.js +1260 -0
  105. package/src/semantic/location.js +154 -0
  106. package/src/semantic/operators.js +28 -0
  107. package/src/semantic/provenance.js +629 -0
  108. package/src/semantic/scalars.js +44 -0
  109. package/src/semantic/types.js +319 -0
  110. package/src/semantic/validate.js +529 -0
  111. package/tsconfig.json +16 -0
@@ -0,0 +1,154 @@
1
+ // @ts-check
2
+
3
+ /**
4
+ * Converts a source offset to a one-based point.
5
+ * @param {string} source - Complete source.
6
+ * @param {number} offset - Zero-based UTF-16 offset.
7
+ * @returns {import("./types.js").SourcePoint} Source point.
8
+ */
9
+ export function pointAt(source, offset) {
10
+ if (!Number.isInteger(offset) || offset < 0 || offset > source.length) {
11
+ throw new RangeError(`Invalid source offset: ${offset}`)
12
+ }
13
+
14
+ let line = 1
15
+ let lineStart = 0
16
+
17
+ for (let index = 0; index < offset; index++) {
18
+ if (source[index] == "\r") {
19
+ if (source[index + 1] == "\n") {
20
+ if (index + 1 < offset) {
21
+ line++
22
+ index++
23
+ lineStart = index + 1
24
+ }
25
+ } else {
26
+ line++
27
+ lineStart = index + 1
28
+ }
29
+ } else if (source[index] == "\n") {
30
+ line++
31
+ lineStart = index + 1
32
+ }
33
+ }
34
+
35
+ return {column: offset - lineStart + 1, line, offset}
36
+ }
37
+
38
+ /**
39
+ * Builds a reusable UTF-16 line index in one pass.
40
+ * @param {string} source - Complete source.
41
+ * @returns {{source: string, lineStarts: number[]}} Coordinate index.
42
+ */
43
+ export function createCoordinateIndex(source) {
44
+ const lineStarts = [0]
45
+
46
+ for (let index = 0; index < source.length; index++) {
47
+ if (source[index] == "\r") {
48
+ if (source[index + 1] == "\n") index++
49
+ lineStarts.push(index + 1)
50
+ } else if (source[index] == "\n") lineStarts.push(index + 1)
51
+ }
52
+
53
+ return {lineStarts, source}
54
+ }
55
+
56
+ /**
57
+ * Converts an offset with a reusable coordinate index.
58
+ * @param {{source: string, lineStarts: number[]}} index - Coordinate index.
59
+ * @param {number} offset - Zero-based UTF-16 offset.
60
+ * @returns {import("./types.js").SourcePoint} Source point.
61
+ */
62
+ export function indexedPointAt(index, offset) {
63
+ const {lineStarts, source} = index
64
+
65
+ if (!Number.isInteger(offset) || offset < 0 || offset > source.length) {
66
+ throw new RangeError(`Invalid source offset: ${offset}`)
67
+ }
68
+
69
+ let low = 0
70
+ let high = lineStarts.length
71
+
72
+ while (low < high) {
73
+ const middle = Math.floor((low + high) / 2)
74
+
75
+ if (lineStarts[middle] <= offset) low = middle + 1
76
+ else high = middle
77
+ }
78
+ const lineIndex = low - 1
79
+
80
+ return {column: offset - lineStarts[lineIndex] + 1, line: lineIndex + 1, offset}
81
+ }
82
+
83
+ /**
84
+ * Converts a canonical one-based UTF-16 line/column pair to its unique offset.
85
+ * @param {{source: string, lineStarts: number[]}} index - Coordinate index.
86
+ * @param {number} line - One-based line.
87
+ * @param {number} column - One-based UTF-16 column.
88
+ * @returns {number} Source offset.
89
+ */
90
+ export function indexedOffsetAt(index, line, column) {
91
+ if (!Number.isInteger(line) || line < 1 || line > index.lineStarts.length || !Number.isInteger(column) || column < 1) {
92
+ throw new RangeError(`Invalid source position ${line}:${column}.`)
93
+ }
94
+ const offset = index.lineStarts[line - 1] + column - 1
95
+ const point = indexedPointAt(index, offset)
96
+
97
+ if (point.line != line || point.column != column) throw new RangeError(`Invalid source position ${line}:${column}.`)
98
+
99
+ return offset
100
+ }
101
+
102
+ /**
103
+ * Converts a parser UTF-8 byte offset to Semantifold's UTF-16 source offset.
104
+ * @param {string} source - Complete source.
105
+ * @param {number} byteOffset - Zero-based UTF-8 byte offset.
106
+ * @returns {number} Zero-based UTF-16 offset.
107
+ */
108
+ export function utf8ByteOffsetToUtf16Offset(source, byteOffset) {
109
+ if (!Number.isInteger(byteOffset) || byteOffset < 0) throw new RangeError(`Invalid UTF-8 source offset: ${byteOffset}`)
110
+
111
+ let bytes = 0
112
+
113
+ for (let index = 0; index < source.length;) {
114
+ if (bytes == byteOffset) return index
115
+
116
+ const codePoint = source.codePointAt(index)
117
+
118
+ if (codePoint === undefined) throw new RangeError(`Invalid UTF-8 source offset: ${byteOffset}`)
119
+
120
+ bytes += codePoint <= 0x7F ? 1 : codePoint <= 0x7FF ? 2 : codePoint <= 0xFFFF ? 3 : 4
121
+ if (bytes > byteOffset) throw new RangeError(`Invalid UTF-8 source offset: ${byteOffset}`)
122
+ index += codePoint > 0xFFFF ? 2 : 1
123
+ }
124
+
125
+ if (bytes == byteOffset) return source.length
126
+
127
+ throw new RangeError(`Invalid UTF-8 source offset: ${byteOffset}`)
128
+ }
129
+
130
+ /**
131
+ * Builds a normalized source location from offsets.
132
+ * @param {string} filename - Originating filename.
133
+ * @param {string} source - Complete source.
134
+ * @param {number} startOffset - Inclusive start offset.
135
+ * @param {number} endOffset - Exclusive end offset.
136
+ * @returns {import("./types.js").SourceLocation} Source location.
137
+ */
138
+ export function locationFromOffsets(filename, source, startOffset, endOffset) {
139
+ return {
140
+ filename,
141
+ start: pointAt(source, startOffset),
142
+ end: pointAt(source, endOffset)
143
+ }
144
+ }
145
+
146
+ /**
147
+ * Builds a location spanning a complete source file.
148
+ * @param {string} filename - Originating filename.
149
+ * @param {string} source - Complete source.
150
+ * @returns {import("./types.js").SourceLocation} Source location.
151
+ */
152
+ export function moduleLocation(filename, source) {
153
+ return locationFromOffsets(filename, source, 0, source.length)
154
+ }
@@ -0,0 +1,28 @@
1
+ // @ts-check
2
+
3
+ /** @typedef {"Add" | "PhpAdd" | "Subtract" | "Multiply" | "Negate" | "Not" | "And" | "Or" | "Equal" | "NotEqual" | "JavaEqual" | "JavaNotEqual" | "StringEqual" | "StringNotEqual" | "StringConcat" | "LessThan" | "LessThanOrEqual" | "GreaterThan" | "GreaterThanOrEqual"} AdaptedOperation */
4
+
5
+ /** @type {WeakMap<object, AdaptedOperation>} */
6
+ const adaptedOperations = new WeakMap()
7
+
8
+ /**
9
+ * Associates parser-normalized intent without adding it to a semantic value.
10
+ * @template {object} Expression
11
+ * @param {Expression} expression - Adapted expression awaiting type resolution.
12
+ * @param {AdaptedOperation} operation - Parser-normalized operation intent.
13
+ * @returns {Expression} The same expression.
14
+ */
15
+ export function withAdaptedOperation(expression, operation) {
16
+ adaptedOperations.set(expression, operation)
17
+
18
+ return expression
19
+ }
20
+
21
+ /**
22
+ * Reads private frontend intent during parsed-module validation.
23
+ * @param {object} expression - Adapted expression.
24
+ * @returns {AdaptedOperation | undefined} Associated operation.
25
+ */
26
+ export function adaptedOperationFor(expression) {
27
+ return adaptedOperations.get(expression)
28
+ }