(node: p.TSESTree.Expression, ctx: Context)
| 672 | |
| 673 | // Convert estree expression node to our simplified node definition |
| 674 | function convertExpr(node: p.TSESTree.Expression, ctx: Context): Term { |
| 675 | switch (node.type) { |
| 676 | case "UnaryExpression": { |
| 677 | if (node.operator !== "!") error(`unsupported operator: ${node.operator}`, node); |
| 678 | const body = convertExpr(node.argument, ctx); |
| 679 | return { tag: "not", cond: body, loc: node.loc }; |
| 680 | } |
| 681 | // deno-lint-ignore no-fallthrough |
| 682 | case "BinaryExpression": { |
| 683 | if (node.left.type === "PrivateIdentifier") error("private identifer is not allowed", node.left); |
| 684 | switch (node.operator) { |
| 685 | case "+": { |
| 686 | const left = convertExpr(node.left, ctx); |
| 687 | const right = convertExpr(node.right, ctx); |
| 688 | return { tag: "add", left, right, loc: node.loc }; |
| 689 | } |
| 690 | case "===": |
| 691 | case "!==": { |
| 692 | const left = convertExpr(node.left, ctx); |
| 693 | const right = convertExpr(node.right, ctx); |
| 694 | return { tag: "compare", op: node.operator, left, right, loc: node.loc }; |
| 695 | } |
| 696 | case "in": { |
| 697 | const key = convertExpr(node.left, ctx); |
| 698 | const record = convertExpr(node.right, ctx); |
| 699 | return { tag: "recordIn", record, key, loc: node.loc }; |
| 700 | } |
| 701 | default: |
| 702 | error(`unsupported operator: ${node.operator}`, node); |
| 703 | } |
| 704 | } |
| 705 | case "Identifier": |
| 706 | return { tag: "var", name: node.name, loc: node.loc }; |
| 707 | // deno-lint-ignore no-fallthrough |
| 708 | case "Literal": |
| 709 | switch (typeof node.value) { |
| 710 | case "number": |
| 711 | return { tag: "number", n: node.value, loc: node.loc }; |
| 712 | case "boolean": |
| 713 | return { tag: node.value ? "true" : "false", loc: node.loc }; |
| 714 | case "string": |
| 715 | return { tag: "string", s: node.value, loc: node.loc }; |
| 716 | default: |
| 717 | error(`unsupported literal: ${node.value}`, node); |
| 718 | } |
| 719 | case "ArrowFunctionExpression": { |
| 720 | const typeParams = node.typeParameters?.params.map((typeParameter) => typeParameter.name.name); |
| 721 | const newCtx = typeParams ? extendContextWithTypeVars(ctx, typeParams) : ctx; |
| 722 | const params = node.params.map((param) => { |
| 723 | const { name, type } = getParam(param); |
| 724 | return { name, type: simplifyType(type, newCtx) }; |
| 725 | }); |
| 726 | let retType; |
| 727 | if (node.returnType) { |
| 728 | retType = simplifyType(convertType(node.returnType.typeAnnotation), ctx); |
| 729 | } |
| 730 | const body = node.body.type === "BlockStatement" |
| 731 | ? convertStmts(node.body.body, true, newCtx) |
no test coverage detected