-
Notifications
You must be signed in to change notification settings - Fork 0
/
index.ts
70 lines (60 loc) · 2.54 KB
/
index.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
// IMPORTS
// ================================================================================================
import { StarkLimits } from '@guildofweavers/air-script';
import { lexer } from './lib/lexer';
import { parser } from './lib/parser';
import { visitor } from './lib/visitor';
import { AirObject, AirConfig } from './lib/AirObject';
import { AirScriptError } from './lib/errors';
import { isPowerOf2 } from './lib/utils';
// MODULE VARIABLES
// ================================================================================================
const DEFAULT_LIMITS: StarkLimits = {
maxSteps : 2**20,
maxMutableRegisters : 64,
maxReadonlyRegisters : 64,
maxConstraintCount : 1024,
maxConstraintDegree : 16,
maxExtensionFactor : 32
};
// PUBLIC FUNCTIONS
// ================================================================================================
export function parseScript(text: string, limits?: Partial<StarkLimits>, extensionFactor?: number): AirObject {
// apply defaults
limits = {...DEFAULT_LIMITS, ...limits};
// tokenize input
const lexResult = lexer.tokenize(text);
if(lexResult.errors.length > 0) {
throw new AirScriptError(lexResult.errors);
}
// apply grammar rules
parser.input = lexResult.tokens;
const cst = parser.script();
if (parser.errors.length > 0) {
throw new AirScriptError(parser.errors);
}
// build STARK config
try {
const airConfig: AirConfig = visitor.visit(cst, limits);
const air = new AirObject(airConfig, extensionFactor);
validateExtensionFactor(air.extensionFactor, air.maxConstraintDegree, limits.maxExtensionFactor!);
return air;
}
catch (error) {
throw new AirScriptError([error]);
}
}
// HELPER FUNCTIONS
// ================================================================================================
function validateExtensionFactor(extensionFactor: number, maxConstraintDegree: number, maxExtensionFactor: number) {
const minExtensionFactor = 2**Math.ceil(Math.log2(maxConstraintDegree * 2));
if (extensionFactor > maxExtensionFactor || !Number.isInteger(extensionFactor)) {
throw new TypeError(`Extension factor must be an integer smaller than or equal to ${maxExtensionFactor}`);
}
if (!isPowerOf2(extensionFactor)) {
throw new TypeError(`Extension factor must be a power of 2`);
}
if (extensionFactor < minExtensionFactor) {
throw new TypeError(`Extension factor must be at ${minExtensionFactor}`);
}
}