parser stuff

This commit is contained in:
sfja 2025-01-27 23:57:27 +01:00
parent 48e95bdef5
commit c92fce8ccb
5 changed files with 1168 additions and 46 deletions

View File

@ -22,7 +22,8 @@ export type StmtKind =
export type ItemStmt = { item: Item };
export type LetStmt = {
subject: Pat;
pat: Pat;
ty: Ty;
expr?: Expr;
};
@ -56,11 +57,18 @@ export type ItemKind =
| { tag: "use" } & UseItem
| { tag: "type_alias" } & TypeAliasItem;
export type ModBlockItem = { ident: Ident; stmts: Stmt[] };
export type ModFileItem = { ident: Ident; filePath: string };
export type ModBlockItem = { stmts: Stmt[] };
export type ModFileItem = { filePath: string };
export type EnumItem = { variants: Variant[] };
export type StructItem = { data: VariantData };
export type FnItem = { _: 0 };
export type FnItem = {
generics?: Generics;
params: Param[];
returnTy?: Ty;
body: Block;
};
export type UseItem = { _: 0 };
export type TypeAliasItem = { ty: Ty };
@ -92,6 +100,21 @@ export type FieldDef = {
span: Span;
};
export type Param = {
pat: Pat;
ty: Ty;
span: Span;
};
export type Generics = {
params: GenericParam[];
};
export type GenericParam = {
ident: Ident;
span: Span;
};
export type Expr = {
kind: ExprKind;
span: Span;
@ -129,7 +152,7 @@ export type StringExpr = { value: string };
export type GroupExpr = { expr: Expr };
export type ArrayExpr = { exprs: Expr[] };
export type RepeatExpr = { expr: Expr; length: Expr };
export type StructExpr = { path?: Path; field: ExprField[] };
export type StructExpr = { path?: Path; fields: ExprField[] };
export type RefExpr = { expr: Expr; refType: RefType; mut: boolean };
export type DerefExpr = { expr: Expr };
export type ElemExpr = { expr: Expr; elem: number };
@ -137,8 +160,8 @@ export type FieldExpr = { expr: Expr; ident: Ident };
export type IndexExpr = { expr: Expr; index: Expr };
export type CallExpr = { expr: Expr; args: Expr[] };
export type UnaryExpr = { unaryType: UnaryType; expr: Expr };
export type BinaryExpr = { unaryType: UnaryType; left: Expr; right: Expr };
export type IfExpr = { cond: Expr; truthy: Block; falsy?: Block };
export type BinaryExpr = { binaryType: BinaryType; left: Expr; right: Expr };
export type IfExpr = { cond: Expr; truthy: Block; falsy?: Expr };
export type LoopExpr = { body: Block };
export type WhileExpr = { cond: Expr; body: Block };
export type ForExpr = { pat: Pat; expr: Expr; body: Block };

View File

@ -12,6 +12,10 @@ export type Pos = {
col: number;
};
export const Span = {
fromto: ({ begin }: Span, { end }: Span): Span => ({ begin, end }),
} as const;
export type Report = {
severity: "fatal" | "error" | "warning" | "info";
origin?: string;
@ -31,43 +35,82 @@ function severityColor(severity: "fatal" | "error" | "warning" | "info") {
return "\x1b[1m\x1b[33m";
case "info":
return "\x1b[1m\x1b[34m";
}
exhausted(severity)
}
exhausted(severity);
}
export function prettyPrintReport(ctx: Ctx, rep: Report) {
const { severity, msg } = rep;
const origin = rep.origin ? `\x1b[1m${rep.origin}:\x1b[0m ` : "";
console.error(`${origin}${severityColor(severity)}${severity}:\x1b[0m \x1b[37m${msg}\x1b[0m`);
console.error(
`${origin}${
severityColor(severity)
}${severity}:\x1b[0m \x1b[37m${msg}\x1b[0m`,
);
if (rep.file && (rep.span || rep.pos)) {
const errorLineOffset = 2
const errorLineOffset = 2;
const { absPath: path } = ctx.fileInfo(rep.file);
const { line, col } = rep.span?.begin ?? rep.pos!;
console.error(` --> ./${path}:${line}:${col}`);
if (rep.span) {
const spanLines = ctx.fileSpanText(rep.file, rep.span).split("\n");
spanLines.pop()
spanLines.pop();
if (spanLines.length == 1) {
console.error(`${rep.span.begin.line.toString().padStart(4, ' ')}| ${spanLines[0]}`);
console.error(` | ${severityColor(severity)}${" ".repeat(rep.span.begin.col)}${"~".repeat(rep.span.end.col-rep.span.begin.col)}\x1b[0m`)
return
console.error(
`${rep.span.begin.line.toString().padStart(4, " ")}| ${
spanLines[0]
}`,
);
console.error(
` | ${severityColor(severity)}${
" ".repeat(rep.span.begin.col)
}${
"~".repeat(rep.span.end.col - rep.span.begin.col)
}\x1b[0m`,
);
return;
}
for (let i = 0; i < spanLines.length; i++) {
console.error(`${(rep.span.begin.line+i).toString().padStart(4, ' ')}| ${spanLines[i]}`);
console.error(
`${
(rep.span.begin.line + i).toString().padStart(4, " ")
}| ${spanLines[i]}`,
);
if (i == 0) {
console.error(` | ${" ".repeat(rep.span.begin.col-1)}${severityColor(severity)}${"~".repeat(spanLines[i].length-(rep.span.begin.col-1))}\x1b[0m`)
}
else if (i == spanLines.length-1) {
console.error(` | ${severityColor(severity)}${"~".repeat(rep.span.end.col)}\x1b[0m`)
}
else {
console.error(` | ${severityColor(severity)}${"~".repeat(spanLines[i].length)}\x1b[0m`)
console.error(
` | ${" ".repeat(rep.span.begin.col - 1)}${
severityColor(severity)
}${
"~".repeat(
spanLines[i].length - (rep.span.begin.col - 1),
)
}\x1b[0m`,
);
} else if (i == spanLines.length - 1) {
console.error(
` | ${severityColor(severity)}${
"~".repeat(rep.span.end.col)
}\x1b[0m`,
);
} else {
console.error(
` | ${severityColor(severity)}${
"~".repeat(spanLines[i].length)
}\x1b[0m`,
);
}
}
}
else if (rep.pos) {
console.error(`${rep.pos.line.toString().padStart(4, ' ')}| ${ctx.filePosLineText(rep.file, rep.pos)}`);
console.error(` | ${severityColor(severity)}${" ".repeat(rep.pos.col)}^\x1b[0m`)
} else if (rep.pos) {
console.error(
`${rep.pos.line.toString().padStart(4, " ")}| ${
ctx.filePosLineText(rep.file, rep.pos)
}`,
);
console.error(
` | ${severityColor(severity)}${
" ".repeat(rep.pos.col)
}^\x1b[0m`,
);
}
}
}

File diff suppressed because it is too large Load Diff

View File

@ -1,16 +1,14 @@
import { Span } from "../diagnostics.ts";
export type Token = TokenData & {
export type Token = {
type: string;
span: Span;
length: number;
identValue?: string;
intValue?: number;
stringValue?: string;
};
export type TokenData =
| { type: "ident"; identValue: string }
| { type: "int"; intValue: number }
| { type: "string"; stringValue: string }
| { type: string };
export interface TokenIter {
next(): Token | null;
}
@ -29,4 +27,3 @@ export class SigFilter implements TokenIter {
return token;
}
}

View File

@ -15,6 +15,8 @@ export type Err<E> = { ok: false; val: E };
export const Ok = <V>(val: V): Ok<V> => ({ ok: true, val });
export const Err = <E>(val: E): Err<E> => ({ ok: false, val });
export const Res = { Ok, Err } as const;
export type ControlFlow<
R = undefined,
V = undefined,