language-design
Use when designing language features - covers lexer, parser, AST, and interpreter patterns
التثبيت باستخدام Codex أو Claude انسخ هذا Prompt والصقه في Codex أو Claude أو مساعد آخر ليراجع صفحة Skill ويثبّتها لك.
القائمة
Use when designing language features - covers lexer, parser, AST, and interpreter patterns
التثبيت باستخدام Codex أو Claude انسخ هذا Prompt والصقه في Codex أو Claude أو مساعد آخر ليراجع صفحة Skill ويثبّتها لك.
استنادا إلى تصنيف SOC المهني
Use when configuring ESLint - covers flat config, TypeScript integration, and custom rules
Use when creating GitHub Actions workflows - covers CI/CD, matrix testing, and release automation
Use when writing Jest tests - covers testing patterns for interpreters, parsers, and async code
Use when implementing Language Server Protocol features - covers completions, hover, diagnostics, and navigation
Use when creating Mermaid diagrams - covers flowcharts, sequence diagrams, and AST visualization
Use when publishing npm packages - covers package.json configuration, versioning, and provenance
| name | language-design |
| description | Use when designing language features - covers lexer, parser, AST, and interpreter patterns |
Source Code → Lexer → Tokens → Parser → AST → Interpreter → Result
enum TokenType {
// Literals
NUMBER, STRING, IDENTIFIER,
// Keywords
LET, IF, ELSE, RETURN,
// Operators
PLUS, MINUS, STAR, SLASH,
PIPE, // />
// Delimiters
LPAREN, RPAREN, LBRACE, RBRACE,
// Special
EOF, NEWLINE,
}
class Lexer {
private source: string;
private pos = 0;
private line = 1;
private column = 1;
nextToken(): Token {
this.skipWhitespace();
if (this.isAtEnd()) return this.makeToken(TokenType.EOF);
const char = this.advance();
if (this.isDigit(char)) return this.number();
if (this.isAlpha(char)) return this.identifier();
if (char === '"') return this.string();
// Operators
switch (char) {
case '+': return this.makeToken(TokenType.PLUS);
case '/':
if (this.match('>')) return this.makeToken(TokenType.PIPE);
return this.makeToken(TokenType.SLASH);
}
throw new LexerError(`Unexpected character: ${char}`, this.line, this.column);
}
}
class Parser {
private tokens: Token[];
private current = 0;
parse(): Program {
const statements: Stmt[] = [];
while (!this.isAtEnd()) {
statements.push(this.statement());
}
return { type: "Program", body: statements };
}
// Precedence climbing
private expression(): Expr {
return this.pipe();
}
private pipe(): Expr {
let left = this.equality();
while (this.match(TokenType.PIPE)) {
const right = this.equality();
left = { type: "PipeExpr", left, right };
}
return left;
}
private equality(): Expr {
let left = this.comparison();
while (this.match(TokenType.EQEQ, TokenType.NEQ)) {
const op = this.previous().type;
const right = this.comparison();
left = { type: "BinaryExpr", op, left, right };
}
return left;
}
// Continue down precedence...
}
1. Ternary ? : (lowest)
2. Equality == !=
3. Comparison < > <= >=
4. Term + - ++
5. Factor * / %
6. Pipe />
7. Unary -
8. Call fn()
9. Primary literals (highest)
type Expr =
| { type: "NumberLiteral"; value: number; line: number }
| { type: "StringLiteral"; value: string; line: number }
| { type: "Identifier"; name: string; line: number }
| { type: "BinaryExpr"; op: string; left: Expr; right: Expr; line: number }
| { type: "PipeExpr"; left: Expr; right: Expr; line: number }
| { type: "CallExpr"; callee: Expr; args: Expr[]; line: number };
type Stmt =
| { type: "LetStmt"; name: string; value: Expr; line: number }
| { type: "ExprStmt"; expression: Expr; line: number };
class Interpreter {
private env = new Environment();
evaluate(expr: Expr): Value {
switch (expr.type) {
case "NumberLiteral":
return expr.value;
case "BinaryExpr":
const left = this.evaluate(expr.left);
const right = this.evaluate(expr.right);
return this.applyOperator(expr.op, left, right);
case "PipeExpr":
const value = this.evaluate(expr.left);
const fn = this.evaluate(expr.right);
return this.call(fn, [value]);
case "Identifier":
return this.env.get(expr.name);
}
}
}
class Environment {
private values = new Map<string, Value>();
private parent?: Environment;
constructor(parent?: Environment) {
this.parent = parent;
}
define(name: string, value: Value): void {
this.values.set(name, value);
}
get(name: string): Value {
if (this.values.has(name)) return this.values.get(name)!;
if (this.parent) return this.parent.get(name);
throw new RuntimeError(`Undefined variable: ${name}`);
}
}