english-lang 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.
package/README.md ADDED
@@ -0,0 +1,119 @@
1
+ # English (.eng)
2
+
3
+ > **Write what you mean. Build what you know.**
4
+
5
+ A programming language where you write plain English that compiles directly to React Native — shipping real iOS and Android apps with zero JSX, zero hooks, and zero accidental complexity.
6
+
7
+ ---
8
+
9
+ ## Install
10
+
11
+ ```bash
12
+ npm install -g english-lang
13
+ ```
14
+
15
+ ---
16
+
17
+ ## Usage
18
+
19
+ ```bash
20
+ # Compile a single file
21
+ engc screens/HomeScreen.eng
22
+
23
+ # Compile a single file to a specific output directory
24
+ engc screens/HomeScreen.eng --out rn/src/
25
+
26
+ # Compile all .eng files in a directory
27
+ engc compile screens/ --out rn/src/
28
+
29
+ # Watch a directory and recompile on every save
30
+ engc watch screens/ --out rn/src/
31
+ ```
32
+
33
+ ---
34
+
35
+ ## Example
36
+
37
+ Write this in `screens/HomeScreen.eng`:
38
+
39
+ ```
40
+ screen HomeScreen:
41
+ title is "Hello World"
42
+
43
+ state:
44
+ message is "Hello!"
45
+ count is 0
46
+
47
+ when screen opens:
48
+ set count to 1
49
+
50
+ when "Say Hello" is pressed:
51
+ set message to "Hello from English!"
52
+
53
+ layout:
54
+ vertical stack spacing 16 padding 16:
55
+ show message as heading
56
+ show count
57
+ button "Say Hello"
58
+ ```
59
+
60
+ Run `engc screens/HomeScreen.eng --out rn/src/` and get this:
61
+
62
+ ```tsx
63
+ export function HomeScreen({ navigation }: any) {
64
+ const [message, setMessage] = useState<string>("Hello!");
65
+ const [count, setCount] = useState<number>(0);
66
+
67
+ useEffect(() => {
68
+ setCount(1);
69
+ }, []);
70
+
71
+ const handleSayHello = () => {
72
+ setMessage("Hello from English!");
73
+ };
74
+
75
+ return (
76
+ <View style={styles.container}>
77
+ <View style={{ flexDirection: 'column', gap: 16, padding: 16 }}>
78
+ <Text style={styles.heading}>{message}</Text>
79
+ <Text style={styles.body}>{count}</Text>
80
+ <TouchableOpacity style={styles.button} onPress={handleSayHello}>
81
+ <Text style={styles.buttonText}>Say Hello</Text>
82
+ </TouchableOpacity>
83
+ </View>
84
+ </View>
85
+ );
86
+ }
87
+ ```
88
+
89
+ ---
90
+
91
+ ## Project structure
92
+
93
+ ```
94
+ my-app/
95
+ ├── package.json ← devDependency: english-lang
96
+ ├── screens/ ← write your .eng files here
97
+ │ ├── HomeScreen.eng
98
+ │ └── ProductScreen.eng
99
+ └── rn/ ← react native project
100
+ ├── src/ ← compiled .tsx files go here
101
+ ├── ios/
102
+ └── android/
103
+ ```
104
+
105
+ ---
106
+
107
+ ## Programmatic use
108
+
109
+ ```ts
110
+ import { compile } from 'english-lang';
111
+
112
+ const tsx = compile(engSource, 'HomeScreen.eng');
113
+ ```
114
+
115
+ ---
116
+
117
+ ## License
118
+
119
+ MIT
@@ -0,0 +1,198 @@
1
+ #!/usr/bin/env node
2
+ "use strict";
3
+ // ============================================================
4
+ // engc — English (.eng) compiler CLI
5
+ //
6
+ // Usage:
7
+ // engc <file.eng> compile → .tsx alongside source
8
+ // engc <file.eng> --out <dir> compile → specific output dir
9
+ // engc <file.eng> -o <output.tsx> compile → specific output file
10
+ // engc <file.eng> --print print generated code to stdout
11
+ // engc compile <dir> --out <dir> compile all .eng files in a dir
12
+ // engc watch <dir> --out <dir> watch dir, recompile on save
13
+ // ============================================================
14
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
15
+ if (k2 === undefined) k2 = k;
16
+ var desc = Object.getOwnPropertyDescriptor(m, k);
17
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
18
+ desc = { enumerable: true, get: function() { return m[k]; } };
19
+ }
20
+ Object.defineProperty(o, k2, desc);
21
+ }) : (function(o, m, k, k2) {
22
+ if (k2 === undefined) k2 = k;
23
+ o[k2] = m[k];
24
+ }));
25
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
26
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
27
+ }) : function(o, v) {
28
+ o["default"] = v;
29
+ });
30
+ var __importStar = (this && this.__importStar) || (function () {
31
+ var ownKeys = function(o) {
32
+ ownKeys = Object.getOwnPropertyNames || function (o) {
33
+ var ar = [];
34
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
35
+ return ar;
36
+ };
37
+ return ownKeys(o);
38
+ };
39
+ return function (mod) {
40
+ if (mod && mod.__esModule) return mod;
41
+ var result = {};
42
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
43
+ __setModuleDefault(result, mod);
44
+ return result;
45
+ };
46
+ })();
47
+ Object.defineProperty(exports, "__esModule", { value: true });
48
+ const fs = __importStar(require("fs"));
49
+ const path = __importStar(require("path"));
50
+ const index_1 = require("../index");
51
+ // ── Helpers ───────────────────────────────────────────────────
52
+ function compileFile(inputPath, outDir) {
53
+ const source = fs.readFileSync(inputPath, 'utf8');
54
+ const sourceFile = path.basename(inputPath);
55
+ let tsx;
56
+ try {
57
+ tsx = (0, index_1.compile)(source, sourceFile);
58
+ }
59
+ catch (err) {
60
+ console.error(`[engc] Parse error in ${sourceFile}:\n ${err.message}\n`);
61
+ return;
62
+ }
63
+ const outputPath = outDir
64
+ ? path.join(outDir, sourceFile.replace(/\.eng$/, '.tsx'))
65
+ : inputPath.replace(/\.eng$/, '.tsx');
66
+ fs.mkdirSync(path.dirname(outputPath), { recursive: true });
67
+ fs.writeFileSync(outputPath, tsx, 'utf8');
68
+ const relIn = path.relative(process.cwd(), inputPath);
69
+ const relOut = path.relative(process.cwd(), outputPath);
70
+ console.log(`[engc] ${relIn} → ${relOut}`);
71
+ }
72
+ function compileDir(srcDir, outDir) {
73
+ const engFiles = fs.readdirSync(srcDir).filter(f => f.endsWith('.eng'));
74
+ if (engFiles.length === 0) {
75
+ console.log(`[engc] No .eng files found in ${srcDir}`);
76
+ return;
77
+ }
78
+ for (const file of engFiles) {
79
+ compileFile(path.join(srcDir, file), outDir);
80
+ }
81
+ }
82
+ function watchDir(srcDir, outDir) {
83
+ // Run once on start
84
+ compileDir(srcDir, outDir);
85
+ console.log(`[engc] Watching ${srcDir} ...`);
86
+ fs.watch(srcDir, { recursive: false }, (event, filename) => {
87
+ if (!filename || !filename.endsWith('.eng'))
88
+ return;
89
+ const filePath = path.join(srcDir, filename);
90
+ if (!fs.existsSync(filePath))
91
+ return;
92
+ compileFile(filePath, outDir);
93
+ });
94
+ }
95
+ // ── CLI entry point ───────────────────────────────────────────
96
+ function main() {
97
+ const args = process.argv.slice(2);
98
+ if (args.length === 0 || args[0] === '--help' || args[0] === '-h') {
99
+ console.log(`
100
+ English Compiler (engc)
101
+
102
+ Usage:
103
+ engc <file.eng> compile → .tsx alongside source
104
+ engc <file.eng> --out <dir> compile → specific output directory
105
+ engc <file.eng> -o <output.tsx> compile → specific output file
106
+ engc <file.eng> --print print generated code, no file written
107
+ engc <file.eng> --tokens dump token stream (debug)
108
+ engc <file.eng> --ast dump parsed AST (debug)
109
+ engc compile <dir> [--out <dir>] compile all .eng files in a directory
110
+ engc watch <dir> [--out <dir>] watch directory, recompile on save
111
+
112
+ Examples:
113
+ engc screens/HomeScreen.eng
114
+ engc screens/HomeScreen.eng --out rn/src/
115
+ engc compile screens/ --out rn/src/
116
+ engc watch screens/ --out rn/src/
117
+ `.trim());
118
+ process.exit(0);
119
+ }
120
+ // Sub-commands: compile <dir> | watch <dir>
121
+ if (args[0] === 'compile' || args[0] === 'watch') {
122
+ const cmd = args[0];
123
+ const srcDir = args[1] ? path.resolve(args[1]) : process.cwd();
124
+ const outIdx = args.indexOf('--out');
125
+ const outDir = outIdx !== -1 ? path.resolve(args[outIdx + 1]) : undefined;
126
+ if (!fs.existsSync(srcDir)) {
127
+ console.error(`[engc] Directory not found: ${srcDir}`);
128
+ process.exit(1);
129
+ }
130
+ if (cmd === 'compile') {
131
+ compileDir(srcDir, outDir);
132
+ }
133
+ else {
134
+ watchDir(srcDir, outDir);
135
+ }
136
+ return;
137
+ }
138
+ // Single file mode
139
+ const inputArg = args[0];
140
+ const printOnly = args.includes('--print');
141
+ const dumpTokens = args.includes('--tokens');
142
+ const dumpAST = args.includes('--ast');
143
+ const outDirIdx = args.indexOf('--out');
144
+ const outDir = outDirIdx !== -1 ? args[outDirIdx + 1] : undefined;
145
+ const outputIdx = args.indexOf('-o');
146
+ const explicitOutput = outputIdx !== -1 ? args[outputIdx + 1] : null;
147
+ const inputPath = path.resolve(inputArg);
148
+ if (!fs.existsSync(inputPath)) {
149
+ console.error(`[engc] File not found: ${inputPath}`);
150
+ process.exit(1);
151
+ }
152
+ const source = fs.readFileSync(inputPath, 'utf8');
153
+ const sourceFile = path.basename(inputPath);
154
+ // Debug modes — need raw Lexer/Parser
155
+ if (dumpTokens || dumpAST) {
156
+ const { Lexer } = require('../src/lexer/Lexer');
157
+ const { Parser } = require('../src/parser/Parser');
158
+ const tokens = new Lexer(source).tokenize();
159
+ if (dumpTokens) {
160
+ console.log('── Token stream ──────────────────────────────────────');
161
+ for (const tok of tokens) {
162
+ const val = tok.value ? ` "${tok.value}"` : '';
163
+ console.log(` ${String(tok.line).padStart(3)}:${String(tok.col).padStart(3)} ${tok.type.padEnd(14)}${val}`);
164
+ }
165
+ console.log('');
166
+ }
167
+ if (dumpAST) {
168
+ const program = new Parser(tokens).parse();
169
+ console.log('── AST ───────────────────────────────────────────────');
170
+ console.log(JSON.stringify(program, null, 2));
171
+ console.log('');
172
+ }
173
+ return;
174
+ }
175
+ let tsx;
176
+ try {
177
+ tsx = (0, index_1.compile)(source, sourceFile);
178
+ }
179
+ catch (err) {
180
+ console.error(`\n[engc] Parse error:\n ${err.message}\n`);
181
+ process.exit(1);
182
+ }
183
+ if (printOnly) {
184
+ console.log(tsx);
185
+ return;
186
+ }
187
+ const outputPath = explicitOutput
188
+ ? path.resolve(explicitOutput)
189
+ : outDir
190
+ ? path.join(path.resolve(outDir), sourceFile.replace(/\.eng$/, '.tsx'))
191
+ : inputPath.replace(/\.eng$/, '.tsx');
192
+ fs.mkdirSync(path.dirname(outputPath), { recursive: true });
193
+ fs.writeFileSync(outputPath, tsx, 'utf8');
194
+ const relIn = path.relative(process.cwd(), inputPath);
195
+ const relOut = path.relative(process.cwd(), outputPath);
196
+ console.log(`[engc] ${relIn} → ${relOut}`);
197
+ }
198
+ main();
package/dist/index.js ADDED
@@ -0,0 +1,20 @@
1
+ "use strict";
2
+ // english-lang — public API
3
+ // Import this if you want to use the compiler programmatically.
4
+ Object.defineProperty(exports, "__esModule", { value: true });
5
+ exports.ReactNativeBackend = exports.Parser = exports.Lexer = void 0;
6
+ exports.compile = compile;
7
+ var Lexer_1 = require("./src/lexer/Lexer");
8
+ Object.defineProperty(exports, "Lexer", { enumerable: true, get: function () { return Lexer_1.Lexer; } });
9
+ var Parser_1 = require("./src/parser/Parser");
10
+ Object.defineProperty(exports, "Parser", { enumerable: true, get: function () { return Parser_1.Parser; } });
11
+ var ReactNativeBackend_1 = require("./src/codegen/ReactNativeBackend");
12
+ Object.defineProperty(exports, "ReactNativeBackend", { enumerable: true, get: function () { return ReactNativeBackend_1.ReactNativeBackend; } });
13
+ const Lexer_2 = require("./src/lexer/Lexer");
14
+ const Parser_2 = require("./src/parser/Parser");
15
+ const ReactNativeBackend_2 = require("./src/codegen/ReactNativeBackend");
16
+ function compile(source, sourceFile) {
17
+ const tokens = new Lexer_2.Lexer(source).tokenize();
18
+ const program = new Parser_2.Parser(tokens).parse();
19
+ return new ReactNativeBackend_2.ReactNativeBackend().emit(program, sourceFile);
20
+ }
@@ -0,0 +1,6 @@
1
+ "use strict";
2
+ // ============================================================
3
+ // ASTNodes.ts — All node type definitions for the English compiler
4
+ // Every node carries a `kind` discriminant for exhaustive switch.
5
+ // ============================================================
6
+ Object.defineProperty(exports, "__esModule", { value: true });