@danielx/civet 0.7.5 → 0.7.6

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/browser.js CHANGED
@@ -38,9 +38,9 @@ var Civet = (() => {
38
38
  ));
39
39
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
40
40
 
41
- // node_modules/@danielx/hera/dist/machine.js
41
+ // ../Hera/dist/machine.js
42
42
  var require_machine = __commonJS({
43
- "node_modules/@danielx/hera/dist/machine.js"(exports, module) {
43
+ "../Hera/dist/machine.js"(exports, module) {
44
44
  "use strict";
45
45
  var __defProp2 = Object.defineProperty;
46
46
  var __getOwnPropDesc2 = Object.getOwnPropertyDescriptor;
@@ -489,6 +489,7 @@ ${input.slice(result.pos)}
489
489
  // source/main.civet
490
490
  var main_exports = {};
491
491
  __export(main_exports, {
492
+ ParseErrors: () => ParseErrors,
492
493
  compile: () => compile,
493
494
  default: () => main_default,
494
495
  generate: () => generate_default,
@@ -970,6 +971,9 @@ ${input.slice(result.pos)}
970
971
  wrapIterationReturningResults(exp, outer, collect);
971
972
  return;
972
973
  case "BlockStatement":
974
+ if (node.expressions.some(isExit)) {
975
+ return;
976
+ }
973
977
  assignResults(exp.expressions[exp.expressions.length - 1], collect);
974
978
  return;
975
979
  case "IfStatement":
@@ -1004,6 +1008,9 @@ ${input.slice(result.pos)}
1004
1008
  switch (node.type) {
1005
1009
  case "BlockStatement":
1006
1010
  if (node.expressions.length) {
1011
+ if (node.expressions.some(([, exp2]) => isExit(exp2))) {
1012
+ return;
1013
+ }
1007
1014
  const last = node.expressions[node.expressions.length - 1];
1008
1015
  insertReturn(last);
1009
1016
  } else {
@@ -1249,12 +1256,6 @@ ${input.slice(result.pos)}
1249
1256
  // source/parser/block.civet
1250
1257
  function blockWithPrefix(prefixStatements, block) {
1251
1258
  if (prefixStatements && prefixStatements.length) {
1252
- const indent = getIndent(block.expressions[0]);
1253
- if (indent) {
1254
- prefixStatements = prefixStatements.map((statement) => {
1255
- return [indent, ...statement.slice(1)];
1256
- });
1257
- }
1258
1259
  const expressions = [...prefixStatements, ...block.expressions];
1259
1260
  updateParentPointers(prefixStatements, block);
1260
1261
  block = {
@@ -2612,6 +2613,11 @@ ${input.slice(result.pos)}
2612
2613
  declareHelper[base](ref);
2613
2614
  return state.helperRefs[base] = ref;
2614
2615
  }
2616
+ function extractPreludeFor(node) {
2617
+ let helpers = new Set(Object.values(state.helperRefs));
2618
+ helpers = new Set(gatherRecursive(node, helpers.has.bind(helpers)));
2619
+ return state.prelude.filter((s) => gatherRecursive(s, helpers.has.bind(helpers)).length);
2620
+ }
2615
2621
 
2616
2622
  // source/parser/pattern-matching.civet
2617
2623
  function processPatternTest(lhs, patterns) {
@@ -4030,6 +4036,26 @@ ${input.slice(result.pos)}
4030
4036
  scopes.pop();
4031
4037
  }
4032
4038
 
4039
+ // source/browser.civet
4040
+ function dirname(path) {
4041
+ return path.replace(/[^]*\//, "");
4042
+ }
4043
+ function resolve(path) {
4044
+ return path;
4045
+ }
4046
+ function createRequire(path) {
4047
+ return (id) => {
4048
+ throw new ReferenceError(
4049
+ "Civet comptime does not support 'require' on this platform"
4050
+ );
4051
+ };
4052
+ }
4053
+ var browser_default = {
4054
+ dirname,
4055
+ resolve,
4056
+ createRequire
4057
+ };
4058
+
4033
4059
  // source/generate.civet
4034
4060
  function stringify(node) {
4035
4061
  try {
@@ -4115,32 +4141,18 @@ ${input.slice(result.pos)}
4115
4141
  if (!getInitialConfig()?.comptime) {
4116
4142
  return;
4117
4143
  }
4118
- let prepareEval = () => {
4119
- };
4144
+ const promises = runComptime(statements);
4120
4145
  if (getSync()) {
4121
- runComptime(statements, prepareEval);
4122
4146
  return;
4123
4147
  } else {
4124
4148
  return (async () => {
4125
4149
  {
4126
- try {
4127
- const path = (await import("node:path")).default;
4128
- const { createRequire } = await import("node:module");
4129
- return prepareEval = () => {
4130
- global.__filename = path.resolve(getFilename() ?? "");
4131
- global.__dirname = path.dirname(global.__filename);
4132
- return global.require = createRequire(global.__filename);
4133
- };
4134
- } catch (e) {
4135
- return;
4136
- }
4150
+ await Promise.all(promises);
4137
4151
  }
4138
- })().then(async () => {
4139
- await Promise.all(runComptime(statements, prepareEval));
4140
- });
4152
+ })();
4141
4153
  }
4142
4154
  }
4143
- function runComptime(statements, prepareEval) {
4155
+ function runComptime(statements) {
4144
4156
  const sync2 = getSync();
4145
4157
  return gatherRecursive(
4146
4158
  statements,
@@ -4148,20 +4160,77 @@ ${input.slice(result.pos)}
4148
4160
  return node.type === "ComptimeStatement" || node.type === "ComptimeExpression";
4149
4161
  }
4150
4162
  ).map((exp) => {
4151
- const content = exp.type === "ComptimeStatement" ? exp.block : exp.expression;
4163
+ let content = exp.type === "ComptimeStatement" ? exp.block : exp.expression;
4164
+ content = [
4165
+ ...extractPreludeFor(content),
4166
+ content
4167
+ ];
4152
4168
  const options = { js: true };
4153
- const js = generate_default(prune(content), options);
4169
+ let js = generate_default(prune(content), options);
4170
+ js = `"use strict";${js}`;
4154
4171
  if (options.errors != null) {
4155
4172
  return;
4156
4173
  }
4157
- prepareEval();
4158
- let output = eval?.(`"use strict";${js}`);
4174
+ let output, context;
4175
+ try {
4176
+ context = browser_default.createContext?.() ?? globalThis;
4177
+ const filename2 = context.__filename = resolve(getFilename() ?? "");
4178
+ context.__dirname = dirname(filename2);
4179
+ context.require = createRequire(filename2);
4180
+ if (browser_default.runInContext != null) {
4181
+ for (const global of [
4182
+ "RegExp",
4183
+ "Date",
4184
+ "Set",
4185
+ "Map",
4186
+ "URL",
4187
+ "Int8Array",
4188
+ "Uint8Array",
4189
+ "Int16Array",
4190
+ "Uint16Array",
4191
+ "Int32Array",
4192
+ "Uint32Array",
4193
+ "Float32Array",
4194
+ "Float64Array",
4195
+ "Uint8ClampedArray",
4196
+ "BigInt64Array",
4197
+ "BigUint64Array",
4198
+ "Buffer"
4199
+ ]) {
4200
+ context[global] = globalThis[global];
4201
+ }
4202
+ context.Object2 = Object;
4203
+ output = browser_default.runInContext(js, context, {
4204
+ filename: filename2,
4205
+ importModuleDynamically: browser_default.constants?.USE_MAIN_CONTEXT_DEFAULT_LOADER
4206
+ });
4207
+ } else {
4208
+ output = eval?.(js);
4209
+ }
4210
+ } catch (e) {
4211
+ exp.children = [
4212
+ {
4213
+ type: "Error",
4214
+ message: `comptime block failed to execute: ${e}
4215
+ ${js}`
4216
+ }
4217
+ ];
4218
+ return;
4219
+ }
4159
4220
  let promise;
4160
4221
  if (exp.type === "ComptimeExpression") {
4161
4222
  const finish = () => {
4162
4223
  let string;
4163
4224
  try {
4164
- string = serialize(output);
4225
+ if (browser_default.runInContext != null) {
4226
+ context.output = output;
4227
+ string = browser_default.runInContext(
4228
+ `${serialize(serialize)}serialize(output)`,
4229
+ context
4230
+ );
4231
+ } else {
4232
+ string = serialize(output);
4233
+ }
4165
4234
  } catch (e) {
4166
4235
  exp.children = [
4167
4236
  {
@@ -4288,11 +4357,8 @@ ${input.slice(result.pos)}
4288
4357
  })().join(",") + "])";
4289
4358
  break;
4290
4359
  }
4291
- case Array.prototype: {
4292
- ref1 = `[${val.map(recurse).join(",")}]`;
4293
- break;
4294
- }
4295
- case Object.prototype: {
4360
+ case Object.prototype:
4361
+ case globalThis.Object2?.prototype: {
4296
4362
  let objStr = "{";
4297
4363
  let descStr = "";
4298
4364
  for (let ref2 = Object.getOwnPropertyNames(val).concat(Object.getOwnPropertySymbols(val)), i = 0, len3 = ref2.length; i < len3; i++) {
@@ -4357,7 +4423,11 @@ ${input.slice(result.pos)}
4357
4423
  break;
4358
4424
  }
4359
4425
  default: {
4360
- throw new TypeError(`cannot serialize object with prototype ${Object.getPrototypeOf(val)}`);
4426
+ if (Array.isArray(val)) {
4427
+ ref1 = `[${val.map(recurse).join(",")}]`;
4428
+ } else {
4429
+ throw new TypeError(`cannot serialize object with prototype ${val.constructor?.name ?? Object.getPrototypeOf(val)}`);
4430
+ }
4361
4431
  }
4362
4432
  }
4363
4433
  ;
@@ -4743,11 +4813,23 @@ ${input.slice(result.pos)}
4743
4813
  }
4744
4814
  prefix = prefix.concat(glob.dot);
4745
4815
  for (const part of glob.object.properties) {
4816
+ if (part.type === "Error") {
4817
+ parts.push(part);
4818
+ continue;
4819
+ }
4746
4820
  if (part.type === "MethodDefinition") {
4747
- throw new Error("Glob pattern cannot have method definition");
4821
+ parts.push({
4822
+ type: "Error",
4823
+ message: "Glob pattern cannot have method definition"
4824
+ });
4825
+ continue;
4748
4826
  }
4749
4827
  if (part.value && !["CallExpression", "MemberExpression", "Identifier"].includes(part.value.type)) {
4750
- throw new Error(`Glob pattern must have call or member expression value, found ${JSON.stringify(part.value)}`);
4828
+ parts.push({
4829
+ type: "Error",
4830
+ message: `Glob pattern must have call or member expression value, found ${JSON.stringify(part.value)}`
4831
+ });
4832
+ continue;
4751
4833
  }
4752
4834
  let suppressPrefix = false;
4753
4835
  let name = part.name;
@@ -4896,6 +4978,10 @@ ${input.slice(result.pos)}
4896
4978
  }
4897
4979
  let children, i;
4898
4980
  do {
4981
+ if (!(exp.children != null)) {
4982
+ return;
4983
+ }
4984
+ ;
4899
4985
  ({ children } = exp);
4900
4986
  i = children.length - 1;
4901
4987
  while (i >= 0 && (children[i].type === "Call" || children[i].type === "NonNullAssertion" || children[i].type === "Optional"))
@@ -11000,6 +11086,7 @@ ${input.slice(result.pos)}
11000
11086
  if (!state.operators.has(id.name))
11001
11087
  return $skip;
11002
11088
  return {
11089
+ token: id.name,
11003
11090
  call: id,
11004
11091
  special: true,
11005
11092
  ...state.operators.get(id.name)
@@ -11010,6 +11097,7 @@ ${input.slice(result.pos)}
11010
11097
  if (!state.operators.has(id.name))
11011
11098
  return $skip;
11012
11099
  return {
11100
+ token: id.name,
11013
11101
  call: id,
11014
11102
  special: true,
11015
11103
  negated: true,
@@ -16651,6 +16739,21 @@ ${input.slice(result.pos)}
16651
16739
 
16652
16740
  // source/main.civet
16653
16741
  var { SourceMap: SourceMap2 } = util_exports;
16742
+ var ParseErrors = class extends Error {
16743
+ name = "ParseErrors";
16744
+ filename;
16745
+ line;
16746
+ column;
16747
+ offset;
16748
+ constructor(message, filename1, line1, column1, offset1) {
16749
+ super(message);
16750
+ this.filename = filename1;
16751
+ this.line = line1;
16752
+ this.column = column1;
16753
+ this.offset = offset1;
16754
+ this.message = message;
16755
+ }
16756
+ };
16654
16757
  var uncacheable = /* @__PURE__ */ new Set([
16655
16758
  // Meta
16656
16759
  "DebugHere",
@@ -16760,7 +16863,7 @@ ${counts}`;
16760
16863
  }
16761
16864
  function checkErrors() {
16762
16865
  if (options.errors?.length) {
16763
- throw new Error(`Parse errors: ${options.errors.map(($) => $.message).join("\n")} `);
16866
+ throw new ParseErrors(options.errors.map(($) => $.message).join("\n"));
16764
16867
  }
16765
16868
  ;
16766
16869
  return;
package/dist/civet CHANGED
@@ -228,7 +228,7 @@ async function* readFiles(filenames) {
228
228
  }
229
229
  if (process.stdin.isTTY) {
230
230
  const lines = [];
231
- const rl = (await import("readline")).createInterface(process.stdin, process.stdout);
231
+ const rl = (await import("node:readline")).createInterface(process.stdin, process.stdout);
232
232
  rl.on("line", (buffer) => lines.push(buffer + "\n"));
233
233
  content = await new Promise((resolve, reject) => {
234
234
  rl.on("SIGINT", () => {
@@ -259,11 +259,11 @@ async function* readFiles(filenames) {
259
259
  return results1;
260
260
  }
261
261
  async function repl(options) {
262
- const vm = await import("vm");
262
+ const vm = await import("node:vm");
263
263
  let importModuleDynamically = vm.constants?.USE_MAIN_CONTEXT_DEFAULT_LOADER;
264
264
  if (!importModuleDynamically) {
265
265
  if (vm.SourceTextModule != null) {
266
- const { pathToFileURL } = await import("url");
266
+ const { pathToFileURL } = await import("node:url");
267
267
  importModuleDynamically = (specifier) => {
268
268
  if (/^\.\.?[/\\]/.test(specifier)) {
269
269
  return import(pathToFileURL(import_path.default.join(process.cwd(), specifier)));
@@ -273,11 +273,11 @@ async function repl(options) {
273
273
  };
274
274
  } else {
275
275
  const execArgv = ["--experimental-vm-modules"];
276
- const { register } = await import("module");
276
+ const { register } = await import("node:module");
277
277
  if (process.env.NODE_OPTIONS) {
278
278
  execArgv.push(process.env.NODE_OPTIONS);
279
279
  }
280
- const { fork } = await import("child_process");
280
+ const { fork } = await import("node:child_process");
281
281
  fork(__filename, process.argv.slice(2), {
282
282
  execArgv,
283
283
  stdio: "inherit"
@@ -300,7 +300,7 @@ async function repl(options) {
300
300
  }
301
301
  })()} code.`);
302
302
  global.quit = global.exit = () => process.exit(0);
303
- const nodeRepl = await import("repl");
303
+ const nodeRepl = await import("node:repl");
304
304
  const r = nodeRepl.start({
305
305
  prompt: (() => {
306
306
  switch (false) {
@@ -500,6 +500,14 @@ async function cli() {
500
500
  errors++;
501
501
  continue;
502
502
  }
503
+ process.stdout.on("error", (e) => {
504
+ if (["EPIPE", "EOF"].includes(e.code)) {
505
+ return process.exit(0);
506
+ } else {
507
+ console.error(e);
508
+ return process.exit(1);
509
+ }
510
+ });
503
511
  if (options.ast) {
504
512
  process.stdout.write(JSON.stringify(output, null, 2));
505
513
  } else if (options.compile) {
@@ -547,8 +555,8 @@ async function cli() {
547
555
  process.exit(1);
548
556
  }
549
557
  }
550
- const { fork } = await import("child_process");
551
- const { register } = await import("module");
558
+ const { fork } = await import("node:child_process");
559
+ const { register } = await import("node:module");
552
560
  let execArgv;
553
561
  if (register) {
554
562
  execArgv = ["--import", "@danielx/civet/register"];
package/dist/main.js CHANGED
@@ -30,9 +30,9 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
30
30
  ));
31
31
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
32
32
 
33
- // node_modules/@danielx/hera/dist/machine.js
33
+ // ../Hera/dist/machine.js
34
34
  var require_machine = __commonJS({
35
- "node_modules/@danielx/hera/dist/machine.js"(exports2, module2) {
35
+ "../Hera/dist/machine.js"(exports2, module2) {
36
36
  "use strict";
37
37
  var __defProp2 = Object.defineProperty;
38
38
  var __getOwnPropDesc2 = Object.getOwnPropertyDescriptor;
@@ -481,6 +481,7 @@ ${input.slice(result.pos)}
481
481
  // source/main.civet
482
482
  var main_exports = {};
483
483
  __export(main_exports, {
484
+ ParseErrors: () => ParseErrors,
484
485
  compile: () => compile,
485
486
  default: () => main_default,
486
487
  generate: () => generate_default,
@@ -963,6 +964,9 @@ function assignResults(node, collect) {
963
964
  wrapIterationReturningResults(exp, outer, collect);
964
965
  return;
965
966
  case "BlockStatement":
967
+ if (node.expressions.some(isExit)) {
968
+ return;
969
+ }
966
970
  assignResults(exp.expressions[exp.expressions.length - 1], collect);
967
971
  return;
968
972
  case "IfStatement":
@@ -997,6 +1001,9 @@ function insertReturn(node, outerNode = node) {
997
1001
  switch (node.type) {
998
1002
  case "BlockStatement":
999
1003
  if (node.expressions.length) {
1004
+ if (node.expressions.some(([, exp2]) => isExit(exp2))) {
1005
+ return;
1006
+ }
1000
1007
  const last = node.expressions[node.expressions.length - 1];
1001
1008
  insertReturn(last);
1002
1009
  } else {
@@ -1242,12 +1249,6 @@ function skipImplicitArguments(args) {
1242
1249
  // source/parser/block.civet
1243
1250
  function blockWithPrefix(prefixStatements, block) {
1244
1251
  if (prefixStatements && prefixStatements.length) {
1245
- const indent = getIndent(block.expressions[0]);
1246
- if (indent) {
1247
- prefixStatements = prefixStatements.map((statement) => {
1248
- return [indent, ...statement.slice(1)];
1249
- });
1250
- }
1251
1252
  const expressions = [...prefixStatements, ...block.expressions];
1252
1253
  updateParentPointers(prefixStatements, block);
1253
1254
  block = {
@@ -2605,6 +2606,11 @@ function getHelperRef(base) {
2605
2606
  declareHelper[base](ref);
2606
2607
  return state.helperRefs[base] = ref;
2607
2608
  }
2609
+ function extractPreludeFor(node) {
2610
+ let helpers = new Set(Object.values(state.helperRefs));
2611
+ helpers = new Set(gatherRecursive(node, helpers.has.bind(helpers)));
2612
+ return state.prelude.filter((s) => gatherRecursive(s, helpers.has.bind(helpers)).length);
2613
+ }
2608
2614
 
2609
2615
  // source/parser/pattern-matching.civet
2610
2616
  function processPatternTest(lhs, patterns) {
@@ -4023,6 +4029,11 @@ function createVarDecs(block, scopes, pushVar) {
4023
4029
  scopes.pop();
4024
4030
  }
4025
4031
 
4032
+ // source/parser/comptime.civet
4033
+ var import_node_path = require("node:path");
4034
+ var import_node_module = require("node:module");
4035
+ var import_node_vm = __toESM(require("node:vm"));
4036
+
4026
4037
  // source/generate.civet
4027
4038
  function stringify(node) {
4028
4039
  try {
@@ -4108,32 +4119,18 @@ function processComptime(statements) {
4108
4119
  if (!getInitialConfig()?.comptime) {
4109
4120
  return;
4110
4121
  }
4111
- let prepareEval = () => {
4112
- };
4122
+ const promises = runComptime(statements);
4113
4123
  if (getSync()) {
4114
- runComptime(statements, prepareEval);
4115
4124
  return;
4116
4125
  } else {
4117
4126
  return (async () => {
4118
4127
  {
4119
- try {
4120
- const path = (await import("node:path")).default;
4121
- const { createRequire } = await import("node:module");
4122
- return prepareEval = () => {
4123
- global.__filename = path.resolve(getFilename() ?? "");
4124
- global.__dirname = path.dirname(global.__filename);
4125
- return global.require = createRequire(global.__filename);
4126
- };
4127
- } catch (e) {
4128
- return;
4129
- }
4128
+ await Promise.all(promises);
4130
4129
  }
4131
- })().then(async () => {
4132
- await Promise.all(runComptime(statements, prepareEval));
4133
- });
4130
+ })();
4134
4131
  }
4135
4132
  }
4136
- function runComptime(statements, prepareEval) {
4133
+ function runComptime(statements) {
4137
4134
  const sync2 = getSync();
4138
4135
  return gatherRecursive(
4139
4136
  statements,
@@ -4141,20 +4138,77 @@ function runComptime(statements, prepareEval) {
4141
4138
  return node.type === "ComptimeStatement" || node.type === "ComptimeExpression";
4142
4139
  }
4143
4140
  ).map((exp) => {
4144
- const content = exp.type === "ComptimeStatement" ? exp.block : exp.expression;
4141
+ let content = exp.type === "ComptimeStatement" ? exp.block : exp.expression;
4142
+ content = [
4143
+ ...extractPreludeFor(content),
4144
+ content
4145
+ ];
4145
4146
  const options = { js: true };
4146
- const js = generate_default(prune(content), options);
4147
+ let js = generate_default(prune(content), options);
4148
+ js = `"use strict";${js}`;
4147
4149
  if (options.errors != null) {
4148
4150
  return;
4149
4151
  }
4150
- prepareEval();
4151
- let output = eval?.(`"use strict";${js}`);
4152
+ let output, context;
4153
+ try {
4154
+ context = import_node_vm.default.createContext?.() ?? globalThis;
4155
+ const filename2 = context.__filename = (0, import_node_path.resolve)(getFilename() ?? "");
4156
+ context.__dirname = (0, import_node_path.dirname)(filename2);
4157
+ context.require = (0, import_node_module.createRequire)(filename2);
4158
+ if (import_node_vm.default.runInContext != null) {
4159
+ for (const global of [
4160
+ "RegExp",
4161
+ "Date",
4162
+ "Set",
4163
+ "Map",
4164
+ "URL",
4165
+ "Int8Array",
4166
+ "Uint8Array",
4167
+ "Int16Array",
4168
+ "Uint16Array",
4169
+ "Int32Array",
4170
+ "Uint32Array",
4171
+ "Float32Array",
4172
+ "Float64Array",
4173
+ "Uint8ClampedArray",
4174
+ "BigInt64Array",
4175
+ "BigUint64Array",
4176
+ "Buffer"
4177
+ ]) {
4178
+ context[global] = globalThis[global];
4179
+ }
4180
+ context.Object2 = Object;
4181
+ output = import_node_vm.default.runInContext(js, context, {
4182
+ filename: filename2,
4183
+ importModuleDynamically: import_node_vm.default.constants?.USE_MAIN_CONTEXT_DEFAULT_LOADER
4184
+ });
4185
+ } else {
4186
+ output = eval?.(js);
4187
+ }
4188
+ } catch (e) {
4189
+ exp.children = [
4190
+ {
4191
+ type: "Error",
4192
+ message: `comptime block failed to execute: ${e}
4193
+ ${js}`
4194
+ }
4195
+ ];
4196
+ return;
4197
+ }
4152
4198
  let promise;
4153
4199
  if (exp.type === "ComptimeExpression") {
4154
4200
  const finish = () => {
4155
4201
  let string;
4156
4202
  try {
4157
- string = serialize(output);
4203
+ if (import_node_vm.default.runInContext != null) {
4204
+ context.output = output;
4205
+ string = import_node_vm.default.runInContext(
4206
+ `${serialize(serialize)}serialize(output)`,
4207
+ context
4208
+ );
4209
+ } else {
4210
+ string = serialize(output);
4211
+ }
4158
4212
  } catch (e) {
4159
4213
  exp.children = [
4160
4214
  {
@@ -4281,11 +4335,8 @@ function serialize(value) {
4281
4335
  })().join(",") + "])";
4282
4336
  break;
4283
4337
  }
4284
- case Array.prototype: {
4285
- ref1 = `[${val.map(recurse).join(",")}]`;
4286
- break;
4287
- }
4288
- case Object.prototype: {
4338
+ case Object.prototype:
4339
+ case globalThis.Object2?.prototype: {
4289
4340
  let objStr = "{";
4290
4341
  let descStr = "";
4291
4342
  for (let ref2 = Object.getOwnPropertyNames(val).concat(Object.getOwnPropertySymbols(val)), i = 0, len3 = ref2.length; i < len3; i++) {
@@ -4350,7 +4401,11 @@ function serialize(value) {
4350
4401
  break;
4351
4402
  }
4352
4403
  default: {
4353
- throw new TypeError(`cannot serialize object with prototype ${Object.getPrototypeOf(val)}`);
4404
+ if (Array.isArray(val)) {
4405
+ ref1 = `[${val.map(recurse).join(",")}]`;
4406
+ } else {
4407
+ throw new TypeError(`cannot serialize object with prototype ${val.constructor?.name ?? Object.getPrototypeOf(val)}`);
4408
+ }
4354
4409
  }
4355
4410
  }
4356
4411
  ;
@@ -4736,11 +4791,23 @@ function processCallMemberExpression(node) {
4736
4791
  }
4737
4792
  prefix = prefix.concat(glob.dot);
4738
4793
  for (const part of glob.object.properties) {
4794
+ if (part.type === "Error") {
4795
+ parts.push(part);
4796
+ continue;
4797
+ }
4739
4798
  if (part.type === "MethodDefinition") {
4740
- throw new Error("Glob pattern cannot have method definition");
4799
+ parts.push({
4800
+ type: "Error",
4801
+ message: "Glob pattern cannot have method definition"
4802
+ });
4803
+ continue;
4741
4804
  }
4742
4805
  if (part.value && !["CallExpression", "MemberExpression", "Identifier"].includes(part.value.type)) {
4743
- throw new Error(`Glob pattern must have call or member expression value, found ${JSON.stringify(part.value)}`);
4806
+ parts.push({
4807
+ type: "Error",
4808
+ message: `Glob pattern must have call or member expression value, found ${JSON.stringify(part.value)}`
4809
+ });
4810
+ continue;
4744
4811
  }
4745
4812
  let suppressPrefix = false;
4746
4813
  let name = part.name;
@@ -4889,6 +4956,10 @@ function lastAccessInCallExpression(exp) {
4889
4956
  }
4890
4957
  let children, i;
4891
4958
  do {
4959
+ if (!(exp.children != null)) {
4960
+ return;
4961
+ }
4962
+ ;
4892
4963
  ({ children } = exp);
4893
4964
  i = children.length - 1;
4894
4965
  while (i >= 0 && (children[i].type === "Call" || children[i].type === "NonNullAssertion" || children[i].type === "Optional"))
@@ -10993,6 +11064,7 @@ var _BinaryOp$1 = (0, import_lib2.$TV)(Identifier, function($skip, $loc, $0, $1)
10993
11064
  if (!state.operators.has(id.name))
10994
11065
  return $skip;
10995
11066
  return {
11067
+ token: id.name,
10996
11068
  call: id,
10997
11069
  special: true,
10998
11070
  ...state.operators.get(id.name)
@@ -11003,6 +11075,7 @@ var _BinaryOp$2 = (0, import_lib2.$TS)((0, import_lib2.$S)(OmittedNegation, __,
11003
11075
  if (!state.operators.has(id.name))
11004
11076
  return $skip;
11005
11077
  return {
11078
+ token: id.name,
11006
11079
  call: id,
11007
11080
  special: true,
11008
11081
  negated: true,
@@ -16644,6 +16717,21 @@ var StateCache = class {
16644
16717
 
16645
16718
  // source/main.civet
16646
16719
  var { SourceMap: SourceMap2 } = util_exports;
16720
+ var ParseErrors = class extends Error {
16721
+ name = "ParseErrors";
16722
+ filename;
16723
+ line;
16724
+ column;
16725
+ offset;
16726
+ constructor(message, filename1, line1, column1, offset1) {
16727
+ super(message);
16728
+ this.filename = filename1;
16729
+ this.line = line1;
16730
+ this.column = column1;
16731
+ this.offset = offset1;
16732
+ this.message = message;
16733
+ }
16734
+ };
16647
16735
  var uncacheable = /* @__PURE__ */ new Set([
16648
16736
  // Meta
16649
16737
  "DebugHere",
@@ -16753,7 +16841,7 @@ ${counts}`;
16753
16841
  }
16754
16842
  function checkErrors() {
16755
16843
  if (options.errors?.length) {
16756
- throw new Error(`Parse errors: ${options.errors.map(($) => $.message).join("\n")} `);
16844
+ throw new ParseErrors(options.errors.map(($) => $.message).join("\n"));
16757
16845
  }
16758
16846
  ;
16759
16847
  return;
@@ -16851,6 +16939,7 @@ var isCompileError = function(err) {
16851
16939
  var main_default = { parse, parseProgram, generate: generate_default, util: util_exports, compile, isCompileError };
16852
16940
  // Annotate the CommonJS export names for ESM import in node:
16853
16941
  0 && (module.exports = {
16942
+ ParseErrors,
16854
16943
  compile,
16855
16944
  generate,
16856
16945
  isCompileError,
package/dist/main.mjs CHANGED
@@ -28,9 +28,9 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
28
28
  mod
29
29
  ));
30
30
 
31
- // node_modules/@danielx/hera/dist/machine.js
31
+ // ../Hera/dist/machine.js
32
32
  var require_machine = __commonJS({
33
- "node_modules/@danielx/hera/dist/machine.js"(exports, module) {
33
+ "../Hera/dist/machine.js"(exports, module) {
34
34
  "use strict";
35
35
  var __defProp2 = Object.defineProperty;
36
36
  var __getOwnPropDesc2 = Object.getOwnPropertyDescriptor;
@@ -946,6 +946,9 @@ function assignResults(node, collect) {
946
946
  wrapIterationReturningResults(exp, outer, collect);
947
947
  return;
948
948
  case "BlockStatement":
949
+ if (node.expressions.some(isExit)) {
950
+ return;
951
+ }
949
952
  assignResults(exp.expressions[exp.expressions.length - 1], collect);
950
953
  return;
951
954
  case "IfStatement":
@@ -980,6 +983,9 @@ function insertReturn(node, outerNode = node) {
980
983
  switch (node.type) {
981
984
  case "BlockStatement":
982
985
  if (node.expressions.length) {
986
+ if (node.expressions.some(([, exp2]) => isExit(exp2))) {
987
+ return;
988
+ }
983
989
  const last = node.expressions[node.expressions.length - 1];
984
990
  insertReturn(last);
985
991
  } else {
@@ -1225,12 +1231,6 @@ function skipImplicitArguments(args) {
1225
1231
  // source/parser/block.civet
1226
1232
  function blockWithPrefix(prefixStatements, block) {
1227
1233
  if (prefixStatements && prefixStatements.length) {
1228
- const indent = getIndent(block.expressions[0]);
1229
- if (indent) {
1230
- prefixStatements = prefixStatements.map((statement) => {
1231
- return [indent, ...statement.slice(1)];
1232
- });
1233
- }
1234
1234
  const expressions = [...prefixStatements, ...block.expressions];
1235
1235
  updateParentPointers(prefixStatements, block);
1236
1236
  block = {
@@ -2588,6 +2588,11 @@ function getHelperRef(base) {
2588
2588
  declareHelper[base](ref);
2589
2589
  return state.helperRefs[base] = ref;
2590
2590
  }
2591
+ function extractPreludeFor(node) {
2592
+ let helpers = new Set(Object.values(state.helperRefs));
2593
+ helpers = new Set(gatherRecursive(node, helpers.has.bind(helpers)));
2594
+ return state.prelude.filter((s) => gatherRecursive(s, helpers.has.bind(helpers)).length);
2595
+ }
2591
2596
 
2592
2597
  // source/parser/pattern-matching.civet
2593
2598
  function processPatternTest(lhs, patterns) {
@@ -4006,6 +4011,11 @@ function createVarDecs(block, scopes, pushVar) {
4006
4011
  scopes.pop();
4007
4012
  }
4008
4013
 
4014
+ // source/parser/comptime.civet
4015
+ import { resolve, dirname } from "node:path";
4016
+ import { createRequire } from "node:module";
4017
+ import vm from "node:vm";
4018
+
4009
4019
  // source/generate.civet
4010
4020
  function stringify(node) {
4011
4021
  try {
@@ -4091,32 +4101,18 @@ function processComptime(statements) {
4091
4101
  if (!getInitialConfig()?.comptime) {
4092
4102
  return;
4093
4103
  }
4094
- let prepareEval = () => {
4095
- };
4104
+ const promises = runComptime(statements);
4096
4105
  if (getSync()) {
4097
- runComptime(statements, prepareEval);
4098
4106
  return;
4099
4107
  } else {
4100
4108
  return (async () => {
4101
4109
  {
4102
- try {
4103
- const path = (await import("node:path")).default;
4104
- const { createRequire } = await import("node:module");
4105
- return prepareEval = () => {
4106
- global.__filename = path.resolve(getFilename() ?? "");
4107
- global.__dirname = path.dirname(global.__filename);
4108
- return global.require = createRequire(global.__filename);
4109
- };
4110
- } catch (e) {
4111
- return;
4112
- }
4110
+ await Promise.all(promises);
4113
4111
  }
4114
- })().then(async () => {
4115
- await Promise.all(runComptime(statements, prepareEval));
4116
- });
4112
+ })();
4117
4113
  }
4118
4114
  }
4119
- function runComptime(statements, prepareEval) {
4115
+ function runComptime(statements) {
4120
4116
  const sync2 = getSync();
4121
4117
  return gatherRecursive(
4122
4118
  statements,
@@ -4124,20 +4120,77 @@ function runComptime(statements, prepareEval) {
4124
4120
  return node.type === "ComptimeStatement" || node.type === "ComptimeExpression";
4125
4121
  }
4126
4122
  ).map((exp) => {
4127
- const content = exp.type === "ComptimeStatement" ? exp.block : exp.expression;
4123
+ let content = exp.type === "ComptimeStatement" ? exp.block : exp.expression;
4124
+ content = [
4125
+ ...extractPreludeFor(content),
4126
+ content
4127
+ ];
4128
4128
  const options = { js: true };
4129
- const js = generate_default(prune(content), options);
4129
+ let js = generate_default(prune(content), options);
4130
+ js = `"use strict";${js}`;
4130
4131
  if (options.errors != null) {
4131
4132
  return;
4132
4133
  }
4133
- prepareEval();
4134
- let output = eval?.(`"use strict";${js}`);
4134
+ let output, context;
4135
+ try {
4136
+ context = vm.createContext?.() ?? globalThis;
4137
+ const filename2 = context.__filename = resolve(getFilename() ?? "");
4138
+ context.__dirname = dirname(filename2);
4139
+ context.require = createRequire(filename2);
4140
+ if (vm.runInContext != null) {
4141
+ for (const global of [
4142
+ "RegExp",
4143
+ "Date",
4144
+ "Set",
4145
+ "Map",
4146
+ "URL",
4147
+ "Int8Array",
4148
+ "Uint8Array",
4149
+ "Int16Array",
4150
+ "Uint16Array",
4151
+ "Int32Array",
4152
+ "Uint32Array",
4153
+ "Float32Array",
4154
+ "Float64Array",
4155
+ "Uint8ClampedArray",
4156
+ "BigInt64Array",
4157
+ "BigUint64Array",
4158
+ "Buffer"
4159
+ ]) {
4160
+ context[global] = globalThis[global];
4161
+ }
4162
+ context.Object2 = Object;
4163
+ output = vm.runInContext(js, context, {
4164
+ filename: filename2,
4165
+ importModuleDynamically: vm.constants?.USE_MAIN_CONTEXT_DEFAULT_LOADER
4166
+ });
4167
+ } else {
4168
+ output = eval?.(js);
4169
+ }
4170
+ } catch (e) {
4171
+ exp.children = [
4172
+ {
4173
+ type: "Error",
4174
+ message: `comptime block failed to execute: ${e}
4175
+ ${js}`
4176
+ }
4177
+ ];
4178
+ return;
4179
+ }
4135
4180
  let promise;
4136
4181
  if (exp.type === "ComptimeExpression") {
4137
4182
  const finish = () => {
4138
4183
  let string;
4139
4184
  try {
4140
- string = serialize(output);
4185
+ if (vm.runInContext != null) {
4186
+ context.output = output;
4187
+ string = vm.runInContext(
4188
+ `${serialize(serialize)}serialize(output)`,
4189
+ context
4190
+ );
4191
+ } else {
4192
+ string = serialize(output);
4193
+ }
4141
4194
  } catch (e) {
4142
4195
  exp.children = [
4143
4196
  {
@@ -4264,11 +4317,8 @@ function serialize(value) {
4264
4317
  })().join(",") + "])";
4265
4318
  break;
4266
4319
  }
4267
- case Array.prototype: {
4268
- ref1 = `[${val.map(recurse).join(",")}]`;
4269
- break;
4270
- }
4271
- case Object.prototype: {
4320
+ case Object.prototype:
4321
+ case globalThis.Object2?.prototype: {
4272
4322
  let objStr = "{";
4273
4323
  let descStr = "";
4274
4324
  for (let ref2 = Object.getOwnPropertyNames(val).concat(Object.getOwnPropertySymbols(val)), i = 0, len3 = ref2.length; i < len3; i++) {
@@ -4333,7 +4383,11 @@ function serialize(value) {
4333
4383
  break;
4334
4384
  }
4335
4385
  default: {
4336
- throw new TypeError(`cannot serialize object with prototype ${Object.getPrototypeOf(val)}`);
4386
+ if (Array.isArray(val)) {
4387
+ ref1 = `[${val.map(recurse).join(",")}]`;
4388
+ } else {
4389
+ throw new TypeError(`cannot serialize object with prototype ${val.constructor?.name ?? Object.getPrototypeOf(val)}`);
4390
+ }
4337
4391
  }
4338
4392
  }
4339
4393
  ;
@@ -4719,11 +4773,23 @@ function processCallMemberExpression(node) {
4719
4773
  }
4720
4774
  prefix = prefix.concat(glob.dot);
4721
4775
  for (const part of glob.object.properties) {
4776
+ if (part.type === "Error") {
4777
+ parts.push(part);
4778
+ continue;
4779
+ }
4722
4780
  if (part.type === "MethodDefinition") {
4723
- throw new Error("Glob pattern cannot have method definition");
4781
+ parts.push({
4782
+ type: "Error",
4783
+ message: "Glob pattern cannot have method definition"
4784
+ });
4785
+ continue;
4724
4786
  }
4725
4787
  if (part.value && !["CallExpression", "MemberExpression", "Identifier"].includes(part.value.type)) {
4726
- throw new Error(`Glob pattern must have call or member expression value, found ${JSON.stringify(part.value)}`);
4788
+ parts.push({
4789
+ type: "Error",
4790
+ message: `Glob pattern must have call or member expression value, found ${JSON.stringify(part.value)}`
4791
+ });
4792
+ continue;
4727
4793
  }
4728
4794
  let suppressPrefix = false;
4729
4795
  let name = part.name;
@@ -4872,6 +4938,10 @@ function lastAccessInCallExpression(exp) {
4872
4938
  }
4873
4939
  let children, i;
4874
4940
  do {
4941
+ if (!(exp.children != null)) {
4942
+ return;
4943
+ }
4944
+ ;
4875
4945
  ({ children } = exp);
4876
4946
  i = children.length - 1;
4877
4947
  while (i >= 0 && (children[i].type === "Call" || children[i].type === "NonNullAssertion" || children[i].type === "Optional"))
@@ -10976,6 +11046,7 @@ var _BinaryOp$1 = (0, import_lib2.$TV)(Identifier, function($skip, $loc, $0, $1)
10976
11046
  if (!state.operators.has(id.name))
10977
11047
  return $skip;
10978
11048
  return {
11049
+ token: id.name,
10979
11050
  call: id,
10980
11051
  special: true,
10981
11052
  ...state.operators.get(id.name)
@@ -10986,6 +11057,7 @@ var _BinaryOp$2 = (0, import_lib2.$TS)((0, import_lib2.$S)(OmittedNegation, __,
10986
11057
  if (!state.operators.has(id.name))
10987
11058
  return $skip;
10988
11059
  return {
11060
+ token: id.name,
10989
11061
  call: id,
10990
11062
  special: true,
10991
11063
  negated: true,
@@ -16627,6 +16699,21 @@ var StateCache = class {
16627
16699
 
16628
16700
  // source/main.civet
16629
16701
  var { SourceMap: SourceMap2 } = util_exports;
16702
+ var ParseErrors = class extends Error {
16703
+ name = "ParseErrors";
16704
+ filename;
16705
+ line;
16706
+ column;
16707
+ offset;
16708
+ constructor(message, filename1, line1, column1, offset1) {
16709
+ super(message);
16710
+ this.filename = filename1;
16711
+ this.line = line1;
16712
+ this.column = column1;
16713
+ this.offset = offset1;
16714
+ this.message = message;
16715
+ }
16716
+ };
16630
16717
  var uncacheable = /* @__PURE__ */ new Set([
16631
16718
  // Meta
16632
16719
  "DebugHere",
@@ -16736,7 +16823,7 @@ ${counts}`;
16736
16823
  }
16737
16824
  function checkErrors() {
16738
16825
  if (options.errors?.length) {
16739
- throw new Error(`Parse errors: ${options.errors.map(($) => $.message).join("\n")} `);
16826
+ throw new ParseErrors(options.errors.map(($) => $.message).join("\n"));
16740
16827
  }
16741
16828
  ;
16742
16829
  return;
@@ -16833,6 +16920,7 @@ var isCompileError = function(err) {
16833
16920
  };
16834
16921
  var main_default = { parse, parseProgram, generate: generate_default, util: util_exports, compile, isCompileError };
16835
16922
  export {
16923
+ ParseErrors,
16836
16924
  compile,
16837
16925
  main_default as default,
16838
16926
  generate_default as generate,
package/dist/types.d.ts CHANGED
@@ -82,6 +82,7 @@ declare module "@danielx/civet" {
82
82
  export function generate(ast: CivetAST, options?: CompileOptions): string
83
83
 
84
84
  const Civet: {
85
+ version: string
85
86
  compile: typeof compile
86
87
  isCompileError: typeof isCompileError
87
88
  parse: typeof parse
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@danielx/civet",
3
3
  "type": "commonjs",
4
- "version": "0.7.5",
4
+ "version": "0.7.6",
5
5
  "description": "CoffeeScript style syntax for TypeScript",
6
6
  "main": "dist/main.js",
7
7
  "module": "dist/main.mjs",
@@ -89,7 +89,7 @@
89
89
  "ts-node": "^10.9.1",
90
90
  "tslib": "^2.4.0",
91
91
  "tsup": "^7.2.0",
92
- "typescript": "^5.2.2",
92
+ "typescript": "^5.4.5",
93
93
  "vite": "^4.4.12",
94
94
  "vitepress": "^1.0.0-alpha.35",
95
95
  "vscode-languageserver": "^8.1.0",