Skip to content

Commit

Permalink
fix multiple issues with param and take
Browse files Browse the repository at this point in the history
  • Loading branch information
SiriusAshling committed Feb 22, 2022
1 parent a7bf521 commit 13af70f
Show file tree
Hide file tree
Showing 5 changed files with 77 additions and 22 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"name": "header-language",
"displayName": "Ori WotW Header Language",
"description": "Support for the .wotwrh language",
"version": "0.4.1",
"version": "0.4.2",
"publisher": "orirando",
"license": "MIT",
"repository": {
Expand Down
2 changes: 1 addition & 1 deletion src/diagnostics.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ function errorMessage(parseFailure: ParseFailure): string {
}

export function diagnose(document: vscode.TextDocument, parseFailure: ParseFailure): vscode.Diagnostic | undefined {
const position = document.positionAt(parseFailure.status.offset);
const position = document.positionAt(parseFailure.status.offsetInSource());
let range = document.getWordRangeAtPosition(position);
if (range === undefined) { range = new vscode.Range(position, position); }

Expand Down
91 changes: 72 additions & 19 deletions src/parser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -84,27 +84,50 @@ export interface Parameter {
export class ParseStatus {
remaining: string;
offset: number;
lengthChanges: [number, number][];
parameters: Parameter[];
pool: string[];

constructor(input: string, offset: number = 0, parameters: Parameter[] = []) {
constructor(input: string, offset: number = 0, lengthChanges: [number, number][] = [], parameters: Parameter[] = [], pool: string[] = []) {
this.remaining = input;
this.offset = offset;
this.lengthChanges = lengthChanges;
this.parameters = parameters;
this.pool = pool;
}

progress(offset: number) {
this.remaining = this.remaining.slice(offset);
this.offset += offset;
}

take(): string | undefined {
if (this.pool.length === 0) { return undefined; }
const index = Math.floor(Math.random() * this.pool.length);
return this.pool.splice(index, 1)[0];
}

clone(): ParseStatus {
return new ParseStatus(this.remaining, this.offset, this.parameters);
return new ParseStatus(this.remaining, this.offset, this.lengthChanges, this.parameters, this.pool);
}

replaceWith(other: ParseStatus) {
this.remaining = other.remaining;
this.offset = other.offset;
this.lengthChanges = other.lengthChanges;
this.parameters = other.parameters;
this.pool = other.pool;
}

offsetInSource(): number {
let offset = this.offset;
for (const [changeOffset, delta] of this.lengthChanges) {
if (this.offset >= changeOffset) {
offset += delta;
// offset = Math.max(offset + delta, changeOffset);
} else { break; }
}
return offset;
}
}

Expand Down Expand Up @@ -260,27 +283,57 @@ function parsePickup(status: ParseStatus): ParsePickupSuccess | ParseFailure {
return succeed(pickup);
}

// TODO pool interpolation
function preprocessLine(status: ParseStatus): ParseFailure | undefined {
while (true) {
let hasMatch;
do {
hasMatch = false;
const remaining = status.remaining;

const match = remaining.match(/\$PARAM\((.*?)\)|\n|\r/);
if (match === null) { return undefined; }

const identifier = match[1];
const index = match.index;
if (identifier === undefined || index === undefined) { return undefined; }

const value = status.parameters.find(param => param.identifier === identifier)?.defaultValue;
if (value === undefined) {
const errorStatus = status.clone();
errorStatus.offset += index + 7;
return fail(Token.parameter, errorStatus, undefined);
const paramMatch = remaining.match(/\$PARAM\((.*?)\)|\n|\r/);
if (paramMatch !== null) {
const identifier = paramMatch[1];
const index = paramMatch.index;
if (identifier !== undefined && index !== undefined) {
hasMatch = true;

const value = status.parameters.find(param => param.identifier === identifier)?.defaultValue;
if (value === undefined) {
const errorStatus = status.clone();
errorStatus.offset += index + 7;
return fail(Token.parameter, errorStatus, undefined);
}
const valueString = value.toString();

const paramMatchLength = paramMatch[0].length;
const lengthChange: [number, number] = [status.offset + index, paramMatchLength - valueString.length];
status.lengthChanges.push(lengthChange);

status.remaining = remaining.slice(0, index) + valueString + remaining.slice(index + paramMatchLength);
}
}

status.remaining = remaining.slice(0, index) + value + remaining.slice(index + match[0].length);
}
const takeMatch = remaining.match(/(!!take)|\n|\r/);
if (takeMatch !== null) {
const take = takeMatch[1];
const index = takeMatch.index;
if (take !== undefined && index !== undefined) {
hasMatch = true;

const value = status.take();
if (value === undefined) {
const errorStatus = status.clone();
errorStatus.offset += index + 2;
return fail("!!pool before !!take", errorStatus, undefined);
}
const valueString = value.toString();

const takeMatchLength = 6;
const lengthChange: [number, number] = [status.offset + index, takeMatchLength - valueString.length];
status.lengthChanges.push(lengthChange);

status.remaining = remaining.slice(0, index) + valueString + remaining.slice(index + takeMatchLength);
}
}
} while (hasMatch);
}

type ParseLineSuccess = ParseSuccess<Line>;
Expand Down
2 changes: 2 additions & 0 deletions src/parser/parseCommand.ts
Original file line number Diff line number Diff line change
Expand Up @@ -179,6 +179,8 @@ function parsePoolCommand(status: ParseStatus): ParseCommandSuccess | ParseFailu
const poolItem = parseRemainingLine(status);
if (poolItem === null) { return fail(Token.text, status, undefined); }

status.pool.push(poolItem);

const command: Command = {
id: CommandVariant.pool,
poolItem,
Expand Down
2 changes: 1 addition & 1 deletion syntaxes/ori-wotw-header.tmLanguage.json
Original file line number Diff line number Diff line change
Expand Up @@ -179,7 +179,7 @@
}
},
"createWarp": {
"match": "\\G(4\\|22\\|)(\\d+\\|-?\\d+(?:[.,]\\d+)?\\|-?\\d+(?:[.,]\\d+)?)(\\|[^\\s]+)?\\b",
"match": "\\G(4\\|22\\|)(\\d+\\|-?\\d+(?:[.,]\\d+)?\\|-?\\d+(?:[.,]\\d+)?)(\\|[^$|(?=//)]+)?\\b",
"captures": {
"1": { "name": "variable.other.enummember" },
"2": { "name": "variable" },
Expand Down

0 comments on commit 13af70f

Please sign in to comment.