164 Midterm Prep
As of 12:35AM October 28th 2025, I am in poor shape.
FINAL PREP¶
- types
- constructors
- values
Expression: resolves to a value
- returns anything but a Unit
- ex: 3
Statement: expresses an action to be carried out
- returns a Unit (equivalent to Null / Nil / no value in languages besides OCaml)
- ex: print_endline "hi"
semicolon is an operator that errors if the program snippet on its left isn't an expression
Compiler Components¶
Source code --tokenizer(lexer)--> Tokens --parser--> AST --code gen--> Instructions --linker/assembler--> Binary
frontend: tokenizer and parser backend: code gen and linker/assembler
assembler: - takes in program.s - assembly -> machine code
linker: - links machine code chunks
S-expressions: lists containing symbols and numbers
compile.ml¶
compile function:
- input: program
- output: string of assembly representing that program
compile_to_file helper function that puts compile output in a file
runtime.c¶
- uses
_entryfromcompilefunction fromcompile.ml
Compiler Correctness, Booleans¶
@ - list append operator
if we could throw our compiler away and run the program, it happens at runtime!
-
cmp x y
- if x - y = 0 (aka if x == y):
- set zf to 1
- else:
- set zf to 0
- if x - y = 0 (aka if x == y):
-
setz R
- if ZF == 1:
- set last byte of R to 1
- else:
- set last byte of R to 0
- if ZF == 1:
-
jz L
- if ZF == 1, jump to label L
-
jmp L
- jump to label L
anything not false behaves as true in our compiler
our language is: - dynamically typed - eagerly evaluated - function args get evaluated right when function is called, not when they're used within the func! - lexically scoped - For example, say we define a function f: (define (f x y) (+ (g x) (g y))). With lexical scope, we can refer to x and y in the body of f, but we can’t refer to them once we’re in the body of g, even though g is called by f. - https://stackoverflow.com/questions/22394089/static-lexical-scoping-vs-dynamic-scoping-pseudocode
Week 0¶
compiler : source_program -> target_program
Compilers take source code written in one language and return source code written in another language.
interpreter : source_program -> value
Interpreters take source code written in some language and return a value.
164 compiler : OCaml -> x86-64 machine code
- runtime is in C
entry function: the entry point to the code our compiler is producing
OCaml¶
- is a functional programming language
- for each input, it always produces the same output
- has first-class functions
- you can use functions as input to other functions, and produce functions as output
- has type inference
- compiler automatically figures out most data types
- is statically-typed
- detects type errors at compile time
- is type-safe
- limits which kinds of operations can be performed on which kinds of data
- is primarily immutable
- no side effects that update state when producing a return value
In the toplevel, running let x = 24;; returns val x : int = 42.
- "
xhas typeintand equals42."
Week 1¶
S-Expressions¶
type s_exp =
Sym of string | Num of int | Lst of s_exp list
- Lst takes as its argument a list of other s-expressions.
fold_left
Unary Operations¶
Pipeline expressions: x |> f is the same as f x.
Dev environment¶
Works for Fall 2025
{
description = "cs164";
inputs = {
nixpkgs.url = "github:nixos/nixpkgs?ref=nixos-unstable";
systems.url = "github:nix-systems/default";
};
outputs = { self, nixpkgs, systems }:
let
pkgsFor = system: nixpkgs.legacyPackages.${system};
forAllSystems = fn: nixpkgs.lib.genAttrs (import systems) (system: fn (pkgsFor system));
in
{
packages = forAllSystems (pkgs: {
default = pkgs.callPackage ./. { };
});
devShells = forAllSystems (pkgs: {
default = pkgs.mkShell {
inputsFrom = [ self.packages.${pkgs.system}.default ];
#shellHook = "mkdocs serve";
};
});
formatter = forAllSystems (pkgs: pkgs.nixpkgs-fmt);
};
}
{ pkgs }:
pkgs.stdenvNoCC.mkDerivation {
name = "cs164";
src = ./.;
nativeBuildInputs = with pkgs; [
ocaml
dune_3
ocamlPackages.findlib
ocamlPackages.ounit2
ocamlPackages.ppx_deriving
ocamlPackages.menhir
ocamlPackages.yojson
ocamlPackages.janeStreet.shexp
ocamlPackages.core_unix
ocamlPackages.ppx_blob
nasm
# for examples in class notes
libgccjit
];
}
In a directory with both of these files on a machine with Nix installed, run nix develop --extra-experimental-features nix-command --extra-experimental-features flakes. Remove flags if you have flakes or nix-command enabled systemwide.