fazer-lang 0.1.0 → 1.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 +32 -0
- package/fazer.js +204 -145
- package/package.json +6 -23
- package/package.json.bak +44 -0
package/README.md
ADDED
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
# [Logo](logo.png)
|
|
2
|
+
|
|
3
|
+
Langage de programmation.
|
|
4
|
+
|
|
5
|
+
## Features
|
|
6
|
+
- `stash` vars, `broadcast` outputs
|
|
7
|
+
- `risk` pour probabilités
|
|
8
|
+
- `uhquali event` pour random culture boosts
|
|
9
|
+
- `cooldown` et `wait` pour timers
|
|
10
|
+
- `save/load` pour persistence
|
|
11
|
+
- `broadcast to discord` pour bots
|
|
12
|
+
- Et plus : intersects, flows, parallels, territories
|
|
13
|
+
|
|
14
|
+
## Installation
|
|
15
|
+
1. Clone le repo : `git clone https://github.com/tonusername/fazer-lang.git`
|
|
16
|
+
2. `cd fazer-lang`
|
|
17
|
+
3. `npm install`
|
|
18
|
+
4. Build standalone : `npm run build` → get `bin/fazer.exe`
|
|
19
|
+
5. Run : `fazer run monfichier.fz`
|
|
20
|
+
|
|
21
|
+
Ou via npm (si publié) : `npm install -g fazer-lang` puis `fazer run ...`
|
|
22
|
+
|
|
23
|
+
## Exemple (heist.fz)
|
|
24
|
+
`stash rep as 50
|
|
25
|
+
uhquali event "street cred boost"
|
|
26
|
+
cooldown heist 30m
|
|
27
|
+
risk 70% chance of broadcast "Win!" ; stash cash as 1000
|
|
28
|
+
save empire`
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
## Logo
|
|
32
|
+

