@thigasdevelopment/luam 0.10.0 → 0.10.1

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.
Files changed (2) hide show
  1. package/luam.mjs +73 -11
  2. package/package.json +1 -1
package/luam.mjs CHANGED
@@ -3686,7 +3686,8 @@ function scan(source) {
3686
3686
  }
3687
3687
 
3688
3688
  // ../compiler/src/parser/type-annotation.ts
3689
- var TYPE_KEYWORDS = /* @__PURE__ */ new Set(["nil", "true", "false"]);
3689
+ var TYPE_KEYWORDS = /* @__PURE__ */ new Set(["nil"]);
3690
+ var BOOLEAN_KEYWORDS = /* @__PURE__ */ new Set(["true", "false"]);
3690
3691
  var FUNCTION_TYPE = "fun";
3691
3692
  function parseTypeName(stream) {
3692
3693
  const token = stream.current();
@@ -3776,11 +3777,24 @@ function parseObjectType(stream) {
3776
3777
  stream.expect("punctuation", "}");
3777
3778
  return { kind: "type-object", members, position: position2 };
3778
3779
  }
3780
+ function parseNumberLiteralType(stream) {
3781
+ const sign = stream.check("operator", "-") ? stream.next() : null;
3782
+ const token = stream.expect("number");
3783
+ const value = Number(token.value);
3784
+ return { kind: "type-number-literal", value: sign === null ? value : -value, position: sign?.position ?? token.position };
3785
+ }
3779
3786
  function parsePrimaryType(stream) {
3780
3787
  if (stream.check("string")) {
3781
3788
  const token = stream.next();
3782
3789
  return { kind: "type-string-literal", value: token.value, position: token.position };
3783
3790
  }
3791
+ if (stream.check("number") || stream.check("operator", "-") && stream.checkAhead(1, "number")) {
3792
+ return parseNumberLiteralType(stream);
3793
+ }
3794
+ if (stream.check("keyword") && BOOLEAN_KEYWORDS.has(stream.current().value)) {
3795
+ const token = stream.next();
3796
+ return { kind: "type-boolean-literal", value: token.value === "true", position: token.position };
3797
+ }
3784
3798
  if (stream.check("keyword", "function")) {
3785
3799
  throw stream.error(`Use "${FUNCTION_TYPE}" for function types. "function" is a keyword and cannot name a type.`, "parse-invalid-type");
3786
3800
  }
@@ -4792,7 +4806,22 @@ function createMap(key, value) {
4792
4806
  function createStringLiteral(value) {
4793
4807
  return { kind: "string-literal", value };
4794
4808
  }
4809
+ function createBooleanLiteral(value) {
4810
+ return { kind: "boolean-literal", value };
4811
+ }
4812
+ function createNumberLiteral(value) {
4813
+ return { kind: "number-literal", value };
4814
+ }
4815
+ function isLiteralType(type) {
4816
+ return type.kind === "string-literal" || type.kind === "boolean-literal" || type.kind === "number-literal";
4817
+ }
4795
4818
  function widenLiteral(type) {
4819
+ if (type.kind === "boolean-literal") {
4820
+ return BOOLEAN_TYPE;
4821
+ }
4822
+ if (type.kind === "number-literal") {
4823
+ return NUMBER_TYPE;
4824
+ }
4796
4825
  return type.kind === "string-literal" ? STRING_TYPE : type;
4797
4826
  }
4798
4827
  function createRecord(name, members, origin = null) {
@@ -4877,6 +4906,9 @@ function typeToString(type) {
4877
4906
  if (type.kind === "string-literal") {
4878
4907
  return `'${type.value.replace(/(['\\])/g, "\\$1")}'`;
4879
4908
  }
4909
+ if (type.kind === "boolean-literal" || type.kind === "number-literal") {
4910
+ return String(type.value);
4911
+ }
4880
4912
  if (type.kind === "named" || type.kind === "record") {
4881
4913
  return type.name;
4882
4914
  }
@@ -4912,13 +4944,13 @@ function isTableLike(type) {
4912
4944
  }
4913
4945
  function isBooleanType(type) {
4914
4946
  const resolved2 = type?.kind === "optional" ? type.element : type;
4915
- return resolved2?.kind === "boolean";
4947
+ return resolved2?.kind === "boolean" || resolved2?.kind === "boolean-literal";
4916
4948
  }
4917
4949
  function isNumeric(type) {
4918
4950
  if (type.kind === "union") {
4919
4951
  return type.options.every(isNumeric);
4920
4952
  }
4921
- return type.kind === "number" || type.kind === "any" || type.kind === "unknown" || type.kind === "named";
4953
+ return type.kind === "number" || type.kind === "number-literal" || type.kind === "any" || type.kind === "unknown" || type.kind === "named";
4922
4954
  }
4923
4955
  function isConcatenable(type) {
4924
4956
  if (type.kind === "union") {
@@ -5013,7 +5045,13 @@ function isAssignable(source, target, options = { allowNil: false }) {
5013
5045
  if (source.kind === "string-literal") {
5014
5046
  return target.kind === "string" || target.kind === "string-literal" && source.value === target.value;
5015
5047
  }
5016
- if (target.kind === "string-literal") {
5048
+ if (source.kind === "boolean-literal") {
5049
+ return target.kind === "boolean" || target.kind === "boolean-literal" && source.value === target.value;
5050
+ }
5051
+ if (source.kind === "number-literal") {
5052
+ return target.kind === "number" || target.kind === "number-literal" && source.value === target.value;
5053
+ }
5054
+ if (isLiteralType(target)) {
5017
5055
  return false;
5018
5056
  }
5019
5057
  return source.kind === target.kind;
@@ -5999,7 +6037,7 @@ import { tmpdir } from "node:os";
5999
6037
  import { join as join2 } from "node:path";
6000
6038
 
6001
6039
  // src/cli/version.ts
6002
- var VERSION = true ? "0.10.0" : "0.0.0-dev";
6040
+ var VERSION = true ? "0.10.1" : "0.0.0-dev";
6003
6041
  var PROGRAM_NAME = "luam";
6004
6042
  var PROGRAM_DESCRIPTION = "luam \u2014 the Luam compiler for Multi Theft Auto resources.";
6005
6043
 
@@ -7198,6 +7236,9 @@ var Binder = class {
7198
7236
  lookupAlias(name) {
7199
7237
  return this.aliases.get(name) ?? null;
7200
7238
  }
7239
+ resolvedAliases() {
7240
+ return new Map([...this.aliases].map(([name, info]) => [name, info.type]));
7241
+ }
7201
7242
  };
7202
7243
 
7203
7244
  // ../mta-types/src/lua-standard.ts
@@ -11287,6 +11328,12 @@ var CheckContext = class {
11287
11328
  if (annotation.kind === "type-string-literal") {
11288
11329
  return createStringLiteral(annotation.value);
11289
11330
  }
11331
+ if (annotation.kind === "type-boolean-literal") {
11332
+ return createBooleanLiteral(annotation.value);
11333
+ }
11334
+ if (annotation.kind === "type-number-literal") {
11335
+ return createNumberLiteral(annotation.value);
11336
+ }
11290
11337
  if (annotation.kind === "type-object") {
11291
11338
  const members = /* @__PURE__ */ new Map();
11292
11339
  for (const member of annotation.members) {
@@ -11309,7 +11356,7 @@ var CheckContext = class {
11309
11356
  if (isAssignable(source, target, { allowNil: this.allowNil })) {
11310
11357
  return;
11311
11358
  }
11312
- const received = target.kind === "string-literal" || target.kind === "union" ? source : widenLiteral(source);
11359
+ const received = isLiteralType(target) || target.kind === "union" ? source : widenLiteral(source);
11313
11360
  const message = `${subject} expects "${typeToString(target)}" but received "${typeToString(received)}".`;
11314
11361
  this.report("check-type-mismatch", `${message}${nilHint(source, target, this.mode)}`, position2);
11315
11362
  }
@@ -12350,6 +12397,9 @@ function checkUnary(context, operator, operand, expression) {
12350
12397
  if (operator === "-" && !isNumeric(operand)) {
12351
12398
  reportInvalidOperand(context, operator, operand, expression);
12352
12399
  }
12400
+ if (operator === "-" && operand.kind === "number-literal") {
12401
+ return context.record(expression, createNumberLiteral(-operand.value));
12402
+ }
12353
12403
  return context.record(expression, NUMBER_TYPE);
12354
12404
  }
12355
12405
 
@@ -12426,7 +12476,8 @@ var EXTENSION_RESULTS = {
12426
12476
  table: TABLE_TYPE
12427
12477
  };
12428
12478
  function extensionType(receiver, property) {
12429
- const kind = receiver.kind === "string-literal" ? "string" : receiver.kind === "string" || receiver.kind === "number" ? receiver.kind : null;
12479
+ const literal = receiver.kind === "string-literal" ? "string" : receiver.kind === "number-literal" ? "number" : null;
12480
+ const kind = literal ?? (receiver.kind === "string" || receiver.kind === "number" ? receiver.kind : null);
12430
12481
  const target = kind ?? (isTableLike(receiver) ? "table" : null);
12431
12482
  if (target === null) {
12432
12483
  return null;
@@ -12574,9 +12625,9 @@ function checkMultiValueExpression(context, expression) {
12574
12625
  case "nil-literal":
12575
12626
  return context.record(expression, NIL_TYPE);
12576
12627
  case "boolean-literal":
12577
- return context.record(expression, BOOLEAN_TYPE);
12628
+ return context.record(expression, createBooleanLiteral(expression.value));
12578
12629
  case "number-literal":
12579
- return context.record(expression, NUMBER_TYPE);
12630
+ return context.record(expression, createNumberLiteral(expression.value));
12580
12631
  case "string-literal":
12581
12632
  return context.record(expression, createStringLiteral(expression.value));
12582
12633
  case "template-literal":
@@ -12823,11 +12874,21 @@ function checkEnumDeclaration(context, statement) {
12823
12874
  }
12824
12875
 
12825
12876
  // ../compiler/src/checker/discriminant.ts
12877
+ function literalValue(expression) {
12878
+ if (expression.kind === "string-literal") {
12879
+ return createStringLiteral(expression.value);
12880
+ }
12881
+ if (expression.kind === "boolean-literal") {
12882
+ return createBooleanLiteral(expression.value);
12883
+ }
12884
+ return expression.kind === "number-literal" ? createNumberLiteral(expression.value) : null;
12885
+ }
12826
12886
  function discriminantTest(left, right) {
12827
- if (left.kind !== "member-expression" || left.object.kind !== "identifier" || right.kind !== "string-literal") {
12887
+ if (left.kind !== "member-expression" || left.object.kind !== "identifier") {
12828
12888
  return null;
12829
12889
  }
12830
- return { name: left.object.name, property: left.property, value: createStringLiteral(right.value) };
12890
+ const value = literalValue(right);
12891
+ return value === null ? null : { name: left.object.name, property: left.property, value };
12831
12892
  }
12832
12893
  function subjectType(context, name) {
12833
12894
  const type = context.narrowedType(name) ?? context.binder.lookup(name)?.type ?? null;
@@ -13331,6 +13392,7 @@ function check(program2, mode, environment = DEFAULT_ENVIRONMENT, options = {})
13331
13392
  types: context.types,
13332
13393
  references: context.references,
13333
13394
  declarations: context.declarations,
13395
+ aliases: context.binder.resolvedAliases(),
13334
13396
  declaredGlobals: context.declaredGlobals,
13335
13397
  externalReferences: externalReferences(context),
13336
13398
  directives: directives.directives,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@thigasdevelopment/luam",
3
- "version": "0.10.0",
3
+ "version": "0.10.1",
4
4
  "description": "The Luam compiler for Multi Theft Auto resources.",
5
5
  "keywords": [
6
6
  "mta",