@algosail/lang 0.2.9 → 0.2.10

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 CHANGED
@@ -2,6 +2,15 @@
2
2
 
3
3
  Sail language tooling. Re-exports parser and typecheck.
4
4
 
5
+ ## CLI
6
+
7
+ ```bash
8
+ sail check <file.sail> # Typecheck
9
+ sail compile <file.sail> [options] # Compile to JS
10
+ ```
11
+
12
+ Options for `compile`: `--out <file.js>`, `--no-source-map`, `-` (stdout).
13
+
5
14
  ## Exports
6
15
 
7
16
  ```javascript
package/cli/sail.js ADDED
@@ -0,0 +1,151 @@
1
+ #!/usr/bin/env node
2
+
3
+ /**
4
+ * Sail CLI — sail check | sail compile
5
+ */
6
+
7
+ const args = process.argv.slice(2)
8
+ const cmd = args[0]
9
+
10
+ if (!cmd || cmd === '-h' || cmd === '--help') {
11
+ console.log(`sail - Sail language tooling
12
+
13
+ Usage:
14
+ sail check <file.sail> Typecheck a Sail file
15
+ sail compile <file.sail> Compile Sail to JavaScript
16
+
17
+ Options for compile:
18
+ --out <file.js> Output path (default: input.js)
19
+ --no-source-map Disable source map generation
20
+ - Write to stdout
21
+
22
+ Examples:
23
+ sail check main.sail
24
+ sail compile main.sail --out dist/main.js
25
+ sail compile main.sail -
26
+ `)
27
+ process.exit(cmd === '-h' || cmd === '--help' ? 0 : 1)
28
+ }
29
+
30
+ const rest = args.slice(1)
31
+
32
+ if (cmd === 'check') {
33
+ await runCheck(rest)
34
+ } else if (cmd === 'compile') {
35
+ await runCompile(rest)
36
+ } else {
37
+ console.error(`sail: unknown command '${cmd}'. Use 'sail check' or 'sail compile'.`)
38
+ process.exit(1)
39
+ }
40
+
41
+ async function runCheck(args) {
42
+ const filePath = args.find((a) => !a.startsWith('-'))
43
+ if (!filePath) {
44
+ console.error('Usage: sail check <path-to-file.sail>')
45
+ process.exit(1)
46
+ }
47
+
48
+ const { createParser } = await import('@algosail/parser')
49
+ const { typecheck } = await import('@algosail/typecheck')
50
+ const { readFile } = await import('node:fs/promises')
51
+ const { pathToFileURL } = await import('node:url')
52
+ const { resolve } = await import('node:path')
53
+ const { formatError } = await import('@algosail/compiler/lib/formatError.js')
54
+ const { addErrorHints } = await import('@algosail/compiler/lib/errorHints.js')
55
+
56
+ const absPath = resolve(process.cwd(), filePath)
57
+ const uri = pathToFileURL(absPath).href
58
+
59
+ let text
60
+ try {
61
+ text = await readFile(absPath, 'utf8')
62
+ } catch (err) {
63
+ console.error(`sail check: cannot read ${filePath}: ${err.message}`)
64
+ process.exit(1)
65
+ }
66
+
67
+ const parser = await createParser()
68
+ const result = await parser.parseSail(uri, text)
69
+ const parseErrors = (result.errors ?? []).map((e) => ({
70
+ message: e.type === 'error' ? `Parse error: ${e.text}` : `Parse error: missing ${e.text}`,
71
+ startPosition: e.startPosition,
72
+ uri,
73
+ }))
74
+ const typeErrors = typecheck(result).map((e) => {
75
+ const hint = addErrorHints(e)
76
+ return { ...e, uri, ...(hint && { hint }) }
77
+ })
78
+ const errors = [...parseErrors, ...typeErrors]
79
+
80
+ if (errors.length > 0) {
81
+ for (const err of errors) {
82
+ console.error(formatError({ ...err, uri }, uri))
83
+ }
84
+ process.exit(1)
85
+ }
86
+ }
87
+
88
+ async function runCompile(args) {
89
+ let inputPath = null
90
+ let outPath = null
91
+
92
+ for (let i = 0; i < args.length; i++) {
93
+ if (args[i] === '--out' && args[i + 1]) {
94
+ outPath = args[i + 1]
95
+ i++
96
+ } else if (!args[i].startsWith('-')) {
97
+ inputPath = args[i]
98
+ }
99
+ }
100
+
101
+ if (!inputPath) {
102
+ console.error('Usage: sail compile <input.sail> [--out <output.js>] [--no-source-map]')
103
+ process.exit(1)
104
+ }
105
+
106
+ const { compile } = await import('@algosail/compiler')
107
+ const { formatError } = await import('@algosail/compiler/lib/formatError.js')
108
+ const { readFile, writeFile } = await import('node:fs/promises')
109
+ const { dirname, resolve, basename } = await import('node:path')
110
+ const { pathToFileURL } = await import('node:url')
111
+
112
+ const absPath = resolve(process.cwd(), inputPath)
113
+ const uri = pathToFileURL(absPath).href
114
+
115
+ let source
116
+ try {
117
+ source = await readFile(absPath, 'utf8')
118
+ } catch (err) {
119
+ console.error(`sail compile: cannot read ${inputPath}: ${err.message}`)
120
+ process.exit(1)
121
+ }
122
+
123
+ const outputPath = outPath ?? inputPath.replace(/\.sail$/, '.js')
124
+ const compileOpts = {
125
+ outPath: outputPath !== '-' ? dirname(resolve(process.cwd(), outputPath)) : dirname(absPath),
126
+ sourceMap: outputPath !== '-' && !args.includes('--no-source-map'),
127
+ outFile: outputPath !== '-' ? resolve(process.cwd(), outputPath) : null,
128
+ }
129
+
130
+ const result = await compile(uri, source, compileOpts)
131
+
132
+ if (result.errors.length > 0) {
133
+ for (const err of result.errors) {
134
+ console.error(formatError({ ...err, uri }, uri))
135
+ }
136
+ process.exit(1)
137
+ }
138
+
139
+ if (outputPath === '-') {
140
+ process.stdout.write(result.js)
141
+ } else {
142
+ let js = result.js
143
+ if (result.sourceMap) {
144
+ const mapPath = outputPath + '.map'
145
+ await writeFile(mapPath, result.sourceMap, 'utf8')
146
+ js += `\n//# sourceMappingURL=${basename(mapPath)}`
147
+ }
148
+ await writeFile(outputPath, js, 'utf8')
149
+ console.log(`Compiled to ${outputPath}`)
150
+ }
151
+ }
package/cli/typecheck.js CHANGED
File without changes
package/package.json CHANGED
@@ -1,10 +1,10 @@
1
1
  {
2
2
  "name": "@algosail/lang",
3
- "version": "0.2.9",
3
+ "version": "0.2.10",
4
4
  "type": "module",
5
5
  "main": "index.js",
6
6
  "bin": {
7
- "sail-typecheck": "cli/typecheck.js"
7
+ "sail": "cli/sail.js"
8
8
  },
9
9
  "scripts": {
10
10
  "test": "brittle \"test/**/*.test.js\""
@@ -16,6 +16,6 @@
16
16
  "@algosail/builtins": "^0.0.6",
17
17
  "@algosail/compiler": "^0.0.2",
18
18
  "@algosail/parser": "^0.1.1",
19
- "@algosail/typecheck": "^0.1.1"
19
+ "@algosail/typecheck": "^0.1.2"
20
20
  }
21
21
  }
File without changes