Writing An Interpreter In Go is a a fun book which covers writing an end to end interpreter in Go. I took a compiler course at my university which required reading the dragon book, but I feel that this book was a great and to-the-point guide in building your own language. While it doesn’t cover the theory, the intent is a straightforward text to introduce you to interpreters/compilers.

You write a lexer, parser, and the evaluating interpreter in Go from scratch without any third party dependencies. It is fast-paced with an encouraging tone which celebrates your accomplishments. The full code is provided, but I found it helpful to write and then play around with the code to fully understand it. I hadn’t written any significant Go programs before so it was helpful in learning the language.

The book guides the reader to implement the Monkey language. Monkey is fairly featured and covers basic expressions, functions, arrays, hashes, built-ins, closures, and a bit more.

While I haven’t written an end-to-end compiler since college, many of the concepts especially lexing/parsing are useful in a wide range of problems. Knowing how a compiler works is fundamental to advancing programming skills at a certain point. Reading this book has made me appreciate again how important those skills are in a relatively short and practical text.

There is a lost chapter available for free which implements a macro system and a sequel book to implement a bytecode compiler. I intend to read both in the future.

Terraform has a TLS Provider for generating certificates. It can generate a CA, certificates signed by a CA, self-signed certificates, and a bit more.

(Note: While you should not use tls_private_key in production environments (because the data is not encrypted in the Terraform state), it is great for development environments.)

Here’s an example Terraform file which generates a CA and a signed certificate which you can use with your own web server:

provider "tls" {
  version = "~> 1.2"
}

provider "local" {
  version = "~> 1.1"
}

resource "tls_private_key" "acme_ca" {
  algorithm = "RSA"
  rsa_bits  = "4096"
}

resource "local_file" "acme_ca_key" {
  content  = "${tls_private_key.acme_ca.private_key_pem}"
  filename = "${path.module}/certs/acme_ca_private_key.pem"
}

resource "tls_self_signed_cert" "acme_ca" {
  key_algorithm     = "RSA"
  private_key_pem   = "${tls_private_key.acme_ca.private_key_pem}"
  is_ca_certificate = true

  subject {
    common_name         = "Acme Self Signed CA"
    organization        = "Acme Self Signed"
    organizational_unit = "acme"
  }

  validity_period_hours = 87659

  allowed_uses = [
    "digital_signature",
    "cert_signing",
    "crl_signing",
  ]
}

resource "local_file" "acme_ca_cert" {
  content  = "${tls_self_signed_cert.acme_ca.cert_pem}"
  filename = "${path.module}/certs/acme_ca.pem"
}

resource "tls_private_key" "example_com" {
  algorithm = "RSA"
  rsa_bits  = "4096"
}

resource "local_file" "example_com_key" {
  content  = "${tls_private_key.example_com.private_key_pem}"
  filename = "${path.module}/certs/example_com_private_key.pem"
}

resource "tls_cert_request" "example_com" {
  key_algorithm   = "RSA"
  private_key_pem = "${tls_private_key.example_com.private_key_pem}"

  dns_names = ["example.com"]

  subject {
    common_name         = "example.com"
    organization        = "Example Self Signed"
    country             = "US"
    organizational_unit = "example.com"
  }
}

resource "tls_locally_signed_cert" "example_com" {
  cert_request_pem   = "${tls_cert_request.example_com.cert_request_pem}"
  ca_key_algorithm   = "RSA"
  ca_private_key_pem = "${tls_private_key.acme_ca.private_key_pem}"
  ca_cert_pem        = "${tls_self_signed_cert.acme_ca.cert_pem}"

  validity_period_hours = 87659

  allowed_uses = [
    "digital_signature",
    "key_encipherment",
    "server_auth",
    "client_auth",
  ]
}

resource "local_file" "example_com_cert_pem" {
  content  = "${tls_locally_signed_cert.example_com.cert_pem}"
  filename = "${path.module}/certs/example_com_cert.pem"
}

While Vim is my preferred editor of choice, I mostly only used the text editor with a few plugins and never really delved into scripting beyond editing my .vimrc.

After finding a few more useful Vim plugins that helped me out, I started searching for some plugins for Swift. I couldn’t find any beyond some syntax analysis and integration with SwiftLint via Syntastic, so I looked into writing my own plugin for building/testing Swift packages.

:help script and :help plugin are probably the definite resources in learning how to write Vim script. Also, I found an older IBM Developer tutorial and Learn Vimscript the Hard Way to be helpful.

Vim script isn’t too difficult to use and it has helped decipher some of the weird declarations in my .vimrc. For example, I found out why some variables start with g:some_var_name versus s:some_var_name; you can find out by doing :help internal-variables.

If you use Vim, I would seriously spend a day working on building a simple script since it helps explain a lot and can increase your Vim knowledge. Even if you’re not using Vim, I would look into how scriptable your text editor of choice is. For instance, Atom (or the fork VSCode) seems to be very scriptable as well.

I’ve started a swifty-vim plugin and it has made me appreciate how much further I can automate and simplify my workflow.