-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathtokeniser.ts
127 lines (123 loc) · 2.97 KB
/
tokeniser.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
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
import { Token, TokenType } from "./Types";
import { isAlpha, isNumber, isNumericalLiteral, isFunction } from "./Utils";
export function tokenizer(expression: string): Token[] {
let tokens: Token[] = [];
let length: number = expression.length;
let buffer: string = "";
let count = 0;
while (count < length) {
let current: Token;
switch (expression[count]) {
case " ":
count++;
break;
case "\t":
count++;
break;
case "\n":
count++;
break;
case "(":
current = {
type: TokenType.LeftParenthesis,
value: expression[count],
};
tokens.push(current);
count++;
break;
case ")":
current = {
type: TokenType.RightParenthesis,
value: expression[count],
};
tokens.push(current);
count++;
break;
case "+":
case "%":
case "/":
current = {
type: TokenType.Binary,
value: expression[count],
};
tokens.push(current);
count++;
break;
case "^":
current = {
type: TokenType.Binary,
value: "**",
};
tokens.push(current);
count++;
break;
case "*":
if (expression[count + 1] == "*") {
current = {
type: TokenType.Binary,
value: "**",
};
tokens.push(current);
count += 2;
} else {
current = {
type: TokenType.Binary,
value: "*",
};
tokens.push(current);
count++;
}
break;
case "-":
current = {
type: TokenType.Minus,
value: expression[count],
};
tokens.push(current);
count++;
break;
case "!":
current = {
type: TokenType.Unary,
value: expression[count],
};
tokens.push(current);
count++;
break;
default:
if (isNumber(expression[count])) {
while (isNumber(expression[count])) {
buffer += expression[count];
count++;
}
let current = {
type: TokenType.Number,
value: buffer,
};
tokens.push(current);
buffer = "";
} else if (isAlpha(expression[count])) {
while (isAlpha(expression[count])) {
buffer += expression[count];
count++;
}
if (isFunction(buffer)) {
current = {
type: TokenType.Unary,
value: buffer,
};
} else if (buffer == "pi") {
current = {
type: TokenType.Number,
value: Math.PI.toString(),
};
} else {
throw new Error(`Unknown operation: ${buffer}`);
}
tokens.push(current);
buffer = "";
} else count++;
}
}
return tokens;
}