{"version":3,"sources":["../src/parsers.ts"],"names":["NODE","tinyest","isDeclared","ctx","name","scope","BINARY_OP_MAP","LOGICAL_OP_MAP","ASSIGNMENT_OP_MAP","Transpilers","node","body","transpile","result","statement","wgslOp","left","right","argument","object","property","operator","_a","callee","args","arg","elem","decl","id","init","test","consequent","alternate","properties","prop","key","value","condition","update","transpiler"],"mappings":"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","file":"/Users/iwo/Projects/wigsill/packages/tinyest-for-wgsl/dist/index.cjs","sourcesContent":["import type * as babel from '@babel/types';\nimport type * as acorn from 'acorn';\nimport * as tinyest from 'tinyest';\nimport { FuncParameterType } from 'tinyest';\n\nconst { NodeTypeCatalog: NODE } = tinyest;\n\ntype Scope = {\n  /** identifiers declared in this scope */\n  declaredNames: string[];\n};\n\ntype Context = {\n  /** Holds a set of all identifiers that were used in code, but were not declared in code. */\n  externalNames: Set<string>;\n  /** Used to signal to identifiers that they should not treat their resolution as possible external uses. */\n  ignoreExternalDepth: number;\n  stack: Scope[];\n};\n\ntype JsNode = babel.Node | acorn.AnyNode;\n\nfunction isDeclared(ctx: Context, name: string) {\n  return ctx.stack.some((scope) => scope.declaredNames.includes(name));\n}\n\nconst BINARY_OP_MAP = {\n  '==': '==',\n  '!=': '!=',\n  '===': '==',\n  '!==': '!=',\n  '<': '<',\n  '<=': '<=',\n  '>': '>',\n  '>=': '>=',\n  '<<': '<<',\n  '>>': '>>',\n  get '>>>'(): never {\n    throw new Error('The `>>>` operator is unsupported in TGSL.');\n  },\n  '+': '+',\n  '-': '-',\n  '*': '*',\n  '/': '/',\n  '%': '%',\n  '|': '|',\n  '^': '^',\n  '&': '&',\n  get in(): never {\n    throw new Error('The `in` operator is unsupported in TGSL.');\n  },\n  get instanceof(): never {\n    throw new Error('The `instanceof` operator is unsupported in TGSL.');\n  },\n  get '**'(): never {\n    // TODO: Translate 'a ** b' into 'pow(a, b)'.\n    throw new Error(\n      'The `**` operator is unsupported in TGSL. Use std.pow() instead.',\n    );\n  },\n  get '|>'(): never {\n    throw new Error('The `|>` operator is unsupported in TGSL.');\n  },\n} as const;\n\nconst LOGICAL_OP_MAP = {\n  '||': '||',\n  '&&': '&&',\n  get '??'(): never {\n    throw new Error('The `??` operator is unsupported in TGSL.');\n  },\n} as const;\n\nconst ASSIGNMENT_OP_MAP = {\n  '=': '=',\n  '+=': '+=',\n  '-=': '-=',\n  '*=': '*=',\n  '/=': '/=',\n  '%=': '%=',\n  '<<=': '<<=',\n  '>>=': '>>=',\n  get '>>>='(): never {\n    throw new Error('The `>>>=` operator is unsupported in TGSL.');\n  },\n  '|=': '|=',\n  '^=': '^=',\n  '&=': '&=',\n  '**=': '**=',\n  '||=': '||=',\n  '&&=': '&&=',\n  get '??='(): never {\n    throw new Error('The `??=` operator is unsupported in TGSL.');\n  },\n} as const;\n\nconst Transpilers: Partial<\n  {\n    [Type in JsNode['type']]: (\n      ctx: Context,\n      node: Extract<JsNode, { type: Type }>,\n    ) => tinyest.AnyNode;\n  }\n> = {\n  Program(ctx, node) {\n    const body = node.body[0];\n\n    if (!body) {\n      throw new Error('tgpu.fn was not implemented correctly.');\n    }\n\n    return transpile(ctx, body);\n  },\n\n  ExpressionStatement: (ctx, node) => transpile(ctx, node.expression),\n\n  ArrowFunctionExpression: (ctx, node) => {\n    throw new Error('Arrow functions are not supported inside TGSL.');\n  },\n\n  BlockStatement(ctx, node) {\n    ctx.stack.push({ declaredNames: [] });\n\n    const result = [\n      NODE.block,\n      node.body.map(\n        (statement) => transpile(ctx, statement) as tinyest.Statement,\n      ),\n    ] as const;\n\n    ctx.stack.pop();\n\n    return result;\n  },\n\n  ReturnStatement: (ctx, node) =>\n    node.argument\n      ? [NODE.return, transpile(ctx, node.argument) as tinyest.Expression]\n      : [NODE.return],\n\n  Identifier(ctx, node) {\n    if (ctx.ignoreExternalDepth === 0 && !isDeclared(ctx, node.name)) {\n      ctx.externalNames.add(node.name);\n    }\n\n    return node.name;\n  },\n\n  BinaryExpression(ctx, node) {\n    const wgslOp = BINARY_OP_MAP[node.operator];\n    const left = transpile(ctx, node.left) as tinyest.Expression;\n    const right = transpile(ctx, node.right) as tinyest.Expression;\n    return [NODE.binaryExpr, left, wgslOp, right];\n  },\n\n  LogicalExpression(ctx, node) {\n    const wgslOp = LOGICAL_OP_MAP[node.operator];\n    const left = transpile(ctx, node.left) as tinyest.Expression;\n    const right = transpile(ctx, node.right) as tinyest.Expression;\n    return [NODE.logicalExpr, left, wgslOp, right];\n  },\n\n  AssignmentExpression(ctx, node) {\n    const wgslOp = ASSIGNMENT_OP_MAP[node.operator as acorn.AssignmentOperator];\n    const left = transpile(ctx, node.left) as tinyest.Expression;\n    const right = transpile(ctx, node.right) as tinyest.Expression;\n    return [NODE.assignmentExpr, left, wgslOp, right];\n  },\n\n  UnaryExpression(ctx, node) {\n    const wgslOp = node.operator;\n    const argument = transpile(ctx, node.argument) as tinyest.Expression;\n    return [NODE.unaryExpr, wgslOp, argument] as tinyest.UnaryExpression;\n  },\n\n  MemberExpression(ctx, node) {\n    const object = transpile(ctx, node.object) as tinyest.Expression;\n\n    // If the property is computed, it could potentially be an external identifier.\n    if (node.computed) {\n      const property = transpile(ctx, node.property) as tinyest.Expression;\n      return [NODE.indexAccess, object, property];\n    }\n\n    // If the property is not computed, we don't want to register identifiers as external.\n    ctx.ignoreExternalDepth++;\n    const property = transpile(ctx, node.property) as tinyest.Expression;\n    ctx.ignoreExternalDepth--;\n\n    if (typeof property !== 'string') {\n      throw new Error('Expected identifier as property access key.');\n    }\n\n    return [NODE.memberAccess, object, property];\n  },\n\n  UpdateExpression(ctx, node) {\n    const operator = node.operator;\n    const argument = transpile(ctx, node.argument) as tinyest.Expression;\n    if (node.prefix) {\n      throw new Error('Prefix update expressions are not supported in WGSL.');\n    }\n    return [NODE.postUpdate, operator, argument];\n  },\n\n  Literal(ctx, node) {\n    if (typeof node.value === 'boolean') {\n      return node.value;\n    }\n    if (typeof node.value === 'string') {\n      return [NODE.stringLiteral, node.value];\n    }\n    return [NODE.numericLiteral, node.raw ?? ''];\n  },\n\n  NumericLiteral(ctx, node) {\n    return [NODE.numericLiteral, String(node.value) ?? ''];\n  },\n\n  BooleanLiteral(ctx, node) {\n    return node.value;\n  },\n\n  StringLiteral(ctx, node) {\n    return [NODE.stringLiteral, node.value];\n  },\n\n  CallExpression(ctx, node) {\n    const callee = transpile(ctx, node.callee) as tinyest.Expression;\n\n    const args = node.arguments.map((arg) =>\n      transpile(ctx, arg)\n    ) as tinyest.Expression[];\n\n    return [NODE.call, callee, args];\n  },\n\n  ArrayExpression: (ctx, node) => [\n    NODE.arrayExpr,\n    node.elements.map((elem) => {\n      if (!elem || elem.type === 'SpreadElement') {\n        throw new Error('Spread elements are not supported in TGSL.');\n      }\n      return transpile(ctx, elem) as tinyest.Expression;\n    }),\n  ],\n\n  VariableDeclaration(ctx, node) {\n    if (node.declarations.length !== 1 || !node.declarations[0]) {\n      throw new Error(\n        'Currently only one declaration in a statement is supported.',\n      );\n    }\n\n    const decl = node.declarations[0];\n    ctx.ignoreExternalDepth++;\n    const id = transpile(ctx, decl.id);\n    ctx.ignoreExternalDepth--;\n\n    if (typeof id !== 'string') {\n      throw new Error('Invalid variable declaration, expected identifier.');\n    }\n\n    ctx.stack[ctx.stack.length - 1]?.declaredNames.push(id);\n\n    const init = decl.init\n      ? (transpile(ctx, decl.init) as tinyest.Expression)\n      : undefined;\n\n    if (node.kind === 'var') {\n      throw new Error('`var` declarations are not supported.');\n    }\n\n    if (node.kind === 'const') {\n      if (init === undefined) {\n        throw new Error(\n          'Did not provide initial value in `const` declaration.',\n        );\n      }\n      return [NODE.const, id, init];\n    }\n\n    return init !== undefined ? [NODE.let, id, init] : [NODE.let, id];\n  },\n\n  IfStatement(ctx, node) {\n    const test = transpile(ctx, node.test) as tinyest.Expression;\n    const consequent = transpile(ctx, node.consequent) as tinyest.Statement;\n    const alternate = node.alternate\n      ? (transpile(ctx, node.alternate) as tinyest.Statement)\n      : undefined;\n\n    return alternate\n      ? [NODE.if, test, consequent, alternate]\n      : [NODE.if, test, consequent];\n  },\n\n  ObjectExpression(ctx, node) {\n    const properties: Record<string, tinyest.Expression> = {};\n\n    for (const prop of node.properties) {\n      // TODO: Handle SpreadElement\n      if (prop.type === 'SpreadElement') {\n        throw new Error('Spread elements are not supported in TGSL.');\n      }\n\n      // TODO: Handle computed properties\n      if (prop.key.type !== 'Identifier' && prop.key.type !== 'Literal') {\n        throw new Error(\n          'Only Identifier and Literal keys are supported as object keys.',\n        );\n      }\n\n      // TODO: Handle Object method\n      if (prop.type === 'ObjectMethod') {\n        throw new Error('Object method elements are not supported in TGSL.');\n      }\n\n      ctx.ignoreExternalDepth++;\n      const key = prop.key.type === 'Identifier'\n        ? (transpile(ctx, prop.key) as string)\n        : String(prop.key.value);\n      ctx.ignoreExternalDepth--;\n      const value = transpile(ctx, prop.value) as tinyest.Expression;\n\n      properties[key] = value;\n    }\n\n    return [NODE.objectExpr, properties];\n  },\n\n  ForStatement(ctx, node) {\n    const init = node.init\n      ? (transpile(ctx, node.init) as tinyest.Statement)\n      : null;\n    const condition = node.test\n      ? (transpile(ctx, node.test) as tinyest.Expression)\n      : null;\n    const update = node.update\n      ? (transpile(ctx, node.update) as tinyest.Statement)\n      : null;\n    const body = transpile(ctx, node.body) as tinyest.Statement;\n\n    return [NODE.for, init, condition, update, body];\n  },\n\n  WhileStatement(ctx, node) {\n    const condition = transpile(ctx, node.test) as tinyest.Expression;\n    const body = transpile(ctx, node.body) as tinyest.Statement;\n    return [NODE.while, condition, body];\n  },\n\n  ContinueStatement() {\n    return [NODE.continue];\n  },\n\n  BreakStatement() {\n    return [NODE.break];\n  },\n\n  TSAsExpression(ctx, node) {\n    return transpile(ctx, node.expression);\n  },\n\n  TSSatisfiesExpression(ctx, node) {\n    return transpile(ctx, node.expression);\n  },\n};\n\nfunction transpile(ctx: Context, node: JsNode): tinyest.AnyNode {\n  const transpiler = Transpilers[node.type];\n\n  if (!transpiler) {\n    throw new Error(`Unsupported JS functionality: ${node.type}`);\n  }\n\n  // @ts-ignore <too much for typescript, it seems :/ >\n  return transpiler(ctx, node);\n}\n\nexport type TranspilationResult = {\n  params: tinyest.FuncParameter[];\n  body: tinyest.Block;\n  /**\n   * All identifiers found in the function code that are not declared in the\n   * function itself, or in the block that is accessing that identifier.\n   */\n  externalNames: string[];\n};\n\nexport function extractFunctionParts(rootNode: JsNode): {\n  params: tinyest.FuncParameter[];\n  body:\n    | acorn.BlockStatement\n    | acorn.Expression\n    | babel.BlockStatement\n    | babel.Expression;\n} {\n  let functionNode:\n    | acorn.ArrowFunctionExpression\n    | acorn.FunctionExpression\n    | acorn.FunctionDeclaration\n    | acorn.AnonymousFunctionDeclaration\n    | babel.ArrowFunctionExpression\n    | babel.FunctionExpression\n    | babel.FunctionDeclaration\n    | null = null;\n\n  // Unwrapping until we get to a function\n  let unwrappedNode = rootNode;\n  while (true) {\n    if (unwrappedNode.type === 'Program') {\n      const statement = unwrappedNode.body.filter(\n        (n) =>\n          n.type === 'ExpressionStatement' || n.type === 'FunctionDeclaration',\n      )[0]; // <- assuming only one function declaration\n\n      if (!statement) {\n        break;\n      }\n\n      unwrappedNode = statement;\n    } else if (unwrappedNode.type === 'ExpressionStatement') {\n      unwrappedNode = unwrappedNode.expression;\n    } else if (unwrappedNode.type === 'ArrowFunctionExpression') {\n      functionNode = unwrappedNode;\n      break; // We got a function\n    } else if (unwrappedNode.type === 'FunctionExpression') {\n      functionNode = unwrappedNode;\n      break; // We got a function\n    } else if (unwrappedNode.type === 'FunctionDeclaration') {\n      functionNode = unwrappedNode;\n      break; // We got a function\n    } else {\n      // Unsupported node\n      break;\n    }\n  }\n\n  if (!functionNode) {\n    throw new Error(\n      `tgpu.fn expected a single function to be passed as implementation ${\n        JSON.stringify(unwrappedNode)\n      }`,\n    );\n  }\n\n  if (functionNode.async) {\n    throw new Error('tgpu.fn cannot be async');\n  }\n\n  if (functionNode.generator) {\n    throw new Error('tgpu.fn cannot be a generator');\n  }\n\n  const unsupportedTypes = new Set(\n    functionNode.params.flatMap((param) =>\n      param.type === 'ObjectPattern' || param.type === 'Identifier'\n        ? []\n        : [param.type]\n    ),\n  );\n  if (unsupportedTypes.size > 0) {\n    throw new Error(\n      `Unsupported function parameter type(s): ${[...unsupportedTypes]}`,\n    );\n  }\n\n  return {\n    params: (functionNode\n      .params as (\n        | babel.Identifier\n        | acorn.Identifier\n        | babel.ObjectPattern\n        | acorn.ObjectPattern\n      )[]).map((param) =>\n        param.type === 'ObjectPattern'\n          ? {\n            type: FuncParameterType.destructuredObject,\n            props: param.properties.flatMap((prop) =>\n              (prop.type === 'Property' || prop.type === 'ObjectProperty') &&\n                prop.key.type === 'Identifier' &&\n                prop.value.type === 'Identifier'\n                ? [{ name: prop.key.name, alias: prop.value.name }]\n                : []\n            ),\n          }\n          : {\n            type: FuncParameterType.identifier,\n            name: param.name,\n          }\n      ),\n    body: functionNode.body,\n  };\n}\n\nexport function transpileFn(rootNode: JsNode): TranspilationResult {\n  const { params, body } = extractFunctionParts(rootNode);\n\n  const ctx: Context = {\n    externalNames: new Set(),\n    ignoreExternalDepth: 0,\n    stack: [\n      {\n        declaredNames: params.flatMap((param) =>\n          param.type === FuncParameterType.identifier\n            ? param.name\n            : param.props.map((prop) => prop.alias)\n        ),\n      },\n    ],\n  };\n\n  const tinyestBody = transpile(ctx, body);\n  const externalNames = [...ctx.externalNames];\n\n  if (body.type === 'BlockStatement') {\n    return {\n      params,\n      body: tinyestBody as tinyest.Block,\n      externalNames,\n    };\n  }\n\n  return {\n    params,\n    body: [NODE.block, [[NODE.return, tinyestBody as tinyest.Expression]]],\n    externalNames,\n  };\n}\n\nexport function transpileNode(node: JsNode): tinyest.AnyNode {\n  const ctx: Context = {\n    externalNames: new Set(),\n    ignoreExternalDepth: 0,\n    stack: [\n      {\n        declaredNames: [],\n      },\n    ],\n  };\n\n  return transpile(ctx, node);\n}\n"]}