Skip to content

Commit 3a224af

Browse files
committed
Refactored lexer methods and removed JUST_0 and JUST_1.
1 parent f4f2715 commit 3a224af

File tree

7 files changed

+59
-101
lines changed

7 files changed

+59
-101
lines changed

Diff for: lex-utils.ts

+7-5
Original file line numberDiff line numberDiff line change
@@ -11,10 +11,7 @@ export function lexKeyword(s: string, search: string, state: LexState) {
1111
}
1212

1313
export function lexNumber(s: string, state: LexState) {
14-
//If it's a key
15-
if (s[state.cursor] == "0") {
16-
return;
17-
}
14+
let firstNum = s[state.cursor];
1815

1916
let num = "";
2017

@@ -23,6 +20,11 @@ export function lexNumber(s: string, state: LexState) {
2320
state.cursor++;
2421
}
2522

23+
//Number should only start with 0 if it's 0
24+
if (firstNum == "0" && parseInt(num) != 0) {
25+
throw new Error("Please remove any leading 0s");
26+
}
27+
2628
return parseInt(num);
2729
}
2830

@@ -40,4 +42,4 @@ export function lexString(s: string, state: LexState) {
4042
}
4143

4244
return str;
43-
}
45+
}

Diff for: lexer.ts

+48-42
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,6 @@ export default class Lexer {
3131
this.wrapperTokens = wrappers as TokenClass[];
3232
}
3333

34-
//TODO: Cleanup
3534
lex(miniscriptString: string) {
3635
let tokens: Token[] = [];
3736

@@ -40,55 +39,62 @@ export default class Lexer {
4039
};
4140

4241
while (lexState.cursor != miniscriptString.length) {
43-
let node: Token | undefined = undefined;
42+
tokens.push(...this.parseWrappers(lexState, miniscriptString));
43+
tokens.push(
44+
this.parseToken(miniscriptString, lexState, this.tokenClasses)
45+
);
46+
}
4447

45-
let colonIndex = 0;
48+
return tokens;
49+
}
4650

47-
for (let i = lexState.cursor; i < miniscriptString.length; i++) {
48-
if (miniscriptString[i] == ":") {
49-
colonIndex = i;
50-
break;
51-
}
52-
if (miniscriptString[i] < "a" || miniscriptString[i] > "z") break;
53-
}
51+
private parseWrappers(lexState: LexState, miniscriptString: string) {
52+
let colonIndex = 0;
53+
let tokens: Token[] = [];
5454

55-
for (let i = lexState.cursor; i < colonIndex; i++) {
56-
for (let tokenClass of this.wrapperTokens) {
57-
node = tokenClass.lex(miniscriptString, lexState);
58-
if (node) {
59-
tokens.push(node);
60-
break;
61-
}
62-
}
63-
64-
if (node == undefined) {
65-
let errorDescription = `Invalid wrapper token found at position ${lexState.cursor}: `;
66-
let errorMessage = `\n${errorDescription}${miniscriptString.substring(
67-
lexState.cursor
68-
)}\n`;
69-
errorMessage += `${" ".repeat(errorDescription.length)}~`;
70-
throw new Error(errorMessage);
71-
}
55+
for (let i = lexState.cursor; i < miniscriptString.length; i++) {
56+
if (miniscriptString[i] == ":") {
57+
colonIndex = i;
58+
break;
7259
}
60+
if (miniscriptString[i] < "a" || miniscriptString[i] > "z") break;
61+
}
7362

74-
for (let tokenClass of this.tokenClasses) {
75-
node = tokenClass.lex(miniscriptString, lexState);
76-
if (node) {
77-
tokens.push(node);
78-
break;
79-
}
80-
}
63+
if (!colonIndex) {
64+
return [];
65+
}
8166

82-
if (node == undefined) {
83-
let errorDescription = `Invalid token found at position ${lexState.cursor}: `;
84-
let errorMessage = `\n${errorDescription}${miniscriptString.substring(
85-
lexState.cursor
86-
)}\n`;
87-
errorMessage += `${" ".repeat(errorDescription.length)}~`;
88-
throw new Error(errorMessage);
89-
}
67+
for (let i = lexState.cursor; i < colonIndex; i++) {
68+
tokens.push(
69+
this.parseToken(miniscriptString, lexState, this.wrapperTokens)
70+
);
9071
}
9172

9273
return tokens;
9374
}
75+
76+
private parseToken(
77+
miniscriptString: string,
78+
lexState: LexState,
79+
tokenClasses: TokenClass[]
80+
): Token {
81+
let token: Token | undefined;
82+
for (let tokenClass of tokenClasses) {
83+
token = tokenClass.lex(miniscriptString, lexState);
84+
if (token) {
85+
return token;
86+
}
87+
}
88+
89+
throw this.lexError(miniscriptString, lexState.cursor);
90+
}
91+
92+
private lexError(miniscriptString: string, cursor: number) {
93+
let errorDescription = `Invalid token found at position ${cursor}: `;
94+
let errorMessage = `\n${errorDescription}${miniscriptString.substring(
95+
cursor
96+
)}\n`;
97+
errorMessage += `${" ".repeat(errorDescription.length)}~`;
98+
return new Error(errorMessage);
99+
}
94100
}

