Skip to content

Commit

Permalink
fixed SourceView rendering incorrect region
Browse files Browse the repository at this point in the history
  • Loading branch information
AjaniBilby committed May 12, 2024
1 parent e3a6a99 commit 5b1da96
Show file tree
Hide file tree
Showing 3 changed files with 79 additions and 44 deletions.
2 changes: 1 addition & 1 deletion source/compiler/codegen/expression/helper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ export function ResolveLinearType(ctx: Context, type: LinearType, ref: Reference
if (strict) {
const errs = type.getCompositionErrors();
if (errs) {
console.error(`Unable to compose value due to some arguments being uninitialized since:\n`
console.error(`Unable to compose value due to some arguments being uninitialized since: ${errs.map(x => x.start.toString()).join(", ")}\n`
+ errs.map(x => SourceView(ctx.file.path, ctx.file.name, x, true)).join("")
+ SourceView(ctx.file.path, ctx.file.name, ref, false)
);
Expand Down
107 changes: 64 additions & 43 deletions source/parser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,57 +47,78 @@ function RemapRefRange(syntax: SyntaxNode) {


export function SourceView(path: string, name: string, range: ReferenceRange, compact?: boolean) {
const source = ReadByteRange(path, range.start.index-200, range.end.index+200);
if (source === null) return `${name}: ${range.toString()}\n`;

const begin = ExtractLine(source, range.start).replace(/\t/g, " ");
let body = "";

if (range.start.line === range.end.line) {
const margin = ` ${range.start.line} | `;

const trimmed = begin.trim();
const trimDiff = begin.length - trimmed.length;

const underline = "\n"
+ " ".repeat(margin.length + range.start.col - trimDiff)
+ "^".repeat(Math.max(1, range.end.col - range.start.col));

body = margin + trimmed + underline;
} else {
const eLine = " " + range.end.line.toString();
const sLine = range.start.line.toString().padStart(eLine.length, " ");

const finish = ExtractLine(source, range.end).replace(/\t/g, " ");;

body = sLine + " | " + begin + "\n"
+ eLine + " | " + finish;
}

body += compact ? "\n" : `\n ${name}: ${range.toString()}\n`;

return body;
return range.start.line == range.end.line
? SingleLine(path, name, range, compact)
: MultiLine(path, name, range, compact);
}

function ExtractLine(source: string, ref: Reference) {
const begin = FindNewLine(source, ref.index, -1);
const end = FindNewLine(source, ref.index, 1);

return source.slice(begin, end);
function SingleLine(path: string, name: string, range: ReferenceRange, compact?: boolean) {
const offset = Math.max(0, range.start.index - 200);
const slice = ReadByteRange(path, offset, range.end.index+200);
if (slice === null) return `${name}: ${range.toString()}\n`;

let s = slice.lastIndexOf("\n", range.start.index-offset);
if (s === -1) s = 0;
let e = slice.indexOf("\n", range.end.index-offset);
if (e === -1) e = slice.length;

let line = slice.slice(s, e).trimEnd();
let pad = line.length;
line = line.trimStart();
pad -= line.length;

const margin = `${range.start.line} │ `;
const underline = "\n"
+ " ".repeat(margin.length + range.start.col - pad)
+ "^".repeat(Math.max(1, range.end.col - range.start.col))
+ "\n";

const body = margin + line + underline;
return compact ? body : ` ${name}: ${range.toString()}\n`;
}

function FindNewLine(source: string, index: number, step: number) {
index += step;

while (index >= 0 && index < source.length && source[index] !== "\n") {
index += step;
function MultiLine(path: string, name: string, range: ReferenceRange, compact?: boolean) {
const offset = Math.max(0, range.start.index - 200);
const slice = ReadByteRange(path, offset, range.end.index+200);
if (slice === null) return `${name}: ${range.toString()}\n`;

let s = slice.lastIndexOf("\n", range.start.index-offset);
if (s === -1) s = 0;
else s ++;
let e = slice.indexOf("\n", range.end.index-offset);
if (e === -1) e = slice.length;

const lines = slice.slice(s, e).split("\n");
const digits = Math.floor(Math.log10(range.end.line)) + 1;

let maxLen = 0;
function RenderLine(line: string, lnOff: number,) {
const ln = lnOff + range.start.line;
const src = line.replaceAll("\t", " ");
maxLen = Math.max(src.length, maxLen);
return ` ${ln.toString().padStart(digits, " ")}${src}\n`;
}

if (source[index] === "\n") {
index -= step;
let body = "";
if (lines.length <= 5) {
body += lines.map(RenderLine).join("\n");
} else {
let begin = "";
for (let i=0; i<2; i++) {
begin += RenderLine(lines[i], i);
}

let end = "";
for (let i=lines.length-2; i<lines.length; i++) {
end += RenderLine(lines[i], i);
}

body += begin
+ ` ${" ".repeat(digits)}${"░".repeat(maxLen+3)}\n`
+ end;
}

return Math.max(index, 0);
return compact ? body : body + ` ${name}: ${range.toString()}\n`;
}


Expand Down
14 changes: 14 additions & 0 deletions tools/vscode-extension/syntaxes/salient.tmLanguage.json
Original file line number Diff line number Diff line change
Expand Up @@ -210,6 +210,7 @@
{ "include": "#declare" },
{ "include": "#assign" },
{ "include": "#return" },
{ "include": "#lift" },

{ "include": "#expression" }
]
Expand Down Expand Up @@ -341,6 +342,19 @@
},


"lift": {
"begin": "\\b(lift)\\s*",
"beginCaptures": {
"1": { "name": "keyword.control.lift" }
},
"end": "(;)",
"endCaptures": {
"1": { "name": "punctuation.terminator.statement" }
},
"patterns": [
{ "include": "#expression" }
]
},
"return": {
"begin": "\\b(return(_tail)?)\\s*",
"beginCaptures": {
Expand Down

0 comments on commit 5b1da96

Please sign in to comment.