<commit_before>import { SyntaxNode, RootNode, ExpressionNode } from './ast';
import { TypeMap, BUILTIN_TYPES, pretty_type } from './type';
import { BUILTIN_OPERATORS, TypeCheck, gen_check } from './type_check';
import { desugar_cross_stage, desugar_macros } from './sugar';
import * as interp from './interp';
import { compose, assign, Gen, scope_eval } from './util';
import { TypeTable, elaborate } from './type_elaborate';
import * as webgl from './backends/webgl';
import * as gl from './backends/gl';
import * as glsl from './backends/glsl';
import * as js from './backends/js';
import { CompilerIR } from './compile/ir';
import { semantically_analyze } from './compile/compile';
import parser = require('../parser');
import { pretty } from './pretty';

// This is a helper library that orchestrates all the parts of the compiler in
// a configurable way. You invoke it by passing continuations through all the
// steps using a configuration object that handles certain events. The steps
// are:
//
// - `frontend`: Parse, typecheck, and desugar. This needs to be done
//   regardless of whether you want to compile or interpret.
// - `interpret`: More or less what it sounds like.
// - `compile`: Compile the checked code to executable code.
// - `execute`: Run the compiled code, hopefully getting the same
//   result as the interpreter would.

/**
 * Configuration for the driver.
 */
export interface Config {
  webgl: boolean;

  // Expect the program to produce a code value, and just produce the
  // read-to-execute generated code.
  generate: boolean;

  parsed: (tree: SyntaxNode) => void;
  typed: (type: string) => void;
  error: (err: string) => void;
  log: (...msg: any[]) => void;

  /**
   * Whether to use the "presplicing" compiler optimization.
   */
  presplice: boolean;
}

function _intrinsics(config: Config): TypeMap {
  if (config.webgl) {
    return gl.INTRINSICS;
  } else {
    return BUILTIN_OPERATORS;
  }
}

function _runtime(config: Config): string {
  let runtime = js.RUNTIME + "\n";
  if (config.webgl) {
    runtime += webgl.RUNTIME + "\n";
  }
  return runtime;
}

function _types(config: Config): TypeMap {
  if (config.webgl) {
    return assign({}, BUILTIN_TYPES, gl.GL_TYPES);
  } else {
    return BUILTIN_TYPES;
  }
}

function _check(config: Config): Gen<TypeCheck> {
  let check = gen_check;
  if (config.webgl) {
    check = compose(glsl.type_mixin, check);
  }
  return check;
}

export function frontend(config: Config, sources: string[],
    filenames: string[] | null,
    checked: (tree: SyntaxNode, type_table: TypeTable) => void)
{
  if (sources.length != filenames.length) { throw 'Sources and Filenames must have same length'; }

  let emptyExpressionNodeArray: ExpressionNode[] = [];
  let root: RootNode = { tag: "root", children: emptyExpressionNodeArray };

  for (var i = 0; i < sources.length; i++) {
    let source: string = sources[i];
    let filename: string = filenames[i];

    // Parse.<commit_msg>fixed filenames nullable compile issues in driver<commit_after>import { SyntaxNode, RootNode, ExpressionNode } from './ast';
import { TypeMap, BUILTIN_TYPES, pretty_type } from './type';
import { BUILTIN_OPERATORS, TypeCheck, gen_check } from './type_check';
import { desugar_cross_stage, desugar_macros } from './sugar';
import * as interp from './interp';
import { compose, assign, Gen, scope_eval } from './util';
import { TypeTable, elaborate } from './type_elaborate';
import * as webgl from './backends/webgl';
import * as gl from './backends/gl';
import * as glsl from './backends/glsl';
import * as js from './backends/js';
import { CompilerIR } from './compile/ir';
import { semantically_analyze } from './compile/compile';
import parser = require('../parser');
import { pretty } from './pretty';

// This is a helper library that orchestrates all the parts of the compiler in
// a configurable way. You invoke it by passing continuations through all the
// steps using a configuration object that handles certain events. The steps
// are:
//
// - `frontend`: Parse, typecheck, and desugar. This needs to be done
//   regardless of whether you want to compile or interpret.
// - `interpret`: More or less what it sounds like.
// - `compile`: Compile the checked code to executable code.
// - `execute`: Run the compiled code, hopefully getting the same
//   result as the interpreter would.

/**
 * Configuration for the driver.
 */
export interface Config {
  webgl: boolean;

  // Expect the program to produce a code value, and just produce the
  // read-to-execute generated code.
  generate: boolean;

  parsed: (tree: SyntaxNode) => void;
  typed: (type: string) => void;
  error: (err: string) => void;
  log: (...msg: any[]) => void;

  /**
   * Whether to use the "presplicing" compiler optimization.
   */
  presplice: boolean;
}

function _intrinsics(config: Config): TypeMap {
  if (config.webgl) {
    return gl.INTRINSICS;
  } else {
    return BUILTIN_OPERATORS;
  }
}

function _runtime(config: Config): string {
  let runtime = js.RUNTIME + "\n";
  if (config.webgl) {
    runtime += webgl.RUNTIME + "\n";
  }
  return runtime;
}

function _types(config: Config): TypeMap {
  if (config.webgl) {
    return assign({}, BUILTIN_TYPES, gl.GL_TYPES);
  } else {
    return BUILTIN_TYPES;
  }
}

function _check(config: Config): Gen<TypeCheck> {
  let check = gen_check;
  if (config.webgl) {
    check = compose(glsl.type_mixin, check);
  }
  return check;
}

export function frontend(config: Config, sources: string[],
    filenames: string[] | null,
    checked: (tree: SyntaxNode, type_table: TypeTable) => void)
{
  let emptyExpressionNodeArray: ExpressionNode[] = [];
  let root: RootNode = { tag: "root", children: emptyExpressionNodeArray };

  for (var i = 0; i < sources.length; i++) {
    let source: string = sources[i];
    let filename: string | null = (filenames != null && i < sources.length) ? filenames[i] : null;

    // Parse.
{'fraction_non_alphanumeric': 0.13333333333333333, 'fraction_numerical': 0.0003367003367003367, 'mean_word_length': 3.6305533904910368, 'pattern_counts': {'":': 0, '<': 8, '<?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': '3339099', 'n_tokens_mistral': 1863, 'n_tokens_neox': 1841, 'n_words': 636}