Diff for: modules/bitcoin-miniscript/fragments/JUST_1.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ export class JUST_1
2222

2323
static lex = (s: string, state: LexState): Token | undefined => {
2424
let position = state.cursor;
25-
if (s[state.cursor] == "1" && isNaN(parseInt(s[state.cursor + 1]))) {
25+
if (isNaN(parseInt(s[state.cursor + 1])) && lexKeyword(s, "1", state)) {
2626
return {
2727
tokenType: this.tokenType,
2828
position,

Diff for: modules/bitcoin-miniscript/fragments/KEY.ts

-42
This file was deleted.

Diff for: modules/bitcoin-miniscript/fragments/MULTI.ts

+3-3
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { CLOSE_PAREN, COMMA, NUMBER } from "../../../universal-tokens";
1+
import { CLOSE_PAREN, COMMA, NUMBER, STRING } from "../../../universal-tokens";
22
import { lexKeyword } from "../../../lex-utils";
33
import { sanityCheck, Types } from "../../../miniscript-types";
44
import {
@@ -8,7 +8,6 @@ import {
88
Token,
99
} from "../../../types";
1010
import { ParseContext } from "../../../parser";
11-
import { KEY } from "./KEY";
1211
import { PK_K } from "./PK_K";
1312

1413
export class MULTI
@@ -45,7 +44,8 @@ export class MULTI
4544

4645
while (parseContext.peekToken().tokenType != CLOSE_PAREN.tokenType) {
4746
parseContext.eat(COMMA.tokenType);
48-
let key = parseContext.eat(KEY.tokenType);
47+
//TODO: Add key validation with key validator passed into parser
48+
let key = parseContext.eat(STRING.tokenType);
4949
// multi can only be used on pre-taproot keys
5050
children.push(new PK_K(key?.value, false));
5151
}

Diff for: modules/bitcoin-miniscript/fragments/PK_K.ts

-1
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@ import {
88
Token,
99
} from "../../../types";
1010
import { ParseContext } from "../../../parser";
11-
import { KEY } from "./KEY";
1211

1312
export class PK_K
1413
extends MiniscriptFragmentStatic

Diff for: modules/bitcoin-miniscript/index.ts

-7
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@ import { HASH160 } from "./fragments/HASH160";
77
import { HASH256 } from "./fragments/HASH256";
88
import { JUST_0 } from "./fragments/JUST_0";
99
import { JUST_1 } from "./fragments/JUST_1";
10-
import { KEY } from "./fragments/KEY";
1110
import { MULTI } from "./fragments/MULTI";
1211
import { OLDER } from "./fragments/OLDER";
1312
import { OR_B } from "./fragments/OR_B";
@@ -52,12 +51,6 @@ export default {
5251
AND_V,
5352
HASH160,
5453
HASH256,
55-
//TODO: Change key lexing to not look for strings starting with 0
56-
//TODO: Also update lexNumber; it has related logic
57-
//Must come before JUST_0 because of temporary lex rules
58-
KEY,
59-
JUST_0,
60-
JUST_1,
6154
MULTI,
6255
OLDER,
6356
OR_B,

0 commit comments

Comments
 (0)