bobe 0.0.37 → 0.0.38

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 CHANGED
@@ -14,8 +14,15 @@ let TokenType = function (TokenType) {
14
14
  TokenType[TokenType["InsertionExp"] = 128] = "InsertionExp";
15
15
  TokenType[TokenType["Semicolon"] = 256] = "Semicolon";
16
16
  TokenType[TokenType["StaticInsExp"] = 512] = "StaticInsExp";
17
+ TokenType[TokenType["String"] = 1024] = "String";
18
+ TokenType[TokenType["Number"] = 2048] = "Number";
19
+ TokenType[TokenType["Boolean"] = 4096] = "Boolean";
20
+ TokenType[TokenType["Null"] = 8192] = "Null";
21
+ TokenType[TokenType["Undefined"] = 16384] = "Undefined";
17
22
  return TokenType;
18
23
  }({});
24
+ const BaseTokenType = TokenType.String | TokenType.Number | TokenType.Boolean | TokenType.Null | TokenType.Undefined;
25
+ const ValueTokenType = BaseTokenType | TokenType.InsertionExp | TokenType.StaticInsExp;
19
26
  let FakeType = function (FakeType) {
20
27
  FakeType[FakeType["If"] = 1] = "If";
21
28
  FakeType[FakeType["Fail"] = 2] = "Fail";
@@ -51,13 +58,15 @@ let ParseErrorCode = function (ParseErrorCode) {
51
58
  ParseErrorCode[ParseErrorCode["INDENT_MISMATCH"] = 9005] = "INDENT_MISMATCH";
52
59
  ParseErrorCode[ParseErrorCode["MISSING_ASSIGN"] = 9006] = "MISSING_ASSIGN";
53
60
  ParseErrorCode[ParseErrorCode["INVALID_TAG_NAME"] = 9007] = "INVALID_TAG_NAME";
54
- ParseErrorCode[ParseErrorCode["ELSE_WITHOUT_IF"] = 9008] = "ELSE_WITHOUT_IF";
55
- ParseErrorCode[ParseErrorCode["EMPTY_IF_BODY"] = 9009] = "EMPTY_IF_BODY";
56
- ParseErrorCode[ParseErrorCode["EMPTY_FOR_BODY"] = 9010] = "EMPTY_FOR_BODY";
57
- ParseErrorCode[ParseErrorCode["MISSING_FOR_COLLECTION"] = 9011] = "MISSING_FOR_COLLECTION";
58
- ParseErrorCode[ParseErrorCode["MISSING_FOR_SEMICOLON"] = 9012] = "MISSING_FOR_SEMICOLON";
59
- ParseErrorCode[ParseErrorCode["MISSING_FOR_ITEM"] = 9013] = "MISSING_FOR_ITEM";
60
- ParseErrorCode[ParseErrorCode["PIPE_IN_WRONG_CONTEXT"] = 9014] = "PIPE_IN_WRONG_CONTEXT";
61
+ ParseErrorCode[ParseErrorCode["INVALID_PROP_KEY"] = 9008] = "INVALID_PROP_KEY";
62
+ ParseErrorCode[ParseErrorCode["ELSE_WITHOUT_IF"] = 9009] = "ELSE_WITHOUT_IF";
63
+ ParseErrorCode[ParseErrorCode["EMPTY_IF_BODY"] = 9010] = "EMPTY_IF_BODY";
64
+ ParseErrorCode[ParseErrorCode["EMPTY_FOR_BODY"] = 9011] = "EMPTY_FOR_BODY";
65
+ ParseErrorCode[ParseErrorCode["MISSING_FOR_COLLECTION"] = 9012] = "MISSING_FOR_COLLECTION";
66
+ ParseErrorCode[ParseErrorCode["MISSING_FOR_SEMICOLON"] = 9013] = "MISSING_FOR_SEMICOLON";
67
+ ParseErrorCode[ParseErrorCode["MISSING_FOR_ITEM"] = 9014] = "MISSING_FOR_ITEM";
68
+ ParseErrorCode[ParseErrorCode["MISSING_PROP_ASSIGNMENT"] = 9015] = "MISSING_PROP_ASSIGNMENT";
69
+ ParseErrorCode[ParseErrorCode["PIPE_IN_WRONG_CONTEXT"] = 9016] = "PIPE_IN_WRONG_CONTEXT";
61
70
  return ParseErrorCode;
62
71
  }({});
63
72
  class ParseSyntaxError extends SyntaxError {
@@ -589,8 +598,30 @@ class Tokenizer {
589
598
  this.setToken(TokenType.Dedent, '');
590
599
  return;
591
600
  }
592
- let realValue = value === 'null' ? null : value === 'undefined' ? undefined : value === 'false' ? false : value === 'true' ? true : value;
593
- this.setToken(TokenType.Identifier, realValue);
601
+ let realValue, tokenType;
602
+ switch (value) {
603
+ case 'null':
604
+ realValue = null;
605
+ tokenType = TokenType.Null;
606
+ break;
607
+ case 'undefined':
608
+ realValue = undefined;
609
+ tokenType = TokenType.Undefined;
610
+ break;
611
+ case 'false':
612
+ realValue = false;
613
+ tokenType = TokenType.Boolean;
614
+ break;
615
+ case 'true':
616
+ realValue = true;
617
+ tokenType = TokenType.Boolean;
618
+ break;
619
+ default:
620
+ realValue = value;
621
+ tokenType = TokenType.Identifier;
622
+ break;
623
+ }
624
+ this.setToken(tokenType, realValue);
594
625
  }
595
626
  str(char) {
596
627
  const startOffset = this.preI,
@@ -616,7 +647,7 @@ class Tokenizer {
616
647
  }
617
648
  value += nextC;
618
649
  }
619
- this.setToken(TokenType.Identifier, value);
650
+ this.setToken(TokenType.String, value);
620
651
  }