|
package/fazer.js
CHANGED
|
@@ -1,175 +1,234 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
1
3
|
const fs = require('fs');
|
|
2
4
|
const path = require('path');
|
|
3
|
-
const {
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
const
|
|
8
|
-
const
|
|
9
|
-
const
|
|
10
|
-
const
|
|
11
|
-
const
|
|
12
|
-
const
|
|
13
|
-
const
|
|
14
|
-
const
|
|
15
|
-
const
|
|
16
|
-
const
|
|
17
|
-
const
|
|
18
|
-
const
|
|
19
|
-
const
|
|
20
|
-
|
|
21
|
-
const
|
|
22
|
-
const
|
|
23
|
-
const
|
|
24
|
-
const
|
|
25
|
-
const
|
|
26
|
-
const
|
|
27
|
-
const
|
|
28
|
-
const
|
|
29
|
-
const
|
|
30
|
-
const
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
const
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
5
|
+
const { Lexer, Parser, createToken, EmbeddedActionsParser } = require('chevrotain');
|
|
6
|
+
|
|
7
|
+
// Tokens (restent les mêmes, ajoutés Equals, NotEq, And, Or, Not pour expressions)
|
|
8
|
+
const Assign = createToken({ name: 'Assign', pattern: /:=/ });
|
|
9
|
+
const Arrow = createToken({ name: 'Arrow', pattern: /→/ });
|
|
10
|
+
const DoublePipe = createToken({ name: 'DoublePipe', pattern: /→>/ });
|
|
11
|
+
const Case = createToken({ name: 'Case', pattern: /case/ });
|
|
12
|
+
const Rescue = createToken({ name: 'Rescue', pattern: /rescue/ });
|
|
13
|
+
const Catch = createToken({ name: 'Catch', pattern: /catch/ });
|
|
14
|
+
const From = createToken({ name: 'From', pattern: /from/ });
|
|
15
|
+
const End = createToken({ name: 'End', pattern: /end/ });
|
|
16
|
+
const Await = createToken({ name: 'Await', pattern: /await/ });
|
|
17
|
+
const Mut = createToken({ name: 'Mut', pattern: /mut/ });
|
|
18
|
+
const Async = createToken({ name: 'Async', pattern: /async/ });
|
|
19
|
+
const Else = createToken({ name: 'Else', pattern: /else/ });
|
|
20
|
+
const In = createToken({ name: 'In', pattern: /in/ });
|
|
21
|
+
const Step = createToken({ name: 'Step', pattern: /step/ });
|
|
22
|
+
|
|
23
|
+
const Identifier = createToken({ name: 'Identifier', pattern: /[a-zA-Z_][a-zA-Z0-9_]*/ });
|
|
24
|
+
const Integer = createToken({ name: 'Integer', pattern: /-?\d+/ });
|
|
25
|
+
const Float = createToken({ name: 'Float', pattern: /-?\d+\.\d+/ });
|
|
26
|
+
const StringLiteral = createToken({ name: 'StringLiteral', pattern: /"([^"\\]|\\.)*"/ });
|
|
27
|
+
const True = createToken({ name: 'True', pattern: /true/ });
|
|
28
|
+
const False = createToken({ name: 'False', pattern: /false/ });
|
|
29
|
+
const Colon = createToken({ name: 'Colon', pattern: /:/ });
|
|
30
|
+
const LBracket = createToken({ name: 'LBracket', pattern: /\[/ });
|
|
31
|
+
const RBracket = createToken({ name: 'RBracket', pattern: /\]/ });
|
|
32
|
+
const LBrace = createToken({ name: 'LBrace', pattern: /{/ });
|
|
33
|
+
const RBrace = createToken({ name: 'RBrace', pattern: /}/ });
|
|
34
|
+
const Comma = createToken({ name: 'Comma', pattern: /,/ });
|
|
35
|
+
const Dot = createToken({ name: 'Dot', pattern: /\./ });
|
|
36
|
+
const Plus = createToken({ name: 'Plus', pattern: /\+/ });
|
|
37
|
+
const Minus = createToken({ name: 'Minus', pattern: /-/ });
|
|
38
|
+
const Star = createToken({ name: 'Star', pattern: /\*/ });
|
|
39
|
+
const Slash = createToken({ name: 'Slash', pattern: /\// });
|
|
40
|
+
const Percent = createToken({ name: 'Percent', pattern: /%/ });
|
|
41
|
+
const Greater = createToken({ name: 'Greater', pattern: />/ });
|
|
42
|
+
const Less = createToken({ name: 'Less', pattern: /</ });
|
|
43
|
+
const GreaterEq = createToken({ name: 'GreaterEq', pattern: />=/ });
|
|
44
|
+
const LessEq = createToken({ name: 'LessEq', pattern: /<=/ });
|
|
45
|
+
const Eq = createToken({ name: 'Eq', pattern: /==/ });
|
|
46
|
+
const NotEq = createToken({ name: 'NotEq', pattern: /!=/ });
|
|
47
|
+
const And = createToken({ name: 'And', pattern: /and/ });
|
|
48
|
+
const Or = createToken({ name: 'Or', pattern: /or/ });
|
|
49
|
+
const Not = createToken({ name: 'Not', pattern: /not/ });
|
|
50
|
+
const Comment = createToken({ name: 'Comment', pattern: /#.*/, group: Lexer.SKIPPED });
|
|
51
|
+
const WhiteSpace = createToken({ name: 'WhiteSpace', pattern: /\s+/, group: Lexer.SKIPPED });
|
|
52
|
+
|
|
53
|
+
const lexer = new Lexer([
|
|
54
|
+
Assign, Arrow, DoublePipe, Case, Rescue, Catch, From, End, Await, Mut, Async, Else, In, Step,
|
|
55
|
+
Identifier, Float, Integer, StringLiteral, True, False, Colon, LBracket, RBracket, LBrace, RBrace,
|
|
56
|
+
Comma, Dot, Plus, Minus, Star, Slash, Percent, Greater, Less, GreaterEq, LessEq, Eq, NotEq, And, Or, Not,
|
|
57
|
+
Comment, WhiteSpace
|
|
37
58
|
]);
|
|
38
59
|
|
|
39
|
-
// Parser
|
|
40
|
-
class FazerParser extends
|
|
60
|
+
// ── Parser avec Embedded Actions (exécution inline) ──────────────────────────
|
|
61
|
+
class FazerParser extends EmbeddedActionsParser {
|
|
41
62
|
constructor() {
|
|
42
|
-
super(
|
|
63
|
+
super(lexer.allTokens);
|
|
43
64
|
const $ = this;
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
65
|
+
|
|
66
|
+
$.RULE('program', () => {
|
|
67
|
+
const stmts = $.MANY(() => $.SUBRULE($.statement));
|
|
68
|
+
return stmts;
|
|
69
|
+
});
|
|
70
|
+
|
|
71
|
+
$.RULE('statement', () => $.OR([
|
|
72
|
+
{ ALT: () => $.SUBRULE($.assignStmt) },
|
|
73
|
+
{ ALT: () => $.SUBRULE($.functionDef) },
|
|
74
|
+
{ ALT: () => $.SUBRULE($.caseBlock) },
|
|
75
|
+
{ ALT: () => $.SUBRULE($.rescueBlock) },
|
|
76
|
+
{ ALT: () => $.SUBRULE($.expressionStmt) }
|
|
77
|
+
]));
|
|
78
|
+
|
|
79
|
+
$.RULE('assignStmt', () => {
|
|
80
|
+
const isMut = $.OPTION(() => $.CONSUME(Mut));
|
|
81
|
+
const id = $.CONSUME(Identifier);
|
|
82
|
+
let type = null;
|
|
83
|
+
$.OPTION2(() => {
|
|
84
|
+
$.CONSUME(Colon);
|
|
85
|
+
type = $.CONSUME2(Identifier).image;
|
|
86
|
+
});
|
|
87
|
+
$.CONSUME(Assign);
|
|
88
|
+
const value = $.SUBRULE($.expression);
|
|
89
|
+
return { type: 'assign', mut: !!isMut, name: id.image, varType: type, value };
|
|
90
|
+
});
|
|
91
|
+
|
|
92
|
+
$.RULE('caseBlock', () => {
|
|
93
|
+
$.CONSUME(Case);
|
|
94
|
+
const expr = $.SUBRULE($.expression);
|
|
95
|
+
const cases = [];
|
|
96
|
+
$.MANY(() => {
|
|
97
|
+
let pattern = $.OR([
|
|
98
|
+
{ ALT: () => $.SUBRULE($.pattern) },
|
|
99
|
+
{ ALT: () => $.CONSUME(Else) ? 'else' : null }
|
|
100
|
+
]);
|
|
101
|
+
$.CONSUME(Arrow);
|
|
102
|
+
const body = $.SUBRULE($.block);
|
|
103
|
+
cases.push({ pattern, body });
|
|
104
|
+
});
|
|
105
|
+
return { type: 'case', expr, cases };
|
|
106
|
+
});
|
|
107
|
+
|
|
108
|
+
$.RULE('block', () => {
|
|
109
|
+
const stmts = $.MANY(() => $.SUBRULE($.statement));
|
|
110
|
+
$.CONSUME(End);
|
|
111
|
+
return stmts;
|
|
112
|
+
});
|
|
113
|
+
|
|
114
|
+
$.RULE('expression', () => {
|
|
115
|
+
let left = $.SUBRULE($.primaryExpr);
|
|
116
|
+
$.MANY(() => {
|
|
117
|
+
const op = $.OR([
|
|
118
|
+
{ ALT: () => $.CONSUME(Plus).image },
|
|
119
|
+
{ ALT: () => $.CONSUME(Minus).image },
|
|
120
|
+
{ ALT: () => $.CONSUME(Star).image },
|
|
121
|
+
{ ALT: () => $.CONSUME(Slash).image }
|
|
122
|
+
]);
|
|
123
|
+
const right = $.SUBRULE2($.primaryExpr);
|
|
124
|
+
left = { type: 'binop', op, left, right };
|
|
125
|
+
});
|
|
126
|
+
return left;
|
|
57
127
|
});
|
|
58
|
-
|
|
128
|
+
|
|
129
|
+
$.RULE('primaryExpr', () => $.OR([
|
|
130
|
+
{ ALT: () => $.CONSUME(Integer).image },
|
|
131
|
+
{ ALT: () => $.CONSUME(StringLiteral).image.slice(1, -1) },
|
|
132
|
+
{ ALT: () => $.CONSUME(Identifier).image },
|
|
133
|
+
// Ajouter list, map, call, etc.
|
|
134
|
+
]));
|
|
135
|
+
|
|
136
|
+
// Ajouter rules pour functionDef, rescueBlock, pattern, etc.
|
|
137
|
+
|
|
59
138
|
this.performSelfAnalysis();
|
|
60
139
|
}
|
|
61
140
|
}
|
|
62
|
-
const parser = new FazerParser();
|
|
63
141
|
|
|
64
|
-
|
|
142
|
+
// ── Runtime (exécution du CST) ───────────────────────────────────────────────
|
|
143
|
+
class FazerRuntime {
|
|
65
144
|
constructor() {
|
|
66
|
-
this.
|
|
67
|
-
this.
|
|
68
|
-
this.cooldowns = {}; // { name: endTime }
|
|
69
|
-
this.discordClient = null; // Init Discord lazy
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
// Parse avec Chevrotain
|
|
73
|
-
parse(code) {
|
|
74
|
-
const lexResult = fazerLexer.tokenize(code);
|
|
75
|
-
parser.input = lexResult.tokens;
|
|
76
|
-
const cst = parser.statement(); // Parse top-level
|
|
77
|
-
if (parser.errors.length > 0) throw new Error(parser.errors[0].message);
|
|
78
|
-
return cst; // Retourne CST pour exécution
|
|
145
|
+
this.vars = new Map(); // name → {value, mut, type}
|
|
146
|
+
this.fns = new Map();
|
|
79
147
|
}
|
|
80
148
|
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
// Exemple pour uhquali
|
|
92
|
-
if (line.startsWith('uhquali event ')) {
|
|
93
|
-
const eventName = line.slice(13).trim().replace(/"/g, '');
|
|
94
|
-
const events = ['Win culture boost +20 cultural_rep', 'Lose -10, rival diss', 'Neutral vibe'];
|
|
95
|
-
const outcome = events[Math.floor(Math.random() * events.length)];
|
|
96
|
-
this.variables['cultural_rep'] = (this.variables['cultural_rep'] || 0) + (outcome.includes('+') ? 20 : outcome.includes('-') ? -10 : 0);
|
|
97
|
-
console.log(`Uhquali event "${eventName}": ${outcome}`);
|
|
98
|
-
output.push(outcome);
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
// Cooldown
|
|
102
|
-
if (line.startsWith('cooldown ')) {
|
|
103
|
-
const [name, timeStr] = line.slice(9).trim().split(' ');
|
|
104
|
-
const time = this.parseTime(timeStr);
|
|
105
|
-
this.cooldowns[name] = Date.now() + time;
|
|
106
|
-
console.log(`Cooldown set for ${name}: ${timeStr}`);
|
|
107
|
-
}
|
|
108
|
-
|
|
109
|
-
// Check cooldown in actions (ex: in heist, if (Date.now() < this.cooldowns['heist']) bust)
|
|
110
|
-
|
|
111
|
-
// Wait
|
|
112
|
-
if (line.startsWith('wait ')) {
|
|
113
|
-
const timeStr = line.slice(5).trim();
|
|
114
|
-
const time = this.parseTime(timeStr);
|
|
115
|
-
await new Promise(resolve => setTimeout(resolve, time));
|
|
149
|
+
evalExpr(node) {
|
|
150
|
+
if (typeof node === 'string' || typeof node === 'number') return node;
|
|
151
|
+
if (node.type === 'binop') {
|
|
152
|
+
const left = this.evalExpr(node.left);
|
|
153
|
+
const right = this.evalExpr(node.right);
|
|
154
|
+
switch (node.op) {
|
|
155
|
+
case '+': return left + right;
|
|
156
|
+
case '-': return left - right;
|
|
157
|
+
case '*': return left * right;
|
|
158
|
+
case '/': return left / right;
|
|
116
159
|
}
|
|
160
|
+
}
|
|
161
|
+
if (node === 'print') {
|
|
162
|
+
console.log(this.evalExpr(node.args));
|
|
163
|
+
return null;
|
|
164
|
+
}
|
|
165
|
+
return null; // Étendre
|
|
166
|
+
}
|
|
117
167
|
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
168
|
+
execute(stmt) {
|
|
169
|
+
if (stmt.type === 'assign') {
|
|
170
|
+
const value = this.evalExpr(stmt.value);
|
|
171
|
+
this.vars.set(stmt.name, { value, mut: stmt.mut, type: stmt.varType });
|
|
172
|
+
return value;
|
|
173
|
+
}
|
|
124
174
|
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
if (
|
|
129
|
-
this.
|
|
130
|
-
console.log(`State loaded from ${name}.json`);
|
|
175
|
+
if (stmt.type === 'case') {
|
|
176
|
+
const exprValue = this.evalExpr(stmt.expr);
|
|
177
|
+
for (const c of stmt.cases) {
|
|
178
|
+
if (c.pattern === 'else' || this.matchPattern(exprValue, c.pattern)) {
|
|
179
|
+
return this.executeBlock(c.body);
|
|
131
180
|
}
|
|
132
181
|
}
|
|
182
|
+
return null;
|
|
183
|
+
}
|
|
133
184
|
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
const [channelId, ...msgParts] = line.slice(20).trim().split(' ');
|
|
137
|
-
const message = msgParts.join(' ');
|
|
138
|
-
await this.sendToDiscord(channelId, this.evaluate(message));
|
|
139
|
-
}
|
|
140
|
-
|
|
141
|
-
// Territory
|
|
142
|
-
if (line.startsWith('territory ')) {
|
|
143
|
-
const [name, action, key, value] = line.slice(10).trim().split(' ');
|
|
144
|
-
if (!this.variables[name]) this.variables[name] = {};
|
|
145
|
-
if (action === 'add') this.variables[name][key] = this.evaluate(value);
|
|
146
|
-
console.log(`Territory ${name} updated`);
|
|
147
|
-
}
|
|
185
|
+
// Étendre pour fn def, etc.
|
|
186
|
+
}
|
|
148
187
|
|
|
149
|
-
|
|
188
|
+
matchPattern(value, pattern) {
|
|
189
|
+
// Implémentation basique : pour conditions > < ==, ou patterns {key: val}
|
|
190
|
+
return value === pattern; // Étendre
|
|
191
|
+
}
|
|
150
192
|
|
|
151
|
-
|
|
193
|
+
executeBlock(block) {
|
|
194
|
+
let last = null;
|
|
195
|
+
for (const stmt of block) {
|
|
196
|
+
last = this.execute(stmt);
|
|
152
197
|
}
|
|
153
|
-
return
|
|
198
|
+
return last;
|
|
154
199
|
}
|
|
155
200
|
|
|
156
|
-
|
|
157
|
-
const
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
201
|
+
run(code) {
|
|
202
|
+
const lexResult = lexer.tokenize(code);
|
|
203
|
+
if (lexResult.errors.length > 0) {
|
|
204
|
+
console.error('Lexer errors:', lexResult.errors);
|
|
205
|
+
return;
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
const parser = new FazerParser();
|
|
209
|
+
parser.input = lexResult.tokens;
|
|
210
|
+
const cst = parser.program();
|
|
161
211
|
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
await this.discordClient.login(process.env.DISCORD_TOKEN);
|
|
212
|
+
if (parser.errors.length > 0) {
|
|
213
|
+
console.error('Parse errors:', parser.errors);
|
|
214
|
+
return;
|
|
166
215
|
}
|
|
167
|
-
const channel = await this.discordClient.channels.fetch(channelId);
|
|
168
|
-
await channel.send(message);
|
|
169
|
-
}
|
|
170
216
|
|
|
171
|
-
|
|
217
|
+
this.executeBlock(cst);
|
|
218
|
+
}
|
|
172
219
|
}
|
|
173
220
|
|
|
174
|
-
// CLI
|
|
175
|
-
|
|
221
|
+
// ── CLI ──────────────────────────────────────────────────────────────────────
|
|
222
|
+
const args = process.argv.slice(2);
|
|
223
|
+
|
|
224
|
+
if (args[0] === 'run' && args[1]) {
|
|
225
|
+
const filePath = path.resolve(args[1]);
|
|
226
|
+
if (!fs.existsSync(filePath)) {
|
|
227
|
+
console.error(`Fichier non trouvé : ${filePath}`);
|
|
228
|
+
process.exit(1);
|
|
229
|
+
}
|
|
230
|
+
const code = fs.readFileSync(filePath, 'utf8');
|
|
231
|
+
new FazerRuntime().run(code);
|
|
232
|
+
} else {
|
|
233
|
+
console.log('Usage: fazer run fichier.fz');
|
|
234
|
+
}
|
package/package.json
CHANGED
|
@@ -1,13 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "fazer-lang",
|
|
3
|
-
"version": "
|
|
4
|
-
"description": "Fazer
|
|
3
|
+
"version": "1.1.0",
|
|
4
|
+
"description": "Fazer – Langage d'expression fluide : verbes contextuels, pipes →>, assignation :=, pattern matching via case",
|
|
5
5
|
"main": "fazer.js",
|
|
6
6
|
"bin": {
|
|
7
7
|
"fazer": "fazer.js"
|
|
8
8
|
},
|
|
9
9
|
"dependencies": {
|
|
10
|
-
"discord.js": "^14.14.1",
|
|
11
10
|
"chevrotain": "^11.0.3"
|
|
12
11
|
},
|
|
13
12
|
"devDependencies": {
|
|
@@ -20,25 +19,9 @@
|
|
|
20
19
|
"keywords": [
|
|
21
20
|
"fazer",
|
|
22
21
|
"programming-language",
|
|
23
|
-
"
|
|
24
|
-
"
|
|
25
|
-
"simulation",
|
|
26
|
-
"risk-based"
|
|
22
|
+
"scripting",
|
|
23
|
+
"expression-language"
|
|
27
24
|
],
|
|
28
|
-
"author": "hm
|
|
29
|
-
"license": "MIT"
|
|
30
|
-
"files": [
|
|
31
|
-
"fazer.js",
|
|
32
|
-
"bin/",
|
|
33
|
-
"README.md",
|
|
34
|
-
"logo.png"
|
|
35
|
-
],
|
|
36
|
-
"repository": {
|
|
37
|
-
"type": "git",
|
|
38
|
-
"url": "git+https://github.com/hmj34/fazer-lang.git"
|
|
39
|
-
},
|
|
40
|
-
"bugs": {
|
|
41
|
-
"url": "https://github.com/hmj34/fazer-lang/issues"
|
|
42
|
-
},
|
|
43
|
-
"homepage": "https://github.com/hmj34/fazer-lang#readme"
|
|
25
|
+
"author": "hm",
|
|
26
|
+
"license": "MIT"
|
|
44
27
|
}
|
package/package.json.bak
ADDED
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "fazer-lang",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Fazer Language – Un langage de programmation.",
|
|
5
|
+
"main": "fazer.js",
|
|
6
|
+
"bin": {
|
|
7
|
+
"fazer": "fazer.js"
|
|
8
|
+
},
|
|
9
|
+
"dependencies": {
|
|
10
|
+
"discord.js": "^14.14.1",
|
|
11
|
+
"chevrotain": "^11.0.3"
|
|
12
|
+
},
|
|
13
|
+
"devDependencies": {
|
|
14
|
+
"pkg": "^5.8.1"
|
|
15
|
+
},
|
|
16
|
+
"scripts": {
|
|
17
|
+
"start": "node fazer.js",
|
|
18
|
+
"build": "pkg fazer.js -t node18-win-x64 -o bin/fazer.exe"
|
|
19
|
+
},
|
|
20
|
+
"keywords": [
|
|
21
|
+
"fazer",
|
|
22
|
+
"programming-language",
|
|
23
|
+
"street-script",
|
|
24
|
+
"discord-bot",
|
|
25
|
+
"simulation",
|
|
26
|
+
"risk-based"
|
|
27
|
+
],
|
|
28
|
+
"author": "hm (Fazer City)",
|
|
29
|
+
"license": "MIT",
|
|
30
|
+
"files": [
|
|
31
|
+
"fazer.js",
|
|
32
|
+
"bin/",
|
|
33
|
+
"README.md",
|
|
34
|
+
"logo.png"
|
|
35
|
+
],
|
|
36
|
+
"repository": {
|
|
37
|
+
"type": "git",
|
|
38
|
+
"url": "git+https://github.com/hmj34/fazer-lang.git"
|
|
39
|
+
},
|
|
40
|
+
"bugs": {
|
|
41
|
+
"url": "https://github.com/hmj34/fazer-lang/issues"
|
|
42
|
+
},
|
|
43
|
+
"homepage": "https://github.com/hmj34/fazer-lang#readme"
|
|
44
|
+
}
|