steel-lang-2 1.0.0 β 2.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.
- package/README.md +79 -89
- package/package.json +1 -1
- package/src/environment.js +174 -17
- package/src/index.js +23 -29
- package/src/interpreter.js +220 -44
- package/src/lexer.js +167 -74
- package/src/parser.js +298 -126
package/README.md
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
|
|
1
|
+
# Steel Language v2.0
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
[](https://www.npmjs.com/package/steel-lang-2)
|
|
4
4
|
|
|
5
|
-
It focuses on clean syntax, minimal complexity, and fast execution through a custom JavaScript interpreter.
|
|
5
|
+
Steel is a simple, readable programming language designed to be easy to learn and intuitive to use. It focuses on clean syntax, minimal complexity, and fast execution through a custom JavaScript interpreter.
|
|
6
6
|
|
|
7
7
|
## Install
|
|
8
8
|
|
|
@@ -10,110 +10,100 @@ It focuses on clean syntax, minimal complexity, and fast execution through a cus
|
|
|
10
10
|
npm install steel-lang-2
|
|
11
11
|
```
|
|
12
12
|
|
|
13
|
+
## Features
|
|
13
14
|
|
|
15
|
+
- **Variables**: `set x to 10`
|
|
16
|
+
- **Output**: `say "Hello!"`
|
|
17
|
+
- **Template Strings**: `` `Hello ${name}!` ``
|
|
18
|
+
- **Conditionals**: `if / elseif / else / end`
|
|
19
|
+
- **Loops**: `while / for / for each / repeat`
|
|
20
|
+
- **Functions**: `define name as (params) ... return value end` with closures and recursion
|
|
21
|
+
- **Arrays**: `[1, 2, 3]` with index access, `set arr[0] to val`
|
|
22
|
+
- **Full Operators**: `+ - * / % > < >= <= == != and or not`
|
|
23
|
+
- **Comments**: `// line comments`
|
|
24
|
+
- **Booleans**: `true`, `false`, `null`
|
|
25
|
+
- **Operator Precedence**: Proper precedence climbing (multiplication before addition, etc.)
|
|
14
26
|
|
|
27
|
+
## Built-in Functions
|
|
15
28
|
|
|
29
|
+
### Math
|
|
30
|
+
`abs`, `round`, `floor`, `ceil`, `sqrt`, `pow`, `min`, `max`, `random`, `pi`, `e`
|
|
16
31
|
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
β’ β‘ Lightweight interpreter (Node.js)
|
|
20
|
-
β’ π§± Simple variable system
|
|
21
|
-
β’ π Control flow (if statements, loops)
|
|
22
|
-
β’ π¬ Built-in output (say)
|
|
23
|
-
β’ π¨ VS Code syntax highlighting support
|
|
24
|
-
β’ π§ Easy to extend and modify
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
Project Structure:
|
|
30
|
-
|
|
31
|
-
steel-lang/
|
|
32
|
-
βββ src/ # Language engine
|
|
33
|
-
β βββ lexer.js
|
|
34
|
-
β βββ parser.js
|
|
35
|
-
β βββ interpreter.js
|
|
36
|
-
β βββ environment.js
|
|
37
|
-
β βββ index.js
|
|
38
|
-
βββ examples/ # Example programs
|
|
39
|
-
β βββ hello.steel
|
|
40
|
-
β βββ logic.steel
|
|
41
|
-
β βββ variables.steel
|
|
42
|
-
βββ stl/ # VS Code extension
|
|
43
|
-
β βββ syntaxes/
|
|
44
|
-
β βββ icons/
|
|
45
|
-
β βββ package.json
|
|
46
|
-
βββ README.md
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
π Getting Started
|
|
53
|
-
|
|
54
|
-
Clone the repository
|
|
55
|
-
|
|
56
|
-
1. git clone https://github.com/theworker02/steel-lang.git
|
|
32
|
+
### String
|
|
33
|
+
`len`, `upper`, `lower`, `trim`, `substring`, `replace`, `split`, `join`, `contains`, `charAt`, `indexOf`, `startsWith`, `endsWith`, `repeat`, `padStart`, `padEnd`
|
|
57
34
|
|
|
58
|
-
|
|
35
|
+
### Array
|
|
36
|
+
`push`, `pop`, `shift`, `unshift`, `reverse`, `sort`, `slice`, `includes`, `flat`, `range`
|
|
59
37
|
|
|
38
|
+
### Type
|
|
39
|
+
`type`, `isNumber`, `isString`, `isArray`, `toString`, `toNumber`
|
|
60
40
|
|
|
41
|
+
### Misc
|
|
42
|
+
`clock`, `sleep`, `input`
|
|
61
43
|
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
3. "node src/index.js examples/hello.steel"
|
|
44
|
+
## Quick Start
|
|
65
45
|
|
|
46
|
+
```bash
|
|
47
|
+
git clone https://github.com/magnexis/Steel-lang.git
|
|
48
|
+
cd Steel-lang
|
|
49
|
+
node src/index.js examples/hello.steel
|
|
50
|
+
```
|
|
66
51
|
|
|
67
|
-
|
|
52
|
+
## Example
|
|
68
53
|
|
|
69
|
-
|
|
54
|
+
```steel
|
|
55
|
+
// Variables and types
|
|
56
|
+
set name to "Steel"
|
|
57
|
+
set version to 2
|
|
70
58
|
|
|
71
|
-
|
|
72
|
-
|
|
59
|
+
// Functions with recursion
|
|
60
|
+
define factorial as (n)
|
|
61
|
+
if n <= 1 then
|
|
62
|
+
return 1
|
|
63
|
+
end
|
|
64
|
+
return n * factorial(n - 1)
|
|
73
65
|
end
|
|
74
66
|
|
|
67
|
+
say factorial(10) // 3628800
|
|
75
68
|
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
Steel includes a custom VS Code extension for syntax highlighting.
|
|
82
|
-
|
|
83
|
-
Run locally: βcd stlβ
|
|
84
|
-
|
|
85
|
-
Then open the folder in VS code and press: F5
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
π― Goals:
|
|
89
|
-
|
|
90
|
-
β’ Keep syntax simple and readable
|
|
91
|
-
β’ Build a fully custom language ecosystem
|
|
92
|
-
β’ Add functions, modules, and advanced features
|
|
93
|
-
β’ Expand tooling (CLI, debugger, autocomplete)
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
https://steel-lang.base44.app
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
π οΈ Future Plans:
|
|
100
|
-
|
|
101
|
-
β’ CLI command (steel run file.steel)
|
|
102
|
-
β’ Error handling improvements
|
|
103
|
-
β’ Function system
|
|
104
|
-
β’ Package manager (maybe π)
|
|
105
|
-
β’ Full VS Code integration (IntelliSense)
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
π€ Contributing:
|
|
69
|
+
// Arrays and loops
|
|
70
|
+
set nums to [1, 2, 3, 4, 5]
|
|
71
|
+
for each n in nums
|
|
72
|
+
say n * n
|
|
73
|
+
end
|
|
109
74
|
|
|
110
|
-
|
|
75
|
+
// Higher-order patterns
|
|
76
|
+
define sum as (arr)
|
|
77
|
+
set total to 0
|
|
78
|
+
for each val in arr
|
|
79
|
+
set total to total + val
|
|
80
|
+
end
|
|
81
|
+
return total
|
|
82
|
+
end
|
|
111
83
|
|
|
112
|
-
|
|
84
|
+
say sum(range(1, 101)) // 5050
|
|
85
|
+
```
|
|
113
86
|
|
|
114
|
-
|
|
87
|
+
## Project Structure
|
|
115
88
|
|
|
116
|
-
|
|
89
|
+
```
|
|
90
|
+
steel-lang/
|
|
91
|
+
βββ src/ # Language engine
|
|
92
|
+
β βββ lexer.js # Tokenizer
|
|
93
|
+
β βββ parser.js # Recursive descent parser with precedence climbing
|
|
94
|
+
β βββ interpreter.js # Tree-walking interpreter
|
|
95
|
+
β βββ environment.js # Scope, built-ins, function closures
|
|
96
|
+
β βββ index.js # CLI entry point
|
|
97
|
+
βββ examples/ # Example programs
|
|
98
|
+
β βββ hello.steel
|
|
99
|
+
β βββ logic.steel
|
|
100
|
+
β βββ variables.steel
|
|
101
|
+
β βββ features-demo.steel
|
|
102
|
+
β βββ control-flow.steel
|
|
103
|
+
β βββ functions-arrays.steel
|
|
104
|
+
βββ stl/ # VS Code extension
|
|
105
|
+
```
|
|
117
106
|
|
|
118
|
-
|
|
107
|
+
## License
|
|
119
108
|
|
|
109
|
+
MIT
|
package/package.json
CHANGED
package/src/environment.js
CHANGED
|
@@ -1,35 +1,192 @@
|
|
|
1
1
|
class Environment {
|
|
2
|
-
|
|
3
|
-
constructor() {
|
|
4
|
-
|
|
2
|
+
constructor(parent = null) {
|
|
5
3
|
this.variables = {};
|
|
6
|
-
|
|
4
|
+
this.parent = parent;
|
|
7
5
|
}
|
|
8
6
|
|
|
9
|
-
|
|
10
|
-
|
|
11
7
|
set(name, value) {
|
|
12
|
-
|
|
13
8
|
this.variables[name] = value;
|
|
14
|
-
|
|
15
9
|
}
|
|
16
10
|
|
|
17
|
-
|
|
18
|
-
|
|
19
11
|
get(name) {
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
12
|
+
if (name in this.variables) {
|
|
13
|
+
return this.variables[name];
|
|
14
|
+
}
|
|
15
|
+
if (this.parent) {
|
|
16
|
+
return this.parent.get(name);
|
|
25
17
|
}
|
|
18
|
+
throw new Error(`Variable "${name}" is not defined`);
|
|
19
|
+
}
|
|
26
20
|
|
|
27
|
-
|
|
21
|
+
has(name) {
|
|
22
|
+
if (name in this.variables) return true;
|
|
23
|
+
if (this.parent) return this.parent.has(name);
|
|
24
|
+
return false;
|
|
25
|
+
}
|
|
28
26
|
|
|
27
|
+
// Function storage
|
|
28
|
+
defineFunction(name, params, body, closureEnv) {
|
|
29
|
+
this.variables[name] = {
|
|
30
|
+
type: 'function',
|
|
31
|
+
params,
|
|
32
|
+
body,
|
|
33
|
+
closure: closureEnv,
|
|
34
|
+
};
|
|
29
35
|
}
|
|
30
36
|
|
|
31
|
-
|
|
37
|
+
isFunction(name) {
|
|
38
|
+
const val = this.has(name) ? this.get(name) : undefined;
|
|
39
|
+
return val && val.type === 'function';
|
|
40
|
+
}
|
|
32
41
|
|
|
42
|
+
callFunction(name, args) {
|
|
43
|
+
const fn = this.get(name);
|
|
44
|
+
if (!fn || fn.type !== 'function') {
|
|
45
|
+
throw new Error(`"${name}" is not a function`);
|
|
46
|
+
}
|
|
47
|
+
const fnEnv = new Environment(fn.closure);
|
|
48
|
+
for (let i = 0; i < fn.params.length; i++) {
|
|
49
|
+
fnEnv.set(fn.params[i], args[i] !== undefined ? args[i] : null);
|
|
50
|
+
}
|
|
51
|
+
return { env: fnEnv, body: fn.body };
|
|
52
|
+
}
|
|
33
53
|
|
|
54
|
+
// Built-in functions
|
|
55
|
+
static createGlobal() {
|
|
56
|
+
const env = new Environment();
|
|
57
|
+
|
|
58
|
+
// Math functions
|
|
59
|
+
env.set('abs', { type: 'builtin', fn: Math.abs, name: 'abs' });
|
|
60
|
+
env.set('round', { type: 'builtin', fn: (n) => Math.round(n), name: 'round' });
|
|
61
|
+
env.set('floor', { type: 'builtin', fn: Math.floor, name: 'floor' });
|
|
62
|
+
env.set('ceil', { type: 'builtin', fn: Math.ceil, name: 'ceil' });
|
|
63
|
+
env.set('sqrt', { type: 'builtin', fn: Math.sqrt, name: 'sqrt' });
|
|
64
|
+
env.set('pow', { type: 'builtin', fn: (a, b) => Math.pow(a, b), name: 'pow' });
|
|
65
|
+
env.set('min', { type: 'builtin', fn: Math.min, name: 'min' });
|
|
66
|
+
env.set('max', { type: 'builtin', fn: Math.max, name: 'max' });
|
|
67
|
+
env.set('random', { type: 'builtin', fn: () => Math.random(), name: 'random' });
|
|
68
|
+
env.set('pi', Math.PI);
|
|
69
|
+
env.set('e', Math.E);
|
|
70
|
+
|
|
71
|
+
// String functions
|
|
72
|
+
env.set('len', { type: 'builtin', fn: (v) => {
|
|
73
|
+
if (Array.isArray(v)) return v.length;
|
|
74
|
+
if (typeof v === 'string') return v.length;
|
|
75
|
+
return String(v).length;
|
|
76
|
+
}, name: 'len' });
|
|
77
|
+
env.set('upper', { type: 'builtin', fn: (s) => String(s).toUpperCase(), name: 'upper' });
|
|
78
|
+
env.set('lower', { type: 'builtin', fn: (s) => String(s).toLowerCase(), name: 'lower' });
|
|
79
|
+
env.set('trim', { type: 'builtin', fn: (s) => String(s).trim(), name: 'trim' });
|
|
80
|
+
env.set('substring', { type: 'builtin', fn: (s, start, end) => {
|
|
81
|
+
if (end !== undefined) return String(s).substring(start, end);
|
|
82
|
+
return String(s).substring(start);
|
|
83
|
+
}, name: 'substring' });
|
|
84
|
+
env.set('replace', { type: 'builtin', fn: (s, from, to) => String(s).replaceAll(from, to), name: 'replace' });
|
|
85
|
+
env.set('split', { type: 'builtin', fn: (s, sep) => String(s).split(sep), name: 'split' });
|
|
86
|
+
env.set('join', { type: 'builtin', fn: (arr, sep) => Array.isArray(arr) ? arr.join(sep) : String(arr), name: 'join' });
|
|
87
|
+
env.set('contains', { type: 'builtin', fn: (s, sub) => String(s).includes(sub), name: 'contains' });
|
|
88
|
+
env.set('charAt', { type: 'builtin', fn: (s, i) => String(s).charAt(i), name: 'charAt' });
|
|
89
|
+
env.set('indexOf', { type: 'builtin', fn: (s, sub) => String(s).indexOf(sub), name: 'indexOf' });
|
|
90
|
+
env.set('startsWith', { type: 'builtin', fn: (s, prefix) => String(s).startsWith(prefix), name: 'startsWith' });
|
|
91
|
+
env.set('endsWith', { type: 'builtin', fn: (s, suffix) => String(s).endsWith(suffix), name: 'endsWith' });
|
|
92
|
+
env.set('repeat', { type: 'builtin', fn: (s, n) => String(s).repeat(n), name: 'repeat' });
|
|
93
|
+
env.set('padStart', { type: 'builtin', fn: (s, n, ch) => String(s).padStart(n, ch || ' '), name: 'padStart' });
|
|
94
|
+
env.set('padEnd', { type: 'builtin', fn: (s, n, ch) => String(s).padEnd(n, ch || ' '), name: 'padEnd' });
|
|
95
|
+
|
|
96
|
+
// Type checking
|
|
97
|
+
env.set('type', { type: 'builtin', fn: (v) => {
|
|
98
|
+
if (v === null) return 'null';
|
|
99
|
+
if (Array.isArray(v)) return 'array';
|
|
100
|
+
if (typeof v === 'number') return 'number';
|
|
101
|
+
if (typeof v === 'string') return 'string';
|
|
102
|
+
if (typeof v === 'boolean') return 'boolean';
|
|
103
|
+
return 'unknown';
|
|
104
|
+
}, name: 'type' });
|
|
105
|
+
env.set('isNumber', { type: 'builtin', fn: (v) => typeof v === 'number', name: 'isNumber' });
|
|
106
|
+
env.set('isString', { type: 'builtin', fn: (v) => typeof v === 'string', name: 'isString' });
|
|
107
|
+
env.set('isArray', { type: 'builtin', fn: (v) => Array.isArray(v), name: 'isArray' });
|
|
108
|
+
env.set('toString', { type: 'builtin', fn: (v) => String(v), name: 'toString' });
|
|
109
|
+
env.set('toNumber', { type: 'builtin', fn: (v) => Number(v), name: 'toNumber' });
|
|
110
|
+
|
|
111
|
+
// Array functions
|
|
112
|
+
env.set('push', { type: 'builtin', fn: (arr, item) => {
|
|
113
|
+
if (!Array.isArray(arr)) throw new Error('push() requires an array');
|
|
114
|
+
arr.push(item);
|
|
115
|
+
return arr;
|
|
116
|
+
}, name: 'push' });
|
|
117
|
+
env.set('pop', { type: 'builtin', fn: (arr) => {
|
|
118
|
+
if (!Array.isArray(arr)) throw new Error('pop() requires an array');
|
|
119
|
+
return arr.pop();
|
|
120
|
+
}, name: 'pop' });
|
|
121
|
+
env.set('shift', { type: 'builtin', fn: (arr) => {
|
|
122
|
+
if (!Array.isArray(arr)) throw new Error('shift() requires an array');
|
|
123
|
+
return arr.shift();
|
|
124
|
+
}, name: 'shift' });
|
|
125
|
+
env.set('unshift', { type: 'builtin', fn: (arr, item) => {
|
|
126
|
+
if (!Array.isArray(arr)) throw new Error('unshift() requires an array');
|
|
127
|
+
arr.unshift(item);
|
|
128
|
+
return arr;
|
|
129
|
+
}, name: 'unshift' });
|
|
130
|
+
env.set('reverse', { type: 'builtin', fn: (arr) => {
|
|
131
|
+
if (!Array.isArray(arr)) throw new Error('reverse() requires an array');
|
|
132
|
+
return [...arr].reverse();
|
|
133
|
+
}, name: 'reverse' });
|
|
134
|
+
env.set('sort', { type: 'builtin', fn: (arr) => {
|
|
135
|
+
if (!Array.isArray(arr)) throw new Error('sort() requires an array');
|
|
136
|
+
return [...arr].sort((a, b) => a - b);
|
|
137
|
+
}, name: 'sort' });
|
|
138
|
+
env.set('slice', { type: 'builtin', fn: (arr, start, end) => {
|
|
139
|
+
if (!Array.isArray(arr)) throw new Error('slice() requires an array');
|
|
140
|
+
if (end !== undefined) return arr.slice(start, end);
|
|
141
|
+
return arr.slice(start);
|
|
142
|
+
}, name: 'slice' });
|
|
143
|
+
env.set('indexOf_arr', { type: 'builtin', fn: (arr, item) => {
|
|
144
|
+
if (!Array.isArray(arr)) throw new Error('indexOf requires an array');
|
|
145
|
+
return arr.indexOf(item);
|
|
146
|
+
}, name: 'indexOf_arr' });
|
|
147
|
+
env.set('includes', { type: 'builtin', fn: (arr, item) => {
|
|
148
|
+
if (!Array.isArray(arr)) throw new Error('includes() requires an array');
|
|
149
|
+
return arr.includes(item);
|
|
150
|
+
}, name: 'includes' });
|
|
151
|
+
env.set('flat', { type: 'builtin', fn: (arr, depth) => {
|
|
152
|
+
if (!Array.isArray(arr)) throw new Error('flat() requires an array');
|
|
153
|
+
return arr.flat(depth);
|
|
154
|
+
}, name: 'flat' });
|
|
155
|
+
env.set('range', { type: 'builtin', fn: (start, end, step) => {
|
|
156
|
+
step = step || 1;
|
|
157
|
+
const result = [];
|
|
158
|
+
if (step > 0) {
|
|
159
|
+
for (let i = start; i < end; i += step) result.push(i);
|
|
160
|
+
} else {
|
|
161
|
+
for (let i = start; i > end; i += step) result.push(i);
|
|
162
|
+
}
|
|
163
|
+
return result;
|
|
164
|
+
}, name: 'range' });
|
|
165
|
+
|
|
166
|
+
// I/O
|
|
167
|
+
env.set('input', { type: 'builtin', fn: (prompt) => {
|
|
168
|
+
if (typeof require !== 'undefined') {
|
|
169
|
+
const readline = require('readline');
|
|
170
|
+
const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
|
|
171
|
+
return new Promise((resolve) => {
|
|
172
|
+
rl.question(prompt || '', (answer) => {
|
|
173
|
+
rl.close();
|
|
174
|
+
resolve(answer);
|
|
175
|
+
});
|
|
176
|
+
});
|
|
177
|
+
}
|
|
178
|
+
return null;
|
|
179
|
+
}, name: 'input' });
|
|
180
|
+
|
|
181
|
+
// Misc
|
|
182
|
+
env.set('clock', { type: 'builtin', fn: () => Date.now(), name: 'clock' });
|
|
183
|
+
env.set('sleep', { type: 'builtin', fn: (ms) => {
|
|
184
|
+
const end = Date.now() + ms;
|
|
185
|
+
while (Date.now() < end) {} // busy wait
|
|
186
|
+
}, name: 'sleep' });
|
|
187
|
+
|
|
188
|
+
return env;
|
|
189
|
+
}
|
|
190
|
+
}
|
|
34
191
|
|
|
35
192
|
module.exports = Environment;
|
package/src/index.js
CHANGED
|
@@ -1,49 +1,43 @@
|
|
|
1
1
|
const fs = require('fs');
|
|
2
|
-
|
|
3
2
|
const { tokenize } = require('./lexer');
|
|
4
|
-
|
|
5
3
|
const { parse } = require('./parser');
|
|
6
|
-
|
|
7
4
|
const { interpret } = require('./interpreter');
|
|
8
|
-
|
|
9
5
|
const Environment = require('./environment');
|
|
10
6
|
|
|
11
|
-
|
|
12
|
-
|
|
13
7
|
const file = process.argv[2];
|
|
14
8
|
|
|
15
|
-
|
|
16
|
-
|
|
17
9
|
if (!file) {
|
|
18
|
-
|
|
10
|
+
console.log("Steel Language Interpreter v2.0.0");
|
|
19
11
|
console.log("Usage: node src/index.js <file.steel>");
|
|
20
|
-
|
|
12
|
+
console.log("");
|
|
13
|
+
console.log("Features:");
|
|
14
|
+
console.log(" Variables: set x to 10");
|
|
15
|
+
console.log(" Output: say \"Hello!\"");
|
|
16
|
+
console.log(" Conditionals: if x > 5 then ... elseif x > 3 then ... else ... end");
|
|
17
|
+
console.log(" Loops: while x > 0 do ... end");
|
|
18
|
+
console.log(" For loops: for i to 10 ... end | for each item in arr ... end");
|
|
19
|
+
console.log(" Repeat: repeat 5 times ... end");
|
|
20
|
+
console.log(" Functions: define greet as (name) ... return \"Hello \" + name end");
|
|
21
|
+
console.log(" Arrays: set nums to [1, 2, 3, 4, 5]");
|
|
22
|
+
console.log(" Operators: + - * / % > < >= <= == != and or not");
|
|
23
|
+
console.log(" Comments: // this is a comment");
|
|
24
|
+
console.log(" Templates: say `Hello ${name}!`");
|
|
25
|
+
console.log(" Booleans: true, false, null");
|
|
26
|
+
console.log(" Built-ins: abs, round, floor, ceil, sqrt, pow, min, max, random");
|
|
27
|
+
console.log(" Strings: len, upper, lower, trim, substring, replace, split, join");
|
|
28
|
+
console.log(" Arrays: push, pop, shift, unshift, reverse, sort, slice, includes");
|
|
29
|
+
console.log(" Types: type, isNumber, isString, isArray, toString, toNumber");
|
|
30
|
+
console.log(" Misc: pi, e, clock, sleep, input, range");
|
|
21
31
|
process.exit(1);
|
|
22
|
-
|
|
23
32
|
}
|
|
24
33
|
|
|
25
|
-
|
|
26
|
-
|
|
27
34
|
try {
|
|
28
|
-
|
|
29
35
|
const code = fs.readFileSync(file, 'utf-8');
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
36
|
const tokens = tokenize(code);
|
|
34
|
-
|
|
35
37
|
const ast = parse(tokens);
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
const env = new Environment();
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
38
|
+
const env = Environment.createGlobal();
|
|
43
39
|
interpret(ast, env);
|
|
44
|
-
|
|
45
40
|
} catch (err) {
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
41
|
+
console.error("Error: " + err.message);
|
|
42
|
+
process.exit(1);
|
|
49
43
|
}
|