Move language files into dedicated folder
This commit is contained in:
parent
3d1cd89067
commit
1b406899e0
15 changed files with 7 additions and 343 deletions
|
|
@ -1,107 +0,0 @@
|
|||
import { Expr, Pattern, ProductPattern, Literal, FieldAssignment, FieldPattern } from '../value';
|
||||
|
||||
export function exprToString(expr: Expr): string {
|
||||
switch (expr.tag) {
|
||||
case "literal":
|
||||
return literalToString(expr.literal);
|
||||
|
||||
case "var_use":
|
||||
return `\$${expr.name}`;
|
||||
|
||||
case "call":
|
||||
return `${expr.name}(${expr.args.map(exprToString).join(", ")})`;
|
||||
|
||||
case "tuple":
|
||||
return `(${expr.exprs.map(exprToString).join(", ")})`;
|
||||
|
||||
case "record": {
|
||||
const fields = expr.fields.map(fieldAssignmentToString).join(", ");
|
||||
return `{ ${fields} }`;
|
||||
}
|
||||
|
||||
case "tag":
|
||||
return `#${expr.tag_name}`;
|
||||
|
||||
case "tagged": {
|
||||
// We wrap the payload in parens if it's complex to be safe,
|
||||
// but strictly speaking #foo 1 is valid.
|
||||
// Let's just output space + expr.
|
||||
const payload = exprToString(expr.expr);
|
||||
// Heuristic: if payload starts with '(', '{', or is simple, we might not need parens,
|
||||
// but for "tagged" expression precedence, it's often safer to wrap unless atomic.
|
||||
return `#${expr.tag_name} ${payload}`;
|
||||
}
|
||||
|
||||
case "let": {
|
||||
const bindings = expr.bindings
|
||||
.map(b => `${productPatternToString(b.pattern)} = ${exprToString(b.expr)}`)
|
||||
.join(", ");
|
||||
return `let { ${bindings} . ${exprToString(expr.body)} }`;
|
||||
}
|
||||
|
||||
case "lambda": {
|
||||
const params = expr.parameters.map(productPatternToString).join(", ");
|
||||
return `fn { ${params} . ${exprToString(expr.body)} }`;
|
||||
}
|
||||
|
||||
case "apply": {
|
||||
const args = expr.args.map(exprToString).join(", ");
|
||||
return `apply(${exprToString(expr.callee)} ! ${args})`;
|
||||
}
|
||||
|
||||
case "match": {
|
||||
const branches = expr.branches
|
||||
.map(b => `${patternToString(b.pattern)} . ${exprToString(b.body)}`)
|
||||
.join(" | ");
|
||||
return `match ${exprToString(expr.arg)} { ${branches} }`;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// === Helpers ===
|
||||
|
||||
function literalToString(lit: Literal): string {
|
||||
switch (lit.tag) {
|
||||
case "number": return lit.value.toString();
|
||||
case "string": return `"${lit.value}"`; // simplistic string escaping
|
||||
}
|
||||
}
|
||||
|
||||
function fieldAssignmentToString(f: FieldAssignment): string {
|
||||
return `${f.name} = ${exprToString(f.expr)}`;
|
||||
}
|
||||
|
||||
// === Pattern Printers ===
|
||||
|
||||
export function patternToString(pat: Pattern): string {
|
||||
switch (pat.tag) {
|
||||
case "tag":
|
||||
return `#${pat.tag_name}`;
|
||||
case "tagged":
|
||||
return `#${pat.tag_name} ${patternToString(pat.pattern)}`;
|
||||
// If it's a product pattern (any, tuple, record)
|
||||
default:
|
||||
return productPatternToString(pat);
|
||||
}
|
||||
}
|
||||
|
||||
export function productPatternToString(pat: ProductPattern): string {
|
||||
switch (pat.tag) {
|
||||
case "any":
|
||||
return pat.name;
|
||||
|
||||
case "tuple":
|
||||
return `(${pat.patterns.map(productPatternToString).join(", ")})`;
|
||||
|
||||
case "record":
|
||||
return `{ ${pat.fields.map(fieldPatternToString).join(", ")} }`;
|
||||
}
|
||||
}
|
||||
|
||||
function fieldPatternToString(f: FieldPattern): string {
|
||||
// Check for punning: if pattern is "any" and name matches fieldName
|
||||
if (f.pattern.tag === "any" && f.pattern.name === f.fieldName) {
|
||||
return f.fieldName;
|
||||
}
|
||||
return `${f.fieldName} = ${productPatternToString(f.pattern)}`;
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue