# All files / src/generator map-syntax.js

100% Statements 36/36
75% Branches 6/8
100% Functions 2/2
100% Lines 36/36

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    22x
    22x
    22x
    22x
    22x
    22x
    22x
    22x
    22x
    22x
    22x
    22x
    22x
    22x
    22x
    22x
    22x
    22x
    22x

    22x
    22x
    22x
    22x

    22x

    22x

    22x
    1529x
    1529x

    1x

    1x

    1528x
    7004x

    1528x
    1526x
    1234x

    1526x

     // @flow
    import generateFunctionCall from "./function-call";
    import generateIndirectFunctionCall from "./indirect-function-call";
    import generateBinaryExpression from "./binary-expression";
    import generateTernary from "./ternary-expression";
    import generateIf from "./if-then-else";
    import generateFunctionPointer from "./function-pointer";
    import generateReturn from "./return-statement";
    import generateDeclaration from "./declaration";
    import generateArraySubscript from "./array-subscript";
    import generateAssignment from "./assignment";
    import generateMemoryAssignment from "./memory-assignment";
    import generateLoop from "./loop";
    import generateSequence from "./sequence";
    import generateTypecast from "./typecast";
    import generateBreak from "./break";
    import generateNoop from "./noop";
    import generateBlock from "./block";
    import generateElse from "./else";
    import generateSelect from "./select";

    import Syntax from "../Syntax";
    import { getInScope, getConstOpcode } from "./utils";
    import curry from "curry";
    import invariant from "invariant";
    import type { MapSyntaxType, GeneratorType } from "./flow/types";

    import printNode from "../utils/print-node";

    export const syntaxMap: { [string]: GeneratorType } = {
      [Syntax.FunctionCall]: generateFunctionCall,
      [Syntax.IndirectFunctionCall]: generateIndirectFunctionCall,
      // Unary
      [Syntax.Constant]: getConstOpcode,
      [Syntax.BinaryExpression]: generateBinaryExpression,
      [Syntax.TernaryExpression]: generateTernary,
      [Syntax.IfThenElse]: generateIf,
      [Syntax.Else]: generateElse,
      [Syntax.Select]: generateSelect,
      [Syntax.Block]: generateBlock,
      [Syntax.Identifier]: getInScope,
      [Syntax.FunctionIdentifier]: getInScope,
      [Syntax.FunctionPointer]: generateFunctionPointer,
      [Syntax.ReturnStatement]: generateReturn,
      // Binary
      [Syntax.Declaration]: generateDeclaration,
      [Syntax.ArraySubscript]: generateArraySubscript,
      [Syntax.Assignment]: generateAssignment,
      // Memory
      [Syntax.MemoryAssignment]: generateMemoryAssignment,
      // Loops
      [Syntax.Loop]: generateLoop,
      [Syntax.Break]: generateBreak,
      // Comma separated lists
      [Syntax.Sequence]: generateSequence,
      // Typecast
      [Syntax.TypeCast]: generateTypecast,
      [Syntax.Noop]: generateNoop,
    };

    const mapSyntax: MapSyntaxType = curry((parent, operand) => {
      const mapping = syntaxMap[operand.Type];
      if (!mapping) {
        const value =
          operand.id ||
          operand.value ||
          (operand.operator && operand.operator.value);
        throw new Error(`Unexpected Syntax Token ${operand.Type} : ${value}`);
      }

      const validate = (block, i) =>
        invariant(
          block.kind,
          "Unknown opcode generated in block index %s %s. \nOperand: \n%s",
          i,
          JSON.stringify(block),
          printNode(operand)
        );
      const blocks = mapping(operand, parent);
      if (Array.isArray(blocks)) {
        blocks.forEach(validate);
      }

      return blocks;
    });

    export default mapSyntax;