<commit_before>/// <reference path="ast.ts" />
/// <reference path="visit.ts" />
/// <reference path="util.ts" />
/// <reference path="pretty.ts" />

// The kinds of types.
type Type = IntType | FunType | CodeType;

// There is only one Int type.
class IntType {};
const INT = new IntType();

// But function types are more complicated. Really wishing for ADTs here.
class FunType {
  constructor(public params: Type[], public ret: Type) {}
};

// Same with code types.
class CodeType {
  constructor(public inner: Type) {}
};

// A single frame in a type environment holds all the bindings for one stage.
interface TypeEnvFrame {
  [key: string]: Type;
}

// An environment is a stack stack with the current stage at the front of the
// list. Prior stages are to the right. Normal accesses must refer to the top
// environment frame; subsequent ones are "auto-persists".
type TypeEnv = TypeEnvFrame[];


// Type rules.

let Typecheck : ASTVisit<[TypeEnv, number], [Type, TypeEnv]> = {
  visit_literal(tree: LiteralNode, [env, level]: [TypeEnv, number]):
      [Type, TypeEnv] {
    return [INT, env];
  },

  visit_seq(tree: SeqNode, [env, level]: [TypeEnv, number]): [Type, TypeEnv] {
    let [t, e] = check(tree.lhs, env, level);
    return check(tree.rhs, e, level);
  },

  visit_let(tree: LetNode, [env, level]: [TypeEnv, number]): [Type, TypeEnv] {
    let [t, e] = check(tree.expr, env, level);
    let head = overlay(hd(e)); // Update type in an overlay environment.
    head[tree.ident] = t;
    let e2 = cons(head, tl(e));
    return [t, e2];
  },<commit_msg>Start extensible type checker wrapping<commit_after>/// <reference path="ast.ts" />
/// <reference path="visit.ts" />
/// <reference path="util.ts" />
/// <reference path="pretty.ts" />

// The kinds of types.
type Type = IntType | FunType | CodeType;

// There is only one Int type.
class IntType {
  // A workaround to compensate for TypeScript's structural subtyping:
  // https://github.com/Microsoft/TypeScript/issues/202
  _nominal_IntType: void;
};
const INT = new IntType();

// But function types are more complicated. Really wishing for ADTs here.
class FunType {
  constructor(public params: Type[], public ret: Type) {};
  _nominal_FunType: void;
};

// Same with code types.
class CodeType {
  constructor(public inner: Type) {};
  _nominal_CodeType: void;
};

// A single frame in a type environment holds all the bindings for one stage.
interface TypeEnvFrame {
  [key: string]: Type;
}

// An environment is a stack stack with the current stage at the front of the
// list. Prior stages are to the right. Normal accesses must refer to the top
// environment frame; subsequent ones are "auto-persists".
type TypeEnv = TypeEnvFrame[];


// Type rules.

type Gen <T> = (_:T) => T;
type TypeCheck = (tree: SyntaxNode, [env, level]: [TypeEnv, number]) => [Type, TypeEnv];
let gen_check : Gen<TypeCheck> = function(fself) {
  return function (tree, [env, level]) {
    return [INT, env];
  }
}

let Typecheck : ASTVisit<[TypeEnv, number], [Type, TypeEnv]> = {
  visit_literal(tree: LiteralNode, [env, level]: [TypeEnv, number]):
      [Type, TypeEnv] {
    return [INT, env];
  },

  visit_seq(tree: SeqNode, [env, level]: [TypeEnv, number]): [Type, TypeEnv] {
    let [t, e] = check(tree.lhs, env, level);
    return check(tree.rhs, e, level);
  },

  visit_let(tree: LetNode, [env, level]: [TypeEnv, number]): [Type, TypeEnv] {
    let [t, e] = check(tree.expr, env, level);
    let head = overlay(hd(e)); // Update type in an overlay environment.
    head[tree.ident] = t;
    let e2 = cons(head, tl(e));
    return [t, e2];
  },
{'fraction_non_alphanumeric': 0.1508859357696567, 'fraction_numerical': 0.001937984496124031, 'mean_word_length': 3.561868686868687, 'pattern_counts': {'":': 0, '<': 15, '<?xml version=': 0, '>': 17, 'https://': 1, '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': '1006929', 'n_tokens_mistral': 1194, 'n_tokens_neox': 1167, 'n_words': 414}