621
652
  number(char) {
622
653
  let value = char;
@@ -629,7 +660,7 @@ class Tokenizer {
629
660
  value += nextC;
630
661
  this.next();
631
662
  }
632
- this.setToken(TokenType.Identifier, Number(value));
663
+ this.setToken(TokenType.Number, Number(value));
633
664
  }
634
665
  eof() {
635
666
  this.setToken(TokenType.Eof, 'End Of File');
@@ -908,7 +939,7 @@ var NodeType = function (NodeType) {
908
939
  let _initProto;
909
940
  class Compiler {
910
941
  static {
911
- 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);
942
+ 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);
912
943
  _initProto = _applyDecs$e[0];
913
944
  }
914
945
  errors = (_initProto(this), []);
@@ -916,7 +947,10 @@ class Compiler {
916
947
  this.tokenizer = tokenizer;
917
948
  this.hooks = hooks;
918
949
  }
919
- addError(code, message, loc) {
950
+ addError(code, message, loc, node) {
951
+ if (node) {
952
+ node.hasError = true;
953
+ }
920
954
  this.errors.push({
921
955
  code,
922
956
  message,
@@ -1019,7 +1053,7 @@ class Compiler {
1019
1053
  parseElementNode(node) {
1020
1054
  const tagToken = this.tokenizer.token;
1021
1055
  if (!(tagToken.type & TokenType.Identifier)) {
1022
- this.addError(ParseErrorCode.INVALID_TAG_NAME, `无效的标签名,期望标识符但得到 "${tagToken.value}"`, tagToken.loc ?? this.tokenizer.emptyLoc());
1056
+ this.addError(ParseErrorCode.INVALID_TAG_NAME, `无效的标签名,期望标识符但得到 "${tagToken.value}"`, tagToken.loc ?? this.tokenizer.emptyLoc(), node);
1023
1057
  while (!(this.tokenizer.token.type & TokenType.NewLine) && !this.tokenizer.isEof()) {
1024
1058
  this.tokenizer.nextToken();
1025
1059
  }
@@ -1039,7 +1073,7 @@ class Compiler {
1039
1073
  parseConditionalNode(node) {
1040
1074
  const keyword = this.tokenizer.token.value;
1041
1075
  this.tokenizer.condExp();
1042
- const condition = this.parsePropertyValue();
1076
+ const condition = this.parseJsExp();
1043
1077
  this.tokenizer.nextToken();
1044
1078
  this.tokenizer.nextToken();
1045
1079
  node.type = keyword === 'if' ? NodeType.If : keyword === 'else' ? NodeType.Else : NodeType.Fail;
@@ -1052,22 +1086,22 @@ class Compiler {
1052
1086
  parseLoopNode(node) {
1053
1087
  const forLoc = this.tokenizer.token.loc ?? this.tokenizer.emptyLoc();
1054
1088
  this.tokenizer.nextToken();
1055
- const collection = this.parsePropertyValue();
1089
+ const collection = this.parseJsExp();
1056
1090
  if (!collection.value && collection.value !== 0) {
1057
- this.addError(ParseErrorCode.MISSING_FOR_COLLECTION, '"for" 缺少集合表达式', forLoc);
1091
+ this.addError(ParseErrorCode.MISSING_FOR_COLLECTION, '"for" 缺少集合表达式', forLoc, node);
1058
1092
  }
1059
1093
  const semicolonToken = this.tokenizer.nextToken();
1060
1094
  if (!(semicolonToken.type & TokenType.Semicolon)) {
1061
- this.addError(ParseErrorCode.MISSING_FOR_SEMICOLON, '"for" 语法:for <集合>; <item> [index][; key],缺少第一个 ";"', semicolonToken.loc ?? this.tokenizer.emptyLoc());
1095
+ this.addError(ParseErrorCode.MISSING_FOR_SEMICOLON, '"for" 语法:for <集合>; <item> [index][; key],缺少第一个 ";"', semicolonToken.loc ?? this.tokenizer.emptyLoc(), node);
1062
1096
  }
1063
1097
  const itemToken = this.tokenizer.nextToken();
1064
1098
  const isDestruct = itemToken.type === TokenType.InsertionExp;
1065
1099
  if (isDestruct) {
1066
1100
  itemToken.value = '{' + itemToken.value + '}';
1067
1101
  }
1068
- const item = this.parsePropertyValue();
1102
+ const item = this.parseJsExp();
1069
1103
  if (!item.value && item.value !== 0) {
1070
- this.addError(ParseErrorCode.MISSING_FOR_ITEM, '"for" 缺少 item 变量名', itemToken.loc ?? this.tokenizer.emptyLoc());
1104
+ this.addError(ParseErrorCode.MISSING_FOR_ITEM, '"for" 缺少 item 变量名', itemToken.loc ?? this.tokenizer.emptyLoc(), node);
1071
1105
  }
1072
1106
  let char = this.tokenizer.peekChar(),
1073
1107
  key,
@@ -1076,16 +1110,16 @@ class Compiler {
1076
1110
  this.tokenizer.nextToken();
1077
1111
  if (this.tokenizer.peekChar() !== '\n') {
1078
1112
  this.tokenizer.jsExp();
1079
- key = this.parsePropertyValue();
1113
+ key = this.parseJsExp();
1080
1114
  }
1081
1115
  } else if (char === '\n') ; else {
1082
1116
  this.tokenizer.nextToken();
1083
- index = this.parsePropertyValue();
1117
+ index = this.parseJsExp();
1084
1118
  if (this.tokenizer.peekChar() === ';') {
1085
1119
  this.tokenizer.nextToken();
1086
1120
  if (this.tokenizer.peekChar() !== '\n') {
1087
1121
  this.tokenizer.jsExp();
1088
- key = this.parsePropertyValue();
1122
+ key = this.parseJsExp();
1089
1123
  }
1090
1124
  }
1091
1125
  }
@@ -1119,23 +1153,41 @@ class Compiler {
1119
1153
  attributeList() {
1120
1154
  const props = [];
1121
1155
  while (!(this.tokenizer.token.type & TokenType.NewLine) && !(this.tokenizer.token.type & TokenType.Pipe) && !this.tokenizer.isEof()) {
1122
- props.push(this.parseProperty());
1156
+ const prop = this.parseProperty();
1157
+ if (prop) {
1158
+ props.push(prop);
1159
+ }
1123
1160
  }
1124
1161
  return props;
1125
1162
  }
1126
1163
  parseProperty(node) {
1127
1164
  node.type = NodeType.Property;
1128
- node.key = this.parsePropertyKey();
1129
- const token = this.tokenizer.nextToken();
1130
- if (token.value === '=') {
1131
- this.tokenizer.nextToken();
1132
- node.value = this.parsePropertyValue();
1165
+ if (this.tokenizer.token.type !== TokenType.Identifier) {
1166
+ this.addError(ParseErrorCode.INVALID_PROP_KEY, `属性名 "${this.tokenizer.token.value}" 不合法`, this.tokenizer.token.loc ?? this.tokenizer.emptyLoc(), node);
1133
1167
  this.tokenizer.nextToken();
1134
- } else {
1135
- this.addError(ParseErrorCode.MISSING_ASSIGN, `属性 "${node.key.key}" 缺少 "=" 赋值符号`, node.key.loc ?? this.tokenizer.emptyLoc());
1168
+ return null;
1136
1169
  }
1170
+ node.key = this.parsePropertyKey();
1171
+ const token = this.tokenizer.nextToken();
1172
+ if (token.value !== '=') {
1173
+ this.addError(ParseErrorCode.MISSING_ASSIGN, `属性 "${node.key.key}" 缺少 "=" 赋值符号`, node.key.loc ?? this.tokenizer.emptyLoc(), node);
1174
+ node.loc.start = node.key.loc.start;
1175
+ node.loc.end = node.key.loc.end;
1176
+ node.loc.source = this.tokenizer.code.slice(node.loc.start.offset, node.loc.end.offset);
1177
+ return node;
1178
+ }
1179
+ const valueToken = this.tokenizer.nextToken();
1180
+ if ((valueToken.type & ValueTokenType) === 0) {
1181
+ this.addError(ParseErrorCode.MISSING_PROP_ASSIGNMENT, `属性值不合法, "${valueToken.value}" 不合法`, valueToken.loc ?? this.tokenizer.emptyLoc(), node);
1182
+ node.loc.start = node.key.loc.start;
1183
+ node.loc.end = node.key.loc.end;
1184
+ node.loc.source = this.tokenizer.code.slice(node.loc.start.offset, node.loc.end.offset);
1185
+ return node;
1186
+ }
1187
+ node.value = this.parsePropertyValue();
1188
+ this.tokenizer.nextToken();
1137
1189
  node.loc.start = node.key.loc.start;
1138
- node.loc.end = node.value ? node.value.loc.end : node.key.loc.end;
1190
+ node.loc.end = node.value.loc.end;
1139
1191
  node.loc.source = this.tokenizer.code.slice(node.loc.start.offset, node.loc.end.offset);
1140
1192
  return node;
1141
1193
  }
@@ -1144,7 +1196,7 @@ class Compiler {
1144
1196
  node.key = this.tokenizer.token.value;
1145
1197
  return node;
1146
1198
  }
1147
- parsePropertyValue(node) {
1199
+ parseJsExp(node) {
1148
1200
  const _this$tokenizer$_hook3 = this.tokenizer._hook({}),
1149
1201
  _this$tokenizer$_hook4 = _slicedToArray(_this$tokenizer$_hook3, 2),
1150
1202
  hookType = _this$tokenizer$_hook4[0],
@@ -1153,7 +1205,7 @@ class Compiler {
1153
1205
  node.value = value;
1154
1206
  return node;
1155
1207
  }
1156
- parseName(node) {
1208
+ parsePropertyValue(node) {
1157
1209
  const _this$tokenizer$_hook5 = this.tokenizer._hook({}),
1158
1210
  _this$tokenizer$_hook6 = _slicedToArray(_this$tokenizer$_hook5, 2),
1159
1211
  hookType = _this$tokenizer$_hook6[0],
@@ -1162,6 +1214,15 @@ class Compiler {
1162
1214
  node.value = value;
1163
1215
  return node;
1164
1216
  }
1217
+ parseName(node) {
1218
+ const _this$tokenizer$_hook7 = this.tokenizer._hook({}),
1219
+ _this$tokenizer$_hook8 = _slicedToArray(_this$tokenizer$_hook7, 2),
1220
+ hookType = _this$tokenizer$_hook8[0],
1221
+ value = _this$tokenizer$_hook8[1];
1222
+ node.type = hookType === 'dynamic' ? NodeType.DynamicValue : NodeType.StaticValue;
1223
+ node.value = value;
1224
+ return node;
1225
+ }
1165
1226
  }
1166
1227
  function NodeLoc(target, context) {
1167
1228
  return function (_node) {