77 lines
1.6 KiB
TypeScript
77 lines
1.6 KiB
TypeScript
import './style.css'
|
|
import { SourceText, SourceRegion, sourceText } from 'source-region';
|
|
import type { SourceLocation, Span } from 'source-region';
|
|
|
|
|
|
type Expr =
|
|
| { tag: "literal", value: Literal }
|
|
| { tag: "list", values: Expr[] }
|
|
|
|
namespace Expr {
|
|
export function number(value: number): Expr {
|
|
return { tag: "literal", value: { tag: "number", value } };
|
|
}
|
|
export function identifier(value: Identifier): Expr {
|
|
return { tag: "literal", value: { tag: "identifier", value } };
|
|
}
|
|
export function list(values: Expr[]): Expr {
|
|
return { tag: "list", values };
|
|
}
|
|
|
|
export function show(e: Expr): string {
|
|
switch (e.tag) {
|
|
case "literal":
|
|
return showLiteral(e.value);
|
|
case "list":
|
|
return `(${e.values.map(show).join(" ")})`;
|
|
}
|
|
}
|
|
|
|
function showLiteral(e: Literal): string {
|
|
switch (e.tag) {
|
|
case "number":
|
|
return `${e.value}`;
|
|
case "identifier":
|
|
return `${e.value}`;
|
|
}
|
|
}
|
|
}
|
|
|
|
type Literal =
|
|
| { tag: "number", value: number }
|
|
| { tag: "identifier", value: Identifier }
|
|
|
|
type Identifier = string
|
|
|
|
|
|
// === Examples ===
|
|
|
|
function example00() {
|
|
const v: Expr = Expr.list([Expr.identifier("f"), Expr.number(123), Expr.number(512)]);
|
|
console.log(v);
|
|
console.log(Expr.show(v));
|
|
}
|
|
|
|
function example01() {
|
|
const str = `hello, world!
|
|
foo
|
|
bar `;
|
|
|
|
const source = sourceText(str);
|
|
const region = source.fullRegion();
|
|
|
|
console.log(region);
|
|
console.log(region.lineCount);
|
|
region.forEachLine((span, lineNo) => {
|
|
console.log(lineNo, region.stringOf(span));
|
|
});
|
|
}
|
|
|
|
[
|
|
example00,
|
|
example01,
|
|
].forEach((f, i) => {
|
|
console.log(`====${i}===`);
|
|
f();
|
|
})
|
|
|