bobe 0.0.37 → 0.0.39
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/bobe.cjs.js +96 -35
- package/dist/bobe.cjs.js.map +1 -1
- package/dist/bobe.compiler.cjs.js +96 -35
- package/dist/bobe.compiler.cjs.js.map +1 -1
- package/dist/bobe.compiler.esm.js +97 -36
- package/dist/bobe.compiler.esm.js.map +1 -1
- package/dist/bobe.esm.js +97 -36
- package/dist/bobe.esm.js.map +1 -1
- package/dist/index.d.ts +20 -8
- package/dist/index.umd.js +96 -35
- package/dist/index.umd.js.map +1 -1
- package/package.json +3 -3
package/dist/index.d.ts
CHANGED
|
@@ -133,7 +133,12 @@ declare enum TokenType {
|
|
|
133
133
|
InsertionExp = 128,
|
|
134
134
|
Semicolon = 256,
|
|
135
135
|
/** 仅编译时可解析 */
|
|
136
|
-
StaticInsExp = 512
|
|
136
|
+
StaticInsExp = 512,
|
|
137
|
+
String = 1024,
|
|
138
|
+
Number = 2048,
|
|
139
|
+
Boolean = 4096,
|
|
140
|
+
Null = 8192,
|
|
141
|
+
Undefined = 16384
|
|
137
142
|
}
|
|
138
143
|
declare enum FakeType {
|
|
139
144
|
If = 1,
|
|
@@ -182,13 +187,15 @@ declare enum ParseErrorCode {
|
|
|
182
187
|
INDENT_MISMATCH = 9005,
|
|
183
188
|
MISSING_ASSIGN = 9006,
|
|
184
189
|
INVALID_TAG_NAME = 9007,
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
190
|
+
INVALID_PROP_KEY = 9008,
|
|
191
|
+
ELSE_WITHOUT_IF = 9009,
|
|
192
|
+
EMPTY_IF_BODY = 9010,
|
|
193
|
+
EMPTY_FOR_BODY = 9011,
|
|
194
|
+
MISSING_FOR_COLLECTION = 9012,
|
|
195
|
+
MISSING_FOR_SEMICOLON = 9013,
|
|
196
|
+
MISSING_FOR_ITEM = 9014,
|
|
197
|
+
MISSING_PROP_ASSIGNMENT = 9015,
|
|
198
|
+
PIPE_IN_WRONG_CONTEXT = 9016
|
|
192
199
|
}
|
|
193
200
|
type ParseError = {
|
|
194
201
|
code: ParseErrorCode;
|
|
@@ -360,6 +367,7 @@ type ASTNodeType = NodeType;
|
|
|
360
367
|
interface BaseNode {
|
|
361
368
|
type: ASTNodeType;
|
|
362
369
|
loc?: SourceLocation;
|
|
370
|
+
hasError?: boolean;
|
|
363
371
|
}
|
|
364
372
|
interface Program extends BaseNode {
|
|
365
373
|
type: NodeType.Program;
|
|
@@ -467,6 +475,10 @@ declare class Compiler {
|
|
|
467
475
|
* 根据值类型创建属性 key 节点
|
|
468
476
|
*/
|
|
469
477
|
parsePropertyKey(node?: PropertyKeyNode): PropertyKeyNode;
|
|
478
|
+
/**
|
|
479
|
+
* 根据值类型创建属性值节点
|
|
480
|
+
*/
|
|
481
|
+
parseJsExp(node?: PropertyValue): PropertyValue;
|
|
470
482
|
/**
|
|
471
483
|
* 根据值类型创建属性值节点
|
|
472
484
|
*/
|
package/dist/index.umd.js
CHANGED
|
@@ -15,8 +15,15 @@
|
|
|
15
15
|
TokenType[TokenType["InsertionExp"] = 128] = "InsertionExp";
|
|
16
16
|
TokenType[TokenType["Semicolon"] = 256] = "Semicolon";
|
|
17
17
|
TokenType[TokenType["StaticInsExp"] = 512] = "StaticInsExp";
|
|
18
|
+
TokenType[TokenType["String"] = 1024] = "String";
|
|
19
|
+
TokenType[TokenType["Number"] = 2048] = "Number";
|
|
20
|
+
TokenType[TokenType["Boolean"] = 4096] = "Boolean";
|
|
21
|
+
TokenType[TokenType["Null"] = 8192] = "Null";
|
|
22
|
+
TokenType[TokenType["Undefined"] = 16384] = "Undefined";
|
|
18
23
|
return TokenType;
|
|
19
24
|
}({});
|
|
25
|
+
const BaseTokenType = TokenType.String | TokenType.Number | TokenType.Boolean | TokenType.Null | TokenType.Undefined;
|
|
26
|
+
const ValueTokenType = BaseTokenType | TokenType.InsertionExp | TokenType.StaticInsExp;
|
|
20
27
|
let FakeType = function (FakeType) {
|
|
21
28
|
FakeType[FakeType["If"] = 1] = "If";
|
|
22
29
|
FakeType[FakeType["Fail"] = 2] = "Fail";
|
|
@@ -52,13 +59,15 @@
|
|
|
52
59
|
ParseErrorCode[ParseErrorCode["INDENT_MISMATCH"] = 9005] = "INDENT_MISMATCH";
|
|
53
60
|
ParseErrorCode[ParseErrorCode["MISSING_ASSIGN"] = 9006] = "MISSING_ASSIGN";
|
|
54
61
|
ParseErrorCode[ParseErrorCode["INVALID_TAG_NAME"] = 9007] = "INVALID_TAG_NAME";
|
|
55
|
-
ParseErrorCode[ParseErrorCode["
|
|
56
|
-
ParseErrorCode[ParseErrorCode["
|
|
57
|
-
ParseErrorCode[ParseErrorCode["
|
|
58
|
-
ParseErrorCode[ParseErrorCode["
|
|
59
|
-
ParseErrorCode[ParseErrorCode["
|
|
60
|
-
ParseErrorCode[ParseErrorCode["
|
|
61
|
-
ParseErrorCode[ParseErrorCode["
|
|
62
|
+
ParseErrorCode[ParseErrorCode["INVALID_PROP_KEY"] = 9008] = "INVALID_PROP_KEY";
|
|
63
|
+
ParseErrorCode[ParseErrorCode["ELSE_WITHOUT_IF"] = 9009] = "ELSE_WITHOUT_IF";
|
|
64
|
+
ParseErrorCode[ParseErrorCode["EMPTY_IF_BODY"] = 9010] = "EMPTY_IF_BODY";
|
|
65
|
+
ParseErrorCode[ParseErrorCode["EMPTY_FOR_BODY"] = 9011] = "EMPTY_FOR_BODY";
|
|
66
|
+
ParseErrorCode[ParseErrorCode["MISSING_FOR_COLLECTION"] = 9012] = "MISSING_FOR_COLLECTION";
|
|
67
|
+
ParseErrorCode[ParseErrorCode["MISSING_FOR_SEMICOLON"] = 9013] = "MISSING_FOR_SEMICOLON";
|
|
68
|
+
ParseErrorCode[ParseErrorCode["MISSING_FOR_ITEM"] = 9014] = "MISSING_FOR_ITEM";
|
|
69
|
+
ParseErrorCode[ParseErrorCode["MISSING_PROP_ASSIGNMENT"] = 9015] = "MISSING_PROP_ASSIGNMENT";
|
|
70
|
+
ParseErrorCode[ParseErrorCode["PIPE_IN_WRONG_CONTEXT"] = 9016] = "PIPE_IN_WRONG_CONTEXT";
|
|
62
71
|
return ParseErrorCode;
|
|
63
72
|
}({});
|
|
64
73
|
class ParseSyntaxError extends SyntaxError {
|
|
@@ -580,7 +589,7 @@
|
|
|
580
589
|
let nextC;
|
|
581
590
|
while (1) {
|
|
582
591
|
nextC = this.code[this.i + 1];
|
|
583
|
-
if (typeof nextC !== 'string' || !bobeShared.
|
|
592
|
+
if (typeof nextC !== 'string' || !bobeShared.matchId(nextC, 0)) {
|
|
584
593
|
break;
|
|
585
594
|
}
|
|
586
595
|
value += nextC;
|
|
@@ -590,8 +599,30 @@
|
|
|
590
599
|
this.setToken(TokenType.Dedent, '');
|
|
591
600
|
return;
|
|
592
601
|
}
|
|
593
|
-
let realValue
|
|
594
|
-
|
|
602
|
+
let realValue, tokenType;
|
|
603
|
+
switch (value) {
|
|
604
|
+
case 'null':
|
|
605
|
+
realValue = null;
|
|
606
|
+
tokenType = TokenType.Null;
|
|
607
|
+
break;
|
|
608
|
+
case 'undefined':
|
|
609
|
+
realValue = undefined;
|
|
610
|
+
tokenType = TokenType.Undefined;
|
|
611
|
+
break;
|
|
612
|
+
case 'false':
|
|
613
|
+
realValue = false;
|
|
614
|
+
tokenType = TokenType.Boolean;
|
|
615
|
+
break;
|
|
616
|
+
case 'true':
|
|
617
|
+
realValue = true;
|
|
618
|
+
tokenType = TokenType.Boolean;
|
|
619
|
+
break;
|
|
620
|
+
default:
|
|
621
|
+
realValue = value;
|
|
622
|
+
tokenType = TokenType.Identifier;
|
|
623
|
+
break;
|
|
624
|
+
}
|
|
625
|
+
this.setToken(tokenType, realValue);
|
|
595
626
|
}
|
|
596
627
|
str(char) {
|
|
597
628
|
const startOffset = this.preI,
|
|
@@ -617,7 +648,7 @@
|
|
|
617
648
|
}
|
|
618
649
|
value += nextC;
|
|
619
650
|
}
|
|
620
|
-
this.setToken(TokenType.
|
|
651
|
+
this.setToken(TokenType.String, value);
|
|
621
652
|
}
|
|
622
653
|
number(char) {
|
|
623
654
|
let value = char;
|
|
@@ -630,7 +661,7 @@
|
|
|
630
661
|
value += nextC;
|
|
631
662
|
this.next();
|
|
632
663
|
}
|
|
633
|
-
this.setToken(TokenType.
|
|
664
|
+
this.setToken(TokenType.Number, Number(value));
|
|
634
665
|
}
|
|
635
666
|
eof() {
|
|
636
667
|
this.setToken(TokenType.Eof, 'End Of File');
|
|
@@ -909,7 +940,7 @@
|
|
|
909
940
|
let _initProto;
|
|
910
941
|
class Compiler {
|
|
911
942
|
static {
|
|
912
|
-
var _applyDecs$e = _slicedToArray(_applyDecs2311(this, [], [[NodeHook, 2, "parseProgram"], [[NodeHook, NodeLoc], 2, "parseComponentNode"], [[NodeHook, NodeLoc], 2, "parseElementNode"], [[NodeHook, NodeLoc], 2, "parseConditionalNode"], [[NodeHook, NodeLoc], 2, "parseLoopNode"], [NodeHook, 2, "parseProperty"], [[NodeHook, TokenLoc], 2, "parsePropertyKey"], [[NodeHook, TokenLoc], 2, "parsePropertyValue"], [[NodeHook, TokenLoc], 2, "parseName"]]).e, 1);
|
|
943
|
+
var _applyDecs$e = _slicedToArray(_applyDecs2311(this, [], [[NodeHook, 2, "parseProgram"], [[NodeHook, NodeLoc], 2, "parseComponentNode"], [[NodeHook, NodeLoc], 2, "parseElementNode"], [[NodeHook, NodeLoc], 2, "parseConditionalNode"], [[NodeHook, NodeLoc], 2, "parseLoopNode"], [NodeHook, 2, "parseProperty"], [[NodeHook, TokenLoc], 2, "parsePropertyKey"], [[NodeHook, TokenLoc], 2, "parseJsExp"], [[NodeHook, TokenLoc], 2, "parsePropertyValue"], [[NodeHook, TokenLoc], 2, "parseName"]]).e, 1);
|
|
913
944
|
_initProto = _applyDecs$e[0];
|
|
914
945
|
}
|
|
915
946
|
errors = (_initProto(this), []);
|
|
@@ -917,7 +948,10 @@
|
|
|
917
948
|
this.tokenizer = tokenizer;
|
|
918
949
|
this.hooks = hooks;
|
|
919
950
|
}
|
|
920
|
-
addError(code, message, loc) {
|
|
951
|
+
addError(code, message, loc, node) {
|
|
952
|
+
if (node) {
|
|
953
|
+
node.hasError = true;
|
|
954
|
+
}
|
|
921
955
|
this.errors.push({
|
|
922
956
|
code,
|
|
923
957
|
message,
|
|
@@ -1020,7 +1054,7 @@
|
|
|
1020
1054
|
parseElementNode(node) {
|
|
1021
1055
|
const tagToken = this.tokenizer.token;
|
|
1022
1056
|
if (!(tagToken.type & TokenType.Identifier)) {
|
|
1023
|
-
this.addError(ParseErrorCode.INVALID_TAG_NAME, `无效的标签名,期望标识符但得到 "${tagToken.value}"`, tagToken.loc ?? this.tokenizer.emptyLoc());
|
|
1057
|
+
this.addError(ParseErrorCode.INVALID_TAG_NAME, `无效的标签名,期望标识符但得到 "${tagToken.value}"`, tagToken.loc ?? this.tokenizer.emptyLoc(), node);
|
|
1024
1058
|
while (!(this.tokenizer.token.type & TokenType.NewLine) && !this.tokenizer.isEof()) {
|
|
1025
1059
|
this.tokenizer.nextToken();
|
|
1026
1060
|
}
|
|
@@ -1040,7 +1074,7 @@
|
|
|
1040
1074
|
parseConditionalNode(node) {
|
|
1041
1075
|
const keyword = this.tokenizer.token.value;
|
|
1042
1076
|
this.tokenizer.condExp();
|
|
1043
|
-
const condition = this.
|
|
1077
|
+
const condition = this.parseJsExp();
|
|
1044
1078
|
this.tokenizer.nextToken();
|
|
1045
1079
|
this.tokenizer.nextToken();
|
|
1046
1080
|
node.type = keyword === 'if' ? NodeType.If : keyword === 'else' ? NodeType.Else : NodeType.Fail;
|
|
@@ -1053,22 +1087,22 @@
|
|
|
1053
1087
|
parseLoopNode(node) {
|
|
1054
1088
|
const forLoc = this.tokenizer.token.loc ?? this.tokenizer.emptyLoc();
|
|
1055
1089
|
this.tokenizer.nextToken();
|
|
1056
|
-
const collection = this.
|
|
1090
|
+
const collection = this.parseJsExp();
|
|
1057
1091
|
if (!collection.value && collection.value !== 0) {
|
|
1058
|
-
this.addError(ParseErrorCode.MISSING_FOR_COLLECTION, '"for" 缺少集合表达式', forLoc);
|
|
1092
|
+
this.addError(ParseErrorCode.MISSING_FOR_COLLECTION, '"for" 缺少集合表达式', forLoc, node);
|
|
1059
1093
|
}
|
|
1060
1094
|
const semicolonToken = this.tokenizer.nextToken();
|
|
1061
1095
|
if (!(semicolonToken.type & TokenType.Semicolon)) {
|
|
1062
|
-
this.addError(ParseErrorCode.MISSING_FOR_SEMICOLON, '"for" 语法:for <集合>; <item> [index][; key],缺少第一个 ";"', semicolonToken.loc ?? this.tokenizer.emptyLoc());
|
|
1096
|
+
this.addError(ParseErrorCode.MISSING_FOR_SEMICOLON, '"for" 语法:for <集合>; <item> [index][; key],缺少第一个 ";"', semicolonToken.loc ?? this.tokenizer.emptyLoc(), node);
|
|
1063
1097
|
}
|
|
1064
1098
|
const itemToken = this.tokenizer.nextToken();
|
|
1065
1099
|
const isDestruct = itemToken.type === TokenType.InsertionExp;
|
|
1066
1100
|
if (isDestruct) {
|
|
1067
1101
|
itemToken.value = '{' + itemToken.value + '}';
|
|
1068
1102
|
}
|
|
1069
|
-
const item = this.
|
|
1103
|
+
const item = this.parseJsExp();
|
|
1070
1104
|
if (!item.value && item.value !== 0) {
|
|
1071
|
-
this.addError(ParseErrorCode.MISSING_FOR_ITEM, '"for" 缺少 item 变量名', itemToken.loc ?? this.tokenizer.emptyLoc());
|
|
1105
|
+
this.addError(ParseErrorCode.MISSING_FOR_ITEM, '"for" 缺少 item 变量名', itemToken.loc ?? this.tokenizer.emptyLoc(), node);
|
|
1072
1106
|
}
|
|
1073
1107
|
let char = this.tokenizer.peekChar(),
|
|
1074
1108
|
key,
|
|
@@ -1077,16 +1111,16 @@
|
|
|
1077
1111
|
this.tokenizer.nextToken();
|
|
1078
1112
|
if (this.tokenizer.peekChar() !== '\n') {
|
|
1079
1113
|
this.tokenizer.jsExp();
|
|
1080
|
-
key = this.
|
|
1114
|
+
key = this.parseJsExp();
|
|
1081
1115
|
}
|
|
1082
1116
|
} else if (char === '\n') ; else {
|
|
1083
1117
|
this.tokenizer.nextToken();
|
|
1084
|
-
index = this.
|
|
1118
|
+
index = this.parseJsExp();
|
|
1085
1119
|
if (this.tokenizer.peekChar() === ';') {
|
|
1086
1120
|
this.tokenizer.nextToken();
|
|
1087
1121
|
if (this.tokenizer.peekChar() !== '\n') {
|
|
1088
1122
|
this.tokenizer.jsExp();
|
|
1089
|
-
key = this.
|
|
1123
|
+
key = this.parseJsExp();
|
|
1090
1124
|
}
|
|
1091
1125
|
}
|
|
1092
1126
|
}
|
|
@@ -1120,23 +1154,41 @@
|
|
|
1120
1154
|
attributeList() {
|
|
1121
1155
|
const props = [];
|
|
1122
1156
|
while (!(this.tokenizer.token.type & TokenType.NewLine) && !(this.tokenizer.token.type & TokenType.Pipe) && !this.tokenizer.isEof()) {
|
|
1123
|
-
|
|
1157
|
+
const prop = this.parseProperty();
|
|
1158
|
+
if (prop) {
|
|
1159
|
+
props.push(prop);
|
|
1160
|
+
}
|
|
1124
1161
|
}
|
|
1125
1162
|
return props;
|
|
1126
1163
|
}
|
|
1127
1164
|
parseProperty(node) {
|
|
1128
1165
|
node.type = NodeType.Property;
|
|
1129
|
-
|
|
1130
|
-
|
|
1131
|
-
if (token.value === '=') {
|
|
1132
|
-
this.tokenizer.nextToken();
|
|
1133
|
-
node.value = this.parsePropertyValue();
|
|
1166
|
+
if (this.tokenizer.token.type !== TokenType.Identifier) {
|
|
1167
|
+
this.addError(ParseErrorCode.INVALID_PROP_KEY, `属性名 "${this.tokenizer.token.value}" 不合法`, this.tokenizer.token.loc ?? this.tokenizer.emptyLoc(), node);
|
|
1134
1168
|
this.tokenizer.nextToken();
|
|
1135
|
-
|
|
1136
|
-
this.addError(ParseErrorCode.MISSING_ASSIGN, `属性 "${node.key.key}" 缺少 "=" 赋值符号`, node.key.loc ?? this.tokenizer.emptyLoc());
|
|
1169
|
+
return null;
|
|
1137
1170
|
}
|
|
1171
|
+
node.key = this.parsePropertyKey();
|
|
1172
|
+
const token = this.tokenizer.nextToken();
|
|
1173
|
+
if (token.value !== '=') {
|
|
1174
|
+
this.addError(ParseErrorCode.MISSING_ASSIGN, `属性 "${node.key.key}" 缺少 "=" 赋值符号`, node.key.loc ?? this.tokenizer.emptyLoc(), node);
|
|
1175
|
+
node.loc.start = node.key.loc.start;
|
|
1176
|
+
node.loc.end = node.key.loc.end;
|
|
1177
|
+
node.loc.source = this.tokenizer.code.slice(node.loc.start.offset, node.loc.end.offset);
|
|
1178
|
+
return node;
|
|
1179
|
+
}
|
|
1180
|
+
const valueToken = this.tokenizer.nextToken();
|
|
1181
|
+
if ((valueToken.type & ValueTokenType) === 0) {
|
|
1182
|
+
this.addError(ParseErrorCode.MISSING_PROP_ASSIGNMENT, `属性值不合法, "${valueToken.value}" 不合法`, valueToken.loc ?? this.tokenizer.emptyLoc(), node);
|
|
1183
|
+
node.loc.start = node.key.loc.start;
|
|
1184
|
+
node.loc.end = node.key.loc.end;
|
|
1185
|
+
node.loc.source = this.tokenizer.code.slice(node.loc.start.offset, node.loc.end.offset);
|
|
1186
|
+
return node;
|
|
1187
|
+
}
|
|
1188
|
+
node.value = this.parsePropertyValue();
|
|
1189
|
+
this.tokenizer.nextToken();
|
|
1138
1190
|
node.loc.start = node.key.loc.start;
|
|
1139
|
-
node.loc.end = node.value
|
|
1191
|
+
node.loc.end = node.value.loc.end;
|
|
1140
1192
|
node.loc.source = this.tokenizer.code.slice(node.loc.start.offset, node.loc.end.offset);
|
|
1141
1193
|
return node;
|
|
1142
1194
|
}
|
|
@@ -1145,7 +1197,7 @@
|
|
|
1145
1197
|
node.key = this.tokenizer.token.value;
|
|
1146
1198
|
return node;
|
|
1147
1199
|
}
|
|
1148
|
-
|
|
1200
|
+
parseJsExp(node) {
|
|
1149
1201
|
const _this$tokenizer$_hook3 = this.tokenizer._hook({}),
|
|
1150
1202
|
_this$tokenizer$_hook4 = _slicedToArray(_this$tokenizer$_hook3, 2),
|
|
1151
1203
|
hookType = _this$tokenizer$_hook4[0],
|
|
@@ -1154,7 +1206,7 @@
|
|
|
1154
1206
|
node.value = value;
|
|
1155
1207
|
return node;
|
|
1156
1208
|
}
|
|
1157
|
-
|
|
1209
|
+
parsePropertyValue(node) {
|
|
1158
1210
|
const _this$tokenizer$_hook5 = this.tokenizer._hook({}),
|
|
1159
1211
|
_this$tokenizer$_hook6 = _slicedToArray(_this$tokenizer$_hook5, 2),
|
|
1160
1212
|
hookType = _this$tokenizer$_hook6[0],
|
|
@@ -1163,6 +1215,15 @@
|
|
|
1163
1215
|
node.value = value;
|
|
1164
1216
|
return node;
|
|
1165
1217
|
}
|
|
1218
|
+
parseName(node) {
|
|
1219
|
+
const _this$tokenizer$_hook7 = this.tokenizer._hook({}),
|
|
1220
|
+
_this$tokenizer$_hook8 = _slicedToArray(_this$tokenizer$_hook7, 2),
|
|
1221
|
+
hookType = _this$tokenizer$_hook8[0],
|
|
1222
|
+
value = _this$tokenizer$_hook8[1];
|
|
1223
|
+
node.type = hookType === 'dynamic' ? NodeType.DynamicValue : NodeType.StaticValue;
|
|
1224
|
+
node.value = value;
|
|
1225
|
+
return node;
|
|
1226
|
+
}
|
|
1166
1227
|
}
|
|
1167
1228
|
function NodeLoc(target, context) {
|
|
1168
1229
|
return function (_node) {
|