gofront 0.0.8 → 1.0.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 (51) hide show
  1. package/README.md +88 -12
  2. package/package.json +8 -4
  3. package/src/codegen/expressions.js +520 -1717
  4. package/src/{codegen.js → codegen/index.js} +155 -184
  5. package/src/codegen/runtime.js +151 -0
  6. package/src/codegen/statements.js +305 -296
  7. package/src/codegen/stdlib/builder.js +36 -0
  8. package/src/codegen/stdlib/bytes.js +62 -0
  9. package/src/codegen/stdlib/errors.js +17 -0
  10. package/src/codegen/stdlib/fmt.js +101 -0
  11. package/src/codegen/stdlib/gom.js +152 -0
  12. package/src/codegen/stdlib/html.js +17 -0
  13. package/src/codegen/stdlib/index.js +95 -0
  14. package/src/codegen/stdlib/io.js +33 -0
  15. package/src/codegen/stdlib/maps.js +42 -0
  16. package/src/codegen/stdlib/math.js +53 -0
  17. package/src/codegen/stdlib/os.js +10 -0
  18. package/src/codegen/stdlib/path.js +31 -0
  19. package/src/codegen/stdlib/rand.js +24 -0
  20. package/src/codegen/stdlib/regexp.js +51 -0
  21. package/src/codegen/stdlib/slices.js +48 -0
  22. package/src/codegen/stdlib/sort.js +28 -0
  23. package/src/codegen/stdlib/strconv.js +30 -0
  24. package/src/codegen/stdlib/strings.js +83 -0
  25. package/src/codegen/stdlib/time.js +54 -0
  26. package/src/codegen/stdlib/unicode.js +22 -0
  27. package/src/codegen/stdlib/utf8.js +23 -0
  28. package/src/codegen/templ.js +281 -0
  29. package/src/compiler.js +102 -62
  30. package/src/dts-parser.js +355 -371
  31. package/src/index.js +22 -54
  32. package/src/lexer.js +200 -286
  33. package/src/minifier.js +305 -318
  34. package/src/parser/expressions.js +54 -36
  35. package/src/{parser.js → parser/index.js} +12 -5
  36. package/src/parser/statements.js +29 -35
  37. package/src/parser/types.js +31 -29
  38. package/src/templ-lexer.js +737 -0
  39. package/src/templ-parser.js +235 -0
  40. package/src/tokens.js +109 -0
  41. package/src/typechecker/assignability.js +258 -0
  42. package/src/typechecker/expressions.js +559 -549
  43. package/src/typechecker/index.js +555 -0
  44. package/src/typechecker/resolve.js +421 -0
  45. package/src/typechecker/statements.js +267 -280
  46. package/src/typechecker/stdlib/core.js +592 -0
  47. package/src/typechecker/stdlib/extended.js +332 -0
  48. package/src/typechecker/stdlib.js +9 -1060
  49. package/src/typechecker/termination.js +83 -0
  50. package/src/typechecker/types.js +6 -3
  51. package/src/typechecker.js +0 -1271
@@ -0,0 +1,83 @@
1
+ // Termination analysis — determines whether a statement/block always returns.
2
+ // Installed as a mixin on TypeChecker.prototype.
3
+
4
+ export const terminationMethods = {
5
+ _isPanicCall(expr) {
6
+ return (
7
+ expr?.kind === "CallExpr" &&
8
+ expr?.func?.kind === "Ident" &&
9
+ expr?.func?.name === "panic"
10
+ );
11
+ },
12
+
13
+ _isTerminating(stmt) {
14
+ if (!stmt) return false;
15
+ switch (stmt.kind) {
16
+ case "ReturnStmt":
17
+ return true;
18
+ case "BranchStmt":
19
+ return false;
20
+ case "ExprStmt":
21
+ return this._isPanicCall(stmt.expr);
22
+ case "LabeledStmt":
23
+ return this._isTerminating(stmt.body);
24
+ case "Block":
25
+ return this._isTerminatingBlock(stmt);
26
+ case "SwitchStmt":
27
+ return this._isTerminatingSwitch(stmt);
28
+ case "TypeSwitchStmt":
29
+ return this._isTerminatingTypeSwitch(stmt);
30
+ case "ForStmt":
31
+ return !stmt.cond && !this._blockHasBreak(stmt.body);
32
+ case "IfStmt":
33
+ return this._isTerminatingIfStmt(stmt);
34
+ default:
35
+ return false;
36
+ }
37
+ },
38
+
39
+ _isTerminatingIfStmt(stmt) {
40
+ if (!stmt.elseBody) return false;
41
+ return (
42
+ this._isTerminatingBlock(stmt.body) &&
43
+ (stmt.elseBody.kind === "Block"
44
+ ? this._isTerminatingBlock(stmt.elseBody)
45
+ : this._isTerminating(stmt.elseBody))
46
+ );
47
+ },
48
+
49
+ _isTerminatingBlock(block) {
50
+ if (!block?.stmts?.length) return false;
51
+ return this._isTerminating(block.stmts[block.stmts.length - 1]);
52
+ },
53
+
54
+ _blockHasBreak(block) {
55
+ if (!block?.stmts) return false;
56
+ for (const s of block.stmts) {
57
+ if (s.kind === "BranchStmt" && s.keyword === "break") return true;
58
+ }
59
+ return false;
60
+ },
61
+
62
+ _isTerminatingSwitch(stmt) {
63
+ let hasDefault = false;
64
+ for (const c of stmt.cases ?? []) {
65
+ if (!c.list) hasDefault = true;
66
+ if (!c.stmts?.length) return false;
67
+ const last = c.stmts[c.stmts.length - 1];
68
+ if (!this._isTerminating(last)) return false;
69
+ }
70
+ return hasDefault;
71
+ },
72
+
73
+ _isTerminatingTypeSwitch(stmt) {
74
+ let hasDefault = false;
75
+ for (const c of stmt.cases ?? []) {
76
+ if (!c.types) hasDefault = true;
77
+ if (!c.stmts?.length) return false;
78
+ const last = c.stmts[c.stmts.length - 1];
79
+ if (!this._isTerminating(last)) return false;
80
+ }
81
+ return hasDefault;
82
+ },
83
+ };
@@ -15,19 +15,22 @@
15
15
  export class TypeCheckError extends Error {
16
16
  constructor(msg, node, filename, sourceCode) {
17
17
  const lineNum = node?.line || node?._line;
18
+ const colNum = node?.col || node?._col;
18
19
  const loc = filename
19
20
  ? lineNum
20
- ? ` in ${filename} at line ${lineNum}`
21
+ ? ` in ${filename} at line ${lineNum}:${colNum ?? 1}`
21
22
  : ` in ${filename}`
22
23
  : lineNum
23
- ? ` at line ${lineNum}`
24
+ ? ` at line ${lineNum}:${colNum ?? 1}`
24
25
  : "";
25
26
  let lineContext = "";
26
27
  if (lineNum && sourceCode) {
27
28
  const lines = sourceCode.split("\n");
28
29
  const lineStr = lines[lineNum - 1];
29
30
  if (lineStr !== undefined) {
30
- lineContext = `\n ${lineNum} | ${lineStr}`;
31
+ const prefix = ` ${lineNum} | `;
32
+ const caretPad = " ".repeat((colNum ?? 1) - 1);
33
+ lineContext = `\n${prefix}${lineStr}\n${" ".repeat(prefix.length)}${caretPad}^`;
31
34
  }
32
35
  }
33
36
  super(`Type error${loc}: ${msg}${lineContext}`);