<commit_before>// @flow

import type { ASTNode } from '../src/parser.js';
import {
  throwEmptyListError,
  throwEmptyApplicationError,
} from './errors';

export type Compiler = (node: ASTNode) => string;

const firstChildType =
  (node: ASTNode): string => node.children[0].body.type;

const isApplication =
  (node: ASTNode): boolean => firstChildType(node) !== 'VAR_DEC' && firstChildType(node) !== 'LAMBDA_DEC';

type TokenHandler = (node: ASTNode, compile: Compiler) => string;

type TokenHandlers = {
  PROGRAM: TokenHandler,
  VAR_DEC: TokenHandler,
  LAMBDA_DEC: TokenHandler,
  LAMBDA_APPLICATION: TokenHandler,
  ATOM: TokenHandler,
  LIST: TokenHandler,
};
//TODO: move to parser
const buildLambdaApplicationNode = (lambdaNode: ASTNode, argumentNode: ASTNode): ASTNode => ({
  type: 'LAMBDA_APPLICATION',
  body: {
    lambda: lambdaNode,
    argument: argumentNode,
  },
  children: [],
});

const getCompiler = (tokenHandlers: TokenHandlers): Compiler => {
  const heap = {};
  return function Compile(node: ASTNode): string {
    const nodeType = node.body.type;
    if (nodeType === 'LIST') {
      node.children.length === 0 && throwEmptyListError();
      if (isApplication(node)) {
        node.children.length < 2 && throwEmptyApplicationError();
        return tokenHandlers.LAMBDA_APPLICATION(buildLambdaApplicationNode(...node.children), Compile);
      }
      return node.children.map(Compile).join('');
    }<commit_msg>make flow happier<commit_after>// @flow

import type { ASTNode } from '../src/parser.js';
import {
  throwEmptyListError,
  throwEmptyApplicationError,
} from './errors';

export type Compiler = (node: ASTNode) => string;

const firstChildType =
  (node: ASTNode): string => node.children[0].body.type;

const isApplication =
  (node: ASTNode): boolean => firstChildType(node) !== 'VAR_DEC' && firstChildType(node) !== 'LAMBDA_DEC';

type TokenHandler = (node: ASTNode, compile: Compiler, heap: {}) => string;

type TokenHandlers = {
  PROGRAM: TokenHandler,
  VAR_DEC: TokenHandler,
  LAMBDA_DEC: TokenHandler,
  LAMBDA_APPLICATION: TokenHandler,
  ATOM: TokenHandler,
  LIST: TokenHandler,
};
//TODO: move to parser
const buildLambdaApplicationNode = (lambdaNode: ASTNode, argumentNode: ASTNode): ASTNode => ({
  type: 'LAMBDA_APPLICATION',
  body: {
    lambda: lambdaNode,
    argument: argumentNode,
  },
  children: [],
});

const getCompiler = (tokenHandlers: TokenHandlers): Compiler => {
  const heap = {};
  return function Compile(node: ASTNode): string {
    const nodeType = node.body.type;
    if (nodeType === 'LIST') {
      node.children.length === 0 && throwEmptyListError();
      if (isApplication(node)) {
        node.children.length < 2 && throwEmptyApplicationError();
        return tokenHandlers.LAMBDA_APPLICATION(buildLambdaApplicationNode(...node.children), Compile, heap);
      }
      return node.children.map(Compile).join('');
    }
{'fraction_non_alphanumeric': 0.1404532967032967, 'fraction_numerical': 0.0020604395604395605, 'mean_word_length': 4.315693430656935, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 15, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '758736', 'n_tokens_mistral': 939, 'n_tokens_neox': 903, 'n_words': 212}